From 936c450a86c841eea89888c8550c9118fae90c25 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 28 Nov 2016 22:15:48 +0100 Subject: [PATCH] Tree wide: Reformat with clang-format. --- contrib/examples/myplugin.c | 236 +- proto/collectd.proto | 5 +- proto/prometheus.proto | 55 +- src/aggregation.c | 692 ++- src/amqp.c | 1722 +++--- src/apache.c | 1008 ++-- src/apcups.c | 675 +-- src/apple_sensors.c | 312 +- src/aquaero.c | 247 +- src/ascent.c | 583 +- src/barometer.c | 2533 ++++---- src/battery.c | 1253 ++-- src/battery_statefs.c | 34 +- src/bind.c | 1539 +++-- src/ceph.c | 2354 ++++---- src/ceph_test.c | 110 +- src/cgroups.c | 371 +- src/chrony.c | 765 ++- src/collectd-nagios.c | 1206 ++-- src/collectd-tg.c | 357 +- src/collectdctl.c | 478 +- src/collectdmon.c | 575 +- src/conntrack.c | 86 +- src/contextswitch.c | 173 +- src/cpu.c | 1214 ++-- src/cpufreq.c | 97 +- src/cpusleep.c | 4 +- src/cpython.h | 152 +- src/csv.c | 580 +- src/curl.c | 553 +- src/curl_json.c | 781 ++- src/curl_xml.c | 911 ++- src/daemon/collectd.c | 1158 ++-- src/daemon/collectd.h | 274 +- src/daemon/common.c | 2547 ++++---- src/daemon/common.h | 196 +- src/daemon/common_test.c | 314 +- src/daemon/configfile.c | 2166 ++++--- src/daemon/configfile.h | 47 +- src/daemon/filter_chain.c | 769 ++- src/daemon/filter_chain.h | 43 +- src/daemon/meta_data.c | 485 +- src/daemon/meta_data.h | 71 +- src/daemon/meta_data_test.c | 98 +- src/daemon/plugin.c | 4228 +++++++------ src/daemon/plugin.h | 387 +- src/daemon/plugin_mock.c | 46 +- src/daemon/types_list.c | 137 +- src/daemon/types_list.h | 2 +- src/daemon/utils_avltree.c | 1092 ++-- src/daemon/utils_avltree.h | 23 +- src/daemon/utils_avltree_test.c | 111 +- src/daemon/utils_cache.c | 892 ++- src/daemon/utils_cache.h | 106 +- src/daemon/utils_cache_mock.c | 14 +- src/daemon/utils_complain.c | 95 +- src/daemon/utils_complain.h | 52 +- src/daemon/utils_heap.c | 103 +- src/daemon/utils_heap.h | 8 +- src/daemon/utils_heap_test.c | 31 +- src/daemon/utils_ignorelist.c | 344 +- src/daemon/utils_ignorelist.h | 12 +- src/daemon/utils_llist.c | 192 +- src/daemon/utils_llist.h | 35 +- src/daemon/utils_match.c | 273 +- src/daemon/utils_match.h | 60 +- src/daemon/utils_random.c | 28 +- src/daemon/utils_random.h | 4 +- src/daemon/utils_subst.c | 239 +- src/daemon/utils_subst.h | 11 +- src/daemon/utils_subst_test.c | 103 +- src/daemon/utils_tail.c | 234 +- src/daemon/utils_tail.h | 10 +- src/daemon/utils_tail_match.c | 191 +- src/daemon/utils_tail_match.h | 40 +- src/daemon/utils_threshold.c | 85 +- src/daemon/utils_threshold.h | 18 +- src/daemon/utils_time.c | 133 +- src/daemon/utils_time_test.c | 142 +- src/dbi.c | 731 ++- src/df.c | 610 +- src/disk.c | 1663 +++--- src/dns.c | 636 +- src/drbd.c | 232 +- src/email.c | 1116 ++-- src/entropy.c | 40 +- src/ethstat.c | 290 +- src/exec.c | 741 ++- src/fhcount.c | 45 +- src/filecount.c | 490 +- src/fscache.c | 212 +- src/gmond.c | 1023 ++-- src/gps.c | 258 +- src/hddtemp.c | 436 +- src/hugepages.c | 2 +- src/intel_rdt.c | 2 +- src/interface.c | 563 +- src/ipc.c | 226 +- src/ipmi.c | 652 +- src/iptables.c | 716 +-- src/ipvs.c | 452 +- src/irq.c | 265 +- src/java.c | 2888 +++++---- src/libcollectdclient/client.c | 806 ++- src/libcollectdclient/collectd/client.h | 79 +- src/libcollectdclient/collectd/network.h | 33 +- .../collectd/network_buffer.h | 23 +- src/libcollectdclient/network.c | 291 +- src/libcollectdclient/network_buffer.c | 630 +- src/liboconfig/oconfig.c | 166 +- src/liboconfig/oconfig.h | 33 +- src/load.c | 260 +- src/log_logstash.c | 565 +- src/logfile.c | 329 +- src/lpar.c | 372 +- src/lua.c | 26 +- src/lvm.c | 265 +- src/madwifi.c | 1385 +++-- src/match_empty_counter.c | 44 +- src/match_hashed.c | 110 +- src/match_regex.c | 601 +- src/match_timediff.c | 80 +- src/match_value.c | 221 +- src/mbmon.c | 395 +- src/md.c | 141 +- src/memcachec.c | 361 +- src/memcached.c | 536 +- src/memory.c | 741 ++- src/mic.c | 595 +- src/modbus.c | 758 ++- src/mqtt.c | 1184 ++-- src/multimeter.c | 352 +- src/mysql.c | 1792 +++--- src/netapp.c | 5230 ++++++++--------- src/netlink.c | 679 +-- src/network.c | 4623 +++++++-------- src/network.h | 28 +- src/nfs.c | 966 ++- src/nginx.c | 265 +- src/notify_desktop.c | 211 +- src/notify_email.c | 282 +- src/notify_nagios.c | 130 +- src/ntpd.c | 1627 +++-- src/numa.c | 97 +- src/nut.c | 255 +- src/olsrd.c | 533 +- src/onewire.c | 691 +-- src/openldap.c | 1082 ++-- src/openvpn.c | 1347 ++--- src/oracle.c | 639 +- src/perl.c | 4073 +++++++------ src/pf.c | 163 +- src/pinba.c | 516 +- src/pinba.proto | 32 +- src/ping.c | 538 +- src/postgresql.c | 2157 ++++--- src/powerdns.c | 981 ++-- src/processes.c | 4148 +++++++------ src/protocols.c | 178 +- src/pyconfig.c | 331 +- src/python.c | 2298 ++++---- src/pyvalues.c | 2034 ++++--- src/redis.c | 463 +- src/routeros.c | 417 +- src/rrdcached.c | 521 +- src/rrdtool.c | 1867 +++--- src/sensors.c | 872 ++- src/serial.c | 157 +- src/sigrok.c | 629 +- src/smart.c | 279 +- src/snmp.c | 1396 ++--- src/statsd.c | 790 ++- src/swap.c | 1109 ++-- src/syslog.c | 187 +- src/table.c | 839 ++- src/tail.c | 280 +- src/tail_csv.c | 872 ++- src/tape.c | 153 +- src/target_notification.c | 212 +- src/target_replace.c | 498 +- src/target_scale.c | 800 ++- src/target_set.c | 357 +- src/target_v5upgrade.c | 297 +- src/tcpconns.c | 835 ++- src/teamspeak2.c | 1384 ++--- src/ted.c | 463 +- src/testing.h | 173 +- src/thermal.c | 311 +- src/threshold.c | 725 +-- src/tokyotyrant.c | 213 +- src/turbostat.c | 2460 ++++---- src/unixsock.c | 766 ++- src/uptime.c | 329 +- src/users.c | 115 +- src/utils_cmd_flush.c | 307 +- src/utils_cmds.c | 523 +- src/utils_cmds_test.c | 444 +- src/utils_latency_config.c | 2 +- src/utils_lua.c | 7 +- src/utils_lua.h | 2 +- src/utils_mount.c | 1258 ++-- src/utils_mount_test.c | 97 +- src/utils_parse_option.c | 37 +- src/utils_parse_option.h | 4 +- src/utils_rrdcreate.c | 577 +- src/utils_rrdcreate.h | 12 +- src/utils_vl_lookup.c | 530 +- src/utils_vl_lookup.h | 42 +- src/utils_vl_lookup_test.c | 274 +- src/uuid.c | 322 +- src/varnish.c | 2059 ++++--- src/virt.c | 1474 +++-- src/vmem.c | 227 +- src/vserver.c | 544 +- src/wireless.c | 198 +- src/write_graphite.c | 886 ++- src/write_http.c | 1440 +++-- src/write_kafka.c | 764 ++- src/write_log.c | 161 +- src/write_mongodb.c | 323 +- src/write_redis.c | 211 +- src/write_riemann.c | 8 +- src/write_riemann_threshold.c | 152 +- src/write_riemann_threshold.h | 2 +- src/write_sensu.c | 2171 +++---- src/write_tsdb.c | 890 ++- src/xencpu.c | 165 +- src/xmms.c | 33 +- src/zfs_arc.c | 461 +- src/zone.c | 277 +- src/zookeeper.c | 440 +- 231 files changed, 66257 insertions(+), 74743 deletions(-) diff --git a/contrib/examples/myplugin.c b/contrib/examples/myplugin.c index adeae8c3..d95f10b5 100644 --- a/contrib/examples/myplugin.c +++ b/contrib/examples/myplugin.c @@ -18,20 +18,20 @@ * is optional */ -#if ! HAVE_CONFIG_H +#if !HAVE_CONFIG_H #include #include #ifndef __USE_ISOC99 /* required for NAN */ -# define DISABLE_ISOC99 1 -# define __USE_ISOC99 1 +#define DISABLE_ISOC99 1 +#define __USE_ISOC99 1 #endif /* !defined(__USE_ISOC99) */ #include #if DISABLE_ISOC99 -# undef DISABLE_ISOC99 -# undef __USE_ISOC99 +#undef DISABLE_ISOC99 +#undef __USE_ISOC99 #endif /* DISABLE_ISOC99 */ #include @@ -50,10 +50,7 @@ * - minimum allowed value * - maximum allowed value */ -static data_source_t dsrc[1] = -{ - { "my_ds", DS_TYPE_GAUGE, 0, NAN } -}; +static data_source_t dsrc[1] = {{"my_ds", DS_TYPE_GAUGE, 0, NAN}}; /* * data set definition: @@ -67,174 +64,163 @@ static data_source_t dsrc[1] = * It is strongly recommended to use one of the types and data-sets * pre-defined in the types.db file. */ -static data_set_t ds = -{ - "myplugin", STATIC_ARRAY_SIZE (dsrc), dsrc -}; +static data_set_t ds = {"myplugin", STATIC_ARRAY_SIZE(dsrc), dsrc}; /* * This function is called once upon startup to initialize the plugin. */ -static int my_init (void) -{ - /* open sockets, initialize data structures, ... */ +static int my_init(void) { + /* open sockets, initialize data structures, ... */ - /* A return value != 0 indicates an error and causes the plugin to be - disabled. */ - return 0; + /* A return value != 0 indicates an error and causes the plugin to be + disabled. */ + return 0; } /* static int my_init (void) */ /* * This is a utility function used by the read callback to populate a * value_list_t and pass it to plugin_dispatch_values. */ -static int my_submit (gauge_t value) -{ - value_list_t vl = VALUE_LIST_INIT; - - /* Convert the gauge_t to a value_t and add it to the value_list_t. */ - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - - /* Only set vl.time yourself if you update multiple metrics (i.e. you - * have multiple calls to plugin_dispatch_values()) and they need to all - * have the same timestamp. */ - /* vl.time = cdtime(); */ - - sstrncpy (vl.plugin, "myplugin", sizeof (vl.plugin)); - - /* it is strongly recommended to use a type defined in the types.db file - * instead of a custom type */ - sstrncpy (vl.type, "myplugin", sizeof (vl.type)); - /* optionally set vl.plugin_instance and vl.type_instance to reasonable - * values (default: "") */ - - /* dispatch the values to collectd which passes them on to all registered - * write functions */ - return plugin_dispatch_values (&vl); +static int my_submit(gauge_t value) { + value_list_t vl = VALUE_LIST_INIT; + + /* Convert the gauge_t to a value_t and add it to the value_list_t. */ + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + + /* Only set vl.time yourself if you update multiple metrics (i.e. you + * have multiple calls to plugin_dispatch_values()) and they need to all + * have the same timestamp. */ + /* vl.time = cdtime(); */ + + sstrncpy(vl.plugin, "myplugin", sizeof(vl.plugin)); + + /* it is strongly recommended to use a type defined in the types.db file + * instead of a custom type */ + sstrncpy(vl.type, "myplugin", sizeof(vl.type)); + /* optionally set vl.plugin_instance and vl.type_instance to reasonable + * values (default: "") */ + + /* dispatch the values to collectd which passes them on to all registered + * write functions */ + return plugin_dispatch_values(&vl); } /* * This function is called in regular intervalls to collect the data. */ -static int my_read (void) -{ - /* do the magic to read the data */ - gauge_t value = random (); +static int my_read(void) { + /* do the magic to read the data */ + gauge_t value = random(); - if (my_submit (value) != 0) - WARNING ("myplugin plugin: Dispatching a random value failed."); + if (my_submit(value) != 0) + WARNING("myplugin plugin: Dispatching a random value failed."); - /* A return value != 0 indicates an error and the plugin will be skipped - * for an increasing amount of time. */ - return 0; + /* A return value != 0 indicates an error and the plugin will be skipped + * for an increasing amount of time. */ + return 0; } /* static int my_read (void) */ /* * This function is called after values have been dispatched to collectd. */ -static int my_write (const data_set_t *ds, const value_list_t *vl, - user_data_t *ud) -{ - char name[1024] = ""; - int i = 0; - - if (ds->ds_num != vl->values_len) { - plugin_log (LOG_WARNING, "DS number does not match values length"); - return -1; - } - - /* get the default base filename for the output file - depending on the - * provided values this will be something like - * /[-]/[-] */ - if (0 != format_name (name, 1024, vl->host, vl->plugin, - vl->plugin_instance, ds->type, vl->type_instance)) - return -1; - - for (i = 0; i < ds->ds_num; ++i) { - /* do the magic to output the data */ - printf ("%s (%s) at %i: ", name, - (ds->ds->type == DS_TYPE_GAUGE) ? "GAUGE" : "COUNTER", - (int)vl->time); - - if (ds->ds->type == DS_TYPE_GAUGE) - printf ("%f\n", vl->values[i].gauge); - else - printf ("%lld\n", vl->values[i].counter); - } - return 0; +static int my_write(const data_set_t *ds, const value_list_t *vl, + user_data_t *ud) { + char name[1024] = ""; + int i = 0; + + if (ds->ds_num != vl->values_len) { + plugin_log(LOG_WARNING, "DS number does not match values length"); + return -1; + } + + /* get the default base filename for the output file - depending on the + * provided values this will be something like + * /[-]/[-] */ + if (0 != format_name(name, 1024, vl->host, vl->plugin, vl->plugin_instance, + ds->type, vl->type_instance)) + return -1; + + for (i = 0; i < ds->ds_num; ++i) { + /* do the magic to output the data */ + printf("%s (%s) at %i: ", name, + (ds->ds->type == DS_TYPE_GAUGE) ? "GAUGE" : "COUNTER", + (int)vl->time); + + if (ds->ds->type == DS_TYPE_GAUGE) + printf("%f\n", vl->values[i].gauge); + else + printf("%lld\n", vl->values[i].counter); + } + return 0; } /* static int my_write (data_set_t *, value_list_t *) */ /* * This function is called when plugin_log () has been used. */ -static void my_log (int severity, const char *msg, user_data_t *ud) -{ - printf ("LOG: %i - %s\n", severity, msg); - return; +static void my_log(int severity, const char *msg, user_data_t *ud) { + printf("LOG: %i - %s\n", severity, msg); + return; } /* static void my_log (int, const char *) */ /* * This function is called when plugin_dispatch_notification () has been used. */ -static int my_notify (const notification_t *notif, user_data_t *ud) -{ - char time_str[32] = ""; - struct tm *tm = NULL; +static int my_notify(const notification_t *notif, user_data_t *ud) { + char time_str[32] = ""; + struct tm *tm = NULL; - int n = 0; + int n = 0; - if (NULL == (tm = localtime (¬if->time))) - time_str[0] = '\0'; + if (NULL == (tm = localtime(¬if->time))) + time_str[0] = '\0'; - n = strftime (time_str, 32, "%F %T", tm); - if (n >= 32) n = 31; - time_str[n] = '\0'; + n = strftime(time_str, 32, "%F %T", tm); + if (n >= 32) + n = 31; + time_str[n] = '\0'; - printf ("NOTIF (%s): %i - ", time_str, notif->severity); + printf("NOTIF (%s): %i - ", time_str, notif->severity); - if ('\0' != *notif->host) - printf ("%s: ", notif->host); + if ('\0' != *notif->host) + printf("%s: ", notif->host); - if ('\0' != *notif->plugin) - printf ("%s: ", notif->plugin); + if ('\0' != *notif->plugin) + printf("%s: ", notif->plugin); - if ('\0' != *notif->plugin_instance) - printf ("%s: ", notif->plugin_instance); + if ('\0' != *notif->plugin_instance) + printf("%s: ", notif->plugin_instance); - if ('\0' != *notif->type) - printf ("%s: ", notif->type); + if ('\0' != *notif->type) + printf("%s: ", notif->type); - if ('\0' != *notif->type_instance) - printf ("%s: ", notif->type_instance); + if ('\0' != *notif->type_instance) + printf("%s: ", notif->type_instance); - printf ("%s\n", notif->message); - return 0; + printf("%s\n", notif->message); + return 0; } /* static int my_notify (notification_t *) */ /* * This function is called before shutting down collectd. */ -static int my_shutdown (void) -{ - /* close sockets, free data structures, ... */ - return 0; +static int my_shutdown(void) { + /* close sockets, free data structures, ... */ + return 0; } /* static int my_shutdown (void) */ /* * This function is called after loading the plugin to register it with * collectd. */ -void module_register (void) -{ - plugin_register_log ("myplugin", my_log, /* user data */ NULL); - plugin_register_notification ("myplugin", my_notify, - /* user data */ NULL); - plugin_register_data_set (&ds); - plugin_register_read ("myplugin", my_read); - plugin_register_init ("myplugin", my_init); - plugin_register_write ("myplugin", my_write, /* user data */ NULL); - plugin_register_shutdown ("myplugin", my_shutdown); - return; +void module_register(void) { + plugin_register_log("myplugin", my_log, /* user data */ NULL); + plugin_register_notification("myplugin", my_notify, + /* user data */ NULL); + plugin_register_data_set(&ds); + plugin_register_read("myplugin", my_read); + plugin_register_init("myplugin", my_init); + plugin_register_write("myplugin", my_write, /* user data */ NULL); + plugin_register_shutdown("myplugin", my_shutdown); + return; } /* void module_register (void) */ - diff --git a/proto/collectd.proto b/proto/collectd.proto index 614d1bd0..83d21282 100644 --- a/proto/collectd.proto +++ b/proto/collectd.proto @@ -33,12 +33,11 @@ service Collectd { // PutValues reads the value lists from the PutValuesRequest stream. // The gRPC server embedded into collectd will inject them into the system // just like the network plugin. - rpc PutValues(stream PutValuesRequest) - returns (PutValuesResponse); + rpc PutValues(stream PutValuesRequest) returns(PutValuesResponse); // QueryValues returns a stream of matching value lists from collectd's // internal cache. - rpc QueryValues(QueryValuesRequest) returns (stream QueryValuesResponse); + rpc QueryValues(QueryValuesRequest) returns(stream QueryValuesResponse); } // The arguments to PutValues. diff --git a/proto/prometheus.proto b/proto/prometheus.proto index 0b84af92..17adaf4d 100644 --- a/proto/prometheus.proto +++ b/proto/prometheus.proto @@ -17,45 +17,36 @@ package io.prometheus.client; option java_package = "io.prometheus.client"; message LabelPair { - optional string name = 1; + optional string name = 1; optional string value = 2; } enum MetricType { - COUNTER = 0; - GAUGE = 1; - SUMMARY = 2; - UNTYPED = 3; - HISTOGRAM = 4; + COUNTER = 0; GAUGE = 1; SUMMARY = 2; UNTYPED = 3; HISTOGRAM = 4; } -message Gauge { - optional double value = 1; -} +message Gauge { optional double value = 1; } -message Counter { - optional double value = 1; -} +message Counter { optional double value = 1; } message Quantile { optional double quantile = 1; - optional double value = 2; + optional double value = 2; } message Summary { - optional uint64 sample_count = 1; - optional double sample_sum = 2; - repeated Quantile quantile = 3; + optional uint64 sample_count = 1; + optional double sample_sum = 2; + repeated Quantile quantile = 3; } -message Untyped { - optional double value = 1; -} +message Untyped { optional double value = 1; } message Histogram { optional uint64 sample_count = 1; - optional double sample_sum = 2; - repeated Bucket bucket = 3; // Ordered in increasing order of upper_bound, +Inf bucket is optional. + optional double sample_sum = 2; + repeated Bucket bucket = + 3; // Ordered in increasing order of upper_bound, +Inf bucket is optional. } message Bucket { @@ -64,18 +55,18 @@ message Bucket { } message Metric { - repeated LabelPair label = 1; - optional Gauge gauge = 2; - optional Counter counter = 3; - optional Summary summary = 4; - optional Untyped untyped = 5; - optional Histogram histogram = 7; - optional int64 timestamp_ms = 6; + repeated LabelPair label = 1; + optional Gauge gauge = 2; + optional Counter counter = 3; + optional Summary summary = 4; + optional Untyped untyped = 5; + optional Histogram histogram = 7; + optional int64 timestamp_ms = 6; } message MetricFamily { - optional string name = 1; - optional string help = 2; - optional MetricType type = 3; - repeated Metric metric = 4; + optional string name = 1; + optional string help = 2; + optional MetricType type = 3; + repeated Metric metric = 4; } diff --git a/src/aggregation.c b/src/aggregation.c index bb37b858..4e20d0cf 100644 --- a/src/aggregation.c +++ b/src/aggregation.c @@ -26,14 +26,14 @@ #include "collectd.h" -#include "plugin.h" #include "common.h" #include "meta_data.h" +#include "plugin.h" #include "utils_cache.h" /* for uc_get_rate() */ #include "utils_subst.h" #include "utils_vl_lookup.h" -#define AGG_MATCHES_ALL(str) (strcmp ("/.*/", str) == 0) +#define AGG_MATCHES_ALL(str) (strcmp("/.*/", str) == 0) #define AGG_FUNC_PLACEHOLDER "%{aggregation}" struct aggregation_s /* {{{ */ @@ -88,14 +88,14 @@ static lookup_t *lookup = NULL; static pthread_mutex_t agg_instance_list_lock = PTHREAD_MUTEX_INITIALIZER; static agg_instance_t *agg_instance_list_head = NULL; -static _Bool agg_is_regex (char const *str) /* {{{ */ +static _Bool agg_is_regex(char const *str) /* {{{ */ { size_t len; if (str == NULL) return (0); - len = strlen (str); + len = strlen(str); if (len < 3) return (0); @@ -105,124 +105,120 @@ static _Bool agg_is_regex (char const *str) /* {{{ */ return (0); } /* }}} _Bool agg_is_regex */ -static void agg_destroy (aggregation_t *agg) /* {{{ */ +static void agg_destroy(aggregation_t *agg) /* {{{ */ { - sfree (agg); + sfree(agg); } /* }}} void agg_destroy */ /* Frees all dynamically allocated memory within the instance. */ -static void agg_instance_destroy (agg_instance_t *inst) /* {{{ */ +static void agg_instance_destroy(agg_instance_t *inst) /* {{{ */ { if (inst == NULL) return; /* Remove this instance from the global list of instances. */ - pthread_mutex_lock (&agg_instance_list_lock); + pthread_mutex_lock(&agg_instance_list_lock); if (agg_instance_list_head == inst) agg_instance_list_head = inst->next; - else if (agg_instance_list_head != NULL) - { + else if (agg_instance_list_head != NULL) { agg_instance_t *prev = agg_instance_list_head; while ((prev != NULL) && (prev->next != inst)) prev = prev->next; if (prev != NULL) prev->next = inst->next; } - pthread_mutex_unlock (&agg_instance_list_lock); + pthread_mutex_unlock(&agg_instance_list_lock); - sfree (inst->state_num); - sfree (inst->state_sum); - sfree (inst->state_average); - sfree (inst->state_min); - sfree (inst->state_max); - sfree (inst->state_stddev); + sfree(inst->state_num); + sfree(inst->state_sum); + sfree(inst->state_average); + sfree(inst->state_min); + sfree(inst->state_max); + sfree(inst->state_stddev); - memset (inst, 0, sizeof (*inst)); + memset(inst, 0, sizeof(*inst)); inst->ds_type = -1; inst->min = NAN; inst->max = NAN; } /* }}} void agg_instance_destroy */ -static int agg_instance_create_name (agg_instance_t *inst, /* {{{ */ - value_list_t const *vl, aggregation_t const *agg) -{ -#define COPY_FIELD(buffer, buffer_size, field, group_mask, all_value) do { \ - if (agg->set_ ## field != NULL) \ - sstrncpy (buffer, agg->set_ ## field, buffer_size); \ - else if ((agg->regex_fields & group_mask) \ - && (agg->group_by & group_mask)) \ - sstrncpy (buffer, vl->field, buffer_size); \ - else if ((agg->regex_fields & group_mask) \ - && (AGG_MATCHES_ALL (agg->ident.field))) \ - sstrncpy (buffer, all_value, buffer_size); \ - else \ - sstrncpy (buffer, agg->ident.field, buffer_size); \ -} while (0) +static int agg_instance_create_name(agg_instance_t *inst, /* {{{ */ + value_list_t const *vl, + aggregation_t const *agg) { +#define COPY_FIELD(buffer, buffer_size, field, group_mask, all_value) \ + do { \ + if (agg->set_##field != NULL) \ + sstrncpy(buffer, agg->set_##field, buffer_size); \ + else if ((agg->regex_fields & group_mask) && (agg->group_by & group_mask)) \ + sstrncpy(buffer, vl->field, buffer_size); \ + else if ((agg->regex_fields & group_mask) && \ + (AGG_MATCHES_ALL(agg->ident.field))) \ + sstrncpy(buffer, all_value, buffer_size); \ + else \ + sstrncpy(buffer, agg->ident.field, buffer_size); \ + } while (0) /* Host */ - COPY_FIELD (inst->ident.host, sizeof (inst->ident.host), - host, LU_GROUP_BY_HOST, "global"); + COPY_FIELD(inst->ident.host, sizeof(inst->ident.host), host, LU_GROUP_BY_HOST, + "global"); /* Plugin */ if (agg->set_plugin != NULL) - sstrncpy (inst->ident.plugin, agg->set_plugin, - sizeof (inst->ident.plugin)); + sstrncpy(inst->ident.plugin, agg->set_plugin, sizeof(inst->ident.plugin)); else - sstrncpy (inst->ident.plugin, "aggregation", sizeof (inst->ident.plugin)); + sstrncpy(inst->ident.plugin, "aggregation", sizeof(inst->ident.plugin)); /* Plugin instance */ if (agg->set_plugin_instance != NULL) - sstrncpy (inst->ident.plugin_instance, agg->set_plugin_instance, - sizeof (inst->ident.plugin_instance)); - else - { + sstrncpy(inst->ident.plugin_instance, agg->set_plugin_instance, + sizeof(inst->ident.plugin_instance)); + else { char tmp_plugin[DATA_MAX_NAME_LEN]; char tmp_plugin_instance[DATA_MAX_NAME_LEN] = ""; - if ((agg->regex_fields & LU_GROUP_BY_PLUGIN) - && (agg->group_by & LU_GROUP_BY_PLUGIN)) - sstrncpy (tmp_plugin, vl->plugin, sizeof (tmp_plugin)); - else if ((agg->regex_fields & LU_GROUP_BY_PLUGIN) - && (AGG_MATCHES_ALL (agg->ident.plugin))) - sstrncpy (tmp_plugin, "", sizeof (tmp_plugin)); + if ((agg->regex_fields & LU_GROUP_BY_PLUGIN) && + (agg->group_by & LU_GROUP_BY_PLUGIN)) + sstrncpy(tmp_plugin, vl->plugin, sizeof(tmp_plugin)); + else if ((agg->regex_fields & LU_GROUP_BY_PLUGIN) && + (AGG_MATCHES_ALL(agg->ident.plugin))) + sstrncpy(tmp_plugin, "", sizeof(tmp_plugin)); else - sstrncpy (tmp_plugin, agg->ident.plugin, sizeof (tmp_plugin)); - - if ((agg->regex_fields & LU_GROUP_BY_PLUGIN_INSTANCE) - && (agg->group_by & LU_GROUP_BY_PLUGIN_INSTANCE)) - sstrncpy (tmp_plugin_instance, vl->plugin_instance, - sizeof (tmp_plugin_instance)); - else if ((agg->regex_fields & LU_GROUP_BY_PLUGIN_INSTANCE) - && (AGG_MATCHES_ALL (agg->ident.plugin_instance))) - sstrncpy (tmp_plugin_instance, "", sizeof (tmp_plugin_instance)); + sstrncpy(tmp_plugin, agg->ident.plugin, sizeof(tmp_plugin)); + + if ((agg->regex_fields & LU_GROUP_BY_PLUGIN_INSTANCE) && + (agg->group_by & LU_GROUP_BY_PLUGIN_INSTANCE)) + sstrncpy(tmp_plugin_instance, vl->plugin_instance, + sizeof(tmp_plugin_instance)); + else if ((agg->regex_fields & LU_GROUP_BY_PLUGIN_INSTANCE) && + (AGG_MATCHES_ALL(agg->ident.plugin_instance))) + sstrncpy(tmp_plugin_instance, "", sizeof(tmp_plugin_instance)); else - sstrncpy (tmp_plugin_instance, agg->ident.plugin_instance, - sizeof (tmp_plugin_instance)); - - if ((strcmp ("", tmp_plugin) == 0) - && (strcmp ("", tmp_plugin_instance) == 0)) - sstrncpy (inst->ident.plugin_instance, AGG_FUNC_PLACEHOLDER, - sizeof (inst->ident.plugin_instance)); - else if (strcmp ("", tmp_plugin) != 0) - ssnprintf (inst->ident.plugin_instance, - sizeof (inst->ident.plugin_instance), - "%s-%s", tmp_plugin, AGG_FUNC_PLACEHOLDER); - else if (strcmp ("", tmp_plugin_instance) != 0) - ssnprintf (inst->ident.plugin_instance, - sizeof (inst->ident.plugin_instance), - "%s-%s", tmp_plugin_instance, AGG_FUNC_PLACEHOLDER); + sstrncpy(tmp_plugin_instance, agg->ident.plugin_instance, + sizeof(tmp_plugin_instance)); + + if ((strcmp("", tmp_plugin) == 0) && (strcmp("", tmp_plugin_instance) == 0)) + sstrncpy(inst->ident.plugin_instance, AGG_FUNC_PLACEHOLDER, + sizeof(inst->ident.plugin_instance)); + else if (strcmp("", tmp_plugin) != 0) + ssnprintf(inst->ident.plugin_instance, + sizeof(inst->ident.plugin_instance), "%s-%s", tmp_plugin, + AGG_FUNC_PLACEHOLDER); + else if (strcmp("", tmp_plugin_instance) != 0) + ssnprintf(inst->ident.plugin_instance, + sizeof(inst->ident.plugin_instance), "%s-%s", + tmp_plugin_instance, AGG_FUNC_PLACEHOLDER); else - ssnprintf (inst->ident.plugin_instance, - sizeof (inst->ident.plugin_instance), - "%s-%s-%s", tmp_plugin, tmp_plugin_instance, AGG_FUNC_PLACEHOLDER); + ssnprintf(inst->ident.plugin_instance, + sizeof(inst->ident.plugin_instance), "%s-%s-%s", tmp_plugin, + tmp_plugin_instance, AGG_FUNC_PLACEHOLDER); } /* Type */ - sstrncpy (inst->ident.type, agg->ident.type, sizeof (inst->ident.type)); + sstrncpy(inst->ident.type, agg->ident.type, sizeof(inst->ident.type)); /* Type instance */ - COPY_FIELD (inst->ident.type_instance, sizeof (inst->ident.type_instance), - type_instance, LU_GROUP_BY_TYPE_INSTANCE, ""); + COPY_FIELD(inst->ident.type_instance, sizeof(inst->ident.type_instance), + type_instance, LU_GROUP_BY_TYPE_INSTANCE, ""); #undef COPY_FIELD @@ -230,54 +226,54 @@ static int agg_instance_create_name (agg_instance_t *inst, /* {{{ */ } /* }}} int agg_instance_create_name */ /* Create a new aggregation instance. */ -static agg_instance_t *agg_instance_create (data_set_t const *ds, /* {{{ */ - value_list_t const *vl, aggregation_t *agg) -{ +static agg_instance_t *agg_instance_create(data_set_t const *ds, /* {{{ */ + value_list_t const *vl, + aggregation_t *agg) { agg_instance_t *inst; - DEBUG ("aggregation plugin: Creating new instance."); + DEBUG("aggregation plugin: Creating new instance."); - inst = calloc (1, sizeof (*inst)); - if (inst == NULL) - { - ERROR ("aggregation plugin: calloc() failed."); + inst = calloc(1, sizeof(*inst)); + if (inst == NULL) { + ERROR("aggregation plugin: calloc() failed."); return (NULL); } - pthread_mutex_init (&inst->lock, /* attr = */ NULL); + pthread_mutex_init(&inst->lock, /* attr = */ NULL); inst->ds_type = ds->ds[0].type; - agg_instance_create_name (inst, vl, agg); + agg_instance_create_name(inst, vl, agg); inst->min = NAN; inst->max = NAN; -#define INIT_STATE(field) do { \ - inst->state_ ## field = NULL; \ - if (agg->calc_ ## field) { \ - inst->state_ ## field = calloc (1, sizeof (*inst->state_ ## field)); \ - if (inst->state_ ## field == NULL) { \ - agg_instance_destroy (inst); \ - free (inst); \ - ERROR ("aggregation plugin: calloc() failed."); \ - return (NULL); \ - } \ - } \ -} while (0) - - INIT_STATE (num); - INIT_STATE (sum); - INIT_STATE (average); - INIT_STATE (min); - INIT_STATE (max); - INIT_STATE (stddev); +#define INIT_STATE(field) \ + do { \ + inst->state_##field = NULL; \ + if (agg->calc_##field) { \ + inst->state_##field = calloc(1, sizeof(*inst->state_##field)); \ + if (inst->state_##field == NULL) { \ + agg_instance_destroy(inst); \ + free(inst); \ + ERROR("aggregation plugin: calloc() failed."); \ + return (NULL); \ + } \ + } \ + } while (0) + + INIT_STATE(num); + INIT_STATE(sum); + INIT_STATE(average); + INIT_STATE(min); + INIT_STATE(max); + INIT_STATE(stddev); #undef INIT_STATE - pthread_mutex_lock (&agg_instance_list_lock); + pthread_mutex_lock(&agg_instance_list_lock); inst->next = agg_instance_list_head; agg_instance_list_head = inst; - pthread_mutex_unlock (&agg_instance_list_lock); + pthread_mutex_unlock(&agg_instance_list_lock); return (inst); } /* }}} agg_instance_t *agg_instance_create */ @@ -286,83 +282,79 @@ static agg_instance_t *agg_instance_create (data_set_t const *ds, /* {{{ */ * the rate of the value list is available. Value lists with more than one data * source are not supported and will return an error. Returns zero on success * and non-zero otherwise. */ -static int agg_instance_update (agg_instance_t *inst, /* {{{ */ - data_set_t const *ds, value_list_t const *vl) -{ +static int agg_instance_update(agg_instance_t *inst, /* {{{ */ + data_set_t const *ds, value_list_t const *vl) { gauge_t *rate; - if (ds->ds_num != 1) - { - ERROR ("aggregation plugin: The \"%s\" type (data set) has more than one " - "data source. This is currently not supported by this plugin. " - "Sorry.", ds->type); + if (ds->ds_num != 1) { + ERROR("aggregation plugin: The \"%s\" type (data set) has more than one " + "data source. This is currently not supported by this plugin. " + "Sorry.", + ds->type); return (EINVAL); } - rate = uc_get_rate (ds, vl); - if (rate == NULL) - { + rate = uc_get_rate(ds, vl); + if (rate == NULL) { char ident[6 * DATA_MAX_NAME_LEN]; - FORMAT_VL (ident, sizeof (ident), vl); - ERROR ("aggregation plugin: Unable to read the current rate of \"%s\".", - ident); + FORMAT_VL(ident, sizeof(ident), vl); + ERROR("aggregation plugin: Unable to read the current rate of \"%s\".", + ident); return (ENOENT); } - if (isnan (rate[0])) - { - sfree (rate); + if (isnan(rate[0])) { + sfree(rate); return (0); } - pthread_mutex_lock (&inst->lock); + pthread_mutex_lock(&inst->lock); inst->num++; inst->sum += rate[0]; inst->squares_sum += (rate[0] * rate[0]); - if (isnan (inst->min) || (inst->min > rate[0])) + if (isnan(inst->min) || (inst->min > rate[0])) inst->min = rate[0]; - if (isnan (inst->max) || (inst->max < rate[0])) + if (isnan(inst->max) || (inst->max < rate[0])) inst->max = rate[0]; - pthread_mutex_unlock (&inst->lock); + pthread_mutex_unlock(&inst->lock); - sfree (rate); + sfree(rate); return (0); } /* }}} int agg_instance_update */ -static int agg_instance_read_func (agg_instance_t *inst, /* {{{ */ - char const *func, gauge_t rate, rate_to_value_state_t *state, - value_list_t *vl, char const *pi_prefix, cdtime_t t) -{ +static int agg_instance_read_func(agg_instance_t *inst, /* {{{ */ + char const *func, gauge_t rate, + rate_to_value_state_t *state, + value_list_t *vl, char const *pi_prefix, + cdtime_t t) { value_t v; int status; if (pi_prefix[0] != 0) - subst_string (vl->plugin_instance, sizeof (vl->plugin_instance), - pi_prefix, AGG_FUNC_PLACEHOLDER, func); + subst_string(vl->plugin_instance, sizeof(vl->plugin_instance), pi_prefix, + AGG_FUNC_PLACEHOLDER, func); else - sstrncpy (vl->plugin_instance, func, sizeof (vl->plugin_instance)); + sstrncpy(vl->plugin_instance, func, sizeof(vl->plugin_instance)); - status = rate_to_value (&v, rate, state, inst->ds_type, t); - if (status != 0) - { + status = rate_to_value(&v, rate, state, inst->ds_type, t); + if (status != 0) { /* If this is the first iteration and rate_to_value() was asked to return a * COUNTER or a DERIVE, it will return EAGAIN. Catch this and handle * gracefully. */ if (status == EAGAIN) return (0); - WARNING ("aggregation plugin: rate_to_value failed with status %i.", - status); + WARNING("aggregation plugin: rate_to_value failed with status %i.", status); return (-1); } vl->values = &v; vl->values_len = 1; - plugin_dispatch_values (vl); + plugin_dispatch_values(vl); vl->values = NULL; vl->values_len = 0; @@ -370,7 +362,7 @@ static int agg_instance_read_func (agg_instance_t *inst, /* {{{ */ return (0); } /* }}} int agg_instance_read_func */ -static int agg_instance_read (agg_instance_t *inst, cdtime_t t) /* {{{ */ +static int agg_instance_read(agg_instance_t *inst, cdtime_t t) /* {{{ */ { value_list_t vl = VALUE_LIST_INIT; @@ -381,41 +373,41 @@ static int agg_instance_read (agg_instance_t *inst, cdtime_t t) /* {{{ */ vl.time = t; vl.interval = 0; - vl.meta = meta_data_create (); - if (vl.meta == NULL) - { - ERROR ("aggregation plugin: meta_data_create failed."); + vl.meta = meta_data_create(); + if (vl.meta == NULL) { + ERROR("aggregation plugin: meta_data_create failed."); return (-1); } - meta_data_add_boolean (vl.meta, "aggregation:created", 1); + meta_data_add_boolean(vl.meta, "aggregation:created", 1); - sstrncpy (vl.host, inst->ident.host, sizeof (vl.host)); - sstrncpy (vl.plugin, inst->ident.plugin, sizeof (vl.plugin)); - sstrncpy (vl.type, inst->ident.type, sizeof (vl.type)); - sstrncpy (vl.type_instance, inst->ident.type_instance, - sizeof (vl.type_instance)); + sstrncpy(vl.host, inst->ident.host, sizeof(vl.host)); + sstrncpy(vl.plugin, inst->ident.plugin, sizeof(vl.plugin)); + sstrncpy(vl.type, inst->ident.type, sizeof(vl.type)); + sstrncpy(vl.type_instance, inst->ident.type_instance, + sizeof(vl.type_instance)); -#define READ_FUNC(func, rate) do { \ - if (inst->state_ ## func != NULL) { \ - agg_instance_read_func (inst, #func, rate, \ - inst->state_ ## func, &vl, inst->ident.plugin_instance, t); \ - } \ -} while (0) +#define READ_FUNC(func, rate) \ + do { \ + if (inst->state_##func != NULL) { \ + agg_instance_read_func(inst, #func, rate, inst->state_##func, &vl, \ + inst->ident.plugin_instance, t); \ + } \ + } while (0) - pthread_mutex_lock (&inst->lock); + pthread_mutex_lock(&inst->lock); - READ_FUNC (num, (gauge_t) inst->num); + READ_FUNC(num, (gauge_t)inst->num); /* All other aggregations are only defined when there have been any values * at all. */ - if (inst->num > 0) - { - READ_FUNC (sum, inst->sum); - READ_FUNC (average, (inst->sum / ((gauge_t) inst->num))); - READ_FUNC (min, inst->min); - READ_FUNC (max, inst->max); - READ_FUNC (stddev, sqrt((((gauge_t) inst->num) * inst->squares_sum) - - (inst->sum * inst->sum)) / ((gauge_t) inst->num)); + if (inst->num > 0) { + READ_FUNC(sum, inst->sum); + READ_FUNC(average, (inst->sum / ((gauge_t)inst->num))); + READ_FUNC(min, inst->min); + READ_FUNC(max, inst->max); + READ_FUNC(stddev, sqrt((((gauge_t)inst->num) * inst->squares_sum) - + (inst->sum * inst->sum)) / + ((gauge_t)inst->num)); } /* Reset internal state. */ @@ -425,40 +417,40 @@ static int agg_instance_read (agg_instance_t *inst, cdtime_t t) /* {{{ */ inst->min = NAN; inst->max = NAN; - pthread_mutex_unlock (&inst->lock); + pthread_mutex_unlock(&inst->lock); - meta_data_destroy (vl.meta); + meta_data_destroy(vl.meta); vl.meta = NULL; return (0); } /* }}} int agg_instance_read */ /* lookup_class_callback_t for utils_vl_lookup */ -static void *agg_lookup_class_callback ( /* {{{ */ - data_set_t const *ds, value_list_t const *vl, void *user_class) -{ - return (agg_instance_create (ds, vl, (aggregation_t *) user_class)); +static void *agg_lookup_class_callback(/* {{{ */ + data_set_t const *ds, + value_list_t const *vl, + void *user_class) { + return (agg_instance_create(ds, vl, (aggregation_t *)user_class)); } /* }}} void *agg_class_callback */ /* lookup_obj_callback_t for utils_vl_lookup */ -static int agg_lookup_obj_callback (data_set_t const *ds, /* {{{ */ - value_list_t const *vl, - __attribute__((unused)) void *user_class, - void *user_obj) -{ - return (agg_instance_update ((agg_instance_t *) user_obj, ds, vl)); +static int agg_lookup_obj_callback(data_set_t const *ds, /* {{{ */ + value_list_t const *vl, + __attribute__((unused)) void *user_class, + void *user_obj) { + return (agg_instance_update((agg_instance_t *)user_obj, ds, vl)); } /* }}} int agg_lookup_obj_callback */ /* lookup_free_class_callback_t for utils_vl_lookup */ -static void agg_lookup_free_class_callback (void *user_class) /* {{{ */ +static void agg_lookup_free_class_callback(void *user_class) /* {{{ */ { - agg_destroy ((aggregation_t *) user_class); + agg_destroy((aggregation_t *)user_class); } /* }}} void agg_lookup_free_class_callback */ /* lookup_free_obj_callback_t for utils_vl_lookup */ -static void agg_lookup_free_obj_callback (void *user_obj) /* {{{ */ +static void agg_lookup_free_obj_callback(void *user_obj) /* {{{ */ { - agg_instance_destroy ((agg_instance_t *) user_obj); + agg_instance_destroy((agg_instance_t *)user_obj); } /* }}} void agg_lookup_free_obj_callback */ /* @@ -479,240 +471,229 @@ static void agg_lookup_free_obj_callback (void *user_obj) /* {{{ */ * * */ -static int agg_config_handle_group_by (oconfig_item_t const *ci, /* {{{ */ - aggregation_t *agg) -{ - for (int i = 0; i < ci->values_num; i++) - { +static int agg_config_handle_group_by(oconfig_item_t const *ci, /* {{{ */ + aggregation_t *agg) { + for (int i = 0; i < ci->values_num; i++) { char const *value; - if (ci->values[i].type != OCONFIG_TYPE_STRING) - { - ERROR ("aggregation plugin: Argument %i of the \"GroupBy\" option " - "is not a string.", i + 1); + if (ci->values[i].type != OCONFIG_TYPE_STRING) { + ERROR("aggregation plugin: Argument %i of the \"GroupBy\" option " + "is not a string.", + i + 1); continue; } value = ci->values[i].value.string; - if (strcasecmp ("Host", value) == 0) + if (strcasecmp("Host", value) == 0) agg->group_by |= LU_GROUP_BY_HOST; - else if (strcasecmp ("Plugin", value) == 0) + else if (strcasecmp("Plugin", value) == 0) agg->group_by |= LU_GROUP_BY_PLUGIN; - else if (strcasecmp ("PluginInstance", value) == 0) + else if (strcasecmp("PluginInstance", value) == 0) agg->group_by |= LU_GROUP_BY_PLUGIN_INSTANCE; - else if (strcasecmp ("TypeInstance", value) == 0) + else if (strcasecmp("TypeInstance", value) == 0) agg->group_by |= LU_GROUP_BY_TYPE_INSTANCE; - else if (strcasecmp ("Type", value) == 0) - ERROR ("aggregation plugin: Grouping by type is not supported."); + else if (strcasecmp("Type", value) == 0) + ERROR("aggregation plugin: Grouping by type is not supported."); else - WARNING ("aggregation plugin: The \"%s\" argument to the \"GroupBy\" " - "option is invalid and will be ignored.", value); + WARNING("aggregation plugin: The \"%s\" argument to the \"GroupBy\" " + "option is invalid and will be ignored.", + value); } /* for (ci->values) */ return (0); } /* }}} int agg_config_handle_group_by */ -static int agg_config_aggregation (oconfig_item_t *ci) /* {{{ */ +static int agg_config_aggregation(oconfig_item_t *ci) /* {{{ */ { aggregation_t *agg; _Bool is_valid; int status; - agg = calloc (1, sizeof (*agg)); - if (agg == NULL) - { - ERROR ("aggregation plugin: calloc failed."); + agg = calloc(1, sizeof(*agg)); + if (agg == NULL) { + ERROR("aggregation plugin: calloc failed."); return (-1); } - sstrncpy (agg->ident.host, "/.*/", sizeof (agg->ident.host)); - sstrncpy (agg->ident.plugin, "/.*/", sizeof (agg->ident.plugin)); - sstrncpy (agg->ident.plugin_instance, "/.*/", - sizeof (agg->ident.plugin_instance)); - sstrncpy (agg->ident.type, "/.*/", sizeof (agg->ident.type)); - sstrncpy (agg->ident.type_instance, "/.*/", - sizeof (agg->ident.type_instance)); + sstrncpy(agg->ident.host, "/.*/", sizeof(agg->ident.host)); + sstrncpy(agg->ident.plugin, "/.*/", sizeof(agg->ident.plugin)); + sstrncpy(agg->ident.plugin_instance, "/.*/", + sizeof(agg->ident.plugin_instance)); + sstrncpy(agg->ident.type, "/.*/", sizeof(agg->ident.type)); + sstrncpy(agg->ident.type_instance, "/.*/", sizeof(agg->ident.type_instance)); - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Host", child->key) == 0) - cf_util_get_string_buffer (child, agg->ident.host, - sizeof (agg->ident.host)); - else if (strcasecmp ("Plugin", child->key) == 0) - cf_util_get_string_buffer (child, agg->ident.plugin, - sizeof (agg->ident.plugin)); - else if (strcasecmp ("PluginInstance", child->key) == 0) - cf_util_get_string_buffer (child, agg->ident.plugin_instance, - sizeof (agg->ident.plugin_instance)); - else if (strcasecmp ("Type", child->key) == 0) - cf_util_get_string_buffer (child, agg->ident.type, - sizeof (agg->ident.type)); - else if (strcasecmp ("TypeInstance", child->key) == 0) - cf_util_get_string_buffer (child, agg->ident.type_instance, - sizeof (agg->ident.type_instance)); - else if (strcasecmp ("SetHost", child->key) == 0) - cf_util_get_string (child, &agg->set_host); - else if (strcasecmp ("SetPlugin", child->key) == 0) - cf_util_get_string (child, &agg->set_plugin); - else if (strcasecmp ("SetPluginInstance", child->key) == 0) - cf_util_get_string (child, &agg->set_plugin_instance); - else if (strcasecmp ("SetTypeInstance", child->key) == 0) - cf_util_get_string (child, &agg->set_type_instance); - else if (strcasecmp ("GroupBy", child->key) == 0) - agg_config_handle_group_by (child, agg); - else if (strcasecmp ("CalculateNum", child->key) == 0) - cf_util_get_boolean (child, &agg->calc_num); - else if (strcasecmp ("CalculateSum", child->key) == 0) - cf_util_get_boolean (child, &agg->calc_sum); - else if (strcasecmp ("CalculateAverage", child->key) == 0) - cf_util_get_boolean (child, &agg->calc_average); - else if (strcasecmp ("CalculateMinimum", child->key) == 0) - cf_util_get_boolean (child, &agg->calc_min); - else if (strcasecmp ("CalculateMaximum", child->key) == 0) - cf_util_get_boolean (child, &agg->calc_max); - else if (strcasecmp ("CalculateStddev", child->key) == 0) - cf_util_get_boolean (child, &agg->calc_stddev); + if (strcasecmp("Host", child->key) == 0) + cf_util_get_string_buffer(child, agg->ident.host, + sizeof(agg->ident.host)); + else if (strcasecmp("Plugin", child->key) == 0) + cf_util_get_string_buffer(child, agg->ident.plugin, + sizeof(agg->ident.plugin)); + else if (strcasecmp("PluginInstance", child->key) == 0) + cf_util_get_string_buffer(child, agg->ident.plugin_instance, + sizeof(agg->ident.plugin_instance)); + else if (strcasecmp("Type", child->key) == 0) + cf_util_get_string_buffer(child, agg->ident.type, + sizeof(agg->ident.type)); + else if (strcasecmp("TypeInstance", child->key) == 0) + cf_util_get_string_buffer(child, agg->ident.type_instance, + sizeof(agg->ident.type_instance)); + else if (strcasecmp("SetHost", child->key) == 0) + cf_util_get_string(child, &agg->set_host); + else if (strcasecmp("SetPlugin", child->key) == 0) + cf_util_get_string(child, &agg->set_plugin); + else if (strcasecmp("SetPluginInstance", child->key) == 0) + cf_util_get_string(child, &agg->set_plugin_instance); + else if (strcasecmp("SetTypeInstance", child->key) == 0) + cf_util_get_string(child, &agg->set_type_instance); + else if (strcasecmp("GroupBy", child->key) == 0) + agg_config_handle_group_by(child, agg); + else if (strcasecmp("CalculateNum", child->key) == 0) + cf_util_get_boolean(child, &agg->calc_num); + else if (strcasecmp("CalculateSum", child->key) == 0) + cf_util_get_boolean(child, &agg->calc_sum); + else if (strcasecmp("CalculateAverage", child->key) == 0) + cf_util_get_boolean(child, &agg->calc_average); + else if (strcasecmp("CalculateMinimum", child->key) == 0) + cf_util_get_boolean(child, &agg->calc_min); + else if (strcasecmp("CalculateMaximum", child->key) == 0) + cf_util_get_boolean(child, &agg->calc_max); + else if (strcasecmp("CalculateStddev", child->key) == 0) + cf_util_get_boolean(child, &agg->calc_stddev); else - WARNING ("aggregation plugin: The \"%s\" key is not allowed inside " - " blocks and will be ignored.", child->key); + WARNING("aggregation plugin: The \"%s\" key is not allowed inside " + " blocks and will be ignored.", + child->key); } - if (agg_is_regex (agg->ident.host)) + if (agg_is_regex(agg->ident.host)) agg->regex_fields |= LU_GROUP_BY_HOST; - if (agg_is_regex (agg->ident.plugin)) + if (agg_is_regex(agg->ident.plugin)) agg->regex_fields |= LU_GROUP_BY_PLUGIN; - if (agg_is_regex (agg->ident.plugin_instance)) + if (agg_is_regex(agg->ident.plugin_instance)) agg->regex_fields |= LU_GROUP_BY_PLUGIN_INSTANCE; - if (agg_is_regex (agg->ident.type_instance)) + if (agg_is_regex(agg->ident.type_instance)) agg->regex_fields |= LU_GROUP_BY_TYPE_INSTANCE; /* Sanity checking */ is_valid = 1; - if (strcmp ("/.*/", agg->ident.type) == 0) /* {{{ */ + if (strcmp("/.*/", agg->ident.type) == 0) /* {{{ */ { - ERROR ("aggregation plugin: It appears you did not specify the required " - "\"Type\" option in this aggregation. " - "(Host \"%s\", Plugin \"%s\", PluginInstance \"%s\", " - "Type \"%s\", TypeInstance \"%s\")", - agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance, - agg->ident.type, agg->ident.type_instance); + ERROR("aggregation plugin: It appears you did not specify the required " + "\"Type\" option in this aggregation. " + "(Host \"%s\", Plugin \"%s\", PluginInstance \"%s\", " + "Type \"%s\", TypeInstance \"%s\")", + agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance, + agg->ident.type, agg->ident.type_instance); is_valid = 0; - } - else if (strchr (agg->ident.type, '/') != NULL) - { - ERROR ("aggregation plugin: The \"Type\" may not contain the '/' " - "character. Especially, it may not be a regex. The current " - "value is \"%s\".", agg->ident.type); + } else if (strchr(agg->ident.type, '/') != NULL) { + ERROR("aggregation plugin: The \"Type\" may not contain the '/' " + "character. Especially, it may not be a regex. The current " + "value is \"%s\".", + agg->ident.type); is_valid = 0; } /* }}} */ /* Check that there is at least one regex field without a grouping. {{{ */ - if ((agg->regex_fields & ~agg->group_by) == 0) - { - ERROR ("aggregation plugin: An aggregation must contain at least one " - "wildcard. This is achieved by leaving at least one of the \"Host\", " - "\"Plugin\", \"PluginInstance\" and \"TypeInstance\" options blank " - "or using a regular expression and not grouping by that field. " - "(Host \"%s\", Plugin \"%s\", PluginInstance \"%s\", " - "Type \"%s\", TypeInstance \"%s\")", - agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance, - agg->ident.type, agg->ident.type_instance); + if ((agg->regex_fields & ~agg->group_by) == 0) { + ERROR("aggregation plugin: An aggregation must contain at least one " + "wildcard. This is achieved by leaving at least one of the \"Host\", " + "\"Plugin\", \"PluginInstance\" and \"TypeInstance\" options blank " + "or using a regular expression and not grouping by that field. " + "(Host \"%s\", Plugin \"%s\", PluginInstance \"%s\", " + "Type \"%s\", TypeInstance \"%s\")", + agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance, + agg->ident.type, agg->ident.type_instance); is_valid = 0; } /* }}} */ /* Check that all grouping fields are regular expressions. {{{ */ - if (agg->group_by & ~agg->regex_fields) - { - ERROR ("aggregation plugin: Only wildcard fields (fields for which a " - "regular expression is configured or which are left blank) can be " - "specified in the \"GroupBy\" option. " - "(Host \"%s\", Plugin \"%s\", PluginInstance \"%s\", " - "Type \"%s\", TypeInstance \"%s\")", - agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance, - agg->ident.type, agg->ident.type_instance); + if (agg->group_by & ~agg->regex_fields) { + ERROR("aggregation plugin: Only wildcard fields (fields for which a " + "regular expression is configured or which are left blank) can be " + "specified in the \"GroupBy\" option. " + "(Host \"%s\", Plugin \"%s\", PluginInstance \"%s\", " + "Type \"%s\", TypeInstance \"%s\")", + agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance, + agg->ident.type, agg->ident.type_instance); is_valid = 0; } /* }}} */ if (!agg->calc_num && !agg->calc_sum && !agg->calc_average /* {{{ */ - && !agg->calc_min && !agg->calc_max && !agg->calc_stddev) - { - ERROR ("aggregation plugin: No aggregation function has been specified. " - "Without this, I don't know what I should be calculating. " - "(Host \"%s\", Plugin \"%s\", PluginInstance \"%s\", " - "Type \"%s\", TypeInstance \"%s\")", - agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance, - agg->ident.type, agg->ident.type_instance); + && !agg->calc_min && !agg->calc_max && !agg->calc_stddev) { + ERROR("aggregation plugin: No aggregation function has been specified. " + "Without this, I don't know what I should be calculating. " + "(Host \"%s\", Plugin \"%s\", PluginInstance \"%s\", " + "Type \"%s\", TypeInstance \"%s\")", + agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance, + agg->ident.type, agg->ident.type_instance); is_valid = 0; } /* }}} */ if (!is_valid) /* {{{ */ { - sfree (agg); + sfree(agg); return (-1); } /* }}} */ - status = lookup_add (lookup, &agg->ident, agg->group_by, agg); - if (status != 0) - { - ERROR ("aggregation plugin: lookup_add failed with status %i.", status); - sfree (agg); + status = lookup_add(lookup, &agg->ident, agg->group_by, agg); + if (status != 0) { + ERROR("aggregation plugin: lookup_add failed with status %i.", status); + sfree(agg); return (-1); } - DEBUG ("aggregation plugin: Successfully added aggregation: " - "(Host \"%s\", Plugin \"%s\", PluginInstance \"%s\", " - "Type \"%s\", TypeInstance \"%s\")", - agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance, - agg->ident.type, agg->ident.type_instance); + DEBUG("aggregation plugin: Successfully added aggregation: " + "(Host \"%s\", Plugin \"%s\", PluginInstance \"%s\", " + "Type \"%s\", TypeInstance \"%s\")", + agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance, + agg->ident.type, agg->ident.type_instance); return (0); } /* }}} int agg_config_aggregation */ -static int agg_config (oconfig_item_t *ci) /* {{{ */ +static int agg_config(oconfig_item_t *ci) /* {{{ */ { - pthread_mutex_lock (&agg_instance_list_lock); - - if (lookup == NULL) - { - lookup = lookup_create (agg_lookup_class_callback, - agg_lookup_obj_callback, - agg_lookup_free_class_callback, - agg_lookup_free_obj_callback); - if (lookup == NULL) - { - pthread_mutex_unlock (&agg_instance_list_lock); - ERROR ("aggregation plugin: lookup_create failed."); + pthread_mutex_lock(&agg_instance_list_lock); + + if (lookup == NULL) { + lookup = lookup_create(agg_lookup_class_callback, agg_lookup_obj_callback, + agg_lookup_free_class_callback, + agg_lookup_free_obj_callback); + if (lookup == NULL) { + pthread_mutex_unlock(&agg_instance_list_lock); + ERROR("aggregation plugin: lookup_create failed."); return (-1); } } - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Aggregation", child->key) == 0) - agg_config_aggregation (child); + if (strcasecmp("Aggregation", child->key) == 0) + agg_config_aggregation(child); else - WARNING ("aggregation plugin: The \"%s\" key is not allowed inside " - " blocks and will be ignored.", child->key); + WARNING("aggregation plugin: The \"%s\" key is not allowed inside " + " blocks and will be ignored.", + child->key); } - pthread_mutex_unlock (&agg_instance_list_lock); + pthread_mutex_unlock(&agg_instance_list_lock); return (0); } /* }}} int agg_config */ -static int agg_read (void) /* {{{ */ +static int agg_read(void) /* {{{ */ { cdtime_t t; int success; - t = cdtime (); + t = cdtime(); success = 0; - pthread_mutex_lock (&agg_instance_list_lock); + pthread_mutex_lock(&agg_instance_list_lock); /* agg_instance_list_head only holds data, after the "write" callback has * been called with a matching value list at least once. So on startup, @@ -720,47 +701,45 @@ static int agg_read (void) /* {{{ */ * the read() callback is called first, agg_instance_list_head is NULL and * "success" may be zero. This is expected and should not result in an error. * Therefore we need to handle this case separately. */ - if (agg_instance_list_head == NULL) - { - pthread_mutex_unlock (&agg_instance_list_lock); + if (agg_instance_list_head == NULL) { + pthread_mutex_unlock(&agg_instance_list_lock); return (0); } - for (agg_instance_t *this = agg_instance_list_head; this != NULL; this = this->next) - { + for (agg_instance_t *this = agg_instance_list_head; this != NULL; + this = this->next) { int status; - status = agg_instance_read (this, t); + status = agg_instance_read(this, t); if (status != 0) - WARNING ("aggregation plugin: Reading an aggregation instance " - "failed with status %i.", status); + WARNING("aggregation plugin: Reading an aggregation instance " + "failed with status %i.", + status); else success++; } - pthread_mutex_unlock (&agg_instance_list_lock); + pthread_mutex_unlock(&agg_instance_list_lock); return ((success > 0) ? 0 : -1); } /* }}} int agg_read */ -static int agg_write (data_set_t const *ds, value_list_t const *vl, /* {{{ */ - __attribute__((unused)) user_data_t *user_data) -{ +static int agg_write(data_set_t const *ds, value_list_t const *vl, /* {{{ */ + __attribute__((unused)) user_data_t *user_data) { _Bool created_by_aggregation = 0; int status; /* Ignore values that were created by the aggregation plugin to avoid weird * effects. */ - (void) meta_data_get_boolean (vl->meta, "aggregation:created", - &created_by_aggregation); + (void)meta_data_get_boolean(vl->meta, "aggregation:created", + &created_by_aggregation); if (created_by_aggregation) return (0); if (lookup == NULL) status = ENOENT; - else - { - status = lookup_search (lookup, ds, vl); + else { + status = lookup_search(lookup, ds, vl); if (status > 0) status = 0; } @@ -768,11 +747,10 @@ static int agg_write (data_set_t const *ds, value_list_t const *vl, /* {{{ */ return (status); } /* }}} int agg_write */ -void module_register (void) -{ - plugin_register_complex_config ("aggregation", agg_config); - plugin_register_read ("aggregation", agg_read); - plugin_register_write ("aggregation", agg_write, /* user_data = */ NULL); +void module_register(void) { + plugin_register_complex_config("aggregation", agg_config); + plugin_register_read("aggregation", agg_read); + plugin_register_write("aggregation", agg_write, /* user_data = */ NULL); } /* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ diff --git a/src/amqp.c b/src/amqp.c index b237ba3d..cd07023f 100644 --- a/src/amqp.c +++ b/src/amqp.c @@ -31,17 +31,17 @@ #include "common.h" #include "plugin.h" #include "utils_cmd_putval.h" -#include "utils_format_json.h" #include "utils_format_graphite.h" +#include "utils_format_json.h" #include #include #ifdef HAVE_AMQP_TCP_SOCKET_H -# include +#include #endif #ifdef HAVE_AMQP_SOCKET_H -# include +#include #endif #ifdef HAVE_AMQP_TCP_SOCKET #if defined HAVE_DECL_AMQP_SOCKET_CLOSE && !HAVE_DECL_AMQP_SOCKET_CLOSE @@ -53,1070 +53,974 @@ int amqp_socket_close(amqp_socket_t *); /* Defines for the delivery mode. I have no idea why they're not defined by the * library.. */ -#define CAMQP_DM_VOLATILE 1 +#define CAMQP_DM_VOLATILE 1 #define CAMQP_DM_PERSISTENT 2 -#define CAMQP_FORMAT_COMMAND 1 -#define CAMQP_FORMAT_JSON 2 -#define CAMQP_FORMAT_GRAPHITE 3 +#define CAMQP_FORMAT_COMMAND 1 +#define CAMQP_FORMAT_JSON 2 +#define CAMQP_FORMAT_GRAPHITE 3 #define CAMQP_CHANNEL 1 /* * Data types */ -struct camqp_config_s -{ - _Bool publish; - char *name; - - char *host; - int port; - char *vhost; - char *user; - char *password; - - char *exchange; - char *routing_key; - - /* Number of seconds to wait before connection is retried */ - int connection_retry_delay; - - /* publish only */ - uint8_t delivery_mode; - _Bool store_rates; - int format; - /* publish & graphite format only */ - char *prefix; - char *postfix; - char escape_char; - unsigned int graphite_flags; - - /* subscribe only */ - char *exchange_type; - char *queue; - _Bool queue_durable; - _Bool queue_auto_delete; - - amqp_connection_state_t connection; - pthread_mutex_t lock; +struct camqp_config_s { + _Bool publish; + char *name; + + char *host; + int port; + char *vhost; + char *user; + char *password; + + char *exchange; + char *routing_key; + + /* Number of seconds to wait before connection is retried */ + int connection_retry_delay; + + /* publish only */ + uint8_t delivery_mode; + _Bool store_rates; + int format; + /* publish & graphite format only */ + char *prefix; + char *postfix; + char escape_char; + unsigned int graphite_flags; + + /* subscribe only */ + char *exchange_type; + char *queue; + _Bool queue_durable; + _Bool queue_auto_delete; + + amqp_connection_state_t connection; + pthread_mutex_t lock; }; typedef struct camqp_config_s camqp_config_t; /* * Global variables */ -static const char *def_host = "localhost"; -static const char *def_vhost = "/"; -static const char *def_user = "guest"; -static const char *def_password = "guest"; -static const char *def_exchange = "amq.fanout"; +static const char *def_host = "localhost"; +static const char *def_vhost = "/"; +static const char *def_user = "guest"; +static const char *def_password = "guest"; +static const char *def_exchange = "amq.fanout"; -static pthread_t *subscriber_threads = NULL; -static size_t subscriber_threads_num = 0; -static _Bool subscriber_threads_running = 1; +static pthread_t *subscriber_threads = NULL; +static size_t subscriber_threads_num = 0; +static _Bool subscriber_threads_running = 1; -#define CONF(c,f) (((c)->f != NULL) ? (c)->f : def_##f) +#define CONF(c, f) (((c)->f != NULL) ? (c)->f : def_##f) /* * Functions */ -static void camqp_close_connection (camqp_config_t *conf) /* {{{ */ +static void camqp_close_connection(camqp_config_t *conf) /* {{{ */ { - int sockfd; + int sockfd; - if ((conf == NULL) || (conf->connection == NULL)) - return; + if ((conf == NULL) || (conf->connection == NULL)) + return; - sockfd = amqp_get_sockfd (conf->connection); - amqp_channel_close (conf->connection, CAMQP_CHANNEL, AMQP_REPLY_SUCCESS); - amqp_connection_close (conf->connection, AMQP_REPLY_SUCCESS); - amqp_destroy_connection (conf->connection); - close (sockfd); - conf->connection = NULL; + sockfd = amqp_get_sockfd(conf->connection); + amqp_channel_close(conf->connection, CAMQP_CHANNEL, AMQP_REPLY_SUCCESS); + amqp_connection_close(conf->connection, AMQP_REPLY_SUCCESS); + amqp_destroy_connection(conf->connection); + close(sockfd); + conf->connection = NULL; } /* }}} void camqp_close_connection */ -static void camqp_config_free (void *ptr) /* {{{ */ +static void camqp_config_free(void *ptr) /* {{{ */ { - camqp_config_t *conf = ptr; - - if (conf == NULL) - return; - - camqp_close_connection (conf); - - sfree (conf->name); - sfree (conf->host); - sfree (conf->vhost); - sfree (conf->user); - sfree (conf->password); - sfree (conf->exchange); - sfree (conf->exchange_type); - sfree (conf->queue); - sfree (conf->routing_key); - sfree (conf->prefix); - sfree (conf->postfix); - - - sfree (conf); + camqp_config_t *conf = ptr; + + if (conf == NULL) + return; + + camqp_close_connection(conf); + + sfree(conf->name); + sfree(conf->host); + sfree(conf->vhost); + sfree(conf->user); + sfree(conf->password); + sfree(conf->exchange); + sfree(conf->exchange_type); + sfree(conf->queue); + sfree(conf->routing_key); + sfree(conf->prefix); + sfree(conf->postfix); + + sfree(conf); } /* }}} void camqp_config_free */ -static char *camqp_bytes_cstring (amqp_bytes_t *in) /* {{{ */ +static char *camqp_bytes_cstring(amqp_bytes_t *in) /* {{{ */ { - char *ret; + char *ret; - if ((in == NULL) || (in->bytes == NULL)) - return (NULL); + if ((in == NULL) || (in->bytes == NULL)) + return (NULL); - ret = malloc (in->len + 1); - if (ret == NULL) - return (NULL); + ret = malloc(in->len + 1); + if (ret == NULL) + return (NULL); - memcpy (ret, in->bytes, in->len); - ret[in->len] = 0; + memcpy(ret, in->bytes, in->len); + ret[in->len] = 0; - return (ret); + return (ret); } /* }}} char *camqp_bytes_cstring */ -static _Bool camqp_is_error (camqp_config_t *conf) /* {{{ */ +static _Bool camqp_is_error(camqp_config_t *conf) /* {{{ */ { - amqp_rpc_reply_t r; + amqp_rpc_reply_t r; - r = amqp_get_rpc_reply (conf->connection); - if (r.reply_type == AMQP_RESPONSE_NORMAL) - return (0); + r = amqp_get_rpc_reply(conf->connection); + if (r.reply_type == AMQP_RESPONSE_NORMAL) + return (0); - return (1); + return (1); } /* }}} _Bool camqp_is_error */ -static char *camqp_strerror (camqp_config_t *conf, /* {{{ */ - char *buffer, size_t buffer_size) -{ - amqp_rpc_reply_t r; +static char *camqp_strerror(camqp_config_t *conf, /* {{{ */ + char *buffer, size_t buffer_size) { + amqp_rpc_reply_t r; - r = amqp_get_rpc_reply (conf->connection); - switch (r.reply_type) - { - case AMQP_RESPONSE_NORMAL: - sstrncpy (buffer, "Success", buffer_size); - break; + r = amqp_get_rpc_reply(conf->connection); + switch (r.reply_type) { + case AMQP_RESPONSE_NORMAL: + sstrncpy(buffer, "Success", buffer_size); + break; - case AMQP_RESPONSE_NONE: - sstrncpy (buffer, "Missing RPC reply type", buffer_size); - break; + case AMQP_RESPONSE_NONE: + sstrncpy(buffer, "Missing RPC reply type", buffer_size); + break; - case AMQP_RESPONSE_LIBRARY_EXCEPTION: + case AMQP_RESPONSE_LIBRARY_EXCEPTION: #if HAVE_AMQP_RPC_REPLY_T_LIBRARY_ERRNO - if (r.library_errno) - return (sstrerror (r.library_errno, buffer, buffer_size)); + if (r.library_errno) + return (sstrerror(r.library_errno, buffer, buffer_size)); #else - if (r.library_error) - return (sstrerror (r.library_error, buffer, buffer_size)); + if (r.library_error) + return (sstrerror(r.library_error, buffer, buffer_size)); #endif - else - sstrncpy (buffer, "End of stream", buffer_size); - break; - - case AMQP_RESPONSE_SERVER_EXCEPTION: - if (r.reply.id == AMQP_CONNECTION_CLOSE_METHOD) - { - amqp_connection_close_t *m = r.reply.decoded; - char *tmp = camqp_bytes_cstring (&m->reply_text); - ssnprintf (buffer, buffer_size, "Server connection error %d: %s", - m->reply_code, tmp); - sfree (tmp); - } - else if (r.reply.id == AMQP_CHANNEL_CLOSE_METHOD) - { - amqp_channel_close_t *m = r.reply.decoded; - char *tmp = camqp_bytes_cstring (&m->reply_text); - ssnprintf (buffer, buffer_size, "Server channel error %d: %s", - m->reply_code, tmp); - sfree (tmp); - } - else - { - ssnprintf (buffer, buffer_size, "Server error method %#"PRIx32, - r.reply.id); - } - break; - - default: - ssnprintf (buffer, buffer_size, "Unknown reply type %i", - (int) r.reply_type); + else + sstrncpy(buffer, "End of stream", buffer_size); + break; + + case AMQP_RESPONSE_SERVER_EXCEPTION: + if (r.reply.id == AMQP_CONNECTION_CLOSE_METHOD) { + amqp_connection_close_t *m = r.reply.decoded; + char *tmp = camqp_bytes_cstring(&m->reply_text); + ssnprintf(buffer, buffer_size, "Server connection error %d: %s", + m->reply_code, tmp); + sfree(tmp); + } else if (r.reply.id == AMQP_CHANNEL_CLOSE_METHOD) { + amqp_channel_close_t *m = r.reply.decoded; + char *tmp = camqp_bytes_cstring(&m->reply_text); + ssnprintf(buffer, buffer_size, "Server channel error %d: %s", + m->reply_code, tmp); + sfree(tmp); + } else { + ssnprintf(buffer, buffer_size, "Server error method %#" PRIx32, + r.reply.id); } + break; - return (buffer); + default: + ssnprintf(buffer, buffer_size, "Unknown reply type %i", (int)r.reply_type); + } + + return (buffer); } /* }}} char *camqp_strerror */ #if HAVE_AMQP_RPC_REPLY_T_LIBRARY_ERRNO -static int camqp_create_exchange (camqp_config_t *conf) /* {{{ */ +static int camqp_create_exchange(camqp_config_t *conf) /* {{{ */ { - amqp_exchange_declare_ok_t *ed_ret; - - if (conf->exchange_type == NULL) - return (0); - - ed_ret = amqp_exchange_declare (conf->connection, - /* channel = */ CAMQP_CHANNEL, - /* exchange = */ amqp_cstring_bytes (conf->exchange), - /* type = */ amqp_cstring_bytes (conf->exchange_type), - /* passive = */ 0, - /* durable = */ 0, - /* auto_delete = */ 1, - /* arguments = */ AMQP_EMPTY_TABLE); - if ((ed_ret == NULL) && camqp_is_error (conf)) - { - char errbuf[1024]; - ERROR ("amqp plugin: amqp_exchange_declare failed: %s", - camqp_strerror (conf, errbuf, sizeof (errbuf))); - camqp_close_connection (conf); - return (-1); - } - - INFO ("amqp plugin: Successfully created exchange \"%s\" " - "with type \"%s\".", - conf->exchange, conf->exchange_type); + amqp_exchange_declare_ok_t *ed_ret; + if (conf->exchange_type == NULL) return (0); + + ed_ret = amqp_exchange_declare( + conf->connection, + /* channel = */ CAMQP_CHANNEL, + /* exchange = */ amqp_cstring_bytes(conf->exchange), + /* type = */ amqp_cstring_bytes(conf->exchange_type), + /* passive = */ 0, + /* durable = */ 0, + /* auto_delete = */ 1, + /* arguments = */ AMQP_EMPTY_TABLE); + if ((ed_ret == NULL) && camqp_is_error(conf)) { + char errbuf[1024]; + ERROR("amqp plugin: amqp_exchange_declare failed: %s", + camqp_strerror(conf, errbuf, sizeof(errbuf))); + camqp_close_connection(conf); + return (-1); + } + + INFO("amqp plugin: Successfully created exchange \"%s\" " + "with type \"%s\".", + conf->exchange, conf->exchange_type); + + return (0); } /* }}} int camqp_create_exchange */ #else -static int camqp_create_exchange (camqp_config_t *conf) /* {{{ */ +static int camqp_create_exchange(camqp_config_t *conf) /* {{{ */ { - amqp_exchange_declare_ok_t *ed_ret; - amqp_table_t argument_table; - struct amqp_table_entry_t_ argument_table_entries[1]; - - if (conf->exchange_type == NULL) - return (0); - - /* Valid arguments: "auto_delete", "internal" */ - argument_table.num_entries = STATIC_ARRAY_SIZE (argument_table_entries); - argument_table.entries = argument_table_entries; - argument_table_entries[0].key = amqp_cstring_bytes ("auto_delete"); - argument_table_entries[0].value.kind = AMQP_FIELD_KIND_BOOLEAN; - argument_table_entries[0].value.value.boolean = 1; - - ed_ret = amqp_exchange_declare (conf->connection, - /* channel = */ CAMQP_CHANNEL, - /* exchange = */ amqp_cstring_bytes (conf->exchange), - /* type = */ amqp_cstring_bytes (conf->exchange_type), - /* passive = */ 0, - /* durable = */ 0, -#if defined(AMQP_VERSION) && AMQP_VERSION >= 0x00060000 - /* auto delete = */ 0, - /* internal = */ 0, -#endif - /* arguments = */ argument_table); - if ((ed_ret == NULL) && camqp_is_error (conf)) - { - char errbuf[1024]; - ERROR ("amqp plugin: amqp_exchange_declare failed: %s", - camqp_strerror (conf, errbuf, sizeof (errbuf))); - camqp_close_connection (conf); - return (-1); - } - - INFO ("amqp plugin: Successfully created exchange \"%s\" " - "with type \"%s\".", - conf->exchange, conf->exchange_type); + amqp_exchange_declare_ok_t *ed_ret; + amqp_table_t argument_table; + struct amqp_table_entry_t_ argument_table_entries[1]; + if (conf->exchange_type == NULL) return (0); + + /* Valid arguments: "auto_delete", "internal" */ + argument_table.num_entries = STATIC_ARRAY_SIZE(argument_table_entries); + argument_table.entries = argument_table_entries; + argument_table_entries[0].key = amqp_cstring_bytes("auto_delete"); + argument_table_entries[0].value.kind = AMQP_FIELD_KIND_BOOLEAN; + argument_table_entries[0].value.value.boolean = 1; + + ed_ret = amqp_exchange_declare( + conf->connection, + /* channel = */ CAMQP_CHANNEL, + /* exchange = */ amqp_cstring_bytes(conf->exchange), + /* type = */ amqp_cstring_bytes(conf->exchange_type), + /* passive = */ 0, + /* durable = */ 0, +#if defined(AMQP_VERSION) && AMQP_VERSION >= 0x00060000 + /* auto delete = */ 0, + /* internal = */ 0, +#endif + /* arguments = */ argument_table); + if ((ed_ret == NULL) && camqp_is_error(conf)) { + char errbuf[1024]; + ERROR("amqp plugin: amqp_exchange_declare failed: %s", + camqp_strerror(conf, errbuf, sizeof(errbuf))); + camqp_close_connection(conf); + return (-1); + } + + INFO("amqp plugin: Successfully created exchange \"%s\" " + "with type \"%s\".", + conf->exchange, conf->exchange_type); + + return (0); } /* }}} int camqp_create_exchange */ #endif -static int camqp_setup_queue (camqp_config_t *conf) /* {{{ */ +static int camqp_setup_queue(camqp_config_t *conf) /* {{{ */ { - amqp_queue_declare_ok_t *qd_ret; - amqp_basic_consume_ok_t *cm_ret; - - qd_ret = amqp_queue_declare (conf->connection, - /* channel = */ CAMQP_CHANNEL, - /* queue = */ (conf->queue != NULL) - ? amqp_cstring_bytes (conf->queue) - : AMQP_EMPTY_BYTES, - /* passive = */ 0, - /* durable = */ conf->queue_durable, - /* exclusive = */ 0, - /* auto_delete = */ conf->queue_auto_delete, - /* arguments = */ AMQP_EMPTY_TABLE); - if (qd_ret == NULL) - { - ERROR ("amqp plugin: amqp_queue_declare failed."); - camqp_close_connection (conf); - return (-1); + amqp_queue_declare_ok_t *qd_ret; + amqp_basic_consume_ok_t *cm_ret; + + qd_ret = amqp_queue_declare(conf->connection, + /* channel = */ CAMQP_CHANNEL, + /* queue = */ (conf->queue != NULL) + ? amqp_cstring_bytes(conf->queue) + : AMQP_EMPTY_BYTES, + /* passive = */ 0, + /* durable = */ conf->queue_durable, + /* exclusive = */ 0, + /* auto_delete = */ conf->queue_auto_delete, + /* arguments = */ AMQP_EMPTY_TABLE); + if (qd_ret == NULL) { + ERROR("amqp plugin: amqp_queue_declare failed."); + camqp_close_connection(conf); + return (-1); + } + + if (conf->queue == NULL) { + conf->queue = camqp_bytes_cstring(&qd_ret->queue); + if (conf->queue == NULL) { + ERROR("amqp plugin: camqp_bytes_cstring failed."); + camqp_close_connection(conf); + return (-1); } - if (conf->queue == NULL) - { - conf->queue = camqp_bytes_cstring (&qd_ret->queue); - if (conf->queue == NULL) - { - ERROR ("amqp plugin: camqp_bytes_cstring failed."); - camqp_close_connection (conf); - return (-1); - } - - INFO ("amqp plugin: Created queue \"%s\".", conf->queue); - } - DEBUG ("amqp plugin: Successfully created queue \"%s\".", conf->queue); - - /* bind to an exchange */ - if (conf->exchange != NULL) - { - amqp_queue_bind_ok_t *qb_ret; - - assert (conf->queue != NULL); - qb_ret = amqp_queue_bind (conf->connection, - /* channel = */ CAMQP_CHANNEL, - /* queue = */ amqp_cstring_bytes (conf->queue), - /* exchange = */ amqp_cstring_bytes (conf->exchange), - /* routing_key = */ (conf->routing_key != NULL) - ? amqp_cstring_bytes (conf->routing_key) - : AMQP_EMPTY_BYTES, - /* arguments = */ AMQP_EMPTY_TABLE); - if ((qb_ret == NULL) && camqp_is_error (conf)) - { - char errbuf[1024]; - ERROR ("amqp plugin: amqp_queue_bind failed: %s", - camqp_strerror (conf, errbuf, sizeof (errbuf))); - camqp_close_connection (conf); - return (-1); - } - - DEBUG ("amqp plugin: Successfully bound queue \"%s\" to exchange \"%s\".", - conf->queue, conf->exchange); - } /* if (conf->exchange != NULL) */ - - cm_ret = amqp_basic_consume (conf->connection, - /* channel = */ CAMQP_CHANNEL, - /* queue = */ amqp_cstring_bytes (conf->queue), - /* consumer_tag = */ AMQP_EMPTY_BYTES, - /* no_local = */ 0, - /* no_ack = */ 1, - /* exclusive = */ 0, - /* arguments = */ AMQP_EMPTY_TABLE - ); - if ((cm_ret == NULL) && camqp_is_error (conf)) - { - char errbuf[1024]; - ERROR ("amqp plugin: amqp_basic_consume failed: %s", - camqp_strerror (conf, errbuf, sizeof (errbuf))); - camqp_close_connection (conf); - return (-1); + INFO("amqp plugin: Created queue \"%s\".", conf->queue); + } + DEBUG("amqp plugin: Successfully created queue \"%s\".", conf->queue); + + /* bind to an exchange */ + if (conf->exchange != NULL) { + amqp_queue_bind_ok_t *qb_ret; + + assert(conf->queue != NULL); + qb_ret = + amqp_queue_bind(conf->connection, + /* channel = */ CAMQP_CHANNEL, + /* queue = */ amqp_cstring_bytes(conf->queue), + /* exchange = */ amqp_cstring_bytes(conf->exchange), + /* routing_key = */ (conf->routing_key != NULL) + ? amqp_cstring_bytes(conf->routing_key) + : AMQP_EMPTY_BYTES, + /* arguments = */ AMQP_EMPTY_TABLE); + if ((qb_ret == NULL) && camqp_is_error(conf)) { + char errbuf[1024]; + ERROR("amqp plugin: amqp_queue_bind failed: %s", + camqp_strerror(conf, errbuf, sizeof(errbuf))); + camqp_close_connection(conf); + return (-1); } - return (0); + DEBUG("amqp plugin: Successfully bound queue \"%s\" to exchange \"%s\".", + conf->queue, conf->exchange); + } /* if (conf->exchange != NULL) */ + + cm_ret = + amqp_basic_consume(conf->connection, + /* channel = */ CAMQP_CHANNEL, + /* queue = */ amqp_cstring_bytes(conf->queue), + /* consumer_tag = */ AMQP_EMPTY_BYTES, + /* no_local = */ 0, + /* no_ack = */ 1, + /* exclusive = */ 0, + /* arguments = */ AMQP_EMPTY_TABLE); + if ((cm_ret == NULL) && camqp_is_error(conf)) { + char errbuf[1024]; + ERROR("amqp plugin: amqp_basic_consume failed: %s", + camqp_strerror(conf, errbuf, sizeof(errbuf))); + camqp_close_connection(conf); + return (-1); + } + + return (0); } /* }}} int camqp_setup_queue */ -static int camqp_connect (camqp_config_t *conf) /* {{{ */ +static int camqp_connect(camqp_config_t *conf) /* {{{ */ { - static time_t last_connect_time = 0; + static time_t last_connect_time = 0; - amqp_rpc_reply_t reply; - int status; + amqp_rpc_reply_t reply; + int status; #ifdef HAVE_AMQP_TCP_SOCKET - amqp_socket_t *socket; + amqp_socket_t *socket; #else - int sockfd; + int sockfd; #endif - if (conf->connection != NULL) - return (0); + if (conf->connection != NULL) + return (0); - time_t now = time(NULL); - if (now < (last_connect_time + conf->connection_retry_delay)) - { - DEBUG("amqp plugin: skipping connection retry, " - "ConnectionRetryDelay: %d", conf->connection_retry_delay); - return(1); - } - else - { - DEBUG ("amqp plugin: retrying connection"); - last_connect_time = now; - } + time_t now = time(NULL); + if (now < (last_connect_time + conf->connection_retry_delay)) { + DEBUG("amqp plugin: skipping connection retry, " + "ConnectionRetryDelay: %d", + conf->connection_retry_delay); + return (1); + } else { + DEBUG("amqp plugin: retrying connection"); + last_connect_time = now; + } - conf->connection = amqp_new_connection (); - if (conf->connection == NULL) - { - ERROR ("amqp plugin: amqp_new_connection failed."); - return (ENOMEM); - } + conf->connection = amqp_new_connection(); + if (conf->connection == NULL) { + ERROR("amqp plugin: amqp_new_connection failed."); + return (ENOMEM); + } #ifdef HAVE_AMQP_TCP_SOCKET -# define CLOSE_SOCKET() /* amqp_destroy_connection() closes the socket for us */ - /* TODO: add support for SSL using amqp_ssl_socket_new - * and related functions */ - socket = amqp_tcp_socket_new (conf->connection); - if (! socket) - { - ERROR ("amqp plugin: amqp_tcp_socket_new failed."); - amqp_destroy_connection (conf->connection); - conf->connection = NULL; - return (ENOMEM); - } - - status = amqp_socket_open (socket, CONF(conf, host), conf->port); - if (status < 0) - { - char errbuf[1024]; - status *= -1; - ERROR ("amqp plugin: amqp_socket_open failed: %s", - sstrerror (status, errbuf, sizeof (errbuf))); - amqp_destroy_connection (conf->connection); - conf->connection = NULL; - return (status); - } +#define CLOSE_SOCKET() /* amqp_destroy_connection() closes the socket for us \ + */ + /* TODO: add support for SSL using amqp_ssl_socket_new + * and related functions */ + socket = amqp_tcp_socket_new(conf->connection); + if (!socket) { + ERROR("amqp plugin: amqp_tcp_socket_new failed."); + amqp_destroy_connection(conf->connection); + conf->connection = NULL; + return (ENOMEM); + } + + status = amqp_socket_open(socket, CONF(conf, host), conf->port); + if (status < 0) { + char errbuf[1024]; + status *= -1; + ERROR("amqp plugin: amqp_socket_open failed: %s", + sstrerror(status, errbuf, sizeof(errbuf))); + amqp_destroy_connection(conf->connection); + conf->connection = NULL; + return (status); + } #else /* HAVE_AMQP_TCP_SOCKET */ -# define CLOSE_SOCKET() close(sockfd) - /* this interface is deprecated as of rabbitmq-c 0.4 */ - sockfd = amqp_open_socket (CONF(conf, host), conf->port); - if (sockfd < 0) - { - char errbuf[1024]; - status = (-1) * sockfd; - ERROR ("amqp plugin: amqp_open_socket failed: %s", - sstrerror (status, errbuf, sizeof (errbuf))); - amqp_destroy_connection (conf->connection); - conf->connection = NULL; - return (status); - } - amqp_set_sockfd (conf->connection, sockfd); +#define CLOSE_SOCKET() close(sockfd) + /* this interface is deprecated as of rabbitmq-c 0.4 */ + sockfd = amqp_open_socket(CONF(conf, host), conf->port); + if (sockfd < 0) { + char errbuf[1024]; + status = (-1) * sockfd; + ERROR("amqp plugin: amqp_open_socket failed: %s", + sstrerror(status, errbuf, sizeof(errbuf))); + amqp_destroy_connection(conf->connection); + conf->connection = NULL; + return (status); + } + amqp_set_sockfd(conf->connection, sockfd); #endif - reply = amqp_login (conf->connection, CONF(conf, vhost), - /* channel max = */ 0, - /* frame max = */ 131072, - /* heartbeat = */ 0, - /* authentication = */ AMQP_SASL_METHOD_PLAIN, - CONF(conf, user), CONF(conf, password)); - if (reply.reply_type != AMQP_RESPONSE_NORMAL) - { - ERROR ("amqp plugin: amqp_login (vhost = %s, user = %s) failed.", - CONF(conf, vhost), CONF(conf, user)); - amqp_destroy_connection (conf->connection); - CLOSE_SOCKET (); - conf->connection = NULL; - return (1); - } - - amqp_channel_open (conf->connection, /* channel = */ 1); - /* FIXME: Is checking "reply.reply_type" really correct here? How does - * it get set? --octo */ - if (reply.reply_type != AMQP_RESPONSE_NORMAL) - { - ERROR ("amqp plugin: amqp_channel_open failed."); - amqp_connection_close (conf->connection, AMQP_REPLY_SUCCESS); - amqp_destroy_connection (conf->connection); - CLOSE_SOCKET (); - conf->connection = NULL; - return (1); - } + reply = amqp_login(conf->connection, CONF(conf, vhost), + /* channel max = */ 0, + /* frame max = */ 131072, + /* heartbeat = */ 0, + /* authentication = */ AMQP_SASL_METHOD_PLAIN, + CONF(conf, user), CONF(conf, password)); + if (reply.reply_type != AMQP_RESPONSE_NORMAL) { + ERROR("amqp plugin: amqp_login (vhost = %s, user = %s) failed.", + CONF(conf, vhost), CONF(conf, user)); + amqp_destroy_connection(conf->connection); + CLOSE_SOCKET(); + conf->connection = NULL; + return (1); + } + + amqp_channel_open(conf->connection, /* channel = */ 1); + /* FIXME: Is checking "reply.reply_type" really correct here? How does + * it get set? --octo */ + if (reply.reply_type != AMQP_RESPONSE_NORMAL) { + ERROR("amqp plugin: amqp_channel_open failed."); + amqp_connection_close(conf->connection, AMQP_REPLY_SUCCESS); + amqp_destroy_connection(conf->connection); + CLOSE_SOCKET(); + conf->connection = NULL; + return (1); + } - INFO ("amqp plugin: Successfully opened connection to vhost \"%s\" " - "on %s:%i.", CONF(conf, vhost), CONF(conf, host), conf->port); + INFO("amqp plugin: Successfully opened connection to vhost \"%s\" " + "on %s:%i.", + CONF(conf, vhost), CONF(conf, host), conf->port); - status = camqp_create_exchange (conf); - if (status != 0) - return (status); + status = camqp_create_exchange(conf); + if (status != 0) + return (status); - if (!conf->publish) - return (camqp_setup_queue (conf)); - return (0); + if (!conf->publish) + return (camqp_setup_queue(conf)); + return (0); } /* }}} int camqp_connect */ -static int camqp_shutdown (void) /* {{{ */ +static int camqp_shutdown(void) /* {{{ */ { - DEBUG ("amqp plugin: Shutting down %zu subscriber threads.", - subscriber_threads_num); - - subscriber_threads_running = 0; - for (size_t i = 0; i < subscriber_threads_num; i++) - { - /* FIXME: Sending a signal is not very elegant here. Maybe find out how - * to use a timeout in the thread and check for the variable in regular - * intervals. */ - pthread_kill (subscriber_threads[i], SIGTERM); - pthread_join (subscriber_threads[i], /* retval = */ NULL); - } + DEBUG("amqp plugin: Shutting down %zu subscriber threads.", + subscriber_threads_num); - subscriber_threads_num = 0; - sfree (subscriber_threads); + subscriber_threads_running = 0; + for (size_t i = 0; i < subscriber_threads_num; i++) { + /* FIXME: Sending a signal is not very elegant here. Maybe find out how + * to use a timeout in the thread and check for the variable in regular + * intervals. */ + pthread_kill(subscriber_threads[i], SIGTERM); + pthread_join(subscriber_threads[i], /* retval = */ NULL); + } - DEBUG ("amqp plugin: All subscriber threads exited."); + subscriber_threads_num = 0; + sfree(subscriber_threads); - return (0); + DEBUG("amqp plugin: All subscriber threads exited."); + + return (0); } /* }}} int camqp_shutdown */ /* * Subscribing code */ -static int camqp_read_body (camqp_config_t *conf, /* {{{ */ - size_t body_size, const char *content_type) -{ - char body[body_size + 1]; - char *body_ptr; - size_t received; - amqp_frame_t frame; - int status; - - memset (body, 0, sizeof (body)); - body_ptr = &body[0]; - received = 0; - - while (received < body_size) - { - status = amqp_simple_wait_frame (conf->connection, &frame); - if (status < 0) - { - char errbuf[1024]; - status = (-1) * status; - ERROR ("amqp plugin: amqp_simple_wait_frame failed: %s", - sstrerror (status, errbuf, sizeof (errbuf))); - camqp_close_connection (conf); - return (status); - } - - if (frame.frame_type != AMQP_FRAME_BODY) - { - NOTICE ("amqp plugin: Unexpected frame type: %#"PRIx8, - frame.frame_type); - return (-1); - } - - if ((body_size - received) < frame.payload.body_fragment.len) - { - WARNING ("amqp plugin: Body is larger than indicated by header."); - return (-1); - } - - memcpy (body_ptr, frame.payload.body_fragment.bytes, - frame.payload.body_fragment.len); - body_ptr += frame.payload.body_fragment.len; - received += frame.payload.body_fragment.len; - } /* while (received < body_size) */ - - if (strcasecmp ("text/collectd", content_type) == 0) - { - status = cmd_handle_putval (stderr, body); - if (status != 0) - ERROR ("amqp plugin: cmd_handle_putval failed with status %i.", - status); - return (status); +static int camqp_read_body(camqp_config_t *conf, /* {{{ */ + size_t body_size, const char *content_type) { + char body[body_size + 1]; + char *body_ptr; + size_t received; + amqp_frame_t frame; + int status; + + memset(body, 0, sizeof(body)); + body_ptr = &body[0]; + received = 0; + + while (received < body_size) { + status = amqp_simple_wait_frame(conf->connection, &frame); + if (status < 0) { + char errbuf[1024]; + status = (-1) * status; + ERROR("amqp plugin: amqp_simple_wait_frame failed: %s", + sstrerror(status, errbuf, sizeof(errbuf))); + camqp_close_connection(conf); + return (status); } - else if (strcasecmp ("application/json", content_type) == 0) - { - ERROR ("amqp plugin: camqp_read_body: Parsing JSON data has not " - "been implemented yet. FIXME!"); - return (0); + + if (frame.frame_type != AMQP_FRAME_BODY) { + NOTICE("amqp plugin: Unexpected frame type: %#" PRIx8, frame.frame_type); + return (-1); } - else - { - ERROR ("amqp plugin: camqp_read_body: Unknown content type \"%s\".", - content_type); - return (EINVAL); + + if ((body_size - received) < frame.payload.body_fragment.len) { + WARNING("amqp plugin: Body is larger than indicated by header."); + return (-1); } - /* not reached */ + memcpy(body_ptr, frame.payload.body_fragment.bytes, + frame.payload.body_fragment.len); + body_ptr += frame.payload.body_fragment.len; + received += frame.payload.body_fragment.len; + } /* while (received < body_size) */ + + if (strcasecmp("text/collectd", content_type) == 0) { + status = cmd_handle_putval(stderr, body); + if (status != 0) + ERROR("amqp plugin: cmd_handle_putval failed with status %i.", status); + return (status); + } else if (strcasecmp("application/json", content_type) == 0) { + ERROR("amqp plugin: camqp_read_body: Parsing JSON data has not " + "been implemented yet. FIXME!"); return (0); + } else { + ERROR("amqp plugin: camqp_read_body: Unknown content type \"%s\".", + content_type); + return (EINVAL); + } + + /* not reached */ + return (0); } /* }}} int camqp_read_body */ -static int camqp_read_header (camqp_config_t *conf) /* {{{ */ +static int camqp_read_header(camqp_config_t *conf) /* {{{ */ { - int status; + int status; + amqp_frame_t frame; + amqp_basic_properties_t *properties; + char *content_type; + + status = amqp_simple_wait_frame(conf->connection, &frame); + if (status < 0) { + char errbuf[1024]; + status = (-1) * status; + ERROR("amqp plugin: amqp_simple_wait_frame failed: %s", + sstrerror(status, errbuf, sizeof(errbuf))); + camqp_close_connection(conf); + return (status); + } + + if (frame.frame_type != AMQP_FRAME_HEADER) { + NOTICE("amqp plugin: Unexpected frame type: %#" PRIx8, frame.frame_type); + return (-1); + } + + properties = frame.payload.properties.decoded; + content_type = camqp_bytes_cstring(&properties->content_type); + if (content_type == NULL) { + ERROR("amqp plugin: Unable to determine content type."); + return (-1); + } + + status = camqp_read_body(conf, (size_t)frame.payload.properties.body_size, + content_type); + + sfree(content_type); + return (status); +} /* }}} int camqp_read_header */ + +static void *camqp_subscribe_thread(void *user_data) /* {{{ */ +{ + camqp_config_t *conf = user_data; + int status; + + cdtime_t interval = plugin_get_interval(); + + while (subscriber_threads_running) { amqp_frame_t frame; - amqp_basic_properties_t *properties; - char *content_type; - - status = amqp_simple_wait_frame (conf->connection, &frame); - if (status < 0) - { - char errbuf[1024]; - status = (-1) * status; - ERROR ("amqp plugin: amqp_simple_wait_frame failed: %s", - sstrerror (status, errbuf, sizeof (errbuf))); - camqp_close_connection (conf); - return (status); + + status = camqp_connect(conf); + if (status != 0) { + ERROR("amqp plugin: camqp_connect failed. " + "Will sleep for %.3f seconds.", + CDTIME_T_TO_DOUBLE(interval)); + nanosleep(&CDTIME_T_TO_TIMESPEC(interval), /* remaining = */ NULL); + continue; } - if (frame.frame_type != AMQP_FRAME_HEADER) - { - NOTICE ("amqp plugin: Unexpected frame type: %#"PRIx8, - frame.frame_type); - return (-1); + status = amqp_simple_wait_frame(conf->connection, &frame); + if (status < 0) { + ERROR("amqp plugin: amqp_simple_wait_frame failed. " + "Will sleep for %.3f seconds.", + CDTIME_T_TO_DOUBLE(interval)); + camqp_close_connection(conf); + nanosleep(&CDTIME_T_TO_TIMESPEC(interval), /* remaining = */ NULL); + continue; } - properties = frame.payload.properties.decoded; - content_type = camqp_bytes_cstring (&properties->content_type); - if (content_type == NULL) - { - ERROR ("amqp plugin: Unable to determine content type."); - return (-1); + if (frame.frame_type != AMQP_FRAME_METHOD) { + DEBUG("amqp plugin: Unexpected frame type: %#" PRIx8, frame.frame_type); + continue; } - status = camqp_read_body (conf, - (size_t) frame.payload.properties.body_size, - content_type); + if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD) { + DEBUG("amqp plugin: Unexpected method id: %#" PRIx32, + frame.payload.method.id); + continue; + } - sfree (content_type); - return (status); -} /* }}} int camqp_read_header */ + camqp_read_header(conf); -static void *camqp_subscribe_thread (void *user_data) /* {{{ */ -{ - camqp_config_t *conf = user_data; - int status; - - cdtime_t interval = plugin_get_interval (); - - while (subscriber_threads_running) - { - amqp_frame_t frame; - - status = camqp_connect (conf); - if (status != 0) - { - ERROR ("amqp plugin: camqp_connect failed. " - "Will sleep for %.3f seconds.", - CDTIME_T_TO_DOUBLE (interval)); - nanosleep (&CDTIME_T_TO_TIMESPEC (interval), /* remaining = */ NULL); - continue; - } - - status = amqp_simple_wait_frame (conf->connection, &frame); - if (status < 0) - { - ERROR ("amqp plugin: amqp_simple_wait_frame failed. " - "Will sleep for %.3f seconds.", - CDTIME_T_TO_DOUBLE (interval)); - camqp_close_connection (conf); - nanosleep (&CDTIME_T_TO_TIMESPEC (interval), /* remaining = */ NULL); - continue; - } - - if (frame.frame_type != AMQP_FRAME_METHOD) - { - DEBUG ("amqp plugin: Unexpected frame type: %#"PRIx8, - frame.frame_type); - continue; - } - - if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD) - { - DEBUG ("amqp plugin: Unexpected method id: %#"PRIx32, - frame.payload.method.id); - continue; - } - - camqp_read_header (conf); - - amqp_maybe_release_buffers (conf->connection); - } /* while (subscriber_threads_running) */ - - camqp_config_free (conf); - pthread_exit (NULL); - return (NULL); + amqp_maybe_release_buffers(conf->connection); + } /* while (subscriber_threads_running) */ + + camqp_config_free(conf); + pthread_exit(NULL); + return (NULL); } /* }}} void *camqp_subscribe_thread */ -static int camqp_subscribe_init (camqp_config_t *conf) /* {{{ */ +static int camqp_subscribe_init(camqp_config_t *conf) /* {{{ */ { - int status; - pthread_t *tmp; - - tmp = realloc (subscriber_threads, - sizeof (*subscriber_threads) * (subscriber_threads_num + 1)); - if (tmp == NULL) - { - ERROR ("amqp plugin: realloc failed."); - sfree (subscriber_threads); - return (ENOMEM); - } - subscriber_threads = tmp; - tmp = subscriber_threads + subscriber_threads_num; - memset (tmp, 0, sizeof (*tmp)); - - status = plugin_thread_create (tmp, /* attr = */ NULL, - camqp_subscribe_thread, conf, "amqp subscribe"); - if (status != 0) - { - char errbuf[1024]; - ERROR ("amqp plugin: pthread_create failed: %s", - sstrerror (status, errbuf, sizeof (errbuf))); - return (status); - } + int status; + pthread_t *tmp; + + tmp = realloc(subscriber_threads, + sizeof(*subscriber_threads) * (subscriber_threads_num + 1)); + if (tmp == NULL) { + ERROR("amqp plugin: realloc failed."); + sfree(subscriber_threads); + return (ENOMEM); + } + subscriber_threads = tmp; + tmp = subscriber_threads + subscriber_threads_num; + memset(tmp, 0, sizeof(*tmp)); + + status = plugin_thread_create(tmp, /* attr = */ NULL, camqp_subscribe_thread, + conf, "amqp subscribe"); + if (status != 0) { + char errbuf[1024]; + ERROR("amqp plugin: pthread_create failed: %s", + sstrerror(status, errbuf, sizeof(errbuf))); + return (status); + } - subscriber_threads_num++; + subscriber_threads_num++; - return (0); + return (0); } /* }}} int camqp_subscribe_init */ /* * Publishing code */ /* XXX: You must hold "conf->lock" when calling this function! */ -static int camqp_write_locked (camqp_config_t *conf, /* {{{ */ - const char *buffer, const char *routing_key) -{ - int status; - - status = camqp_connect (conf); - if (status != 0) - return (status); - - amqp_basic_properties_t props = { - ._flags = AMQP_BASIC_CONTENT_TYPE_FLAG - | AMQP_BASIC_DELIVERY_MODE_FLAG - | AMQP_BASIC_APP_ID_FLAG, - .delivery_mode = conf->delivery_mode, - .app_id = amqp_cstring_bytes("collectd") - }; - - if (conf->format == CAMQP_FORMAT_COMMAND) - props.content_type = amqp_cstring_bytes("text/collectd"); - else if (conf->format == CAMQP_FORMAT_JSON) - props.content_type = amqp_cstring_bytes("application/json"); - else if (conf->format == CAMQP_FORMAT_GRAPHITE) - props.content_type = amqp_cstring_bytes("text/graphite"); - else - assert (23 == 42); - - status = amqp_basic_publish(conf->connection, - /* channel = */ 1, - amqp_cstring_bytes(CONF(conf, exchange)), - amqp_cstring_bytes (routing_key), - /* mandatory = */ 0, - /* immediate = */ 0, - &props, - amqp_cstring_bytes(buffer)); - if (status != 0) - { - ERROR ("amqp plugin: amqp_basic_publish failed with status %i.", - status); - camqp_close_connection (conf); - } +static int camqp_write_locked(camqp_config_t *conf, /* {{{ */ + const char *buffer, const char *routing_key) { + int status; + status = camqp_connect(conf); + if (status != 0) return (status); -} /* }}} int camqp_write_locked */ - -static int camqp_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */ - user_data_t *user_data) -{ - camqp_config_t *conf = user_data->data; - char routing_key[6 * DATA_MAX_NAME_LEN]; - char buffer[8192]; - int status; - if ((ds == NULL) || (vl == NULL) || (conf == NULL)) - return (EINVAL); + amqp_basic_properties_t props = {._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | + AMQP_BASIC_DELIVERY_MODE_FLAG | + AMQP_BASIC_APP_ID_FLAG, + .delivery_mode = conf->delivery_mode, + .app_id = amqp_cstring_bytes("collectd")}; + + if (conf->format == CAMQP_FORMAT_COMMAND) + props.content_type = amqp_cstring_bytes("text/collectd"); + else if (conf->format == CAMQP_FORMAT_JSON) + props.content_type = amqp_cstring_bytes("application/json"); + else if (conf->format == CAMQP_FORMAT_GRAPHITE) + props.content_type = amqp_cstring_bytes("text/graphite"); + else + assert(23 == 42); + + status = amqp_basic_publish( + conf->connection, + /* channel = */ 1, amqp_cstring_bytes(CONF(conf, exchange)), + amqp_cstring_bytes(routing_key), + /* mandatory = */ 0, + /* immediate = */ 0, &props, amqp_cstring_bytes(buffer)); + if (status != 0) { + ERROR("amqp plugin: amqp_basic_publish failed with status %i.", status); + camqp_close_connection(conf); + } + + return (status); +} /* }}} int camqp_write_locked */ - if (conf->routing_key != NULL) - { - sstrncpy (routing_key, conf->routing_key, sizeof (routing_key)); - } - else - { - ssnprintf (routing_key, sizeof (routing_key), "collectd/%s/%s/%s/%s/%s", - vl->host, - vl->plugin, vl->plugin_instance, - vl->type, vl->type_instance); - - /* Switch slashes (the only character forbidden by collectd) and dots - * (the separation character used by AMQP). */ - for (size_t i = 0; routing_key[i] != 0; i++) - { - if (routing_key[i] == '.') - routing_key[i] = '/'; - else if (routing_key[i] == '/') - routing_key[i] = '.'; - } +static int camqp_write(const data_set_t *ds, const value_list_t *vl, /* {{{ */ + user_data_t *user_data) { + camqp_config_t *conf = user_data->data; + char routing_key[6 * DATA_MAX_NAME_LEN]; + char buffer[8192]; + int status; + + if ((ds == NULL) || (vl == NULL) || (conf == NULL)) + return (EINVAL); + + if (conf->routing_key != NULL) { + sstrncpy(routing_key, conf->routing_key, sizeof(routing_key)); + } else { + ssnprintf(routing_key, sizeof(routing_key), "collectd/%s/%s/%s/%s/%s", + vl->host, vl->plugin, vl->plugin_instance, vl->type, + vl->type_instance); + + /* Switch slashes (the only character forbidden by collectd) and dots + * (the separation character used by AMQP). */ + for (size_t i = 0; routing_key[i] != 0; i++) { + if (routing_key[i] == '.') + routing_key[i] = '/'; + else if (routing_key[i] == '/') + routing_key[i] = '.'; } + } - if (conf->format == CAMQP_FORMAT_COMMAND) - { - status = cmd_create_putval (buffer, sizeof (buffer), ds, vl); - if (status != 0) - { - ERROR ("amqp plugin: cmd_create_putval failed with status %i.", - status); - return (status); - } + if (conf->format == CAMQP_FORMAT_COMMAND) { + status = cmd_create_putval(buffer, sizeof(buffer), ds, vl); + if (status != 0) { + ERROR("amqp plugin: cmd_create_putval failed with status %i.", status); + return (status); } - else if (conf->format == CAMQP_FORMAT_JSON) - { - size_t bfree = sizeof (buffer); - size_t bfill = 0; - - format_json_initialize (buffer, &bfill, &bfree); - format_json_value_list (buffer, &bfill, &bfree, ds, vl, conf->store_rates); - format_json_finalize (buffer, &bfill, &bfree); - } - else if (conf->format == CAMQP_FORMAT_GRAPHITE) - { - status = format_graphite (buffer, sizeof (buffer), ds, vl, - conf->prefix, conf->postfix, conf->escape_char, - conf->graphite_flags); - if (status != 0) - { - ERROR ("amqp plugin: format_graphite failed with status %i.", - status); - return (status); - } - } - else - { - ERROR ("amqp plugin: Invalid format (%i).", conf->format); - return (-1); + } else if (conf->format == CAMQP_FORMAT_JSON) { + size_t bfree = sizeof(buffer); + size_t bfill = 0; + + format_json_initialize(buffer, &bfill, &bfree); + format_json_value_list(buffer, &bfill, &bfree, ds, vl, conf->store_rates); + format_json_finalize(buffer, &bfill, &bfree); + } else if (conf->format == CAMQP_FORMAT_GRAPHITE) { + status = + format_graphite(buffer, sizeof(buffer), ds, vl, conf->prefix, + conf->postfix, conf->escape_char, conf->graphite_flags); + if (status != 0) { + ERROR("amqp plugin: format_graphite failed with status %i.", status); + return (status); } + } else { + ERROR("amqp plugin: Invalid format (%i).", conf->format); + return (-1); + } - pthread_mutex_lock (&conf->lock); - status = camqp_write_locked (conf, buffer, routing_key); - pthread_mutex_unlock (&conf->lock); + pthread_mutex_lock(&conf->lock); + status = camqp_write_locked(conf, buffer, routing_key); + pthread_mutex_unlock(&conf->lock); - return (status); + return (status); } /* }}} int camqp_write */ /* * Config handling */ -static int camqp_config_set_format (oconfig_item_t *ci, /* {{{ */ - camqp_config_t *conf) -{ - char *string; - int status; +static int camqp_config_set_format(oconfig_item_t *ci, /* {{{ */ + camqp_config_t *conf) { + char *string; + int status; + + string = NULL; + status = cf_util_get_string(ci, &string); + if (status != 0) + return (status); - string = NULL; - status = cf_util_get_string (ci, &string); - if (status != 0) - return (status); - - assert (string != NULL); - if (strcasecmp ("Command", string) == 0) - conf->format = CAMQP_FORMAT_COMMAND; - else if (strcasecmp ("JSON", string) == 0) - conf->format = CAMQP_FORMAT_JSON; - else if (strcasecmp ("Graphite", string) == 0) - conf->format = CAMQP_FORMAT_GRAPHITE; - else - { - WARNING ("amqp plugin: Invalid format string: %s", - string); - } + assert(string != NULL); + if (strcasecmp("Command", string) == 0) + conf->format = CAMQP_FORMAT_COMMAND; + else if (strcasecmp("JSON", string) == 0) + conf->format = CAMQP_FORMAT_JSON; + else if (strcasecmp("Graphite", string) == 0) + conf->format = CAMQP_FORMAT_GRAPHITE; + else { + WARNING("amqp plugin: Invalid format string: %s", string); + } - free (string); + free(string); - return (0); + return (0); } /* }}} int config_set_string */ -static int camqp_config_connection (oconfig_item_t *ci, /* {{{ */ - _Bool publish) -{ - camqp_config_t *conf; - int status; - - conf = calloc (1, sizeof (*conf)); - if (conf == NULL) - { - ERROR ("amqp plugin: calloc failed."); - return (ENOMEM); - } - - /* Initialize "conf" {{{ */ - conf->publish = publish; - conf->name = NULL; - conf->format = CAMQP_FORMAT_COMMAND; - conf->host = NULL; - conf->port = 5672; - conf->vhost = NULL; - conf->user = NULL; - conf->password = NULL; - conf->exchange = NULL; - conf->routing_key = NULL; - conf->connection_retry_delay = 0; - - /* publish only */ - conf->delivery_mode = CAMQP_DM_VOLATILE; - conf->store_rates = 0; - conf->graphite_flags = 0; - /* publish & graphite only */ - conf->prefix = NULL; - conf->postfix = NULL; - conf->escape_char = '_'; - /* subscribe only */ - conf->exchange_type = NULL; - conf->queue = NULL; - conf->queue_durable = 0; - conf->queue_auto_delete = 1; - /* general */ - conf->connection = NULL; - pthread_mutex_init (&conf->lock, /* attr = */ NULL); - /* }}} */ +static int camqp_config_connection(oconfig_item_t *ci, /* {{{ */ + _Bool publish) { + camqp_config_t *conf; + int status; + + conf = calloc(1, sizeof(*conf)); + if (conf == NULL) { + ERROR("amqp plugin: calloc failed."); + return (ENOMEM); + } + + /* Initialize "conf" {{{ */ + conf->publish = publish; + conf->name = NULL; + conf->format = CAMQP_FORMAT_COMMAND; + conf->host = NULL; + conf->port = 5672; + conf->vhost = NULL; + conf->user = NULL; + conf->password = NULL; + conf->exchange = NULL; + conf->routing_key = NULL; + conf->connection_retry_delay = 0; + + /* publish only */ + conf->delivery_mode = CAMQP_DM_VOLATILE; + conf->store_rates = 0; + conf->graphite_flags = 0; + /* publish & graphite only */ + conf->prefix = NULL; + conf->postfix = NULL; + conf->escape_char = '_'; + /* subscribe only */ + conf->exchange_type = NULL; + conf->queue = NULL; + conf->queue_durable = 0; + conf->queue_auto_delete = 1; + /* general */ + conf->connection = NULL; + pthread_mutex_init(&conf->lock, /* attr = */ NULL); + /* }}} */ + + status = cf_util_get_string(ci, &conf->name); + if (status != 0) { + sfree(conf); + return (status); + } + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Host", child->key) == 0) + status = cf_util_get_string(child, &conf->host); + else if (strcasecmp("Port", child->key) == 0) { + status = cf_util_get_port_number(child); + if (status > 0) { + conf->port = status; + status = 0; + } + } else if (strcasecmp("VHost", child->key) == 0) + status = cf_util_get_string(child, &conf->vhost); + else if (strcasecmp("User", child->key) == 0) + status = cf_util_get_string(child, &conf->user); + else if (strcasecmp("Password", child->key) == 0) + status = cf_util_get_string(child, &conf->password); + else if (strcasecmp("Exchange", child->key) == 0) + status = cf_util_get_string(child, &conf->exchange); + else if ((strcasecmp("ExchangeType", child->key) == 0) && !publish) + status = cf_util_get_string(child, &conf->exchange_type); + else if ((strcasecmp("Queue", child->key) == 0) && !publish) + status = cf_util_get_string(child, &conf->queue); + else if ((strcasecmp("QueueDurable", child->key) == 0) && !publish) + status = cf_util_get_boolean(child, &conf->queue_durable); + else if ((strcasecmp("QueueAutoDelete", child->key) == 0) && !publish) + status = cf_util_get_boolean(child, &conf->queue_auto_delete); + else if (strcasecmp("RoutingKey", child->key) == 0) + status = cf_util_get_string(child, &conf->routing_key); + else if ((strcasecmp("Persistent", child->key) == 0) && publish) { + _Bool tmp = 0; + status = cf_util_get_boolean(child, &tmp); + if (tmp) + conf->delivery_mode = CAMQP_DM_PERSISTENT; + else + conf->delivery_mode = CAMQP_DM_VOLATILE; + } else if ((strcasecmp("StoreRates", child->key) == 0) && publish) { + status = cf_util_get_boolean(child, &conf->store_rates); + (void)cf_util_get_flag(child, &conf->graphite_flags, + GRAPHITE_STORE_RATES); + } else if ((strcasecmp("Format", child->key) == 0) && publish) + status = camqp_config_set_format(child, conf); + else if ((strcasecmp("GraphiteSeparateInstances", child->key) == 0) && + publish) + status = cf_util_get_flag(child, &conf->graphite_flags, + GRAPHITE_SEPARATE_INSTANCES); + else if ((strcasecmp("GraphiteAlwaysAppendDS", child->key) == 0) && publish) + status = cf_util_get_flag(child, &conf->graphite_flags, + GRAPHITE_ALWAYS_APPEND_DS); + else if ((strcasecmp("GraphitePreserveSeparator", child->key) == 0) && + publish) + status = cf_util_get_flag(child, &conf->graphite_flags, + GRAPHITE_PRESERVE_SEPARATOR); + else if ((strcasecmp("GraphitePrefix", child->key) == 0) && publish) + status = cf_util_get_string(child, &conf->prefix); + else if ((strcasecmp("GraphitePostfix", child->key) == 0) && publish) + status = cf_util_get_string(child, &conf->postfix); + else if ((strcasecmp("GraphiteEscapeChar", child->key) == 0) && publish) { + char *tmp_buff = NULL; + status = cf_util_get_string(child, &tmp_buff); + if (strlen(tmp_buff) > 1) + WARNING("amqp plugin: The option \"GraphiteEscapeChar\" handles " + "only one character. Others will be ignored."); + conf->escape_char = tmp_buff[0]; + sfree(tmp_buff); + } else if (strcasecmp("ConnectionRetryDelay", child->key) == 0) + status = cf_util_get_int(child, &conf->connection_retry_delay); + else + WARNING("amqp plugin: Ignoring unknown " + "configuration option \"%s\".", + child->key); - status = cf_util_get_string (ci, &conf->name); if (status != 0) - { - sfree (conf); - return (status); - } - - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("Host", child->key) == 0) - status = cf_util_get_string (child, &conf->host); - else if (strcasecmp ("Port", child->key) == 0) - { - status = cf_util_get_port_number (child); - if (status > 0) - { - conf->port = status; - status = 0; - } - } - else if (strcasecmp ("VHost", child->key) == 0) - status = cf_util_get_string (child, &conf->vhost); - else if (strcasecmp ("User", child->key) == 0) - status = cf_util_get_string (child, &conf->user); - else if (strcasecmp ("Password", child->key) == 0) - status = cf_util_get_string (child, &conf->password); - else if (strcasecmp ("Exchange", child->key) == 0) - status = cf_util_get_string (child, &conf->exchange); - else if ((strcasecmp ("ExchangeType", child->key) == 0) && !publish) - status = cf_util_get_string (child, &conf->exchange_type); - else if ((strcasecmp ("Queue", child->key) == 0) && !publish) - status = cf_util_get_string (child, &conf->queue); - else if ((strcasecmp ("QueueDurable", child->key) == 0) && !publish) - status = cf_util_get_boolean (child, &conf->queue_durable); - else if ((strcasecmp ("QueueAutoDelete", child->key) == 0) && !publish) - status = cf_util_get_boolean (child, &conf->queue_auto_delete); - else if (strcasecmp ("RoutingKey", child->key) == 0) - status = cf_util_get_string (child, &conf->routing_key); - else if ((strcasecmp ("Persistent", child->key) == 0) && publish) - { - _Bool tmp = 0; - status = cf_util_get_boolean (child, &tmp); - if (tmp) - conf->delivery_mode = CAMQP_DM_PERSISTENT; - else - conf->delivery_mode = CAMQP_DM_VOLATILE; - } - else if ((strcasecmp ("StoreRates", child->key) == 0) && publish) - { - status = cf_util_get_boolean (child, &conf->store_rates); - (void) cf_util_get_flag (child, &conf->graphite_flags, - GRAPHITE_STORE_RATES); - } - else if ((strcasecmp ("Format", child->key) == 0) && publish) - status = camqp_config_set_format (child, conf); - else if ((strcasecmp ("GraphiteSeparateInstances", child->key) == 0) && publish) - status = cf_util_get_flag (child, &conf->graphite_flags, - GRAPHITE_SEPARATE_INSTANCES); - else if ((strcasecmp ("GraphiteAlwaysAppendDS", child->key) == 0) && publish) - status = cf_util_get_flag (child, &conf->graphite_flags, - GRAPHITE_ALWAYS_APPEND_DS); - else if ((strcasecmp ("GraphitePreserveSeparator", child->key) == 0) && publish) - status = cf_util_get_flag (child, &conf->graphite_flags, - GRAPHITE_PRESERVE_SEPARATOR); - else if ((strcasecmp ("GraphitePrefix", child->key) == 0) && publish) - status = cf_util_get_string (child, &conf->prefix); - else if ((strcasecmp ("GraphitePostfix", child->key) == 0) && publish) - status = cf_util_get_string (child, &conf->postfix); - else if ((strcasecmp ("GraphiteEscapeChar", child->key) == 0) && publish) - { - char *tmp_buff = NULL; - status = cf_util_get_string (child, &tmp_buff); - if (strlen (tmp_buff) > 1) - WARNING ("amqp plugin: The option \"GraphiteEscapeChar\" handles " - "only one character. Others will be ignored."); - conf->escape_char = tmp_buff[0]; - sfree (tmp_buff); - } - else if (strcasecmp ("ConnectionRetryDelay", child->key) == 0) - status = cf_util_get_int (child, &conf->connection_retry_delay); - else - WARNING ("amqp plugin: Ignoring unknown " - "configuration option \"%s\".", child->key); - - if (status != 0) - break; - } /* for (i = 0; i < ci->children_num; i++) */ - - if ((status == 0) && (conf->exchange == NULL)) - { - if (conf->exchange_type != NULL) - WARNING ("amqp plugin: The option \"ExchangeType\" was given " - "without the \"Exchange\" option. It will be ignored."); - - if (!publish && (conf->routing_key != NULL)) - WARNING ("amqp plugin: The option \"RoutingKey\" was given " - "without the \"Exchange\" option. It will be ignored."); + break; + } /* for (i = 0; i < ci->children_num; i++) */ - } - - if (status != 0) - { - camqp_config_free (conf); - return (status); - } + if ((status == 0) && (conf->exchange == NULL)) { + if (conf->exchange_type != NULL) + WARNING("amqp plugin: The option \"ExchangeType\" was given " + "without the \"Exchange\" option. It will be ignored."); - if (conf->exchange != NULL) - { - DEBUG ("amqp plugin: camqp_config_connection: exchange = %s;", - conf->exchange); - } + if (!publish && (conf->routing_key != NULL)) + WARNING("amqp plugin: The option \"RoutingKey\" was given " + "without the \"Exchange\" option. It will be ignored."); + } - if (publish) - { - char cbname[128]; - ssnprintf (cbname, sizeof (cbname), "amqp/%s", conf->name); - - status = plugin_register_write (cbname, camqp_write, - &(user_data_t) { - .data = conf, - .free_func = camqp_config_free, - }); - if (status != 0) - { - camqp_config_free (conf); - return (status); - } + if (status != 0) { + camqp_config_free(conf); + return (status); + } + + if (conf->exchange != NULL) { + DEBUG("amqp plugin: camqp_config_connection: exchange = %s;", + conf->exchange); + } + + if (publish) { + char cbname[128]; + ssnprintf(cbname, sizeof(cbname), "amqp/%s", conf->name); + + status = plugin_register_write( + cbname, camqp_write, &(user_data_t){ + .data = conf, .free_func = camqp_config_free, + }); + if (status != 0) { + camqp_config_free(conf); + return (status); } - else - { - status = camqp_subscribe_init (conf); - if (status != 0) - { - camqp_config_free (conf); - return (status); - } + } else { + status = camqp_subscribe_init(conf); + if (status != 0) { + camqp_config_free(conf); + return (status); } + } - return (0); + return (0); } /* }}} int camqp_config_connection */ -static int camqp_config (oconfig_item_t *ci) /* {{{ */ +static int camqp_config(oconfig_item_t *ci) /* {{{ */ { - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("Publish", child->key) == 0) - camqp_config_connection (child, /* publish = */ 1); - else if (strcasecmp ("Subscribe", child->key) == 0) - camqp_config_connection (child, /* publish = */ 0); - else - WARNING ("amqp plugin: Ignoring unknown config option \"%s\".", - child->key); - } /* for (ci->children_num) */ + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; - return (0); + if (strcasecmp("Publish", child->key) == 0) + camqp_config_connection(child, /* publish = */ 1); + else if (strcasecmp("Subscribe", child->key) == 0) + camqp_config_connection(child, /* publish = */ 0); + else + WARNING("amqp plugin: Ignoring unknown config option \"%s\".", + child->key); + } /* for (ci->children_num) */ + + return (0); } /* }}} int camqp_config */ -void module_register (void) -{ - plugin_register_complex_config ("amqp", camqp_config); - plugin_register_shutdown ("amqp", camqp_shutdown); +void module_register(void) { + plugin_register_complex_config("amqp", camqp_config); + plugin_register_shutdown("amqp", camqp_shutdown); } /* void module_register */ /* vim: set sw=4 sts=4 et fdm=marker : */ diff --git a/src/apache.c b/src/apache.c index 7ccdb60d..eaef61b1 100644 --- a/src/apache.c +++ b/src/apache.c @@ -31,136 +31,122 @@ #include -enum server_enum -{ - APACHE = 0, - LIGHTTPD -}; - -struct apache_s -{ - int server_type; - char *name; - char *host; - char *url; - char *user; - char *pass; - _Bool verify_peer; - _Bool verify_host; - char *cacert; - char *ssl_ciphers; - char *server; /* user specific server type */ - char *apache_buffer; - char apache_curl_error[CURL_ERROR_SIZE]; - size_t apache_buffer_size; - size_t apache_buffer_fill; - int timeout; - CURL *curl; +enum server_enum { APACHE = 0, LIGHTTPD }; + +struct apache_s { + int server_type; + char *name; + char *host; + char *url; + char *user; + char *pass; + _Bool verify_peer; + _Bool verify_host; + char *cacert; + char *ssl_ciphers; + char *server; /* user specific server type */ + char *apache_buffer; + char apache_curl_error[CURL_ERROR_SIZE]; + size_t apache_buffer_size; + size_t apache_buffer_fill; + int timeout; + CURL *curl; }; /* apache_s */ typedef struct apache_s apache_t; /* TODO: Remove this prototype */ -static int apache_read_host (user_data_t *user_data); - -static void apache_free (void *arg) -{ - apache_t *st = arg; - - if (st == NULL) - return; - - sfree (st->name); - sfree (st->host); - sfree (st->url); - sfree (st->user); - sfree (st->pass); - sfree (st->cacert); - sfree (st->ssl_ciphers); - sfree (st->server); - sfree (st->apache_buffer); - if (st->curl) { - curl_easy_cleanup(st->curl); - st->curl = NULL; - } - sfree (st); +static int apache_read_host(user_data_t *user_data); + +static void apache_free(void *arg) { + apache_t *st = arg; + + if (st == NULL) + return; + + sfree(st->name); + sfree(st->host); + sfree(st->url); + sfree(st->user); + sfree(st->pass); + sfree(st->cacert); + sfree(st->ssl_ciphers); + sfree(st->server); + sfree(st->apache_buffer); + if (st->curl) { + curl_easy_cleanup(st->curl); + st->curl = NULL; + } + sfree(st); } /* apache_free */ -static size_t apache_curl_callback (void *buf, size_t size, size_t nmemb, - void *user_data) -{ - size_t len = size * nmemb; - apache_t *st; - - st = user_data; - if (st == NULL) - { - ERROR ("apache plugin: apache_curl_callback: " - "user_data pointer is NULL."); - return (0); - } - - if (len == 0) - return (len); - - if ((st->apache_buffer_fill + len) >= st->apache_buffer_size) - { - char *temp; - - temp = realloc (st->apache_buffer, - st->apache_buffer_fill + len + 1); - if (temp == NULL) - { - ERROR ("apache plugin: realloc failed."); - return (0); - } - st->apache_buffer = temp; - st->apache_buffer_size = st->apache_buffer_fill + len + 1; - } - - memcpy (st->apache_buffer + st->apache_buffer_fill, (char *) buf, len); - st->apache_buffer_fill += len; - st->apache_buffer[st->apache_buffer_fill] = 0; - - return (len); +static size_t apache_curl_callback(void *buf, size_t size, size_t nmemb, + void *user_data) { + size_t len = size * nmemb; + apache_t *st; + + st = user_data; + if (st == NULL) { + ERROR("apache plugin: apache_curl_callback: " + "user_data pointer is NULL."); + return (0); + } + + if (len == 0) + return (len); + + if ((st->apache_buffer_fill + len) >= st->apache_buffer_size) { + char *temp; + + temp = realloc(st->apache_buffer, st->apache_buffer_fill + len + 1); + if (temp == NULL) { + ERROR("apache plugin: realloc failed."); + return (0); + } + st->apache_buffer = temp; + st->apache_buffer_size = st->apache_buffer_fill + len + 1; + } + + memcpy(st->apache_buffer + st->apache_buffer_fill, (char *)buf, len); + st->apache_buffer_fill += len; + st->apache_buffer[st->apache_buffer_fill] = 0; + + return (len); } /* int apache_curl_callback */ -static size_t apache_header_callback (void *buf, size_t size, size_t nmemb, - void *user_data) -{ - size_t len = size * nmemb; - apache_t *st; - - st = user_data; - if (st == NULL) - { - ERROR ("apache plugin: apache_header_callback: " - "user_data pointer is NULL."); - return (0); - } - - if (len == 0) - return (len); - - /* look for the Server header */ - if (strncasecmp (buf, "Server: ", strlen ("Server: ")) != 0) - return (len); - - if (strstr (buf, "Apache") != NULL) - st->server_type = APACHE; - else if (strstr (buf, "lighttpd") != NULL) - st->server_type = LIGHTTPD; - else if (strstr (buf, "IBM_HTTP_Server") != NULL) - st->server_type = APACHE; - else - { - const char *hdr = buf; - - hdr += strlen ("Server: "); - NOTICE ("apache plugin: Unknown server software: %s", hdr); - } - - return (len); +static size_t apache_header_callback(void *buf, size_t size, size_t nmemb, + void *user_data) { + size_t len = size * nmemb; + apache_t *st; + + st = user_data; + if (st == NULL) { + ERROR("apache plugin: apache_header_callback: " + "user_data pointer is NULL."); + return (0); + } + + if (len == 0) + return (len); + + /* look for the Server header */ + if (strncasecmp(buf, "Server: ", strlen("Server: ")) != 0) + return (len); + + if (strstr(buf, "Apache") != NULL) + st->server_type = APACHE; + else if (strstr(buf, "lighttpd") != NULL) + st->server_type = LIGHTTPD; + else if (strstr(buf, "IBM_HTTP_Server") != NULL) + st->server_type = APACHE; + else { + const char *hdr = buf; + + hdr += strlen("Server: "); + NOTICE("apache plugin: Unknown server software: %s", hdr); + } + + return (len); } /* apache_header_callback */ /* Configuration handling functiions @@ -171,443 +157,421 @@ static size_t apache_header_callback (void *buf, size_t size, size_t nmemb, * URL ... * */ -static int config_add (oconfig_item_t *ci) -{ - apache_t *st; - int status; - - st = calloc (1, sizeof (*st)); - if (st == NULL) - { - ERROR ("apache plugin: calloc failed."); - return (-1); - } - - st->timeout = -1; - - status = cf_util_get_string (ci, &st->name); - if (status != 0) - { - sfree (st); - return (status); - } - assert (st->name != NULL); - - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("URL", child->key) == 0) - status = cf_util_get_string (child, &st->url); - else if (strcasecmp ("Host", child->key) == 0) - status = cf_util_get_string (child, &st->host); - else if (strcasecmp ("User", child->key) == 0) - status = cf_util_get_string (child, &st->user); - else if (strcasecmp ("Password", child->key) == 0) - status = cf_util_get_string (child, &st->pass); - else if (strcasecmp ("VerifyPeer", child->key) == 0) - status = cf_util_get_boolean (child, &st->verify_peer); - else if (strcasecmp ("VerifyHost", child->key) == 0) - status = cf_util_get_boolean (child, &st->verify_host); - else if (strcasecmp ("CACert", child->key) == 0) - status = cf_util_get_string (child, &st->cacert); - else if (strcasecmp ("SSLCiphers", child->key) == 0) - status = cf_util_get_string (child, &st->ssl_ciphers); - else if (strcasecmp ("Server", child->key) == 0) - status = cf_util_get_string (child, &st->server); - else if (strcasecmp ("Timeout", child->key) == 0) - status = cf_util_get_int (child, &st->timeout); - else - { - WARNING ("apache plugin: Option `%s' not allowed here.", - child->key); - status = -1; - } - - if (status != 0) - break; - } - - /* Check if struct is complete.. */ - if ((status == 0) && (st->url == NULL)) - { - ERROR ("apache plugin: Instance `%s': " - "No URL has been configured.", - st->name); - status = -1; - } - - if (status == 0) - { - char callback_name[3*DATA_MAX_NAME_LEN]; - - ssnprintf (callback_name, sizeof (callback_name), - "apache/%s/%s", - (st->host != NULL) ? st->host : hostname_g, - (st->name != NULL) ? st->name : "default"); - - status = plugin_register_complex_read (/* group = */ NULL, - /* name = */ callback_name, - /* callback = */ apache_read_host, - /* interval = */ 0, - &(user_data_t) { - .data = st, - .free_func = apache_free, - }); - - } - - if (status != 0) - { - apache_free (st); - return (-1); - } - - return (0); +static int config_add(oconfig_item_t *ci) { + apache_t *st; + int status; + + st = calloc(1, sizeof(*st)); + if (st == NULL) { + ERROR("apache plugin: calloc failed."); + return (-1); + } + + st->timeout = -1; + + status = cf_util_get_string(ci, &st->name); + if (status != 0) { + sfree(st); + return (status); + } + assert(st->name != NULL); + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("URL", child->key) == 0) + status = cf_util_get_string(child, &st->url); + else if (strcasecmp("Host", child->key) == 0) + status = cf_util_get_string(child, &st->host); + else if (strcasecmp("User", child->key) == 0) + status = cf_util_get_string(child, &st->user); + else if (strcasecmp("Password", child->key) == 0) + status = cf_util_get_string(child, &st->pass); + else if (strcasecmp("VerifyPeer", child->key) == 0) + status = cf_util_get_boolean(child, &st->verify_peer); + else if (strcasecmp("VerifyHost", child->key) == 0) + status = cf_util_get_boolean(child, &st->verify_host); + else if (strcasecmp("CACert", child->key) == 0) + status = cf_util_get_string(child, &st->cacert); + else if (strcasecmp("SSLCiphers", child->key) == 0) + status = cf_util_get_string(child, &st->ssl_ciphers); + else if (strcasecmp("Server", child->key) == 0) + status = cf_util_get_string(child, &st->server); + else if (strcasecmp("Timeout", child->key) == 0) + status = cf_util_get_int(child, &st->timeout); + else { + WARNING("apache plugin: Option `%s' not allowed here.", child->key); + status = -1; + } + + if (status != 0) + break; + } + + /* Check if struct is complete.. */ + if ((status == 0) && (st->url == NULL)) { + ERROR("apache plugin: Instance `%s': " + "No URL has been configured.", + st->name); + status = -1; + } + + if (status == 0) { + char callback_name[3 * DATA_MAX_NAME_LEN]; + + ssnprintf(callback_name, sizeof(callback_name), "apache/%s/%s", + (st->host != NULL) ? st->host : hostname_g, + (st->name != NULL) ? st->name : "default"); + + status = plugin_register_complex_read( + /* group = */ NULL, + /* name = */ callback_name, + /* callback = */ apache_read_host, + /* interval = */ 0, &(user_data_t){ + .data = st, .free_func = apache_free, + }); + } + + if (status != 0) { + apache_free(st); + return (-1); + } + + return (0); } /* int config_add */ -static int config (oconfig_item_t *ci) -{ - int status = 0; - - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("Instance", child->key) == 0) - config_add (child); - else - WARNING ("apache plugin: The configuration option " - "\"%s\" is not allowed here. Did you " - "forget to add an block " - "around the configuration?", - child->key); - } /* for (ci->children) */ - - return (status); +static int config(oconfig_item_t *ci) { + int status = 0; + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Instance", child->key) == 0) + config_add(child); + else + WARNING("apache plugin: The configuration option " + "\"%s\" is not allowed here. Did you " + "forget to add an block " + "around the configuration?", + child->key); + } /* for (ci->children) */ + + return (status); } /* int config */ /* initialize curl for each host */ -static int init_host (apache_t *st) /* {{{ */ +static int init_host(apache_t *st) /* {{{ */ { - assert (st->url != NULL); - /* (Assured by `config_add') */ - - if (st->curl != NULL) - { - curl_easy_cleanup (st->curl); - st->curl = NULL; - } - - if ((st->curl = curl_easy_init ()) == NULL) - { - ERROR ("apache plugin: init_host: `curl_easy_init' failed."); - return (-1); - } - - curl_easy_setopt (st->curl, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt (st->curl, CURLOPT_WRITEFUNCTION, apache_curl_callback); - curl_easy_setopt (st->curl, CURLOPT_WRITEDATA, st); - - /* not set as yet if the user specified string doesn't match apache or - * lighttpd, then ignore it. Headers will be parsed to find out the - * server type */ - st->server_type = -1; - - if (st->server != NULL) - { - if (strcasecmp(st->server, "apache") == 0) - st->server_type = APACHE; - else if (strcasecmp(st->server, "lighttpd") == 0) - st->server_type = LIGHTTPD; - else if (strcasecmp(st->server, "ibm_http_server") == 0) - st->server_type = APACHE; - else - WARNING ("apache plugin: Unknown `Server' setting: %s", - st->server); - } - - /* if not found register a header callback to determine the server_type */ - if (st->server_type == -1) - { - curl_easy_setopt (st->curl, CURLOPT_HEADERFUNCTION, apache_header_callback); - curl_easy_setopt (st->curl, CURLOPT_WRITEHEADER, st); - } - - curl_easy_setopt (st->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); - curl_easy_setopt (st->curl, CURLOPT_ERRORBUFFER, st->apache_curl_error); - - if (st->user != NULL) - { + assert(st->url != NULL); + /* (Assured by `config_add') */ + + if (st->curl != NULL) { + curl_easy_cleanup(st->curl); + st->curl = NULL; + } + + if ((st->curl = curl_easy_init()) == NULL) { + ERROR("apache plugin: init_host: `curl_easy_init' failed."); + return (-1); + } + + curl_easy_setopt(st->curl, CURLOPT_NOSIGNAL, 1L); + curl_easy_setopt(st->curl, CURLOPT_WRITEFUNCTION, apache_curl_callback); + curl_easy_setopt(st->curl, CURLOPT_WRITEDATA, st); + + /* not set as yet if the user specified string doesn't match apache or + * lighttpd, then ignore it. Headers will be parsed to find out the + * server type */ + st->server_type = -1; + + if (st->server != NULL) { + if (strcasecmp(st->server, "apache") == 0) + st->server_type = APACHE; + else if (strcasecmp(st->server, "lighttpd") == 0) + st->server_type = LIGHTTPD; + else if (strcasecmp(st->server, "ibm_http_server") == 0) + st->server_type = APACHE; + else + WARNING("apache plugin: Unknown `Server' setting: %s", st->server); + } + + /* if not found register a header callback to determine the server_type */ + if (st->server_type == -1) { + curl_easy_setopt(st->curl, CURLOPT_HEADERFUNCTION, apache_header_callback); + curl_easy_setopt(st->curl, CURLOPT_WRITEHEADER, st); + } + + curl_easy_setopt(st->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); + curl_easy_setopt(st->curl, CURLOPT_ERRORBUFFER, st->apache_curl_error); + + if (st->user != NULL) { #ifdef HAVE_CURLOPT_USERNAME - curl_easy_setopt (st->curl, CURLOPT_USERNAME, st->user); - curl_easy_setopt (st->curl, CURLOPT_PASSWORD, - (st->pass == NULL) ? "" : st->pass); + curl_easy_setopt(st->curl, CURLOPT_USERNAME, st->user); + curl_easy_setopt(st->curl, CURLOPT_PASSWORD, + (st->pass == NULL) ? "" : st->pass); #else - static char credentials[1024]; - int status; - - status = ssnprintf (credentials, sizeof (credentials), "%s:%s", - st->user, (st->pass == NULL) ? "" : st->pass); - if ((status < 0) || ((size_t) status >= sizeof (credentials))) - { - ERROR ("apache plugin: init_host: Returning an error " - "because the credentials have been " - "truncated."); - curl_easy_cleanup (st->curl); - st->curl = NULL; - return (-1); - } - - curl_easy_setopt (st->curl, CURLOPT_USERPWD, credentials); + static char credentials[1024]; + int status; + + status = ssnprintf(credentials, sizeof(credentials), "%s:%s", st->user, + (st->pass == NULL) ? "" : st->pass); + if ((status < 0) || ((size_t)status >= sizeof(credentials))) { + ERROR("apache plugin: init_host: Returning an error " + "because the credentials have been " + "truncated."); + curl_easy_cleanup(st->curl); + st->curl = NULL; + return (-1); + } + + curl_easy_setopt(st->curl, CURLOPT_USERPWD, credentials); #endif - } + } - curl_easy_setopt (st->curl, CURLOPT_URL, st->url); - curl_easy_setopt (st->curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt (st->curl, CURLOPT_MAXREDIRS, 50L); + curl_easy_setopt(st->curl, CURLOPT_URL, st->url); + curl_easy_setopt(st->curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(st->curl, CURLOPT_MAXREDIRS, 50L); - curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYPEER, - (long) st->verify_peer); - curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYHOST, - st->verify_host ? 2L : 0L); - if (st->cacert != NULL) - curl_easy_setopt (st->curl, CURLOPT_CAINFO, st->cacert); - if (st->ssl_ciphers != NULL) - curl_easy_setopt (st->curl, CURLOPT_SSL_CIPHER_LIST,st->ssl_ciphers); + curl_easy_setopt(st->curl, CURLOPT_SSL_VERIFYPEER, (long)st->verify_peer); + curl_easy_setopt(st->curl, CURLOPT_SSL_VERIFYHOST, st->verify_host ? 2L : 0L); + if (st->cacert != NULL) + curl_easy_setopt(st->curl, CURLOPT_CAINFO, st->cacert); + if (st->ssl_ciphers != NULL) + curl_easy_setopt(st->curl, CURLOPT_SSL_CIPHER_LIST, st->ssl_ciphers); #ifdef HAVE_CURLOPT_TIMEOUT_MS - if (st->timeout >= 0) - curl_easy_setopt (st->curl, CURLOPT_TIMEOUT_MS, (long) st->timeout); - else - curl_easy_setopt (st->curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval())); + if (st->timeout >= 0) + curl_easy_setopt(st->curl, CURLOPT_TIMEOUT_MS, (long)st->timeout); + else + curl_easy_setopt(st->curl, CURLOPT_TIMEOUT_MS, + (long)CDTIME_T_TO_MS(plugin_get_interval())); #endif - return (0); + return (0); } /* }}} int init_host */ -static void submit_value (const char *type, const char *type_instance, - value_t value, apache_t *st) -{ - value_list_t vl = VALUE_LIST_INIT; +static void submit_value(const char *type, const char *type_instance, + value_t value, apache_t *st) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &value; - vl.values_len = 1; + vl.values = &value; + vl.values_len = 1; - if (st->host != NULL) - sstrncpy (vl.host, st->host, sizeof (vl.host)); + if (st->host != NULL) + sstrncpy(vl.host, st->host, sizeof(vl.host)); - sstrncpy (vl.plugin, "apache", sizeof (vl.plugin)); - if (st->name != NULL) - sstrncpy (vl.plugin_instance, st->name, - sizeof (vl.plugin_instance)); + sstrncpy(vl.plugin, "apache", sizeof(vl.plugin)); + if (st->name != NULL) + sstrncpy(vl.plugin_instance, st->name, sizeof(vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, - sizeof (vl.type_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + if (type_instance != NULL) + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* void submit_value */ -static void submit_derive (const char *type, const char *type_instance, - derive_t d, apache_t *st) -{ - submit_value (type, type_instance, (value_t) { .derive = d }, st); +static void submit_derive(const char *type, const char *type_instance, + derive_t d, apache_t *st) { + submit_value(type, type_instance, (value_t){.derive = d}, st); } /* void submit_derive */ -static void submit_gauge (const char *type, const char *type_instance, - gauge_t g, apache_t *st) -{ - submit_value (type, type_instance, (value_t) { .gauge = g }, st); +static void submit_gauge(const char *type, const char *type_instance, gauge_t g, + apache_t *st) { + submit_value(type, type_instance, (value_t){.gauge = g}, st); } /* void submit_gauge */ -static void submit_scoreboard (char *buf, apache_t *st) -{ - /* - * Scoreboard Key: - * "_" Waiting for Connection, "S" Starting up, - * "R" Reading Request for apache and read-POST for lighttpd, - * "W" Sending Reply, "K" Keepalive (read), "D" DNS Lookup, - * "C" Closing connection, "L" Logging, "G" Gracefully finishing, - * "I" Idle cleanup of worker, "." Open slot with no current process - * Lighttpd specific legends - - * "E" hard error, "." connect, "h" handle-request, - * "q" request-start, "Q" request-end, "s" response-start - * "S" response-end, "r" read - */ - long long open = 0LL; - long long waiting = 0LL; - long long starting = 0LL; - long long reading = 0LL; - long long sending = 0LL; - long long keepalive = 0LL; - long long dnslookup = 0LL; - long long closing = 0LL; - long long logging = 0LL; - long long finishing = 0LL; - long long idle_cleanup = 0LL; - - /* lighttpd specific */ - long long hard_error = 0LL; - long long lighttpd_read = 0LL; - long long handle_request = 0LL; - long long request_start = 0LL; - long long request_end = 0LL; - long long response_start = 0LL; - long long response_end = 0LL; - - for (int i = 0; buf[i] != '\0'; i++) - { - if (buf[i] == '.') open++; - else if (buf[i] == '_') waiting++; - else if (buf[i] == 'S') starting++; - else if (buf[i] == 'R') reading++; - else if (buf[i] == 'W') sending++; - else if (buf[i] == 'K') keepalive++; - else if (buf[i] == 'D') dnslookup++; - else if (buf[i] == 'C') closing++; - else if (buf[i] == 'L') logging++; - else if (buf[i] == 'G') finishing++; - else if (buf[i] == 'I') idle_cleanup++; - else if (buf[i] == 'r') lighttpd_read++; - else if (buf[i] == 'h') handle_request++; - else if (buf[i] == 'E') hard_error++; - else if (buf[i] == 'q') request_start++; - else if (buf[i] == 'Q') request_end++; - else if (buf[i] == 's') response_start++; - else if (buf[i] == 'S') response_end++; - } - - if (st->server_type == APACHE) - { - submit_gauge ("apache_scoreboard", "open" , open, st); - submit_gauge ("apache_scoreboard", "waiting" , waiting, st); - submit_gauge ("apache_scoreboard", "starting" , starting, st); - submit_gauge ("apache_scoreboard", "reading" , reading, st); - submit_gauge ("apache_scoreboard", "sending" , sending, st); - submit_gauge ("apache_scoreboard", "keepalive", keepalive, st); - submit_gauge ("apache_scoreboard", "dnslookup", dnslookup, st); - submit_gauge ("apache_scoreboard", "closing" , closing, st); - submit_gauge ("apache_scoreboard", "logging" , logging, st); - submit_gauge ("apache_scoreboard", "finishing", finishing, st); - submit_gauge ("apache_scoreboard", "idle_cleanup", idle_cleanup, st); - } - else - { - submit_gauge ("apache_scoreboard", "connect" , open, st); - submit_gauge ("apache_scoreboard", "close" , closing, st); - submit_gauge ("apache_scoreboard", "hard_error" , hard_error, st); - submit_gauge ("apache_scoreboard", "read" , lighttpd_read, st); - submit_gauge ("apache_scoreboard", "read_post" , reading, st); - submit_gauge ("apache_scoreboard", "write" , sending, st); - submit_gauge ("apache_scoreboard", "handle_request", handle_request, st); - submit_gauge ("apache_scoreboard", "request_start" , request_start, st); - submit_gauge ("apache_scoreboard", "request_end" , request_end, st); - submit_gauge ("apache_scoreboard", "response_start", response_start, st); - submit_gauge ("apache_scoreboard", "response_end" , response_end, st); - } +static void submit_scoreboard(char *buf, apache_t *st) { + /* + * Scoreboard Key: + * "_" Waiting for Connection, "S" Starting up, + * "R" Reading Request for apache and read-POST for lighttpd, + * "W" Sending Reply, "K" Keepalive (read), "D" DNS Lookup, + * "C" Closing connection, "L" Logging, "G" Gracefully finishing, + * "I" Idle cleanup of worker, "." Open slot with no current process + * Lighttpd specific legends - + * "E" hard error, "." connect, "h" handle-request, + * "q" request-start, "Q" request-end, "s" response-start + * "S" response-end, "r" read + */ + long long open = 0LL; + long long waiting = 0LL; + long long starting = 0LL; + long long reading = 0LL; + long long sending = 0LL; + long long keepalive = 0LL; + long long dnslookup = 0LL; + long long closing = 0LL; + long long logging = 0LL; + long long finishing = 0LL; + long long idle_cleanup = 0LL; + + /* lighttpd specific */ + long long hard_error = 0LL; + long long lighttpd_read = 0LL; + long long handle_request = 0LL; + long long request_start = 0LL; + long long request_end = 0LL; + long long response_start = 0LL; + long long response_end = 0LL; + + for (int i = 0; buf[i] != '\0'; i++) { + if (buf[i] == '.') + open++; + else if (buf[i] == '_') + waiting++; + else if (buf[i] == 'S') + starting++; + else if (buf[i] == 'R') + reading++; + else if (buf[i] == 'W') + sending++; + else if (buf[i] == 'K') + keepalive++; + else if (buf[i] == 'D') + dnslookup++; + else if (buf[i] == 'C') + closing++; + else if (buf[i] == 'L') + logging++; + else if (buf[i] == 'G') + finishing++; + else if (buf[i] == 'I') + idle_cleanup++; + else if (buf[i] == 'r') + lighttpd_read++; + else if (buf[i] == 'h') + handle_request++; + else if (buf[i] == 'E') + hard_error++; + else if (buf[i] == 'q') + request_start++; + else if (buf[i] == 'Q') + request_end++; + else if (buf[i] == 's') + response_start++; + else if (buf[i] == 'S') + response_end++; + } + + if (st->server_type == APACHE) { + submit_gauge("apache_scoreboard", "open", open, st); + submit_gauge("apache_scoreboard", "waiting", waiting, st); + submit_gauge("apache_scoreboard", "starting", starting, st); + submit_gauge("apache_scoreboard", "reading", reading, st); + submit_gauge("apache_scoreboard", "sending", sending, st); + submit_gauge("apache_scoreboard", "keepalive", keepalive, st); + submit_gauge("apache_scoreboard", "dnslookup", dnslookup, st); + submit_gauge("apache_scoreboard", "closing", closing, st); + submit_gauge("apache_scoreboard", "logging", logging, st); + submit_gauge("apache_scoreboard", "finishing", finishing, st); + submit_gauge("apache_scoreboard", "idle_cleanup", idle_cleanup, st); + } else { + submit_gauge("apache_scoreboard", "connect", open, st); + submit_gauge("apache_scoreboard", "close", closing, st); + submit_gauge("apache_scoreboard", "hard_error", hard_error, st); + submit_gauge("apache_scoreboard", "read", lighttpd_read, st); + submit_gauge("apache_scoreboard", "read_post", reading, st); + submit_gauge("apache_scoreboard", "write", sending, st); + submit_gauge("apache_scoreboard", "handle_request", handle_request, st); + submit_gauge("apache_scoreboard", "request_start", request_start, st); + submit_gauge("apache_scoreboard", "request_end", request_end, st); + submit_gauge("apache_scoreboard", "response_start", response_start, st); + submit_gauge("apache_scoreboard", "response_end", response_end, st); + } } -static int apache_read_host (user_data_t *user_data) /* {{{ */ +static int apache_read_host(user_data_t *user_data) /* {{{ */ { - char *ptr; - char *saveptr; - char *line; - - char *fields[4]; - int fields_num; - - apache_t *st; - - st = user_data->data; - - int status; - - char *content_type; - static const char *text_plain = "text/plain"; - - assert (st->url != NULL); - /* (Assured by `config_add') */ - - if (st->curl == NULL) - { - status = init_host (st); - if (status != 0) - return (-1); - } - assert (st->curl != NULL); - - st->apache_buffer_fill = 0; - if (curl_easy_perform (st->curl) != CURLE_OK) - { - ERROR ("apache: curl_easy_perform failed: %s", - st->apache_curl_error); - return (-1); - } - - /* fallback - server_type to apache if not set at this time */ - if (st->server_type == -1) - { - WARNING ("apache plugin: Unable to determine server software " - "automatically. Will assume Apache."); - st->server_type = APACHE; - } - - status = curl_easy_getinfo (st->curl, CURLINFO_CONTENT_TYPE, &content_type); - if ((status == CURLE_OK) && (content_type != NULL) && - (strncasecmp (content_type, text_plain, strlen (text_plain)) != 0)) - { - WARNING ("apache plugin: `Content-Type' response header is not `%s' " - "(received: `%s'). Expecting unparseable data. Please check `URL' " - "parameter (missing `?auto' suffix ?)", - text_plain, content_type); - } - - ptr = st->apache_buffer; - saveptr = NULL; - while ((line = strtok_r (ptr, "\n\r", &saveptr)) != NULL) - { - ptr = NULL; - fields_num = strsplit (line, fields, STATIC_ARRAY_SIZE (fields)); - - if (fields_num == 3) - { - if ((strcmp (fields[0], "Total") == 0) && (strcmp (fields[1], "Accesses:") == 0)) - submit_derive ("apache_requests", "", atoll (fields[2]), st); - else if ((strcmp (fields[0], "Total") == 0) && (strcmp (fields[1], "kBytes:") == 0)) - submit_derive ("apache_bytes", "", 1024LL * atoll (fields[2]), st); - } - else if (fields_num == 2) - { - if (strcmp (fields[0], "Scoreboard:") == 0) - submit_scoreboard (fields[1], st); - else if ((strcmp (fields[0], "BusyServers:") == 0) /* Apache 1.* */ - || (strcmp (fields[0], "BusyWorkers:") == 0) /* Apache 2.* */) - submit_gauge ("apache_connections", NULL, atol (fields[1]), st); - else if ((strcmp (fields[0], "IdleServers:") == 0) /* Apache 1.x */ - || (strcmp (fields[0], "IdleWorkers:") == 0) /* Apache 2.x */) - submit_gauge ("apache_idle_workers", NULL, atol (fields[1]), st); - } - } - - st->apache_buffer_fill = 0; - - return (0); + char *ptr; + char *saveptr; + char *line; + + char *fields[4]; + int fields_num; + + apache_t *st; + + st = user_data->data; + + int status; + + char *content_type; + static const char *text_plain = "text/plain"; + + assert(st->url != NULL); + /* (Assured by `config_add') */ + + if (st->curl == NULL) { + status = init_host(st); + if (status != 0) + return (-1); + } + assert(st->curl != NULL); + + st->apache_buffer_fill = 0; + if (curl_easy_perform(st->curl) != CURLE_OK) { + ERROR("apache: curl_easy_perform failed: %s", st->apache_curl_error); + return (-1); + } + + /* fallback - server_type to apache if not set at this time */ + if (st->server_type == -1) { + WARNING("apache plugin: Unable to determine server software " + "automatically. Will assume Apache."); + st->server_type = APACHE; + } + + status = curl_easy_getinfo(st->curl, CURLINFO_CONTENT_TYPE, &content_type); + if ((status == CURLE_OK) && (content_type != NULL) && + (strncasecmp(content_type, text_plain, strlen(text_plain)) != 0)) { + WARNING("apache plugin: `Content-Type' response header is not `%s' " + "(received: `%s'). Expecting unparseable data. Please check `URL' " + "parameter (missing `?auto' suffix ?)", + text_plain, content_type); + } + + ptr = st->apache_buffer; + saveptr = NULL; + while ((line = strtok_r(ptr, "\n\r", &saveptr)) != NULL) { + ptr = NULL; + fields_num = strsplit(line, fields, STATIC_ARRAY_SIZE(fields)); + + if (fields_num == 3) { + if ((strcmp(fields[0], "Total") == 0) && + (strcmp(fields[1], "Accesses:") == 0)) + submit_derive("apache_requests", "", atoll(fields[2]), st); + else if ((strcmp(fields[0], "Total") == 0) && + (strcmp(fields[1], "kBytes:") == 0)) + submit_derive("apache_bytes", "", 1024LL * atoll(fields[2]), st); + } else if (fields_num == 2) { + if (strcmp(fields[0], "Scoreboard:") == 0) + submit_scoreboard(fields[1], st); + else if ((strcmp(fields[0], "BusyServers:") == 0) /* Apache 1.* */ + || (strcmp(fields[0], "BusyWorkers:") == 0) /* Apache 2.* */) + submit_gauge("apache_connections", NULL, atol(fields[1]), st); + else if ((strcmp(fields[0], "IdleServers:") == 0) /* Apache 1.x */ + || (strcmp(fields[0], "IdleWorkers:") == 0) /* Apache 2.x */) + submit_gauge("apache_idle_workers", NULL, atol(fields[1]), st); + } + } + + st->apache_buffer_fill = 0; + + return (0); } /* }}} int apache_read_host */ -static int apache_init (void) /* {{{ */ +static int apache_init(void) /* {{{ */ { - /* Call this while collectd is still single-threaded to avoid - * initialization issues in libgcrypt. */ - curl_global_init (CURL_GLOBAL_SSL); - return (0); + /* Call this while collectd is still single-threaded to avoid + * initialization issues in libgcrypt. */ + curl_global_init(CURL_GLOBAL_SSL); + return (0); } /* }}} int apache_init */ -void module_register (void) -{ - plugin_register_complex_config ("apache", config); - plugin_register_init ("apache", apache_init); +void module_register(void) { + plugin_register_complex_config("apache", config); + plugin_register_init("apache", apache_init); } /* void module_register */ /* vim: set sw=8 noet fdm=marker : */ diff --git a/src/apcups.c b/src/apcups.c index 50c45e7b..3b8b03c2 100644 --- a/src/apcups.c +++ b/src/apcups.c @@ -26,45 +26,44 @@ #include "collectd.h" -#include "common.h" /* rrd_update_file */ -#include "plugin.h" /* plugin_register, plugin_submit */ +#include "common.h" /* rrd_update_file */ +#include "plugin.h" /* plugin_register, plugin_submit */ #if HAVE_SYS_TYPES_H -# include +#include #endif #if HAVE_NETDB_H -# include +#include #endif #if HAVE_NETINET_IN_H -# include +#include #endif #ifndef APCUPS_SERVER_TIMEOUT -# define APCUPS_SERVER_TIMEOUT 15.0 +#define APCUPS_SERVER_TIMEOUT 15.0 #endif #ifndef APCUPS_DEFAULT_NODE -# define APCUPS_DEFAULT_NODE "localhost" +#define APCUPS_DEFAULT_NODE "localhost" #endif #ifndef APCUPS_DEFAULT_SERVICE -# define APCUPS_DEFAULT_SERVICE "3551" +#define APCUPS_DEFAULT_SERVICE "3551" #endif /* * Private data types */ -typedef struct -{ - gauge_t linev; - gauge_t loadpct; - gauge_t bcharge; - gauge_t timeleft; - gauge_t outputv; - gauge_t itemp; - gauge_t battv; - gauge_t linefreq; +typedef struct { + gauge_t linev; + gauge_t loadpct; + gauge_t bcharge; + gauge_t timeleft; + gauge_t outputv; + gauge_t itemp; + gauge_t battv; + gauge_t linefreq; } apc_detail_t; /* @@ -82,28 +81,26 @@ static int global_sockfd = -1; static int count_retries = 0; static int count_iterations = 0; -static int net_shutdown (int *fd) -{ - uint16_t packet_size = 0; +static int net_shutdown(int *fd) { + uint16_t packet_size = 0; - if ((fd == NULL) || (*fd < 0)) - return (EINVAL); + if ((fd == NULL) || (*fd < 0)) + return (EINVAL); - (void)swrite (*fd, (void *) &packet_size, sizeof (packet_size)); - close (*fd); - *fd = -1; + (void)swrite(*fd, (void *)&packet_size, sizeof(packet_size)); + close(*fd); + *fd = -1; - return (0); + return (0); } /* int net_shutdown */ /* Close the network connection */ -static int apcups_shutdown (void) -{ - if (global_sockfd < 0) - return (0); +static int apcups_shutdown(void) { + if (global_sockfd < 0) + return (0); - net_shutdown (&global_sockfd); - return (0); + net_shutdown(&global_sockfd); + return (0); } /* int apcups_shutdown */ /* @@ -111,63 +108,55 @@ static int apcups_shutdown (void) * Returns -1 on error * Returns socket file descriptor otherwise */ -static int net_open (char const *node, char const *service) -{ - int sd; - int status; - struct addrinfo *ai_return; - struct addrinfo *ai_list; - - /* TODO: Change this to `AF_UNSPEC' if apcupsd can handle IPv6 */ - struct addrinfo ai_hints = { - .ai_family = AF_INET, - .ai_socktype = SOCK_STREAM - }; - - status = getaddrinfo (node, service, &ai_hints, &ai_return); - if (status != 0) - { - char errbuf[1024]; - INFO ("apcups plugin: getaddrinfo failed: %s", - (status == EAI_SYSTEM) - ? sstrerror (errno, errbuf, sizeof (errbuf)) - : gai_strerror (status)); - return (-1); - } - - /* Create socket */ - sd = -1; - for (ai_list = ai_return; ai_list != NULL; ai_list = ai_list->ai_next) - { - sd = socket (ai_list->ai_family, ai_list->ai_socktype, ai_list->ai_protocol); - if (sd >= 0) - break; - } - /* `ai_list' still holds the current description of the socket.. */ - - if (sd < 0) - { - DEBUG ("apcups plugin: Unable to open a socket"); - freeaddrinfo (ai_return); - return (-1); - } - - status = connect (sd, ai_list->ai_addr, ai_list->ai_addrlen); - - freeaddrinfo (ai_return); - - if (status != 0) /* `connect(2)' failed */ - { - char errbuf[1024]; - INFO ("apcups plugin: connect failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - close (sd); - return (-1); - } - - DEBUG ("apcups plugin: Done opening a socket %i", sd); - - return (sd); +static int net_open(char const *node, char const *service) { + int sd; + int status; + struct addrinfo *ai_return; + struct addrinfo *ai_list; + + /* TODO: Change this to `AF_UNSPEC' if apcupsd can handle IPv6 */ + struct addrinfo ai_hints = {.ai_family = AF_INET, .ai_socktype = SOCK_STREAM}; + + status = getaddrinfo(node, service, &ai_hints, &ai_return); + if (status != 0) { + char errbuf[1024]; + INFO("apcups plugin: getaddrinfo failed: %s", + (status == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf)) + : gai_strerror(status)); + return (-1); + } + + /* Create socket */ + sd = -1; + for (ai_list = ai_return; ai_list != NULL; ai_list = ai_list->ai_next) { + sd = socket(ai_list->ai_family, ai_list->ai_socktype, ai_list->ai_protocol); + if (sd >= 0) + break; + } + /* `ai_list' still holds the current description of the socket.. */ + + if (sd < 0) { + DEBUG("apcups plugin: Unable to open a socket"); + freeaddrinfo(ai_return); + return (-1); + } + + status = connect(sd, ai_list->ai_addr, ai_list->ai_addrlen); + + freeaddrinfo(ai_return); + + if (status != 0) /* `connect(2)' failed */ + { + char errbuf[1024]; + INFO("apcups plugin: connect failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(sd); + return (-1); + } + + DEBUG("apcups plugin: Done opening a socket %i", sd); + + return (sd); } /* int net_open */ /* @@ -179,41 +168,37 @@ static int net_open (char const *node, char const *service) * Returns -1 on hard end of file (i.e. network connection close) * Returns -2 on error */ -static int net_recv (int *sockfd, char *buf, int buflen) -{ - uint16_t packet_size; - - /* get data size -- in short */ - if (sread (*sockfd, (void *) &packet_size, sizeof (packet_size)) != 0) - { - close (*sockfd); - *sockfd = -1; - return (-1); - } - - packet_size = ntohs (packet_size); - if (packet_size > buflen) - { - ERROR ("apcups plugin: Received %"PRIu16" bytes of payload " - "but have only %i bytes of buffer available.", - packet_size, buflen); - close (*sockfd); - *sockfd = -1; - return (-2); - } - - if (packet_size == 0) - return (0); - - /* now read the actual data */ - if (sread (*sockfd, (void *) buf, packet_size) != 0) - { - close (*sockfd); - *sockfd = -1; - return (-1); - } - - return ((int) packet_size); +static int net_recv(int *sockfd, char *buf, int buflen) { + uint16_t packet_size; + + /* get data size -- in short */ + if (sread(*sockfd, (void *)&packet_size, sizeof(packet_size)) != 0) { + close(*sockfd); + *sockfd = -1; + return (-1); + } + + packet_size = ntohs(packet_size); + if (packet_size > buflen) { + ERROR("apcups plugin: Received %" PRIu16 " bytes of payload " + "but have only %i bytes of buffer available.", + packet_size, buflen); + close(*sockfd); + *sockfd = -1; + return (-2); + } + + if (packet_size == 0) + return (0); + + /* now read the actual data */ + if (sread(*sockfd, (void *)buf, packet_size) != 0) { + close(*sockfd); + *sockfd = -1; + return (-1); + } + + return ((int)packet_size); } /* static int net_recv (int *sockfd, char *buf, int buflen) */ /* @@ -223,258 +208,236 @@ static int net_recv (int *sockfd, char *buf, int buflen) * Returns zero on success * Returns non-zero on error */ -static int net_send (int *sockfd, const char *buff, int len) -{ - uint16_t packet_size; - - assert (len > 0); - assert (*sockfd >= 0); - - /* send short containing size of data packet */ - packet_size = htons ((uint16_t) len); - - if (swrite (*sockfd, (void *) &packet_size, sizeof (packet_size)) != 0) - { - close (*sockfd); - *sockfd = -1; - return (-1); - } - - /* send data packet */ - if (swrite (*sockfd, (void *) buff, len) != 0) - { - close (*sockfd); - *sockfd = -1; - return (-2); - } - - return (0); +static int net_send(int *sockfd, const char *buff, int len) { + uint16_t packet_size; + + assert(len > 0); + assert(*sockfd >= 0); + + /* send short containing size of data packet */ + packet_size = htons((uint16_t)len); + + if (swrite(*sockfd, (void *)&packet_size, sizeof(packet_size)) != 0) { + close(*sockfd); + *sockfd = -1; + return (-1); + } + + /* send data packet */ + if (swrite(*sockfd, (void *)buff, len) != 0) { + close(*sockfd); + *sockfd = -1; + return (-2); + } + + return (0); } /* Get and print status from apcupsd NIS server */ -static int apc_query_server (char const *node, char const *service, - apc_detail_t *apcups_detail) -{ - int n; - char recvline[1024]; - char *tokptr; - char *toksaveptr; - _Bool retry = 1; - int status; +static int apc_query_server(char const *node, char const *service, + apc_detail_t *apcups_detail) { + int n; + char recvline[1024]; + char *tokptr; + char *toksaveptr; + _Bool retry = 1; + int status; #if APCMAIN -# define PRINT_VALUE(name, val) printf(" Found property: name = %s; value = %f;\n", name, val) +#define PRINT_VALUE(name, val) \ + printf(" Found property: name = %s; value = %f;\n", name, val) #else -# define PRINT_VALUE(name, val) /**/ +#define PRINT_VALUE(name, val) /**/ #endif - while (retry) - { - if (global_sockfd < 0) - { - global_sockfd = net_open (node, service); - if (global_sockfd < 0) - { - ERROR ("apcups plugin: Connecting to the " - "apcupsd failed."); - return (-1); - } - } - - - status = net_send (&global_sockfd, "status", strlen ("status")); - if (status != 0) - { - /* net_send is closing the socket on error. */ - assert (global_sockfd < 0); - if (retry) - { - retry = 0; - count_retries++; - continue; - } - - ERROR ("apcups plugin: Writing to the socket failed."); - return (-1); - } - - break; - } /* while (retry) */ - - /* When collectd's collection interval is larger than apcupsd's - * timeout, we would have to retry / re-connect each iteration. Try to - * detect this situation and shut down the socket gracefully in that - * case. Otherwise, keep the socket open to avoid overhead. */ - count_iterations++; - if ((count_iterations == 10) && (count_retries > 2)) - { - NOTICE ("apcups plugin: There have been %i retries in the " - "first %i iterations. Will close the socket " - "in future iterations.", - count_retries, count_iterations); - conf_persistent_conn = 0; - } - - while ((n = net_recv (&global_sockfd, recvline, sizeof (recvline) - 1)) > 0) - { - assert ((size_t)n < sizeof (recvline)); - recvline[n] = 0; + while (retry) { + if (global_sockfd < 0) { + global_sockfd = net_open(node, service); + if (global_sockfd < 0) { + ERROR("apcups plugin: Connecting to the " + "apcupsd failed."); + return (-1); + } + } + + status = net_send(&global_sockfd, "status", strlen("status")); + if (status != 0) { + /* net_send is closing the socket on error. */ + assert(global_sockfd < 0); + if (retry) { + retry = 0; + count_retries++; + continue; + } + + ERROR("apcups plugin: Writing to the socket failed."); + return (-1); + } + + break; + } /* while (retry) */ + + /* When collectd's collection interval is larger than apcupsd's + * timeout, we would have to retry / re-connect each iteration. Try to + * detect this situation and shut down the socket gracefully in that + * case. Otherwise, keep the socket open to avoid overhead. */ + count_iterations++; + if ((count_iterations == 10) && (count_retries > 2)) { + NOTICE("apcups plugin: There have been %i retries in the " + "first %i iterations. Will close the socket " + "in future iterations.", + count_retries, count_iterations); + conf_persistent_conn = 0; + } + + while ((n = net_recv(&global_sockfd, recvline, sizeof(recvline) - 1)) > 0) { + assert((size_t)n < sizeof(recvline)); + recvline[n] = 0; #if APCMAIN - printf ("net_recv = `%s';\n", recvline); + printf("net_recv = `%s';\n", recvline); #endif /* if APCMAIN */ - toksaveptr = NULL; - tokptr = strtok_r (recvline, " :\t", &toksaveptr); - while (tokptr != NULL) - { - char *key = tokptr; - if ((tokptr = strtok_r (NULL, " :\t", &toksaveptr)) == NULL) - continue; - - gauge_t value; - if (strtogauge (tokptr, &value) != 0) - continue; - - PRINT_VALUE (key, value); - - if (strcmp ("LINEV", key) == 0) - apcups_detail->linev = value; - else if (strcmp ("BATTV", key) == 0) - apcups_detail->battv = value; - else if (strcmp ("ITEMP", key) == 0) - apcups_detail->itemp = value; - else if (strcmp ("LOADPCT", key) == 0) - apcups_detail->loadpct = value; - else if (strcmp ("BCHARGE", key) == 0) - apcups_detail->bcharge = value; - else if (strcmp ("OUTPUTV", key) == 0) - apcups_detail->outputv = value; - else if (strcmp ("LINEFREQ", key) == 0) - apcups_detail->linefreq = value; - else if (strcmp ("TIMELEFT", key) == 0) - { - /* Convert minutes to seconds if requested by - * the user. */ - if (conf_report_seconds) - value *= 60.0; - apcups_detail->timeleft = value; - } - - tokptr = strtok_r (NULL, ":", &toksaveptr); - } /* while (tokptr != NULL) */ - } - status = errno; /* save errno, net_shutdown() may re-set it. */ - - if (!conf_persistent_conn) - net_shutdown (&global_sockfd); - - if (n < 0) - { - char errbuf[1024]; - ERROR ("apcups plugin: Reading from socket failed: %s", - sstrerror (status, errbuf, sizeof (errbuf))); - return (-1); - } - - return (0); + toksaveptr = NULL; + tokptr = strtok_r(recvline, " :\t", &toksaveptr); + while (tokptr != NULL) { + char *key = tokptr; + if ((tokptr = strtok_r(NULL, " :\t", &toksaveptr)) == NULL) + continue; + + gauge_t value; + if (strtogauge(tokptr, &value) != 0) + continue; + + PRINT_VALUE(key, value); + + if (strcmp("LINEV", key) == 0) + apcups_detail->linev = value; + else if (strcmp("BATTV", key) == 0) + apcups_detail->battv = value; + else if (strcmp("ITEMP", key) == 0) + apcups_detail->itemp = value; + else if (strcmp("LOADPCT", key) == 0) + apcups_detail->loadpct = value; + else if (strcmp("BCHARGE", key) == 0) + apcups_detail->bcharge = value; + else if (strcmp("OUTPUTV", key) == 0) + apcups_detail->outputv = value; + else if (strcmp("LINEFREQ", key) == 0) + apcups_detail->linefreq = value; + else if (strcmp("TIMELEFT", key) == 0) { + /* Convert minutes to seconds if requested by + * the user. */ + if (conf_report_seconds) + value *= 60.0; + apcups_detail->timeleft = value; + } + + tokptr = strtok_r(NULL, ":", &toksaveptr); + } /* while (tokptr != NULL) */ + } + status = errno; /* save errno, net_shutdown() may re-set it. */ + + if (!conf_persistent_conn) + net_shutdown(&global_sockfd); + + if (n < 0) { + char errbuf[1024]; + ERROR("apcups plugin: Reading from socket failed: %s", + sstrerror(status, errbuf, sizeof(errbuf))); + return (-1); + } + + return (0); } -static int apcups_config (oconfig_item_t *ci) -{ - _Bool persistent_conn_set = 0; - - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp (child->key, "Host") == 0) - cf_util_get_string (child, &conf_node); - else if (strcasecmp (child->key, "Port") == 0) - cf_util_get_service (child, &conf_service); - else if (strcasecmp (child->key, "ReportSeconds") == 0) - cf_util_get_boolean (child, &conf_report_seconds); - else if (strcasecmp (child->key, "PersistentConnection") == 0) { - cf_util_get_boolean (child, &conf_persistent_conn); - persistent_conn_set = 1; - } - else - ERROR ("apcups plugin: Unknown config option \"%s\".", child->key); - } - - if (!persistent_conn_set) { - double interval = CDTIME_T_TO_DOUBLE(plugin_get_interval()); - if (interval > APCUPS_SERVER_TIMEOUT) { - NOTICE ("apcups plugin: Plugin poll interval set to %.3f seconds. " - "Apcupsd NIS socket timeout is %.3f seconds, " - "PersistentConnection disabled by default.", - interval, APCUPS_SERVER_TIMEOUT); - conf_persistent_conn = 0; - } - } - - return (0); +static int apcups_config(oconfig_item_t *ci) { + _Bool persistent_conn_set = 0; + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp(child->key, "Host") == 0) + cf_util_get_string(child, &conf_node); + else if (strcasecmp(child->key, "Port") == 0) + cf_util_get_service(child, &conf_service); + else if (strcasecmp(child->key, "ReportSeconds") == 0) + cf_util_get_boolean(child, &conf_report_seconds); + else if (strcasecmp(child->key, "PersistentConnection") == 0) { + cf_util_get_boolean(child, &conf_persistent_conn); + persistent_conn_set = 1; + } else + ERROR("apcups plugin: Unknown config option \"%s\".", child->key); + } + + if (!persistent_conn_set) { + double interval = CDTIME_T_TO_DOUBLE(plugin_get_interval()); + if (interval > APCUPS_SERVER_TIMEOUT) { + NOTICE("apcups plugin: Plugin poll interval set to %.3f seconds. " + "Apcupsd NIS socket timeout is %.3f seconds, " + "PersistentConnection disabled by default.", + interval, APCUPS_SERVER_TIMEOUT); + conf_persistent_conn = 0; + } + } + + return (0); } /* int apcups_config */ -static void apc_submit_generic (const char *type, const char *type_inst, gauge_t value) -{ - if (isnan (value)) - return; +static void apc_submit_generic(const char *type, const char *type_inst, + gauge_t value) { + if (isnan(value)) + return; - value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "apcups", sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance)); + value_list_t vl = VALUE_LIST_INIT; + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "apcups", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, type_inst, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static void apc_submit (apc_detail_t const *apcups_detail) -{ - apc_submit_generic ("voltage", "input", apcups_detail->linev); - apc_submit_generic ("voltage", "output", apcups_detail->outputv); - apc_submit_generic ("voltage", "battery", apcups_detail->battv); - apc_submit_generic ("charge", "", apcups_detail->bcharge); - apc_submit_generic ("percent", "load", apcups_detail->loadpct); - apc_submit_generic ("timeleft", "", apcups_detail->timeleft); - apc_submit_generic ("temperature", "", apcups_detail->itemp); - apc_submit_generic ("frequency", "input", apcups_detail->linefreq); +static void apc_submit(apc_detail_t const *apcups_detail) { + apc_submit_generic("voltage", "input", apcups_detail->linev); + apc_submit_generic("voltage", "output", apcups_detail->outputv); + apc_submit_generic("voltage", "battery", apcups_detail->battv); + apc_submit_generic("charge", "", apcups_detail->bcharge); + apc_submit_generic("percent", "load", apcups_detail->loadpct); + apc_submit_generic("timeleft", "", apcups_detail->timeleft); + apc_submit_generic("temperature", "", apcups_detail->itemp); + apc_submit_generic("frequency", "input", apcups_detail->linefreq); } -static int apcups_read (void) -{ - apc_detail_t apcups_detail = { - .linev = NAN, - .outputv = NAN, - .battv = NAN, - .loadpct = NAN, - .bcharge = NAN, - .timeleft = NAN, - .itemp = NAN, - .linefreq = NAN, - }; - - int status = apc_query_server (conf_node == NULL - ? APCUPS_DEFAULT_NODE - : conf_node, - conf_service, &apcups_detail); - if (status != 0) - { - DEBUG ("apcups plugin: apc_query_server (\"%s\", \"%s\") = %d", - conf_node == NULL ? APCUPS_DEFAULT_NODE : conf_node, - conf_service, status); - return (status); - } - - apc_submit (&apcups_detail); - - return (0); +static int apcups_read(void) { + apc_detail_t apcups_detail = { + .linev = NAN, + .outputv = NAN, + .battv = NAN, + .loadpct = NAN, + .bcharge = NAN, + .timeleft = NAN, + .itemp = NAN, + .linefreq = NAN, + }; + + int status = + apc_query_server(conf_node == NULL ? APCUPS_DEFAULT_NODE : conf_node, + conf_service, &apcups_detail); + if (status != 0) { + DEBUG("apcups plugin: apc_query_server (\"%s\", \"%s\") = %d", + conf_node == NULL ? APCUPS_DEFAULT_NODE : conf_node, conf_service, + status); + return (status); + } + + apc_submit(&apcups_detail); + + return (0); } /* apcups_read */ -void module_register (void) -{ - plugin_register_complex_config ("apcups", apcups_config); - plugin_register_read ("apcups", apcups_read); - plugin_register_shutdown ("apcups", apcups_shutdown); +void module_register(void) { + plugin_register_complex_config("apcups", apcups_config); + plugin_register_read("apcups", apcups_read); + plugin_register_shutdown("apcups", apcups_shutdown); } /* void module_register */ diff --git a/src/apple_sensors.c b/src/apple_sensors.c index 17c822ff..2f8cccd8 100644 --- a/src/apple_sensors.c +++ b/src/apple_sensors.c @@ -30,206 +30,168 @@ #include "plugin.h" #if HAVE_CTYPE_H -# include +#include #endif #if HAVE_MACH_MACH_TYPES_H -# include +#include #endif #if HAVE_MACH_MACH_INIT_H -# include +#include #endif #if HAVE_MACH_MACH_ERROR_H -# include +#include #endif #if HAVE_MACH_MACH_PORT_H -# include +#include #endif #if HAVE_COREFOUNDATION_COREFOUNDATION_H -# include +#include #endif #if HAVE_IOKIT_IOKITLIB_H -# include +#include #endif #if HAVE_IOKIT_IOTYPES_H -# include +#include #endif static mach_port_t io_master_port = MACH_PORT_NULL; -static int as_init (void) -{ - kern_return_t status; - - if (io_master_port != MACH_PORT_NULL) - { - mach_port_deallocate (mach_task_self (), - io_master_port); - io_master_port = MACH_PORT_NULL; - } - - status = IOMasterPort (MACH_PORT_NULL, &io_master_port); - if (status != kIOReturnSuccess) - { - ERROR ("IOMasterPort failed: %s", - mach_error_string (status)); - io_master_port = MACH_PORT_NULL; - return (-1); - } - - return (0); +static int as_init(void) { + kern_return_t status; + + if (io_master_port != MACH_PORT_NULL) { + mach_port_deallocate(mach_task_self(), io_master_port); + io_master_port = MACH_PORT_NULL; + } + + status = IOMasterPort(MACH_PORT_NULL, &io_master_port); + if (status != kIOReturnSuccess) { + ERROR("IOMasterPort failed: %s", mach_error_string(status)); + io_master_port = MACH_PORT_NULL; + return (-1); + } + + return (0); } -static void as_submit (const char *type, const char *type_instance, - double val) -{ - value_list_t vl = VALUE_LIST_INIT; +static void as_submit(const char *type, const char *type_instance, double val) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = val }; - vl.values_len = 1; - sstrncpy (vl.plugin, "apple_sensors", sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + vl.values = &(value_t){.gauge = val}; + vl.values_len = 1; + sstrncpy(vl.plugin, "apple_sensors", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static int as_read (void) -{ - kern_return_t status; - io_iterator_t iterator; - io_object_t io_obj; - CFMutableDictionaryRef prop_dict; - CFTypeRef property; - - char type[128]; - char inst[128]; - int value_int; - double value_double; - if (!io_master_port || (io_master_port == MACH_PORT_NULL)) - return (-1); - - status = IOServiceGetMatchingServices (io_master_port, - IOServiceNameMatching("IOHWSensor"), - &iterator); - if (status != kIOReturnSuccess) - { - ERROR ("IOServiceGetMatchingServices failed: %s", - mach_error_string (status)); - return (-1); - } - - while ((io_obj = IOIteratorNext (iterator))) - { - prop_dict = NULL; - status = IORegistryEntryCreateCFProperties (io_obj, - &prop_dict, - kCFAllocatorDefault, - kNilOptions); - if (status != kIOReturnSuccess) - { - DEBUG ("IORegistryEntryCreateCFProperties failed: %s", - mach_error_string (status)); - continue; - } - - /* Copy the sensor type. */ - property = NULL; - if (!CFDictionaryGetValueIfPresent (prop_dict, - CFSTR ("type"), - &property)) - continue; - if (CFGetTypeID (property) != CFStringGetTypeID ()) - continue; - if (!CFStringGetCString (property, - type, sizeof (type), - kCFStringEncodingASCII)) - continue; - type[sizeof (type) - 1] = '\0'; - - /* Copy the sensor location. This will be used as `instance'. */ - property = NULL; - if (!CFDictionaryGetValueIfPresent (prop_dict, - CFSTR ("location"), - &property)) - continue; - if (CFGetTypeID (property) != CFStringGetTypeID ()) - continue; - if (!CFStringGetCString (property, - inst, sizeof (inst), - kCFStringEncodingASCII)) - continue; - inst[sizeof (inst) - 1] = '\0'; - for (int i = 0; i < 128; i++) - { - if (inst[i] == '\0') - break; - else if (isalnum (inst[i])) - inst[i] = (char) tolower (inst[i]); - else - inst[i] = '_'; - } - - /* Get the actual value. Some computation, based on the `type' - * is neccessary. */ - property = NULL; - if (!CFDictionaryGetValueIfPresent (prop_dict, - CFSTR ("current-value"), - &property)) - continue; - if (CFGetTypeID (property) != CFNumberGetTypeID ()) - continue; - if (!CFNumberGetValue (property, - kCFNumberIntType, - &value_int)) - continue; - - /* Found e.g. in the 1.5GHz PowerBooks */ - if (strcmp (type, "temperature") == 0) - { - value_double = ((double) value_int) / 65536.0; - sstrncpy (type, "temperature", sizeof (type)); - } - else if (strcmp (type, "temp") == 0) - { - value_double = ((double) value_int) / 10.0; - sstrncpy (type, "temperature", sizeof (type)); - } - else if (strcmp (type, "fanspeed") == 0) - { - value_double = ((double) value_int) / 65536.0; - sstrncpy (type, "fanspeed", sizeof (type)); - } - else if (strcmp (type, "voltage") == 0) - { - /* Leave this to the battery plugin. */ - continue; - } - else if (strcmp (type, "adc") == 0) - { - value_double = ((double) value_int) / 10.0; - sstrncpy (type, "fanspeed", sizeof (type)); - } - else - { - DEBUG ("apple_sensors: Read unknown sensor type: %s", - type); - value_double = (double) value_int; - } - - as_submit (type, inst, value_double); - - CFRelease (prop_dict); - IOObjectRelease (io_obj); - } /* while (iterator) */ - - IOObjectRelease (iterator); - - return (0); +static int as_read(void) { + kern_return_t status; + io_iterator_t iterator; + io_object_t io_obj; + CFMutableDictionaryRef prop_dict; + CFTypeRef property; + + char type[128]; + char inst[128]; + int value_int; + double value_double; + if (!io_master_port || (io_master_port == MACH_PORT_NULL)) + return (-1); + + status = IOServiceGetMatchingServices( + io_master_port, IOServiceNameMatching("IOHWSensor"), &iterator); + if (status != kIOReturnSuccess) { + ERROR("IOServiceGetMatchingServices failed: %s", mach_error_string(status)); + return (-1); + } + + while ((io_obj = IOIteratorNext(iterator))) { + prop_dict = NULL; + status = IORegistryEntryCreateCFProperties( + io_obj, &prop_dict, kCFAllocatorDefault, kNilOptions); + if (status != kIOReturnSuccess) { + DEBUG("IORegistryEntryCreateCFProperties failed: %s", + mach_error_string(status)); + continue; + } + + /* Copy the sensor type. */ + property = NULL; + if (!CFDictionaryGetValueIfPresent(prop_dict, CFSTR("type"), &property)) + continue; + if (CFGetTypeID(property) != CFStringGetTypeID()) + continue; + if (!CFStringGetCString(property, type, sizeof(type), + kCFStringEncodingASCII)) + continue; + type[sizeof(type) - 1] = '\0'; + + /* Copy the sensor location. This will be used as `instance'. */ + property = NULL; + if (!CFDictionaryGetValueIfPresent(prop_dict, CFSTR("location"), &property)) + continue; + if (CFGetTypeID(property) != CFStringGetTypeID()) + continue; + if (!CFStringGetCString(property, inst, sizeof(inst), + kCFStringEncodingASCII)) + continue; + inst[sizeof(inst) - 1] = '\0'; + for (int i = 0; i < 128; i++) { + if (inst[i] == '\0') + break; + else if (isalnum(inst[i])) + inst[i] = (char)tolower(inst[i]); + else + inst[i] = '_'; + } + + /* Get the actual value. Some computation, based on the `type' + * is neccessary. */ + property = NULL; + if (!CFDictionaryGetValueIfPresent(prop_dict, CFSTR("current-value"), + &property)) + continue; + if (CFGetTypeID(property) != CFNumberGetTypeID()) + continue; + if (!CFNumberGetValue(property, kCFNumberIntType, &value_int)) + continue; + + /* Found e.g. in the 1.5GHz PowerBooks */ + if (strcmp(type, "temperature") == 0) { + value_double = ((double)value_int) / 65536.0; + sstrncpy(type, "temperature", sizeof(type)); + } else if (strcmp(type, "temp") == 0) { + value_double = ((double)value_int) / 10.0; + sstrncpy(type, "temperature", sizeof(type)); + } else if (strcmp(type, "fanspeed") == 0) { + value_double = ((double)value_int) / 65536.0; + sstrncpy(type, "fanspeed", sizeof(type)); + } else if (strcmp(type, "voltage") == 0) { + /* Leave this to the battery plugin. */ + continue; + } else if (strcmp(type, "adc") == 0) { + value_double = ((double)value_int) / 10.0; + sstrncpy(type, "fanspeed", sizeof(type)); + } else { + DEBUG("apple_sensors: Read unknown sensor type: %s", type); + value_double = (double)value_int; + } + + as_submit(type, inst, value_double); + + CFRelease(prop_dict); + IOObjectRelease(io_obj); + } /* while (iterator) */ + + IOObjectRelease(iterator); + + return (0); } /* int as_read */ -void module_register (void) -{ - plugin_register_init ("apple_sensors", as_init); - plugin_register_read ("apple_sensors", as_read); +void module_register(void) { + plugin_register_init("apple_sensors", as_init); + plugin_register_read("apple_sensors", as_read); } /* void module_register */ diff --git a/src/aquaero.c b/src/aquaero.c index 8872409f..4a78f685 100644 --- a/src/aquaero.c +++ b/src/aquaero.c @@ -32,155 +32,134 @@ /* Default values for contacting daemon */ static char *conf_device = NULL; -static int aquaero_config (oconfig_item_t *ci) -{ - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("Device", child->key)) - cf_util_get_string (child, &conf_device); - else - { - ERROR ("aquaero plugin: Unknown config option \"%s\".", - child->key); - } - } - - return (0); +static int aquaero_config(oconfig_item_t *ci) { + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Device", child->key)) + cf_util_get_string(child, &conf_device); + else { + ERROR("aquaero plugin: Unknown config option \"%s\".", child->key); + } + } + + return (0); } -static int aquaero_shutdown (void) -{ - libaquaero5_exit(); - return (0); +static int aquaero_shutdown(void) { + libaquaero5_exit(); + return (0); } /* int aquaero_shutdown */ -static void aquaero_submit (const char *type, const char *type_instance, - double value) -{ - const char *instance = conf_device?conf_device:"default"; - value_list_t vl = VALUE_LIST_INIT; +static void aquaero_submit(const char *type, const char *type_instance, + double value) { + const char *instance = conf_device ? conf_device : "default"; + value_list_t vl = VALUE_LIST_INIT; - /* Don't report undefined values. */ - if (value == AQ5_FLOAT_UNDEF) - return; + /* Don't report undefined values. */ + if (value == AQ5_FLOAT_UNDEF) + return; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; - sstrncpy (vl.plugin, "aquaero", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, instance, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + sstrncpy(vl.plugin, "aquaero", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* int aquaero_submit */ /* aquaero_submit_array submits every value of a given array of values */ -static void aquaero_submit_array (const char *type, - const char *type_instance_prefix, double *value_array, int len) -{ - char type_instance[DATA_MAX_NAME_LEN]; - - for (int i = 0; i < len; i++) - { - if (value_array[i] == AQ5_FLOAT_UNDEF) - continue; - - snprintf (type_instance, sizeof (type_instance), "%s%d", - type_instance_prefix, i + 1); - aquaero_submit (type, type_instance, value_array[i]); - } +static void aquaero_submit_array(const char *type, + const char *type_instance_prefix, + double *value_array, int len) { + char type_instance[DATA_MAX_NAME_LEN]; + + for (int i = 0; i < len; i++) { + if (value_array[i] == AQ5_FLOAT_UNDEF) + continue; + + snprintf(type_instance, sizeof(type_instance), "%s%d", type_instance_prefix, + i + 1); + aquaero_submit(type, type_instance, value_array[i]); + } } -static int aquaero_read (void) -{ - aq5_data_t aq_data; - aq5_settings_t aq_sett; - char *err_msg = NULL; - char type_instance[DATA_MAX_NAME_LEN]; - - if (libaquaero5_poll(conf_device, &aq_data, &err_msg) < 0) - { - char errbuf[1024]; - ERROR ("aquaero plugin: Failed to poll device \"%s\": %s (%s)", - conf_device ? conf_device : "default", err_msg, - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - if (libaquaero5_getsettings(conf_device, &aq_sett, &err_msg) < 0) - { - char errbuf[1024]; - ERROR ("aquaero plugin: Failed to get settings " - "for device \"%s\": %s (%s)", - conf_device ? conf_device : "default", err_msg, - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - /* CPU Temperature sensor */ - aquaero_submit("temperature", "cpu", aq_data.cpu_temp[0]); - - /* Temperature sensors */ - aquaero_submit_array("temperature", "sensor", aq_data.temp, - AQ5_NUM_TEMP); - - /* Virtual temperature sensors */ - aquaero_submit_array("temperature", "virtual", aq_data.vtemp, - AQ5_NUM_VIRT_SENSORS); - - /* Software temperature sensors */ - aquaero_submit_array("temperature", "software", aq_data.stemp, - AQ5_NUM_SOFT_SENSORS); - - /* Other temperature sensors */ - aquaero_submit_array("temperature", "other", aq_data.otemp, - AQ5_NUM_OTHER_SENSORS); - - /* Fans */ - for (int i = 0; i < AQ5_NUM_FAN; i++) - { - if ((aq_sett.fan_data_source[i] == NONE) - || (aq_data.fan_vrm_temp[i] != AQ5_FLOAT_UNDEF)) - continue; - - snprintf (type_instance, sizeof (type_instance), - "fan%d", i + 1); - - aquaero_submit ("fanspeed", type_instance, - aq_data.fan_rpm[i]); - aquaero_submit ("percent", type_instance, - aq_data.fan_duty[i]); - aquaero_submit ("voltage", type_instance, - aq_data.fan_voltage[i]); - aquaero_submit ("current", type_instance, - aq_data.fan_current[i]); - - /* Report the voltage reglator module (VRM) temperature with a - * different type instance. */ - snprintf (type_instance, sizeof (type_instance), - "fan%d-vrm", i + 1); - aquaero_submit ("temperature", type_instance, - aq_data.fan_vrm_temp[i]); - } - - /* Flow sensors */ - aquaero_submit_array("flow", "sensor", aq_data.flow, AQ5_NUM_FLOW); - - /* Liquid level */ - aquaero_submit_array("percent", "waterlevel", - aq_data.level, AQ5_NUM_LEVEL); - - return (0); +static int aquaero_read(void) { + aq5_data_t aq_data; + aq5_settings_t aq_sett; + char *err_msg = NULL; + char type_instance[DATA_MAX_NAME_LEN]; + + if (libaquaero5_poll(conf_device, &aq_data, &err_msg) < 0) { + char errbuf[1024]; + ERROR("aquaero plugin: Failed to poll device \"%s\": %s (%s)", + conf_device ? conf_device : "default", err_msg, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + if (libaquaero5_getsettings(conf_device, &aq_sett, &err_msg) < 0) { + char errbuf[1024]; + ERROR("aquaero plugin: Failed to get settings " + "for device \"%s\": %s (%s)", + conf_device ? conf_device : "default", err_msg, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + /* CPU Temperature sensor */ + aquaero_submit("temperature", "cpu", aq_data.cpu_temp[0]); + + /* Temperature sensors */ + aquaero_submit_array("temperature", "sensor", aq_data.temp, AQ5_NUM_TEMP); + + /* Virtual temperature sensors */ + aquaero_submit_array("temperature", "virtual", aq_data.vtemp, + AQ5_NUM_VIRT_SENSORS); + + /* Software temperature sensors */ + aquaero_submit_array("temperature", "software", aq_data.stemp, + AQ5_NUM_SOFT_SENSORS); + + /* Other temperature sensors */ + aquaero_submit_array("temperature", "other", aq_data.otemp, + AQ5_NUM_OTHER_SENSORS); + + /* Fans */ + for (int i = 0; i < AQ5_NUM_FAN; i++) { + if ((aq_sett.fan_data_source[i] == NONE) || + (aq_data.fan_vrm_temp[i] != AQ5_FLOAT_UNDEF)) + continue; + + snprintf(type_instance, sizeof(type_instance), "fan%d", i + 1); + + aquaero_submit("fanspeed", type_instance, aq_data.fan_rpm[i]); + aquaero_submit("percent", type_instance, aq_data.fan_duty[i]); + aquaero_submit("voltage", type_instance, aq_data.fan_voltage[i]); + aquaero_submit("current", type_instance, aq_data.fan_current[i]); + + /* Report the voltage reglator module (VRM) temperature with a + * different type instance. */ + snprintf(type_instance, sizeof(type_instance), "fan%d-vrm", i + 1); + aquaero_submit("temperature", type_instance, aq_data.fan_vrm_temp[i]); + } + + /* Flow sensors */ + aquaero_submit_array("flow", "sensor", aq_data.flow, AQ5_NUM_FLOW); + + /* Liquid level */ + aquaero_submit_array("percent", "waterlevel", aq_data.level, AQ5_NUM_LEVEL); + + return (0); } -void module_register (void) -{ - plugin_register_complex_config ("aquaero", aquaero_config); - plugin_register_read ("aquaero", aquaero_read); - plugin_register_shutdown ("aquaero", aquaero_shutdown); +void module_register(void) { + plugin_register_complex_config("aquaero", aquaero_config); + plugin_register_read("aquaero", aquaero_read); + plugin_register_shutdown("aquaero", aquaero_shutdown); } /* void module_register */ /* vim: set sw=8 sts=8 noet : */ diff --git a/src/ascent.c b/src/ascent.c index b14be3c0..840fe8b8 100644 --- a/src/ascent.c +++ b/src/ascent.c @@ -33,48 +33,39 @@ #include static const char *races_list[] = /* {{{ */ -{ - NULL, - "Human", /* 1 */ - "Orc", /* 2 */ - "Dwarf", /* 3 */ - "Nightelf", /* 4 */ - "Undead", /* 5 */ - "Tauren", /* 6 */ - "Gnome", /* 7 */ - "Troll", /* 8 */ - NULL, - "Bloodelf", /* 10 */ - "Draenei" /* 11 */ -}; /* }}} */ -#define RACES_LIST_LENGTH STATIC_ARRAY_SIZE (races_list) + { + NULL, "Human", /* 1 */ + "Orc", /* 2 */ + "Dwarf", /* 3 */ + "Nightelf", /* 4 */ + "Undead", /* 5 */ + "Tauren", /* 6 */ + "Gnome", /* 7 */ + "Troll", /* 8 */ + NULL, "Bloodelf", /* 10 */ + "Draenei" /* 11 */ +}; /* }}} */ +#define RACES_LIST_LENGTH STATIC_ARRAY_SIZE(races_list) static const char *classes_list[] = /* {{{ */ -{ - NULL, - "Warrior", /* 1 */ - "Paladin", /* 2 */ - "Hunter", /* 3 */ - "Rogue", /* 4 */ - "Priest", /* 5 */ - NULL, - "Shaman", /* 7 */ - "Mage", /* 8 */ - "Warlock", /* 9 */ - NULL, - "Druid" /* 11 */ -}; /* }}} */ -#define CLASSES_LIST_LENGTH STATIC_ARRAY_SIZE (classes_list) + { + NULL, "Warrior", /* 1 */ + "Paladin", /* 2 */ + "Hunter", /* 3 */ + "Rogue", /* 4 */ + "Priest", /* 5 */ + NULL, "Shaman", /* 7 */ + "Mage", /* 8 */ + "Warlock", /* 9 */ + NULL, "Druid" /* 11 */ +}; /* }}} */ +#define CLASSES_LIST_LENGTH STATIC_ARRAY_SIZE(classes_list) static const char *genders_list[] = /* {{{ */ -{ - "Male", - "Female" -}; /* }}} */ -#define GENDERS_LIST_LENGTH STATIC_ARRAY_SIZE (genders_list) + {"Male", "Female"}; /* }}} */ +#define GENDERS_LIST_LENGTH STATIC_ARRAY_SIZE(genders_list) -struct player_stats_s -{ +struct player_stats_s { int races[RACES_LIST_LENGTH]; int classes[CLASSES_LIST_LENGTH]; int genders[GENDERS_LIST_LENGTH]; @@ -85,8 +76,7 @@ struct player_stats_s }; typedef struct player_stats_s player_stats_t; -struct player_info_s -{ +struct player_info_s { int race; int class; int gender; @@ -94,162 +84,144 @@ struct player_info_s int latency; }; typedef struct player_info_s player_info_t; -#define PLAYER_INFO_STATIC_INIT { -1, -1, -1, -1, -1 } +#define PLAYER_INFO_STATIC_INIT \ + { -1, -1, -1, -1, -1 } -static char *url = NULL; -static char *user = NULL; -static char *pass = NULL; +static char *url = NULL; +static char *user = NULL; +static char *pass = NULL; static char *verify_peer = NULL; static char *verify_host = NULL; -static char *cacert = NULL; -static char *timeout = NULL; +static char *cacert = NULL; +static char *timeout = NULL; static CURL *curl = NULL; -static char *ascent_buffer = NULL; +static char *ascent_buffer = NULL; static size_t ascent_buffer_size = 0; static size_t ascent_buffer_fill = 0; -static char ascent_curl_error[CURL_ERROR_SIZE]; +static char ascent_curl_error[CURL_ERROR_SIZE]; -static const char *config_keys[] = -{ - "URL", - "User", - "Password", - "VerifyPeer", - "VerifyHost", - "CACert", - "Timeout", +static const char *config_keys[] = { + "URL", "User", "Password", "VerifyPeer", "VerifyHost", "CACert", "Timeout", }; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); -static int ascent_submit_gauge (const char *plugin_instance, /* {{{ */ - const char *type, const char *type_instance, gauge_t value) -{ +static int ascent_submit_gauge(const char *plugin_instance, /* {{{ */ + const char *type, const char *type_instance, + gauge_t value) { value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; + vl.values = &(value_t){.gauge = value}; vl.values_len = 1; - sstrncpy (vl.plugin, "ascent", sizeof (vl.plugin)); + sstrncpy(vl.plugin, "ascent", sizeof(vl.plugin)); if (plugin_instance != NULL) - sstrncpy (vl.plugin_instance, plugin_instance, - sizeof (vl.plugin_instance)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); + sstrncpy(vl.type, type, sizeof(vl.type)); if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); return (0); } /* }}} int ascent_submit_gauge */ -static size_t ascent_curl_callback (void *buf, size_t size, size_t nmemb, /* {{{ */ - void __attribute__((unused)) *stream) -{ +static size_t ascent_curl_callback(void *buf, size_t size, + size_t nmemb, /* {{{ */ + void __attribute__((unused)) * stream) { size_t len = size * nmemb; if (len == 0) return (len); - if ((ascent_buffer_fill + len) >= ascent_buffer_size) - { + if ((ascent_buffer_fill + len) >= ascent_buffer_size) { char *temp; - temp = realloc (ascent_buffer, - ascent_buffer_fill + len + 1); - if (temp == NULL) - { - ERROR ("ascent plugin: realloc failed."); + temp = realloc(ascent_buffer, ascent_buffer_fill + len + 1); + if (temp == NULL) { + ERROR("ascent plugin: realloc failed."); return (0); } ascent_buffer = temp; ascent_buffer_size = ascent_buffer_fill + len + 1; } - memcpy (ascent_buffer + ascent_buffer_fill, (char *) buf, len); + memcpy(ascent_buffer + ascent_buffer_fill, (char *)buf, len); ascent_buffer_fill += len; ascent_buffer[ascent_buffer_fill] = 0; return (len); } /* }}} size_t ascent_curl_callback */ -static int ascent_submit_players (player_stats_t *ps) /* {{{ */ +static int ascent_submit_players(player_stats_t *ps) /* {{{ */ { gauge_t value; for (size_t i = 0; i < RACES_LIST_LENGTH; i++) if (races_list[i] != NULL) - ascent_submit_gauge ("by-race", "players", races_list[i], - (gauge_t) ps->races[i]); + ascent_submit_gauge("by-race", "players", races_list[i], + (gauge_t)ps->races[i]); for (size_t i = 0; i < CLASSES_LIST_LENGTH; i++) if (classes_list[i] != NULL) - ascent_submit_gauge ("by-class", "players", classes_list[i], - (gauge_t) ps->classes[i]); + ascent_submit_gauge("by-class", "players", classes_list[i], + (gauge_t)ps->classes[i]); for (size_t i = 0; i < GENDERS_LIST_LENGTH; i++) if (genders_list[i] != NULL) - ascent_submit_gauge ("by-gender", "players", genders_list[i], - (gauge_t) ps->genders[i]); + ascent_submit_gauge("by-gender", "players", genders_list[i], + (gauge_t)ps->genders[i]); if (ps->level_num <= 0) value = NAN; else - value = ((double) ps->level_sum) / ((double) ps->level_num); - ascent_submit_gauge (NULL, "gauge", "avg-level", value); + value = ((double)ps->level_sum) / ((double)ps->level_num); + ascent_submit_gauge(NULL, "gauge", "avg-level", value); /* Latency is in ms, but we store seconds. */ if (ps->latency_num <= 0) value = NAN; else - value = ((double) ps->latency_sum) / (1000.0 * ((double) ps->latency_num)); - ascent_submit_gauge (NULL, "latency", "average", value); + value = ((double)ps->latency_sum) / (1000.0 * ((double)ps->latency_num)); + ascent_submit_gauge(NULL, "latency", "average", value); return (0); } /* }}} int ascent_submit_players */ -static int ascent_account_player (player_stats_t *ps, /* {{{ */ - player_info_t *pi) -{ - if (pi->race >= 0) - { - if (((size_t) pi->race >= RACES_LIST_LENGTH) - || (races_list[pi->race] == NULL)) - ERROR ("ascent plugin: Ignoring invalid numeric race %i.", pi->race); +static int ascent_account_player(player_stats_t *ps, /* {{{ */ + player_info_t *pi) { + if (pi->race >= 0) { + if (((size_t)pi->race >= RACES_LIST_LENGTH) || + (races_list[pi->race] == NULL)) + ERROR("ascent plugin: Ignoring invalid numeric race %i.", pi->race); else ps->races[pi->race]++; } - if (pi->class >= 0) - { - if (((size_t) pi->class >= CLASSES_LIST_LENGTH) - || (classes_list[pi->class] == NULL)) - ERROR ("ascent plugin: Ignoring invalid numeric class %i.", pi->class); + if (pi->class >= 0) { + if (((size_t)pi->class >= CLASSES_LIST_LENGTH) || + (classes_list[pi->class] == NULL)) + ERROR("ascent plugin: Ignoring invalid numeric class %i.", pi->class); else ps->classes[pi->class]++; } - if (pi->gender >= 0) - { - if (((size_t) pi->gender >= GENDERS_LIST_LENGTH) - || (genders_list[pi->gender] == NULL)) - ERROR ("ascent plugin: Ignoring invalid numeric gender %i.", - pi->gender); + if (pi->gender >= 0) { + if (((size_t)pi->gender >= GENDERS_LIST_LENGTH) || + (genders_list[pi->gender] == NULL)) + ERROR("ascent plugin: Ignoring invalid numeric gender %i.", pi->gender); else ps->genders[pi->gender]++; } - - if (pi->level > 0) - { + if (pi->level > 0) { ps->level_sum += pi->level; ps->level_num++; } - if (pi->latency >= 0) - { + if (pi->latency >= 0) { ps->latency_sum += pi->latency; ps->latency_num++; } @@ -257,60 +229,55 @@ static int ascent_account_player (player_stats_t *ps, /* {{{ */ return (0); } /* }}} int ascent_account_player */ -static int ascent_xml_submit_gauge (xmlDoc *doc, xmlNode *node, /* {{{ */ - const char *plugin_instance, const char *type, const char *type_instance) -{ +static int ascent_xml_submit_gauge(xmlDoc *doc, xmlNode *node, /* {{{ */ + const char *plugin_instance, + const char *type, + const char *type_instance) { char *str_ptr; gauge_t value; - str_ptr = (char *) xmlNodeListGetString (doc, node->xmlChildrenNode, 1); - if (str_ptr == NULL) - { - ERROR ("ascent plugin: ascent_xml_submit_gauge: xmlNodeListGetString failed."); + str_ptr = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); + if (str_ptr == NULL) { + ERROR( + "ascent plugin: ascent_xml_submit_gauge: xmlNodeListGetString failed."); return (-1); } - if (strcasecmp ("N/A", str_ptr) == 0) + if (strcasecmp("N/A", str_ptr) == 0) value = NAN; - else - { + else { char *end_ptr = NULL; - value = strtod (str_ptr, &end_ptr); - if (str_ptr == end_ptr) - { + value = strtod(str_ptr, &end_ptr); + if (str_ptr == end_ptr) { xmlFree(str_ptr); - ERROR ("ascent plugin: ascent_xml_submit_gauge: strtod failed."); + ERROR("ascent plugin: ascent_xml_submit_gauge: strtod failed."); return (-1); } } xmlFree(str_ptr); - return (ascent_submit_gauge (plugin_instance, type, type_instance, value)); + return (ascent_submit_gauge(plugin_instance, type, type_instance, value)); } /* }}} int ascent_xml_submit_gauge */ -static int ascent_xml_read_int (xmlDoc *doc, xmlNode *node, /* {{{ */ - int *ret_value) -{ +static int ascent_xml_read_int(xmlDoc *doc, xmlNode *node, /* {{{ */ + int *ret_value) { char *str_ptr; int value; - str_ptr = (char *) xmlNodeListGetString (doc, node->xmlChildrenNode, 1); - if (str_ptr == NULL) - { - ERROR ("ascent plugin: ascent_xml_read_int: xmlNodeListGetString failed."); + str_ptr = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); + if (str_ptr == NULL) { + ERROR("ascent plugin: ascent_xml_read_int: xmlNodeListGetString failed."); return (-1); } - if (strcasecmp ("N/A", str_ptr) == 0) + if (strcasecmp("N/A", str_ptr) == 0) value = -1; - else - { + else { char *end_ptr = NULL; - value = strtol (str_ptr, &end_ptr, 0); - if (str_ptr == end_ptr) - { + value = strtol(str_ptr, &end_ptr, 0); + if (str_ptr == end_ptr) { xmlFree(str_ptr); - ERROR ("ascent plugin: ascent_xml_read_int: strtol failed."); + ERROR("ascent plugin: ascent_xml_read_int: strtol failed."); return (-1); } } @@ -320,111 +287,103 @@ static int ascent_xml_read_int (xmlDoc *doc, xmlNode *node, /* {{{ */ return (0); } /* }}} int ascent_xml_read_int */ -static int ascent_xml_sessions_plr (xmlDoc *doc, xmlNode *node, /* {{{ */ - player_info_t *pi) -{ - for (xmlNode *child = node->xmlChildrenNode; child != NULL; child = child->next) - { - if ((xmlStrcmp ((const xmlChar *) "comment", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "text", child->name) == 0)) +static int ascent_xml_sessions_plr(xmlDoc *doc, xmlNode *node, /* {{{ */ + player_info_t *pi) { + for (xmlNode *child = node->xmlChildrenNode; child != NULL; + child = child->next) { + if ((xmlStrcmp((const xmlChar *)"comment", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"text", child->name) == 0)) /* ignore */; - else if (xmlStrcmp ((const xmlChar *) "race", child->name) == 0) - ascent_xml_read_int (doc, child, &pi->race); - else if (xmlStrcmp ((const xmlChar *) "class", child->name) == 0) - ascent_xml_read_int (doc, child, &pi->class); - else if (xmlStrcmp ((const xmlChar *) "gender", child->name) == 0) - ascent_xml_read_int (doc, child, &pi->gender); - else if (xmlStrcmp ((const xmlChar *) "level", child->name) == 0) - ascent_xml_read_int (doc, child, &pi->level); - else if (xmlStrcmp ((const xmlChar *) "latency", child->name) == 0) - ascent_xml_read_int (doc, child, &pi->latency); - else if ((xmlStrcmp ((const xmlChar *) "name", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "pvprank", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "map", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "areaid", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "xpos", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "ypos", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "onime", child->name) == 0)) + else if (xmlStrcmp((const xmlChar *)"race", child->name) == 0) + ascent_xml_read_int(doc, child, &pi->race); + else if (xmlStrcmp((const xmlChar *)"class", child->name) == 0) + ascent_xml_read_int(doc, child, &pi->class); + else if (xmlStrcmp((const xmlChar *)"gender", child->name) == 0) + ascent_xml_read_int(doc, child, &pi->gender); + else if (xmlStrcmp((const xmlChar *)"level", child->name) == 0) + ascent_xml_read_int(doc, child, &pi->level); + else if (xmlStrcmp((const xmlChar *)"latency", child->name) == 0) + ascent_xml_read_int(doc, child, &pi->latency); + else if ((xmlStrcmp((const xmlChar *)"name", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"pvprank", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"map", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"areaid", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"xpos", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"ypos", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"onime", child->name) == 0)) /* ignore */; - else - { - WARNING ("ascent plugin: ascent_xml_status: Unknown tag: %s", child->name); + else { + WARNING("ascent plugin: ascent_xml_status: Unknown tag: %s", child->name); } } /* for (child) */ return (0); } /* }}} int ascent_xml_sessions_plr */ -static int ascent_xml_sessions (xmlDoc *doc, xmlNode *node) /* {{{ */ +static int ascent_xml_sessions(xmlDoc *doc, xmlNode *node) /* {{{ */ { - player_stats_t ps = { - .level_sum = 0 - }; - - for (xmlNode *child = node->xmlChildrenNode; child != NULL; child = child->next) - { - if ((xmlStrcmp ((const xmlChar *) "comment", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "text", child->name) == 0)) + player_stats_t ps = {.level_sum = 0}; + + for (xmlNode *child = node->xmlChildrenNode; child != NULL; + child = child->next) { + if ((xmlStrcmp((const xmlChar *)"comment", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"text", child->name) == 0)) /* ignore */; - else if (xmlStrcmp ((const xmlChar *) "plr", child->name) == 0) - { + else if (xmlStrcmp((const xmlChar *)"plr", child->name) == 0) { int status; player_info_t pi = PLAYER_INFO_STATIC_INIT; - status = ascent_xml_sessions_plr (doc, child, &pi); + status = ascent_xml_sessions_plr(doc, child, &pi); if (status == 0) - ascent_account_player (&ps, &pi); - } - else - { - WARNING ("ascent plugin: ascent_xml_status: Unknown tag: %s", child->name); + ascent_account_player(&ps, &pi); + } else { + WARNING("ascent plugin: ascent_xml_status: Unknown tag: %s", child->name); } } /* for (child) */ - ascent_submit_players (&ps); + ascent_submit_players(&ps); return (0); } /* }}} int ascent_xml_sessions */ -static int ascent_xml_status (xmlDoc *doc, xmlNode *node) /* {{{ */ +static int ascent_xml_status(xmlDoc *doc, xmlNode *node) /* {{{ */ { - for (xmlNode *child = node->xmlChildrenNode; child != NULL; child = child->next) - { - if ((xmlStrcmp ((const xmlChar *) "comment", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "text", child->name) == 0)) + for (xmlNode *child = node->xmlChildrenNode; child != NULL; + child = child->next) { + if ((xmlStrcmp((const xmlChar *)"comment", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"text", child->name) == 0)) /* ignore */; - else if (xmlStrcmp ((const xmlChar *) "alliance", child->name) == 0) - ascent_xml_submit_gauge (doc, child, NULL, "players", "alliance"); - else if (xmlStrcmp ((const xmlChar *) "horde", child->name) == 0) - ascent_xml_submit_gauge (doc, child, NULL, "players", "horde"); - else if (xmlStrcmp ((const xmlChar *) "qplayers", child->name) == 0) - ascent_xml_submit_gauge (doc, child, NULL, "players", "queued"); - else if ((xmlStrcmp ((const xmlChar *) "acceptedconns", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "avglat", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "cdbquerysize", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "cpu", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "fthreads", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "gmcount", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "lastupdate", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "ontime", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "oplayers", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "peakcount", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "platform", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "ram", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "threads", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "uptime", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "wdbquerysize", child->name) == 0)) + else if (xmlStrcmp((const xmlChar *)"alliance", child->name) == 0) + ascent_xml_submit_gauge(doc, child, NULL, "players", "alliance"); + else if (xmlStrcmp((const xmlChar *)"horde", child->name) == 0) + ascent_xml_submit_gauge(doc, child, NULL, "players", "horde"); + else if (xmlStrcmp((const xmlChar *)"qplayers", child->name) == 0) + ascent_xml_submit_gauge(doc, child, NULL, "players", "queued"); + else if ((xmlStrcmp((const xmlChar *)"acceptedconns", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"avglat", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"cdbquerysize", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"cpu", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"fthreads", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"gmcount", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"lastupdate", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"ontime", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"oplayers", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"peakcount", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"platform", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"ram", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"threads", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"uptime", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"wdbquerysize", child->name) == 0)) /* ignore */; - else - { - WARNING ("ascent plugin: ascent_xml_status: Unknown tag: %s", child->name); + else { + WARNING("ascent plugin: ascent_xml_status: Unknown tag: %s", child->name); } } /* for (child) */ return (0); } /* }}} int ascent_xml_status */ -static int ascent_xml (const char *data) /* {{{ */ +static int ascent_xml(const char *data) /* {{{ */ { xmlDoc *doc; xmlNode *cur; @@ -435,196 +394,182 @@ static int ascent_xml (const char *data) /* {{{ */ /* encoding = */ NULL, /* options = */ 0); #else - doc = xmlParseMemory (data, strlen (data)); + doc = xmlParseMemory(data, strlen(data)); #endif - if (doc == NULL) - { - ERROR ("ascent plugin: xmlParseMemory failed."); + if (doc == NULL) { + ERROR("ascent plugin: xmlParseMemory failed."); return (-1); } - cur = xmlDocGetRootElement (doc); - if (cur == NULL) - { - ERROR ("ascent plugin: XML document is empty."); - xmlFreeDoc (doc); + cur = xmlDocGetRootElement(doc); + if (cur == NULL) { + ERROR("ascent plugin: XML document is empty."); + xmlFreeDoc(doc); return (-1); } - if (xmlStrcmp ((const xmlChar *) "serverpage", cur->name) != 0) - { - ERROR ("ascent plugin: XML root element is not \"serverpage\"."); - xmlFreeDoc (doc); + if (xmlStrcmp((const xmlChar *)"serverpage", cur->name) != 0) { + ERROR("ascent plugin: XML root element is not \"serverpage\"."); + xmlFreeDoc(doc); return (-1); } - for (xmlNode *child = cur->xmlChildrenNode; child != NULL; child = child->next) - { - if ((xmlStrcmp ((const xmlChar *) "comment", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "text", child->name) == 0)) + for (xmlNode *child = cur->xmlChildrenNode; child != NULL; + child = child->next) { + if ((xmlStrcmp((const xmlChar *)"comment", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"text", child->name) == 0)) /* ignore */; - else if (xmlStrcmp ((const xmlChar *) "status", child->name) == 0) - ascent_xml_status (doc, child); - else if (xmlStrcmp ((const xmlChar *) "instances", child->name) == 0) + else if (xmlStrcmp((const xmlChar *)"status", child->name) == 0) + ascent_xml_status(doc, child); + else if (xmlStrcmp((const xmlChar *)"instances", child->name) == 0) /* ignore for now */; - else if (xmlStrcmp ((const xmlChar *) "gms", child->name) == 0) + else if (xmlStrcmp((const xmlChar *)"gms", child->name) == 0) /* ignore for now */; - else if (xmlStrcmp ((const xmlChar *) "sessions", child->name) == 0) - ascent_xml_sessions (doc, child); - else - { - WARNING ("ascent plugin: ascent_xml: Unknown tag: %s", child->name); + else if (xmlStrcmp((const xmlChar *)"sessions", child->name) == 0) + ascent_xml_sessions(doc, child); + else { + WARNING("ascent plugin: ascent_xml: Unknown tag: %s", child->name); } } /* for (child) */ - xmlFreeDoc (doc); + xmlFreeDoc(doc); return (0); } /* }}} int ascent_xml */ -static int config_set (char **var, const char *value) /* {{{ */ +static int config_set(char **var, const char *value) /* {{{ */ { - if (*var != NULL) - { - free (*var); + if (*var != NULL) { + free(*var); *var = NULL; } - if ((*var = strdup (value)) == NULL) + if ((*var = strdup(value)) == NULL) return (1); else return (0); } /* }}} int config_set */ -static int ascent_config (const char *key, const char *value) /* {{{ */ +static int ascent_config(const char *key, const char *value) /* {{{ */ { - if (strcasecmp (key, "URL") == 0) - return (config_set (&url, value)); - else if (strcasecmp (key, "User") == 0) - return (config_set (&user, value)); - else if (strcasecmp (key, "Password") == 0) - return (config_set (&pass, value)); - else if (strcasecmp (key, "VerifyPeer") == 0) - return (config_set (&verify_peer, value)); - else if (strcasecmp (key, "VerifyHost") == 0) - return (config_set (&verify_host, value)); - else if (strcasecmp (key, "CACert") == 0) - return (config_set (&cacert, value)); - else if (strcasecmp (key, "Timeout") == 0) - return (config_set (&timeout, value)); + if (strcasecmp(key, "URL") == 0) + return (config_set(&url, value)); + else if (strcasecmp(key, "User") == 0) + return (config_set(&user, value)); + else if (strcasecmp(key, "Password") == 0) + return (config_set(&pass, value)); + else if (strcasecmp(key, "VerifyPeer") == 0) + return (config_set(&verify_peer, value)); + else if (strcasecmp(key, "VerifyHost") == 0) + return (config_set(&verify_host, value)); + else if (strcasecmp(key, "CACert") == 0) + return (config_set(&cacert, value)); + else if (strcasecmp(key, "Timeout") == 0) + return (config_set(&timeout, value)); else return (-1); } /* }}} int ascent_config */ -static int ascent_init (void) /* {{{ */ +static int ascent_init(void) /* {{{ */ { - if (url == NULL) - { - WARNING ("ascent plugin: ascent_init: No URL configured, " - "returning an error."); + if (url == NULL) { + WARNING("ascent plugin: ascent_init: No URL configured, " + "returning an error."); return (-1); } - if (curl != NULL) - { - curl_easy_cleanup (curl); + if (curl != NULL) { + curl_easy_cleanup(curl); } - if ((curl = curl_easy_init ()) == NULL) - { - ERROR ("ascent plugin: ascent_init: curl_easy_init failed."); + if ((curl = curl_easy_init()) == NULL) { + ERROR("ascent plugin: ascent_init: curl_easy_init failed."); return (-1); } - curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, ascent_curl_callback); - curl_easy_setopt (curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); - curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, ascent_curl_error); + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ascent_curl_callback); + curl_easy_setopt(curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, ascent_curl_error); - if (user != NULL) - { + if (user != NULL) { #ifdef HAVE_CURLOPT_USERNAME - curl_easy_setopt (curl, CURLOPT_USERNAME, user); - curl_easy_setopt (curl, CURLOPT_PASSWORD, (pass == NULL) ? "" : pass); + curl_easy_setopt(curl, CURLOPT_USERNAME, user); + curl_easy_setopt(curl, CURLOPT_PASSWORD, (pass == NULL) ? "" : pass); #else static char credentials[1024]; int status; - status = ssnprintf (credentials, sizeof (credentials), "%s:%s", - user, (pass == NULL) ? "" : pass); - if ((status < 0) || ((size_t) status >= sizeof (credentials))) - { - ERROR ("ascent plugin: ascent_init: Returning an error because the " - "credentials have been truncated."); + status = ssnprintf(credentials, sizeof(credentials), "%s:%s", user, + (pass == NULL) ? "" : pass); + if ((status < 0) || ((size_t)status >= sizeof(credentials))) { + ERROR("ascent plugin: ascent_init: Returning an error because the " + "credentials have been truncated."); return (-1); } - curl_easy_setopt (curl, CURLOPT_USERPWD, credentials); + curl_easy_setopt(curl, CURLOPT_USERPWD, credentials); #endif } - curl_easy_setopt (curl, CURLOPT_URL, url); - curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt (curl, CURLOPT_MAXREDIRS, 50L); + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L); - if ((verify_peer == NULL) || IS_TRUE (verify_peer)) - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 1L); + if ((verify_peer == NULL) || IS_TRUE(verify_peer)) + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); else - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); - if ((verify_host == NULL) || IS_TRUE (verify_host)) - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 2L); + if ((verify_host == NULL) || IS_TRUE(verify_host)) + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L); else - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); if (cacert != NULL) - curl_easy_setopt (curl, CURLOPT_CAINFO, cacert); + curl_easy_setopt(curl, CURLOPT_CAINFO, cacert); #ifdef HAVE_CURLOPT_TIMEOUT_MS if (timeout != NULL) - curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS, atol(timeout)); + curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, atol(timeout)); else - curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval())); + curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, + (long)CDTIME_T_TO_MS(plugin_get_interval())); #endif return (0); } /* }}} int ascent_init */ -static int ascent_read (void) /* {{{ */ +static int ascent_read(void) /* {{{ */ { int status; - if (curl == NULL) - { - ERROR ("ascent plugin: I don't have a CURL object."); + if (curl == NULL) { + ERROR("ascent plugin: I don't have a CURL object."); return (-1); } - if (url == NULL) - { - ERROR ("ascent plugin: No URL has been configured."); + if (url == NULL) { + ERROR("ascent plugin: No URL has been configured."); return (-1); } ascent_buffer_fill = 0; - if (curl_easy_perform (curl) != CURLE_OK) - { - ERROR ("ascent plugin: curl_easy_perform failed: %s", - ascent_curl_error); + if (curl_easy_perform(curl) != CURLE_OK) { + ERROR("ascent plugin: curl_easy_perform failed: %s", ascent_curl_error); return (-1); } - status = ascent_xml (ascent_buffer); + status = ascent_xml(ascent_buffer); if (status != 0) return (-1); else return (0); } /* }}} int ascent_read */ -void module_register (void) -{ - plugin_register_config ("ascent", ascent_config, config_keys, config_keys_num); - plugin_register_init ("ascent", ascent_init); - plugin_register_read ("ascent", ascent_read); +void module_register(void) { + plugin_register_config("ascent", ascent_config, config_keys, config_keys_num); + plugin_register_init("ascent", ascent_init); + plugin_register_read("ascent", ascent_read); } /* void module_register */ /* vim: set sw=2 sts=2 ts=8 et fdm=marker : */ diff --git a/src/barometer.c b/src/barometer.c index 53c55b84..b3f1b7f6 100644 --- a/src/barometer.c +++ b/src/barometer.c @@ -22,187 +22,184 @@ #include "collectd.h" #include "common.h" -#include "utils_cache.h" #include "plugin.h" +#include "utils_cache.h" -#include #include -#include #include #include +#include #include +#include /* ------------ MPL115 defines ------------ */ /* I2C address of the MPL115 sensor */ -#define MPL115_I2C_ADDRESS 0x60 +#define MPL115_I2C_ADDRESS 0x60 /* register addresses */ -#define MPL115_ADDR_CONV 0x00 -#define MPL115_ADDR_COEFFS 0x04 +#define MPL115_ADDR_CONV 0x00 +#define MPL115_ADDR_COEFFS 0x04 /* register sizes */ -#define MPL115_NUM_CONV 4 -#define MPL115_NUM_COEFFS 12 +#define MPL115_NUM_CONV 4 +#define MPL115_NUM_COEFFS 12 /* commands / addresses */ -#define MPL115_CMD_CONVERT_PRESS 0x10 -#define MPL115_CMD_CONVERT_TEMP 0x11 -#define MPL115_CMD_CONVERT_BOTH 0x12 - -#define MPL115_CONVERSION_RETRIES 5 +#define MPL115_CMD_CONVERT_PRESS 0x10 +#define MPL115_CMD_CONVERT_TEMP 0x11 +#define MPL115_CMD_CONVERT_BOTH 0x12 +#define MPL115_CONVERSION_RETRIES 5 /* ------------ MPL3115 defines ------------ */ /* MPL3115 I2C address */ -#define MPL3115_I2C_ADDRESS 0x60 +#define MPL3115_I2C_ADDRESS 0x60 /* register addresses (only the interesting ones) */ -#define MPL3115_REG_STATUS 0x00 -#define MPL3115_REG_OUT_P_MSB 0x01 -#define MPL3115_REG_OUT_P_CSB 0x02 -#define MPL3115_REG_OUT_P_LSB 0x03 -#define MPL3115_REG_OUT_T_MSB 0x04 -#define MPL3115_REG_OUT_T_LSB 0x05 -#define MPL3115_REG_DR_STATUS 0x06 -#define MPL3115_REG_WHO_AM_I 0x0C -#define MPL3115_REG_SYSMOD 0x11 -#define MPL3115_REG_PT_DATA_CFG 0x13 -#define MPL3115_REG_BAR_IN_MSB 0x14 -#define MPL3115_REG_BAR_IN_LSB 0x15 -#define MPL3115_REG_CTRL_REG1 0x26 -#define MPL3115_REG_CTRL_REG2 0x27 -#define MPL3115_REG_CTRL_REG3 0x28 -#define MPL3115_REG_CTRL_REG4 0x29 -#define MPL3115_REG_CTRL_REG5 0x2A -#define MPL3115_REG_OFF_P 0x2B -#define MPL3115_REG_OFF_T 0x2C -#define MPL3115_REG_OFF_H 0x2D +#define MPL3115_REG_STATUS 0x00 +#define MPL3115_REG_OUT_P_MSB 0x01 +#define MPL3115_REG_OUT_P_CSB 0x02 +#define MPL3115_REG_OUT_P_LSB 0x03 +#define MPL3115_REG_OUT_T_MSB 0x04 +#define MPL3115_REG_OUT_T_LSB 0x05 +#define MPL3115_REG_DR_STATUS 0x06 +#define MPL3115_REG_WHO_AM_I 0x0C +#define MPL3115_REG_SYSMOD 0x11 +#define MPL3115_REG_PT_DATA_CFG 0x13 +#define MPL3115_REG_BAR_IN_MSB 0x14 +#define MPL3115_REG_BAR_IN_LSB 0x15 +#define MPL3115_REG_CTRL_REG1 0x26 +#define MPL3115_REG_CTRL_REG2 0x27 +#define MPL3115_REG_CTRL_REG3 0x28 +#define MPL3115_REG_CTRL_REG4 0x29 +#define MPL3115_REG_CTRL_REG5 0x2A +#define MPL3115_REG_OFF_P 0x2B +#define MPL3115_REG_OFF_T 0x2C +#define MPL3115_REG_OFF_H 0x2D /* Register values, masks */ -#define MPL3115_WHO_AM_I_RESP 0xC4 - -#define MPL3115_PT_DATA_DREM 0x04 -#define MPL3115_PT_DATA_PDEF 0x02 -#define MPL3115_PT_DATA_TDEF 0x01 - -#define MPL3115_DR_STATUS_TDR 0x02 -#define MPL3115_DR_STATUS_PDR 0x04 -#define MPL3115_DR_STATUS_PTDR 0x08 -#define MPL3115_DR_STATUS_DR (MPL3115_DR_STATUS_TDR | MPL3115_DR_STATUS_PDR | MPL3115_DR_STATUS_PTDR) - -#define MPL3115_DR_STATUS_TOW 0x20 -#define MPL3115_DR_STATUS_POW 0x40 -#define MPL3115_DR_STATUS_PTOW 0x80 - -#define MPL3115_CTRL_REG1_ALT 0x80 -#define MPL3115_CTRL_REG1_RAW 0x40 -#define MPL3115_CTRL_REG1_OST_MASK 0x38 -#define MPL3115_CTRL_REG1_OST_1 0x00 -#define MPL3115_CTRL_REG1_OST_2 0x08 -#define MPL3115_CTRL_REG1_OST_4 0x10 -#define MPL3115_CTRL_REG1_OST_8 0x18 -#define MPL3115_CTRL_REG1_OST_16 0x20 -#define MPL3115_CTRL_REG1_OST_32 0x28 -#define MPL3115_CTRL_REG1_OST_64 0x30 -#define MPL3115_CTRL_REG1_OST_128 0x38 -#define MPL3115_CTRL_REG1_RST 0x04 -#define MPL3115_CTRL_REG1_OST 0x02 -#define MPL3115_CTRL_REG1_SBYB 0x01 +#define MPL3115_WHO_AM_I_RESP 0xC4 + +#define MPL3115_PT_DATA_DREM 0x04 +#define MPL3115_PT_DATA_PDEF 0x02 +#define MPL3115_PT_DATA_TDEF 0x01 + +#define MPL3115_DR_STATUS_TDR 0x02 +#define MPL3115_DR_STATUS_PDR 0x04 +#define MPL3115_DR_STATUS_PTDR 0x08 +#define MPL3115_DR_STATUS_DR \ + (MPL3115_DR_STATUS_TDR | MPL3115_DR_STATUS_PDR | MPL3115_DR_STATUS_PTDR) + +#define MPL3115_DR_STATUS_TOW 0x20 +#define MPL3115_DR_STATUS_POW 0x40 +#define MPL3115_DR_STATUS_PTOW 0x80 + +#define MPL3115_CTRL_REG1_ALT 0x80 +#define MPL3115_CTRL_REG1_RAW 0x40 +#define MPL3115_CTRL_REG1_OST_MASK 0x38 +#define MPL3115_CTRL_REG1_OST_1 0x00 +#define MPL3115_CTRL_REG1_OST_2 0x08 +#define MPL3115_CTRL_REG1_OST_4 0x10 +#define MPL3115_CTRL_REG1_OST_8 0x18 +#define MPL3115_CTRL_REG1_OST_16 0x20 +#define MPL3115_CTRL_REG1_OST_32 0x28 +#define MPL3115_CTRL_REG1_OST_64 0x30 +#define MPL3115_CTRL_REG1_OST_128 0x38 +#define MPL3115_CTRL_REG1_RST 0x04 +#define MPL3115_CTRL_REG1_OST 0x02 +#define MPL3115_CTRL_REG1_SBYB 0x01 #define MPL3115_CTRL_REG1_SBYB_MASK 0xFE -#define MPL3115_NUM_CONV_VALS 5 - +#define MPL3115_NUM_CONV_VALS 5 /* ------------ BMP085 defines ------------ */ /* I2C address of the BMP085 sensor */ -#define BMP085_I2C_ADDRESS 0x77 +#define BMP085_I2C_ADDRESS 0x77 /* register addresses */ -#define BMP085_ADDR_ID_REG 0xD0 -#define BMP085_ADDR_VERSION 0xD1 +#define BMP085_ADDR_ID_REG 0xD0 +#define BMP085_ADDR_VERSION 0xD1 -#define BMP085_ADDR_CONV 0xF6 +#define BMP085_ADDR_CONV 0xF6 -#define BMP085_ADDR_CTRL_REG 0xF4 -#define BMP085_ADDR_COEFFS 0xAA +#define BMP085_ADDR_CTRL_REG 0xF4 +#define BMP085_ADDR_COEFFS 0xAA /* register sizes */ -#define BMP085_NUM_COEFFS 22 +#define BMP085_NUM_COEFFS 22 /* commands, values */ -#define BMP085_CHIP_ID 0x55 +#define BMP085_CHIP_ID 0x55 -#define BMP085_CMD_CONVERT_TEMP 0x2E +#define BMP085_CMD_CONVERT_TEMP 0x2E -#define BMP085_CMD_CONVERT_PRESS_0 0x34 -#define BMP085_CMD_CONVERT_PRESS_1 0x74 -#define BMP085_CMD_CONVERT_PRESS_2 0xB4 -#define BMP085_CMD_CONVERT_PRESS_3 0xF4 +#define BMP085_CMD_CONVERT_PRESS_0 0x34 +#define BMP085_CMD_CONVERT_PRESS_1 0x74 +#define BMP085_CMD_CONVERT_PRESS_2 0xB4 +#define BMP085_CMD_CONVERT_PRESS_3 0xF4 /* in us */ -#define BMP085_TIME_CNV_TEMP 4500 - -#define BMP085_TIME_CNV_PRESS_0 4500 -#define BMP085_TIME_CNV_PRESS_1 7500 -#define BMP085_TIME_CNV_PRESS_2 13500 -#define BMP085_TIME_CNV_PRESS_3 25500 +#define BMP085_TIME_CNV_TEMP 4500 +#define BMP085_TIME_CNV_PRESS_0 4500 +#define BMP085_TIME_CNV_PRESS_1 7500 +#define BMP085_TIME_CNV_PRESS_2 13500 +#define BMP085_TIME_CNV_PRESS_3 25500 /* ------------ Normalization ------------ */ /* Mean sea level pressure normalization methods */ -#define MSLP_NONE 0 +#define MSLP_NONE 0 #define MSLP_INTERNATIONAL 1 -#define MSLP_DEU_WETT 2 - -/** Temperature reference history depth for averaging. See #get_reference_temperature */ -#define REF_TEMP_AVG_NUM 5 +#define MSLP_DEU_WETT 2 +/** Temperature reference history depth for averaging. See + * #get_reference_temperature */ +#define REF_TEMP_AVG_NUM 5 /* ------------------------------------------ */ /** Supported sensor types */ enum Sensor_type { - Sensor_none = 0, - Sensor_MPL115, - Sensor_MPL3115, - Sensor_BMP085 + Sensor_none = 0, + Sensor_MPL115, + Sensor_MPL3115, + Sensor_BMP085 }; -static const char *config_keys[] = -{ +static const char *config_keys[] = { "Device", "Oversampling", "PressureOffset", /**< only for MPL3115 */ "TemperatureOffset", /**< only for MPL3115 */ "Altitude", "Normalization", - "TemperatureSensor" -}; + "TemperatureSensor"}; -static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); -static char * config_device = NULL; /**< I2C bus device */ -static int config_oversample = 1; /**< averaging window */ +static char *config_device = NULL; /**< I2C bus device */ +static int config_oversample = 1; /**< averaging window */ -static double config_press_offset = 0.0; /**< pressure offset */ -static double config_temp_offset = 0.0; /**< temperature offset */ +static double config_press_offset = 0.0; /**< pressure offset */ +static double config_temp_offset = 0.0; /**< temperature offset */ -static double config_altitude = NAN; /**< altitude */ -static int config_normalize = 0; /**< normalization method */ +static double config_altitude = NAN; /**< altitude */ +static int config_normalize = 0; /**< normalization method */ -static _Bool configured = 0; /**< the whole plugin config status */ +static _Bool configured = 0; /**< the whole plugin config status */ -static int i2c_bus_fd = -1; /**< I2C bus device FD */ +static int i2c_bus_fd = -1; /**< I2C bus device FD */ -static enum Sensor_type sensor_type = Sensor_none; /**< detected/used sensor type */ +static enum Sensor_type sensor_type = + Sensor_none; /**< detected/used sensor type */ -static __s32 mpl3115_oversample = 0; /**< MPL3115 CTRL1 oversample setting */ +static __s32 mpl3115_oversample = 0; /**< MPL3115 CTRL1 oversample setting */ // BMP085 configuration -static unsigned bmp085_oversampling; /**< BMP085 oversampling (0-3) */ -static unsigned long bmp085_timeCnvPress; /**< BMP085 conversion time for pressure in us */ -static __u8 bmp085_cmdCnvPress; /**< BMP085 pressure conversion command */ - +static unsigned bmp085_oversampling; /**< BMP085 oversampling (0-3) */ +static unsigned long + bmp085_timeCnvPress; /**< BMP085 conversion time for pressure in us */ +static __u8 bmp085_cmdCnvPress; /**< BMP085 pressure conversion command */ /* MPL115 conversion coefficients */ static double mpl115_coeffA0; @@ -225,25 +222,21 @@ static short bmp085_MB; static short bmp085_MC; static short bmp085_MD; - - /* ------------------------ averaging ring buffer ------------------------ */ /* Used only for MPL115. MPL3115 supports real oversampling in the device so */ /* no need for any postprocessing. */ -static _Bool avg_initialized = 0; /**< already initialized by real values */ +static _Bool avg_initialized = 0; /**< already initialized by real values */ typedef struct averaging_s { - long int * ring_buffer; - int ring_buffer_size; - long int ring_buffer_sum; - int ring_buffer_head; + long int *ring_buffer; + int ring_buffer_size; + long int ring_buffer_sum; + int ring_buffer_head; } averaging_t; - -static averaging_t pressure_averaging = { NULL, 0, 0L, 0 }; -static averaging_t temperature_averaging = { NULL, 0, 0L, 0 }; - +static averaging_t pressure_averaging = {NULL, 0, 0L, 0}; +static averaging_t temperature_averaging = {NULL, 0, 0L, 0}; /** * Create / allocate averaging buffer @@ -255,42 +248,37 @@ static averaging_t temperature_averaging = { NULL, 0, 0L, 0 }; * * @return Zero when successful */ -static int averaging_create(averaging_t *avg, int size) -{ - avg->ring_buffer = calloc ((size_t) size, sizeof (*avg->ring_buffer)); - if (avg->ring_buffer == NULL) - { - ERROR ("barometer: averaging_create - ring buffer allocation of size %d failed", - size); - return -1; - } - - avg->ring_buffer_size = size; - avg->ring_buffer_sum = 0L; - avg->ring_buffer_head = 0; - - return 0; +static int averaging_create(averaging_t *avg, int size) { + avg->ring_buffer = calloc((size_t)size, sizeof(*avg->ring_buffer)); + if (avg->ring_buffer == NULL) { + ERROR("barometer: averaging_create - ring buffer allocation of size %d " + "failed", + size); + return -1; + } + + avg->ring_buffer_size = size; + avg->ring_buffer_sum = 0L; + avg->ring_buffer_head = 0; + + return 0; } - /** * Delete / free existing averaging buffer * * @param avg pointer to the ring buffer to be deleted */ -static void averaging_delete(averaging_t * avg) -{ - if (avg->ring_buffer != NULL) - { - free(avg->ring_buffer); - avg->ring_buffer = NULL; - } - avg->ring_buffer_size = 0; - avg->ring_buffer_sum = 0L; - avg->ring_buffer_head = 0; +static void averaging_delete(averaging_t *avg) { + if (avg->ring_buffer != NULL) { + free(avg->ring_buffer); + avg->ring_buffer = NULL; + } + avg->ring_buffer_size = 0; + avg->ring_buffer_sum = 0L; + avg->ring_buffer_head = 0; } - /* * Add new sample to the averaging buffer * @@ -303,37 +291,33 @@ static void averaging_delete(averaging_t * avg) * * @return Averaged sample value */ -static double averaging_add_sample(averaging_t * avg, long int sample) -{ - double result; +static double averaging_add_sample(averaging_t *avg, long int sample) { + double result; - avg->ring_buffer_sum += sample - avg->ring_buffer[avg->ring_buffer_head]; - avg->ring_buffer[avg->ring_buffer_head] = sample; - avg->ring_buffer_head = (avg->ring_buffer_head+1) % avg->ring_buffer_size; - result = (double)(avg->ring_buffer_sum) / (double)(avg->ring_buffer_size); + avg->ring_buffer_sum += sample - avg->ring_buffer[avg->ring_buffer_head]; + avg->ring_buffer[avg->ring_buffer_head] = sample; + avg->ring_buffer_head = (avg->ring_buffer_head + 1) % avg->ring_buffer_size; + result = (double)(avg->ring_buffer_sum) / (double)(avg->ring_buffer_size); - DEBUG ("barometer: averaging_add_sample - added %ld, result = %lf", - sample, - result); + DEBUG("barometer: averaging_add_sample - added %ld, result = %lf", sample, + result); - return result; + return result; } - /* ------------------------ temperature refference ------------------------ */ /** * Linked list type of temperature sensor references */ typedef struct temperature_list_s { - char * sensor_name; /**< sensor name/reference */ - size_t num_values; /**< number of values (usually one) */ - _Bool initialized; /**< sensor already provides data */ - struct temperature_list_s * next; /**< next in the list */ + char *sensor_name; /**< sensor name/reference */ + size_t num_values; /**< number of values (usually one) */ + _Bool initialized; /**< sensor already provides data */ + struct temperature_list_s *next; /**< next in the list */ } temperature_list_t; -static temperature_list_t * temp_list = NULL; - +static temperature_list_t *temp_list = NULL; /* * Add new sensor to the temperature reference list @@ -343,59 +327,58 @@ static temperature_list_t * temp_list = NULL; * * @return Zero when successful */ -static int temp_list_add(temperature_list_t * list, const char * sensor) -{ - temperature_list_t *new_temp; - - new_temp = malloc(sizeof (*new_temp)); - if(new_temp == NULL) - return -1; - - new_temp->sensor_name = strdup(sensor); - new_temp->initialized = 0; - new_temp->num_values = 0; - if(new_temp->sensor_name == NULL) - { - free(new_temp); - return -1; - } - - new_temp->next = temp_list; - temp_list = new_temp; - return 0; +static int temp_list_add(temperature_list_t *list, const char *sensor) { + temperature_list_t *new_temp; + + new_temp = malloc(sizeof(*new_temp)); + if (new_temp == NULL) + return -1; + + new_temp->sensor_name = strdup(sensor); + new_temp->initialized = 0; + new_temp->num_values = 0; + if (new_temp->sensor_name == NULL) { + free(new_temp); + return -1; + } + + new_temp->next = temp_list; + temp_list = new_temp; + return 0; } - /* * Delete the whole temperature reference list * * @param list the list to be deleted */ -static void temp_list_delete(temperature_list_t ** list) -{ - temperature_list_t * tmp; - - while (*list != NULL) - { - tmp = (*list); - (*list) = (*list)->next; - free(tmp->sensor_name); - free(tmp); - tmp = NULL; - } +static void temp_list_delete(temperature_list_t **list) { + temperature_list_t *tmp; + + while (*list != NULL) { + tmp = (*list); + (*list) = (*list)->next; + free(tmp->sensor_name); + free(tmp); + tmp = NULL; + } } - /* * Get reference temperature value * - * First initially uc_get_rate_by_name is tried. At the startup due to nondeterministic - * order the temperature may not be read yet (then it fails and first measurment gives - * only absolute air pressure reading which is acceptable). Once it succedes (should be + * First initially uc_get_rate_by_name is tried. At the startup due to + * nondeterministic + * order the temperature may not be read yet (then it fails and first measurment + * gives + * only absolute air pressure reading which is acceptable). Once it succedes + * (should be * second measurement at the latest) we use average of few last readings from - * uc_get_history_by_name. It may take few readings to start filling so again we use + * uc_get_history_by_name. It may take few readings to start filling so again we + * use * uc_get_rate_by_name as a fallback. - * The idea is to use basic "noise" filtering (history averaging) across all the values + * The idea is to use basic "noise" filtering (history averaging) across all the + * values * which given sensor provides (up to given depth). Then we get minimum among * the sensors. * @@ -403,145 +386,123 @@ static void temp_list_delete(temperature_list_t ** list) * * @return Zero when successful */ -static int get_reference_temperature(double * result) -{ - temperature_list_t * list = temp_list; +static int get_reference_temperature(double *result) { + temperature_list_t *list = temp_list; - gauge_t * values = NULL; /**< rate values */ - size_t values_num = 0; /**< number of rate values */ + gauge_t *values = NULL; /**< rate values */ + size_t values_num = 0; /**< number of rate values */ - gauge_t values_history[REF_TEMP_AVG_NUM]; + gauge_t values_history[REF_TEMP_AVG_NUM]; - double avg_sum; /**< Value sum for computing average */ - int avg_num; /**< Number of values for computing average */ - double average; /**< Resulting value average */ + double avg_sum; /**< Value sum for computing average */ + int avg_num; /**< Number of values for computing average */ + double average; /**< Resulting value average */ - *result = NAN; + *result = NAN; - while(list != NULL) - { - avg_sum = 0.0; - avg_num = 0; - - /* First time need to read current rate to learn how many values are - there (typically for temperature it would be just one). - We do not expect dynamic changing of number of temperarure values - in runtime yet (are there any such cases?). */ - if(!list->initialized) - { - if(uc_get_rate_by_name(list->sensor_name, - &values, - &values_num)) - { - DEBUG ("barometer: get_reference_temperature - rate \"%s\" not found yet", - list->sensor_name); - list = list->next; - continue; - } - - DEBUG ("barometer: get_reference_temperature - initialize \"%s\", %zu vals", - list->sensor_name, - values_num); - - list->initialized = 1; - list->num_values = values_num; - - for(size_t i=0; isensor_name, - values_history, - REF_TEMP_AVG_NUM, - list->num_values)) - { - ERROR ("barometer: get_reference_temperature - history \"%s\" lost", - list->sensor_name); - list->initialized = 0; - list->num_values = 0; - list = list->next; - continue; - } - - for(size_t i=0; inum_values; ++i) - { - DEBUG ("barometer: get_reference_temperature - history %zu: %lf", - i, values_history[i]); - if(!isnan(values_history[i])) - { - avg_sum += values_history[i]; - ++avg_num; - } - } + while (list != NULL) { + avg_sum = 0.0; + avg_num = 0; - if(avg_num == 0) /* still no history? fallback to current */ - { - if(uc_get_rate_by_name(list->sensor_name, - &values, - &values_num)) - { - ERROR ("barometer: get_reference_temperature - rate \"%s\" lost", - list->sensor_name); - list->initialized = 0; - list->num_values = 0; - list = list->next; - continue; - } - - for(size_t i=0; isensor_name); - list->initialized = 0; - list->num_values = 0; - } - else - { - average = avg_sum / (double) avg_num; - if(isnan(*result)) - *result=average; - else if(*result>average) - *result=average; + /* First time need to read current rate to learn how many values are + there (typically for temperature it would be just one). + We do not expect dynamic changing of number of temperarure values + in runtime yet (are there any such cases?). */ + if (!list->initialized) { + if (uc_get_rate_by_name(list->sensor_name, &values, &values_num)) { + DEBUG( + "barometer: get_reference_temperature - rate \"%s\" not found yet", + list->sensor_name); + list = list->next; + continue; + } + + DEBUG( + "barometer: get_reference_temperature - initialize \"%s\", %zu vals", + list->sensor_name, values_num); + + list->initialized = 1; + list->num_values = values_num; + + for (size_t i = 0; i < values_num; ++i) { + DEBUG("barometer: get_reference_temperature - rate %zu: %lf **", i, + values[i]); + if (!isnan(values[i])) { + avg_sum += values[i]; + ++avg_num; } + } + free(values); + values = NULL; + } + + /* It is OK to get here the first time as well, in the worst case + the history will full of NANs. */ + if (uc_get_history_by_name(list->sensor_name, values_history, + REF_TEMP_AVG_NUM, list->num_values)) { + ERROR("barometer: get_reference_temperature - history \"%s\" lost", + list->sensor_name); + list->initialized = 0; + list->num_values = 0; + list = list->next; + continue; + } + + for (size_t i = 0; i < REF_TEMP_AVG_NUM * list->num_values; ++i) { + DEBUG("barometer: get_reference_temperature - history %zu: %lf", i, + values_history[i]); + if (!isnan(values_history[i])) { + avg_sum += values_history[i]; + ++avg_num; + } + } + + if (avg_num == 0) /* still no history? fallback to current */ + { + if (uc_get_rate_by_name(list->sensor_name, &values, &values_num)) { + ERROR("barometer: get_reference_temperature - rate \"%s\" lost", + list->sensor_name); + list->initialized = 0; + list->num_values = 0; list = list->next; - } /* while sensor list */ - - if(*result == NAN) - { - ERROR("barometer: get_reference_temperature - no sensor available (yet?)"); - return -1; - } - DEBUG ("barometer: get_reference_temperature - temp is %lf", *result); - return 0; + continue; + } + + for (size_t i = 0; i < values_num; ++i) { + DEBUG("barometer: get_reference_temperature - rate last %zu: %lf **", i, + values[i]); + if (!isnan(values[i])) { + avg_sum += values[i]; + ++avg_num; + } + } + free(values); + values = NULL; + } + + if (avg_num == 0) { + ERROR("barometer: get_reference_temperature - could not read \"%s\"", + list->sensor_name); + list->initialized = 0; + list->num_values = 0; + } else { + average = avg_sum / (double)avg_num; + if (isnan(*result)) + *result = average; + else if (*result > average) + *result = average; + } + list = list->next; + } /* while sensor list */ + + if (*result == NAN) { + ERROR("barometer: get_reference_temperature - no sensor available (yet?)"); + return -1; + } + DEBUG("barometer: get_reference_temperature - temp is %lf", *result); + return 0; } - /* ------------------------ MPL115 access ------------------------ */ /** @@ -549,34 +510,32 @@ static int get_reference_temperature(double * result) * * Unfortunately there seems to be no ID register so we just try to read first * conversion coefficient from device at MPL115 address and hope it is really - * MPL115. We should use this check as the last resort (which would be the typical + * MPL115. We should use this check as the last resort (which would be the + * typical * case anyway since MPL115 is the least accurate sensor). * As a sideeffect will leave set I2C slave address. * * @return 1 if MPL115, 0 otherwise */ -static int MPL115_detect(void) -{ - __s32 res; - char errbuf[1024]; - - if (ioctl(i2c_bus_fd, I2C_SLAVE_FORCE, MPL115_I2C_ADDRESS) < 0) - { - ERROR("barometer: MPL115_detect problem setting i2c slave address to 0x%02X: %s", - MPL115_I2C_ADDRESS, - sstrerror (errno, errbuf, sizeof (errbuf))); - return 0 ; - } +static int MPL115_detect(void) { + __s32 res; + char errbuf[1024]; + + if (ioctl(i2c_bus_fd, I2C_SLAVE_FORCE, MPL115_I2C_ADDRESS) < 0) { + ERROR("barometer: MPL115_detect problem setting i2c slave address to " + "0x%02X: %s", + MPL115_I2C_ADDRESS, sstrerror(errno, errbuf, sizeof(errbuf))); + return 0; + } - res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL115_ADDR_COEFFS); - if(res >= 0) - { - DEBUG ("barometer: MPL115_detect - positive detection"); - return 1; - } + res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL115_ADDR_COEFFS); + if (res >= 0) { + DEBUG("barometer: MPL115_detect - positive detection"); + return 1; + } - DEBUG ("barometer: MPL115_detect - negative detection"); - return 0; + DEBUG("barometer: MPL115_detect - negative detection"); + return 0; } /** @@ -586,91 +545,84 @@ static int MPL115_detect(void) * * @return Zero when successful */ -static int MPL115_read_coeffs(void) -{ - uint8_t mpl115_coeffs[MPL115_NUM_COEFFS] = { 0 }; - int32_t res; - - int8_t sia0MSB, sia0LSB, sib1MSB, sib1LSB, sib2MSB, sib2LSB; - int8_t sic12MSB, sic12LSB, sic11MSB, sic11LSB, sic22MSB, sic22LSB; - int16_t sia0, sib1, sib2, sic12, sic11, sic22; - - char errbuf[1024]; - - res = i2c_smbus_read_i2c_block_data(i2c_bus_fd, - MPL115_ADDR_COEFFS, - STATIC_ARRAY_SIZE (mpl115_coeffs), - mpl115_coeffs); - if (res < 0) - { - ERROR ("barometer: MPL115_read_coeffs - problem reading data: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return -1; - } - - /* Using perhaps less elegant/efficient code, but more readable. */ - /* a0: 16total 1sign 12int 4fract 0pad */ - sia0MSB = mpl115_coeffs[0]; - sia0LSB = mpl115_coeffs[1]; - sia0 = (int16_t) sia0MSB <<8; /* s16 type, Shift to MSB */ - sia0 += (int16_t) sia0LSB & 0x00FF; /* Add LSB to 16bit number */ - mpl115_coeffA0 = (double) (sia0); - mpl115_coeffA0 /= 8.0; /* 3 fract bits */ - - /* b1: 16total 1sign 2int 13fract 0pad */ - sib1MSB= mpl115_coeffs[2]; - sib1LSB= mpl115_coeffs[3]; - sib1 = sib1MSB <<8; /* Shift to MSB */ - sib1 += sib1LSB & 0x00FF; /* Add LSB to 16bit number */ - mpl115_coeffB1 = (double) (sib1); - mpl115_coeffB1 /= 8192.0; /* 13 fract */ - - /* b2: 16total 1sign 1int 14fract 0pad */ - sib2MSB= mpl115_coeffs[4]; - sib2LSB= mpl115_coeffs[5]; - sib2 = sib2MSB <<8; /* Shift to MSB */ - sib2 += sib2LSB & 0x00FF; /* Add LSB to 16bit number */ - mpl115_coeffB2 = (double) (sib2); - mpl115_coeffB2 /= 16384.0; /* 14 fract */ - - /* c12: 14total 1sign 0int 13fract 9pad */ - sic12MSB= mpl115_coeffs[6]; - sic12LSB= mpl115_coeffs[7]; - sic12 = sic12MSB <<8; /* Shift to MSB only by 8 for MSB */ - sic12 += sic12LSB & 0x00FF; - mpl115_coeffC12 = (double) (sic12); - mpl115_coeffC12 /= 4.0; /* 16-14=2 */ - mpl115_coeffC12 /= 4194304.0; /* 13+9=22 fract */ - - /* c11: 11total 1sign 0int 11fract 11pad */ - sic11MSB= mpl115_coeffs[8]; - sic11LSB= mpl115_coeffs[9]; - sic11 = sic11MSB <<8; /* Shift to MSB only by 8 for MSB */ - sic11 += sic11LSB & 0x00FF; - mpl115_coeffC11 = (double) (sic11); - mpl115_coeffC11 /= 32.0; /* 16-11=5 */ - mpl115_coeffC11 /= 4194304.0; /* 11+11=22 fract */ - - /* c12: 11total 1sign 0int 10fract 15pad */ - sic22MSB= mpl115_coeffs[10]; - sic22LSB= mpl115_coeffs[11]; - sic22 = sic22MSB <<8; /* Shift to MSB only by 8 for MSB */ - sic22 += sic22LSB & 0x00FF; - mpl115_coeffC22 = (double) (sic22); - mpl115_coeffC22 /= 32.0; //16-11=5 - mpl115_coeffC22 /= 33554432.0; /* 10+15=25 fract */ - - DEBUG("barometer: MPL115_read_coeffs: a0=%lf, b1=%lf, b2=%lf, c12=%lf, c11=%lf, c22=%lf", - mpl115_coeffA0, - mpl115_coeffB1, - mpl115_coeffB2, - mpl115_coeffC12, - mpl115_coeffC11, - mpl115_coeffC22); - return 0; +static int MPL115_read_coeffs(void) { + uint8_t mpl115_coeffs[MPL115_NUM_COEFFS] = {0}; + int32_t res; + + int8_t sia0MSB, sia0LSB, sib1MSB, sib1LSB, sib2MSB, sib2LSB; + int8_t sic12MSB, sic12LSB, sic11MSB, sic11LSB, sic22MSB, sic22LSB; + int16_t sia0, sib1, sib2, sic12, sic11, sic22; + + char errbuf[1024]; + + res = i2c_smbus_read_i2c_block_data(i2c_bus_fd, MPL115_ADDR_COEFFS, + STATIC_ARRAY_SIZE(mpl115_coeffs), + mpl115_coeffs); + if (res < 0) { + ERROR("barometer: MPL115_read_coeffs - problem reading data: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return -1; + } + + /* Using perhaps less elegant/efficient code, but more readable. */ + /* a0: 16total 1sign 12int 4fract 0pad */ + sia0MSB = mpl115_coeffs[0]; + sia0LSB = mpl115_coeffs[1]; + sia0 = (int16_t)sia0MSB << 8; /* s16 type, Shift to MSB */ + sia0 += (int16_t)sia0LSB & 0x00FF; /* Add LSB to 16bit number */ + mpl115_coeffA0 = (double)(sia0); + mpl115_coeffA0 /= 8.0; /* 3 fract bits */ + + /* b1: 16total 1sign 2int 13fract 0pad */ + sib1MSB = mpl115_coeffs[2]; + sib1LSB = mpl115_coeffs[3]; + sib1 = sib1MSB << 8; /* Shift to MSB */ + sib1 += sib1LSB & 0x00FF; /* Add LSB to 16bit number */ + mpl115_coeffB1 = (double)(sib1); + mpl115_coeffB1 /= 8192.0; /* 13 fract */ + + /* b2: 16total 1sign 1int 14fract 0pad */ + sib2MSB = mpl115_coeffs[4]; + sib2LSB = mpl115_coeffs[5]; + sib2 = sib2MSB << 8; /* Shift to MSB */ + sib2 += sib2LSB & 0x00FF; /* Add LSB to 16bit number */ + mpl115_coeffB2 = (double)(sib2); + mpl115_coeffB2 /= 16384.0; /* 14 fract */ + + /* c12: 14total 1sign 0int 13fract 9pad */ + sic12MSB = mpl115_coeffs[6]; + sic12LSB = mpl115_coeffs[7]; + sic12 = sic12MSB << 8; /* Shift to MSB only by 8 for MSB */ + sic12 += sic12LSB & 0x00FF; + mpl115_coeffC12 = (double)(sic12); + mpl115_coeffC12 /= 4.0; /* 16-14=2 */ + mpl115_coeffC12 /= 4194304.0; /* 13+9=22 fract */ + + /* c11: 11total 1sign 0int 11fract 11pad */ + sic11MSB = mpl115_coeffs[8]; + sic11LSB = mpl115_coeffs[9]; + sic11 = sic11MSB << 8; /* Shift to MSB only by 8 for MSB */ + sic11 += sic11LSB & 0x00FF; + mpl115_coeffC11 = (double)(sic11); + mpl115_coeffC11 /= 32.0; /* 16-11=5 */ + mpl115_coeffC11 /= 4194304.0; /* 11+11=22 fract */ + + /* c12: 11total 1sign 0int 10fract 15pad */ + sic22MSB = mpl115_coeffs[10]; + sic22LSB = mpl115_coeffs[11]; + sic22 = sic22MSB << 8; /* Shift to MSB only by 8 for MSB */ + sic22 += sic22LSB & 0x00FF; + mpl115_coeffC22 = (double)(sic22); + mpl115_coeffC22 /= 32.0; // 16-11=5 + mpl115_coeffC22 /= 33554432.0; /* 10+15=25 fract */ + + DEBUG("barometer: MPL115_read_coeffs: a0=%lf, b1=%lf, b2=%lf, c12=%lf, " + "c11=%lf, c22=%lf", + mpl115_coeffA0, mpl115_coeffB1, mpl115_coeffB2, mpl115_coeffC12, + mpl115_coeffC11, mpl115_coeffC22); + return 0; } - /** * Convert raw adc values to real data using the sensor coefficients. * @@ -679,24 +631,21 @@ static int MPL115_read_coeffs(void) * @param pressure computed real pressure * @param temperature computed real temperature */ -static void MPL115_convert_adc_to_real(double adc_pressure, - double adc_temp, - double * pressure, - double * temperature) -{ - double Pcomp; - Pcomp = mpl115_coeffA0 + \ - (mpl115_coeffB1 + mpl115_coeffC11*adc_pressure + mpl115_coeffC12*adc_temp) * adc_pressure + \ - (mpl115_coeffB2 + mpl115_coeffC22*adc_temp) * adc_temp; - - *pressure = ((1150.0-500.0) * Pcomp / 1023.0) + 500.0; - *temperature = (472.0 - adc_temp) / 5.35 + 25.0; - DEBUG ("barometer: MPL115_convert_adc_to_real - got %lf hPa, %lf C", - *pressure, - *temperature); +static void MPL115_convert_adc_to_real(double adc_pressure, double adc_temp, + double *pressure, double *temperature) { + double Pcomp; + Pcomp = mpl115_coeffA0 + + (mpl115_coeffB1 + mpl115_coeffC11 * adc_pressure + + mpl115_coeffC12 * adc_temp) * + adc_pressure + + (mpl115_coeffB2 + mpl115_coeffC22 * adc_temp) * adc_temp; + + *pressure = ((1150.0 - 500.0) * Pcomp / 1023.0) + 500.0; + *temperature = (472.0 - adc_temp) / 5.35 + 25.0; + DEBUG("barometer: MPL115_convert_adc_to_real - got %lf hPa, %lf C", *pressure, + *temperature); } - /** * Read sensor averegaed measurements * @@ -705,97 +654,82 @@ static void MPL115_convert_adc_to_real(double adc_pressure, * * @return Zero when successful */ -static int MPL115_read_averaged(double * pressure, double * temperature) -{ - uint8_t mpl115_conv[MPL115_NUM_CONV] = { 0 }; - int8_t res; - int retries; - int conv_pressure; - int conv_temperature; - double adc_pressure; - double adc_temperature; - char errbuf[1024]; - - *pressure = 0.0; - *temperature = 0.0; - - /* start conversion of both temp and presure */ - retries = MPL115_CONVERSION_RETRIES; - while (retries>0) - { - /* write 1 to start conversion */ - res = i2c_smbus_write_byte_data (i2c_bus_fd, - MPL115_CMD_CONVERT_BOTH, - 0x01); - if (res >= 0) - break; - - --retries; - if(retries>0) - { - ERROR ("barometer: MPL115_read_averaged - requesting conversion: %s, " \ - "will retry at most %d more times", - sstrerror (errno, errbuf, sizeof (errbuf)), - retries); - } - else - { - ERROR ("barometer: MPL115_read_averaged - requesting conversion: %s, "\ - "too many failed retries", - sstrerror (errno, errbuf, sizeof (errbuf))); - return -1; - } - } - - usleep (10000); /* wait 10ms for the conversion */ - - retries=MPL115_CONVERSION_RETRIES; - while (retries>0) - { - res = i2c_smbus_read_i2c_block_data(i2c_bus_fd, - MPL115_ADDR_CONV, - STATIC_ARRAY_SIZE (mpl115_conv), - mpl115_conv); - if (res >= 0) - break; - - --retries; - if (retries>0) - { - ERROR ("barometer: MPL115_read_averaged - reading conversion: %s, " \ - "will retry at most %d more times", - sstrerror (errno, errbuf, sizeof (errbuf)), - retries); - } - else - { - ERROR ("barometer: MPL115_read_averaged - reading conversion: %s, " \ - "too many failed retries", - sstrerror (errno, errbuf, sizeof (errbuf))); - return -1; - } - } - - conv_pressure = ((mpl115_conv[0] << 8) | mpl115_conv[1]) >> 6; - conv_temperature = ((mpl115_conv[2] << 8) | mpl115_conv[3]) >> 6; - DEBUG ("barometer: MPL115_read_averaged, raw pressure ADC value = %d, " \ - "raw temperature ADC value = %d", - conv_pressure, - conv_temperature); - - adc_pressure = averaging_add_sample (&pressure_averaging, conv_pressure); - adc_temperature = averaging_add_sample (&temperature_averaging, conv_temperature); - - MPL115_convert_adc_to_real(adc_pressure, adc_temperature, pressure, temperature); - - DEBUG ("barometer: MPL115_read_averaged - averaged ADC pressure = %lf / temperature = %lf, " \ - "real pressure = %lf hPa / temperature = %lf C", - adc_pressure, - adc_temperature, - *pressure, - *temperature); - - return 0; +static int MPL115_read_averaged(double *pressure, double *temperature) { + uint8_t mpl115_conv[MPL115_NUM_CONV] = {0}; + int8_t res; + int retries; + int conv_pressure; + int conv_temperature; + double adc_pressure; + double adc_temperature; + char errbuf[1024]; + + *pressure = 0.0; + *temperature = 0.0; + + /* start conversion of both temp and presure */ + retries = MPL115_CONVERSION_RETRIES; + while (retries > 0) { + /* write 1 to start conversion */ + res = i2c_smbus_write_byte_data(i2c_bus_fd, MPL115_CMD_CONVERT_BOTH, 0x01); + if (res >= 0) + break; + + --retries; + if (retries > 0) { + ERROR("barometer: MPL115_read_averaged - requesting conversion: %s, " + "will retry at most %d more times", + sstrerror(errno, errbuf, sizeof(errbuf)), retries); + } else { + ERROR("barometer: MPL115_read_averaged - requesting conversion: %s, " + "too many failed retries", + sstrerror(errno, errbuf, sizeof(errbuf))); + return -1; + } + } + + usleep(10000); /* wait 10ms for the conversion */ + + retries = MPL115_CONVERSION_RETRIES; + while (retries > 0) { + res = i2c_smbus_read_i2c_block_data(i2c_bus_fd, MPL115_ADDR_CONV, + STATIC_ARRAY_SIZE(mpl115_conv), + mpl115_conv); + if (res >= 0) + break; + + --retries; + if (retries > 0) { + ERROR("barometer: MPL115_read_averaged - reading conversion: %s, " + "will retry at most %d more times", + sstrerror(errno, errbuf, sizeof(errbuf)), retries); + } else { + ERROR("barometer: MPL115_read_averaged - reading conversion: %s, " + "too many failed retries", + sstrerror(errno, errbuf, sizeof(errbuf))); + return -1; + } + } + + conv_pressure = ((mpl115_conv[0] << 8) | mpl115_conv[1]) >> 6; + conv_temperature = ((mpl115_conv[2] << 8) | mpl115_conv[3]) >> 6; + DEBUG("barometer: MPL115_read_averaged, raw pressure ADC value = %d, " + "raw temperature ADC value = %d", + conv_pressure, conv_temperature); + + adc_pressure = averaging_add_sample(&pressure_averaging, conv_pressure); + adc_temperature = + averaging_add_sample(&temperature_averaging, conv_temperature); + + MPL115_convert_adc_to_real(adc_pressure, adc_temperature, pressure, + temperature); + + DEBUG("barometer: MPL115_read_averaged - averaged ADC pressure = %lf / " + "temperature = %lf, " + "real pressure = %lf hPa / temperature = %lf C", + adc_pressure, adc_temperature, *pressure, *temperature); + + return 0; } /* ------------------------ MPL3115 access ------------------------ */ @@ -807,28 +741,25 @@ static int MPL115_read_averaged(double * pressure, double * temperature) * * @return 1 if MPL3115, 0 otherwise */ -static int MPL3115_detect(void) -{ - __s32 res; - char errbuf[1024]; +static int MPL3115_detect(void) { + __s32 res; + char errbuf[1024]; + + if (ioctl(i2c_bus_fd, I2C_SLAVE_FORCE, MPL3115_I2C_ADDRESS) < 0) { + ERROR("barometer: MPL3115_detect problem setting i2c slave address to " + "0x%02X: %s", + MPL3115_I2C_ADDRESS, sstrerror(errno, errbuf, sizeof(errbuf))); + return 0; + } - if (ioctl(i2c_bus_fd, I2C_SLAVE_FORCE, MPL3115_I2C_ADDRESS) < 0) - { - ERROR("barometer: MPL3115_detect problem setting i2c slave address to 0x%02X: %s", - MPL3115_I2C_ADDRESS, - sstrerror (errno, errbuf, sizeof (errbuf))); - return 0 ; - } + res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_WHO_AM_I); + if (res == MPL3115_WHO_AM_I_RESP) { + DEBUG("barometer: MPL3115_detect - positive detection"); + return 1; + } - res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_WHO_AM_I); - if(res == MPL3115_WHO_AM_I_RESP) - { - DEBUG ("barometer: MPL3115_detect - positive detection"); - return 1; - } - - DEBUG ("barometer: MPL3115_detect - negative detection"); - return 0; + DEBUG("barometer: MPL3115_detect - negative detection"); + return 0; } /** @@ -836,55 +767,39 @@ static int MPL3115_detect(void) * * MPL3115 supports only power of 2 in the range 1 to 128. */ -static void MPL3115_adjust_oversampling(void) -{ - int new_val = 0; - - if(config_oversample > 100) - { - new_val = 128; - mpl3115_oversample = MPL3115_CTRL_REG1_OST_128; - } - else if(config_oversample > 48) - { - new_val = 64; - mpl3115_oversample = MPL3115_CTRL_REG1_OST_64; - } - else if(config_oversample > 24) - { - new_val = 32; - mpl3115_oversample = MPL3115_CTRL_REG1_OST_32; - } - else if(config_oversample > 12) - { - new_val = 16; - mpl3115_oversample = MPL3115_CTRL_REG1_OST_16; - } - else if(config_oversample > 6) - { - new_val = 8; - mpl3115_oversample = MPL3115_CTRL_REG1_OST_8; - } - else if(config_oversample > 3) - { - new_val = 4; - mpl3115_oversample = MPL3115_CTRL_REG1_OST_4; - } - else if(config_oversample > 1) - { - new_val = 2; - mpl3115_oversample = MPL3115_CTRL_REG1_OST_2; - } - else - { - new_val = 1; - mpl3115_oversample = MPL3115_CTRL_REG1_OST_1; - } - - DEBUG("barometer: MPL3115_adjust_oversampling - correcting oversampling from %d to %d", - config_oversample, - new_val); - config_oversample = new_val; +static void MPL3115_adjust_oversampling(void) { + int new_val = 0; + + if (config_oversample > 100) { + new_val = 128; + mpl3115_oversample = MPL3115_CTRL_REG1_OST_128; + } else if (config_oversample > 48) { + new_val = 64; + mpl3115_oversample = MPL3115_CTRL_REG1_OST_64; + } else if (config_oversample > 24) { + new_val = 32; + mpl3115_oversample = MPL3115_CTRL_REG1_OST_32; + } else if (config_oversample > 12) { + new_val = 16; + mpl3115_oversample = MPL3115_CTRL_REG1_OST_16; + } else if (config_oversample > 6) { + new_val = 8; + mpl3115_oversample = MPL3115_CTRL_REG1_OST_8; + } else if (config_oversample > 3) { + new_val = 4; + mpl3115_oversample = MPL3115_CTRL_REG1_OST_4; + } else if (config_oversample > 1) { + new_val = 2; + mpl3115_oversample = MPL3115_CTRL_REG1_OST_2; + } else { + new_val = 1; + mpl3115_oversample = MPL3115_CTRL_REG1_OST_1; + } + + DEBUG("barometer: MPL3115_adjust_oversampling - correcting oversampling from " + "%d to %d", + config_oversample, new_val); + config_oversample = new_val; } /** @@ -895,91 +810,79 @@ static void MPL3115_adjust_oversampling(void) * * @return Zero when successful */ -static int MPL3115_read(double * pressure, double * temperature) -{ - __s32 res; - __s32 ctrl ; - __u8 data[MPL3115_NUM_CONV_VALS]; - long int tmp_value = 0; - char errbuf[1024]; - - /* Set Active - activate the device from standby */ - res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_CTRL_REG1); - if (res < 0) - { - ERROR ("barometer: MPL3115_read - cannot read CTRL_REG1: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return 1; - } - ctrl = res; - res = i2c_smbus_write_byte_data(i2c_bus_fd, - MPL3115_REG_CTRL_REG1, - ctrl | MPL3115_CTRL_REG1_SBYB); - if (res < 0) - { - ERROR ("barometer: MPL3115_read - problem activating: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return 1; - } - - /* base sleep is 5ms x OST */ - usleep(5000 * config_oversample); - - /* check the flags/status if ready */ +static int MPL3115_read(double *pressure, double *temperature) { + __s32 res; + __s32 ctrl; + __u8 data[MPL3115_NUM_CONV_VALS]; + long int tmp_value = 0; + char errbuf[1024]; + + /* Set Active - activate the device from standby */ + res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_CTRL_REG1); + if (res < 0) { + ERROR("barometer: MPL3115_read - cannot read CTRL_REG1: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return 1; + } + ctrl = res; + res = i2c_smbus_write_byte_data(i2c_bus_fd, MPL3115_REG_CTRL_REG1, + ctrl | MPL3115_CTRL_REG1_SBYB); + if (res < 0) { + ERROR("barometer: MPL3115_read - problem activating: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return 1; + } + + /* base sleep is 5ms x OST */ + usleep(5000 * config_oversample); + + /* check the flags/status if ready */ + res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_STATUS); + if (res < 0) { + ERROR("barometer: MPL3115_read - cannot read status register: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return 1; + } + + while ((res & MPL3115_DR_STATUS_DR) != MPL3115_DR_STATUS_DR) { + /* try some extra sleep... */ + usleep(10000); + + /* ... and repeat the check. The conversion has to finish sooner or later. + */ res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_STATUS); - if (res < 0) - { - ERROR ("barometer: MPL3115_read - cannot read status register: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return 1; - } - - while ((res & MPL3115_DR_STATUS_DR) != MPL3115_DR_STATUS_DR) - { - /* try some extra sleep... */ - usleep(10000); - - /* ... and repeat the check. The conversion has to finish sooner or later. */ - res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_STATUS); - if (res < 0) - { - ERROR ("barometer: MPL3115_read - cannot read status register: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return 1; - } - } - - /* Now read all the data in one block. There is address autoincrement. */ - res = i2c_smbus_read_i2c_block_data(i2c_bus_fd, - MPL3115_REG_OUT_P_MSB, - MPL3115_NUM_CONV_VALS, - data); - if (res < 0) - { - ERROR ("barometer: MPL3115_read - cannot read data registers: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return 1; - } - - tmp_value = (data[0] << 16) | (data[1] << 8) | data[2]; - *pressure = ((double) tmp_value) / 4.0 / 16.0 / 100.0; - DEBUG ("barometer: MPL3115_read - absolute pressure = %lf hPa", *pressure); - - if(data[3] > 0x7F) - { - data[3] = ~data[3] + 1; - *temperature = data[3]; - *temperature = - *temperature; - } - else - { - *temperature = data[3]; - } - - *temperature += (double)(data[4]) / 256.0; - DEBUG ("barometer: MPL3115_read - temperature = %lf C", *temperature); - - return 0; + if (res < 0) { + ERROR("barometer: MPL3115_read - cannot read status register: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return 1; + } + } + + /* Now read all the data in one block. There is address autoincrement. */ + res = i2c_smbus_read_i2c_block_data(i2c_bus_fd, MPL3115_REG_OUT_P_MSB, + MPL3115_NUM_CONV_VALS, data); + if (res < 0) { + ERROR("barometer: MPL3115_read - cannot read data registers: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return 1; + } + + tmp_value = (data[0] << 16) | (data[1] << 8) | data[2]; + *pressure = ((double)tmp_value) / 4.0 / 16.0 / 100.0; + DEBUG("barometer: MPL3115_read - absolute pressure = %lf hPa", *pressure); + + if (data[3] > 0x7F) { + data[3] = ~data[3] + 1; + *temperature = data[3]; + *temperature = -*temperature; + } else { + *temperature = data[3]; + } + + *temperature += (double)(data[4]) / 256.0; + DEBUG("barometer: MPL3115_read - temperature = %lf C", *temperature); + + return 0; } /** @@ -987,70 +890,62 @@ static int MPL3115_read(double * pressure, double * temperature) * * @return 0 if successful */ -static int MPL3115_init_sensor(void) -{ - __s32 res; - __s8 offset; - char errbuf[1024]; - - /* Reset the sensor. It will reset immediately without ACKing */ - /* the transaction, so no error handling here. */ - i2c_smbus_write_byte_data(i2c_bus_fd, - MPL3115_REG_CTRL_REG1, - MPL3115_CTRL_REG1_RST); - - /* wait some time for the reset to finish */ - usleep(100000); - - /* now it should be in standby already so we can go and configure it */ - - /* Set temperature offset. */ - /* result = ADCtemp + offset [C] */ - offset = (__s8) (config_temp_offset * 16.0); - res = i2c_smbus_write_byte_data(i2c_bus_fd, MPL3115_REG_OFF_T, offset); - if (res < 0) - { - ERROR ("barometer: MPL3115_init_sensor - problem setting temp offset: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return -1; - } - - /* Set pressure offset. */ - /* result = ADCpress + offset [hPa] */ - offset = (__s8) (config_press_offset * 100.0 / 4.0); - res = i2c_smbus_write_byte_data(i2c_bus_fd, MPL3115_REG_OFF_P, offset); - if (res < 0) - { - ERROR ("barometer: MPL3115_init_sensor - problem setting pressure offset: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return -1; - } - - /* Enable Data Flags in PT_DATA_CFG - flags on both pressure and temp */ - res = i2c_smbus_write_byte_data(i2c_bus_fd, - MPL3115_REG_PT_DATA_CFG, - MPL3115_PT_DATA_DREM \ - | MPL3115_PT_DATA_PDEF \ - | MPL3115_PT_DATA_TDEF); - if (res < 0) - { - ERROR ("barometer: MPL3115_init_sensor - problem setting PT_DATA_CFG: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return -1; - } - - /* Set to barometer with an OSR */ - res = i2c_smbus_write_byte_data(i2c_bus_fd, - MPL3115_REG_CTRL_REG1, - mpl3115_oversample); - if (res < 0) - { - ERROR ("barometer: MPL3115_init_sensor - problem configuring CTRL_REG1: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return -1; - } - - return 0; +static int MPL3115_init_sensor(void) { + __s32 res; + __s8 offset; + char errbuf[1024]; + + /* Reset the sensor. It will reset immediately without ACKing */ + /* the transaction, so no error handling here. */ + i2c_smbus_write_byte_data(i2c_bus_fd, MPL3115_REG_CTRL_REG1, + MPL3115_CTRL_REG1_RST); + + /* wait some time for the reset to finish */ + usleep(100000); + + /* now it should be in standby already so we can go and configure it */ + + /* Set temperature offset. */ + /* result = ADCtemp + offset [C] */ + offset = (__s8)(config_temp_offset * 16.0); + res = i2c_smbus_write_byte_data(i2c_bus_fd, MPL3115_REG_OFF_T, offset); + if (res < 0) { + ERROR("barometer: MPL3115_init_sensor - problem setting temp offset: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return -1; + } + + /* Set pressure offset. */ + /* result = ADCpress + offset [hPa] */ + offset = (__s8)(config_press_offset * 100.0 / 4.0); + res = i2c_smbus_write_byte_data(i2c_bus_fd, MPL3115_REG_OFF_P, offset); + if (res < 0) { + ERROR( + "barometer: MPL3115_init_sensor - problem setting pressure offset: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return -1; + } + + /* Enable Data Flags in PT_DATA_CFG - flags on both pressure and temp */ + res = i2c_smbus_write_byte_data(i2c_bus_fd, MPL3115_REG_PT_DATA_CFG, + MPL3115_PT_DATA_DREM | MPL3115_PT_DATA_PDEF | + MPL3115_PT_DATA_TDEF); + if (res < 0) { + ERROR("barometer: MPL3115_init_sensor - problem setting PT_DATA_CFG: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return -1; + } + + /* Set to barometer with an OSR */ + res = i2c_smbus_write_byte_data(i2c_bus_fd, MPL3115_REG_CTRL_REG1, + mpl3115_oversample); + if (res < 0) { + ERROR("barometer: MPL3115_init_sensor - problem configuring CTRL_REG1: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return -1; + } + + return 0; } /* ------------------------ BMP085 access ------------------------ */ @@ -1062,88 +957,77 @@ static int MPL3115_init_sensor(void) * * @return 1 if BMP085, 0 otherwise */ -static int BMP085_detect(void) -{ - __s32 res; - char errbuf[1024]; - - if (ioctl(i2c_bus_fd, I2C_SLAVE_FORCE, BMP085_I2C_ADDRESS) < 0) - { - ERROR("barometer: BMP085_detect - problem setting i2c slave address to 0x%02X: %s", - BMP085_I2C_ADDRESS, - sstrerror (errno, errbuf, sizeof (errbuf))); - return 0 ; - } - - res = i2c_smbus_read_byte_data(i2c_bus_fd, BMP085_ADDR_ID_REG); - if(res == BMP085_CHIP_ID) - { - DEBUG ("barometer: BMP085_detect - positive detection"); - - /* get version */ - res = i2c_smbus_read_byte_data(i2c_bus_fd, BMP085_ADDR_VERSION ); - if (res < 0) - { - ERROR("barometer: BMP085_detect - problem checking chip version: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return 0 ; - } - DEBUG ("barometer: BMP085_detect - chip version ML:0x%02X AL:0x%02X", - res & 0x0f, - (res & 0xf0) >> 4); - return 1; - } - - DEBUG ("barometer: BMP085_detect - negative detection"); +static int BMP085_detect(void) { + __s32 res; + char errbuf[1024]; + + if (ioctl(i2c_bus_fd, I2C_SLAVE_FORCE, BMP085_I2C_ADDRESS) < 0) { + ERROR("barometer: BMP085_detect - problem setting i2c slave address to " + "0x%02X: %s", + BMP085_I2C_ADDRESS, sstrerror(errno, errbuf, sizeof(errbuf))); return 0; + } + + res = i2c_smbus_read_byte_data(i2c_bus_fd, BMP085_ADDR_ID_REG); + if (res == BMP085_CHIP_ID) { + DEBUG("barometer: BMP085_detect - positive detection"); + + /* get version */ + res = i2c_smbus_read_byte_data(i2c_bus_fd, BMP085_ADDR_VERSION); + if (res < 0) { + ERROR("barometer: BMP085_detect - problem checking chip version: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return 0; + } + DEBUG("barometer: BMP085_detect - chip version ML:0x%02X AL:0x%02X", + res & 0x0f, (res & 0xf0) >> 4); + return 1; + } + + DEBUG("barometer: BMP085_detect - negative detection"); + return 0; } - /** * Adjusts oversampling settings to values supported by BMP085 * * BMP085 supports only 1,2,4 or 8 samples. */ -static void BMP085_adjust_oversampling(void) -{ - int new_val = 0; - - if( config_oversample > 6 ) /* 8 */ - { - new_val = 8; - bmp085_oversampling = 3; - bmp085_cmdCnvPress = BMP085_CMD_CONVERT_PRESS_3; - bmp085_timeCnvPress = BMP085_TIME_CNV_PRESS_3; - } - else if( config_oversample > 3 ) /* 4 */ - { - new_val = 4; - bmp085_oversampling = 2; - bmp085_cmdCnvPress = BMP085_CMD_CONVERT_PRESS_2; - bmp085_timeCnvPress = BMP085_TIME_CNV_PRESS_2; - } - else if( config_oversample > 1 ) /* 2 */ - { - new_val = 2; - bmp085_oversampling = 1; - bmp085_cmdCnvPress = BMP085_CMD_CONVERT_PRESS_1; - bmp085_timeCnvPress = BMP085_TIME_CNV_PRESS_1; - } - else /* 1 */ - { - new_val = 1; - bmp085_oversampling = 0; - bmp085_cmdCnvPress = BMP085_CMD_CONVERT_PRESS_0; - bmp085_timeCnvPress = BMP085_TIME_CNV_PRESS_0; - } - - DEBUG("barometer: BMP085_adjust_oversampling - correcting oversampling from %d to %d", - config_oversample, - new_val); - config_oversample = new_val; +static void BMP085_adjust_oversampling(void) { + int new_val = 0; + + if (config_oversample > 6) /* 8 */ + { + new_val = 8; + bmp085_oversampling = 3; + bmp085_cmdCnvPress = BMP085_CMD_CONVERT_PRESS_3; + bmp085_timeCnvPress = BMP085_TIME_CNV_PRESS_3; + } else if (config_oversample > 3) /* 4 */ + { + new_val = 4; + bmp085_oversampling = 2; + bmp085_cmdCnvPress = BMP085_CMD_CONVERT_PRESS_2; + bmp085_timeCnvPress = BMP085_TIME_CNV_PRESS_2; + } else if (config_oversample > 1) /* 2 */ + { + new_val = 2; + bmp085_oversampling = 1; + bmp085_cmdCnvPress = BMP085_CMD_CONVERT_PRESS_1; + bmp085_timeCnvPress = BMP085_TIME_CNV_PRESS_1; + } else /* 1 */ + { + new_val = 1; + bmp085_oversampling = 0; + bmp085_cmdCnvPress = BMP085_CMD_CONVERT_PRESS_0; + bmp085_timeCnvPress = BMP085_TIME_CNV_PRESS_0; + } + + DEBUG("barometer: BMP085_adjust_oversampling - correcting oversampling from " + "%d to %d", + config_oversample, new_val); + config_oversample = new_val; } - /** * Read the BMP085 sensor conversion coefficients. * @@ -1151,53 +1035,39 @@ static void BMP085_adjust_oversampling(void) * * @return Zero when successful */ -static int BMP085_read_coeffs(void) -{ - __s32 res; - __u8 coeffs[BMP085_NUM_COEFFS]; - char errbuf[1024]; - - res = i2c_smbus_read_i2c_block_data(i2c_bus_fd, - BMP085_ADDR_COEFFS, - BMP085_NUM_COEFFS, - coeffs); - if (res < 0) - { - ERROR ("barometer: BMP085_read_coeffs - problem reading data: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return -1; - } - - bmp085_AC1 = ((int16_t) coeffs[0] <<8) | (int16_t) coeffs[1]; - bmp085_AC2 = ((int16_t) coeffs[2] <<8) | (int16_t) coeffs[3]; - bmp085_AC3 = ((int16_t) coeffs[4] <<8) | (int16_t) coeffs[5]; - bmp085_AC4 = ((uint16_t) coeffs[6] <<8) | (uint16_t) coeffs[7]; - bmp085_AC5 = ((uint16_t) coeffs[8] <<8) | (uint16_t) coeffs[9]; - bmp085_AC6 = ((uint16_t) coeffs[10] <<8) | (uint16_t) coeffs[11]; - bmp085_B1 = ((int16_t) coeffs[12] <<8) | (int16_t) coeffs[13]; - bmp085_B2 = ((int16_t) coeffs[14] <<8) | (int16_t) coeffs[15]; - bmp085_MB = ((int16_t) coeffs[16] <<8) | (int16_t) coeffs[17]; - bmp085_MC = ((int16_t) coeffs[18] <<8) | (int16_t) coeffs[19]; - bmp085_MD = ((int16_t) coeffs[20] <<8) | (int16_t) coeffs[21]; - - DEBUG("barometer: BMP085_read_coeffs - AC1=%d, AC2=%d, AC3=%d, AC4=%u,"\ - " AC5=%u, AC6=%u, B1=%d, B2=%d, MB=%d, MC=%d, MD=%d", - bmp085_AC1, - bmp085_AC2, - bmp085_AC3, - bmp085_AC4, - bmp085_AC5, - bmp085_AC6, - bmp085_B1, - bmp085_B2, - bmp085_MB, - bmp085_MC, - bmp085_MD); - - return 0; +static int BMP085_read_coeffs(void) { + __s32 res; + __u8 coeffs[BMP085_NUM_COEFFS]; + char errbuf[1024]; + + res = i2c_smbus_read_i2c_block_data(i2c_bus_fd, BMP085_ADDR_COEFFS, + BMP085_NUM_COEFFS, coeffs); + if (res < 0) { + ERROR("barometer: BMP085_read_coeffs - problem reading data: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return -1; + } + + bmp085_AC1 = ((int16_t)coeffs[0] << 8) | (int16_t)coeffs[1]; + bmp085_AC2 = ((int16_t)coeffs[2] << 8) | (int16_t)coeffs[3]; + bmp085_AC3 = ((int16_t)coeffs[4] << 8) | (int16_t)coeffs[5]; + bmp085_AC4 = ((uint16_t)coeffs[6] << 8) | (uint16_t)coeffs[7]; + bmp085_AC5 = ((uint16_t)coeffs[8] << 8) | (uint16_t)coeffs[9]; + bmp085_AC6 = ((uint16_t)coeffs[10] << 8) | (uint16_t)coeffs[11]; + bmp085_B1 = ((int16_t)coeffs[12] << 8) | (int16_t)coeffs[13]; + bmp085_B2 = ((int16_t)coeffs[14] << 8) | (int16_t)coeffs[15]; + bmp085_MB = ((int16_t)coeffs[16] << 8) | (int16_t)coeffs[17]; + bmp085_MC = ((int16_t)coeffs[18] << 8) | (int16_t)coeffs[19]; + bmp085_MD = ((int16_t)coeffs[20] << 8) | (int16_t)coeffs[21]; + + DEBUG("barometer: BMP085_read_coeffs - AC1=%d, AC2=%d, AC3=%d, AC4=%u," + " AC5=%u, AC6=%u, B1=%d, B2=%d, MB=%d, MC=%d, MD=%d", + bmp085_AC1, bmp085_AC2, bmp085_AC3, bmp085_AC4, bmp085_AC5, bmp085_AC6, + bmp085_B1, bmp085_B2, bmp085_MB, bmp085_MC, bmp085_MD); + + return 0; } - /** * Convert raw BMP085 adc values to real data using the sensor coefficients. * @@ -1206,67 +1076,60 @@ static int BMP085_read_coeffs(void) * @param pressure computed real pressure * @param temperature computed real temperature */ -static void BMP085_convert_adc_to_real(long adc_pressure, - long adc_temperature, - double * pressure, - double * temperature) +static void BMP085_convert_adc_to_real(long adc_pressure, long adc_temperature, + double *pressure, double *temperature) { - long X1, X2, X3; - long B3, B5, B6; - unsigned long B4, B7; - - long T; - long P; - - - /* calculate real temperature */ - X1 = ( (adc_temperature - bmp085_AC6) * bmp085_AC5) >> 15; - X2 = (bmp085_MC << 11) / (X1 + bmp085_MD); - - /* B5, T */ - B5 = X1 + X2; - T = (B5 + 8) >> 4; - *temperature = (double)T * 0.1; - - /* calculate real pressure */ - /* in general X1, X2, X3 are recycled while values of B3, B4, B5, B6 are kept */ - - /* B6, B3 */ - B6 = B5 - 4000; - X1 = ((bmp085_B2 * ((B6 * B6)>>12)) >> 11 ); - X2 = (((long)bmp085_AC2 * B6) >> 11); - X3 = X1 + X2; - B3 = (((((long)bmp085_AC1 * 4) + X3) << bmp085_oversampling) + 2) >> 2; - - /* B4 */ - X1 = (((long)bmp085_AC3*B6) >> 13); - X2 = (bmp085_B1*((B6*B6) >> 12) ) >> 16; - X3 = ((X1 + X2) + 2 ) >> 2; - B4 = ((long)bmp085_AC4* (unsigned long)(X3 + 32768)) >> 15; - - /* B7, P */ - B7 = (unsigned long)(adc_pressure - B3)*(50000>>bmp085_oversampling); - if( B7 < 0x80000000 ) - { - P = (B7 << 1) / B4; - } - else - { - P = (B7/B4) << 1; - } - X1 = (P >> 8) * (P >> 8); - X1 = (X1 * 3038) >> 16; - X2 = ((-7357) * P) >> 16; - P = P + ( ( X1 + X2 + 3791 ) >> 4); - - *pressure = P / 100.0; // in [hPa] - DEBUG ("barometer: BMP085_convert_adc_to_real - got %lf hPa, %lf C", - *pressure, - *temperature); + long X1, X2, X3; + long B3, B5, B6; + unsigned long B4, B7; + + long T; + long P; + + /* calculate real temperature */ + X1 = ((adc_temperature - bmp085_AC6) * bmp085_AC5) >> 15; + X2 = (bmp085_MC << 11) / (X1 + bmp085_MD); + + /* B5, T */ + B5 = X1 + X2; + T = (B5 + 8) >> 4; + *temperature = (double)T * 0.1; + + /* calculate real pressure */ + /* in general X1, X2, X3 are recycled while values of B3, B4, B5, B6 are kept + */ + + /* B6, B3 */ + B6 = B5 - 4000; + X1 = ((bmp085_B2 * ((B6 * B6) >> 12)) >> 11); + X2 = (((long)bmp085_AC2 * B6) >> 11); + X3 = X1 + X2; + B3 = (((((long)bmp085_AC1 * 4) + X3) << bmp085_oversampling) + 2) >> 2; + + /* B4 */ + X1 = (((long)bmp085_AC3 * B6) >> 13); + X2 = (bmp085_B1 * ((B6 * B6) >> 12)) >> 16; + X3 = ((X1 + X2) + 2) >> 2; + B4 = ((long)bmp085_AC4 * (unsigned long)(X3 + 32768)) >> 15; + + /* B7, P */ + B7 = (unsigned long)(adc_pressure - B3) * (50000 >> bmp085_oversampling); + if (B7 < 0x80000000) { + P = (B7 << 1) / B4; + } else { + P = (B7 / B4) << 1; + } + X1 = (P >> 8) * (P >> 8); + X1 = (X1 * 3038) >> 16; + X2 = ((-7357) * P) >> 16; + P = P + ((X1 + X2 + 3791) >> 4); + + *pressure = P / 100.0; // in [hPa] + DEBUG("barometer: BMP085_convert_adc_to_real - got %lf hPa, %lf C", *pressure, + *temperature); } - /** * Read compensated sensor measurements * @@ -1275,82 +1138,70 @@ static void BMP085_convert_adc_to_real(long adc_pressure, * * @return Zero when successful */ -static int BMP085_read(double * pressure, double * temperature) -{ - __s32 res; - __u8 measBuff[3]; - - long adc_pressure; - long adc_temperature; - - char errbuf[1024]; - - /* start conversion of temperature */ - res = i2c_smbus_write_byte_data( i2c_bus_fd, - BMP085_ADDR_CTRL_REG, - BMP085_CMD_CONVERT_TEMP ); - if (res < 0) - { - ERROR ("barometer: BMP085_read - problem requesting temperature conversion: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return 1; - } - - usleep(BMP085_TIME_CNV_TEMP); /* wait for the conversion */ - - res = i2c_smbus_read_i2c_block_data( i2c_bus_fd, - BMP085_ADDR_CONV, - 2, - measBuff); - if (res < 0) - { - ERROR ("barometer: BMP085_read - problem reading temperature data: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return 1; - } - - adc_temperature = ( (unsigned short)measBuff[0] << 8 ) + measBuff[1]; - - - /* get presure */ - res = i2c_smbus_write_byte_data( i2c_bus_fd, - BMP085_ADDR_CTRL_REG, - bmp085_cmdCnvPress ); - if (res < 0) - { - ERROR ("barometer: BMP085_read - problem requesting pressure conversion: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return 1; - } - - usleep(bmp085_timeCnvPress); /* wait for the conversion */ - - res = i2c_smbus_read_i2c_block_data( i2c_bus_fd, - BMP085_ADDR_CONV, - 3, - measBuff ); - if (res < 0) - { - ERROR ("barometer: BMP085_read - problem reading pressure data: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return 1; - } - - adc_pressure = (long)((((ulong)measBuff[0]<<16) | ((ulong)measBuff[1]<<8) | (ulong)measBuff[2] ) >> (8 - bmp085_oversampling)); - - - DEBUG ("barometer: BMP085_read - raw pressure ADC value = %ld, " \ - "raw temperature ADC value = %ld", - adc_pressure, - adc_temperature); - - BMP085_convert_adc_to_real(adc_pressure, adc_temperature, pressure, temperature); - - return 0; +static int BMP085_read(double *pressure, double *temperature) { + __s32 res; + __u8 measBuff[3]; + + long adc_pressure; + long adc_temperature; + + char errbuf[1024]; + + /* start conversion of temperature */ + res = i2c_smbus_write_byte_data(i2c_bus_fd, BMP085_ADDR_CTRL_REG, + BMP085_CMD_CONVERT_TEMP); + if (res < 0) { + ERROR("barometer: BMP085_read - problem requesting temperature conversion: " + "%s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return 1; + } + + usleep(BMP085_TIME_CNV_TEMP); /* wait for the conversion */ + + res = + i2c_smbus_read_i2c_block_data(i2c_bus_fd, BMP085_ADDR_CONV, 2, measBuff); + if (res < 0) { + ERROR("barometer: BMP085_read - problem reading temperature data: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return 1; + } + + adc_temperature = ((unsigned short)measBuff[0] << 8) + measBuff[1]; + + /* get presure */ + res = i2c_smbus_write_byte_data(i2c_bus_fd, BMP085_ADDR_CTRL_REG, + bmp085_cmdCnvPress); + if (res < 0) { + ERROR("barometer: BMP085_read - problem requesting pressure conversion: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return 1; + } + + usleep(bmp085_timeCnvPress); /* wait for the conversion */ + + res = + i2c_smbus_read_i2c_block_data(i2c_bus_fd, BMP085_ADDR_CONV, 3, measBuff); + if (res < 0) { + ERROR("barometer: BMP085_read - problem reading pressure data: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return 1; + } + + adc_pressure = (long)((((ulong)measBuff[0] << 16) | + ((ulong)measBuff[1] << 8) | (ulong)measBuff[2]) >> + (8 - bmp085_oversampling)); + + DEBUG("barometer: BMP085_read - raw pressure ADC value = %ld, " + "raw temperature ADC value = %ld", + adc_pressure, adc_temperature); + + BMP085_convert_adc_to_real(adc_pressure, adc_temperature, pressure, + temperature); + + return 0; } - - /* ------------------------ Sensor detection ------------------------ */ /** * Detect presence of a supported sensor. @@ -1361,18 +1212,17 @@ static int BMP085_read(double * pressure, double * temperature) * * @return detected sensor type */ -static enum Sensor_type detect_sensor_type(void) -{ - if(BMP085_detect()) - return Sensor_BMP085; +static enum Sensor_type detect_sensor_type(void) { + if (BMP085_detect()) + return Sensor_BMP085; - else if(MPL3115_detect()) - return Sensor_MPL3115; + else if (MPL3115_detect()) + return Sensor_MPL3115; - else if(MPL115_detect()) - return Sensor_MPL115; + else if (MPL115_detect()) + return Sensor_MPL115; - return Sensor_none; + return Sensor_none; } /* ------------------------ Common functionality ------------------------ */ @@ -1383,7 +1233,8 @@ static enum Sensor_type detect_sensor_type(void) * Implemented methods are: * - MSLP_NONE - no converions, returns absolute pressure * - * - MSLP_INTERNATIONAL - see http://en.wikipedia.org/wiki/Atmospheric_pressure#Altitude_atmospheric_pressure_variation + * - MSLP_INTERNATIONAL - see + * http://en.wikipedia.org/wiki/Atmospheric_pressure#Altitude_atmospheric_pressure_variation * Requires #config_altitude * * - MSLP_DEU_WETT - formula as recommended by the Deutsche Wetterdienst. See @@ -1394,58 +1245,54 @@ static enum Sensor_type detect_sensor_type(void) * * @return mean sea level pressure if successful, NAN otherwise */ -static double abs_to_mean_sea_level_pressure(double abs_pressure) -{ - double mean = -1.0; - double temp = 0.0; - int result = 0; +static double abs_to_mean_sea_level_pressure(double abs_pressure) { + double mean = -1.0; + double temp = 0.0; + int result = 0; - if (config_normalize >= MSLP_DEU_WETT) - { - result = get_reference_temperature(&temp); - if(result) - { - return NAN; - } + if (config_normalize >= MSLP_DEU_WETT) { + result = get_reference_temperature(&temp); + if (result) { + return NAN; } + } - switch(config_normalize) - { - case MSLP_NONE: - mean = abs_pressure; - break; - - case MSLP_INTERNATIONAL: - mean = abs_pressure / \ - pow(1.0 - 0.0065*config_altitude/288.15, 9.80665*0.0289644/(8.31447*0.0065)); - break; + switch (config_normalize) { + case MSLP_NONE: + mean = abs_pressure; + break; - case MSLP_DEU_WETT: - { - double E; /* humidity */ - double x; - if(temp<9.1) - E = 5.6402 * (-0.0916 + exp(0.06*temp) ); - else - E = 18.2194 * (1.0463 - exp(-0.0666*temp) ); - x = 9.80665 / (287.05 * (temp+273.15 + 0.12*E + 0.0065*config_altitude/2)) * config_altitude; - mean = abs_pressure * exp(x); - } + case MSLP_INTERNATIONAL: + mean = abs_pressure / pow(1.0 - 0.0065 * config_altitude / 288.15, + 9.80665 * 0.0289644 / (8.31447 * 0.0065)); break; - default: - ERROR ("barometer: abs_to_mean_sea_level_pressure: wrong conversion method %d", - config_normalize); - mean = abs_pressure; - break; - } + case MSLP_DEU_WETT: { + double E; /* humidity */ + double x; + if (temp < 9.1) + E = 5.6402 * (-0.0916 + exp(0.06 * temp)); + else + E = 18.2194 * (1.0463 - exp(-0.0666 * temp)); + x = 9.80665 / + (287.05 * (temp + 273.15 + 0.12 * E + 0.0065 * config_altitude / 2)) * + config_altitude; + mean = abs_pressure * exp(x); + } break; + + default: + ERROR( + "barometer: abs_to_mean_sea_level_pressure: wrong conversion method %d", + config_normalize); + mean = abs_pressure; + break; + } - DEBUG ("barometer: abs_to_mean_sea_level_pressure: absPressure = %lf hPa, method = %d, meanPressure = %lf hPa", - abs_pressure, - config_normalize, - mean); + DEBUG("barometer: abs_to_mean_sea_level_pressure: absPressure = %lf hPa, " + "method = %d, meanPressure = %lf hPa", + abs_pressure, config_normalize, mean); - return mean; + return mean; } /* ------------------------ main plugin callbacks ------------------------ */ @@ -1458,66 +1305,47 @@ static double abs_to_mean_sea_level_pressure(double abs_pressure) * * @return Zero when successful. */ -static int collectd_barometer_config (const char *key, const char *value) -{ - DEBUG("barometer: collectd_barometer_config"); - - if (strcasecmp (key, "Device") == 0) - { - sfree (config_device); - config_device = strdup (value); - } - else if (strcasecmp (key, "Oversampling") == 0) - { - int oversampling_tmp = atoi (value); - if (oversampling_tmp < 1 || oversampling_tmp > 1024) - { - WARNING ("barometer: collectd_barometer_config: invalid oversampling: %d." \ - " Allowed values are 1 to 1024 (for MPL115) or 1 to 128 (for MPL3115) or 1 to 8 (for BMP085).", - oversampling_tmp); - return 1; - } - config_oversample = oversampling_tmp; - } - else if (strcasecmp (key, "Altitude") == 0) - { - config_altitude = atof (value); - } - else if (strcasecmp (key, "Normalization") == 0) - { - int normalize_tmp = atoi (value); - if (normalize_tmp < 0 || normalize_tmp > 2) - { - WARNING ("barometer: collectd_barometer_config: invalid normalization: %d", - normalize_tmp); - return 1; - } - config_normalize = normalize_tmp; - } - else if (strcasecmp (key, "TemperatureSensor") == 0) - { - if(temp_list_add(temp_list, value)) - { - return -1; - } - } - else if (strcasecmp (key, "PressureOffset") == 0) - { - config_press_offset = atof(value); - } - else if (strcasecmp (key, "TemperatureOffset") == 0) - { - config_temp_offset = atof(value); - } - else - { - return -1; - } - - return 0; +static int collectd_barometer_config(const char *key, const char *value) { + DEBUG("barometer: collectd_barometer_config"); + + if (strcasecmp(key, "Device") == 0) { + sfree(config_device); + config_device = strdup(value); + } else if (strcasecmp(key, "Oversampling") == 0) { + int oversampling_tmp = atoi(value); + if (oversampling_tmp < 1 || oversampling_tmp > 1024) { + WARNING("barometer: collectd_barometer_config: invalid oversampling: %d." + " Allowed values are 1 to 1024 (for MPL115) or 1 to 128 (for " + "MPL3115) or 1 to 8 (for BMP085).", + oversampling_tmp); + return 1; + } + config_oversample = oversampling_tmp; + } else if (strcasecmp(key, "Altitude") == 0) { + config_altitude = atof(value); + } else if (strcasecmp(key, "Normalization") == 0) { + int normalize_tmp = atoi(value); + if (normalize_tmp < 0 || normalize_tmp > 2) { + WARNING("barometer: collectd_barometer_config: invalid normalization: %d", + normalize_tmp); + return 1; + } + config_normalize = normalize_tmp; + } else if (strcasecmp(key, "TemperatureSensor") == 0) { + if (temp_list_add(temp_list, value)) { + return -1; + } + } else if (strcasecmp(key, "PressureOffset") == 0) { + config_press_offset = atof(value); + } else if (strcasecmp(key, "TemperatureOffset") == 0) { + config_temp_offset = atof(value); + } else { + return -1; + } + + return 0; } - /** * Shutdown callback. * @@ -1525,29 +1353,25 @@ static int collectd_barometer_config (const char *key, const char *value) * * @return Zero when successful (at the moment the only possible outcome) */ -static int collectd_barometer_shutdown(void) -{ - DEBUG ("barometer: collectd_barometer_shutdown"); +static int collectd_barometer_shutdown(void) { + DEBUG("barometer: collectd_barometer_shutdown"); - if(sensor_type == Sensor_MPL115) - { - averaging_delete (&pressure_averaging); - averaging_delete (&temperature_averaging); + if (sensor_type == Sensor_MPL115) { + averaging_delete(&pressure_averaging); + averaging_delete(&temperature_averaging); - temp_list_delete(&temp_list); - } + temp_list_delete(&temp_list); + } - if (i2c_bus_fd > 0) - { - close (i2c_bus_fd); - i2c_bus_fd = -1; - sfree (config_device); - } + if (i2c_bus_fd > 0) { + close(i2c_bus_fd); + i2c_bus_fd = -1; + sfree(config_device); + } - return 0; + return 0; } - /** * Plugin read callback for MPL115. * @@ -1558,76 +1382,72 @@ static int collectd_barometer_shutdown(void) * * @return Zero when successful. */ -static int MPL115_collectd_barometer_read (void) -{ - int result = 0; - - double pressure = 0.0; - double temperature = 0.0; - double norm_pressure = 0.0; - - value_list_t vl = VALUE_LIST_INIT; - value_t values[1]; - - DEBUG("barometer: MPL115_collectd_barometer_read"); - - if (!configured) - { - return -1; - } - - /* Rather than delaying init, we will intitialize during first read. This - way at least we have a better chance to have the reference temperature - already available. */ - if(!avg_initialized) - { - for(int i=0; i= MSLP_INTERNATIONAL && isnan(config_altitude)) - { - ERROR("barometer: collectd_barometer_init no altitude configured " \ - "for mean sea level pressure normalization."); - return -1; - } + if (config_normalize >= MSLP_INTERNATIONAL && isnan(config_altitude)) { + ERROR("barometer: collectd_barometer_init no altitude configured " + "for mean sea level pressure normalization."); + return -1; + } - if (config_normalize == MSLP_DEU_WETT - && - temp_list == NULL) - { - ERROR("barometer: collectd_barometer_init no temperature reference "\ - "configured for mean sea level pressure normalization."); - return -1; - } + if (config_normalize == MSLP_DEU_WETT && temp_list == NULL) { + ERROR("barometer: collectd_barometer_init no temperature reference " + "configured for mean sea level pressure normalization."); + return -1; + } + i2c_bus_fd = open(config_device, O_RDWR); + if (i2c_bus_fd < 0) { + ERROR("barometer: collectd_barometer_init problem opening I2C bus device " + "\"%s\": %s (is loaded mod i2c-dev?)", + config_device, sstrerror(errno, errbuf, sizeof(errbuf))); + return -1; + } - i2c_bus_fd = open(config_device, O_RDWR); - if (i2c_bus_fd < 0) - { - ERROR ("barometer: collectd_barometer_init problem opening I2C bus device \"%s\": %s (is loaded mod i2c-dev?)", - config_device, - sstrerror (errno, errbuf, sizeof (errbuf))); - return -1; - } + /* detect sensor type - this will also set slave address */ + sensor_type = detect_sensor_type(); - /* detect sensor type - this will also set slave address */ - sensor_type = detect_sensor_type(); + /* init correct sensor type */ + switch (sensor_type) { + /* MPL3115 */ + case Sensor_MPL3115: { + MPL3115_adjust_oversampling(); - /* init correct sensor type */ - switch(sensor_type) - { -/* MPL3115 */ - case Sensor_MPL3115: - { - MPL3115_adjust_oversampling(); + if (MPL3115_init_sensor()) + return -1; - if(MPL3115_init_sensor()) - return -1; + plugin_register_read("barometer", MPL3115_collectd_barometer_read); + } break; - plugin_register_read ("barometer", MPL3115_collectd_barometer_read); + /* MPL115 */ + case Sensor_MPL115: { + if (averaging_create(&pressure_averaging, config_oversample)) { + ERROR( + "barometer: collectd_barometer_init pressure averaging init failed"); + return -1; } - break; - -/* MPL115 */ - case Sensor_MPL115: - { - if (averaging_create (&pressure_averaging, config_oversample)) - { - ERROR("barometer: collectd_barometer_init pressure averaging init failed"); - return -1; - } - - if (averaging_create (&temperature_averaging, config_oversample)) - { - ERROR("barometer: collectd_barometer_init temperature averaging init failed"); - return -1; - } - - if (MPL115_read_coeffs() < 0) - return -1; - plugin_register_read ("barometer", MPL115_collectd_barometer_read); + if (averaging_create(&temperature_averaging, config_oversample)) { + ERROR("barometer: collectd_barometer_init temperature averaging init " + "failed"); + return -1; } - break; -/* BMP085 */ - case Sensor_BMP085: - { - BMP085_adjust_oversampling(); + if (MPL115_read_coeffs() < 0) + return -1; - if (BMP085_read_coeffs() < 0) - return -1; + plugin_register_read("barometer", MPL115_collectd_barometer_read); + } break; - plugin_register_read ("barometer", BMP085_collectd_barometer_read); - } - break; + /* BMP085 */ + case Sensor_BMP085: { + BMP085_adjust_oversampling(); -/* anything else -> error */ - default: - ERROR("barometer: collectd_barometer_init - no supported sensor found"); - return -1; - } + if (BMP085_read_coeffs() < 0) + return -1; + plugin_register_read("barometer", BMP085_collectd_barometer_read); + } break; - configured = 1; - return 0; + /* anything else -> error */ + default: + ERROR("barometer: collectd_barometer_init - no supported sensor found"); + return -1; + } + + configured = 1; + return 0; } -/* ------------------------ plugin register / entry point ------------------------ */ +/* ------------------------ plugin register / entry point + * ------------------------ */ /** * Plugin "entry" - register all callback. * */ -void module_register (void) -{ - plugin_register_config ("barometer", - collectd_barometer_config, - config_keys, - config_keys_num); - plugin_register_init ("barometer", collectd_barometer_init); - plugin_register_shutdown ("barometer", collectd_barometer_shutdown); +void module_register(void) { + plugin_register_config("barometer", collectd_barometer_config, config_keys, + config_keys_num); + plugin_register_init("barometer", collectd_barometer_init); + plugin_register_shutdown("barometer", collectd_barometer_shutdown); } diff --git a/src/battery.c b/src/battery.c index fbc64f47..5c02fee2 100644 --- a/src/battery.c +++ b/src/battery.c @@ -29,354 +29,312 @@ #include "plugin.h" #if HAVE_MACH_MACH_TYPES_H -# include +#include #endif #if HAVE_MACH_MACH_INIT_H -# include +#include #endif #if HAVE_MACH_MACH_ERROR_H -# include +#include #endif #if HAVE_COREFOUNDATION_COREFOUNDATION_H -# include +#include #endif #if HAVE_IOKIT_IOKITLIB_H -# include +#include #endif #if HAVE_IOKIT_IOTYPES_H -# include +#include #endif #if HAVE_IOKIT_PS_IOPOWERSOURCES_H -# include +#include #endif #if HAVE_IOKIT_PS_IOPSKEYS_H -# include +#include #endif #if !HAVE_IOKIT_IOKITLIB_H && !HAVE_IOKIT_PS_IOPOWERSOURCES_H && !KERNEL_LINUX -# error "No applicable input method." +#error "No applicable input method." #endif #if HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H - /* No global variables */ +/* No global variables */ /* #endif HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H */ #elif KERNEL_LINUX -# define PROC_PMU_PATH_FORMAT "/proc/pmu/battery_%i" -# define PROC_ACPI_PATH "/proc/acpi/battery" -# define PROC_ACPI_FACTOR 0.001 -# define SYSFS_PATH "/sys/class/power_supply" -# define SYSFS_FACTOR 0.000001 +#define PROC_PMU_PATH_FORMAT "/proc/pmu/battery_%i" +#define PROC_ACPI_PATH "/proc/acpi/battery" +#define PROC_ACPI_FACTOR 0.001 +#define SYSFS_PATH "/sys/class/power_supply" +#define SYSFS_FACTOR 0.000001 #endif /* KERNEL_LINUX */ -int battery_read_statefs (void); /* defined in battery_statefs; used by StateFS backend */ +int battery_read_statefs( + void); /* defined in battery_statefs; used by StateFS backend */ static _Bool report_percent = 0; static _Bool report_degraded = 0; static _Bool query_statefs = 0; -static void battery_submit2 (char const *plugin_instance, /* {{{ */ - char const *type, char const *type_instance, gauge_t value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void battery_submit2(char const *plugin_instance, /* {{{ */ + char const *type, char const *type_instance, + gauge_t value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "battery", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "battery", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + if (type_instance != NULL) + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* }}} void battery_submit2 */ -static void battery_submit (char const *plugin_instance, /* {{{ */ - char const *type, gauge_t value) -{ - battery_submit2 (plugin_instance, type, NULL, value); +static void battery_submit(char const *plugin_instance, /* {{{ */ + char const *type, gauge_t value) { + battery_submit2(plugin_instance, type, NULL, value); } /* }}} void battery_submit */ -static void submit_capacity (char const *plugin_instance, /* {{{ */ - gauge_t capacity_charged, - gauge_t capacity_full, - gauge_t capacity_design) -{ - if (report_percent && (capacity_charged > capacity_full)) - return; - if (report_degraded && (capacity_full > capacity_design)) - return; - - if (report_percent) - { - gauge_t capacity_max; - - if (report_degraded) - capacity_max = capacity_design; - else - capacity_max = capacity_full; - - battery_submit2 (plugin_instance, "percent", "charged", - 100.0 * capacity_charged / capacity_max); - battery_submit2 (plugin_instance, "percent", "discharged", - 100.0 * (capacity_full - capacity_charged) / capacity_max); - - if (report_degraded) - battery_submit2 (plugin_instance, "percent", "degraded", - 100.0 * (capacity_design - capacity_full) / capacity_max); - } - else if (report_degraded) /* && !report_percent */ - { - battery_submit2 (plugin_instance, "capacity", "charged", - capacity_charged); - battery_submit2 (plugin_instance, "capacity", "discharged", - (capacity_full - capacity_charged)); - battery_submit2 (plugin_instance, "capacity", "degraded", - (capacity_design - capacity_full)); - } - else /* !report_percent && !report_degraded */ - { - battery_submit (plugin_instance, "capacity", capacity_charged); - } +static void submit_capacity(char const *plugin_instance, /* {{{ */ + gauge_t capacity_charged, gauge_t capacity_full, + gauge_t capacity_design) { + if (report_percent && (capacity_charged > capacity_full)) + return; + if (report_degraded && (capacity_full > capacity_design)) + return; + + if (report_percent) { + gauge_t capacity_max; + + if (report_degraded) + capacity_max = capacity_design; + else + capacity_max = capacity_full; + + battery_submit2(plugin_instance, "percent", "charged", + 100.0 * capacity_charged / capacity_max); + battery_submit2(plugin_instance, "percent", "discharged", + 100.0 * (capacity_full - capacity_charged) / capacity_max); + + if (report_degraded) + battery_submit2(plugin_instance, "percent", "degraded", + 100.0 * (capacity_design - capacity_full) / capacity_max); + } else if (report_degraded) /* && !report_percent */ + { + battery_submit2(plugin_instance, "capacity", "charged", capacity_charged); + battery_submit2(plugin_instance, "capacity", "discharged", + (capacity_full - capacity_charged)); + battery_submit2(plugin_instance, "capacity", "degraded", + (capacity_design - capacity_full)); + } else /* !report_percent && !report_degraded */ + { + battery_submit(plugin_instance, "capacity", capacity_charged); + } } /* }}} void submit_capacity */ #if HAVE_IOKIT_PS_IOPOWERSOURCES_H || HAVE_IOKIT_IOKITLIB_H -static double dict_get_double (CFDictionaryRef dict, const char *key_string) /* {{{ */ +static double dict_get_double(CFDictionaryRef dict, + const char *key_string) /* {{{ */ { - double val_double; - long long val_int; - CFNumberRef val_obj; - CFStringRef key_obj; - - key_obj = CFStringCreateWithCString (kCFAllocatorDefault, key_string, - kCFStringEncodingASCII); - if (key_obj == NULL) - { - DEBUG ("CFStringCreateWithCString (%s) failed.\n", key_string); - return (NAN); - } - - if ((val_obj = CFDictionaryGetValue (dict, key_obj)) == NULL) - { - DEBUG ("CFDictionaryGetValue (%s) failed.", key_string); - CFRelease (key_obj); - return (NAN); - } - CFRelease (key_obj); - - if (CFGetTypeID (val_obj) == CFNumberGetTypeID ()) - { - if (CFNumberIsFloatType (val_obj)) - { - CFNumberGetValue (val_obj, - kCFNumberDoubleType, - &val_double); - } - else - { - CFNumberGetValue (val_obj, - kCFNumberLongLongType, - &val_int); - val_double = val_int; - } - } - else - { - DEBUG ("CFGetTypeID (val_obj) = %i", (int) CFGetTypeID (val_obj)); - return (NAN); - } - - return (val_double); + double val_double; + long long val_int; + CFNumberRef val_obj; + CFStringRef key_obj; + + key_obj = CFStringCreateWithCString(kCFAllocatorDefault, key_string, + kCFStringEncodingASCII); + if (key_obj == NULL) { + DEBUG("CFStringCreateWithCString (%s) failed.\n", key_string); + return (NAN); + } + + if ((val_obj = CFDictionaryGetValue(dict, key_obj)) == NULL) { + DEBUG("CFDictionaryGetValue (%s) failed.", key_string); + CFRelease(key_obj); + return (NAN); + } + CFRelease(key_obj); + + if (CFGetTypeID(val_obj) == CFNumberGetTypeID()) { + if (CFNumberIsFloatType(val_obj)) { + CFNumberGetValue(val_obj, kCFNumberDoubleType, &val_double); + } else { + CFNumberGetValue(val_obj, kCFNumberLongLongType, &val_int); + val_double = val_int; + } + } else { + DEBUG("CFGetTypeID (val_obj) = %i", (int)CFGetTypeID(val_obj)); + return (NAN); + } + + return (val_double); } /* }}} double dict_get_double */ -# if HAVE_IOKIT_PS_IOPOWERSOURCES_H -static void get_via_io_power_sources (double *ret_charge, /* {{{ */ - double *ret_current, - double *ret_voltage) -{ - CFTypeRef ps_raw; - CFArrayRef ps_array; - int ps_array_len; - CFDictionaryRef ps_dict; - CFTypeRef ps_obj; - - double temp_double; - - ps_raw = IOPSCopyPowerSourcesInfo (); - ps_array = IOPSCopyPowerSourcesList (ps_raw); - ps_array_len = CFArrayGetCount (ps_array); - - DEBUG ("ps_array_len == %i", ps_array_len); - - for (int i = 0; i < ps_array_len; i++) - { - ps_obj = CFArrayGetValueAtIndex (ps_array, i); - ps_dict = IOPSGetPowerSourceDescription (ps_raw, ps_obj); - - if (ps_dict == NULL) - { - DEBUG ("IOPSGetPowerSourceDescription failed."); - continue; - } - - if (CFGetTypeID (ps_dict) != CFDictionaryGetTypeID ()) - { - DEBUG ("IOPSGetPowerSourceDescription did not return a CFDictionaryRef"); - continue; - } - - /* FIXME: Check if this is really an internal battery */ - - if (isnan (*ret_charge)) - { - /* This is the charge in percent. */ - temp_double = dict_get_double (ps_dict, - kIOPSCurrentCapacityKey); - if (!isnan ((temp_double)) - && (temp_double >= 0.0) - && (temp_double <= 100.0)) - *ret_charge = temp_double; - } - - if (isnan (*ret_current)) - { - temp_double = dict_get_double (ps_dict, - kIOPSCurrentKey); - if (!isnan (temp_double)) - *ret_current = temp_double / 1000.0; - } - - if (isnan (*ret_voltage)) - { - temp_double = dict_get_double (ps_dict, - kIOPSVoltageKey); - if (!isnan (temp_double)) - *ret_voltage = temp_double / 1000.0; - } - } - - CFRelease(ps_array); - CFRelease(ps_raw); +#if HAVE_IOKIT_PS_IOPOWERSOURCES_H +static void get_via_io_power_sources(double *ret_charge, /* {{{ */ + double *ret_current, double *ret_voltage) { + CFTypeRef ps_raw; + CFArrayRef ps_array; + int ps_array_len; + CFDictionaryRef ps_dict; + CFTypeRef ps_obj; + + double temp_double; + + ps_raw = IOPSCopyPowerSourcesInfo(); + ps_array = IOPSCopyPowerSourcesList(ps_raw); + ps_array_len = CFArrayGetCount(ps_array); + + DEBUG("ps_array_len == %i", ps_array_len); + + for (int i = 0; i < ps_array_len; i++) { + ps_obj = CFArrayGetValueAtIndex(ps_array, i); + ps_dict = IOPSGetPowerSourceDescription(ps_raw, ps_obj); + + if (ps_dict == NULL) { + DEBUG("IOPSGetPowerSourceDescription failed."); + continue; + } + + if (CFGetTypeID(ps_dict) != CFDictionaryGetTypeID()) { + DEBUG("IOPSGetPowerSourceDescription did not return a CFDictionaryRef"); + continue; + } + + /* FIXME: Check if this is really an internal battery */ + + if (isnan(*ret_charge)) { + /* This is the charge in percent. */ + temp_double = dict_get_double(ps_dict, kIOPSCurrentCapacityKey); + if (!isnan((temp_double)) && (temp_double >= 0.0) && + (temp_double <= 100.0)) + *ret_charge = temp_double; + } + + if (isnan(*ret_current)) { + temp_double = dict_get_double(ps_dict, kIOPSCurrentKey); + if (!isnan(temp_double)) + *ret_current = temp_double / 1000.0; + } + + if (isnan(*ret_voltage)) { + temp_double = dict_get_double(ps_dict, kIOPSVoltageKey); + if (!isnan(temp_double)) + *ret_voltage = temp_double / 1000.0; + } + } + + CFRelease(ps_array); + CFRelease(ps_raw); } /* }}} void get_via_io_power_sources */ -# endif /* HAVE_IOKIT_PS_IOPOWERSOURCES_H */ +#endif /* HAVE_IOKIT_PS_IOPOWERSOURCES_H */ -# if HAVE_IOKIT_IOKITLIB_H -static void get_via_generic_iokit (double *ret_capacity_full, /* {{{ */ - double *ret_capacity_design, - double *ret_current, - double *ret_voltage) -{ - kern_return_t status; - io_iterator_t iterator; - io_object_t io_obj; - - CFDictionaryRef bat_root_dict; - CFArrayRef bat_info_arry; - CFIndex bat_info_arry_len; - CFDictionaryRef bat_info_dict; - - double temp_double; - - status = IOServiceGetMatchingServices (kIOMasterPortDefault, - IOServiceNameMatching ("battery"), - &iterator); - if (status != kIOReturnSuccess) - { - DEBUG ("IOServiceGetMatchingServices failed."); - return; - } - - while ((io_obj = IOIteratorNext (iterator))) - { - status = IORegistryEntryCreateCFProperties (io_obj, - (CFMutableDictionaryRef *) &bat_root_dict, - kCFAllocatorDefault, - kNilOptions); - if (status != kIOReturnSuccess) - { - DEBUG ("IORegistryEntryCreateCFProperties failed."); - continue; - } - - bat_info_arry = (CFArrayRef) CFDictionaryGetValue (bat_root_dict, - CFSTR ("IOBatteryInfo")); - if (bat_info_arry == NULL) - { - CFRelease (bat_root_dict); - continue; - } - bat_info_arry_len = CFArrayGetCount (bat_info_arry); - - for (CFIndex bat_info_arry_pos = 0; - bat_info_arry_pos < bat_info_arry_len; - bat_info_arry_pos++) - { - bat_info_dict = (CFDictionaryRef) CFArrayGetValueAtIndex (bat_info_arry, bat_info_arry_pos); - - if (isnan (*ret_capacity_full)) - { - temp_double = dict_get_double (bat_info_dict, "Capacity"); - *ret_capacity_full = temp_double / 1000.0; - } - - if (isnan (*ret_capacity_design)) - { - temp_double = dict_get_double (bat_info_dict, "AbsoluteMaxCapacity"); - *ret_capacity_design = temp_double / 1000.0; - } - - if (isnan (*ret_current)) - { - temp_double = dict_get_double (bat_info_dict, "Current"); - *ret_current = temp_double / 1000.0; - } - - if (isnan (*ret_voltage)) - { - temp_double = dict_get_double (bat_info_dict, "Voltage"); - *ret_voltage = temp_double / 1000.0; - } - } - - CFRelease (bat_root_dict); - } - - IOObjectRelease (iterator); +#if HAVE_IOKIT_IOKITLIB_H +static void get_via_generic_iokit(double *ret_capacity_full, /* {{{ */ + double *ret_capacity_design, + double *ret_current, double *ret_voltage) { + kern_return_t status; + io_iterator_t iterator; + io_object_t io_obj; + + CFDictionaryRef bat_root_dict; + CFArrayRef bat_info_arry; + CFIndex bat_info_arry_len; + CFDictionaryRef bat_info_dict; + + double temp_double; + + status = IOServiceGetMatchingServices( + kIOMasterPortDefault, IOServiceNameMatching("battery"), &iterator); + if (status != kIOReturnSuccess) { + DEBUG("IOServiceGetMatchingServices failed."); + return; + } + + while ((io_obj = IOIteratorNext(iterator))) { + status = IORegistryEntryCreateCFProperties( + io_obj, (CFMutableDictionaryRef *)&bat_root_dict, kCFAllocatorDefault, + kNilOptions); + if (status != kIOReturnSuccess) { + DEBUG("IORegistryEntryCreateCFProperties failed."); + continue; + } + + bat_info_arry = + (CFArrayRef)CFDictionaryGetValue(bat_root_dict, CFSTR("IOBatteryInfo")); + if (bat_info_arry == NULL) { + CFRelease(bat_root_dict); + continue; + } + bat_info_arry_len = CFArrayGetCount(bat_info_arry); + + for (CFIndex bat_info_arry_pos = 0; bat_info_arry_pos < bat_info_arry_len; + bat_info_arry_pos++) { + bat_info_dict = (CFDictionaryRef)CFArrayGetValueAtIndex( + bat_info_arry, bat_info_arry_pos); + + if (isnan(*ret_capacity_full)) { + temp_double = dict_get_double(bat_info_dict, "Capacity"); + *ret_capacity_full = temp_double / 1000.0; + } + + if (isnan(*ret_capacity_design)) { + temp_double = dict_get_double(bat_info_dict, "AbsoluteMaxCapacity"); + *ret_capacity_design = temp_double / 1000.0; + } + + if (isnan(*ret_current)) { + temp_double = dict_get_double(bat_info_dict, "Current"); + *ret_current = temp_double / 1000.0; + } + + if (isnan(*ret_voltage)) { + temp_double = dict_get_double(bat_info_dict, "Voltage"); + *ret_voltage = temp_double / 1000.0; + } + } + + CFRelease(bat_root_dict); + } + + IOObjectRelease(iterator); } /* }}} void get_via_generic_iokit */ -# endif /* HAVE_IOKIT_IOKITLIB_H */ +#endif /* HAVE_IOKIT_IOKITLIB_H */ -static int battery_read (void) /* {{{ */ +static int battery_read(void) /* {{{ */ { - gauge_t current = NAN; /* Current in A */ - gauge_t voltage = NAN; /* Voltage in V */ + gauge_t current = NAN; /* Current in A */ + gauge_t voltage = NAN; /* Voltage in V */ - /* We only get the charged capacity as a percentage from - * IOPowerSources. IOKit, on the other hand, only reports the full - * capacity. We use the two to calculate the current charged capacity. */ - gauge_t charge_rel = NAN; /* Current charge in percent */ - gauge_t capacity_charged; /* Charged capacity */ - gauge_t capacity_full = NAN; /* Total capacity */ - gauge_t capacity_design = NAN; /* Full design capacity */ + /* We only get the charged capacity as a percentage from + * IOPowerSources. IOKit, on the other hand, only reports the full + * capacity. We use the two to calculate the current charged capacity. */ + gauge_t charge_rel = NAN; /* Current charge in percent */ + gauge_t capacity_charged; /* Charged capacity */ + gauge_t capacity_full = NAN; /* Total capacity */ + gauge_t capacity_design = NAN; /* Full design capacity */ - if (query_statefs) - return battery_read_statefs (); + if (query_statefs) + return battery_read_statefs(); #if HAVE_IOKIT_PS_IOPOWERSOURCES_H - get_via_io_power_sources (&charge_rel, ¤t, &voltage); + get_via_io_power_sources(&charge_rel, ¤t, &voltage); #endif #if HAVE_IOKIT_IOKITLIB_H - get_via_generic_iokit (&capacity_full, &capacity_design, ¤t, &voltage); + get_via_generic_iokit(&capacity_full, &capacity_design, ¤t, &voltage); #endif - capacity_charged = charge_rel * capacity_full / 100.0; - submit_capacity ("0", capacity_charged, capacity_full, capacity_design); + capacity_charged = charge_rel * capacity_full / 100.0; + submit_capacity("0", capacity_charged, capacity_full, capacity_design); - if (!isnan (current)) - battery_submit ("0", "current", current); - if (!isnan (voltage)) - battery_submit ("0", "voltage", voltage); + if (!isnan(current)) + battery_submit("0", "current", current); + if (!isnan(voltage)) + battery_submit("0", "voltage", voltage); - return (0); + return (0); } /* }}} int battery_read */ /* #endif HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H */ @@ -384,418 +342,395 @@ static int battery_read (void) /* {{{ */ /* Reads a file which contains only a number (and optionally a trailing * newline) and parses that number. */ static int sysfs_file_to_buffer(char const *dir, /* {{{ */ - char const *power_supply, - char const *basename, - char *buffer, size_t buffer_size) -{ - char filename[PATH_MAX]; - int status; + char const *power_supply, char const *basename, + char *buffer, size_t buffer_size) { + char filename[PATH_MAX]; + int status; - ssnprintf (filename, sizeof (filename), "%s/%s/%s", - dir, power_supply, basename); + ssnprintf(filename, sizeof(filename), "%s/%s/%s", dir, power_supply, + basename); - status = (int) read_file_contents (filename, buffer, buffer_size); - if (status < 0) - return status; + status = (int)read_file_contents(filename, buffer, buffer_size); + if (status < 0) + return status; - strstripnewline (buffer); - return 0; + strstripnewline(buffer); + return 0; } /* }}} int sysfs_file_to_buffer */ /* Reads a file which contains only a number (and optionally a trailing * newline) and parses that number. */ static int sysfs_file_to_gauge(char const *dir, /* {{{ */ - char const *power_supply, - char const *basename, gauge_t *ret_value) -{ - int status; - char buffer[32] = ""; + char const *power_supply, char const *basename, + gauge_t *ret_value) { + int status; + char buffer[32] = ""; - status = sysfs_file_to_buffer (dir, power_supply, basename, buffer, sizeof (buffer)); - if (status != 0) - return (status); + status = + sysfs_file_to_buffer(dir, power_supply, basename, buffer, sizeof(buffer)); + if (status != 0) + return (status); - return (strtogauge (buffer, ret_value)); + return (strtogauge(buffer, ret_value)); } /* }}} sysfs_file_to_gauge */ -static int read_sysfs_capacity (char const *dir, /* {{{ */ - char const *power_supply, - char const *plugin_instance) -{ - gauge_t capacity_charged = NAN; - gauge_t capacity_full = NAN; - gauge_t capacity_design = NAN; - int status; - - status = sysfs_file_to_gauge (dir, power_supply, "energy_now", &capacity_charged); - if (status != 0) - return (status); - - status = sysfs_file_to_gauge (dir, power_supply, "energy_full", &capacity_full); - if (status != 0) - return (status); - - status = sysfs_file_to_gauge (dir, power_supply, "energy_full_design", &capacity_design); - if (status != 0) - return (status); - - submit_capacity (plugin_instance, - capacity_charged * SYSFS_FACTOR, - capacity_full * SYSFS_FACTOR, - capacity_design * SYSFS_FACTOR); - return (0); +static int read_sysfs_capacity(char const *dir, /* {{{ */ + char const *power_supply, + char const *plugin_instance) { + gauge_t capacity_charged = NAN; + gauge_t capacity_full = NAN; + gauge_t capacity_design = NAN; + int status; + + status = + sysfs_file_to_gauge(dir, power_supply, "energy_now", &capacity_charged); + if (status != 0) + return (status); + + status = + sysfs_file_to_gauge(dir, power_supply, "energy_full", &capacity_full); + if (status != 0) + return (status); + + status = sysfs_file_to_gauge(dir, power_supply, "energy_full_design", + &capacity_design); + if (status != 0) + return (status); + + submit_capacity(plugin_instance, capacity_charged * SYSFS_FACTOR, + capacity_full * SYSFS_FACTOR, capacity_design * SYSFS_FACTOR); + return (0); } /* }}} int read_sysfs_capacity */ -static int read_sysfs_callback (char const *dir, /* {{{ */ - char const *power_supply, - void *user_data) -{ - int *battery_index = user_data; - - char const *plugin_instance; - char buffer[32]; - gauge_t v = NAN; - _Bool discharging = 0; - int status; - - /* Ignore non-battery directories, such as AC power. */ - status = sysfs_file_to_buffer (dir, power_supply, "type", buffer, sizeof (buffer)); - if (status != 0) - return (0); - if (strcasecmp ("Battery", buffer) != 0) - return (0); - - (void) sysfs_file_to_buffer (dir, power_supply, "status", buffer, sizeof (buffer)); - if (strcasecmp ("Discharging", buffer) == 0) - discharging = 1; - - /* FIXME: This is a dirty hack for backwards compatibility: The battery - * plugin, for a very long time, has had the plugin_instance - * hard-coded to "0". So, to keep backwards compatibility, we'll use - * "0" for the first battery we find and the power_supply name for all - * following. This should be reverted in a future major version. */ - plugin_instance = (*battery_index == 0) ? "0" : power_supply; - (*battery_index)++; - - read_sysfs_capacity (dir, power_supply, plugin_instance); - - if (sysfs_file_to_gauge (dir, power_supply, "power_now", &v) == 0) - { - if (discharging) - v *= -1.0; - battery_submit (plugin_instance, "power", v * SYSFS_FACTOR); - } - if (sysfs_file_to_gauge (dir, power_supply, "current_now", &v) == 0) - { - if (discharging) - v *= -1.0; - battery_submit (plugin_instance, "current", v * SYSFS_FACTOR); - } - - if (sysfs_file_to_gauge (dir, power_supply, "voltage_now", &v) == 0) - battery_submit (plugin_instance, "voltage", v * SYSFS_FACTOR); - - return (0); +static int read_sysfs_callback(char const *dir, /* {{{ */ + char const *power_supply, void *user_data) { + int *battery_index = user_data; + + char const *plugin_instance; + char buffer[32]; + gauge_t v = NAN; + _Bool discharging = 0; + int status; + + /* Ignore non-battery directories, such as AC power. */ + status = + sysfs_file_to_buffer(dir, power_supply, "type", buffer, sizeof(buffer)); + if (status != 0) + return (0); + if (strcasecmp("Battery", buffer) != 0) + return (0); + + (void)sysfs_file_to_buffer(dir, power_supply, "status", buffer, + sizeof(buffer)); + if (strcasecmp("Discharging", buffer) == 0) + discharging = 1; + + /* FIXME: This is a dirty hack for backwards compatibility: The battery + * plugin, for a very long time, has had the plugin_instance + * hard-coded to "0". So, to keep backwards compatibility, we'll use + * "0" for the first battery we find and the power_supply name for all + * following. This should be reverted in a future major version. */ + plugin_instance = (*battery_index == 0) ? "0" : power_supply; + (*battery_index)++; + + read_sysfs_capacity(dir, power_supply, plugin_instance); + + if (sysfs_file_to_gauge(dir, power_supply, "power_now", &v) == 0) { + if (discharging) + v *= -1.0; + battery_submit(plugin_instance, "power", v * SYSFS_FACTOR); + } + if (sysfs_file_to_gauge(dir, power_supply, "current_now", &v) == 0) { + if (discharging) + v *= -1.0; + battery_submit(plugin_instance, "current", v * SYSFS_FACTOR); + } + + if (sysfs_file_to_gauge(dir, power_supply, "voltage_now", &v) == 0) + battery_submit(plugin_instance, "voltage", v * SYSFS_FACTOR); + + return (0); } /* }}} int read_sysfs_callback */ -static int read_sysfs (void) /* {{{ */ +static int read_sysfs(void) /* {{{ */ { - int status; - int battery_counter = 0; + int status; + int battery_counter = 0; - if (access (SYSFS_PATH, R_OK) != 0) - return (ENOENT); + if (access(SYSFS_PATH, R_OK) != 0) + return (ENOENT); - status = walk_directory (SYSFS_PATH, read_sysfs_callback, - /* user_data = */ &battery_counter, - /* include hidden */ 0); - return (status); + status = walk_directory(SYSFS_PATH, read_sysfs_callback, + /* user_data = */ &battery_counter, + /* include hidden */ 0); + return (status); } /* }}} int read_sysfs */ -static int read_acpi_full_capacity (char const *dir, /* {{{ */ - char const *power_supply, - gauge_t *ret_capacity_full, - gauge_t *ret_capacity_design) +static int read_acpi_full_capacity(char const *dir, /* {{{ */ + char const *power_supply, + gauge_t *ret_capacity_full, + gauge_t *ret_capacity_design) { - char filename[PATH_MAX]; - char buffer[1024]; - - FILE *fh; - - ssnprintf (filename, sizeof (filename), "%s/%s/info", dir, power_supply); - fh = fopen (filename, "r"); - if (fh == NULL) - return (errno); - - /* last full capacity: 40090 mWh */ - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - gauge_t *value_ptr; - int fields_num; - char *fields[8]; - int index; - - if (strncmp ("last full capacity:", buffer, strlen ("last full capacity:")) == 0) - { - value_ptr = ret_capacity_full; - index = 3; - } - else if (strncmp ("design capacity:", buffer, strlen ("design capacity:")) == 0) - { - value_ptr = ret_capacity_design; - index = 2; - } - else - { - continue; - } - - fields_num = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields)); - if (fields_num <= index) - continue; - - strtogauge (fields[index], value_ptr); - } - - fclose (fh); - return (0); + char filename[PATH_MAX]; + char buffer[1024]; + + FILE *fh; + + ssnprintf(filename, sizeof(filename), "%s/%s/info", dir, power_supply); + fh = fopen(filename, "r"); + if (fh == NULL) + return (errno); + + /* last full capacity: 40090 mWh */ + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + gauge_t *value_ptr; + int fields_num; + char *fields[8]; + int index; + + if (strncmp("last full capacity:", buffer, strlen("last full capacity:")) == + 0) { + value_ptr = ret_capacity_full; + index = 3; + } else if (strncmp("design capacity:", buffer, + strlen("design capacity:")) == 0) { + value_ptr = ret_capacity_design; + index = 2; + } else { + continue; + } + + fields_num = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + if (fields_num <= index) + continue; + + strtogauge(fields[index], value_ptr); + } + + fclose(fh); + return (0); } /* }}} int read_acpi_full_capacity */ -static int read_acpi_callback (char const *dir, /* {{{ */ - char const *power_supply, - void *user_data) -{ - int *battery_index = user_data; - - gauge_t power = NAN; - gauge_t voltage = NAN; - gauge_t capacity_charged = NAN; - gauge_t capacity_full = NAN; - gauge_t capacity_design = NAN; - _Bool charging = 0; - _Bool is_current = 0; - - char const *plugin_instance; - char filename[PATH_MAX]; - char buffer[1024]; - - FILE *fh; - - ssnprintf (filename, sizeof (filename), "%s/%s/state", dir, power_supply); - fh = fopen (filename, "r"); - if (fh == NULL) - { - if ((errno == EAGAIN) || (errno == EINTR) || (errno == ENOENT)) - return (0); - else - return (errno); - } - - /* - * [11:00] <@tokkee> $ cat /proc/acpi/battery/BAT1/state - * [11:00] <@tokkee> present: yes - * [11:00] <@tokkee> capacity state: ok - * [11:00] <@tokkee> charging state: charging - * [11:00] <@tokkee> present rate: 1724 mA - * [11:00] <@tokkee> remaining capacity: 4136 mAh - * [11:00] <@tokkee> present voltage: 12428 mV - */ - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - char *fields[8]; - int numfields; - - numfields = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields)); - if (numfields < 3) - continue; - - if ((strcmp (fields[0], "charging") == 0) - && (strcmp (fields[1], "state:") == 0)) - { - if (strcmp (fields[2], "charging") == 0) - charging = 1; - else - charging = 0; - continue; - } - - /* The unit of "present rate" depends on the battery. Modern - * batteries export power (watts), older batteries (used to) - * export current (amperes). We check the fourth column and try - * to find old batteries this way. */ - if ((strcmp (fields[0], "present") == 0) - && (strcmp (fields[1], "rate:") == 0)) - { - strtogauge (fields[2], &power); - - if ((numfields >= 4) && (strcmp ("mA", fields[3]) == 0)) - is_current = 1; - } - else if ((strcmp (fields[0], "remaining") == 0) - && (strcmp (fields[1], "capacity:") == 0)) - strtogauge (fields[2], &capacity_charged); - else if ((strcmp (fields[0], "present") == 0) - && (strcmp (fields[1], "voltage:") == 0)) - strtogauge (fields[2], &voltage); - } /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */ - - fclose (fh); - - if (!charging) - power *= -1.0; - - /* FIXME: This is a dirty hack for backwards compatibility: The battery - * plugin, for a very long time, has had the plugin_instance - * hard-coded to "0". So, to keep backwards compatibility, we'll use - * "0" for the first battery we find and the power_supply name for all - * following. This should be reverted in a future major version. */ - plugin_instance = (*battery_index == 0) ? "0" : power_supply; - (*battery_index)++; - - read_acpi_full_capacity (dir, power_supply, &capacity_full, &capacity_design); - - submit_capacity (plugin_instance, - capacity_charged * PROC_ACPI_FACTOR, - capacity_full * PROC_ACPI_FACTOR, - capacity_design * PROC_ACPI_FACTOR); - - battery_submit (plugin_instance, - is_current ? "current" : "power", - power * PROC_ACPI_FACTOR); - battery_submit (plugin_instance, "voltage", voltage * PROC_ACPI_FACTOR); - - return 0; +static int read_acpi_callback(char const *dir, /* {{{ */ + char const *power_supply, void *user_data) { + int *battery_index = user_data; + + gauge_t power = NAN; + gauge_t voltage = NAN; + gauge_t capacity_charged = NAN; + gauge_t capacity_full = NAN; + gauge_t capacity_design = NAN; + _Bool charging = 0; + _Bool is_current = 0; + + char const *plugin_instance; + char filename[PATH_MAX]; + char buffer[1024]; + + FILE *fh; + + ssnprintf(filename, sizeof(filename), "%s/%s/state", dir, power_supply); + fh = fopen(filename, "r"); + if (fh == NULL) { + if ((errno == EAGAIN) || (errno == EINTR) || (errno == ENOENT)) + return (0); + else + return (errno); + } + + /* + * [11:00] <@tokkee> $ cat /proc/acpi/battery/BAT1/state + * [11:00] <@tokkee> present: yes + * [11:00] <@tokkee> capacity state: ok + * [11:00] <@tokkee> charging state: charging + * [11:00] <@tokkee> present rate: 1724 mA + * [11:00] <@tokkee> remaining capacity: 4136 mAh + * [11:00] <@tokkee> present voltage: 12428 mV + */ + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + char *fields[8]; + int numfields; + + numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + if (numfields < 3) + continue; + + if ((strcmp(fields[0], "charging") == 0) && + (strcmp(fields[1], "state:") == 0)) { + if (strcmp(fields[2], "charging") == 0) + charging = 1; + else + charging = 0; + continue; + } + + /* The unit of "present rate" depends on the battery. Modern + * batteries export power (watts), older batteries (used to) + * export current (amperes). We check the fourth column and try + * to find old batteries this way. */ + if ((strcmp(fields[0], "present") == 0) && + (strcmp(fields[1], "rate:") == 0)) { + strtogauge(fields[2], &power); + + if ((numfields >= 4) && (strcmp("mA", fields[3]) == 0)) + is_current = 1; + } else if ((strcmp(fields[0], "remaining") == 0) && + (strcmp(fields[1], "capacity:") == 0)) + strtogauge(fields[2], &capacity_charged); + else if ((strcmp(fields[0], "present") == 0) && + (strcmp(fields[1], "voltage:") == 0)) + strtogauge(fields[2], &voltage); + } /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */ + + fclose(fh); + + if (!charging) + power *= -1.0; + + /* FIXME: This is a dirty hack for backwards compatibility: The battery + * plugin, for a very long time, has had the plugin_instance + * hard-coded to "0". So, to keep backwards compatibility, we'll use + * "0" for the first battery we find and the power_supply name for all + * following. This should be reverted in a future major version. */ + plugin_instance = (*battery_index == 0) ? "0" : power_supply; + (*battery_index)++; + + read_acpi_full_capacity(dir, power_supply, &capacity_full, &capacity_design); + + submit_capacity(plugin_instance, capacity_charged * PROC_ACPI_FACTOR, + capacity_full * PROC_ACPI_FACTOR, + capacity_design * PROC_ACPI_FACTOR); + + battery_submit(plugin_instance, is_current ? "current" : "power", + power * PROC_ACPI_FACTOR); + battery_submit(plugin_instance, "voltage", voltage * PROC_ACPI_FACTOR); + + return 0; } /* }}} int read_acpi_callback */ -static int read_acpi (void) /* {{{ */ +static int read_acpi(void) /* {{{ */ { - int status; - int battery_counter = 0; + int status; + int battery_counter = 0; - if (access (PROC_ACPI_PATH, R_OK) != 0) - return (ENOENT); + if (access(PROC_ACPI_PATH, R_OK) != 0) + return (ENOENT); - status = walk_directory (PROC_ACPI_PATH, read_acpi_callback, - /* user_data = */ &battery_counter, - /* include hidden */ 0); - return (status); + status = walk_directory(PROC_ACPI_PATH, read_acpi_callback, + /* user_data = */ &battery_counter, + /* include hidden */ 0); + return (status); } /* }}} int read_acpi */ -static int read_pmu (void) /* {{{ */ +static int read_pmu(void) /* {{{ */ { - int i = 0; - /* The upper limit here is just a safeguard. If there is a system with - * more than 100 batteries, this can easily be increased. */ - for (; i < 100; i++) - { - FILE *fh; - - char buffer[1024]; - char filename[PATH_MAX]; - char plugin_instance[DATA_MAX_NAME_LEN]; - - gauge_t current = NAN; - gauge_t voltage = NAN; - gauge_t charge = NAN; - - ssnprintf (filename, sizeof (filename), PROC_PMU_PATH_FORMAT, i); - if (access (filename, R_OK) != 0) - break; - - ssnprintf (plugin_instance, sizeof (plugin_instance), "%i", i); - - fh = fopen (filename, "r"); - if (fh == NULL) - { - if (errno == ENOENT) - break; - else if ((errno == EAGAIN) || (errno == EINTR)) - continue; - else - return (errno); - } - - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - char *fields[8]; - int numfields; - - numfields = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields)); - if (numfields < 3) - continue; - - if (strcmp ("current", fields[0]) == 0) - strtogauge (fields[2], ¤t); - else if (strcmp ("voltage", fields[0]) == 0) - strtogauge (fields[2], &voltage); - else if (strcmp ("charge", fields[0]) == 0) - strtogauge (fields[2], &charge); - } - - fclose (fh); - fh = NULL; - - battery_submit (plugin_instance, "charge", charge / 1000.0); - battery_submit (plugin_instance, "current", current / 1000.0); - battery_submit (plugin_instance, "voltage", voltage / 1000.0); - } - - if (i == 0) - return (ENOENT); - return (0); + int i = 0; + /* The upper limit here is just a safeguard. If there is a system with + * more than 100 batteries, this can easily be increased. */ + for (; i < 100; i++) { + FILE *fh; + + char buffer[1024]; + char filename[PATH_MAX]; + char plugin_instance[DATA_MAX_NAME_LEN]; + + gauge_t current = NAN; + gauge_t voltage = NAN; + gauge_t charge = NAN; + + ssnprintf(filename, sizeof(filename), PROC_PMU_PATH_FORMAT, i); + if (access(filename, R_OK) != 0) + break; + + ssnprintf(plugin_instance, sizeof(plugin_instance), "%i", i); + + fh = fopen(filename, "r"); + if (fh == NULL) { + if (errno == ENOENT) + break; + else if ((errno == EAGAIN) || (errno == EINTR)) + continue; + else + return (errno); + } + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + char *fields[8]; + int numfields; + + numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + if (numfields < 3) + continue; + + if (strcmp("current", fields[0]) == 0) + strtogauge(fields[2], ¤t); + else if (strcmp("voltage", fields[0]) == 0) + strtogauge(fields[2], &voltage); + else if (strcmp("charge", fields[0]) == 0) + strtogauge(fields[2], &charge); + } + + fclose(fh); + fh = NULL; + + battery_submit(plugin_instance, "charge", charge / 1000.0); + battery_submit(plugin_instance, "current", current / 1000.0); + battery_submit(plugin_instance, "voltage", voltage / 1000.0); + } + + if (i == 0) + return (ENOENT); + return (0); } /* }}} int read_pmu */ -static int battery_read (void) /* {{{ */ +static int battery_read(void) /* {{{ */ { - int status; + int status; - if (query_statefs) - return battery_read_statefs (); + if (query_statefs) + return battery_read_statefs(); - DEBUG ("battery plugin: Trying sysfs ..."); - status = read_sysfs (); - if (status == 0) - return (0); + DEBUG("battery plugin: Trying sysfs ..."); + status = read_sysfs(); + if (status == 0) + return (0); - DEBUG ("battery plugin: Trying acpi ..."); - status = read_acpi (); - if (status == 0) - return (0); + DEBUG("battery plugin: Trying acpi ..."); + status = read_acpi(); + if (status == 0) + return (0); - DEBUG ("battery plugin: Trying pmu ..."); - status = read_pmu (); - if (status == 0) - return (0); + DEBUG("battery plugin: Trying pmu ..."); + status = read_pmu(); + if (status == 0) + return (0); - ERROR ("battery plugin: All available input methods failed."); - return (-1); + ERROR("battery plugin: All available input methods failed."); + return (-1); } /* }}} int battery_read */ #endif /* KERNEL_LINUX */ -static int battery_config (oconfig_item_t *ci) -{ - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("ValuesPercentage", child->key) == 0) - cf_util_get_boolean (child, &report_percent); - else if (strcasecmp ("ReportDegraded", child->key) == 0) - cf_util_get_boolean (child, &report_degraded); - else if (strcasecmp ("QueryStateFS", child->key) == 0) - cf_util_get_boolean (child, &query_statefs); - else - WARNING ("battery plugin: Ignoring unknown " - "configuration option \"%s\".", - child->key); - } - - return (0); +static int battery_config(oconfig_item_t *ci) { + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("ValuesPercentage", child->key) == 0) + cf_util_get_boolean(child, &report_percent); + else if (strcasecmp("ReportDegraded", child->key) == 0) + cf_util_get_boolean(child, &report_degraded); + else if (strcasecmp("QueryStateFS", child->key) == 0) + cf_util_get_boolean(child, &query_statefs); + else + WARNING("battery plugin: Ignoring unknown " + "configuration option \"%s\".", + child->key); + } + + return (0); } /* }}} int battery_config */ -void module_register (void) -{ - plugin_register_complex_config ("battery", battery_config); - plugin_register_read ("battery", battery_read); +void module_register(void) { + plugin_register_complex_config("battery", battery_config); + plugin_register_read("battery", battery_read); } /* void module_register */ diff --git a/src/battery_statefs.c b/src/battery_statefs.c index a0ff1872..4b9baf42 100644 --- a/src/battery_statefs.c +++ b/src/battery_statefs.c @@ -44,9 +44,9 @@ SOFTWARE. **/ -#include "collectd.h" #include "common.h" #include "plugin.h" +#include "collectd.h" #include @@ -56,7 +56,7 @@ static void battery_submit(const char *type, gauge_t value, const char *type_instance) { value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; + vl.values = &(value_t){.gauge = value}; vl.values_len = 1; sstrncpy(vl.plugin, "battery", sizeof(vl.plugin)); /* statefs supports 1 battery at present */ @@ -72,16 +72,18 @@ int battery_read_statefs(void) { value_t v; int success = 0; - if (parse_value_file(STATEFS_ROOT "ChargePercentage", &v, DS_TYPE_GAUGE) == 0) { + if (parse_value_file(STATEFS_ROOT "ChargePercentage", &v, DS_TYPE_GAUGE) == + 0) { battery_submit("charge", v.gauge, NULL); success++; - } else if (parse_value_file(STATEFS_ROOT "Capacity", &v, DS_TYPE_GAUGE) == 0) { + } else if (parse_value_file(STATEFS_ROOT "Capacity", &v, DS_TYPE_GAUGE) == + 0) { // Use capacity as a charge estimate if ChargePercentage is not available battery_submit("charge", v.gauge, NULL); success++; } else { - WARNING("battery plugin: Neither \""STATEFS_ROOT"ChargePercentage\" " - "nor \""STATEFS_ROOT"Capacity\" could be read."); + WARNING("battery plugin: Neither \"" STATEFS_ROOT "ChargePercentage\" " + "nor \"" STATEFS_ROOT "Capacity\" could be read."); } struct { @@ -90,13 +92,13 @@ int battery_read_statefs(void) { char *type_instance; gauge_t factor; } metrics[] = { - {STATEFS_ROOT "Current", "current", NULL, 1e-6}, // from uA to A - {STATEFS_ROOT "Energy", "energy_wh", NULL, 1e-6}, // from uWh to Wh - {STATEFS_ROOT "Power", "power", NULL, 1e-6}, // from uW to W - {STATEFS_ROOT "Temperature", "temperature", NULL, 0.1}, // from 10xC to C - {STATEFS_ROOT "TimeUntilFull", "duration", "full", 1.0}, - {STATEFS_ROOT "TimeUntilLow", "duration", "low", 1.0}, - {STATEFS_ROOT "Voltage", "voltage", NULL, 1e-6}, // from uV to V + {STATEFS_ROOT "Current", "current", NULL, 1e-6}, // from uA to A + {STATEFS_ROOT "Energy", "energy_wh", NULL, 1e-6}, // from uWh to Wh + {STATEFS_ROOT "Power", "power", NULL, 1e-6}, // from uW to W + {STATEFS_ROOT "Temperature", "temperature", NULL, 0.1}, // from 10xC to C + {STATEFS_ROOT "TimeUntilFull", "duration", "full", 1.0}, + {STATEFS_ROOT "TimeUntilLow", "duration", "low", 1.0}, + {STATEFS_ROOT "Voltage", "voltage", NULL, 1e-6}, // from uV to V }; for (size_t i = 0; i < STATIC_ARRAY_SIZE(metrics); i++) { @@ -105,12 +107,14 @@ int battery_read_statefs(void) { continue; } - battery_submit(metrics[i].type, v.gauge * metrics[i].factor, metrics[i].type_instance); + battery_submit(metrics[i].type, v.gauge * metrics[i].factor, + metrics[i].type_instance); success++; } if (success == 0) { - ERROR("battery plugin: statefs backend: none of the statistics are available"); + ERROR("battery plugin: statefs backend: none of the statistics are " + "available"); return (-1); } diff --git a/src/bind.c b/src/bind.c index 2b7ad757..9bb662fc 100644 --- a/src/bind.c +++ b/src/bind.c @@ -24,15 +24,15 @@ #include "config.h" #if STRPTIME_NEEDS_STANDARDS -# ifndef _ISOC99_SOURCE -# define _ISOC99_SOURCE 1 -# endif -# ifndef _POSIX_C_SOURCE -# define _POSIX_C_SOURCE 200112L -# endif -# ifndef _XOPEN_SOURCE -# define _XOPEN_SOURCE 500 -# endif +#ifndef _ISOC99_SOURCE +#define _ISOC99_SOURCE 1 +#endif +#ifndef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200112L +#endif +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 500 +#endif #endif /* STRPTIME_NEEDS_STANDARDS */ #include "collectd.h" @@ -43,7 +43,7 @@ /* Some versions of libcurl don't include this themselves and then don't have * fd_set available. */ #if HAVE_SYS_SELECT_H -# include +#include #endif #include @@ -51,7 +51,7 @@ #include #ifndef BIND_DEFAULT_URL -# define BIND_DEFAULT_URL "http://localhost:8053/" +#define BIND_DEFAULT_URL "http://localhost:8053/" #endif /* @@ -59,11 +59,10 @@ * `list_info_ptr_t' are passed to the callbacks in the `void *user_data' * pointer. */ -typedef int (*list_callback_t) (const char *name, value_t value, - time_t current_time, void *user_data); +typedef int (*list_callback_t)(const char *name, value_t value, + time_t current_time, void *user_data); -struct cb_view_s -{ +struct cb_view_s { char *name; int qtypes; @@ -75,24 +74,21 @@ struct cb_view_s }; typedef struct cb_view_s cb_view_t; -struct translation_info_s -{ +struct translation_info_s { const char *xml_name; const char *type; const char *type_instance; }; typedef struct translation_info_s translation_info_t; -struct translation_table_ptr_s -{ +struct translation_table_ptr_s { const translation_info_t *table; size_t table_length; const char *plugin_instance; }; typedef struct translation_table_ptr_s translation_table_ptr_t; -struct list_info_ptr_s -{ +struct list_info_ptr_s { const char *plugin_instance; const char *type; }; @@ -102,62 +98,62 @@ typedef struct list_info_ptr_s list_info_ptr_t; /* TODO: Remove time parsing code. */ static _Bool config_parse_time = 1; -static char *url = NULL; -static int global_opcodes = 1; -static int global_qtypes = 1; -static int global_server_stats = 1; +static char *url = NULL; +static int global_opcodes = 1; +static int global_qtypes = 1; +static int global_server_stats = 1; static int global_zone_maint_stats = 1; -static int global_resolver_stats = 0; -static int global_memory_stats = 1; -static int timeout = -1; +static int global_resolver_stats = 0; +static int global_memory_stats = 1; +static int timeout = -1; static cb_view_t *views = NULL; -static size_t views_num = 0; +static size_t views_num = 0; static CURL *curl = NULL; -static char *bind_buffer = NULL; +static char *bind_buffer = NULL; static size_t bind_buffer_size = 0; static size_t bind_buffer_fill = 0; -static char bind_curl_error[CURL_ERROR_SIZE]; +static char bind_curl_error[CURL_ERROR_SIZE]; /* Translation table for the `nsstats' values. */ static const translation_info_t nsstats_translation_table[] = /* {{{ */ -{ - /* Requests */ - { "Requestv4", "dns_request", "IPv4" }, - { "Requestv6", "dns_request", "IPv6" }, - { "ReqEdns0", "dns_request", "EDNS0" }, - { "ReqBadEDNSVer", "dns_request", "BadEDNSVer" }, - { "ReqTSIG", "dns_request", "TSIG" }, - { "ReqSIG0", "dns_request", "SIG0" }, - { "ReqBadSIG", "dns_request", "BadSIG" }, - { "ReqTCP", "dns_request", "TCP" }, - /* Rejects */ - { "AuthQryRej", "dns_reject", "authoritative" }, - { "RecQryRej", "dns_reject", "recursive" }, - { "XfrRej", "dns_reject", "transfer" }, - { "UpdateRej", "dns_reject", "update" }, - /* Responses */ - { "Response", "dns_response", "normal" }, - { "TruncatedResp", "dns_response", "truncated" }, - { "RespEDNS0", "dns_response", "EDNS0" }, - { "RespTSIG", "dns_response", "TSIG" }, - { "RespSIG0", "dns_response", "SIG0" }, - /* Queries */ - { "QryAuthAns", "dns_query", "authoritative" }, - { "QryNoauthAns", "dns_query", "nonauth" }, - { "QryReferral", "dns_query", "referral" }, - { "QryRecursion", "dns_query", "recursion" }, - { "QryDuplicate", "dns_query", "duplicate" }, - { "QryDropped", "dns_query", "dropped" }, - { "QryFailure", "dns_query", "failure" }, - /* Response codes */ - { "QrySuccess", "dns_rcode", "tx-NOERROR" }, - { "QryNxrrset", "dns_rcode", "tx-NXRRSET" }, - { "QrySERVFAIL", "dns_rcode", "tx-SERVFAIL" }, - { "QryFORMERR", "dns_rcode", "tx-FORMERR" }, - { "QryNXDOMAIN", "dns_rcode", "tx-NXDOMAIN" } + { + /* Requests */ + {"Requestv4", "dns_request", "IPv4"}, + {"Requestv6", "dns_request", "IPv6"}, + {"ReqEdns0", "dns_request", "EDNS0"}, + {"ReqBadEDNSVer", "dns_request", "BadEDNSVer"}, + {"ReqTSIG", "dns_request", "TSIG"}, + {"ReqSIG0", "dns_request", "SIG0"}, + {"ReqBadSIG", "dns_request", "BadSIG"}, + {"ReqTCP", "dns_request", "TCP"}, + /* Rejects */ + {"AuthQryRej", "dns_reject", "authoritative"}, + {"RecQryRej", "dns_reject", "recursive"}, + {"XfrRej", "dns_reject", "transfer"}, + {"UpdateRej", "dns_reject", "update"}, + /* Responses */ + {"Response", "dns_response", "normal"}, + {"TruncatedResp", "dns_response", "truncated"}, + {"RespEDNS0", "dns_response", "EDNS0"}, + {"RespTSIG", "dns_response", "TSIG"}, + {"RespSIG0", "dns_response", "SIG0"}, + /* Queries */ + {"QryAuthAns", "dns_query", "authoritative"}, + {"QryNoauthAns", "dns_query", "nonauth"}, + {"QryReferral", "dns_query", "referral"}, + {"QryRecursion", "dns_query", "recursion"}, + {"QryDuplicate", "dns_query", "duplicate"}, + {"QryDropped", "dns_query", "dropped"}, + {"QryFailure", "dns_query", "failure"}, + /* Response codes */ + {"QrySuccess", "dns_rcode", "tx-NOERROR"}, + {"QryNxrrset", "dns_rcode", "tx-NXRRSET"}, + {"QrySERVFAIL", "dns_rcode", "tx-SERVFAIL"}, + {"QryFORMERR", "dns_rcode", "tx-FORMERR"}, + {"QryNXDOMAIN", "dns_rcode", "tx-NXDOMAIN"} #if 0 { "XfrReqDone", "type", "type_instance" }, { "UpdateReqFwd", "type", "type_instance" }, @@ -169,128 +165,119 @@ static const translation_info_t nsstats_translation_table[] = /* {{{ */ #endif }; static int nsstats_translation_table_length = - STATIC_ARRAY_SIZE (nsstats_translation_table); + STATIC_ARRAY_SIZE(nsstats_translation_table); /* }}} */ /* Translation table for the `zonestats' values. */ static const translation_info_t zonestats_translation_table[] = /* {{{ */ -{ - /* Notify's */ - { "NotifyOutv4", "dns_notify", "tx-IPv4" }, - { "NotifyOutv6", "dns_notify", "tx-IPv6" }, - { "NotifyInv4", "dns_notify", "rx-IPv4" }, - { "NotifyInv6", "dns_notify", "rx-IPv6" }, - { "NotifyRej", "dns_notify", "rejected" }, - /* SOA/AXFS/IXFS requests */ - { "SOAOutv4", "dns_opcode", "SOA-IPv4" }, - { "SOAOutv6", "dns_opcode", "SOA-IPv6" }, - { "AXFRReqv4", "dns_opcode", "AXFR-IPv4" }, - { "AXFRReqv6", "dns_opcode", "AXFR-IPv6" }, - { "IXFRReqv4", "dns_opcode", "IXFR-IPv4" }, - { "IXFRReqv6", "dns_opcode", "IXFR-IPv6" }, - /* Domain transfers */ - { "XfrSuccess", "dns_transfer", "success" }, - { "XfrFail", "dns_transfer", "failure" } -}; + { + /* Notify's */ + {"NotifyOutv4", "dns_notify", "tx-IPv4"}, + {"NotifyOutv6", "dns_notify", "tx-IPv6"}, + {"NotifyInv4", "dns_notify", "rx-IPv4"}, + {"NotifyInv6", "dns_notify", "rx-IPv6"}, + {"NotifyRej", "dns_notify", "rejected"}, + /* SOA/AXFS/IXFS requests */ + {"SOAOutv4", "dns_opcode", "SOA-IPv4"}, + {"SOAOutv6", "dns_opcode", "SOA-IPv6"}, + {"AXFRReqv4", "dns_opcode", "AXFR-IPv4"}, + {"AXFRReqv6", "dns_opcode", "AXFR-IPv6"}, + {"IXFRReqv4", "dns_opcode", "IXFR-IPv4"}, + {"IXFRReqv6", "dns_opcode", "IXFR-IPv6"}, + /* Domain transfers */ + {"XfrSuccess", "dns_transfer", "success"}, + {"XfrFail", "dns_transfer", "failure"}}; static int zonestats_translation_table_length = - STATIC_ARRAY_SIZE (zonestats_translation_table); + STATIC_ARRAY_SIZE(zonestats_translation_table); /* }}} */ /* Translation table for the `resstats' values. */ static const translation_info_t resstats_translation_table[] = /* {{{ */ -{ - /* Generic resolver information */ - { "Queryv4", "dns_query", "IPv4" }, - { "Queryv6", "dns_query", "IPv6" }, - { "Responsev4", "dns_response", "IPv4" }, - { "Responsev6", "dns_response", "IPv6" }, - /* Received response codes */ - { "NXDOMAIN", "dns_rcode", "rx-NXDOMAIN" }, - { "SERVFAIL", "dns_rcode", "rx-SERVFAIL" }, - { "FORMERR", "dns_rcode", "rx-FORMERR" }, - { "OtherError", "dns_rcode", "rx-OTHER" }, - { "EDNS0Fail", "dns_rcode", "rx-EDNS0Fail"}, - /* Received responses */ - { "Mismatch", "dns_response", "mismatch" }, - { "Truncated", "dns_response", "truncated" }, - { "Lame", "dns_response", "lame" }, - { "Retry", "dns_query", "retry" }, + { + /* Generic resolver information */ + {"Queryv4", "dns_query", "IPv4"}, + {"Queryv6", "dns_query", "IPv6"}, + {"Responsev4", "dns_response", "IPv4"}, + {"Responsev6", "dns_response", "IPv6"}, + /* Received response codes */ + {"NXDOMAIN", "dns_rcode", "rx-NXDOMAIN"}, + {"SERVFAIL", "dns_rcode", "rx-SERVFAIL"}, + {"FORMERR", "dns_rcode", "rx-FORMERR"}, + {"OtherError", "dns_rcode", "rx-OTHER"}, + {"EDNS0Fail", "dns_rcode", "rx-EDNS0Fail"}, + /* Received responses */ + {"Mismatch", "dns_response", "mismatch"}, + {"Truncated", "dns_response", "truncated"}, + {"Lame", "dns_response", "lame"}, + {"Retry", "dns_query", "retry"}, #if 0 { "GlueFetchv4", "type", "type_instance" }, { "GlueFetchv6", "type", "type_instance" }, { "GlueFetchv4Fail", "type", "type_instance" }, { "GlueFetchv6Fail", "type", "type_instance" }, #endif - /* DNSSEC information */ - { "ValAttempt", "dns_resolver", "DNSSEC-attempt" }, - { "ValOk", "dns_resolver", "DNSSEC-okay" }, - { "ValNegOk", "dns_resolver", "DNSSEC-negokay" }, - { "ValFail", "dns_resolver", "DNSSEC-fail" } -}; + /* DNSSEC information */ + {"ValAttempt", "dns_resolver", "DNSSEC-attempt"}, + {"ValOk", "dns_resolver", "DNSSEC-okay"}, + {"ValNegOk", "dns_resolver", "DNSSEC-negokay"}, + {"ValFail", "dns_resolver", "DNSSEC-fail"}}; static int resstats_translation_table_length = - STATIC_ARRAY_SIZE (resstats_translation_table); + STATIC_ARRAY_SIZE(resstats_translation_table); /* }}} */ /* Translation table for the `memory/summary' values. */ static const translation_info_t memsummary_translation_table[] = /* {{{ */ -{ - { "TotalUse", "memory", "TotalUse" }, - { "InUse", "memory", "InUse" }, - { "BlockSize", "memory", "BlockSize" }, - { "ContextSize", "memory", "ContextSize" }, - { "Lost", "memory", "Lost" } -}; + {{"TotalUse", "memory", "TotalUse"}, + {"InUse", "memory", "InUse"}, + {"BlockSize", "memory", "BlockSize"}, + {"ContextSize", "memory", "ContextSize"}, + {"Lost", "memory", "Lost"}}; static int memsummary_translation_table_length = - STATIC_ARRAY_SIZE (memsummary_translation_table); + STATIC_ARRAY_SIZE(memsummary_translation_table); /* }}} */ -static void submit (time_t ts, const char *plugin_instance, /* {{{ */ - const char *type, const char *type_instance, value_t value) -{ +static void submit(time_t ts, const char *plugin_instance, /* {{{ */ + const char *type, const char *type_instance, value_t value) { value_list_t vl = VALUE_LIST_INIT; vl.values = &value; vl.values_len = 1; if (config_parse_time) - vl.time = TIME_T_TO_CDTIME_T (ts); + vl.time = TIME_T_TO_CDTIME_T(ts); sstrncpy(vl.plugin, "bind", sizeof(vl.plugin)); if (plugin_instance) { - sstrncpy(vl.plugin_instance, plugin_instance, - sizeof(vl.plugin_instance)); - replace_special (vl.plugin_instance, sizeof (vl.plugin_instance)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + replace_special(vl.plugin_instance, sizeof(vl.plugin_instance)); } sstrncpy(vl.type, type, sizeof(vl.type)); if (type_instance) { - sstrncpy(vl.type_instance, type_instance, - sizeof(vl.type_instance)); - replace_special (vl.type_instance, sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + replace_special(vl.type_instance, sizeof(vl.type_instance)); } plugin_dispatch_values(&vl); } /* }}} void submit */ -static size_t bind_curl_callback (void *buf, size_t size, /* {{{ */ - size_t nmemb, void __attribute__((unused)) *stream) -{ +static size_t bind_curl_callback(void *buf, size_t size, /* {{{ */ + size_t nmemb, + void __attribute__((unused)) * stream) { size_t len = size * nmemb; if (len == 0) return (len); - if ((bind_buffer_fill + len) >= bind_buffer_size) - { + if ((bind_buffer_fill + len) >= bind_buffer_size) { char *temp; - temp = realloc (bind_buffer, bind_buffer_fill + len + 1); - if (temp == NULL) - { - ERROR ("bind plugin: realloc failed."); + temp = realloc(bind_buffer, bind_buffer_fill + len + 1); + if (temp == NULL) { + ERROR("bind plugin: realloc failed."); return (0); } bind_buffer = temp; bind_buffer_size = bind_buffer_fill + len + 1; } - memcpy (bind_buffer + bind_buffer_fill, (char *) buf, len); + memcpy(bind_buffer + bind_buffer_fill, (char *)buf, len); bind_buffer_fill += len; bind_buffer[bind_buffer_fill] = 0; @@ -301,24 +288,19 @@ static size_t bind_curl_callback (void *buf, size_t size, /* {{{ */ * Callback, that's called with a translation table. * (Plugin instance is fixed, type and type instance come from lookup table.) */ -static int bind_xml_table_callback (const char *name, value_t value, /* {{{ */ - time_t current_time, void *user_data) -{ - translation_table_ptr_t *table = (translation_table_ptr_t *) user_data; +static int bind_xml_table_callback(const char *name, value_t value, /* {{{ */ + time_t current_time, void *user_data) { + translation_table_ptr_t *table = (translation_table_ptr_t *)user_data; if (table == NULL) return (-1); - for (size_t i = 0; i < table->table_length; i++) - { - if (strcmp (table->table[i].xml_name, name) != 0) + for (size_t i = 0; i < table->table_length; i++) { + if (strcmp(table->table[i].xml_name, name) != 0) continue; - submit (current_time, - table->plugin_instance, - table->table[i].type, - table->table[i].type_instance, - value); + submit(current_time, table->plugin_instance, table->table[i].type, + table->table[i].type_instance, value); break; } @@ -329,42 +311,36 @@ static int bind_xml_table_callback (const char *name, value_t value, /* {{{ */ * Callback, that's used for lists. * (Plugin instance and type are fixed, xml name is used as type instance.) */ -static int bind_xml_list_callback (const char *name, /* {{{ */ - value_t value, time_t current_time, void *user_data) -{ - list_info_ptr_t *list_info = (list_info_ptr_t *) user_data; +static int bind_xml_list_callback(const char *name, /* {{{ */ + value_t value, time_t current_time, + void *user_data) { + list_info_ptr_t *list_info = (list_info_ptr_t *)user_data; if (list_info == NULL) return (-1); - submit (current_time, - list_info->plugin_instance, - list_info->type, - /* type instance = */ name, - value); + submit(current_time, list_info->plugin_instance, list_info->type, + /* type instance = */ name, value); return (0); } /* }}} int bind_xml_list_callback */ -static int bind_xml_read_derive (xmlDoc *doc, xmlNode *node, /* {{{ */ - derive_t *ret_value) -{ +static int bind_xml_read_derive(xmlDoc *doc, xmlNode *node, /* {{{ */ + derive_t *ret_value) { char *str_ptr; value_t value; int status; - str_ptr = (char *) xmlNodeListGetString (doc, node->xmlChildrenNode, 1); - if (str_ptr == NULL) - { - ERROR ("bind plugin: bind_xml_read_derive: xmlNodeListGetString failed."); + str_ptr = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); + if (str_ptr == NULL) { + ERROR("bind plugin: bind_xml_read_derive: xmlNodeListGetString failed."); return (-1); } - status = parse_value (str_ptr, &value, DS_TYPE_DERIVE); - if (status != 0) - { - ERROR ("bind plugin: Parsing string \"%s\" to derive value failed.", - str_ptr); + status = parse_value(str_ptr, &value, DS_TYPE_DERIVE); + if (status != 0) { + ERROR("bind plugin: Parsing string \"%s\" to derive value failed.", + str_ptr); xmlFree(str_ptr); return (-1); } @@ -374,97 +350,88 @@ static int bind_xml_read_derive (xmlDoc *doc, xmlNode *node, /* {{{ */ return (0); } /* }}} int bind_xml_read_derive */ -static int bind_xml_read_gauge (xmlDoc *doc, xmlNode *node, /* {{{ */ - gauge_t *ret_value) -{ +static int bind_xml_read_gauge(xmlDoc *doc, xmlNode *node, /* {{{ */ + gauge_t *ret_value) { char *str_ptr, *end_ptr; double value; - str_ptr = (char *) xmlNodeListGetString (doc, node->xmlChildrenNode, 1); - if (str_ptr == NULL) - { - ERROR ("bind plugin: bind_xml_read_gauge: xmlNodeListGetString failed."); + str_ptr = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); + if (str_ptr == NULL) { + ERROR("bind plugin: bind_xml_read_gauge: xmlNodeListGetString failed."); return (-1); } errno = 0; - value = strtod (str_ptr, &end_ptr); + value = strtod(str_ptr, &end_ptr); xmlFree(str_ptr); - if (str_ptr == end_ptr || errno) - { + if (str_ptr == end_ptr || errno) { if (errno && (value < 0)) - ERROR ("bind plugin: bind_xml_read_gauge: strtod failed with underflow."); + ERROR("bind plugin: bind_xml_read_gauge: strtod failed with underflow."); else if (errno && (value > 0)) - ERROR ("bind plugin: bind_xml_read_gauge: strtod failed with overflow."); + ERROR("bind plugin: bind_xml_read_gauge: strtod failed with overflow."); else - ERROR ("bind plugin: bind_xml_read_gauge: strtod failed."); + ERROR("bind plugin: bind_xml_read_gauge: strtod failed."); return (-1); } - *ret_value = (gauge_t) value; + *ret_value = (gauge_t)value; return (0); } /* }}} int bind_xml_read_gauge */ -static int bind_xml_read_timestamp (const char *xpath_expression, /* {{{ */ - xmlDoc *doc, xmlXPathContext *xpathCtx, time_t *ret_value) -{ +static int bind_xml_read_timestamp(const char *xpath_expression, /* {{{ */ + xmlDoc *doc, xmlXPathContext *xpathCtx, + time_t *ret_value) { xmlXPathObject *xpathObj = NULL; xmlNode *node; char *str_ptr; char *tmp; - struct tm tm = { 0 }; + struct tm tm = {0}; - xpathObj = xmlXPathEvalExpression (BAD_CAST xpath_expression, xpathCtx); - if (xpathObj == NULL) - { - ERROR ("bind plugin: Unable to evaluate XPath expression `%s'.", - xpath_expression); + xpathObj = xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx); + if (xpathObj == NULL) { + ERROR("bind plugin: Unable to evaluate XPath expression `%s'.", + xpath_expression); return (-1); } - if ((xpathObj->nodesetval == NULL) || (xpathObj->nodesetval->nodeNr < 1)) - { - xmlXPathFreeObject (xpathObj); + if ((xpathObj->nodesetval == NULL) || (xpathObj->nodesetval->nodeNr < 1)) { + xmlXPathFreeObject(xpathObj); return (-1); } - if (xpathObj->nodesetval->nodeNr != 1) - { - NOTICE ("bind plugin: Evaluating the XPath expression `%s' returned " - "%i nodes. Only handling the first one.", - xpath_expression, xpathObj->nodesetval->nodeNr); + if (xpathObj->nodesetval->nodeNr != 1) { + NOTICE("bind plugin: Evaluating the XPath expression `%s' returned " + "%i nodes. Only handling the first one.", + xpath_expression, xpathObj->nodesetval->nodeNr); } node = xpathObj->nodesetval->nodeTab[0]; - if (node->xmlChildrenNode == NULL) - { - ERROR ("bind plugin: bind_xml_read_timestamp: " - "node->xmlChildrenNode == NULL"); - xmlXPathFreeObject (xpathObj); + if (node->xmlChildrenNode == NULL) { + ERROR("bind plugin: bind_xml_read_timestamp: " + "node->xmlChildrenNode == NULL"); + xmlXPathFreeObject(xpathObj); return (-1); } - str_ptr = (char *) xmlNodeListGetString (doc, node->xmlChildrenNode, 1); - if (str_ptr == NULL) - { - ERROR ("bind plugin: bind_xml_read_timestamp: xmlNodeListGetString failed."); - xmlXPathFreeObject (xpathObj); + str_ptr = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); + if (str_ptr == NULL) { + ERROR("bind plugin: bind_xml_read_timestamp: xmlNodeListGetString failed."); + xmlXPathFreeObject(xpathObj); return (-1); } - tmp = strptime (str_ptr, "%Y-%m-%dT%T", &tm); + tmp = strptime(str_ptr, "%Y-%m-%dT%T", &tm); xmlFree(str_ptr); - if (tmp == NULL) - { - ERROR ("bind plugin: bind_xml_read_timestamp: strptime failed."); - xmlXPathFreeObject (xpathObj); + if (tmp == NULL) { + ERROR("bind plugin: bind_xml_read_timestamp: strptime failed."); + xmlXPathFreeObject(xpathObj); return (-1); } *ret_value = mktime(&tm); - xmlXPathFreeObject (xpathObj); + xmlXPathFreeObject(xpathObj); return (0); } /* }}} int bind_xml_read_timestamp */ @@ -477,74 +444,68 @@ static int bind_xml_read_timestamp (const char *xpath_expression, /* {{{ */ * 123 * */ -static int bind_parse_generic_name_value (const char *xpath_expression, /* {{{ */ - list_callback_t list_callback, - void *user_data, - xmlDoc *doc, xmlXPathContext *xpathCtx, - time_t current_time, int ds_type) -{ +static int bind_parse_generic_name_value(const char *xpath_expression, /* {{{ */ + list_callback_t list_callback, + void *user_data, xmlDoc *doc, + xmlXPathContext *xpathCtx, + time_t current_time, int ds_type) { xmlXPathObject *xpathObj = NULL; int num_entries; xpathObj = xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx); - if (xpathObj == NULL) - { + if (xpathObj == NULL) { ERROR("bind plugin: Unable to evaluate XPath expression `%s'.", - xpath_expression); + xpath_expression); return (-1); } num_entries = 0; /* Iterate over all matching nodes. */ - for (int i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); i++) - { + for (int i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); + i++) { xmlNode *name_node = NULL; xmlNode *counter = NULL; xmlNode *parent; parent = xpathObj->nodesetval->nodeTab[i]; - DEBUG ("bind plugin: bind_parse_generic_name_value: parent->name = %s;", - (char *) parent->name); + DEBUG("bind plugin: bind_parse_generic_name_value: parent->name = %s;", + (char *)parent->name); /* Iterate over all child nodes. */ - for (xmlNode *child = parent->xmlChildrenNode; - child != NULL; - child = child->next) - { + for (xmlNode *child = parent->xmlChildrenNode; child != NULL; + child = child->next) { if (child->type != XML_ELEMENT_NODE) continue; - if (xmlStrcmp (BAD_CAST "name", child->name) == 0) + if (xmlStrcmp(BAD_CAST "name", child->name) == 0) name_node = child; - else if (xmlStrcmp (BAD_CAST "counter", child->name) == 0) + else if (xmlStrcmp(BAD_CAST "counter", child->name) == 0) counter = child; } - if ((name_node != NULL) && (counter != NULL)) - { - char *name = (char *) xmlNodeListGetString (doc, - name_node->xmlChildrenNode, 1); + if ((name_node != NULL) && (counter != NULL)) { + char *name = + (char *)xmlNodeListGetString(doc, name_node->xmlChildrenNode, 1); value_t value; int status; if (ds_type == DS_TYPE_GAUGE) - status = bind_xml_read_gauge (doc, counter, &value.gauge); + status = bind_xml_read_gauge(doc, counter, &value.gauge); else - status = bind_xml_read_derive (doc, counter, &value.derive); + status = bind_xml_read_derive(doc, counter, &value.derive); if (status != 0) continue; - status = (*list_callback) (name, value, current_time, user_data); + status = (*list_callback)(name, value, current_time, user_data); if (status == 0) num_entries++; - xmlFree (name); + xmlFree(name); } } - DEBUG ("bind plugin: Found %d %s for XPath expression `%s'", - num_entries, (num_entries == 1) ? "entry" : "entries", - xpath_expression); + DEBUG("bind plugin: Found %d %s for XPath expression `%s'", num_entries, + (num_entries == 1) ? "entry" : "entries", xpath_expression); xmlXPathFreeObject(xpathObj); @@ -562,32 +523,28 @@ static int bind_parse_generic_name_value (const char *xpath_expression, /* {{{ * * : * */ -static int bind_parse_generic_value_list (const char *xpath_expression, /* {{{ */ - list_callback_t list_callback, - void *user_data, - xmlDoc *doc, xmlXPathContext *xpathCtx, - time_t current_time, int ds_type) -{ +static int bind_parse_generic_value_list(const char *xpath_expression, /* {{{ */ + list_callback_t list_callback, + void *user_data, xmlDoc *doc, + xmlXPathContext *xpathCtx, + time_t current_time, int ds_type) { xmlXPathObject *xpathObj = NULL; int num_entries; xpathObj = xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx); - if (xpathObj == NULL) - { + if (xpathObj == NULL) { ERROR("bind plugin: Unable to evaluate XPath expression `%s'.", - xpath_expression); + xpath_expression); return (-1); } num_entries = 0; /* Iterate over all matching nodes. */ - for (int i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); i++) - { + for (int i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); + i++) { /* Iterate over all child nodes. */ for (xmlNode *child = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode; - child != NULL; - child = child->next) - { + child != NULL; child = child->next) { char *node_name; value_t value; int status; @@ -595,24 +552,23 @@ static int bind_parse_generic_value_list (const char *xpath_expression, /* {{{ * if (child->type != XML_ELEMENT_NODE) continue; - node_name = (char *) child->name; + node_name = (char *)child->name; if (ds_type == DS_TYPE_GAUGE) - status = bind_xml_read_gauge (doc, child, &value.gauge); + status = bind_xml_read_gauge(doc, child, &value.gauge); else - status = bind_xml_read_derive (doc, child, &value.derive); + status = bind_xml_read_derive(doc, child, &value.derive); if (status != 0) continue; - status = (*list_callback) (node_name, value, current_time, user_data); + status = (*list_callback)(node_name, value, current_time, user_data); if (status == 0) num_entries++; } } - DEBUG ("bind plugin: Found %d %s for XPath expression `%s'", - num_entries, (num_entries == 1) ? "entry" : "entries", - xpath_expression); + DEBUG("bind plugin: Found %d %s for XPath expression `%s'", num_entries, + (num_entries == 1) ? "entry" : "entries", xpath_expression); xmlXPathFreeObject(xpathObj); @@ -630,122 +586,107 @@ static int bind_parse_generic_value_list (const char *xpath_expression, /* {{{ * * : * */ -static int bind_parse_generic_name_attr_value_list (const char *xpath_expression, /* {{{ */ - list_callback_t list_callback, - void *user_data, - xmlDoc *doc, xmlXPathContext *xpathCtx, - time_t current_time, int ds_type) -{ +static int bind_parse_generic_name_attr_value_list( + const char *xpath_expression, /* {{{ */ + list_callback_t list_callback, void *user_data, xmlDoc *doc, + xmlXPathContext *xpathCtx, time_t current_time, int ds_type) { xmlXPathObject *xpathObj = NULL; int num_entries; xpathObj = xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx); - if (xpathObj == NULL) - { + if (xpathObj == NULL) { ERROR("bind plugin: Unable to evaluate XPath expression `%s'.", - xpath_expression); + xpath_expression); return (-1); } num_entries = 0; /* Iterate over all matching nodes. */ - for (int i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); i++) - { + for (int i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); + i++) { /* Iterate over all child nodes. */ for (xmlNode *child = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode; - child != NULL; - child = child->next) - { + child != NULL; child = child->next) { if (child->type != XML_ELEMENT_NODE) continue; - if (strncmp ("counter", (char *) child->name, strlen ("counter")) != 0) + if (strncmp("counter", (char *)child->name, strlen("counter")) != 0) continue; char *attr_name; value_t value; int status; - attr_name = (char *) xmlGetProp (child, BAD_CAST "name"); - if (attr_name == NULL) - { - DEBUG ("bind plugin: found without name."); + attr_name = (char *)xmlGetProp(child, BAD_CAST "name"); + if (attr_name == NULL) { + DEBUG("bind plugin: found without name."); continue; } if (ds_type == DS_TYPE_GAUGE) - status = bind_xml_read_gauge (doc, child, &value.gauge); + status = bind_xml_read_gauge(doc, child, &value.gauge); else - status = bind_xml_read_derive (doc, child, &value.derive); + status = bind_xml_read_derive(doc, child, &value.derive); if (status != 0) continue; - status = (*list_callback) (attr_name, value, current_time, user_data); + status = (*list_callback)(attr_name, value, current_time, user_data); if (status == 0) num_entries++; } } - DEBUG ("bind plugin: Found %d %s for XPath expression `%s'", - num_entries, (num_entries == 1) ? "entry" : "entries", - xpath_expression); + DEBUG("bind plugin: Found %d %s for XPath expression `%s'", num_entries, + (num_entries == 1) ? "entry" : "entries", xpath_expression); xmlXPathFreeObject(xpathObj); return (0); } /* }}} int bind_parse_generic_name_attr_value_list */ -static int bind_xml_stats_handle_zone (int version, xmlDoc *doc, /* {{{ */ - xmlXPathContext *path_ctx, xmlNode *node, cb_view_t *view, - time_t current_time) -{ +static int bind_xml_stats_handle_zone(int version, xmlDoc *doc, /* {{{ */ + xmlXPathContext *path_ctx, xmlNode *node, + cb_view_t *view, time_t current_time) { xmlXPathObject *path_obj; char *zone_name = NULL; size_t j; - if (version >= 3) - { - char *n = (char *) xmlGetProp (node, BAD_CAST "name"); - char *c = (char *) xmlGetProp (node, BAD_CAST "rdataclass"); - if (n && c) - { - zone_name = (char *) xmlMalloc(strlen(n) + strlen(c) + 2); + if (version >= 3) { + char *n = (char *)xmlGetProp(node, BAD_CAST "name"); + char *c = (char *)xmlGetProp(node, BAD_CAST "rdataclass"); + if (n && c) { + zone_name = (char *)xmlMalloc(strlen(n) + strlen(c) + 2); snprintf(zone_name, strlen(n) + strlen(c) + 2, "%s/%s", n, c); } xmlFree(n); xmlFree(c); - } - else - { - path_obj = xmlXPathEvalExpression (BAD_CAST "name", path_ctx); - if (path_obj == NULL) - { - ERROR ("bind plugin: xmlXPathEvalExpression failed."); + } else { + path_obj = xmlXPathEvalExpression(BAD_CAST "name", path_ctx); + if (path_obj == NULL) { + ERROR("bind plugin: xmlXPathEvalExpression failed."); return (-1); } - for (int i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); i++) - { - zone_name = (char *) xmlNodeListGetString (doc, - path_obj->nodesetval->nodeTab[i]->xmlChildrenNode, 1); + for (int i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); + i++) { + zone_name = (char *)xmlNodeListGetString( + doc, path_obj->nodesetval->nodeTab[i]->xmlChildrenNode, 1); if (zone_name != NULL) break; } - xmlXPathFreeObject (path_obj); + xmlXPathFreeObject(path_obj); } - if (zone_name == NULL) - { - ERROR ("bind plugin: Could not determine zone name."); + if (zone_name == NULL) { + ERROR("bind plugin: Could not determine zone name."); return (-1); } - for (j = 0; j < view->zones_num; j++) - { - if (strcasecmp (zone_name, view->zones[j]) == 0) + for (j = 0; j < view->zones_num; j++) { + if (strcasecmp(zone_name, view->zones[j]) == 0) break; } - xmlFree (zone_name); + xmlFree(zone_name); zone_name = NULL; if (j >= view->zones_num) @@ -753,212 +694,181 @@ static int bind_xml_stats_handle_zone (int version, xmlDoc *doc, /* {{{ */ zone_name = view->zones[j]; - DEBUG ("bind plugin: bind_xml_stats_handle_zone: Found zone `%s'.", - zone_name); + DEBUG("bind plugin: bind_xml_stats_handle_zone: Found zone `%s'.", zone_name); { /* Parse the tag {{{ */ char plugin_instance[DATA_MAX_NAME_LEN]; - translation_table_ptr_t table_ptr = - { - nsstats_translation_table, - nsstats_translation_table_length, - plugin_instance - }; - - ssnprintf (plugin_instance, sizeof (plugin_instance), "%s-zone-%s", - view->name, zone_name); - - if (version == 3) - { - list_info_ptr_t list_info = - { - plugin_instance, - /* type = */ "dns_qtype" - }; - bind_parse_generic_name_attr_value_list (/* xpath = */ "counters[@type='rcode']", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, path_ctx, current_time, DS_TYPE_COUNTER); - bind_parse_generic_name_attr_value_list (/* xpath = */ "counters[@type='qtype']", - /* callback = */ bind_xml_list_callback, - /* user_data = */ &list_info, - doc, path_ctx, current_time, DS_TYPE_COUNTER); - } - else - { - bind_parse_generic_value_list (/* xpath = */ "counters", + translation_table_ptr_t table_ptr = {nsstats_translation_table, + nsstats_translation_table_length, + plugin_instance}; + + ssnprintf(plugin_instance, sizeof(plugin_instance), "%s-zone-%s", + view->name, zone_name); + + if (version == 3) { + list_info_ptr_t list_info = {plugin_instance, + /* type = */ "dns_qtype"}; + bind_parse_generic_name_attr_value_list( + /* xpath = */ "counters[@type='rcode']", /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, path_ctx, current_time, DS_TYPE_COUNTER); + /* user_data = */ &table_ptr, doc, path_ctx, current_time, + DS_TYPE_COUNTER); + bind_parse_generic_name_attr_value_list( + /* xpath = */ "counters[@type='qtype']", + /* callback = */ bind_xml_list_callback, + /* user_data = */ &list_info, doc, path_ctx, current_time, + DS_TYPE_COUNTER); + } else { + bind_parse_generic_value_list(/* xpath = */ "counters", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, path_ctx, + current_time, DS_TYPE_COUNTER); } } /* }}} */ return (0); } /* }}} int bind_xml_stats_handle_zone */ -static int bind_xml_stats_search_zones (int version, xmlDoc *doc, /* {{{ */ - xmlXPathContext *path_ctx, xmlNode *node, cb_view_t *view, - time_t current_time) -{ +static int bind_xml_stats_search_zones(int version, xmlDoc *doc, /* {{{ */ + xmlXPathContext *path_ctx, xmlNode *node, + cb_view_t *view, time_t current_time) { xmlXPathObject *zone_nodes = NULL; xmlXPathContext *zone_path_context; - zone_path_context = xmlXPathNewContext (doc); - if (zone_path_context == NULL) - { - ERROR ("bind plugin: xmlXPathNewContext failed."); + zone_path_context = xmlXPathNewContext(doc); + if (zone_path_context == NULL) { + ERROR("bind plugin: xmlXPathNewContext failed."); return (-1); } - zone_nodes = xmlXPathEvalExpression (BAD_CAST "zones/zone", path_ctx); - if (zone_nodes == NULL) - { - ERROR ("bind plugin: Cannot find any tags."); - xmlXPathFreeContext (zone_path_context); + zone_nodes = xmlXPathEvalExpression(BAD_CAST "zones/zone", path_ctx); + if (zone_nodes == NULL) { + ERROR("bind plugin: Cannot find any tags."); + xmlXPathFreeContext(zone_path_context); return (-1); } - for (int i = 0; i < zone_nodes->nodesetval->nodeNr; i++) - { + for (int i = 0; i < zone_nodes->nodesetval->nodeNr; i++) { node = zone_nodes->nodesetval->nodeTab[i]; - assert (node != NULL); + assert(node != NULL); zone_path_context->node = node; - bind_xml_stats_handle_zone (version, doc, zone_path_context, node, view, - current_time); + bind_xml_stats_handle_zone(version, doc, zone_path_context, node, view, + current_time); } - xmlXPathFreeObject (zone_nodes); - xmlXPathFreeContext (zone_path_context); + xmlXPathFreeObject(zone_nodes); + xmlXPathFreeContext(zone_path_context); return (0); } /* }}} int bind_xml_stats_search_zones */ -static int bind_xml_stats_handle_view (int version, xmlDoc *doc, /* {{{ */ - xmlXPathContext *path_ctx, xmlNode *node, time_t current_time) -{ +static int bind_xml_stats_handle_view(int version, xmlDoc *doc, /* {{{ */ + xmlXPathContext *path_ctx, xmlNode *node, + time_t current_time) { char *view_name = NULL; cb_view_t *view; size_t j; - if (version == 3) - { - view_name = (char*) xmlGetProp(node, BAD_CAST "name"); + if (version == 3) { + view_name = (char *)xmlGetProp(node, BAD_CAST "name"); - if (view_name == NULL) - { - ERROR ("bind plugin: Could not determine view name."); + if (view_name == NULL) { + ERROR("bind plugin: Could not determine view name."); return (-1); } - for (j = 0; j < views_num; j++) - { - if (strcasecmp (view_name, views[j].name) == 0) + for (j = 0; j < views_num; j++) { + if (strcasecmp(view_name, views[j].name) == 0) break; } - xmlFree (view_name); + xmlFree(view_name); view_name = NULL; - } - else - { + } else { xmlXPathObject *path_obj; - path_obj = xmlXPathEvalExpression (BAD_CAST "name", path_ctx); - if (path_obj == NULL) - { - ERROR ("bind plugin: xmlXPathEvalExpression failed."); + path_obj = xmlXPathEvalExpression(BAD_CAST "name", path_ctx); + if (path_obj == NULL) { + ERROR("bind plugin: xmlXPathEvalExpression failed."); return (-1); } - for (int i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); i++) - { - view_name = (char *) xmlNodeListGetString (doc, - path_obj->nodesetval->nodeTab[i]->xmlChildrenNode, 1); + for (int i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); + i++) { + view_name = (char *)xmlNodeListGetString( + doc, path_obj->nodesetval->nodeTab[i]->xmlChildrenNode, 1); if (view_name != NULL) break; } - if (view_name == NULL) - { - ERROR ("bind plugin: Could not determine view name."); - xmlXPathFreeObject (path_obj); + if (view_name == NULL) { + ERROR("bind plugin: Could not determine view name."); + xmlXPathFreeObject(path_obj); return (-1); } - for (j = 0; j < views_num; j++) - { - if (strcasecmp (view_name, views[j].name) == 0) + for (j = 0; j < views_num; j++) { + if (strcasecmp(view_name, views[j].name) == 0) break; } - xmlFree (view_name); - xmlXPathFreeObject (path_obj); + xmlFree(view_name); + xmlXPathFreeObject(path_obj); view_name = NULL; path_obj = NULL; } - if (j >= views_num) return (0); view = views + j; - DEBUG ("bind plugin: bind_xml_stats_handle_view: Found view `%s'.", - view->name); + DEBUG("bind plugin: bind_xml_stats_handle_view: Found view `%s'.", + view->name); if (view->qtypes != 0) /* {{{ */ { char plugin_instance[DATA_MAX_NAME_LEN]; - list_info_ptr_t list_info = - { - plugin_instance, - /* type = */ "dns_qtype" - }; - - ssnprintf (plugin_instance, sizeof (plugin_instance), "%s-qtypes", - view->name); - if (version == 3) - { - bind_parse_generic_name_attr_value_list (/* xpath = */ "counters[@type='resqtype']", - /* callback = */ bind_xml_list_callback, - /* user_data = */ &list_info, - doc, path_ctx, current_time, DS_TYPE_COUNTER); - } - else - { - bind_parse_generic_name_value (/* xpath = */ "rdtype", - /* callback = */ bind_xml_list_callback, - /* user_data = */ &list_info, - doc, path_ctx, current_time, DS_TYPE_COUNTER); + list_info_ptr_t list_info = {plugin_instance, + /* type = */ "dns_qtype"}; + + ssnprintf(plugin_instance, sizeof(plugin_instance), "%s-qtypes", + view->name); + if (version == 3) { + bind_parse_generic_name_attr_value_list( + /* xpath = */ "counters[@type='resqtype']", + /* callback = */ bind_xml_list_callback, + /* user_data = */ &list_info, doc, path_ctx, current_time, + DS_TYPE_COUNTER); + } else { + bind_parse_generic_name_value(/* xpath = */ "rdtype", + /* callback = */ bind_xml_list_callback, + /* user_data = */ &list_info, doc, path_ctx, + current_time, DS_TYPE_COUNTER); } } /* }}} */ if (view->resolver_stats != 0) /* {{{ */ { char plugin_instance[DATA_MAX_NAME_LEN]; - translation_table_ptr_t table_ptr = - { - resstats_translation_table, - resstats_translation_table_length, - plugin_instance - }; - - ssnprintf (plugin_instance, sizeof (plugin_instance), - "%s-resolver_stats", view->name); - if (version == 3) - { - bind_parse_generic_name_attr_value_list ("counters[@type='resstats']", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, path_ctx, current_time, DS_TYPE_COUNTER); - } - else - { - bind_parse_generic_name_value ("resstat", + translation_table_ptr_t table_ptr = {resstats_translation_table, + resstats_translation_table_length, + plugin_instance}; + + ssnprintf(plugin_instance, sizeof(plugin_instance), "%s-resolver_stats", + view->name); + if (version == 3) { + bind_parse_generic_name_attr_value_list( + "counters[@type='resstats']", /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, path_ctx, current_time, DS_TYPE_COUNTER); + /* user_data = */ &table_ptr, doc, path_ctx, current_time, + DS_TYPE_COUNTER); + } else { + bind_parse_generic_name_value("resstat", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, path_ctx, + current_time, DS_TYPE_COUNTER); } } /* }}} */ @@ -966,70 +876,65 @@ static int bind_xml_stats_handle_view (int version, xmlDoc *doc, /* {{{ */ if (view->cacherrsets != 0) /* {{{ */ { char plugin_instance[DATA_MAX_NAME_LEN]; - list_info_ptr_t list_info = - { - plugin_instance, - /* type = */ "dns_qtype_cached" - }; + list_info_ptr_t list_info = {plugin_instance, + /* type = */ "dns_qtype_cached"}; - ssnprintf (plugin_instance, sizeof (plugin_instance), "%s-cache_rr_sets", - view->name); + ssnprintf(plugin_instance, sizeof(plugin_instance), "%s-cache_rr_sets", + view->name); - bind_parse_generic_name_value (/* xpath = */ "cache/rrset", - /* callback = */ bind_xml_list_callback, - /* user_data = */ &list_info, - doc, path_ctx, current_time, DS_TYPE_GAUGE); + bind_parse_generic_name_value(/* xpath = */ "cache/rrset", + /* callback = */ bind_xml_list_callback, + /* user_data = */ &list_info, doc, path_ctx, + current_time, DS_TYPE_GAUGE); } /* }}} */ if (view->zones_num > 0) - bind_xml_stats_search_zones (version, doc, path_ctx, node, view, - current_time); + bind_xml_stats_search_zones(version, doc, path_ctx, node, view, + current_time); return (0); } /* }}} int bind_xml_stats_handle_view */ -static int bind_xml_stats_search_views (int version, xmlDoc *doc, /* {{{ */ - xmlXPathContext *xpathCtx, xmlNode *statsnode, time_t current_time) -{ +static int bind_xml_stats_search_views(int version, xmlDoc *doc, /* {{{ */ + xmlXPathContext *xpathCtx, + xmlNode *statsnode, + time_t current_time) { xmlXPathObject *view_nodes = NULL; xmlXPathContext *view_path_context; - view_path_context = xmlXPathNewContext (doc); - if (view_path_context == NULL) - { - ERROR ("bind plugin: xmlXPathNewContext failed."); + view_path_context = xmlXPathNewContext(doc); + if (view_path_context == NULL) { + ERROR("bind plugin: xmlXPathNewContext failed."); return (-1); } - view_nodes = xmlXPathEvalExpression (BAD_CAST "views/view", xpathCtx); - if (view_nodes == NULL) - { - ERROR ("bind plugin: Cannot find any tags."); - xmlXPathFreeContext (view_path_context); + view_nodes = xmlXPathEvalExpression(BAD_CAST "views/view", xpathCtx); + if (view_nodes == NULL) { + ERROR("bind plugin: Cannot find any tags."); + xmlXPathFreeContext(view_path_context); return (-1); } - for (int i = 0; i < view_nodes->nodesetval->nodeNr; i++) - { + for (int i = 0; i < view_nodes->nodesetval->nodeNr; i++) { xmlNode *node; node = view_nodes->nodesetval->nodeTab[i]; - assert (node != NULL); + assert(node != NULL); view_path_context->node = node; - bind_xml_stats_handle_view (version, doc, view_path_context, node, - current_time); + bind_xml_stats_handle_view(version, doc, view_path_context, node, + current_time); } - xmlXPathFreeObject (view_nodes); - xmlXPathFreeContext (view_path_context); + xmlXPathFreeObject(view_nodes); + xmlXPathFreeContext(view_path_context); return (0); } /* }}} int bind_xml_stats_search_views */ -static void bind_xml_stats_v3 (xmlDoc *doc, /* {{{ */ - xmlXPathContext *xpathCtx, xmlNode *statsnode, time_t current_time) -{ +static void bind_xml_stats_v3(xmlDoc *doc, /* {{{ */ + xmlXPathContext *xpathCtx, xmlNode *statsnode, + time_t current_time) { /* XPath: server/counters[@type='opcode'] * Variables: QUERY, IQUERY, NOTIFY, UPDATE, ... * Layout v3: @@ -1038,17 +943,14 @@ static void bind_xml_stats_v3 (xmlDoc *doc, /* {{{ */ * : * */ - if (global_opcodes != 0) - { - list_info_ptr_t list_info = - { - /* plugin instance = */ "global-opcodes", - /* type = */ "dns_opcode" - }; - bind_parse_generic_name_attr_value_list (/* xpath = */ "server/counters[@type='opcode']", - /* callback = */ bind_xml_list_callback, - /* user_data = */ &list_info, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); + if (global_opcodes != 0) { + list_info_ptr_t list_info = {/* plugin instance = */ "global-opcodes", + /* type = */ "dns_opcode"}; + bind_parse_generic_name_attr_value_list( + /* xpath = */ "server/counters[@type='opcode']", + /* callback = */ bind_xml_list_callback, + /* user_data = */ &list_info, doc, xpathCtx, current_time, + DS_TYPE_COUNTER); } /* XPath: server/counters[@type='qtype'] @@ -1061,18 +963,15 @@ static void bind_xml_stats_v3 (xmlDoc *doc, /* {{{ */ * : * */ - if (global_qtypes != 0) - { - list_info_ptr_t list_info = - { - /* plugin instance = */ "global-qtypes", - /* type = */ "dns_qtype" - }; + if (global_qtypes != 0) { + list_info_ptr_t list_info = {/* plugin instance = */ "global-qtypes", + /* type = */ "dns_qtype"}; - bind_parse_generic_name_attr_value_list (/* xpath = */ "server/counters[@type='qtype']", + bind_parse_generic_name_attr_value_list( + /* xpath = */ "server/counters[@type='qtype']", /* callback = */ bind_xml_list_callback, - /* user_data = */ &list_info, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); + /* user_data = */ &list_info, doc, xpathCtx, current_time, + DS_TYPE_COUNTER); } /* XPath: server/counters[@type='nsstat'] @@ -1091,22 +990,20 @@ static void bind_xml_stats_v3 (xmlDoc *doc, /* {{{ */ * : * */ - if (global_server_stats) - { - translation_table_ptr_t table_ptr = - { - nsstats_translation_table, - nsstats_translation_table_length, - /* plugin_instance = */ "global-server_stats" - }; + if (global_server_stats) { + translation_table_ptr_t table_ptr = { + nsstats_translation_table, nsstats_translation_table_length, + /* plugin_instance = */ "global-server_stats"}; - bind_parse_generic_name_attr_value_list ("server/counters[@type='nsstat']", + bind_parse_generic_name_attr_value_list( + "server/counters[@type='nsstat']", /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); + /* user_data = */ &table_ptr, doc, xpathCtx, current_time, + DS_TYPE_COUNTER); } - /* XPath: server/zonestats, server/zonestat, server/counters[@type='zonestat'] + /* XPath: server/zonestats, server/zonestat, + * server/counters[@type='zonestat'] * Variables: NotifyOutv4, NotifyOutv6, NotifyInv4, NotifyInv6, NotifyRej, * SOAOutv4, SOAOutv6, AXFRReqv4, AXFRReqv6, IXFRReqv4, IXFRReqv6, * XfrSuccess, XfrFail @@ -1117,19 +1014,16 @@ static void bind_xml_stats_v3 (xmlDoc *doc, /* {{{ */ * : * */ - if (global_zone_maint_stats) - { - translation_table_ptr_t table_ptr = - { - zonestats_translation_table, - zonestats_translation_table_length, - /* plugin_instance = */ "global-zone_maint_stats" - }; + if (global_zone_maint_stats) { + translation_table_ptr_t table_ptr = { + zonestats_translation_table, zonestats_translation_table_length, + /* plugin_instance = */ "global-zone_maint_stats"}; - bind_parse_generic_name_attr_value_list ("server/counters[@type='zonestat']", + bind_parse_generic_name_attr_value_list( + "server/counters[@type='zonestat']", /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); + /* user_data = */ &table_ptr, doc, xpathCtx, current_time, + DS_TYPE_COUNTER); } /* XPath: server/resstats, server/counters[@type='resstat'] @@ -1144,25 +1038,22 @@ static void bind_xml_stats_v3 (xmlDoc *doc, /* {{{ */ * : * */ - if (global_resolver_stats != 0) - { - translation_table_ptr_t table_ptr = - { - resstats_translation_table, - resstats_translation_table_length, - /* plugin_instance = */ "global-resolver_stats" - }; + if (global_resolver_stats != 0) { + translation_table_ptr_t table_ptr = { + resstats_translation_table, resstats_translation_table_length, + /* plugin_instance = */ "global-resolver_stats"}; - bind_parse_generic_name_attr_value_list ("server/counters[@type='resstat']", + bind_parse_generic_name_attr_value_list( + "server/counters[@type='resstat']", /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); + /* user_data = */ &table_ptr, doc, xpathCtx, current_time, + DS_TYPE_COUNTER); } } /* }}} bind_xml_stats_v3 */ -static void bind_xml_stats_v1_v2 (int version, xmlDoc *doc, /* {{{ */ - xmlXPathContext *xpathCtx, xmlNode *statsnode, time_t current_time) -{ +static void bind_xml_stats_v1_v2(int version, xmlDoc *doc, /* {{{ */ + xmlXPathContext *xpathCtx, xmlNode *statsnode, + time_t current_time) { /* XPath: server/requests/opcode, server/counters[@type='opcode'] * Variables: QUERY, IQUERY, NOTIFY, UPDATE, ... * Layout V1 and V2: @@ -1172,18 +1063,14 @@ static void bind_xml_stats_v1_v2 (int version, xmlDoc *doc, /* {{{ */ * * : */ - if (global_opcodes != 0) - { - list_info_ptr_t list_info = - { - /* plugin instance = */ "global-opcodes", - /* type = */ "dns_opcode" - }; + if (global_opcodes != 0) { + list_info_ptr_t list_info = {/* plugin instance = */ "global-opcodes", + /* type = */ "dns_opcode"}; - bind_parse_generic_name_value (/* xpath = */ "server/requests/opcode", - /* callback = */ bind_xml_list_callback, - /* user_data = */ &list_info, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); + bind_parse_generic_name_value(/* xpath = */ "server/requests/opcode", + /* callback = */ bind_xml_list_callback, + /* user_data = */ &list_info, doc, xpathCtx, + current_time, DS_TYPE_COUNTER); } /* XPath: server/queries-in/rdtype, server/counters[@type='qtype'] @@ -1197,18 +1084,14 @@ static void bind_xml_stats_v1_v2 (int version, xmlDoc *doc, /* {{{ */ * * : */ - if (global_qtypes != 0) - { - list_info_ptr_t list_info = - { - /* plugin instance = */ "global-qtypes", - /* type = */ "dns_qtype" - }; + if (global_qtypes != 0) { + list_info_ptr_t list_info = {/* plugin instance = */ "global-qtypes", + /* type = */ "dns_qtype"}; - bind_parse_generic_name_value (/* xpath = */ "server/queries-in/rdtype", - /* callback = */ bind_xml_list_callback, - /* user_data = */ &list_info, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); + bind_parse_generic_name_value(/* xpath = */ "server/queries-in/rdtype", + /* callback = */ bind_xml_list_callback, + /* user_data = */ &list_info, doc, xpathCtx, + current_time, DS_TYPE_COUNTER); } /* XPath: server/nsstats, server/nsstat, server/counters[@type='nsstat'] @@ -1237,32 +1120,26 @@ static void bind_xml_stats_v1_v2 (int version, xmlDoc *doc, /* {{{ */ * * : */ - if (global_server_stats) - { - translation_table_ptr_t table_ptr = - { - nsstats_translation_table, - nsstats_translation_table_length, - /* plugin_instance = */ "global-server_stats" - }; - - if (version == 1) - { - bind_parse_generic_value_list ("server/nsstats", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); - } - else - { - bind_parse_generic_name_value ("server/nsstat", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); + if (global_server_stats) { + translation_table_ptr_t table_ptr = { + nsstats_translation_table, nsstats_translation_table_length, + /* plugin_instance = */ "global-server_stats"}; + + if (version == 1) { + bind_parse_generic_value_list("server/nsstats", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, xpathCtx, + current_time, DS_TYPE_COUNTER); + } else { + bind_parse_generic_name_value("server/nsstat", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, xpathCtx, + current_time, DS_TYPE_COUNTER); } } - /* XPath: server/zonestats, server/zonestat, server/counters[@type='zonestat'] + /* XPath: server/zonestats, server/zonestat, + * server/counters[@type='zonestat'] * Variables: NotifyOutv4, NotifyOutv6, NotifyInv4, NotifyInv6, NotifyRej, * SOAOutv4, SOAOutv6, AXFRReqv4, AXFRReqv6, IXFRReqv4, IXFRReqv6, * XfrSuccess, XfrFail @@ -1283,28 +1160,21 @@ static void bind_xml_stats_v1_v2 (int version, xmlDoc *doc, /* {{{ */ * * : */ - if (global_zone_maint_stats) - { - translation_table_ptr_t table_ptr = - { - zonestats_translation_table, - zonestats_translation_table_length, - /* plugin_instance = */ "global-zone_maint_stats" - }; - - if (version == 1) - { - bind_parse_generic_value_list ("server/zonestats", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); - } - else - { - bind_parse_generic_name_value ("server/zonestat", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); + if (global_zone_maint_stats) { + translation_table_ptr_t table_ptr = { + zonestats_translation_table, zonestats_translation_table_length, + /* plugin_instance = */ "global-zone_maint_stats"}; + + if (version == 1) { + bind_parse_generic_value_list("server/zonestats", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, xpathCtx, + current_time, DS_TYPE_COUNTER); + } else { + bind_parse_generic_name_value("server/zonestat", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, xpathCtx, + current_time, DS_TYPE_COUNTER); } } @@ -1330,35 +1200,27 @@ static void bind_xml_stats_v1_v2 (int version, xmlDoc *doc, /* {{{ */ * * : */ - if (global_resolver_stats != 0) - { - translation_table_ptr_t table_ptr = - { - resstats_translation_table, - resstats_translation_table_length, - /* plugin_instance = */ "global-resolver_stats" - }; - - if (version == 1) - { - bind_parse_generic_value_list ("server/resstats", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); - } - else - { - bind_parse_generic_name_value ("server/resstat", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); + if (global_resolver_stats != 0) { + translation_table_ptr_t table_ptr = { + resstats_translation_table, resstats_translation_table_length, + /* plugin_instance = */ "global-resolver_stats"}; + + if (version == 1) { + bind_parse_generic_value_list("server/resstats", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, xpathCtx, + current_time, DS_TYPE_COUNTER); + } else { + bind_parse_generic_name_value("server/resstat", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, xpathCtx, + current_time, DS_TYPE_COUNTER); } } } /* }}} bind_xml_stats_v1_v2 */ -static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ - xmlXPathContext *xpathCtx, xmlNode *statsnode) -{ +static int bind_xml_stats(int version, xmlDoc *doc, /* {{{ */ + xmlXPathContext *xpathCtx, xmlNode *statsnode) { time_t current_time = 0; int status; @@ -1366,21 +1228,17 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ /* TODO: Check `server/boot-time' to recognize server restarts. */ - status = bind_xml_read_timestamp ("server/current-time", - doc, xpathCtx, ¤t_time); - if (status != 0) - { - ERROR ("bind plugin: Reading `server/current-time' failed."); + status = bind_xml_read_timestamp("server/current-time", doc, xpathCtx, + ¤t_time); + if (status != 0) { + ERROR("bind plugin: Reading `server/current-time' failed."); return (-1); } - DEBUG ("bind plugin: Current server time is %i.", (int) current_time); + DEBUG("bind plugin: Current server time is %i.", (int)current_time); - if (version == 3) - { + if (version == 3) { bind_xml_stats_v3(doc, xpathCtx, statsnode, current_time); - } - else - { + } else { bind_xml_stats_v1_v2(version, doc, xpathCtx, statsnode, current_time); } @@ -1395,47 +1253,41 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ * 0 * */ - if (global_memory_stats != 0) - { - translation_table_ptr_t table_ptr = - { - memsummary_translation_table, - memsummary_translation_table_length, - /* plugin_instance = */ "global-memory_stats" - }; + if (global_memory_stats != 0) { + translation_table_ptr_t table_ptr = { + memsummary_translation_table, memsummary_translation_table_length, + /* plugin_instance = */ "global-memory_stats"}; - bind_parse_generic_value_list ("memory/summary", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, xpathCtx, current_time, DS_TYPE_GAUGE); + bind_parse_generic_value_list("memory/summary", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, xpathCtx, + current_time, DS_TYPE_GAUGE); } if (views_num > 0) - bind_xml_stats_search_views (version, doc, xpathCtx, statsnode, - current_time); + bind_xml_stats_search_views(version, doc, xpathCtx, statsnode, + current_time); return 0; } /* }}} int bind_xml_stats */ -static int bind_xml (const char *data) /* {{{ */ +static int bind_xml(const char *data) /* {{{ */ { xmlDoc *doc = NULL; xmlXPathContext *xpathCtx = NULL; xmlXPathObject *xpathObj = NULL; int ret = -1; - doc = xmlParseMemory (data, strlen (data)); - if (doc == NULL) - { - ERROR ("bind plugin: xmlParseMemory failed."); + doc = xmlParseMemory(data, strlen(data)); + if (doc == NULL) { + ERROR("bind plugin: xmlParseMemory failed."); return (-1); } - xpathCtx = xmlXPathNewContext (doc); - if (xpathCtx == NULL) - { - ERROR ("bind plugin: xmlXPathNewContext failed."); - xmlFreeDoc (doc); + xpathCtx = xmlXPathNewContext(doc); + if (xpathCtx == NULL) { + ERROR("bind plugin: xmlXPathNewContext failed."); + xmlFreeDoc(doc); return (-1); } @@ -1443,52 +1295,50 @@ static int bind_xml (const char *data) /* {{{ */ // version 3.* of statistics XML (since BIND9.9) // - xpathObj = xmlXPathEvalExpression (BAD_CAST "/statistics", xpathCtx); - if (xpathObj == NULL || xpathObj->nodesetval == NULL || xpathObj->nodesetval->nodeNr == 0) - { - DEBUG ("bind plugin: Statistics appears not to be v3"); + xpathObj = xmlXPathEvalExpression(BAD_CAST "/statistics", xpathCtx); + if (xpathObj == NULL || xpathObj->nodesetval == NULL || + xpathObj->nodesetval->nodeNr == 0) { + DEBUG("bind plugin: Statistics appears not to be v3"); // we will fallback to v1 or v2 detection - if (xpathObj != NULL) { xmlXPathFreeObject (xpathObj); } - } - else - { - for (int i = 0; i < xpathObj->nodesetval->nodeNr; i++) - { + if (xpathObj != NULL) { + xmlXPathFreeObject(xpathObj); + } + } else { + for (int i = 0; i < xpathObj->nodesetval->nodeNr; i++) { xmlNode *node; char *attr_version; node = xpathObj->nodesetval->nodeTab[i]; - assert (node != NULL); + assert(node != NULL); - attr_version = (char *) xmlGetProp (node, BAD_CAST "version"); - if (attr_version == NULL) - { - NOTICE ("bind plugin: Found tag doesn't have a " - "`version' attribute."); + attr_version = (char *)xmlGetProp(node, BAD_CAST "version"); + if (attr_version == NULL) { + NOTICE("bind plugin: Found tag doesn't have a " + "`version' attribute."); continue; } - DEBUG ("bind plugin: Found: ", attr_version); + DEBUG("bind plugin: Found: ", attr_version); - if (strncmp ("3.", attr_version, strlen ("3.")) != 0) - { + if (strncmp("3.", attr_version, strlen("3.")) != 0) { /* TODO: Use the complaint mechanism here. */ - NOTICE ("bind plugin: Found tag with version `%s'. " - "Unfortunately I have no clue how to parse that. " - "Please open a bug report for this.", attr_version); - xmlFree (attr_version); + NOTICE("bind plugin: Found tag with version `%s'. " + "Unfortunately I have no clue how to parse that. " + "Please open a bug report for this.", + attr_version); + xmlFree(attr_version); continue; } - ret = bind_xml_stats (3, doc, xpathCtx, node); + ret = bind_xml_stats(3, doc, xpathCtx, node); - xmlFree (attr_version); + xmlFree(attr_version); /* One node ought to be enough. */ break; } // we are finished, early-return - xmlXPathFreeObject (xpathObj); - xmlXPathFreeContext (xpathCtx); - xmlFreeDoc (doc); + xmlXPathFreeObject(xpathObj); + xmlXPathFreeContext(xpathCtx); + xmlFreeDoc(doc); return (ret); } @@ -1497,81 +1347,74 @@ static int bind_xml (const char *data) /* {{{ */ // versions 1.* or 2.* of statistics XML // - xpathObj = xmlXPathEvalExpression (BAD_CAST "/isc/bind/statistics", xpathCtx); - if (xpathObj == NULL) - { - ERROR ("bind plugin: Cannot find the tag."); - xmlXPathFreeContext (xpathCtx); - xmlFreeDoc (doc); + xpathObj = xmlXPathEvalExpression(BAD_CAST "/isc/bind/statistics", xpathCtx); + if (xpathObj == NULL) { + ERROR("bind plugin: Cannot find the tag."); + xmlXPathFreeContext(xpathCtx); + xmlFreeDoc(doc); return (-1); - } - else if (xpathObj->nodesetval == NULL) - { - ERROR ("bind plugin: xmlXPathEvalExpression failed."); - xmlXPathFreeObject (xpathObj); - xmlXPathFreeContext (xpathCtx); - xmlFreeDoc (doc); + } else if (xpathObj->nodesetval == NULL) { + ERROR("bind plugin: xmlXPathEvalExpression failed."); + xmlXPathFreeObject(xpathObj); + xmlXPathFreeContext(xpathCtx); + xmlFreeDoc(doc); return (-1); } - for (int i = 0; i < xpathObj->nodesetval->nodeNr; i++) - { + for (int i = 0; i < xpathObj->nodesetval->nodeNr; i++) { xmlNode *node; char *attr_version; int parsed_version = 0; node = xpathObj->nodesetval->nodeTab[i]; - assert (node != NULL); + assert(node != NULL); - attr_version = (char *) xmlGetProp (node, BAD_CAST "version"); - if (attr_version == NULL) - { - NOTICE ("bind plugin: Found tag doesn't have a " - "`version' attribute."); + attr_version = (char *)xmlGetProp(node, BAD_CAST "version"); + if (attr_version == NULL) { + NOTICE("bind plugin: Found tag doesn't have a " + "`version' attribute."); continue; } - DEBUG ("bind plugin: Found: ", attr_version); + DEBUG("bind plugin: Found: ", attr_version); /* At the time this plugin was written, version "1.0" was used by * BIND 9.5.0, version "2.0" was used by BIND 9.5.1 and 9.6.0. We assume * that "1.*" and "2.*" don't introduce structural changes, so we just * check for the first two characters here. */ - if (strncmp ("1.", attr_version, strlen ("1.")) == 0) + if (strncmp("1.", attr_version, strlen("1.")) == 0) parsed_version = 1; - else if (strncmp ("2.", attr_version, strlen ("2.")) == 0) + else if (strncmp("2.", attr_version, strlen("2.")) == 0) parsed_version = 2; - else - { + else { /* TODO: Use the complaint mechanism here. */ - NOTICE ("bind plugin: Found tag with version `%s'. " - "Unfortunately I have no clue how to parse that. " - "Please open a bug report for this.", attr_version); - xmlFree (attr_version); + NOTICE("bind plugin: Found tag with version `%s'. " + "Unfortunately I have no clue how to parse that. " + "Please open a bug report for this.", + attr_version); + xmlFree(attr_version); continue; } - ret = bind_xml_stats (parsed_version, - doc, xpathCtx, node); + ret = bind_xml_stats(parsed_version, doc, xpathCtx, node); - xmlFree (attr_version); + xmlFree(attr_version); /* One node ought to be enough. */ break; } - xmlXPathFreeObject (xpathObj); - xmlXPathFreeContext (xpathCtx); - xmlFreeDoc (doc); + xmlXPathFreeObject(xpathObj); + xmlXPathFreeContext(xpathCtx); + xmlFreeDoc(doc); return (ret); } /* }}} int bind_xml */ -static int bind_config_set_bool (const char *name, int *var, /* {{{ */ - oconfig_item_t *ci) -{ - if ((ci->values_num != 1) || ( ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) - { - WARNING ("bind plugin: The `%s' option needs " - "exactly one boolean argument.", name); +static int bind_config_set_bool(const char *name, int *var, /* {{{ */ + oconfig_item_t *ci) { + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) { + WARNING("bind plugin: The `%s' option needs " + "exactly one boolean argument.", + name); return (-1); } @@ -1582,31 +1425,26 @@ static int bind_config_set_bool (const char *name, int *var, /* {{{ */ return 0; } /* }}} int bind_config_set_bool */ -static int bind_config_add_view_zone (cb_view_t *view, /* {{{ */ - oconfig_item_t *ci) -{ +static int bind_config_add_view_zone(cb_view_t *view, /* {{{ */ + oconfig_item_t *ci) { char **tmp; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("bind plugin: The `Zone' option needs " - "exactly one string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("bind plugin: The `Zone' option needs " + "exactly one string argument."); return (-1); } - tmp = realloc (view->zones, - sizeof (char *) * (view->zones_num + 1)); - if (tmp == NULL) - { - ERROR ("bind plugin: realloc failed."); + tmp = realloc(view->zones, sizeof(char *) * (view->zones_num + 1)); + if (tmp == NULL) { + ERROR("bind plugin: realloc failed."); return (-1); } view->zones = tmp; - view->zones[view->zones_num] = strdup (ci->values[0].value.string); - if (view->zones[view->zones_num] == NULL) - { - ERROR ("bind plugin: strdup failed."); + view->zones[view->zones_num] = strdup(ci->values[0].value.string); + if (view->zones[view->zones_num] == NULL) { + ERROR("bind plugin: strdup failed."); return (-1); } view->zones_num++; @@ -1614,56 +1452,52 @@ static int bind_config_add_view_zone (cb_view_t *view, /* {{{ */ return (0); } /* }}} int bind_config_add_view_zone */ -static int bind_config_add_view (oconfig_item_t *ci) /* {{{ */ +static int bind_config_add_view(oconfig_item_t *ci) /* {{{ */ { cb_view_t *tmp; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("bind plugin: `View' blocks need exactly one string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("bind plugin: `View' blocks need exactly one string argument."); return (-1); } - tmp = realloc (views, sizeof (*views) * (views_num + 1)); - if (tmp == NULL) - { - ERROR ("bind plugin: realloc failed."); + tmp = realloc(views, sizeof(*views) * (views_num + 1)); + if (tmp == NULL) { + ERROR("bind plugin: realloc failed."); return (-1); } views = tmp; tmp = views + views_num; - memset (tmp, 0, sizeof (*tmp)); + memset(tmp, 0, sizeof(*tmp)); tmp->qtypes = 1; tmp->resolver_stats = 1; tmp->cacherrsets = 1; tmp->zones = NULL; tmp->zones_num = 0; - tmp->name = strdup (ci->values[0].value.string); - if (tmp->name == NULL) - { - ERROR ("bind plugin: strdup failed."); - sfree (views); + tmp->name = strdup(ci->values[0].value.string); + if (tmp->name == NULL) { + ERROR("bind plugin: strdup failed."); + sfree(views); return (-1); } - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("QTypes", child->key) == 0) - bind_config_set_bool ("QTypes", &tmp->qtypes, child); - else if (strcasecmp ("ResolverStats", child->key) == 0) - bind_config_set_bool ("ResolverStats", &tmp->resolver_stats, child); - else if (strcasecmp ("CacheRRSets", child->key) == 0) - bind_config_set_bool ("CacheRRSets", &tmp->cacherrsets, child); - else if (strcasecmp ("Zone", child->key) == 0) - bind_config_add_view_zone (tmp, child); - else - { - WARNING ("bind plugin: Unknown configuration option " - "`%s' in view `%s' will be ignored.", child->key, tmp->name); + if (strcasecmp("QTypes", child->key) == 0) + bind_config_set_bool("QTypes", &tmp->qtypes, child); + else if (strcasecmp("ResolverStats", child->key) == 0) + bind_config_set_bool("ResolverStats", &tmp->resolver_stats, child); + else if (strcasecmp("CacheRRSets", child->key) == 0) + bind_config_set_bool("CacheRRSets", &tmp->cacherrsets, child); + else if (strcasecmp("Zone", child->key) == 0) + bind_config_add_view_zone(tmp, child); + else { + WARNING("bind plugin: Unknown configuration option " + "`%s' in view `%s' will be ignored.", + child->key, tmp->name); } } /* for (i = 0; i < ci->children_num; i++) */ @@ -1671,120 +1505,113 @@ static int bind_config_add_view (oconfig_item_t *ci) /* {{{ */ return (0); } /* }}} int bind_config_add_view */ -static int bind_config (oconfig_item_t *ci) /* {{{ */ +static int bind_config(oconfig_item_t *ci) /* {{{ */ { - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Url", child->key) == 0) { - if ((child->values_num != 1) || (child->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("bind plugin: The `Url' option needs " - "exactly one string argument."); + if (strcasecmp("Url", child->key) == 0) { + if ((child->values_num != 1) || + (child->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("bind plugin: The `Url' option needs " + "exactly one string argument."); return (-1); } - sfree (url); - url = strdup (child->values[0].value.string); - } else if (strcasecmp ("OpCodes", child->key) == 0) - bind_config_set_bool ("OpCodes", &global_opcodes, child); - else if (strcasecmp ("QTypes", child->key) == 0) - bind_config_set_bool ("QTypes", &global_qtypes, child); - else if (strcasecmp ("ServerStats", child->key) == 0) - bind_config_set_bool ("ServerStats", &global_server_stats, child); - else if (strcasecmp ("ZoneMaintStats", child->key) == 0) - bind_config_set_bool ("ZoneMaintStats", &global_zone_maint_stats, child); - else if (strcasecmp ("ResolverStats", child->key) == 0) - bind_config_set_bool ("ResolverStats", &global_resolver_stats, child); - else if (strcasecmp ("MemoryStats", child->key) == 0) - bind_config_set_bool ("MemoryStats", &global_memory_stats, child); - else if (strcasecmp ("View", child->key) == 0) - bind_config_add_view (child); - else if (strcasecmp ("ParseTime", child->key) == 0) - cf_util_get_boolean (child, &config_parse_time); - else if (strcasecmp ("Timeout", child->key) == 0) - cf_util_get_int (child, &timeout); - else - { - WARNING ("bind plugin: Unknown configuration option " - "`%s' will be ignored.", child->key); + sfree(url); + url = strdup(child->values[0].value.string); + } else if (strcasecmp("OpCodes", child->key) == 0) + bind_config_set_bool("OpCodes", &global_opcodes, child); + else if (strcasecmp("QTypes", child->key) == 0) + bind_config_set_bool("QTypes", &global_qtypes, child); + else if (strcasecmp("ServerStats", child->key) == 0) + bind_config_set_bool("ServerStats", &global_server_stats, child); + else if (strcasecmp("ZoneMaintStats", child->key) == 0) + bind_config_set_bool("ZoneMaintStats", &global_zone_maint_stats, child); + else if (strcasecmp("ResolverStats", child->key) == 0) + bind_config_set_bool("ResolverStats", &global_resolver_stats, child); + else if (strcasecmp("MemoryStats", child->key) == 0) + bind_config_set_bool("MemoryStats", &global_memory_stats, child); + else if (strcasecmp("View", child->key) == 0) + bind_config_add_view(child); + else if (strcasecmp("ParseTime", child->key) == 0) + cf_util_get_boolean(child, &config_parse_time); + else if (strcasecmp("Timeout", child->key) == 0) + cf_util_get_int(child, &timeout); + else { + WARNING("bind plugin: Unknown configuration option " + "`%s' will be ignored.", + child->key); } } return (0); } /* }}} int bind_config */ -static int bind_init (void) /* {{{ */ +static int bind_init(void) /* {{{ */ { if (curl != NULL) return (0); - curl = curl_easy_init (); - if (curl == NULL) - { - ERROR ("bind plugin: bind_init: curl_easy_init failed."); + curl = curl_easy_init(); + if (curl == NULL) { + ERROR("bind plugin: bind_init: curl_easy_init failed."); return (-1); } - curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, bind_curl_callback); - curl_easy_setopt (curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); - curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, bind_curl_error); - curl_easy_setopt (curl, CURLOPT_URL, (url != NULL) ? url : BIND_DEFAULT_URL); - curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt (curl, CURLOPT_MAXREDIRS, 50L); + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, bind_curl_callback); + curl_easy_setopt(curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, bind_curl_error); + curl_easy_setopt(curl, CURLOPT_URL, (url != NULL) ? url : BIND_DEFAULT_URL); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L); #ifdef HAVE_CURLOPT_TIMEOUT_MS - curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS, (timeout >= 0) ? - (long) timeout : (long) CDTIME_T_TO_MS(plugin_get_interval())); + curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, + (timeout >= 0) ? (long)timeout : (long)CDTIME_T_TO_MS( + plugin_get_interval())); #endif - return (0); } /* }}} int bind_init */ -static int bind_read (void) /* {{{ */ +static int bind_read(void) /* {{{ */ { int status; - if (curl == NULL) - { - ERROR ("bind plugin: I don't have a CURL object."); + if (curl == NULL) { + ERROR("bind plugin: I don't have a CURL object."); return (-1); } bind_buffer_fill = 0; - if (curl_easy_perform (curl) != CURLE_OK) - { - ERROR ("bind plugin: curl_easy_perform failed: %s", - bind_curl_error); + if (curl_easy_perform(curl) != CURLE_OK) { + ERROR("bind plugin: curl_easy_perform failed: %s", bind_curl_error); return (-1); } - status = bind_xml (bind_buffer); + status = bind_xml(bind_buffer); if (status != 0) return (-1); else return (0); } /* }}} int bind_read */ -static int bind_shutdown (void) /* {{{ */ +static int bind_shutdown(void) /* {{{ */ { - if (curl != NULL) - { - curl_easy_cleanup (curl); + if (curl != NULL) { + curl_easy_cleanup(curl); curl = NULL; } return (0); } /* }}} int bind_shutdown */ -void module_register (void) -{ - plugin_register_complex_config ("bind", bind_config); - plugin_register_init ("bind", bind_init); - plugin_register_read ("bind", bind_read); - plugin_register_shutdown ("bind", bind_shutdown); +void module_register(void) { + plugin_register_complex_config("bind", bind_config); + plugin_register_init("bind", bind_init); + plugin_register_read("bind", bind_read); + plugin_register_shutdown("bind", bind_shutdown); } /* void module_register */ /* vim: set sw=2 sts=2 ts=8 et fdm=marker : */ diff --git a/src/ceph.c b/src/ceph.c index 7c5c8a5b..4e435b3e 100644 --- a/src/ceph.c +++ b/src/ceph.c @@ -39,10 +39,12 @@ #include #endif #ifdef HAVE_SYS_CAPABILITY_H -# include +#include #endif +#include #include +#include #include #include #include @@ -53,30 +55,28 @@ #include #include #include -#include -#include #define RETRY_AVGCOUNT -1 #if defined(YAJL_MAJOR) && (YAJL_MAJOR > 1) -# define HAVE_YAJL_V2 1 +#define HAVE_YAJL_V2 1 #endif -#define RETRY_ON_EINTR(ret, expr) \ - while(1) { \ - ret = expr; \ - if(ret >= 0) \ - break; \ - ret = -errno; \ - if(ret != -EINTR) \ - break; \ - } +#define RETRY_ON_EINTR(ret, expr) \ + while (1) { \ + ret = expr; \ + if (ret >= 0) \ + break; \ + ret = -errno; \ + if (ret != -EINTR) \ + break; \ + } /** Timeout interval in seconds */ #define CEPH_TIMEOUT_INTERVAL 1 /** Maximum path length for a UNIX domain socket on this system */ -#define UNIX_DOMAIN_SOCK_PATH_MAX (sizeof(((struct sockaddr_un*)0)->sun_path)) +#define UNIX_DOMAIN_SOCK_PATH_MAX (sizeof(((struct sockaddr_un *)0)->sun_path)) /** Yajl callback returns */ #define CEPH_CB_CONTINUE 1 @@ -91,63 +91,60 @@ typedef unsigned int yajl_len_t; /** Number of types for ceph defined in types.db */ #define CEPH_DSET_TYPES_NUM 3 /** ceph types enum */ -enum ceph_dset_type_d -{ - DSET_LATENCY = 0, - DSET_BYTES = 1, - DSET_RATE = 2, - DSET_TYPE_UNFOUND = 1000 +enum ceph_dset_type_d { + DSET_LATENCY = 0, + DSET_BYTES = 1, + DSET_RATE = 2, + DSET_TYPE_UNFOUND = 1000 }; /** Valid types for ceph defined in types.db */ -static const char * const ceph_dset_types [CEPH_DSET_TYPES_NUM] = - {"ceph_latency", "ceph_bytes", "ceph_rate"}; +static const char *const ceph_dset_types[CEPH_DSET_TYPES_NUM] = { + "ceph_latency", "ceph_bytes", "ceph_rate"}; /******* ceph_daemon *******/ -struct ceph_daemon -{ - /** Version of the admin_socket interface */ - uint32_t version; - /** daemon name **/ - char name[DATA_MAX_NAME_LEN]; - - /** Path to the socket that we use to talk to the ceph daemon */ - char asok_path[UNIX_DOMAIN_SOCK_PATH_MAX]; - - /** Number of counters */ - int ds_num; - /** Track ds types */ - uint32_t *ds_types; - /** Track ds names to match with types */ - char **ds_names; - - /** - * Keep track of last data for latency values so we can calculate rate - * since last poll. - */ - struct last_data **last_poll_data; - /** index of last poll data */ - int last_idx; +struct ceph_daemon { + /** Version of the admin_socket interface */ + uint32_t version; + /** daemon name **/ + char name[DATA_MAX_NAME_LEN]; + + /** Path to the socket that we use to talk to the ceph daemon */ + char asok_path[UNIX_DOMAIN_SOCK_PATH_MAX]; + + /** Number of counters */ + int ds_num; + /** Track ds types */ + uint32_t *ds_types; + /** Track ds names to match with types */ + char **ds_names; + + /** + * Keep track of last data for latency values so we can calculate rate + * since last poll. + */ + struct last_data **last_poll_data; + /** index of last poll data */ + int last_idx; }; /******* JSON parsing *******/ -typedef int (*node_handler_t)(void *, const char*, const char*); +typedef int (*node_handler_t)(void *, const char *, const char *); /** Track state and handler while parsing JSON */ -struct yajl_struct -{ - node_handler_t handler; - void * handler_arg; - - char *key; - char *stack[YAJL_MAX_DEPTH]; - size_t depth; +struct yajl_struct { + node_handler_t handler; + void *handler_arg; + + char *key; + char *stack[YAJL_MAX_DEPTH]; + size_t depth; }; typedef struct yajl_struct yajl_struct; -enum perfcounter_type_d -{ - PERFCOUNTER_LATENCY = 0x4, PERFCOUNTER_DERIVE = 0x8, +enum perfcounter_type_d { + PERFCOUNTER_LATENCY = 0x4, + PERFCOUNTER_DERIVE = 0x8, }; /** Give user option to use default (long run = since daemon started) avg */ @@ -172,424 +169,376 @@ static size_t g_num_daemons = 0; /** * A set of data that we build up in memory while parsing the JSON. */ -struct values_tmp -{ - /** ceph daemon we are processing data for*/ - struct ceph_daemon *d; - /** track avgcount across counters for avgcount/sum latency pairs */ - uint64_t avgcount; - /** current index of counters - used to get type of counter */ - int index; - /** do we already have an avgcount for latency pair */ - int avgcount_exists; - /** - * similar to index, but current index of latency type counters - - * used to get last poll data of counter - */ - int latency_index; - /** - * values list - maintain across counters since - * host/plugin/plugin instance are always the same - */ - value_list_t vlist; +struct values_tmp { + /** ceph daemon we are processing data for*/ + struct ceph_daemon *d; + /** track avgcount across counters for avgcount/sum latency pairs */ + uint64_t avgcount; + /** current index of counters - used to get type of counter */ + int index; + /** do we already have an avgcount for latency pair */ + int avgcount_exists; + /** + * similar to index, but current index of latency type counters - + * used to get last poll data of counter + */ + int latency_index; + /** + * values list - maintain across counters since + * host/plugin/plugin instance are always the same + */ + value_list_t vlist; }; /** * A set of count/sum pairs to keep track of latency types and get difference * between this poll data and last poll data. */ -struct last_data -{ - char ds_name[DATA_MAX_NAME_LEN]; - double last_sum; - uint64_t last_count; +struct last_data { + char ds_name[DATA_MAX_NAME_LEN]; + double last_sum; + uint64_t last_count; }; /******* network I/O *******/ -enum cstate_t -{ - CSTATE_UNCONNECTED = 0, - CSTATE_WRITE_REQUEST, - CSTATE_READ_VERSION, - CSTATE_READ_AMT, - CSTATE_READ_JSON, +enum cstate_t { + CSTATE_UNCONNECTED = 0, + CSTATE_WRITE_REQUEST, + CSTATE_READ_VERSION, + CSTATE_READ_AMT, + CSTATE_READ_JSON, }; -enum request_type_t -{ - ASOK_REQ_VERSION = 0, - ASOK_REQ_DATA = 1, - ASOK_REQ_SCHEMA = 2, - ASOK_REQ_NONE = 1000, +enum request_type_t { + ASOK_REQ_VERSION = 0, + ASOK_REQ_DATA = 1, + ASOK_REQ_SCHEMA = 2, + ASOK_REQ_NONE = 1000, }; -struct cconn -{ - /** The Ceph daemon that we're talking to */ - struct ceph_daemon *d; +struct cconn { + /** The Ceph daemon that we're talking to */ + struct ceph_daemon *d; - /** Request type */ - uint32_t request_type; + /** Request type */ + uint32_t request_type; - /** The connection state */ - enum cstate_t state; + /** The connection state */ + enum cstate_t state; - /** The socket we use to talk to this daemon */ - int asok; + /** The socket we use to talk to this daemon */ + int asok; - /** The amount of data remaining to read / write. */ - uint32_t amt; + /** The amount of data remaining to read / write. */ + uint32_t amt; - /** Length of the JSON to read */ - uint32_t json_len; + /** Length of the JSON to read */ + uint32_t json_len; - /** Buffer containing JSON data */ - unsigned char *json; + /** Buffer containing JSON data */ + unsigned char *json; - /** Keep data important to yajl processing */ - struct yajl_struct yajl; + /** Keep data important to yajl processing */ + struct yajl_struct yajl; }; -static int ceph_cb_null(void *ctx) -{ - return CEPH_CB_CONTINUE; -} - -static int ceph_cb_boolean(void *ctx, int bool_val) -{ - return CEPH_CB_CONTINUE; -} +static int ceph_cb_null(void *ctx) { return CEPH_CB_CONTINUE; } + +static int ceph_cb_boolean(void *ctx, int bool_val) { return CEPH_CB_CONTINUE; } + +#define BUFFER_ADD(dest, src) \ + do { \ + size_t dest_size = sizeof(dest); \ + size_t dest_len = strlen(dest); \ + if (dest_size > dest_len) { \ + sstrncpy((dest) + dest_len, (src), dest_size - dest_len); \ + } \ + (dest)[dest_size - 1] = 0; \ + } while (0) + +static int ceph_cb_number(void *ctx, const char *number_val, + yajl_len_t number_len) { + yajl_struct *state = (yajl_struct *)ctx; + char buffer[number_len + 1]; + char key[2 * DATA_MAX_NAME_LEN] = {0}; + _Bool latency_type = 0; + int status; + + memcpy(buffer, number_val, number_len); + buffer[sizeof(buffer) - 1] = '\0'; + + for (size_t i = 0; i < state->depth; i++) { + if (state->stack[i] == NULL) + continue; + + if (strlen(key) != 0) + BUFFER_ADD(key, "."); + BUFFER_ADD(key, state->stack[i]); + } -#define BUFFER_ADD(dest, src) do { \ - size_t dest_size = sizeof (dest); \ - size_t dest_len = strlen (dest); \ - if (dest_size > dest_len) { \ - sstrncpy ((dest) + dest_len, (src), dest_size - dest_len); \ - } \ - (dest)[dest_size - 1] = 0; \ -} while (0) - -static int -ceph_cb_number(void *ctx, const char *number_val, yajl_len_t number_len) -{ - yajl_struct *state = (yajl_struct*) ctx; - char buffer[number_len+1]; - char key[2 * DATA_MAX_NAME_LEN] = { 0 }; - _Bool latency_type = 0; - int status; - - memcpy(buffer, number_val, number_len); - buffer[sizeof(buffer) - 1] = '\0'; - - for (size_t i = 0; i < state->depth; i++) - { - if (state->stack[i] == NULL) - continue; - - if (strlen (key) != 0) - BUFFER_ADD (key, "."); - BUFFER_ADD (key, state->stack[i]); - } + /* Special case for latency metrics. */ + if ((strcmp("avgcount", state->key) == 0) || + (strcmp("sum", state->key) == 0)) { + latency_type = 1; + + /* depth >= 2 => (stack[-1] != NULL && stack[-2] != NULL) */ + assert((state->depth < 2) || ((state->stack[state->depth - 1] != NULL) && + (state->stack[state->depth - 2] != NULL))); + + /* Super-special case for filestore.journal_wr_bytes.avgcount: For + * some reason, Ceph schema encodes this as a count/sum pair while all + * other "Bytes" data (excluding used/capacity bytes for OSD space) uses + * a single "Derive" type. To spare further confusion, keep this KPI as + * the same type of other "Bytes". Instead of keeping an "average" or + * "rate", use the "sum" in the pair and assign that to the derive + * value. */ + if (convert_special_metrics && (state->depth >= 2) && + (strcmp("filestore", state->stack[state->depth - 2]) == 0) && + (strcmp("journal_wr_bytes", state->stack[state->depth - 1]) == 0) && + (strcmp("avgcount", state->key) == 0)) { + DEBUG("ceph plugin: Skipping avgcount for filestore.JournalWrBytes"); + return CEPH_CB_CONTINUE; + } + } else /* not a latency type */ + { + BUFFER_ADD(key, "."); + BUFFER_ADD(key, state->key); + } - /* Special case for latency metrics. */ - if ((strcmp ("avgcount", state->key) == 0) - || (strcmp ("sum", state->key) == 0)) - { - latency_type = 1; - - /* depth >= 2 => (stack[-1] != NULL && stack[-2] != NULL) */ - assert ((state->depth < 2) - || ((state->stack[state->depth - 1] != NULL) - && (state->stack[state->depth - 2] != NULL))); - - /* Super-special case for filestore.journal_wr_bytes.avgcount: For - * some reason, Ceph schema encodes this as a count/sum pair while all - * other "Bytes" data (excluding used/capacity bytes for OSD space) uses - * a single "Derive" type. To spare further confusion, keep this KPI as - * the same type of other "Bytes". Instead of keeping an "average" or - * "rate", use the "sum" in the pair and assign that to the derive - * value. */ - if (convert_special_metrics && (state->depth >= 2) - && (strcmp("filestore", state->stack[state->depth - 2]) == 0) - && (strcmp("journal_wr_bytes", state->stack[state->depth - 1]) == 0) - && (strcmp("avgcount", state->key) == 0)) - { - DEBUG("ceph plugin: Skipping avgcount for filestore.JournalWrBytes"); - return CEPH_CB_CONTINUE; - } - } - else /* not a latency type */ - { - BUFFER_ADD (key, "."); - BUFFER_ADD (key, state->key); - } + status = state->handler(state->handler_arg, buffer, key); + if ((status == RETRY_AVGCOUNT) && latency_type) { + /* Add previously skipped part of the key, either "avgcount" or "sum", + * and try again. */ + BUFFER_ADD(key, "."); + BUFFER_ADD(key, state->key); status = state->handler(state->handler_arg, buffer, key); - if((status == RETRY_AVGCOUNT) && latency_type) - { - /* Add previously skipped part of the key, either "avgcount" or "sum", - * and try again. */ - BUFFER_ADD (key, "."); - BUFFER_ADD (key, state->key); - - status = state->handler(state->handler_arg, buffer, key); - } + } - if (status != 0) - { - ERROR("ceph plugin: JSON handler failed with status %d.", status); - return CEPH_CB_ABORT; - } + if (status != 0) { + ERROR("ceph plugin: JSON handler failed with status %d.", status); + return CEPH_CB_ABORT; + } - return CEPH_CB_CONTINUE; + return CEPH_CB_CONTINUE; } static int ceph_cb_string(void *ctx, const unsigned char *string_val, - yajl_len_t string_len) -{ - return CEPH_CB_CONTINUE; + yajl_len_t string_len) { + return CEPH_CB_CONTINUE; } -static int ceph_cb_start_map(void *ctx) -{ - yajl_struct *state = (yajl_struct*) ctx; +static int ceph_cb_start_map(void *ctx) { + yajl_struct *state = (yajl_struct *)ctx; - /* Push key to the stack */ - if (state->depth == YAJL_MAX_DEPTH) - return CEPH_CB_ABORT; + /* Push key to the stack */ + if (state->depth == YAJL_MAX_DEPTH) + return CEPH_CB_ABORT; - state->stack[state->depth] = state->key; - state->depth++; - state->key = NULL; + state->stack[state->depth] = state->key; + state->depth++; + state->key = NULL; - return CEPH_CB_CONTINUE; + return CEPH_CB_CONTINUE; } -static int ceph_cb_end_map(void *ctx) -{ - yajl_struct *state = (yajl_struct*) ctx; +static int ceph_cb_end_map(void *ctx) { + yajl_struct *state = (yajl_struct *)ctx; - /* Pop key from the stack */ - if (state->depth == 0) - return CEPH_CB_ABORT; + /* Pop key from the stack */ + if (state->depth == 0) + return CEPH_CB_ABORT; - sfree (state->key); - state->depth--; - state->key = state->stack[state->depth]; - state->stack[state->depth] = NULL; + sfree(state->key); + state->depth--; + state->key = state->stack[state->depth]; + state->stack[state->depth] = NULL; - return CEPH_CB_CONTINUE; + return CEPH_CB_CONTINUE; } -static int -ceph_cb_map_key(void *ctx, const unsigned char *key, yajl_len_t string_len) -{ - yajl_struct *state = (yajl_struct*) ctx; - size_t sz = ((size_t) string_len) + 1; - - sfree (state->key); - state->key = malloc (sz); - if (state->key == NULL) - { - ERROR ("ceph plugin: malloc failed."); - return CEPH_CB_ABORT; - } +static int ceph_cb_map_key(void *ctx, const unsigned char *key, + yajl_len_t string_len) { + yajl_struct *state = (yajl_struct *)ctx; + size_t sz = ((size_t)string_len) + 1; - memmove (state->key, key, sz - 1); - state->key[sz - 1] = 0; + sfree(state->key); + state->key = malloc(sz); + if (state->key == NULL) { + ERROR("ceph plugin: malloc failed."); + return CEPH_CB_ABORT; + } - return CEPH_CB_CONTINUE; -} + memmove(state->key, key, sz - 1); + state->key[sz - 1] = 0; -static int ceph_cb_start_array(void *ctx) -{ - return CEPH_CB_CONTINUE; + return CEPH_CB_CONTINUE; } -static int ceph_cb_end_array(void *ctx) -{ - return CEPH_CB_CONTINUE; -} +static int ceph_cb_start_array(void *ctx) { return CEPH_CB_CONTINUE; } -static yajl_callbacks callbacks = { - ceph_cb_null, - ceph_cb_boolean, - NULL, - NULL, - ceph_cb_number, - ceph_cb_string, - ceph_cb_start_map, - ceph_cb_map_key, - ceph_cb_end_map, - ceph_cb_start_array, - ceph_cb_end_array -}; +static int ceph_cb_end_array(void *ctx) { return CEPH_CB_CONTINUE; } -static void ceph_daemon_print(const struct ceph_daemon *d) -{ - DEBUG("ceph plugin: name=%s, asok_path=%s", d->name, d->asok_path); +static yajl_callbacks callbacks = {ceph_cb_null, + ceph_cb_boolean, + NULL, + NULL, + ceph_cb_number, + ceph_cb_string, + ceph_cb_start_map, + ceph_cb_map_key, + ceph_cb_end_map, + ceph_cb_start_array, + ceph_cb_end_array}; + +static void ceph_daemon_print(const struct ceph_daemon *d) { + DEBUG("ceph plugin: name=%s, asok_path=%s", d->name, d->asok_path); } -static void ceph_daemons_print(void) -{ - for(size_t i = 0; i < g_num_daemons; ++i) - { - ceph_daemon_print(g_daemons[i]); - } +static void ceph_daemons_print(void) { + for (size_t i = 0; i < g_num_daemons; ++i) { + ceph_daemon_print(g_daemons[i]); + } } -static void ceph_daemon_free(struct ceph_daemon *d) -{ - for(int i = 0; i < d->last_idx; i++) - { - sfree(d->last_poll_data[i]); - } - sfree(d->last_poll_data); - d->last_poll_data = NULL; - d->last_idx = 0; +static void ceph_daemon_free(struct ceph_daemon *d) { + for (int i = 0; i < d->last_idx; i++) { + sfree(d->last_poll_data[i]); + } + sfree(d->last_poll_data); + d->last_poll_data = NULL; + d->last_idx = 0; - for(int i = 0; i < d->ds_num; i++) - { - sfree(d->ds_names[i]); - } - sfree(d->ds_types); - sfree(d->ds_names); - sfree(d); + for (int i = 0; i < d->ds_num; i++) { + sfree(d->ds_names[i]); + } + sfree(d->ds_types); + sfree(d->ds_names); + sfree(d); } /* compact_ds_name removed the special characters ":", "_", "-" and "+" from the * intput string. Characters following these special characters are capitalized. * Trailing "+" and "-" characters are replaces with the strings "Plus" and * "Minus". */ -static int compact_ds_name (char *buffer, size_t buffer_size, char const *src) -{ - char *src_copy; - size_t src_len; - char *ptr = buffer; - size_t ptr_size = buffer_size; - _Bool append_plus = 0; - _Bool append_minus = 0; - - if ((buffer == NULL) || (buffer_size <= strlen ("Minus")) || (src == NULL)) - return EINVAL; - - src_copy = strdup (src); - src_len = strlen(src); - - /* Remove trailing "+" and "-". */ - if (src_copy[src_len - 1] == '+') - { - append_plus = 1; - src_len--; - src_copy[src_len] = 0; - } - else if (src_copy[src_len - 1] == '-') - { - append_minus = 1; - src_len--; - src_copy[src_len] = 0; - } +static int compact_ds_name(char *buffer, size_t buffer_size, char const *src) { + char *src_copy; + size_t src_len; + char *ptr = buffer; + size_t ptr_size = buffer_size; + _Bool append_plus = 0; + _Bool append_minus = 0; + + if ((buffer == NULL) || (buffer_size <= strlen("Minus")) || (src == NULL)) + return EINVAL; + + src_copy = strdup(src); + src_len = strlen(src); + + /* Remove trailing "+" and "-". */ + if (src_copy[src_len - 1] == '+') { + append_plus = 1; + src_len--; + src_copy[src_len] = 0; + } else if (src_copy[src_len - 1] == '-') { + append_minus = 1; + src_len--; + src_copy[src_len] = 0; + } - /* Split at special chars, capitalize first character, append to buffer. */ - char *dummy = src_copy; - char *token; - char *save_ptr = NULL; - while ((token = strtok_r (dummy, ":_-+", &save_ptr)) != NULL) - { - size_t len; + /* Split at special chars, capitalize first character, append to buffer. */ + char *dummy = src_copy; + char *token; + char *save_ptr = NULL; + while ((token = strtok_r(dummy, ":_-+", &save_ptr)) != NULL) { + size_t len; - dummy = NULL; + dummy = NULL; - token[0] = toupper ((int) token[0]); + token[0] = toupper((int)token[0]); - assert (ptr_size > 1); + assert(ptr_size > 1); - len = strlen (token); - if (len >= ptr_size) - len = ptr_size - 1; + len = strlen(token); + if (len >= ptr_size) + len = ptr_size - 1; - assert (len > 0); - assert (len < ptr_size); + assert(len > 0); + assert(len < ptr_size); - sstrncpy (ptr, token, len + 1); - ptr += len; - ptr_size -= len; + sstrncpy(ptr, token, len + 1); + ptr += len; + ptr_size -= len; - assert (*ptr == 0); - if (ptr_size <= 1) - break; - } + assert(*ptr == 0); + if (ptr_size <= 1) + break; + } - /* Append "Plus" or "Minus" if "+" or "-" has been stripped above. */ - if (append_plus || append_minus) - { - char const *append = "Plus"; - if (append_minus) - append = "Minus"; + /* Append "Plus" or "Minus" if "+" or "-" has been stripped above. */ + if (append_plus || append_minus) { + char const *append = "Plus"; + if (append_minus) + append = "Minus"; - size_t offset = buffer_size - (strlen (append) + 1); - if (offset > strlen (buffer)) - offset = strlen (buffer); + size_t offset = buffer_size - (strlen(append) + 1); + if (offset > strlen(buffer)) + offset = strlen(buffer); - sstrncpy (buffer + offset, append, buffer_size - offset); - } + sstrncpy(buffer + offset, append, buffer_size - offset); + } - sfree (src_copy); - return 0; + sfree(src_copy); + return 0; } -static _Bool has_suffix (char const *str, char const *suffix) -{ - size_t str_len = strlen (str); - size_t suffix_len = strlen (suffix); - size_t offset; +static _Bool has_suffix(char const *str, char const *suffix) { + size_t str_len = strlen(str); + size_t suffix_len = strlen(suffix); + size_t offset; - if (suffix_len > str_len) - return 0; - offset = str_len - suffix_len; + if (suffix_len > str_len) + return 0; + offset = str_len - suffix_len; - if (strcmp (str + offset, suffix) == 0) - return 1; + if (strcmp(str + offset, suffix) == 0) + return 1; - return 0; + return 0; } /* count_parts returns the number of elements a "foo.bar.baz" style key has. */ -static size_t count_parts (char const *key) -{ - size_t parts_num = 0; +static size_t count_parts(char const *key) { + size_t parts_num = 0; - for (const char *ptr = key; ptr != NULL; ptr = strchr (ptr + 1, '.')) - parts_num++; + for (const char *ptr = key; ptr != NULL; ptr = strchr(ptr + 1, '.')) + parts_num++; - return parts_num; + return parts_num; } /** * Parse key to remove "type" if this is for schema and initiate compaction */ -static int parse_keys (char *buffer, size_t buffer_size, const char *key_str) -{ - char tmp[2 * buffer_size]; - - if (buffer == NULL || buffer_size == 0 || key_str == NULL || strlen (key_str) == 0) - return EINVAL; - - if ((count_parts (key_str) > 2) && has_suffix (key_str, ".type")) - { - /* strip ".type" suffix iff the key has more than two parts. */ - size_t sz = strlen (key_str) - strlen (".type") + 1; - - if (sz > sizeof (tmp)) - sz = sizeof (tmp); - sstrncpy (tmp, key_str, sz); - } - else - { - sstrncpy (tmp, key_str, sizeof (tmp)); - } +static int parse_keys(char *buffer, size_t buffer_size, const char *key_str) { + char tmp[2 * buffer_size]; + + if (buffer == NULL || buffer_size == 0 || key_str == NULL || + strlen(key_str) == 0) + return EINVAL; + + if ((count_parts(key_str) > 2) && has_suffix(key_str, ".type")) { + /* strip ".type" suffix iff the key has more than two parts. */ + size_t sz = strlen(key_str) - strlen(".type") + 1; + + if (sz > sizeof(tmp)) + sz = sizeof(tmp); + sstrncpy(tmp, key_str, sz); + } else { + sstrncpy(tmp, key_str, sizeof(tmp)); + } - return compact_ds_name (buffer, buffer_size, tmp); + return compact_ds_name(buffer, buffer_size, tmp); } /** @@ -597,322 +546,270 @@ static int parse_keys (char *buffer, size_t buffer_size, const char *key_str) * data processing */ static int ceph_daemon_add_ds_entry(struct ceph_daemon *d, const char *name, - int pc_type) -{ - uint32_t type; - char ds_name[DATA_MAX_NAME_LEN]; - - if(convert_special_metrics) - { - /** - * Special case for filestore:JournalWrBytes. For some reason, Ceph - * schema encodes this as a count/sum pair while all other "Bytes" data - * (excluding used/capacity bytes for OSD space) uses a single "Derive" - * type. To spare further confusion, keep this KPI as the same type of - * other "Bytes". Instead of keeping an "average" or "rate", use the - * "sum" in the pair and assign that to the derive value. - */ - if((strcmp(name,"filestore.journal_wr_bytes.type") == 0)) - { - pc_type = 10; - } - } + int pc_type) { + uint32_t type; + char ds_name[DATA_MAX_NAME_LEN]; - d->ds_names = realloc(d->ds_names, sizeof(char *) * (d->ds_num + 1)); - if(!d->ds_names) - { - return -ENOMEM; + if (convert_special_metrics) { + /** + * Special case for filestore:JournalWrBytes. For some reason, Ceph + * schema encodes this as a count/sum pair while all other "Bytes" data + * (excluding used/capacity bytes for OSD space) uses a single "Derive" + * type. To spare further confusion, keep this KPI as the same type of + * other "Bytes". Instead of keeping an "average" or "rate", use the + * "sum" in the pair and assign that to the derive value. + */ + if ((strcmp(name, "filestore.journal_wr_bytes.type") == 0)) { + pc_type = 10; } + } - d->ds_types = realloc(d->ds_types, sizeof(uint32_t) * (d->ds_num + 1)); - if(!d->ds_types) - { - return -ENOMEM; - } + d->ds_names = realloc(d->ds_names, sizeof(char *) * (d->ds_num + 1)); + if (!d->ds_names) { + return -ENOMEM; + } - d->ds_names[d->ds_num] = malloc(DATA_MAX_NAME_LEN); - if(!d->ds_names[d->ds_num]) - { - return -ENOMEM; - } + d->ds_types = realloc(d->ds_types, sizeof(uint32_t) * (d->ds_num + 1)); + if (!d->ds_types) { + return -ENOMEM; + } + + d->ds_names[d->ds_num] = malloc(DATA_MAX_NAME_LEN); + if (!d->ds_names[d->ds_num]) { + return -ENOMEM; + } - type = (pc_type & PERFCOUNTER_DERIVE) ? DSET_RATE : - ((pc_type & PERFCOUNTER_LATENCY) ? DSET_LATENCY : DSET_BYTES); - d->ds_types[d->ds_num] = type; + type = (pc_type & PERFCOUNTER_DERIVE) + ? DSET_RATE + : ((pc_type & PERFCOUNTER_LATENCY) ? DSET_LATENCY : DSET_BYTES); + d->ds_types[d->ds_num] = type; - if (parse_keys(ds_name, sizeof (ds_name), name)) - { - return 1; - } + if (parse_keys(ds_name, sizeof(ds_name), name)) { + return 1; + } - sstrncpy(d->ds_names[d->ds_num], ds_name, DATA_MAX_NAME_LEN -1); - d->ds_num = (d->ds_num + 1); + sstrncpy(d->ds_names[d->ds_num], ds_name, DATA_MAX_NAME_LEN - 1); + d->ds_num = (d->ds_num + 1); - return 0; + return 0; } /******* ceph_config *******/ -static int cc_handle_str(struct oconfig_item_s *item, char *dest, int dest_len) -{ - const char *val; - if(item->values_num != 1) - { - return -ENOTSUP; - } - if(item->values[0].type != OCONFIG_TYPE_STRING) - { - return -ENOTSUP; - } - val = item->values[0].value.string; - if(snprintf(dest, dest_len, "%s", val) > (dest_len - 1)) - { - ERROR("ceph plugin: configuration parameter '%s' is too long.\n", - item->key); - return -ENAMETOOLONG; - } - return 0; +static int cc_handle_str(struct oconfig_item_s *item, char *dest, + int dest_len) { + const char *val; + if (item->values_num != 1) { + return -ENOTSUP; + } + if (item->values[0].type != OCONFIG_TYPE_STRING) { + return -ENOTSUP; + } + val = item->values[0].value.string; + if (snprintf(dest, dest_len, "%s", val) > (dest_len - 1)) { + ERROR("ceph plugin: configuration parameter '%s' is too long.\n", + item->key); + return -ENAMETOOLONG; + } + return 0; } -static int cc_handle_bool(struct oconfig_item_s *item, int *dest) -{ - if(item->values_num != 1) - { - return -ENOTSUP; - } +static int cc_handle_bool(struct oconfig_item_s *item, int *dest) { + if (item->values_num != 1) { + return -ENOTSUP; + } - if(item->values[0].type != OCONFIG_TYPE_BOOLEAN) - { - return -ENOTSUP; - } + if (item->values[0].type != OCONFIG_TYPE_BOOLEAN) { + return -ENOTSUP; + } - *dest = (item->values[0].value.boolean) ? 1 : 0; - return 0; + *dest = (item->values[0].value.boolean) ? 1 : 0; + return 0; } -static int cc_add_daemon_config(oconfig_item_t *ci) -{ - int ret; - struct ceph_daemon *nd, cd = { 0 }; - struct ceph_daemon **tmp; - - if((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING("ceph plugin: `Daemon' blocks need exactly one string " - "argument."); - return (-1); - } +static int cc_add_daemon_config(oconfig_item_t *ci) { + int ret; + struct ceph_daemon *nd, cd = {0}; + struct ceph_daemon **tmp; - ret = cc_handle_str(ci, cd.name, DATA_MAX_NAME_LEN); - if(ret) - { - return ret; - } + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("ceph plugin: `Daemon' blocks need exactly one string " + "argument."); + return (-1); + } - for(int i=0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if(strcasecmp("SocketPath", child->key) == 0) - { - ret = cc_handle_str(child, cd.asok_path, sizeof(cd.asok_path)); - if(ret) - { - return ret; - } - } - else - { - WARNING("ceph plugin: ignoring unknown option %s", child->key); - } - } - if(cd.name[0] == '\0') - { - ERROR("ceph plugin: you must configure a daemon name.\n"); - return -EINVAL; - } - else if(cd.asok_path[0] == '\0') - { - ERROR("ceph plugin(name=%s): you must configure an administrative " - "socket path.\n", cd.name); - return -EINVAL; - } - else if(!((cd.asok_path[0] == '/') || - (cd.asok_path[0] == '.' && cd.asok_path[1] == '/'))) - { - ERROR("ceph plugin(name=%s): administrative socket paths must begin " - "with '/' or './' Can't parse: '%s'\n", cd.name, cd.asok_path); - return -EINVAL; - } + ret = cc_handle_str(ci, cd.name, DATA_MAX_NAME_LEN); + if (ret) { + return ret; + } - tmp = realloc(g_daemons, (g_num_daemons+1) * sizeof(*g_daemons)); - if(tmp == NULL) - { - /* The positive return value here indicates that this is a - * runtime error, not a configuration error. */ - return ENOMEM; - } - g_daemons = tmp; + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; - nd = malloc(sizeof (*nd)); - if(!nd) - { - return ENOMEM; + if (strcasecmp("SocketPath", child->key) == 0) { + ret = cc_handle_str(child, cd.asok_path, sizeof(cd.asok_path)); + if (ret) { + return ret; + } + } else { + WARNING("ceph plugin: ignoring unknown option %s", child->key); } - memcpy(nd, &cd, sizeof(*nd)); - g_daemons[g_num_daemons] = nd; - g_num_daemons++; - return 0; + } + if (cd.name[0] == '\0') { + ERROR("ceph plugin: you must configure a daemon name.\n"); + return -EINVAL; + } else if (cd.asok_path[0] == '\0') { + ERROR("ceph plugin(name=%s): you must configure an administrative " + "socket path.\n", + cd.name); + return -EINVAL; + } else if (!((cd.asok_path[0] == '/') || + (cd.asok_path[0] == '.' && cd.asok_path[1] == '/'))) { + ERROR("ceph plugin(name=%s): administrative socket paths must begin " + "with '/' or './' Can't parse: '%s'\n", + cd.name, cd.asok_path); + return -EINVAL; + } + + tmp = realloc(g_daemons, (g_num_daemons + 1) * sizeof(*g_daemons)); + if (tmp == NULL) { + /* The positive return value here indicates that this is a + * runtime error, not a configuration error. */ + return ENOMEM; + } + g_daemons = tmp; + + nd = malloc(sizeof(*nd)); + if (!nd) { + return ENOMEM; + } + memcpy(nd, &cd, sizeof(*nd)); + g_daemons[g_num_daemons] = nd; + g_num_daemons++; + return 0; } -static int ceph_config(oconfig_item_t *ci) -{ - int ret; - - for(int i = 0; i < ci->children_num; ++i) - { - oconfig_item_t *child = ci->children + i; - if(strcasecmp("Daemon", child->key) == 0) - { - ret = cc_add_daemon_config(child); - if(ret == ENOMEM) - { - ERROR("ceph plugin: Couldn't allocate memory"); - return ret; - } - else if(ret) - { - //process other daemons and ignore this one - continue; - } - } - else if(strcasecmp("LongRunAvgLatency", child->key) == 0) - { - ret = cc_handle_bool(child, &long_run_latency_avg); - if(ret) - { - return ret; - } - } - else if(strcasecmp("ConvertSpecialMetricTypes", child->key) == 0) - { - ret = cc_handle_bool(child, &convert_special_metrics); - if(ret) - { - return ret; - } - } - else - { - WARNING("ceph plugin: ignoring unknown option %s", child->key); - } +static int ceph_config(oconfig_item_t *ci) { + int ret; + + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *child = ci->children + i; + if (strcasecmp("Daemon", child->key) == 0) { + ret = cc_add_daemon_config(child); + if (ret == ENOMEM) { + ERROR("ceph plugin: Couldn't allocate memory"); + return ret; + } else if (ret) { + // process other daemons and ignore this one + continue; + } + } else if (strcasecmp("LongRunAvgLatency", child->key) == 0) { + ret = cc_handle_bool(child, &long_run_latency_avg); + if (ret) { + return ret; + } + } else if (strcasecmp("ConvertSpecialMetricTypes", child->key) == 0) { + ret = cc_handle_bool(child, &convert_special_metrics); + if (ret) { + return ret; + } + } else { + WARNING("ceph plugin: ignoring unknown option %s", child->key); } - return 0; + } + return 0; } /** * Parse JSON and get error message if present */ -static int -traverse_json(const unsigned char *json, uint32_t json_len, yajl_handle hand) -{ - yajl_status status = yajl_parse(hand, json, json_len); - unsigned char *msg; - - switch(status) - { - case yajl_status_error: - msg = yajl_get_error(hand, /* verbose = */ 1, - /* jsonText = */ (unsigned char *) json, - (unsigned int) json_len); - ERROR ("ceph plugin: yajl_parse failed: %s", msg); - yajl_free_error(hand, msg); - return 1; - case yajl_status_client_canceled: - return 1; - default: - return 0; - } +static int traverse_json(const unsigned char *json, uint32_t json_len, + yajl_handle hand) { + yajl_status status = yajl_parse(hand, json, json_len); + unsigned char *msg; + + switch (status) { + case yajl_status_error: + msg = yajl_get_error(hand, /* verbose = */ 1, + /* jsonText = */ (unsigned char *)json, + (unsigned int)json_len); + ERROR("ceph plugin: yajl_parse failed: %s", msg); + yajl_free_error(hand, msg); + return 1; + case yajl_status_client_canceled: + return 1; + default: + return 0; + } } /** * Add entry for each counter while parsing schema */ -static int -node_handler_define_schema(void *arg, const char *val, const char *key) -{ - struct ceph_daemon *d = (struct ceph_daemon *) arg; - int pc_type; - pc_type = atoi(val); - return ceph_daemon_add_ds_entry(d, key, pc_type); +static int node_handler_define_schema(void *arg, const char *val, + const char *key) { + struct ceph_daemon *d = (struct ceph_daemon *)arg; + int pc_type; + pc_type = atoi(val); + return ceph_daemon_add_ds_entry(d, key, pc_type); } /** * Latency counter does not yet have an entry in last poll data - add it. */ static int add_last(struct ceph_daemon *d, const char *ds_n, double cur_sum, - uint64_t cur_count) -{ - d->last_poll_data[d->last_idx] = malloc(sizeof (*d->last_poll_data[d->last_idx])); - if(!d->last_poll_data[d->last_idx]) - { - return -ENOMEM; - } - sstrncpy(d->last_poll_data[d->last_idx]->ds_name,ds_n, - sizeof(d->last_poll_data[d->last_idx]->ds_name)); - d->last_poll_data[d->last_idx]->last_sum = cur_sum; - d->last_poll_data[d->last_idx]->last_count = cur_count; - d->last_idx = (d->last_idx + 1); - return 0; + uint64_t cur_count) { + d->last_poll_data[d->last_idx] = + malloc(sizeof(*d->last_poll_data[d->last_idx])); + if (!d->last_poll_data[d->last_idx]) { + return -ENOMEM; + } + sstrncpy(d->last_poll_data[d->last_idx]->ds_name, ds_n, + sizeof(d->last_poll_data[d->last_idx]->ds_name)); + d->last_poll_data[d->last_idx]->last_sum = cur_sum; + d->last_poll_data[d->last_idx]->last_count = cur_count; + d->last_idx = (d->last_idx + 1); + return 0; } /** * Update latency counter or add new entry if it doesn't exist */ static int update_last(struct ceph_daemon *d, const char *ds_n, int index, - double cur_sum, uint64_t cur_count) -{ - if((d->last_idx > index) && (strcmp(d->last_poll_data[index]->ds_name, ds_n) == 0)) - { - d->last_poll_data[index]->last_sum = cur_sum; - d->last_poll_data[index]->last_count = cur_count; - return 0; - } + double cur_sum, uint64_t cur_count) { + if ((d->last_idx > index) && + (strcmp(d->last_poll_data[index]->ds_name, ds_n) == 0)) { + d->last_poll_data[index]->last_sum = cur_sum; + d->last_poll_data[index]->last_count = cur_count; + return 0; + } - if(!d->last_poll_data) - { - d->last_poll_data = malloc(sizeof (*d->last_poll_data)); - if(!d->last_poll_data) - { - return -ENOMEM; - } + if (!d->last_poll_data) { + d->last_poll_data = malloc(sizeof(*d->last_poll_data)); + if (!d->last_poll_data) { + return -ENOMEM; } - else - { - struct last_data **tmp_last = realloc(d->last_poll_data, - ((d->last_idx+1) * sizeof(struct last_data *))); - if(!tmp_last) - { - return -ENOMEM; - } - d->last_poll_data = tmp_last; + } else { + struct last_data **tmp_last = realloc( + d->last_poll_data, ((d->last_idx + 1) * sizeof(struct last_data *))); + if (!tmp_last) { + return -ENOMEM; } - return add_last(d, ds_n, cur_sum, cur_count); + d->last_poll_data = tmp_last; + } + return add_last(d, ds_n, cur_sum, cur_count); } /** * If using index guess failed (shouldn't happen, but possible if counters * get rearranged), resort to searching for counter name */ -static int backup_search_for_last_avg(struct ceph_daemon *d, const char *ds_n) -{ - for(int i = 0; i < d->last_idx; i++) - { - if(strcmp(d->last_poll_data[i]->ds_name, ds_n) == 0) - { - return i; - } +static int backup_search_for_last_avg(struct ceph_daemon *d, const char *ds_n) { + for (int i = 0; i < d->last_idx; i++) { + if (strcmp(d->last_poll_data[i]->ds_name, ds_n) == 0) { + return i; } - return -1; + } + return -1; } /** @@ -920,720 +817,633 @@ static int backup_search_for_last_avg(struct ceph_daemon *d, const char *ds_n) * if last poll data exists */ static double get_last_avg(struct ceph_daemon *d, const char *ds_n, int index, - double cur_sum, uint64_t cur_count) -{ - double result = -1.1, sum_delt = 0.0; - uint64_t count_delt = 0; - int tmp_index = 0; - if(d->last_idx > index) - { - if(strcmp(d->last_poll_data[index]->ds_name, ds_n) == 0) - { - tmp_index = index; - } - //test previous index - else if((index > 0) && (strcmp(d->last_poll_data[index-1]->ds_name, ds_n) == 0)) - { - tmp_index = (index - 1); - } - else - { - tmp_index = backup_search_for_last_avg(d, ds_n); - } - - if((tmp_index > -1) && (cur_count > d->last_poll_data[tmp_index]->last_count)) - { - sum_delt = (cur_sum - d->last_poll_data[tmp_index]->last_sum); - count_delt = (cur_count - d->last_poll_data[tmp_index]->last_count); - result = (sum_delt / count_delt); - } + double cur_sum, uint64_t cur_count) { + double result = -1.1, sum_delt = 0.0; + uint64_t count_delt = 0; + int tmp_index = 0; + if (d->last_idx > index) { + if (strcmp(d->last_poll_data[index]->ds_name, ds_n) == 0) { + tmp_index = index; + } + // test previous index + else if ((index > 0) && + (strcmp(d->last_poll_data[index - 1]->ds_name, ds_n) == 0)) { + tmp_index = (index - 1); + } else { + tmp_index = backup_search_for_last_avg(d, ds_n); + } + + if ((tmp_index > -1) && + (cur_count > d->last_poll_data[tmp_index]->last_count)) { + sum_delt = (cur_sum - d->last_poll_data[tmp_index]->last_sum); + count_delt = (cur_count - d->last_poll_data[tmp_index]->last_count); + result = (sum_delt / count_delt); } + } - if(result == -1.1) - { - result = NAN; - } - if(update_last(d, ds_n, tmp_index, cur_sum, cur_count) == -ENOMEM) - { - return -ENOMEM; - } - return result; + if (result == -1.1) { + result = NAN; + } + if (update_last(d, ds_n, tmp_index, cur_sum, cur_count) == -ENOMEM) { + return -ENOMEM; + } + return result; } /** * If using index guess failed, resort to searching for counter name */ -static uint32_t backup_search_for_type(struct ceph_daemon *d, char *ds_name) -{ - for(int i = 0; i < d->ds_num; i++) - { - if(strcmp(d->ds_names[i], ds_name) == 0) - { - return d->ds_types[i]; - } +static uint32_t backup_search_for_type(struct ceph_daemon *d, char *ds_name) { + for (int i = 0; i < d->ds_num; i++) { + if (strcmp(d->ds_names[i], ds_name) == 0) { + return d->ds_types[i]; } - return DSET_TYPE_UNFOUND; + } + return DSET_TYPE_UNFOUND; } /** * Process counter data and dispatch values */ -static int node_handler_fetch_data(void *arg, const char *val, const char *key) -{ - value_t uv; - double tmp_d; - uint64_t tmp_u; - struct values_tmp *vtmp = (struct values_tmp*) arg; - uint32_t type = DSET_TYPE_UNFOUND; - int index = vtmp->index; - - char ds_name[DATA_MAX_NAME_LEN]; - - if (parse_keys (ds_name, sizeof (ds_name), key)) - { - return 1; - } +static int node_handler_fetch_data(void *arg, const char *val, + const char *key) { + value_t uv; + double tmp_d; + uint64_t tmp_u; + struct values_tmp *vtmp = (struct values_tmp *)arg; + uint32_t type = DSET_TYPE_UNFOUND; + int index = vtmp->index; + + char ds_name[DATA_MAX_NAME_LEN]; + + if (parse_keys(ds_name, sizeof(ds_name), key)) { + return 1; + } - if(index >= vtmp->d->ds_num) - { - //don't overflow bounds of array - index = (vtmp->d->ds_num - 1); - } + if (index >= vtmp->d->ds_num) { + // don't overflow bounds of array + index = (vtmp->d->ds_num - 1); + } - /** - * counters should remain in same order we parsed schema... we maintain the - * index variable to keep track of current point in list of counters. first - * use index to guess point in array for retrieving type. if that doesn't - * work, use the old way to get the counter type - */ - if(strcmp(ds_name, vtmp->d->ds_names[index]) == 0) - { - //found match - type = vtmp->d->ds_types[index]; - } - else if((index > 0) && (strcmp(ds_name, vtmp->d->ds_names[index-1]) == 0)) - { - //try previous key - type = vtmp->d->ds_types[index-1]; - } + /** + * counters should remain in same order we parsed schema... we maintain the + * index variable to keep track of current point in list of counters. first + * use index to guess point in array for retrieving type. if that doesn't + * work, use the old way to get the counter type + */ + if (strcmp(ds_name, vtmp->d->ds_names[index]) == 0) { + // found match + type = vtmp->d->ds_types[index]; + } else if ((index > 0) && + (strcmp(ds_name, vtmp->d->ds_names[index - 1]) == 0)) { + // try previous key + type = vtmp->d->ds_types[index - 1]; + } - if(type == DSET_TYPE_UNFOUND) - { - //couldn't find right type by guessing, check the old way - type = backup_search_for_type(vtmp->d, ds_name); - } + if (type == DSET_TYPE_UNFOUND) { + // couldn't find right type by guessing, check the old way + type = backup_search_for_type(vtmp->d, ds_name); + } - switch(type) - { - case DSET_LATENCY: - if(vtmp->avgcount_exists == -1) - { - sscanf(val, "%" PRIu64, &vtmp->avgcount); - vtmp->avgcount_exists = 0; - //return after saving avgcount - don't dispatch value - //until latency calculation - return 0; - } - else - { - double sum, result; - sscanf(val, "%lf", &sum); - - if(vtmp->avgcount == 0) - { - vtmp->avgcount = 1; - } - - /** User wants latency values as long run avg */ - if(long_run_latency_avg) - { - result = (sum / vtmp->avgcount); - } - else - { - result = get_last_avg(vtmp->d, ds_name, vtmp->latency_index, sum, vtmp->avgcount); - if(result == -ENOMEM) - { - return -ENOMEM; - } - } - - uv.gauge = result; - vtmp->avgcount_exists = -1; - vtmp->latency_index = (vtmp->latency_index + 1); - } - break; - case DSET_BYTES: - sscanf(val, "%lf", &tmp_d); - uv.gauge = tmp_d; - break; - case DSET_RATE: - sscanf(val, "%" PRIu64, &tmp_u); - uv.derive = tmp_u; - break; - case DSET_TYPE_UNFOUND: - default: - ERROR("ceph plugin: ds %s was not properly initialized.", ds_name); - return -1; - } + switch (type) { + case DSET_LATENCY: + if (vtmp->avgcount_exists == -1) { + sscanf(val, "%" PRIu64, &vtmp->avgcount); + vtmp->avgcount_exists = 0; + // return after saving avgcount - don't dispatch value + // until latency calculation + return 0; + } else { + double sum, result; + sscanf(val, "%lf", &sum); + + if (vtmp->avgcount == 0) { + vtmp->avgcount = 1; + } + + /** User wants latency values as long run avg */ + if (long_run_latency_avg) { + result = (sum / vtmp->avgcount); + } else { + result = get_last_avg(vtmp->d, ds_name, vtmp->latency_index, sum, + vtmp->avgcount); + if (result == -ENOMEM) { + return -ENOMEM; + } + } + + uv.gauge = result; + vtmp->avgcount_exists = -1; + vtmp->latency_index = (vtmp->latency_index + 1); + } + break; + case DSET_BYTES: + sscanf(val, "%lf", &tmp_d); + uv.gauge = tmp_d; + break; + case DSET_RATE: + sscanf(val, "%" PRIu64, &tmp_u); + uv.derive = tmp_u; + break; + case DSET_TYPE_UNFOUND: + default: + ERROR("ceph plugin: ds %s was not properly initialized.", ds_name); + return -1; + } - sstrncpy(vtmp->vlist.type, ceph_dset_types[type], sizeof(vtmp->vlist.type)); - sstrncpy(vtmp->vlist.type_instance, ds_name, sizeof(vtmp->vlist.type_instance)); - vtmp->vlist.values = &uv; - vtmp->vlist.values_len = 1; + sstrncpy(vtmp->vlist.type, ceph_dset_types[type], sizeof(vtmp->vlist.type)); + sstrncpy(vtmp->vlist.type_instance, ds_name, + sizeof(vtmp->vlist.type_instance)); + vtmp->vlist.values = &uv; + vtmp->vlist.values_len = 1; - vtmp->index = (vtmp->index + 1); - plugin_dispatch_values(&vtmp->vlist); + vtmp->index = (vtmp->index + 1); + plugin_dispatch_values(&vtmp->vlist); - return 0; + return 0; } -static int cconn_connect(struct cconn *io) -{ - struct sockaddr_un address = { 0 }; - int flags, fd, err; - if(io->state != CSTATE_UNCONNECTED) - { - ERROR("ceph plugin: cconn_connect: io->state != CSTATE_UNCONNECTED"); - return -EDOM; - } - fd = socket(PF_UNIX, SOCK_STREAM, 0); - if(fd < 0) - { - err = -errno; - ERROR("ceph plugin: cconn_connect: socket(PF_UNIX, SOCK_STREAM, 0) " - "failed: error %d", err); - return err; - } - address.sun_family = AF_UNIX; - snprintf(address.sun_path, sizeof(address.sun_path), "%s", - io->d->asok_path); - RETRY_ON_EINTR(err, - connect(fd, (struct sockaddr *) &address, sizeof(struct sockaddr_un))); - if(err < 0) - { - ERROR("ceph plugin: cconn_connect: connect(%d) failed: error %d", - fd, err); - close(fd); - return err; - } +static int cconn_connect(struct cconn *io) { + struct sockaddr_un address = {0}; + int flags, fd, err; + if (io->state != CSTATE_UNCONNECTED) { + ERROR("ceph plugin: cconn_connect: io->state != CSTATE_UNCONNECTED"); + return -EDOM; + } + fd = socket(PF_UNIX, SOCK_STREAM, 0); + if (fd < 0) { + err = -errno; + ERROR("ceph plugin: cconn_connect: socket(PF_UNIX, SOCK_STREAM, 0) " + "failed: error %d", + err); + return err; + } + address.sun_family = AF_UNIX; + snprintf(address.sun_path, sizeof(address.sun_path), "%s", io->d->asok_path); + RETRY_ON_EINTR(err, connect(fd, (struct sockaddr *)&address, + sizeof(struct sockaddr_un))); + if (err < 0) { + ERROR("ceph plugin: cconn_connect: connect(%d) failed: error %d", fd, err); + close(fd); + return err; + } - flags = fcntl(fd, F_GETFL, 0); - if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) != 0) - { - err = -errno; - ERROR("ceph plugin: cconn_connect: fcntl(%d, O_NONBLOCK) error %d", - fd, err); - close(fd); - return err; - } - io->asok = fd; - io->state = CSTATE_WRITE_REQUEST; - io->amt = 0; - io->json_len = 0; - io->json = NULL; - return 0; + flags = fcntl(fd, F_GETFL, 0); + if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) != 0) { + err = -errno; + ERROR("ceph plugin: cconn_connect: fcntl(%d, O_NONBLOCK) error %d", fd, + err); + close(fd); + return err; + } + io->asok = fd; + io->state = CSTATE_WRITE_REQUEST; + io->amt = 0; + io->json_len = 0; + io->json = NULL; + return 0; } -static void cconn_close(struct cconn *io) -{ - io->state = CSTATE_UNCONNECTED; - if(io->asok != -1) - { - int res; - RETRY_ON_EINTR(res, close(io->asok)); - } - io->asok = -1; - io->amt = 0; - io->json_len = 0; - sfree(io->json); - io->json = NULL; +static void cconn_close(struct cconn *io) { + io->state = CSTATE_UNCONNECTED; + if (io->asok != -1) { + int res; + RETRY_ON_EINTR(res, close(io->asok)); + } + io->asok = -1; + io->amt = 0; + io->json_len = 0; + sfree(io->json); + io->json = NULL; } /* Process incoming JSON counter data */ -static int -cconn_process_data(struct cconn *io, yajl_struct *yajl, yajl_handle hand) -{ - int ret; - struct values_tmp *vtmp = calloc(1, sizeof(struct values_tmp) * 1); - if(!vtmp) - { - return -ENOMEM; - } +static int cconn_process_data(struct cconn *io, yajl_struct *yajl, + yajl_handle hand) { + int ret; + struct values_tmp *vtmp = calloc(1, sizeof(struct values_tmp) * 1); + if (!vtmp) { + return -ENOMEM; + } - vtmp->vlist = (value_list_t)VALUE_LIST_INIT; - sstrncpy(vtmp->vlist.plugin, "ceph", sizeof(vtmp->vlist.plugin)); - sstrncpy(vtmp->vlist.plugin_instance, io->d->name, sizeof(vtmp->vlist.plugin_instance)); - - vtmp->d = io->d; - vtmp->avgcount_exists = -1; - vtmp->latency_index = 0; - vtmp->index = 0; - yajl->handler_arg = vtmp; - ret = traverse_json(io->json, io->json_len, hand); - sfree(vtmp); - return ret; + vtmp->vlist = (value_list_t)VALUE_LIST_INIT; + sstrncpy(vtmp->vlist.plugin, "ceph", sizeof(vtmp->vlist.plugin)); + sstrncpy(vtmp->vlist.plugin_instance, io->d->name, + sizeof(vtmp->vlist.plugin_instance)); + + vtmp->d = io->d; + vtmp->avgcount_exists = -1; + vtmp->latency_index = 0; + vtmp->index = 0; + yajl->handler_arg = vtmp; + ret = traverse_json(io->json, io->json_len, hand); + sfree(vtmp); + return ret; } /** * Initiate JSON parsing and print error if one occurs */ -static int cconn_process_json(struct cconn *io) -{ - if((io->request_type != ASOK_REQ_DATA) && - (io->request_type != ASOK_REQ_SCHEMA)) - { - return -EDOM; - } +static int cconn_process_json(struct cconn *io) { + if ((io->request_type != ASOK_REQ_DATA) && + (io->request_type != ASOK_REQ_SCHEMA)) { + return -EDOM; + } - int result = 1; - yajl_handle hand; - yajl_status status; + int result = 1; + yajl_handle hand; + yajl_status status; - hand = yajl_alloc(&callbacks, + hand = yajl_alloc(&callbacks, #if HAVE_YAJL_V2 - /* alloc funcs = */ NULL, + /* alloc funcs = */ NULL, #else - /* alloc funcs = */ NULL, NULL, + /* alloc funcs = */ NULL, NULL, #endif - /* context = */ (void *)(&io->yajl)); + /* context = */ (void *)(&io->yajl)); - if(!hand) - { - ERROR ("ceph plugin: yajl_alloc failed."); - return ENOMEM; - } + if (!hand) { + ERROR("ceph plugin: yajl_alloc failed."); + return ENOMEM; + } - io->yajl.depth = 0; - - switch(io->request_type) - { - case ASOK_REQ_DATA: - io->yajl.handler = node_handler_fetch_data; - result = cconn_process_data(io, &io->yajl, hand); - break; - case ASOK_REQ_SCHEMA: - //init daemon specific variables - io->d->ds_num = 0; - io->d->last_idx = 0; - io->d->last_poll_data = NULL; - io->yajl.handler = node_handler_define_schema; - io->yajl.handler_arg = io->d; - result = traverse_json(io->json, io->json_len, hand); - break; - } + io->yajl.depth = 0; + + switch (io->request_type) { + case ASOK_REQ_DATA: + io->yajl.handler = node_handler_fetch_data; + result = cconn_process_data(io, &io->yajl, hand); + break; + case ASOK_REQ_SCHEMA: + // init daemon specific variables + io->d->ds_num = 0; + io->d->last_idx = 0; + io->d->last_poll_data = NULL; + io->yajl.handler = node_handler_define_schema; + io->yajl.handler_arg = io->d; + result = traverse_json(io->json, io->json_len, hand); + break; + } - if(result) - { - goto done; - } + if (result) { + goto done; + } #if HAVE_YAJL_V2 - status = yajl_complete_parse(hand); + status = yajl_complete_parse(hand); #else - status = yajl_parse_complete(hand); + status = yajl_parse_complete(hand); #endif - if (status != yajl_status_ok) - { - unsigned char *errmsg = yajl_get_error (hand, /* verbose = */ 0, - /* jsonText = */ NULL, /* jsonTextLen = */ 0); - ERROR ("ceph plugin: yajl_parse_complete failed: %s", - (char *) errmsg); - yajl_free_error (hand, errmsg); - yajl_free (hand); - return 1; - } + if (status != yajl_status_ok) { + unsigned char *errmsg = + yajl_get_error(hand, /* verbose = */ 0, + /* jsonText = */ NULL, /* jsonTextLen = */ 0); + ERROR("ceph plugin: yajl_parse_complete failed: %s", (char *)errmsg); + yajl_free_error(hand, errmsg); + yajl_free(hand); + return 1; + } - done: - yajl_free (hand); - return result; +done: + yajl_free(hand); + return result; } -static int cconn_validate_revents(struct cconn *io, int revents) -{ - if(revents & POLLERR) - { - ERROR("ceph plugin: cconn_validate_revents(name=%s): got POLLERR", - io->d->name); - return -EIO; - } - switch (io->state) - { - case CSTATE_WRITE_REQUEST: - return (revents & POLLOUT) ? 0 : -EINVAL; - case CSTATE_READ_VERSION: - case CSTATE_READ_AMT: - case CSTATE_READ_JSON: - return (revents & POLLIN) ? 0 : -EINVAL; - default: - ERROR("ceph plugin: cconn_validate_revents(name=%s) got to " - "illegal state on line %d", io->d->name, __LINE__); - return -EDOM; - } +static int cconn_validate_revents(struct cconn *io, int revents) { + if (revents & POLLERR) { + ERROR("ceph plugin: cconn_validate_revents(name=%s): got POLLERR", + io->d->name); + return -EIO; + } + switch (io->state) { + case CSTATE_WRITE_REQUEST: + return (revents & POLLOUT) ? 0 : -EINVAL; + case CSTATE_READ_VERSION: + case CSTATE_READ_AMT: + case CSTATE_READ_JSON: + return (revents & POLLIN) ? 0 : -EINVAL; + default: + ERROR("ceph plugin: cconn_validate_revents(name=%s) got to " + "illegal state on line %d", + io->d->name, __LINE__); + return -EDOM; + } } /** Handle a network event for a connection */ -static int cconn_handle_event(struct cconn *io) -{ - int ret; - switch (io->state) - { - case CSTATE_UNCONNECTED: - ERROR("ceph plugin: cconn_handle_event(name=%s) got to illegal " - "state on line %d", io->d->name, __LINE__); - - return -EDOM; - case CSTATE_WRITE_REQUEST: - { - char cmd[32]; - snprintf(cmd, sizeof(cmd), "%s%d%s", "{ \"prefix\": \"", - io->request_type, "\" }\n"); - size_t cmd_len = strlen(cmd); - RETRY_ON_EINTR(ret, - write(io->asok, ((char*)&cmd) + io->amt, cmd_len - io->amt)); - DEBUG("ceph plugin: cconn_handle_event(name=%s,state=%d,amt=%d,ret=%d)", - io->d->name, io->state, io->amt, ret); - if(ret < 0) - { - return ret; - } - io->amt += ret; - if(io->amt >= cmd_len) - { - io->amt = 0; - switch (io->request_type) - { - case ASOK_REQ_VERSION: - io->state = CSTATE_READ_VERSION; - break; - default: - io->state = CSTATE_READ_AMT; - break; - } - } - return 0; - } - case CSTATE_READ_VERSION: - { - RETRY_ON_EINTR(ret, - read(io->asok, ((char*)(&io->d->version)) + io->amt, - sizeof(io->d->version) - io->amt)); - DEBUG("ceph plugin: cconn_handle_event(name=%s,state=%d,ret=%d)", - io->d->name, io->state, ret); - if(ret < 0) - { - return ret; - } - io->amt += ret; - if(io->amt >= sizeof(io->d->version)) - { - io->d->version = ntohl(io->d->version); - if(io->d->version != 1) - { - ERROR("ceph plugin: cconn_handle_event(name=%s) not " - "expecting version %d!", io->d->name, io->d->version); - return -ENOTSUP; - } - DEBUG("ceph plugin: cconn_handle_event(name=%s): identified as " - "version %d", io->d->name, io->d->version); - io->amt = 0; - cconn_close(io); - io->request_type = ASOK_REQ_SCHEMA; - } - return 0; - } - case CSTATE_READ_AMT: - { - RETRY_ON_EINTR(ret, - read(io->asok, ((char*)(&io->json_len)) + io->amt, - sizeof(io->json_len) - io->amt)); - DEBUG("ceph plugin: cconn_handle_event(name=%s,state=%d,ret=%d)", - io->d->name, io->state, ret); - if(ret < 0) - { - return ret; - } - io->amt += ret; - if(io->amt >= sizeof(io->json_len)) - { - io->json_len = ntohl(io->json_len); - io->amt = 0; - io->state = CSTATE_READ_JSON; - io->json = calloc(1, io->json_len + 1); - if(!io->json) - { - ERROR("ceph plugin: error callocing io->json"); - return -ENOMEM; - } - } - return 0; - } - case CSTATE_READ_JSON: - { - RETRY_ON_EINTR(ret, +static int cconn_handle_event(struct cconn *io) { + int ret; + switch (io->state) { + case CSTATE_UNCONNECTED: + ERROR("ceph plugin: cconn_handle_event(name=%s) got to illegal " + "state on line %d", + io->d->name, __LINE__); + + return -EDOM; + case CSTATE_WRITE_REQUEST: { + char cmd[32]; + snprintf(cmd, sizeof(cmd), "%s%d%s", "{ \"prefix\": \"", io->request_type, + "\" }\n"); + size_t cmd_len = strlen(cmd); + RETRY_ON_EINTR( + ret, write(io->asok, ((char *)&cmd) + io->amt, cmd_len - io->amt)); + DEBUG("ceph plugin: cconn_handle_event(name=%s,state=%d,amt=%d,ret=%d)", + io->d->name, io->state, io->amt, ret); + if (ret < 0) { + return ret; + } + io->amt += ret; + if (io->amt >= cmd_len) { + io->amt = 0; + switch (io->request_type) { + case ASOK_REQ_VERSION: + io->state = CSTATE_READ_VERSION; + break; + default: + io->state = CSTATE_READ_AMT; + break; + } + } + return 0; + } + case CSTATE_READ_VERSION: { + RETRY_ON_EINTR(ret, read(io->asok, ((char *)(&io->d->version)) + io->amt, + sizeof(io->d->version) - io->amt)); + DEBUG("ceph plugin: cconn_handle_event(name=%s,state=%d,ret=%d)", + io->d->name, io->state, ret); + if (ret < 0) { + return ret; + } + io->amt += ret; + if (io->amt >= sizeof(io->d->version)) { + io->d->version = ntohl(io->d->version); + if (io->d->version != 1) { + ERROR("ceph plugin: cconn_handle_event(name=%s) not " + "expecting version %d!", + io->d->name, io->d->version); + return -ENOTSUP; + } + DEBUG("ceph plugin: cconn_handle_event(name=%s): identified as " + "version %d", + io->d->name, io->d->version); + io->amt = 0; + cconn_close(io); + io->request_type = ASOK_REQ_SCHEMA; + } + return 0; + } + case CSTATE_READ_AMT: { + RETRY_ON_EINTR(ret, read(io->asok, ((char *)(&io->json_len)) + io->amt, + sizeof(io->json_len) - io->amt)); + DEBUG("ceph plugin: cconn_handle_event(name=%s,state=%d,ret=%d)", + io->d->name, io->state, ret); + if (ret < 0) { + return ret; + } + io->amt += ret; + if (io->amt >= sizeof(io->json_len)) { + io->json_len = ntohl(io->json_len); + io->amt = 0; + io->state = CSTATE_READ_JSON; + io->json = calloc(1, io->json_len + 1); + if (!io->json) { + ERROR("ceph plugin: error callocing io->json"); + return -ENOMEM; + } + } + return 0; + } + case CSTATE_READ_JSON: { + RETRY_ON_EINTR(ret, read(io->asok, io->json + io->amt, io->json_len - io->amt)); - DEBUG("ceph plugin: cconn_handle_event(name=%s,state=%d,ret=%d)", - io->d->name, io->state, ret); - if(ret < 0) - { - return ret; - } - io->amt += ret; - if(io->amt >= io->json_len) - { - ret = cconn_process_json(io); - if(ret) - { - return ret; - } - cconn_close(io); - io->request_type = ASOK_REQ_NONE; - } - return 0; - } - default: - ERROR("ceph plugin: cconn_handle_event(name=%s) got to illegal " - "state on line %d", io->d->name, __LINE__); - return -EDOM; + DEBUG("ceph plugin: cconn_handle_event(name=%s,state=%d,ret=%d)", + io->d->name, io->state, ret); + if (ret < 0) { + return ret; + } + io->amt += ret; + if (io->amt >= io->json_len) { + ret = cconn_process_json(io); + if (ret) { + return ret; + } + cconn_close(io); + io->request_type = ASOK_REQ_NONE; } + return 0; + } + default: + ERROR("ceph plugin: cconn_handle_event(name=%s) got to illegal " + "state on line %d", + io->d->name, __LINE__); + return -EDOM; + } } -static int cconn_prepare(struct cconn *io, struct pollfd* fds) -{ - int ret; - if(io->request_type == ASOK_REQ_NONE) - { - /* The request has already been serviced. */ - return 0; - } - else if((io->request_type == ASOK_REQ_DATA) && (io->d->ds_num == 0)) - { - /* If there are no counters to report on, don't bother - * connecting */ - return 0; - } +static int cconn_prepare(struct cconn *io, struct pollfd *fds) { + int ret; + if (io->request_type == ASOK_REQ_NONE) { + /* The request has already been serviced. */ + return 0; + } else if ((io->request_type == ASOK_REQ_DATA) && (io->d->ds_num == 0)) { + /* If there are no counters to report on, don't bother + * connecting */ + return 0; + } - switch (io->state) - { - case CSTATE_UNCONNECTED: - ret = cconn_connect(io); - if(ret > 0) - { - return -ret; - } - else if(ret < 0) - { - return ret; - } - fds->fd = io->asok; - fds->events = POLLOUT; - return 1; - case CSTATE_WRITE_REQUEST: - fds->fd = io->asok; - fds->events = POLLOUT; - return 1; - case CSTATE_READ_VERSION: - case CSTATE_READ_AMT: - case CSTATE_READ_JSON: - fds->fd = io->asok; - fds->events = POLLIN; - return 1; - default: - ERROR("ceph plugin: cconn_prepare(name=%s) got to illegal state " - "on line %d", io->d->name, __LINE__); - return -EDOM; - } + switch (io->state) { + case CSTATE_UNCONNECTED: + ret = cconn_connect(io); + if (ret > 0) { + return -ret; + } else if (ret < 0) { + return ret; + } + fds->fd = io->asok; + fds->events = POLLOUT; + return 1; + case CSTATE_WRITE_REQUEST: + fds->fd = io->asok; + fds->events = POLLOUT; + return 1; + case CSTATE_READ_VERSION: + case CSTATE_READ_AMT: + case CSTATE_READ_JSON: + fds->fd = io->asok; + fds->events = POLLIN; + return 1; + default: + ERROR("ceph plugin: cconn_prepare(name=%s) got to illegal state " + "on line %d", + io->d->name, __LINE__); + return -EDOM; + } } /** Returns the difference between two struct timevals in milliseconds. * On overflow, we return max/min int. */ -static int milli_diff(const struct timeval *t1, const struct timeval *t2) -{ - int64_t ret; - int sec_diff = t1->tv_sec - t2->tv_sec; - int usec_diff = t1->tv_usec - t2->tv_usec; - ret = usec_diff / 1000; - ret += (sec_diff * 1000); - return (ret > INT_MAX) ? INT_MAX : ((ret < INT_MIN) ? INT_MIN : (int)ret); +static int milli_diff(const struct timeval *t1, const struct timeval *t2) { + int64_t ret; + int sec_diff = t1->tv_sec - t2->tv_sec; + int usec_diff = t1->tv_usec - t2->tv_usec; + ret = usec_diff / 1000; + ret += (sec_diff * 1000); + return (ret > INT_MAX) ? INT_MAX : ((ret < INT_MIN) ? INT_MIN : (int)ret); } /** This handles the actual network I/O to talk to the Ceph daemons. */ -static int cconn_main_loop(uint32_t request_type) -{ - int ret, some_unreachable = 0; - struct timeval end_tv; - struct cconn io_array[g_num_daemons]; - - DEBUG ("ceph plugin: entering cconn_main_loop(request_type = %"PRIu32")", request_type); - - if (g_num_daemons < 1) - { - ERROR ("ceph plugin: No daemons configured. See the \"Daemon\" config option."); - return ENOENT; - } +static int cconn_main_loop(uint32_t request_type) { + int ret, some_unreachable = 0; + struct timeval end_tv; + struct cconn io_array[g_num_daemons]; + + DEBUG("ceph plugin: entering cconn_main_loop(request_type = %" PRIu32 ")", + request_type); + + if (g_num_daemons < 1) { + ERROR("ceph plugin: No daemons configured. See the \"Daemon\" config " + "option."); + return ENOENT; + } - /* create cconn array */ - for (size_t i = 0; i < g_num_daemons; i++) - { - io_array[i] = (struct cconn) { - .d = g_daemons[i], - .request_type = request_type, - .state = CSTATE_UNCONNECTED, - }; - } + /* create cconn array */ + for (size_t i = 0; i < g_num_daemons; i++) { + io_array[i] = (struct cconn){ + .d = g_daemons[i], + .request_type = request_type, + .state = CSTATE_UNCONNECTED, + }; + } - /** Calculate the time at which we should give up */ - gettimeofday(&end_tv, NULL); - end_tv.tv_sec += CEPH_TIMEOUT_INTERVAL; - - while (1) - { - int nfds, diff; - struct timeval tv; - struct cconn *polled_io_array[g_num_daemons]; - struct pollfd fds[g_num_daemons]; - memset(fds, 0, sizeof(fds)); - nfds = 0; - for(size_t i = 0; i < g_num_daemons; ++i) - { - struct cconn *io = io_array + i; - ret = cconn_prepare(io, fds + nfds); - if(ret < 0) - { - WARNING("ceph plugin: cconn_prepare(name=%s,i=%zu,st=%d)=%d", - io->d->name, i, io->state, ret); - cconn_close(io); - io->request_type = ASOK_REQ_NONE; - some_unreachable = 1; - } - else if(ret == 1) - { - polled_io_array[nfds++] = io_array + i; - } - } - if(nfds == 0) - { - /* finished */ - ret = 0; - goto done; - } - gettimeofday(&tv, NULL); - diff = milli_diff(&end_tv, &tv); - if(diff <= 0) - { - /* Timed out */ - ret = -ETIMEDOUT; - WARNING("ceph plugin: cconn_main_loop: timed out."); - goto done; - } - RETRY_ON_EINTR(ret, poll(fds, nfds, diff)); - if(ret < 0) - { - ERROR("ceph plugin: poll(2) error: %d", ret); - goto done; - } - for(int i = 0; i < nfds; ++i) - { - struct cconn *io = polled_io_array[i]; - int revents = fds[i].revents; - if(revents == 0) - { - /* do nothing */ - continue; - } - else if(cconn_validate_revents(io, revents)) - { - WARNING("ceph plugin: cconn(name=%s,i=%d,st=%d): " + /** Calculate the time at which we should give up */ + gettimeofday(&end_tv, NULL); + end_tv.tv_sec += CEPH_TIMEOUT_INTERVAL; + + while (1) { + int nfds, diff; + struct timeval tv; + struct cconn *polled_io_array[g_num_daemons]; + struct pollfd fds[g_num_daemons]; + memset(fds, 0, sizeof(fds)); + nfds = 0; + for (size_t i = 0; i < g_num_daemons; ++i) { + struct cconn *io = io_array + i; + ret = cconn_prepare(io, fds + nfds); + if (ret < 0) { + WARNING("ceph plugin: cconn_prepare(name=%s,i=%zu,st=%d)=%d", + io->d->name, i, io->state, ret); + cconn_close(io); + io->request_type = ASOK_REQ_NONE; + some_unreachable = 1; + } else if (ret == 1) { + polled_io_array[nfds++] = io_array + i; + } + } + if (nfds == 0) { + /* finished */ + ret = 0; + goto done; + } + gettimeofday(&tv, NULL); + diff = milli_diff(&end_tv, &tv); + if (diff <= 0) { + /* Timed out */ + ret = -ETIMEDOUT; + WARNING("ceph plugin: cconn_main_loop: timed out."); + goto done; + } + RETRY_ON_EINTR(ret, poll(fds, nfds, diff)); + if (ret < 0) { + ERROR("ceph plugin: poll(2) error: %d", ret); + goto done; + } + for (int i = 0; i < nfds; ++i) { + struct cconn *io = polled_io_array[i]; + int revents = fds[i].revents; + if (revents == 0) { + /* do nothing */ + continue; + } else if (cconn_validate_revents(io, revents)) { + WARNING("ceph plugin: cconn(name=%s,i=%d,st=%d): " "revents validation error: " - "revents=0x%08x", io->d->name, i, io->state, revents); - cconn_close(io); - io->request_type = ASOK_REQ_NONE; - some_unreachable = 1; - } - else - { - ret = cconn_handle_event(io); - if(ret) - { - WARNING("ceph plugin: cconn_handle_event(name=%s," - "i=%d,st=%d): error %d", io->d->name, i, io->state, ret); - cconn_close(io); - io->request_type = ASOK_REQ_NONE; - some_unreachable = 1; - } - } + "revents=0x%08x", + io->d->name, i, io->state, revents); + cconn_close(io); + io->request_type = ASOK_REQ_NONE; + some_unreachable = 1; + } else { + ret = cconn_handle_event(io); + if (ret) { + WARNING("ceph plugin: cconn_handle_event(name=%s," + "i=%d,st=%d): error %d", + io->d->name, i, io->state, ret); + cconn_close(io); + io->request_type = ASOK_REQ_NONE; + some_unreachable = 1; } + } } - done: for(size_t i = 0; i < g_num_daemons; ++i) - { - cconn_close(io_array + i); - } - if(some_unreachable) - { - DEBUG("ceph plugin: cconn_main_loop: some Ceph daemons were unreachable."); - } - else - { - DEBUG("ceph plugin: cconn_main_loop: reached all Ceph daemons :)"); - } - return ret; + } +done: + for (size_t i = 0; i < g_num_daemons; ++i) { + cconn_close(io_array + i); + } + if (some_unreachable) { + DEBUG("ceph plugin: cconn_main_loop: some Ceph daemons were unreachable."); + } else { + DEBUG("ceph plugin: cconn_main_loop: reached all Ceph daemons :)"); + } + return ret; } -static int ceph_read(void) -{ - return cconn_main_loop(ASOK_REQ_DATA); -} +static int ceph_read(void) { return cconn_main_loop(ASOK_REQ_DATA); } /******* lifecycle *******/ -static int ceph_init(void) -{ +static int ceph_init(void) { #if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_DAC_OVERRIDE) - if (check_capability (CAP_DAC_OVERRIDE) != 0) - { - if (getuid () == 0) - WARNING ("ceph plugin: Running collectd as root, but the " - "CAP_DAC_OVERRIDE capability is missing. The plugin's read " - "function will probably fail. Is your init system dropping " - "capabilities?"); + if (check_capability(CAP_DAC_OVERRIDE) != 0) { + if (getuid() == 0) + WARNING("ceph plugin: Running collectd as root, but the " + "CAP_DAC_OVERRIDE capability is missing. The plugin's read " + "function will probably fail. Is your init system dropping " + "capabilities?"); else - WARNING ("ceph plugin: collectd doesn't have the CAP_DAC_OVERRIDE " + WARNING( + "ceph plugin: collectd doesn't have the CAP_DAC_OVERRIDE " "capability. If you don't want to run collectd as root, try running " "\"setcap cap_dac_override=ep\" on the collectd binary."); } #endif - ceph_daemons_print(); + ceph_daemons_print(); - if (g_num_daemons < 1) - { - ERROR ("ceph plugin: No daemons configured. See the \"Daemon\" config option."); - return ENOENT; - } + if (g_num_daemons < 1) { + ERROR("ceph plugin: No daemons configured. See the \"Daemon\" config " + "option."); + return ENOENT; + } - return cconn_main_loop(ASOK_REQ_VERSION); + return cconn_main_loop(ASOK_REQ_VERSION); } -static int ceph_shutdown(void) -{ - for(size_t i = 0; i < g_num_daemons; ++i) - { - ceph_daemon_free(g_daemons[i]); - } - sfree(g_daemons); - g_daemons = NULL; - g_num_daemons = 0; - DEBUG("ceph plugin: finished ceph_shutdown"); - return 0; +static int ceph_shutdown(void) { + for (size_t i = 0; i < g_num_daemons; ++i) { + ceph_daemon_free(g_daemons[i]); + } + sfree(g_daemons); + g_daemons = NULL; + g_num_daemons = 0; + DEBUG("ceph plugin: finished ceph_shutdown"); + return 0; } -void module_register(void) -{ - plugin_register_complex_config("ceph", ceph_config); - plugin_register_init("ceph", ceph_init); - plugin_register_read("ceph", ceph_read); - plugin_register_shutdown("ceph", ceph_shutdown); +void module_register(void) { + plugin_register_complex_config("ceph", ceph_config); + plugin_register_init("ceph", ceph_init); + plugin_register_read("ceph", ceph_read); + plugin_register_shutdown("ceph", ceph_shutdown); } /* vim: set sw=4 sts=4 et : */ diff --git a/src/ceph_test.c b/src/ceph_test.c index 91f084f7..3da4098c 100644 --- a/src/ceph_test.c +++ b/src/ceph_test.c @@ -22,22 +22,19 @@ #include "ceph.c" /* sic */ #include "testing.h" -struct case_s -{ +struct case_s { const char *key; const char *value; }; typedef struct case_s case_t; -struct test_s -{ +struct test_s { case_t *cases; - size_t cases_num; + size_t cases_num; }; typedef struct test_s test_t; -static int test_handler(void *user, char const *val, char const *key) -{ +static int test_handler(void *user, char const *val, char const *key) { test_t *t = user; size_t i; @@ -45,25 +42,26 @@ static int test_handler(void *user, char const *val, char const *key) _Bool ok; /* special case for latency metrics. */ - if (strcmp ("filestore.example_latency", key) == 0) + if (strcmp("filestore.example_latency", key) == 0) return RETRY_AVGCOUNT; - snprintf (status, sizeof (status), "unexpected call: test_handler(\"%s\") = \"%s\"", key, val); + snprintf(status, sizeof(status), + "unexpected call: test_handler(\"%s\") = \"%s\"", key, val); ok = 0; - for (i = 0; i < t->cases_num; i++) - { - if (strcmp (key, t->cases[i].key) != 0) + for (i = 0; i < t->cases_num; i++) { + if (strcmp(key, t->cases[i].key) != 0) continue; - if (strcmp (val, t->cases[i].value) != 0) - { - snprintf (status, sizeof (status), "test_handler(\"%s\") = \"%s\", want \"%s\"", key, val, t->cases[i].value); + if (strcmp(val, t->cases[i].value) != 0) { + snprintf(status, sizeof(status), + "test_handler(\"%s\") = \"%s\", want \"%s\"", key, val, + t->cases[i].value); ok = 0; break; } - snprintf (status, sizeof (status), "test_handler(\"%s\") = \"%s\"", key, val); + snprintf(status, sizeof(status), "test_handler(\"%s\") = \"%s\"", key, val); ok = 1; break; } @@ -72,9 +70,9 @@ static int test_handler(void *user, char const *val, char const *key) return ok ? 0 : -1; } -DEF_TEST(traverse_json) -{ - char const *json = "{\n" +DEF_TEST(traverse_json) { + char const *json = + "{\n" " \"WBThrottle\": {\n" " \"bytes_dirtied\": {\n" " \"type\": 2,\n" @@ -119,67 +117,71 @@ DEF_TEST(traverse_json) " }\n" "}\n"; case_t cases[] = { - {"WBThrottle.bytes_dirtied.type", "2"}, - {"WBThrottle.bytes_wb.type", "2"}, - {"WBThrottle.ios_dirtied.type", "2"}, - {"WBThrottle.ios_wb.type", "2"}, - {"WBThrottle.inodes_dirtied.type", "2"}, - {"WBThrottle.inodes_wb.type", "10"}, - {"filestore.journal_wr_bytes", "3117"}, - {"filestore.example_latency.avgcount", "42"}, - {"filestore.example_latency.sum", "4711"}, + {"WBThrottle.bytes_dirtied.type", "2"}, + {"WBThrottle.bytes_wb.type", "2"}, + {"WBThrottle.ios_dirtied.type", "2"}, + {"WBThrottle.ios_wb.type", "2"}, + {"WBThrottle.inodes_dirtied.type", "2"}, + {"WBThrottle.inodes_wb.type", "10"}, + {"filestore.journal_wr_bytes", "3117"}, + {"filestore.example_latency.avgcount", "42"}, + {"filestore.example_latency.sum", "4711"}, }; - test_t t = {cases, STATIC_ARRAY_SIZE (cases)}; + test_t t = {cases, STATIC_ARRAY_SIZE(cases)}; yajl_struct ctx = {test_handler, &t}; yajl_handle hndl; #if HAVE_YAJL_V2 - hndl = yajl_alloc (&callbacks, NULL, &ctx); - CHECK_ZERO (traverse_json ((const unsigned char *) json, (uint32_t) strlen (json), hndl)); - CHECK_ZERO (yajl_complete_parse (hndl)); + hndl = yajl_alloc(&callbacks, NULL, &ctx); + CHECK_ZERO( + traverse_json((const unsigned char *)json, (uint32_t)strlen(json), hndl)); + CHECK_ZERO(yajl_complete_parse(hndl)); #else - hndl = yajl_alloc (&callbacks, NULL, NULL, &ctx); - CHECK_ZERO (traverse_json ((const unsigned char *) json, (uint32_t) strlen (json), hndl)); - CHECK_ZERO (yajl_parse_complete (hndl)); + hndl = yajl_alloc(&callbacks, NULL, NULL, &ctx); + CHECK_ZERO( + traverse_json((const unsigned char *)json, (uint32_t)strlen(json), hndl)); + CHECK_ZERO(yajl_parse_complete(hndl)); #endif - yajl_free (hndl); + yajl_free(hndl); return 0; } -DEF_TEST(parse_keys) -{ +DEF_TEST(parse_keys) { struct { const char *str; const char *want; } cases[] = { - {"WBThrottle.bytes_dirtied.description.bytes_wb.description.ios_dirtied.description.ios_wb.type", "WBThrottle.bytesDirtied.description.bytesWb.description.iosDirt"}, - {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, - {"foo:bar", "FooBar"}, - {"foo:bar+", "FooBarPlus"}, - {"foo:bar-", "FooBarMinus"}, - {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+", "AaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPlus"}, - {"aa.bb.cc.dd.ee.ff", "Aa.bb.cc.dd.ee.ff"}, - {"aa.bb.cc.dd.ee.ff.type", "Aa.bb.cc.dd.ee.ff"}, - {"aa.type", "Aa.type"}, - {"WBThrottle.bytes_dirtied.type", "WBThrottle.bytesDirtied"}, + {"WBThrottle.bytes_dirtied.description.bytes_wb.description.ios_dirtied." + "description.ios_wb.type", + "WBThrottle.bytesDirtied.description.bytesWb.description.iosDirt"}, + {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:" + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, + {"foo:bar", "FooBar"}, + {"foo:bar+", "FooBarPlus"}, + {"foo:bar-", "FooBarMinus"}, + {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+", + "AaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPlus"}, + {"aa.bb.cc.dd.ee.ff", "Aa.bb.cc.dd.ee.ff"}, + {"aa.bb.cc.dd.ee.ff.type", "Aa.bb.cc.dd.ee.ff"}, + {"aa.type", "Aa.type"}, + {"WBThrottle.bytes_dirtied.type", "WBThrottle.bytesDirtied"}, }; size_t i; - for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) - { + for (i = 0; i < STATIC_ARRAY_SIZE(cases); i++) { char got[64]; - CHECK_ZERO (parse_keys (got, sizeof (got), cases[i].str)); - EXPECT_EQ_STR (cases[i].want, got); + CHECK_ZERO(parse_keys(got, sizeof(got), cases[i].str)); + EXPECT_EQ_STR(cases[i].want, got); } return 0; } -int main (void) -{ +int main(void) { RUN_TEST(traverse_json); RUN_TEST(parse_keys); diff --git a/src/cgroups.c b/src/cgroups.c index 2584eff0..3f7d4f41 100644 --- a/src/cgroups.c +++ b/src/cgroups.c @@ -25,120 +25,106 @@ #include "common.h" #include "plugin.h" -#include "utils_mount.h" #include "utils_ignorelist.h" +#include "utils_mount.h" -static char const *config_keys[] = -{ - "CGroup", - "IgnoreSelected" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static char const *config_keys[] = {"CGroup", "IgnoreSelected"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static ignorelist_t *il_cgroup = NULL; -__attribute__ ((nonnull(1))) -__attribute__ ((nonnull(2))) -static void cgroups_submit_one (char const *plugin_instance, - char const *type_instance, value_t value) -{ - value_list_t vl = VALUE_LIST_INIT; - - vl.values = &value; - vl.values_len = 1; - sstrncpy (vl.plugin, "cgroups", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, plugin_instance, - sizeof (vl.plugin_instance)); - sstrncpy (vl.type, "cpu", sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, - sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); +__attribute__((nonnull(1))) __attribute__((nonnull(2))) static void +cgroups_submit_one(char const *plugin_instance, char const *type_instance, + value_t value) { + value_list_t vl = VALUE_LIST_INIT; + + vl.values = &value; + vl.values_len = 1; + sstrncpy(vl.plugin, "cgroups", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "cpu", sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); } /* void cgroups_submit_one */ /* * This callback reads the user/system CPU time for each cgroup. */ -static int read_cpuacct_procs (const char *dirname, char const *cgroup_name, - void *user_data) -{ - char abs_path[PATH_MAX]; - struct stat statbuf; - char buf[1024]; - int status; - - FILE *fh; - - if (ignorelist_match (il_cgroup, cgroup_name)) - return (0); - - ssnprintf (abs_path, sizeof (abs_path), "%s/%s", dirname, cgroup_name); - - status = lstat (abs_path, &statbuf); - if (status != 0) - { - ERROR ("cgroups plugin: stat (\"%s\") failed.", - abs_path); - return (-1); - } - - /* We are only interested in directories, so skip everything else. */ - if (!S_ISDIR (statbuf.st_mode)) - return (0); - - ssnprintf (abs_path, sizeof (abs_path), "%s/%s/cpuacct.stat", - dirname, cgroup_name); - fh = fopen (abs_path, "r"); - if (fh == NULL) - { - char errbuf[1024]; - ERROR ("cgroups plugin: fopen (\"%s\") failed: %s", - abs_path, - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - while (fgets (buf, sizeof (buf), fh) != NULL) - { - char *fields[8]; - int numfields = 0; - char *key; - size_t key_len; - value_t value; - - /* Expected format: - * - * user: 12345 - * system: 23456 - * - * Or: - * - * user 12345 - * system 23456 - */ - strstripnewline (buf); - numfields = strsplit (buf, fields, STATIC_ARRAY_SIZE (fields)); - if (numfields != 2) - continue; - - key = fields[0]; - key_len = strlen (key); - if (key_len < 2) - continue; - - /* Strip colon off the first column, if found */ - if (key[key_len - 1] == ':') - key[key_len - 1] = 0; - - status = parse_value (fields[1], &value, DS_TYPE_DERIVE); - if (status != 0) - continue; - - cgroups_submit_one (cgroup_name, key, value); - } - - fclose (fh); - return (0); +static int read_cpuacct_procs(const char *dirname, char const *cgroup_name, + void *user_data) { + char abs_path[PATH_MAX]; + struct stat statbuf; + char buf[1024]; + int status; + + FILE *fh; + + if (ignorelist_match(il_cgroup, cgroup_name)) + return (0); + + ssnprintf(abs_path, sizeof(abs_path), "%s/%s", dirname, cgroup_name); + + status = lstat(abs_path, &statbuf); + if (status != 0) { + ERROR("cgroups plugin: stat (\"%s\") failed.", abs_path); + return (-1); + } + + /* We are only interested in directories, so skip everything else. */ + if (!S_ISDIR(statbuf.st_mode)) + return (0); + + ssnprintf(abs_path, sizeof(abs_path), "%s/%s/cpuacct.stat", dirname, + cgroup_name); + fh = fopen(abs_path, "r"); + if (fh == NULL) { + char errbuf[1024]; + ERROR("cgroups plugin: fopen (\"%s\") failed: %s", abs_path, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + while (fgets(buf, sizeof(buf), fh) != NULL) { + char *fields[8]; + int numfields = 0; + char *key; + size_t key_len; + value_t value; + + /* Expected format: + * + * user: 12345 + * system: 23456 + * + * Or: + * + * user 12345 + * system 23456 + */ + strstripnewline(buf); + numfields = strsplit(buf, fields, STATIC_ARRAY_SIZE(fields)); + if (numfields != 2) + continue; + + key = fields[0]; + key_len = strlen(key); + if (key_len < 2) + continue; + + /* Strip colon off the first column, if found */ + if (key[key_len - 1] == ':') + key[key_len - 1] = 0; + + status = parse_value(fields[1], &value, DS_TYPE_DERIVE); + if (status != 0) + continue; + + cgroups_submit_one(cgroup_name, key, value); + } + + fclose(fh); + return (0); } /* int read_cpuacct_procs */ /* @@ -146,108 +132,95 @@ static int read_cpuacct_procs (const char *dirname, char const *cgroup_name, * wherever cpuacct is mounted on the system). Calls walk_directory with the * read_cpuacct_procs callback on every folder it finds, such as "system". */ -static int read_cpuacct_root (const char *dirname, const char *filename, - void *user_data) -{ - char abs_path[PATH_MAX]; - struct stat statbuf; - int status; - - ssnprintf (abs_path, sizeof (abs_path), "%s/%s", dirname, filename); - - status = lstat (abs_path, &statbuf); - if (status != 0) - { - ERROR ("cgroups plugin: stat (%s) failed.", abs_path); - return (-1); - } - - if (S_ISDIR (statbuf.st_mode)) - { - status = walk_directory (abs_path, read_cpuacct_procs, - /* user_data = */ NULL, - /* include_hidden = */ 0); - return (status); - } - - return (0); +static int read_cpuacct_root(const char *dirname, const char *filename, + void *user_data) { + char abs_path[PATH_MAX]; + struct stat statbuf; + int status; + + ssnprintf(abs_path, sizeof(abs_path), "%s/%s", dirname, filename); + + status = lstat(abs_path, &statbuf); + if (status != 0) { + ERROR("cgroups plugin: stat (%s) failed.", abs_path); + return (-1); + } + + if (S_ISDIR(statbuf.st_mode)) { + status = walk_directory(abs_path, read_cpuacct_procs, + /* user_data = */ NULL, + /* include_hidden = */ 0); + return (status); + } + + return (0); } -static int cgroups_init (void) -{ - if (il_cgroup == NULL) - il_cgroup = ignorelist_create (1); +static int cgroups_init(void) { + if (il_cgroup == NULL) + il_cgroup = ignorelist_create(1); - return (0); + return (0); } -static int cgroups_config (const char *key, const char *value) -{ - cgroups_init (); - - if (strcasecmp (key, "CGroup") == 0) - { - if (ignorelist_add (il_cgroup, value)) - return (1); - return (0); - } - else if (strcasecmp (key, "IgnoreSelected") == 0) - { - if (IS_TRUE (value)) - ignorelist_set_invert (il_cgroup, 0); - else - ignorelist_set_invert (il_cgroup, 1); - return (0); - } - - return (-1); +static int cgroups_config(const char *key, const char *value) { + cgroups_init(); + + if (strcasecmp(key, "CGroup") == 0) { + if (ignorelist_add(il_cgroup, value)) + return (1); + return (0); + } else if (strcasecmp(key, "IgnoreSelected") == 0) { + if (IS_TRUE(value)) + ignorelist_set_invert(il_cgroup, 0); + else + ignorelist_set_invert(il_cgroup, 1); + return (0); + } + + return (-1); } -static int cgroups_read (void) -{ - cu_mount_t *mnt_list = NULL; - _Bool cgroup_found = 0; - - if (cu_mount_getlist (&mnt_list) == NULL) - { - ERROR ("cgroups plugin: cu_mount_getlist failed."); - return (-1); - } - - for (cu_mount_t *mnt_ptr = mnt_list; mnt_ptr != NULL; mnt_ptr = mnt_ptr->next) - { - /* Find the cgroup mountpoint which contains the cpuacct - * controller. */ - if ((strcmp(mnt_ptr->type, "cgroup") != 0) - || !cu_mount_checkoption(mnt_ptr->options, - "cpuacct", /* full = */ 1)) - continue; - - walk_directory (mnt_ptr->dir, read_cpuacct_root, - /* user_data = */ NULL, - /* include_hidden = */ 0); - cgroup_found = 1; - /* It doesn't make sense to check other cpuacct mount-points - * (if any), they contain the same data. */ - break; - } - - cu_mount_freelist (mnt_list); - - if (!cgroup_found) - { - WARNING ("cgroups plugin: Unable to find cgroup " - "mount-point with the \"cpuacct\" option."); - return (-1); - } - - return (0); +static int cgroups_read(void) { + cu_mount_t *mnt_list = NULL; + _Bool cgroup_found = 0; + + if (cu_mount_getlist(&mnt_list) == NULL) { + ERROR("cgroups plugin: cu_mount_getlist failed."); + return (-1); + } + + for (cu_mount_t *mnt_ptr = mnt_list; mnt_ptr != NULL; + mnt_ptr = mnt_ptr->next) { + /* Find the cgroup mountpoint which contains the cpuacct + * controller. */ + if ((strcmp(mnt_ptr->type, "cgroup") != 0) || + !cu_mount_checkoption(mnt_ptr->options, "cpuacct", /* full = */ 1)) + continue; + + walk_directory(mnt_ptr->dir, read_cpuacct_root, + /* user_data = */ NULL, + /* include_hidden = */ 0); + cgroup_found = 1; + /* It doesn't make sense to check other cpuacct mount-points + * (if any), they contain the same data. */ + break; + } + + cu_mount_freelist(mnt_list); + + if (!cgroup_found) { + WARNING("cgroups plugin: Unable to find cgroup " + "mount-point with the \"cpuacct\" option."); + return (-1); + } + + return (0); } /* int cgroup_read */ -void module_register (void) -{ - plugin_register_config ("cgroups", cgroups_config, - config_keys, config_keys_num); - plugin_register_init ("cgroups", cgroups_init); - plugin_register_read ("cgroups", cgroups_read); +void module_register(void) { + plugin_register_config("cgroups", cgroups_config, config_keys, + config_keys_num); + plugin_register_init("cgroups", cgroups_init); + plugin_register_read("cgroups", cgroups_read); } /* void module_register */ diff --git a/src/chrony.c b/src/chrony.c index 77ba8cc4..11310b19 100644 --- a/src/chrony.c +++ b/src/chrony.c @@ -1,182 +1,161 @@ /* chrony plugin for collectd (monitoring of chrony time server daemon) ********************************************************************** - * Copyright (C) Claudius M Zingerli, ZSeng, 2015-2016 + * Copyright (C) Claudius M Zingerli, ZSeng, 2015-2016 * * Internals roughly based on the ntpd plugin * Some functions copied from chronyd/web (as marked) - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * + * * TODO: * - More robust udp parsing (using offsets instead of structs?) - * -> Currently chrony parses its data the same way as we do (using structs) + * -> Currently chrony parses its data the same way as we do (using + *structs) * - Plausibility checks on values received * -> Done at higher levels */ #include "collectd.h" -#include "common.h" /* auxiliary functions */ -#include "plugin.h" /* plugin_register_*, plugin_dispatch_values */ +#include "common.h" /* auxiliary functions */ +#include "plugin.h" /* plugin_register_*, plugin_dispatch_values */ #if HAVE_NETDB_H -# include /* struct addrinfo */ +#include /* struct addrinfo */ #endif #if HAVE_ARPA_INET_H -# include /* ntohs/ntohl */ +#include /* ntohs/ntohl */ #endif - -#define CONFIG_KEY_HOST "Host" -#define CONFIG_KEY_PORT "Port" +#define CONFIG_KEY_HOST "Host" +#define CONFIG_KEY_PORT "Port" #define CONFIG_KEY_TIMEOUT "Timeout" -#define URAND_DEVICE_PATH "/dev/urandom" /* Used to initialize seq nr generator */ -#define RAND_DEVICE_PATH "/dev/random" /* Used to initialize seq nr generator (fall back) */ - -static const char *g_config_keys[] = { - CONFIG_KEY_HOST, - CONFIG_KEY_PORT, - CONFIG_KEY_TIMEOUT -}; - -static int g_config_keys_num = STATIC_ARRAY_SIZE(g_config_keys); -static int g_chrony_is_connected; -static int g_chrony_socket = -1; -static time_t g_chrony_timeout = -1; -static char *g_chrony_plugin_instance; -static char *g_chrony_host; -static char *g_chrony_port; -static uint32_t g_chrony_rand = 1; -static uint32_t g_chrony_seq_is_initialized; +#define URAND_DEVICE_PATH \ + "/dev/urandom" /* Used to initialize seq nr generator */ +#define RAND_DEVICE_PATH \ + "/dev/random" /* Used to initialize seq nr generator (fall back) */ + +static const char *g_config_keys[] = {CONFIG_KEY_HOST, CONFIG_KEY_PORT, + CONFIG_KEY_TIMEOUT}; + +static int g_config_keys_num = STATIC_ARRAY_SIZE(g_config_keys); +static int g_chrony_is_connected; +static int g_chrony_socket = -1; +static time_t g_chrony_timeout = -1; +static char *g_chrony_plugin_instance; +static char *g_chrony_host; +static char *g_chrony_port; +static uint32_t g_chrony_rand = 1; +static uint32_t g_chrony_seq_is_initialized; #define PLUGIN_NAME_SHORT "chrony" -#define PLUGIN_NAME PLUGIN_NAME_SHORT " plugin" -#define DAEMON_NAME PLUGIN_NAME_SHORT +#define PLUGIN_NAME PLUGIN_NAME_SHORT " plugin" +#define DAEMON_NAME PLUGIN_NAME_SHORT #define CHRONY_DEFAULT_HOST "localhost" #define CHRONY_DEFAULT_PORT "323" #define CHRONY_DEFAULT_TIMEOUT 2 /* Return codes (collectd expects non-zero on errors) */ -#define CHRONY_RC_OK 0 -#define CHRONY_RC_FAIL 1 +#define CHRONY_RC_OK 0 +#define CHRONY_RC_FAIL 1 /* Chronyd command packet variables adapted from chrony/candm.h (GPL2) */ #define PROTO_VERSION_NUMBER 6 #define IPADDR_UNSPEC 0 -#define IPADDR_INET4 1 -#define IPADDR_INET6 2 -#define IPV6_STR_MAX_SIZE (8*4+7+1) - -typedef enum -{ - PKT_TYPE_CMD_REQUEST = 1, - PKT_TYPE_CMD_REPLY = 2 -} ePacketType; - -typedef enum -{ - REQ_N_SOURCES = 14, - REQ_SOURCE_DATA = 15, - REQ_TRACKING = 33, +#define IPADDR_INET4 1 +#define IPADDR_INET6 2 +#define IPV6_STR_MAX_SIZE (8 * 4 + 7 + 1) + +typedef enum { PKT_TYPE_CMD_REQUEST = 1, PKT_TYPE_CMD_REPLY = 2 } ePacketType; + +typedef enum { + REQ_N_SOURCES = 14, + REQ_SOURCE_DATA = 15, + REQ_TRACKING = 33, REQ_SOURCE_STATS = 34 } eDaemonRequests; - -typedef enum -{ - RPY_NULL = 1, - RPY_N_SOURCES = 2, - RPY_SOURCE_DATA = 3, +typedef enum { + RPY_NULL = 1, + RPY_N_SOURCES = 2, + RPY_SOURCE_DATA = 3, RPY_MANUAL_TIMESTAMP = 4, - RPY_TRACKING = 5, - RPY_SOURCE_STATS = 6, - RPY_RTC = 7 + RPY_TRACKING = 5, + RPY_SOURCE_STATS = 6, + RPY_RTC = 7 } eDaemonReplies; - -#if defined(__GNUC__) || defined (__SUNPRO_C) || defined(lint) -# /* extension to enforce struct packing. */ -# define ATTRIB_PACKED __attribute__((packed)) +#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(lint) +#/* extension to enforce struct packing. */ +#define ATTRIB_PACKED __attribute__((packed)) #else -# error Not defining packed attribute (unknown compiler) -# define ATTRIB_PACKED +#error Not defining packed attribute (unknown compiler) +#define ATTRIB_PACKED #endif -typedef struct ATTRIB_PACKED -{ - int32_t value; -} tFloat; +typedef struct ATTRIB_PACKED { int32_t value; } tFloat; -typedef struct ATTRIB_PACKED -{ +typedef struct ATTRIB_PACKED { uint32_t tv_sec_high; uint32_t tv_sec_low; uint32_t tv_nsec; } tTimeval; -typedef enum -{ - STT_SUCCESS = 0, - STT_FAILED = 1, - STT_UNAUTH = 2, - STT_INVALID = 3, - STT_NOSUCHSOURCE = 4, - STT_INVALIDTS = 5, - STT_NOTENABLED = 6, - STT_BADSUBNET = 7, - STT_ACCESSALLOWED = 8, - STT_ACCESSDENIED = 9, - STT_NOHOSTACCESS = 10, +typedef enum { + STT_SUCCESS = 0, + STT_FAILED = 1, + STT_UNAUTH = 2, + STT_INVALID = 3, + STT_NOSUCHSOURCE = 4, + STT_INVALIDTS = 5, + STT_NOTENABLED = 6, + STT_BADSUBNET = 7, + STT_ACCESSALLOWED = 8, + STT_ACCESSDENIED = 9, + STT_NOHOSTACCESS = 10, STT_SOURCEALREADYKNOWN = 11, STT_TOOMANYSOURCES = 12, - STT_NORTC = 13, - STT_BADRTCFILE = 14, - STT_INACTIVE = 15, - STT_BADSAMPLE = 16, - STT_INVALIDAF = 17, - STT_BADPKTVERSION = 18, - STT_BADPKTLENGTH = 19 + STT_NORTC = 13, + STT_BADRTCFILE = 14, + STT_INACTIVE = 15, + STT_BADSAMPLE = 16, + STT_INVALIDAF = 17, + STT_BADPKTVERSION = 18, + STT_BADPKTLENGTH = 19 } eChrony_Status; /* Chrony client request packets */ -typedef struct ATTRIB_PACKED -{ - uint8_t f_dummy0[80]; /* Chrony expects 80bytes dummy data (Avoiding UDP Amplification) */ +typedef struct ATTRIB_PACKED { + uint8_t f_dummy0[80]; /* Chrony expects 80bytes dummy data (Avoiding UDP + Amplification) */ } tChrony_Req_Tracking; -typedef struct ATTRIB_PACKED -{ - uint32_t f_n_sources; -} tChrony_Req_N_Sources; +typedef struct ATTRIB_PACKED { uint32_t f_n_sources; } tChrony_Req_N_Sources; -typedef struct ATTRIB_PACKED -{ +typedef struct ATTRIB_PACKED { int32_t f_index; uint8_t f_dummy0[44]; } tChrony_Req_Source_data; -typedef struct ATTRIB_PACKED -{ +typedef struct ATTRIB_PACKED { int32_t f_index; uint8_t f_dummy0[56]; } tChrony_Req_Source_stats; -typedef struct ATTRIB_PACKED -{ - struct - { +typedef struct ATTRIB_PACKED { + struct { uint8_t f_version; uint8_t f_type; uint8_t f_dummy0; @@ -187,71 +166,72 @@ typedef struct ATTRIB_PACKED uint32_t f_dummy2; uint32_t f_dummy3; - } header; /* Packed: 20Bytes */ - union - { + } header; /* Packed: 20Bytes */ + union { tChrony_Req_N_Sources n_sources; tChrony_Req_Source_data source_data; tChrony_Req_Source_stats source_stats; tChrony_Req_Tracking tracking; } body; - uint8_t padding[4 + 16]; /* Padding to match minimal response size */ + uint8_t padding[4 + 16]; /* Padding to match minimal response size */ } tChrony_Request; /* Chrony daemon response packets */ -typedef struct ATTRIB_PACKED -{ - uint32_t f_n_sources; -} tChrony_Resp_N_Sources; - -typedef struct ATTRIB_PACKED -{ - union - { +typedef struct ATTRIB_PACKED { uint32_t f_n_sources; } tChrony_Resp_N_Sources; + +typedef struct ATTRIB_PACKED { + union { uint32_t ip4; uint8_t ip6[16]; } addr; uint16_t f_family; } tChrony_IPAddr; -typedef struct ATTRIB_PACKED -{ +typedef struct ATTRIB_PACKED { tChrony_IPAddr addr; - uint16_t dummy; /* FIXME: Strange dummy space. Needed on gcc 4.8.3/clang 3.4.1 on x86_64 */ - int16_t f_poll; /* 2^f_poll = Time between polls (s) */ - uint16_t f_stratum; /* Remote clock stratum */ - uint16_t f_state; /* 0 = RPY_SD_ST_SYNC, 1 = RPY_SD_ST_UNREACH, 2 = RPY_SD_ST_FALSETICKER */ - /* 3 = RPY_SD_ST_JITTERY, 4 = RPY_SD_ST_CANDIDATE, 5 = RPY_SD_ST_OUTLIER */ - uint16_t f_mode; /* 0 = RPY_SD_MD_CLIENT, 1 = RPY_SD_MD_PEER, 2 = RPY_SD_MD_REF */ - uint16_t f_flags; /* unused */ - uint16_t f_reachability; /* Bit mask of successfull tries to reach the source */ - - uint32_t f_since_sample; /* Time since last sample (s) */ - tFloat f_origin_latest_meas; /* */ - tFloat f_latest_meas; /* */ - tFloat f_latest_meas_err; /* */ + uint16_t + dummy; /* FIXME: Strange dummy space. Needed on gcc 4.8.3/clang 3.4.1 on + x86_64 */ + int16_t f_poll; /* 2^f_poll = Time between polls (s) */ + uint16_t f_stratum; /* Remote clock stratum */ + uint16_t f_state; /* 0 = RPY_SD_ST_SYNC, 1 = RPY_SD_ST_UNREACH, 2 = + RPY_SD_ST_FALSETICKER */ + /* 3 = RPY_SD_ST_JITTERY, 4 = RPY_SD_ST_CANDIDATE, 5 = RPY_SD_ST_OUTLIER */ + uint16_t f_mode; /* 0 = RPY_SD_MD_CLIENT, 1 = RPY_SD_MD_PEER, 2 = + RPY_SD_MD_REF */ + uint16_t f_flags; /* unused */ + uint16_t + f_reachability; /* Bit mask of successfull tries to reach the source */ + + uint32_t f_since_sample; /* Time since last sample (s) */ + tFloat f_origin_latest_meas; /* */ + tFloat f_latest_meas; /* */ + tFloat f_latest_meas_err; /* */ } tChrony_Resp_Source_data; -typedef struct ATTRIB_PACKED -{ +typedef struct ATTRIB_PACKED { uint32_t f_ref_id; tChrony_IPAddr addr; - uint16_t dummy; /* FIXME: Strange dummy space. Needed on gcc 4.8.3/clang 3.4.1 on x86_64 */ - uint32_t f_n_samples; /* Number of measurements done */ - uint32_t f_n_runs; /* How many measurements to come */ - uint32_t f_span_seconds; /* For how long we're measuring */ - tFloat f_rtc_seconds_fast; /* ??? */ - tFloat f_rtc_gain_rate_ppm; /* Estimated relative frequency error */ - tFloat f_skew_ppm; /* Clock skew (ppm) (worst case freq est error (skew: peak2peak)) */ - tFloat f_est_offset; /* Estimated offset of source */ - tFloat f_est_offset_err; /* Error of estimation */ + uint16_t + dummy; /* FIXME: Strange dummy space. Needed on gcc 4.8.3/clang 3.4.1 on + x86_64 */ + uint32_t f_n_samples; /* Number of measurements done */ + uint32_t f_n_runs; /* How many measurements to come */ + uint32_t f_span_seconds; /* For how long we're measuring */ + tFloat f_rtc_seconds_fast; /* ??? */ + tFloat f_rtc_gain_rate_ppm; /* Estimated relative frequency error */ + tFloat f_skew_ppm; /* Clock skew (ppm) (worst case freq est error (skew: + peak2peak)) */ + tFloat f_est_offset; /* Estimated offset of source */ + tFloat f_est_offset_err; /* Error of estimation */ } tChrony_Resp_Source_stats; -typedef struct ATTRIB_PACKED -{ +typedef struct ATTRIB_PACKED { uint32_t f_ref_id; tChrony_IPAddr addr; - uint16_t dummy; /* FIXME: Strange dummy space. Needed on gcc 4.8.3/clang 3.4.1 on x86_64 */ + uint16_t + dummy; /* FIXME: Strange dummy space. Needed on gcc 4.8.3/clang 3.4.1 on + x86_64 */ uint16_t f_stratum; uint16_t f_leap_status; tTimeval f_ref_time; @@ -266,10 +246,8 @@ typedef struct ATTRIB_PACKED tFloat f_last_update_interval; } tChrony_Resp_Tracking; -typedef struct ATTRIB_PACKED -{ - struct - { +typedef struct ATTRIB_PACKED { + struct { uint8_t f_version; uint8_t f_type; uint8_t f_dummy0; @@ -283,10 +261,9 @@ typedef struct ATTRIB_PACKED uint32_t f_seq; uint32_t f_dummy5; uint32_t f_dummy6; - } header; /* Packed: 28 Bytes */ + } header; /* Packed: 28 Bytes */ - union - { + union { tChrony_Resp_N_Sources n_sources; tChrony_Resp_Source_data source_data; tChrony_Resp_Source_stats source_stats; @@ -296,29 +273,24 @@ typedef struct ATTRIB_PACKED uint8_t padding[1024]; } tChrony_Response; - /*****************************************************************************/ /* Internal functions */ /*****************************************************************************/ -/* connect_client code adapted from: http://long.ccaba.upc.edu/long/045Guidelines/eva/ipv6.html#daytimeClient6 */ -/* License granted by Eva M Castro via e-mail on 2016-02-18 under the terms of GPLv3 */ -static int -connect_client(const char *p_hostname, - const char *p_service, int p_family, int p_socktype) -{ +/* connect_client code adapted from: + * http://long.ccaba.upc.edu/long/045Guidelines/eva/ipv6.html#daytimeClient6 */ +/* License granted by Eva M Castro via e-mail on 2016-02-18 under the terms of + * GPLv3 */ +static int connect_client(const char *p_hostname, const char *p_service, + int p_family, int p_socktype) { struct addrinfo *res, *ressave; int n, sockfd; - struct addrinfo ai_hints = { - .ai_family = p_family, - .ai_socktype = p_socktype - }; + struct addrinfo ai_hints = {.ai_family = p_family, .ai_socktype = p_socktype}; n = getaddrinfo(p_hostname, p_service, &ai_hints, &res); - if (n < 0) - { + if (n < 0) { ERROR(PLUGIN_NAME ": getaddrinfo error:: [%s]", gai_strerror(n)); return -1; } @@ -326,14 +298,11 @@ connect_client(const char *p_hostname, ressave = res; sockfd = -1; - while (res) - { + while (res) { sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (!(sockfd < 0)) - { - if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0) - { + if (!(sockfd < 0)) { + if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0) { /* Success */ break; } @@ -348,18 +317,16 @@ connect_client(const char *p_hostname, return sockfd; } - -/* niptoha code originally from: git://git.tuxfamily.org/gitroot/chrony/chrony.git:util.c */ +/* niptoha code originally from: + * git://git.tuxfamily.org/gitroot/chrony/chrony.git:util.c */ /* Original code licensed as GPLv2, by Richard P. Purnow, Miroslav Lichvar */ /* Original name: char * UTI_IPToString(IPAddr *addr)*/ -static char * -niptoha(const tChrony_IPAddr * addr, char *p_buf, size_t p_buf_size) -{ +static char *niptoha(const tChrony_IPAddr *addr, char *p_buf, + size_t p_buf_size) { int rc = 1; unsigned long a, b, c, d, ip; - switch (ntohs(addr->f_family)) - { + switch (ntohs(addr->f_family)) { case IPADDR_UNSPEC: rc = snprintf(p_buf, p_buf_size, "[UNSPEC]"); break; @@ -371,12 +338,11 @@ niptoha(const tChrony_IPAddr * addr, char *p_buf, size_t p_buf_size) d = (ip >> 0) & 0xff; rc = snprintf(p_buf, p_buf_size, "%ld.%ld.%ld.%ld", a, b, c, d); break; - case IPADDR_INET6: - { + case IPADDR_INET6: { const char *rp = inet_ntop(AF_INET6, addr->addr.ip6, p_buf, p_buf_size); - if (rp == NULL) - { - ERROR(PLUGIN_NAME ": Error converting ipv6 address to string. Errno = %d", errno); + if (rp == NULL) { + ERROR(PLUGIN_NAME ": Error converting ipv6 address to string. Errno = %d", + errno); rc = snprintf(p_buf, p_buf_size, "[UNKNOWN]"); } break; @@ -388,11 +354,9 @@ niptoha(const tChrony_IPAddr * addr, char *p_buf, size_t p_buf_size) return p_buf; } - -static int -chrony_set_timeout(void) -{ - /* Set the socket's timeout to g_chrony_timeout; a value of 0 signals infinite timeout */ +static int chrony_set_timeout(void) { + /* Set the socket's timeout to g_chrony_timeout; a value of 0 signals + * infinite timeout */ /* Returns 0 on success, !0 on error (check errno) */ struct timeval tv; @@ -400,58 +364,47 @@ chrony_set_timeout(void) tv.tv_usec = 0; assert(g_chrony_socket >= 0); - if (setsockopt(g_chrony_socket, SOL_SOCKET, - SO_RCVTIMEO, (char *) &tv, sizeof(struct timeval)) < 0) - { + if (setsockopt(g_chrony_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, + sizeof(struct timeval)) < 0) { return CHRONY_RC_FAIL; } return CHRONY_RC_OK; } - -static int -chrony_connect(void) -{ +static int chrony_connect(void) { /* Connects to the chrony daemon */ /* Returns 0 on success, !0 on error (check errno) */ int socket; - if (g_chrony_host == NULL) - { + if (g_chrony_host == NULL) { g_chrony_host = strdup(CHRONY_DEFAULT_HOST); - if (g_chrony_host == NULL) - { + if (g_chrony_host == NULL) { ERROR(PLUGIN_NAME ": Error duplicating chrony host name"); return CHRONY_RC_FAIL; } } - if (g_chrony_port == NULL) - { + if (g_chrony_port == NULL) { g_chrony_port = strdup(CHRONY_DEFAULT_PORT); - if (g_chrony_port == NULL) - { + if (g_chrony_port == NULL) { ERROR(PLUGIN_NAME ": Error duplicating chrony port string"); return CHRONY_RC_FAIL; } } - if (g_chrony_timeout < 0) - { + if (g_chrony_timeout < 0) { g_chrony_timeout = CHRONY_DEFAULT_TIMEOUT; assert(g_chrony_timeout >= 0); } DEBUG(PLUGIN_NAME ": Connecting to %s:%s", g_chrony_host, g_chrony_port); socket = connect_client(g_chrony_host, g_chrony_port, AF_UNSPEC, SOCK_DGRAM); - if (socket < 0) - { + if (socket < 0) { ERROR(PLUGIN_NAME ": Error connecting to daemon. Errno = %d", errno); return CHRONY_RC_FAIL; } DEBUG(PLUGIN_NAME ": Connected"); g_chrony_socket = socket; - if (chrony_set_timeout()) - { + if (chrony_set_timeout()) { ERROR(PLUGIN_NAME ": Error setting timeout to %llds. Errno = %d", (long long)g_chrony_timeout, errno); return CHRONY_RC_FAIL; @@ -459,88 +412,71 @@ chrony_connect(void) return CHRONY_RC_OK; } - -static int -chrony_send_request(const tChrony_Request * p_req, size_t p_req_size) -{ - if (send(g_chrony_socket, p_req, p_req_size, 0) < 0) - { +static int chrony_send_request(const tChrony_Request *p_req, + size_t p_req_size) { + if (send(g_chrony_socket, p_req, p_req_size, 0) < 0) { ERROR(PLUGIN_NAME ": Error sending packet. Errno = %d", errno); return CHRONY_RC_FAIL; } return CHRONY_RC_OK; } - -static int -chrony_recv_response(tChrony_Response * p_resp, size_t p_resp_max_size, - size_t * p_resp_size) -{ +static int chrony_recv_response(tChrony_Response *p_resp, + size_t p_resp_max_size, size_t *p_resp_size) { ssize_t rc = recv(g_chrony_socket, p_resp, p_resp_max_size, 0); - if (rc <= 0) - { + if (rc <= 0) { ERROR(PLUGIN_NAME ": Error receiving packet: %s (%d)", strerror(errno), errno); return CHRONY_RC_FAIL; - } - else - { + } else { *p_resp_size = rc; return CHRONY_RC_OK; } } - -static int -chrony_query(const int p_command, tChrony_Request * p_req, - tChrony_Response * p_resp, size_t * p_resp_size) -{ - /* Check connection. We simply perform one try as collectd already handles retries */ +static int chrony_query(const int p_command, tChrony_Request *p_req, + tChrony_Response *p_resp, size_t *p_resp_size) { + /* Check connection. We simply perform one try as collectd already handles + * retries */ assert(p_req); assert(p_resp); assert(p_resp_size); - if (g_chrony_is_connected == 0) - { - if (chrony_connect() == CHRONY_RC_OK) - { + if (g_chrony_is_connected == 0) { + if (chrony_connect() == CHRONY_RC_OK) { g_chrony_is_connected = 1; - } - else - { + } else { ERROR(PLUGIN_NAME ": Unable to connect. Errno = %d", errno); return CHRONY_RC_FAIL; } } - do - { + do { int valid_command = 0; - size_t req_size = sizeof(p_req->header) + sizeof(p_req->padding); + size_t req_size = sizeof(p_req->header) + sizeof(p_req->padding); size_t resp_size = sizeof(p_resp->header); uint16_t resp_code = RPY_NULL; - switch (p_command) - { + switch (p_command) { case REQ_TRACKING: - req_size += sizeof(p_req->body.tracking); + req_size += sizeof(p_req->body.tracking); resp_size += sizeof(p_resp->body.tracking); resp_code = RPY_TRACKING; valid_command = 1; break; case REQ_N_SOURCES: - req_size += sizeof(p_req->body.n_sources); + req_size += sizeof(p_req->body.n_sources); resp_size += sizeof(p_resp->body.n_sources); resp_code = RPY_N_SOURCES; valid_command = 1; break; case REQ_SOURCE_DATA: - req_size += sizeof(p_req->body.source_data); + req_size += sizeof(p_req->body.source_data); resp_size += sizeof(p_resp->body.source_data); resp_code = RPY_SOURCE_DATA; valid_command = 1; break; case REQ_SOURCE_STATS: - req_size += sizeof(p_req->body.source_stats); + req_size += sizeof(p_req->body.source_stats); resp_size += sizeof(p_resp->body.source_stats); resp_code = RPY_SOURCE_STATS; valid_command = 1; @@ -567,48 +503,41 @@ chrony_query(const int p_command, tChrony_Request * p_req, if (chrony_recv_response(p_resp, resp_size, p_resp_size) != 0) break; - DEBUG(PLUGIN_NAME - ": Received response: .version = %u, .type = %u, .cmd = %u, .reply = %u, .status = %u, .seq = %u", + DEBUG(PLUGIN_NAME ": Received response: .version = %u, .type = %u, .cmd = " + "%u, .reply = %u, .status = %u, .seq = %u", p_resp->header.f_version, p_resp->header.f_type, ntohs(p_resp->header.f_cmd), ntohs(p_resp->header.f_reply), ntohs(p_resp->header.f_status), p_resp->header.f_seq); - if (p_resp->header.f_version != p_req->header.f_version) - { + if (p_resp->header.f_version != p_req->header.f_version) { ERROR(PLUGIN_NAME ": Wrong protocol version (Was: %d, expected: %d)", p_resp->header.f_version, p_req->header.f_version); return CHRONY_RC_FAIL; } - if (p_resp->header.f_type != PKT_TYPE_CMD_REPLY) - { + if (p_resp->header.f_type != PKT_TYPE_CMD_REPLY) { ERROR(PLUGIN_NAME ": Wrong packet type (Was: %d, expected: %d)", p_resp->header.f_type, PKT_TYPE_CMD_REPLY); return CHRONY_RC_FAIL; } - if (p_resp->header.f_seq != seq_nr) - { + if (p_resp->header.f_seq != seq_nr) { /* FIXME: Implement sequence number handling */ - ERROR(PLUGIN_NAME - ": Unexpected sequence number (Was: %d, expected: %d)", + ERROR(PLUGIN_NAME ": Unexpected sequence number (Was: %d, expected: %d)", p_resp->header.f_seq, p_req->header.f_seq); return CHRONY_RC_FAIL; } - if (p_resp->header.f_cmd != p_req->header.f_cmd) - { + if (p_resp->header.f_cmd != p_req->header.f_cmd) { ERROR(PLUGIN_NAME ": Wrong reply command (Was: %d, expected: %d)", p_resp->header.f_cmd, p_req->header.f_cmd); return CHRONY_RC_FAIL; } - if (ntohs(p_resp->header.f_reply) != resp_code) - { + if (ntohs(p_resp->header.f_reply) != resp_code) { ERROR(PLUGIN_NAME ": Wrong reply code (Was: %d, expected: %d)", ntohs(p_resp->header.f_reply), resp_code); return CHRONY_RC_FAIL; } - switch (p_resp->header.f_status) - { + switch (p_resp->header.f_status) { case STT_SUCCESS: DEBUG(PLUGIN_NAME ": Reply packet status STT_SUCCESS"); break; @@ -621,39 +550,33 @@ chrony_query(const int p_command, tChrony_Request * p_req, /* Good result */ return CHRONY_RC_OK; - } - while (0); + } while (0); /* Some error occured */ return CHRONY_RC_FAIL; } - -static void -chrony_init_req(tChrony_Request * p_req) -{ +static void chrony_init_req(tChrony_Request *p_req) { memset(p_req, 0, sizeof(*p_req)); p_req->header.f_version = PROTO_VERSION_NUMBER; - p_req->header.f_type = PKT_TYPE_CMD_REQUEST; - p_req->header.f_dummy0 = 0; - p_req->header.f_dummy1 = 0; - p_req->header.f_dummy2 = 0; - p_req->header.f_dummy3 = 0; + p_req->header.f_type = PKT_TYPE_CMD_REQUEST; + p_req->header.f_dummy0 = 0; + p_req->header.f_dummy1 = 0; + p_req->header.f_dummy2 = 0; + p_req->header.f_dummy3 = 0; } - -/* ntohf code originally from: git://git.tuxfamily.org/gitroot/chrony/chrony.git:util.c */ +/* ntohf code originally from: + * git://git.tuxfamily.org/gitroot/chrony/chrony.git:util.c */ /* Original code licensed as GPLv2, by Richard P. Purnow, Miroslav Lichvar */ /* Original name: double UTI_tFloatNetworkToHost(tFloat f) */ -static double -ntohf(tFloat p_float) -{ - /* Convert tFloat in Network-bit-order to double in host-bit-order */ +static double ntohf(tFloat p_float) { +/* Convert tFloat in Network-bit-order to double in host-bit-order */ #define FLOAT_EXP_BITS 7 #define FLOAT_EXP_MIN (-(1 << (FLOAT_EXP_BITS - 1))) #define FLOAT_EXP_MAX (-FLOAT_EXP_MIN - 1) -#define FLOAT_COEF_BITS ((int)sizeof (int32_t) * 8 - FLOAT_EXP_BITS) +#define FLOAT_COEF_BITS ((int)sizeof(int32_t) * 8 - FLOAT_EXP_BITS) #define FLOAT_COEF_MIN (-(1 << (FLOAT_COEF_BITS - 1))) #define FLOAT_COEF_MAX (-FLOAT_COEF_MIN - 1) @@ -673,19 +596,17 @@ ntohf(tFloat p_float) return coef * pow(2.0, exp); } - -static void -chrony_push_data(const char *p_type, const char *p_type_inst, double p_value) -{ +static void chrony_push_data(const char *p_type, const char *p_type_inst, + double p_value) { value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = p_value }; + vl.values = &(value_t){.gauge = p_value}; vl.values_len = 1; - /* XXX: Shall g_chrony_host/g_chrony_port be reflected in the plugin's output? */ + /* XXX: Shall g_chrony_host/g_chrony_port be reflected in the plugin's output? + */ sstrncpy(vl.plugin, PLUGIN_NAME_SHORT, sizeof(vl.plugin)); - if (g_chrony_plugin_instance != NULL) - { + if (g_chrony_plugin_instance != NULL) { sstrncpy(vl.plugin_instance, g_chrony_plugin_instance, sizeof(vl.plugin_instance)); } @@ -698,22 +619,17 @@ chrony_push_data(const char *p_type, const char *p_type_inst, double p_value) plugin_dispatch_values(&vl); } - -static void -chrony_push_data_valid(const char *p_type, const char *p_type_inst, const int p_is_valid, - double p_value) -{ - /* Push real value if p_is_valid is true, push NAN if p_is_valid is not true (idea from ntp plugin) */ +static void chrony_push_data_valid(const char *p_type, const char *p_type_inst, + const int p_is_valid, double p_value) { + /* Push real value if p_is_valid is true, push NAN if p_is_valid is not true + * (idea from ntp plugin) */ if (p_is_valid == 0) p_value = NAN; chrony_push_data(p_type, p_type_inst, p_value); } - -static int -chrony_init_seq(void) -{ +static int chrony_init_seq(void) { /* Initialize the sequence number generator from /dev/urandom */ /* Fallbacks: /dev/random and time(NULL) */ @@ -721,11 +637,9 @@ chrony_init_seq(void) /* Try urandom */ fh = open(URAND_DEVICE_PATH, O_RDONLY); - if (fh >= 0) - { + if (fh >= 0) { ssize_t rc = read(fh, &g_chrony_rand, sizeof(g_chrony_rand)); - if (rc != sizeof(g_chrony_rand)) - { + if (rc != sizeof(g_chrony_rand)) { ERROR(PLUGIN_NAME ": Reading from random source \'%s\'failed: %s (%d)", URAND_DEVICE_PATH, strerror(errno), errno); close(fh); @@ -733,18 +647,14 @@ chrony_init_seq(void) } close(fh); DEBUG(PLUGIN_NAME ": Seeding RNG from " URAND_DEVICE_PATH); - } - else - { - if (errno == ENOENT) - { - /* URAND_DEVICE_PATH device not found. Try RAND_DEVICE_PATH as fall-back */ + } else { + if (errno == ENOENT) { + /* URAND_DEVICE_PATH device not found. Try RAND_DEVICE_PATH as fall-back + */ fh = open(RAND_DEVICE_PATH, O_RDONLY); - if (fh >= 0) - { + if (fh >= 0) { ssize_t rc = read(fh, &g_chrony_rand, sizeof(g_chrony_rand)); - if (rc != sizeof(g_chrony_rand)) - { + if (rc != sizeof(g_chrony_rand)) { ERROR(PLUGIN_NAME ": Reading from random source \'%s\'failed: %s (%d)", RAND_DEVICE_PATH, strerror(errno), errno); @@ -753,16 +663,12 @@ chrony_init_seq(void) } close(fh); DEBUG(PLUGIN_NAME ": Seeding RNG from " RAND_DEVICE_PATH); - } - else - { + } else { /* Error opening RAND_DEVICE_PATH. Try time(NULL) as fall-back */ DEBUG(PLUGIN_NAME ": Seeding RNG from time(NULL)"); g_chrony_rand = time(NULL) ^ getpid(); } - } - else - { + } else { ERROR(PLUGIN_NAME ": Opening random source \'%s\' failed: %s (%d)", URAND_DEVICE_PATH, strerror(errno), errno); return CHRONY_RC_FAIL; @@ -772,64 +678,50 @@ chrony_init_seq(void) return CHRONY_RC_OK; } - /*****************************************************************************/ /* Exported functions */ /*****************************************************************************/ -static int -chrony_config(const char *p_key, const char *p_value) -{ +static int chrony_config(const char *p_key, const char *p_value) { assert(p_key); assert(p_value); /* Parse config variables */ - if (strcasecmp(p_key, CONFIG_KEY_HOST) == 0) - { + if (strcasecmp(p_key, CONFIG_KEY_HOST) == 0) { if (g_chrony_host != NULL) free(g_chrony_host); - if ((g_chrony_host = strdup(p_value)) == NULL) - { + if ((g_chrony_host = strdup(p_value)) == NULL) { ERROR(PLUGIN_NAME ": Error duplicating host name"); return CHRONY_RC_FAIL; } - } - else - { - if (strcasecmp(p_key, CONFIG_KEY_PORT) == 0) - { + } else { + if (strcasecmp(p_key, CONFIG_KEY_PORT) == 0) { if (g_chrony_port != NULL) free(g_chrony_port); - if ((g_chrony_port = strdup(p_value)) == NULL) - { + if ((g_chrony_port = strdup(p_value)) == NULL) { ERROR(PLUGIN_NAME ": Error duplicating port name"); return CHRONY_RC_FAIL; } - } - else - { - if (strcasecmp(p_key, CONFIG_KEY_TIMEOUT) == 0) - { + } else { + if (strcasecmp(p_key, CONFIG_KEY_TIMEOUT) == 0) { time_t tosec = strtol(p_value, NULL, 0); g_chrony_timeout = tosec; - } - else - { - WARNING(PLUGIN_NAME ": Unknown configuration variable: %s %s", p_key, p_value); + } else { + WARNING(PLUGIN_NAME ": Unknown configuration variable: %s %s", p_key, + p_value); return CHRONY_RC_FAIL; } } } - /* XXX: We could set g_chrony_plugin_instance here to "g_chrony_host-g_chrony_port", but as multiple instances aren't yet supported, we skip this for now */ + /* XXX: We could set g_chrony_plugin_instance here to + * "g_chrony_host-g_chrony_port", but as multiple instances aren't yet + * supported, we skip this for now */ return CHRONY_RC_OK; } - -static int -chrony_request_daemon_stats(void) -{ +static int chrony_request_daemon_stats(void) { /* Perform Tracking request */ int rc; size_t chrony_resp_size; @@ -837,19 +729,22 @@ chrony_request_daemon_stats(void) tChrony_Response chrony_resp; chrony_init_req(&chrony_req); - rc = - chrony_query(REQ_TRACKING, &chrony_req, &chrony_resp, &chrony_resp_size); - if (rc != 0) - { + rc = chrony_query(REQ_TRACKING, &chrony_req, &chrony_resp, &chrony_resp_size); + if (rc != 0) { ERROR(PLUGIN_NAME ": chrony_query (REQ_TRACKING) failed with status %i", rc); return rc; } #if COLLECT_DEBUG { - char src_addr[IPV6_STR_MAX_SIZE] = { 0 }; + char src_addr[IPV6_STR_MAX_SIZE] = {0}; niptoha(&chrony_resp.body.tracking.addr, src_addr, sizeof(src_addr)); - DEBUG(PLUGIN_NAME ": Daemon stat: .addr = %s, .ref_id= %u, .stratum = %u, .leap_status = %u, .ref_time = %u:%u:%u, .current_correction = %f, .last_offset = %f, .rms_offset = %f, .freq_ppm = %f, .skew_ppm = %f, .root_delay = %f, .root_dispersion = %f, .last_update_interval = %f", src_addr, ntohs(chrony_resp.body.tracking.f_ref_id), + DEBUG(PLUGIN_NAME + ": Daemon stat: .addr = %s, .ref_id= %u, .stratum = %u, .leap_status " + "= %u, .ref_time = %u:%u:%u, .current_correction = %f, .last_offset " + "= %f, .rms_offset = %f, .freq_ppm = %f, .skew_ppm = %f, .root_delay " + "= %f, .root_dispersion = %f, .last_update_interval = %f", + src_addr, ntohs(chrony_resp.body.tracking.f_ref_id), ntohs(chrony_resp.body.tracking.f_stratum), ntohs(chrony_resp.body.tracking.f_leap_status), ntohl(chrony_resp.body.tracking.f_ref_time.tv_sec_high), @@ -869,10 +764,8 @@ chrony_request_daemon_stats(void) double time_ref = ntohl(chrony_resp.body.tracking.f_ref_time.tv_nsec); time_ref /= 1000000000.0; time_ref += ntohl(chrony_resp.body.tracking.f_ref_time.tv_sec_low); - if (chrony_resp.body.tracking.f_ref_time.tv_sec_high) - { - double secs_high = - ntohl(chrony_resp.body.tracking.f_ref_time.tv_sec_high); + if (chrony_resp.body.tracking.f_ref_time.tv_sec_high) { + double secs_high = ntohl(chrony_resp.body.tracking.f_ref_time.tv_sec_high); secs_high *= 4294967296.0; time_ref += secs_high; } @@ -880,24 +773,43 @@ chrony_request_daemon_stats(void) /* Forward results to collectd-daemon */ /* Type_instance is always 'chrony' to tag daemon-wide data */ /* Type Type_instan Value */ - chrony_push_data("clock_stratum", DAEMON_NAME, ntohs(chrony_resp.body.tracking.f_stratum)); - chrony_push_data("time_ref", DAEMON_NAME, time_ref); /* unit: s */ - chrony_push_data("time_offset_ntp", DAEMON_NAME, ntohf(chrony_resp.body.tracking.f_current_correction)); /* Offset between system time and NTP, unit: s */ - chrony_push_data("time_offset", DAEMON_NAME, ntohf(chrony_resp.body.tracking.f_last_offset)); /* Estimated Offset of the NTP time, unit: s */ - chrony_push_data("time_offset_rms", DAEMON_NAME, ntohf(chrony_resp.body.tracking.f_rms_offset)); /* averaged value of the above, unit: s */ - chrony_push_data("frequency_error", DAEMON_NAME, ntohf(chrony_resp.body.tracking.f_freq_ppm)); /* Frequency error of the local osc, unit: ppm */ - chrony_push_data("clock_skew_ppm", DAEMON_NAME, ntohf(chrony_resp.body.tracking.f_skew_ppm)); - chrony_push_data("root_delay", DAEMON_NAME, ntohf(chrony_resp.body.tracking.f_root_delay)); /* Network latency between local daemon and the current source */ - chrony_push_data("root_dispersion", DAEMON_NAME, ntohf(chrony_resp.body.tracking.f_root_dispersion)); - chrony_push_data("clock_last_update", DAEMON_NAME, ntohf(chrony_resp.body.tracking.f_last_update_interval)); + chrony_push_data("clock_stratum", DAEMON_NAME, + ntohs(chrony_resp.body.tracking.f_stratum)); + chrony_push_data("time_ref", DAEMON_NAME, time_ref); /* unit: s */ + chrony_push_data( + "time_offset_ntp", DAEMON_NAME, + ntohf(chrony_resp.body.tracking.f_current_correction)); /* Offset between + system time and + NTP, unit: s */ + chrony_push_data( + "time_offset", DAEMON_NAME, + ntohf( + chrony_resp.body.tracking + .f_last_offset)); /* Estimated Offset of the NTP time, unit: s */ + chrony_push_data( + "time_offset_rms", DAEMON_NAME, + ntohf(chrony_resp.body.tracking + .f_rms_offset)); /* averaged value of the above, unit: s */ + chrony_push_data( + "frequency_error", DAEMON_NAME, + ntohf(chrony_resp.body.tracking + .f_freq_ppm)); /* Frequency error of the local osc, unit: ppm */ + chrony_push_data("clock_skew_ppm", DAEMON_NAME, + ntohf(chrony_resp.body.tracking.f_skew_ppm)); + chrony_push_data( + "root_delay", DAEMON_NAME, + ntohf(chrony_resp.body.tracking.f_root_delay)); /* Network latency between + local daemon and the + current source */ + chrony_push_data("root_dispersion", DAEMON_NAME, + ntohf(chrony_resp.body.tracking.f_root_dispersion)); + chrony_push_data("clock_last_update", DAEMON_NAME, + ntohf(chrony_resp.body.tracking.f_last_update_interval)); return CHRONY_RC_OK; } - -static int -chrony_request_sources_count(unsigned int *p_count) -{ +static int chrony_request_sources_count(unsigned int *p_count) { /* Requests the number of time sources from the chrony daemon */ int rc; size_t chrony_resp_size; @@ -907,9 +819,8 @@ chrony_request_sources_count(unsigned int *p_count) DEBUG(PLUGIN_NAME ": Requesting data"); chrony_init_req(&chrony_req); rc = - chrony_query(REQ_N_SOURCES, &chrony_req, &chrony_resp, &chrony_resp_size); - if (rc != 0) - { + chrony_query(REQ_N_SOURCES, &chrony_req, &chrony_resp, &chrony_resp_size); + if (rc != 0) { ERROR(PLUGIN_NAME ": chrony_query (REQ_N_SOURCES) failed with status %i", rc); return rc; @@ -921,33 +832,30 @@ chrony_request_sources_count(unsigned int *p_count) return CHRONY_RC_OK; } - -static int -chrony_request_source_data(int p_src_idx, int *p_is_reachable) -{ +static int chrony_request_source_data(int p_src_idx, int *p_is_reachable) { /* Perform Source data request for source #p_src_idx */ int rc; size_t chrony_resp_size; tChrony_Request chrony_req; tChrony_Response chrony_resp; - char src_addr[IPV6_STR_MAX_SIZE] = { 0 }; + char src_addr[IPV6_STR_MAX_SIZE] = {0}; chrony_init_req(&chrony_req); chrony_req.body.source_data.f_index = htonl(p_src_idx); - rc = - chrony_query(REQ_SOURCE_DATA, &chrony_req, &chrony_resp, - &chrony_resp_size); - if (rc != 0) - { - ERROR(PLUGIN_NAME - ": chrony_query (REQ_SOURCE_DATA) failed with status %i", rc); + rc = chrony_query(REQ_SOURCE_DATA, &chrony_req, &chrony_resp, + &chrony_resp_size); + if (rc != 0) { + ERROR(PLUGIN_NAME ": chrony_query (REQ_SOURCE_DATA) failed with status %i", + rc); return rc; } niptoha(&chrony_resp.body.source_data.addr, src_addr, sizeof(src_addr)); - DEBUG(PLUGIN_NAME - ": Source[%d] data: .addr = %s, .poll = %u, .stratum = %u, .state = %u, .mode = %u, .flags = %u, .reach = %u, .latest_meas_ago = %u, .orig_latest_meas = %f, .latest_meas = %f, .latest_meas_err = %f", + DEBUG(PLUGIN_NAME ": Source[%d] data: .addr = %s, .poll = %u, .stratum = %u, " + ".state = %u, .mode = %u, .flags = %u, .reach = %u, " + ".latest_meas_ago = %u, .orig_latest_meas = %f, " + ".latest_meas = %f, .latest_meas_err = %f", p_src_idx, src_addr, ntohs(chrony_resp.body.source_data.f_poll), ntohs(chrony_resp.body.source_data.f_stratum), ntohs(chrony_resp.body.source_data.f_state), @@ -960,8 +868,7 @@ chrony_request_source_data(int p_src_idx, int *p_is_reachable) ntohf(chrony_resp.body.source_data.f_latest_meas_err)); /* Push NaN if source is currently not reachable */ - int is_reachable = - ntohs(chrony_resp.body.source_data.f_reachability) & 0x01; + int is_reachable = ntohs(chrony_resp.body.source_data.f_reachability) & 0x01; *p_is_reachable = is_reachable; /* Forward results to collectd-daemon */ @@ -979,10 +886,8 @@ chrony_request_source_data(int p_src_idx, int *p_is_reachable) return CHRONY_RC_OK; } - -static int -chrony_request_source_stats(int p_src_idx, const int *p_is_reachable) -{ +static int chrony_request_source_stats(int p_src_idx, + const int *p_is_reachable) { /* Perform Source stats request for source #p_src_idx */ int rc; size_t chrony_resp_size; @@ -990,40 +895,35 @@ chrony_request_source_stats(int p_src_idx, const int *p_is_reachable) tChrony_Response chrony_resp; double skew_ppm, frequency_error, time_offset; - char src_addr[IPV6_STR_MAX_SIZE] = { 0 }; + char src_addr[IPV6_STR_MAX_SIZE] = {0}; - if (*p_is_reachable == 0) - { + if (*p_is_reachable == 0) { skew_ppm = 0; frequency_error = 0; time_offset = 0; - } - else - { + } else { chrony_init_req(&chrony_req); chrony_req.body.source_stats.f_index = htonl(p_src_idx); - rc = - chrony_query(REQ_SOURCE_STATS, &chrony_req, &chrony_resp, - &chrony_resp_size); - if (rc != 0) - { + rc = chrony_query(REQ_SOURCE_STATS, &chrony_req, &chrony_resp, + &chrony_resp_size); + if (rc != 0) { ERROR(PLUGIN_NAME - ": chrony_query (REQ_SOURCE_STATS) failed with status %i", rc); + ": chrony_query (REQ_SOURCE_STATS) failed with status %i", + rc); return rc; } skew_ppm = ntohf(chrony_resp.body.source_stats.f_skew_ppm); - frequency_error = - ntohf(chrony_resp.body.source_stats.f_rtc_gain_rate_ppm); + frequency_error = ntohf(chrony_resp.body.source_stats.f_rtc_gain_rate_ppm); time_offset = ntohf(chrony_resp.body.source_stats.f_est_offset); niptoha(&chrony_resp.body.source_stats.addr, src_addr, sizeof(src_addr)); DEBUG(PLUGIN_NAME ": Source[%d] stat: .addr = %s, .ref_id= %u, .n_samples = %u, " ".n_runs = %u, .span_seconds = %u, .rtc_seconds_fast = %f, " - ".rtc_gain_rate_ppm = %f, .skew_ppm= %f, .est_offset = %f, .est_offset_err = %f", - p_src_idx, src_addr, - ntohl(chrony_resp.body.source_stats.f_ref_id), + ".rtc_gain_rate_ppm = %f, .skew_ppm= %f, .est_offset = %f, " + ".est_offset_err = %f", + p_src_idx, src_addr, ntohl(chrony_resp.body.source_stats.f_ref_id), ntohl(chrony_resp.body.source_stats.f_n_samples), ntohl(chrony_resp.body.source_stats.f_n_runs), ntohl(chrony_resp.body.source_stats.f_span_seconds), @@ -1035,22 +935,20 @@ chrony_request_source_stats(int p_src_idx, const int *p_is_reachable) /* Forward results to collectd-daemon */ chrony_push_data_valid("clock_skew_ppm", src_addr, *p_is_reachable, skew_ppm); - chrony_push_data_valid("frequency_error", src_addr, *p_is_reachable, frequency_error); /* unit: ppm */ - chrony_push_data_valid("time_offset", src_addr, *p_is_reachable, time_offset); /* unit: s */ + chrony_push_data_valid("frequency_error", src_addr, *p_is_reachable, + frequency_error); /* unit: ppm */ + chrony_push_data_valid("time_offset", src_addr, *p_is_reachable, + time_offset); /* unit: s */ return CHRONY_RC_OK; } - -static int -chrony_read(void) -{ +static int chrony_read(void) { /* collectd read callback: Perform data acquisition */ int rc; unsigned int n_sources; - if (g_chrony_seq_is_initialized == 0) - { + if (g_chrony_seq_is_initialized == 0) { /* Seed RNG for sequence number generation */ rc = chrony_init_seq(); if (rc != CHRONY_RC_OK) @@ -1069,8 +967,7 @@ chrony_read(void) if (rc != CHRONY_RC_OK) return rc; - for (unsigned int now_src = 0; now_src < n_sources; ++now_src) - { + for (unsigned int now_src = 0; now_src < n_sources; ++now_src) { int is_reachable; rc = chrony_request_source_data(now_src, &is_reachable); if (rc != CHRONY_RC_OK) @@ -1079,18 +976,13 @@ chrony_read(void) rc = chrony_request_source_stats(now_src, &is_reachable); if (rc != CHRONY_RC_OK) return rc; - } return CHRONY_RC_OK; } - -static int -chrony_shutdown(void) -{ +static int chrony_shutdown(void) { /* Collectd shutdown callback: Free mem */ - if (g_chrony_is_connected != 0) - { + if (g_chrony_is_connected != 0) { close(g_chrony_socket); g_chrony_is_connected = 0; } @@ -1099,17 +991,14 @@ chrony_shutdown(void) if (g_chrony_port != NULL) sfree(g_chrony_port); - + if (g_chrony_plugin_instance != NULL) sfree(g_chrony_plugin_instance); - + return CHRONY_RC_OK; } - -void -module_register(void) -{ +void module_register(void) { plugin_register_config(PLUGIN_NAME_SHORT, chrony_config, g_config_keys, g_config_keys_num); plugin_register_read(PLUGIN_NAME_SHORT, chrony_read); diff --git a/src/collectd-nagios.c b/src/collectd-nagios.c index 12187f30..993541d8 100644 --- a/src/collectd-nagios.c +++ b/src/collectd-nagios.c @@ -25,69 +25,68 @@ **/ #if HAVE_CONFIG_H -# include "config.h" +#include "config.h" #endif #if !defined(__GNUC__) || !__GNUC__ -# define __attribute__(x) /**/ +#define __attribute__(x) /**/ #endif -#include -#include -#include +#include #include +#include +#include #include #include -#include +#include #if NAN_STATIC_DEFAULT -# include +#include /* #endif NAN_STATIC_DEFAULT*/ #elif NAN_STATIC_ISOC -# ifndef __USE_ISOC99 -# define DISABLE_ISOC99 1 -# define __USE_ISOC99 1 -# endif /* !defined(__USE_ISOC99) */ -# include -# if DISABLE_ISOC99 -# undef DISABLE_ISOC99 -# undef __USE_ISOC99 -# endif /* DISABLE_ISOC99 */ +#ifndef __USE_ISOC99 +#define DISABLE_ISOC99 1 +#define __USE_ISOC99 1 +#endif /* !defined(__USE_ISOC99) */ +#include +#if DISABLE_ISOC99 +#undef DISABLE_ISOC99 +#undef __USE_ISOC99 +#endif /* DISABLE_ISOC99 */ /* #endif NAN_STATIC_ISOC */ #elif NAN_ZERO_ZERO -# include -# ifdef NAN -# undef NAN -# endif -# define NAN (0.0 / 0.0) -# ifndef isnan -# define isnan(f) ((f) != (f)) -# endif /* !defined(isnan) */ -# ifndef isfinite -# define isfinite(f) (((f) - (f)) == 0.0) -# endif -# ifndef isinf -# define isinf(f) (!isfinite(f) && !isnan(f)) -# endif +#include +#ifdef NAN +#undef NAN +#endif +#define NAN (0.0 / 0.0) +#ifndef isnan +#define isnan(f) ((f) != (f)) +#endif /* !defined(isnan) */ +#ifndef isfinite +#define isfinite(f) (((f) - (f)) == 0.0) +#endif +#ifndef isinf +#define isinf(f) (!isfinite(f) && !isnan(f)) +#endif #endif /* NAN_ZERO_ZERO */ #include "libcollectdclient/collectd/client.h" -#define RET_OKAY 0 -#define RET_WARNING 1 +#define RET_OKAY 0 +#define RET_WARNING 1 #define RET_CRITICAL 2 -#define RET_UNKNOWN 3 +#define RET_UNKNOWN 3 -#define CON_NONE 0 -#define CON_AVERAGE 1 -#define CON_SUM 2 -#define CON_PERCENTAGE 3 +#define CON_NONE 0 +#define CON_AVERAGE 1 +#define CON_SUM 2 +#define CON_PERCENTAGE 3 -struct range_s -{ - double min; - double max; - int invert; +struct range_s { + double min; + double max; + int invert; }; typedef struct range_s range_t; @@ -109,631 +108,560 @@ static size_t match_ds_num_g = 0; /* `strdup' is an XSI extension. I don't want to pull in all of XSI just for * that, so here's an own implementation.. It's easy enough. The GCC attributes * are supposed to get good performance.. -octo */ -__attribute__((malloc, nonnull (1))) -static char *cn_strdup (const char *str) /* {{{ */ +__attribute__((malloc, nonnull(1))) static char * +cn_strdup(const char *str) /* {{{ */ { size_t strsize; char *ret; - strsize = strlen (str) + 1; - ret = (char *) malloc (strsize); + strsize = strlen(str) + 1; + ret = (char *)malloc(strsize); if (ret != NULL) - memcpy (ret, str, strsize); + memcpy(ret, str, strsize); return (ret); } /* }}} char *cn_strdup */ -static int filter_ds (size_t *values_num, - double **values, char ***values_names) -{ - gauge_t *new_values; - char **new_names; - - if (match_ds_g == NULL) - return (RET_OKAY); - - new_values = (gauge_t *)calloc (match_ds_num_g, sizeof (*new_values)); - if (new_values == NULL) - { - fprintf (stderr, "calloc failed: %s\n", strerror (errno)); - return (RET_UNKNOWN); - } - - new_names = (char **)calloc (match_ds_num_g, sizeof (*new_names)); - if (new_names == NULL) - { - fprintf (stderr, "calloc failed: %s\n", strerror (errno)); - free (new_values); - return (RET_UNKNOWN); - } - - for (size_t i = 0; i < match_ds_num_g; i++) - { - size_t j; - - /* match_ds_g keeps pointers into argv but the names will be freed */ - new_names[i] = cn_strdup (match_ds_g[i]); - if (new_names[i] == NULL) - { - fprintf (stderr, "cn_strdup failed: %s\n", strerror (errno)); - free (new_values); - for (j = 0; j < i; j++) - free (new_names[j]); - free (new_names); - return (RET_UNKNOWN); - } - - for (j = 0; j < *values_num; j++) - if (strcasecmp (new_names[i], (*values_names)[j]) == 0) - break; - - if (j == *values_num) - { - printf ("ERROR: DS `%s' is not available.\n", new_names[i]); - free (new_values); - for (j = 0; j <= i; j++) - free (new_names[j]); - free (new_names); - return (RET_CRITICAL); - } - - new_values[i] = (*values)[j]; - } - - free (*values); - for (size_t i = 0; i < *values_num; i++) - free ((*values_names)[i]); - free (*values_names); - - *values = new_values; - *values_names = new_names; - *values_num = match_ds_num_g; - return (RET_OKAY); +static int filter_ds(size_t *values_num, double **values, + char ***values_names) { + gauge_t *new_values; + char **new_names; + + if (match_ds_g == NULL) + return (RET_OKAY); + + new_values = (gauge_t *)calloc(match_ds_num_g, sizeof(*new_values)); + if (new_values == NULL) { + fprintf(stderr, "calloc failed: %s\n", strerror(errno)); + return (RET_UNKNOWN); + } + + new_names = (char **)calloc(match_ds_num_g, sizeof(*new_names)); + if (new_names == NULL) { + fprintf(stderr, "calloc failed: %s\n", strerror(errno)); + free(new_values); + return (RET_UNKNOWN); + } + + for (size_t i = 0; i < match_ds_num_g; i++) { + size_t j; + + /* match_ds_g keeps pointers into argv but the names will be freed */ + new_names[i] = cn_strdup(match_ds_g[i]); + if (new_names[i] == NULL) { + fprintf(stderr, "cn_strdup failed: %s\n", strerror(errno)); + free(new_values); + for (j = 0; j < i; j++) + free(new_names[j]); + free(new_names); + return (RET_UNKNOWN); + } + + for (j = 0; j < *values_num; j++) + if (strcasecmp(new_names[i], (*values_names)[j]) == 0) + break; + + if (j == *values_num) { + printf("ERROR: DS `%s' is not available.\n", new_names[i]); + free(new_values); + for (j = 0; j <= i; j++) + free(new_names[j]); + free(new_names); + return (RET_CRITICAL); + } + + new_values[i] = (*values)[j]; + } + + free(*values); + for (size_t i = 0; i < *values_num; i++) + free((*values_names)[i]); + free(*values_names); + + *values = new_values; + *values_names = new_names; + *values_num = match_ds_num_g; + return (RET_OKAY); } /* int filter_ds */ -static void parse_range (char *string, range_t *range) -{ - char *min_ptr; - char *max_ptr; - - if (*string == '@') - { - range->invert = 1; - string++; - } - - max_ptr = strchr (string, ':'); - if (max_ptr == NULL) - { - min_ptr = NULL; - max_ptr = string; - } - else - { - min_ptr = string; - *max_ptr = '\0'; - max_ptr++; - } - - assert (max_ptr != NULL); - - /* `10' == `0:10' */ - if (min_ptr == NULL) - range->min = 0.0; - /* :10 == ~:10 == -inf:10 */ - else if ((*min_ptr == '\0') || (*min_ptr == '~')) - range->min = NAN; - else - range->min = atof (min_ptr); - - if ((*max_ptr == '\0') || (*max_ptr == '~')) - range->max = NAN; - else - range->max = atof (max_ptr); +static void parse_range(char *string, range_t *range) { + char *min_ptr; + char *max_ptr; + + if (*string == '@') { + range->invert = 1; + string++; + } + + max_ptr = strchr(string, ':'); + if (max_ptr == NULL) { + min_ptr = NULL; + max_ptr = string; + } else { + min_ptr = string; + *max_ptr = '\0'; + max_ptr++; + } + + assert(max_ptr != NULL); + + /* `10' == `0:10' */ + if (min_ptr == NULL) + range->min = 0.0; + /* :10 == ~:10 == -inf:10 */ + else if ((*min_ptr == '\0') || (*min_ptr == '~')) + range->min = NAN; + else + range->min = atof(min_ptr); + + if ((*max_ptr == '\0') || (*max_ptr == '~')) + range->max = NAN; + else + range->max = atof(max_ptr); } /* void parse_range */ -static int match_range (range_t *range, double value) -{ - int ret = 0; +static int match_range(range_t *range, double value) { + int ret = 0; - if (!isnan (range->min) && (range->min > value)) - ret = 1; - if (!isnan (range->max) && (range->max < value)) - ret = 1; + if (!isnan(range->min) && (range->min > value)) + ret = 1; + if (!isnan(range->max) && (range->max < value)) + ret = 1; - return (((ret - range->invert) == 0) ? 0 : 1); + return (((ret - range->invert) == 0) ? 0 : 1); } /* int match_range */ -__attribute__((noreturn)) -static void usage (const char *name) -{ - fprintf (stderr, "Usage: %s <-s socket> <-n value_spec> <-H hostname> [options]\n" - "\n" - "Valid options are:\n" - " -s Path to collectd's UNIX-socket.\n" - " -n Value specification to get from collectd.\n" - " Format: `plugin-instance/type-instance'\n" - " -d Select the DS to examine. May be repeated to examine multiple\n" - " DSes. By default all DSes are used.\n" - " -g Method to use to consolidate several DSes.\n" - " See below for a list of valid arguments.\n" - " -H Hostname to query the values for.\n" - " -c Critical range\n" - " -w Warning range\n" - " -m Treat \"Not a Number\" (NaN) as critical (default: warning)\n" - "\n" - "Consolidation functions:\n" - " none: Apply the warning- and critical-ranges to each data-source\n" - " individually.\n" - " average: Calculate the average of all matching DSes and apply the\n" - " warning- and critical-ranges to the calculated average.\n" - " sum: Apply the ranges to the sum of all DSes.\n" - " percentage: Apply the ranges to the ratio (in percent) of the first value\n" - " and the sum of all values." - "\n", name); - exit (1); +__attribute__((noreturn)) static void usage(const char *name) { + fprintf(stderr, + "Usage: %s <-s socket> <-n value_spec> <-H hostname> [options]\n" + "\n" + "Valid options are:\n" + " -s Path to collectd's UNIX-socket.\n" + " -n Value specification to get from collectd.\n" + " Format: `plugin-instance/type-instance'\n" + " -d Select the DS to examine. May be repeated to " + "examine multiple\n" + " DSes. By default all DSes are used.\n" + " -g Method to use to consolidate several DSes.\n" + " See below for a list of valid arguments.\n" + " -H Hostname to query the values for.\n" + " -c Critical range\n" + " -w Warning range\n" + " -m Treat \"Not a Number\" (NaN) as critical (default: " + "warning)\n" + "\n" + "Consolidation functions:\n" + " none: Apply the warning- and critical-ranges to each " + "data-source\n" + " individually.\n" + " average: Calculate the average of all matching DSes and " + "apply the\n" + " warning- and critical-ranges to the calculated " + "average.\n" + " sum: Apply the ranges to the sum of all DSes.\n" + " percentage: Apply the ranges to the ratio (in percent) of the " + "first value\n" + " and the sum of all values." + "\n", + name); + exit(1); } /* void usage */ -static int do_listval (lcc_connection_t *connection) -{ - lcc_identifier_t *ret_ident = NULL; - size_t ret_ident_num = 0; - - char *hostname = NULL; - - int status; - - status = lcc_listval (connection, &ret_ident, &ret_ident_num); - if (status != 0) { - printf ("UNKNOWN: %s\n", lcc_strerror (connection)); - if (ret_ident != NULL) - free (ret_ident); - return (RET_UNKNOWN); - } - - status = lcc_sort_identifiers (connection, ret_ident, ret_ident_num); - if (status != 0) { - printf ("UNKNOWN: %s\n", lcc_strerror (connection)); - if (ret_ident != NULL) - free (ret_ident); - return (RET_UNKNOWN); - } - - for (size_t i = 0; i < ret_ident_num; ++i) { - char id[1024]; - - if ((hostname_g != NULL) && (strcasecmp (hostname_g, ret_ident[i].host))) - continue; - - if ((hostname == NULL) || strcasecmp (hostname, ret_ident[i].host)) - { - free (hostname); - hostname = strdup (ret_ident[i].host); - printf ("Host: %s\n", hostname); - } - - /* empty hostname; not to be printed again */ - ret_ident[i].host[0] = '\0'; - - status = lcc_identifier_to_string (connection, - id, sizeof (id), ret_ident + i); - if (status != 0) { - printf ("ERROR: listval: Failed to convert returned " - "identifier to a string: %s\n", - lcc_strerror (connection)); - free (hostname); - hostname = NULL; - continue; - } - - /* skip over the (empty) hostname and following '/' */ - printf ("\t%s\n", id + 1); - } - - free (ret_ident); - free (hostname); - return (RET_OKAY); +static int do_listval(lcc_connection_t *connection) { + lcc_identifier_t *ret_ident = NULL; + size_t ret_ident_num = 0; + + char *hostname = NULL; + + int status; + + status = lcc_listval(connection, &ret_ident, &ret_ident_num); + if (status != 0) { + printf("UNKNOWN: %s\n", lcc_strerror(connection)); + if (ret_ident != NULL) + free(ret_ident); + return (RET_UNKNOWN); + } + + status = lcc_sort_identifiers(connection, ret_ident, ret_ident_num); + if (status != 0) { + printf("UNKNOWN: %s\n", lcc_strerror(connection)); + if (ret_ident != NULL) + free(ret_ident); + return (RET_UNKNOWN); + } + + for (size_t i = 0; i < ret_ident_num; ++i) { + char id[1024]; + + if ((hostname_g != NULL) && (strcasecmp(hostname_g, ret_ident[i].host))) + continue; + + if ((hostname == NULL) || strcasecmp(hostname, ret_ident[i].host)) { + free(hostname); + hostname = strdup(ret_ident[i].host); + printf("Host: %s\n", hostname); + } + + /* empty hostname; not to be printed again */ + ret_ident[i].host[0] = '\0'; + + status = + lcc_identifier_to_string(connection, id, sizeof(id), ret_ident + i); + if (status != 0) { + printf("ERROR: listval: Failed to convert returned " + "identifier to a string: %s\n", + lcc_strerror(connection)); + free(hostname); + hostname = NULL; + continue; + } + + /* skip over the (empty) hostname and following '/' */ + printf("\t%s\n", id + 1); + } + + free(ret_ident); + free(hostname); + return (RET_OKAY); } /* int do_listval */ -static int do_check_con_none (size_t values_num, - double *values, char **values_names) -{ - int num_critical = 0; - int num_warning = 0; - int num_okay = 0; - const char *status_str = "UNKNOWN"; - int status_code = RET_UNKNOWN; - - for (size_t i = 0; i < values_num; i++) - { - if (isnan (values[i])) - { - if (nan_is_error_g) - num_critical++; - else - num_warning++; - } - else if (match_range (&range_critical_g, values[i]) != 0) - num_critical++; - else if (match_range (&range_warning_g, values[i]) != 0) - num_warning++; - else - num_okay++; - } - - if ((num_critical == 0) && (num_warning == 0) && (num_okay == 0)) - { - printf ("WARNING: No defined values found\n"); - return (RET_WARNING); - } - else if ((num_critical == 0) && (num_warning == 0)) - { - status_str = "OKAY"; - status_code = RET_OKAY; - } - else if (num_critical == 0) - { - status_str = "WARNING"; - status_code = RET_WARNING; - } - else - { - status_str = "CRITICAL"; - status_code = RET_CRITICAL; - } - - printf ("%s: %i critical, %i warning, %i okay", status_str, - num_critical, num_warning, num_okay); - if (values_num > 0) - { - printf (" |"); - for (size_t i = 0; i < values_num; i++) - printf (" %s=%f;;;;", values_names[i], values[i]); - } - printf ("\n"); - - return (status_code); +static int do_check_con_none(size_t values_num, double *values, + char **values_names) { + int num_critical = 0; + int num_warning = 0; + int num_okay = 0; + const char *status_str = "UNKNOWN"; + int status_code = RET_UNKNOWN; + + for (size_t i = 0; i < values_num; i++) { + if (isnan(values[i])) { + if (nan_is_error_g) + num_critical++; + else + num_warning++; + } else if (match_range(&range_critical_g, values[i]) != 0) + num_critical++; + else if (match_range(&range_warning_g, values[i]) != 0) + num_warning++; + else + num_okay++; + } + + if ((num_critical == 0) && (num_warning == 0) && (num_okay == 0)) { + printf("WARNING: No defined values found\n"); + return (RET_WARNING); + } else if ((num_critical == 0) && (num_warning == 0)) { + status_str = "OKAY"; + status_code = RET_OKAY; + } else if (num_critical == 0) { + status_str = "WARNING"; + status_code = RET_WARNING; + } else { + status_str = "CRITICAL"; + status_code = RET_CRITICAL; + } + + printf("%s: %i critical, %i warning, %i okay", status_str, num_critical, + num_warning, num_okay); + if (values_num > 0) { + printf(" |"); + for (size_t i = 0; i < values_num; i++) + printf(" %s=%f;;;;", values_names[i], values[i]); + } + printf("\n"); + + return (status_code); } /* int do_check_con_none */ -static int do_check_con_average (size_t values_num, - double *values, char **values_names) -{ - double total; - int total_num; - double average; - const char *status_str = "UNKNOWN"; - int status_code = RET_UNKNOWN; - - total = 0.0; - total_num = 0; - for (size_t i = 0; i < values_num; i++) - { - if (isnan (values[i])) - { - if (!nan_is_error_g) - continue; - - printf ("CRITICAL: Data source \"%s\" is NaN\n", - values_names[i]); - return (RET_CRITICAL); - } - - total += values[i]; - total_num++; - } - - if (total_num == 0) - { - printf ("WARNING: No defined values found\n"); - return (RET_WARNING); - } - - average = total / total_num; - - if (match_range (&range_critical_g, average) != 0) - { - status_str = "CRITICAL"; - status_code = RET_CRITICAL; - } - else if (match_range (&range_warning_g, average) != 0) - { - status_str = "WARNING"; - status_code = RET_WARNING; - } - else - { - status_str = "OKAY"; - status_code = RET_OKAY; - } - - printf ("%s: %g average |", status_str, average); - for (size_t i = 0; i < values_num; i++) - printf (" %s=%f;;;;", values_names[i], values[i]); - printf ("\n"); - - return (status_code); +static int do_check_con_average(size_t values_num, double *values, + char **values_names) { + double total; + int total_num; + double average; + const char *status_str = "UNKNOWN"; + int status_code = RET_UNKNOWN; + + total = 0.0; + total_num = 0; + for (size_t i = 0; i < values_num; i++) { + if (isnan(values[i])) { + if (!nan_is_error_g) + continue; + + printf("CRITICAL: Data source \"%s\" is NaN\n", values_names[i]); + return (RET_CRITICAL); + } + + total += values[i]; + total_num++; + } + + if (total_num == 0) { + printf("WARNING: No defined values found\n"); + return (RET_WARNING); + } + + average = total / total_num; + + if (match_range(&range_critical_g, average) != 0) { + status_str = "CRITICAL"; + status_code = RET_CRITICAL; + } else if (match_range(&range_warning_g, average) != 0) { + status_str = "WARNING"; + status_code = RET_WARNING; + } else { + status_str = "OKAY"; + status_code = RET_OKAY; + } + + printf("%s: %g average |", status_str, average); + for (size_t i = 0; i < values_num; i++) + printf(" %s=%f;;;;", values_names[i], values[i]); + printf("\n"); + + return (status_code); } /* int do_check_con_average */ -static int do_check_con_sum (size_t values_num, - double *values, char **values_names) -{ - double total; - int total_num; - const char *status_str = "UNKNOWN"; - int status_code = RET_UNKNOWN; - - total = 0.0; - total_num = 0; - for (size_t i = 0; i < values_num; i++) - { - if (isnan (values[i])) - { - if (!nan_is_error_g) - continue; - - printf ("CRITICAL: Data source \"%s\" is NaN\n", - values_names[i]); - return (RET_CRITICAL); - } - - total += values[i]; - total_num++; - } - - if (total_num == 0) - { - printf ("WARNING: No defined values found\n"); - return (RET_WARNING); - } - - if (match_range (&range_critical_g, total) != 0) - { - status_str = "CRITICAL"; - status_code = RET_CRITICAL; - } - else if (match_range (&range_warning_g, total) != 0) - { - status_str = "WARNING"; - status_code = RET_WARNING; - } - else - { - status_str = "OKAY"; - status_code = RET_OKAY; - } - - printf ("%s: %g sum |", status_str, total); - for (size_t i = 0; i < values_num; i++) - printf (" %s=%f;;;;", values_names[i], values[i]); - printf ("\n"); - - return (status_code); +static int do_check_con_sum(size_t values_num, double *values, + char **values_names) { + double total; + int total_num; + const char *status_str = "UNKNOWN"; + int status_code = RET_UNKNOWN; + + total = 0.0; + total_num = 0; + for (size_t i = 0; i < values_num; i++) { + if (isnan(values[i])) { + if (!nan_is_error_g) + continue; + + printf("CRITICAL: Data source \"%s\" is NaN\n", values_names[i]); + return (RET_CRITICAL); + } + + total += values[i]; + total_num++; + } + + if (total_num == 0) { + printf("WARNING: No defined values found\n"); + return (RET_WARNING); + } + + if (match_range(&range_critical_g, total) != 0) { + status_str = "CRITICAL"; + status_code = RET_CRITICAL; + } else if (match_range(&range_warning_g, total) != 0) { + status_str = "WARNING"; + status_code = RET_WARNING; + } else { + status_str = "OKAY"; + status_code = RET_OKAY; + } + + printf("%s: %g sum |", status_str, total); + for (size_t i = 0; i < values_num; i++) + printf(" %s=%f;;;;", values_names[i], values[i]); + printf("\n"); + + return (status_code); } /* int do_check_con_sum */ -static int do_check_con_percentage (size_t values_num, - double *values, char **values_names) -{ - double sum = 0.0; - double percentage; - - const char *status_str = "UNKNOWN"; - int status_code = RET_UNKNOWN; - - if ((values_num < 1) || (isnan (values[0]))) - { - printf ("WARNING: The first value is not defined\n"); - return (RET_WARNING); - } - - for (size_t i = 0; i < values_num; i++) - { - if (isnan (values[i])) - { - if (!nan_is_error_g) - continue; - - printf ("CRITICAL: Data source \"%s\" is NaN\n", - values_names[i]); - return (RET_CRITICAL); - } - - sum += values[i]; - } - - if (sum == 0.0) - { - printf ("WARNING: Values sum up to zero\n"); - return (RET_WARNING); - } - - percentage = 100.0 * values[0] / sum; - - if (match_range (&range_critical_g, percentage) != 0) - { - status_str = "CRITICAL"; - status_code = RET_CRITICAL; - } - else if (match_range (&range_warning_g, percentage) != 0) - { - status_str = "WARNING"; - status_code = RET_WARNING; - } - else - { - status_str = "OKAY"; - status_code = RET_OKAY; - } - - printf ("%s: %lf percent |", status_str, percentage); - for (size_t i = 0; i < values_num; i++) - printf (" %s=%lf;;;;", values_names[i], values[i]); - return (status_code); +static int do_check_con_percentage(size_t values_num, double *values, + char **values_names) { + double sum = 0.0; + double percentage; + + const char *status_str = "UNKNOWN"; + int status_code = RET_UNKNOWN; + + if ((values_num < 1) || (isnan(values[0]))) { + printf("WARNING: The first value is not defined\n"); + return (RET_WARNING); + } + + for (size_t i = 0; i < values_num; i++) { + if (isnan(values[i])) { + if (!nan_is_error_g) + continue; + + printf("CRITICAL: Data source \"%s\" is NaN\n", values_names[i]); + return (RET_CRITICAL); + } + + sum += values[i]; + } + + if (sum == 0.0) { + printf("WARNING: Values sum up to zero\n"); + return (RET_WARNING); + } + + percentage = 100.0 * values[0] / sum; + + if (match_range(&range_critical_g, percentage) != 0) { + status_str = "CRITICAL"; + status_code = RET_CRITICAL; + } else if (match_range(&range_warning_g, percentage) != 0) { + status_str = "WARNING"; + status_code = RET_WARNING; + } else { + status_str = "OKAY"; + status_code = RET_OKAY; + } + + printf("%s: %lf percent |", status_str, percentage); + for (size_t i = 0; i < values_num; i++) + printf(" %s=%lf;;;;", values_names[i], values[i]); + return (status_code); } /* int do_check_con_percentage */ -static int do_check (lcc_connection_t *connection) -{ - gauge_t *values; - char **values_names; - size_t values_num; - char ident_str[1024]; - lcc_identifier_t ident; - int status; - - snprintf (ident_str, sizeof (ident_str), "%s/%s", - hostname_g, value_string_g); - ident_str[sizeof (ident_str) - 1] = 0; - - status = lcc_string_to_identifier (connection, &ident, ident_str); - if (status != 0) - { - printf ("ERROR: Creating an identifier failed: %s.\n", - lcc_strerror (connection)); - LCC_DESTROY (connection); - return (RET_CRITICAL); - } - - status = lcc_getval (connection, &ident, - &values_num, &values, &values_names); - if (status != 0) - { - printf ("ERROR: Retrieving values from the daemon failed: %s.\n", - lcc_strerror (connection)); - LCC_DESTROY (connection); - return (RET_CRITICAL); - } - - LCC_DESTROY (connection); - - status = filter_ds (&values_num, &values, &values_names); - if (status != RET_OKAY) - return (status); - - status = RET_UNKNOWN; - if (consolitation_g == CON_NONE) - status = do_check_con_none (values_num, values, values_names); - else if (consolitation_g == CON_AVERAGE) - status = do_check_con_average (values_num, values, values_names); - else if (consolitation_g == CON_SUM) - status = do_check_con_sum (values_num, values, values_names); - else if (consolitation_g == CON_PERCENTAGE) - status = do_check_con_percentage (values_num, values, values_names); - - free (values); - if (values_names != NULL) - for (size_t i = 0; i < values_num; i++) - free (values_names[i]); - free (values_names); - - return (status); +static int do_check(lcc_connection_t *connection) { + gauge_t *values; + char **values_names; + size_t values_num; + char ident_str[1024]; + lcc_identifier_t ident; + int status; + + snprintf(ident_str, sizeof(ident_str), "%s/%s", hostname_g, value_string_g); + ident_str[sizeof(ident_str) - 1] = 0; + + status = lcc_string_to_identifier(connection, &ident, ident_str); + if (status != 0) { + printf("ERROR: Creating an identifier failed: %s.\n", + lcc_strerror(connection)); + LCC_DESTROY(connection); + return (RET_CRITICAL); + } + + status = lcc_getval(connection, &ident, &values_num, &values, &values_names); + if (status != 0) { + printf("ERROR: Retrieving values from the daemon failed: %s.\n", + lcc_strerror(connection)); + LCC_DESTROY(connection); + return (RET_CRITICAL); + } + + LCC_DESTROY(connection); + + status = filter_ds(&values_num, &values, &values_names); + if (status != RET_OKAY) + return (status); + + status = RET_UNKNOWN; + if (consolitation_g == CON_NONE) + status = do_check_con_none(values_num, values, values_names); + else if (consolitation_g == CON_AVERAGE) + status = do_check_con_average(values_num, values, values_names); + else if (consolitation_g == CON_SUM) + status = do_check_con_sum(values_num, values, values_names); + else if (consolitation_g == CON_PERCENTAGE) + status = do_check_con_percentage(values_num, values, values_names); + + free(values); + if (values_names != NULL) + for (size_t i = 0; i < values_num; i++) + free(values_names[i]); + free(values_names); + + return (status); } /* int do_check */ -int main (int argc, char **argv) -{ - char address[1024]; - lcc_connection_t *connection; - - int status; - - range_critical_g.min = NAN; - range_critical_g.max = NAN; - range_critical_g.invert = 0; - - range_warning_g.min = NAN; - range_warning_g.max = NAN; - range_warning_g.invert = 0; - - while (42) - { - int c; - - c = getopt (argc, argv, "w:c:s:n:H:g:d:hm"); - if (c < 0) - break; - - switch (c) - { - case 'c': - parse_range (optarg, &range_critical_g); - break; - case 'w': - parse_range (optarg, &range_warning_g); - break; - case 's': - socket_file_g = optarg; - break; - case 'n': - value_string_g = optarg; - break; - case 'H': - hostname_g = optarg; - break; - case 'g': - if (strcasecmp (optarg, "none") == 0) - consolitation_g = CON_NONE; - else if (strcasecmp (optarg, "average") == 0) - consolitation_g = CON_AVERAGE; - else if (strcasecmp (optarg, "sum") == 0) - consolitation_g = CON_SUM; - else if (strcasecmp (optarg, "percentage") == 0) - consolitation_g = CON_PERCENTAGE; - else - { - fprintf (stderr, "Unknown consolidation function `%s'.\n", - optarg); - usage (argv[0]); - } - break; - case 'd': - { - char **tmp; - tmp = realloc (match_ds_g, - (match_ds_num_g + 1) - * sizeof (char *)); - if (tmp == NULL) - { - fprintf (stderr, "realloc failed: %s\n", - strerror (errno)); - return (RET_UNKNOWN); - } - match_ds_g = tmp; - match_ds_g[match_ds_num_g] = cn_strdup (optarg); - if (match_ds_g[match_ds_num_g] == NULL) - { - fprintf (stderr, "cn_strdup failed: %s\n", - strerror (errno)); - return (RET_UNKNOWN); - } - match_ds_num_g++; - break; - } - case 'm': - nan_is_error_g = 1; - break; - default: - usage (argv[0]); - } /* switch (c) */ - } - - if ((socket_file_g == NULL) || (value_string_g == NULL) - || ((hostname_g == NULL) && (strcasecmp (value_string_g, "LIST")))) - { - fprintf (stderr, "Missing required arguments.\n"); - usage (argv[0]); - } - - snprintf (address, sizeof (address), "unix:%s", socket_file_g); - address[sizeof (address) - 1] = 0; - - connection = NULL; - status = lcc_connect (address, &connection); - if (status != 0) - { - printf ("ERROR: Connecting to daemon at %s failed.\n", - socket_file_g); - return (RET_CRITICAL); - } - - if (0 == strcasecmp (value_string_g, "LIST")) - return (do_listval (connection)); - - return (do_check (connection)); +int main(int argc, char **argv) { + char address[1024]; + lcc_connection_t *connection; + + int status; + + range_critical_g.min = NAN; + range_critical_g.max = NAN; + range_critical_g.invert = 0; + + range_warning_g.min = NAN; + range_warning_g.max = NAN; + range_warning_g.invert = 0; + + while (42) { + int c; + + c = getopt(argc, argv, "w:c:s:n:H:g:d:hm"); + if (c < 0) + break; + + switch (c) { + case 'c': + parse_range(optarg, &range_critical_g); + break; + case 'w': + parse_range(optarg, &range_warning_g); + break; + case 's': + socket_file_g = optarg; + break; + case 'n': + value_string_g = optarg; + break; + case 'H': + hostname_g = optarg; + break; + case 'g': + if (strcasecmp(optarg, "none") == 0) + consolitation_g = CON_NONE; + else if (strcasecmp(optarg, "average") == 0) + consolitation_g = CON_AVERAGE; + else if (strcasecmp(optarg, "sum") == 0) + consolitation_g = CON_SUM; + else if (strcasecmp(optarg, "percentage") == 0) + consolitation_g = CON_PERCENTAGE; + else { + fprintf(stderr, "Unknown consolidation function `%s'.\n", optarg); + usage(argv[0]); + } + break; + case 'd': { + char **tmp; + tmp = realloc(match_ds_g, (match_ds_num_g + 1) * sizeof(char *)); + if (tmp == NULL) { + fprintf(stderr, "realloc failed: %s\n", strerror(errno)); + return (RET_UNKNOWN); + } + match_ds_g = tmp; + match_ds_g[match_ds_num_g] = cn_strdup(optarg); + if (match_ds_g[match_ds_num_g] == NULL) { + fprintf(stderr, "cn_strdup failed: %s\n", strerror(errno)); + return (RET_UNKNOWN); + } + match_ds_num_g++; + break; + } + case 'm': + nan_is_error_g = 1; + break; + default: + usage(argv[0]); + } /* switch (c) */ + } + + if ((socket_file_g == NULL) || (value_string_g == NULL) || + ((hostname_g == NULL) && (strcasecmp(value_string_g, "LIST")))) { + fprintf(stderr, "Missing required arguments.\n"); + usage(argv[0]); + } + + snprintf(address, sizeof(address), "unix:%s", socket_file_g); + address[sizeof(address) - 1] = 0; + + connection = NULL; + status = lcc_connect(address, &connection); + if (status != 0) { + printf("ERROR: Connecting to daemon at %s failed.\n", socket_file_g); + return (RET_CRITICAL); + } + + if (0 == strcasecmp(value_string_g, "LIST")) + return (do_listval(connection)); + + return (do_check(connection)); } /* int main */ diff --git a/src/collectd-tg.c b/src/collectd-tg.c index 7db9fe71..71f6040d 100644 --- a/src/collectd-tg.c +++ b/src/collectd-tg.c @@ -25,32 +25,32 @@ **/ #if HAVE_CONFIG_H -# include "config.h" +#include "config.h" #endif #if !__GNUC__ -# define __attribute__(x) /**/ +#define __attribute__(x) /**/ #endif -#include -#include -#include -#include -#include -#include #include #include +#include +#include +#include +#include #include +#include +#include #include "utils_heap.h" #include "libcollectdclient/collectd/client.h" #include "libcollectdclient/collectd/network.h" -#define DEF_NUM_HOSTS 1000 -#define DEF_NUM_PLUGINS 20 +#define DEF_NUM_HOSTS 1000 +#define DEF_NUM_PLUGINS 20 #define DEF_NUM_VALUES 100000 -#define DEF_INTERVAL 10.0 +#define DEF_INTERVAL 10.0 static int conf_num_hosts = DEF_NUM_HOSTS; static int conf_num_plugins = DEF_NUM_PLUGINS; @@ -68,10 +68,10 @@ static struct sigaction sigterm_action; static _Bool loop = 1; -__attribute__((noreturn)) -static void exit_usage (int exit_status) /* {{{ */ +__attribute__((noreturn)) static void exit_usage(int exit_status) /* {{{ */ { - fprintf ((exit_status == EXIT_FAILURE) ? stderr : stdout, + fprintf( + (exit_status == EXIT_FAILURE) ? stderr : stdout, "collectd-tg -- collectd traffic generator\n" "\n" " Usage: collectd-ng [OPTION]\n" @@ -89,41 +89,40 @@ static void exit_usage (int exit_status) /* {{{ */ "\n" "Copyright (C) 2010-2012 Florian Forster\n" "Licensed under the MIT license.\n", - DEF_NUM_VALUES, DEF_NUM_HOSTS, DEF_NUM_PLUGINS, - DEF_INTERVAL, + DEF_NUM_VALUES, DEF_NUM_HOSTS, DEF_NUM_PLUGINS, DEF_INTERVAL, NET_DEFAULT_V6_ADDR, NET_DEFAULT_PORT); - exit (exit_status); + exit(exit_status); } /* }}} void exit_usage */ -static void signal_handler (int signal) /* {{{ */ +static void signal_handler(int signal) /* {{{ */ { loop = 0; } /* }}} void signal_handler */ #if HAVE_CLOCK_GETTIME -static double dtime (void) /* {{{ */ +static double dtime(void) /* {{{ */ { - struct timespec ts = { 0 }; + struct timespec ts = {0}; - if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) - perror ("clock_gettime"); + if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) + perror("clock_gettime"); - return ((double) ts.tv_sec) + (((double) ts.tv_nsec) / 1e9); + return ((double)ts.tv_sec) + (((double)ts.tv_nsec) / 1e9); } /* }}} double dtime */ #else /* Work around for Mac OS X which doesn't have clock_gettime(2). *sigh* */ -static double dtime (void) /* {{{ */ +static double dtime(void) /* {{{ */ { - struct timeval tv = { 0 }; + struct timeval tv = {0}; - if (gettimeofday (&tv, /* timezone = */ NULL) != 0) - perror ("gettimeofday"); + if (gettimeofday(&tv, /* timezone = */ NULL) != 0) + perror("gettimeofday"); - return ((double) tv.tv_sec) + (((double) tv.tv_usec) / 1e6); + return ((double)tv.tv_sec) + (((double)tv.tv_usec) / 1e6); } /* }}} double dtime */ #endif -static int compare_time (const void *v0, const void *v1) /* {{{ */ +static int compare_time(const void *v0, const void *v1) /* {{{ */ { const lcc_value_list_t *vl0 = v0; const lcc_value_list_t *vl1 = v1; @@ -136,7 +135,7 @@ static int compare_time (const void *v0, const void *v1) /* {{{ */ return (0); } /* }}} int compare_time */ -static int get_boundet_random (int min, int max) /* {{{ */ +static int get_boundet_random(int min, int max) /* {{{ */ { int range; @@ -147,281 +146,256 @@ static int get_boundet_random (int min, int max) /* {{{ */ range = max - min; - return (min + ((int) (((double) range) * ((double) random ()) / (((double) RAND_MAX) + 1.0)))); + return (min + ((int)(((double)range) * ((double)random()) / + (((double)RAND_MAX) + 1.0)))); } /* }}} int get_boundet_random */ -static lcc_value_list_t *create_value_list (void) /* {{{ */ +static lcc_value_list_t *create_value_list(void) /* {{{ */ { lcc_value_list_t *vl; int host_num; - vl = calloc (1, sizeof (*vl)); - if (vl == NULL) - { - fprintf (stderr, "calloc failed.\n"); + vl = calloc(1, sizeof(*vl)); + if (vl == NULL) { + fprintf(stderr, "calloc failed.\n"); return (NULL); } - vl->values = calloc (/* nmemb = */ 1, sizeof (*vl->values)); - if (vl->values == NULL) - { - fprintf (stderr, "calloc failed.\n"); - free (vl); + vl->values = calloc(/* nmemb = */ 1, sizeof(*vl->values)); + if (vl->values == NULL) { + fprintf(stderr, "calloc failed.\n"); + free(vl); return (NULL); } - vl->values_types = calloc (/* nmemb = */ 1, sizeof (*vl->values_types)); - if (vl->values_types == NULL) - { - fprintf (stderr, "calloc failed.\n"); - free (vl->values); - free (vl); + vl->values_types = calloc(/* nmemb = */ 1, sizeof(*vl->values_types)); + if (vl->values_types == NULL) { + fprintf(stderr, "calloc failed.\n"); + free(vl->values); + free(vl); return (NULL); } vl->values_len = 1; - host_num = get_boundet_random (0, conf_num_hosts); + host_num = get_boundet_random(0, conf_num_hosts); vl->interval = conf_interval; - vl->time = 1.0 + dtime () - + (host_num % (1 + (int) vl->interval)); + vl->time = 1.0 + dtime() + (host_num % (1 + (int)vl->interval)); - if (get_boundet_random (0, 2) == 0) + if (get_boundet_random(0, 2) == 0) vl->values_types[0] = LCC_TYPE_GAUGE; else vl->values_types[0] = LCC_TYPE_DERIVE; - snprintf (vl->identifier.host, sizeof (vl->identifier.host), - "host%04i", host_num); - snprintf (vl->identifier.plugin, sizeof (vl->identifier.plugin), - "plugin%03i", get_boundet_random (0, conf_num_plugins)); - strncpy (vl->identifier.type, - (vl->values_types[0] == LCC_TYPE_GAUGE) ? "gauge" : "derive", - sizeof (vl->identifier.type)); - vl->identifier.type[sizeof (vl->identifier.type) - 1] = 0; - snprintf (vl->identifier.type_instance, sizeof (vl->identifier.type_instance), - "ti%li", random ()); + snprintf(vl->identifier.host, sizeof(vl->identifier.host), "host%04i", + host_num); + snprintf(vl->identifier.plugin, sizeof(vl->identifier.plugin), "plugin%03i", + get_boundet_random(0, conf_num_plugins)); + strncpy(vl->identifier.type, + (vl->values_types[0] == LCC_TYPE_GAUGE) ? "gauge" : "derive", + sizeof(vl->identifier.type)); + vl->identifier.type[sizeof(vl->identifier.type) - 1] = 0; + snprintf(vl->identifier.type_instance, sizeof(vl->identifier.type_instance), + "ti%li", random()); return (vl); } /* }}} int create_value_list */ -static void destroy_value_list (lcc_value_list_t *vl) /* {{{ */ +static void destroy_value_list(lcc_value_list_t *vl) /* {{{ */ { if (vl == NULL) return; - free (vl->values); - free (vl->values_types); - free (vl); + free(vl->values); + free(vl->values_types); + free(vl); } /* }}} void destroy_value_list */ -static int send_value (lcc_value_list_t *vl) /* {{{ */ +static int send_value(lcc_value_list_t *vl) /* {{{ */ { int status; if (vl->values_types[0] == LCC_TYPE_GAUGE) - vl->values[0].gauge = 100.0 * ((gauge_t) random ()) / (((gauge_t) RAND_MAX) + 1.0); + vl->values[0].gauge = + 100.0 * ((gauge_t)random()) / (((gauge_t)RAND_MAX) + 1.0); else - vl->values[0].derive += (derive_t) get_boundet_random (0, 100); + vl->values[0].derive += (derive_t)get_boundet_random(0, 100); - status = lcc_network_values_send (net, vl); + status = lcc_network_values_send(net, vl); if (status != 0) - fprintf (stderr, "lcc_network_values_send failed with status %i.\n", status); + fprintf(stderr, "lcc_network_values_send failed with status %i.\n", status); vl->time += vl->interval; return (0); } /* }}} int send_value */ -static int get_integer_opt (const char *str, int *ret_value) /* {{{ */ +static int get_integer_opt(const char *str, int *ret_value) /* {{{ */ { char *endptr; int tmp; errno = 0; endptr = NULL; - tmp = (int) strtol (str, &endptr, /* base = */ 0); - if (errno != 0) - { - fprintf (stderr, "Unable to parse option as a number: \"%s\": %s\n", - str, strerror (errno)); - exit (EXIT_FAILURE); - } - else if (endptr == str) - { - fprintf (stderr, "Unable to parse option as a number: \"%s\"\n", str); - exit (EXIT_FAILURE); - } - else if (*endptr != 0) - { - fprintf (stderr, "Garbage after end of value: \"%s\"\n", str); - exit (EXIT_FAILURE); + tmp = (int)strtol(str, &endptr, /* base = */ 0); + if (errno != 0) { + fprintf(stderr, "Unable to parse option as a number: \"%s\": %s\n", str, + strerror(errno)); + exit(EXIT_FAILURE); + } else if (endptr == str) { + fprintf(stderr, "Unable to parse option as a number: \"%s\"\n", str); + exit(EXIT_FAILURE); + } else if (*endptr != 0) { + fprintf(stderr, "Garbage after end of value: \"%s\"\n", str); + exit(EXIT_FAILURE); } *ret_value = tmp; return (0); } /* }}} int get_integer_opt */ -static int get_double_opt (const char *str, double *ret_value) /* {{{ */ +static int get_double_opt(const char *str, double *ret_value) /* {{{ */ { char *endptr; double tmp; errno = 0; endptr = NULL; - tmp = strtod (str, &endptr); - if (errno != 0) - { - fprintf (stderr, "Unable to parse option as a number: \"%s\": %s\n", - str, strerror (errno)); - exit (EXIT_FAILURE); - } - else if (endptr == str) - { - fprintf (stderr, "Unable to parse option as a number: \"%s\"\n", str); - exit (EXIT_FAILURE); - } - else if (*endptr != 0) - { - fprintf (stderr, "Garbage after end of value: \"%s\"\n", str); - exit (EXIT_FAILURE); + tmp = strtod(str, &endptr); + if (errno != 0) { + fprintf(stderr, "Unable to parse option as a number: \"%s\": %s\n", str, + strerror(errno)); + exit(EXIT_FAILURE); + } else if (endptr == str) { + fprintf(stderr, "Unable to parse option as a number: \"%s\"\n", str); + exit(EXIT_FAILURE); + } else if (*endptr != 0) { + fprintf(stderr, "Garbage after end of value: \"%s\"\n", str); + exit(EXIT_FAILURE); } *ret_value = tmp; return (0); } /* }}} int get_double_opt */ -static int read_options (int argc, char **argv) /* {{{ */ +static int read_options(int argc, char **argv) /* {{{ */ { int opt; - while ((opt = getopt (argc, argv, "n:H:p:i:d:D:h")) != -1) - { - switch (opt) - { - case 'n': - get_integer_opt (optarg, &conf_num_values); - break; + while ((opt = getopt(argc, argv, "n:H:p:i:d:D:h")) != -1) { + switch (opt) { + case 'n': + get_integer_opt(optarg, &conf_num_values); + break; - case 'H': - get_integer_opt (optarg, &conf_num_hosts); - break; + case 'H': + get_integer_opt(optarg, &conf_num_hosts); + break; - case 'p': - get_integer_opt (optarg, &conf_num_plugins); - break; + case 'p': + get_integer_opt(optarg, &conf_num_plugins); + break; - case 'i': - get_double_opt (optarg, &conf_interval); - break; + case 'i': + get_double_opt(optarg, &conf_interval); + break; - case 'd': - conf_destination = optarg; - break; + case 'd': + conf_destination = optarg; + break; - case 'D': - conf_service = optarg; - break; + case 'D': + conf_service = optarg; + break; - case 'h': - exit_usage (EXIT_SUCCESS); + case 'h': + exit_usage(EXIT_SUCCESS); - default: - exit_usage (EXIT_FAILURE); + default: + exit_usage(EXIT_FAILURE); } /* switch (opt) */ - } /* while (getopt) */ + } /* while (getopt) */ return (0); } /* }}} int read_options */ -int main (int argc, char **argv) /* {{{ */ +int main(int argc, char **argv) /* {{{ */ { double last_time; int values_sent = 0; - read_options (argc, argv); + read_options(argc, argv); sigint_action.sa_handler = signal_handler; - sigaction (SIGINT, &sigint_action, /* old = */ NULL); + sigaction(SIGINT, &sigint_action, /* old = */ NULL); sigterm_action.sa_handler = signal_handler; - sigaction (SIGTERM, &sigterm_action, /* old = */ NULL); - + sigaction(SIGTERM, &sigterm_action, /* old = */ NULL); - values_heap = c_heap_create (compare_time); - if (values_heap == NULL) - { - fprintf (stderr, "c_heap_create failed.\n"); - exit (EXIT_FAILURE); + values_heap = c_heap_create(compare_time); + if (values_heap == NULL) { + fprintf(stderr, "c_heap_create failed.\n"); + exit(EXIT_FAILURE); } - net = lcc_network_create (); - if (net == NULL) - { - fprintf (stderr, "lcc_network_create failed.\n"); - exit (EXIT_FAILURE); - } - else - { + net = lcc_network_create(); + if (net == NULL) { + fprintf(stderr, "lcc_network_create failed.\n"); + exit(EXIT_FAILURE); + } else { lcc_server_t *srv; - srv = lcc_server_create (net, conf_destination, conf_service); - if (srv == NULL) - { - fprintf (stderr, "lcc_server_create failed.\n"); - exit (EXIT_FAILURE); + srv = lcc_server_create(net, conf_destination, conf_service); + if (srv == NULL) { + fprintf(stderr, "lcc_server_create failed.\n"); + exit(EXIT_FAILURE); } - lcc_server_set_ttl (srv, 42); + lcc_server_set_ttl(srv, 42); #if 0 lcc_server_set_security_level (srv, ENCRYPT, "admin", "password1"); #endif } - fprintf (stdout, "Creating %i values ... ", conf_num_values); - fflush (stdout); - for (int i = 0; i < conf_num_values; i++) - { + fprintf(stdout, "Creating %i values ... ", conf_num_values); + fflush(stdout); + for (int i = 0; i < conf_num_values; i++) { lcc_value_list_t *vl; - vl = create_value_list (); - if (vl == NULL) - { - fprintf (stderr, "create_value_list failed.\n"); - exit (EXIT_FAILURE); + vl = create_value_list(); + if (vl == NULL) { + fprintf(stderr, "create_value_list failed.\n"); + exit(EXIT_FAILURE); } - c_heap_insert (values_heap, vl); + c_heap_insert(values_heap, vl); } - fprintf (stdout, "done\n"); + fprintf(stdout, "done\n"); last_time = 0; - while (loop) - { - lcc_value_list_t *vl = c_heap_get_root (values_heap); + while (loop) { + lcc_value_list_t *vl = c_heap_get_root(values_heap); if (vl == NULL) break; - if (vl->time != last_time) - { - printf ("%i values have been sent.\n", values_sent); + if (vl->time != last_time) { + printf("%i values have been sent.\n", values_sent); /* Check if we need to sleep */ - double now = dtime (); + double now = dtime(); - while (now < vl->time) - { + while (now < vl->time) { /* 1 / 100 second */ - struct timespec ts = { 0, 10000000 }; + struct timespec ts = {0, 10000000}; - ts.tv_sec = (time_t) now; - ts.tv_nsec = (long) ((now - ((double) ts.tv_sec)) * 1e9); + ts.tv_sec = (time_t)now; + ts.tv_nsec = (long)((now - ((double)ts.tv_sec)) * 1e9); - nanosleep (&ts, /* remaining = */ NULL); - now = dtime (); + nanosleep(&ts, /* remaining = */ NULL); + now = dtime(); if (!loop) break; @@ -429,26 +403,25 @@ int main (int argc, char **argv) /* {{{ */ last_time = vl->time; } - send_value (vl); + send_value(vl); values_sent++; - c_heap_insert (values_heap, vl); + c_heap_insert(values_heap, vl); } - fprintf (stdout, "Shutting down.\n"); - fflush (stdout); + fprintf(stdout, "Shutting down.\n"); + fflush(stdout); - while (42) - { - lcc_value_list_t *vl = c_heap_get_root (values_heap); + while (42) { + lcc_value_list_t *vl = c_heap_get_root(values_heap); if (vl == NULL) break; - destroy_value_list (vl); + destroy_value_list(vl); } - c_heap_destroy (values_heap); + c_heap_destroy(values_heap); - lcc_network_destroy (net); - exit (EXIT_SUCCESS); + lcc_network_destroy(net); + exit(EXIT_SUCCESS); } /* }}} int main */ /* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/collectdctl.c b/src/collectdctl.c index 8c884796..30d1cdc0 100644 --- a/src/collectdctl.c +++ b/src/collectdctl.c @@ -22,72 +22,72 @@ **/ #if HAVE_CONFIG_H -# include "config.h" +#include "config.h" #endif -#include -#include #include +#include #include #include +#include #include #include #if NAN_STATIC_DEFAULT -# include +#include /* #endif NAN_STATIC_DEFAULT*/ #elif NAN_STATIC_ISOC -# ifndef __USE_ISOC99 -# define DISABLE_ISOC99 1 -# define __USE_ISOC99 1 -# endif /* !defined(__USE_ISOC99) */ -# include -# if DISABLE_ISOC99 -# undef DISABLE_ISOC99 -# undef __USE_ISOC99 -# endif /* DISABLE_ISOC99 */ +#ifndef __USE_ISOC99 +#define DISABLE_ISOC99 1 +#define __USE_ISOC99 1 +#endif /* !defined(__USE_ISOC99) */ +#include +#if DISABLE_ISOC99 +#undef DISABLE_ISOC99 +#undef __USE_ISOC99 +#endif /* DISABLE_ISOC99 */ /* #endif NAN_STATIC_ISOC */ #elif NAN_ZERO_ZERO -# include -# ifdef NAN -# undef NAN -# endif -# define NAN (0.0 / 0.0) -# ifndef isnan -# define isnan(f) ((f) != (f)) -# endif /* !defined(isnan) */ -# ifndef isfinite -# define isfinite(f) (((f) - (f)) == 0.0) -# endif -# ifndef isinf -# define isinf(f) (!isfinite(f) && !isnan(f)) -# endif +#include +#ifdef NAN +#undef NAN +#endif +#define NAN (0.0 / 0.0) +#ifndef isnan +#define isnan(f) ((f) != (f)) +#endif /* !defined(isnan) */ +#ifndef isfinite +#define isfinite(f) (((f) - (f)) == 0.0) +#endif +#ifndef isinf +#define isinf(f) (!isfinite(f) && !isnan(f)) +#endif #endif /* NAN_ZERO_ZERO */ #include "libcollectdclient/collectd/client.h" #ifndef PREFIX -# define PREFIX "/opt/" PACKAGE_NAME +#define PREFIX "/opt/" PACKAGE_NAME #endif #ifndef LOCALSTATEDIR -# define LOCALSTATEDIR PREFIX "/var" +#define LOCALSTATEDIR PREFIX "/var" #endif -#define DEFAULT_SOCK LOCALSTATEDIR"/run/"PACKAGE_NAME"-unixsock" +#define DEFAULT_SOCK LOCALSTATEDIR "/run/" PACKAGE_NAME "-unixsock" extern char *optarg; -extern int optind; +extern int optind; -__attribute__((noreturn)) -static void exit_usage (const char *name, int status) { - fprintf ((status == 0) ? stdout : stderr, +__attribute__((noreturn)) static void exit_usage(const char *name, int status) { + fprintf( + (status == 0) ? stdout : stderr, "Usage: %s [options] [cmd options]\n\n" "Available options:\n" " -s Path to collectd's UNIX socket.\n" - " Default: "DEFAULT_SOCK"\n" + " Default: " DEFAULT_SOCK "\n" "\n -h Display this help and exit.\n" @@ -104,19 +104,20 @@ static void exit_usage (const char *name, int status) { " [/][-]/[-]\n\n" - "Hostname defaults to the local hostname if omitted (e.g., uptime/uptime).\n" + "Hostname defaults to the local hostname if omitted (e.g., " + "uptime/uptime).\n" "No error is returned if the specified identifier does not exist.\n" - "\n"PACKAGE_NAME" "PACKAGE_VERSION", http://collectd.org/\n" + "\n" PACKAGE_NAME " " PACKAGE_VERSION ", http://collectd.org/\n" "by Florian octo Forster \n" - "for contributions see `AUTHORS'\n" - , name); - exit (status); + "for contributions see `AUTHORS'\n", + name); + exit(status); } /* Count the number of occurrences of the character 'chr' * in the specified string. */ -static int count_chars (const char *str, char chr) { +static int count_chars(const char *str, char chr) { int count = 0; while (*str != '\0') { @@ -129,15 +130,14 @@ static int count_chars (const char *str, char chr) { return count; } /* count_chars */ -static int array_grow (void **array, size_t *array_len, size_t elem_size) -{ +static int array_grow(void **array, size_t *array_len, size_t elem_size) { void *tmp; - assert ((array != NULL) && (array_len != NULL)); + assert((array != NULL) && (array_len != NULL)); - tmp = realloc (*array, (*array_len + 1) * elem_size); + tmp = realloc(*array, (*array_len + 1) * elem_size); if (tmp == NULL) { - fprintf (stderr, "ERROR: Failed to allocate memory.\n"); + fprintf(stderr, "ERROR: Failed to allocate memory.\n"); return (-1); } @@ -146,93 +146,89 @@ static int array_grow (void **array, size_t *array_len, size_t elem_size) return (0); } /* array_grow */ -static int parse_identifier (lcc_connection_t *c, - const char *value, lcc_identifier_t *ident) -{ +static int parse_identifier(lcc_connection_t *c, const char *value, + lcc_identifier_t *ident) { char hostname[1024]; char ident_str[1024] = ""; - int n_slashes; + int n_slashes; int status; - n_slashes = count_chars (value, '/'); + n_slashes = count_chars(value, '/'); if (n_slashes == 1) { /* The user has omitted the hostname part of the identifier * (there is only one '/' in the identifier) * Let's add the local hostname */ - if (gethostname (hostname, sizeof (hostname)) != 0) { - fprintf (stderr, "ERROR: Failed to get local hostname: %s", - strerror (errno)); + if (gethostname(hostname, sizeof(hostname)) != 0) { + fprintf(stderr, "ERROR: Failed to get local hostname: %s", + strerror(errno)); return (-1); } - hostname[sizeof (hostname) - 1] = '\0'; + hostname[sizeof(hostname) - 1] = '\0'; - snprintf (ident_str, sizeof (ident_str), "%s/%s", hostname, value); + snprintf(ident_str, sizeof(ident_str), "%s/%s", hostname, value); + ident_str[sizeof(ident_str) - 1] = '\0'; + } else { + strncpy(ident_str, value, sizeof(ident_str)); ident_str[sizeof(ident_str) - 1] = '\0'; - } - else { - strncpy (ident_str, value, sizeof (ident_str)); - ident_str[sizeof (ident_str) - 1] = '\0'; } - status = lcc_string_to_identifier (c, ident, ident_str); + status = lcc_string_to_identifier(c, ident, ident_str); if (status != 0) { - fprintf (stderr, "ERROR: Failed to parse identifier ``%s'': %s.\n", - ident_str, lcc_strerror(c)); + fprintf(stderr, "ERROR: Failed to parse identifier ``%s'': %s.\n", + ident_str, lcc_strerror(c)); return (-1); } return (0); } /* parse_identifier */ -static int getval (lcc_connection_t *c, int argc, char **argv) -{ +static int getval(lcc_connection_t *c, int argc, char **argv) { lcc_identifier_t ident; - size_t ret_values_num = 0; - gauge_t *ret_values = NULL; - char **ret_values_names = NULL; + size_t ret_values_num = 0; + gauge_t *ret_values = NULL; + char **ret_values_names = NULL; int status; - assert (strcasecmp (argv[0], "getval") == 0); + assert(strcasecmp(argv[0], "getval") == 0); if (argc != 2) { - fprintf (stderr, "ERROR: getval: Missing identifier.\n"); + fprintf(stderr, "ERROR: getval: Missing identifier.\n"); return (-1); } - status = parse_identifier (c, argv[1], &ident); + status = parse_identifier(c, argv[1], &ident); if (status != 0) return (status); -#define BAIL_OUT(s) \ - do { \ - if (ret_values != NULL) \ - free (ret_values); \ - if (ret_values_names != NULL) { \ - for (size_t i = 0; i < ret_values_num; ++i) \ - free (ret_values_names[i]); \ - free (ret_values_names); \ - } \ - ret_values_num = 0; \ - return (s); \ +#define BAIL_OUT(s) \ + do { \ + if (ret_values != NULL) \ + free(ret_values); \ + if (ret_values_names != NULL) { \ + for (size_t i = 0; i < ret_values_num; ++i) \ + free(ret_values_names[i]); \ + free(ret_values_names); \ + } \ + ret_values_num = 0; \ + return (s); \ } while (0) - status = lcc_getval (c, &ident, - &ret_values_num, &ret_values, &ret_values_names); + status = + lcc_getval(c, &ident, &ret_values_num, &ret_values, &ret_values_names); if (status != 0) { - fprintf (stderr, "ERROR: %s\n", lcc_strerror (c)); - BAIL_OUT (-1); + fprintf(stderr, "ERROR: %s\n", lcc_strerror(c)); + BAIL_OUT(-1); } for (size_t i = 0; i < ret_values_num; ++i) - printf ("%s=%e\n", ret_values_names[i], ret_values[i]); - BAIL_OUT (0); + printf("%s=%e\n", ret_values_names[i], ret_values[i]); + BAIL_OUT(0); #undef BAIL_OUT } /* getval */ -static int flush (lcc_connection_t *c, int argc, char **argv) -{ +static int flush(lcc_connection_t *c, int argc, char **argv) { int timeout = -1; lcc_identifier_t *identifiers = NULL; @@ -243,241 +239,229 @@ static int flush (lcc_connection_t *c, int argc, char **argv) int status; - assert (strcasecmp (argv[0], "flush") == 0); - -#define BAIL_OUT(s) \ - do { \ - if (identifiers != NULL) \ - free (identifiers); \ - identifiers_num = 0; \ - if (plugins != NULL) \ - free (plugins); \ - plugins_num = 0; \ - return (s); \ + assert(strcasecmp(argv[0], "flush") == 0); + +#define BAIL_OUT(s) \ + do { \ + if (identifiers != NULL) \ + free(identifiers); \ + identifiers_num = 0; \ + if (plugins != NULL) \ + free(plugins); \ + plugins_num = 0; \ + return (s); \ } while (0) for (int i = 1; i < argc; ++i) { char *key, *value; - key = argv[i]; - value = strchr (argv[i], (int)'='); + key = argv[i]; + value = strchr(argv[i], (int)'='); - if (! value) { - fprintf (stderr, "ERROR: flush: Invalid option ``%s''.\n", argv[i]); - BAIL_OUT (-1); + if (!value) { + fprintf(stderr, "ERROR: flush: Invalid option ``%s''.\n", argv[i]); + BAIL_OUT(-1); } *value = '\0'; ++value; - if (strcasecmp (key, "timeout") == 0) { + if (strcasecmp(key, "timeout") == 0) { char *endptr = NULL; - timeout = (int) strtol (value, &endptr, 0); + timeout = (int)strtol(value, &endptr, 0); if (endptr == value) { - fprintf (stderr, "ERROR: Failed to parse timeout as number: %s.\n", - value); - BAIL_OUT (-1); + fprintf(stderr, "ERROR: Failed to parse timeout as number: %s.\n", + value); + BAIL_OUT(-1); + } else if ((endptr != NULL) && (*endptr != '\0')) { + fprintf(stderr, "WARNING: Ignoring trailing garbage after timeout: " + "%s.\n", + endptr); } - else if ((endptr != NULL) && (*endptr != '\0')) { - fprintf (stderr, "WARNING: Ignoring trailing garbage after timeout: " - "%s.\n", endptr); - } - } - else if (strcasecmp (key, "plugin") == 0) { - status = array_grow ((void *)&plugins, &plugins_num, - sizeof (*plugins)); + } else if (strcasecmp(key, "plugin") == 0) { + status = array_grow((void *)&plugins, &plugins_num, sizeof(*plugins)); if (status != 0) - BAIL_OUT (status); + BAIL_OUT(status); plugins[plugins_num - 1] = value; - } - else if (strcasecmp (key, "identifier") == 0) { - status = array_grow ((void *)&identifiers, &identifiers_num, - sizeof (*identifiers)); + } else if (strcasecmp(key, "identifier") == 0) { + status = array_grow((void *)&identifiers, &identifiers_num, + sizeof(*identifiers)); if (status != 0) - BAIL_OUT (status); + BAIL_OUT(status); - memset (identifiers + (identifiers_num - 1), 0, sizeof (*identifiers)); - status = parse_identifier (c, value, - identifiers + (identifiers_num - 1)); + memset(identifiers + (identifiers_num - 1), 0, sizeof(*identifiers)); + status = parse_identifier(c, value, identifiers + (identifiers_num - 1)); if (status != 0) - BAIL_OUT (status); - } - else { - fprintf (stderr, "ERROR: flush: Unknown option `%s'.\n", key); - BAIL_OUT (-1); + BAIL_OUT(status); + } else { + fprintf(stderr, "ERROR: flush: Unknown option `%s'.\n", key); + BAIL_OUT(-1); } } if (plugins_num == 0) { - status = array_grow ((void *)&plugins, &plugins_num, sizeof (*plugins)); + status = array_grow((void *)&plugins, &plugins_num, sizeof(*plugins)); if (status != 0) - BAIL_OUT (status); + BAIL_OUT(status); - assert (plugins_num == 1); + assert(plugins_num == 1); plugins[0] = NULL; } for (size_t i = 0; i < plugins_num; ++i) { if (identifiers_num == 0) { - status = lcc_flush (c, plugins[i], NULL, timeout); + status = lcc_flush(c, plugins[i], NULL, timeout); if (status != 0) - fprintf (stderr, "ERROR: Failed to flush plugin `%s': %s.\n", - (plugins[i] == NULL) ? "(all)" : plugins[i], lcc_strerror (c)); - } - else { + fprintf(stderr, "ERROR: Failed to flush plugin `%s': %s.\n", + (plugins[i] == NULL) ? "(all)" : plugins[i], lcc_strerror(c)); + } else { for (size_t j = 0; j < identifiers_num; ++j) { - status = lcc_flush (c, plugins[i], identifiers + j, timeout); + status = lcc_flush(c, plugins[i], identifiers + j, timeout); if (status != 0) { char id[1024]; - lcc_identifier_to_string (c, id, sizeof (id), identifiers + j); - fprintf (stderr, "ERROR: Failed to flush plugin `%s', " - "identifier `%s': %s.\n", - (plugins[i] == NULL) ? "(all)" : plugins[i], - id, lcc_strerror (c)); + lcc_identifier_to_string(c, id, sizeof(id), identifiers + j); + fprintf(stderr, "ERROR: Failed to flush plugin `%s', " + "identifier `%s': %s.\n", + (plugins[i] == NULL) ? "(all)" : plugins[i], id, + lcc_strerror(c)); } } } } - BAIL_OUT (0); + BAIL_OUT(0); #undef BAIL_OUT } /* flush */ -static int listval (lcc_connection_t *c, int argc, char **argv) -{ - lcc_identifier_t *ret_ident = NULL; - size_t ret_ident_num = 0; +static int listval(lcc_connection_t *c, int argc, char **argv) { + lcc_identifier_t *ret_ident = NULL; + size_t ret_ident_num = 0; int status; - assert (strcasecmp (argv[0], "listval") == 0); + assert(strcasecmp(argv[0], "listval") == 0); if (argc != 1) { - fprintf (stderr, "ERROR: listval: Does not accept any arguments.\n"); + fprintf(stderr, "ERROR: listval: Does not accept any arguments.\n"); return (-1); } -#define BAIL_OUT(s) \ - do { \ - if (ret_ident != NULL) \ - free (ret_ident); \ - ret_ident_num = 0; \ - return (s); \ +#define BAIL_OUT(s) \ + do { \ + if (ret_ident != NULL) \ + free(ret_ident); \ + ret_ident_num = 0; \ + return (s); \ } while (0) - status = lcc_listval (c, &ret_ident, &ret_ident_num); + status = lcc_listval(c, &ret_ident, &ret_ident_num); if (status != 0) { - fprintf (stderr, "ERROR: %s\n", lcc_strerror (c)); - BAIL_OUT (status); + fprintf(stderr, "ERROR: %s\n", lcc_strerror(c)); + BAIL_OUT(status); } for (size_t i = 0; i < ret_ident_num; ++i) { char id[1024]; - status = lcc_identifier_to_string (c, id, sizeof (id), ret_ident + i); + status = lcc_identifier_to_string(c, id, sizeof(id), ret_ident + i); if (status != 0) { - fprintf (stderr, "ERROR: listval: Failed to convert returned " - "identifier to a string: %s\n", lcc_strerror (c)); + fprintf(stderr, "ERROR: listval: Failed to convert returned " + "identifier to a string: %s\n", + lcc_strerror(c)); continue; } - printf ("%s\n", id); + printf("%s\n", id); } - BAIL_OUT (0); + BAIL_OUT(0); #undef BAIL_OUT } /* listval */ -static int putval (lcc_connection_t *c, int argc, char **argv) -{ +static int putval(lcc_connection_t *c, int argc, char **argv) { lcc_value_list_t vl = LCC_VALUE_LIST_INIT; /* 64 ought to be enough for anybody ;-) */ value_t values[64]; - int values_types[64]; - size_t values_len = 0; + int values_types[64]; + size_t values_len = 0; int status; - assert (strcasecmp (argv[0], "putval") == 0); + assert(strcasecmp(argv[0], "putval") == 0); if (argc < 3) { - fprintf (stderr, "ERROR: putval: Missing identifier " - "and/or value list.\n"); + fprintf(stderr, "ERROR: putval: Missing identifier " + "and/or value list.\n"); return (-1); } - vl.values = values; + vl.values = values; vl.values_types = values_types; - status = parse_identifier (c, argv[1], &vl.identifier); + status = parse_identifier(c, argv[1], &vl.identifier); if (status != 0) return (status); for (int i = 2; i < argc; ++i) { char *tmp; - tmp = strchr (argv[i], (int)'='); + tmp = strchr(argv[i], (int)'='); if (tmp != NULL) { /* option */ - char *key = argv[i]; + char *key = argv[i]; char *value = tmp; *value = '\0'; ++value; - if (strcasecmp (key, "interval") == 0) { + if (strcasecmp(key, "interval") == 0) { char *endptr; - vl.interval = strtol (value, &endptr, 0); + vl.interval = strtol(value, &endptr, 0); if (endptr == value) { - fprintf (stderr, "ERROR: Failed to parse interval as number: %s.\n", - value); + fprintf(stderr, "ERROR: Failed to parse interval as number: %s.\n", + value); return (-1); + } else if ((endptr != NULL) && (*endptr != '\0')) { + fprintf(stderr, "WARNING: Ignoring trailing garbage after " + "interval: %s.\n", + endptr); } - else if ((endptr != NULL) && (*endptr != '\0')) { - fprintf (stderr, "WARNING: Ignoring trailing garbage after " - "interval: %s.\n", endptr); - } - } - else { - fprintf (stderr, "ERROR: putval: Unknown option `%s'.\n", key); + } else { + fprintf(stderr, "ERROR: putval: Unknown option `%s'.\n", key); return (-1); } - } - else { /* value list */ + } else { /* value list */ char *value; - tmp = strchr (argv[i], (int)':'); + tmp = strchr(argv[i], (int)':'); if (tmp == NULL) { - fprintf (stderr, "ERROR: putval: Invalid value list: %s.\n", - argv[i]); + fprintf(stderr, "ERROR: putval: Invalid value list: %s.\n", argv[i]); return (-1); } *tmp = '\0'; ++tmp; - if (strcasecmp (argv[i], "N") == 0) { + if (strcasecmp(argv[i], "N") == 0) { vl.time = 0; - } - else { + } else { char *endptr; - vl.time = strtol (argv[i], &endptr, 0); + vl.time = strtol(argv[i], &endptr, 0); if (endptr == argv[i]) { - fprintf (stderr, "ERROR: Failed to parse time as number: %s.\n", - argv[i]); + fprintf(stderr, "ERROR: Failed to parse time as number: %s.\n", + argv[i]); return (-1); - } - else if ((endptr != NULL) && (*endptr != '\0')) { - fprintf (stderr, "ERROR: Garbage after time: %s.\n", endptr); + } else if ((endptr != NULL) && (*endptr != '\0')) { + fprintf(stderr, "ERROR: Garbage after time: %s.\n", endptr); return (-1); } } @@ -487,7 +471,7 @@ static int putval (lcc_connection_t *c, int argc, char **argv) while (value != NULL) { char *dot, *endptr; - tmp = strchr (value, (int)':'); + tmp = strchr(value, (int)':'); if (tmp != NULL) { *tmp = '\0'; @@ -498,55 +482,52 @@ static int putval (lcc_connection_t *c, int argc, char **argv) * much sense imho -- the server might have different types defined * anyway. Also, lcc uses the type information for formatting the * number only, so the real meaning does not matter. -tokkee */ - dot = strchr (value, (int)'.'); + dot = strchr(value, (int)'.'); endptr = NULL; - if (strcasecmp (value, "U") == 0) { + if (strcasecmp(value, "U") == 0) { values[values_len].gauge = NAN; values_types[values_len] = LCC_TYPE_GAUGE; - } - else if (dot) { /* floating point value */ - values[values_len].gauge = strtod (value, &endptr); + } else if (dot) { /* floating point value */ + values[values_len].gauge = strtod(value, &endptr); values_types[values_len] = LCC_TYPE_GAUGE; - } - else { /* integer */ - values[values_len].counter = (counter_t) strtoull (value, &endptr, 0); + } else { /* integer */ + values[values_len].counter = (counter_t)strtoull(value, &endptr, 0); values_types[values_len] = LCC_TYPE_COUNTER; } ++values_len; if (endptr == value) { - fprintf (stderr, "ERROR: Failed to parse value as number: %s.\n", - argv[i]); + fprintf(stderr, "ERROR: Failed to parse value as number: %s.\n", + argv[i]); return (-1); - } - else if ((endptr != NULL) && (*endptr != '\0')) { - fprintf (stderr, "ERROR: Garbage after value: %s.\n", endptr); + } else if ((endptr != NULL) && (*endptr != '\0')) { + fprintf(stderr, "ERROR: Garbage after value: %s.\n", endptr); return (-1); } value = tmp; } - assert (values_len >= 1); + assert(values_len >= 1); vl.values_len = values_len; - status = lcc_putval (c, &vl); + status = lcc_putval(c, &vl); if (status != 0) { - fprintf (stderr, "ERROR: %s\n", lcc_strerror (c)); + fprintf(stderr, "ERROR: %s\n", lcc_strerror(c)); return (-1); } } } if (values_len == 0) { - fprintf (stderr, "ERROR: putval: Missing value list(s).\n"); + fprintf(stderr, "ERROR: putval: Missing value list(s).\n"); return (-1); } return (0); } /* putval */ -int main (int argc, char **argv) { - char address[1024] = "unix:"DEFAULT_SOCK; +int main(int argc, char **argv) { + char address[1024] = "unix:" DEFAULT_SOCK; lcc_connection_t *c; @@ -555,50 +536,50 @@ int main (int argc, char **argv) { while (42) { int opt; - opt = getopt (argc, argv, "s:h"); + opt = getopt(argc, argv, "s:h"); if (opt == -1) break; switch (opt) { - case 's': - snprintf (address, sizeof (address), "unix:%s", optarg); - address[sizeof (address) - 1] = '\0'; - break; - case 'h': - exit_usage (argv[0], 0); - default: - exit_usage (argv[0], 1); + case 's': + snprintf(address, sizeof(address), "unix:%s", optarg); + address[sizeof(address) - 1] = '\0'; + break; + case 'h': + exit_usage(argv[0], 0); + default: + exit_usage(argv[0], 1); } } if (optind >= argc) { - fprintf (stderr, "%s: missing command\n", argv[0]); - exit_usage (argv[0], 1); + fprintf(stderr, "%s: missing command\n", argv[0]); + exit_usage(argv[0], 1); } c = NULL; - status = lcc_connect (address, &c); + status = lcc_connect(address, &c); if (status != 0) { - fprintf (stderr, "ERROR: Failed to connect to daemon at %s: %s.\n", - address, strerror (errno)); + fprintf(stderr, "ERROR: Failed to connect to daemon at %s: %s.\n", address, + strerror(errno)); return (1); } - if (strcasecmp (argv[optind], "getval") == 0) - status = getval (c, argc - optind, argv + optind); - else if (strcasecmp (argv[optind], "flush") == 0) - status = flush (c, argc - optind, argv + optind); - else if (strcasecmp (argv[optind], "listval") == 0) - status = listval (c, argc - optind, argv + optind); - else if (strcasecmp (argv[optind], "putval") == 0) - status = putval (c, argc - optind, argv + optind); + if (strcasecmp(argv[optind], "getval") == 0) + status = getval(c, argc - optind, argv + optind); + else if (strcasecmp(argv[optind], "flush") == 0) + status = flush(c, argc - optind, argv + optind); + else if (strcasecmp(argv[optind], "listval") == 0) + status = listval(c, argc - optind, argv + optind); + else if (strcasecmp(argv[optind], "putval") == 0) + status = putval(c, argc - optind, argv + optind); else { - fprintf (stderr, "%s: invalid command: %s\n", argv[0], argv[optind]); + fprintf(stderr, "%s: invalid command: %s\n", argv[0], argv[optind]); return (1); } - LCC_DESTROY (c); + LCC_DESTROY(c); if (status != 0) return (status); @@ -606,4 +587,3 @@ int main (int argc, char **argv) { } /* main */ /* vim: set sw=2 ts=2 tw=78 expandtab : */ - diff --git a/src/collectdmon.c b/src/collectdmon.c index 61daa58c..9040f8d9 100644 --- a/src/collectdmon.c +++ b/src/collectdmon.c @@ -25,7 +25,7 @@ **/ #if !defined(__GNUC__) || !__GNUC__ -# define __attribute__(x) /**/ +#define __attribute__(x) /**/ #endif #include "config.h" @@ -46,9 +46,9 @@ #include #include +#include #include #include -#include #include #include @@ -56,348 +56,335 @@ #include #ifndef PREFIX -# define PREFIX "/opt/" PACKAGE_NAME +#define PREFIX "/opt/" PACKAGE_NAME #endif #ifndef LOCALSTATEDIR -# define LOCALSTATEDIR PREFIX "/var" +#define LOCALSTATEDIR PREFIX "/var" #endif #ifndef COLLECTDMON_PIDFILE -# define COLLECTDMON_PIDFILE LOCALSTATEDIR"/run/collectdmon.pid" +#define COLLECTDMON_PIDFILE LOCALSTATEDIR "/run/collectdmon.pid" #endif /* ! COLLECTDMON_PIDFILE */ #ifndef WCOREDUMP -# define WCOREDUMP(s) 0 +#define WCOREDUMP(s) 0 #endif /* ! WCOREDUMP */ -static int loop = 0; +static int loop = 0; static int restart = 0; -static const char *pidfile = NULL; -static pid_t collectd_pid = 0; +static const char *pidfile = NULL; +static pid_t collectd_pid = 0; -__attribute__((noreturn)) -static void exit_usage (const char *name) -{ - printf ("Usage: %s [-- ]\n" +__attribute__((noreturn)) static void exit_usage(const char *name) { + printf("Usage: %s [-- ]\n" - "\nAvailable options:\n" - " -h Display this help and exit.\n" - " -c Path to the collectd binary.\n" - " -P PID-file.\n" + "\nAvailable options:\n" + " -h Display this help and exit.\n" + " -c Path to the collectd binary.\n" + " -P PID-file.\n" - "\nFor see collectd.conf(5).\n" + "\nFor see collectd.conf(5).\n" - "\n"PACKAGE_NAME" "PACKAGE_VERSION", http://collectd.org/\n" - "by Florian octo Forster \n" - "for contributions see `AUTHORS'\n", name); - exit (0); + "\n" PACKAGE_NAME " " PACKAGE_VERSION ", http://collectd.org/\n" + "by Florian octo Forster \n" + "for contributions see `AUTHORS'\n", + name); + exit(0); } /* exit_usage */ -static int pidfile_create (void) -{ - FILE *file = NULL; +static int pidfile_create(void) { + FILE *file = NULL; - if (NULL == pidfile) - pidfile = COLLECTDMON_PIDFILE; + if (NULL == pidfile) + pidfile = COLLECTDMON_PIDFILE; - if (NULL == (file = fopen (pidfile, "w"))) { - syslog (LOG_ERR, "Error: couldn't open PID-file (%s) for writing: %s", - pidfile, strerror (errno)); - return -1; - } + if (NULL == (file = fopen(pidfile, "w"))) { + syslog(LOG_ERR, "Error: couldn't open PID-file (%s) for writing: %s", + pidfile, strerror(errno)); + return -1; + } - fprintf (file, "%i\n", (int)getpid ()); - fclose (file); - return 0; + fprintf(file, "%i\n", (int)getpid()); + fclose(file); + return 0; } /* pidfile_create */ -static int pidfile_delete (void) -{ - assert (NULL != pidfile); +static int pidfile_delete(void) { + assert(NULL != pidfile); - if (0 != unlink (pidfile)) { - syslog (LOG_ERR, "Error: couldn't delete PID-file (%s): %s", - pidfile, strerror (errno)); - return -1; - } - return 0; + if (0 != unlink(pidfile)) { + syslog(LOG_ERR, "Error: couldn't delete PID-file (%s): %s", pidfile, + strerror(errno)); + return -1; + } + return 0; } /* pidfile_remove */ -static int daemonize (void) -{ - struct rlimit rl; - int dev_null; - - pid_t pid = 0; - int i = 0; - - if (0 != chdir ("/")) { - fprintf (stderr, "Error: chdir() failed: %s\n", strerror (errno)); - return -1; - } - - if (0 != getrlimit (RLIMIT_NOFILE, &rl)) { - fprintf (stderr, "Error: getrlimit() failed: %s\n", strerror (errno)); - return -1; - } - - if (0 > (pid = fork ())) { - fprintf (stderr, "Error: fork() failed: %s\n", strerror (errno)); - return -1; - } - else if (pid != 0) { - exit (0); - } - - if (0 != pidfile_create ()) - return -1; - - setsid (); - - if (RLIM_INFINITY == rl.rlim_max) - rl.rlim_max = 1024; - - for (i = 0; i < (int)rl.rlim_max; ++i) - close (i); - - dev_null = open ("/dev/null", O_RDWR); - if (dev_null == -1) { - syslog (LOG_ERR, "Error: couldn't open /dev/null: %s", strerror (errno)); - return -1; - } - - if (dup2 (dev_null, STDIN_FILENO) == -1) { - close (dev_null); - syslog (LOG_ERR, "Error: couldn't connect STDIN to /dev/null: %s", strerror (errno)); - return -1; - } - - if (dup2 (dev_null, STDOUT_FILENO) == -1) { - close (dev_null); - syslog (LOG_ERR, "Error: couldn't connect STDOUT to /dev/null: %s", strerror (errno)); - return -1; - } - - if (dup2 (dev_null, STDERR_FILENO) == -1) { - close (dev_null); - syslog (LOG_ERR, "Error: couldn't connect STDERR to /dev/null: %s", strerror (errno)); - return -1; - } - - if ((dev_null != STDIN_FILENO) && (dev_null != STDOUT_FILENO) && (dev_null != STDERR_FILENO)) - close (dev_null); - - return 0; +static int daemonize(void) { + struct rlimit rl; + int dev_null; + + pid_t pid = 0; + int i = 0; + + if (0 != chdir("/")) { + fprintf(stderr, "Error: chdir() failed: %s\n", strerror(errno)); + return -1; + } + + if (0 != getrlimit(RLIMIT_NOFILE, &rl)) { + fprintf(stderr, "Error: getrlimit() failed: %s\n", strerror(errno)); + return -1; + } + + if (0 > (pid = fork())) { + fprintf(stderr, "Error: fork() failed: %s\n", strerror(errno)); + return -1; + } else if (pid != 0) { + exit(0); + } + + if (0 != pidfile_create()) + return -1; + + setsid(); + + if (RLIM_INFINITY == rl.rlim_max) + rl.rlim_max = 1024; + + for (i = 0; i < (int)rl.rlim_max; ++i) + close(i); + + dev_null = open("/dev/null", O_RDWR); + if (dev_null == -1) { + syslog(LOG_ERR, "Error: couldn't open /dev/null: %s", strerror(errno)); + return -1; + } + + if (dup2(dev_null, STDIN_FILENO) == -1) { + close(dev_null); + syslog(LOG_ERR, "Error: couldn't connect STDIN to /dev/null: %s", + strerror(errno)); + return -1; + } + + if (dup2(dev_null, STDOUT_FILENO) == -1) { + close(dev_null); + syslog(LOG_ERR, "Error: couldn't connect STDOUT to /dev/null: %s", + strerror(errno)); + return -1; + } + + if (dup2(dev_null, STDERR_FILENO) == -1) { + close(dev_null); + syslog(LOG_ERR, "Error: couldn't connect STDERR to /dev/null: %s", + strerror(errno)); + return -1; + } + + if ((dev_null != STDIN_FILENO) && (dev_null != STDOUT_FILENO) && + (dev_null != STDERR_FILENO)) + close(dev_null); + + return 0; } /* daemonize */ -static int collectd_start (char **argv) -{ - pid_t pid = 0; - - if (0 > (pid = fork ())) { - syslog (LOG_ERR, "Error: fork() failed: %s", strerror (errno)); - return -1; - } - else if (pid != 0) { - collectd_pid = pid; - return 0; - } - - execvp (argv[0], argv); - syslog (LOG_ERR, "Error: execvp(%s) failed: %s", - argv[0], strerror (errno)); - exit (-1); +static int collectd_start(char **argv) { + pid_t pid = 0; + + if (0 > (pid = fork())) { + syslog(LOG_ERR, "Error: fork() failed: %s", strerror(errno)); + return -1; + } else if (pid != 0) { + collectd_pid = pid; + return 0; + } + + execvp(argv[0], argv); + syslog(LOG_ERR, "Error: execvp(%s) failed: %s", argv[0], strerror(errno)); + exit(-1); } /* collectd_start */ -static int collectd_stop (void) -{ - if (0 == collectd_pid) - return 0; +static int collectd_stop(void) { + if (0 == collectd_pid) + return 0; - if (0 != kill (collectd_pid, SIGTERM)) { - syslog (LOG_ERR, "Error: kill() failed: %s", strerror (errno)); - return -1; - } - return 0; + if (0 != kill(collectd_pid, SIGTERM)) { + syslog(LOG_ERR, "Error: kill() failed: %s", strerror(errno)); + return -1; + } + return 0; } /* collectd_stop */ -static void sig_int_term_handler (int __attribute__((unused)) signo) -{ - ++loop; - return; +static void sig_int_term_handler(int __attribute__((unused)) signo) { + ++loop; + return; } /* sig_int_term_handler */ -static void sig_hup_handler (int __attribute__((unused)) signo) -{ - ++restart; - return; +static void sig_hup_handler(int __attribute__((unused)) signo) { + ++restart; + return; } /* sig_hup_handler */ -static void log_status (int status) -{ - if (WIFEXITED (status)) { - if (0 == WEXITSTATUS (status)) - syslog (LOG_INFO, "Info: collectd terminated with exit status %i", - WEXITSTATUS (status)); - else - syslog (LOG_WARNING, - "Warning: collectd terminated with exit status %i", - WEXITSTATUS (status)); - } - else if (WIFSIGNALED (status)) { - syslog (LOG_WARNING, "Warning: collectd was terminated by signal %i%s", - WTERMSIG (status), WCOREDUMP (status) ? " (core dumped)" : ""); - } - return; +static void log_status(int status) { + if (WIFEXITED(status)) { + if (0 == WEXITSTATUS(status)) + syslog(LOG_INFO, "Info: collectd terminated with exit status %i", + WEXITSTATUS(status)); + else + syslog(LOG_WARNING, "Warning: collectd terminated with exit status %i", + WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + syslog(LOG_WARNING, "Warning: collectd was terminated by signal %i%s", + WTERMSIG(status), WCOREDUMP(status) ? " (core dumped)" : ""); + } + return; } /* log_status */ -static void check_respawn (void) -{ - time_t t = time (NULL); +static void check_respawn(void) { + time_t t = time(NULL); - static time_t timestamp = 0; - static int counter = 0; + static time_t timestamp = 0; + static int counter = 0; - if ((t - 120) < timestamp) - ++counter; - else { - timestamp = t; - counter = 0; - } + if ((t - 120) < timestamp) + ++counter; + else { + timestamp = t; + counter = 0; + } - if (10 < counter) { - unsigned int time_left = 300; + if (10 < counter) { + unsigned int time_left = 300; - syslog (LOG_ERR, "Error: collectd is respawning too fast - " - "disabled for %i seconds", time_left); + syslog(LOG_ERR, "Error: collectd is respawning too fast - " + "disabled for %i seconds", + time_left); - while ((0 < (time_left = sleep (time_left))) && (0 == loop)); - } - return; + while ((0 < (time_left = sleep(time_left))) && (0 == loop)) + ; + } + return; } /* check_respawn */ -int main (int argc, char **argv) -{ - int collectd_argc = 0; - char *collectd = NULL; - char **collectd_argv = NULL; +int main(int argc, char **argv) { + int collectd_argc = 0; + char *collectd = NULL; + char **collectd_argv = NULL; + + struct sigaction sa; + + int i = 0; + + /* parse command line options */ + while (42) { + int c = getopt(argc, argv, "hc:P:"); + + if (-1 == c) + break; + + switch (c) { + case 'c': + collectd = optarg; + break; + case 'P': + pidfile = optarg; + break; + case 'h': + default: + exit_usage(argv[0]); + } + } + + for (i = optind; i < argc; ++i) + if (0 == strcmp(argv[i], "-f")) + break; + + /* i < argc => -f already present */ + collectd_argc = 1 + argc - optind + ((i < argc) ? 0 : 1); + collectd_argv = (char **)calloc(collectd_argc + 1, sizeof(char *)); + + if (NULL == collectd_argv) { + fprintf(stderr, "Out of memory."); + return 3; + } + + collectd_argv[0] = (NULL == collectd) ? "collectd" : collectd; + + if (i == argc) + collectd_argv[collectd_argc - 1] = "-f"; - struct sigaction sa; - - int i = 0; - - /* parse command line options */ - while (42) { - int c = getopt (argc, argv, "hc:P:"); + for (i = optind; i < argc; ++i) + collectd_argv[i - optind + 1] = argv[i]; - if (-1 == c) - break; + collectd_argv[collectd_argc] = NULL; - switch (c) { - case 'c': - collectd = optarg; - break; - case 'P': - pidfile = optarg; - break; - case 'h': - default: - exit_usage (argv[0]); - } - } - - for (i = optind; i < argc; ++i) - if (0 == strcmp (argv[i], "-f")) - break; - - /* i < argc => -f already present */ - collectd_argc = 1 + argc - optind + ((i < argc) ? 0 : 1); - collectd_argv = (char **)calloc (collectd_argc + 1, sizeof (char *)); - - if (NULL == collectd_argv) { - fprintf (stderr, "Out of memory."); - return 3; - } - - collectd_argv[0] = (NULL == collectd) ? "collectd" : collectd; - - if (i == argc) - collectd_argv[collectd_argc - 1] = "-f"; - - for (i = optind; i < argc; ++i) - collectd_argv[i - optind + 1] = argv[i]; - - collectd_argv[collectd_argc] = NULL; - - openlog ("collectdmon", LOG_CONS | LOG_PID, LOG_DAEMON); - - if (-1 == daemonize ()) - { - free (collectd_argv); - return 1; - } - - sa.sa_handler = sig_int_term_handler; - sa.sa_flags = 0; - sigemptyset (&sa.sa_mask); - - if (0 != sigaction (SIGINT, &sa, NULL)) { - syslog (LOG_ERR, "Error: sigaction() failed: %s", strerror (errno)); - free (collectd_argv); - return 1; - } - - if (0 != sigaction (SIGTERM, &sa, NULL)) { - syslog (LOG_ERR, "Error: sigaction() failed: %s", strerror (errno)); - free (collectd_argv); - return 1; - } - - sa.sa_handler = sig_hup_handler; - - if (0 != sigaction (SIGHUP, &sa, NULL)) { - syslog (LOG_ERR, "Error: sigaction() failed: %s", strerror (errno)); - free (collectd_argv); - return 1; - } - - while (0 == loop) { - int status = 0; - - if (0 != collectd_start (collectd_argv)) { - syslog (LOG_ERR, "Error: failed to start collectd."); - break; - } - - assert (0 < collectd_pid); - while ((collectd_pid != waitpid (collectd_pid, &status, 0)) - && (EINTR == errno)) - if ((0 != loop) || (0 != restart)) - collectd_stop (); - - collectd_pid = 0; - - log_status (status); - check_respawn (); - - if (0 != restart) { - syslog (LOG_INFO, "Info: restarting collectd"); - restart = 0; - } - else if (0 == loop) - syslog (LOG_WARNING, "Warning: restarting collectd"); - } - - syslog (LOG_INFO, "Info: shutting down collectdmon"); - - pidfile_delete (); - closelog (); - - free (collectd_argv); - return 0; + openlog("collectdmon", LOG_CONS | LOG_PID, LOG_DAEMON); + + if (-1 == daemonize()) { + free(collectd_argv); + return 1; + } + + sa.sa_handler = sig_int_term_handler; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + + if (0 != sigaction(SIGINT, &sa, NULL)) { + syslog(LOG_ERR, "Error: sigaction() failed: %s", strerror(errno)); + free(collectd_argv); + return 1; + } + + if (0 != sigaction(SIGTERM, &sa, NULL)) { + syslog(LOG_ERR, "Error: sigaction() failed: %s", strerror(errno)); + free(collectd_argv); + return 1; + } + + sa.sa_handler = sig_hup_handler; + + if (0 != sigaction(SIGHUP, &sa, NULL)) { + syslog(LOG_ERR, "Error: sigaction() failed: %s", strerror(errno)); + free(collectd_argv); + return 1; + } + + while (0 == loop) { + int status = 0; + + if (0 != collectd_start(collectd_argv)) { + syslog(LOG_ERR, "Error: failed to start collectd."); + break; + } + + assert(0 < collectd_pid); + while ((collectd_pid != waitpid(collectd_pid, &status, 0)) && + (EINTR == errno)) + if ((0 != loop) || (0 != restart)) + collectd_stop(); + + collectd_pid = 0; + + log_status(status); + check_respawn(); + + if (0 != restart) { + syslog(LOG_INFO, "Info: restarting collectd"); + restart = 0; + } else if (0 == loop) + syslog(LOG_WARNING, "Warning: restarting collectd"); + } + + syslog(LOG_INFO, "Info: shutting down collectdmon"); + + pidfile_delete(); + closelog(); + + free(collectd_argv); + return 0; } /* main */ /* vim: set sw=4 ts=4 tw=78 noexpandtab : */ - diff --git a/src/conntrack.c b/src/conntrack.c index 26f62786..8a9200dd 100644 --- a/src/conntrack.c +++ b/src/conntrack.c @@ -27,7 +27,7 @@ #include "plugin.h" #if !KERNEL_LINUX -# error "No applicable input method." +#error "No applicable input method." #endif #define CONNTRACK_FILE "/proc/sys/net/netfilter/nf_conntrack_count" @@ -35,71 +35,61 @@ #define CONNTRACK_FILE_OLD "/proc/sys/net/ipv4/netfilter/ip_conntrack_count" #define CONNTRACK_MAX_FILE_OLD "/proc/sys/net/ipv4/netfilter/ip_conntrack_max" -static const char *config_keys[] = -{ - "OldFiles" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"OldFiles"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); /* Each table/chain combo that will be queried goes into this list */ static int old_files = 0; -static int conntrack_config(const char *key, const char *value) -{ - if (strcmp(key, "OldFiles") == 0) - old_files = 1; +static int conntrack_config(const char *key, const char *value) { + if (strcmp(key, "OldFiles") == 0) + old_files = 1; - return 0; + return 0; } -static void conntrack_submit (const char *type, const char *type_instance, - value_t conntrack) -{ - value_list_t vl = VALUE_LIST_INIT; +static void conntrack_submit(const char *type, const char *type_instance, + value_t conntrack) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &conntrack; - vl.values_len = 1; - sstrncpy (vl.plugin, "conntrack", sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof (vl.type)); - if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, - sizeof (vl.type_instance)); + vl.values = &conntrack; + vl.values_len = 1; + sstrncpy(vl.plugin, "conntrack", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); + if (type_instance != NULL) + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* static void conntrack_submit */ -static int conntrack_read (void) -{ - value_t conntrack, conntrack_max, conntrack_pct; +static int conntrack_read(void) { + value_t conntrack, conntrack_max, conntrack_pct; - char const *path = old_files ? CONNTRACK_FILE_OLD : CONNTRACK_FILE; - if (parse_value_file (path, &conntrack, DS_TYPE_GAUGE) != 0) - { - ERROR ("conntrack plugin: Reading \"%s\" failed.", path); - return (-1); - } + char const *path = old_files ? CONNTRACK_FILE_OLD : CONNTRACK_FILE; + if (parse_value_file(path, &conntrack, DS_TYPE_GAUGE) != 0) { + ERROR("conntrack plugin: Reading \"%s\" failed.", path); + return (-1); + } - path = old_files ? CONNTRACK_MAX_FILE_OLD : CONNTRACK_MAX_FILE; - if (parse_value_file (path, &conntrack_max, DS_TYPE_GAUGE) != 0) - { - ERROR ("conntrack plugin: Reading \"%s\" failed.", path); - return (-1); - } + path = old_files ? CONNTRACK_MAX_FILE_OLD : CONNTRACK_MAX_FILE; + if (parse_value_file(path, &conntrack_max, DS_TYPE_GAUGE) != 0) { + ERROR("conntrack plugin: Reading \"%s\" failed.", path); + return (-1); + } - conntrack_pct.gauge = (conntrack.gauge / conntrack_max.gauge) * 100; + conntrack_pct.gauge = (conntrack.gauge / conntrack_max.gauge) * 100; - conntrack_submit ("conntrack", NULL, conntrack); - conntrack_submit ("conntrack", "max", conntrack_max); - conntrack_submit ("percent", "used", conntrack_pct); + conntrack_submit("conntrack", NULL, conntrack); + conntrack_submit("conntrack", "max", conntrack_max); + conntrack_submit("percent", "used", conntrack_pct); - return (0); + return (0); } /* static int conntrack_read */ -void module_register (void) -{ - plugin_register_config ("conntrack", conntrack_config, - config_keys, config_keys_num); - plugin_register_read ("conntrack", conntrack_read); +void module_register(void) { + plugin_register_config("conntrack", conntrack_config, config_keys, + config_keys_num); + plugin_register_read("conntrack", conntrack_read); } /* void module_register */ diff --git a/src/contextswitch.c b/src/contextswitch.c index 834fbd74..1d73f041 100644 --- a/src/contextswitch.c +++ b/src/contextswitch.c @@ -27,7 +27,7 @@ #include "plugin.h" #ifdef HAVE_SYS_SYSCTL_H -# include +#include #endif #if HAVE_SYSCTLBYNAME @@ -39,113 +39,106 @@ /* #endif KERNEL_LINUX */ #elif HAVE_PERFSTAT -# include -# include +#include +#include /* #endif HAVE_PERFSTAT */ #else -# error "No applicable input method." +#error "No applicable input method." #endif -static void cs_submit (derive_t context_switches) -{ - value_list_t vl = VALUE_LIST_INIT; +static void cs_submit(derive_t context_switches) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .derive = context_switches }; - vl.values_len = 1; - sstrncpy (vl.plugin, "contextswitch", sizeof (vl.plugin)); - sstrncpy (vl.type, "contextswitch", sizeof (vl.type)); + vl.values = &(value_t){.derive = context_switches}; + vl.values_len = 1; + sstrncpy(vl.plugin, "contextswitch", sizeof(vl.plugin)); + sstrncpy(vl.type, "contextswitch", sizeof(vl.type)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static int cs_read (void) -{ +static int cs_read(void) { #if HAVE_SYSCTLBYNAME - int value = 0; - size_t value_len = sizeof (value); - int status; - - status = sysctlbyname ("vm.stats.sys.v_swtch", - &value, &value_len, - /* new pointer = */ NULL, /* new length = */ 0); - if (status != 0) - { - ERROR("contextswitch plugin: sysctlbyname " - "(vm.stats.sys.v_swtch) failed"); - return (-1); - } - - cs_submit (value); + int value = 0; + size_t value_len = sizeof(value); + int status; + + status = sysctlbyname("vm.stats.sys.v_swtch", &value, &value_len, + /* new pointer = */ NULL, /* new length = */ 0); + if (status != 0) { + ERROR("contextswitch plugin: sysctlbyname " + "(vm.stats.sys.v_swtch) failed"); + return (-1); + } + + cs_submit(value); /* #endif HAVE_SYSCTLBYNAME */ #elif KERNEL_LINUX - FILE *fh; - char buffer[64]; - int numfields; - char *fields[3]; - derive_t result = 0; - int status = -2; - - fh = fopen ("/proc/stat", "r"); - if (fh == NULL) { - ERROR ("contextswitch plugin: unable to open /proc/stat: %s", - sstrerror (errno, buffer, sizeof (buffer))); - return (-1); - } - - while (fgets(buffer, sizeof(buffer), fh) != NULL) - { - char *endptr; - - numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE (fields)); - if (numfields != 2) - continue; - - if (strcmp("ctxt", fields[0]) != 0) - continue; - - errno = 0; - endptr = NULL; - result = (derive_t) strtoll (fields[1], &endptr, /* base = */ 10); - if ((endptr == fields[1]) || (errno != 0)) { - ERROR ("contextswitch plugin: Cannot parse ctxt value: %s", - fields[1]); - status = -1; - break; - } - - cs_submit(result); - status = 0; - break; - } - fclose(fh); - - if (status == -2) - ERROR ("contextswitch plugin: Unable to find context switch value."); + FILE *fh; + char buffer[64]; + int numfields; + char *fields[3]; + derive_t result = 0; + int status = -2; + + fh = fopen("/proc/stat", "r"); + if (fh == NULL) { + ERROR("contextswitch plugin: unable to open /proc/stat: %s", + sstrerror(errno, buffer, sizeof(buffer))); + return (-1); + } + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + char *endptr; + + numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + if (numfields != 2) + continue; + + if (strcmp("ctxt", fields[0]) != 0) + continue; + + errno = 0; + endptr = NULL; + result = (derive_t)strtoll(fields[1], &endptr, /* base = */ 10); + if ((endptr == fields[1]) || (errno != 0)) { + ERROR("contextswitch plugin: Cannot parse ctxt value: %s", fields[1]); + status = -1; + break; + } + + cs_submit(result); + status = 0; + break; + } + fclose(fh); + + if (status == -2) + ERROR("contextswitch plugin: Unable to find context switch value."); /* #endif KERNEL_LINUX */ #elif HAVE_PERFSTAT - int status = 0; - perfstat_cpu_total_t perfcputotal; - - status = perfstat_cpu_total(NULL, &perfcputotal, sizeof(perfstat_cpu_total_t), 1); - if (status < 0) - { - char errbuf[1024]; - ERROR ("contextswitch plugin: perfstat_cpu_total: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - cs_submit(perfcputotal.pswitch); - status = 0; + int status = 0; + perfstat_cpu_total_t perfcputotal; + + status = + perfstat_cpu_total(NULL, &perfcputotal, sizeof(perfstat_cpu_total_t), 1); + if (status < 0) { + char errbuf[1024]; + ERROR("contextswitch plugin: perfstat_cpu_total: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + cs_submit(perfcputotal.pswitch); + status = 0; #endif /* defined(HAVE_PERFSTAT) */ - return status; + return status; } -void module_register (void) -{ - plugin_register_read ("contextswitch", cs_read); +void module_register(void) { + plugin_register_read("contextswitch", cs_read); } /* void module_register */ diff --git a/src/cpu.c b/src/cpu.c index 36c49720..9091fef9 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -33,60 +33,61 @@ #include "plugin.h" #ifdef HAVE_MACH_KERN_RETURN_H -# include +#include #endif #ifdef HAVE_MACH_MACH_INIT_H -# include +#include #endif #ifdef HAVE_MACH_HOST_PRIV_H -# include +#include #endif #if HAVE_MACH_MACH_ERROR_H -# include +#include #endif #ifdef HAVE_MACH_PROCESSOR_INFO_H -# include +#include #endif #ifdef HAVE_MACH_PROCESSOR_H -# include +#include #endif #ifdef HAVE_MACH_VM_MAP_H -# include +#include #endif #ifdef HAVE_LIBKSTAT -# include +#include #endif /* HAVE_LIBKSTAT */ -#if (defined(HAVE_SYSCTL) && HAVE_SYSCTL) \ - || (defined(HAVE_SYSCTLBYNAME) && HAVE_SYSCTLBYNAME) -# ifdef HAVE_SYS_SYSCTL_H -# include -# endif - -# ifdef HAVE_SYS_DKSTAT_H -# include -# endif - -# if !defined(CP_USER) || !defined(CP_NICE) || !defined(CP_SYS) || !defined(CP_INTR) || !defined(CP_IDLE) || !defined(CPUSTATES) -# define CP_USER 0 -# define CP_NICE 1 -# define CP_SYS 2 -# define CP_INTR 3 -# define CP_IDLE 4 -# define CPUSTATES 5 -# endif +#if (defined(HAVE_SYSCTL) && HAVE_SYSCTL) || \ + (defined(HAVE_SYSCTLBYNAME) && HAVE_SYSCTLBYNAME) +#ifdef HAVE_SYS_SYSCTL_H +#include +#endif + +#ifdef HAVE_SYS_DKSTAT_H +#include +#endif + +#if !defined(CP_USER) || !defined(CP_NICE) || !defined(CP_SYS) || \ + !defined(CP_INTR) || !defined(CP_IDLE) || !defined(CPUSTATES) +#define CP_USER 0 +#define CP_NICE 1 +#define CP_SYS 2 +#define CP_INTR 3 +#define CP_IDLE 4 +#define CPUSTATES 5 +#endif #endif /* HAVE_SYSCTL || HAVE_SYSCTLBYNAME */ #if HAVE_SYSCTL -# if defined(CTL_HW) && defined(HW_NCPU) \ - && defined(CTL_KERN) && defined(KERN_CPTIME) && defined(CPUSTATES) -# define CAN_USE_SYSCTL 1 -# else -# define CAN_USE_SYSCTL 0 -# endif +#if defined(CTL_HW) && defined(HW_NCPU) && defined(CTL_KERN) && \ + defined(KERN_CPTIME) && defined(CPUSTATES) +#define CAN_USE_SYSCTL 1 #else -# define CAN_USE_SYSCTL 0 +#define CAN_USE_SYSCTL 0 +#endif +#else +#define CAN_USE_SYSCTL 0 #endif #define COLLECTD_CPU_STATE_USER 0 @@ -99,34 +100,26 @@ #define COLLECTD_CPU_STATE_STEAL 7 #define COLLECTD_CPU_STATE_IDLE 8 #define COLLECTD_CPU_STATE_ACTIVE 9 /* sum of (!idle) */ -#define COLLECTD_CPU_STATE_MAX 10 /* #states */ +#define COLLECTD_CPU_STATE_MAX 10 /* #states */ #if HAVE_STATGRAB_H -# include +#include #endif -# ifdef HAVE_PERFSTAT -# include -# include -# endif /* HAVE_PERFSTAT */ +#ifdef HAVE_PERFSTAT +#include +#include +#endif /* HAVE_PERFSTAT */ -#if !PROCESSOR_CPU_LOAD_INFO && !KERNEL_LINUX && !HAVE_LIBKSTAT \ - && !CAN_USE_SYSCTL && !HAVE_SYSCTLBYNAME && !HAVE_LIBSTATGRAB && !HAVE_PERFSTAT -# error "No applicable input method." +#if !PROCESSOR_CPU_LOAD_INFO && !KERNEL_LINUX && !HAVE_LIBKSTAT && \ + !CAN_USE_SYSCTL && !HAVE_SYSCTLBYNAME && !HAVE_LIBSTATGRAB && \ + !HAVE_PERFSTAT +#error "No applicable input method." #endif -static const char *cpu_state_names[] = { - "user", - "system", - "wait", - "nice", - "swap", - "interrupt", - "softirq", - "steal", - "idle", - "active" -}; +static const char *cpu_state_names[] = {"user", "system", "wait", "nice", + "swap", "interrupt", "softirq", "steal", + "idle", "active"}; #ifdef PROCESSOR_CPU_LOAD_INFO static mach_port_t port_host; @@ -139,8 +132,9 @@ static mach_msg_type_number_t cpu_list_len; /* #endif KERNEL_LINUX */ #elif defined(HAVE_LIBKSTAT) -/* colleague tells me that Sun doesn't sell systems with more than 100 or so CPUs.. */ -# define MAX_NUMCPU 256 +/* colleague tells me that Sun doesn't sell systems with more than 100 or so + * CPUs.. */ +#define MAX_NUMCPU 256 extern kstat_ctl_t *kc; static kstat_t *ksp[MAX_NUMCPU]; static int numcpu; @@ -152,9 +146,9 @@ static int numcpu; #elif defined(HAVE_SYSCTLBYNAME) static int numcpu; -# ifdef HAVE_SYSCTL_KERN_CP_TIMES +#ifdef HAVE_SYSCTL_KERN_CP_TIMES static int maxcpu; -# endif /* HAVE_SYSCTL_KERN_CP_TIMES */ +#endif /* HAVE_SYSCTL_KERN_CP_TIMES */ /* #endif HAVE_SYSCTLBYNAME */ #elif defined(HAVE_LIBSTATGRAB) @@ -173,18 +167,18 @@ static int numcpu; static int pnumcpu; #endif /* HAVE_PERFSTAT */ -#define RATE_ADD(sum, val) do { \ - if (isnan (sum)) \ - (sum) = (val); \ - else if (!isnan (val)) \ - (sum) += (val); \ -} while (0) - -struct cpu_state_s -{ - value_to_rate_state_t conv; - gauge_t rate; - _Bool has_value; +#define RATE_ADD(sum, val) \ + do { \ + if (isnan(sum)) \ + (sum) = (val); \ + else if (!isnan(val)) \ + (sum) += (val); \ + } while (0) + +struct cpu_state_s { + value_to_rate_state_t conv; + gauge_t rate; + _Bool has_value; }; typedef struct cpu_state_s cpu_state_t; @@ -200,695 +194,673 @@ static _Bool report_by_state = 1; static _Bool report_percent = 0; static _Bool report_num_cpu = 0; -static const char *config_keys[] = -{ - "ReportByCpu", - "ReportByState", - "ReportNumCpu", - "ValuesPercentage" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"ReportByCpu", "ReportByState", + "ReportNumCpu", "ValuesPercentage"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); -static int cpu_config (char const *key, char const *value) /* {{{ */ +static int cpu_config(char const *key, char const *value) /* {{{ */ { - if (strcasecmp (key, "ReportByCpu") == 0) - report_by_cpu = IS_TRUE (value) ? 1 : 0; - else if (strcasecmp (key, "ValuesPercentage") == 0) - report_percent = IS_TRUE (value) ? 1 : 0; - else if (strcasecmp (key, "ReportByState") == 0) - report_by_state = IS_TRUE (value) ? 1 : 0; - else if (strcasecmp (key, "ReportNumCpu") == 0) - report_num_cpu = IS_TRUE (value) ? 1 : 0; - else - return (-1); - - return (0); + if (strcasecmp(key, "ReportByCpu") == 0) + report_by_cpu = IS_TRUE(value) ? 1 : 0; + else if (strcasecmp(key, "ValuesPercentage") == 0) + report_percent = IS_TRUE(value) ? 1 : 0; + else if (strcasecmp(key, "ReportByState") == 0) + report_by_state = IS_TRUE(value) ? 1 : 0; + else if (strcasecmp(key, "ReportNumCpu") == 0) + report_num_cpu = IS_TRUE(value) ? 1 : 0; + else + return (-1); + + return (0); } /* }}} int cpu_config */ -static int init (void) -{ +static int init(void) { #if PROCESSOR_CPU_LOAD_INFO - kern_return_t status; - - port_host = mach_host_self (); - - status = host_processors (port_host, &cpu_list, &cpu_list_len); - if (status == KERN_INVALID_ARGUMENT) - { - ERROR ("cpu plugin: Don't have a privileged host control port. " - "The most common cause for this problem is " - "that collectd is running without root " - "privileges, which are required to read CPU " - "load information. " - ""); - cpu_list_len = 0; - return (-1); - } - if (status != KERN_SUCCESS) - { - ERROR ("cpu plugin: host_processors() failed with status %d.", (int) status); - cpu_list_len = 0; - return (-1); - } - - INFO ("cpu plugin: Found %i processor%s.", (int) cpu_list_len, cpu_list_len == 1 ? "" : "s"); + kern_return_t status; + + port_host = mach_host_self(); + + status = host_processors(port_host, &cpu_list, &cpu_list_len); + if (status == KERN_INVALID_ARGUMENT) { + ERROR("cpu plugin: Don't have a privileged host control port. " + "The most common cause for this problem is " + "that collectd is running without root " + "privileges, which are required to read CPU " + "load information. " + ""); + cpu_list_len = 0; + return (-1); + } + if (status != KERN_SUCCESS) { + ERROR("cpu plugin: host_processors() failed with status %d.", (int)status); + cpu_list_len = 0; + return (-1); + } + + INFO("cpu plugin: Found %i processor%s.", (int)cpu_list_len, + cpu_list_len == 1 ? "" : "s"); /* #endif PROCESSOR_CPU_LOAD_INFO */ #elif defined(HAVE_LIBKSTAT) - kstat_t *ksp_chain; + kstat_t *ksp_chain; - numcpu = 0; + numcpu = 0; - if (kc == NULL) - return (-1); + if (kc == NULL) + return (-1); - /* Solaris doesn't count linear.. *sigh* */ - for (numcpu = 0, ksp_chain = kc->kc_chain; - (numcpu < MAX_NUMCPU) && (ksp_chain != NULL); - ksp_chain = ksp_chain->ks_next) - if (strncmp (ksp_chain->ks_module, "cpu_stat", 8) == 0) - ksp[numcpu++] = ksp_chain; + /* Solaris doesn't count linear.. *sigh* */ + for (numcpu = 0, ksp_chain = kc->kc_chain; + (numcpu < MAX_NUMCPU) && (ksp_chain != NULL); + ksp_chain = ksp_chain->ks_next) + if (strncmp(ksp_chain->ks_module, "cpu_stat", 8) == 0) + ksp[numcpu++] = ksp_chain; /* #endif HAVE_LIBKSTAT */ #elif CAN_USE_SYSCTL - size_t numcpu_size; - int mib[2] = {CTL_HW, HW_NCPU}; - int status; - - numcpu = 0; - numcpu_size = sizeof (numcpu); - - status = sysctl (mib, STATIC_ARRAY_SIZE (mib), - &numcpu, &numcpu_size, NULL, 0); - if (status == -1) - { - char errbuf[1024]; - WARNING ("cpu plugin: sysctl: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } + size_t numcpu_size; + int mib[2] = {CTL_HW, HW_NCPU}; + int status; + + numcpu = 0; + numcpu_size = sizeof(numcpu); + + status = sysctl(mib, STATIC_ARRAY_SIZE(mib), &numcpu, &numcpu_size, NULL, 0); + if (status == -1) { + char errbuf[1024]; + WARNING("cpu plugin: sysctl: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } /* #endif CAN_USE_SYSCTL */ -#elif defined (HAVE_SYSCTLBYNAME) - size_t numcpu_size; +#elif defined(HAVE_SYSCTLBYNAME) + size_t numcpu_size; - numcpu_size = sizeof (numcpu); + numcpu_size = sizeof(numcpu); - if (sysctlbyname ("hw.ncpu", &numcpu, &numcpu_size, NULL, 0) < 0) - { - char errbuf[1024]; - WARNING ("cpu plugin: sysctlbyname(hw.ncpu): %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } + if (sysctlbyname("hw.ncpu", &numcpu, &numcpu_size, NULL, 0) < 0) { + char errbuf[1024]; + WARNING("cpu plugin: sysctlbyname(hw.ncpu): %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } #ifdef HAVE_SYSCTL_KERN_CP_TIMES - numcpu_size = sizeof (maxcpu); - - if (sysctlbyname("kern.smp.maxcpus", &maxcpu, &numcpu_size, NULL, 0) < 0) - { - char errbuf[1024]; - WARNING ("cpu plugin: sysctlbyname(kern.smp.maxcpus): %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } + numcpu_size = sizeof(maxcpu); + + if (sysctlbyname("kern.smp.maxcpus", &maxcpu, &numcpu_size, NULL, 0) < 0) { + char errbuf[1024]; + WARNING("cpu plugin: sysctlbyname(kern.smp.maxcpus): %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } #else - if (numcpu != 1) - NOTICE ("cpu: Only one processor supported when using `sysctlbyname' (found %i)", numcpu); + if (numcpu != 1) + NOTICE("cpu: Only one processor supported when using `sysctlbyname' (found " + "%i)", + numcpu); #endif /* #endif HAVE_SYSCTLBYNAME */ #elif defined(HAVE_LIBSTATGRAB) - /* nothing to initialize */ +/* nothing to initialize */ /* #endif HAVE_LIBSTATGRAB */ #elif defined(HAVE_PERFSTAT) - /* nothing to initialize */ +/* nothing to initialize */ #endif /* HAVE_PERFSTAT */ - return (0); + return (0); } /* int init */ -static void submit_value (int cpu_num, int cpu_state, const char *type, value_t value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void submit_value(int cpu_num, int cpu_state, const char *type, + value_t value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &value; - vl.values_len = 1; + vl.values = &value; + vl.values_len = 1; - sstrncpy (vl.plugin, "cpu", sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, cpu_state_names[cpu_state], - sizeof (vl.type_instance)); + sstrncpy(vl.plugin, "cpu", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, cpu_state_names[cpu_state], + sizeof(vl.type_instance)); - if (cpu_num >= 0) { - ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), - "%i", cpu_num); - } - plugin_dispatch_values (&vl); + if (cpu_num >= 0) { + ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", cpu_num); + } + plugin_dispatch_values(&vl); } -static void submit_percent (int cpu_num, int cpu_state, gauge_t value) -{ - /* This function is called for all known CPU states, but each read - * method will only report a subset. The remaining states are left as - * NAN and we ignore them here. */ - if (isnan (value)) - return; - - submit_value (cpu_num, cpu_state, "percent", - (value_t) { .gauge = value }); +static void submit_percent(int cpu_num, int cpu_state, gauge_t value) { + /* This function is called for all known CPU states, but each read + * method will only report a subset. The remaining states are left as + * NAN and we ignore them here. */ + if (isnan(value)) + return; + + submit_value(cpu_num, cpu_state, "percent", (value_t){.gauge = value}); } -static void submit_derive (int cpu_num, int cpu_state, derive_t value) -{ - submit_value (cpu_num, cpu_state, "cpu", - (value_t) { .derive = value }); +static void submit_derive(int cpu_num, int cpu_state, derive_t value) { + submit_value(cpu_num, cpu_state, "cpu", (value_t){.derive = value}); } /* Takes the zero-index number of a CPU and makes sure that the module-global * cpu_states buffer is large enough. Returne ENOMEM on erorr. */ -static int cpu_states_alloc (size_t cpu_num) /* {{{ */ +static int cpu_states_alloc(size_t cpu_num) /* {{{ */ { - cpu_state_t *tmp; - size_t sz; - - sz = (((size_t) cpu_num) + 1) * COLLECTD_CPU_STATE_MAX; - assert (sz > 0); - - /* We already have enough space. */ - if (cpu_states_num >= sz) - return 0; - - tmp = realloc (cpu_states, sz * sizeof (*cpu_states)); - if (tmp == NULL) - { - ERROR ("cpu plugin: realloc failed."); - return (ENOMEM); - } - cpu_states = tmp; - tmp = cpu_states + cpu_states_num; - - memset (tmp, 0, (sz - cpu_states_num) * sizeof (*cpu_states)); - cpu_states_num = sz; - return 0; + cpu_state_t *tmp; + size_t sz; + + sz = (((size_t)cpu_num) + 1) * COLLECTD_CPU_STATE_MAX; + assert(sz > 0); + + /* We already have enough space. */ + if (cpu_states_num >= sz) + return 0; + + tmp = realloc(cpu_states, sz * sizeof(*cpu_states)); + if (tmp == NULL) { + ERROR("cpu plugin: realloc failed."); + return (ENOMEM); + } + cpu_states = tmp; + tmp = cpu_states + cpu_states_num; + + memset(tmp, 0, (sz - cpu_states_num) * sizeof(*cpu_states)); + cpu_states_num = sz; + return 0; } /* }}} cpu_states_alloc */ -static cpu_state_t *get_cpu_state (size_t cpu_num, size_t state) /* {{{ */ +static cpu_state_t *get_cpu_state(size_t cpu_num, size_t state) /* {{{ */ { - size_t index = ((cpu_num * COLLECTD_CPU_STATE_MAX) + state); + size_t index = ((cpu_num * COLLECTD_CPU_STATE_MAX) + state); - if (index >= cpu_states_num) - return (NULL); + if (index >= cpu_states_num) + return (NULL); - return (&cpu_states[index]); + return (&cpu_states[index]); } /* }}} cpu_state_t *get_cpu_state */ #if defined(HAVE_PERFSTAT) /* {{{ */ /* populate global aggregate cpu rate */ static int total_rate(gauge_t *sum_by_state, size_t state, derive_t d, - value_to_rate_state_t* conv, cdtime_t now) -{ - gauge_t rate = NAN; - int status = value_to_rate (&rate, (value_t) { .derive = d }, DS_TYPE_DERIVE, now, conv); - if (status != 0) - return (status); - - sum_by_state[state] = rate; - - if (state != COLLECTD_CPU_STATE_IDLE) - RATE_ADD (sum_by_state[COLLECTD_CPU_STATE_ACTIVE], sum_by_state[state]); - return (0); + value_to_rate_state_t *conv, cdtime_t now) { + gauge_t rate = NAN; + int status = + value_to_rate(&rate, (value_t){.derive = d}, DS_TYPE_DERIVE, now, conv); + if (status != 0) + return (status); + + sum_by_state[state] = rate; + + if (state != COLLECTD_CPU_STATE_IDLE) + RATE_ADD(sum_by_state[COLLECTD_CPU_STATE_ACTIVE], sum_by_state[state]); + return (0); } #endif /* }}} HAVE_PERFSTAT */ -/* Populates the per-CPU COLLECTD_CPU_STATE_ACTIVE rate and the global rate_by_state +/* Populates the per-CPU COLLECTD_CPU_STATE_ACTIVE rate and the global + * rate_by_state * array. */ -static void aggregate (gauge_t *sum_by_state) /* {{{ */ +static void aggregate(gauge_t *sum_by_state) /* {{{ */ { - for (size_t state = 0; state < COLLECTD_CPU_STATE_MAX; state++) - sum_by_state[state] = NAN; + for (size_t state = 0; state < COLLECTD_CPU_STATE_MAX; state++) + sum_by_state[state] = NAN; - for (size_t cpu_num = 0; cpu_num < global_cpu_num; cpu_num++) - { - cpu_state_t *this_cpu_states = get_cpu_state (cpu_num, 0); + for (size_t cpu_num = 0; cpu_num < global_cpu_num; cpu_num++) { + cpu_state_t *this_cpu_states = get_cpu_state(cpu_num, 0); - this_cpu_states[COLLECTD_CPU_STATE_ACTIVE].rate = NAN; + this_cpu_states[COLLECTD_CPU_STATE_ACTIVE].rate = NAN; - for (size_t state = 0; state < COLLECTD_CPU_STATE_ACTIVE; state++) - { - if (!this_cpu_states[state].has_value) - continue; + for (size_t state = 0; state < COLLECTD_CPU_STATE_ACTIVE; state++) { + if (!this_cpu_states[state].has_value) + continue; - RATE_ADD (sum_by_state[state], this_cpu_states[state].rate); - if (state != COLLECTD_CPU_STATE_IDLE) - RATE_ADD (this_cpu_states[COLLECTD_CPU_STATE_ACTIVE].rate, this_cpu_states[state].rate); - } + RATE_ADD(sum_by_state[state], this_cpu_states[state].rate); + if (state != COLLECTD_CPU_STATE_IDLE) + RATE_ADD(this_cpu_states[COLLECTD_CPU_STATE_ACTIVE].rate, + this_cpu_states[state].rate); + } - if (!isnan (this_cpu_states[COLLECTD_CPU_STATE_ACTIVE].rate)) - this_cpu_states[COLLECTD_CPU_STATE_ACTIVE].has_value = 1; + if (!isnan(this_cpu_states[COLLECTD_CPU_STATE_ACTIVE].rate)) + this_cpu_states[COLLECTD_CPU_STATE_ACTIVE].has_value = 1; - RATE_ADD (sum_by_state[COLLECTD_CPU_STATE_ACTIVE], this_cpu_states[COLLECTD_CPU_STATE_ACTIVE].rate); - } + RATE_ADD(sum_by_state[COLLECTD_CPU_STATE_ACTIVE], + this_cpu_states[COLLECTD_CPU_STATE_ACTIVE].rate); + } #if defined(HAVE_PERFSTAT) /* {{{ */ - cdtime_t now = cdtime (); - perfstat_cpu_total_t cputotal = { 0 }; - - if (!perfstat_cpu_total(NULL, &cputotal, sizeof(cputotal), 1)) { - char errbuf[1024]; - WARNING ("cpu plugin: perfstat_cpu_total: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return; - } - - /* Reset COLLECTD_CPU_STATE_ACTIVE */ - sum_by_state[COLLECTD_CPU_STATE_ACTIVE] = NAN; - - /* Physical Processor Utilization */ - total_rate(sum_by_state, COLLECTD_CPU_STATE_IDLE, (derive_t) cputotal.pidle, &total_conv[TOTAL_IDLE], now); - total_rate(sum_by_state, COLLECTD_CPU_STATE_USER, (derive_t) cputotal.puser, &total_conv[TOTAL_USER], now); - total_rate(sum_by_state, COLLECTD_CPU_STATE_SYSTEM, (derive_t) cputotal.psys , &total_conv[TOTAL_SYS], now); - total_rate(sum_by_state, COLLECTD_CPU_STATE_WAIT, (derive_t) cputotal.pwait, &total_conv[TOTAL_WAIT], now); + cdtime_t now = cdtime(); + perfstat_cpu_total_t cputotal = {0}; + + if (!perfstat_cpu_total(NULL, &cputotal, sizeof(cputotal), 1)) { + char errbuf[1024]; + WARNING("cpu plugin: perfstat_cpu_total: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return; + } + + /* Reset COLLECTD_CPU_STATE_ACTIVE */ + sum_by_state[COLLECTD_CPU_STATE_ACTIVE] = NAN; + + /* Physical Processor Utilization */ + total_rate(sum_by_state, COLLECTD_CPU_STATE_IDLE, (derive_t)cputotal.pidle, + &total_conv[TOTAL_IDLE], now); + total_rate(sum_by_state, COLLECTD_CPU_STATE_USER, (derive_t)cputotal.puser, + &total_conv[TOTAL_USER], now); + total_rate(sum_by_state, COLLECTD_CPU_STATE_SYSTEM, (derive_t)cputotal.psys, + &total_conv[TOTAL_SYS], now); + total_rate(sum_by_state, COLLECTD_CPU_STATE_WAIT, (derive_t)cputotal.pwait, + &total_conv[TOTAL_WAIT], now); #endif /* }}} HAVE_PERFSTAT */ } /* }}} void aggregate */ /* Commits (dispatches) the values for one CPU or the global aggregation. * cpu_num is the index of the CPU to be committed or -1 in case of the global - * aggregation. rates is a pointer to COLLECTD_CPU_STATE_MAX gauge_t values holding the + * aggregation. rates is a pointer to COLLECTD_CPU_STATE_MAX gauge_t values + * holding the * current rate; each rate may be NAN. Calculates the percentage of each state * and dispatches the metric. */ -static void cpu_commit_one (int cpu_num, /* {{{ */ - gauge_t rates[static COLLECTD_CPU_STATE_MAX]) -{ - gauge_t sum; - - sum = rates[COLLECTD_CPU_STATE_ACTIVE]; - RATE_ADD (sum, rates[COLLECTD_CPU_STATE_IDLE]); - - if (!report_by_state) - { - gauge_t percent = 100.0 * rates[COLLECTD_CPU_STATE_ACTIVE] / sum; - submit_percent (cpu_num, COLLECTD_CPU_STATE_ACTIVE, percent); - return; - } - - for (size_t state = 0; state < COLLECTD_CPU_STATE_ACTIVE; state++) - { - gauge_t percent = 100.0 * rates[state] / sum; - submit_percent (cpu_num, state, percent); - } +static void cpu_commit_one(int cpu_num, /* {{{ */ + gauge_t rates[static COLLECTD_CPU_STATE_MAX]) { + gauge_t sum; + + sum = rates[COLLECTD_CPU_STATE_ACTIVE]; + RATE_ADD(sum, rates[COLLECTD_CPU_STATE_IDLE]); + + if (!report_by_state) { + gauge_t percent = 100.0 * rates[COLLECTD_CPU_STATE_ACTIVE] / sum; + submit_percent(cpu_num, COLLECTD_CPU_STATE_ACTIVE, percent); + return; + } + + for (size_t state = 0; state < COLLECTD_CPU_STATE_ACTIVE; state++) { + gauge_t percent = 100.0 * rates[state] / sum; + submit_percent(cpu_num, state, percent); + } } /* }}} void cpu_commit_one */ /* Commits the number of cores */ -static void cpu_commit_num_cpu (gauge_t value) /* {{{ */ +static void cpu_commit_num_cpu(gauge_t value) /* {{{ */ { - value_list_t vl = VALUE_LIST_INIT; + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; - sstrncpy (vl.plugin, "cpu", sizeof (vl.plugin)); - sstrncpy (vl.type, "count", sizeof (vl.type)); + sstrncpy(vl.plugin, "cpu", sizeof(vl.plugin)); + sstrncpy(vl.type, "count", sizeof(vl.type)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* }}} void cpu_commit_num_cpu */ /* Resets the internal aggregation. This is called by the read callback after * each iteration / after each call to cpu_commit(). */ -static void cpu_reset (void) /* {{{ */ +static void cpu_reset(void) /* {{{ */ { - for (size_t i = 0; i < cpu_states_num; i++) - cpu_states[i].has_value = 0; + for (size_t i = 0; i < cpu_states_num; i++) + cpu_states[i].has_value = 0; - global_cpu_num = 0; + global_cpu_num = 0; } /* }}} void cpu_reset */ /* Legacy behavior: Dispatches the raw derive values without any aggregation. */ -static void cpu_commit_without_aggregation (void) /* {{{ */ +static void cpu_commit_without_aggregation(void) /* {{{ */ { - for (int state = 0; state < COLLECTD_CPU_STATE_ACTIVE; state++) - { - for (size_t cpu_num = 0; cpu_num < global_cpu_num; cpu_num++) - { - cpu_state_t *s = get_cpu_state (cpu_num, state); - - if (!s->has_value) - continue; - - submit_derive ((int) cpu_num, (int) state, s->conv.last_value.derive); - } - } + for (int state = 0; state < COLLECTD_CPU_STATE_ACTIVE; state++) { + for (size_t cpu_num = 0; cpu_num < global_cpu_num; cpu_num++) { + cpu_state_t *s = get_cpu_state(cpu_num, state); + + if (!s->has_value) + continue; + + submit_derive((int)cpu_num, (int)state, s->conv.last_value.derive); + } + } } /* }}} void cpu_commit_without_aggregation */ /* Aggregates the internal state and dispatches the metrics. */ -static void cpu_commit (void) /* {{{ */ +static void cpu_commit(void) /* {{{ */ { - gauge_t global_rates[COLLECTD_CPU_STATE_MAX] = { - NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN /* Batman! */ - }; - - if (report_num_cpu) - cpu_commit_num_cpu ((gauge_t) global_cpu_num); - - if (report_by_state && report_by_cpu && !report_percent) - { - cpu_commit_without_aggregation (); - return; - } - - aggregate (global_rates); - - if (!report_by_cpu) - { - cpu_commit_one (-1, global_rates); - return; - } - - for (size_t cpu_num = 0; cpu_num < global_cpu_num; cpu_num++) - { - cpu_state_t *this_cpu_states = get_cpu_state (cpu_num, 0); - gauge_t local_rates[COLLECTD_CPU_STATE_MAX] = { - NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN - }; - - for (size_t state = 0; state < COLLECTD_CPU_STATE_MAX; state++) - if (this_cpu_states[state].has_value) - local_rates[state] = this_cpu_states[state].rate; - - cpu_commit_one ((int) cpu_num, local_rates); - } + gauge_t global_rates[COLLECTD_CPU_STATE_MAX] = { + NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN /* Batman! */ + }; + + if (report_num_cpu) + cpu_commit_num_cpu((gauge_t)global_cpu_num); + + if (report_by_state && report_by_cpu && !report_percent) { + cpu_commit_without_aggregation(); + return; + } + + aggregate(global_rates); + + if (!report_by_cpu) { + cpu_commit_one(-1, global_rates); + return; + } + + for (size_t cpu_num = 0; cpu_num < global_cpu_num; cpu_num++) { + cpu_state_t *this_cpu_states = get_cpu_state(cpu_num, 0); + gauge_t local_rates[COLLECTD_CPU_STATE_MAX] = {NAN, NAN, NAN, NAN, NAN, + NAN, NAN, NAN, NAN, NAN}; + + for (size_t state = 0; state < COLLECTD_CPU_STATE_MAX; state++) + if (this_cpu_states[state].has_value) + local_rates[state] = this_cpu_states[state].rate; + + cpu_commit_one((int)cpu_num, local_rates); + } } /* }}} void cpu_commit */ /* Adds a derive value to the internal state. This should be used by each read * function for each state. At the end of the iteration, the read function * should call cpu_commit(). */ -static int cpu_stage (size_t cpu_num, size_t state, derive_t d, cdtime_t now) /* {{{ */ +static int cpu_stage(size_t cpu_num, size_t state, derive_t d, + cdtime_t now) /* {{{ */ { - int status; - cpu_state_t *s; - gauge_t rate = NAN; - value_t val = { .derive = d }; + int status; + cpu_state_t *s; + gauge_t rate = NAN; + value_t val = {.derive = d}; - if (state >= COLLECTD_CPU_STATE_ACTIVE) - return (EINVAL); + if (state >= COLLECTD_CPU_STATE_ACTIVE) + return (EINVAL); - status = cpu_states_alloc (cpu_num); - if (status != 0) - return (status); + status = cpu_states_alloc(cpu_num); + if (status != 0) + return (status); - if (global_cpu_num <= cpu_num) - global_cpu_num = cpu_num + 1; + if (global_cpu_num <= cpu_num) + global_cpu_num = cpu_num + 1; - s = get_cpu_state (cpu_num, state); + s = get_cpu_state(cpu_num, state); - status = value_to_rate (&rate, val, DS_TYPE_DERIVE, now, &s->conv); - if (status != 0) - return (status); + status = value_to_rate(&rate, val, DS_TYPE_DERIVE, now, &s->conv); + if (status != 0) + return (status); - s->rate = rate; - s->has_value = 1; - return (0); + s->rate = rate; + s->has_value = 1; + return (0); } /* }}} int cpu_stage */ -static int cpu_read (void) -{ - cdtime_t now = cdtime (); +static int cpu_read(void) { + cdtime_t now = cdtime(); #if PROCESSOR_CPU_LOAD_INFO /* {{{ */ - kern_return_t status; - - processor_cpu_load_info_data_t cpu_info; - mach_msg_type_number_t cpu_info_len; - - host_t cpu_host; - - for (mach_msg_type_number_t cpu = 0; cpu < cpu_list_len; cpu++) - { - cpu_host = 0; - cpu_info_len = PROCESSOR_BASIC_INFO_COUNT; - - status = processor_info (cpu_list[cpu], PROCESSOR_CPU_LOAD_INFO, &cpu_host, - (processor_info_t) &cpu_info, &cpu_info_len); - if (status != KERN_SUCCESS) - { - ERROR ("cpu plugin: processor_info (PROCESSOR_CPU_LOAD_INFO) failed: %s", - mach_error_string (status)); - continue; - } - - if (cpu_info_len < CPU_STATE_MAX) - { - ERROR ("cpu plugin: processor_info returned only %i elements..", cpu_info_len); - continue; - } - - cpu_stage (cpu, COLLECTD_CPU_STATE_USER, (derive_t) cpu_info.cpu_ticks[CPU_STATE_USER], now); - cpu_stage (cpu, COLLECTD_CPU_STATE_NICE, (derive_t) cpu_info.cpu_ticks[CPU_STATE_NICE], now); - cpu_stage (cpu, COLLECTD_CPU_STATE_SYSTEM, (derive_t) cpu_info.cpu_ticks[CPU_STATE_SYSTEM], now); - cpu_stage (cpu, COLLECTD_CPU_STATE_IDLE, (derive_t) cpu_info.cpu_ticks[CPU_STATE_IDLE], now); - } + kern_return_t status; + + processor_cpu_load_info_data_t cpu_info; + mach_msg_type_number_t cpu_info_len; + + host_t cpu_host; + + for (mach_msg_type_number_t cpu = 0; cpu < cpu_list_len; cpu++) { + cpu_host = 0; + cpu_info_len = PROCESSOR_BASIC_INFO_COUNT; + + status = processor_info(cpu_list[cpu], PROCESSOR_CPU_LOAD_INFO, &cpu_host, + (processor_info_t)&cpu_info, &cpu_info_len); + if (status != KERN_SUCCESS) { + ERROR("cpu plugin: processor_info (PROCESSOR_CPU_LOAD_INFO) failed: %s", + mach_error_string(status)); + continue; + } + + if (cpu_info_len < CPU_STATE_MAX) { + ERROR("cpu plugin: processor_info returned only %i elements..", + cpu_info_len); + continue; + } + + cpu_stage(cpu, COLLECTD_CPU_STATE_USER, + (derive_t)cpu_info.cpu_ticks[CPU_STATE_USER], now); + cpu_stage(cpu, COLLECTD_CPU_STATE_NICE, + (derive_t)cpu_info.cpu_ticks[CPU_STATE_NICE], now); + cpu_stage(cpu, COLLECTD_CPU_STATE_SYSTEM, + (derive_t)cpu_info.cpu_ticks[CPU_STATE_SYSTEM], now); + cpu_stage(cpu, COLLECTD_CPU_STATE_IDLE, + (derive_t)cpu_info.cpu_ticks[CPU_STATE_IDLE], now); + } /* }}} #endif PROCESSOR_CPU_LOAD_INFO */ #elif defined(KERNEL_LINUX) /* {{{ */ - int cpu; - FILE *fh; - char buf[1024]; - - char *fields[9]; - int numfields; - - if ((fh = fopen ("/proc/stat", "r")) == NULL) - { - char errbuf[1024]; - ERROR ("cpu plugin: fopen (/proc/stat) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - while (fgets (buf, 1024, fh) != NULL) - { - if (strncmp (buf, "cpu", 3)) - continue; - if ((buf[3] < '0') || (buf[3] > '9')) - continue; - - numfields = strsplit (buf, fields, 9); - if (numfields < 5) - continue; - - cpu = atoi (fields[0] + 3); - - cpu_stage (cpu, COLLECTD_CPU_STATE_USER, (derive_t) atoll(fields[1]), now); - cpu_stage (cpu, COLLECTD_CPU_STATE_NICE, (derive_t) atoll(fields[2]), now); - cpu_stage (cpu, COLLECTD_CPU_STATE_SYSTEM, (derive_t) atoll(fields[3]), now); - cpu_stage (cpu, COLLECTD_CPU_STATE_IDLE, (derive_t) atoll(fields[4]), now); - - if (numfields >= 8) - { - cpu_stage (cpu, COLLECTD_CPU_STATE_WAIT, (derive_t) atoll(fields[5]), now); - cpu_stage (cpu, COLLECTD_CPU_STATE_INTERRUPT, (derive_t) atoll(fields[6]), now); - cpu_stage (cpu, COLLECTD_CPU_STATE_SOFTIRQ, (derive_t) atoll(fields[7]), now); - - if (numfields >= 9) - cpu_stage (cpu, COLLECTD_CPU_STATE_STEAL, (derive_t) atoll(fields[8]), now); - } - } - fclose (fh); + int cpu; + FILE *fh; + char buf[1024]; + + char *fields[9]; + int numfields; + + if ((fh = fopen("/proc/stat", "r")) == NULL) { + char errbuf[1024]; + ERROR("cpu plugin: fopen (/proc/stat) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + while (fgets(buf, 1024, fh) != NULL) { + if (strncmp(buf, "cpu", 3)) + continue; + if ((buf[3] < '0') || (buf[3] > '9')) + continue; + + numfields = strsplit(buf, fields, 9); + if (numfields < 5) + continue; + + cpu = atoi(fields[0] + 3); + + cpu_stage(cpu, COLLECTD_CPU_STATE_USER, (derive_t)atoll(fields[1]), now); + cpu_stage(cpu, COLLECTD_CPU_STATE_NICE, (derive_t)atoll(fields[2]), now); + cpu_stage(cpu, COLLECTD_CPU_STATE_SYSTEM, (derive_t)atoll(fields[3]), now); + cpu_stage(cpu, COLLECTD_CPU_STATE_IDLE, (derive_t)atoll(fields[4]), now); + + if (numfields >= 8) { + cpu_stage(cpu, COLLECTD_CPU_STATE_WAIT, (derive_t)atoll(fields[5]), now); + cpu_stage(cpu, COLLECTD_CPU_STATE_INTERRUPT, (derive_t)atoll(fields[6]), + now); + cpu_stage(cpu, COLLECTD_CPU_STATE_SOFTIRQ, (derive_t)atoll(fields[7]), + now); + + if (numfields >= 9) + cpu_stage(cpu, COLLECTD_CPU_STATE_STEAL, (derive_t)atoll(fields[8]), + now); + } + } + fclose(fh); /* }}} #endif defined(KERNEL_LINUX) */ #elif defined(HAVE_LIBKSTAT) /* {{{ */ - static cpu_stat_t cs; - - if (kc == NULL) - return (-1); - - for (int cpu = 0; cpu < numcpu; cpu++) - { - if (kstat_read (kc, ksp[cpu], &cs) == -1) - continue; /* error message? */ - - cpu_stage (ksp[cpu]->ks_instance, COLLECTD_CPU_STATE_IDLE, (derive_t) cs.cpu_sysinfo.cpu[CPU_IDLE], now); - cpu_stage (ksp[cpu]->ks_instance, COLLECTD_CPU_STATE_USER, (derive_t) cs.cpu_sysinfo.cpu[CPU_USER], now); - cpu_stage (ksp[cpu]->ks_instance, COLLECTD_CPU_STATE_SYSTEM, (derive_t) cs.cpu_sysinfo.cpu[CPU_KERNEL], now); - cpu_stage (ksp[cpu]->ks_instance, COLLECTD_CPU_STATE_WAIT, (derive_t) cs.cpu_sysinfo.cpu[CPU_WAIT], now); - } + static cpu_stat_t cs; + + if (kc == NULL) + return (-1); + + for (int cpu = 0; cpu < numcpu; cpu++) { + if (kstat_read(kc, ksp[cpu], &cs) == -1) + continue; /* error message? */ + + cpu_stage(ksp[cpu]->ks_instance, COLLECTD_CPU_STATE_IDLE, + (derive_t)cs.cpu_sysinfo.cpu[CPU_IDLE], now); + cpu_stage(ksp[cpu]->ks_instance, COLLECTD_CPU_STATE_USER, + (derive_t)cs.cpu_sysinfo.cpu[CPU_USER], now); + cpu_stage(ksp[cpu]->ks_instance, COLLECTD_CPU_STATE_SYSTEM, + (derive_t)cs.cpu_sysinfo.cpu[CPU_KERNEL], now); + cpu_stage(ksp[cpu]->ks_instance, COLLECTD_CPU_STATE_WAIT, + (derive_t)cs.cpu_sysinfo.cpu[CPU_WAIT], now); + } /* }}} #endif defined(HAVE_LIBKSTAT) */ #elif CAN_USE_SYSCTL /* {{{ */ - uint64_t cpuinfo[numcpu][CPUSTATES]; - size_t cpuinfo_size; - int status; + uint64_t cpuinfo[numcpu][CPUSTATES]; + size_t cpuinfo_size; + int status; - if (numcpu < 1) - { - ERROR ("cpu plugin: Could not determine number of " - "installed CPUs using sysctl(3)."); - return (-1); - } + if (numcpu < 1) { + ERROR("cpu plugin: Could not determine number of " + "installed CPUs using sysctl(3)."); + return (-1); + } - memset (cpuinfo, 0, sizeof (cpuinfo)); + memset(cpuinfo, 0, sizeof(cpuinfo)); #if defined(KERN_CPTIME2) - if (numcpu > 1) { - for (int i = 0; i < numcpu; i++) { - int mib[] = {CTL_KERN, KERN_CPTIME2, i}; - - cpuinfo_size = sizeof (cpuinfo[0]); - - status = sysctl (mib, STATIC_ARRAY_SIZE (mib), - cpuinfo[i], &cpuinfo_size, NULL, 0); - if (status == -1) { - char errbuf[1024]; - ERROR ("cpu plugin: sysctl failed: %s.", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - } - } - else + if (numcpu > 1) { + for (int i = 0; i < numcpu; i++) { + int mib[] = {CTL_KERN, KERN_CPTIME2, i}; + + cpuinfo_size = sizeof(cpuinfo[0]); + + status = sysctl(mib, STATIC_ARRAY_SIZE(mib), cpuinfo[i], &cpuinfo_size, + NULL, 0); + if (status == -1) { + char errbuf[1024]; + ERROR("cpu plugin: sysctl failed: %s.", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + } + } else #endif /* defined(KERN_CPTIME2) */ - { - int mib[] = {CTL_KERN, KERN_CPTIME}; - long cpuinfo_tmp[CPUSTATES]; - - cpuinfo_size = sizeof(cpuinfo_tmp); - - status = sysctl (mib, STATIC_ARRAY_SIZE (mib), - &cpuinfo_tmp, &cpuinfo_size, NULL, 0); - if (status == -1) - { - char errbuf[1024]; - ERROR ("cpu plugin: sysctl failed: %s.", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - for(int i = 0; i < CPUSTATES; i++) { - cpuinfo[0][i] = cpuinfo_tmp[i]; - } - } - - for (int i = 0; i < numcpu; i++) { - cpu_stage (i, COLLECTD_CPU_STATE_USER, (derive_t) cpuinfo[i][CP_USER], now); - cpu_stage (i, COLLECTD_CPU_STATE_NICE, (derive_t) cpuinfo[i][CP_NICE], now); - cpu_stage (i, COLLECTD_CPU_STATE_SYSTEM, (derive_t) cpuinfo[i][CP_SYS], now); - cpu_stage (i, COLLECTD_CPU_STATE_IDLE, (derive_t) cpuinfo[i][CP_IDLE], now); - cpu_stage (i, COLLECTD_CPU_STATE_INTERRUPT, (derive_t) cpuinfo[i][CP_INTR], now); - } + { + int mib[] = {CTL_KERN, KERN_CPTIME}; + long cpuinfo_tmp[CPUSTATES]; + + cpuinfo_size = sizeof(cpuinfo_tmp); + + status = sysctl(mib, STATIC_ARRAY_SIZE(mib), &cpuinfo_tmp, &cpuinfo_size, + NULL, 0); + if (status == -1) { + char errbuf[1024]; + ERROR("cpu plugin: sysctl failed: %s.", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + for (int i = 0; i < CPUSTATES; i++) { + cpuinfo[0][i] = cpuinfo_tmp[i]; + } + } + + for (int i = 0; i < numcpu; i++) { + cpu_stage(i, COLLECTD_CPU_STATE_USER, (derive_t)cpuinfo[i][CP_USER], now); + cpu_stage(i, COLLECTD_CPU_STATE_NICE, (derive_t)cpuinfo[i][CP_NICE], now); + cpu_stage(i, COLLECTD_CPU_STATE_SYSTEM, (derive_t)cpuinfo[i][CP_SYS], now); + cpu_stage(i, COLLECTD_CPU_STATE_IDLE, (derive_t)cpuinfo[i][CP_IDLE], now); + cpu_stage(i, COLLECTD_CPU_STATE_INTERRUPT, (derive_t)cpuinfo[i][CP_INTR], + now); + } /* }}} #endif CAN_USE_SYSCTL */ -#elif defined(HAVE_SYSCTLBYNAME) && defined(HAVE_SYSCTL_KERN_CP_TIMES) /* {{{ */ - long cpuinfo[maxcpu][CPUSTATES]; - size_t cpuinfo_size; - - memset (cpuinfo, 0, sizeof (cpuinfo)); - - cpuinfo_size = sizeof (cpuinfo); - if (sysctlbyname("kern.cp_times", &cpuinfo, &cpuinfo_size, NULL, 0) < 0) - { - char errbuf[1024]; - ERROR ("cpu plugin: sysctlbyname failed: %s.", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - for (int i = 0; i < numcpu; i++) { - cpu_stage (i, COLLECTD_CPU_STATE_USER, (derive_t) cpuinfo[i][CP_USER], now); - cpu_stage (i, COLLECTD_CPU_STATE_NICE, (derive_t) cpuinfo[i][CP_NICE], now); - cpu_stage (i, COLLECTD_CPU_STATE_SYSTEM, (derive_t) cpuinfo[i][CP_SYS], now); - cpu_stage (i, COLLECTD_CPU_STATE_IDLE, (derive_t) cpuinfo[i][CP_IDLE], now); - cpu_stage (i, COLLECTD_CPU_STATE_INTERRUPT, (derive_t) cpuinfo[i][CP_INTR], now); - } +#elif defined(HAVE_SYSCTLBYNAME) && defined(HAVE_SYSCTL_KERN_CP_TIMES) /* {{{ \ + */ + long cpuinfo[maxcpu][CPUSTATES]; + size_t cpuinfo_size; + + memset(cpuinfo, 0, sizeof(cpuinfo)); + + cpuinfo_size = sizeof(cpuinfo); + if (sysctlbyname("kern.cp_times", &cpuinfo, &cpuinfo_size, NULL, 0) < 0) { + char errbuf[1024]; + ERROR("cpu plugin: sysctlbyname failed: %s.", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + for (int i = 0; i < numcpu; i++) { + cpu_stage(i, COLLECTD_CPU_STATE_USER, (derive_t)cpuinfo[i][CP_USER], now); + cpu_stage(i, COLLECTD_CPU_STATE_NICE, (derive_t)cpuinfo[i][CP_NICE], now); + cpu_stage(i, COLLECTD_CPU_STATE_SYSTEM, (derive_t)cpuinfo[i][CP_SYS], now); + cpu_stage(i, COLLECTD_CPU_STATE_IDLE, (derive_t)cpuinfo[i][CP_IDLE], now); + cpu_stage(i, COLLECTD_CPU_STATE_INTERRUPT, (derive_t)cpuinfo[i][CP_INTR], + now); + } /* }}} #endif HAVE_SYSCTL_KERN_CP_TIMES */ #elif defined(HAVE_SYSCTLBYNAME) /* {{{ */ - long cpuinfo[CPUSTATES]; - size_t cpuinfo_size; - - cpuinfo_size = sizeof (cpuinfo); - - if (sysctlbyname("kern.cp_time", &cpuinfo, &cpuinfo_size, NULL, 0) < 0) - { - char errbuf[1024]; - ERROR ("cpu plugin: sysctlbyname failed: %s.", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - cpu_stage (0, COLLECTD_CPU_STATE_USER, (derive_t) cpuinfo[CP_USER], now); - cpu_stage (0, COLLECTD_CPU_STATE_NICE, (derive_t) cpuinfo[CP_NICE], now); - cpu_stage (0, COLLECTD_CPU_STATE_SYSTEM, (derive_t) cpuinfo[CP_SYS], now); - cpu_stage (0, COLLECTD_CPU_STATE_IDLE, (derive_t) cpuinfo[CP_IDLE], now); - cpu_stage (0, COLLECTD_CPU_STATE_INTERRUPT, (derive_t) cpuinfo[CP_INTR], now); + long cpuinfo[CPUSTATES]; + size_t cpuinfo_size; + + cpuinfo_size = sizeof(cpuinfo); + + if (sysctlbyname("kern.cp_time", &cpuinfo, &cpuinfo_size, NULL, 0) < 0) { + char errbuf[1024]; + ERROR("cpu plugin: sysctlbyname failed: %s.", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + cpu_stage(0, COLLECTD_CPU_STATE_USER, (derive_t)cpuinfo[CP_USER], now); + cpu_stage(0, COLLECTD_CPU_STATE_NICE, (derive_t)cpuinfo[CP_NICE], now); + cpu_stage(0, COLLECTD_CPU_STATE_SYSTEM, (derive_t)cpuinfo[CP_SYS], now); + cpu_stage(0, COLLECTD_CPU_STATE_IDLE, (derive_t)cpuinfo[CP_IDLE], now); + cpu_stage(0, COLLECTD_CPU_STATE_INTERRUPT, (derive_t)cpuinfo[CP_INTR], now); /* }}} #endif HAVE_SYSCTLBYNAME */ #elif defined(HAVE_LIBSTATGRAB) /* {{{ */ - sg_cpu_stats *cs; - cs = sg_get_cpu_stats (); - - if (cs == NULL) - { - ERROR ("cpu plugin: sg_get_cpu_stats failed."); - return (-1); - } - - cpu_state (0, COLLECTD_CPU_STATE_IDLE, (derive_t) cs->idle); - cpu_state (0, COLLECTD_CPU_STATE_NICE, (derive_t) cs->nice); - cpu_state (0, COLLECTD_CPU_STATE_SWAP, (derive_t) cs->swap); - cpu_state (0, COLLECTD_CPU_STATE_SYSTEM, (derive_t) cs->kernel); - cpu_state (0, COLLECTD_CPU_STATE_USER, (derive_t) cs->user); - cpu_state (0, COLLECTD_CPU_STATE_WAIT, (derive_t) cs->iowait); + sg_cpu_stats *cs; + cs = sg_get_cpu_stats(); + + if (cs == NULL) { + ERROR("cpu plugin: sg_get_cpu_stats failed."); + return (-1); + } + + cpu_state(0, COLLECTD_CPU_STATE_IDLE, (derive_t)cs->idle); + cpu_state(0, COLLECTD_CPU_STATE_NICE, (derive_t)cs->nice); + cpu_state(0, COLLECTD_CPU_STATE_SWAP, (derive_t)cs->swap); + cpu_state(0, COLLECTD_CPU_STATE_SYSTEM, (derive_t)cs->kernel); + cpu_state(0, COLLECTD_CPU_STATE_USER, (derive_t)cs->user); + cpu_state(0, COLLECTD_CPU_STATE_WAIT, (derive_t)cs->iowait); /* }}} #endif HAVE_LIBSTATGRAB */ #elif defined(HAVE_PERFSTAT) /* {{{ */ - perfstat_id_t id; - int cpus; - - numcpu = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0); - if(numcpu == -1) - { - char errbuf[1024]; - WARNING ("cpu plugin: perfstat_cpu: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - if (pnumcpu != numcpu || perfcpu == NULL) - { - free(perfcpu); - perfcpu = malloc(numcpu * sizeof(perfstat_cpu_t)); - } - pnumcpu = numcpu; - - id.name[0] = '\0'; - if ((cpus = perfstat_cpu(&id, perfcpu, sizeof(perfstat_cpu_t), numcpu)) < 0) - { - char errbuf[1024]; - WARNING ("cpu plugin: perfstat_cpu: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - for (int i = 0; i < cpus; i++) - { - cpu_stage (i, COLLECTD_CPU_STATE_IDLE, (derive_t) perfcpu[i].idle, now); - cpu_stage (i, COLLECTD_CPU_STATE_SYSTEM, (derive_t) perfcpu[i].sys, now); - cpu_stage (i, COLLECTD_CPU_STATE_USER, (derive_t) perfcpu[i].user, now); - cpu_stage (i, COLLECTD_CPU_STATE_WAIT, (derive_t) perfcpu[i].wait, now); - } -#endif /* }}} HAVE_PERFSTAT */ - - cpu_commit (); - cpu_reset (); - return (0); + perfstat_id_t id; + int cpus; + + numcpu = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0); + if (numcpu == -1) { + char errbuf[1024]; + WARNING("cpu plugin: perfstat_cpu: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + if (pnumcpu != numcpu || perfcpu == NULL) { + free(perfcpu); + perfcpu = malloc(numcpu * sizeof(perfstat_cpu_t)); + } + pnumcpu = numcpu; + + id.name[0] = '\0'; + if ((cpus = perfstat_cpu(&id, perfcpu, sizeof(perfstat_cpu_t), numcpu)) < 0) { + char errbuf[1024]; + WARNING("cpu plugin: perfstat_cpu: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + for (int i = 0; i < cpus; i++) { + cpu_stage(i, COLLECTD_CPU_STATE_IDLE, (derive_t)perfcpu[i].idle, now); + cpu_stage(i, COLLECTD_CPU_STATE_SYSTEM, (derive_t)perfcpu[i].sys, now); + cpu_stage(i, COLLECTD_CPU_STATE_USER, (derive_t)perfcpu[i].user, now); + cpu_stage(i, COLLECTD_CPU_STATE_WAIT, (derive_t)perfcpu[i].wait, now); + } +#endif /* }}} HAVE_PERFSTAT */ + + cpu_commit(); + cpu_reset(); + return (0); } -void module_register (void) -{ - plugin_register_init ("cpu", init); - plugin_register_config ("cpu", cpu_config, config_keys, config_keys_num); - plugin_register_read ("cpu", cpu_read); +void module_register(void) { + plugin_register_init("cpu", init); + plugin_register_config("cpu", cpu_config, config_keys, config_keys_num); + plugin_register_read("cpu", cpu_read); } /* void module_register */ /* vim: set sw=8 sts=8 noet fdm=marker : */ diff --git a/src/cpufreq.c b/src/cpufreq.c index 285ee6c6..c3080cbf 100644 --- a/src/cpufreq.c +++ b/src/cpufreq.c @@ -27,75 +27,68 @@ static int num_cpu = 0; -static int cpufreq_init (void) -{ - int status; - char filename[256]; +static int cpufreq_init(void) { + int status; + char filename[256]; - num_cpu = 0; + num_cpu = 0; - while (1) - { - status = ssnprintf (filename, sizeof (filename), - "/sys/devices/system/cpu/cpu%d/cpufreq/" - "scaling_cur_freq", num_cpu); - if ((status < 1) || ((unsigned int)status >= sizeof (filename))) - break; + while (1) { + status = ssnprintf(filename, sizeof(filename), + "/sys/devices/system/cpu/cpu%d/cpufreq/" + "scaling_cur_freq", + num_cpu); + if ((status < 1) || ((unsigned int)status >= sizeof(filename))) + break; - if (access (filename, R_OK)) - break; + if (access(filename, R_OK)) + break; - num_cpu++; - } + num_cpu++; + } - INFO ("cpufreq plugin: Found %d CPU%s", num_cpu, - (num_cpu == 1) ? "" : "s"); + INFO("cpufreq plugin: Found %d CPU%s", num_cpu, (num_cpu == 1) ? "" : "s"); - if (num_cpu == 0) - plugin_unregister_read ("cpufreq"); + if (num_cpu == 0) + plugin_unregister_read("cpufreq"); - return (0); + return (0); } /* int cpufreq_init */ -static void cpufreq_submit (int cpu_num, value_t value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void cpufreq_submit(int cpu_num, value_t value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &value; - vl.values_len = 1; - sstrncpy (vl.plugin, "cpufreq", sizeof (vl.plugin)); - sstrncpy (vl.type, "cpufreq", sizeof (vl.type)); - ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%i", cpu_num); + vl.values = &value; + vl.values_len = 1; + sstrncpy(vl.plugin, "cpufreq", sizeof(vl.plugin)); + sstrncpy(vl.type, "cpufreq", sizeof(vl.type)); + ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%i", cpu_num); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static int cpufreq_read (void) -{ - for (int i = 0; i < num_cpu; i++) - { - char filename[PATH_MAX]; - ssnprintf (filename, sizeof (filename), - "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq", i); +static int cpufreq_read(void) { + for (int i = 0; i < num_cpu; i++) { + char filename[PATH_MAX]; + ssnprintf(filename, sizeof(filename), + "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq", i); - value_t v; - if (parse_value_file (filename, &v, DS_TYPE_GAUGE) != 0) - { - WARNING ("cpufreq plugin: Reading \"%s\" failed.", filename); - continue; - } + value_t v; + if (parse_value_file(filename, &v, DS_TYPE_GAUGE) != 0) { + WARNING("cpufreq plugin: Reading \"%s\" failed.", filename); + continue; + } - /* convert kHz to Hz */ - v.gauge *= 1000.0; + /* convert kHz to Hz */ + v.gauge *= 1000.0; - cpufreq_submit (i, v); - } + cpufreq_submit(i, v); + } - return (0); + return (0); } /* int cpufreq_read */ -void module_register (void) -{ - plugin_register_init ("cpufreq", cpufreq_init); - plugin_register_read ("cpufreq", cpufreq_read); +void module_register(void) { + plugin_register_init("cpufreq", cpufreq_init); + plugin_register_read("cpufreq", cpufreq_read); } diff --git a/src/cpusleep.c b/src/cpusleep.c index 31bb25d6..62988fb0 100644 --- a/src/cpusleep.c +++ b/src/cpusleep.c @@ -32,14 +32,14 @@ #include "collectd.h" +#include #include "common.h" #include "plugin.h" -#include static void cpusleep_submit(derive_t cpu_sleep) { value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .derive = cpu_sleep }; + vl.values = &(value_t){.derive = cpu_sleep}; vl.values_len = 1; sstrncpy(vl.plugin, "cpusleep", sizeof(vl.plugin)); sstrncpy(vl.type, "total_time_in_ms", sizeof(vl.type)); diff --git a/src/cpython.h b/src/cpython.h index 070d33af..41170404 100644 --- a/src/cpython.h +++ b/src/cpython.h @@ -28,7 +28,8 @@ #include -/* These two macros are basically Py_BEGIN_ALLOW_THREADS and Py_BEGIN_ALLOW_THREADS +/* These two macros are basically Py_BEGIN_ALLOW_THREADS and + * Py_BEGIN_ALLOW_THREADS * from the other direction. If a Python thread calls a C function * Py_BEGIN_ALLOW_THREADS is used to allow other python threads to run because * we don't intend to call any Python functions. @@ -36,21 +37,24 @@ * These two macros are used whenever a C thread intends to call some Python * function, usually because some registered callback was triggered. * Just like Py_BEGIN_ALLOW_THREADS it opens a block so these macros have to be - * used in pairs. They acquire the GIL, create a new Python thread state and swap - * the current thread state with the new one. This means this thread is now allowed + * used in pairs. They acquire the GIL, create a new Python thread state and + * swap + * the current thread state with the new one. This means this thread is now + * allowed * to execute Python code. */ -#define CPY_LOCK_THREADS {\ - PyGILState_STATE gil_state;\ - gil_state = PyGILState_Ensure(); +#define CPY_LOCK_THREADS \ + { \ + PyGILState_STATE gil_state; \ + gil_state = PyGILState_Ensure(); -#define CPY_RETURN_FROM_THREADS \ - PyGILState_Release(gil_state);\ - return +#define CPY_RETURN_FROM_THREADS \ + PyGILState_Release(gil_state); \ + return -#define CPY_RELEASE_THREADS \ - PyGILState_Release(gil_state);\ -} +#define CPY_RELEASE_THREADS \ + PyGILState_Release(gil_state); \ + } /* This macro is a shortcut for calls like * x = PyObject_Repr(x); @@ -59,13 +63,14 @@ * This calling syntax is less than elegant but it works, saves * a lot of lines and avoids potential refcount errors. */ -#define CPY_SUBSTITUTE(func, a, ...) do {\ - if ((a) != NULL) {\ - PyObject *__tmp = (a);\ - (a) = func(__VA_ARGS__);\ - Py_DECREF(__tmp);\ - }\ -} while(0) +#define CPY_SUBSTITUTE(func, a, ...) \ + do { \ + if ((a) != NULL) { \ + PyObject *__tmp = (a); \ + (a) = func(__VA_ARGS__); \ + Py_DECREF(__tmp); \ + } \ + } while (0) /* Python3 compatibility layer. To keep the actual code as clean as possible * do a lot of defines here. */ @@ -77,26 +82,27 @@ #ifdef IS_PY3K #define PyInt_FromLong PyLong_FromLong -#define CPY_INIT_TYPE PyVarObject_HEAD_INIT(NULL, 0) +#define CPY_INIT_TYPE PyVarObject_HEAD_INIT(NULL, 0) #define IS_BYTES_OR_UNICODE(o) (PyUnicode_Check(o) || PyBytes_Check(o)) -#define CPY_STRCAT_AND_DEL(a, b) do {\ - CPY_STRCAT((a), (b));\ - Py_XDECREF((b));\ -} while (0) +#define CPY_STRCAT_AND_DEL(a, b) \ + do { \ + CPY_STRCAT((a), (b)); \ + Py_XDECREF((b)); \ + } while (0) static inline void CPY_STRCAT(PyObject **a, PyObject *b) { - PyObject *ret; + PyObject *ret; - if (!a || !*a) - return; + if (!a || !*a) + return; - ret = PyUnicode_Concat(*a, b); - Py_DECREF(*a); - *a = ret; + ret = PyUnicode_Concat(*a, b); + Py_DECREF(*a); + *a = ret; } #else -#define CPY_INIT_TYPE PyObject_HEAD_INIT(NULL) 0, +#define CPY_INIT_TYPE PyObject_HEAD_INIT(NULL) 0, #define IS_BYTES_OR_UNICODE(o) (PyUnicode_Check(o) || PyString_Check(o)) #define CPY_STRCAT_AND_DEL PyString_ConcatAndDel #define CPY_STRCAT PyString_Concat @@ -104,32 +110,32 @@ static inline void CPY_STRCAT(PyObject **a, PyObject *b) { #endif static inline const char *cpy_unicode_or_bytes_to_string(PyObject **o) { - if (PyUnicode_Check(*o)) { - PyObject *tmp; - tmp = PyUnicode_AsEncodedString(*o, NULL, NULL); /* New reference. */ - if (tmp == NULL) - return NULL; - Py_DECREF(*o); - *o = tmp; - } + if (PyUnicode_Check(*o)) { + PyObject *tmp; + tmp = PyUnicode_AsEncodedString(*o, NULL, NULL); /* New reference. */ + if (tmp == NULL) + return NULL; + Py_DECREF(*o); + *o = tmp; + } #ifdef IS_PY3K - return PyBytes_AsString(*o); + return PyBytes_AsString(*o); #else - return PyString_AsString(*o); + return PyString_AsString(*o); #endif } static inline PyObject *cpy_string_to_unicode_or_bytes(const char *buf) { #ifdef IS_PY3K -/* Python3 preferrs unicode */ - PyObject *ret; - ret = PyUnicode_Decode(buf, strlen(buf), NULL, NULL); - if (ret != NULL) - return ret; - PyErr_Clear(); - return PyBytes_FromString(buf); + /* Python3 preferrs unicode */ + PyObject *ret; + ret = PyUnicode_Decode(buf, strlen(buf), NULL, NULL); + if (ret != NULL) + return ret; + PyErr_Clear(); + return PyBytes_FromString(buf); #else - return PyString_FromString(buf); + return PyString_FromString(buf); #endif } @@ -138,46 +144,48 @@ void cpy_log_exception(const char *context); /* Python object declarations. */ typedef struct { - PyObject_HEAD /* No semicolon! */ - PyObject *parent; /* Config */ - PyObject *key; /* String */ - PyObject *values; /* Sequence */ - PyObject *children; /* Sequence */ + PyObject_HEAD /* No semicolon! */ + PyObject *parent; /* Config */ + PyObject *key; /* String */ + PyObject *values; /* Sequence */ + PyObject *children; /* Sequence */ } Config; extern PyTypeObject ConfigType; typedef struct { - PyObject_HEAD /* No semicolon! */ - double time; - char host[DATA_MAX_NAME_LEN]; - char plugin[DATA_MAX_NAME_LEN]; - char plugin_instance[DATA_MAX_NAME_LEN]; - char type[DATA_MAX_NAME_LEN]; - char type_instance[DATA_MAX_NAME_LEN]; + PyObject_HEAD /* No semicolon! */ + double time; + char host[DATA_MAX_NAME_LEN]; + char plugin[DATA_MAX_NAME_LEN]; + char plugin_instance[DATA_MAX_NAME_LEN]; + char type[DATA_MAX_NAME_LEN]; + char type_instance[DATA_MAX_NAME_LEN]; } PluginData; extern PyTypeObject PluginDataType; -#define PluginData_New() PyObject_CallFunctionObjArgs((PyObject *) &PluginDataType, (void *) 0) +#define PluginData_New() \ + PyObject_CallFunctionObjArgs((PyObject *)&PluginDataType, (void *)0) typedef struct { - PluginData data; - PyObject *values; /* Sequence */ - PyObject *meta; /* dict */ - double interval; + PluginData data; + PyObject *values; /* Sequence */ + PyObject *meta; /* dict */ + double interval; } Values; extern PyTypeObject ValuesType; -#define Values_New() PyObject_CallFunctionObjArgs((PyObject *) &ValuesType, (void *) 0) +#define Values_New() \ + PyObject_CallFunctionObjArgs((PyObject *)&ValuesType, (void *)0) typedef struct { - PluginData data; - int severity; - char message[NOTIF_MAX_MSG_LEN]; + PluginData data; + int severity; + char message[NOTIF_MAX_MSG_LEN]; } Notification; extern PyTypeObject NotificationType; -#define Notification_New() PyObject_CallFunctionObjArgs((PyObject *) &NotificationType, (void *) 0) +#define Notification_New() \ + PyObject_CallFunctionObjArgs((PyObject *)&NotificationType, (void *)0) typedef PyLongObject Signed; extern PyTypeObject SignedType; typedef PyLongObject Unsigned; extern PyTypeObject UnsignedType; - diff --git a/src/csv.c b/src/csv.c index e008ecfe..c1759f5a 100644 --- a/src/csv.c +++ b/src/csv.c @@ -23,348 +23,284 @@ #include "collectd.h" -#include "plugin.h" #include "common.h" +#include "plugin.h" #include "utils_cache.h" /* * Private variables */ -static const char *config_keys[] = -{ - "DataDir", - "StoreRates" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); - -static char *datadir = NULL; +static const char *config_keys[] = {"DataDir", "StoreRates"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); + +static char *datadir = NULL; static int store_rates = 0; -static int use_stdio = 0; - -static int value_list_to_string (char *buffer, int buffer_len, - const data_set_t *ds, const value_list_t *vl) -{ - int offset; - int status; - gauge_t *rates = NULL; - - assert (0 == strcmp (ds->type, vl->type)); - - memset (buffer, '\0', buffer_len); - - status = ssnprintf (buffer, buffer_len, "%.3f", - CDTIME_T_TO_DOUBLE (vl->time)); - if ((status < 1) || (status >= buffer_len)) - return (-1); - offset = status; - - for (size_t i = 0; i < ds->ds_num; i++) - { - if ((ds->ds[i].type != DS_TYPE_COUNTER) - && (ds->ds[i].type != DS_TYPE_GAUGE) - && (ds->ds[i].type != DS_TYPE_DERIVE) - && (ds->ds[i].type != DS_TYPE_ABSOLUTE)) - { - sfree (rates); - return (-1); - } - - if (ds->ds[i].type == DS_TYPE_GAUGE) - { - status = ssnprintf (buffer + offset, buffer_len - offset, - ",%lf", vl->values[i].gauge); - } - else if (store_rates != 0) - { - if (rates == NULL) - rates = uc_get_rate (ds, vl); - if (rates == NULL) - { - WARNING ("csv plugin: " - "uc_get_rate failed."); - return (-1); - } - status = ssnprintf (buffer + offset, - buffer_len - offset, - ",%lf", rates[i]); - } - else if (ds->ds[i].type == DS_TYPE_COUNTER) - { - status = ssnprintf (buffer + offset, - buffer_len - offset, - ",%llu", - vl->values[i].counter); - } - else if (ds->ds[i].type == DS_TYPE_DERIVE) - { - status = ssnprintf (buffer + offset, - buffer_len - offset, - ",%"PRIi64, - vl->values[i].derive); - } - else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) - { - status = ssnprintf (buffer + offset, - buffer_len - offset, - ",%"PRIu64, - vl->values[i].absolute); - } - - if ((status < 1) || (status >= (buffer_len - offset))) - { - sfree (rates); - return (-1); - } - - offset += status; - } /* for ds->ds_num */ - - sfree (rates); - return (0); +static int use_stdio = 0; + +static int value_list_to_string(char *buffer, int buffer_len, + const data_set_t *ds, const value_list_t *vl) { + int offset; + int status; + gauge_t *rates = NULL; + + assert(0 == strcmp(ds->type, vl->type)); + + memset(buffer, '\0', buffer_len); + + status = ssnprintf(buffer, buffer_len, "%.3f", CDTIME_T_TO_DOUBLE(vl->time)); + if ((status < 1) || (status >= buffer_len)) + return (-1); + offset = status; + + for (size_t i = 0; i < ds->ds_num; i++) { + if ((ds->ds[i].type != DS_TYPE_COUNTER) && + (ds->ds[i].type != DS_TYPE_GAUGE) && + (ds->ds[i].type != DS_TYPE_DERIVE) && + (ds->ds[i].type != DS_TYPE_ABSOLUTE)) { + sfree(rates); + return (-1); + } + + if (ds->ds[i].type == DS_TYPE_GAUGE) { + status = ssnprintf(buffer + offset, buffer_len - offset, ",%lf", + vl->values[i].gauge); + } else if (store_rates != 0) { + if (rates == NULL) + rates = uc_get_rate(ds, vl); + if (rates == NULL) { + WARNING("csv plugin: " + "uc_get_rate failed."); + return (-1); + } + status = + ssnprintf(buffer + offset, buffer_len - offset, ",%lf", rates[i]); + } else if (ds->ds[i].type == DS_TYPE_COUNTER) { + status = ssnprintf(buffer + offset, buffer_len - offset, ",%llu", + vl->values[i].counter); + } else if (ds->ds[i].type == DS_TYPE_DERIVE) { + status = ssnprintf(buffer + offset, buffer_len - offset, ",%" PRIi64, + vl->values[i].derive); + } else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) { + status = ssnprintf(buffer + offset, buffer_len - offset, ",%" PRIu64, + vl->values[i].absolute); + } + + if ((status < 1) || (status >= (buffer_len - offset))) { + sfree(rates); + return (-1); + } + + offset += status; + } /* for ds->ds_num */ + + sfree(rates); + return (0); } /* int value_list_to_string */ -static int value_list_to_filename (char *buffer, size_t buffer_size, - value_list_t const *vl) -{ - int status; - - char *ptr = buffer; - size_t ptr_size = buffer_size; - time_t now; - struct tm struct_tm; - - if (datadir != NULL) - { - size_t len = strlen (datadir) + 1; - - if (len >= ptr_size) - return (ENOBUFS); - - memcpy (ptr, datadir, len); - ptr[len-1] = '/'; - ptr_size -= len; - ptr += len; - } - - status = FORMAT_VL (ptr, ptr_size, vl); - if (status != 0) - return (status); - - /* Skip all the time formatting stuff when printing to STDOUT or - * STDERR. */ - if (use_stdio) - return (0); - - ptr_size -= strlen (ptr); - ptr += strlen (ptr); - - /* "-2013-07-12" => 11 bytes */ - if (ptr_size < 12) - { - ERROR ("csv plugin: Buffer too small."); - return (ENOMEM); - } - - /* TODO: Find a way to minimize the calls to `localtime_r', - * since they are pretty expensive.. */ - now = time (NULL); - if (localtime_r (&now, &struct_tm) == NULL) - { - ERROR ("csv plugin: localtime_r failed"); - return (-1); - } - - status = strftime (ptr, ptr_size, "-%Y-%m-%d", &struct_tm); - if (status == 0) /* yep, it returns zero on error. */ - { - ERROR ("csv plugin: strftime failed"); - return (-1); - } - - return (0); +static int value_list_to_filename(char *buffer, size_t buffer_size, + value_list_t const *vl) { + int status; + + char *ptr = buffer; + size_t ptr_size = buffer_size; + time_t now; + struct tm struct_tm; + + if (datadir != NULL) { + size_t len = strlen(datadir) + 1; + + if (len >= ptr_size) + return (ENOBUFS); + + memcpy(ptr, datadir, len); + ptr[len - 1] = '/'; + ptr_size -= len; + ptr += len; + } + + status = FORMAT_VL(ptr, ptr_size, vl); + if (status != 0) + return (status); + + /* Skip all the time formatting stuff when printing to STDOUT or + * STDERR. */ + if (use_stdio) + return (0); + + ptr_size -= strlen(ptr); + ptr += strlen(ptr); + + /* "-2013-07-12" => 11 bytes */ + if (ptr_size < 12) { + ERROR("csv plugin: Buffer too small."); + return (ENOMEM); + } + + /* TODO: Find a way to minimize the calls to `localtime_r', + * since they are pretty expensive.. */ + now = time(NULL); + if (localtime_r(&now, &struct_tm) == NULL) { + ERROR("csv plugin: localtime_r failed"); + return (-1); + } + + status = strftime(ptr, ptr_size, "-%Y-%m-%d", &struct_tm); + if (status == 0) /* yep, it returns zero on error. */ + { + ERROR("csv plugin: strftime failed"); + return (-1); + } + + return (0); } /* int value_list_to_filename */ -static int csv_create_file (const char *filename, const data_set_t *ds) -{ - FILE *csv; +static int csv_create_file(const char *filename, const data_set_t *ds) { + FILE *csv; - if (check_create_dir (filename)) - return (-1); + if (check_create_dir(filename)) + return (-1); - csv = fopen (filename, "w"); - if (csv == NULL) - { - char errbuf[1024]; - ERROR ("csv plugin: fopen (%s) failed: %s", - filename, - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } + csv = fopen(filename, "w"); + if (csv == NULL) { + char errbuf[1024]; + ERROR("csv plugin: fopen (%s) failed: %s", filename, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } - fprintf (csv, "epoch"); - for (size_t i = 0; i < ds->ds_num; i++) - fprintf (csv, ",%s", ds->ds[i].name); + fprintf(csv, "epoch"); + for (size_t i = 0; i < ds->ds_num; i++) + fprintf(csv, ",%s", ds->ds[i].name); - fprintf (csv, "\n"); - fclose (csv); + fprintf(csv, "\n"); + fclose(csv); - return 0; + return 0; } /* int csv_create_file */ -static int csv_config (const char *key, const char *value) -{ - if (strcasecmp ("DataDir", key) == 0) - { - if (datadir != NULL) - { - free (datadir); - datadir = NULL; - } - if (strcasecmp ("stdout", value) == 0) - { - use_stdio = 1; - return (0); - } - else if (strcasecmp ("stderr", value) == 0) - { - use_stdio = 2; - return (0); - } - datadir = strdup (value); - if (datadir != NULL) - { - int len = strlen (datadir); - while ((len > 0) && (datadir[len - 1] == '/')) - { - len--; - datadir[len] = '\0'; - } - if (len <= 0) - { - free (datadir); - datadir = NULL; - } - } - } - else if (strcasecmp ("StoreRates", key) == 0) - { - if (IS_TRUE (value)) - store_rates = 1; - else - store_rates = 0; - } - else - { - return (-1); - } - return (0); +static int csv_config(const char *key, const char *value) { + if (strcasecmp("DataDir", key) == 0) { + if (datadir != NULL) { + free(datadir); + datadir = NULL; + } + if (strcasecmp("stdout", value) == 0) { + use_stdio = 1; + return (0); + } else if (strcasecmp("stderr", value) == 0) { + use_stdio = 2; + return (0); + } + datadir = strdup(value); + if (datadir != NULL) { + int len = strlen(datadir); + while ((len > 0) && (datadir[len - 1] == '/')) { + len--; + datadir[len] = '\0'; + } + if (len <= 0) { + free(datadir); + datadir = NULL; + } + } + } else if (strcasecmp("StoreRates", key) == 0) { + if (IS_TRUE(value)) + store_rates = 1; + else + store_rates = 0; + } else { + return (-1); + } + return (0); } /* int csv_config */ -static int csv_write (const data_set_t *ds, const value_list_t *vl, - user_data_t __attribute__((unused)) *user_data) -{ - struct stat statbuf; - char filename[512]; - char values[4096]; - FILE *csv; - int csv_fd; - struct flock fl = { 0 }; - int status; - - if (0 != strcmp (ds->type, vl->type)) { - ERROR ("csv plugin: DS type does not match value list type"); - return -1; - } - - status = value_list_to_filename (filename, sizeof (filename), vl); - if (status != 0) - return (-1); - - DEBUG ("csv plugin: csv_write: filename = %s;", filename); - - if (value_list_to_string (values, sizeof (values), ds, vl) != 0) - return (-1); - - if (use_stdio) - { - escape_string (filename, sizeof (filename)); - - /* Replace commas by colons for PUTVAL compatible output. */ - for (size_t i = 0; i < sizeof (values); i++) - { - if (values[i] == 0) - break; - else if (values[i] == ',') - values[i] = ':'; - } - - fprintf (use_stdio == 1 ? stdout : stderr, - "PUTVAL %s interval=%.3f %s\n", - filename, - CDTIME_T_TO_DOUBLE (vl->interval), - values); - return (0); - } - - if (stat (filename, &statbuf) == -1) - { - if (errno == ENOENT) - { - if (csv_create_file (filename, ds)) - return (-1); - } - else - { - char errbuf[1024]; - ERROR ("stat(%s) failed: %s", filename, - sstrerror (errno, errbuf, - sizeof (errbuf))); - return (-1); - } - } - else if (!S_ISREG (statbuf.st_mode)) - { - ERROR ("stat(%s): Not a regular file!", - filename); - return (-1); - } - - csv = fopen (filename, "a"); - if (csv == NULL) - { - char errbuf[1024]; - ERROR ("csv plugin: fopen (%s) failed: %s", filename, - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - csv_fd = fileno (csv); - - fl.l_pid = getpid (); - fl.l_type = F_WRLCK; - fl.l_whence = SEEK_SET; - - status = fcntl (csv_fd, F_SETLK, &fl); - if (status != 0) - { - char errbuf[1024]; - ERROR ("csv plugin: flock (%s) failed: %s", filename, - sstrerror (errno, errbuf, sizeof (errbuf))); - fclose (csv); - return (-1); - } - - fprintf (csv, "%s\n", values); - - /* The lock is implicitely released. I we don't release it explicitely - * because the `FILE *' may need to flush a cache first */ - fclose (csv); - - return (0); +static int csv_write(const data_set_t *ds, const value_list_t *vl, + user_data_t __attribute__((unused)) * user_data) { + struct stat statbuf; + char filename[512]; + char values[4096]; + FILE *csv; + int csv_fd; + struct flock fl = {0}; + int status; + + if (0 != strcmp(ds->type, vl->type)) { + ERROR("csv plugin: DS type does not match value list type"); + return -1; + } + + status = value_list_to_filename(filename, sizeof(filename), vl); + if (status != 0) + return (-1); + + DEBUG("csv plugin: csv_write: filename = %s;", filename); + + if (value_list_to_string(values, sizeof(values), ds, vl) != 0) + return (-1); + + if (use_stdio) { + escape_string(filename, sizeof(filename)); + + /* Replace commas by colons for PUTVAL compatible output. */ + for (size_t i = 0; i < sizeof(values); i++) { + if (values[i] == 0) + break; + else if (values[i] == ',') + values[i] = ':'; + } + + fprintf(use_stdio == 1 ? stdout : stderr, "PUTVAL %s interval=%.3f %s\n", + filename, CDTIME_T_TO_DOUBLE(vl->interval), values); + return (0); + } + + if (stat(filename, &statbuf) == -1) { + if (errno == ENOENT) { + if (csv_create_file(filename, ds)) + return (-1); + } else { + char errbuf[1024]; + ERROR("stat(%s) failed: %s", filename, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + } else if (!S_ISREG(statbuf.st_mode)) { + ERROR("stat(%s): Not a regular file!", filename); + return (-1); + } + + csv = fopen(filename, "a"); + if (csv == NULL) { + char errbuf[1024]; + ERROR("csv plugin: fopen (%s) failed: %s", filename, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + csv_fd = fileno(csv); + + fl.l_pid = getpid(); + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + + status = fcntl(csv_fd, F_SETLK, &fl); + if (status != 0) { + char errbuf[1024]; + ERROR("csv plugin: flock (%s) failed: %s", filename, + sstrerror(errno, errbuf, sizeof(errbuf))); + fclose(csv); + return (-1); + } + + fprintf(csv, "%s\n", values); + + /* The lock is implicitely released. I we don't release it explicitely + * because the `FILE *' may need to flush a cache first */ + fclose(csv); + + return (0); } /* int csv_write */ -void module_register (void) -{ - plugin_register_config ("csv", csv_config, - config_keys, config_keys_num); - plugin_register_write ("csv", csv_write, /* user_data = */ NULL); +void module_register(void) { + plugin_register_config("csv", csv_config, config_keys, config_keys_num); + plugin_register_write("csv", csv_write, /* user_data = */ NULL); } /* void module_register */ diff --git a/src/curl.c b/src/curl.c index ced31e93..c6f0b607 100644 --- a/src/curl.c +++ b/src/curl.c @@ -90,9 +90,8 @@ static web_page_t *pages_g = NULL; /* * Private functions */ -static size_t cc_curl_callback (void *buf, /* {{{ */ - size_t size, size_t nmemb, void *user_data) -{ +static size_t cc_curl_callback(void *buf, /* {{{ */ + size_t size, size_t nmemb, void *user_data) { web_page_t *wp; size_t len; @@ -104,76 +103,73 @@ static size_t cc_curl_callback (void *buf, /* {{{ */ if (wp == NULL) return (0); - if ((wp->buffer_fill + len) >= wp->buffer_size) - { + if ((wp->buffer_fill + len) >= wp->buffer_size) { char *temp; size_t temp_size; temp_size = wp->buffer_fill + len + 1; - temp = realloc (wp->buffer, temp_size); - if (temp == NULL) - { - ERROR ("curl plugin: realloc failed."); + temp = realloc(wp->buffer, temp_size); + if (temp == NULL) { + ERROR("curl plugin: realloc failed."); return (0); } wp->buffer = temp; wp->buffer_size = temp_size; } - memcpy (wp->buffer + wp->buffer_fill, (char *) buf, len); + memcpy(wp->buffer + wp->buffer_fill, (char *)buf, len); wp->buffer_fill += len; wp->buffer[wp->buffer_fill] = 0; return (len); } /* }}} size_t cc_curl_callback */ -static void cc_web_match_free (web_match_t *wm) /* {{{ */ +static void cc_web_match_free(web_match_t *wm) /* {{{ */ { if (wm == NULL) return; - sfree (wm->regex); - sfree (wm->type); - sfree (wm->instance); - match_destroy (wm->match); - cc_web_match_free (wm->next); - sfree (wm); + sfree(wm->regex); + sfree(wm->type); + sfree(wm->instance); + match_destroy(wm->match); + cc_web_match_free(wm->next); + sfree(wm); } /* }}} void cc_web_match_free */ -static void cc_web_page_free (web_page_t *wp) /* {{{ */ +static void cc_web_page_free(web_page_t *wp) /* {{{ */ { if (wp == NULL) return; if (wp->curl != NULL) - curl_easy_cleanup (wp->curl); + curl_easy_cleanup(wp->curl); wp->curl = NULL; - sfree (wp->instance); + sfree(wp->instance); - sfree (wp->url); - sfree (wp->user); - sfree (wp->pass); - sfree (wp->credentials); - sfree (wp->cacert); - sfree (wp->post_body); - curl_slist_free_all (wp->headers); - curl_stats_destroy (wp->stats); + sfree(wp->url); + sfree(wp->user); + sfree(wp->pass); + sfree(wp->credentials); + sfree(wp->cacert); + sfree(wp->post_body); + curl_slist_free_all(wp->headers); + curl_stats_destroy(wp->stats); - sfree (wp->buffer); + sfree(wp->buffer); - cc_web_match_free (wp->matches); - cc_web_page_free (wp->next); - sfree (wp); + cc_web_match_free(wp->matches); + cc_web_page_free(wp->next); + sfree(wp); } /* }}} void cc_web_page_free */ -static int cc_config_append_string (const char *name, struct curl_slist **dest, /* {{{ */ - oconfig_item_t *ci) -{ +static int cc_config_append_string(const char *name, + struct curl_slist **dest, /* {{{ */ + oconfig_item_t *ci) { struct curl_slist *temp = NULL; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("curl plugin: `%s' needs exactly one string argument.", name); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("curl plugin: `%s' needs exactly one string argument.", name); return (-1); } @@ -186,77 +182,67 @@ static int cc_config_append_string (const char *name, struct curl_slist **dest, return (0); } /* }}} int cc_config_append_string */ -static int cc_config_add_match_dstype (int *dstype_ret, /* {{{ */ - oconfig_item_t *ci) -{ +static int cc_config_add_match_dstype(int *dstype_ret, /* {{{ */ + oconfig_item_t *ci) { int dstype; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("curl plugin: `DSType' needs exactly one string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("curl plugin: `DSType' needs exactly one string argument."); return (-1); } - if (strncasecmp ("Gauge", ci->values[0].value.string, - strlen ("Gauge")) == 0) - { + if (strncasecmp("Gauge", ci->values[0].value.string, strlen("Gauge")) == 0) { dstype = UTILS_MATCH_DS_TYPE_GAUGE; - if (strcasecmp ("GaugeAverage", ci->values[0].value.string) == 0) + if (strcasecmp("GaugeAverage", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_GAUGE_AVERAGE; - else if (strcasecmp ("GaugeMin", ci->values[0].value.string) == 0) + else if (strcasecmp("GaugeMin", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_GAUGE_MIN; - else if (strcasecmp ("GaugeMax", ci->values[0].value.string) == 0) + else if (strcasecmp("GaugeMax", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_GAUGE_MAX; - else if (strcasecmp ("GaugeLast", ci->values[0].value.string) == 0) + else if (strcasecmp("GaugeLast", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_GAUGE_LAST; else dstype = 0; - } - else if (strncasecmp ("Counter", ci->values[0].value.string, - strlen ("Counter")) == 0) - { + } else if (strncasecmp("Counter", ci->values[0].value.string, + strlen("Counter")) == 0) { dstype = UTILS_MATCH_DS_TYPE_COUNTER; - if (strcasecmp ("CounterSet", ci->values[0].value.string) == 0) + if (strcasecmp("CounterSet", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_COUNTER_SET; - else if (strcasecmp ("CounterAdd", ci->values[0].value.string) == 0) + else if (strcasecmp("CounterAdd", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_COUNTER_ADD; - else if (strcasecmp ("CounterInc", ci->values[0].value.string) == 0) + else if (strcasecmp("CounterInc", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_COUNTER_INC; else dstype = 0; - } -else if (strncasecmp ("Derive", ci->values[0].value.string, - strlen ("Derive")) == 0) - { + } else if (strncasecmp("Derive", ci->values[0].value.string, + strlen("Derive")) == 0) { dstype = UTILS_MATCH_DS_TYPE_DERIVE; - if (strcasecmp ("DeriveSet", ci->values[0].value.string) == 0) + if (strcasecmp("DeriveSet", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_DERIVE_SET; - else if (strcasecmp ("DeriveAdd", ci->values[0].value.string) == 0) + else if (strcasecmp("DeriveAdd", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_DERIVE_ADD; - else if (strcasecmp ("DeriveInc", ci->values[0].value.string) == 0) + else if (strcasecmp("DeriveInc", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_DERIVE_INC; else dstype = 0; - } -else if (strncasecmp ("Absolute", ci->values[0].value.string, - strlen ("Absolute")) == 0) - { + } else if (strncasecmp("Absolute", ci->values[0].value.string, + strlen("Absolute")) == 0) { dstype = UTILS_MATCH_DS_TYPE_ABSOLUTE; - if (strcasecmp ("AbsoluteSet", ci->values[0].value.string) == 0) /* Absolute DS is reset-on-read so no sense doin anything else but set */ + if (strcasecmp("AbsoluteSet", ci->values[0].value.string) == + 0) /* Absolute DS is reset-on-read so no sense doin anything else but + set */ dstype |= UTILS_MATCH_CF_ABSOLUTE_SET; else dstype = 0; } - else - { + else { dstype = 0; } - if (dstype == 0) - { - WARNING ("curl plugin: `%s' is not a valid argument to `DSType'.", - ci->values[0].value.string); + if (dstype == 0) { + WARNING("curl plugin: `%s' is not a valid argument to `DSType'.", + ci->values[0].value.string); return (-1); } @@ -264,42 +250,37 @@ else if (strncasecmp ("Absolute", ci->values[0].value.string, return (0); } /* }}} int cc_config_add_match_dstype */ -static int cc_config_add_match (web_page_t *page, /* {{{ */ - oconfig_item_t *ci) -{ +static int cc_config_add_match(web_page_t *page, /* {{{ */ + oconfig_item_t *ci) { web_match_t *match; int status; - if (ci->values_num != 0) - { - WARNING ("curl plugin: Ignoring arguments for the `Match' block."); + if (ci->values_num != 0) { + WARNING("curl plugin: Ignoring arguments for the `Match' block."); } - match = calloc (1, sizeof (*match)); - if (match == NULL) - { - ERROR ("curl plugin: calloc failed."); + match = calloc(1, sizeof(*match)); + if (match == NULL) { + ERROR("curl plugin: calloc failed."); return (-1); } status = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Regex", child->key) == 0) - status = cf_util_get_string (child, &match->regex); - else if (strcasecmp ("ExcludeRegex", child->key) == 0) - status = cf_util_get_string (child, &match->exclude_regex); - else if (strcasecmp ("DSType", child->key) == 0) - status = cc_config_add_match_dstype (&match->dstype, child); - else if (strcasecmp ("Type", child->key) == 0) - status = cf_util_get_string (child, &match->type); - else if (strcasecmp ("Instance", child->key) == 0) - status = cf_util_get_string (child, &match->instance); - else - { - WARNING ("curl plugin: Option `%s' not allowed here.", child->key); + if (strcasecmp("Regex", child->key) == 0) + status = cf_util_get_string(child, &match->regex); + else if (strcasecmp("ExcludeRegex", child->key) == 0) + status = cf_util_get_string(child, &match->exclude_regex); + else if (strcasecmp("DSType", child->key) == 0) + status = cc_config_add_match_dstype(&match->dstype, child); + else if (strcasecmp("Type", child->key) == 0) + status = cf_util_get_string(child, &match->type); + else if (strcasecmp("Instance", child->key) == 0) + status = cf_util_get_string(child, &match->instance); + else { + WARNING("curl plugin: Option `%s' not allowed here.", child->key); status = -1; } @@ -307,45 +288,37 @@ static int cc_config_add_match (web_page_t *page, /* {{{ */ break; } /* for (i = 0; i < ci->children_num; i++) */ - while (status == 0) - { - if (match->regex == NULL) - { - WARNING ("curl plugin: `Regex' missing in `Match' block."); + while (status == 0) { + if (match->regex == NULL) { + WARNING("curl plugin: `Regex' missing in `Match' block."); status = -1; } - if (match->type == NULL) - { - WARNING ("curl plugin: `Type' missing in `Match' block."); + if (match->type == NULL) { + WARNING("curl plugin: `Type' missing in `Match' block."); status = -1; } - if (match->dstype == 0) - { - WARNING ("curl plugin: `DSType' missing in `Match' block."); + if (match->dstype == 0) { + WARNING("curl plugin: `DSType' missing in `Match' block."); status = -1; } break; } /* while (status == 0) */ - if (status != 0) - { - cc_web_match_free (match); + if (status != 0) { + cc_web_match_free(match); return (status); } - match->match = match_create_simple (match->regex, match->exclude_regex, - match->dstype); - if (match->match == NULL) - { - ERROR ("curl plugin: match_create_simple failed."); - cc_web_match_free (match); + match->match = + match_create_simple(match->regex, match->exclude_regex, match->dstype); + if (match->match == NULL) { + ERROR("curl plugin: match_create_simple failed."); + cc_web_match_free(match); return (-1); - } - else - { + } else { web_match_t *prev; prev = page->matches; @@ -361,88 +334,83 @@ static int cc_config_add_match (web_page_t *page, /* {{{ */ return (0); } /* }}} int cc_config_add_match */ -static int cc_page_init_curl (web_page_t *wp) /* {{{ */ +static int cc_page_init_curl(web_page_t *wp) /* {{{ */ { - wp->curl = curl_easy_init (); - if (wp->curl == NULL) - { - ERROR ("curl plugin: curl_easy_init failed."); + wp->curl = curl_easy_init(); + if (wp->curl == NULL) { + ERROR("curl plugin: curl_easy_init failed."); return (-1); } - curl_easy_setopt (wp->curl, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt (wp->curl, CURLOPT_WRITEFUNCTION, cc_curl_callback); - curl_easy_setopt (wp->curl, CURLOPT_WRITEDATA, wp); - curl_easy_setopt (wp->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); - curl_easy_setopt (wp->curl, CURLOPT_ERRORBUFFER, wp->curl_errbuf); - curl_easy_setopt (wp->curl, CURLOPT_URL, wp->url); - curl_easy_setopt (wp->curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt (wp->curl, CURLOPT_MAXREDIRS, 50L); - - if (wp->user != NULL) - { + curl_easy_setopt(wp->curl, CURLOPT_NOSIGNAL, 1L); + curl_easy_setopt(wp->curl, CURLOPT_WRITEFUNCTION, cc_curl_callback); + curl_easy_setopt(wp->curl, CURLOPT_WRITEDATA, wp); + curl_easy_setopt(wp->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); + curl_easy_setopt(wp->curl, CURLOPT_ERRORBUFFER, wp->curl_errbuf); + curl_easy_setopt(wp->curl, CURLOPT_URL, wp->url); + curl_easy_setopt(wp->curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(wp->curl, CURLOPT_MAXREDIRS, 50L); + + if (wp->user != NULL) { #ifdef HAVE_CURLOPT_USERNAME - curl_easy_setopt (wp->curl, CURLOPT_USERNAME, wp->user); - curl_easy_setopt (wp->curl, CURLOPT_PASSWORD, - (wp->pass == NULL) ? "" : wp->pass); + curl_easy_setopt(wp->curl, CURLOPT_USERNAME, wp->user); + curl_easy_setopt(wp->curl, CURLOPT_PASSWORD, + (wp->pass == NULL) ? "" : wp->pass); #else size_t credentials_size; - credentials_size = strlen (wp->user) + 2; + credentials_size = strlen(wp->user) + 2; if (wp->pass != NULL) - credentials_size += strlen (wp->pass); + credentials_size += strlen(wp->pass); - wp->credentials = malloc (credentials_size); - if (wp->credentials == NULL) - { - ERROR ("curl plugin: malloc failed."); + wp->credentials = malloc(credentials_size); + if (wp->credentials == NULL) { + ERROR("curl plugin: malloc failed."); return (-1); } - ssnprintf (wp->credentials, credentials_size, "%s:%s", - wp->user, (wp->pass == NULL) ? "" : wp->pass); - curl_easy_setopt (wp->curl, CURLOPT_USERPWD, wp->credentials); + ssnprintf(wp->credentials, credentials_size, "%s:%s", wp->user, + (wp->pass == NULL) ? "" : wp->pass); + curl_easy_setopt(wp->curl, CURLOPT_USERPWD, wp->credentials); #endif if (wp->digest) - curl_easy_setopt (wp->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); + curl_easy_setopt(wp->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); } - curl_easy_setopt (wp->curl, CURLOPT_SSL_VERIFYPEER, (long) wp->verify_peer); - curl_easy_setopt (wp->curl, CURLOPT_SSL_VERIFYHOST, - wp->verify_host ? 2L : 0L); + curl_easy_setopt(wp->curl, CURLOPT_SSL_VERIFYPEER, (long)wp->verify_peer); + curl_easy_setopt(wp->curl, CURLOPT_SSL_VERIFYHOST, wp->verify_host ? 2L : 0L); if (wp->cacert != NULL) - curl_easy_setopt (wp->curl, CURLOPT_CAINFO, wp->cacert); + curl_easy_setopt(wp->curl, CURLOPT_CAINFO, wp->cacert); if (wp->headers != NULL) - curl_easy_setopt (wp->curl, CURLOPT_HTTPHEADER, wp->headers); + curl_easy_setopt(wp->curl, CURLOPT_HTTPHEADER, wp->headers); if (wp->post_body != NULL) - curl_easy_setopt (wp->curl, CURLOPT_POSTFIELDS, wp->post_body); + curl_easy_setopt(wp->curl, CURLOPT_POSTFIELDS, wp->post_body); #ifdef HAVE_CURLOPT_TIMEOUT_MS if (wp->timeout >= 0) - curl_easy_setopt (wp->curl, CURLOPT_TIMEOUT_MS, (long) wp->timeout); + curl_easy_setopt(wp->curl, CURLOPT_TIMEOUT_MS, (long)wp->timeout); else - curl_easy_setopt (wp->curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval())); + curl_easy_setopt(wp->curl, CURLOPT_TIMEOUT_MS, + (long)CDTIME_T_TO_MS(plugin_get_interval())); #endif return (0); } /* }}} int cc_page_init_curl */ -static int cc_config_add_page (oconfig_item_t *ci) /* {{{ */ +static int cc_config_add_page(oconfig_item_t *ci) /* {{{ */ { web_page_t *page; int status; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("curl plugin: `Page' blocks need exactly one string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("curl plugin: `Page' blocks need exactly one string argument."); return (-1); } - page = calloc (1, sizeof (*page)); - if (page == NULL) - { - ERROR ("curl plugin: calloc failed."); + page = calloc(1, sizeof(*page)); + if (page == NULL) { + ERROR("curl plugin: calloc failed."); return (-1); } page->url = NULL; @@ -456,55 +424,51 @@ static int cc_config_add_page (oconfig_item_t *ci) /* {{{ */ page->timeout = -1; page->stats = NULL; - page->instance = strdup (ci->values[0].value.string); - if (page->instance == NULL) - { - ERROR ("curl plugin: strdup failed."); - sfree (page); + page->instance = strdup(ci->values[0].value.string); + if (page->instance == NULL) { + ERROR("curl plugin: strdup failed."); + sfree(page); return (-1); } /* Process all children */ status = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("URL", child->key) == 0) - status = cf_util_get_string (child, &page->url); - else if (strcasecmp ("User", child->key) == 0) - status = cf_util_get_string (child, &page->user); - else if (strcasecmp ("Password", child->key) == 0) - status = cf_util_get_string (child, &page->pass); - else if (strcasecmp ("Digest", child->key) == 0) - status = cf_util_get_boolean (child, &page->digest); - else if (strcasecmp ("VerifyPeer", child->key) == 0) - status = cf_util_get_boolean (child, &page->verify_peer); - else if (strcasecmp ("VerifyHost", child->key) == 0) - status = cf_util_get_boolean (child, &page->verify_host); - else if (strcasecmp ("MeasureResponseTime", child->key) == 0) - status = cf_util_get_boolean (child, &page->response_time); - else if (strcasecmp ("MeasureResponseCode", child->key) == 0) - status = cf_util_get_boolean (child, &page->response_code); - else if (strcasecmp ("CACert", child->key) == 0) - status = cf_util_get_string (child, &page->cacert); - else if (strcasecmp ("Match", child->key) == 0) + if (strcasecmp("URL", child->key) == 0) + status = cf_util_get_string(child, &page->url); + else if (strcasecmp("User", child->key) == 0) + status = cf_util_get_string(child, &page->user); + else if (strcasecmp("Password", child->key) == 0) + status = cf_util_get_string(child, &page->pass); + else if (strcasecmp("Digest", child->key) == 0) + status = cf_util_get_boolean(child, &page->digest); + else if (strcasecmp("VerifyPeer", child->key) == 0) + status = cf_util_get_boolean(child, &page->verify_peer); + else if (strcasecmp("VerifyHost", child->key) == 0) + status = cf_util_get_boolean(child, &page->verify_host); + else if (strcasecmp("MeasureResponseTime", child->key) == 0) + status = cf_util_get_boolean(child, &page->response_time); + else if (strcasecmp("MeasureResponseCode", child->key) == 0) + status = cf_util_get_boolean(child, &page->response_code); + else if (strcasecmp("CACert", child->key) == 0) + status = cf_util_get_string(child, &page->cacert); + else if (strcasecmp("Match", child->key) == 0) /* Be liberal with failing matches => don't set `status'. */ - cc_config_add_match (page, child); - else if (strcasecmp ("Header", child->key) == 0) - status = cc_config_append_string ("Header", &page->headers, child); - else if (strcasecmp ("Post", child->key) == 0) - status = cf_util_get_string (child, &page->post_body); - else if (strcasecmp ("Timeout", child->key) == 0) - status = cf_util_get_int (child, &page->timeout); - else if (strcasecmp ("Statistics", child->key) == 0) { - page->stats = curl_stats_from_config (child); + cc_config_add_match(page, child); + else if (strcasecmp("Header", child->key) == 0) + status = cc_config_append_string("Header", &page->headers, child); + else if (strcasecmp("Post", child->key) == 0) + status = cf_util_get_string(child, &page->post_body); + else if (strcasecmp("Timeout", child->key) == 0) + status = cf_util_get_int(child, &page->timeout); + else if (strcasecmp("Statistics", child->key) == 0) { + page->stats = curl_stats_from_config(child); if (page->stats == NULL) status = -1; - } - else - { - WARNING ("curl plugin: Option `%s' not allowed here.", child->key); + } else { + WARNING("curl plugin: Option `%s' not allowed here.", child->key); status = -1; } @@ -513,41 +477,37 @@ static int cc_config_add_page (oconfig_item_t *ci) /* {{{ */ } /* for (i = 0; i < ci->children_num; i++) */ /* Additionial sanity checks and libCURL initialization. */ - while (status == 0) - { - if (page->url == NULL) - { - WARNING ("curl plugin: `URL' missing in `Page' block."); + while (status == 0) { + if (page->url == NULL) { + WARNING("curl plugin: `URL' missing in `Page' block."); status = -1; } - if (page->matches == NULL && page->stats == NULL - && !page->response_time && !page->response_code) - { - assert (page->instance != NULL); - WARNING ("curl plugin: No (valid) `Match' block " - "or Statistics or MeasureResponseTime or MeasureResponseCode " - "within `Page' block `%s'.", page->instance); + if (page->matches == NULL && page->stats == NULL && !page->response_time && + !page->response_code) { + assert(page->instance != NULL); + WARNING("curl plugin: No (valid) `Match' block " + "or Statistics or MeasureResponseTime or MeasureResponseCode " + "within `Page' block `%s'.", + page->instance); status = -1; } if (status == 0) - status = cc_page_init_curl (page); + status = cc_page_init_curl(page); break; } /* while (status == 0) */ - if (status != 0) - { - cc_web_page_free (page); + if (status != 0) { + cc_web_page_free(page); return (status); } /* Add the new page to the linked list */ if (pages_g == NULL) pages_g = page; - else - { + else { web_page_t *prev; prev = pages_g; @@ -559,7 +519,7 @@ static int cc_config_add_page (oconfig_item_t *ci) /* {{{ */ return (0); } /* }}} int cc_config_add_page */ -static int cc_config (oconfig_item_t *ci) /* {{{ */ +static int cc_config(oconfig_item_t *ci) /* {{{ */ { int success; int errors; @@ -568,169 +528,156 @@ static int cc_config (oconfig_item_t *ci) /* {{{ */ success = 0; errors = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Page", child->key) == 0) - { - status = cc_config_add_page (child); + if (strcasecmp("Page", child->key) == 0) { + status = cc_config_add_page(child); if (status == 0) success++; else errors++; - } - else - { - WARNING ("curl plugin: Option `%s' not allowed here.", child->key); + } else { + WARNING("curl plugin: Option `%s' not allowed here.", child->key); errors++; } } - if ((success == 0) && (errors > 0)) - { - ERROR ("curl plugin: All statements failed."); + if ((success == 0) && (errors > 0)) { + ERROR("curl plugin: All statements failed."); return (-1); } return (0); } /* }}} int cc_config */ -static int cc_init (void) /* {{{ */ +static int cc_init(void) /* {{{ */ { - if (pages_g == NULL) - { - INFO ("curl plugin: No pages have been defined."); + if (pages_g == NULL) { + INFO("curl plugin: No pages have been defined."); return (-1); } - curl_global_init (CURL_GLOBAL_SSL); + curl_global_init(CURL_GLOBAL_SSL); return (0); } /* }}} int cc_init */ -static void cc_submit (const web_page_t *wp, const web_match_t *wm, /* {{{ */ - value_t value) -{ +static void cc_submit(const web_page_t *wp, const web_match_t *wm, /* {{{ */ + value_t value) { value_list_t vl = VALUE_LIST_INIT; vl.values = &value; vl.values_len = 1; - sstrncpy (vl.plugin, "curl", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, wp->instance, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, wm->type, sizeof (vl.type)); + sstrncpy(vl.plugin, "curl", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, wp->instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, wm->type, sizeof(vl.type)); if (wm->instance != NULL) - sstrncpy (vl.type_instance, wm->instance, sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, wm->instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* }}} void cc_submit */ -static void cc_submit_response_code (const web_page_t *wp, long code) /* {{{ */ +static void cc_submit_response_code(const web_page_t *wp, long code) /* {{{ */ { value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = (gauge_t) code }; + vl.values = &(value_t){.gauge = (gauge_t)code}; vl.values_len = 1; - sstrncpy (vl.plugin, "curl", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, wp->instance, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, "response_code", sizeof (vl.type)); + sstrncpy(vl.plugin, "curl", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, wp->instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "response_code", sizeof(vl.type)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* }}} void cc_submit_response_code */ -static void cc_submit_response_time (const web_page_t *wp, /* {{{ */ - gauge_t response_time) -{ +static void cc_submit_response_time(const web_page_t *wp, /* {{{ */ + gauge_t response_time) { value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = response_time }; + vl.values = &(value_t){.gauge = response_time}; vl.values_len = 1; - sstrncpy (vl.plugin, "curl", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, wp->instance, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, "response_time", sizeof (vl.type)); + sstrncpy(vl.plugin, "curl", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, wp->instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "response_time", sizeof(vl.type)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* }}} void cc_submit_response_time */ -static int cc_read_page (web_page_t *wp) /* {{{ */ +static int cc_read_page(web_page_t *wp) /* {{{ */ { int status; cdtime_t start = 0; if (wp->response_time) - start = cdtime (); + start = cdtime(); wp->buffer_fill = 0; - status = curl_easy_perform (wp->curl); - if (status != CURLE_OK) - { - ERROR ("curl plugin: curl_easy_perform failed with status %i: %s", - status, wp->curl_errbuf); + status = curl_easy_perform(wp->curl); + if (status != CURLE_OK) { + ERROR("curl plugin: curl_easy_perform failed with status %i: %s", status, + wp->curl_errbuf); return (-1); } if (wp->response_time) - cc_submit_response_time (wp, CDTIME_T_TO_DOUBLE (cdtime() - start)); + cc_submit_response_time(wp, CDTIME_T_TO_DOUBLE(cdtime() - start)); if (wp->stats != NULL) - curl_stats_dispatch (wp->stats, wp->curl, hostname_g, "curl", wp->instance); + curl_stats_dispatch(wp->stats, wp->curl, hostname_g, "curl", wp->instance); - if(wp->response_code) - { + if (wp->response_code) { long response_code = 0; - status = curl_easy_getinfo(wp->curl, CURLINFO_RESPONSE_CODE, &response_code); - if(status != CURLE_OK) { - ERROR ("curl plugin: Fetching response code failed with status %i: %s", - status, wp->curl_errbuf); + status = + curl_easy_getinfo(wp->curl, CURLINFO_RESPONSE_CODE, &response_code); + if (status != CURLE_OK) { + ERROR("curl plugin: Fetching response code failed with status %i: %s", + status, wp->curl_errbuf); } else { cc_submit_response_code(wp, response_code); } } - for (web_match_t *wm = wp->matches; wm != NULL; wm = wm->next) - { + for (web_match_t *wm = wp->matches; wm != NULL; wm = wm->next) { cu_match_value_t *mv; - status = match_apply (wm->match, wp->buffer); - if (status != 0) - { - WARNING ("curl plugin: match_apply failed."); + status = match_apply(wm->match, wp->buffer); + if (status != 0) { + WARNING("curl plugin: match_apply failed."); continue; } - mv = match_get_user_data (wm->match); - if (mv == NULL) - { - WARNING ("curl plugin: match_get_user_data returned NULL."); + mv = match_get_user_data(wm->match); + if (mv == NULL) { + WARNING("curl plugin: match_get_user_data returned NULL."); continue; } - cc_submit (wp, wm, mv->value); - match_value_reset (mv); + cc_submit(wp, wm, mv->value); + match_value_reset(mv); } /* for (wm = wp->matches; wm != NULL; wm = wm->next) */ return (0); } /* }}} int cc_read_page */ -static int cc_read (void) /* {{{ */ +static int cc_read(void) /* {{{ */ { for (web_page_t *wp = pages_g; wp != NULL; wp = wp->next) - cc_read_page (wp); + cc_read_page(wp); return (0); } /* }}} int cc_read */ -static int cc_shutdown (void) /* {{{ */ +static int cc_shutdown(void) /* {{{ */ { - cc_web_page_free (pages_g); + cc_web_page_free(pages_g); pages_g = NULL; return (0); } /* }}} int cc_shutdown */ -void module_register (void) -{ - plugin_register_complex_config ("curl", cc_config); - plugin_register_init ("curl", cc_init); - plugin_register_read ("curl", cc_read); - plugin_register_shutdown ("curl", cc_shutdown); +void module_register(void) { + plugin_register_complex_config("curl", cc_config); + plugin_register_init("curl", cc_init); + plugin_register_read("curl", cc_read); + plugin_register_shutdown("curl", cc_shutdown); } /* void module_register */ /* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/curl_json.c b/src/curl_json.c index 4dab1abd..aa1ae797 100644 --- a/src/curl_json.c +++ b/src/curl_json.c @@ -36,18 +36,18 @@ #include #if HAVE_YAJL_YAJL_VERSION_H -# include +#include #endif #if defined(YAJL_MAJOR) && (YAJL_MAJOR > 1) -# define HAVE_YAJL_V2 1 +#define HAVE_YAJL_V2 1 #endif #define CJ_DEFAULT_HOST "localhost" #define CJ_KEY_MAGIC 0x43484b59UL /* CHKY */ #define CJ_IS_KEY(key) ((key)->magic == CJ_KEY_MAGIC) #define CJ_ANY "*" -#define COUCH_MIN(x,y) ((x) < (y) ? (x) : (y)) +#define COUCH_MIN(x, y) ((x) < (y) ? (x) : (y)) struct cj_key_s; typedef struct cj_key_s cj_key_t; @@ -106,12 +106,11 @@ typedef size_t yajl_len_t; typedef unsigned int yajl_len_t; #endif -static int cj_read (user_data_t *ud); -static void cj_submit (cj_t *db, cj_key_t *key, value_t *value); +static int cj_read(user_data_t *ud); +static void cj_submit(cj_t *db, cj_key_t *key, value_t *value); -static size_t cj_curl_callback (void *buf, /* {{{ */ - size_t size, size_t nmemb, void *user_data) -{ +static size_t cj_curl_callback(void *buf, /* {{{ */ + size_t size, size_t nmemb, void *user_data) { cj_t *db; size_t len; yajl_status status; @@ -133,40 +132,36 @@ static size_t cj_curl_callback (void *buf, /* {{{ */ return (len); #endif - unsigned char *msg = yajl_get_error(db->yajl, /* verbose = */ 1, - /* jsonText = */ (unsigned char *) buf, (unsigned int) len); - ERROR ("curl_json plugin: yajl_parse failed: %s", msg); + unsigned char *msg = + yajl_get_error(db->yajl, /* verbose = */ 1, + /* jsonText = */ (unsigned char *)buf, (unsigned int)len); + ERROR("curl_json plugin: yajl_parse failed: %s", msg); yajl_free_error(db->yajl, msg); return (0); /* abort write callback */ } /* }}} size_t cj_curl_callback */ -static int cj_get_type (cj_key_t *key) -{ +static int cj_get_type(cj_key_t *key) { const data_set_t *ds; - if ((key == NULL) || !CJ_IS_KEY (key)) + if ((key == NULL) || !CJ_IS_KEY(key)) return -EINVAL; - ds = plugin_get_ds (key->type); - if (ds == NULL) - { + ds = plugin_get_ds(key->type); + if (ds == NULL) { static char type[DATA_MAX_NAME_LEN] = "!!!invalid!!!"; - assert (key->type != NULL); - if (strcmp (type, key->type) != 0) - { - ERROR ("curl_json plugin: Unable to look up DS type \"%s\".", - key->type); - sstrncpy (type, key->type, sizeof (type)); + assert(key->type != NULL); + if (strcmp(type, key->type) != 0) { + ERROR("curl_json plugin: Unable to look up DS type \"%s\".", key->type); + sstrncpy(type, key->type, sizeof(type)); } return -1; - } - else if (ds->ds_num > 1) - { + } else if (ds->ds_num > 1) { static c_complain_t complaint = C_COMPLAIN_INIT_STATIC; - c_complain_once (LOG_WARNING, &complaint, + c_complain_once( + LOG_WARNING, &complaint, "curl_json plugin: The type \"%s\" has more than one data source. " "This is currently not supported. I will return the type of the " "first data source, but this will likely lead to problems later on.", @@ -176,11 +171,9 @@ static int cj_get_type (cj_key_t *key) return ds->ds[0].type; } -static int cj_cb_map_key (void *ctx, const unsigned char *val, - yajl_len_t len); +static int cj_cb_map_key(void *ctx, const unsigned char *val, yajl_len_t len); -static void cj_cb_inc_array_index (void *ctx, _Bool update_key) -{ +static void cj_cb_inc_array_index(void *ctx, _Bool update_key) { cj_t *db = (cj_t *)ctx; if (!db->state[db->depth].in_array) @@ -188,35 +181,30 @@ static void cj_cb_inc_array_index (void *ctx, _Bool update_key) db->state[db->depth].index++; - if (update_key) - { + if (update_key) { char name[DATA_MAX_NAME_LEN]; - ssnprintf (name, sizeof (name), "%d", db->state[db->depth].index - 1); + ssnprintf(name, sizeof(name), "%d", db->state[db->depth].index - 1); - cj_cb_map_key (ctx, (unsigned char *)name, (yajl_len_t) strlen (name)); + cj_cb_map_key(ctx, (unsigned char *)name, (yajl_len_t)strlen(name)); } } /* yajl callbacks */ -#define CJ_CB_ABORT 0 +#define CJ_CB_ABORT 0 #define CJ_CB_CONTINUE 1 -static int cj_cb_boolean (void * ctx, int boolVal) -{ - cj_cb_inc_array_index (ctx, /* update_key = */ 0); +static int cj_cb_boolean(void *ctx, int boolVal) { + cj_cb_inc_array_index(ctx, /* update_key = */ 0); return (CJ_CB_CONTINUE); } -static int cj_cb_null (void * ctx) -{ - cj_cb_inc_array_index (ctx, /* update_key = */ 0); +static int cj_cb_null(void *ctx) { + cj_cb_inc_array_index(ctx, /* update_key = */ 0); return (CJ_CB_CONTINUE); } -static int cj_cb_number (void *ctx, - const char *number, yajl_len_t number_len) -{ +static int cj_cb_number(void *ctx, const char *number, yajl_len_t number_len) { char buffer[number_len + 1]; cj_t *db = (cj_t *)ctx; @@ -226,77 +214,71 @@ static int cj_cb_number (void *ctx, int status; /* Create a null-terminated version of the string. */ - memcpy (buffer, number, number_len); - buffer[sizeof (buffer) - 1] = 0; - - if ((key == NULL) || !CJ_IS_KEY (key)) { - if (key != NULL && !db->state[db->depth].in_array/*can be inhomogeneous*/) { - NOTICE ("curl_json plugin: Found \"%s\", but the configuration expects" - " a map.", buffer); + memcpy(buffer, number, number_len); + buffer[sizeof(buffer) - 1] = 0; + + if ((key == NULL) || !CJ_IS_KEY(key)) { + if (key != NULL && + !db->state[db->depth].in_array /*can be inhomogeneous*/) { + NOTICE("curl_json plugin: Found \"%s\", but the configuration expects" + " a map.", + buffer); return (CJ_CB_CONTINUE); } - cj_cb_inc_array_index (ctx, /* update_key = */ 1); + cj_cb_inc_array_index(ctx, /* update_key = */ 1); key = db->state[db->depth].key; - if ((key == NULL) || !CJ_IS_KEY (key)) { + if ((key == NULL) || !CJ_IS_KEY(key)) { return (CJ_CB_CONTINUE); } - } - else - { - cj_cb_inc_array_index (ctx, /* update_key = */ 1); + } else { + cj_cb_inc_array_index(ctx, /* update_key = */ 1); } - type = cj_get_type (key); - status = parse_value (buffer, &vt, type); - if (status != 0) - { - NOTICE ("curl_json plugin: Unable to parse number: \"%s\"", buffer); + type = cj_get_type(key); + status = parse_value(buffer, &vt, type); + if (status != 0) { + NOTICE("curl_json plugin: Unable to parse number: \"%s\"", buffer); return (CJ_CB_CONTINUE); } - cj_submit (db, key, &vt); + cj_submit(db, key, &vt); return (CJ_CB_CONTINUE); } /* int cj_cb_number */ /* Queries the key-tree of the parent context for "in_name" and, if found, * updates the "key" field of the current context. Otherwise, "key" is set to * NULL. */ -static int cj_cb_map_key (void *ctx, - unsigned char const *in_name, yajl_len_t in_name_len) -{ +static int cj_cb_map_key(void *ctx, unsigned char const *in_name, + yajl_len_t in_name_len) { cj_t *db = (cj_t *)ctx; c_avl_tree_t *tree; - tree = db->state[db->depth-1].tree; + tree = db->state[db->depth - 1].tree; - if (tree != NULL) - { + if (tree != NULL) { cj_key_t *value = NULL; char *name; size_t name_len; /* Create a null-terminated version of the name. */ name = db->state[db->depth].name; - name_len = COUCH_MIN ((size_t) in_name_len, - sizeof (db->state[db->depth].name) - 1); - memcpy (name, in_name, name_len); + name_len = + COUCH_MIN((size_t)in_name_len, sizeof(db->state[db->depth].name) - 1); + memcpy(name, in_name, name_len); name[name_len] = 0; - if (c_avl_get (tree, name, (void *) &value) == 0) { - if (CJ_IS_KEY((cj_key_t*)value)) { + if (c_avl_get(tree, name, (void *)&value) == 0) { + if (CJ_IS_KEY((cj_key_t *)value)) { db->state[db->depth].key = value; + } else { + db->state[db->depth].tree = (c_avl_tree_t *)value; } - else { - db->state[db->depth].tree = (c_avl_tree_t*) value; - } - } - else if (c_avl_get (tree, CJ_ANY, (void *) &value) == 0) - if (CJ_IS_KEY((cj_key_t*)value)) { + } else if (c_avl_get(tree, CJ_ANY, (void *)&value) == 0) + if (CJ_IS_KEY((cj_key_t *)value)) { db->state[db->depth].key = value; - } - else { - db->state[db->depth].tree = (c_avl_tree_t*) value; + } else { + db->state[db->depth].tree = (c_avl_tree_t *)value; } else db->state[db->depth].key = NULL; @@ -305,160 +287,140 @@ static int cj_cb_map_key (void *ctx, return (CJ_CB_CONTINUE); } -static int cj_cb_string (void *ctx, const unsigned char *val, - yajl_len_t len) -{ +static int cj_cb_string(void *ctx, const unsigned char *val, yajl_len_t len) { /* Handle the string as if it was a number. */ - return (cj_cb_number (ctx, (const char *) val, len)); + return (cj_cb_number(ctx, (const char *)val, len)); } /* int cj_cb_string */ -static int cj_cb_start (void *ctx) -{ +static int cj_cb_start(void *ctx) { cj_t *db = (cj_t *)ctx; - if (++db->depth >= YAJL_MAX_DEPTH) - { - ERROR ("curl_json plugin: %s depth exceeds max, aborting.", - db->url ? db->url : db->sock); + if (++db->depth >= YAJL_MAX_DEPTH) { + ERROR("curl_json plugin: %s depth exceeds max, aborting.", + db->url ? db->url : db->sock); return (CJ_CB_ABORT); } return (CJ_CB_CONTINUE); } -static int cj_cb_end (void *ctx) -{ +static int cj_cb_end(void *ctx) { cj_t *db = (cj_t *)ctx; db->state[db->depth].tree = NULL; --db->depth; return (CJ_CB_CONTINUE); } -static int cj_cb_start_map (void *ctx) -{ - cj_cb_inc_array_index (ctx, /* update_key = */ 1); - return cj_cb_start (ctx); +static int cj_cb_start_map(void *ctx) { + cj_cb_inc_array_index(ctx, /* update_key = */ 1); + return cj_cb_start(ctx); } -static int cj_cb_end_map (void *ctx) -{ - return cj_cb_end (ctx); -} +static int cj_cb_end_map(void *ctx) { return cj_cb_end(ctx); } -static int cj_cb_start_array (void * ctx) -{ +static int cj_cb_start_array(void *ctx) { cj_t *db = (cj_t *)ctx; - cj_cb_inc_array_index (ctx, /* update_key = */ 1); - if (db->depth+1 < YAJL_MAX_DEPTH) { - db->state[db->depth+1].in_array = 1; - db->state[db->depth+1].index = 0; + cj_cb_inc_array_index(ctx, /* update_key = */ 1); + if (db->depth + 1 < YAJL_MAX_DEPTH) { + db->state[db->depth + 1].in_array = 1; + db->state[db->depth + 1].index = 0; } - return cj_cb_start (ctx); + return cj_cb_start(ctx); } -static int cj_cb_end_array (void * ctx) -{ +static int cj_cb_end_array(void *ctx) { cj_t *db = (cj_t *)ctx; db->state[db->depth].in_array = 0; - return cj_cb_end (ctx); + return cj_cb_end(ctx); } static yajl_callbacks ycallbacks = { - cj_cb_null, /* null */ - cj_cb_boolean, /* boolean */ - NULL, /* integer */ - NULL, /* double */ - cj_cb_number, - cj_cb_string, - cj_cb_start_map, - cj_cb_map_key, - cj_cb_end_map, - cj_cb_start_array, - cj_cb_end_array -}; + cj_cb_null, /* null */ + cj_cb_boolean, /* boolean */ + NULL, /* integer */ + NULL, /* double */ + cj_cb_number, cj_cb_string, cj_cb_start_map, cj_cb_map_key, + cj_cb_end_map, cj_cb_start_array, cj_cb_end_array}; /* end yajl callbacks */ -static void cj_key_free (cj_key_t *key) /* {{{ */ +static void cj_key_free(cj_key_t *key) /* {{{ */ { if (key == NULL) return; - sfree (key->path); - sfree (key->type); - sfree (key->instance); + sfree(key->path); + sfree(key->type); + sfree(key->instance); - sfree (key); + sfree(key); } /* }}} void cj_key_free */ -static void cj_tree_free (c_avl_tree_t *tree) /* {{{ */ +static void cj_tree_free(c_avl_tree_t *tree) /* {{{ */ { char *name; void *value; - while (c_avl_pick (tree, (void *) &name, (void *) &value) == 0) - { + while (c_avl_pick(tree, (void *)&name, (void *)&value) == 0) { cj_key_t *key = (cj_key_t *)value; if (CJ_IS_KEY(key)) - cj_key_free (key); + cj_key_free(key); else - cj_tree_free ((c_avl_tree_t *)value); + cj_tree_free((c_avl_tree_t *)value); - sfree (name); + sfree(name); } - c_avl_destroy (tree); + c_avl_destroy(tree); } /* }}} void cj_tree_free */ -static void cj_free (void *arg) /* {{{ */ +static void cj_free(void *arg) /* {{{ */ { cj_t *db; - DEBUG ("curl_json plugin: cj_free (arg = %p);", arg); + DEBUG("curl_json plugin: cj_free (arg = %p);", arg); - db = (cj_t *) arg; + db = (cj_t *)arg; if (db == NULL) return; if (db->curl != NULL) - curl_easy_cleanup (db->curl); + curl_easy_cleanup(db->curl); db->curl = NULL; if (db->tree != NULL) - cj_tree_free (db->tree); + cj_tree_free(db->tree); db->tree = NULL; - sfree (db->instance); - sfree (db->host); + sfree(db->instance); + sfree(db->host); - sfree (db->sock); + sfree(db->sock); - sfree (db->url); - sfree (db->user); - sfree (db->pass); - sfree (db->credentials); - sfree (db->cacert); - sfree (db->post_body); - curl_slist_free_all (db->headers); - curl_stats_destroy (db->stats); + sfree(db->url); + sfree(db->user); + sfree(db->pass); + sfree(db->credentials); + sfree(db->cacert); + sfree(db->post_body); + curl_slist_free_all(db->headers); + curl_stats_destroy(db->stats); - sfree (db); + sfree(db); } /* }}} void cj_free */ /* Configuration handling functions {{{ */ -static c_avl_tree_t *cj_avl_create(void) -{ - return c_avl_create ((int (*) (const void *, const void *)) strcmp); +static c_avl_tree_t *cj_avl_create(void) { + return c_avl_create((int (*)(const void *, const void *))strcmp); } -static int cj_config_append_string (const char *name, struct curl_slist **dest, /* {{{ */ - oconfig_item_t *ci) -{ +static int cj_config_append_string(const char *name, + struct curl_slist **dest, /* {{{ */ + oconfig_item_t *ci) { struct curl_slist *temp = NULL; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("curl_json plugin: `%s' needs exactly one string argument.", name); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("curl_json plugin: `%s' needs exactly one string argument.", name); return (-1); } @@ -471,57 +433,48 @@ static int cj_config_append_string (const char *name, struct curl_slist **dest, return (0); } /* }}} int cj_config_append_string */ -static int cj_config_add_key (cj_t *db, /* {{{ */ - oconfig_item_t *ci) -{ +static int cj_config_add_key(cj_t *db, /* {{{ */ + oconfig_item_t *ci) { cj_key_t *key; int status; - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("curl_json plugin: The `Key' block " - "needs exactly one string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("curl_json plugin: The `Key' block " + "needs exactly one string argument."); return (-1); } - key = calloc (1, sizeof (*key)); - if (key == NULL) - { - ERROR ("curl_json plugin: calloc failed."); + key = calloc(1, sizeof(*key)); + if (key == NULL) { + ERROR("curl_json plugin: calloc failed."); return (-1); } key->magic = CJ_KEY_MAGIC; - if (strcasecmp ("Key", ci->key) == 0) - { - status = cf_util_get_string (ci, &key->path); - if (status != 0) - { - sfree (key); + if (strcasecmp("Key", ci->key) == 0) { + status = cf_util_get_string(ci, &key->path); + if (status != 0) { + sfree(key); return (status); } - } - else - { - ERROR ("curl_json plugin: cj_config: " - "Invalid key: %s", ci->key); - cj_key_free (key); + } else { + ERROR("curl_json plugin: cj_config: " + "Invalid key: %s", + ci->key); + cj_key_free(key); return (-1); } status = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Type", child->key) == 0) - status = cf_util_get_string (child, &key->type); - else if (strcasecmp ("Instance", child->key) == 0) - status = cf_util_get_string (child, &key->instance); - else - { - WARNING ("curl_json plugin: Option `%s' not allowed here.", child->key); + if (strcasecmp("Type", child->key) == 0) + status = cf_util_get_string(child, &key->type); + else if (strcasecmp("Instance", child->key) == 0) + status = cf_util_get_string(child, &key->instance); + else { + WARNING("curl_json plugin: Option `%s' not allowed here.", child->key); status = -1; } @@ -529,16 +482,14 @@ static int cj_config_add_key (cj_t *db, /* {{{ */ break; } /* for (i = 0; i < ci->children_num; i++) */ - if (status != 0) - { - cj_key_free (key); + if (status != 0) { + cj_key_free(key); return (-1); } - if (key->type == NULL) - { - WARNING ("curl_json plugin: `Type' missing in `Key' block."); - cj_key_free (key); + if (key->type == NULL) { + WARNING("curl_json plugin: `Type' missing in `Key' block."); + cj_key_free(key); return (-1); } @@ -560,8 +511,7 @@ static int cj_config_add_key (cj_t *db, /* {{{ */ ++ptr; name = ptr; - while ((ptr = strchr (name, '/')) != NULL) - { + while ((ptr = strchr(name, '/')) != NULL) { char ent[PATH_MAX]; c_avl_tree_t *value; size_t len; @@ -570,178 +520,166 @@ static int cj_config_add_key (cj_t *db, /* {{{ */ if (len == 0) break; - len = COUCH_MIN(len, sizeof (ent)-1); - sstrncpy (ent, name, len+1); + len = COUCH_MIN(len, sizeof(ent) - 1); + sstrncpy(ent, name, len + 1); - if (c_avl_get (tree, ent, (void *) &value) != 0) - { - value = cj_avl_create (); - c_avl_insert (tree, strdup (ent), value); + if (c_avl_get(tree, ent, (void *)&value) != 0) { + value = cj_avl_create(); + c_avl_insert(tree, strdup(ent), value); } tree = value; name = ptr + 1; } - if (strlen (name) == 0) - { - ERROR ("curl_json plugin: invalid key: %s", key->path); - cj_key_free (key); + if (strlen(name) == 0) { + ERROR("curl_json plugin: invalid key: %s", key->path); + cj_key_free(key); return (-1); } - c_avl_insert (tree, strdup (name), key); + c_avl_insert(tree, strdup(name), key); return (status); } /* }}} int cj_config_add_key */ -static int cj_init_curl (cj_t *db) /* {{{ */ +static int cj_init_curl(cj_t *db) /* {{{ */ { - db->curl = curl_easy_init (); - if (db->curl == NULL) - { - ERROR ("curl_json plugin: curl_easy_init failed."); + db->curl = curl_easy_init(); + if (db->curl == NULL) { + ERROR("curl_json plugin: curl_easy_init failed."); return (-1); } - curl_easy_setopt (db->curl, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt (db->curl, CURLOPT_WRITEFUNCTION, cj_curl_callback); - curl_easy_setopt (db->curl, CURLOPT_WRITEDATA, db); - curl_easy_setopt (db->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); - curl_easy_setopt (db->curl, CURLOPT_ERRORBUFFER, db->curl_errbuf); - curl_easy_setopt (db->curl, CURLOPT_URL, db->url); - curl_easy_setopt (db->curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt (db->curl, CURLOPT_MAXREDIRS, 50L); - - if (db->user != NULL) - { + curl_easy_setopt(db->curl, CURLOPT_NOSIGNAL, 1L); + curl_easy_setopt(db->curl, CURLOPT_WRITEFUNCTION, cj_curl_callback); + curl_easy_setopt(db->curl, CURLOPT_WRITEDATA, db); + curl_easy_setopt(db->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); + curl_easy_setopt(db->curl, CURLOPT_ERRORBUFFER, db->curl_errbuf); + curl_easy_setopt(db->curl, CURLOPT_URL, db->url); + curl_easy_setopt(db->curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(db->curl, CURLOPT_MAXREDIRS, 50L); + + if (db->user != NULL) { #ifdef HAVE_CURLOPT_USERNAME - curl_easy_setopt (db->curl, CURLOPT_USERNAME, db->user); - curl_easy_setopt (db->curl, CURLOPT_PASSWORD, - (db->pass == NULL) ? "" : db->pass); + curl_easy_setopt(db->curl, CURLOPT_USERNAME, db->user); + curl_easy_setopt(db->curl, CURLOPT_PASSWORD, + (db->pass == NULL) ? "" : db->pass); #else size_t credentials_size; - credentials_size = strlen (db->user) + 2; + credentials_size = strlen(db->user) + 2; if (db->pass != NULL) - credentials_size += strlen (db->pass); + credentials_size += strlen(db->pass); - db->credentials = malloc (credentials_size); - if (db->credentials == NULL) - { - ERROR ("curl_json plugin: malloc failed."); + db->credentials = malloc(credentials_size); + if (db->credentials == NULL) { + ERROR("curl_json plugin: malloc failed."); return (-1); } - ssnprintf (db->credentials, credentials_size, "%s:%s", - db->user, (db->pass == NULL) ? "" : db->pass); - curl_easy_setopt (db->curl, CURLOPT_USERPWD, db->credentials); + ssnprintf(db->credentials, credentials_size, "%s:%s", db->user, + (db->pass == NULL) ? "" : db->pass); + curl_easy_setopt(db->curl, CURLOPT_USERPWD, db->credentials); #endif if (db->digest) - curl_easy_setopt (db->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); + curl_easy_setopt(db->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); } - curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYPEER, (long) db->verify_peer); - curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYHOST, - db->verify_host ? 2L : 0L); + curl_easy_setopt(db->curl, CURLOPT_SSL_VERIFYPEER, (long)db->verify_peer); + curl_easy_setopt(db->curl, CURLOPT_SSL_VERIFYHOST, db->verify_host ? 2L : 0L); if (db->cacert != NULL) - curl_easy_setopt (db->curl, CURLOPT_CAINFO, db->cacert); + curl_easy_setopt(db->curl, CURLOPT_CAINFO, db->cacert); if (db->headers != NULL) - curl_easy_setopt (db->curl, CURLOPT_HTTPHEADER, db->headers); + curl_easy_setopt(db->curl, CURLOPT_HTTPHEADER, db->headers); if (db->post_body != NULL) - curl_easy_setopt (db->curl, CURLOPT_POSTFIELDS, db->post_body); + curl_easy_setopt(db->curl, CURLOPT_POSTFIELDS, db->post_body); #ifdef HAVE_CURLOPT_TIMEOUT_MS if (db->timeout >= 0) - curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) db->timeout); + curl_easy_setopt(db->curl, CURLOPT_TIMEOUT_MS, (long)db->timeout); else if (db->interval > 0) - curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(db->timeout)); + curl_easy_setopt(db->curl, CURLOPT_TIMEOUT_MS, + (long)CDTIME_T_TO_MS(db->timeout)); else - curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval())); + curl_easy_setopt(db->curl, CURLOPT_TIMEOUT_MS, + (long)CDTIME_T_TO_MS(plugin_get_interval())); #endif return (0); } /* }}} int cj_init_curl */ -static int cj_config_add_url (oconfig_item_t *ci) /* {{{ */ +static int cj_config_add_url(oconfig_item_t *ci) /* {{{ */ { cj_t *db; int status = 0; - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("curl_json plugin: The `URL' block " - "needs exactly one string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("curl_json plugin: The `URL' block " + "needs exactly one string argument."); return (-1); } - db = calloc (1, sizeof (*db)); - if (db == NULL) - { - ERROR ("curl_json plugin: calloc failed."); + db = calloc(1, sizeof(*db)); + if (db == NULL) { + ERROR("curl_json plugin: calloc failed."); return (-1); } db->timeout = -1; - if (strcasecmp ("URL", ci->key) == 0) - status = cf_util_get_string (ci, &db->url); - else if (strcasecmp ("Sock", ci->key) == 0) - status = cf_util_get_string (ci, &db->sock); - else - { - ERROR ("curl_json plugin: cj_config: " - "Invalid key: %s", ci->key); - cj_free (db); + if (strcasecmp("URL", ci->key) == 0) + status = cf_util_get_string(ci, &db->url); + else if (strcasecmp("Sock", ci->key) == 0) + status = cf_util_get_string(ci, &db->sock); + else { + ERROR("curl_json plugin: cj_config: " + "Invalid key: %s", + ci->key); + cj_free(db); return (-1); } - if (status != 0) - { - sfree (db); + if (status != 0) { + sfree(db); return (status); } /* Fill the `cj_t' structure.. */ - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Instance", child->key) == 0) - status = cf_util_get_string (child, &db->instance); - else if (strcasecmp ("Host", child->key) == 0) - status = cf_util_get_string (child, &db->host); - else if (db->url && strcasecmp ("User", child->key) == 0) - status = cf_util_get_string (child, &db->user); - else if (db->url && strcasecmp ("Password", child->key) == 0) - status = cf_util_get_string (child, &db->pass); - else if (strcasecmp ("Digest", child->key) == 0) - status = cf_util_get_boolean (child, &db->digest); - else if (db->url && strcasecmp ("VerifyPeer", child->key) == 0) - status = cf_util_get_boolean (child, &db->verify_peer); - else if (db->url && strcasecmp ("VerifyHost", child->key) == 0) - status = cf_util_get_boolean (child, &db->verify_host); - else if (db->url && strcasecmp ("CACert", child->key) == 0) - status = cf_util_get_string (child, &db->cacert); - else if (db->url && strcasecmp ("Header", child->key) == 0) - status = cj_config_append_string ("Header", &db->headers, child); - else if (db->url && strcasecmp ("Post", child->key) == 0) - status = cf_util_get_string (child, &db->post_body); - else if (strcasecmp ("Key", child->key) == 0) - status = cj_config_add_key (db, child); - else if (strcasecmp ("Interval", child->key) == 0) + if (strcasecmp("Instance", child->key) == 0) + status = cf_util_get_string(child, &db->instance); + else if (strcasecmp("Host", child->key) == 0) + status = cf_util_get_string(child, &db->host); + else if (db->url && strcasecmp("User", child->key) == 0) + status = cf_util_get_string(child, &db->user); + else if (db->url && strcasecmp("Password", child->key) == 0) + status = cf_util_get_string(child, &db->pass); + else if (strcasecmp("Digest", child->key) == 0) + status = cf_util_get_boolean(child, &db->digest); + else if (db->url && strcasecmp("VerifyPeer", child->key) == 0) + status = cf_util_get_boolean(child, &db->verify_peer); + else if (db->url && strcasecmp("VerifyHost", child->key) == 0) + status = cf_util_get_boolean(child, &db->verify_host); + else if (db->url && strcasecmp("CACert", child->key) == 0) + status = cf_util_get_string(child, &db->cacert); + else if (db->url && strcasecmp("Header", child->key) == 0) + status = cj_config_append_string("Header", &db->headers, child); + else if (db->url && strcasecmp("Post", child->key) == 0) + status = cf_util_get_string(child, &db->post_body); + else if (strcasecmp("Key", child->key) == 0) + status = cj_config_add_key(db, child); + else if (strcasecmp("Interval", child->key) == 0) status = cf_util_get_cdtime(child, &db->interval); - else if (strcasecmp ("Timeout", child->key) == 0) - status = cf_util_get_int (child, &db->timeout); - else if (strcasecmp ("Statistics", child->key) == 0) - { - db->stats = curl_stats_from_config (child); + else if (strcasecmp("Timeout", child->key) == 0) + status = cf_util_get_int(child, &db->timeout); + else if (strcasecmp("Statistics", child->key) == 0) { + db->stats = curl_stats_from_config(child); if (db->stats == NULL) status = -1; - } - else - { - WARNING ("curl_json plugin: Option `%s' not allowed here.", child->key); + } else { + WARNING("curl_json plugin: Option `%s' not allowed here.", child->key); status = -1; } @@ -749,51 +687,44 @@ static int cj_config_add_url (oconfig_item_t *ci) /* {{{ */ break; } - if (status == 0) - { - if (db->tree == NULL) - { - WARNING ("curl_json plugin: No (valid) `Key' block within `%s' \"`%s'\".", - db->url ? "URL" : "Sock", db->url ? db->url : db->sock); + if (status == 0) { + if (db->tree == NULL) { + WARNING("curl_json plugin: No (valid) `Key' block within `%s' \"`%s'\".", + db->url ? "URL" : "Sock", db->url ? db->url : db->sock); status = -1; } if (status == 0 && db->url) - status = cj_init_curl (db); + status = cj_init_curl(db); } /* If all went well, register this database for reading */ - if (status == 0) - { + if (status == 0) { char *cb_name; if (db->instance == NULL) db->instance = strdup("default"); - DEBUG ("curl_json plugin: Registering new read callback: %s", - db->instance); + DEBUG("curl_json plugin: Registering new read callback: %s", db->instance); - cb_name = ssnprintf_alloc ("curl_json-%s-%s", - db->instance, db->url ? db->url : db->sock); + cb_name = ssnprintf_alloc("curl_json-%s-%s", db->instance, + db->url ? db->url : db->sock); - plugin_register_complex_read (/* group = */ NULL, cb_name, cj_read, - /* interval = */ db->interval, - &(user_data_t) { - .data = db, - .free_func = cj_free, - }); - sfree (cb_name); - } - else - { - cj_free (db); + plugin_register_complex_read(/* group = */ NULL, cb_name, cj_read, + /* interval = */ db->interval, + &(user_data_t){ + .data = db, .free_func = cj_free, + }); + sfree(cb_name); + } else { + cj_free(db); return (-1); } return (0); } - /* }}} int cj_config_add_database */ +/* }}} int cj_config_add_database */ -static int cj_config (oconfig_item_t *ci) /* {{{ */ +static int cj_config(oconfig_item_t *ci) /* {{{ */ { int success; int errors; @@ -802,29 +733,24 @@ static int cj_config (oconfig_item_t *ci) /* {{{ */ success = 0; errors = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Sock", child->key) == 0 - || strcasecmp ("URL", child->key) == 0) - { - status = cj_config_add_url (child); + if (strcasecmp("Sock", child->key) == 0 || + strcasecmp("URL", child->key) == 0) { + status = cj_config_add_url(child); if (status == 0) success++; else errors++; - } - else - { - WARNING ("curl_json plugin: Option `%s' not allowed here.", child->key); + } else { + WARNING("curl_json plugin: Option `%s' not allowed here.", child->key); errors++; } } - if ((success == 0) && (errors > 0)) - { - ERROR ("curl_json plugin: All statements failed."); + if ((success == 0) && (errors > 0)) { + ERROR("curl_json plugin: All statements failed."); return (-1); } @@ -833,81 +759,76 @@ static int cj_config (oconfig_item_t *ci) /* {{{ */ /* }}} End of configuration handling functions */ -static const char *cj_host (cj_t *db) /* {{{ */ +static const char *cj_host(cj_t *db) /* {{{ */ { - if ((db->host == NULL) - || (strcmp ("", db->host) == 0) - || (strcmp (CJ_DEFAULT_HOST, db->host) == 0)) + if ((db->host == NULL) || (strcmp("", db->host) == 0) || + (strcmp(CJ_DEFAULT_HOST, db->host) == 0)) return hostname_g; return db->host; } /* }}} cj_host */ -static void cj_submit (cj_t *db, cj_key_t *key, value_t *value) /* {{{ */ +static void cj_submit(cj_t *db, cj_key_t *key, value_t *value) /* {{{ */ { value_list_t vl = VALUE_LIST_INIT; - vl.values = value; + vl.values = value; vl.values_len = 1; - if (key->instance == NULL) - { + if (key->instance == NULL) { int len = 0; for (int i = 0; i < db->depth; i++) - len += ssnprintf(vl.type_instance+len, sizeof(vl.type_instance)-len, - i ? "-%s" : "%s", db->state[i+1].name); - } - else - sstrncpy (vl.type_instance, key->instance, sizeof (vl.type_instance)); + len += ssnprintf(vl.type_instance + len, sizeof(vl.type_instance) - len, + i ? "-%s" : "%s", db->state[i + 1].name); + } else + sstrncpy(vl.type_instance, key->instance, sizeof(vl.type_instance)); - sstrncpy (vl.host, cj_host (db), sizeof (vl.host)); - sstrncpy (vl.plugin, "curl_json", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, db->instance, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, key->type, sizeof (vl.type)); + sstrncpy(vl.host, cj_host(db), sizeof(vl.host)); + sstrncpy(vl.plugin, "curl_json", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, db->instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, key->type, sizeof(vl.type)); if (db->interval > 0) vl.interval = db->interval; - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* }}} int cj_submit */ -static int cj_sock_perform (cj_t *db) /* {{{ */ +static int cj_sock_perform(cj_t *db) /* {{{ */ { char errbuf[1024]; - struct sockaddr_un sa_unix = { 0 }; + struct sockaddr_un sa_unix = {0}; sa_unix.sun_family = AF_UNIX; - sstrncpy (sa_unix.sun_path, db->sock, sizeof (sa_unix.sun_path)); + sstrncpy(sa_unix.sun_path, db->sock, sizeof(sa_unix.sun_path)); - int fd = socket (AF_UNIX, SOCK_STREAM, 0); + int fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) return (-1); - if (connect (fd, (struct sockaddr *)&sa_unix, sizeof(sa_unix)) < 0) - { - ERROR ("curl_json plugin: connect(%s) failed: %s", - (db->sock != NULL) ? db->sock : "", - sstrerror(errno, errbuf, sizeof (errbuf))); - close (fd); + if (connect(fd, (struct sockaddr *)&sa_unix, sizeof(sa_unix)) < 0) { + ERROR("curl_json plugin: connect(%s) failed: %s", + (db->sock != NULL) ? db->sock : "", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(fd); return (-1); } ssize_t red; do { unsigned char buffer[4096]; - red = read (fd, buffer, sizeof(buffer)); + red = read(fd, buffer, sizeof(buffer)); if (red < 0) { - ERROR ("curl_json plugin: read(%s) failed: %s", - (db->sock != NULL) ? db->sock : "", - sstrerror(errno, errbuf, sizeof (errbuf))); - close (fd); - return (-1); + ERROR("curl_json plugin: read(%s) failed: %s", + (db->sock != NULL) ? db->sock : "", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(fd); + return (-1); } - if (!cj_curl_callback (buffer, red, 1, db)) - break; + if (!cj_curl_callback(buffer, red, 1, db)) + break; } while (red > 0); - close (fd); + close(fd); return (0); } /* }}} int cj_sock_perform */ - static int cj_curl_perform(cj_t *db) /* {{{ */ { int status; @@ -915,55 +836,53 @@ static int cj_curl_perform(cj_t *db) /* {{{ */ char *url; url = db->url; - status = curl_easy_perform (db->curl); - if (status != CURLE_OK) - { - ERROR ("curl_json plugin: curl_easy_perform failed with status %i: %s (%s)", - status, db->curl_errbuf, url); + status = curl_easy_perform(db->curl); + if (status != CURLE_OK) { + ERROR("curl_json plugin: curl_easy_perform failed with status %i: %s (%s)", + status, db->curl_errbuf, url); return (-1); } if (db->stats != NULL) - curl_stats_dispatch (db->stats, db->curl, cj_host (db), "curl_json", db->instance); + curl_stats_dispatch(db->stats, db->curl, cj_host(db), "curl_json", + db->instance); curl_easy_getinfo(db->curl, CURLINFO_EFFECTIVE_URL, &url); curl_easy_getinfo(db->curl, CURLINFO_RESPONSE_CODE, &rc); /* The response code is zero if a non-HTTP transport was used. */ - if ((rc != 0) && (rc != 200)) - { - ERROR ("curl_json plugin: curl_easy_perform failed with " - "response code %ld (%s)", rc, url); + if ((rc != 0) && (rc != 200)) { + ERROR("curl_json plugin: curl_easy_perform failed with " + "response code %ld (%s)", + rc, url); return (-1); } return (0); } /* }}} int cj_curl_perform */ -static int cj_perform (cj_t *db) /* {{{ */ +static int cj_perform(cj_t *db) /* {{{ */ { int status; yajl_handle yprev = db->yajl; - db->yajl = yajl_alloc (&ycallbacks, + db->yajl = yajl_alloc(&ycallbacks, #if HAVE_YAJL_V2 - /* alloc funcs = */ NULL, + /* alloc funcs = */ NULL, #else - /* alloc funcs = */ NULL, NULL, + /* alloc funcs = */ NULL, NULL, #endif - /* context = */ (void *)db); - if (db->yajl == NULL) - { - ERROR ("curl_json plugin: yajl_alloc failed."); + /* context = */ (void *)db); + if (db->yajl == NULL) { + ERROR("curl_json plugin: yajl_alloc failed."); db->yajl = yprev; return (-1); } if (db->url) - status = cj_curl_perform (db); + status = cj_curl_perform(db); else - status = cj_sock_perform (db); - if (status < 0) - { - yajl_free (db->yajl); + status = cj_sock_perform(db); + if (status < 0) { + yajl_free(db->yajl); db->yajl = yprev; return (-1); } @@ -973,57 +892,53 @@ static int cj_perform (cj_t *db) /* {{{ */ #else status = yajl_parse_complete(db->yajl); #endif - if (status != yajl_status_ok) - { + if (status != yajl_status_ok) { unsigned char *errmsg; - errmsg = yajl_get_error (db->yajl, /* verbose = */ 0, - /* jsonText = */ NULL, /* jsonTextLen = */ 0); - ERROR ("curl_json plugin: yajl_parse_complete failed: %s", - (char *) errmsg); - yajl_free_error (db->yajl, errmsg); - yajl_free (db->yajl); + errmsg = yajl_get_error(db->yajl, /* verbose = */ 0, + /* jsonText = */ NULL, /* jsonTextLen = */ 0); + ERROR("curl_json plugin: yajl_parse_complete failed: %s", (char *)errmsg); + yajl_free_error(db->yajl, errmsg); + yajl_free(db->yajl); db->yajl = yprev; return (-1); } - yajl_free (db->yajl); + yajl_free(db->yajl); db->yajl = yprev; return (0); } /* }}} int cj_perform */ -static int cj_read (user_data_t *ud) /* {{{ */ +static int cj_read(user_data_t *ud) /* {{{ */ { cj_t *db; - if ((ud == NULL) || (ud->data == NULL)) - { - ERROR ("curl_json plugin: cj_read: Invalid user data."); + if ((ud == NULL) || (ud->data == NULL)) { + ERROR("curl_json plugin: cj_read: Invalid user data."); return (-1); } - db = (cj_t *) ud->data; + db = (cj_t *)ud->data; db->depth = 0; - memset (&db->state, 0, sizeof(db->state)); + memset(&db->state, 0, sizeof(db->state)); db->state[db->depth].tree = db->tree; db->key = NULL; - return cj_perform (db); + return cj_perform(db); } /* }}} int cj_read */ -static int cj_init (void) /* {{{ */ +static int cj_init(void) /* {{{ */ { /* Call this while collectd is still single-threaded to avoid * initialization issues in libgcrypt. */ - curl_global_init (CURL_GLOBAL_SSL); + curl_global_init(CURL_GLOBAL_SSL); return (0); } /* }}} int cj_init */ -void module_register (void) -{ - plugin_register_complex_config ("curl_json", cj_config); - plugin_register_init ("curl_json", cj_init); +void module_register(void) { + plugin_register_complex_config("curl_json", cj_config); + plugin_register_init("curl_json", cj_init); } /* void module_register */ /* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/curl_xml.c b/src/curl_xml.c index 924665c7..4e4c6f99 100644 --- a/src/curl_xml.c +++ b/src/curl_xml.c @@ -102,133 +102,125 @@ typedef struct cx_s cx_t; /* }}} */ /* * Private functions */ -static size_t cx_curl_callback (void *buf, /* {{{ */ - size_t size, size_t nmemb, void *user_data) -{ +static size_t cx_curl_callback(void *buf, /* {{{ */ + size_t size, size_t nmemb, void *user_data) { size_t len = size * nmemb; cx_t *db; db = user_data; - if (db == NULL) - { - ERROR ("curl_xml plugin: cx_curl_callback: " - "user_data pointer is NULL."); + if (db == NULL) { + ERROR("curl_xml plugin: cx_curl_callback: " + "user_data pointer is NULL."); return (0); } if (len == 0) return (len); - if ((db->buffer_fill + len) >= db->buffer_size) - { + if ((db->buffer_fill + len) >= db->buffer_size) { char *temp; - temp = realloc (db->buffer, - db->buffer_fill + len + 1); - if (temp == NULL) - { - ERROR ("curl_xml plugin: realloc failed."); + temp = realloc(db->buffer, db->buffer_fill + len + 1); + if (temp == NULL) { + ERROR("curl_xml plugin: realloc failed."); return (0); } db->buffer = temp; db->buffer_size = db->buffer_fill + len + 1; } - memcpy (db->buffer + db->buffer_fill, (char *) buf, len); + memcpy(db->buffer + db->buffer_fill, (char *)buf, len); db->buffer_fill += len; db->buffer[db->buffer_fill] = 0; return (len); } /* }}} size_t cx_curl_callback */ -static void cx_xpath_free (cx_xpath_t *xpath) /* {{{ */ +static void cx_xpath_free(cx_xpath_t *xpath) /* {{{ */ { if (xpath == NULL) return; - sfree (xpath->path); - sfree (xpath->type); - sfree (xpath->instance_prefix); - sfree (xpath->instance); - sfree (xpath->values); - sfree (xpath); + sfree(xpath->path); + sfree(xpath->type); + sfree(xpath->instance_prefix); + sfree(xpath->instance); + sfree(xpath->values); + sfree(xpath); } /* }}} void cx_xpath_free */ -static void cx_list_free (llist_t *list) /* {{{ */ +static void cx_list_free(llist_t *list) /* {{{ */ { llentry_t *le; - le = llist_head (list); - while (le != NULL) - { + le = llist_head(list); + while (le != NULL) { llentry_t *le_next; le_next = le->next; - sfree (le->key); - cx_xpath_free (le->value); + sfree(le->key); + cx_xpath_free(le->value); le = le_next; } - llist_destroy (list); + llist_destroy(list); } /* }}} void cx_list_free */ -static void cx_free (void *arg) /* {{{ */ +static void cx_free(void *arg) /* {{{ */ { cx_t *db; - DEBUG ("curl_xml plugin: cx_free (arg = %p);", arg); + DEBUG("curl_xml plugin: cx_free (arg = %p);", arg); - db = (cx_t *) arg; + db = (cx_t *)arg; if (db == NULL) return; if (db->curl != NULL) - curl_easy_cleanup (db->curl); + curl_easy_cleanup(db->curl); db->curl = NULL; if (db->list != NULL) - cx_list_free (db->list); - - sfree (db->buffer); - sfree (db->instance); - sfree (db->host); - - sfree (db->url); - sfree (db->user); - sfree (db->pass); - sfree (db->credentials); - sfree (db->cacert); - sfree (db->post_body); - curl_slist_free_all (db->headers); - curl_stats_destroy (db->stats); - - for (size_t i = 0; i < db->namespaces_num; i++) - { - sfree (db->namespaces[i].prefix); - sfree (db->namespaces[i].url); + cx_list_free(db->list); + + sfree(db->buffer); + sfree(db->instance); + sfree(db->host); + + sfree(db->url); + sfree(db->user); + sfree(db->pass); + sfree(db->credentials); + sfree(db->cacert); + sfree(db->post_body); + curl_slist_free_all(db->headers); + curl_stats_destroy(db->stats); + + for (size_t i = 0; i < db->namespaces_num; i++) { + sfree(db->namespaces[i].prefix); + sfree(db->namespaces[i].url); } - sfree (db->namespaces); + sfree(db->namespaces); - sfree (db); + sfree(db); } /* }}} void cx_free */ -static const char *cx_host (cx_t *db) /* {{{ */ +static const char *cx_host(cx_t *db) /* {{{ */ { if (db->host == NULL) return hostname_g; return db->host; } /* }}} cx_host */ -static int cx_config_append_string (const char *name, struct curl_slist **dest, /* {{{ */ - oconfig_item_t *ci) -{ +static int cx_config_append_string(const char *name, + struct curl_slist **dest, /* {{{ */ + oconfig_item_t *ci) { struct curl_slist *temp = NULL; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("curl_xml plugin: `%s' needs exactly one string argument.", name); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("curl_xml plugin: `%s' needs exactly one string argument.", name); return (-1); } @@ -241,250 +233,241 @@ static int cx_config_append_string (const char *name, struct curl_slist **dest, return (0); } /* }}} int cx_config_append_string */ -static int cx_check_type (const data_set_t *ds, cx_xpath_t *xpath) /* {{{ */ +static int cx_check_type(const data_set_t *ds, cx_xpath_t *xpath) /* {{{ */ { - if (!ds) - { - WARNING ("curl_xml plugin: DataSet `%s' not defined.", xpath->type); + if (!ds) { + WARNING("curl_xml plugin: DataSet `%s' not defined.", xpath->type); return (-1); } - if (ds->ds_num != xpath->values_len) - { - WARNING ("curl_xml plugin: DataSet `%s' requires %zu values, but config talks about %zu", - xpath->type, ds->ds_num, xpath->values_len); + if (ds->ds_num != xpath->values_len) { + WARNING("curl_xml plugin: DataSet `%s' requires %zu values, but config " + "talks about %zu", + xpath->type, ds->ds_num, xpath->values_len); return (-1); } return (0); } /* }}} cx_check_type */ -static xmlXPathObjectPtr cx_evaluate_xpath (xmlXPathContextPtr xpath_ctx, /* {{{ */ - xmlChar *expr) -{ +static xmlXPathObjectPtr +cx_evaluate_xpath(xmlXPathContextPtr xpath_ctx, /* {{{ */ + xmlChar *expr) { xmlXPathObjectPtr xpath_obj; /* XXX: When to free this? */ xpath_obj = xmlXPathEvalExpression(BAD_CAST expr, xpath_ctx); - if (xpath_obj == NULL) - { - WARNING ("curl_xml plugin: " - "Error unable to evaluate xpath expression \"%s\". Skipping...", expr); - return NULL; + if (xpath_obj == NULL) { + WARNING("curl_xml plugin: " + "Error unable to evaluate xpath expression \"%s\". Skipping...", + expr); + return NULL; } return xpath_obj; } /* }}} cx_evaluate_xpath */ -static int cx_if_not_text_node (xmlNodePtr node) /* {{{ */ +static int cx_if_not_text_node(xmlNodePtr node) /* {{{ */ { if (node->type == XML_TEXT_NODE || node->type == XML_ATTRIBUTE_NODE || node->type == XML_ELEMENT_NODE) return (0); - WARNING ("curl_xml plugin: " - "Node \"%s\" doesn't seem to be a text node. Skipping...", node->name); + WARNING("curl_xml plugin: " + "Node \"%s\" doesn't seem to be a text node. Skipping...", + node->name); return -1; } /* }}} cx_if_not_text_node */ -static int cx_handle_single_value_xpath (xmlXPathContextPtr xpath_ctx, /* {{{ */ - cx_xpath_t *xpath, - const data_set_t *ds, value_list_t *vl, int index) -{ +static int cx_handle_single_value_xpath(xmlXPathContextPtr xpath_ctx, /* {{{ */ + cx_xpath_t *xpath, const data_set_t *ds, + value_list_t *vl, int index) { xmlXPathObjectPtr values_node_obj; xmlNodeSetPtr values_node; int tmp_size; char *node_value; - values_node_obj = cx_evaluate_xpath (xpath_ctx, BAD_CAST xpath->values[index].path); + values_node_obj = + cx_evaluate_xpath(xpath_ctx, BAD_CAST xpath->values[index].path); if (values_node_obj == NULL) return (-1); /* Error already logged. */ values_node = values_node_obj->nodesetval; tmp_size = (values_node) ? values_node->nodeNr : 0; - if (tmp_size == 0) - { - WARNING ("curl_xml plugin: " - "relative xpath expression \"%s\" doesn't match any of the nodes. " - "Skipping...", xpath->values[index].path); - xmlXPathFreeObject (values_node_obj); + if (tmp_size == 0) { + WARNING("curl_xml plugin: " + "relative xpath expression \"%s\" doesn't match any of the nodes. " + "Skipping...", + xpath->values[index].path); + xmlXPathFreeObject(values_node_obj); return (-1); } - if (tmp_size > 1) - { - WARNING ("curl_xml plugin: " - "relative xpath expression \"%s\" is expected to return " - "only one node. Skipping...", xpath->values[index].path); - xmlXPathFreeObject (values_node_obj); + if (tmp_size > 1) { + WARNING("curl_xml plugin: " + "relative xpath expression \"%s\" is expected to return " + "only one node. Skipping...", + xpath->values[index].path); + xmlXPathFreeObject(values_node_obj); return (-1); } /* ignoring the element if other than textnode/attribute*/ - if (cx_if_not_text_node(values_node->nodeTab[0])) - { - WARNING ("curl_xml plugin: " - "relative xpath expression \"%s\" is expected to return " - "only text/attribute node which is not the case. Skipping...", - xpath->values[index].path); - xmlXPathFreeObject (values_node_obj); + if (cx_if_not_text_node(values_node->nodeTab[0])) { + WARNING("curl_xml plugin: " + "relative xpath expression \"%s\" is expected to return " + "only text/attribute node which is not the case. Skipping...", + xpath->values[index].path); + xmlXPathFreeObject(values_node_obj); return (-1); } - node_value = (char *) xmlNodeGetContent(values_node->nodeTab[0]); - switch (ds->ds[index].type) - { - case DS_TYPE_COUNTER: - vl->values[index].counter = (counter_t) strtoull (node_value, - /* endptr = */ NULL, /* base = */ 0); - break; - case DS_TYPE_DERIVE: - vl->values[index].derive = (derive_t) strtoll (node_value, - /* endptr = */ NULL, /* base = */ 0); - break; - case DS_TYPE_ABSOLUTE: - vl->values[index].absolute = (absolute_t) strtoull (node_value, - /* endptr = */ NULL, /* base = */ 0); - break; - case DS_TYPE_GAUGE: - vl->values[index].gauge = (gauge_t) strtod (node_value, - /* endptr = */ NULL); + node_value = (char *)xmlNodeGetContent(values_node->nodeTab[0]); + switch (ds->ds[index].type) { + case DS_TYPE_COUNTER: + vl->values[index].counter = + (counter_t)strtoull(node_value, + /* endptr = */ NULL, /* base = */ 0); + break; + case DS_TYPE_DERIVE: + vl->values[index].derive = + (derive_t)strtoll(node_value, + /* endptr = */ NULL, /* base = */ 0); + break; + case DS_TYPE_ABSOLUTE: + vl->values[index].absolute = + (absolute_t)strtoull(node_value, + /* endptr = */ NULL, /* base = */ 0); + break; + case DS_TYPE_GAUGE: + vl->values[index].gauge = (gauge_t)strtod(node_value, + /* endptr = */ NULL); } /* free up object */ - xmlXPathFreeObject (values_node_obj); - sfree (node_value); + xmlXPathFreeObject(values_node_obj); + sfree(node_value); /* We have reached here which means that * we have got something to work */ return (0); } /* }}} int cx_handle_single_value_xpath */ -static int cx_handle_all_value_xpaths (xmlXPathContextPtr xpath_ctx, /* {{{ */ - cx_xpath_t *xpath, - const data_set_t *ds, value_list_t *vl) -{ +static int cx_handle_all_value_xpaths(xmlXPathContextPtr xpath_ctx, /* {{{ */ + cx_xpath_t *xpath, const data_set_t *ds, + value_list_t *vl) { value_t values[xpath->values_len]; int status; - assert (xpath->values_len > 0); - assert (xpath->values_len == vl->values_len); - assert (xpath->values_len == ds->ds_num); + assert(xpath->values_len > 0); + assert(xpath->values_len == vl->values_len); + assert(xpath->values_len == ds->ds_num); vl->values = values; - for (size_t i = 0; i < xpath->values_len; i++) - { - status = cx_handle_single_value_xpath (xpath_ctx, xpath, ds, vl, i); + for (size_t i = 0; i < xpath->values_len; i++) { + status = cx_handle_single_value_xpath(xpath_ctx, xpath, ds, vl, i); if (status != 0) return (-1); /* An error has been printed. */ - } /* for (i = 0; i < xpath->values_len; i++) */ + } /* for (i = 0; i < xpath->values_len; i++) */ - plugin_dispatch_values (vl); + plugin_dispatch_values(vl); vl->values = NULL; return (0); } /* }}} int cx_handle_all_value_xpaths */ -static int cx_handle_instance_xpath (xmlXPathContextPtr xpath_ctx, /* {{{ */ - cx_xpath_t *xpath, value_list_t *vl, - _Bool is_table) -{ +static int cx_handle_instance_xpath(xmlXPathContextPtr xpath_ctx, /* {{{ */ + cx_xpath_t *xpath, value_list_t *vl, + _Bool is_table) { xmlXPathObjectPtr instance_node_obj = NULL; xmlNodeSetPtr instance_node = NULL; - memset (vl->type_instance, 0, sizeof (vl->type_instance)); + memset(vl->type_instance, 0, sizeof(vl->type_instance)); /* If the base xpath returns more than one block, the result is assumed to be * a table. The `Instance' option is not optional in this case. Check for the * condition and inform the user. */ - if (is_table && (xpath->instance == NULL)) - { - WARNING ("curl_xml plugin: " - "Base-XPath %s is a table (more than one result was returned), " - "but no instance-XPath has been defined.", - xpath->path); + if (is_table && (xpath->instance == NULL)) { + WARNING("curl_xml plugin: " + "Base-XPath %s is a table (more than one result was returned), " + "but no instance-XPath has been defined.", + xpath->path); return (-1); } /* instance has to be an xpath expression */ - if (xpath->instance != NULL) - { + if (xpath->instance != NULL) { int tmp_size; - instance_node_obj = cx_evaluate_xpath (xpath_ctx, BAD_CAST xpath->instance); + instance_node_obj = cx_evaluate_xpath(xpath_ctx, BAD_CAST xpath->instance); if (instance_node_obj == NULL) return (-1); /* error is logged already */ instance_node = instance_node_obj->nodesetval; tmp_size = (instance_node) ? instance_node->nodeNr : 0; - if (tmp_size <= 0) - { - WARNING ("curl_xml plugin: " + if (tmp_size <= 0) { + WARNING( + "curl_xml plugin: " "relative xpath expression for 'InstanceFrom' \"%s\" doesn't match " - "any of the nodes. Skipping the node.", xpath->instance); - xmlXPathFreeObject (instance_node_obj); + "any of the nodes. Skipping the node.", + xpath->instance); + xmlXPathFreeObject(instance_node_obj); return (-1); } - if (tmp_size > 1) - { - WARNING ("curl_xml plugin: " - "relative xpath expression for 'InstanceFrom' \"%s\" is expected " - "to return only one text node. Skipping the node.", xpath->instance); - xmlXPathFreeObject (instance_node_obj); + if (tmp_size > 1) { + WARNING("curl_xml plugin: " + "relative xpath expression for 'InstanceFrom' \"%s\" is expected " + "to return only one text node. Skipping the node.", + xpath->instance); + xmlXPathFreeObject(instance_node_obj); return (-1); } /* ignoring the element if other than textnode/attribute */ - if (cx_if_not_text_node(instance_node->nodeTab[0])) - { - WARNING ("curl_xml plugin: " - "relative xpath expression \"%s\" is expected to return only text node " - "which is not the case. Skipping the node.", xpath->instance); - xmlXPathFreeObject (instance_node_obj); + if (cx_if_not_text_node(instance_node->nodeTab[0])) { + WARNING("curl_xml plugin: " + "relative xpath expression \"%s\" is expected to return only " + "text node " + "which is not the case. Skipping the node.", + xpath->instance); + xmlXPathFreeObject(instance_node_obj); return (-1); } } /* if (xpath->instance != NULL) */ - if (xpath->instance_prefix != NULL) - { - if (instance_node != NULL) - { - char *node_value = (char *) xmlNodeGetContent(instance_node->nodeTab[0]); - ssnprintf (vl->type_instance, sizeof (vl->type_instance),"%s%s", - xpath->instance_prefix, node_value); - sfree (node_value); - } - else - sstrncpy (vl->type_instance, xpath->instance_prefix, - sizeof (vl->type_instance)); - } - else - { + if (xpath->instance_prefix != NULL) { + if (instance_node != NULL) { + char *node_value = (char *)xmlNodeGetContent(instance_node->nodeTab[0]); + ssnprintf(vl->type_instance, sizeof(vl->type_instance), "%s%s", + xpath->instance_prefix, node_value); + sfree(node_value); + } else + sstrncpy(vl->type_instance, xpath->instance_prefix, + sizeof(vl->type_instance)); + } else { /* If instance_prefix and instance_node are NULL, then * don't set the type_instance */ - if (instance_node != NULL) - { - char *node_value = (char *) xmlNodeGetContent(instance_node->nodeTab[0]); - sstrncpy (vl->type_instance, node_value, sizeof (vl->type_instance)); - sfree (node_value); + if (instance_node != NULL) { + char *node_value = (char *)xmlNodeGetContent(instance_node->nodeTab[0]); + sstrncpy(vl->type_instance, node_value, sizeof(vl->type_instance)); + sfree(node_value); } } /* Free `instance_node_obj' this late, because `instance_node' points to * somewhere inside this structure. */ - xmlXPathFreeObject (instance_node_obj); + xmlXPathFreeObject(instance_node_obj); return (0); } /* }}} int cx_handle_instance_xpath */ -static int cx_handle_base_xpath (char const *plugin_instance, /* {{{ */ - char const *host, - xmlXPathContextPtr xpath_ctx, const data_set_t *ds, - char *base_xpath, cx_xpath_t *xpath) -{ +static int cx_handle_base_xpath(char const *plugin_instance, /* {{{ */ + char const *host, xmlXPathContextPtr xpath_ctx, + const data_set_t *ds, char *base_xpath, + cx_xpath_t *xpath) { int total_nodes; xmlXPathObjectPtr base_node_obj = NULL; @@ -492,81 +475,78 @@ static int cx_handle_base_xpath (char const *plugin_instance, /* {{{ */ value_list_t vl = VALUE_LIST_INIT; - base_node_obj = cx_evaluate_xpath (xpath_ctx, BAD_CAST base_xpath); + base_node_obj = cx_evaluate_xpath(xpath_ctx, BAD_CAST base_xpath); if (base_node_obj == NULL) return -1; /* error is logged already */ base_nodes = base_node_obj->nodesetval; total_nodes = (base_nodes) ? base_nodes->nodeNr : 0; - if (total_nodes == 0) - { - ERROR ("curl_xml plugin: " - "xpath expression \"%s\" doesn't match any of the nodes. " - "Skipping the xpath block...", base_xpath); - xmlXPathFreeObject (base_node_obj); - return -1; + if (total_nodes == 0) { + ERROR("curl_xml plugin: " + "xpath expression \"%s\" doesn't match any of the nodes. " + "Skipping the xpath block...", + base_xpath); + xmlXPathFreeObject(base_node_obj); + return -1; } /* If base_xpath returned multiple results, then */ /* Instance in the xpath block is required */ - if (total_nodes > 1 && xpath->instance == NULL) - { - ERROR ("curl_xml plugin: " - "InstanceFrom is must in xpath block since the base xpath expression \"%s\" " - "returned multiple results. Skipping the xpath block...", base_xpath); + if (total_nodes > 1 && xpath->instance == NULL) { + ERROR("curl_xml plugin: " + "InstanceFrom is must in xpath block since the base xpath expression " + "\"%s\" " + "returned multiple results. Skipping the xpath block...", + base_xpath); return -1; } /* set the values for the value_list */ vl.values_len = ds->ds_num; - sstrncpy (vl.type, xpath->type, sizeof (vl.type)); - sstrncpy (vl.plugin, "curl_xml", sizeof (vl.plugin)); - sstrncpy (vl.host, host, sizeof (vl.host)); + sstrncpy(vl.type, xpath->type, sizeof(vl.type)); + sstrncpy(vl.plugin, "curl_xml", sizeof(vl.plugin)); + sstrncpy(vl.host, host, sizeof(vl.host)); if (plugin_instance != NULL) - sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); - for (int i = 0; i < total_nodes; i++) - { + for (int i = 0; i < total_nodes; i++) { int status; xpath_ctx->node = base_nodes->nodeTab[i]; - status = cx_handle_instance_xpath (xpath_ctx, xpath, &vl, - /* is_table = */ (total_nodes > 1)); + status = cx_handle_instance_xpath(xpath_ctx, xpath, &vl, + /* is_table = */ (total_nodes > 1)); if (status != 0) continue; /* An error has already been reported. */ - status = cx_handle_all_value_xpaths (xpath_ctx, xpath, ds, &vl); + status = cx_handle_all_value_xpaths(xpath_ctx, xpath, ds, &vl); if (status != 0) continue; /* An error has been logged. */ - } /* for (i = 0; i < total_nodes; i++) */ + } /* for (i = 0; i < total_nodes; i++) */ /* free up the allocated memory */ - xmlXPathFreeObject (base_node_obj); + xmlXPathFreeObject(base_node_obj); return (0); } /* }}} cx_handle_base_xpath */ static int cx_handle_parsed_xml(xmlDocPtr doc, /* {{{ */ - xmlXPathContextPtr xpath_ctx, cx_t *db) -{ + xmlXPathContextPtr xpath_ctx, cx_t *db) { llentry_t *le; const data_set_t *ds; cx_xpath_t *xpath; - int status=-1; + int status = -1; - - le = llist_head (db->list); - while (le != NULL) - { + le = llist_head(db->list); + while (le != NULL) { /* get the ds */ - xpath = (cx_xpath_t *) le->value; - ds = plugin_get_ds (xpath->type); + xpath = (cx_xpath_t *)le->value; + ds = plugin_get_ds(xpath->type); - if ( (cx_check_type(ds, xpath) == 0) && - (cx_handle_base_xpath(db->instance, cx_host (db), - xpath_ctx, ds, le->key, xpath) == 0) ) + if ((cx_check_type(ds, xpath) == 0) && + (cx_handle_base_xpath(db->instance, cx_host(db), xpath_ctx, ds, le->key, + xpath) == 0)) status = 0; /* we got atleast one success */ le = le->next; @@ -575,7 +555,7 @@ static int cx_handle_parsed_xml(xmlDocPtr doc, /* {{{ */ return status; } /* }}} cx_handle_parsed_xml */ -static int cx_parse_stats_xml(xmlChar* xml, cx_t *db) /* {{{ */ +static int cx_parse_stats_xml(xmlChar *xml, cx_t *db) /* {{{ */ { int status; xmlDocPtr doc; @@ -583,44 +563,40 @@ static int cx_parse_stats_xml(xmlChar* xml, cx_t *db) /* {{{ */ /* Load the XML */ doc = xmlParseDoc(xml); - if (doc == NULL) - { - ERROR ("curl_xml plugin: Failed to parse the xml document - %s", xml); + if (doc == NULL) { + ERROR("curl_xml plugin: Failed to parse the xml document - %s", xml); return (-1); } xpath_ctx = xmlXPathNewContext(doc); - if(xpath_ctx == NULL) - { - ERROR ("curl_xml plugin: Failed to create the xml context"); + if (xpath_ctx == NULL) { + ERROR("curl_xml plugin: Failed to create the xml context"); xmlFreeDoc(doc); return (-1); } - for (size_t i = 0; i < db->namespaces_num; i++) - { + for (size_t i = 0; i < db->namespaces_num; i++) { cx_namespace_t const *ns = db->namespaces + i; - status = xmlXPathRegisterNs (xpath_ctx, - BAD_CAST ns->prefix, BAD_CAST ns->url); - if (status != 0) - { - ERROR ("curl_xml plugin: " - "unable to register NS with prefix=\"%s\" and href=\"%s\"\n", - ns->prefix, ns->url); + status = + xmlXPathRegisterNs(xpath_ctx, BAD_CAST ns->prefix, BAD_CAST ns->url); + if (status != 0) { + ERROR("curl_xml plugin: " + "unable to register NS with prefix=\"%s\" and href=\"%s\"\n", + ns->prefix, ns->url); xmlXPathFreeContext(xpath_ctx); - xmlFreeDoc (doc); + xmlFreeDoc(doc); return (status); } } - status = cx_handle_parsed_xml (doc, xpath_ctx, db); + status = cx_handle_parsed_xml(doc, xpath_ctx, db); /* Cleanup */ xmlXPathFreeContext(xpath_ctx); xmlFreeDoc(doc); return status; } /* }}} cx_parse_stats_xml */ -static int cx_curl_perform (cx_t *db, CURL *curl) /* {{{ */ +static int cx_curl_perform(cx_t *db, CURL *curl) /* {{{ */ { int status; long rc; @@ -629,24 +605,24 @@ static int cx_curl_perform (cx_t *db, CURL *curl) /* {{{ */ url = db->url; db->buffer_fill = 0; - status = curl_easy_perform (curl); - if (status != CURLE_OK) - { - ERROR ("curl_xml plugin: curl_easy_perform failed with status %i: %s (%s)", - status, db->curl_errbuf, url); + status = curl_easy_perform(curl); + if (status != CURLE_OK) { + ERROR("curl_xml plugin: curl_easy_perform failed with status %i: %s (%s)", + status, db->curl_errbuf, url); return (-1); } if (db->stats != NULL) - curl_stats_dispatch (db->stats, db->curl, cx_host (db), "curl_xml", db->instance); + curl_stats_dispatch(db->stats, db->curl, cx_host(db), "curl_xml", + db->instance); curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url); curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &rc); /* The response code is zero if a non-HTTP transport was used. */ - if ((rc != 0) && (rc != 200)) - { - ERROR ("curl_xml plugin: curl_easy_perform failed with response code %ld (%s)", - rc, url); + if ((rc != 0) && (rc != 200)) { + ERROR( + "curl_xml plugin: curl_easy_perform failed with response code %ld (%s)", + rc, url); return (-1); } @@ -658,103 +634,94 @@ static int cx_curl_perform (cx_t *db, CURL *curl) /* {{{ */ return status; } /* }}} int cx_curl_perform */ -static int cx_read (user_data_t *ud) /* {{{ */ +static int cx_read(user_data_t *ud) /* {{{ */ { cx_t *db; - if ((ud == NULL) || (ud->data == NULL)) - { - ERROR ("curl_xml plugin: cx_read: Invalid user data."); + if ((ud == NULL) || (ud->data == NULL)) { + ERROR("curl_xml plugin: cx_read: Invalid user data."); return (-1); } - db = (cx_t *) ud->data; + db = (cx_t *)ud->data; - return cx_curl_perform (db, db->curl); + return cx_curl_perform(db, db->curl); } /* }}} int cx_read */ /* Configuration handling functions {{{ */ -static int cx_config_add_values (const char *name, cx_xpath_t *xpath, /* {{{ */ - oconfig_item_t *ci) -{ - if (ci->values_num < 1) - { - WARNING ("curl_xml plugin: `ValuesFrom' needs at least one argument."); +static int cx_config_add_values(const char *name, cx_xpath_t *xpath, /* {{{ */ + oconfig_item_t *ci) { + if (ci->values_num < 1) { + WARNING("curl_xml plugin: `ValuesFrom' needs at least one argument."); return (-1); } for (int i = 0; i < ci->values_num; i++) - if (ci->values[i].type != OCONFIG_TYPE_STRING) - { - WARNING ("curl_xml plugin: `ValuesFrom' needs only string argument."); + if (ci->values[i].type != OCONFIG_TYPE_STRING) { + WARNING("curl_xml plugin: `ValuesFrom' needs only string argument."); return (-1); } - sfree (xpath->values); + sfree(xpath->values); xpath->values_len = 0; - xpath->values = malloc (sizeof (cx_values_t) * ci->values_num); + xpath->values = malloc(sizeof(cx_values_t) * ci->values_num); if (xpath->values == NULL) return (-1); - xpath->values_len = (size_t) ci->values_num; + xpath->values_len = (size_t)ci->values_num; /* populate cx_values_t structure */ - for (int i = 0; i < ci->values_num; i++) - { - xpath->values[i].path_len = sizeof (ci->values[i].value.string); - sstrncpy (xpath->values[i].path, ci->values[i].value.string, sizeof (xpath->values[i].path)); + for (int i = 0; i < ci->values_num; i++) { + xpath->values[i].path_len = sizeof(ci->values[i].value.string); + sstrncpy(xpath->values[i].path, ci->values[i].value.string, + sizeof(xpath->values[i].path)); } return (0); } /* }}} cx_config_add_values */ -static int cx_config_add_xpath (cx_t *db, oconfig_item_t *ci) /* {{{ */ +static int cx_config_add_xpath(cx_t *db, oconfig_item_t *ci) /* {{{ */ { cx_xpath_t *xpath; char *name; llentry_t *le; int status; - xpath = calloc (1, sizeof (*xpath)); - if (xpath == NULL) - { - ERROR ("curl_xml plugin: calloc failed."); + xpath = calloc(1, sizeof(*xpath)); + if (xpath == NULL) { + ERROR("curl_xml plugin: calloc failed."); return (-1); } - status = cf_util_get_string (ci, &xpath->path); - if (status != 0) - { - cx_xpath_free (xpath); + status = cf_util_get_string(ci, &xpath->path); + if (status != 0) { + cx_xpath_free(xpath); return (status); } /* error out if xpath->path is an empty string */ - if (strlen (xpath->path) == 0) - { - ERROR ("curl_xml plugin: invalid xpath. " - "xpath value can't be an empty string"); - cx_xpath_free (xpath); + if (strlen(xpath->path) == 0) { + ERROR("curl_xml plugin: invalid xpath. " + "xpath value can't be an empty string"); + cx_xpath_free(xpath); return (-1); } status = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Type", child->key) == 0) - status = cf_util_get_string (child, &xpath->type); - else if (strcasecmp ("InstancePrefix", child->key) == 0) - status = cf_util_get_string (child, &xpath->instance_prefix); - else if (strcasecmp ("InstanceFrom", child->key) == 0) - status = cf_util_get_string (child, &xpath->instance); - else if (strcasecmp ("ValuesFrom", child->key) == 0) - status = cx_config_add_values ("ValuesFrom", xpath, child); - else - { - WARNING ("curl_xml plugin: Option `%s' not allowed here.", child->key); + if (strcasecmp("Type", child->key) == 0) + status = cf_util_get_string(child, &xpath->type); + else if (strcasecmp("InstancePrefix", child->key) == 0) + status = cf_util_get_string(child, &xpath->instance_prefix); + else if (strcasecmp("InstanceFrom", child->key) == 0) + status = cf_util_get_string(child, &xpath->instance); + else if (strcasecmp("ValuesFrom", child->key) == 0) + status = cx_config_add_values("ValuesFrom", xpath, child); + else { + WARNING("curl_xml plugin: Option `%s' not allowed here.", child->key); status = -1; } @@ -762,84 +729,73 @@ static int cx_config_add_xpath (cx_t *db, oconfig_item_t *ci) /* {{{ */ break; } /* for (i = 0; i < ci->children_num; i++) */ - if (status != 0) - { - cx_xpath_free (xpath); + if (status != 0) { + cx_xpath_free(xpath); return status; } - if (xpath->type == NULL) - { - WARNING ("curl_xml plugin: `Type' missing in `xpath' block."); - cx_xpath_free (xpath); + if (xpath->type == NULL) { + WARNING("curl_xml plugin: `Type' missing in `xpath' block."); + cx_xpath_free(xpath); return -1; } - if (db->list == NULL) - { + if (db->list == NULL) { db->list = llist_create(); - if (db->list == NULL) - { - ERROR ("curl_xml plugin: list creation failed."); - cx_xpath_free (xpath); + if (db->list == NULL) { + ERROR("curl_xml plugin: list creation failed."); + cx_xpath_free(xpath); return (-1); } } - name = strdup (xpath->path); - if (name == NULL) - { - ERROR ("curl_xml plugin: strdup failed."); - cx_xpath_free (xpath); + name = strdup(xpath->path); + if (name == NULL) { + ERROR("curl_xml plugin: strdup failed."); + cx_xpath_free(xpath); return (-1); } - le = llentry_create (name, xpath); - if (le == NULL) - { - ERROR ("curl_xml plugin: llentry_create failed."); - cx_xpath_free (xpath); - sfree (name); + le = llentry_create(name, xpath); + if (le == NULL) { + ERROR("curl_xml plugin: llentry_create failed."); + cx_xpath_free(xpath); + sfree(name); return (-1); } - llist_append (db->list, le); + llist_append(db->list, le); return (0); } /* }}} int cx_config_add_xpath */ -static int cx_config_add_namespace (cx_t *db, /* {{{ */ - oconfig_item_t *ci) -{ +static int cx_config_add_namespace(cx_t *db, /* {{{ */ + oconfig_item_t *ci) { cx_namespace_t *ns; - if ((ci->values_num != 2) - || (ci->values[0].type != OCONFIG_TYPE_STRING) - || (ci->values[1].type != OCONFIG_TYPE_STRING)) - { - WARNING ("curl_xml plugin: The `Namespace' option " - "needs exactly two string arguments."); + if ((ci->values_num != 2) || (ci->values[0].type != OCONFIG_TYPE_STRING) || + (ci->values[1].type != OCONFIG_TYPE_STRING)) { + WARNING("curl_xml plugin: The `Namespace' option " + "needs exactly two string arguments."); return (EINVAL); } - ns = realloc (db->namespaces, sizeof (*db->namespaces) - * (db->namespaces_num + 1)); - if (ns == NULL) - { - ERROR ("curl_xml plugin: realloc failed."); + ns = realloc(db->namespaces, + sizeof(*db->namespaces) * (db->namespaces_num + 1)); + if (ns == NULL) { + ERROR("curl_xml plugin: realloc failed."); return (ENOMEM); } db->namespaces = ns; ns = db->namespaces + db->namespaces_num; - memset (ns, 0, sizeof (*ns)); + memset(ns, 0, sizeof(*ns)); - ns->prefix = strdup (ci->values[0].value.string); - ns->url = strdup (ci->values[1].value.string); + ns->prefix = strdup(ci->values[0].value.string); + ns->url = strdup(ci->values[1].value.string); - if ((ns->prefix == NULL) || (ns->url == NULL)) - { - sfree (ns->prefix); - sfree (ns->url); - ERROR ("curl_xml plugin: strdup failed."); + if ((ns->prefix == NULL) || (ns->url == NULL)) { + sfree(ns->prefix); + sfree(ns->url); + ERROR("curl_xml plugin: strdup failed."); return (ENOMEM); } @@ -848,152 +804,139 @@ static int cx_config_add_namespace (cx_t *db, /* {{{ */ } /* }}} int cx_config_add_namespace */ /* Initialize db->curl */ -static int cx_init_curl (cx_t *db) /* {{{ */ +static int cx_init_curl(cx_t *db) /* {{{ */ { - db->curl = curl_easy_init (); - if (db->curl == NULL) - { - ERROR ("curl_xml plugin: curl_easy_init failed."); + db->curl = curl_easy_init(); + if (db->curl == NULL) { + ERROR("curl_xml plugin: curl_easy_init failed."); return (-1); } - curl_easy_setopt (db->curl, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt (db->curl, CURLOPT_WRITEFUNCTION, cx_curl_callback); - curl_easy_setopt (db->curl, CURLOPT_WRITEDATA, db); - curl_easy_setopt (db->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); - curl_easy_setopt (db->curl, CURLOPT_ERRORBUFFER, db->curl_errbuf); - curl_easy_setopt (db->curl, CURLOPT_URL, db->url); - curl_easy_setopt (db->curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt (db->curl, CURLOPT_MAXREDIRS, 50L); - - if (db->user != NULL) - { + curl_easy_setopt(db->curl, CURLOPT_NOSIGNAL, 1L); + curl_easy_setopt(db->curl, CURLOPT_WRITEFUNCTION, cx_curl_callback); + curl_easy_setopt(db->curl, CURLOPT_WRITEDATA, db); + curl_easy_setopt(db->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); + curl_easy_setopt(db->curl, CURLOPT_ERRORBUFFER, db->curl_errbuf); + curl_easy_setopt(db->curl, CURLOPT_URL, db->url); + curl_easy_setopt(db->curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(db->curl, CURLOPT_MAXREDIRS, 50L); + + if (db->user != NULL) { #ifdef HAVE_CURLOPT_USERNAME - curl_easy_setopt (db->curl, CURLOPT_USERNAME, db->user); - curl_easy_setopt (db->curl, CURLOPT_PASSWORD, - (db->pass == NULL) ? "" : db->pass); + curl_easy_setopt(db->curl, CURLOPT_USERNAME, db->user); + curl_easy_setopt(db->curl, CURLOPT_PASSWORD, + (db->pass == NULL) ? "" : db->pass); #else size_t credentials_size; - credentials_size = strlen (db->user) + 2; + credentials_size = strlen(db->user) + 2; if (db->pass != NULL) - credentials_size += strlen (db->pass); + credentials_size += strlen(db->pass); - db->credentials = malloc (credentials_size); - if (db->credentials == NULL) - { - ERROR ("curl_xml plugin: malloc failed."); + db->credentials = malloc(credentials_size); + if (db->credentials == NULL) { + ERROR("curl_xml plugin: malloc failed."); return (-1); } - ssnprintf (db->credentials, credentials_size, "%s:%s", - db->user, (db->pass == NULL) ? "" : db->pass); - curl_easy_setopt (db->curl, CURLOPT_USERPWD, db->credentials); + ssnprintf(db->credentials, credentials_size, "%s:%s", db->user, + (db->pass == NULL) ? "" : db->pass); + curl_easy_setopt(db->curl, CURLOPT_USERPWD, db->credentials); #endif if (db->digest) - curl_easy_setopt (db->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); + curl_easy_setopt(db->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); } - curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYPEER, db->verify_peer ? 1L : 0L); - curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYHOST, - db->verify_host ? 2L : 0L); + curl_easy_setopt(db->curl, CURLOPT_SSL_VERIFYPEER, db->verify_peer ? 1L : 0L); + curl_easy_setopt(db->curl, CURLOPT_SSL_VERIFYHOST, db->verify_host ? 2L : 0L); if (db->cacert != NULL) - curl_easy_setopt (db->curl, CURLOPT_CAINFO, db->cacert); + curl_easy_setopt(db->curl, CURLOPT_CAINFO, db->cacert); if (db->headers != NULL) - curl_easy_setopt (db->curl, CURLOPT_HTTPHEADER, db->headers); + curl_easy_setopt(db->curl, CURLOPT_HTTPHEADER, db->headers); if (db->post_body != NULL) - curl_easy_setopt (db->curl, CURLOPT_POSTFIELDS, db->post_body); + curl_easy_setopt(db->curl, CURLOPT_POSTFIELDS, db->post_body); #ifdef HAVE_CURLOPT_TIMEOUT_MS if (db->timeout >= 0) - curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) db->timeout); + curl_easy_setopt(db->curl, CURLOPT_TIMEOUT_MS, (long)db->timeout); else - curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval())); + curl_easy_setopt(db->curl, CURLOPT_TIMEOUT_MS, + (long)CDTIME_T_TO_MS(plugin_get_interval())); #endif return (0); } /* }}} int cx_init_curl */ -static int cx_config_add_url (oconfig_item_t *ci) /* {{{ */ +static int cx_config_add_url(oconfig_item_t *ci) /* {{{ */ { cx_t *db; int status = 0; - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("curl_xml plugin: The `URL' block " - "needs exactly one string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("curl_xml plugin: The `URL' block " + "needs exactly one string argument."); return (-1); } - db = calloc (1, sizeof (*db)); - if (db == NULL) - { - ERROR ("curl_xml plugin: calloc failed."); + db = calloc(1, sizeof(*db)); + if (db == NULL) { + ERROR("curl_xml plugin: calloc failed."); return (-1); } db->timeout = -1; - if (strcasecmp ("URL", ci->key) == 0) - { - status = cf_util_get_string (ci, &db->url); - if (status != 0) - { - sfree (db); + if (strcasecmp("URL", ci->key) == 0) { + status = cf_util_get_string(ci, &db->url); + if (status != 0) { + sfree(db); return (status); } - } - else - { - ERROR ("curl_xml plugin: cx_config: " - "Invalid key: %s", ci->key); - cx_free (db); + } else { + ERROR("curl_xml plugin: cx_config: " + "Invalid key: %s", + ci->key); + cx_free(db); return (-1); } /* Fill the `cx_t' structure.. */ - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Instance", child->key) == 0) - status = cf_util_get_string (child, &db->instance); - else if (strcasecmp ("Host", child->key) == 0) - status = cf_util_get_string (child, &db->host); - else if (strcasecmp ("User", child->key) == 0) - status = cf_util_get_string (child, &db->user); - else if (strcasecmp ("Password", child->key) == 0) - status = cf_util_get_string (child, &db->pass); - else if (strcasecmp ("Digest", child->key) == 0) - status = cf_util_get_boolean (child, &db->digest); - else if (strcasecmp ("VerifyPeer", child->key) == 0) - status = cf_util_get_boolean (child, &db->verify_peer); - else if (strcasecmp ("VerifyHost", child->key) == 0) - status = cf_util_get_boolean (child, &db->verify_host); - else if (strcasecmp ("CACert", child->key) == 0) - status = cf_util_get_string (child, &db->cacert); - else if (strcasecmp ("xpath", child->key) == 0) - status = cx_config_add_xpath (db, child); - else if (strcasecmp ("Header", child->key) == 0) - status = cx_config_append_string ("Header", &db->headers, child); - else if (strcasecmp ("Post", child->key) == 0) - status = cf_util_get_string (child, &db->post_body); - else if (strcasecmp ("Namespace", child->key) == 0) - status = cx_config_add_namespace (db, child); - else if (strcasecmp ("Timeout", child->key) == 0) - status = cf_util_get_int (child, &db->timeout); - else if (strcasecmp ("Statistics", child->key) == 0) - { - db->stats = curl_stats_from_config (child); + if (strcasecmp("Instance", child->key) == 0) + status = cf_util_get_string(child, &db->instance); + else if (strcasecmp("Host", child->key) == 0) + status = cf_util_get_string(child, &db->host); + else if (strcasecmp("User", child->key) == 0) + status = cf_util_get_string(child, &db->user); + else if (strcasecmp("Password", child->key) == 0) + status = cf_util_get_string(child, &db->pass); + else if (strcasecmp("Digest", child->key) == 0) + status = cf_util_get_boolean(child, &db->digest); + else if (strcasecmp("VerifyPeer", child->key) == 0) + status = cf_util_get_boolean(child, &db->verify_peer); + else if (strcasecmp("VerifyHost", child->key) == 0) + status = cf_util_get_boolean(child, &db->verify_host); + else if (strcasecmp("CACert", child->key) == 0) + status = cf_util_get_string(child, &db->cacert); + else if (strcasecmp("xpath", child->key) == 0) + status = cx_config_add_xpath(db, child); + else if (strcasecmp("Header", child->key) == 0) + status = cx_config_append_string("Header", &db->headers, child); + else if (strcasecmp("Post", child->key) == 0) + status = cf_util_get_string(child, &db->post_body); + else if (strcasecmp("Namespace", child->key) == 0) + status = cx_config_add_namespace(db, child); + else if (strcasecmp("Timeout", child->key) == 0) + status = cf_util_get_int(child, &db->timeout); + else if (strcasecmp("Statistics", child->key) == 0) { + db->stats = curl_stats_from_config(child); if (db->stats == NULL) status = -1; - } - else - { - WARNING ("curl_xml plugin: Option `%s' not allowed here.", child->key); + } else { + WARNING("curl_xml plugin: Option `%s' not allowed here.", child->key); status = -1; } @@ -1001,42 +944,36 @@ static int cx_config_add_url (oconfig_item_t *ci) /* {{{ */ break; } - if (status == 0) - { - if (db->list == NULL) - { - WARNING ("curl_xml plugin: No (valid) `Key' block " - "within `URL' block `%s'.", db->url); + if (status == 0) { + if (db->list == NULL) { + WARNING("curl_xml plugin: No (valid) `Key' block " + "within `URL' block `%s'.", + db->url); status = -1; } if (status == 0) - status = cx_init_curl (db); + status = cx_init_curl(db); } /* If all went well, register this database for reading */ - if (status == 0) - { + if (status == 0) { char *cb_name; if (db->instance == NULL) db->instance = strdup("default"); - DEBUG ("curl_xml plugin: Registering new read callback: %s", - db->instance); + DEBUG("curl_xml plugin: Registering new read callback: %s", db->instance); - cb_name = ssnprintf_alloc ("curl_xml-%s-%s", db->instance, db->url); + cb_name = ssnprintf_alloc("curl_xml-%s-%s", db->instance, db->url); - plugin_register_complex_read (/* group = */ "curl_xml", cb_name, cx_read, - /* interval = */ 0, - &(user_data_t) { - .data = db, - .free_func = cx_free, - }); - sfree (cb_name); - } - else - { - cx_free (db); + plugin_register_complex_read(/* group = */ "curl_xml", cb_name, cx_read, + /* interval = */ 0, + &(user_data_t){ + .data = db, .free_func = cx_free, + }); + sfree(cb_name); + } else { + cx_free(db); return (-1); } @@ -1045,7 +982,7 @@ static int cx_config_add_url (oconfig_item_t *ci) /* {{{ */ /* }}} End of configuration handling functions */ -static int cx_config (oconfig_item_t *ci) /* {{{ */ +static int cx_config(oconfig_item_t *ci) /* {{{ */ { int success; int errors; @@ -1054,46 +991,40 @@ static int cx_config (oconfig_item_t *ci) /* {{{ */ success = 0; errors = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("URL", child->key) == 0) - { - status = cx_config_add_url (child); + if (strcasecmp("URL", child->key) == 0) { + status = cx_config_add_url(child); if (status == 0) success++; else errors++; - } - else - { - WARNING ("curl_xml plugin: Option `%s' not allowed here.", child->key); + } else { + WARNING("curl_xml plugin: Option `%s' not allowed here.", child->key); errors++; } } - if ((success == 0) && (errors > 0)) - { - ERROR ("curl_xml plugin: All statements failed."); + if ((success == 0) && (errors > 0)) { + ERROR("curl_xml plugin: All statements failed."); return (-1); } return (0); } /* }}} int cx_config */ -static int cx_init (void) /* {{{ */ +static int cx_init(void) /* {{{ */ { /* Call this while collectd is still single-threaded to avoid * initialization issues in libgcrypt. */ - curl_global_init (CURL_GLOBAL_SSL); + curl_global_init(CURL_GLOBAL_SSL); return (0); } /* }}} int cx_init */ -void module_register (void) -{ - plugin_register_complex_config ("curl_xml", cx_config); - plugin_register_init ("curl_xml", cx_init); +void module_register(void) { + plugin_register_complex_config("curl_xml", cx_config); + plugin_register_init("curl_xml", cx_init); } /* void module_register */ /* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/daemon/collectd.c b/src/daemon/collectd.c index 4843fc65..f3df795d 100644 --- a/src/daemon/collectd.c +++ b/src/daemon/collectd.c @@ -28,23 +28,23 @@ #include "collectd.h" #include "common.h" -#include "plugin.h" #include "configfile.h" +#include "plugin.h" +#include #include #include -#include #if HAVE_LOCALE_H -# include +#include #endif #if HAVE_STATGRAB_H -# include +#include #endif #ifndef COLLECTD_LOCALE -# define COLLECTD_LOCALE "C" +#define COLLECTD_LOCALE "C" #endif /* @@ -52,711 +52,633 @@ */ char hostname_g[DATA_MAX_NAME_LEN]; cdtime_t interval_g; -int timeout_g; +int timeout_g; #if HAVE_LIBKSTAT kstat_ctl_t *kc; #endif /* HAVE_LIBKSTAT */ static int loop = 0; -static void *do_flush (void __attribute__((unused)) *arg) -{ - INFO ("Flushing all data."); - plugin_flush (/* plugin = */ NULL, - /* timeout = */ 0, - /* ident = */ NULL); - INFO ("Finished flushing all data."); - pthread_exit (NULL); - return NULL; +static void *do_flush(void __attribute__((unused)) * arg) { + INFO("Flushing all data."); + plugin_flush(/* plugin = */ NULL, + /* timeout = */ 0, + /* ident = */ NULL); + INFO("Finished flushing all data."); + pthread_exit(NULL); + return NULL; } -static void sig_int_handler (int __attribute__((unused)) signal) -{ - loop++; -} +static void sig_int_handler(int __attribute__((unused)) signal) { loop++; } -static void sig_term_handler (int __attribute__((unused)) signal) -{ - loop++; -} +static void sig_term_handler(int __attribute__((unused)) signal) { loop++; } -static void sig_usr1_handler (int __attribute__((unused)) signal) -{ - pthread_t thread; - pthread_attr_t attr; - - /* flushing the data might take a while, - * so it should be done asynchronously */ - pthread_attr_init (&attr); - pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); - pthread_create (&thread, &attr, do_flush, NULL); - pthread_attr_destroy (&attr); +static void sig_usr1_handler(int __attribute__((unused)) signal) { + pthread_t thread; + pthread_attr_t attr; + + /* flushing the data might take a while, + * so it should be done asynchronously */ + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_create(&thread, &attr, do_flush, NULL); + pthread_attr_destroy(&attr); } -static int init_hostname (void) -{ - const char *str; - - struct addrinfo *ai_list; - int status; - - str = global_option_get ("Hostname"); - if ((str != NULL) && (str[0] != 0)) - { - sstrncpy (hostname_g, str, sizeof (hostname_g)); - return (0); - } - - if (gethostname (hostname_g, sizeof (hostname_g)) != 0) - { - fprintf (stderr, "`gethostname' failed and no " - "hostname was configured.\n"); - return (-1); - } - - str = global_option_get ("FQDNLookup"); - if (IS_FALSE (str)) - return (0); - - struct addrinfo ai_hints = { - .ai_flags = AI_CANONNAME - }; - - status = getaddrinfo (hostname_g, NULL, &ai_hints, &ai_list); - if (status != 0) - { - ERROR ("Looking up \"%s\" failed. You have set the " - "\"FQDNLookup\" option, but I cannot resolve " - "my hostname to a fully qualified domain " - "name. Please fix the network " - "configuration.", hostname_g); - return (-1); - } - - for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) - { - if (ai_ptr->ai_canonname == NULL) - continue; - - sstrncpy (hostname_g, ai_ptr->ai_canonname, sizeof (hostname_g)); - break; - } - - freeaddrinfo (ai_list); - return (0); +static int init_hostname(void) { + const char *str; + + struct addrinfo *ai_list; + int status; + + str = global_option_get("Hostname"); + if ((str != NULL) && (str[0] != 0)) { + sstrncpy(hostname_g, str, sizeof(hostname_g)); + return (0); + } + + if (gethostname(hostname_g, sizeof(hostname_g)) != 0) { + fprintf(stderr, "`gethostname' failed and no " + "hostname was configured.\n"); + return (-1); + } + + str = global_option_get("FQDNLookup"); + if (IS_FALSE(str)) + return (0); + + struct addrinfo ai_hints = {.ai_flags = AI_CANONNAME}; + + status = getaddrinfo(hostname_g, NULL, &ai_hints, &ai_list); + if (status != 0) { + ERROR("Looking up \"%s\" failed. You have set the " + "\"FQDNLookup\" option, but I cannot resolve " + "my hostname to a fully qualified domain " + "name. Please fix the network " + "configuration.", + hostname_g); + return (-1); + } + + for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; + ai_ptr = ai_ptr->ai_next) { + if (ai_ptr->ai_canonname == NULL) + continue; + + sstrncpy(hostname_g, ai_ptr->ai_canonname, sizeof(hostname_g)); + break; + } + + freeaddrinfo(ai_list); + return (0); } /* int init_hostname */ -static int init_global_variables (void) -{ - char const *str; - - interval_g = cf_get_default_interval (); - assert (interval_g > 0); - DEBUG ("interval_g = %.3f;", CDTIME_T_TO_DOUBLE (interval_g)); - - str = global_option_get ("Timeout"); - if (str == NULL) - str = "2"; - timeout_g = atoi (str); - if (timeout_g <= 1) - { - fprintf (stderr, "Cannot set the timeout to a correct value.\n" - "Please check your settings.\n"); - return (-1); - } - DEBUG ("timeout_g = %i;", timeout_g); - - if (init_hostname () != 0) - return (-1); - DEBUG ("hostname_g = %s;", hostname_g); - - return (0); +static int init_global_variables(void) { + char const *str; + + interval_g = cf_get_default_interval(); + assert(interval_g > 0); + DEBUG("interval_g = %.3f;", CDTIME_T_TO_DOUBLE(interval_g)); + + str = global_option_get("Timeout"); + if (str == NULL) + str = "2"; + timeout_g = atoi(str); + if (timeout_g <= 1) { + fprintf(stderr, "Cannot set the timeout to a correct value.\n" + "Please check your settings.\n"); + return (-1); + } + DEBUG("timeout_g = %i;", timeout_g); + + if (init_hostname() != 0) + return (-1); + DEBUG("hostname_g = %s;", hostname_g); + + return (0); } /* int init_global_variables */ -static int change_basedir (const char *orig_dir) -{ - char *dir; - size_t dirlen; - int status; - - dir = strdup (orig_dir); - if (dir == NULL) - { - char errbuf[1024]; - ERROR ("strdup failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - dirlen = strlen (dir); - while ((dirlen > 0) && (dir[dirlen - 1] == '/')) - dir[--dirlen] = '\0'; - - if (dirlen == 0) { - free (dir); - return (-1); - } - - status = chdir (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) - { - 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(const char *orig_dir) { + char *dir; + size_t dirlen; + int status; + + dir = strdup(orig_dir); + if (dir == NULL) { + char errbuf[1024]; + ERROR("strdup failed: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + dirlen = strlen(dir); + while ((dirlen > 0) && (dir[dirlen - 1] == '/')) + dir[--dirlen] = '\0'; + + if (dirlen == 0) { + free(dir); + return (-1); + } + + status = chdir(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) { + 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) */ #if HAVE_LIBKSTAT -static void update_kstat (void) -{ - if (kc == NULL) - { - if ((kc = kstat_open ()) == NULL) - ERROR ("Unable to open kstat control structure"); - } - else - { - kid_t kid; - kid = kstat_chain_update (kc); - if (kid > 0) - { - INFO ("kstat chain has been updated"); - plugin_init_all (); - } - else if (kid < 0) - ERROR ("kstat chain update failed"); - /* else: everything works as expected */ - } - - return; +static void update_kstat(void) { + if (kc == NULL) { + if ((kc = kstat_open()) == NULL) + ERROR("Unable to open kstat control structure"); + } else { + kid_t kid; + kid = kstat_chain_update(kc); + if (kid > 0) { + INFO("kstat chain has been updated"); + plugin_init_all(); + } else if (kid < 0) + ERROR("kstat chain update failed"); + /* else: everything works as expected */ + } + + return; } /* static void update_kstat (void) */ #endif /* HAVE_LIBKSTAT */ /* TODO * Remove all settings but `-f' and `-C' */ -__attribute__((noreturn)) -static void exit_usage (int status) -{ - printf ("Usage: "PACKAGE_NAME" [OPTIONS]\n\n" - - "Available options:\n" - " General:\n" - " -C Configuration file.\n" - " Default: "CONFIGFILE"\n" - " -t Test config and exit.\n" - " -T Test plugin read and exit.\n" - " -P PID-file.\n" - " Default: "PIDFILE"\n" +__attribute__((noreturn)) static void exit_usage(int status) { + printf("Usage: " PACKAGE_NAME " [OPTIONS]\n\n" + + "Available options:\n" + " General:\n" + " -C Configuration file.\n" + " Default: " CONFIGFILE "\n" + " -t Test config and exit.\n" + " -T Test plugin read and exit.\n" + " -P PID-file.\n" + " Default: " PIDFILE "\n" #if COLLECT_DAEMON - " -f Don't fork to the background.\n" + " -f Don't fork to the background.\n" #endif - " -h Display help (this message)\n" - "\nBuiltin defaults:\n" - " Config file "CONFIGFILE"\n" - " PID file "PIDFILE"\n" - " Plugin directory "PLUGINDIR"\n" - " Data directory "PKGLOCALSTATEDIR"\n" - "\n"PACKAGE_NAME" "PACKAGE_VERSION", http://collectd.org/\n" - "by Florian octo Forster \n" - "for contributions see `AUTHORS'\n"); - exit (status); + " -h Display help (this message)\n" + "\nBuiltin defaults:\n" + " Config file " CONFIGFILE "\n" + " PID file " PIDFILE "\n" + " Plugin directory " PLUGINDIR "\n" + " Data directory " PKGLOCALSTATEDIR "\n" + "\n" PACKAGE_NAME " " PACKAGE_VERSION ", http://collectd.org/\n" + "by Florian octo Forster \n" + "for contributions see `AUTHORS'\n"); + exit(status); } /* static void exit_usage (int status) */ -static int do_init (void) -{ +static int do_init(void) { #if HAVE_SETLOCALE - if (setlocale (LC_NUMERIC, COLLECTD_LOCALE) == NULL) - WARNING ("setlocale (\"%s\") failed.", COLLECTD_LOCALE); + if (setlocale(LC_NUMERIC, COLLECTD_LOCALE) == NULL) + WARNING("setlocale (\"%s\") failed.", COLLECTD_LOCALE); - /* Update the environment, so that libraries that are calling - * setlocale(LC_NUMERIC, "") don't accidentally revert these changes. */ - unsetenv ("LC_ALL"); - setenv ("LC_NUMERIC", COLLECTD_LOCALE, /* overwrite = */ 1); + /* Update the environment, so that libraries that are calling + * setlocale(LC_NUMERIC, "") don't accidentally revert these changes. */ + unsetenv("LC_ALL"); + setenv("LC_NUMERIC", COLLECTD_LOCALE, /* overwrite = */ 1); #endif #if HAVE_LIBKSTAT - kc = NULL; - update_kstat (); + kc = NULL; + update_kstat(); #endif #if HAVE_LIBSTATGRAB - if (sg_init ( -# if HAVE_LIBSTATGRAB_0_90 - 0 -# endif - )) - { - ERROR ("sg_init: %s", sg_str_error (sg_get_error ())); - return (-1); - } - - if (sg_drop_privileges ()) - { - ERROR ("sg_drop_privileges: %s", sg_str_error (sg_get_error ())); - return (-1); - } + if (sg_init( +#if HAVE_LIBSTATGRAB_0_90 + 0 +#endif + )) { + ERROR("sg_init: %s", sg_str_error(sg_get_error())); + return (-1); + } + + if (sg_drop_privileges()) { + ERROR("sg_drop_privileges: %s", sg_str_error(sg_get_error())); + return (-1); + } #endif - return plugin_init_all (); + return plugin_init_all(); } /* int do_init () */ +static int do_loop(void) { + cdtime_t interval = cf_get_default_interval(); + cdtime_t wait_until; -static int do_loop (void) -{ - cdtime_t interval = cf_get_default_interval (); - cdtime_t wait_until; - - wait_until = cdtime () + interval; + wait_until = cdtime() + interval; - while (loop == 0) - { - cdtime_t now; + while (loop == 0) { + cdtime_t now; #if HAVE_LIBKSTAT - update_kstat (); + update_kstat(); #endif - /* Issue all plugins */ - plugin_read_all (); - - now = cdtime (); - if (now >= wait_until) - { - WARNING ("Not sleeping because the next interval is " - "%.3f seconds in the past!", - CDTIME_T_TO_DOUBLE (now - wait_until)); - wait_until = now + interval; - continue; - } - - struct timespec ts_wait = CDTIME_T_TO_TIMESPEC (wait_until - now); - wait_until = wait_until + interval; - - while ((loop == 0) && (nanosleep (&ts_wait, &ts_wait) != 0)) - { - if (errno != EINTR) - { - char errbuf[1024]; - ERROR ("nanosleep failed: %s", - sstrerror (errno, errbuf, - sizeof (errbuf))); - return (-1); - } - } - } /* while (loop == 0) */ - - return (0); + /* Issue all plugins */ + plugin_read_all(); + + now = cdtime(); + if (now >= wait_until) { + WARNING("Not sleeping because the next interval is " + "%.3f seconds in the past!", + CDTIME_T_TO_DOUBLE(now - wait_until)); + wait_until = now + interval; + continue; + } + + struct timespec ts_wait = CDTIME_T_TO_TIMESPEC(wait_until - now); + wait_until = wait_until + interval; + + while ((loop == 0) && (nanosleep(&ts_wait, &ts_wait) != 0)) { + if (errno != EINTR) { + char errbuf[1024]; + ERROR("nanosleep failed: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + } + } /* while (loop == 0) */ + + return (0); } /* int do_loop */ -static int do_shutdown (void) -{ - return plugin_shutdown_all (); +static int do_shutdown(void) { + return plugin_shutdown_all(); } /* int do_shutdown */ #if COLLECT_DAEMON -static int pidfile_create (void) -{ - FILE *fh; - const char *file = global_option_get ("PIDFile"); - - if ((fh = fopen (file, "w")) == NULL) - { - char errbuf[1024]; - ERROR ("fopen (%s): %s", file, - sstrerror (errno, errbuf, sizeof (errbuf))); - return (1); - } - - fprintf (fh, "%i\n", (int) getpid ()); - fclose(fh); - - return (0); +static int pidfile_create(void) { + FILE *fh; + const char *file = global_option_get("PIDFile"); + + if ((fh = fopen(file, "w")) == NULL) { + char errbuf[1024]; + ERROR("fopen (%s): %s", file, sstrerror(errno, errbuf, sizeof(errbuf))); + return (1); + } + + fprintf(fh, "%i\n", (int)getpid()); + fclose(fh); + + return (0); } /* static int pidfile_create (const char *file) */ -static int pidfile_remove (void) -{ - const char *file = global_option_get ("PIDFile"); - if (file == NULL) - return 0; +static int pidfile_remove(void) { + const char *file = global_option_get("PIDFile"); + if (file == NULL) + return 0; - return (unlink (file)); + return (unlink(file)); } /* static int pidfile_remove (const char *file) */ #endif /* COLLECT_DAEMON */ #ifdef KERNEL_LINUX -static int notify_upstart (void) -{ - char const *upstart_job = getenv("UPSTART_JOB"); +static int notify_upstart(void) { + char const *upstart_job = getenv("UPSTART_JOB"); - if (upstart_job == NULL) - return 0; + if (upstart_job == NULL) + return 0; - if (strcmp(upstart_job, "collectd") != 0) - { - WARNING ("Environment specifies unexpected UPSTART_JOB=\"%s\", expected \"collectd\". Ignoring the variable.", upstart_job); - return 0; - } + if (strcmp(upstart_job, "collectd") != 0) { + WARNING("Environment specifies unexpected UPSTART_JOB=\"%s\", expected " + "\"collectd\". Ignoring the variable.", + upstart_job); + return 0; + } - NOTICE("Upstart detected, stopping now to signal readyness."); - raise(SIGSTOP); - unsetenv("UPSTART_JOB"); + NOTICE("Upstart detected, stopping now to signal readyness."); + raise(SIGSTOP); + unsetenv("UPSTART_JOB"); - return 1; + return 1; } -static int notify_systemd (void) -{ - int fd; - const char *notifysocket; - struct sockaddr_un su = { 0 }; - size_t su_size; - char buffer[] = "READY=1\n"; - - notifysocket = getenv ("NOTIFY_SOCKET"); - if (notifysocket == NULL) - return 0; - - if ((strlen (notifysocket) < 2) - || ((notifysocket[0] != '@') && (notifysocket[0] != '/'))) - { - ERROR ("invalid notification socket NOTIFY_SOCKET=\"%s\": path must be absolute", notifysocket); - return 0; - } - NOTICE ("Systemd detected, trying to signal readyness."); +static int notify_systemd(void) { + int fd; + const char *notifysocket; + struct sockaddr_un su = {0}; + size_t su_size; + char buffer[] = "READY=1\n"; + + notifysocket = getenv("NOTIFY_SOCKET"); + if (notifysocket == NULL) + return 0; + + if ((strlen(notifysocket) < 2) || + ((notifysocket[0] != '@') && (notifysocket[0] != '/'))) { + ERROR("invalid notification socket NOTIFY_SOCKET=\"%s\": path must be " + "absolute", + notifysocket); + return 0; + } + NOTICE("Systemd detected, trying to signal readyness."); - unsetenv ("NOTIFY_SOCKET"); + unsetenv("NOTIFY_SOCKET"); #if defined(SOCK_CLOEXEC) - fd = socket (AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, /* protocol = */ 0); + fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, /* protocol = */ 0); #else - fd = socket (AF_UNIX, SOCK_DGRAM, /* protocol = */ 0); + fd = socket(AF_UNIX, SOCK_DGRAM, /* protocol = */ 0); #endif - if (fd < 0) { - char errbuf[1024]; - ERROR ("creating UNIX socket failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return 0; - } - - su.sun_family = AF_UNIX; - if (notifysocket[0] != '@') - { - /* regular UNIX socket */ - sstrncpy (su.sun_path, notifysocket, sizeof (su.sun_path)); - su_size = sizeof (su); - } - else - { - /* Linux abstract namespace socket: specify address as "\0foo", i.e. - * start with a null byte. Since null bytes have no special meaning in - * that case, we have to set su_size correctly to cover only the bytes - * that are part of the address. */ - sstrncpy (su.sun_path, notifysocket, sizeof (su.sun_path)); - su.sun_path[0] = 0; - su_size = sizeof (sa_family_t) + strlen (notifysocket); - if (su_size > sizeof (su)) - su_size = sizeof (su); - } - - if (sendto (fd, buffer, strlen (buffer), MSG_NOSIGNAL, (void *) &su, (socklen_t) su_size) < 0) - { - char errbuf[1024]; - ERROR ("sendto(\"%s\") failed: %s", notifysocket, - sstrerror (errno, errbuf, sizeof (errbuf))); - close(fd); - return 0; - } - - unsetenv ("NOTIFY_SOCKET"); + if (fd < 0) { + char errbuf[1024]; + ERROR("creating UNIX socket failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return 0; + } + + su.sun_family = AF_UNIX; + if (notifysocket[0] != '@') { + /* regular UNIX socket */ + sstrncpy(su.sun_path, notifysocket, sizeof(su.sun_path)); + su_size = sizeof(su); + } else { + /* Linux abstract namespace socket: specify address as "\0foo", i.e. + * start with a null byte. Since null bytes have no special meaning in + * that case, we have to set su_size correctly to cover only the bytes + * that are part of the address. */ + sstrncpy(su.sun_path, notifysocket, sizeof(su.sun_path)); + su.sun_path[0] = 0; + su_size = sizeof(sa_family_t) + strlen(notifysocket); + if (su_size > sizeof(su)) + su_size = sizeof(su); + } + + if (sendto(fd, buffer, strlen(buffer), MSG_NOSIGNAL, (void *)&su, + (socklen_t)su_size) < 0) { + char errbuf[1024]; + ERROR("sendto(\"%s\") failed: %s", notifysocket, + sstrerror(errno, errbuf, sizeof(errbuf))); close(fd); - return 1; + return 0; + } + + unsetenv("NOTIFY_SOCKET"); + close(fd); + return 1; } #endif /* KERNEL_LINUX */ -int main (int argc, char **argv) -{ - const char *configfile = CONFIGFILE; - int test_config = 0; - int test_readall = 0; - const char *basedir; +int main(int argc, char **argv) { + const char *configfile = CONFIGFILE; + int test_config = 0; + int test_readall = 0; + const char *basedir; #if COLLECT_DAEMON - pid_t pid; - int daemonize = 1; + pid_t pid; + int daemonize = 1; #endif - int exit_status = 0; + int exit_status = 0; - /* read options */ - while (1) - { - int c; + /* read options */ + while (1) { + int c; - c = getopt (argc, argv, "htTC:" + c = getopt(argc, argv, "htTC:" #if COLLECT_DAEMON - "fP:" + "fP:" #endif - ); - - if (c == -1) - break; - - switch (c) - { - case 'C': - configfile = optarg; - break; - case 't': - test_config = 1; - break; - case 'T': - test_readall = 1; - global_option_set ("ReadThreads", "-1", 1); + ); + + if (c == -1) + break; + + switch (c) { + case 'C': + configfile = optarg; + break; + case 't': + test_config = 1; + break; + case 'T': + test_readall = 1; + global_option_set("ReadThreads", "-1", 1); #if COLLECT_DAEMON - daemonize = 0; + daemonize = 0; #endif /* COLLECT_DAEMON */ - break; + break; #if COLLECT_DAEMON - case 'P': - global_option_set ("PIDFile", optarg, 1); - break; - case 'f': - daemonize = 0; - break; + case 'P': + global_option_set("PIDFile", optarg, 1); + break; + case 'f': + daemonize = 0; + break; #endif /* COLLECT_DAEMON */ - case 'h': - exit_usage (0); - break; - default: - exit_usage (1); - } /* switch (c) */ - } /* while (1) */ - - if (optind < argc) - exit_usage (1); - - plugin_init_ctx (); - - /* - * Read options from the config file, the environment and the command - * line (in that order, with later options overwriting previous ones in - * general). - * Also, this will automatically load modules. - */ - if (cf_read (configfile)) - { - fprintf (stderr, "Error: Reading the config file failed!\n" - "Read the syslog for details.\n"); - return (1); - } - - /* - * Change directory. We do this _after_ reading the config and loading - * modules to relative paths work as expected. - */ - if ((basedir = global_option_get ("BaseDir")) == NULL) - { - fprintf (stderr, "Don't have a basedir to use. This should not happen. Ever."); - return (1); - } - else if (change_basedir (basedir)) - { - fprintf (stderr, "Error: Unable to change to directory `%s'.\n", basedir); - return (1); - } - - /* - * Set global variables or, if that failes, exit. We cannot run with - * them being uninitialized. If nothing is configured, then defaults - * are being used. So this means that the user has actually done - * something wrong. - */ - if (init_global_variables () != 0) - exit (EXIT_FAILURE); - - if (test_config) - return (0); + case 'h': + exit_usage(0); + break; + default: + exit_usage(1); + } /* switch (c) */ + } /* while (1) */ + + if (optind < argc) + exit_usage(1); + + plugin_init_ctx(); + + /* + * Read options from the config file, the environment and the command + * line (in that order, with later options overwriting previous ones in + * general). + * Also, this will automatically load modules. + */ + if (cf_read(configfile)) { + fprintf(stderr, "Error: Reading the config file failed!\n" + "Read the syslog for details.\n"); + return (1); + } + + /* + * Change directory. We do this _after_ reading the config and loading + * modules to relative paths work as expected. + */ + if ((basedir = global_option_get("BaseDir")) == NULL) { + fprintf(stderr, + "Don't have a basedir to use. This should not happen. Ever."); + return (1); + } else if (change_basedir(basedir)) { + fprintf(stderr, "Error: Unable to change to directory `%s'.\n", basedir); + return (1); + } + + /* + * Set global variables or, if that failes, exit. We cannot run with + * them being uninitialized. If nothing is configured, then defaults + * are being used. So this means that the user has actually done + * something wrong. + */ + if (init_global_variables() != 0) + exit(EXIT_FAILURE); + + if (test_config) + return (0); #if COLLECT_DAEMON - /* - * fork off child - */ - struct sigaction sig_chld_action = { - .sa_handler = SIG_IGN - }; - - sigaction (SIGCHLD, &sig_chld_action, NULL); - - /* - * Only daemonize if we're not being supervised - * by upstart or systemd (when using Linux). - */ - if (daemonize + /* + * fork off child + */ + struct sigaction sig_chld_action = {.sa_handler = SIG_IGN}; + + sigaction(SIGCHLD, &sig_chld_action, NULL); + + /* + * Only daemonize if we're not being supervised + * by upstart or systemd (when using Linux). + */ + if (daemonize #ifdef KERNEL_LINUX - && notify_upstart() == 0 && notify_systemd() == 0 + && notify_upstart() == 0 && notify_systemd() == 0 #endif - ) - { - int status; - - if ((pid = fork ()) == -1) - { - /* error */ - char errbuf[1024]; - fprintf (stderr, "fork: %s", - sstrerror (errno, errbuf, - sizeof (errbuf))); - return (1); - } - else if (pid != 0) - { - /* parent */ - /* printf ("Running (PID %i)\n", pid); */ - return (0); - } - - /* Detach from session */ - setsid (); - - /* Write pidfile */ - if (pidfile_create ()) - exit (2); - - /* close standard descriptors */ - close (2); - close (1); - close (0); - - status = open ("/dev/null", O_RDWR); - if (status != 0) - { - ERROR ("Error: Could not connect `STDIN' to `/dev/null' (status %d)", status); - return (1); - } - - status = dup (0); - if (status != 1) - { - ERROR ("Error: Could not connect `STDOUT' to `/dev/null' (status %d)", status); - return (1); - } - - status = dup (0); - if (status != 2) - { - ERROR ("Error: Could not connect `STDERR' to `/dev/null', (status %d)", status); - return (1); - } - } /* if (daemonize) */ + ) { + int status; + + if ((pid = fork()) == -1) { + /* error */ + char errbuf[1024]; + fprintf(stderr, "fork: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + return (1); + } else if (pid != 0) { + /* parent */ + /* printf ("Running (PID %i)\n", pid); */ + return (0); + } + + /* Detach from session */ + setsid(); + + /* Write pidfile */ + if (pidfile_create()) + exit(2); + + /* close standard descriptors */ + close(2); + close(1); + close(0); + + status = open("/dev/null", O_RDWR); + if (status != 0) { + ERROR("Error: Could not connect `STDIN' to `/dev/null' (status %d)", + status); + return (1); + } + + status = dup(0); + if (status != 1) { + ERROR("Error: Could not connect `STDOUT' to `/dev/null' (status %d)", + status); + return (1); + } + + status = dup(0); + if (status != 2) { + ERROR("Error: Could not connect `STDERR' to `/dev/null', (status %d)", + status); + return (1); + } + } /* if (daemonize) */ #endif /* COLLECT_DAEMON */ - struct sigaction sig_pipe_action = { - .sa_handler = SIG_IGN - }; - - sigaction (SIGPIPE, &sig_pipe_action, NULL); - - /* - * install signal handlers - */ - struct sigaction sig_int_action = { - .sa_handler = sig_int_handler - }; - - if (0 != sigaction (SIGINT, &sig_int_action, NULL)) { - char errbuf[1024]; - ERROR ("Error: Failed to install a signal handler for signal INT: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (1); - } - - struct sigaction sig_term_action = { - .sa_handler = sig_term_handler - }; - - if (0 != sigaction (SIGTERM, &sig_term_action, NULL)) { - char errbuf[1024]; - ERROR ("Error: Failed to install a signal handler for signal TERM: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (1); - } - - struct sigaction sig_usr1_action = { - .sa_handler = sig_usr1_handler - }; - - if (0 != sigaction (SIGUSR1, &sig_usr1_action, NULL)) { - char errbuf[1024]; - ERROR ("Error: Failed to install a signal handler for signal USR1: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (1); - } - - /* - * run the actual loops - */ - if (do_init () != 0) - { - ERROR ("Error: one or more plugin init callbacks failed."); - exit_status = 1; - } - - if (test_readall) - { - if (plugin_read_all_once () != 0) - { - ERROR ("Error: one or more plugin read callbacks failed."); - exit_status = 1; - } - } - else - { - INFO ("Initialization complete, entering read-loop."); - do_loop (); - } - - /* close syslog */ - INFO ("Exiting normally."); - - if (do_shutdown () != 0) - { - ERROR ("Error: one or more plugin shutdown callbacks failed."); - exit_status = 1; - } + struct sigaction sig_pipe_action = {.sa_handler = SIG_IGN}; + + sigaction(SIGPIPE, &sig_pipe_action, NULL); + + /* + * install signal handlers + */ + struct sigaction sig_int_action = {.sa_handler = sig_int_handler}; + + if (0 != sigaction(SIGINT, &sig_int_action, NULL)) { + char errbuf[1024]; + ERROR("Error: Failed to install a signal handler for signal INT: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (1); + } + + struct sigaction sig_term_action = {.sa_handler = sig_term_handler}; + + if (0 != sigaction(SIGTERM, &sig_term_action, NULL)) { + char errbuf[1024]; + ERROR("Error: Failed to install a signal handler for signal TERM: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (1); + } + + struct sigaction sig_usr1_action = {.sa_handler = sig_usr1_handler}; + + if (0 != sigaction(SIGUSR1, &sig_usr1_action, NULL)) { + char errbuf[1024]; + ERROR("Error: Failed to install a signal handler for signal USR1: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (1); + } + + /* + * run the actual loops + */ + if (do_init() != 0) { + ERROR("Error: one or more plugin init callbacks failed."); + exit_status = 1; + } + + if (test_readall) { + if (plugin_read_all_once() != 0) { + ERROR("Error: one or more plugin read callbacks failed."); + exit_status = 1; + } + } else { + INFO("Initialization complete, entering read-loop."); + do_loop(); + } + + /* close syslog */ + INFO("Exiting normally."); + + if (do_shutdown() != 0) { + ERROR("Error: one or more plugin shutdown callbacks failed."); + exit_status = 1; + } #if COLLECT_DAEMON - if (daemonize) - pidfile_remove (); + if (daemonize) + pidfile_remove(); #endif /* COLLECT_DAEMON */ - return (exit_status); + return (exit_status); } /* int main */ diff --git a/src/daemon/collectd.h b/src/daemon/collectd.h index 3cb0c1bb..4ec002de 100644 --- a/src/daemon/collectd.h +++ b/src/daemon/collectd.h @@ -28,264 +28,264 @@ #define COLLECTD_H #if HAVE_CONFIG_H -# include "config.h" +#include "config.h" #endif #include #if HAVE_SYS_TYPES_H -# include +#include #endif #if HAVE_SYS_STAT_H -# include +#include #endif #if STDC_HEADERS -# include -# include +#include +#include #else -# if HAVE_STDLIB_H -# include -# endif +#if HAVE_STDLIB_H +#include +#endif #endif #if HAVE_STRING_H -# if !STDC_HEADERS && HAVE_MEMORY_H -# include -# endif -# include +#if !STDC_HEADERS && HAVE_MEMORY_H +#include +#endif +#include #endif #if HAVE_STRINGS_H -# include +#include #endif #if HAVE_INTTYPES_H -# include +#include #endif #if HAVE_STDINT_H -# include +#include #endif #if HAVE_UNISTD_H -# include +#include #endif #if HAVE_SYS_WAIT_H -# include +#include #endif #ifndef WEXITSTATUS -# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) +#define WEXITSTATUS(stat_val) ((unsigned int)(stat_val) >> 8) #endif #ifndef WIFEXITED -# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#define WIFEXITED(stat_val) (((stat_val)&255) == 0) #endif #if HAVE_SIGNAL_H -# include +#include #endif #if HAVE_FCNTL_H -# include +#include #endif #if HAVE_ERRNO_H -# include +#include #endif #if HAVE_LIMITS_H -# include +#include #endif #if TIME_WITH_SYS_TIME -# include -# include +#include +#include +#else +#if HAVE_SYS_TIME_H +#include #else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif +#include +#endif #endif #if HAVE_SYS_SOCKET_H -# include +#include #endif #if HAVE_ASSERT_H -# include +#include #else -# define assert(...) /* nop */ +#define assert(...) /* nop */ #endif #if !defined(HAVE__BOOL) || !HAVE__BOOL typedef int _Bool; -# undef HAVE__BOOL -# define HAVE__BOOL 1 +#undef HAVE__BOOL +#define HAVE__BOOL 1 #endif #if NAN_STATIC_DEFAULT -# include +#include /* #endif NAN_STATIC_DEFAULT*/ #elif NAN_STATIC_ISOC -# ifndef __USE_ISOC99 -# define DISABLE_ISOC99 1 -# define __USE_ISOC99 1 -# endif /* !defined(__USE_ISOC99) */ -# include -# if DISABLE_ISOC99 -# undef DISABLE_ISOC99 -# undef __USE_ISOC99 -# endif /* DISABLE_ISOC99 */ +#ifndef __USE_ISOC99 +#define DISABLE_ISOC99 1 +#define __USE_ISOC99 1 +#endif /* !defined(__USE_ISOC99) */ +#include +#if DISABLE_ISOC99 +#undef DISABLE_ISOC99 +#undef __USE_ISOC99 +#endif /* DISABLE_ISOC99 */ /* #endif NAN_STATIC_ISOC */ #elif NAN_ZERO_ZERO -# include -# ifdef NAN -# undef NAN -# endif -# define NAN (0.0 / 0.0) -# ifndef isnan -# define isnan(f) ((f) != (f)) -# endif /* !defined(isnan) */ -# ifndef isfinite -# define isfinite(f) (((f) - (f)) == 0.0) -# endif -# ifndef isinf -# define isinf(f) (!isfinite(f) && !isnan(f)) -# endif +#include +#ifdef NAN +#undef NAN +#endif +#define NAN (0.0 / 0.0) +#ifndef isnan +#define isnan(f) ((f) != (f)) +#endif /* !defined(isnan) */ +#ifndef isfinite +#define isfinite(f) (((f) - (f)) == 0.0) +#endif +#ifndef isinf +#define isinf(f) (!isfinite(f) && !isnan(f)) +#endif #endif /* NAN_ZERO_ZERO */ /* Try really, really hard to determine endianess. Under NexentaStor 1.0.2 this * information is in , possibly some other Solaris versions do * this too.. */ #if HAVE_ENDIAN_H -# include +#include #elif HAVE_SYS_ISA_DEFS_H -# include +#include #endif #ifndef BYTE_ORDER -# if defined(_BYTE_ORDER) -# define BYTE_ORDER _BYTE_ORDER -# elif defined(__BYTE_ORDER) -# define BYTE_ORDER __BYTE_ORDER -# elif defined(__DARWIN_BYTE_ORDER) -# define BYTE_ORDER __DARWIN_BYTE_ORDER -# endif +#if defined(_BYTE_ORDER) +#define BYTE_ORDER _BYTE_ORDER +#elif defined(__BYTE_ORDER) +#define BYTE_ORDER __BYTE_ORDER +#elif defined(__DARWIN_BYTE_ORDER) +#define BYTE_ORDER __DARWIN_BYTE_ORDER +#endif #endif #ifndef BIG_ENDIAN -# if defined(_BIG_ENDIAN) -# define BIG_ENDIAN _BIG_ENDIAN -# elif defined(__BIG_ENDIAN) -# define BIG_ENDIAN __BIG_ENDIAN -# elif defined(__DARWIN_BIG_ENDIAN) -# define BIG_ENDIAN __DARWIN_BIG_ENDIAN -# endif +#if defined(_BIG_ENDIAN) +#define BIG_ENDIAN _BIG_ENDIAN +#elif defined(__BIG_ENDIAN) +#define BIG_ENDIAN __BIG_ENDIAN +#elif defined(__DARWIN_BIG_ENDIAN) +#define BIG_ENDIAN __DARWIN_BIG_ENDIAN +#endif #endif #ifndef LITTLE_ENDIAN -# if defined(_LITTLE_ENDIAN) -# define LITTLE_ENDIAN _LITTLE_ENDIAN -# elif defined(__LITTLE_ENDIAN) -# define LITTLE_ENDIAN __LITTLE_ENDIAN -# elif defined(__DARWIN_LITTLE_ENDIAN) -# define LITTLE_ENDIAN __DARWIN_LITTLE_ENDIAN -# endif +#if defined(_LITTLE_ENDIAN) +#define LITTLE_ENDIAN _LITTLE_ENDIAN +#elif defined(__LITTLE_ENDIAN) +#define LITTLE_ENDIAN __LITTLE_ENDIAN +#elif defined(__DARWIN_LITTLE_ENDIAN) +#define LITTLE_ENDIAN __DARWIN_LITTLE_ENDIAN +#endif #endif #ifndef BYTE_ORDER -# if defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN) -# undef BIG_ENDIAN -# define BIG_ENDIAN 4321 -# define LITTLE_ENDIAN 1234 -# define BYTE_ORDER BIG_ENDIAN -# elif !defined(BIG_ENDIAN) && defined(LITTLE_ENDIAN) -# undef LITTLE_ENDIAN -# define BIG_ENDIAN 4321 -# define LITTLE_ENDIAN 1234 -# define BYTE_ORDER LITTLE_ENDIAN -# endif +#if defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN) +#undef BIG_ENDIAN +#define BIG_ENDIAN 4321 +#define LITTLE_ENDIAN 1234 +#define BYTE_ORDER BIG_ENDIAN +#elif !defined(BIG_ENDIAN) && defined(LITTLE_ENDIAN) +#undef LITTLE_ENDIAN +#define BIG_ENDIAN 4321 +#define LITTLE_ENDIAN 1234 +#define BYTE_ORDER LITTLE_ENDIAN +#endif #endif #if !defined(BYTE_ORDER) || !defined(BIG_ENDIAN) -# error "Cannot determine byte order" +#error "Cannot determine byte order" #endif #if HAVE_DIRENT_H -# include -# define NAMLEN(dirent) strlen((dirent)->d_name) +#include +#define NAMLEN(dirent) strlen((dirent)->d_name) #else -# define dirent direct -# define NAMLEN(dirent) (dirent)->d_namlen -# if HAVE_SYS_NDIR_H -# include -# endif -# if HAVE_SYS_DIR_H -# include -# endif -# if HAVE_NDIR_H -# include -# endif +#define dirent direct +#define NAMLEN(dirent) (dirent)->d_namlen +#if HAVE_SYS_NDIR_H +#include +#endif +#if HAVE_SYS_DIR_H +#include +#endif +#if HAVE_NDIR_H +#include +#endif #endif #if HAVE_STDARG_H -# include +#include #endif #if HAVE_CTYPE_H -# include +#include #endif #if HAVE_SYS_PARAM_H -# include +#include #endif #if HAVE_KSTAT_H -# include +#include #endif #ifndef PACKAGE_NAME -# define PACKAGE_NAME "collectd" +#define PACKAGE_NAME "collectd" #endif #ifndef PREFIX -# define PREFIX "/opt/" PACKAGE_NAME +#define PREFIX "/opt/" PACKAGE_NAME #endif #ifndef SYSCONFDIR -# define SYSCONFDIR PREFIX "/etc" +#define SYSCONFDIR PREFIX "/etc" #endif #ifndef CONFIGFILE -# define CONFIGFILE SYSCONFDIR"/collectd.conf" +#define CONFIGFILE SYSCONFDIR "/collectd.conf" #endif #ifndef LOCALSTATEDIR -# define LOCALSTATEDIR PREFIX "/var" +#define LOCALSTATEDIR PREFIX "/var" #endif #ifndef PKGLOCALSTATEDIR -# define PKGLOCALSTATEDIR PREFIX "/var/lib/" PACKAGE_NAME +#define PKGLOCALSTATEDIR PREFIX "/var/lib/" PACKAGE_NAME #endif #ifndef PIDFILE -# define PIDFILE PREFIX "/var/run/" PACKAGE_NAME ".pid" +#define PIDFILE PREFIX "/var/run/" PACKAGE_NAME ".pid" #endif #ifndef PLUGINDIR -# define PLUGINDIR PREFIX "/lib/" PACKAGE_NAME +#define PLUGINDIR PREFIX "/lib/" PACKAGE_NAME #endif #ifndef PKGDATADIR -# define PKGDATADIR PREFIX "/share/" PACKAGE_NAME +#define PKGDATADIR PREFIX "/share/" PACKAGE_NAME #endif #ifndef COLLECTD_GRP_NAME -# define COLLECTD_GRP_NAME "collectd" +#define COLLECTD_GRP_NAME "collectd" #endif #ifndef COLLECTD_DEFAULT_INTERVAL -# define COLLECTD_DEFAULT_INTERVAL 10.0 +#define COLLECTD_DEFAULT_INTERVAL 10.0 #endif #ifndef COLLECTD_USERAGENT -# define COLLECTD_USERAGENT PACKAGE_NAME "/" PACKAGE_VERSION +#define COLLECTD_USERAGENT PACKAGE_NAME "/" PACKAGE_VERSION #endif /* Only enable __attribute__() for compilers known to support it. */ #if !defined(__clang__) && !defined(__GNUC__) -# if !defined(__attribute__) -# define __attribute__(x) /**/ -# endif +#if !defined(__attribute__) +#define __attribute__(x) /**/ +#endif #endif #if defined(COLLECT_DEBUG) && COLLECT_DEBUG && defined(__GNUC__) && __GNUC__ -# undef strcpy -# undef strcat -# undef strtok -# pragma GCC poison strcpy strcat strtok +#undef strcpy +#undef strcat +#undef strtok +#pragma GCC poison strcpy strcat strtok #endif /* @@ -295,21 +295,21 @@ typedef int _Bool; * included. */ #ifndef DONT_POISON_SPRINTF_YET -# if defined(COLLECT_DEBUG) && COLLECT_DEBUG && defined(__GNUC__) && __GNUC__ -# undef sprintf -# pragma GCC poison sprintf -# endif +#if defined(COLLECT_DEBUG) && COLLECT_DEBUG && defined(__GNUC__) && __GNUC__ +#undef sprintf +#pragma GCC poison sprintf +#endif #endif #ifndef GAUGE_FORMAT -# define GAUGE_FORMAT "%.15g" +#define GAUGE_FORMAT "%.15g" #endif /* Type for time as used by "utils_time.h" */ typedef uint64_t cdtime_t; -extern char hostname_g[]; +extern char hostname_g[]; extern cdtime_t interval_g; -extern int timeout_g; +extern int timeout_g; #endif /* COLLECTD_H */ diff --git a/src/daemon/common.c b/src/daemon/common.c index d2cc19da..0aa5345b 100644 --- a/src/daemon/common.c +++ b/src/daemon/common.c @@ -28,7 +28,7 @@ **/ #if HAVE_CONFIG_H -# include "config.h" +#include "config.h" #endif #include "collectd.h" @@ -38,30 +38,30 @@ #include "utils_cache.h" #ifdef HAVE_MATH_H -# include +#include #endif /* for getaddrinfo */ -#include #include +#include #include #if HAVE_NETINET_IN_H -# include +#include #endif #if HAVE_NETINET_TCP_H -# include +#include #endif /* for ntohl and htonl */ #if HAVE_ARPA_INET_H -# include +#include #endif #if HAVE_CAPABILITY -# include +#include #endif #ifdef HAVE_LIBKSTAT @@ -70,7 +70,7 @@ extern kstat_ctl_t *kc; /* AIX doesn't have MSG_DONTWAIT */ #ifndef MSG_DONTWAIT -# define MSG_DONTWAIT MSG_NONBLOCK +#define MSG_DONTWAIT MSG_NONBLOCK #endif #if !HAVE_GETPWNAM_R @@ -81,147 +81,138 @@ static pthread_mutex_t getpwnam_r_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t strerror_r_lock = PTHREAD_MUTEX_INITIALIZER; #endif -char *sstrncpy (char *dest, const char *src, size_t n) -{ - strncpy (dest, src, n); - dest[n - 1] = '\0'; +char *sstrncpy(char *dest, const char *src, size_t n) { + strncpy(dest, src, n); + dest[n - 1] = '\0'; - return (dest); + return (dest); } /* char *sstrncpy */ -int ssnprintf (char *dest, size_t n, const char *format, ...) -{ - int ret = 0; - va_list ap; +int ssnprintf(char *dest, size_t n, const char *format, ...) { + int ret = 0; + va_list ap; - va_start (ap, format); - ret = vsnprintf (dest, n, format, ap); - dest[n - 1] = '\0'; - va_end (ap); + va_start(ap, format); + ret = vsnprintf(dest, n, format, ap); + dest[n - 1] = '\0'; + va_end(ap); - return (ret); + return (ret); } /* int ssnprintf */ -char *ssnprintf_alloc (char const *format, ...) /* {{{ */ +char *ssnprintf_alloc(char const *format, ...) /* {{{ */ { - char static_buffer[1024] = ""; - char *alloc_buffer; - size_t alloc_buffer_size; - int status; - va_list ap; - - /* Try printing into the static buffer. In many cases it will be - * sufficiently large and we can simply return a strdup() of this - * buffer. */ - va_start (ap, format); - status = vsnprintf (static_buffer, sizeof (static_buffer), format, ap); - va_end (ap); - if (status < 0) - return (NULL); - - /* "status" does not include the null byte. */ - alloc_buffer_size = (size_t) (status + 1); - if (alloc_buffer_size <= sizeof (static_buffer)) - return (strdup (static_buffer)); - - /* Allocate a buffer large enough to hold the string. */ - alloc_buffer = calloc (1, alloc_buffer_size); - if (alloc_buffer == NULL) - return (NULL); - - /* Print again into this new buffer. */ - va_start (ap, format); - status = vsnprintf (alloc_buffer, alloc_buffer_size, format, ap); - va_end (ap); - if (status < 0) - { - sfree (alloc_buffer); - return (NULL); - } - - return (alloc_buffer); + char static_buffer[1024] = ""; + char *alloc_buffer; + size_t alloc_buffer_size; + int status; + va_list ap; + + /* Try printing into the static buffer. In many cases it will be + * sufficiently large and we can simply return a strdup() of this + * buffer. */ + va_start(ap, format); + status = vsnprintf(static_buffer, sizeof(static_buffer), format, ap); + va_end(ap); + if (status < 0) + return (NULL); + + /* "status" does not include the null byte. */ + alloc_buffer_size = (size_t)(status + 1); + if (alloc_buffer_size <= sizeof(static_buffer)) + return (strdup(static_buffer)); + + /* Allocate a buffer large enough to hold the string. */ + alloc_buffer = calloc(1, alloc_buffer_size); + if (alloc_buffer == NULL) + return (NULL); + + /* Print again into this new buffer. */ + va_start(ap, format); + status = vsnprintf(alloc_buffer, alloc_buffer_size, format, ap); + va_end(ap); + if (status < 0) { + sfree(alloc_buffer); + return (NULL); + } + + return (alloc_buffer); } /* }}} char *ssnprintf_alloc */ -char *sstrdup (const char *s) -{ - char *r; - size_t sz; - - if (s == NULL) - return (NULL); - - /* Do not use `strdup' here, because it's not specified in POSIX. It's - * ``only'' an XSI extension. */ - sz = strlen (s) + 1; - r = malloc (sz); - if (r == NULL) - { - ERROR ("sstrdup: Out of memory."); - exit (3); - } - memcpy (r, s, sizeof (char) * sz); - - return (r); +char *sstrdup(const char *s) { + char *r; + size_t sz; + + if (s == NULL) + return (NULL); + + /* Do not use `strdup' here, because it's not specified in POSIX. It's + * ``only'' an XSI extension. */ + sz = strlen(s) + 1; + r = malloc(sz); + if (r == NULL) { + ERROR("sstrdup: Out of memory."); + exit(3); + } + memcpy(r, s, sizeof(char) * sz); + + return (r); } /* char *sstrdup */ /* Even though Posix requires "strerror_r" to return an "int", * some systems (e.g. the GNU libc) return a "char *" _and_ * ignore the second argument ... -tokkee */ -char *sstrerror (int errnum, char *buf, size_t buflen) -{ - buf[0] = '\0'; +char *sstrerror(int errnum, char *buf, size_t buflen) { + buf[0] = '\0'; #if !HAVE_STRERROR_R - { - char *temp; + { + char *temp; - pthread_mutex_lock (&strerror_r_lock); + pthread_mutex_lock(&strerror_r_lock); - temp = strerror (errnum); - sstrncpy (buf, temp, buflen); + temp = strerror(errnum); + sstrncpy(buf, temp, buflen); - pthread_mutex_unlock (&strerror_r_lock); - } + pthread_mutex_unlock(&strerror_r_lock); + } /* #endif !HAVE_STRERROR_R */ #elif STRERROR_R_CHAR_P - { - char *temp; - temp = strerror_r (errnum, buf, buflen); - if (buf[0] == '\0') - { - if ((temp != NULL) && (temp != buf) && (temp[0] != '\0')) - sstrncpy (buf, temp, buflen); - else - sstrncpy (buf, "strerror_r did not return " - "an error message", buflen); - } - } + { + char *temp; + temp = strerror_r(errnum, buf, buflen); + if (buf[0] == '\0') { + if ((temp != NULL) && (temp != buf) && (temp[0] != '\0')) + sstrncpy(buf, temp, buflen); + else + sstrncpy(buf, "strerror_r did not return " + "an error message", + buflen); + } + } /* #endif STRERROR_R_CHAR_P */ #else - if (strerror_r (errnum, buf, buflen) != 0) - { - ssnprintf (buf, buflen, "Error #%i; " - "Additionally, strerror_r failed.", - errnum); - } + if (strerror_r(errnum, buf, buflen) != 0) { + ssnprintf(buf, buflen, "Error #%i; " + "Additionally, strerror_r failed.", + errnum); + } #endif /* STRERROR_R_CHAR_P */ - return (buf); + return (buf); } /* char *sstrerror */ -void *smalloc (size_t size) -{ - void *r; +void *smalloc(size_t size) { + void *r; - if ((r = malloc (size)) == NULL) - { - ERROR ("Not enough memory."); - exit (3); - } + if ((r = malloc(size)) == NULL) { + ERROR("Not enough memory."); + exit(3); + } - return (r); + return (r); } /* void *smalloc */ #if 0 @@ -237,106 +228,99 @@ void sfree (void **ptr) } #endif -ssize_t sread (int fd, void *buf, size_t count) -{ - char *ptr; - size_t nleft; - ssize_t status; +ssize_t sread(int fd, void *buf, size_t count) { + char *ptr; + size_t nleft; + ssize_t status; - ptr = (char *) buf; - nleft = count; + ptr = (char *)buf; + nleft = count; - while (nleft > 0) - { - status = read (fd, (void *) ptr, nleft); + while (nleft > 0) { + status = read(fd, (void *)ptr, nleft); - if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) - continue; + if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) + continue; - if (status < 0) - return (status); + if (status < 0) + return (status); - if (status == 0) - { - DEBUG ("Received EOF from fd %i. " - "Closing fd and returning error.", - fd); - close (fd); - return (-1); - } + if (status == 0) { + DEBUG("Received EOF from fd %i. " + "Closing fd and returning error.", + fd); + close(fd); + return (-1); + } - assert ((0 > status) || (nleft >= (size_t)status)); + assert((0 > status) || (nleft >= (size_t)status)); - nleft = nleft - ((size_t) status); - ptr = ptr + ((size_t) status); - } + nleft = nleft - ((size_t)status); + ptr = ptr + ((size_t)status); + } - return (0); + return (0); } +ssize_t swrite(int fd, const void *buf, size_t count) { + const char *ptr; + size_t nleft; + ssize_t status; + struct pollfd pfd; + + ptr = (const char *)buf; + nleft = count; + + if (fd < 0) + return (-1); + + /* checking for closed peer connection */ + pfd.fd = fd; + pfd.events = POLLIN | POLLHUP; + pfd.revents = 0; + if (poll(&pfd, 1, 0) > 0) { + char buffer[32]; + if (recv(fd, buffer, sizeof(buffer), MSG_PEEK | MSG_DONTWAIT) == 0) { + // if recv returns zero (even though poll() said there is data to be + // read), + // that means the connection has been closed + return -1; + } + } + + while (nleft > 0) { + status = write(fd, (const void *)ptr, nleft); -ssize_t swrite (int fd, const void *buf, size_t count) -{ - const char *ptr; - size_t nleft; - ssize_t status; - struct pollfd pfd; - - ptr = (const char *) buf; - nleft = count; - - if (fd < 0) - return (-1); - - /* checking for closed peer connection */ - pfd.fd = fd; - pfd.events = POLLIN | POLLHUP; - pfd.revents = 0; - if (poll(&pfd, 1, 0) > 0) { - char buffer[32]; - if (recv(fd, buffer, sizeof(buffer), MSG_PEEK | MSG_DONTWAIT) == 0) { - // if recv returns zero (even though poll() said there is data to be read), - // that means the connection has been closed - return -1; - } - } - - while (nleft > 0) - { - status = write (fd, (const void *) ptr, nleft); - - if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) - continue; - - if (status < 0) - return (status); - - nleft = nleft - ((size_t) status); - ptr = ptr + ((size_t) status); - } - - return (0); + if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) + continue; + + if (status < 0) + return (status); + + nleft = nleft - ((size_t)status); + ptr = ptr + ((size_t)status); + } + + return (0); } -int strsplit (char *string, char **fields, size_t size) -{ - size_t i; - char *ptr; - char *saveptr; - - i = 0; - ptr = string; - saveptr = NULL; - while ((fields[i] = strtok_r (ptr, " \t\r\n", &saveptr)) != NULL) - { - ptr = NULL; - i++; - - if (i >= size) - break; - } - - return ((int) i); +int strsplit(char *string, char **fields, size_t size) { + size_t i; + char *ptr; + char *saveptr; + + i = 0; + ptr = string; + saveptr = NULL; + while ((fields[i] = strtok_r(ptr, " \t\r\n", &saveptr)) != NULL) { + ptr = NULL; + i++; + + if (i >= size) + break; + } + + return ((int)i); } int strjoin(char *buffer, size_t buffer_size, char **fields, size_t fields_num, @@ -395,42 +379,35 @@ int strjoin(char *buffer, size_t buffer_size, char **fields, size_t fields_num, return (int)buffer_req; } -int escape_string (char *buffer, size_t buffer_size) -{ +int escape_string(char *buffer, size_t buffer_size) { char *temp; size_t j; /* Check if we need to escape at all first */ - temp = strpbrk (buffer, " \t\"\\"); + temp = strpbrk(buffer, " \t\"\\"); if (temp == NULL) return (0); if (buffer_size < 3) return (EINVAL); - temp = calloc (1, buffer_size); + temp = calloc(1, buffer_size); if (temp == NULL) return (ENOMEM); temp[0] = '"'; j = 1; - for (size_t i = 0; i < buffer_size; i++) - { - if (buffer[i] == 0) - { + for (size_t i = 0; i < buffer_size; i++) { + if (buffer[i] == 0) { break; - } - else if ((buffer[i] == '"') || (buffer[i] == '\\')) - { + } else if ((buffer[i] == '"') || (buffer[i] == '\\')) { if (j > (buffer_size - 4)) break; temp[j] = '\\'; temp[j + 1] = buffer[i]; j += 2; - } - else - { + } else { if (j > (buffer_size - 3)) break; temp[j] = buffer[i]; @@ -438,390 +415,349 @@ int escape_string (char *buffer, size_t buffer_size) } } - assert ((j + 1) < buffer_size); + assert((j + 1) < buffer_size); temp[j] = '"'; temp[j + 1] = 0; - sstrncpy (buffer, temp, buffer_size); - sfree (temp); + sstrncpy(buffer, temp, buffer_size); + sfree(temp); return (0); } /* int escape_string */ -int strunescape (char *buf, size_t buf_len) -{ - for (size_t i = 0; (i < buf_len) && (buf[i] != '\0'); ++i) - { - if (buf[i] != '\\') - continue; - - if (((i + 1) >= buf_len) || (buf[i + 1] == 0)) { - ERROR ("string unescape: backslash found at end of string."); - /* Ensure null-byte at the end of the buffer. */ - buf[i] = 0; - return (-1); - } - - switch (buf[i + 1]) { - case 't': - buf[i] = '\t'; - break; - case 'n': - buf[i] = '\n'; - break; - case 'r': - buf[i] = '\r'; - break; - default: - buf[i] = buf[i + 1]; - break; - } - - /* Move everything after the position one position to the left. - * Add a null-byte as last character in the buffer. */ - memmove (buf + i + 1, buf + i + 2, buf_len - i - 2); - buf[buf_len - 1] = 0; - } - return (0); +int strunescape(char *buf, size_t buf_len) { + for (size_t i = 0; (i < buf_len) && (buf[i] != '\0'); ++i) { + if (buf[i] != '\\') + continue; + + if (((i + 1) >= buf_len) || (buf[i + 1] == 0)) { + ERROR("string unescape: backslash found at end of string."); + /* Ensure null-byte at the end of the buffer. */ + buf[i] = 0; + return (-1); + } + + switch (buf[i + 1]) { + case 't': + buf[i] = '\t'; + break; + case 'n': + buf[i] = '\n'; + break; + case 'r': + buf[i] = '\r'; + break; + default: + buf[i] = buf[i + 1]; + break; + } + + /* Move everything after the position one position to the left. + * Add a null-byte as last character in the buffer. */ + memmove(buf + i + 1, buf + i + 2, buf_len - i - 2); + buf[buf_len - 1] = 0; + } + return (0); } /* int strunescape */ -size_t strstripnewline (char *buffer) -{ - size_t buffer_len = strlen (buffer); - - while (buffer_len > 0) - { - if ((buffer[buffer_len - 1] != '\n') - && (buffer[buffer_len - 1] != '\r')) - break; - buffer_len--; - buffer[buffer_len] = 0; - } - - return (buffer_len); +size_t strstripnewline(char *buffer) { + size_t buffer_len = strlen(buffer); + + while (buffer_len > 0) { + if ((buffer[buffer_len - 1] != '\n') && (buffer[buffer_len - 1] != '\r')) + break; + buffer_len--; + buffer[buffer_len] = 0; + } + + return (buffer_len); } /* size_t strstripnewline */ -int escape_slashes (char *buffer, size_t buffer_size) -{ - size_t buffer_len; - - buffer_len = strlen (buffer); - - if (buffer_len <= 1) - { - if (strcmp ("/", buffer) == 0) - { - if (buffer_size < 5) - return (-1); - sstrncpy (buffer, "root", buffer_size); - } - return (0); - } - - /* Move one to the left */ - if (buffer[0] == '/') - { - memmove (buffer, buffer + 1, buffer_len); - buffer_len--; - } - - for (size_t i = 0; i < buffer_len; i++) - { - if (buffer[i] == '/') - buffer[i] = '_'; - } - - return (0); +int escape_slashes(char *buffer, size_t buffer_size) { + size_t buffer_len; + + buffer_len = strlen(buffer); + + if (buffer_len <= 1) { + if (strcmp("/", buffer) == 0) { + if (buffer_size < 5) + return (-1); + sstrncpy(buffer, "root", buffer_size); + } + return (0); + } + + /* Move one to the left */ + if (buffer[0] == '/') { + memmove(buffer, buffer + 1, buffer_len); + buffer_len--; + } + + for (size_t i = 0; i < buffer_len; i++) { + if (buffer[i] == '/') + buffer[i] = '_'; + } + + return (0); } /* int escape_slashes */ -void replace_special (char *buffer, size_t buffer_size) -{ - for (size_t i = 0; i < buffer_size; i++) - { - if (buffer[i] == 0) - return; - if ((!isalnum ((int) buffer[i])) && (buffer[i] != '-')) - buffer[i] = '_'; - } +void replace_special(char *buffer, size_t buffer_size) { + for (size_t i = 0; i < buffer_size; i++) { + if (buffer[i] == 0) + return; + if ((!isalnum((int)buffer[i])) && (buffer[i] != '-')) + buffer[i] = '_'; + } } /* void replace_special */ -int timeval_cmp (struct timeval tv0, struct timeval tv1, struct timeval *delta) -{ - struct timeval *larger; - struct timeval *smaller; - - int status; - - NORMALIZE_TIMEVAL (tv0); - NORMALIZE_TIMEVAL (tv1); - - if ((tv0.tv_sec == tv1.tv_sec) && (tv0.tv_usec == tv1.tv_usec)) - { - if (delta != NULL) { - delta->tv_sec = 0; - delta->tv_usec = 0; - } - return (0); - } - - if ((tv0.tv_sec < tv1.tv_sec) - || ((tv0.tv_sec == tv1.tv_sec) && (tv0.tv_usec < tv1.tv_usec))) - { - larger = &tv1; - smaller = &tv0; - status = -1; - } - else - { - larger = &tv0; - smaller = &tv1; - status = 1; - } - - if (delta != NULL) { - delta->tv_sec = larger->tv_sec - smaller->tv_sec; - - if (smaller->tv_usec <= larger->tv_usec) - delta->tv_usec = larger->tv_usec - smaller->tv_usec; - else - { - --delta->tv_sec; - delta->tv_usec = 1000000 + larger->tv_usec - smaller->tv_usec; - } - } - - assert ((delta == NULL) - || ((0 <= delta->tv_usec) && (delta->tv_usec < 1000000))); - - return (status); +int timeval_cmp(struct timeval tv0, struct timeval tv1, struct timeval *delta) { + struct timeval *larger; + struct timeval *smaller; + + int status; + + NORMALIZE_TIMEVAL(tv0); + NORMALIZE_TIMEVAL(tv1); + + if ((tv0.tv_sec == tv1.tv_sec) && (tv0.tv_usec == tv1.tv_usec)) { + if (delta != NULL) { + delta->tv_sec = 0; + delta->tv_usec = 0; + } + return (0); + } + + if ((tv0.tv_sec < tv1.tv_sec) || + ((tv0.tv_sec == tv1.tv_sec) && (tv0.tv_usec < tv1.tv_usec))) { + larger = &tv1; + smaller = &tv0; + status = -1; + } else { + larger = &tv0; + smaller = &tv1; + status = 1; + } + + if (delta != NULL) { + delta->tv_sec = larger->tv_sec - smaller->tv_sec; + + if (smaller->tv_usec <= larger->tv_usec) + delta->tv_usec = larger->tv_usec - smaller->tv_usec; + else { + --delta->tv_sec; + delta->tv_usec = 1000000 + larger->tv_usec - smaller->tv_usec; + } + } + + assert((delta == NULL) || + ((0 <= delta->tv_usec) && (delta->tv_usec < 1000000))); + + return (status); } /* int timeval_cmp */ -int check_create_dir (const char *file_orig) -{ - struct stat statbuf; - - char file_copy[512]; - char dir[512]; - int dir_len = 512; - char *fields[16]; - int fields_num; - char *ptr; - char *saveptr; - int last_is_file = 1; - int path_is_absolute = 0; - size_t len; - - /* - * Sanity checks first - */ - if (file_orig == NULL) - return (-1); - - if ((len = strlen (file_orig)) < 1) - return (-1); - else if (len >= sizeof (file_copy)) - return (-1); - - /* - * If `file_orig' ends in a slash the last component is a directory, - * otherwise it's a file. Act accordingly.. - */ - if (file_orig[len - 1] == '/') - last_is_file = 0; - if (file_orig[0] == '/') - path_is_absolute = 1; - - /* - * Create a copy for `strtok_r' to destroy - */ - sstrncpy (file_copy, file_orig, sizeof (file_copy)); - - /* - * Break into components. This will eat up several slashes in a row and - * remove leading and trailing slashes.. - */ - ptr = file_copy; - saveptr = NULL; - fields_num = 0; - while ((fields[fields_num] = strtok_r (ptr, "/", &saveptr)) != NULL) - { - ptr = NULL; - fields_num++; - - if (fields_num >= 16) - break; - } - - /* - * For each component, do.. - */ - for (int i = 0; i < (fields_num - last_is_file); i++) - { - /* - * Do not create directories that start with a dot. This - * prevents `../../' attacks and other likely malicious - * behavior. - */ - if (fields[i][0] == '.') - { - ERROR ("Cowardly refusing to create a directory that " - "begins with a `.' (dot): `%s'", file_orig); - return (-2); - } - - /* - * Join the components together again - */ - dir[0] = '/'; - if (strjoin (dir + path_is_absolute, (size_t) (dir_len - path_is_absolute), - fields, (size_t) (i + 1), "/") < 0) - { - ERROR ("strjoin failed: `%s', component #%i", file_orig, i); - return (-1); - } - - while (42) { - if ((stat (dir, &statbuf) == -1) - && (lstat (dir, &statbuf) == -1)) - { - if (errno == ENOENT) - { - if (mkdir (dir, S_IRWXU | S_IRWXG | S_IRWXO) == 0) - break; - - /* this might happen, if a different thread created - * the directory in the meantime - * => call stat() again to check for S_ISDIR() */ - if (EEXIST == errno) - continue; - - char errbuf[1024]; - ERROR ("check_create_dir: mkdir (%s): %s", dir, - sstrerror (errno, - errbuf, sizeof (errbuf))); - return (-1); - } - else - { - char errbuf[1024]; - ERROR ("check_create_dir: stat (%s): %s", dir, - sstrerror (errno, errbuf, - sizeof (errbuf))); - return (-1); - } - } - else if (!S_ISDIR (statbuf.st_mode)) - { - ERROR ("check_create_dir: `%s' exists but is not " - "a directory!", dir); - return (-1); - } - break; - } - } - - return (0); +int check_create_dir(const char *file_orig) { + struct stat statbuf; + + char file_copy[512]; + char dir[512]; + int dir_len = 512; + char *fields[16]; + int fields_num; + char *ptr; + char *saveptr; + int last_is_file = 1; + int path_is_absolute = 0; + size_t len; + + /* + * Sanity checks first + */ + if (file_orig == NULL) + return (-1); + + if ((len = strlen(file_orig)) < 1) + return (-1); + else if (len >= sizeof(file_copy)) + return (-1); + + /* + * If `file_orig' ends in a slash the last component is a directory, + * otherwise it's a file. Act accordingly.. + */ + if (file_orig[len - 1] == '/') + last_is_file = 0; + if (file_orig[0] == '/') + path_is_absolute = 1; + + /* + * Create a copy for `strtok_r' to destroy + */ + sstrncpy(file_copy, file_orig, sizeof(file_copy)); + + /* + * Break into components. This will eat up several slashes in a row and + * remove leading and trailing slashes.. + */ + ptr = file_copy; + saveptr = NULL; + fields_num = 0; + while ((fields[fields_num] = strtok_r(ptr, "/", &saveptr)) != NULL) { + ptr = NULL; + fields_num++; + + if (fields_num >= 16) + break; + } + + /* + * For each component, do.. + */ + for (int i = 0; i < (fields_num - last_is_file); i++) { + /* + * Do not create directories that start with a dot. This + * prevents `../../' attacks and other likely malicious + * behavior. + */ + if (fields[i][0] == '.') { + ERROR("Cowardly refusing to create a directory that " + "begins with a `.' (dot): `%s'", + file_orig); + return (-2); + } + + /* + * Join the components together again + */ + dir[0] = '/'; + if (strjoin(dir + path_is_absolute, (size_t)(dir_len - path_is_absolute), + fields, (size_t)(i + 1), "/") < 0) { + ERROR("strjoin failed: `%s', component #%i", file_orig, i); + return (-1); + } + + while (42) { + if ((stat(dir, &statbuf) == -1) && (lstat(dir, &statbuf) == -1)) { + if (errno == ENOENT) { + if (mkdir(dir, S_IRWXU | S_IRWXG | S_IRWXO) == 0) + break; + + /* this might happen, if a different thread created + * the directory in the meantime + * => call stat() again to check for S_ISDIR() */ + if (EEXIST == errno) + continue; + + char errbuf[1024]; + ERROR("check_create_dir: mkdir (%s): %s", dir, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } else { + char errbuf[1024]; + ERROR("check_create_dir: stat (%s): %s", dir, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + } else if (!S_ISDIR(statbuf.st_mode)) { + ERROR("check_create_dir: `%s' exists but is not " + "a directory!", + dir); + return (-1); + } + break; + } + } + + return (0); } /* check_create_dir */ #ifdef HAVE_LIBKSTAT -int get_kstat (kstat_t **ksp_ptr, char *module, int instance, char *name) -{ - char ident[128]; +int get_kstat(kstat_t **ksp_ptr, char *module, int instance, char *name) { + char ident[128]; - *ksp_ptr = NULL; + *ksp_ptr = NULL; - if (kc == NULL) - return (-1); + if (kc == NULL) + return (-1); - ssnprintf (ident, sizeof (ident), "%s,%i,%s", module, instance, name); + ssnprintf(ident, sizeof(ident), "%s,%i,%s", module, instance, name); - *ksp_ptr = kstat_lookup (kc, module, instance, name); - if (*ksp_ptr == NULL) - { - ERROR ("get_kstat: Cound not find kstat %s", ident); - return (-1); - } + *ksp_ptr = kstat_lookup(kc, module, instance, name); + if (*ksp_ptr == NULL) { + ERROR("get_kstat: Cound not find kstat %s", ident); + return (-1); + } - if ((*ksp_ptr)->ks_type != KSTAT_TYPE_NAMED) - { - ERROR ("get_kstat: kstat %s has wrong type", ident); - *ksp_ptr = NULL; - return (-1); - } + if ((*ksp_ptr)->ks_type != KSTAT_TYPE_NAMED) { + ERROR("get_kstat: kstat %s has wrong type", ident); + *ksp_ptr = NULL; + return (-1); + } #ifdef assert - assert (*ksp_ptr != NULL); - assert ((*ksp_ptr)->ks_type == KSTAT_TYPE_NAMED); + assert(*ksp_ptr != NULL); + assert((*ksp_ptr)->ks_type == KSTAT_TYPE_NAMED); #endif - if (kstat_read (kc, *ksp_ptr, NULL) == -1) - { - ERROR ("get_kstat: kstat %s could not be read", ident); - return (-1); - } + if (kstat_read(kc, *ksp_ptr, NULL) == -1) { + ERROR("get_kstat: kstat %s could not be read", ident); + return (-1); + } - if ((*ksp_ptr)->ks_type != KSTAT_TYPE_NAMED) - { - ERROR ("get_kstat: kstat %s has wrong type", ident); - return (-1); - } + if ((*ksp_ptr)->ks_type != KSTAT_TYPE_NAMED) { + ERROR("get_kstat: kstat %s has wrong type", ident); + return (-1); + } - return (0); + return (0); } -long long get_kstat_value (kstat_t *ksp, char *name) -{ - kstat_named_t *kn; - long long retval = -1LL; - - if (ksp == NULL) - { - ERROR ("get_kstat_value (\"%s\"): ksp is NULL.", name); - return (-1LL); - } - else if (ksp->ks_type != KSTAT_TYPE_NAMED) - { - ERROR ("get_kstat_value (\"%s\"): ksp->ks_type (%#x) " - "is not KSTAT_TYPE_NAMED (%#x).", - name, - (unsigned int) ksp->ks_type, - (unsigned int) KSTAT_TYPE_NAMED); - return (-1LL); - } - - if ((kn = (kstat_named_t *) kstat_data_lookup (ksp, name)) == NULL) - return (-1LL); - - if (kn->data_type == KSTAT_DATA_INT32) - retval = (long long) kn->value.i32; - else if (kn->data_type == KSTAT_DATA_UINT32) - retval = (long long) kn->value.ui32; - else if (kn->data_type == KSTAT_DATA_INT64) - retval = (long long) kn->value.i64; /* According to ANSI C99 `long long' must hold at least 64 bits */ - else if (kn->data_type == KSTAT_DATA_UINT64) - retval = (long long) kn->value.ui64; /* XXX: Might overflow! */ - else - WARNING ("get_kstat_value: Not a numeric value: %s", name); - - return (retval); +long long get_kstat_value(kstat_t *ksp, char *name) { + kstat_named_t *kn; + long long retval = -1LL; + + if (ksp == NULL) { + ERROR("get_kstat_value (\"%s\"): ksp is NULL.", name); + return (-1LL); + } else if (ksp->ks_type != KSTAT_TYPE_NAMED) { + ERROR("get_kstat_value (\"%s\"): ksp->ks_type (%#x) " + "is not KSTAT_TYPE_NAMED (%#x).", + name, (unsigned int)ksp->ks_type, (unsigned int)KSTAT_TYPE_NAMED); + return (-1LL); + } + + if ((kn = (kstat_named_t *)kstat_data_lookup(ksp, name)) == NULL) + return (-1LL); + + if (kn->data_type == KSTAT_DATA_INT32) + retval = (long long)kn->value.i32; + else if (kn->data_type == KSTAT_DATA_UINT32) + retval = (long long)kn->value.ui32; + else if (kn->data_type == KSTAT_DATA_INT64) + retval = + (long long)kn->value.i64; /* According to ANSI C99 `long long' must hold + at least 64 bits */ + else if (kn->data_type == KSTAT_DATA_UINT64) + retval = (long long)kn->value.ui64; /* XXX: Might overflow! */ + else + WARNING("get_kstat_value: Not a numeric value: %s", name); + + return (retval); } #endif /* HAVE_LIBKSTAT */ #ifndef HAVE_HTONLL -unsigned long long ntohll (unsigned long long n) -{ +unsigned long long ntohll(unsigned long long n) { #if BYTE_ORDER == BIG_ENDIAN - return (n); + return (n); #else - return (((unsigned long long) ntohl (n)) << 32) + ntohl (n >> 32); + return (((unsigned long long)ntohl(n)) << 32) + ntohl(n >> 32); #endif } /* unsigned long long ntohll */ -unsigned long long htonll (unsigned long long n) -{ +unsigned long long htonll(unsigned long long n) { #if BYTE_ORDER == BIG_ENDIAN - return (n); + return (n); #else - return (((unsigned long long) htonl (n)) << 32) + htonl (n >> 32); + return (((unsigned long long)htonl(n)) << 32) + htonl(n >> 32); #endif } /* unsigned long long htonll */ #endif /* HAVE_HTONLL */ @@ -831,284 +767,253 @@ unsigned long long htonll (unsigned long long n) /* #endif FP_LAYOUT_NEED_NOTHING */ #elif FP_LAYOUT_NEED_ENDIANFLIP || FP_LAYOUT_NEED_INTSWAP -# if FP_LAYOUT_NEED_ENDIANFLIP -# define FP_CONVERT(A) ((((uint64_t)(A) & 0xff00000000000000LL) >> 56) | \ - (((uint64_t)(A) & 0x00ff000000000000LL) >> 40) | \ - (((uint64_t)(A) & 0x0000ff0000000000LL) >> 24) | \ - (((uint64_t)(A) & 0x000000ff00000000LL) >> 8) | \ - (((uint64_t)(A) & 0x00000000ff000000LL) << 8) | \ - (((uint64_t)(A) & 0x0000000000ff0000LL) << 24) | \ - (((uint64_t)(A) & 0x000000000000ff00LL) << 40) | \ - (((uint64_t)(A) & 0x00000000000000ffLL) << 56)) -# else -# define FP_CONVERT(A) ((((uint64_t)(A) & 0xffffffff00000000LL) >> 32) | \ - (((uint64_t)(A) & 0x00000000ffffffffLL) << 32)) -# endif - -double ntohd (double d) -{ - union - { - uint8_t byte[8]; - uint64_t integer; - double floating; - } ret; - - ret.floating = d; - - /* NAN in x86 byte order */ - if ((ret.byte[0] == 0x00) && (ret.byte[1] == 0x00) - && (ret.byte[2] == 0x00) && (ret.byte[3] == 0x00) - && (ret.byte[4] == 0x00) && (ret.byte[5] == 0x00) - && (ret.byte[6] == 0xf8) && (ret.byte[7] == 0x7f)) - { - return (NAN); - } - else - { - uint64_t tmp; - - tmp = ret.integer; - ret.integer = FP_CONVERT (tmp); - return (ret.floating); - } +#if FP_LAYOUT_NEED_ENDIANFLIP +#define FP_CONVERT(A) \ + ((((uint64_t)(A)&0xff00000000000000LL) >> 56) | \ + (((uint64_t)(A)&0x00ff000000000000LL) >> 40) | \ + (((uint64_t)(A)&0x0000ff0000000000LL) >> 24) | \ + (((uint64_t)(A)&0x000000ff00000000LL) >> 8) | \ + (((uint64_t)(A)&0x00000000ff000000LL) << 8) | \ + (((uint64_t)(A)&0x0000000000ff0000LL) << 24) | \ + (((uint64_t)(A)&0x000000000000ff00LL) << 40) | \ + (((uint64_t)(A)&0x00000000000000ffLL) << 56)) +#else +#define FP_CONVERT(A) \ + ((((uint64_t)(A)&0xffffffff00000000LL) >> 32) | \ + (((uint64_t)(A)&0x00000000ffffffffLL) << 32)) +#endif + +double ntohd(double d) { + union { + uint8_t byte[8]; + uint64_t integer; + double floating; + } ret; + + ret.floating = d; + + /* NAN in x86 byte order */ + if ((ret.byte[0] == 0x00) && (ret.byte[1] == 0x00) && (ret.byte[2] == 0x00) && + (ret.byte[3] == 0x00) && (ret.byte[4] == 0x00) && (ret.byte[5] == 0x00) && + (ret.byte[6] == 0xf8) && (ret.byte[7] == 0x7f)) { + return (NAN); + } else { + uint64_t tmp; + + tmp = ret.integer; + ret.integer = FP_CONVERT(tmp); + return (ret.floating); + } } /* double ntohd */ -double htond (double d) -{ - union - { - uint8_t byte[8]; - uint64_t integer; - double floating; - } ret; - - if (isnan (d)) - { - ret.byte[0] = ret.byte[1] = ret.byte[2] = ret.byte[3] = 0x00; - ret.byte[4] = ret.byte[5] = 0x00; - ret.byte[6] = 0xf8; - ret.byte[7] = 0x7f; - return (ret.floating); - } - else - { - uint64_t tmp; - - ret.floating = d; - tmp = FP_CONVERT (ret.integer); - ret.integer = tmp; - return (ret.floating); - } +double htond(double d) { + union { + uint8_t byte[8]; + uint64_t integer; + double floating; + } ret; + + if (isnan(d)) { + ret.byte[0] = ret.byte[1] = ret.byte[2] = ret.byte[3] = 0x00; + ret.byte[4] = ret.byte[5] = 0x00; + ret.byte[6] = 0xf8; + ret.byte[7] = 0x7f; + return (ret.floating); + } else { + uint64_t tmp; + + ret.floating = d; + tmp = FP_CONVERT(ret.integer); + ret.integer = tmp; + return (ret.floating); + } } /* double htond */ #endif /* FP_LAYOUT_NEED_ENDIANFLIP || FP_LAYOUT_NEED_INTSWAP */ -int format_name (char *ret, int ret_len, - const char *hostname, - const char *plugin, const char *plugin_instance, - const char *type, const char *type_instance) -{ +int format_name(char *ret, int ret_len, const char *hostname, + const char *plugin, const char *plugin_instance, + const char *type, const char *type_instance) { char *buffer; size_t buffer_size; buffer = ret; - buffer_size = (size_t) ret_len; - -#define APPEND(str) do { \ - size_t l = strlen (str); \ - if (l >= buffer_size) \ - return (ENOBUFS); \ - memcpy (buffer, (str), l); \ - buffer += l; buffer_size -= l; \ -} while (0) - - assert (plugin != NULL); - assert (type != NULL); - - APPEND (hostname); - APPEND ("/"); - APPEND (plugin); - if ((plugin_instance != NULL) && (plugin_instance[0] != 0)) - { - APPEND ("-"); - APPEND (plugin_instance); + buffer_size = (size_t)ret_len; + +#define APPEND(str) \ + do { \ + size_t l = strlen(str); \ + if (l >= buffer_size) \ + return (ENOBUFS); \ + memcpy(buffer, (str), l); \ + buffer += l; \ + buffer_size -= l; \ + } while (0) + + assert(plugin != NULL); + assert(type != NULL); + + APPEND(hostname); + APPEND("/"); + APPEND(plugin); + if ((plugin_instance != NULL) && (plugin_instance[0] != 0)) { + APPEND("-"); + APPEND(plugin_instance); } - APPEND ("/"); - APPEND (type); - if ((type_instance != NULL) && (type_instance[0] != 0)) - { - APPEND ("-"); - APPEND (type_instance); + APPEND("/"); + APPEND(type); + if ((type_instance != NULL) && (type_instance[0] != 0)) { + APPEND("-"); + APPEND(type_instance); } - assert (buffer_size > 0); + assert(buffer_size > 0); buffer[0] = 0; #undef APPEND 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; - 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 (size_t i = 0; i < ds->ds_num; i++) - { - if (ds->ds[i].type == DS_TYPE_GAUGE) - BUFFER_ADD (":"GAUGE_FORMAT, 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 (":"GAUGE_FORMAT, 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: Unknown data source type: %i", - ds->ds[i].type); - sfree (rates); - return (-1); - } - } /* for ds->ds_num */ +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; + 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 (size_t i = 0; i < ds->ds_num; i++) { + if (ds->ds[i].type == DS_TYPE_GAUGE) + BUFFER_ADD(":" GAUGE_FORMAT, 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(":" GAUGE_FORMAT, 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: Unknown data source type: %i", ds->ds[i].type); + sfree(rates); + return (-1); + } + } /* for ds->ds_num */ #undef BUFFER_ADD - sfree (rates); - return (0); + 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, - char *default_host) -{ - char *hostname = NULL; - char *plugin = NULL; - char *plugin_instance = NULL; - char *type = NULL; - char *type_instance = NULL; - - hostname = str; - if (hostname == NULL) - return (-1); - - plugin = strchr (hostname, '/'); - if (plugin == NULL) - return (-1); - *plugin = '\0'; plugin++; - - type = strchr (plugin, '/'); - if (type == NULL) - { - if (default_host == NULL) - return (-1); - /* else: no host specified; use default */ - type = plugin; - plugin = hostname; - hostname = default_host; - } - else - { - *type = '\0'; - type++; - } - - plugin_instance = strchr (plugin, '-'); - if (plugin_instance != NULL) - { - *plugin_instance = '\0'; - plugin_instance++; - } - - type_instance = strchr (type, '-'); - if (type_instance != NULL) - { - *type_instance = '\0'; - type_instance++; - } - - *ret_host = hostname; - *ret_plugin = plugin; - *ret_plugin_instance = plugin_instance; - *ret_type = type; - *ret_type_instance = type_instance; - return (0); +int parse_identifier(char *str, char **ret_host, char **ret_plugin, + char **ret_plugin_instance, char **ret_type, + char **ret_type_instance, char *default_host) { + char *hostname = NULL; + char *plugin = NULL; + char *plugin_instance = NULL; + char *type = NULL; + char *type_instance = NULL; + + hostname = str; + if (hostname == NULL) + return (-1); + + plugin = strchr(hostname, '/'); + if (plugin == NULL) + return (-1); + *plugin = '\0'; + plugin++; + + type = strchr(plugin, '/'); + if (type == NULL) { + if (default_host == NULL) + return (-1); + /* else: no host specified; use default */ + type = plugin; + plugin = hostname; + hostname = default_host; + } else { + *type = '\0'; + type++; + } + + plugin_instance = strchr(plugin, '-'); + if (plugin_instance != NULL) { + *plugin_instance = '\0'; + plugin_instance++; + } + + type_instance = strchr(type, '-'); + if (type_instance != NULL) { + *type_instance = '\0'; + type_instance++; + } + + *ret_host = hostname; + *ret_plugin = plugin; + *ret_plugin_instance = plugin_instance; + *ret_type = type; + *ret_type_instance = type_instance; + return (0); } /* int parse_identifier */ -int parse_identifier_vl (const char *str, value_list_t *vl) /* {{{ */ +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, - /* default_host = */ NULL); - 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); + 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, + /* default_host = */ NULL); + 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) -{ +int parse_value(const char *value_orig, value_t *ret_value, int ds_type) { char *value; char *endptr = NULL; size_t value_len; @@ -1116,630 +1021,568 @@ int parse_value (const char *value_orig, value_t *ret_value, int ds_type) if (value_orig == NULL) return (EINVAL); - value = strdup (value_orig); + value = strdup(value_orig); if (value == NULL) return (ENOMEM); - value_len = strlen (value); + value_len = strlen(value); - while ((value_len > 0) && isspace ((int) value[value_len - 1])) - { + while ((value_len > 0) && isspace((int)value[value_len - 1])) { value[value_len - 1] = 0; value_len--; } - switch (ds_type) - { - case DS_TYPE_COUNTER: - ret_value->counter = (counter_t) strtoull (value, &endptr, 0); - break; + switch (ds_type) { + case DS_TYPE_COUNTER: + ret_value->counter = (counter_t)strtoull(value, &endptr, 0); + break; - case DS_TYPE_GAUGE: - ret_value->gauge = (gauge_t) strtod (value, &endptr); - break; + case DS_TYPE_GAUGE: + ret_value->gauge = (gauge_t)strtod(value, &endptr); + break; - case DS_TYPE_DERIVE: - ret_value->derive = (derive_t) strtoll (value, &endptr, 0); - break; + case DS_TYPE_DERIVE: + ret_value->derive = (derive_t)strtoll(value, &endptr, 0); + break; - case DS_TYPE_ABSOLUTE: - ret_value->absolute = (absolute_t) strtoull (value, &endptr, 0); - break; + case DS_TYPE_ABSOLUTE: + ret_value->absolute = (absolute_t)strtoull(value, &endptr, 0); + break; - default: - sfree (value); - ERROR ("parse_value: Invalid data source type: %i.", ds_type); - return -1; + default: + sfree(value); + ERROR("parse_value: Invalid data source type: %i.", ds_type); + return -1; } if (value == endptr) { - ERROR ("parse_value: Failed to parse string as %s: \"%s\".", - DS_TYPE_TO_STRING (ds_type), value); - sfree (value); + ERROR("parse_value: Failed to parse string as %s: \"%s\".", + DS_TYPE_TO_STRING(ds_type), value); + sfree(value); return -1; - } - else if ((NULL != endptr) && ('\0' != *endptr)) - INFO ("parse_value: Ignoring trailing garbage \"%s\" after %s value. " - "Input string was \"%s\".", - endptr, DS_TYPE_TO_STRING (ds_type), value_orig); + } else if ((NULL != endptr) && ('\0' != *endptr)) + INFO("parse_value: Ignoring trailing garbage \"%s\" after %s value. " + "Input string was \"%s\".", + endptr, DS_TYPE_TO_STRING(ds_type), value_orig); - sfree (value); + sfree(value); return 0; } /* int parse_value */ -int parse_values (char *buffer, value_list_t *vl, const data_set_t *ds) -{ - size_t i; - char *dummy; - char *ptr; - char *saveptr; - - if ((buffer == NULL) || (vl == NULL) || (ds == NULL)) - return EINVAL; - - i = 0; - dummy = buffer; - saveptr = NULL; - vl->time = 0; - while ((ptr = strtok_r (dummy, ":", &saveptr)) != NULL) - { - dummy = NULL; - - if (i >= vl->values_len) - { - /* Make sure i is invalid. */ - i = 0; - break; - } - - if (vl->time == 0) - { - if (strcmp ("N", ptr) == 0) - vl->time = cdtime (); - else - { - 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); - } - - continue; - } - - if ((strcmp ("U", ptr) == 0) && (ds->ds[i].type == DS_TYPE_GAUGE)) - vl->values[i].gauge = NAN; - else if (0 != parse_value (ptr, &vl->values[i], ds->ds[i].type)) - return -1; - - i++; - } /* while (strtok_r) */ - - if ((ptr != NULL) || (i == 0)) - return (-1); - return (0); +int parse_values(char *buffer, value_list_t *vl, const data_set_t *ds) { + size_t i; + char *dummy; + char *ptr; + char *saveptr; + + if ((buffer == NULL) || (vl == NULL) || (ds == NULL)) + return EINVAL; + + i = 0; + dummy = buffer; + saveptr = NULL; + vl->time = 0; + while ((ptr = strtok_r(dummy, ":", &saveptr)) != NULL) { + dummy = NULL; + + if (i >= vl->values_len) { + /* Make sure i is invalid. */ + i = 0; + break; + } + + if (vl->time == 0) { + if (strcmp("N", ptr) == 0) + vl->time = cdtime(); + else { + 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); + } + + continue; + } + + if ((strcmp("U", ptr) == 0) && (ds->ds[i].type == DS_TYPE_GAUGE)) + vl->values[i].gauge = NAN; + else if (0 != parse_value(ptr, &vl->values[i], ds->ds[i].type)) + return -1; + + i++; + } /* while (strtok_r) */ + + if ((ptr != NULL) || (i == 0)) + return (-1); + return (0); } /* int parse_values */ -int parse_value_file (char const *path, value_t *ret_value, int ds_type) -{ - FILE *fh; - char buffer[256]; +int parse_value_file(char const *path, value_t *ret_value, int ds_type) { + FILE *fh; + char buffer[256]; - fh = fopen (path, "r"); - if (fh == NULL) - return (-1); + fh = fopen(path, "r"); + if (fh == NULL) + return (-1); - if (fgets (buffer, sizeof (buffer), fh) == NULL) - { - fclose (fh); - return (-1); - } + if (fgets(buffer, sizeof(buffer), fh) == NULL) { + fclose(fh); + return (-1); + } - fclose (fh); + fclose(fh); - strstripnewline (buffer); + strstripnewline(buffer); - return parse_value (buffer, ret_value, ds_type); + return parse_value(buffer, ret_value, ds_type); } /* int parse_value_file */ #if !HAVE_GETPWNAM_R -int getpwnam_r (const char *name, struct passwd *pwbuf, char *buf, - size_t buflen, struct passwd **pwbufp) -{ - int status = 0; - struct passwd *pw; - - memset (pwbuf, '\0', sizeof (struct passwd)); - - pthread_mutex_lock (&getpwnam_r_lock); - - do - { - pw = getpwnam (name); - if (pw == NULL) - { - status = (errno != 0) ? errno : ENOENT; - break; - } - -#define GETPWNAM_COPY_MEMBER(member) \ - if (pw->member != NULL) \ - { \ - int len = strlen (pw->member); \ - if (len >= buflen) \ - { \ - status = ENOMEM; \ - break; \ - } \ - sstrncpy (buf, pw->member, buflen); \ - pwbuf->member = buf; \ - buf += (len + 1); \ - buflen -= (len + 1); \ - } - GETPWNAM_COPY_MEMBER(pw_name); - GETPWNAM_COPY_MEMBER(pw_passwd); - GETPWNAM_COPY_MEMBER(pw_gecos); - GETPWNAM_COPY_MEMBER(pw_dir); - GETPWNAM_COPY_MEMBER(pw_shell); - - pwbuf->pw_uid = pw->pw_uid; - pwbuf->pw_gid = pw->pw_gid; - - if (pwbufp != NULL) - *pwbufp = pwbuf; - } while (0); - - pthread_mutex_unlock (&getpwnam_r_lock); - - return (status); +int getpwnam_r(const char *name, struct passwd *pwbuf, char *buf, size_t buflen, + struct passwd **pwbufp) { + int status = 0; + struct passwd *pw; + + memset(pwbuf, '\0', sizeof(struct passwd)); + + pthread_mutex_lock(&getpwnam_r_lock); + + do { + pw = getpwnam(name); + if (pw == NULL) { + status = (errno != 0) ? errno : ENOENT; + break; + } + +#define GETPWNAM_COPY_MEMBER(member) \ + if (pw->member != NULL) { \ + int len = strlen(pw->member); \ + if (len >= buflen) { \ + status = ENOMEM; \ + break; \ + } \ + sstrncpy(buf, pw->member, buflen); \ + pwbuf->member = buf; \ + buf += (len + 1); \ + buflen -= (len + 1); \ + } + GETPWNAM_COPY_MEMBER(pw_name); + GETPWNAM_COPY_MEMBER(pw_passwd); + GETPWNAM_COPY_MEMBER(pw_gecos); + GETPWNAM_COPY_MEMBER(pw_dir); + GETPWNAM_COPY_MEMBER(pw_shell); + + pwbuf->pw_uid = pw->pw_uid; + pwbuf->pw_gid = pw->pw_gid; + + if (pwbufp != NULL) + *pwbufp = pwbuf; + } while (0); + + pthread_mutex_unlock(&getpwnam_r_lock); + + return (status); } /* int getpwnam_r */ #endif /* !HAVE_GETPWNAM_R */ -int notification_init (notification_t *n, int severity, const char *message, - const char *host, - const char *plugin, const char *plugin_instance, - const char *type, const char *type_instance) -{ - memset (n, '\0', sizeof (notification_t)); - - n->severity = severity; - - if (message != NULL) - sstrncpy (n->message, message, sizeof (n->message)); - if (host != NULL) - sstrncpy (n->host, host, sizeof (n->host)); - if (plugin != NULL) - sstrncpy (n->plugin, plugin, sizeof (n->plugin)); - if (plugin_instance != NULL) - sstrncpy (n->plugin_instance, plugin_instance, - sizeof (n->plugin_instance)); - if (type != NULL) - sstrncpy (n->type, type, sizeof (n->type)); - if (type_instance != NULL) - sstrncpy (n->type_instance, type_instance, - sizeof (n->type_instance)); - - return (0); +int notification_init(notification_t *n, int severity, const char *message, + const char *host, const char *plugin, + const char *plugin_instance, const char *type, + const char *type_instance) { + memset(n, '\0', sizeof(notification_t)); + + n->severity = severity; + + if (message != NULL) + sstrncpy(n->message, message, sizeof(n->message)); + if (host != NULL) + sstrncpy(n->host, host, sizeof(n->host)); + if (plugin != NULL) + sstrncpy(n->plugin, plugin, sizeof(n->plugin)); + if (plugin_instance != NULL) + sstrncpy(n->plugin_instance, plugin_instance, sizeof(n->plugin_instance)); + if (type != NULL) + sstrncpy(n->type, type, sizeof(n->type)); + if (type_instance != NULL) + sstrncpy(n->type_instance, type_instance, sizeof(n->type_instance)); + + return (0); } /* int notification_init */ -int walk_directory (const char *dir, dirwalk_callback_f callback, - void *user_data, int include_hidden) -{ - struct dirent *ent; - DIR *dh; - int success; - int failure; - - success = 0; - failure = 0; - - if ((dh = opendir (dir)) == NULL) - { - char errbuf[1024]; - ERROR ("walk_directory: Cannot open '%s': %s", dir, - sstrerror (errno, errbuf, sizeof (errbuf))); - return -1; - } - - while ((ent = readdir (dh)) != NULL) - { - int status; - - if (include_hidden) - { - if ((strcmp (".", ent->d_name) == 0) - || (strcmp ("..", ent->d_name) == 0)) - continue; - } - else /* if (!include_hidden) */ - { - if (ent->d_name[0]=='.') - continue; - } - - status = (*callback) (dir, ent->d_name, user_data); - if (status != 0) - failure++; - else - success++; - } - - closedir (dh); - - if ((success == 0) && (failure > 0)) - return (-1); - return (0); +int walk_directory(const char *dir, dirwalk_callback_f callback, + void *user_data, int include_hidden) { + struct dirent *ent; + DIR *dh; + int success; + int failure; + + success = 0; + failure = 0; + + if ((dh = opendir(dir)) == NULL) { + char errbuf[1024]; + ERROR("walk_directory: Cannot open '%s': %s", dir, + sstrerror(errno, errbuf, sizeof(errbuf))); + return -1; + } + + while ((ent = readdir(dh)) != NULL) { + int status; + + if (include_hidden) { + if ((strcmp(".", ent->d_name) == 0) || (strcmp("..", ent->d_name) == 0)) + continue; + } else /* if (!include_hidden) */ + { + if (ent->d_name[0] == '.') + continue; + } + + status = (*callback)(dir, ent->d_name, user_data); + if (status != 0) + failure++; + else + success++; + } + + closedir(dh); + + if ((success == 0) && (failure > 0)) + return (-1); + return (0); } -ssize_t read_file_contents (const char *filename, char *buf, size_t bufsize) -{ - FILE *fh; - ssize_t ret; - - fh = fopen (filename, "r"); - if (fh == NULL) - return (-1); - - ret = (ssize_t) fread (buf, 1, bufsize, fh); - if ((ret == 0) && (ferror (fh) != 0)) - { - ERROR ("read_file_contents: Reading file \"%s\" failed.", - filename); - ret = -1; - } - - fclose(fh); - return (ret); +ssize_t read_file_contents(const char *filename, char *buf, size_t bufsize) { + FILE *fh; + ssize_t ret; + + fh = fopen(filename, "r"); + if (fh == NULL) + return (-1); + + ret = (ssize_t)fread(buf, 1, bufsize, fh); + if ((ret == 0) && (ferror(fh) != 0)) { + ERROR("read_file_contents: Reading file \"%s\" failed.", filename); + ret = -1; + } + + fclose(fh); + return (ret); } -counter_t counter_diff (counter_t old_value, counter_t new_value) -{ - counter_t diff; - - if (old_value > new_value) - { - if (old_value <= 4294967295U) - diff = (4294967295U - old_value) + new_value + 1; - else - diff = (18446744073709551615ULL - old_value) + new_value + 1; - } - else - { - diff = new_value - old_value; - } - - return (diff); +counter_t counter_diff(counter_t old_value, counter_t new_value) { + counter_t diff; + + if (old_value > new_value) { + if (old_value <= 4294967295U) + diff = (4294967295U - old_value) + new_value + 1; + else + diff = (18446744073709551615ULL - old_value) + new_value + 1; + } else { + diff = new_value - old_value; + } + + return (diff); } /* counter_t counter_diff */ -int rate_to_value (value_t *ret_value, gauge_t rate, /* {{{ */ - rate_to_value_state_t *state, - int ds_type, cdtime_t t) -{ - gauge_t delta_gauge; - cdtime_t delta_t; - - if (ds_type == DS_TYPE_GAUGE) - { - state->last_value.gauge = rate; - state->last_time = t; - - *ret_value = state->last_value; - return (0); - } - - /* Counter and absolute can't handle negative rates. Reset "last time" - * to zero, so that the next valid rate will re-initialize the - * structure. */ - if ((rate < 0.0) - && ((ds_type == DS_TYPE_COUNTER) - || (ds_type == DS_TYPE_ABSOLUTE))) - { - memset (state, 0, sizeof (*state)); - return (EINVAL); - } - - /* Another invalid state: The time is not increasing. */ - if (t <= state->last_time) - { - memset (state, 0, sizeof (*state)); - return (EINVAL); - } - - delta_t = t - state->last_time; - delta_gauge = (rate * CDTIME_T_TO_DOUBLE (delta_t)) + state->residual; - - /* Previous value is invalid. */ - if (state->last_time == 0) /* {{{ */ - { - if (ds_type == DS_TYPE_DERIVE) - { - state->last_value.derive = (derive_t) rate; - state->residual = rate - ((gauge_t) state->last_value.derive); - } - else if (ds_type == DS_TYPE_COUNTER) - { - state->last_value.counter = (counter_t) rate; - state->residual = rate - ((gauge_t) state->last_value.counter); - } - else if (ds_type == DS_TYPE_ABSOLUTE) - { - state->last_value.absolute = (absolute_t) rate; - state->residual = rate - ((gauge_t) state->last_value.absolute); - } - else - { - assert (23 == 42); - } - - state->last_time = t; - return (EAGAIN); - } /* }}} */ - - if (ds_type == DS_TYPE_DERIVE) - { - derive_t delta_derive = (derive_t) delta_gauge; - - state->last_value.derive += delta_derive; - state->residual = delta_gauge - ((gauge_t) delta_derive); - } - else if (ds_type == DS_TYPE_COUNTER) - { - counter_t delta_counter = (counter_t) delta_gauge; - - state->last_value.counter += delta_counter; - state->residual = delta_gauge - ((gauge_t) delta_counter); - } - else if (ds_type == DS_TYPE_ABSOLUTE) - { - absolute_t delta_absolute = (absolute_t) delta_gauge; - - state->last_value.absolute = delta_absolute; - state->residual = delta_gauge - ((gauge_t) delta_absolute); - } - else - { - assert (23 == 42); - } - - state->last_time = t; - *ret_value = state->last_value; - return (0); +int rate_to_value(value_t *ret_value, gauge_t rate, /* {{{ */ + rate_to_value_state_t *state, int ds_type, cdtime_t t) { + gauge_t delta_gauge; + cdtime_t delta_t; + + if (ds_type == DS_TYPE_GAUGE) { + state->last_value.gauge = rate; + state->last_time = t; + + *ret_value = state->last_value; + return (0); + } + + /* Counter and absolute can't handle negative rates. Reset "last time" + * to zero, so that the next valid rate will re-initialize the + * structure. */ + if ((rate < 0.0) && + ((ds_type == DS_TYPE_COUNTER) || (ds_type == DS_TYPE_ABSOLUTE))) { + memset(state, 0, sizeof(*state)); + return (EINVAL); + } + + /* Another invalid state: The time is not increasing. */ + if (t <= state->last_time) { + memset(state, 0, sizeof(*state)); + return (EINVAL); + } + + delta_t = t - state->last_time; + delta_gauge = (rate * CDTIME_T_TO_DOUBLE(delta_t)) + state->residual; + + /* Previous value is invalid. */ + if (state->last_time == 0) /* {{{ */ + { + if (ds_type == DS_TYPE_DERIVE) { + state->last_value.derive = (derive_t)rate; + state->residual = rate - ((gauge_t)state->last_value.derive); + } else if (ds_type == DS_TYPE_COUNTER) { + state->last_value.counter = (counter_t)rate; + state->residual = rate - ((gauge_t)state->last_value.counter); + } else if (ds_type == DS_TYPE_ABSOLUTE) { + state->last_value.absolute = (absolute_t)rate; + state->residual = rate - ((gauge_t)state->last_value.absolute); + } else { + assert(23 == 42); + } + + state->last_time = t; + return (EAGAIN); + } /* }}} */ + + if (ds_type == DS_TYPE_DERIVE) { + derive_t delta_derive = (derive_t)delta_gauge; + + state->last_value.derive += delta_derive; + state->residual = delta_gauge - ((gauge_t)delta_derive); + } else if (ds_type == DS_TYPE_COUNTER) { + counter_t delta_counter = (counter_t)delta_gauge; + + state->last_value.counter += delta_counter; + state->residual = delta_gauge - ((gauge_t)delta_counter); + } else if (ds_type == DS_TYPE_ABSOLUTE) { + absolute_t delta_absolute = (absolute_t)delta_gauge; + + state->last_value.absolute = delta_absolute; + state->residual = delta_gauge - ((gauge_t)delta_absolute); + } else { + assert(23 == 42); + } + + state->last_time = t; + *ret_value = state->last_value; + return (0); } /* }}} value_t rate_to_value */ -int value_to_rate (gauge_t *ret_rate, /* {{{ */ - value_t value, int ds_type, cdtime_t t, value_to_rate_state_t *state) -{ - gauge_t interval; - - /* Another invalid state: The time is not increasing. */ - if (t <= state->last_time) - { - memset (state, 0, sizeof (*state)); - return (EINVAL); - } - - interval = CDTIME_T_TO_DOUBLE(t - state->last_time); - - /* Previous value is invalid. */ - if (state->last_time == 0) - { - state->last_value = value; - state->last_time = t; - return (EAGAIN); - } - - switch (ds_type) { - case DS_TYPE_DERIVE: { - derive_t diff = value.derive - state->last_value.derive; - *ret_rate = ((gauge_t) diff) / ((gauge_t) interval); - break; - } - case DS_TYPE_GAUGE: { - *ret_rate = value.gauge; - break; - } - case DS_TYPE_COUNTER: { - counter_t diff = counter_diff (state->last_value.counter, value.counter); - *ret_rate = ((gauge_t) diff) / ((gauge_t) interval); - break; - } - case DS_TYPE_ABSOLUTE: { - absolute_t diff = value.absolute; - *ret_rate = ((gauge_t) diff) / ((gauge_t) interval); - break; - } - default: - return EINVAL; - } - - state->last_value = value; - state->last_time = t; - return (0); +int value_to_rate(gauge_t *ret_rate, /* {{{ */ + value_t value, int ds_type, cdtime_t t, + value_to_rate_state_t *state) { + gauge_t interval; + + /* Another invalid state: The time is not increasing. */ + if (t <= state->last_time) { + memset(state, 0, sizeof(*state)); + return (EINVAL); + } + + interval = CDTIME_T_TO_DOUBLE(t - state->last_time); + + /* Previous value is invalid. */ + if (state->last_time == 0) { + state->last_value = value; + state->last_time = t; + return (EAGAIN); + } + + switch (ds_type) { + case DS_TYPE_DERIVE: { + derive_t diff = value.derive - state->last_value.derive; + *ret_rate = ((gauge_t)diff) / ((gauge_t)interval); + break; + } + case DS_TYPE_GAUGE: { + *ret_rate = value.gauge; + break; + } + case DS_TYPE_COUNTER: { + counter_t diff = counter_diff(state->last_value.counter, value.counter); + *ret_rate = ((gauge_t)diff) / ((gauge_t)interval); + break; + } + case DS_TYPE_ABSOLUTE: { + absolute_t diff = value.absolute; + *ret_rate = ((gauge_t)diff) / ((gauge_t)interval); + break; + } + default: + return EINVAL; + } + + state->last_value = value; + state->last_time = t; + return (0); } /* }}} value_t rate_to_value */ -int service_name_to_port_number (const char *service_name) -{ - struct addrinfo *ai_list; - int status; - int service_number; - - if (service_name == NULL) - return (-1); - - struct addrinfo ai_hints = { - .ai_family = AF_UNSPEC - }; - - status = getaddrinfo (/* node = */ NULL, service_name, - &ai_hints, &ai_list); - if (status != 0) - { - ERROR ("service_name_to_port_number: getaddrinfo failed: %s", - gai_strerror (status)); - return (-1); - } - - service_number = -1; - for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) - { - if (ai_ptr->ai_family == AF_INET) - { - struct sockaddr_in *sa; - - sa = (void *) ai_ptr->ai_addr; - service_number = (int) ntohs (sa->sin_port); - } - else if (ai_ptr->ai_family == AF_INET6) - { - struct sockaddr_in6 *sa; - - sa = (void *) ai_ptr->ai_addr; - service_number = (int) ntohs (sa->sin6_port); - } - - if ((service_number > 0) && (service_number <= 65535)) - break; - } - - freeaddrinfo (ai_list); - - if ((service_number > 0) && (service_number <= 65535)) - return (service_number); - return (-1); +int service_name_to_port_number(const char *service_name) { + struct addrinfo *ai_list; + int status; + int service_number; + + if (service_name == NULL) + return (-1); + + struct addrinfo ai_hints = {.ai_family = AF_UNSPEC}; + + status = getaddrinfo(/* node = */ NULL, service_name, &ai_hints, &ai_list); + if (status != 0) { + ERROR("service_name_to_port_number: getaddrinfo failed: %s", + gai_strerror(status)); + return (-1); + } + + service_number = -1; + for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; + ai_ptr = ai_ptr->ai_next) { + if (ai_ptr->ai_family == AF_INET) { + struct sockaddr_in *sa; + + sa = (void *)ai_ptr->ai_addr; + service_number = (int)ntohs(sa->sin_port); + } else if (ai_ptr->ai_family == AF_INET6) { + struct sockaddr_in6 *sa; + + sa = (void *)ai_ptr->ai_addr; + service_number = (int)ntohs(sa->sin6_port); + } + + if ((service_number > 0) && (service_number <= 65535)) + break; + } + + freeaddrinfo(ai_list); + + if ((service_number > 0) && (service_number <= 65535)) + return (service_number); + return (-1); } /* int service_name_to_port_number */ -void set_sock_opts (int sockfd) /* {{{ */ +void set_sock_opts(int sockfd) /* {{{ */ { - int status; - int socktype; - - status = getsockopt (sockfd, SOL_SOCKET, SO_TYPE, - &socktype, &(socklen_t) { sizeof (socktype) }); - if (status != 0) - { - WARNING ("set_sock_opts: failed to determine socket type"); - return; - } + int status; + int socktype; + + status = getsockopt(sockfd, SOL_SOCKET, SO_TYPE, &socktype, + &(socklen_t){sizeof(socktype)}); + if (status != 0) { + WARNING("set_sock_opts: failed to determine socket type"); + return; + } - if (socktype == SOCK_STREAM) - { - status = setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, - &(int) {1}, sizeof (int)); - if (status != 0) - WARNING ("set_sock_opts: failed to set socket keepalive flag"); + if (socktype == SOCK_STREAM) { + status = + setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &(int){1}, sizeof(int)); + if (status != 0) + WARNING("set_sock_opts: failed to set socket keepalive flag"); #ifdef TCP_KEEPIDLE - int tcp_keepidle = ((CDTIME_T_TO_MS(plugin_get_interval()) - 1) / 100 + 1); - status = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, - &tcp_keepidle, sizeof (tcp_keepidle)); - if (status != 0) - WARNING ("set_sock_opts: failed to set socket tcp keepalive time"); + int tcp_keepidle = ((CDTIME_T_TO_MS(plugin_get_interval()) - 1) / 100 + 1); + status = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, &tcp_keepidle, + sizeof(tcp_keepidle)); + if (status != 0) + WARNING("set_sock_opts: failed to set socket tcp keepalive time"); #endif #ifdef TCP_KEEPINTVL - int tcp_keepintvl = ((CDTIME_T_TO_MS(plugin_get_interval()) - 1) / 1000 + 1); - status = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, - &tcp_keepintvl, sizeof (tcp_keepintvl)); - if (status != 0) - WARNING ("set_sock_opts: failed to set socket tcp keepalive interval"); + int tcp_keepintvl = + ((CDTIME_T_TO_MS(plugin_get_interval()) - 1) / 1000 + 1); + status = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, &tcp_keepintvl, + sizeof(tcp_keepintvl)); + if (status != 0) + WARNING("set_sock_opts: failed to set socket tcp keepalive interval"); #endif - } + } } /* }}} void set_sock_opts */ -int strtoderive (const char *string, derive_t *ret_value) /* {{{ */ +int strtoderive(const char *string, derive_t *ret_value) /* {{{ */ { - derive_t tmp; - char *endptr; + derive_t tmp; + char *endptr; - if ((string == NULL) || (ret_value == NULL)) - return (EINVAL); + if ((string == NULL) || (ret_value == NULL)) + return (EINVAL); - errno = 0; - endptr = NULL; - tmp = (derive_t) strtoll (string, &endptr, /* base = */ 0); - if ((endptr == string) || (errno != 0)) - return (-1); + errno = 0; + endptr = NULL; + tmp = (derive_t)strtoll(string, &endptr, /* base = */ 0); + if ((endptr == string) || (errno != 0)) + return (-1); - *ret_value = tmp; - return (0); + *ret_value = tmp; + return (0); } /* }}} int strtoderive */ -int strtogauge (const char *string, gauge_t *ret_value) /* {{{ */ +int strtogauge(const char *string, gauge_t *ret_value) /* {{{ */ { - gauge_t tmp; - char *endptr = NULL; - - if ((string == NULL) || (ret_value == NULL)) - return (EINVAL); - - errno = 0; - endptr = NULL; - tmp = (gauge_t) strtod (string, &endptr); - if (errno != 0) - return (errno); - else if ((endptr == NULL) || (*endptr != 0)) - return (EINVAL); - - *ret_value = tmp; - return (0); + gauge_t tmp; + char *endptr = NULL; + + if ((string == NULL) || (ret_value == NULL)) + return (EINVAL); + + errno = 0; + endptr = NULL; + tmp = (gauge_t)strtod(string, &endptr); + if (errno != 0) + return (errno); + else if ((endptr == NULL) || (*endptr != 0)) + return (EINVAL); + + *ret_value = tmp; + return (0); } /* }}} int strtogauge */ -int strarray_add (char ***ret_array, size_t *ret_array_len, char const *str) /* {{{ */ +int strarray_add(char ***ret_array, size_t *ret_array_len, + char const *str) /* {{{ */ { - char **array; - size_t array_len = *ret_array_len; + char **array; + size_t array_len = *ret_array_len; - if (str == NULL) - return (EINVAL); + if (str == NULL) + return (EINVAL); - array = realloc (*ret_array, - (array_len + 1) * sizeof (*array)); - if (array == NULL) - return (ENOMEM); - *ret_array = array; + array = realloc(*ret_array, (array_len + 1) * sizeof(*array)); + if (array == NULL) + return (ENOMEM); + *ret_array = array; - array[array_len] = strdup (str); - if (array[array_len] == NULL) - return (ENOMEM); + array[array_len] = strdup(str); + if (array[array_len] == NULL) + return (ENOMEM); - array_len++; - *ret_array_len = array_len; - return (0); + array_len++; + *ret_array_len = array_len; + return (0); } /* }}} int strarray_add */ -void strarray_free (char **array, size_t array_len) /* {{{ */ +void strarray_free(char **array, size_t array_len) /* {{{ */ { - for (size_t i = 0; i < array_len; i++) - sfree (array[i]); - sfree (array); + for (size_t i = 0; i < array_len; i++) + sfree(array[i]); + sfree(array); } /* }}} void strarray_free */ #if HAVE_CAPABILITY -int check_capability (int arg) /* {{{ */ +int check_capability(int arg) /* {{{ */ { - cap_value_t cap = (cap_value_t) arg; + cap_value_t cap = (cap_value_t)arg; - if (!CAP_IS_SUPPORTED (cap)) - return (-1); + if (!CAP_IS_SUPPORTED(cap)) + return (-1); - int have_cap = cap_get_bound (cap); - if (have_cap != 1) - return (-1); + int have_cap = cap_get_bound(cap); + if (have_cap != 1) + return (-1); - return (0); + return (0); } /* }}} int check_capability */ #else -int check_capability (__attribute__((unused)) int arg) /* {{{ */ +int check_capability(__attribute__((unused)) int arg) /* {{{ */ { - WARNING ("check_capability: unsupported capability implementation. " - "Some plugin(s) may require elevated privileges to work properly."); - return (0); + WARNING("check_capability: unsupported capability implementation. " + "Some plugin(s) may require elevated privileges to work properly."); + return (0); } /* }}} int check_capability */ #endif /* HAVE_CAPABILITY */ diff --git a/src/daemon/common.h b/src/daemon/common.h index 67ca1c14..a1a25289 100644 --- a/src/daemon/common.h +++ b/src/daemon/common.h @@ -33,50 +33,48 @@ #include "plugin.h" #if HAVE_PWD_H -# include +#include #endif -#define sfree(ptr) \ - do { \ - free(ptr); \ - (ptr) = NULL; \ - } while (0) +#define sfree(ptr) \ + do { \ + free(ptr); \ + (ptr) = NULL; \ + } while (0) -#define STATIC_ARRAY_SIZE(a) (sizeof (a) / sizeof (*(a))) +#define STATIC_ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) -#define IS_TRUE(s) ((strcasecmp ("true", (s)) == 0) \ - || (strcasecmp ("yes", (s)) == 0) \ - || (strcasecmp ("on", (s)) == 0)) -#define IS_FALSE(s) ((strcasecmp ("false", (s)) == 0) \ - || (strcasecmp ("no", (s)) == 0) \ - || (strcasecmp ("off", (s)) == 0)) +#define IS_TRUE(s) \ + ((strcasecmp("true", (s)) == 0) || (strcasecmp("yes", (s)) == 0) || \ + (strcasecmp("on", (s)) == 0)) +#define IS_FALSE(s) \ + ((strcasecmp("false", (s)) == 0) || (strcasecmp("no", (s)) == 0) || \ + (strcasecmp("off", (s)) == 0)) -struct rate_to_value_state_s -{ +struct rate_to_value_state_s { value_t last_value; cdtime_t last_time; gauge_t residual; }; typedef struct rate_to_value_state_s rate_to_value_state_t; -struct value_to_rate_state_s -{ +struct value_to_rate_state_s { value_t last_value; cdtime_t last_time; }; typedef struct value_to_rate_state_s value_to_rate_state_t; -char *sstrncpy (char *dest, const char *src, size_t n); +char *sstrncpy(char *dest, const char *src, size_t n); -__attribute__ ((format(printf,3,4))) -int ssnprintf (char *dest, size_t n, const char *format, ...); +__attribute__((format(printf, 3, 4))) int ssnprintf(char *dest, size_t n, + const char *format, ...); -__attribute__ ((format(printf,1,2))) -char *ssnprintf_alloc (char const *format, ...); +__attribute__((format(printf, 1, 2))) char *ssnprintf_alloc(char const *format, + ...); char *sstrdup(const char *s); void *smalloc(size_t size); -char *sstrerror (int errnum, char *buf, size_t buflen); +char *sstrerror(int errnum, char *buf, size_t buflen); /* * NAME @@ -96,7 +94,7 @@ char *sstrerror (int errnum, char *buf, size_t buflen); * Zero upon success or non-zero if an error occurred. `errno' is set in this * case. */ -ssize_t sread (int fd, void *buf, size_t count); +ssize_t sread(int fd, void *buf, size_t count); /* * NAME @@ -115,7 +113,7 @@ ssize_t sread (int fd, void *buf, size_t count); * Zero upon success or non-zero if an error occurred. `errno' is set in this * case. */ -ssize_t swrite (int fd, const void *buf, size_t count); +ssize_t swrite(int fd, const void *buf, size_t count); /* * NAME @@ -136,7 +134,7 @@ ssize_t swrite (int fd, const void *buf, size_t count); * RETURN VALUE * Returns the number of parts stored in `fields'. */ -int strsplit (char *string, char **fields, size_t size); +int strsplit(char *string, char **fields, size_t size); /* * NAME @@ -165,7 +163,8 @@ int strsplit (char *string, char **fields, size_t size); * result in "dst" is truncated (but still null terminated). On error a * negative value is returned. */ -int strjoin (char *dst, size_t dst_len, char **fields, size_t fields_num, const char *sep); +int strjoin(char *dst, size_t dst_len, char **fields, size_t fields_num, + const char *sep); /* * NAME @@ -186,7 +185,7 @@ int strjoin (char *dst, size_t dst_len, char **fields, size_t fields_num, const * RETURN VALUE * Returns zero upon success and a value smaller than zero upon failure. */ -int escape_slashes (char *buffer, size_t buffer_size); +int escape_slashes(char *buffer, size_t buffer_size); /** * NAME @@ -207,7 +206,7 @@ int escape_slashes (char *buffer, size_t buffer_size); * Returns zero on success, even if the string was truncated. Non-zero on * failure. */ -int escape_string (char *buffer, size_t buffer_size); +int escape_string(char *buffer, size_t buffer_size); /* * NAME @@ -224,7 +223,7 @@ int escape_string (char *buffer, size_t buffer_size); * `buffer_size' Length of the string. The function returns after * encountering a null-byte or reading this many bytes. */ -void replace_special (char *buffer, size_t buffer_size); +void replace_special(char *buffer, size_t buffer_size); /* * NAME @@ -247,14 +246,13 @@ void replace_special (char *buffer, size_t buffer_size); * RETURN VALUE * Returns zero upon success, a value less than zero else. */ -int strunescape (char *buf, size_t buf_len); +int strunescape(char *buf, size_t buf_len); /** * Removed trailing newline characters (CR and LF) from buffer, which must be * null terminated. Returns the length of the resulting string. */ -__attribute__((nonnull (1))) -size_t strstripnewline (char *buffer); +__attribute__((nonnull(1))) size_t strstripnewline(char *buffer); /* * NAME @@ -269,90 +267,88 @@ size_t strstripnewline (char *buffer); * Returns an integer less than, equal to, or greater than zero if `tv0' is * less than, equal to, or greater than `tv1' respectively. */ -int timeval_cmp (struct timeval tv0, struct timeval tv1, struct timeval *delta); +int timeval_cmp(struct timeval tv0, struct timeval tv1, struct timeval *delta); /* make sure tv_usec stores less than a second */ -#define NORMALIZE_TIMEVAL(tv) \ - do { \ - (tv).tv_sec += (tv).tv_usec / 1000000; \ - (tv).tv_usec = (tv).tv_usec % 1000000; \ - } while (0) +#define NORMALIZE_TIMEVAL(tv) \ + do { \ + (tv).tv_sec += (tv).tv_usec / 1000000; \ + (tv).tv_usec = (tv).tv_usec % 1000000; \ + } while (0) /* make sure tv_sec stores less than a second */ -#define NORMALIZE_TIMESPEC(tv) \ - do { \ - (tv).tv_sec += (tv).tv_nsec / 1000000000; \ - (tv).tv_nsec = (tv).tv_nsec % 1000000000; \ - } while (0) +#define NORMALIZE_TIMESPEC(tv) \ + do { \ + (tv).tv_sec += (tv).tv_nsec / 1000000000; \ + (tv).tv_nsec = (tv).tv_nsec % 1000000000; \ + } while (0) -int check_create_dir (const char *file_orig); +int check_create_dir(const char *file_orig); #ifdef HAVE_LIBKSTAT -int get_kstat (kstat_t **ksp_ptr, char *module, int instance, char *name); -long long get_kstat_value (kstat_t *ksp, char *name); +int get_kstat(kstat_t **ksp_ptr, char *module, int instance, char *name); +long long get_kstat_value(kstat_t *ksp, char *name); #endif #ifndef HAVE_HTONLL -unsigned long long ntohll (unsigned long long n); -unsigned long long htonll (unsigned long long n); +unsigned long long ntohll(unsigned long long n); +unsigned long long htonll(unsigned long long n); #endif #if FP_LAYOUT_NEED_NOTHING -# define ntohd(d) (d) -# define htond(d) (d) +#define ntohd(d) (d) +#define htond(d) (d) #elif FP_LAYOUT_NEED_ENDIANFLIP || FP_LAYOUT_NEED_INTSWAP -double ntohd (double d); -double htond (double d); +double ntohd(double d); +double htond(double d); #else -# error "Don't know how to convert between host and network representation of doubles." +#error \ + "Don't know how to convert between host and network representation of doubles." #endif -int format_name (char *ret, int ret_len, - const char *hostname, - const char *plugin, const char *plugin_instance, - const char *type, const char *type_instance); -#define FORMAT_VL(ret, ret_len, vl) \ - format_name (ret, ret_len, (vl)->host, (vl)->plugin, (vl)->plugin_instance, \ - (vl)->type, (vl)->type_instance) -int format_values (char *ret, size_t ret_len, - const data_set_t *ds, const value_list_t *vl, - _Bool store_rates); - -int parse_identifier (char *str, char **ret_host, - char **ret_plugin, char **ret_plugin_instance, - char **ret_type, char **ret_type_instance, - char *default_host); -int parse_identifier_vl (const char *str, value_list_t *vl); -int parse_value (const char *value, value_t *ret_value, int ds_type); -int parse_values (char *buffer, value_list_t *vl, const data_set_t *ds); +int format_name(char *ret, int ret_len, const char *hostname, + const char *plugin, const char *plugin_instance, + const char *type, const char *type_instance); +#define FORMAT_VL(ret, ret_len, vl) \ + format_name(ret, ret_len, (vl)->host, (vl)->plugin, (vl)->plugin_instance, \ + (vl)->type, (vl)->type_instance) +int format_values(char *ret, size_t ret_len, const data_set_t *ds, + const value_list_t *vl, _Bool store_rates); + +int parse_identifier(char *str, char **ret_host, char **ret_plugin, + char **ret_plugin_instance, char **ret_type, + char **ret_type_instance, char *default_host); +int parse_identifier_vl(const char *str, value_list_t *vl); +int parse_value(const char *value, value_t *ret_value, int ds_type); +int parse_values(char *buffer, value_list_t *vl, const data_set_t *ds); /* parse_value_file reads "path" and parses its content as an integer or * floating point, depending on "ds_type". On success, the value is stored in - * "ret_value" and zero is returned. On failure, a non-zero value is returned. */ -int parse_value_file (char const *path, value_t *ret_value, int ds_type); + * "ret_value" and zero is returned. On failure, a non-zero value is returned. + */ +int parse_value_file(char const *path, value_t *ret_value, int ds_type); #if !HAVE_GETPWNAM_R -int getpwnam_r (const char *name, struct passwd *pwbuf, char *buf, - size_t buflen, struct passwd **pwbufp); +int getpwnam_r(const char *name, struct passwd *pwbuf, char *buf, size_t buflen, + struct passwd **pwbufp); #endif -int notification_init (notification_t *n, int severity, const char *message, - const char *host, - const char *plugin, const char *plugin_instance, - const char *type, const char *type_instance); -#define NOTIFICATION_INIT_VL(n, vl) \ - notification_init (n, NOTIF_FAILURE, NULL, \ - (vl)->host, (vl)->plugin, (vl)->plugin_instance, \ - (vl)->type, (vl)->type_instance) +int notification_init(notification_t *n, int severity, const char *message, + const char *host, const char *plugin, + const char *plugin_instance, const char *type, + const char *type_instance); +#define NOTIFICATION_INIT_VL(n, vl) \ + notification_init(n, NOTIF_FAILURE, NULL, (vl)->host, (vl)->plugin, \ + (vl)->plugin_instance, (vl)->type, (vl)->type_instance) typedef int (*dirwalk_callback_f)(const char *dirname, const char *filename, - void *user_data); -int walk_directory (const char *dir, dirwalk_callback_f callback, - void *user_data, int hidden); + void *user_data); +int walk_directory(const char *dir, dirwalk_callback_f callback, + void *user_data, int hidden); /* Returns the number of bytes read or negative on error. */ -ssize_t read_file_contents (char const *filename, char *buf, size_t bufsize); +ssize_t read_file_contents(char const *filename, char *buf, size_t bufsize); -counter_t counter_diff (counter_t old_value, counter_t new_value); +counter_t counter_diff(counter_t old_value, counter_t new_value); /* Convert a rate back to a value_t. When converting to a derive_t, counter_t * or absoltue_t, take fractional residuals into account. This is important @@ -360,36 +356,36 @@ counter_t counter_diff (counter_t old_value, counter_t new_value); * Returns zero on success. Returns EAGAIN when called for the first time; in * this case the value_t is invalid and the next call should succeed. Other * return values indicate an error. */ -int rate_to_value (value_t *ret_value, gauge_t rate, - rate_to_value_state_t *state, int ds_type, cdtime_t t); +int rate_to_value(value_t *ret_value, gauge_t rate, + rate_to_value_state_t *state, int ds_type, cdtime_t t); -int value_to_rate (gauge_t *ret_rate, value_t value, int ds_type, cdtime_t t, - value_to_rate_state_t *state); +int value_to_rate(gauge_t *ret_rate, value_t value, int ds_type, cdtime_t t, + value_to_rate_state_t *state); /* Converts a service name (a string) to a port number * (in the range [1-65535]). Returns less than zero on error. */ -int service_name_to_port_number (const char *service_name); +int service_name_to_port_number(const char *service_name); /* Sets various, non-default, socket options */ -void set_sock_opts (int sockfd); +void set_sock_opts(int sockfd); /** Parse a string to a derive_t value. Returns zero on success or non-zero on * failure. If failure is returned, ret_value is not touched. */ -int strtoderive (const char *string, derive_t *ret_value); +int strtoderive(const char *string, derive_t *ret_value); /** Parse a string to a gauge_t value. Returns zero on success or non-zero on * failure. If failure is returned, ret_value is not touched. */ -int strtogauge (const char *string, gauge_t *ret_value); +int strtogauge(const char *string, gauge_t *ret_value); -int strarray_add (char ***ret_array, size_t *ret_array_len, char const *str); -void strarray_free (char **array, size_t array_len); +int strarray_add(char ***ret_array, size_t *ret_array_len, char const *str); +void strarray_free(char **array, size_t array_len); #ifdef HAVE_SYS_CAPABILITY_H /** Check if the current process benefits from the capability passed in * argument. Returns zero if it does, less than zero if it doesn't or on error. * See capabilities(7) for the list of possible capabilities. * */ -int check_capability (int capability); +int check_capability(int capability); #endif /* HAVE_SYS_CAPABILITY_H */ #endif /* COMMON_H */ diff --git a/src/daemon/common_test.c b/src/daemon/common_test.c index 61435959..0c96945f 100644 --- a/src/daemon/common_test.c +++ b/src/daemon/common_test.c @@ -31,8 +31,7 @@ kstat_ctl_t *kc; #endif /* HAVE_LIBKSTAT */ -DEF_TEST(sstrncpy) -{ +DEF_TEST(sstrncpy) { char buffer[16] = ""; char *ptr = &buffer[4]; char *ret; @@ -40,27 +39,26 @@ DEF_TEST(sstrncpy) buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0xff; buffer[12] = buffer[13] = buffer[14] = buffer[15] = 0xff; - ret = sstrncpy (ptr, "foobar", 8); + ret = sstrncpy(ptr, "foobar", 8); OK(ret == ptr); - EXPECT_EQ_STR ("foobar", ptr); + EXPECT_EQ_STR("foobar", ptr); OK(buffer[3] == buffer[12]); - ret = sstrncpy (ptr, "abc", 8); + ret = sstrncpy(ptr, "abc", 8); OK(ret == ptr); - EXPECT_EQ_STR ("abc", ptr); + EXPECT_EQ_STR("abc", ptr); OK(buffer[3] == buffer[12]); - ret = sstrncpy (ptr, "collectd", 8); + ret = sstrncpy(ptr, "collectd", 8); OK(ret == ptr); OK(ptr[7] == 0); - EXPECT_EQ_STR ("collect", ptr); + EXPECT_EQ_STR("collect", ptr); OK(buffer[3] == buffer[12]); return (0); } -DEF_TEST(ssnprintf) -{ +DEF_TEST(ssnprintf) { char buffer[16] = ""; char *ptr = &buffer[4]; int status; @@ -68,81 +66,79 @@ DEF_TEST(ssnprintf) buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0xff; buffer[12] = buffer[13] = buffer[14] = buffer[15] = 0xff; - status = ssnprintf (ptr, 8, "%i", 1337); + status = ssnprintf(ptr, 8, "%i", 1337); OK(status == 4); - EXPECT_EQ_STR ("1337", ptr); + EXPECT_EQ_STR("1337", ptr); - status = ssnprintf (ptr, 8, "%s", "collectd"); + status = ssnprintf(ptr, 8, "%s", "collectd"); OK(status == 8); OK(ptr[7] == 0); - EXPECT_EQ_STR ("collect", ptr); + EXPECT_EQ_STR("collect", ptr); OK(buffer[3] == buffer[12]); return (0); } -DEF_TEST(sstrdup) -{ +DEF_TEST(sstrdup) { char *ptr; - ptr = sstrdup ("collectd"); + ptr = sstrdup("collectd"); OK(ptr != NULL); - EXPECT_EQ_STR ("collectd", ptr); + EXPECT_EQ_STR("collectd", ptr); sfree(ptr); - ptr = sstrdup (NULL); + ptr = sstrdup(NULL); OK(ptr == NULL); return (0); } -DEF_TEST(strsplit) -{ +DEF_TEST(strsplit) { char buffer[32]; char *fields[8]; int status; - strncpy (buffer, "foo bar", sizeof (buffer)); - status = strsplit (buffer, fields, 8); + strncpy(buffer, "foo bar", sizeof(buffer)); + status = strsplit(buffer, fields, 8); OK(status == 2); - EXPECT_EQ_STR ("foo", fields[0]); - EXPECT_EQ_STR ("bar", fields[1]); + EXPECT_EQ_STR("foo", fields[0]); + EXPECT_EQ_STR("bar", fields[1]); - strncpy (buffer, "foo \t bar", sizeof (buffer)); - status = strsplit (buffer, fields, 8); + strncpy(buffer, "foo \t bar", sizeof(buffer)); + status = strsplit(buffer, fields, 8); OK(status == 2); - EXPECT_EQ_STR ("foo", fields[0]); - EXPECT_EQ_STR ("bar", fields[1]); + EXPECT_EQ_STR("foo", fields[0]); + EXPECT_EQ_STR("bar", fields[1]); - strncpy (buffer, "one two\tthree\rfour\nfive", sizeof (buffer)); - status = strsplit (buffer, fields, 8); + strncpy(buffer, "one two\tthree\rfour\nfive", sizeof(buffer)); + status = strsplit(buffer, fields, 8); OK(status == 5); - EXPECT_EQ_STR ("one", fields[0]); - EXPECT_EQ_STR ("two", fields[1]); - EXPECT_EQ_STR ("three", fields[2]); - EXPECT_EQ_STR ("four", fields[3]); - EXPECT_EQ_STR ("five", fields[4]); - - strncpy (buffer, "\twith trailing\n", sizeof (buffer)); - status = strsplit (buffer, fields, 8); + EXPECT_EQ_STR("one", fields[0]); + EXPECT_EQ_STR("two", fields[1]); + EXPECT_EQ_STR("three", fields[2]); + EXPECT_EQ_STR("four", fields[3]); + EXPECT_EQ_STR("five", fields[4]); + + strncpy(buffer, "\twith trailing\n", sizeof(buffer)); + status = strsplit(buffer, fields, 8); OK(status == 2); - EXPECT_EQ_STR ("with", fields[0]); - EXPECT_EQ_STR ("trailing", fields[1]); + EXPECT_EQ_STR("with", fields[0]); + EXPECT_EQ_STR("trailing", fields[1]); - strncpy (buffer, "1 2 3 4 5 6 7 8 9 10 11 12 13", sizeof (buffer)); - status = strsplit (buffer, fields, 8); + strncpy(buffer, "1 2 3 4 5 6 7 8 9 10 11 12 13", sizeof(buffer)); + status = strsplit(buffer, fields, 8); OK(status == 8); - EXPECT_EQ_STR ("7", fields[6]); - EXPECT_EQ_STR ("8", fields[7]); + EXPECT_EQ_STR("7", fields[6]); + EXPECT_EQ_STR("8", fields[7]); - strncpy (buffer, "single", sizeof (buffer)); - status = strsplit (buffer, fields, 8); + strncpy(buffer, "single", sizeof(buffer)); + status = strsplit(buffer, fields, 8); OK(status == 1); - EXPECT_EQ_STR ("single", fields[0]); + EXPECT_EQ_STR("single", fields[0]); - strncpy (buffer, "", sizeof (buffer)); - status = strsplit (buffer, fields, 8); + strncpy(buffer, "", sizeof(buffer)); + status = strsplit(buffer, fields, 8); OK(status == 0); return (0); @@ -156,32 +152,29 @@ DEF_TEST(strjoin) { int want_return; char *want_buffer; - } cases - [] = { - /* Normal case. */ - {(char *[]){"foo", "bar"}, 2, "!", 7, "foo!bar"}, - /* One field only. */ - {(char *[]){"foo"}, 1, "!", 3, "foo"}, - /* No fields at all. */ - {NULL, 0, "!", 0, ""}, - /* Longer separator. */ - {(char *[]){"foo", "bar"}, 2, "rcht", 10, "foorchtbar"}, - /* Empty separator. */ - {(char *[]){"foo", "bar"}, 2, "", 6, "foobar"}, - /* NULL separator. */ - {(char *[]){"foo", "bar"}, 2, NULL, 6, "foobar"}, - /* buffer not large enough -> string is truncated. */ - {(char *[]){"aaaaaa", "bbbbbb", "c!"}, 3, "-", 16, "aaaaaa-bbbbbb-c"}, - /* buffer not large enough -> last field fills buffer completely. */ - {(char *[]){"aaaaaaa", "bbbbbbb", "!"}, 3, "-", 17, - "aaaaaaa-bbbbbbb"}, - /* buffer not large enough -> string does *not* end in separator. */ - {(char *[]){"aaaa", "bbbb", "cccc", "!"}, 4, "-", 16, - "aaaa-bbbb-cccc"}, - /* buffer not large enough -> string does not end with partial - separator. */ - {(char *[]){"aaaaaa", "bbbbbb", "!"}, 3, "+-", 17, "aaaaaa+-bbbbbb"}, - }; + } cases[] = { + /* Normal case. */ + {(char *[]){"foo", "bar"}, 2, "!", 7, "foo!bar"}, + /* One field only. */ + {(char *[]){"foo"}, 1, "!", 3, "foo"}, + /* No fields at all. */ + {NULL, 0, "!", 0, ""}, + /* Longer separator. */ + {(char *[]){"foo", "bar"}, 2, "rcht", 10, "foorchtbar"}, + /* Empty separator. */ + {(char *[]){"foo", "bar"}, 2, "", 6, "foobar"}, + /* NULL separator. */ + {(char *[]){"foo", "bar"}, 2, NULL, 6, "foobar"}, + /* buffer not large enough -> string is truncated. */ + {(char *[]){"aaaaaa", "bbbbbb", "c!"}, 3, "-", 16, "aaaaaa-bbbbbb-c"}, + /* buffer not large enough -> last field fills buffer completely. */ + {(char *[]){"aaaaaaa", "bbbbbbb", "!"}, 3, "-", 17, "aaaaaaa-bbbbbbb"}, + /* buffer not large enough -> string does *not* end in separator. */ + {(char *[]){"aaaa", "bbbb", "cccc", "!"}, 4, "-", 16, "aaaa-bbbb-cccc"}, + /* buffer not large enough -> string does not end with partial + separator. */ + {(char *[]){"aaaaaa", "bbbbbb", "!"}, 3, "+-", 17, "aaaaaa+-bbbbbb"}, + }; for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) { char buffer[16]; @@ -200,85 +193,82 @@ DEF_TEST(strjoin) { return (0); } -DEF_TEST(escape_slashes) -{ +DEF_TEST(escape_slashes) { struct { char *str; char *want; } cases[] = { - {"foo/bar/baz", "foo_bar_baz"}, - {"/like/a/path", "like_a_path"}, - {"trailing/slash/", "trailing_slash_"}, - {"foo//bar", "foo__bar"}, + {"foo/bar/baz", "foo_bar_baz"}, + {"/like/a/path", "like_a_path"}, + {"trailing/slash/", "trailing_slash_"}, + {"foo//bar", "foo__bar"}, }; - for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) { + for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) { char buffer[32]; - strncpy (buffer, cases[i].str, sizeof (buffer)); - OK(escape_slashes (buffer, sizeof (buffer)) == 0); + strncpy(buffer, cases[i].str, sizeof(buffer)); + OK(escape_slashes(buffer, sizeof(buffer)) == 0); EXPECT_EQ_STR(cases[i].want, buffer); } return 0; } -DEF_TEST(escape_string) -{ +DEF_TEST(escape_string) { struct { char *str; char *want; } cases[] = { - {"foobar", "foobar"}, - {"f00bar", "f00bar"}, - {"foo bar", "\"foo bar\""}, - {"foo \"bar\"", "\"foo \\\"bar\\\"\""}, - {"012345678901234", "012345678901234"}, - {"012345 78901234", "\"012345 789012\""}, - {"012345 78901\"34", "\"012345 78901\""}, + {"foobar", "foobar"}, + {"f00bar", "f00bar"}, + {"foo bar", "\"foo bar\""}, + {"foo \"bar\"", "\"foo \\\"bar\\\"\""}, + {"012345678901234", "012345678901234"}, + {"012345 78901234", "\"012345 789012\""}, + {"012345 78901\"34", "\"012345 78901\""}, }; - for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) { + for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) { char buffer[16]; - strncpy (buffer, cases[i].str, sizeof (buffer)); - OK(escape_string (buffer, sizeof (buffer)) == 0); + strncpy(buffer, cases[i].str, sizeof(buffer)); + OK(escape_string(buffer, sizeof(buffer)) == 0); EXPECT_EQ_STR(cases[i].want, buffer); } return 0; } -DEF_TEST(strunescape) -{ +DEF_TEST(strunescape) { char buffer[16]; int status; - strncpy (buffer, "foo\\tbar", sizeof (buffer)); - status = strunescape (buffer, sizeof (buffer)); + strncpy(buffer, "foo\\tbar", sizeof(buffer)); + status = strunescape(buffer, sizeof(buffer)); OK(status == 0); - EXPECT_EQ_STR ("foo\tbar", buffer); + EXPECT_EQ_STR("foo\tbar", buffer); - strncpy (buffer, "\\tfoo\\r\\n", sizeof (buffer)); - status = strunescape (buffer, sizeof (buffer)); + strncpy(buffer, "\\tfoo\\r\\n", sizeof(buffer)); + status = strunescape(buffer, sizeof(buffer)); OK(status == 0); - EXPECT_EQ_STR ("\tfoo\r\n", buffer); + EXPECT_EQ_STR("\tfoo\r\n", buffer); - strncpy (buffer, "With \\\"quotes\\\"", sizeof (buffer)); - status = strunescape (buffer, sizeof (buffer)); + strncpy(buffer, "With \\\"quotes\\\"", sizeof(buffer)); + status = strunescape(buffer, sizeof(buffer)); OK(status == 0); - EXPECT_EQ_STR ("With \"quotes\"", buffer); + EXPECT_EQ_STR("With \"quotes\"", buffer); /* Backslash before null byte */ - strncpy (buffer, "\\tbackslash end\\", sizeof (buffer)); - status = strunescape (buffer, sizeof (buffer)); + strncpy(buffer, "\\tbackslash end\\", sizeof(buffer)); + status = strunescape(buffer, sizeof(buffer)); OK(status != 0); - EXPECT_EQ_STR ("\tbackslash end", buffer); + EXPECT_EQ_STR("\tbackslash end", buffer); return (0); /* Backslash at buffer end */ - strncpy (buffer, "\\t3\\56", sizeof (buffer)); - status = strunescape (buffer, 4); + strncpy(buffer, "\\t3\\56", sizeof(buffer)); + status = strunescape(buffer, 4); OK(status != 0); OK(buffer[0] == '\t'); OK(buffer[1] == '3'); @@ -291,63 +281,52 @@ DEF_TEST(strunescape) return (0); } -DEF_TEST(parse_values) -{ +DEF_TEST(parse_values) { struct { char buffer[64]; int status; gauge_t value; } cases[] = { - {"1435044576:42", 0, 42.0}, - {"1435044576:42:23", -1, NAN}, - {"1435044576:U", 0, NAN}, - {"N:12.3", 0, 12.3}, - {"N:42.0:23", -1, NAN}, - {"N:U", 0, NAN}, - {"T:42.0", -1, NAN}, + {"1435044576:42", 0, 42.0}, {"1435044576:42:23", -1, NAN}, + {"1435044576:U", 0, NAN}, {"N:12.3", 0, 12.3}, + {"N:42.0:23", -1, NAN}, {"N:U", 0, NAN}, + {"T:42.0", -1, NAN}, }; - for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) - { + for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) { data_source_t dsrc = { - .name = "value", - .type = DS_TYPE_GAUGE, - .min = 0.0, - .max = NAN, + .name = "value", .type = DS_TYPE_GAUGE, .min = 0.0, .max = NAN, }; data_set_t ds = { - .type = "example", - .ds_num = 1, - .ds = &dsrc, + .type = "example", .ds_num = 1, .ds = &dsrc, }; value_t v = { - .gauge = NAN, + .gauge = NAN, }; value_list_t vl = { - .values = &v, - .values_len = 1, - .time = 0, - .interval = 0, - .host = "example.com", - .plugin = "common_test", - .type = "example", - .meta = NULL, + .values = &v, + .values_len = 1, + .time = 0, + .interval = 0, + .host = "example.com", + .plugin = "common_test", + .type = "example", + .meta = NULL, }; - int status = parse_values (cases[i].buffer, &vl, &ds); - EXPECT_EQ_INT (cases[i].status, status); + int status = parse_values(cases[i].buffer, &vl, &ds); + EXPECT_EQ_INT(cases[i].status, status); if (status != 0) continue; - EXPECT_EQ_DOUBLE (cases[i].value, vl.values[0].gauge); + EXPECT_EQ_DOUBLE(cases[i].value, vl.values[0].gauge); } return (0); } -DEF_TEST(value_to_rate) -{ +DEF_TEST(value_to_rate) { struct { time_t t0; time_t t1; @@ -356,39 +335,50 @@ DEF_TEST(value_to_rate) value_t v1; gauge_t want; } cases[] = { - { 0, 10, DS_TYPE_DERIVE, {.derive = 0}, {.derive = 1000}, NAN}, - {10, 20, DS_TYPE_DERIVE, {.derive = 1000}, {.derive = 2000}, 100.0}, - {20, 30, DS_TYPE_DERIVE, {.derive = 2000}, {.derive = 1800}, -20.0}, - { 0, 10, DS_TYPE_COUNTER, {.counter = 0}, {.counter = 1000}, NAN}, - {10, 20, DS_TYPE_COUNTER, {.counter = 1000}, {.counter = 5000}, 400.0}, - /* 32bit wrap-around. */ - {20, 30, DS_TYPE_COUNTER, {.counter = 4294967238ULL}, {.counter = 42}, 10.0}, - /* 64bit wrap-around. */ - {30, 40, DS_TYPE_COUNTER, {.counter = 18446744073709551558ULL}, {.counter = 42}, 10.0}, + {0, 10, DS_TYPE_DERIVE, {.derive = 0}, {.derive = 1000}, NAN}, + {10, 20, DS_TYPE_DERIVE, {.derive = 1000}, {.derive = 2000}, 100.0}, + {20, 30, DS_TYPE_DERIVE, {.derive = 2000}, {.derive = 1800}, -20.0}, + {0, 10, DS_TYPE_COUNTER, {.counter = 0}, {.counter = 1000}, NAN}, + {10, 20, DS_TYPE_COUNTER, {.counter = 1000}, {.counter = 5000}, 400.0}, + /* 32bit wrap-around. */ + {20, + 30, + DS_TYPE_COUNTER, + {.counter = 4294967238ULL}, + {.counter = 42}, + 10.0}, + /* 64bit wrap-around. */ + {30, + 40, + DS_TYPE_COUNTER, + {.counter = 18446744073709551558ULL}, + {.counter = 42}, + 10.0}, }; - for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) { - cdtime_t t0 = TIME_T_TO_CDTIME_T (cases[i].t0); + for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) { + cdtime_t t0 = TIME_T_TO_CDTIME_T(cases[i].t0); value_to_rate_state_t state = { - .last_value = cases[i].v0, - .last_time = t0, + .last_value = cases[i].v0, .last_time = t0, }; gauge_t got; if (cases[i].t0 == 0) { - EXPECT_EQ_INT(EAGAIN, value_to_rate (&got, cases[i].v1, cases[i].ds_type, TIME_T_TO_CDTIME_T(cases[i].t1), &state)); + EXPECT_EQ_INT(EAGAIN, + value_to_rate(&got, cases[i].v1, cases[i].ds_type, + TIME_T_TO_CDTIME_T(cases[i].t1), &state)); continue; } - EXPECT_EQ_INT(0, value_to_rate (&got, cases[i].v1, cases[i].ds_type, TIME_T_TO_CDTIME_T(cases[i].t1), &state)); + EXPECT_EQ_INT(0, value_to_rate(&got, cases[i].v1, cases[i].ds_type, + TIME_T_TO_CDTIME_T(cases[i].t1), &state)); EXPECT_EQ_DOUBLE(cases[i].want, got); } return 0; } -int main (void) -{ +int main(void) { RUN_TEST(sstrncpy); RUN_TEST(ssnprintf); RUN_TEST(sstrdup); diff --git a/src/daemon/configfile.c b/src/daemon/configfile.c index a31fb64d..d5f01e07 100644 --- a/src/daemon/configfile.c +++ b/src/daemon/configfile.c @@ -30,21 +30,21 @@ #include "liboconfig/oconfig.h" #include "common.h" -#include "plugin.h" #include "configfile.h" -#include "types_list.h" #include "filter_chain.h" +#include "plugin.h" +#include "types_list.h" #if HAVE_WORDEXP_H -# include +#include #endif /* HAVE_WORDEXP_H */ #if HAVE_FNMATCH_H -# include +#include #endif /* HAVE_FNMATCH_H */ #if HAVE_LIBGEN_H -# include +#include #endif /* HAVE_LIBGEN_H */ #define ESCAPE_NULL(str) ((str) == NULL ? "(null)" : (str)) @@ -52,45 +52,41 @@ /* * Private types */ -typedef struct cf_callback -{ - const char *type; - int (*callback) (const char *, const char *); - const char **keys; - int keys_num; - plugin_ctx_t ctx; - struct cf_callback *next; +typedef struct cf_callback { + const char *type; + int (*callback)(const char *, const char *); + const char **keys; + int keys_num; + plugin_ctx_t ctx; + struct cf_callback *next; } cf_callback_t; -typedef struct cf_complex_callback_s -{ - char *type; - int (*callback) (oconfig_item_t *); - plugin_ctx_t ctx; - struct cf_complex_callback_s *next; +typedef struct cf_complex_callback_s { + char *type; + int (*callback)(oconfig_item_t *); + plugin_ctx_t ctx; + struct cf_complex_callback_s *next; } cf_complex_callback_t; -typedef struct cf_value_map_s -{ - const char *key; - int (*func) (oconfig_item_t *); +typedef struct cf_value_map_s { + const char *key; + int (*func)(oconfig_item_t *); } cf_value_map_t; -typedef struct cf_global_option_s -{ - const char *key; - char *value; - _Bool from_cli; /* value set from CLI */ - const char *def; +typedef struct cf_global_option_s { + const char *key; + char *value; + _Bool from_cli; /* value set from CLI */ + const char *def; } cf_global_option_t; /* * Prototypes of callback functions */ -static int dispatch_value_typesdb (oconfig_item_t *ci); -static int dispatch_value_plugindir (oconfig_item_t *ci); -static int dispatch_loadplugin (oconfig_item_t *ci); -static int dispatch_block_plugin (oconfig_item_t *ci); +static int dispatch_value_typesdb(oconfig_item_t *ci); +static int dispatch_value_plugindir(oconfig_item_t *ci); +static int dispatch_loadplugin(oconfig_item_t *ci); +static int dispatch_block_plugin(oconfig_item_t *ci); /* * Private variables @@ -98,34 +94,29 @@ static int dispatch_block_plugin (oconfig_item_t *ci); static cf_callback_t *first_callback = NULL; static cf_complex_callback_t *complex_callback_head = NULL; -static cf_value_map_t cf_value_map[] = -{ - {"TypesDB", dispatch_value_typesdb}, - {"PluginDir", dispatch_value_plugindir}, - {"LoadPlugin", dispatch_loadplugin}, - {"Plugin", dispatch_block_plugin} -}; -static int cf_value_map_num = STATIC_ARRAY_SIZE (cf_value_map); - -static cf_global_option_t cf_global_options[] = -{ - {"BaseDir", NULL, 0, PKGLOCALSTATEDIR}, - {"PIDFile", NULL, 0, PIDFILE}, - {"Hostname", NULL, 0, NULL}, - {"FQDNLookup", NULL, 0, "true"}, - {"Interval", NULL, 0, NULL}, - {"ReadThreads", NULL, 0, "5"}, - {"WriteThreads", NULL, 0, "5"}, - {"WriteQueueLimitHigh", NULL, 0, NULL}, - {"WriteQueueLimitLow", NULL, 0, NULL}, - {"Timeout", NULL, 0, "2"}, - {"AutoLoadPlugin", NULL, 0, "false"}, - {"CollectInternalStats", NULL, 0, "false"}, - {"PreCacheChain", NULL, 0, "PreCache"}, - {"PostCacheChain", NULL, 0, "PostCache"}, - {"MaxReadInterval", NULL, 0, "86400"} -}; -static int cf_global_options_num = STATIC_ARRAY_SIZE (cf_global_options); +static cf_value_map_t cf_value_map[] = {{"TypesDB", dispatch_value_typesdb}, + {"PluginDir", dispatch_value_plugindir}, + {"LoadPlugin", dispatch_loadplugin}, + {"Plugin", dispatch_block_plugin}}; +static int cf_value_map_num = STATIC_ARRAY_SIZE(cf_value_map); + +static cf_global_option_t cf_global_options[] = { + {"BaseDir", NULL, 0, PKGLOCALSTATEDIR}, + {"PIDFile", NULL, 0, PIDFILE}, + {"Hostname", NULL, 0, NULL}, + {"FQDNLookup", NULL, 0, "true"}, + {"Interval", NULL, 0, NULL}, + {"ReadThreads", NULL, 0, "5"}, + {"WriteThreads", NULL, 0, "5"}, + {"WriteQueueLimitHigh", NULL, 0, NULL}, + {"WriteQueueLimitLow", NULL, 0, NULL}, + {"Timeout", NULL, 0, "2"}, + {"AutoLoadPlugin", NULL, 0, "false"}, + {"CollectInternalStats", NULL, 0, "false"}, + {"PreCacheChain", NULL, 0, "PreCache"}, + {"PostCacheChain", NULL, 0, "PostCache"}, + {"MaxReadInterval", NULL, 0, "86400"}}; +static int cf_global_options_num = STATIC_ARRAY_SIZE(cf_global_options); static int cf_default_typesdb = 1; @@ -133,655 +124,593 @@ static int cf_default_typesdb = 1; * Functions to handle register/unregister, search, and other plugin related * stuff */ -static cf_callback_t *cf_search (const char *type) -{ - cf_callback_t *cf_cb; +static cf_callback_t *cf_search(const char *type) { + cf_callback_t *cf_cb; - if (type == NULL) - return (NULL); + if (type == NULL) + return (NULL); - for (cf_cb = first_callback; cf_cb != NULL; cf_cb = cf_cb->next) - if (strcasecmp (cf_cb->type, type) == 0) - break; + for (cf_cb = first_callback; cf_cb != NULL; cf_cb = cf_cb->next) + if (strcasecmp(cf_cb->type, type) == 0) + break; - return (cf_cb); + return (cf_cb); } -static int cf_dispatch (const char *type, const char *orig_key, - const char *orig_value) -{ - cf_callback_t *cf_cb; - plugin_ctx_t old_ctx; - char *key; - char *value; - int ret; - int i = 0; - - if (orig_key == NULL) - return (EINVAL); - - DEBUG ("type = %s, key = %s, value = %s", - ESCAPE_NULL(type), - orig_key, - ESCAPE_NULL(orig_value)); - - if ((cf_cb = cf_search (type)) == NULL) - { - WARNING ("Found a configuration for the `%s' plugin, but " - "the plugin isn't loaded or didn't register " - "a configuration callback.", type); - return (-1); - } - - if ((key = strdup (orig_key)) == NULL) - return (1); - if ((value = strdup (orig_value)) == NULL) - { - free (key); - return (2); - } - - ret = -1; - - old_ctx = plugin_set_ctx (cf_cb->ctx); - - for (i = 0; i < cf_cb->keys_num; i++) - { - if ((cf_cb->keys[i] != NULL) - && (strcasecmp (cf_cb->keys[i], key) == 0)) - { - ret = (*cf_cb->callback) (key, value); - break; - } - } - - plugin_set_ctx (old_ctx); - - if (i >= cf_cb->keys_num) - WARNING ("Plugin `%s' did not register for value `%s'.", type, key); - - free (key); - free (value); - - return (ret); +static int cf_dispatch(const char *type, const char *orig_key, + const char *orig_value) { + cf_callback_t *cf_cb; + plugin_ctx_t old_ctx; + char *key; + char *value; + int ret; + int i = 0; + + if (orig_key == NULL) + return (EINVAL); + + DEBUG("type = %s, key = %s, value = %s", ESCAPE_NULL(type), orig_key, + ESCAPE_NULL(orig_value)); + + if ((cf_cb = cf_search(type)) == NULL) { + WARNING("Found a configuration for the `%s' plugin, but " + "the plugin isn't loaded or didn't register " + "a configuration callback.", + type); + return (-1); + } + + if ((key = strdup(orig_key)) == NULL) + return (1); + if ((value = strdup(orig_value)) == NULL) { + free(key); + return (2); + } + + ret = -1; + + old_ctx = plugin_set_ctx(cf_cb->ctx); + + for (i = 0; i < cf_cb->keys_num; i++) { + if ((cf_cb->keys[i] != NULL) && (strcasecmp(cf_cb->keys[i], key) == 0)) { + ret = (*cf_cb->callback)(key, value); + break; + } + } + + plugin_set_ctx(old_ctx); + + if (i >= cf_cb->keys_num) + WARNING("Plugin `%s' did not register for value `%s'.", type, key); + + free(key); + free(value); + + return (ret); } /* int cf_dispatch */ -static int dispatch_global_option (const oconfig_item_t *ci) -{ - if (ci->values_num != 1) - return (-1); - if (ci->values[0].type == OCONFIG_TYPE_STRING) - return (global_option_set (ci->key, ci->values[0].value.string, 0)); - else if (ci->values[0].type == OCONFIG_TYPE_NUMBER) - { - char tmp[128]; - ssnprintf (tmp, sizeof (tmp), "%lf", ci->values[0].value.number); - return (global_option_set (ci->key, tmp, 0)); - } - else if (ci->values[0].type == OCONFIG_TYPE_BOOLEAN) - { - if (ci->values[0].value.boolean) - return (global_option_set (ci->key, "true", 0)); - else - return (global_option_set (ci->key, "false", 0)); - } - - return (-1); +static int dispatch_global_option(const oconfig_item_t *ci) { + if (ci->values_num != 1) + return (-1); + if (ci->values[0].type == OCONFIG_TYPE_STRING) + return (global_option_set(ci->key, ci->values[0].value.string, 0)); + else if (ci->values[0].type == OCONFIG_TYPE_NUMBER) { + char tmp[128]; + ssnprintf(tmp, sizeof(tmp), "%lf", ci->values[0].value.number); + return (global_option_set(ci->key, tmp, 0)); + } else if (ci->values[0].type == OCONFIG_TYPE_BOOLEAN) { + if (ci->values[0].value.boolean) + return (global_option_set(ci->key, "true", 0)); + else + return (global_option_set(ci->key, "false", 0)); + } + + return (-1); } /* int dispatch_global_option */ -static int dispatch_value_typesdb (oconfig_item_t *ci) -{ - assert (strcasecmp (ci->key, "TypesDB") == 0); - - cf_default_typesdb = 0; - - if (ci->values_num < 1) { - ERROR ("configfile: `TypesDB' needs at least one argument."); - return (-1); - } - - for (int i = 0; i < ci->values_num; ++i) - { - if (OCONFIG_TYPE_STRING != ci->values[i].type) { - WARNING ("configfile: TypesDB: Skipping %i. argument which " - "is not a string.", i + 1); - continue; - } - - read_types_list (ci->values[i].value.string); - } - return (0); +static int dispatch_value_typesdb(oconfig_item_t *ci) { + assert(strcasecmp(ci->key, "TypesDB") == 0); + + cf_default_typesdb = 0; + + if (ci->values_num < 1) { + ERROR("configfile: `TypesDB' needs at least one argument."); + return (-1); + } + + for (int i = 0; i < ci->values_num; ++i) { + if (OCONFIG_TYPE_STRING != ci->values[i].type) { + WARNING("configfile: TypesDB: Skipping %i. argument which " + "is not a string.", + i + 1); + continue; + } + + read_types_list(ci->values[i].value.string); + } + return (0); } /* int dispatch_value_typesdb */ -static int dispatch_value_plugindir (oconfig_item_t *ci) -{ - assert (strcasecmp (ci->key, "PluginDir") == 0); +static int dispatch_value_plugindir(oconfig_item_t *ci) { + assert(strcasecmp(ci->key, "PluginDir") == 0); - if (ci->values_num != 1) - return (-1); - if (ci->values[0].type != OCONFIG_TYPE_STRING) - return (-1); + if (ci->values_num != 1) + return (-1); + if (ci->values[0].type != OCONFIG_TYPE_STRING) + return (-1); - plugin_set_dir (ci->values[0].value.string); - return (0); + plugin_set_dir(ci->values[0].value.string); + return (0); } -static int dispatch_loadplugin (oconfig_item_t *ci) -{ - const char *name; - unsigned int flags = 0; - plugin_ctx_t ctx = { 0 }; - plugin_ctx_t old_ctx; - int ret_val; - - assert (strcasecmp (ci->key, "LoadPlugin") == 0); - - if (ci->values_num != 1) - return (-1); - if (ci->values[0].type != OCONFIG_TYPE_STRING) - return (-1); - - name = ci->values[0].value.string; - if (strcmp ("libvirt", name) == 0) - name = "virt"; - - /* default to the global interval set before loading this plugin */ - ctx.interval = cf_get_default_interval (); - ctx.flush_interval = 0; - ctx.flush_timeout = 0; - - for (int i = 0; i < ci->children_num; ++i) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp("Globals", child->key) == 0) - cf_util_get_flag (child, &flags, PLUGIN_FLAGS_GLOBAL); - else if (strcasecmp ("Interval", child->key) == 0) - cf_util_get_cdtime (child, &ctx.interval); - else if (strcasecmp ("FlushInterval", child->key) == 0) - cf_util_get_cdtime (child, &ctx.flush_interval); - else if (strcasecmp ("FlushTimeout", child->key) == 0) - cf_util_get_cdtime (child, &ctx.flush_timeout); - else { - WARNING("Ignoring unknown LoadPlugin option \"%s\" " - "for plugin \"%s\"", - child->key, ci->values[0].value.string); - } - } - - old_ctx = plugin_set_ctx (ctx); - ret_val = plugin_load (name, (uint32_t) flags); - /* reset to the "global" context */ - plugin_set_ctx (old_ctx); - - return (ret_val); +static int dispatch_loadplugin(oconfig_item_t *ci) { + const char *name; + unsigned int flags = 0; + plugin_ctx_t ctx = {0}; + plugin_ctx_t old_ctx; + int ret_val; + + assert(strcasecmp(ci->key, "LoadPlugin") == 0); + + if (ci->values_num != 1) + return (-1); + if (ci->values[0].type != OCONFIG_TYPE_STRING) + return (-1); + + name = ci->values[0].value.string; + if (strcmp("libvirt", name) == 0) + name = "virt"; + + /* default to the global interval set before loading this plugin */ + ctx.interval = cf_get_default_interval(); + ctx.flush_interval = 0; + ctx.flush_timeout = 0; + + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Globals", child->key) == 0) + cf_util_get_flag(child, &flags, PLUGIN_FLAGS_GLOBAL); + else if (strcasecmp("Interval", child->key) == 0) + cf_util_get_cdtime(child, &ctx.interval); + else if (strcasecmp("FlushInterval", child->key) == 0) + cf_util_get_cdtime(child, &ctx.flush_interval); + else if (strcasecmp("FlushTimeout", child->key) == 0) + cf_util_get_cdtime(child, &ctx.flush_timeout); + else { + WARNING("Ignoring unknown LoadPlugin option \"%s\" " + "for plugin \"%s\"", + child->key, ci->values[0].value.string); + } + } + + old_ctx = plugin_set_ctx(ctx); + ret_val = plugin_load(name, (uint32_t)flags); + /* reset to the "global" context */ + plugin_set_ctx(old_ctx); + + return (ret_val); } /* int dispatch_value_loadplugin */ -static int dispatch_value_plugin (const char *plugin, oconfig_item_t *ci) -{ - char buffer[4096]; - char *buffer_ptr; - int buffer_free; - - buffer_ptr = buffer; - buffer_free = sizeof (buffer); - - for (int i = 0; i < ci->values_num; i++) - { - int status = -1; - - if (ci->values[i].type == OCONFIG_TYPE_STRING) - status = ssnprintf (buffer_ptr, buffer_free, " %s", - ci->values[i].value.string); - else if (ci->values[i].type == OCONFIG_TYPE_NUMBER) - status = ssnprintf (buffer_ptr, buffer_free, " %lf", - ci->values[i].value.number); - else if (ci->values[i].type == OCONFIG_TYPE_BOOLEAN) - status = ssnprintf (buffer_ptr, buffer_free, " %s", - ci->values[i].value.boolean - ? "true" : "false"); - - if ((status < 0) || (status >= buffer_free)) - return (-1); - buffer_free -= status; - buffer_ptr += status; - } - /* skip the initial space */ - buffer_ptr = buffer + 1; - - return (cf_dispatch (plugin, ci->key, buffer_ptr)); +static int dispatch_value_plugin(const char *plugin, oconfig_item_t *ci) { + char buffer[4096]; + char *buffer_ptr; + int buffer_free; + + buffer_ptr = buffer; + buffer_free = sizeof(buffer); + + for (int i = 0; i < ci->values_num; i++) { + int status = -1; + + if (ci->values[i].type == OCONFIG_TYPE_STRING) + status = + ssnprintf(buffer_ptr, buffer_free, " %s", ci->values[i].value.string); + else if (ci->values[i].type == OCONFIG_TYPE_NUMBER) + status = ssnprintf(buffer_ptr, buffer_free, " %lf", + ci->values[i].value.number); + else if (ci->values[i].type == OCONFIG_TYPE_BOOLEAN) + status = ssnprintf(buffer_ptr, buffer_free, " %s", + ci->values[i].value.boolean ? "true" : "false"); + + if ((status < 0) || (status >= buffer_free)) + return (-1); + buffer_free -= status; + buffer_ptr += status; + } + /* skip the initial space */ + buffer_ptr = buffer + 1; + + return (cf_dispatch(plugin, ci->key, buffer_ptr)); } /* int dispatch_value_plugin */ -static int dispatch_value (oconfig_item_t *ci) -{ - int ret = 0; - - for (int i = 0; i < cf_value_map_num; i++) - if (strcasecmp (cf_value_map[i].key, ci->key) == 0) - { - ret = cf_value_map[i].func (ci); - break; - } - - for (int i = 0; i < cf_global_options_num; i++) - if (strcasecmp (cf_global_options[i].key, ci->key) == 0) - { - ret = dispatch_global_option (ci); - break; - } - - return (ret); +static int dispatch_value(oconfig_item_t *ci) { + int ret = 0; + + for (int i = 0; i < cf_value_map_num; i++) + if (strcasecmp(cf_value_map[i].key, ci->key) == 0) { + ret = cf_value_map[i].func(ci); + break; + } + + for (int i = 0; i < cf_global_options_num; i++) + if (strcasecmp(cf_global_options[i].key, ci->key) == 0) { + ret = dispatch_global_option(ci); + break; + } + + return (ret); } /* int dispatch_value */ -static int dispatch_block_plugin (oconfig_item_t *ci) -{ - const char *name; - - if (strcasecmp (ci->key, "Plugin") != 0) - return (-1); - if (ci->values_num < 1) - return (-1); - if (ci->values[0].type != OCONFIG_TYPE_STRING) - return (-1); - - name = ci->values[0].value.string; - if (strcmp ("libvirt", name) == 0) - { - /* TODO(octo): Remove this legacy. */ - WARNING ("The \"libvirt\" plugin has been renamed to \"virt\" to avoid problems with the build system. " - "Your configuration is still using the old name. " - "Please change it to use \"virt\" as soon as possible. " - "This compatibility code will go away eventually."); - name = "virt"; - } - - if (IS_TRUE (global_option_get ("AutoLoadPlugin"))) - { - plugin_ctx_t ctx = { 0 }; - plugin_ctx_t old_ctx; - int status; - - /* default to the global interval set before loading this plugin */ - ctx.interval = cf_get_default_interval (); - - old_ctx = plugin_set_ctx (ctx); - status = plugin_load (name, /* flags = */ 0); - /* reset to the "global" context */ - plugin_set_ctx (old_ctx); - - if (status != 0) - { - ERROR ("Automatically loading plugin \"%s\" failed " - "with status %i.", name, status); - return (status); - } - } - - /* Check for a complex callback first */ - for (cf_complex_callback_t *cb = complex_callback_head; cb != NULL; cb = cb->next) - { - if (strcasecmp (name, cb->type) == 0) - { - plugin_ctx_t old_ctx; - int ret_val; - - old_ctx = plugin_set_ctx (cb->ctx); - ret_val = (cb->callback (ci)); - plugin_set_ctx (old_ctx); - return (ret_val); - } - } - - /* Hm, no complex plugin found. Dispatch the values one by one */ - for (int i = 0; i < ci->children_num; i++) - { - if (ci->children[i].children == NULL) - dispatch_value_plugin (name, ci->children + i); - else - { - WARNING ("There is a `%s' block within the " - "configuration for the %s plugin. " - "The plugin either only expects " - "\"simple\" configuration statements " - "or wasn't loaded using `LoadPlugin'." - " Please check your configuration.", - ci->children[i].key, name); - } - } - - return (0); +static int dispatch_block_plugin(oconfig_item_t *ci) { + const char *name; + + if (strcasecmp(ci->key, "Plugin") != 0) + return (-1); + if (ci->values_num < 1) + return (-1); + if (ci->values[0].type != OCONFIG_TYPE_STRING) + return (-1); + + name = ci->values[0].value.string; + if (strcmp("libvirt", name) == 0) { + /* TODO(octo): Remove this legacy. */ + WARNING("The \"libvirt\" plugin has been renamed to \"virt\" to avoid " + "problems with the build system. " + "Your configuration is still using the old name. " + "Please change it to use \"virt\" as soon as possible. " + "This compatibility code will go away eventually."); + name = "virt"; + } + + if (IS_TRUE(global_option_get("AutoLoadPlugin"))) { + plugin_ctx_t ctx = {0}; + plugin_ctx_t old_ctx; + int status; + + /* default to the global interval set before loading this plugin */ + ctx.interval = cf_get_default_interval(); + + old_ctx = plugin_set_ctx(ctx); + status = plugin_load(name, /* flags = */ 0); + /* reset to the "global" context */ + plugin_set_ctx(old_ctx); + + if (status != 0) { + ERROR("Automatically loading plugin \"%s\" failed " + "with status %i.", + name, status); + return (status); + } + } + + /* Check for a complex callback first */ + for (cf_complex_callback_t *cb = complex_callback_head; cb != NULL; + cb = cb->next) { + if (strcasecmp(name, cb->type) == 0) { + plugin_ctx_t old_ctx; + int ret_val; + + old_ctx = plugin_set_ctx(cb->ctx); + ret_val = (cb->callback(ci)); + plugin_set_ctx(old_ctx); + return (ret_val); + } + } + + /* Hm, no complex plugin found. Dispatch the values one by one */ + for (int i = 0; i < ci->children_num; i++) { + if (ci->children[i].children == NULL) + dispatch_value_plugin(name, ci->children + i); + else { + WARNING("There is a `%s' block within the " + "configuration for the %s plugin. " + "The plugin either only expects " + "\"simple\" configuration statements " + "or wasn't loaded using `LoadPlugin'." + " Please check your configuration.", + ci->children[i].key, name); + } + } + + return (0); } +static int dispatch_block(oconfig_item_t *ci) { + if (strcasecmp(ci->key, "LoadPlugin") == 0) + return (dispatch_loadplugin(ci)); + else if (strcasecmp(ci->key, "Plugin") == 0) + return (dispatch_block_plugin(ci)); + else if (strcasecmp(ci->key, "Chain") == 0) + return (fc_configure(ci)); -static int dispatch_block (oconfig_item_t *ci) -{ - if (strcasecmp (ci->key, "LoadPlugin") == 0) - return (dispatch_loadplugin (ci)); - else if (strcasecmp (ci->key, "Plugin") == 0) - return (dispatch_block_plugin (ci)); - else if (strcasecmp (ci->key, "Chain") == 0) - return (fc_configure (ci)); - - return (0); + return (0); } -static int cf_ci_replace_child (oconfig_item_t *dst, oconfig_item_t *src, - int offset) -{ - oconfig_item_t *temp; - - assert (offset >= 0); - assert (dst->children_num > offset); - - /* Free the memory used by the replaced child. Usually that's the - * `Include "blah"' statement. */ - temp = dst->children + offset; - for (int i = 0; i < temp->values_num; i++) - { - if (temp->values[i].type == OCONFIG_TYPE_STRING) - { - sfree (temp->values[i].value.string); - } - } - sfree (temp->values); - temp = NULL; - - /* If (src->children_num == 0) the array size is decreased. If offset - * is _not_ the last element, (offset < (dst->children_num - 1)), then - * we need to move the trailing elements before resizing the array. */ - if ((src->children_num == 0) && (offset < (dst->children_num - 1))) - { - int nmemb = dst->children_num - (offset + 1); - memmove (dst->children + offset, dst->children + offset + 1, - sizeof (oconfig_item_t) * nmemb); - } - - /* Resize the memory containing the children to be big enough to hold - * all children. */ - if (dst->children_num + src->children_num - 1 == 0) - { - dst->children_num = 0; - return (0); - } - - temp = realloc (dst->children, - sizeof (oconfig_item_t) - * (dst->children_num + src->children_num - 1)); - if (temp == NULL) - { - ERROR ("configfile: realloc failed."); - return (-1); - } - dst->children = temp; - - /* If there are children behind the include statement, and they have - * not yet been moved because (src->children_num == 0), then move them - * to the end of the list, so that the new children have room before - * them. */ - if ((src->children_num > 0) - && ((dst->children_num - (offset + 1)) > 0)) - { - int nmemb = dst->children_num - (offset + 1); - int old_offset = offset + 1; - int new_offset = offset + src->children_num; - - memmove (dst->children + new_offset, - dst->children + old_offset, - sizeof (oconfig_item_t) * nmemb); - } - - /* Last but not least: If there are new children, copy them to the - * memory reserved for them. */ - if (src->children_num > 0) - { - memcpy (dst->children + offset, - src->children, - sizeof (oconfig_item_t) * src->children_num); - } - - /* Update the number of children. */ - dst->children_num += (src->children_num - 1); - - return (0); +static int cf_ci_replace_child(oconfig_item_t *dst, oconfig_item_t *src, + int offset) { + oconfig_item_t *temp; + + assert(offset >= 0); + assert(dst->children_num > offset); + + /* Free the memory used by the replaced child. Usually that's the + * `Include "blah"' statement. */ + temp = dst->children + offset; + for (int i = 0; i < temp->values_num; i++) { + if (temp->values[i].type == OCONFIG_TYPE_STRING) { + sfree(temp->values[i].value.string); + } + } + sfree(temp->values); + temp = NULL; + + /* If (src->children_num == 0) the array size is decreased. If offset + * is _not_ the last element, (offset < (dst->children_num - 1)), then + * we need to move the trailing elements before resizing the array. */ + if ((src->children_num == 0) && (offset < (dst->children_num - 1))) { + int nmemb = dst->children_num - (offset + 1); + memmove(dst->children + offset, dst->children + offset + 1, + sizeof(oconfig_item_t) * nmemb); + } + + /* Resize the memory containing the children to be big enough to hold + * all children. */ + if (dst->children_num + src->children_num - 1 == 0) { + dst->children_num = 0; + return (0); + } + + temp = + realloc(dst->children, sizeof(oconfig_item_t) * + (dst->children_num + src->children_num - 1)); + if (temp == NULL) { + ERROR("configfile: realloc failed."); + return (-1); + } + dst->children = temp; + + /* If there are children behind the include statement, and they have + * not yet been moved because (src->children_num == 0), then move them + * to the end of the list, so that the new children have room before + * them. */ + if ((src->children_num > 0) && ((dst->children_num - (offset + 1)) > 0)) { + int nmemb = dst->children_num - (offset + 1); + int old_offset = offset + 1; + int new_offset = offset + src->children_num; + + memmove(dst->children + new_offset, dst->children + old_offset, + sizeof(oconfig_item_t) * nmemb); + } + + /* Last but not least: If there are new children, copy them to the + * memory reserved for them. */ + if (src->children_num > 0) { + memcpy(dst->children + offset, src->children, + sizeof(oconfig_item_t) * src->children_num); + } + + /* Update the number of children. */ + dst->children_num += (src->children_num - 1); + + return (0); } /* int cf_ci_replace_child */ -static int cf_ci_append_children (oconfig_item_t *dst, oconfig_item_t *src) -{ - oconfig_item_t *temp; - - if ((src == NULL) || (src->children_num == 0)) - return (0); - - temp = realloc (dst->children, - sizeof (oconfig_item_t) - * (dst->children_num + src->children_num)); - if (temp == NULL) - { - ERROR ("configfile: realloc failed."); - return (-1); - } - dst->children = temp; - - memcpy (dst->children + dst->children_num, - src->children, - sizeof (oconfig_item_t) - * src->children_num); - dst->children_num += src->children_num; - - return (0); +static int cf_ci_append_children(oconfig_item_t *dst, oconfig_item_t *src) { + oconfig_item_t *temp; + + if ((src == NULL) || (src->children_num == 0)) + return (0); + + temp = realloc(dst->children, sizeof(oconfig_item_t) * + (dst->children_num + src->children_num)); + if (temp == NULL) { + ERROR("configfile: realloc failed."); + return (-1); + } + dst->children = temp; + + memcpy(dst->children + dst->children_num, src->children, + sizeof(oconfig_item_t) * src->children_num); + dst->children_num += src->children_num; + + return (0); } /* int cf_ci_append_children */ #define CF_MAX_DEPTH 8 -static oconfig_item_t *cf_read_generic (const char *path, - const char *pattern, int depth); +static oconfig_item_t *cf_read_generic(const char *path, const char *pattern, + int depth); -static int cf_include_all (oconfig_item_t *root, int depth) -{ - for (int i = 0; i < root->children_num; i++) - { - oconfig_item_t *new; - oconfig_item_t *old; +static int cf_include_all(oconfig_item_t *root, int depth) { + for (int i = 0; i < root->children_num; i++) { + oconfig_item_t *new; + oconfig_item_t *old; - char *pattern = NULL; + char *pattern = NULL; - if (strcasecmp (root->children[i].key, "Include") != 0) - continue; + if (strcasecmp(root->children[i].key, "Include") != 0) + continue; - old = root->children + i; + old = root->children + i; - if ((old->values_num != 1) - || (old->values[0].type != OCONFIG_TYPE_STRING)) - { - ERROR ("configfile: `Include' needs exactly one string argument."); - continue; - } + if ((old->values_num != 1) || + (old->values[0].type != OCONFIG_TYPE_STRING)) { + ERROR("configfile: `Include' needs exactly one string argument."); + continue; + } - for (int j = 0; j < old->children_num; ++j) - { - oconfig_item_t *child = old->children + j; + for (int j = 0; j < old->children_num; ++j) { + oconfig_item_t *child = old->children + j; - if (strcasecmp (child->key, "Filter") == 0) - cf_util_get_string (child, &pattern); - else - ERROR ("configfile: Option `%s' not allowed in block.", - child->key); - } + if (strcasecmp(child->key, "Filter") == 0) + cf_util_get_string(child, &pattern); + else + ERROR("configfile: Option `%s' not allowed in block.", + child->key); + } - new = cf_read_generic (old->values[0].value.string, pattern, depth + 1); - sfree (pattern); + new = cf_read_generic(old->values[0].value.string, pattern, depth + 1); + sfree(pattern); - if (new == NULL) - return (-1); + if (new == NULL) + return (-1); - /* Now replace the i'th child in `root' with `new'. */ - if (cf_ci_replace_child (root, new, i) < 0) { - sfree (new->values); - sfree (new); - return (-1); - } + /* Now replace the i'th child in `root' with `new'. */ + if (cf_ci_replace_child(root, new, i) < 0) { + sfree(new->values); + sfree(new); + return (-1); + } - /* ... and go back to the new i'th child. */ - --i; + /* ... and go back to the new i'th child. */ + --i; - sfree (new->values); - sfree (new); - } /* for (i = 0; i < root->children_num; i++) */ + sfree(new->values); + sfree(new); + } /* for (i = 0; i < root->children_num; i++) */ - return (0); + return (0); } /* int cf_include_all */ -static oconfig_item_t *cf_read_file (const char *file, - const char *pattern, int depth) -{ - oconfig_item_t *root; - int status; +static oconfig_item_t *cf_read_file(const char *file, const char *pattern, + int depth) { + oconfig_item_t *root; + int status; - assert (depth < CF_MAX_DEPTH); + assert(depth < CF_MAX_DEPTH); - if (pattern != NULL) { + if (pattern != NULL) { #if HAVE_FNMATCH_H && HAVE_LIBGEN_H - char *tmp = sstrdup (file); - char *filename = basename (tmp); - - if ((filename != NULL) && (fnmatch (pattern, filename, 0) != 0)) { - DEBUG ("configfile: Not including `%s' because it " - "does not match pattern `%s'.", - filename, pattern); - free (tmp); - return (NULL); - } - - free (tmp); + char *tmp = sstrdup(file); + char *filename = basename(tmp); + + if ((filename != NULL) && (fnmatch(pattern, filename, 0) != 0)) { + DEBUG("configfile: Not including `%s' because it " + "does not match pattern `%s'.", + filename, pattern); + free(tmp); + return (NULL); + } + + free(tmp); #else - ERROR ("configfile: Cannot apply pattern filter '%s' " - "to file '%s': functions basename() and / or " - "fnmatch() not available.", pattern, file); + ERROR("configfile: Cannot apply pattern filter '%s' " + "to file '%s': functions basename() and / or " + "fnmatch() not available.", + pattern, file); #endif /* HAVE_FNMATCH_H && HAVE_LIBGEN_H */ - } - - root = oconfig_parse_file (file); - if (root == NULL) - { - ERROR ("configfile: Cannot read file `%s'.", file); - return (NULL); - } - - status = cf_include_all (root, depth); - if (status != 0) - { - oconfig_free (root); - return (NULL); - } - - return (root); + } + + root = oconfig_parse_file(file); + if (root == NULL) { + ERROR("configfile: Cannot read file `%s'.", file); + return (NULL); + } + + status = cf_include_all(root, depth); + if (status != 0) { + oconfig_free(root); + return (NULL); + } + + return (root); } /* oconfig_item_t *cf_read_file */ -static int cf_compare_string (const void *p1, const void *p2) -{ - return strcmp (*(const char **) p1, *(const char **) p2); +static int cf_compare_string(const void *p1, const void *p2) { + return strcmp(*(const char **)p1, *(const char **)p2); } -static oconfig_item_t *cf_read_dir (const char *dir, - const char *pattern, int depth) -{ - oconfig_item_t *root = NULL; - DIR *dh; - struct dirent *de; - char **filenames = NULL; - int filenames_num = 0; - int status; - - assert (depth < CF_MAX_DEPTH); - - dh = opendir (dir); - if (dh == NULL) - { - char errbuf[1024]; - ERROR ("configfile: opendir failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (NULL); - } - - root = calloc (1, sizeof (*root)); - if (root == NULL) - { - ERROR ("configfile: calloc failed."); - closedir (dh); - return (NULL); - } - - while ((de = readdir (dh)) != NULL) - { - char name[1024]; - char **tmp; - - if ((de->d_name[0] == '.') || (de->d_name[0] == 0)) - continue; - - status = ssnprintf (name, sizeof (name), "%s/%s", - dir, de->d_name); - if ((status < 0) || ((size_t) status >= sizeof (name))) - { - ERROR ("configfile: Not including `%s/%s' because its" - " name is too long.", - dir, de->d_name); - closedir (dh); - for (int i = 0; i < filenames_num; ++i) - free (filenames[i]); - free (filenames); - free (root); - return (NULL); - } - - ++filenames_num; - tmp = realloc (filenames, - filenames_num * sizeof (*filenames)); - if (tmp == NULL) { - ERROR ("configfile: realloc failed."); - closedir (dh); - for (int i = 0; i < filenames_num - 1; ++i) - free (filenames[i]); - free (filenames); - free (root); - return (NULL); - } - filenames = tmp; - - filenames[filenames_num - 1] = sstrdup (name); - } - - if (filenames == NULL) - { - closedir (dh); - return (root); - } - - qsort ((void *) filenames, filenames_num, sizeof (*filenames), - cf_compare_string); - - for (int i = 0; i < filenames_num; ++i) - { - oconfig_item_t *temp; - char *name = filenames[i]; - - temp = cf_read_generic (name, pattern, depth); - if (temp == NULL) - { - /* An error should already have been reported. */ - sfree (name); - continue; - } - - cf_ci_append_children (root, temp); - sfree (temp->children); - sfree (temp); - - free (name); - } - - closedir (dh); - free(filenames); - return (root); +static oconfig_item_t *cf_read_dir(const char *dir, const char *pattern, + int depth) { + oconfig_item_t *root = NULL; + DIR *dh; + struct dirent *de; + char **filenames = NULL; + int filenames_num = 0; + int status; + + assert(depth < CF_MAX_DEPTH); + + dh = opendir(dir); + if (dh == NULL) { + char errbuf[1024]; + ERROR("configfile: opendir failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (NULL); + } + + root = calloc(1, sizeof(*root)); + if (root == NULL) { + ERROR("configfile: calloc failed."); + closedir(dh); + return (NULL); + } + + while ((de = readdir(dh)) != NULL) { + char name[1024]; + char **tmp; + + if ((de->d_name[0] == '.') || (de->d_name[0] == 0)) + continue; + + status = ssnprintf(name, sizeof(name), "%s/%s", dir, de->d_name); + if ((status < 0) || ((size_t)status >= sizeof(name))) { + ERROR("configfile: Not including `%s/%s' because its" + " name is too long.", + dir, de->d_name); + closedir(dh); + for (int i = 0; i < filenames_num; ++i) + free(filenames[i]); + free(filenames); + free(root); + return (NULL); + } + + ++filenames_num; + tmp = realloc(filenames, filenames_num * sizeof(*filenames)); + if (tmp == NULL) { + ERROR("configfile: realloc failed."); + closedir(dh); + for (int i = 0; i < filenames_num - 1; ++i) + free(filenames[i]); + free(filenames); + free(root); + return (NULL); + } + filenames = tmp; + + filenames[filenames_num - 1] = sstrdup(name); + } + + if (filenames == NULL) { + closedir(dh); + return (root); + } + + qsort((void *)filenames, filenames_num, sizeof(*filenames), + cf_compare_string); + + for (int i = 0; i < filenames_num; ++i) { + oconfig_item_t *temp; + char *name = filenames[i]; + + temp = cf_read_generic(name, pattern, depth); + if (temp == NULL) { + /* An error should already have been reported. */ + sfree(name); + continue; + } + + cf_ci_append_children(root, temp); + sfree(temp->children); + sfree(temp); + + free(name); + } + + closedir(dh); + free(filenames); + return (root); } /* oconfig_item_t *cf_read_dir */ /* @@ -796,476 +725,432 @@ static oconfig_item_t *cf_read_dir (const char *dir, * simpler function is used which does not do any such expansion. */ #if HAVE_WORDEXP_H -static oconfig_item_t *cf_read_generic (const char *path, - const char *pattern, int depth) -{ - oconfig_item_t *root = NULL; - int status; - const char *path_ptr; - wordexp_t we; - - if (depth >= CF_MAX_DEPTH) - { - ERROR ("configfile: Not including `%s' because the maximum " - "nesting depth has been reached.", path); - return (NULL); - } - - status = wordexp (path, &we, WRDE_NOCMD); - if (status != 0) - { - ERROR ("configfile: wordexp (%s) failed.", path); - return (NULL); - } - - root = calloc (1, sizeof (*root)); - if (root == NULL) - { - ERROR ("configfile: calloc failed."); - return (NULL); - } - - /* wordexp() might return a sorted list already. That's not - * documented though, so let's make sure we get what we want. */ - qsort ((void *) we.we_wordv, we.we_wordc, sizeof (*we.we_wordv), - cf_compare_string); - - for (size_t i = 0; i < we.we_wordc; i++) - { - oconfig_item_t *temp; - struct stat statbuf; - - path_ptr = we.we_wordv[i]; - - status = stat (path_ptr, &statbuf); - if (status != 0) - { - char errbuf[1024]; - WARNING ("configfile: stat (%s) failed: %s", - path_ptr, - sstrerror (errno, errbuf, sizeof (errbuf))); - continue; - } - - if (S_ISREG (statbuf.st_mode)) - temp = cf_read_file (path_ptr, pattern, depth); - else if (S_ISDIR (statbuf.st_mode)) - temp = cf_read_dir (path_ptr, pattern, depth); - else - { - WARNING ("configfile: %s is neither a file nor a " - "directory.", path); - continue; - } - - if (temp == NULL) { - oconfig_free (root); - return (NULL); - } - - cf_ci_append_children (root, temp); - sfree (temp->children); - sfree (temp); - } - - wordfree (&we); - - return (root); +static oconfig_item_t *cf_read_generic(const char *path, const char *pattern, + int depth) { + oconfig_item_t *root = NULL; + int status; + const char *path_ptr; + wordexp_t we; + + if (depth >= CF_MAX_DEPTH) { + ERROR("configfile: Not including `%s' because the maximum " + "nesting depth has been reached.", + path); + return (NULL); + } + + status = wordexp(path, &we, WRDE_NOCMD); + if (status != 0) { + ERROR("configfile: wordexp (%s) failed.", path); + return (NULL); + } + + root = calloc(1, sizeof(*root)); + if (root == NULL) { + ERROR("configfile: calloc failed."); + return (NULL); + } + + /* wordexp() might return a sorted list already. That's not + * documented though, so let's make sure we get what we want. */ + qsort((void *)we.we_wordv, we.we_wordc, sizeof(*we.we_wordv), + cf_compare_string); + + for (size_t i = 0; i < we.we_wordc; i++) { + oconfig_item_t *temp; + struct stat statbuf; + + path_ptr = we.we_wordv[i]; + + status = stat(path_ptr, &statbuf); + if (status != 0) { + char errbuf[1024]; + WARNING("configfile: stat (%s) failed: %s", path_ptr, + sstrerror(errno, errbuf, sizeof(errbuf))); + continue; + } + + if (S_ISREG(statbuf.st_mode)) + temp = cf_read_file(path_ptr, pattern, depth); + else if (S_ISDIR(statbuf.st_mode)) + temp = cf_read_dir(path_ptr, pattern, depth); + else { + WARNING("configfile: %s is neither a file nor a " + "directory.", + path); + continue; + } + + if (temp == NULL) { + oconfig_free(root); + return (NULL); + } + + cf_ci_append_children(root, temp); + sfree(temp->children); + sfree(temp); + } + + wordfree(&we); + + return (root); } /* oconfig_item_t *cf_read_generic */ /* #endif HAVE_WORDEXP_H */ -#else /* if !HAVE_WORDEXP_H */ -static oconfig_item_t *cf_read_generic (const char *path, - const char *pattern, int depth) -{ - struct stat statbuf; - int status; - - if (depth >= CF_MAX_DEPTH) - { - ERROR ("configfile: Not including `%s' because the maximum " - "nesting depth has been reached.", path); - return (NULL); - } - - status = stat (path, &statbuf); - if (status != 0) - { - char errbuf[1024]; - ERROR ("configfile: stat (%s) failed: %s", - path, - sstrerror (errno, errbuf, sizeof (errbuf))); - return (NULL); - } - - if (S_ISREG (statbuf.st_mode)) - return (cf_read_file (path, pattern, depth)); - else if (S_ISDIR (statbuf.st_mode)) - return (cf_read_dir (path, pattern, depth)); - - ERROR ("configfile: %s is neither a file nor a directory.", path); - return (NULL); +#else /* if !HAVE_WORDEXP_H */ +static oconfig_item_t *cf_read_generic(const char *path, const char *pattern, + int depth) { + struct stat statbuf; + int status; + + if (depth >= CF_MAX_DEPTH) { + ERROR("configfile: Not including `%s' because the maximum " + "nesting depth has been reached.", + path); + return (NULL); + } + + status = stat(path, &statbuf); + if (status != 0) { + char errbuf[1024]; + ERROR("configfile: stat (%s) failed: %s", path, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (NULL); + } + + if (S_ISREG(statbuf.st_mode)) + return (cf_read_file(path, pattern, depth)); + else if (S_ISDIR(statbuf.st_mode)) + return (cf_read_dir(path, pattern, depth)); + + ERROR("configfile: %s is neither a file nor a directory.", path); + return (NULL); } /* oconfig_item_t *cf_read_generic */ #endif /* !HAVE_WORDEXP_H */ /* * Public functions */ -int global_option_set (const char *option, const char *value, _Bool from_cli) -{ - int i; - DEBUG ("option = %s; value = %s;", option, value); +int global_option_set(const char *option, const char *value, _Bool from_cli) { + int i; + DEBUG("option = %s; value = %s;", option, value); - for (i = 0; i < cf_global_options_num; i++) - if (strcasecmp (cf_global_options[i].key, option) == 0) - break; + for (i = 0; i < cf_global_options_num; i++) + if (strcasecmp(cf_global_options[i].key, option) == 0) + break; - if (i >= cf_global_options_num) - { - ERROR ("configfile: Cannot set unknown global option `%s'.", option); - return (-1); - } + if (i >= cf_global_options_num) { + ERROR("configfile: Cannot set unknown global option `%s'.", option); + return (-1); + } - if (cf_global_options[i].from_cli && (! from_cli)) - { - DEBUG ("configfile: Ignoring %s `%s' option because " - "it was overriden by a command-line option.", - option, value); - return (0); - } + if (cf_global_options[i].from_cli && (!from_cli)) { + DEBUG("configfile: Ignoring %s `%s' option because " + "it was overriden by a command-line option.", + option, value); + return (0); + } - sfree (cf_global_options[i].value); + sfree(cf_global_options[i].value); - if (value != NULL) - cf_global_options[i].value = strdup (value); - else - cf_global_options[i].value = NULL; + if (value != NULL) + cf_global_options[i].value = strdup(value); + else + cf_global_options[i].value = NULL; - cf_global_options[i].from_cli = from_cli; + cf_global_options[i].from_cli = from_cli; - return (0); + return (0); } -const char *global_option_get (const char *option) -{ - int i; - for (i = 0; i < cf_global_options_num; i++) - if (strcasecmp (cf_global_options[i].key, option) == 0) - break; - - if (i >= cf_global_options_num) - { - ERROR ("configfile: Cannot get unknown global option `%s'.", option); - return (NULL); - } - - return ((cf_global_options[i].value != NULL) - ? cf_global_options[i].value - : cf_global_options[i].def); +const char *global_option_get(const char *option) { + int i; + for (i = 0; i < cf_global_options_num; i++) + if (strcasecmp(cf_global_options[i].key, option) == 0) + break; + + if (i >= cf_global_options_num) { + ERROR("configfile: Cannot get unknown global option `%s'.", option); + return (NULL); + } + + return ((cf_global_options[i].value != NULL) ? cf_global_options[i].value + : cf_global_options[i].def); } /* char *global_option_get */ -long global_option_get_long (const char *option, long default_value) -{ - const char *str; - long value; +long global_option_get_long(const char *option, long default_value) { + const char *str; + long value; - str = global_option_get (option); - if (NULL == str) - return (default_value); + str = global_option_get(option); + if (NULL == str) + return (default_value); - errno = 0; - value = strtol (str, /* endptr = */ NULL, /* base = */ 0); - if (errno != 0) - return (default_value); + errno = 0; + value = strtol(str, /* endptr = */ NULL, /* base = */ 0); + if (errno != 0) + return (default_value); - return (value); + return (value); } /* char *global_option_get_long */ -cdtime_t global_option_get_time (const char *name, cdtime_t def) /* {{{ */ +cdtime_t global_option_get_time(const char *name, cdtime_t def) /* {{{ */ { - char const *optstr; - char *endptr = NULL; - double v; - - optstr = global_option_get (name); - if (optstr == NULL) - return (def); - - errno = 0; - v = strtod (optstr, &endptr); - if ((endptr == NULL) || (*endptr != 0) || (errno != 0)) - return (def); - else if (v <= 0.0) - return (def); - - return (DOUBLE_TO_CDTIME_T (v)); + char const *optstr; + char *endptr = NULL; + double v; + + optstr = global_option_get(name); + if (optstr == NULL) + return (def); + + errno = 0; + v = strtod(optstr, &endptr); + if ((endptr == NULL) || (*endptr != 0) || (errno != 0)) + return (def); + else if (v <= 0.0) + return (def); + + return (DOUBLE_TO_CDTIME_T(v)); } /* }}} cdtime_t global_option_get_time */ -cdtime_t cf_get_default_interval (void) -{ - return (global_option_get_time ("Interval", - DOUBLE_TO_CDTIME_T (COLLECTD_DEFAULT_INTERVAL))); +cdtime_t cf_get_default_interval(void) { + return (global_option_get_time( + "Interval", DOUBLE_TO_CDTIME_T(COLLECTD_DEFAULT_INTERVAL))); } -void cf_unregister (const char *type) -{ - for (cf_callback_t *prev = NULL, *this = first_callback; - this != NULL; - prev = this, this = this->next) - if (strcasecmp (this->type, type) == 0) - { - if (prev == NULL) - first_callback = this->next; - else - prev->next = this->next; - - free (this); - break; - } +void cf_unregister(const char *type) { + for (cf_callback_t *prev = NULL, *this = first_callback; this != NULL; + prev = this, this = this->next) + if (strcasecmp(this->type, type) == 0) { + if (prev == NULL) + first_callback = this->next; + else + prev->next = this->next; + + free(this); + break; + } } /* void cf_unregister */ -void cf_unregister_complex (const char *type) -{ - for (cf_complex_callback_t *prev = NULL, *this = complex_callback_head; - this != NULL; - prev = this, this = this->next) - if (strcasecmp (this->type, type) == 0) - { - if (prev == NULL) - complex_callback_head = this->next; - else - prev->next = this->next; - - sfree (this->type); - sfree (this); - break; - } +void cf_unregister_complex(const char *type) { + for (cf_complex_callback_t *prev = NULL, *this = complex_callback_head; + this != NULL; prev = this, this = this->next) + if (strcasecmp(this->type, type) == 0) { + if (prev == NULL) + complex_callback_head = this->next; + else + prev->next = this->next; + + sfree(this->type); + sfree(this); + break; + } } /* void cf_unregister */ -void cf_register (const char *type, - int (*callback) (const char *, const char *), - const char **keys, int keys_num) -{ - cf_callback_t *cf_cb; +void cf_register(const char *type, int (*callback)(const char *, const char *), + const char **keys, int keys_num) { + cf_callback_t *cf_cb; - /* Remove this module from the list, if it already exists */ - cf_unregister (type); + /* Remove this module from the list, if it already exists */ + cf_unregister(type); - /* This pointer will be free'd in `cf_unregister' */ - if ((cf_cb = malloc (sizeof (*cf_cb))) == NULL) - return; + /* This pointer will be free'd in `cf_unregister' */ + if ((cf_cb = malloc(sizeof(*cf_cb))) == NULL) + return; - cf_cb->type = type; - cf_cb->callback = callback; - cf_cb->keys = keys; - cf_cb->keys_num = keys_num; - cf_cb->ctx = plugin_get_ctx (); + cf_cb->type = type; + cf_cb->callback = callback; + cf_cb->keys = keys; + cf_cb->keys_num = keys_num; + cf_cb->ctx = plugin_get_ctx(); - cf_cb->next = first_callback; - first_callback = cf_cb; + cf_cb->next = first_callback; + first_callback = cf_cb; } /* void cf_register */ -int cf_register_complex (const char *type, int (*callback) (oconfig_item_t *)) -{ - cf_complex_callback_t *new; - - new = malloc (sizeof (*new)); - if (new == NULL) - return (-1); - - new->type = strdup (type); - if (new->type == NULL) - { - sfree (new); - return (-1); - } - - new->callback = callback; - new->next = NULL; - - new->ctx = plugin_get_ctx (); - - if (complex_callback_head == NULL) - { - complex_callback_head = new; - } - else - { - cf_complex_callback_t *last = complex_callback_head; - while (last->next != NULL) - last = last->next; - last->next = new; - } - - return (0); +int cf_register_complex(const char *type, int (*callback)(oconfig_item_t *)) { + cf_complex_callback_t *new; + + new = malloc(sizeof(*new)); + if (new == NULL) + return (-1); + + new->type = strdup(type); + if (new->type == NULL) { + sfree(new); + return (-1); + } + + new->callback = callback; + new->next = NULL; + + new->ctx = plugin_get_ctx(); + + if (complex_callback_head == NULL) { + complex_callback_head = new; + } else { + cf_complex_callback_t *last = complex_callback_head; + while (last->next != NULL) + last = last->next; + last->next = new; + } + + return (0); } /* int cf_register_complex */ -int cf_read (const char *filename) -{ - oconfig_item_t *conf; - int ret = 0; - - conf = cf_read_generic (filename, /* pattern = */ NULL, /* depth = */ 0); - if (conf == NULL) - { - ERROR ("Unable to read config file %s.", filename); - return (-1); - } - else if (conf->children_num == 0) - { - ERROR ("Configuration file %s is empty.", filename); - oconfig_free (conf); - return (-1); - } - - for (int i = 0; i < conf->children_num; i++) - { - if (conf->children[i].children == NULL) - { - if (dispatch_value (conf->children + i) != 0) - ret = -1; - } - else - { - if (dispatch_block (conf->children + i) != 0) - ret = -1; - } - } - - oconfig_free (conf); - - /* Read the default types.db if no `TypesDB' option was given. */ - if (cf_default_typesdb) - { - if (read_types_list (PKGDATADIR"/types.db") != 0) - ret = -1; - } - - return ret; +int cf_read(const char *filename) { + oconfig_item_t *conf; + int ret = 0; + + conf = cf_read_generic(filename, /* pattern = */ NULL, /* depth = */ 0); + if (conf == NULL) { + ERROR("Unable to read config file %s.", filename); + return (-1); + } else if (conf->children_num == 0) { + ERROR("Configuration file %s is empty.", filename); + oconfig_free(conf); + return (-1); + } + + for (int i = 0; i < conf->children_num; i++) { + if (conf->children[i].children == NULL) { + if (dispatch_value(conf->children + i) != 0) + ret = -1; + } else { + if (dispatch_block(conf->children + i) != 0) + ret = -1; + } + } + + oconfig_free(conf); + + /* Read the default types.db if no `TypesDB' option was given. */ + if (cf_default_typesdb) { + if (read_types_list(PKGDATADIR "/types.db") != 0) + ret = -1; + } + + return ret; } /* int cf_read */ /* Assures the config option is a string, duplicates it and returns the copy in * "ret_string". If necessary "*ret_string" is freed first. Returns zero upon * success. */ -int cf_util_get_string (const oconfig_item_t *ci, char **ret_string) /* {{{ */ +int cf_util_get_string(const oconfig_item_t *ci, char **ret_string) /* {{{ */ { - char *string; + char *string; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - ERROR ("cf_util_get_string: The %s option requires " - "exactly one string argument.", ci->key); - return (-1); - } + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + ERROR("cf_util_get_string: The %s option requires " + "exactly one string argument.", + ci->key); + return (-1); + } - string = strdup (ci->values[0].value.string); - if (string == NULL) - return (-1); + string = strdup(ci->values[0].value.string); + if (string == NULL) + return (-1); - if (*ret_string != NULL) - sfree (*ret_string); - *ret_string = string; + if (*ret_string != NULL) + sfree(*ret_string); + *ret_string = string; - return (0); + return (0); } /* }}} int cf_util_get_string */ /* Assures the config option is a string and copies it to the provided buffer. * Assures null-termination. */ -int cf_util_get_string_buffer (const oconfig_item_t *ci, char *buffer, /* {{{ */ - size_t buffer_size) -{ - if ((ci == NULL) || (buffer == NULL) || (buffer_size < 1)) - return (EINVAL); - - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - ERROR ("cf_util_get_string_buffer: The %s option requires " - "exactly one string argument.", ci->key); - return (-1); - } - - strncpy (buffer, ci->values[0].value.string, buffer_size); - buffer[buffer_size - 1] = 0; - - return (0); +int cf_util_get_string_buffer(const oconfig_item_t *ci, char *buffer, /* {{{ */ + size_t buffer_size) { + if ((ci == NULL) || (buffer == NULL) || (buffer_size < 1)) + return (EINVAL); + + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + ERROR("cf_util_get_string_buffer: The %s option requires " + "exactly one string argument.", + ci->key); + return (-1); + } + + strncpy(buffer, ci->values[0].value.string, buffer_size); + buffer[buffer_size - 1] = 0; + + return (0); } /* }}} int cf_util_get_string_buffer */ /* Assures the config option is a number and returns it as an int. */ -int cf_util_get_int (const oconfig_item_t *ci, int *ret_value) /* {{{ */ +int cf_util_get_int(const oconfig_item_t *ci, int *ret_value) /* {{{ */ { - if ((ci == NULL) || (ret_value == NULL)) - return (EINVAL); + if ((ci == NULL) || (ret_value == NULL)) + return (EINVAL); - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) - { - ERROR ("cf_util_get_int: The %s option requires " - "exactly one numeric argument.", ci->key); - return (-1); - } + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) { + ERROR("cf_util_get_int: The %s option requires " + "exactly one numeric argument.", + ci->key); + return (-1); + } - *ret_value = (int) ci->values[0].value.number; + *ret_value = (int)ci->values[0].value.number; - return (0); + return (0); } /* }}} int cf_util_get_int */ -int cf_util_get_double (const oconfig_item_t *ci, double *ret_value) /* {{{ */ +int cf_util_get_double(const oconfig_item_t *ci, double *ret_value) /* {{{ */ { - if ((ci == NULL) || (ret_value == NULL)) - return (EINVAL); + if ((ci == NULL) || (ret_value == NULL)) + return (EINVAL); - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) - { - ERROR ("cf_util_get_double: The %s option requires " - "exactly one numeric argument.", ci->key); - return (-1); - } + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) { + ERROR("cf_util_get_double: The %s option requires " + "exactly one numeric argument.", + ci->key); + return (-1); + } - *ret_value = ci->values[0].value.number; + *ret_value = ci->values[0].value.number; - return (0); + return (0); } /* }}} int cf_util_get_double */ -int cf_util_get_boolean (const oconfig_item_t *ci, _Bool *ret_bool) /* {{{ */ +int cf_util_get_boolean(const oconfig_item_t *ci, _Bool *ret_bool) /* {{{ */ { - if ((ci == NULL) || (ret_bool == NULL)) - return (EINVAL); + if ((ci == NULL) || (ret_bool == NULL)) + return (EINVAL); - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) - { - ERROR ("cf_util_get_boolean: The %s option requires " - "exactly one boolean argument.", ci->key); - return (-1); - } + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) { + ERROR("cf_util_get_boolean: The %s option requires " + "exactly one boolean argument.", + ci->key); + return (-1); + } - *ret_bool = ci->values[0].value.boolean ? 1 : 0; + *ret_bool = ci->values[0].value.boolean ? 1 : 0; - return (0); + return (0); } /* }}} int cf_util_get_boolean */ -int cf_util_get_flag (const oconfig_item_t *ci, /* {{{ */ - unsigned int *ret_value, unsigned int flag) -{ - int status; - _Bool b; - - if (ret_value == NULL) - return (EINVAL); - - b = 0; - status = cf_util_get_boolean (ci, &b); - if (status != 0) - return (status); - - if (b) - { - *ret_value |= flag; - } - else - { - *ret_value &= ~flag; - } - - return (0); +int cf_util_get_flag(const oconfig_item_t *ci, /* {{{ */ + unsigned int *ret_value, unsigned int flag) { + int status; + _Bool b; + + if (ret_value == NULL) + return (EINVAL); + + b = 0; + status = cf_util_get_boolean(ci, &b); + if (status != 0) + return (status); + + if (b) { + *ret_value |= flag; + } else { + *ret_value &= ~flag; + } + + return (0); } /* }}} int cf_util_get_flag */ /* Assures that the config option is a string or a number if the correct range @@ -1273,106 +1158,101 @@ int cf_util_get_flag (const oconfig_item_t *ci, /* {{{ */ * `service_name_to_port_number' and returned. * Returns the port number in the range [1-65535] or less than zero upon * failure. */ -int cf_util_get_port_number (const oconfig_item_t *ci) /* {{{ */ +int cf_util_get_port_number(const oconfig_item_t *ci) /* {{{ */ { - int tmp; - - if ((ci->values_num != 1) - || ((ci->values[0].type != OCONFIG_TYPE_STRING) - && (ci->values[0].type != OCONFIG_TYPE_NUMBER))) - { - ERROR ("cf_util_get_port_number: The \"%s\" option requires " - "exactly one string argument.", ci->key); - return (-1); - } - - if (ci->values[0].type == OCONFIG_TYPE_STRING) - return (service_name_to_port_number (ci->values[0].value.string)); - - assert (ci->values[0].type == OCONFIG_TYPE_NUMBER); - tmp = (int) (ci->values[0].value.number + 0.5); - if ((tmp < 1) || (tmp > 65535)) - { - ERROR ("cf_util_get_port_number: The \"%s\" option requires " - "a service name or a port number. The number " - "you specified, %i, is not in the valid " - "range of 1-65535.", - ci->key, tmp); - return (-1); - } - - return (tmp); + int tmp; + + if ((ci->values_num != 1) || ((ci->values[0].type != OCONFIG_TYPE_STRING) && + (ci->values[0].type != OCONFIG_TYPE_NUMBER))) { + ERROR("cf_util_get_port_number: The \"%s\" option requires " + "exactly one string argument.", + ci->key); + return (-1); + } + + if (ci->values[0].type == OCONFIG_TYPE_STRING) + return (service_name_to_port_number(ci->values[0].value.string)); + + assert(ci->values[0].type == OCONFIG_TYPE_NUMBER); + tmp = (int)(ci->values[0].value.number + 0.5); + if ((tmp < 1) || (tmp > 65535)) { + ERROR("cf_util_get_port_number: The \"%s\" option requires " + "a service name or a port number. The number " + "you specified, %i, is not in the valid " + "range of 1-65535.", + ci->key, tmp); + return (-1); + } + + return (tmp); } /* }}} int cf_util_get_port_number */ -int cf_util_get_service (const oconfig_item_t *ci, char **ret_string) /* {{{ */ +int cf_util_get_service(const oconfig_item_t *ci, char **ret_string) /* {{{ */ { - int port; - char *service; - int status; - - if (ci->values_num != 1) - { - ERROR ("cf_util_get_service: The %s option requires exactly " - "one argument.", ci->key); - return (-1); - } - - if (ci->values[0].type == OCONFIG_TYPE_STRING) - return (cf_util_get_string (ci, ret_string)); - if (ci->values[0].type != OCONFIG_TYPE_NUMBER) - { - ERROR ("cf_util_get_service: The %s option requires " - "exactly one string or numeric argument.", - ci->key); - } - - port = 0; - status = cf_util_get_int (ci, &port); - if (status != 0) - return (status); - else if ((port < 1) || (port > 65535)) - { - ERROR ("cf_util_get_service: The port number given " - "for the %s option is out of " - "range (%i).", ci->key, port); - return (-1); - } - - service = malloc (6); - if (service == NULL) - { - ERROR ("cf_util_get_service: Out of memory."); - return (-1); - } - ssnprintf (service, 6, "%i", port); - - sfree (*ret_string); - *ret_string = service; - - return (0); + int port; + char *service; + int status; + + if (ci->values_num != 1) { + ERROR("cf_util_get_service: The %s option requires exactly " + "one argument.", + ci->key); + return (-1); + } + + if (ci->values[0].type == OCONFIG_TYPE_STRING) + return (cf_util_get_string(ci, ret_string)); + if (ci->values[0].type != OCONFIG_TYPE_NUMBER) { + ERROR("cf_util_get_service: The %s option requires " + "exactly one string or numeric argument.", + ci->key); + } + + port = 0; + status = cf_util_get_int(ci, &port); + if (status != 0) + return (status); + else if ((port < 1) || (port > 65535)) { + ERROR("cf_util_get_service: The port number given " + "for the %s option is out of " + "range (%i).", + ci->key, port); + return (-1); + } + + service = malloc(6); + if (service == NULL) { + ERROR("cf_util_get_service: Out of memory."); + return (-1); + } + ssnprintf(service, 6, "%i", port); + + sfree(*ret_string); + *ret_string = service; + + return (0); } /* }}} int cf_util_get_service */ -int cf_util_get_cdtime (const oconfig_item_t *ci, cdtime_t *ret_value) /* {{{ */ +int cf_util_get_cdtime(const oconfig_item_t *ci, cdtime_t *ret_value) /* {{{ */ { - if ((ci == NULL) || (ret_value == NULL)) - return (EINVAL); - - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) - { - ERROR ("cf_util_get_cdtime: The %s option requires " - "exactly one numeric argument.", ci->key); - return (-1); - } - - if (ci->values[0].value.number < 0.0) - { - ERROR ("cf_util_get_cdtime: The numeric argument of the %s " - "option must not be negative.", ci->key); - return (-1); - } - - *ret_value = DOUBLE_TO_CDTIME_T (ci->values[0].value.number); - - return (0); + if ((ci == NULL) || (ret_value == NULL)) + return (EINVAL); + + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) { + ERROR("cf_util_get_cdtime: The %s option requires " + "exactly one numeric argument.", + ci->key); + return (-1); + } + + if (ci->values[0].value.number < 0.0) { + ERROR("cf_util_get_cdtime: The numeric argument of the %s " + "option must not be negative.", + ci->key); + return (-1); + } + + *ret_value = DOUBLE_TO_CDTIME_T(ci->values[0].value.number); + + return (0); } /* }}} int cf_util_get_cdtime */ - diff --git a/src/daemon/configfile.h b/src/daemon/configfile.h index a13bc09d..7cebb97e 100644 --- a/src/daemon/configfile.h +++ b/src/daemon/configfile.h @@ -29,8 +29,8 @@ #include "collectd.h" -#include "utils_time.h" #include "liboconfig/oconfig.h" +#include "utils_time.h" /* * DESCRIPTION @@ -40,8 +40,8 @@ * `type' Name of the plugin (must be the same as passed to * `plugin_register' */ -void cf_unregister (const char *type); -void cf_unregister_complex (const char *type); +void cf_unregister(const char *type); +void cf_unregister_complex(const char *type); /* * DESCRIPTION @@ -67,11 +67,10 @@ void cf_unregister_complex (const char *type); * exists for each `type' at any time. This means that `cf_register' may be * called multiple times, but only the last call will have an effect. */ -void cf_register (const char *type, - int (*callback) (const char *, const char *), - const char **keys, int keys_num); +void cf_register(const char *type, int (*callback)(const char *, const char *), + const char **keys, int keys_num); -int cf_register_complex (const char *type, int (*callback) (oconfig_item_t *)); +int cf_register_complex(const char *type, int (*callback)(oconfig_item_t *)); /* * DESCRIPTION @@ -88,54 +87,54 @@ int cf_register_complex (const char *type, int (*callback) (oconfig_item_t *)); * Returns zero upon success and non-zero otherwise. A error-message will have * been printed in this case. */ -int cf_read (const char *filename); +int cf_read(const char *filename); -int global_option_set (const char *option, const char *value, _Bool from_cli); -const char *global_option_get (const char *option); -long global_option_get_long (const char *option, long default_value); +int global_option_set(const char *option, const char *value, _Bool from_cli); +const char *global_option_get(const char *option); +long global_option_get_long(const char *option, long default_value); -cdtime_t global_option_get_time (char const *option, cdtime_t default_value); +cdtime_t global_option_get_time(char const *option, cdtime_t default_value); -cdtime_t cf_get_default_interval (void); +cdtime_t cf_get_default_interval(void); /* Assures the config option is a string, duplicates it and returns the copy in * "ret_string". If necessary "*ret_string" is freed first. Returns zero upon * success. */ -int cf_util_get_string (const oconfig_item_t *ci, char **ret_string); +int cf_util_get_string(const oconfig_item_t *ci, char **ret_string); /* Assures the config option is a string and copies it to the provided buffer. * Assures null-termination. */ -int cf_util_get_string_buffer (const oconfig_item_t *ci, char *buffer, - size_t buffer_size); +int cf_util_get_string_buffer(const oconfig_item_t *ci, char *buffer, + size_t buffer_size); /* Assures the config option is a number and returns it as an int. */ -int cf_util_get_int (const oconfig_item_t *ci, int *ret_value); +int cf_util_get_int(const oconfig_item_t *ci, int *ret_value); /* Assures the config option is a number and returns it as a double. */ -int cf_util_get_double (const oconfig_item_t *ci, double *ret_value); +int cf_util_get_double(const oconfig_item_t *ci, double *ret_value); /* Assures the config option is a boolean and assignes it to `ret_bool'. * Otherwise, `ret_bool' is not changed and non-zero is returned. */ -int cf_util_get_boolean (const oconfig_item_t *ci, _Bool *ret_bool); +int cf_util_get_boolean(const oconfig_item_t *ci, _Bool *ret_bool); /* Assures the config option is a boolean and set or unset the given flag in * `ret_value' as appropriate. Returns non-zero on error. */ -int cf_util_get_flag (const oconfig_item_t *ci, - unsigned int *ret_value, unsigned int flag); +int cf_util_get_flag(const oconfig_item_t *ci, unsigned int *ret_value, + unsigned int flag); /* Assures that the config option is a string or a number if the correct range * of 1-65535. The string is then converted to a port number using * `service_name_to_port_number' and returned. * Returns the port number in the range [1-65535] or less than zero upon * failure. */ -int cf_util_get_port_number (const oconfig_item_t *ci); +int cf_util_get_port_number(const oconfig_item_t *ci); /* Assures that the config option is either a service name (a string) or a port * number (an integer in the appropriate range) and returns a newly allocated * string. If ret_string points to a non-NULL pointer, it is freed before * assigning a new value. */ -int cf_util_get_service (const oconfig_item_t *ci, char **ret_string); +int cf_util_get_service(const oconfig_item_t *ci, char **ret_string); -int cf_util_get_cdtime (const oconfig_item_t *ci, cdtime_t *ret_value); +int cf_util_get_cdtime(const oconfig_item_t *ci, cdtime_t *ret_value); #endif /* defined(CONFIGFILE_H) */ diff --git a/src/daemon/filter_chain.c b/src/daemon/filter_chain.c index cee479a8..9c4a89c1 100644 --- a/src/daemon/filter_chain.c +++ b/src/daemon/filter_chain.c @@ -26,11 +26,11 @@ #include "collectd.h" +#include "common.h" #include "configfile.h" +#include "filter_chain.h" #include "plugin.h" #include "utils_complain.h" -#include "common.h" -#include "filter_chain.h" /* * Data types @@ -39,8 +39,7 @@ * variable. */ struct fc_match_s; typedef struct fc_match_s fc_match_t; /* {{{ */ -struct fc_match_s -{ +struct fc_match_s { char name[DATA_MAX_NAME_LEN]; match_proc_t proc; void *user_data; @@ -51,8 +50,7 @@ struct fc_match_s * variable. */ struct fc_target_s; typedef struct fc_target_s fc_target_t; /* {{{ */ -struct fc_target_s -{ +struct fc_target_s { char name[DATA_MAX_NAME_LEN]; void *user_data; target_proc_t proc; @@ -62,10 +60,9 @@ struct fc_target_s /* List of rules, used in fc_chain_t */ struct fc_rule_s; typedef struct fc_rule_s fc_rule_t; /* {{{ */ -struct fc_rule_s -{ +struct fc_rule_s { char name[DATA_MAX_NAME_LEN]; - fc_match_t *matches; + fc_match_t *matches; fc_target_t *targets; fc_rule_t *next; }; /* }}} */ @@ -74,16 +71,15 @@ struct fc_rule_s struct fc_chain_s /* {{{ */ { char name[DATA_MAX_NAME_LEN]; - fc_rule_t *rules; + fc_rule_t *rules; fc_target_t *targets; - fc_chain_t *next; + fc_chain_t *next; }; /* }}} */ /* Writer configuration. */ struct fc_writer_s; typedef struct fc_writer_s fc_writer_t; /* {{{ */ -struct fc_writer_s -{ +struct fc_writer_s { char *plugin; c_complain_t complaint; }; /* }}} */ @@ -91,82 +87,80 @@ struct fc_writer_s /* * Global variables */ -static fc_match_t *match_list_head; +static fc_match_t *match_list_head; static fc_target_t *target_list_head; -static fc_chain_t *chain_list_head; +static fc_chain_t *chain_list_head; /* * Private functions */ -static void fc_free_matches (fc_match_t *m) /* {{{ */ +static void fc_free_matches(fc_match_t *m) /* {{{ */ { if (m == NULL) return; if (m->proc.destroy != NULL) - (*m->proc.destroy) (&m->user_data); - else if (m->user_data != NULL) - { - ERROR ("Filter subsystem: fc_free_matches: There is user data, but no " - "destroy functions has been specified. " - "Memory will probably be lost!"); + (*m->proc.destroy)(&m->user_data); + else if (m->user_data != NULL) { + ERROR("Filter subsystem: fc_free_matches: There is user data, but no " + "destroy functions has been specified. " + "Memory will probably be lost!"); } if (m->next != NULL) - fc_free_matches (m->next); + fc_free_matches(m->next); - free (m); + free(m); } /* }}} void fc_free_matches */ -static void fc_free_targets (fc_target_t *t) /* {{{ */ +static void fc_free_targets(fc_target_t *t) /* {{{ */ { if (t == NULL) return; if (t->proc.destroy != NULL) - (*t->proc.destroy) (&t->user_data); - else if (t->user_data != NULL) - { - ERROR ("Filter subsystem: fc_free_targets: There is user data, but no " - "destroy functions has been specified. " - "Memory will probably be lost!"); + (*t->proc.destroy)(&t->user_data); + else if (t->user_data != NULL) { + ERROR("Filter subsystem: fc_free_targets: There is user data, but no " + "destroy functions has been specified. " + "Memory will probably be lost!"); } if (t->next != NULL) - fc_free_targets (t->next); + fc_free_targets(t->next); - free (t); + free(t); } /* }}} void fc_free_targets */ -static void fc_free_rules (fc_rule_t *r) /* {{{ */ +static void fc_free_rules(fc_rule_t *r) /* {{{ */ { if (r == NULL) return; - fc_free_matches (r->matches); - fc_free_targets (r->targets); + fc_free_matches(r->matches); + fc_free_targets(r->targets); if (r->next != NULL) - fc_free_rules (r->next); + fc_free_rules(r->next); - free (r); + free(r); } /* }}} void fc_free_rules */ -static void fc_free_chains (fc_chain_t *c) /* {{{ */ +static void fc_free_chains(fc_chain_t *c) /* {{{ */ { if (c == NULL) return; - fc_free_rules (c->rules); - fc_free_targets (c->targets); + fc_free_rules(c->rules); + fc_free_targets(c->targets); if (c->next != NULL) - fc_free_chains (c->next); + fc_free_chains(c->next); - free (c); + free(c); } /* }}} void fc_free_chains */ -static char *fc_strdup (const char *orig) /* {{{ */ +static char *fc_strdup(const char *orig) /* {{{ */ { size_t sz; char *dest; @@ -174,12 +168,12 @@ static char *fc_strdup (const char *orig) /* {{{ */ if (orig == NULL) return (NULL); - sz = strlen (orig) + 1; - dest = malloc (sz); + sz = strlen(orig) + 1; + dest = malloc(sz); if (dest == NULL) return (NULL); - memcpy (dest, orig, sz); + memcpy(dest, orig, sz); return (dest); } /* }}} char *fc_strdup */ @@ -205,198 +199,165 @@ static char *fc_strdup (const char *orig) /* {{{ */ * * */ -static int fc_config_add_match (fc_match_t **matches_head, /* {{{ */ - oconfig_item_t *ci) -{ +static int fc_config_add_match(fc_match_t **matches_head, /* {{{ */ + oconfig_item_t *ci) { fc_match_t *m; fc_match_t *ptr; int status; - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("Filter subsystem: `Match' blocks require " - "exactly one string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("Filter subsystem: `Match' blocks require " + "exactly one string argument."); return (-1); } ptr = match_list_head; - while (ptr != NULL) - { - if (strcasecmp (ptr->name, ci->values[0].value.string) == 0) + while (ptr != NULL) { + if (strcasecmp(ptr->name, ci->values[0].value.string) == 0) break; ptr = ptr->next; } - if (ptr == NULL) - { - WARNING ("Filter subsystem: Cannot find a \"%s\" match. " - "Did you load the appropriate plugin?", - ci->values[0].value.string); + if (ptr == NULL) { + WARNING("Filter subsystem: Cannot find a \"%s\" match. " + "Did you load the appropriate plugin?", + ci->values[0].value.string); return (-1); } - m = calloc (1, sizeof (*m)); - if (m == NULL) - { - ERROR ("fc_config_add_match: calloc failed."); + m = calloc(1, sizeof(*m)); + if (m == NULL) { + ERROR("fc_config_add_match: calloc failed."); return (-1); } - sstrncpy (m->name, ptr->name, sizeof (m->name)); - memcpy (&m->proc, &ptr->proc, sizeof (m->proc)); + sstrncpy(m->name, ptr->name, sizeof(m->name)); + memcpy(&m->proc, &ptr->proc, sizeof(m->proc)); m->user_data = NULL; m->next = NULL; - if (m->proc.create != NULL) - { - status = (*m->proc.create) (ci, &m->user_data); - if (status != 0) - { - WARNING ("Filter subsystem: Failed to create a %s match.", - m->name); - fc_free_matches (m); + if (m->proc.create != NULL) { + status = (*m->proc.create)(ci, &m->user_data); + if (status != 0) { + WARNING("Filter subsystem: Failed to create a %s match.", m->name); + fc_free_matches(m); return (-1); } } - if (*matches_head != NULL) - { + if (*matches_head != NULL) { ptr = *matches_head; while (ptr->next != NULL) ptr = ptr->next; ptr->next = m; - } - else - { + } else { *matches_head = m; } return (0); } /* }}} int fc_config_add_match */ -static int fc_config_add_target (fc_target_t **targets_head, /* {{{ */ - oconfig_item_t *ci) -{ +static int fc_config_add_target(fc_target_t **targets_head, /* {{{ */ + oconfig_item_t *ci) { fc_target_t *t; fc_target_t *ptr; int status; - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("Filter subsystem: `Target' blocks require " - "exactly one string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("Filter subsystem: `Target' blocks require " + "exactly one string argument."); return (-1); } ptr = target_list_head; - while (ptr != NULL) - { - if (strcasecmp (ptr->name, ci->values[0].value.string) == 0) + while (ptr != NULL) { + if (strcasecmp(ptr->name, ci->values[0].value.string) == 0) break; ptr = ptr->next; } - if (ptr == NULL) - { - WARNING ("Filter subsystem: Cannot find a \"%s\" target. " - "Did you load the appropriate plugin?", - ci->values[0].value.string); + if (ptr == NULL) { + WARNING("Filter subsystem: Cannot find a \"%s\" target. " + "Did you load the appropriate plugin?", + ci->values[0].value.string); return (-1); } - t = calloc (1, sizeof (*t)); - if (t == NULL) - { - ERROR ("fc_config_add_target: calloc failed."); + t = calloc(1, sizeof(*t)); + if (t == NULL) { + ERROR("fc_config_add_target: calloc failed."); return (-1); } - sstrncpy (t->name, ptr->name, sizeof (t->name)); - memcpy (&t->proc, &ptr->proc, sizeof (t->proc)); + sstrncpy(t->name, ptr->name, sizeof(t->name)); + memcpy(&t->proc, &ptr->proc, sizeof(t->proc)); t->user_data = NULL; t->next = NULL; - if (t->proc.create != NULL) - { - status = (*t->proc.create) (ci, &t->user_data); - if (status != 0) - { - WARNING ("Filter subsystem: Failed to create a %s target.", - t->name); - fc_free_targets (t); + if (t->proc.create != NULL) { + status = (*t->proc.create)(ci, &t->user_data); + if (status != 0) { + WARNING("Filter subsystem: Failed to create a %s target.", t->name); + fc_free_targets(t); return (-1); } - } - else - { + } else { t->user_data = NULL; } - if (*targets_head != NULL) - { + if (*targets_head != NULL) { ptr = *targets_head; while (ptr->next != NULL) ptr = ptr->next; ptr->next = t; - } - else - { + } else { *targets_head = t; } return (0); } /* }}} int fc_config_add_target */ -static int fc_config_add_rule (fc_chain_t *chain, /* {{{ */ - oconfig_item_t *ci) -{ +static int fc_config_add_rule(fc_chain_t *chain, /* {{{ */ + oconfig_item_t *ci) { fc_rule_t *rule; - char rule_name[2*DATA_MAX_NAME_LEN] = "Unnamed rule"; + char rule_name[2 * DATA_MAX_NAME_LEN] = "Unnamed rule"; int status = 0; - if (ci->values_num > 1) - { - WARNING ("Filter subsystem: `Rule' blocks have at most one argument."); + if (ci->values_num > 1) { + WARNING("Filter subsystem: `Rule' blocks have at most one argument."); return (-1); - } - else if ((ci->values_num == 1) - && (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("Filter subsystem: `Rule' blocks expect one string argument " - "or no argument at all."); + } else if ((ci->values_num == 1) && + (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("Filter subsystem: `Rule' blocks expect one string argument " + "or no argument at all."); return (-1); } - rule = calloc (1, sizeof (*rule)); - if (rule == NULL) - { - ERROR ("fc_config_add_rule: calloc failed."); + rule = calloc(1, sizeof(*rule)); + if (rule == NULL) { + ERROR("fc_config_add_rule: calloc failed."); return (-1); } - if (ci->values_num == 1) - { - sstrncpy (rule->name, ci->values[0].value.string, sizeof (rule->name)); - ssnprintf (rule_name, sizeof (rule_name), "Rule \"%s\"", - ci->values[0].value.string); + if (ci->values_num == 1) { + sstrncpy(rule->name, ci->values[0].value.string, sizeof(rule->name)); + ssnprintf(rule_name, sizeof(rule_name), "Rule \"%s\"", + ci->values[0].value.string); } - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; - if (strcasecmp ("Match", option->key) == 0) - status = fc_config_add_match (&rule->matches, option); - else if (strcasecmp ("Target", option->key) == 0) - status = fc_config_add_target (&rule->targets, option); - else - { - WARNING ("Filter subsystem: %s: Option `%s' not allowed " - "inside a block.", rule_name, option->key); + if (strcasecmp("Match", option->key) == 0) + status = fc_config_add_match(&rule->matches, option); + else if (strcasecmp("Target", option->key) == 0) + status = fc_config_add_target(&rule->targets, option); + else { + WARNING("Filter subsystem: %s: Option `%s' not allowed " + "inside a block.", + rule_name, option->key); status = -1; } @@ -405,12 +366,9 @@ static int fc_config_add_rule (fc_chain_t *chain, /* {{{ */ } /* for (ci->children) */ /* Additional sanity checking. */ - while (status == 0) - { - if (rule->targets == NULL) - { - WARNING ("Filter subsystem: %s: No target has been specified.", - rule_name); + while (status == 0) { + if (rule->targets == NULL) { + WARNING("Filter subsystem: %s: No target has been specified.", rule_name); status = -1; break; } @@ -418,14 +376,12 @@ static int fc_config_add_rule (fc_chain_t *chain, /* {{{ */ break; } /* while (status == 0) */ - if (status != 0) - { - fc_free_rules (rule); + if (status != 0) { + fc_free_rules(rule); return (-1); } - if (chain->rules != NULL) - { + if (chain->rules != NULL) { fc_rule_t *ptr; ptr = chain->rules; @@ -433,58 +389,50 @@ static int fc_config_add_rule (fc_chain_t *chain, /* {{{ */ ptr = ptr->next; ptr->next = rule; - } - else - { + } else { chain->rules = rule; } return (0); } /* }}} int fc_config_add_rule */ -static int fc_config_add_chain (const oconfig_item_t *ci) /* {{{ */ +static int fc_config_add_chain(const oconfig_item_t *ci) /* {{{ */ { fc_chain_t *chain = NULL; int status = 0; int new_chain = 1; - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("Filter subsystem: blocks require exactly one " - "string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("Filter subsystem: blocks require exactly one " + "string argument."); return (-1); } - if (chain_list_head != NULL) - { - if ((chain = fc_chain_get_by_name (ci->values[0].value.string)) != NULL) + if (chain_list_head != NULL) { + if ((chain = fc_chain_get_by_name(ci->values[0].value.string)) != NULL) new_chain = 0; } - if (chain == NULL) - { - chain = calloc (1, sizeof (*chain)); - if (chain == NULL) - { - ERROR ("fc_config_add_chain: calloc failed."); + if (chain == NULL) { + chain = calloc(1, sizeof(*chain)); + if (chain == NULL) { + ERROR("fc_config_add_chain: calloc failed."); return (-1); } - sstrncpy (chain->name, ci->values[0].value.string, sizeof (chain->name)); + sstrncpy(chain->name, ci->values[0].value.string, sizeof(chain->name)); } - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; - if (strcasecmp ("Rule", option->key) == 0) - status = fc_config_add_rule (chain, option); - else if (strcasecmp ("Target", option->key) == 0) - status = fc_config_add_target (&chain->targets, option); - else - { - WARNING ("Filter subsystem: Chain %s: Option `%s' not allowed " - "inside a block.", chain->name, option->key); + if (strcasecmp("Rule", option->key) == 0) + status = fc_config_add_rule(chain, option); + else if (strcasecmp("Target", option->key) == 0) + status = fc_config_add_target(&chain->targets, option); + else { + WARNING("Filter subsystem: Chain %s: Option `%s' not allowed " + "inside a block.", + chain->name, option->key); status = -1; } @@ -492,14 +440,12 @@ static int fc_config_add_chain (const oconfig_item_t *ci) /* {{{ */ break; } /* for (ci->children) */ - if (status != 0) - { - fc_free_chains (chain); + if (status != 0) { + fc_free_chains(chain); return (-1); } - if (chain_list_head != NULL) - { + if (chain_list_head != NULL) { if (!new_chain) return (0); @@ -510,9 +456,7 @@ static int fc_config_add_chain (const oconfig_item_t *ci) /* {{{ */ ptr = ptr->next; ptr->next = chain; - } - else - { + } else { chain_list_head = chain; } @@ -524,60 +468,55 @@ static int fc_config_add_chain (const oconfig_item_t *ci) /* {{{ */ * * Prefix `bit' like `_b_uilt-_i_n _t_arget' */ -static int fc_bit_jump_create (const oconfig_item_t *ci, /* {{{ */ - void **user_data) -{ +static int fc_bit_jump_create(const oconfig_item_t *ci, /* {{{ */ + void **user_data) { oconfig_item_t *ci_chain; - if (ci->children_num != 1) - { - ERROR ("Filter subsystem: The built-in target `jump' needs exactly " - "one `Chain' argument!"); + if (ci->children_num != 1) { + ERROR("Filter subsystem: The built-in target `jump' needs exactly " + "one `Chain' argument!"); return (-1); } ci_chain = ci->children; - if (strcasecmp ("Chain", ci_chain->key) != 0) - { - ERROR ("Filter subsystem: The built-in target `jump' does not " - "support the configuration option `%s'.", - ci_chain->key); + if (strcasecmp("Chain", ci_chain->key) != 0) { + ERROR("Filter subsystem: The built-in target `jump' does not " + "support the configuration option `%s'.", + ci_chain->key); return (-1); } - if ((ci_chain->values_num != 1) - || (ci_chain->values[0].type != OCONFIG_TYPE_STRING)) - { - ERROR ("Filter subsystem: Built-in target `jump': The `Chain' option " - "needs exactly one string argument."); + if ((ci_chain->values_num != 1) || + (ci_chain->values[0].type != OCONFIG_TYPE_STRING)) { + ERROR("Filter subsystem: Built-in target `jump': The `Chain' option " + "needs exactly one string argument."); return (-1); } - *user_data = fc_strdup (ci_chain->values[0].value.string); - if (*user_data == NULL) - { - ERROR ("fc_bit_jump_create: fc_strdup failed."); + *user_data = fc_strdup(ci_chain->values[0].value.string); + if (*user_data == NULL) { + ERROR("fc_bit_jump_create: fc_strdup failed."); return (-1); } return (0); } /* }}} int fc_bit_jump_create */ -static int fc_bit_jump_destroy (void **user_data) /* {{{ */ +static int fc_bit_jump_destroy(void **user_data) /* {{{ */ { - if (user_data != NULL) - { - free (*user_data); + if (user_data != NULL) { + free(*user_data); *user_data = NULL; } return (0); } /* }}} int fc_bit_jump_destroy */ -static int fc_bit_jump_invoke (const data_set_t *ds, /* {{{ */ - value_list_t *vl, notification_meta_t __attribute__((unused)) **meta, - void **user_data) -{ +static int fc_bit_jump_invoke(const data_set_t *ds, /* {{{ */ + value_list_t *vl, + notification_meta_t __attribute__((unused)) * + *meta, + void **user_data) { char *chain_name; fc_chain_t *chain; int status; @@ -585,17 +524,17 @@ static int fc_bit_jump_invoke (const data_set_t *ds, /* {{{ */ chain_name = *user_data; for (chain = chain_list_head; chain != NULL; chain = chain->next) - if (strcasecmp (chain_name, chain->name) == 0) + if (strcasecmp(chain_name, chain->name) == 0) break; - if (chain == NULL) - { - ERROR ("Filter subsystem: Built-in target `jump': There is no chain " - "named `%s'.", chain_name); + if (chain == NULL) { + ERROR("Filter subsystem: Built-in target `jump': There is no chain " + "named `%s'.", + chain_name); return (-1); } - status = fc_process_chain (ds, vl, chain); + status = fc_process_chain(ds, vl, chain); if (status < 0) return (status); else if (status == FC_TARGET_STOP) @@ -604,80 +543,73 @@ static int fc_bit_jump_invoke (const data_set_t *ds, /* {{{ */ return (FC_TARGET_CONTINUE); } /* }}} int fc_bit_jump_invoke */ -static int fc_bit_stop_invoke (const data_set_t __attribute__((unused)) *ds, /* {{{ */ - value_list_t __attribute__((unused)) *vl, - notification_meta_t __attribute__((unused)) **meta, - void __attribute__((unused)) **user_data) -{ +static int +fc_bit_stop_invoke(const data_set_t __attribute__((unused)) * ds, /* {{{ */ + value_list_t __attribute__((unused)) * vl, + notification_meta_t __attribute__((unused)) * *meta, + void __attribute__((unused)) * *user_data) { return (FC_TARGET_STOP); } /* }}} int fc_bit_stop_invoke */ -static int fc_bit_return_invoke (const data_set_t __attribute__((unused)) *ds, /* {{{ */ - value_list_t __attribute__((unused)) *vl, - notification_meta_t __attribute__((unused)) **meta, - void __attribute__((unused)) **user_data) -{ +static int +fc_bit_return_invoke(const data_set_t __attribute__((unused)) * ds, /* {{{ */ + value_list_t __attribute__((unused)) * vl, + notification_meta_t __attribute__((unused)) * *meta, + void __attribute__((unused)) * *user_data) { return (FC_TARGET_RETURN); } /* }}} int fc_bit_return_invoke */ -static int fc_bit_write_create (const oconfig_item_t *ci, /* {{{ */ - void **user_data) -{ +static int fc_bit_write_create(const oconfig_item_t *ci, /* {{{ */ + void **user_data) { fc_writer_t *plugin_list = NULL; size_t plugin_list_len = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; fc_writer_t *temp; - if (strcasecmp ("Plugin", child->key) != 0) - { - ERROR ("Filter subsystem: The built-in target `write' does not " - "support the configuration option `%s'.", - child->key); + if (strcasecmp("Plugin", child->key) != 0) { + ERROR("Filter subsystem: The built-in target `write' does not " + "support the configuration option `%s'.", + child->key); continue; } - for (int j = 0; j < child->values_num; j++) - { + for (int j = 0; j < child->values_num; j++) { char *plugin; - if (child->values[j].type != OCONFIG_TYPE_STRING) - { - ERROR ("Filter subsystem: Built-in target `write': " - "The `Plugin' option accepts only string arguments."); + if (child->values[j].type != OCONFIG_TYPE_STRING) { + ERROR("Filter subsystem: Built-in target `write': " + "The `Plugin' option accepts only string arguments."); continue; } plugin = child->values[j].value.string; - temp = realloc (plugin_list, (plugin_list_len + 2) - * (sizeof (*plugin_list))); - if (temp == NULL) - { - ERROR ("fc_bit_write_create: realloc failed."); + temp = + realloc(plugin_list, (plugin_list_len + 2) * (sizeof(*plugin_list))); + if (temp == NULL) { + ERROR("fc_bit_write_create: realloc failed."); continue; } plugin_list = temp; - plugin_list[plugin_list_len].plugin = fc_strdup (plugin); - if (plugin_list[plugin_list_len].plugin == NULL) - { - ERROR ("fc_bit_write_create: fc_strdup failed."); + plugin_list[plugin_list_len].plugin = fc_strdup(plugin); + if (plugin_list[plugin_list_len].plugin == NULL) { + ERROR("fc_bit_write_create: fc_strdup failed."); continue; } - C_COMPLAIN_INIT (&plugin_list[plugin_list_len].complaint); + C_COMPLAIN_INIT(&plugin_list[plugin_list_len].complaint); plugin_list_len++; plugin_list[plugin_list_len].plugin = NULL; } /* for (j = 0; j < child->values_num; j++) */ - } /* for (i = 0; i < ci->children_num; i++) */ + } /* for (i = 0; i < ci->children_num; i++) */ *user_data = plugin_list; return (0); } /* }}} int fc_bit_write_create */ -static int fc_bit_write_destroy (void **user_data) /* {{{ */ +static int fc_bit_write_destroy(void **user_data) /* {{{ */ { fc_writer_t *plugin_list; @@ -687,16 +619,17 @@ static int fc_bit_write_destroy (void **user_data) /* {{{ */ plugin_list = *user_data; for (size_t i = 0; plugin_list[i].plugin != NULL; i++) - free (plugin_list[i].plugin); - free (plugin_list); + free(plugin_list[i].plugin); + free(plugin_list); return (0); } /* }}} int fc_bit_write_destroy */ -static int fc_bit_write_invoke (const data_set_t *ds, /* {{{ */ - value_list_t *vl, notification_meta_t __attribute__((unused)) **meta, - void **user_data) -{ +static int fc_bit_write_invoke(const data_set_t *ds, /* {{{ */ + value_list_t *vl, + notification_meta_t __attribute__((unused)) * + *meta, + void **user_data) { fc_writer_t *plugin_list; int status; @@ -704,58 +637,53 @@ static int fc_bit_write_invoke (const data_set_t *ds, /* {{{ */ if (user_data != NULL) plugin_list = *user_data; - if ((plugin_list == NULL) || (plugin_list[0].plugin == NULL)) - { + if ((plugin_list == NULL) || (plugin_list[0].plugin == NULL)) { static c_complain_t write_complaint = C_COMPLAIN_INIT_STATIC; - status = plugin_write (/* plugin = */ NULL, ds, vl); - if (status == ENOENT) - { + status = plugin_write(/* plugin = */ NULL, ds, vl); + if (status == ENOENT) { /* in most cases this is a permanent error, so use the complain * mechanism rather than spamming the logs */ - c_complain (LOG_INFO, &write_complaint, + c_complain( + LOG_INFO, &write_complaint, "Filter subsystem: Built-in target `write': Dispatching value to " "all write plugins failed with status %i (ENOENT). " "Most likely this means you didn't load any write plugins.", status); - plugin_log_available_writers (); - } - else if (status != 0) - { + plugin_log_available_writers(); + } else if (status != 0) { /* often, this is a permanent error (e.g. target system unavailable), * so use the complain mechanism rather than spamming the logs */ - c_complain (LOG_INFO, &write_complaint, + c_complain( + LOG_INFO, &write_complaint, "Filter subsystem: Built-in target `write': Dispatching value to " - "all write plugins failed with status %i.", status); - } - else - { - assert (status == 0); - c_release (LOG_INFO, &write_complaint, "Filter subsystem: " - "Built-in target `write': Some write plugin is back to normal " - "operation. `write' succeeded."); + "all write plugins failed with status %i.", + status); + } else { + assert(status == 0); + c_release(LOG_INFO, &write_complaint, + "Filter subsystem: " + "Built-in target `write': Some write plugin is back to normal " + "operation. `write' succeeded."); } - } - else - { - for (size_t i = 0; plugin_list[i].plugin != NULL; i++) - { - status = plugin_write (plugin_list[i].plugin, ds, vl); - if (status != 0) - { - c_complain (LOG_INFO, &plugin_list[i].complaint, + } else { + for (size_t i = 0; plugin_list[i].plugin != NULL; i++) { + status = plugin_write(plugin_list[i].plugin, ds, vl); + if (status != 0) { + c_complain( + LOG_INFO, &plugin_list[i].complaint, "Filter subsystem: Built-in target `write': Dispatching value to " "the `%s' plugin failed with status %i.", plugin_list[i].plugin, status); - plugin_log_available_writers (); - } - else - { - c_release (LOG_INFO, &plugin_list[i].complaint, + plugin_log_available_writers(); + } else { + c_release( + LOG_INFO, &plugin_list[i].complaint, "Filter subsystem: Built-in target `write': Plugin `%s' is back " - "to normal operation. `write' succeeded.", plugin_list[i].plugin); + "to normal operation. `write' succeeded.", + plugin_list[i].plugin); } } /* for (i = 0; plugin_list[i] != NULL; i++) */ } @@ -763,36 +691,36 @@ static int fc_bit_write_invoke (const data_set_t *ds, /* {{{ */ return (FC_TARGET_CONTINUE); } /* }}} int fc_bit_write_invoke */ -static int fc_init_once (void) /* {{{ */ +static int fc_init_once(void) /* {{{ */ { static int done = 0; - target_proc_t tproc = { 0 }; + target_proc_t tproc = {0}; if (done != 0) return (0); - tproc.create = fc_bit_jump_create; + tproc.create = fc_bit_jump_create; tproc.destroy = fc_bit_jump_destroy; - tproc.invoke = fc_bit_jump_invoke; - fc_register_target ("jump", tproc); + tproc.invoke = fc_bit_jump_invoke; + fc_register_target("jump", tproc); - memset (&tproc, 0, sizeof (tproc)); - tproc.create = NULL; + memset(&tproc, 0, sizeof(tproc)); + tproc.create = NULL; tproc.destroy = NULL; - tproc.invoke = fc_bit_stop_invoke; - fc_register_target ("stop", tproc); + tproc.invoke = fc_bit_stop_invoke; + fc_register_target("stop", tproc); - memset (&tproc, 0, sizeof (tproc)); - tproc.create = NULL; + memset(&tproc, 0, sizeof(tproc)); + tproc.create = NULL; tproc.destroy = NULL; - tproc.invoke = fc_bit_return_invoke; - fc_register_target ("return", tproc); + tproc.invoke = fc_bit_return_invoke; + fc_register_target("return", tproc); - memset (&tproc, 0, sizeof (tproc)); - tproc.create = fc_bit_write_create; + memset(&tproc, 0, sizeof(tproc)); + tproc.create = fc_bit_write_create; tproc.destroy = fc_bit_write_destroy; - tproc.invoke = fc_bit_write_invoke; - fc_register_target ("write", tproc); + tproc.invoke = fc_bit_write_invoke; + fc_register_target("write", tproc); done++; return (0); @@ -802,25 +730,22 @@ static int fc_init_once (void) /* {{{ */ * Public functions */ /* Add a match to list of available matches. */ -int fc_register_match (const char *name, match_proc_t proc) /* {{{ */ +int fc_register_match(const char *name, match_proc_t proc) /* {{{ */ { fc_match_t *m; - DEBUG ("fc_register_match (%s);", name); + DEBUG("fc_register_match (%s);", name); - m = calloc (1, sizeof (*m)); + m = calloc(1, sizeof(*m)); if (m == NULL) return (-ENOMEM); - sstrncpy (m->name, name, sizeof (m->name)); - memcpy (&m->proc, &proc, sizeof (m->proc)); + sstrncpy(m->name, name, sizeof(m->name)); + memcpy(&m->proc, &proc, sizeof(m->proc)); - if (match_list_head == NULL) - { + if (match_list_head == NULL) { match_list_head = m; - } - else - { + } else { fc_match_t *ptr; ptr = match_list_head; @@ -834,25 +759,22 @@ int fc_register_match (const char *name, match_proc_t proc) /* {{{ */ } /* }}} int fc_register_match */ /* Add a target to list of available targets. */ -int fc_register_target (const char *name, target_proc_t proc) /* {{{ */ +int fc_register_target(const char *name, target_proc_t proc) /* {{{ */ { fc_target_t *t; - DEBUG ("fc_register_target (%s);", name); + DEBUG("fc_register_target (%s);", name); - t = calloc (1, sizeof (*t)); + t = calloc(1, sizeof(*t)); if (t == NULL) return (-ENOMEM); - sstrncpy (t->name, name, sizeof (t->name)); - memcpy (&t->proc, &proc, sizeof (t->proc)); + sstrncpy(t->name, name, sizeof(t->name)); + memcpy(&t->proc, &proc, sizeof(t->proc)); - if (target_list_head == NULL) - { + if (target_list_head == NULL) { target_list_head = t; - } - else - { + } else { fc_target_t *ptr; ptr = target_list_head; @@ -865,102 +787,88 @@ int fc_register_target (const char *name, target_proc_t proc) /* {{{ */ return (0); } /* }}} int fc_register_target */ -fc_chain_t *fc_chain_get_by_name (const char *chain_name) /* {{{ */ +fc_chain_t *fc_chain_get_by_name(const char *chain_name) /* {{{ */ { if (chain_name == NULL) return (NULL); for (fc_chain_t *chain = chain_list_head; chain != NULL; chain = chain->next) - if (strcasecmp (chain_name, chain->name) == 0) + if (strcasecmp(chain_name, chain->name) == 0) return (chain); return (NULL); } /* }}} int fc_chain_get_by_name */ -int fc_process_chain (const data_set_t *ds, value_list_t *vl, /* {{{ */ - fc_chain_t *chain) -{ +int fc_process_chain(const data_set_t *ds, value_list_t *vl, /* {{{ */ + fc_chain_t *chain) { fc_target_t *target; int status = FC_TARGET_CONTINUE; if (chain == NULL) return (-1); - DEBUG ("fc_process_chain (chain = %s);", chain->name); + DEBUG("fc_process_chain (chain = %s);", chain->name); - for (fc_rule_t *rule = chain->rules; rule != NULL; rule = rule->next) - { + for (fc_rule_t *rule = chain->rules; rule != NULL; rule = rule->next) { fc_match_t *match; status = FC_TARGET_CONTINUE; - if (rule->name[0] != 0) - { - DEBUG ("fc_process_chain (%s): Testing the `%s' rule.", - chain->name, rule->name); + if (rule->name[0] != 0) { + DEBUG("fc_process_chain (%s): Testing the `%s' rule.", chain->name, + rule->name); } /* N. B.: rule->matches may be NULL. */ - for (match = rule->matches; match != NULL; match = match->next) - { + for (match = rule->matches; match != NULL; match = match->next) { /* FIXME: Pass the meta-data to match targets here (when implemented). */ - status = (*match->proc.match) (ds, vl, /* meta = */ NULL, - &match->user_data); - if (status < 0) - { - WARNING ("fc_process_chain (%s): A match failed.", chain->name); + status = + (*match->proc.match)(ds, vl, /* meta = */ NULL, &match->user_data); + if (status < 0) { + WARNING("fc_process_chain (%s): A match failed.", chain->name); break; - } - else if (status != FC_MATCH_MATCHES) + } else if (status != FC_MATCH_MATCHES) break; } /* for-loop has been aborted: Either error or no match. */ - if (match != NULL) - { + if (match != NULL) { status = FC_TARGET_CONTINUE; continue; } - if (rule->name[0] != 0) - { - DEBUG ("fc_process_chain (%s): Rule `%s' matches.", - chain->name, rule->name); + if (rule->name[0] != 0) { + DEBUG("fc_process_chain (%s): Rule `%s' matches.", chain->name, + rule->name); } - for (target = rule->targets; target != NULL; target = target->next) - { + for (target = rule->targets; target != NULL; target = target->next) { /* If we get here, all matches have matched the value. Execute the * target. */ /* FIXME: Pass the meta-data to match targets here (when implemented). */ - status = (*target->proc.invoke) (ds, vl, /* meta = */ NULL, - &target->user_data); - if (status < 0) - { - WARNING ("fc_process_chain (%s): A target failed.", chain->name); + status = + (*target->proc.invoke)(ds, vl, /* meta = */ NULL, &target->user_data); + if (status < 0) { + WARNING("fc_process_chain (%s): A target failed.", chain->name); continue; - } - else if (status == FC_TARGET_CONTINUE) + } else if (status == FC_TARGET_CONTINUE) continue; else if (status == FC_TARGET_STOP) break; else if (status == FC_TARGET_RETURN) break; - else - { - WARNING ("fc_process_chain (%s): Unknown return value " - "from target `%s': %i", - chain->name, target->name, status); + else { + WARNING("fc_process_chain (%s): Unknown return value " + "from target `%s': %i", + chain->name, target->name, status); } } - if ((status == FC_TARGET_STOP) || (status == FC_TARGET_RETURN)) - { - if (rule->name[0] != 0) - { - DEBUG ("fc_process_chain (%s): Rule `%s' signaled " - "the %s condition.", - chain->name, rule->name, - (status == FC_TARGET_STOP) ? "stop" : "return"); + if ((status == FC_TARGET_STOP) || (status == FC_TARGET_RETURN)) { + if (rule->name[0] != 0) { + DEBUG("fc_process_chain (%s): Rule `%s' signaled " + "the %s condition.", + chain->name, rule->name, + (status == FC_TARGET_STOP) ? "stop" : "return"); } break; } @@ -969,77 +877,68 @@ int fc_process_chain (const data_set_t *ds, value_list_t *vl, /* {{{ */ if ((status == FC_TARGET_STOP) || (status == FC_TARGET_RETURN)) return (status); - DEBUG ("fc_process_chain (%s): Executing the default targets.", - chain->name); + DEBUG("fc_process_chain (%s): Executing the default targets.", chain->name); status = FC_TARGET_CONTINUE; - for (target = chain->targets; target != NULL; target = target->next) - { + for (target = chain->targets; target != NULL; target = target->next) { /* If we get here, all matches have matched the value. Execute the * target. */ /* FIXME: Pass the meta-data to match targets here (when implemented). */ - status = (*target->proc.invoke) (ds, vl, /* meta = */ NULL, - &target->user_data); - if (status < 0) - { - WARNING ("fc_process_chain (%s): The default target failed.", - chain->name); - } - else if (status == FC_TARGET_CONTINUE) + status = + (*target->proc.invoke)(ds, vl, /* meta = */ NULL, &target->user_data); + if (status < 0) { + WARNING("fc_process_chain (%s): The default target failed.", chain->name); + } else if (status == FC_TARGET_CONTINUE) continue; else if (status == FC_TARGET_STOP) break; else if (status == FC_TARGET_RETURN) break; - else - { - WARNING ("fc_process_chain (%s): Unknown return value " - "from target `%s': %i", - chain->name, target->name, status); + else { + WARNING("fc_process_chain (%s): Unknown return value " + "from target `%s': %i", + chain->name, target->name, status); } } - if ((status == FC_TARGET_STOP) - || (status == FC_TARGET_RETURN)) - { - assert (target != NULL); - DEBUG ("fc_process_chain (%s): Default target `%s' signaled " - "the %s condition.", - chain->name, target->name, - (status == FC_TARGET_STOP) ? "stop" : "return"); + if ((status == FC_TARGET_STOP) || (status == FC_TARGET_RETURN)) { + assert(target != NULL); + DEBUG("fc_process_chain (%s): Default target `%s' signaled " + "the %s condition.", + chain->name, target->name, + (status == FC_TARGET_STOP) ? "stop" : "return"); if (status == FC_TARGET_STOP) return (FC_TARGET_STOP); else return (FC_TARGET_CONTINUE); } - DEBUG ("fc_process_chain (%s): Signaling `continue' at end of chain.", - chain->name); + DEBUG("fc_process_chain (%s): Signaling `continue' at end of chain.", + chain->name); return (FC_TARGET_CONTINUE); } /* }}} int fc_process_chain */ /* Iterate over all rules in the chain and execute all targets for which all * matches match. */ -int fc_default_action (const data_set_t *ds, value_list_t *vl) /* {{{ */ +int fc_default_action(const data_set_t *ds, value_list_t *vl) /* {{{ */ { /* FIXME: Pass the meta-data to match targets here (when implemented). */ - return (fc_bit_write_invoke (ds, vl, - /* meta = */ NULL, /* user_data = */ NULL)); + return (fc_bit_write_invoke(ds, vl, + /* meta = */ NULL, /* user_data = */ NULL)); } /* }}} int fc_default_action */ -int fc_configure (const oconfig_item_t *ci) /* {{{ */ +int fc_configure(const oconfig_item_t *ci) /* {{{ */ { - fc_init_once (); + fc_init_once(); if (ci == NULL) return (-EINVAL); - if (strcasecmp ("Chain", ci->key) == 0) - return (fc_config_add_chain (ci)); + if (strcasecmp("Chain", ci->key) == 0) + return (fc_config_add_chain(ci)); - WARNING ("Filter subsystem: Unknown top level config option `%s'.", - ci->key); + WARNING("Filter subsystem: Unknown top level config option `%s'.", ci->key); return (-1); } /* }}} int fc_configure */ diff --git a/src/daemon/filter_chain.h b/src/daemon/filter_chain.h index 2d280f89..36ccbae9 100644 --- a/src/daemon/filter_chain.h +++ b/src/daemon/filter_chain.h @@ -31,43 +31,41 @@ #include "plugin.h" -#define FC_MATCH_NO_MATCH 0 -#define FC_MATCH_MATCHES 1 +#define FC_MATCH_NO_MATCH 0 +#define FC_MATCH_MATCHES 1 #define FC_TARGET_CONTINUE 0 -#define FC_TARGET_STOP 1 -#define FC_TARGET_RETURN 2 +#define FC_TARGET_STOP 1 +#define FC_TARGET_RETURN 2 /* * Match functions */ -struct match_proc_s -{ - int (*create) (const oconfig_item_t *ci, void **user_data); - int (*destroy) (void **user_data); - int (*match) (const data_set_t *ds, const value_list_t *vl, - notification_meta_t **meta, void **user_data); +struct match_proc_s { + int (*create)(const oconfig_item_t *ci, void **user_data); + int (*destroy)(void **user_data); + int (*match)(const data_set_t *ds, const value_list_t *vl, + notification_meta_t **meta, void **user_data); }; typedef struct match_proc_s match_proc_t; -int fc_register_match (const char *name, match_proc_t proc); +int fc_register_match(const char *name, match_proc_t proc); /* * Target functions */ -struct target_proc_s -{ - int (*create) (const oconfig_item_t *ci, void **user_data); - int (*destroy) (void **user_data); - int (*invoke) (const data_set_t *ds, value_list_t *vl, - notification_meta_t **meta, void **user_data); +struct target_proc_s { + int (*create)(const oconfig_item_t *ci, void **user_data); + int (*destroy)(void **user_data); + int (*invoke)(const data_set_t *ds, value_list_t *vl, + notification_meta_t **meta, void **user_data); }; typedef struct target_proc_s target_proc_t; struct fc_chain_s; typedef struct fc_chain_s fc_chain_t; -int fc_register_target (const char *name, target_proc_t proc); +int fc_register_target(const char *name, target_proc_t proc); /* * TODO: Chain management @@ -91,17 +89,16 @@ int fc_rule_delete (const char *chain_name, int position); /* * Processing function */ -fc_chain_t *fc_chain_get_by_name (const char *chain_name); +fc_chain_t *fc_chain_get_by_name(const char *chain_name); -int fc_process_chain (const data_set_t *ds, value_list_t *vl, - fc_chain_t *chain); +int fc_process_chain(const data_set_t *ds, value_list_t *vl, fc_chain_t *chain); -int fc_default_action (const data_set_t *ds, value_list_t *vl); +int fc_default_action(const data_set_t *ds, value_list_t *vl); /* * Shortcut for global configuration */ -int fc_configure (const oconfig_item_t *ci); +int fc_configure(const oconfig_item_t *ci); #endif /* FILTER_CHAIN_H */ /* vim: set sw=2 sts=2 et : */ diff --git a/src/daemon/meta_data.c b/src/daemon/meta_data.c index a11fccb2..583d8196 100644 --- a/src/daemon/meta_data.c +++ b/src/daemon/meta_data.c @@ -27,44 +27,41 @@ #include "collectd.h" #include "common.h" -#include "plugin.h" #include "meta_data.h" +#include "plugin.h" #define MD_MAX_NONSTRING_CHARS 128 /* * Data types */ -union meta_value_u -{ - char *mv_string; - int64_t mv_signed_int; +union meta_value_u { + char *mv_string; + int64_t mv_signed_int; uint64_t mv_unsigned_int; - double mv_double; - _Bool mv_boolean; + double mv_double; + _Bool mv_boolean; }; typedef union meta_value_u meta_value_t; struct meta_entry_s; typedef struct meta_entry_s meta_entry_t; -struct meta_entry_s -{ - char *key; - meta_value_t value; - int type; +struct meta_entry_s { + char *key; + meta_value_t value; + int type; meta_entry_t *next; }; -struct meta_data_s -{ - meta_entry_t *head; +struct meta_data_s { + meta_entry_t *head; pthread_mutex_t lock; }; /* * Private functions */ -static char *md_strdup (const char *orig) /* {{{ */ +static char *md_strdup(const char *orig) /* {{{ */ { size_t sz; char *dest; @@ -72,32 +69,30 @@ static char *md_strdup (const char *orig) /* {{{ */ if (orig == NULL) return (NULL); - sz = strlen (orig) + 1; - dest = malloc (sz); + sz = strlen(orig) + 1; + dest = malloc(sz); if (dest == NULL) return (NULL); - memcpy (dest, orig, sz); + memcpy(dest, orig, sz); return (dest); } /* }}} char *md_strdup */ -static meta_entry_t *md_entry_alloc (const char *key) /* {{{ */ +static meta_entry_t *md_entry_alloc(const char *key) /* {{{ */ { meta_entry_t *e; - e = calloc (1, sizeof (*e)); - if (e == NULL) - { - ERROR ("md_entry_alloc: calloc failed."); + e = calloc(1, sizeof(*e)); + if (e == NULL) { + ERROR("md_entry_alloc: calloc failed."); return (NULL); } - e->key = md_strdup (key); - if (e->key == NULL) - { - free (e); - ERROR ("md_entry_alloc: md_strdup failed."); + e->key = md_strdup(key); + if (e->key == NULL) { + free(e); + ERROR("md_entry_alloc: md_strdup failed."); return (NULL); } @@ -108,28 +103,29 @@ static meta_entry_t *md_entry_alloc (const char *key) /* {{{ */ } /* }}} meta_entry_t *md_entry_alloc */ /* XXX: The lock on md must be held while calling this function! */ -static meta_entry_t *md_entry_clone_contents (const meta_entry_t *orig) /* {{{ */ +static meta_entry_t *md_entry_clone_contents(const meta_entry_t *orig) /* {{{ */ { meta_entry_t *copy; /* WARNINGS : * - we do not check that orig != NULL here. You should have done it before. - * - we do not set copy->next. DO NOT FORGET TO SET copy->next IN YOUR FUNCTION + * - we do not set copy->next. DO NOT FORGET TO SET copy->next IN YOUR + * FUNCTION */ - copy = md_entry_alloc (orig->key); + copy = md_entry_alloc(orig->key); if (copy == NULL) return (NULL); copy->type = orig->type; if (copy->type == MD_TYPE_STRING) - copy->value.mv_string = strdup (orig->value.mv_string); + copy->value.mv_string = strdup(orig->value.mv_string); else copy->value = orig->value; return (copy); } /* }}} meta_entry_t *md_entry_clone_contents */ -static meta_entry_t *md_entry_clone (const meta_entry_t *orig) /* {{{ */ +static meta_entry_t *md_entry_clone(const meta_entry_t *orig) /* {{{ */ { meta_entry_t *copy; @@ -138,27 +134,27 @@ static meta_entry_t *md_entry_clone (const meta_entry_t *orig) /* {{{ */ copy = md_entry_clone_contents(orig); - copy->next = md_entry_clone (orig->next); + copy->next = md_entry_clone(orig->next); return (copy); } /* }}} meta_entry_t *md_entry_clone */ -static void md_entry_free (meta_entry_t *e) /* {{{ */ +static void md_entry_free(meta_entry_t *e) /* {{{ */ { if (e == NULL) return; - free (e->key); + free(e->key); if (e->type == MD_TYPE_STRING) - free (e->value.mv_string); + free(e->value.mv_string); if (e->next != NULL) - md_entry_free (e->next); + md_entry_free(e->next); - free (e); + free(e); } /* }}} void md_entry_free */ -static int md_entry_insert (meta_data_t *md, meta_entry_t *e) /* {{{ */ +static int md_entry_insert(meta_data_t *md, meta_entry_t *e) /* {{{ */ { meta_entry_t *this; meta_entry_t *prev; @@ -166,33 +162,29 @@ static int md_entry_insert (meta_data_t *md, meta_entry_t *e) /* {{{ */ if ((md == NULL) || (e == NULL)) return (-EINVAL); - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); prev = NULL; this = md->head; - while (this != NULL) - { - if (strcasecmp (e->key, this->key) == 0) + while (this != NULL) { + if (strcasecmp(e->key, this->key) == 0) break; prev = this; this = this->next; } - if (this == NULL) - { + if (this == NULL) { /* This key does not exist yet. */ if (md->head == NULL) md->head = e; - else - { - assert (prev != NULL); + else { + assert(prev != NULL); prev->next = e; } e->next = NULL; - } - else /* (this != NULL) */ + } else /* (this != NULL) */ { if (prev == NULL) md->head = e; @@ -202,26 +194,26 @@ static int md_entry_insert (meta_data_t *md, meta_entry_t *e) /* {{{ */ e->next = this->next; } - pthread_mutex_unlock (&md->lock); + pthread_mutex_unlock(&md->lock); - if (this != NULL) - { + if (this != NULL) { this->next = NULL; - md_entry_free (this); + md_entry_free(this); } return (0); } /* }}} int md_entry_insert */ /* XXX: The lock on md must be held while calling this function! */ -static int md_entry_insert_clone (meta_data_t *md, meta_entry_t *orig) /* {{{ */ +static int md_entry_insert_clone(meta_data_t *md, meta_entry_t *orig) /* {{{ */ { meta_entry_t *e; meta_entry_t *this; meta_entry_t *prev; /* WARNINGS : - * - we do not check that md and e != NULL here. You should have done it before. + * - we do not check that md and e != NULL here. You should have done it + * before. * - we do not use the lock. You should have set it before. */ @@ -229,29 +221,25 @@ static int md_entry_insert_clone (meta_data_t *md, meta_entry_t *orig) /* {{{ */ prev = NULL; this = md->head; - while (this != NULL) - { - if (strcasecmp (e->key, this->key) == 0) + while (this != NULL) { + if (strcasecmp(e->key, this->key) == 0) break; prev = this; this = this->next; } - if (this == NULL) - { + if (this == NULL) { /* This key does not exist yet. */ if (md->head == NULL) md->head = e; - else - { - assert (prev != NULL); + else { + assert(prev != NULL); prev->next = e; } e->next = NULL; - } - else /* (this != NULL) */ + } else /* (this != NULL) */ { if (prev == NULL) md->head = e; @@ -261,26 +249,24 @@ static int md_entry_insert_clone (meta_data_t *md, meta_entry_t *orig) /* {{{ */ e->next = this->next; } - if (this != NULL) - { + if (this != NULL) { this->next = NULL; - md_entry_free (this); + md_entry_free(this); } return (0); } /* }}} int md_entry_insert_clone */ /* XXX: The lock on md must be held while calling this function! */ -static meta_entry_t *md_entry_lookup (meta_data_t *md, /* {{{ */ - const char *key) -{ +static meta_entry_t *md_entry_lookup(meta_data_t *md, /* {{{ */ + const char *key) { meta_entry_t *e; if ((md == NULL) || (key == NULL)) return (NULL); for (e = md->head; e != NULL; e = e->next) - if (strcasecmp (key, e->key) == 0) + if (strcasecmp(key, e->key) == 0) break; return (e); @@ -300,125 +286,118 @@ static meta_entry_t *md_entry_lookup (meta_data_t *md, /* {{{ */ /* * Public functions */ -meta_data_t *meta_data_create (void) /* {{{ */ +meta_data_t *meta_data_create(void) /* {{{ */ { meta_data_t *md; - md = calloc (1, sizeof (*md)); - if (md == NULL) - { - ERROR ("meta_data_create: calloc failed."); + md = calloc(1, sizeof(*md)); + if (md == NULL) { + ERROR("meta_data_create: calloc failed."); return (NULL); } - pthread_mutex_init (&md->lock, /* attr = */ NULL); + pthread_mutex_init(&md->lock, /* attr = */ NULL); return (md); } /* }}} meta_data_t *meta_data_create */ -meta_data_t *meta_data_clone (meta_data_t *orig) /* {{{ */ +meta_data_t *meta_data_clone(meta_data_t *orig) /* {{{ */ { meta_data_t *copy; if (orig == NULL) return (NULL); - copy = meta_data_create (); + copy = meta_data_create(); if (copy == NULL) return (NULL); - pthread_mutex_lock (&orig->lock); - copy->head = md_entry_clone (orig->head); - pthread_mutex_unlock (&orig->lock); + pthread_mutex_lock(&orig->lock); + copy->head = md_entry_clone(orig->head); + pthread_mutex_unlock(&orig->lock); return (copy); } /* }}} meta_data_t *meta_data_clone */ -int meta_data_clone_merge (meta_data_t **dest, meta_data_t *orig) /* {{{ */ +int meta_data_clone_merge(meta_data_t **dest, meta_data_t *orig) /* {{{ */ { if (orig == NULL) return (0); if (*dest == NULL) { *dest = meta_data_clone(orig); - return(0); + return (0); } - pthread_mutex_lock (&orig->lock); - for (meta_entry_t *e=orig->head; e != NULL; e = e->next) - { + pthread_mutex_lock(&orig->lock); + for (meta_entry_t *e = orig->head; e != NULL; e = e->next) { md_entry_insert_clone((*dest), e); } - pthread_mutex_unlock (&orig->lock); + pthread_mutex_unlock(&orig->lock); return (0); } /* }}} int meta_data_clone_merge */ -void meta_data_destroy (meta_data_t *md) /* {{{ */ +void meta_data_destroy(meta_data_t *md) /* {{{ */ { if (md == NULL) return; - md_entry_free (md->head); - pthread_mutex_destroy (&md->lock); - free (md); + md_entry_free(md->head); + pthread_mutex_destroy(&md->lock); + free(md); } /* }}} void meta_data_destroy */ -int meta_data_exists (meta_data_t *md, const char *key) /* {{{ */ +int meta_data_exists(meta_data_t *md, const char *key) /* {{{ */ { if ((md == NULL) || (key == NULL)) return (-EINVAL); - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); - for (meta_entry_t *e = md->head; e != NULL; e = e->next) - { - if (strcasecmp (key, e->key) == 0) - { - pthread_mutex_unlock (&md->lock); + for (meta_entry_t *e = md->head; e != NULL; e = e->next) { + if (strcasecmp(key, e->key) == 0) { + pthread_mutex_unlock(&md->lock); return (1); } } - pthread_mutex_unlock (&md->lock); + pthread_mutex_unlock(&md->lock); return (0); } /* }}} int meta_data_exists */ -int meta_data_type (meta_data_t *md, const char *key) /* {{{ */ +int meta_data_type(meta_data_t *md, const char *key) /* {{{ */ { if ((md == NULL) || (key == NULL)) return -EINVAL; - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); - for (meta_entry_t *e = md->head; e != NULL; e = e->next) - { - if (strcasecmp (key, e->key) == 0) - { - pthread_mutex_unlock (&md->lock); + for (meta_entry_t *e = md->head; e != NULL; e = e->next) { + if (strcasecmp(key, e->key) == 0) { + pthread_mutex_unlock(&md->lock); return e->type; } } - pthread_mutex_unlock (&md->lock); + pthread_mutex_unlock(&md->lock); return 0; } /* }}} int meta_data_type */ -int meta_data_toc (meta_data_t *md, char ***toc) /* {{{ */ +int meta_data_toc(meta_data_t *md, char ***toc) /* {{{ */ { int i = 0, count = 0; if ((md == NULL) || (toc == NULL)) return -EINVAL; - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); for (meta_entry_t *e = md->head; e != NULL; e = e->next) ++count; - if (count == 0) - { - pthread_mutex_unlock (&md->lock); + if (count == 0) { + pthread_mutex_unlock(&md->lock); return (count); } @@ -426,11 +405,11 @@ int meta_data_toc (meta_data_t *md, char ***toc) /* {{{ */ for (meta_entry_t *e = md->head; e != NULL; e = e->next) (*toc)[i++] = strdup(e->key); - pthread_mutex_unlock (&md->lock); + pthread_mutex_unlock(&md->lock); return count; } /* }}} int meta_data_toc */ -int meta_data_delete (meta_data_t *md, const char *key) /* {{{ */ +int meta_data_delete(meta_data_t *md, const char *key) /* {{{ */ { meta_entry_t *this; meta_entry_t *prev; @@ -438,22 +417,20 @@ int meta_data_delete (meta_data_t *md, const char *key) /* {{{ */ if ((md == NULL) || (key == NULL)) return (-EINVAL); - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); prev = NULL; this = md->head; - while (this != NULL) - { - if (strcasecmp (key, this->key) == 0) + while (this != NULL) { + if (strcasecmp(key, this->key) == 0) break; prev = this; this = this->next; } - if (this == NULL) - { - pthread_mutex_unlock (&md->lock); + if (this == NULL) { + pthread_mutex_unlock(&md->lock); return (-ENOENT); } @@ -462,10 +439,10 @@ int meta_data_delete (meta_data_t *md, const char *key) /* {{{ */ else prev->next = this->next; - pthread_mutex_unlock (&md->lock); + pthread_mutex_unlock(&md->lock); this->next = NULL; - md_entry_free (this); + md_entry_free(this); return (0); } /* }}} int meta_data_delete */ @@ -473,321 +450,295 @@ int meta_data_delete (meta_data_t *md, const char *key) /* {{{ */ /* * Add functions */ -int meta_data_add_string (meta_data_t *md, /* {{{ */ - const char *key, const char *value) -{ +int meta_data_add_string(meta_data_t *md, /* {{{ */ + const char *key, const char *value) { meta_entry_t *e; if ((md == NULL) || (key == NULL) || (value == NULL)) return (-EINVAL); - e = md_entry_alloc (key); + e = md_entry_alloc(key); if (e == NULL) return (-ENOMEM); - e->value.mv_string = md_strdup (value); - if (e->value.mv_string == NULL) - { - ERROR ("meta_data_add_string: md_strdup failed."); - md_entry_free (e); + e->value.mv_string = md_strdup(value); + if (e->value.mv_string == NULL) { + ERROR("meta_data_add_string: md_strdup failed."); + md_entry_free(e); return (-ENOMEM); } e->type = MD_TYPE_STRING; - return (md_entry_insert (md, e)); + return (md_entry_insert(md, e)); } /* }}} int meta_data_add_string */ -int meta_data_add_signed_int (meta_data_t *md, /* {{{ */ - const char *key, int64_t value) -{ +int meta_data_add_signed_int(meta_data_t *md, /* {{{ */ + const char *key, int64_t value) { meta_entry_t *e; if ((md == NULL) || (key == NULL)) return (-EINVAL); - e = md_entry_alloc (key); + e = md_entry_alloc(key); if (e == NULL) return (-ENOMEM); e->value.mv_signed_int = value; e->type = MD_TYPE_SIGNED_INT; - return (md_entry_insert (md, e)); + return (md_entry_insert(md, e)); } /* }}} int meta_data_add_signed_int */ -int meta_data_add_unsigned_int (meta_data_t *md, /* {{{ */ - const char *key, uint64_t value) -{ +int meta_data_add_unsigned_int(meta_data_t *md, /* {{{ */ + const char *key, uint64_t value) { meta_entry_t *e; if ((md == NULL) || (key == NULL)) return (-EINVAL); - e = md_entry_alloc (key); + e = md_entry_alloc(key); if (e == NULL) return (-ENOMEM); e->value.mv_unsigned_int = value; e->type = MD_TYPE_UNSIGNED_INT; - return (md_entry_insert (md, e)); + return (md_entry_insert(md, e)); } /* }}} int meta_data_add_unsigned_int */ -int meta_data_add_double (meta_data_t *md, /* {{{ */ - const char *key, double value) -{ +int meta_data_add_double(meta_data_t *md, /* {{{ */ + const char *key, double value) { meta_entry_t *e; if ((md == NULL) || (key == NULL)) return (-EINVAL); - e = md_entry_alloc (key); + e = md_entry_alloc(key); if (e == NULL) return (-ENOMEM); e->value.mv_double = value; e->type = MD_TYPE_DOUBLE; - return (md_entry_insert (md, e)); + return (md_entry_insert(md, e)); } /* }}} int meta_data_add_double */ -int meta_data_add_boolean (meta_data_t *md, /* {{{ */ - const char *key, _Bool value) -{ +int meta_data_add_boolean(meta_data_t *md, /* {{{ */ + const char *key, _Bool value) { meta_entry_t *e; if ((md == NULL) || (key == NULL)) return (-EINVAL); - e = md_entry_alloc (key); + e = md_entry_alloc(key); if (e == NULL) return (-ENOMEM); e->value.mv_boolean = value; e->type = MD_TYPE_BOOLEAN; - return (md_entry_insert (md, e)); + return (md_entry_insert(md, e)); } /* }}} int meta_data_add_boolean */ /* * Get functions */ -int meta_data_get_string (meta_data_t *md, /* {{{ */ - const char *key, char **value) -{ +int meta_data_get_string(meta_data_t *md, /* {{{ */ + const char *key, char **value) { meta_entry_t *e; char *temp; if ((md == NULL) || (key == NULL) || (value == NULL)) return (-EINVAL); - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); - e = md_entry_lookup (md, key); - if (e == NULL) - { - pthread_mutex_unlock (&md->lock); + e = md_entry_lookup(md, key); + if (e == NULL) { + pthread_mutex_unlock(&md->lock); return (-ENOENT); } - if (e->type != MD_TYPE_STRING) - { - ERROR ("meta_data_get_string: Type mismatch for key `%s'", e->key); - pthread_mutex_unlock (&md->lock); + if (e->type != MD_TYPE_STRING) { + ERROR("meta_data_get_string: Type mismatch for key `%s'", e->key); + pthread_mutex_unlock(&md->lock); return (-ENOENT); } - temp = md_strdup (e->value.mv_string); - if (temp == NULL) - { - pthread_mutex_unlock (&md->lock); - ERROR ("meta_data_get_string: md_strdup failed."); + temp = md_strdup(e->value.mv_string); + if (temp == NULL) { + pthread_mutex_unlock(&md->lock); + ERROR("meta_data_get_string: md_strdup failed."); return (-ENOMEM); } - pthread_mutex_unlock (&md->lock); + pthread_mutex_unlock(&md->lock); *value = temp; return (0); } /* }}} int meta_data_get_string */ -int meta_data_get_signed_int (meta_data_t *md, /* {{{ */ - const char *key, int64_t *value) -{ +int meta_data_get_signed_int(meta_data_t *md, /* {{{ */ + const char *key, int64_t *value) { meta_entry_t *e; if ((md == NULL) || (key == NULL) || (value == NULL)) return (-EINVAL); - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); - e = md_entry_lookup (md, key); - if (e == NULL) - { - pthread_mutex_unlock (&md->lock); + e = md_entry_lookup(md, key); + if (e == NULL) { + pthread_mutex_unlock(&md->lock); return (-ENOENT); } - if (e->type != MD_TYPE_SIGNED_INT) - { - ERROR ("meta_data_get_signed_int: Type mismatch for key `%s'", e->key); - pthread_mutex_unlock (&md->lock); + if (e->type != MD_TYPE_SIGNED_INT) { + ERROR("meta_data_get_signed_int: Type mismatch for key `%s'", e->key); + pthread_mutex_unlock(&md->lock); return (-ENOENT); } *value = e->value.mv_signed_int; - pthread_mutex_unlock (&md->lock); + pthread_mutex_unlock(&md->lock); return (0); } /* }}} int meta_data_get_signed_int */ -int meta_data_get_unsigned_int (meta_data_t *md, /* {{{ */ - const char *key, uint64_t *value) -{ +int meta_data_get_unsigned_int(meta_data_t *md, /* {{{ */ + const char *key, uint64_t *value) { meta_entry_t *e; if ((md == NULL) || (key == NULL) || (value == NULL)) return (-EINVAL); - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); - e = md_entry_lookup (md, key); - if (e == NULL) - { - pthread_mutex_unlock (&md->lock); + e = md_entry_lookup(md, key); + if (e == NULL) { + pthread_mutex_unlock(&md->lock); return (-ENOENT); } - if (e->type != MD_TYPE_UNSIGNED_INT) - { - ERROR ("meta_data_get_unsigned_int: Type mismatch for key `%s'", e->key); - pthread_mutex_unlock (&md->lock); + if (e->type != MD_TYPE_UNSIGNED_INT) { + ERROR("meta_data_get_unsigned_int: Type mismatch for key `%s'", e->key); + pthread_mutex_unlock(&md->lock); return (-ENOENT); } *value = e->value.mv_unsigned_int; - pthread_mutex_unlock (&md->lock); + pthread_mutex_unlock(&md->lock); return (0); } /* }}} int meta_data_get_unsigned_int */ -int meta_data_get_double (meta_data_t *md, /* {{{ */ - const char *key, double *value) -{ +int meta_data_get_double(meta_data_t *md, /* {{{ */ + const char *key, double *value) { meta_entry_t *e; if ((md == NULL) || (key == NULL) || (value == NULL)) return (-EINVAL); - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); - e = md_entry_lookup (md, key); - if (e == NULL) - { - pthread_mutex_unlock (&md->lock); + e = md_entry_lookup(md, key); + if (e == NULL) { + pthread_mutex_unlock(&md->lock); return (-ENOENT); } - if (e->type != MD_TYPE_DOUBLE) - { - ERROR ("meta_data_get_double: Type mismatch for key `%s'", e->key); - pthread_mutex_unlock (&md->lock); + if (e->type != MD_TYPE_DOUBLE) { + ERROR("meta_data_get_double: Type mismatch for key `%s'", e->key); + pthread_mutex_unlock(&md->lock); return (-ENOENT); } *value = e->value.mv_double; - pthread_mutex_unlock (&md->lock); + pthread_mutex_unlock(&md->lock); return (0); } /* }}} int meta_data_get_double */ -int meta_data_get_boolean (meta_data_t *md, /* {{{ */ - const char *key, _Bool *value) -{ +int meta_data_get_boolean(meta_data_t *md, /* {{{ */ + const char *key, _Bool *value) { meta_entry_t *e; if ((md == NULL) || (key == NULL) || (value == NULL)) return (-EINVAL); - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); - e = md_entry_lookup (md, key); - if (e == NULL) - { - pthread_mutex_unlock (&md->lock); + e = md_entry_lookup(md, key); + if (e == NULL) { + pthread_mutex_unlock(&md->lock); return (-ENOENT); } - if (e->type != MD_TYPE_BOOLEAN) - { - ERROR ("meta_data_get_boolean: Type mismatch for key `%s'", e->key); - pthread_mutex_unlock (&md->lock); + if (e->type != MD_TYPE_BOOLEAN) { + ERROR("meta_data_get_boolean: Type mismatch for key `%s'", e->key); + pthread_mutex_unlock(&md->lock); return (-ENOENT); } *value = e->value.mv_boolean; - pthread_mutex_unlock (&md->lock); + pthread_mutex_unlock(&md->lock); return (0); } /* }}} int meta_data_get_boolean */ -int meta_data_as_string (meta_data_t *md, /* {{{ */ - const char *key, char **value) -{ +int meta_data_as_string(meta_data_t *md, /* {{{ */ + const char *key, char **value) { meta_entry_t *e; char *actual; - char buffer[MD_MAX_NONSTRING_CHARS]; /* For non-string types. */ + char buffer[MD_MAX_NONSTRING_CHARS]; /* For non-string types. */ char *temp; int type; if ((md == NULL) || (key == NULL) || (value == NULL)) return (-EINVAL); - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); - e = md_entry_lookup (md, key); - if (e == NULL) - { - pthread_mutex_unlock (&md->lock); + e = md_entry_lookup(md, key); + if (e == NULL) { + pthread_mutex_unlock(&md->lock); return (-ENOENT); } type = e->type; - switch (type) - { - case MD_TYPE_STRING: - actual = e->value.mv_string; - break; - case MD_TYPE_SIGNED_INT: - ssnprintf (buffer, sizeof (buffer), "%"PRIi64, e->value.mv_signed_int); - actual = buffer; - break; - case MD_TYPE_UNSIGNED_INT: - ssnprintf (buffer, sizeof (buffer), "%"PRIu64, e->value.mv_unsigned_int); - actual = buffer; - break; - case MD_TYPE_DOUBLE: - ssnprintf (buffer, sizeof (buffer), GAUGE_FORMAT, e->value.mv_double); - actual = buffer; - break; - case MD_TYPE_BOOLEAN: - actual = e->value.mv_boolean ? "true" : "false"; - break; - default: - pthread_mutex_unlock (&md->lock); - ERROR ("meta_data_as_string: unknown type %d for key `%s'", type, key); - return (-ENOENT); + switch (type) { + case MD_TYPE_STRING: + actual = e->value.mv_string; + break; + case MD_TYPE_SIGNED_INT: + ssnprintf(buffer, sizeof(buffer), "%" PRIi64, e->value.mv_signed_int); + actual = buffer; + break; + case MD_TYPE_UNSIGNED_INT: + ssnprintf(buffer, sizeof(buffer), "%" PRIu64, e->value.mv_unsigned_int); + actual = buffer; + break; + case MD_TYPE_DOUBLE: + ssnprintf(buffer, sizeof(buffer), GAUGE_FORMAT, e->value.mv_double); + actual = buffer; + break; + case MD_TYPE_BOOLEAN: + actual = e->value.mv_boolean ? "true" : "false"; + break; + default: + pthread_mutex_unlock(&md->lock); + ERROR("meta_data_as_string: unknown type %d for key `%s'", type, key); + return (-ENOENT); } - pthread_mutex_unlock (&md->lock); + pthread_mutex_unlock(&md->lock); - temp = md_strdup (actual); - if (temp == NULL) - { - pthread_mutex_unlock (&md->lock); - ERROR ("meta_data_as_string: md_strdup failed for key `%s'.", key); + temp = md_strdup(actual); + if (temp == NULL) { + pthread_mutex_unlock(&md->lock); + ERROR("meta_data_as_string: md_strdup failed for key `%s'.", key); return (-ENOMEM); } diff --git a/src/daemon/meta_data.h b/src/daemon/meta_data.h index f4a4f212..3ef33604 100644 --- a/src/daemon/meta_data.h +++ b/src/daemon/meta_data.h @@ -29,65 +29,44 @@ #include "collectd.h" - /* * Defines */ -#define MD_TYPE_STRING 1 -#define MD_TYPE_SIGNED_INT 2 +#define MD_TYPE_STRING 1 +#define MD_TYPE_SIGNED_INT 2 #define MD_TYPE_UNSIGNED_INT 3 -#define MD_TYPE_DOUBLE 4 -#define MD_TYPE_BOOLEAN 5 +#define MD_TYPE_DOUBLE 4 +#define MD_TYPE_BOOLEAN 5 struct meta_data_s; typedef struct meta_data_s meta_data_t; -meta_data_t *meta_data_create (void); -meta_data_t *meta_data_clone (meta_data_t *orig); -int meta_data_clone_merge (meta_data_t **dest, meta_data_t *orig); -void meta_data_destroy (meta_data_t *md); +meta_data_t *meta_data_create(void); +meta_data_t *meta_data_clone(meta_data_t *orig); +int meta_data_clone_merge(meta_data_t **dest, meta_data_t *orig); +void meta_data_destroy(meta_data_t *md); -int meta_data_exists (meta_data_t *md, const char *key); -int meta_data_type (meta_data_t *md, const char *key); -int meta_data_toc (meta_data_t *md, char ***toc); -int meta_data_delete (meta_data_t *md, const char *key); +int meta_data_exists(meta_data_t *md, const char *key); +int meta_data_type(meta_data_t *md, const char *key); +int meta_data_toc(meta_data_t *md, char ***toc); +int meta_data_delete(meta_data_t *md, const char *key); -int meta_data_add_string (meta_data_t *md, - const char *key, - const char *value); -int meta_data_add_signed_int (meta_data_t *md, - const char *key, - int64_t value); -int meta_data_add_unsigned_int (meta_data_t *md, - const char *key, - uint64_t value); -int meta_data_add_double (meta_data_t *md, - const char *key, - double value); -int meta_data_add_boolean (meta_data_t *md, - const char *key, - _Bool value); +int meta_data_add_string(meta_data_t *md, const char *key, const char *value); +int meta_data_add_signed_int(meta_data_t *md, const char *key, int64_t value); +int meta_data_add_unsigned_int(meta_data_t *md, const char *key, + uint64_t value); +int meta_data_add_double(meta_data_t *md, const char *key, double value); +int meta_data_add_boolean(meta_data_t *md, const char *key, _Bool value); -int meta_data_get_string (meta_data_t *md, - const char *key, - char **value); -int meta_data_get_signed_int (meta_data_t *md, - const char *key, - int64_t *value); -int meta_data_get_unsigned_int (meta_data_t *md, - const char *key, - uint64_t *value); -int meta_data_get_double (meta_data_t *md, - const char *key, - double *value); -int meta_data_get_boolean (meta_data_t *md, - const char *key, - _Bool *value); +int meta_data_get_string(meta_data_t *md, const char *key, char **value); +int meta_data_get_signed_int(meta_data_t *md, const char *key, int64_t *value); +int meta_data_get_unsigned_int(meta_data_t *md, const char *key, + uint64_t *value); +int meta_data_get_double(meta_data_t *md, const char *key, double *value); +int meta_data_get_boolean(meta_data_t *md, const char *key, _Bool *value); /* Returns the value as a string, regardless of the type. */ -int meta_data_as_string (meta_data_t *md, - const char *key, - char **value); +int meta_data_as_string(meta_data_t *md, const char *key, char **value); #endif /* META_DATA_H */ /* vim: set sw=2 sts=2 et : */ diff --git a/src/daemon/meta_data_test.c b/src/daemon/meta_data_test.c index 35cfe715..803c7454 100644 --- a/src/daemon/meta_data_test.c +++ b/src/daemon/meta_data_test.c @@ -27,11 +27,10 @@ #include "common.h" /* for STATIC_ARRAY_SIZE */ #include "collectd.h" -#include "testing.h" #include "meta_data.h" +#include "testing.h" -DEF_TEST(base) -{ +DEF_TEST(base) { meta_data_t *m; char *s; @@ -40,78 +39,77 @@ DEF_TEST(base) double d; _Bool b; - CHECK_NOT_NULL (m = meta_data_create ()); + CHECK_NOT_NULL(m = meta_data_create()); /* all of these are absent */ - OK(meta_data_get_string (m, "string", &s) != 0); - OK(meta_data_get_signed_int (m, "signed_int", &si) != 0); - OK(meta_data_get_unsigned_int (m, "unsigned_int", &ui) != 0); - OK(meta_data_get_double (m, "double", &d) != 0); - OK(meta_data_get_boolean (m, "boolean", &b) != 0); + OK(meta_data_get_string(m, "string", &s) != 0); + OK(meta_data_get_signed_int(m, "signed_int", &si) != 0); + OK(meta_data_get_unsigned_int(m, "unsigned_int", &ui) != 0); + OK(meta_data_get_double(m, "double", &d) != 0); + OK(meta_data_get_boolean(m, "boolean", &b) != 0); /* populate structure */ - CHECK_ZERO (meta_data_add_string (m, "string", "foobar")); - OK(meta_data_exists (m, "string")); - OK(meta_data_type (m, "string") == MD_TYPE_STRING); + CHECK_ZERO(meta_data_add_string(m, "string", "foobar")); + OK(meta_data_exists(m, "string")); + OK(meta_data_type(m, "string") == MD_TYPE_STRING); - CHECK_ZERO (meta_data_add_signed_int (m, "signed_int", -1)); - OK(meta_data_exists (m, "signed_int")); - OK(meta_data_type (m, "signed_int") == MD_TYPE_SIGNED_INT); + CHECK_ZERO(meta_data_add_signed_int(m, "signed_int", -1)); + OK(meta_data_exists(m, "signed_int")); + OK(meta_data_type(m, "signed_int") == MD_TYPE_SIGNED_INT); - CHECK_ZERO (meta_data_add_unsigned_int (m, "unsigned_int", 1)); - OK(meta_data_exists (m, "unsigned_int")); - OK(meta_data_type (m, "unsigned_int") == MD_TYPE_UNSIGNED_INT); + CHECK_ZERO(meta_data_add_unsigned_int(m, "unsigned_int", 1)); + OK(meta_data_exists(m, "unsigned_int")); + OK(meta_data_type(m, "unsigned_int") == MD_TYPE_UNSIGNED_INT); - CHECK_ZERO (meta_data_add_double (m, "double", 47.11)); - OK(meta_data_exists (m, "double")); - OK(meta_data_type (m, "double") == MD_TYPE_DOUBLE); + CHECK_ZERO(meta_data_add_double(m, "double", 47.11)); + OK(meta_data_exists(m, "double")); + OK(meta_data_type(m, "double") == MD_TYPE_DOUBLE); - CHECK_ZERO (meta_data_add_boolean (m, "boolean", 1)); - OK(meta_data_exists (m, "boolean")); - OK(meta_data_type (m, "boolean") == MD_TYPE_BOOLEAN); + CHECK_ZERO(meta_data_add_boolean(m, "boolean", 1)); + OK(meta_data_exists(m, "boolean")); + OK(meta_data_type(m, "boolean") == MD_TYPE_BOOLEAN); /* retrieve and check all values */ - CHECK_ZERO (meta_data_get_string (m, "string", &s)); - EXPECT_EQ_STR ("foobar", s); - sfree (s); + CHECK_ZERO(meta_data_get_string(m, "string", &s)); + EXPECT_EQ_STR("foobar", s); + sfree(s); - CHECK_ZERO (meta_data_get_signed_int (m, "signed_int", &si)); - EXPECT_EQ_INT (-1, (int) si); + CHECK_ZERO(meta_data_get_signed_int(m, "signed_int", &si)); + EXPECT_EQ_INT(-1, (int)si); - CHECK_ZERO (meta_data_get_unsigned_int (m, "unsigned_int", &ui)); - EXPECT_EQ_INT (1, (int) ui); + CHECK_ZERO(meta_data_get_unsigned_int(m, "unsigned_int", &ui)); + EXPECT_EQ_INT(1, (int)ui); - CHECK_ZERO (meta_data_get_double (m, "double", &d)); - EXPECT_EQ_DOUBLE (47.11, d); + CHECK_ZERO(meta_data_get_double(m, "double", &d)); + EXPECT_EQ_DOUBLE(47.11, d); - CHECK_ZERO (meta_data_get_boolean (m, "boolean", &b)); - OK1 (b, "b evaluates to true"); + CHECK_ZERO(meta_data_get_boolean(m, "boolean", &b)); + OK1(b, "b evaluates to true"); /* retrieving the wrong type always fails */ - EXPECT_EQ_INT (-2, meta_data_get_boolean (m, "string", &b)); - EXPECT_EQ_INT (-2, meta_data_get_string (m, "signed_int", &s)); - EXPECT_EQ_INT (-2, meta_data_get_string (m, "unsigned_int", &s)); - EXPECT_EQ_INT (-2, meta_data_get_string (m, "double", &s)); - EXPECT_EQ_INT (-2, meta_data_get_string (m, "boolean", &s)); + EXPECT_EQ_INT(-2, meta_data_get_boolean(m, "string", &b)); + EXPECT_EQ_INT(-2, meta_data_get_string(m, "signed_int", &s)); + EXPECT_EQ_INT(-2, meta_data_get_string(m, "unsigned_int", &s)); + EXPECT_EQ_INT(-2, meta_data_get_string(m, "double", &s)); + EXPECT_EQ_INT(-2, meta_data_get_string(m, "boolean", &s)); /* replace existing keys */ - CHECK_ZERO (meta_data_add_signed_int (m, "string", 666)); - OK(meta_data_type (m, "string") == MD_TYPE_SIGNED_INT); + CHECK_ZERO(meta_data_add_signed_int(m, "string", 666)); + OK(meta_data_type(m, "string") == MD_TYPE_SIGNED_INT); - CHECK_ZERO (meta_data_add_signed_int (m, "signed_int", 666)); - CHECK_ZERO (meta_data_get_signed_int (m, "signed_int", &si)); - EXPECT_EQ_INT (666, (int) si); + CHECK_ZERO(meta_data_add_signed_int(m, "signed_int", 666)); + CHECK_ZERO(meta_data_get_signed_int(m, "signed_int", &si)); + EXPECT_EQ_INT(666, (int)si); /* deleting keys */ - CHECK_ZERO (meta_data_delete (m, "signed_int")); - EXPECT_EQ_INT (-2, meta_data_delete (m, "doesnt exist")); + CHECK_ZERO(meta_data_delete(m, "signed_int")); + EXPECT_EQ_INT(-2, meta_data_delete(m, "doesnt exist")); - meta_data_destroy (m); + meta_data_destroy(m); return 0; } -int main (void) -{ +int main(void) { RUN_TEST(base); END_TEST; diff --git a/src/daemon/plugin.c b/src/daemon/plugin.c index d54abeea..f313f368 100644 --- a/src/daemon/plugin.c +++ b/src/daemon/plugin.c @@ -31,19 +31,19 @@ #include "collectd.h" #include "common.h" -#include "plugin.h" #include "configfile.h" #include "filter_chain.h" +#include "plugin.h" #include "utils_avltree.h" #include "utils_cache.h" #include "utils_complain.h" -#include "utils_llist.h" #include "utils_heap.h" -#include "utils_time.h" +#include "utils_llist.h" #include "utils_random.h" +#include "utils_time.h" #if HAVE_PTHREAD_NP_H -# include /* for pthread_set_name_np(3) */ +#include /* for pthread_set_name_np(3) */ #endif #include @@ -51,46 +51,43 @@ /* * Private structures */ -struct callback_func_s -{ - void *cf_callback; - user_data_t cf_udata; - plugin_ctx_t cf_ctx; +struct callback_func_s { + void *cf_callback; + user_data_t cf_udata; + plugin_ctx_t cf_ctx; }; typedef struct callback_func_s callback_func_t; -#define RF_SIMPLE 0 +#define RF_SIMPLE 0 #define RF_COMPLEX 1 -#define RF_REMOVE 65535 -struct read_func_s -{ - /* `read_func_t' "inherits" from `callback_func_t'. - * The `rf_super' member MUST be the first one in this structure! */ +#define RF_REMOVE 65535 +struct read_func_s { +/* `read_func_t' "inherits" from `callback_func_t'. + * The `rf_super' member MUST be the first one in this structure! */ #define rf_callback rf_super.cf_callback #define rf_udata rf_super.cf_udata #define rf_ctx rf_super.cf_ctx - callback_func_t rf_super; - char rf_group[DATA_MAX_NAME_LEN]; - char *rf_name; - int rf_type; - cdtime_t rf_interval; - cdtime_t rf_effective_interval; - cdtime_t rf_next_read; + callback_func_t rf_super; + char rf_group[DATA_MAX_NAME_LEN]; + char *rf_name; + int rf_type; + cdtime_t rf_interval; + cdtime_t rf_effective_interval; + cdtime_t rf_next_read; }; typedef struct read_func_s read_func_t; struct write_queue_s; typedef struct write_queue_s write_queue_t; -struct write_queue_s -{ - value_list_t *vl; - plugin_ctx_t ctx; - write_queue_t *next; +struct write_queue_s { + value_list_t *vl; + plugin_ctx_t ctx; + write_queue_t *next; }; struct flush_callback_s { - char *name; - cdtime_t timeout; + char *name; + cdtime_t timeout; }; typedef struct flush_callback_s flush_callback_t; @@ -115,304 +112,276 @@ static c_avl_tree_t *data_sets; static char *plugindir = NULL; #ifndef DEFAULT_MAX_READ_INTERVAL -# define DEFAULT_MAX_READ_INTERVAL TIME_T_TO_CDTIME_T_STATIC (86400) +#define DEFAULT_MAX_READ_INTERVAL TIME_T_TO_CDTIME_T_STATIC(86400) #endif -static c_heap_t *read_heap = NULL; -static llist_t *read_list; -static int read_loop = 1; +static c_heap_t *read_heap = NULL; +static llist_t *read_list; +static int read_loop = 1; static pthread_mutex_t read_lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t read_cond = PTHREAD_COND_INITIALIZER; -static pthread_t *read_threads = NULL; -static size_t read_threads_num = 0; -static cdtime_t max_read_interval = DEFAULT_MAX_READ_INTERVAL; - -static write_queue_t *write_queue_head; -static write_queue_t *write_queue_tail; -static long write_queue_length = 0; -static _Bool write_loop = 1; +static pthread_cond_t read_cond = PTHREAD_COND_INITIALIZER; +static pthread_t *read_threads = NULL; +static size_t read_threads_num = 0; +static cdtime_t max_read_interval = DEFAULT_MAX_READ_INTERVAL; + +static write_queue_t *write_queue_head; +static write_queue_t *write_queue_tail; +static long write_queue_length = 0; +static _Bool write_loop = 1; static pthread_mutex_t write_lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t write_cond = PTHREAD_COND_INITIALIZER; -static pthread_t *write_threads = NULL; -static size_t write_threads_num = 0; +static pthread_cond_t write_cond = PTHREAD_COND_INITIALIZER; +static pthread_t *write_threads = NULL; +static size_t write_threads_num = 0; -static pthread_key_t plugin_ctx_key; -static _Bool plugin_ctx_key_initialized = 0; +static pthread_key_t plugin_ctx_key; +static _Bool plugin_ctx_key_initialized = 0; -static long write_limit_high = 0; -static long write_limit_low = 0; +static long write_limit_high = 0; +static long write_limit_low = 0; -static derive_t stats_values_dropped = 0; -static _Bool record_statistics = 0; +static derive_t stats_values_dropped = 0; +static _Bool record_statistics = 0; /* * Static functions */ -static int plugin_dispatch_values_internal (value_list_t *vl); +static int plugin_dispatch_values_internal(value_list_t *vl); -static const char *plugin_get_dir (void) -{ - if (plugindir == NULL) - return (PLUGINDIR); - else - return (plugindir); +static const char *plugin_get_dir(void) { + if (plugindir == NULL) + return (PLUGINDIR); + else + return (plugindir); } -static void plugin_update_internal_statistics (void) { /* {{{ */ - - gauge_t copy_write_queue_length = (gauge_t) write_queue_length; - - /* Initialize `vl' */ - value_list_t vl = VALUE_LIST_INIT; - sstrncpy (vl.host, hostname_g, sizeof (vl.host)); - sstrncpy (vl.plugin, "collectd", sizeof (vl.plugin)); - - /* Write queue */ - sstrncpy (vl.plugin_instance, "write_queue", - sizeof (vl.plugin_instance)); - - /* Write queue : queue length */ - vl.values = &(value_t) { .gauge = copy_write_queue_length }; - vl.values_len = 1; - sstrncpy (vl.type, "queue_length", sizeof (vl.type)); - vl.type_instance[0] = 0; - plugin_dispatch_values (&vl); - - /* Write queue : Values dropped (queue length > low limit) */ - vl.values = &(value_t) { .gauge = (gauge_t) stats_values_dropped }; - vl.values_len = 1; - sstrncpy (vl.type, "derive", sizeof (vl.type)); - sstrncpy (vl.type_instance, "dropped", sizeof (vl.type_instance)); - plugin_dispatch_values (&vl); - - /* Cache */ - sstrncpy (vl.plugin_instance, "cache", - sizeof (vl.plugin_instance)); - - /* Cache : Nb entry in cache tree */ - vl.values = &(value_t) { .gauge = (gauge_t) uc_get_size() }; - vl.values_len = 1; - sstrncpy (vl.type, "cache_size", sizeof (vl.type)); - vl.type_instance[0] = 0; - plugin_dispatch_values (&vl); - - return; +static void plugin_update_internal_statistics(void) { /* {{{ */ + + gauge_t copy_write_queue_length = (gauge_t)write_queue_length; + + /* Initialize `vl' */ + value_list_t vl = VALUE_LIST_INIT; + sstrncpy(vl.host, hostname_g, sizeof(vl.host)); + sstrncpy(vl.plugin, "collectd", sizeof(vl.plugin)); + + /* Write queue */ + sstrncpy(vl.plugin_instance, "write_queue", sizeof(vl.plugin_instance)); + + /* Write queue : queue length */ + vl.values = &(value_t){.gauge = copy_write_queue_length}; + vl.values_len = 1; + sstrncpy(vl.type, "queue_length", sizeof(vl.type)); + vl.type_instance[0] = 0; + plugin_dispatch_values(&vl); + + /* Write queue : Values dropped (queue length > low limit) */ + vl.values = &(value_t){.gauge = (gauge_t)stats_values_dropped}; + vl.values_len = 1; + sstrncpy(vl.type, "derive", sizeof(vl.type)); + sstrncpy(vl.type_instance, "dropped", sizeof(vl.type_instance)); + plugin_dispatch_values(&vl); + + /* Cache */ + sstrncpy(vl.plugin_instance, "cache", sizeof(vl.plugin_instance)); + + /* Cache : Nb entry in cache tree */ + vl.values = &(value_t){.gauge = (gauge_t)uc_get_size()}; + vl.values_len = 1; + sstrncpy(vl.type, "cache_size", sizeof(vl.type)); + vl.type_instance[0] = 0; + plugin_dispatch_values(&vl); + + return; } /* }}} void plugin_update_internal_statistics */ -static void destroy_callback (callback_func_t *cf) /* {{{ */ +static void destroy_callback(callback_func_t *cf) /* {{{ */ { - if (cf == NULL) - return; - - if ((cf->cf_udata.data != NULL) && (cf->cf_udata.free_func != NULL)) - { - cf->cf_udata.free_func (cf->cf_udata.data); - cf->cf_udata.data = NULL; - cf->cf_udata.free_func = NULL; - } - sfree (cf); + if (cf == NULL) + return; + + if ((cf->cf_udata.data != NULL) && (cf->cf_udata.free_func != NULL)) { + cf->cf_udata.free_func(cf->cf_udata.data); + cf->cf_udata.data = NULL; + cf->cf_udata.free_func = NULL; + } + sfree(cf); } /* }}} void destroy_callback */ -static void destroy_all_callbacks (llist_t **list) /* {{{ */ +static void destroy_all_callbacks(llist_t **list) /* {{{ */ { - llentry_t *le; + llentry_t *le; - if (*list == NULL) - return; + if (*list == NULL) + return; - le = llist_head (*list); - while (le != NULL) - { - llentry_t *le_next; + le = llist_head(*list); + while (le != NULL) { + llentry_t *le_next; - le_next = le->next; + le_next = le->next; - sfree (le->key); - destroy_callback (le->value); - le->value = NULL; + sfree(le->key); + destroy_callback(le->value); + le->value = NULL; - le = le_next; - } + le = le_next; + } - llist_destroy (*list); - *list = NULL; + llist_destroy(*list); + *list = NULL; } /* }}} void destroy_all_callbacks */ -static void destroy_read_heap (void) /* {{{ */ +static void destroy_read_heap(void) /* {{{ */ { - if (read_heap == NULL) - return; - - while (42) - { - read_func_t *rf; - - rf = c_heap_get_root (read_heap); - if (rf == NULL) - break; - sfree (rf->rf_name); - destroy_callback ((callback_func_t *) rf); - } - - c_heap_destroy (read_heap); - read_heap = NULL; + if (read_heap == NULL) + return; + + while (42) { + read_func_t *rf; + + rf = c_heap_get_root(read_heap); + if (rf == NULL) + break; + sfree(rf->rf_name); + destroy_callback((callback_func_t *)rf); + } + + c_heap_destroy(read_heap); + read_heap = NULL; } /* }}} void destroy_read_heap */ -static int register_callback (llist_t **list, /* {{{ */ - const char *name, callback_func_t *cf) -{ - llentry_t *le; - char *key; - - if (*list == NULL) - { - *list = llist_create (); - if (*list == NULL) - { - ERROR ("plugin: register_callback: " - "llist_create failed."); - destroy_callback (cf); - return (-1); - } - } - - key = strdup (name); - if (key == NULL) - { - ERROR ("plugin: register_callback: strdup failed."); - destroy_callback (cf); - return (-1); - } - - le = llist_search (*list, name); - if (le == NULL) - { - le = llentry_create (key, cf); - if (le == NULL) - { - ERROR ("plugin: register_callback: " - "llentry_create failed."); - sfree (key); - destroy_callback (cf); - return (-1); - } - - llist_append (*list, le); - } - else - { - callback_func_t *old_cf; - - old_cf = le->value; - le->value = cf; - - WARNING ("plugin: register_callback: " - "a callback named `%s' already exists - " - "overwriting the old entry!", name); - - destroy_callback (old_cf); - sfree (key); - } - - return (0); +static int register_callback(llist_t **list, /* {{{ */ + const char *name, callback_func_t *cf) { + llentry_t *le; + char *key; + + if (*list == NULL) { + *list = llist_create(); + if (*list == NULL) { + ERROR("plugin: register_callback: " + "llist_create failed."); + destroy_callback(cf); + return (-1); + } + } + + key = strdup(name); + if (key == NULL) { + ERROR("plugin: register_callback: strdup failed."); + destroy_callback(cf); + return (-1); + } + + le = llist_search(*list, name); + if (le == NULL) { + le = llentry_create(key, cf); + if (le == NULL) { + ERROR("plugin: register_callback: " + "llentry_create failed."); + sfree(key); + destroy_callback(cf); + return (-1); + } + + llist_append(*list, le); + } else { + callback_func_t *old_cf; + + old_cf = le->value; + le->value = cf; + + WARNING("plugin: register_callback: " + "a callback named `%s' already exists - " + "overwriting the old entry!", + name); + + destroy_callback(old_cf); + sfree(key); + } + + return (0); } /* }}} int register_callback */ -static void log_list_callbacks (llist_t **list, /* {{{ */ - const char *comment) -{ - char *str; - int len; - int i; - llentry_t *le; - int n; - char **keys; - - n = llist_size(*list); - if (n == 0) - { - INFO("%s [none]", comment); - return; - } - - keys = calloc(n, sizeof(char*)); - - if (keys == NULL) - { - ERROR("%s: failed to allocate memory for list of callbacks", - comment); - - return; - } - - for (le = llist_head (*list), i = 0, len = 0; - le != NULL; - le = le->next, i++) - { - keys[i] = le->key; - len += strlen(le->key) + 6; - } - str = malloc(len + 10); - if (str == NULL) - { - ERROR("%s: failed to allocate memory for list of callbacks", - comment); - } - else - { - *str = '\0'; - strjoin(str, len, keys, n, "', '"); - INFO("%s ['%s']", comment, str); - sfree (str); - } - sfree (keys); +static void log_list_callbacks(llist_t **list, /* {{{ */ + const char *comment) { + char *str; + int len; + int i; + llentry_t *le; + int n; + char **keys; + + n = llist_size(*list); + if (n == 0) { + INFO("%s [none]", comment); + return; + } + + keys = calloc(n, sizeof(char *)); + + if (keys == NULL) { + ERROR("%s: failed to allocate memory for list of callbacks", comment); + + return; + } + + for (le = llist_head(*list), i = 0, len = 0; le != NULL; le = le->next, i++) { + keys[i] = le->key; + len += strlen(le->key) + 6; + } + str = malloc(len + 10); + if (str == NULL) { + ERROR("%s: failed to allocate memory for list of callbacks", comment); + } else { + *str = '\0'; + strjoin(str, len, keys, n, "', '"); + INFO("%s ['%s']", comment, str); + sfree(str); + } + sfree(keys); } /* }}} void log_list_callbacks */ -static int create_register_callback (llist_t **list, /* {{{ */ - const char *name, void *callback, user_data_t const *ud) -{ - callback_func_t *cf; - - cf = calloc (1, sizeof (*cf)); - if (cf == NULL) - { - ERROR ("plugin: create_register_callback: calloc failed."); - return (-1); - } - - cf->cf_callback = callback; - if (ud == NULL) - { - cf->cf_udata.data = NULL; - cf->cf_udata.free_func = NULL; - } - else - { - cf->cf_udata = *ud; - } - - cf->cf_ctx = plugin_get_ctx (); - - return (register_callback (list, name, cf)); +static int create_register_callback(llist_t **list, /* {{{ */ + const char *name, void *callback, + user_data_t const *ud) { + callback_func_t *cf; + + cf = calloc(1, sizeof(*cf)); + if (cf == NULL) { + ERROR("plugin: create_register_callback: calloc failed."); + return (-1); + } + + cf->cf_callback = callback; + if (ud == NULL) { + cf->cf_udata.data = NULL; + cf->cf_udata.free_func = NULL; + } else { + cf->cf_udata = *ud; + } + + cf->cf_ctx = plugin_get_ctx(); + + return (register_callback(list, name, cf)); } /* }}} int create_register_callback */ -static int plugin_unregister (llist_t *list, const char *name) /* {{{ */ +static int plugin_unregister(llist_t *list, const char *name) /* {{{ */ { - llentry_t *e; + llentry_t *e; - if (list == NULL) - return (-1); + if (list == NULL) + return (-1); - e = llist_search (list, name); - if (e == NULL) - return (-1); + e = llist_search(list, name); + if (e == NULL) + return (-1); - llist_remove (list, e); + llist_remove(list, e); - sfree (e->key); - destroy_callback (e->value); + sfree(e->key); + destroy_callback(e->value); - llentry_destroy (e); + llentry_destroy(e); - return (0); + return (0); } /* }}} int plugin_unregister */ /* @@ -420,1484 +389,1334 @@ static int plugin_unregister (llist_t *list, const char *name) /* {{{ */ * object, but it will bitch about a shared object not having a * ``module_register'' symbol.. */ -static int plugin_load_file (char *file, uint32_t flags) -{ - lt_dlhandle dlh; - void (*reg_handle) (void); +static int plugin_load_file(char *file, uint32_t flags) { + lt_dlhandle dlh; + void (*reg_handle)(void); - lt_dlinit (); - lt_dlerror (); /* clear errors */ + lt_dlinit(); + lt_dlerror(); /* clear errors */ #if LIBTOOL_VERSION == 2 - if (flags & PLUGIN_FLAGS_GLOBAL) { - lt_dladvise advise; - lt_dladvise_init(&advise); - lt_dladvise_global(&advise); - dlh = lt_dlopenadvise(file, advise); - lt_dladvise_destroy(&advise); - } else { - dlh = lt_dlopen (file); - } + if (flags & PLUGIN_FLAGS_GLOBAL) { + lt_dladvise advise; + lt_dladvise_init(&advise); + lt_dladvise_global(&advise); + dlh = lt_dlopenadvise(file, advise); + lt_dladvise_destroy(&advise); + } else { + dlh = lt_dlopen(file); + } #else /* if LIBTOOL_VERSION == 1 */ - if (flags & PLUGIN_FLAGS_GLOBAL) - WARNING ("plugin_load_file: The global flag is not supported, " - "libtool 2 is required for this."); - dlh = lt_dlopen (file); + if (flags & PLUGIN_FLAGS_GLOBAL) + WARNING("plugin_load_file: The global flag is not supported, " + "libtool 2 is required for this."); + dlh = lt_dlopen(file); #endif - if (dlh == NULL) - { - char errbuf[1024] = ""; - - ssnprintf (errbuf, sizeof (errbuf), - "lt_dlopen (\"%s\") failed: %s. " - "The most common cause for this problem is " - "missing dependencies. Use ldd(1) to check " - "the dependencies of the plugin " - "/ shared object.", - file, lt_dlerror ()); - - ERROR ("%s", errbuf); - /* Make sure this is printed to STDERR in any case, but also - * make sure it's printed only once. */ - if (list_log != NULL) - fprintf (stderr, "ERROR: %s\n", errbuf); - - return (1); - } - - if ((reg_handle = (void (*) (void)) lt_dlsym (dlh, "module_register")) == NULL) - { - WARNING ("Couldn't find symbol \"module_register\" in \"%s\": %s\n", - file, lt_dlerror ()); - lt_dlclose (dlh); - return (-1); - } - - (*reg_handle) (); - - return (0); + if (dlh == NULL) { + char errbuf[1024] = ""; + + ssnprintf(errbuf, sizeof(errbuf), + "lt_dlopen (\"%s\") failed: %s. " + "The most common cause for this problem is " + "missing dependencies. Use ldd(1) to check " + "the dependencies of the plugin " + "/ shared object.", + file, lt_dlerror()); + + ERROR("%s", errbuf); + /* Make sure this is printed to STDERR in any case, but also + * make sure it's printed only once. */ + if (list_log != NULL) + fprintf(stderr, "ERROR: %s\n", errbuf); + + return (1); + } + + if ((reg_handle = (void (*)(void))lt_dlsym(dlh, "module_register")) == NULL) { + WARNING("Couldn't find symbol \"module_register\" in \"%s\": %s\n", file, + lt_dlerror()); + lt_dlclose(dlh); + return (-1); + } + + (*reg_handle)(); + + return (0); } -static void *plugin_read_thread (void __attribute__((unused)) *args) -{ - while (read_loop != 0) - { - read_func_t *rf; - plugin_ctx_t old_ctx; - cdtime_t start; - cdtime_t now; - cdtime_t elapsed; - int status; - int rf_type; - int rc; - - /* Get the read function that needs to be read next. - * We don't need to hold "read_lock" for the heap, but we need - * to call c_heap_get_root() and pthread_cond_wait() in the - * same protected block. */ - pthread_mutex_lock (&read_lock); - rf = c_heap_get_root (read_heap); - if (rf == NULL) - { - pthread_cond_wait (&read_cond, &read_lock); - pthread_mutex_unlock (&read_lock); - continue; - } - pthread_mutex_unlock (&read_lock); - - if (rf->rf_interval == 0) - { - /* this should not happen, because the interval is set - * for each plugin when loading it - * XXX: issue a warning? */ - rf->rf_interval = plugin_get_interval (); - rf->rf_effective_interval = rf->rf_interval; - - rf->rf_next_read = cdtime (); - } - - /* sleep until this entry is due, - * using pthread_cond_timedwait */ - pthread_mutex_lock (&read_lock); - /* In pthread_cond_timedwait, spurious wakeups are possible - * (and really happen, at least on NetBSD with > 1 CPU), thus - * we need to re-evaluate the condition every time - * pthread_cond_timedwait returns. */ - rc = 0; - while ((read_loop != 0) - && (cdtime () < rf->rf_next_read) - && rc == 0) - { - rc = pthread_cond_timedwait (&read_cond, &read_lock, - &CDTIME_T_TO_TIMESPEC (rf->rf_next_read)); - } - - /* Must hold `read_lock' when accessing `rf->rf_type'. */ - rf_type = rf->rf_type; - pthread_mutex_unlock (&read_lock); - - /* Check if we're supposed to stop.. This may have interrupted - * the sleep, too. */ - if (read_loop == 0) - { - /* Insert `rf' again, so it can be free'd correctly */ - c_heap_insert (read_heap, rf); - break; - } - - /* The entry has been marked for deletion. The linked list - * entry has already been removed by `plugin_unregister_read'. - * All we have to do here is free the `read_func_t' and - * continue. */ - if (rf_type == RF_REMOVE) - { - DEBUG ("plugin_read_thread: Destroying the `%s' " - "callback.", rf->rf_name); - sfree (rf->rf_name); - destroy_callback ((callback_func_t *) rf); - rf = NULL; - continue; - } - - DEBUG ("plugin_read_thread: Handling `%s'.", rf->rf_name); - - start = cdtime (); - - old_ctx = plugin_set_ctx (rf->rf_ctx); - - if (rf_type == RF_SIMPLE) - { - int (*callback) (void); - - callback = rf->rf_callback; - status = (*callback) (); - } - else - { - plugin_read_cb callback; - - assert (rf_type == RF_COMPLEX); - - callback = rf->rf_callback; - status = (*callback) (&rf->rf_udata); - } - - plugin_set_ctx (old_ctx); - - /* If the function signals failure, we will increase the - * intervals in which it will be called. */ - if (status != 0) - { - rf->rf_effective_interval *= 2; - if (rf->rf_effective_interval > max_read_interval) - rf->rf_effective_interval = max_read_interval; - - NOTICE ("read-function of plugin `%s' failed. " - "Will suspend it for %.3f seconds.", - rf->rf_name, - CDTIME_T_TO_DOUBLE (rf->rf_effective_interval)); - } - else - { - /* Success: Restore the interval, if it was changed. */ - rf->rf_effective_interval = rf->rf_interval; - } - - /* update the ``next read due'' field */ - now = cdtime (); - - /* calculate the time spent in the read function */ - elapsed = (now - start); - - if (elapsed > rf->rf_effective_interval) - WARNING ("plugin_read_thread: read-function of the `%s' plugin took %.3f " - "seconds, which is above its read interval (%.3f seconds). You might " - "want to adjust the `Interval' or `ReadThreads' settings.", - rf->rf_name, CDTIME_T_TO_DOUBLE(elapsed), - CDTIME_T_TO_DOUBLE(rf->rf_effective_interval)); - - DEBUG ("plugin_read_thread: read-function of the `%s' plugin took " - "%.6f seconds.", - rf->rf_name, CDTIME_T_TO_DOUBLE(elapsed)); - - DEBUG ("plugin_read_thread: Effective interval of the " - "`%s' plugin is %.3f seconds.", - rf->rf_name, - CDTIME_T_TO_DOUBLE (rf->rf_effective_interval)); - - /* Calculate the next (absolute) time at which this function - * should be called. */ - rf->rf_next_read += rf->rf_effective_interval; - - /* Check, if `rf_next_read' is in the past. */ - if (rf->rf_next_read < now) - { - /* `rf_next_read' is in the past. Insert `now' - * so this value doesn't trail off into the - * past too much. */ - rf->rf_next_read = now; - } - - DEBUG ("plugin_read_thread: Next read of the `%s' plugin at %.3f.", - rf->rf_name, - CDTIME_T_TO_DOUBLE (rf->rf_next_read)); - - /* Re-insert this read function into the heap again. */ - c_heap_insert (read_heap, rf); - } /* while (read_loop) */ - - pthread_exit (NULL); - return ((void *) 0); +static void *plugin_read_thread(void __attribute__((unused)) * args) { + while (read_loop != 0) { + read_func_t *rf; + plugin_ctx_t old_ctx; + cdtime_t start; + cdtime_t now; + cdtime_t elapsed; + int status; + int rf_type; + int rc; + + /* Get the read function that needs to be read next. + * We don't need to hold "read_lock" for the heap, but we need + * to call c_heap_get_root() and pthread_cond_wait() in the + * same protected block. */ + pthread_mutex_lock(&read_lock); + rf = c_heap_get_root(read_heap); + if (rf == NULL) { + pthread_cond_wait(&read_cond, &read_lock); + pthread_mutex_unlock(&read_lock); + continue; + } + pthread_mutex_unlock(&read_lock); + + if (rf->rf_interval == 0) { + /* this should not happen, because the interval is set + * for each plugin when loading it + * XXX: issue a warning? */ + rf->rf_interval = plugin_get_interval(); + rf->rf_effective_interval = rf->rf_interval; + + rf->rf_next_read = cdtime(); + } + + /* sleep until this entry is due, + * using pthread_cond_timedwait */ + pthread_mutex_lock(&read_lock); + /* In pthread_cond_timedwait, spurious wakeups are possible + * (and really happen, at least on NetBSD with > 1 CPU), thus + * we need to re-evaluate the condition every time + * pthread_cond_timedwait returns. */ + rc = 0; + while ((read_loop != 0) && (cdtime() < rf->rf_next_read) && rc == 0) { + rc = pthread_cond_timedwait(&read_cond, &read_lock, + &CDTIME_T_TO_TIMESPEC(rf->rf_next_read)); + } + + /* Must hold `read_lock' when accessing `rf->rf_type'. */ + rf_type = rf->rf_type; + pthread_mutex_unlock(&read_lock); + + /* Check if we're supposed to stop.. This may have interrupted + * the sleep, too. */ + if (read_loop == 0) { + /* Insert `rf' again, so it can be free'd correctly */ + c_heap_insert(read_heap, rf); + break; + } + + /* The entry has been marked for deletion. The linked list + * entry has already been removed by `plugin_unregister_read'. + * All we have to do here is free the `read_func_t' and + * continue. */ + if (rf_type == RF_REMOVE) { + DEBUG("plugin_read_thread: Destroying the `%s' " + "callback.", + rf->rf_name); + sfree(rf->rf_name); + destroy_callback((callback_func_t *)rf); + rf = NULL; + continue; + } + + DEBUG("plugin_read_thread: Handling `%s'.", rf->rf_name); + + start = cdtime(); + + old_ctx = plugin_set_ctx(rf->rf_ctx); + + if (rf_type == RF_SIMPLE) { + int (*callback)(void); + + callback = rf->rf_callback; + status = (*callback)(); + } else { + plugin_read_cb callback; + + assert(rf_type == RF_COMPLEX); + + callback = rf->rf_callback; + status = (*callback)(&rf->rf_udata); + } + + plugin_set_ctx(old_ctx); + + /* If the function signals failure, we will increase the + * intervals in which it will be called. */ + if (status != 0) { + rf->rf_effective_interval *= 2; + if (rf->rf_effective_interval > max_read_interval) + rf->rf_effective_interval = max_read_interval; + + NOTICE("read-function of plugin `%s' failed. " + "Will suspend it for %.3f seconds.", + rf->rf_name, CDTIME_T_TO_DOUBLE(rf->rf_effective_interval)); + } else { + /* Success: Restore the interval, if it was changed. */ + rf->rf_effective_interval = rf->rf_interval; + } + + /* update the ``next read due'' field */ + now = cdtime(); + + /* calculate the time spent in the read function */ + elapsed = (now - start); + + if (elapsed > rf->rf_effective_interval) + WARNING( + "plugin_read_thread: read-function of the `%s' plugin took %.3f " + "seconds, which is above its read interval (%.3f seconds). You might " + "want to adjust the `Interval' or `ReadThreads' settings.", + rf->rf_name, CDTIME_T_TO_DOUBLE(elapsed), + CDTIME_T_TO_DOUBLE(rf->rf_effective_interval)); + + DEBUG("plugin_read_thread: read-function of the `%s' plugin took " + "%.6f seconds.", + rf->rf_name, CDTIME_T_TO_DOUBLE(elapsed)); + + DEBUG("plugin_read_thread: Effective interval of the " + "`%s' plugin is %.3f seconds.", + rf->rf_name, CDTIME_T_TO_DOUBLE(rf->rf_effective_interval)); + + /* Calculate the next (absolute) time at which this function + * should be called. */ + rf->rf_next_read += rf->rf_effective_interval; + + /* Check, if `rf_next_read' is in the past. */ + if (rf->rf_next_read < now) { + /* `rf_next_read' is in the past. Insert `now' + * so this value doesn't trail off into the + * past too much. */ + rf->rf_next_read = now; + } + + DEBUG("plugin_read_thread: Next read of the `%s' plugin at %.3f.", + rf->rf_name, CDTIME_T_TO_DOUBLE(rf->rf_next_read)); + + /* Re-insert this read function into the heap again. */ + c_heap_insert(read_heap, rf); + } /* while (read_loop) */ + + pthread_exit(NULL); + return ((void *)0); } /* void *plugin_read_thread */ #ifdef PTHREAD_MAX_NAMELEN_NP -# define THREAD_NAME_MAX PTHREAD_MAX_NAMELEN_NP +#define THREAD_NAME_MAX PTHREAD_MAX_NAMELEN_NP #else -# define THREAD_NAME_MAX 16 +#define THREAD_NAME_MAX 16 #endif static void set_thread_name(pthread_t tid, char const *name) { #if defined(HAVE_PTHREAD_SETNAME_NP) || defined(HAVE_PTHREAD_SET_NAME_NP) - /* glibc limits the length of the name and fails if the passed string - * is too long, so we truncate it here. */ - char n[THREAD_NAME_MAX]; - if (strlen (name) >= THREAD_NAME_MAX) - WARNING("set_thread_name(\"%s\"): name too long", name); - sstrncpy (n, name, sizeof(n)); + /* glibc limits the length of the name and fails if the passed string + * is too long, so we truncate it here. */ + char n[THREAD_NAME_MAX]; + if (strlen(name) >= THREAD_NAME_MAX) + WARNING("set_thread_name(\"%s\"): name too long", name); + sstrncpy(n, name, sizeof(n)); #if defined(HAVE_PTHREAD_SETNAME_NP) - int status = pthread_setname_np (tid, n); - if (status != 0) - { - char errbuf[1024]; - ERROR ("set_thread_name(\"%s\"): %s", n, - sstrerror (status, errbuf, sizeof(errbuf))); - } + int status = pthread_setname_np(tid, n); + if (status != 0) { + char errbuf[1024]; + ERROR("set_thread_name(\"%s\"): %s", n, + sstrerror(status, errbuf, sizeof(errbuf))); + } #else /* if defined(HAVE_PTHREAD_SET_NAME_NP) */ - pthread_set_name_np (tid, n); + pthread_set_name_np(tid, n); #endif #endif } -static void start_read_threads (size_t num) /* {{{ */ +static void start_read_threads(size_t num) /* {{{ */ { - if (read_threads != NULL) - return; - - read_threads = (pthread_t *) calloc (num, sizeof (pthread_t)); - if (read_threads == NULL) - { - ERROR ("plugin: start_read_threads: calloc failed."); - return; - } - - read_threads_num = 0; - for (size_t i = 0; i < num; i++) - { - int status = pthread_create (read_threads + read_threads_num, - /* attr = */ NULL, - plugin_read_thread, - /* arg = */ NULL); - if (status != 0) - { - char errbuf[1024]; - ERROR ("plugin: start_read_threads: pthread_create failed " - "with status %i (%s).", status, - sstrerror (status, errbuf, sizeof (errbuf))); - return; - } - - char name[THREAD_NAME_MAX]; - ssnprintf (name, sizeof (name), "reader#%zu", read_threads_num); - set_thread_name (read_threads[read_threads_num], name); - - read_threads_num++; - } /* for (i) */ + if (read_threads != NULL) + return; + + read_threads = (pthread_t *)calloc(num, sizeof(pthread_t)); + if (read_threads == NULL) { + ERROR("plugin: start_read_threads: calloc failed."); + return; + } + + read_threads_num = 0; + for (size_t i = 0; i < num; i++) { + int status = pthread_create(read_threads + read_threads_num, + /* attr = */ NULL, plugin_read_thread, + /* arg = */ NULL); + if (status != 0) { + char errbuf[1024]; + ERROR("plugin: start_read_threads: pthread_create failed " + "with status %i (%s).", + status, sstrerror(status, errbuf, sizeof(errbuf))); + return; + } + + char name[THREAD_NAME_MAX]; + ssnprintf(name, sizeof(name), "reader#%zu", read_threads_num); + set_thread_name(read_threads[read_threads_num], name); + + read_threads_num++; + } /* for (i) */ } /* }}} void start_read_threads */ -static void stop_read_threads (void) -{ - if (read_threads == NULL) - return; - - INFO ("collectd: Stopping %zu read threads.", read_threads_num); - - pthread_mutex_lock (&read_lock); - read_loop = 0; - DEBUG ("plugin: stop_read_threads: Signalling `read_cond'"); - pthread_cond_broadcast (&read_cond); - pthread_mutex_unlock (&read_lock); - - for (size_t i = 0; i < read_threads_num; i++) - { - if (pthread_join (read_threads[i], NULL) != 0) - { - ERROR ("plugin: stop_read_threads: pthread_join failed."); - } - read_threads[i] = (pthread_t) 0; - } - sfree (read_threads); - read_threads_num = 0; +static void stop_read_threads(void) { + if (read_threads == NULL) + return; + + INFO("collectd: Stopping %zu read threads.", read_threads_num); + + pthread_mutex_lock(&read_lock); + read_loop = 0; + DEBUG("plugin: stop_read_threads: Signalling `read_cond'"); + pthread_cond_broadcast(&read_cond); + pthread_mutex_unlock(&read_lock); + + for (size_t i = 0; i < read_threads_num; i++) { + if (pthread_join(read_threads[i], NULL) != 0) { + ERROR("plugin: stop_read_threads: pthread_join failed."); + } + read_threads[i] = (pthread_t)0; + } + sfree(read_threads); + read_threads_num = 0; } /* void stop_read_threads */ -static void plugin_value_list_free (value_list_t *vl) /* {{{ */ +static void plugin_value_list_free(value_list_t *vl) /* {{{ */ { - if (vl == NULL) - return; + if (vl == NULL) + return; - meta_data_destroy (vl->meta); - sfree (vl->values); - sfree (vl); + meta_data_destroy(vl->meta); + sfree(vl->values); + sfree(vl); } /* }}} void plugin_value_list_free */ -static value_list_t *plugin_value_list_clone (value_list_t const *vl_orig) /* {{{ */ +static value_list_t * +plugin_value_list_clone(value_list_t const *vl_orig) /* {{{ */ { - value_list_t *vl; - - if (vl_orig == NULL) - return (NULL); - - vl = malloc (sizeof (*vl)); - if (vl == NULL) - return (NULL); - memcpy (vl, vl_orig, sizeof (*vl)); - - if (vl->host[0] == 0) - sstrncpy (vl->host, hostname_g, sizeof (vl->host)); - - vl->values = calloc (vl_orig->values_len, sizeof (*vl->values)); - if (vl->values == NULL) - { - plugin_value_list_free (vl); - return (NULL); - } - memcpy (vl->values, vl_orig->values, - vl_orig->values_len * sizeof (*vl->values)); - - vl->meta = meta_data_clone (vl->meta); - if ((vl_orig->meta != NULL) && (vl->meta == NULL)) - { - plugin_value_list_free (vl); - return (NULL); - } - - if (vl->time == 0) - vl->time = cdtime (); - - /* Fill in the interval from the thread context, if it is zero. */ - if (vl->interval == 0) - { - plugin_ctx_t ctx = plugin_get_ctx (); - - if (ctx.interval != 0) - vl->interval = ctx.interval; - else - { - char name[6 * DATA_MAX_NAME_LEN]; - FORMAT_VL (name, sizeof (name), vl); - ERROR ("plugin_value_list_clone: Unable to determine " - "interval from context for " - "value list \"%s\". " - "This indicates a broken plugin. " - "Please report this problem to the " - "collectd mailing list or at " - ".", name); - vl->interval = cf_get_default_interval (); - } - } - - return (vl); + value_list_t *vl; + + if (vl_orig == NULL) + return (NULL); + + vl = malloc(sizeof(*vl)); + if (vl == NULL) + return (NULL); + memcpy(vl, vl_orig, sizeof(*vl)); + + if (vl->host[0] == 0) + sstrncpy(vl->host, hostname_g, sizeof(vl->host)); + + vl->values = calloc(vl_orig->values_len, sizeof(*vl->values)); + if (vl->values == NULL) { + plugin_value_list_free(vl); + return (NULL); + } + memcpy(vl->values, vl_orig->values, + vl_orig->values_len * sizeof(*vl->values)); + + vl->meta = meta_data_clone(vl->meta); + if ((vl_orig->meta != NULL) && (vl->meta == NULL)) { + plugin_value_list_free(vl); + return (NULL); + } + + if (vl->time == 0) + vl->time = cdtime(); + + /* Fill in the interval from the thread context, if it is zero. */ + if (vl->interval == 0) { + plugin_ctx_t ctx = plugin_get_ctx(); + + if (ctx.interval != 0) + vl->interval = ctx.interval; + else { + char name[6 * DATA_MAX_NAME_LEN]; + FORMAT_VL(name, sizeof(name), vl); + ERROR("plugin_value_list_clone: Unable to determine " + "interval from context for " + "value list \"%s\". " + "This indicates a broken plugin. " + "Please report this problem to the " + "collectd mailing list or at " + ".", + name); + vl->interval = cf_get_default_interval(); + } + } + + return (vl); } /* }}} value_list_t *plugin_value_list_clone */ -static int plugin_write_enqueue (value_list_t const *vl) /* {{{ */ +static int plugin_write_enqueue(value_list_t const *vl) /* {{{ */ { - write_queue_t *q; - - q = malloc (sizeof (*q)); - if (q == NULL) - return (ENOMEM); - q->next = NULL; - - q->vl = plugin_value_list_clone (vl); - if (q->vl == NULL) - { - sfree (q); - return (ENOMEM); - } - - /* Store context of caller (read plugin); otherwise, it would not be - * available to the write plugins when actually dispatching the - * value-list later on. */ - q->ctx = plugin_get_ctx (); - - pthread_mutex_lock (&write_lock); - - if (write_queue_tail == NULL) - { - write_queue_head = q; - write_queue_tail = q; - write_queue_length = 1; - } - else - { - write_queue_tail->next = q; - write_queue_tail = q; - write_queue_length += 1; - } - - pthread_cond_signal (&write_cond); - pthread_mutex_unlock (&write_lock); - - return (0); + write_queue_t *q; + + q = malloc(sizeof(*q)); + if (q == NULL) + return (ENOMEM); + q->next = NULL; + + q->vl = plugin_value_list_clone(vl); + if (q->vl == NULL) { + sfree(q); + return (ENOMEM); + } + + /* Store context of caller (read plugin); otherwise, it would not be + * available to the write plugins when actually dispatching the + * value-list later on. */ + q->ctx = plugin_get_ctx(); + + pthread_mutex_lock(&write_lock); + + if (write_queue_tail == NULL) { + write_queue_head = q; + write_queue_tail = q; + write_queue_length = 1; + } else { + write_queue_tail->next = q; + write_queue_tail = q; + write_queue_length += 1; + } + + pthread_cond_signal(&write_cond); + pthread_mutex_unlock(&write_lock); + + return (0); } /* }}} int plugin_write_enqueue */ -static value_list_t *plugin_write_dequeue (void) /* {{{ */ +static value_list_t *plugin_write_dequeue(void) /* {{{ */ { - write_queue_t *q; - value_list_t *vl; + write_queue_t *q; + value_list_t *vl; - pthread_mutex_lock (&write_lock); + pthread_mutex_lock(&write_lock); - while (write_loop && (write_queue_head == NULL)) - pthread_cond_wait (&write_cond, &write_lock); + while (write_loop && (write_queue_head == NULL)) + pthread_cond_wait(&write_cond, &write_lock); - if (write_queue_head == NULL) - { - pthread_mutex_unlock (&write_lock); - return (NULL); - } + if (write_queue_head == NULL) { + pthread_mutex_unlock(&write_lock); + return (NULL); + } - q = write_queue_head; - write_queue_head = q->next; - write_queue_length -= 1; - if (write_queue_head == NULL) { - write_queue_tail = NULL; - assert(0 == write_queue_length); - } + q = write_queue_head; + write_queue_head = q->next; + write_queue_length -= 1; + if (write_queue_head == NULL) { + write_queue_tail = NULL; + assert(0 == write_queue_length); + } - pthread_mutex_unlock (&write_lock); + pthread_mutex_unlock(&write_lock); - (void) plugin_set_ctx (q->ctx); + (void)plugin_set_ctx(q->ctx); - vl = q->vl; - sfree (q); - return (vl); + vl = q->vl; + sfree(q); + return (vl); } /* }}} value_list_t *plugin_write_dequeue */ -static void *plugin_write_thread (void __attribute__((unused)) *args) /* {{{ */ +static void *plugin_write_thread(void __attribute__((unused)) * args) /* {{{ */ { - while (write_loop) - { - value_list_t *vl = plugin_write_dequeue (); - if (vl == NULL) - continue; + while (write_loop) { + value_list_t *vl = plugin_write_dequeue(); + if (vl == NULL) + continue; - plugin_dispatch_values_internal (vl); + plugin_dispatch_values_internal(vl); - plugin_value_list_free (vl); - } + plugin_value_list_free(vl); + } - pthread_exit (NULL); - return ((void *) 0); + pthread_exit(NULL); + return ((void *)0); } /* }}} void *plugin_write_thread */ -static void start_write_threads (size_t num) /* {{{ */ +static void start_write_threads(size_t num) /* {{{ */ { - if (write_threads != NULL) - return; - - write_threads = (pthread_t *) calloc (num, sizeof (pthread_t)); - if (write_threads == NULL) - { - ERROR ("plugin: start_write_threads: calloc failed."); - return; - } - - write_threads_num = 0; - for (size_t i = 0; i < num; i++) - { - int status = pthread_create (write_threads + write_threads_num, - /* attr = */ NULL, - plugin_write_thread, - /* arg = */ NULL); - if (status != 0) - { - char errbuf[1024]; - ERROR ("plugin: start_write_threads: pthread_create failed " - "with status %i (%s).", status, - sstrerror (status, errbuf, sizeof (errbuf))); - return; - } - - char name[THREAD_NAME_MAX]; - ssnprintf (name, sizeof (name), "writer#%zu", write_threads_num); - set_thread_name (write_threads[write_threads_num], name); - - write_threads_num++; - } /* for (i) */ + if (write_threads != NULL) + return; + + write_threads = (pthread_t *)calloc(num, sizeof(pthread_t)); + if (write_threads == NULL) { + ERROR("plugin: start_write_threads: calloc failed."); + return; + } + + write_threads_num = 0; + for (size_t i = 0; i < num; i++) { + int status = pthread_create(write_threads + write_threads_num, + /* attr = */ NULL, plugin_write_thread, + /* arg = */ NULL); + if (status != 0) { + char errbuf[1024]; + ERROR("plugin: start_write_threads: pthread_create failed " + "with status %i (%s).", + status, sstrerror(status, errbuf, sizeof(errbuf))); + return; + } + + char name[THREAD_NAME_MAX]; + ssnprintf(name, sizeof(name), "writer#%zu", write_threads_num); + set_thread_name(write_threads[write_threads_num], name); + + write_threads_num++; + } /* for (i) */ } /* }}} void start_write_threads */ -static void stop_write_threads (void) /* {{{ */ +static void stop_write_threads(void) /* {{{ */ { - write_queue_t *q; - size_t i; - - if (write_threads == NULL) - return; - - INFO ("collectd: Stopping %zu write threads.", write_threads_num); - - pthread_mutex_lock (&write_lock); - write_loop = 0; - DEBUG ("plugin: stop_write_threads: Signalling `write_cond'"); - pthread_cond_broadcast (&write_cond); - pthread_mutex_unlock (&write_lock); - - for (i = 0; i < write_threads_num; i++) - { - if (pthread_join (write_threads[i], NULL) != 0) - { - ERROR ("plugin: stop_write_threads: pthread_join failed."); - } - write_threads[i] = (pthread_t) 0; - } - sfree (write_threads); - write_threads_num = 0; - - pthread_mutex_lock (&write_lock); - i = 0; - for (q = write_queue_head; q != NULL; ) - { - write_queue_t *q1 = q; - plugin_value_list_free (q->vl); - q = q->next; - sfree (q1); - i++; - } - write_queue_head = NULL; - write_queue_tail = NULL; - write_queue_length = 0; - pthread_mutex_unlock (&write_lock); - - if (i > 0) - { - WARNING ("plugin: %zu value list%s left after shutting down " - "the write threads.", - i, (i == 1) ? " was" : "s were"); - } + write_queue_t *q; + size_t i; + + if (write_threads == NULL) + return; + + INFO("collectd: Stopping %zu write threads.", write_threads_num); + + pthread_mutex_lock(&write_lock); + write_loop = 0; + DEBUG("plugin: stop_write_threads: Signalling `write_cond'"); + pthread_cond_broadcast(&write_cond); + pthread_mutex_unlock(&write_lock); + + for (i = 0; i < write_threads_num; i++) { + if (pthread_join(write_threads[i], NULL) != 0) { + ERROR("plugin: stop_write_threads: pthread_join failed."); + } + write_threads[i] = (pthread_t)0; + } + sfree(write_threads); + write_threads_num = 0; + + pthread_mutex_lock(&write_lock); + i = 0; + for (q = write_queue_head; q != NULL;) { + write_queue_t *q1 = q; + plugin_value_list_free(q->vl); + q = q->next; + sfree(q1); + i++; + } + write_queue_head = NULL; + write_queue_tail = NULL; + write_queue_length = 0; + pthread_mutex_unlock(&write_lock); + + if (i > 0) { + WARNING("plugin: %zu value list%s left after shutting down " + "the write threads.", + i, (i == 1) ? " was" : "s were"); + } } /* }}} void stop_write_threads */ /* * Public functions */ -void plugin_set_dir (const char *dir) -{ - sfree (plugindir); +void plugin_set_dir(const char *dir) { + sfree(plugindir); - if (dir == NULL) - { - plugindir = NULL; - return; - } + if (dir == NULL) { + plugindir = NULL; + return; + } - plugindir = strdup (dir); - if (plugindir == NULL) - ERROR ("plugin_set_dir: strdup(\"%s\") failed", dir); + plugindir = strdup(dir); + if (plugindir == NULL) + ERROR("plugin_set_dir: strdup(\"%s\") failed", dir); } -static _Bool plugin_is_loaded (char const *name) -{ - int status; +static _Bool plugin_is_loaded(char const *name) { + int status; - if (plugins_loaded == NULL) - plugins_loaded = c_avl_create ((int (*) (const void *, const void *)) strcasecmp); - assert (plugins_loaded != NULL); + if (plugins_loaded == NULL) + plugins_loaded = + c_avl_create((int (*)(const void *, const void *))strcasecmp); + assert(plugins_loaded != NULL); - status = c_avl_get (plugins_loaded, name, /* ret_value = */ NULL); - return (status == 0); + status = c_avl_get(plugins_loaded, name, /* ret_value = */ NULL); + return (status == 0); } -static int plugin_mark_loaded (char const *name) -{ - char *name_copy; - int status; +static int plugin_mark_loaded(char const *name) { + char *name_copy; + int status; - name_copy = strdup (name); - if (name_copy == NULL) - return (ENOMEM); + name_copy = strdup(name); + if (name_copy == NULL) + return (ENOMEM); - status = c_avl_insert (plugins_loaded, - /* key = */ name_copy, /* value = */ NULL); - return (status); + status = c_avl_insert(plugins_loaded, + /* key = */ name_copy, /* value = */ NULL); + return (status); } -static void plugin_free_loaded (void) -{ - void *key; - void *value; +static void plugin_free_loaded(void) { + void *key; + void *value; - if (plugins_loaded == NULL) - return; + if (plugins_loaded == NULL) + return; - while (c_avl_pick (plugins_loaded, &key, &value) == 0) - { - sfree (key); - assert (value == NULL); - } + while (c_avl_pick(plugins_loaded, &key, &value) == 0) { + sfree(key); + assert(value == NULL); + } - c_avl_destroy (plugins_loaded); - plugins_loaded = NULL; + c_avl_destroy(plugins_loaded); + plugins_loaded = NULL; } #define BUFSIZE 512 -int plugin_load (char const *plugin_name, uint32_t flags) -{ - DIR *dh; - const char *dir; - char filename[BUFSIZE] = ""; - char typename[BUFSIZE]; - int ret; - struct stat statbuf; - struct dirent *de; - int status; - - if (plugin_name == NULL) - return (EINVAL); - - /* Check if plugin is already loaded and don't do anything in this - * case. */ - if (plugin_is_loaded (plugin_name)) - return (0); - - dir = plugin_get_dir (); - ret = 1; - - /* - * XXX: Magic at work: - * - * Some of the language bindings, for example the Python and Perl - * plugins, need to be able to export symbols to the scripts they run. - * For this to happen, the "Globals" flag needs to be set. - * Unfortunately, this technical detail is hard to explain to the - * average user and she shouldn't have to worry about this, ideally. - * So in order to save everyone's sanity use a different default for a - * handful of special plugins. --octo - */ - if ((strcasecmp ("perl", plugin_name) == 0) - || (strcasecmp ("python", plugin_name) == 0)) - flags |= PLUGIN_FLAGS_GLOBAL; - - /* `cpu' should not match `cpufreq'. To solve this we add `.so' to the - * type when matching the filename */ - status = ssnprintf (typename, sizeof (typename), "%s.so", plugin_name); - if ((status < 0) || ((size_t) status >= sizeof (typename))) - { - WARNING ("plugin_load: Filename too long: \"%s.so\"", plugin_name); - return (-1); - } - - if ((dh = opendir (dir)) == NULL) - { - char errbuf[1024]; - ERROR ("plugin_load: opendir (%s) failed: %s", dir, - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - while ((de = readdir (dh)) != NULL) - { - if (strcasecmp (de->d_name, typename)) - continue; - - status = ssnprintf (filename, sizeof (filename), - "%s/%s", dir, de->d_name); - if ((status < 0) || ((size_t) status >= sizeof (filename))) - { - WARNING ("plugin_load: Filename too long: \"%s/%s\"", - dir, de->d_name); - continue; - } - - if (lstat (filename, &statbuf) == -1) - { - char errbuf[1024]; - WARNING ("plugin_load: stat (\"%s\") failed: %s", - filename, - sstrerror (errno, errbuf, sizeof (errbuf))); - continue; - } - else if (!S_ISREG (statbuf.st_mode)) - { - /* don't follow symlinks */ - WARNING ("plugin_load: %s is not a regular file.", - filename); - continue; - } - - status = plugin_load_file (filename, flags); - if (status == 0) - { - /* success */ - plugin_mark_loaded (plugin_name); - ret = 0; - INFO ("plugin_load: plugin \"%s\" successfully loaded.", plugin_name); - break; - } - else - { - ERROR ("plugin_load: Load plugin \"%s\" failed with " - "status %i.", plugin_name, status); - } - } - - closedir (dh); - - if (filename[0] == 0) - ERROR ("plugin_load: Could not find plugin \"%s\" in %s", - plugin_name, dir); - - return (ret); +int plugin_load(char const *plugin_name, uint32_t flags) { + DIR *dh; + const char *dir; + char filename[BUFSIZE] = ""; + char typename[BUFSIZE]; + int ret; + struct stat statbuf; + struct dirent *de; + int status; + + if (plugin_name == NULL) + return (EINVAL); + + /* Check if plugin is already loaded and don't do anything in this + * case. */ + if (plugin_is_loaded(plugin_name)) + return (0); + + dir = plugin_get_dir(); + ret = 1; + + /* + * XXX: Magic at work: + * + * Some of the language bindings, for example the Python and Perl + * plugins, need to be able to export symbols to the scripts they run. + * For this to happen, the "Globals" flag needs to be set. + * Unfortunately, this technical detail is hard to explain to the + * average user and she shouldn't have to worry about this, ideally. + * So in order to save everyone's sanity use a different default for a + * handful of special plugins. --octo + */ + if ((strcasecmp("perl", plugin_name) == 0) || + (strcasecmp("python", plugin_name) == 0)) + flags |= PLUGIN_FLAGS_GLOBAL; + + /* `cpu' should not match `cpufreq'. To solve this we add `.so' to the + * type when matching the filename */ + status = ssnprintf(typename, sizeof(typename), "%s.so", plugin_name); + if ((status < 0) || ((size_t)status >= sizeof(typename))) { + WARNING("plugin_load: Filename too long: \"%s.so\"", plugin_name); + return (-1); + } + + if ((dh = opendir(dir)) == NULL) { + char errbuf[1024]; + ERROR("plugin_load: opendir (%s) failed: %s", dir, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + while ((de = readdir(dh)) != NULL) { + if (strcasecmp(de->d_name, typename)) + continue; + + status = ssnprintf(filename, sizeof(filename), "%s/%s", dir, de->d_name); + if ((status < 0) || ((size_t)status >= sizeof(filename))) { + WARNING("plugin_load: Filename too long: \"%s/%s\"", dir, de->d_name); + continue; + } + + if (lstat(filename, &statbuf) == -1) { + char errbuf[1024]; + WARNING("plugin_load: stat (\"%s\") failed: %s", filename, + sstrerror(errno, errbuf, sizeof(errbuf))); + continue; + } else if (!S_ISREG(statbuf.st_mode)) { + /* don't follow symlinks */ + WARNING("plugin_load: %s is not a regular file.", filename); + continue; + } + + status = plugin_load_file(filename, flags); + if (status == 0) { + /* success */ + plugin_mark_loaded(plugin_name); + ret = 0; + INFO("plugin_load: plugin \"%s\" successfully loaded.", plugin_name); + break; + } else { + ERROR("plugin_load: Load plugin \"%s\" failed with " + "status %i.", + plugin_name, status); + } + } + + closedir(dh); + + if (filename[0] == 0) + ERROR("plugin_load: Could not find plugin \"%s\" in %s", plugin_name, dir); + + return (ret); } /* * The `register_*' functions follow */ -int plugin_register_config (const char *name, - int (*callback) (const char *key, const char *val), - const char **keys, int keys_num) -{ - cf_register (name, callback, keys, keys_num); - return (0); +int plugin_register_config(const char *name, + int (*callback)(const char *key, const char *val), + const char **keys, int keys_num) { + cf_register(name, callback, keys, keys_num); + return (0); } /* int plugin_register_config */ -int plugin_register_complex_config (const char *type, - int (*callback) (oconfig_item_t *)) -{ - return (cf_register_complex (type, callback)); +int plugin_register_complex_config(const char *type, + int (*callback)(oconfig_item_t *)) { + return (cf_register_complex(type, callback)); } /* int plugin_register_complex_config */ -int plugin_register_init (const char *name, - int (*callback) (void)) -{ - return (create_register_callback (&list_init, name, (void *) callback, - /* user_data = */ NULL)); +int plugin_register_init(const char *name, int (*callback)(void)) { + return (create_register_callback(&list_init, name, (void *)callback, + /* user_data = */ NULL)); } /* plugin_register_init */ -static int plugin_compare_read_func (const void *arg0, const void *arg1) -{ - const read_func_t *rf0; - const read_func_t *rf1; - - rf0 = arg0; - rf1 = arg1; - - if (rf0->rf_next_read < rf1->rf_next_read) - return (-1); - else if (rf0->rf_next_read > rf1->rf_next_read) - return (1); - else - return (0); +static int plugin_compare_read_func(const void *arg0, const void *arg1) { + const read_func_t *rf0; + const read_func_t *rf1; + + rf0 = arg0; + rf1 = arg1; + + if (rf0->rf_next_read < rf1->rf_next_read) + return (-1); + else if (rf0->rf_next_read > rf1->rf_next_read) + return (1); + else + return (0); } /* int plugin_compare_read_func */ /* Add a read function to both, the heap and a linked list. The linked list if * used to look-up read functions, especially for the remove function. The heap * is used to determine which plugin to read next. */ -static int plugin_insert_read (read_func_t *rf) -{ - int status; - llentry_t *le; - - rf->rf_next_read = cdtime (); - rf->rf_effective_interval = rf->rf_interval; - - pthread_mutex_lock (&read_lock); - - if (read_list == NULL) - { - read_list = llist_create (); - if (read_list == NULL) - { - pthread_mutex_unlock (&read_lock); - ERROR ("plugin_insert_read: read_list failed."); - return (-1); - } - } - - if (read_heap == NULL) - { - read_heap = c_heap_create (plugin_compare_read_func); - if (read_heap == NULL) - { - pthread_mutex_unlock (&read_lock); - ERROR ("plugin_insert_read: c_heap_create failed."); - return (-1); - } - } - - le = llist_search (read_list, rf->rf_name); - if (le != NULL) - { - pthread_mutex_unlock (&read_lock); - WARNING ("The read function \"%s\" is already registered. " - "Check for duplicate \"LoadPlugin\" lines " - "in your configuration!", - rf->rf_name); - return (EINVAL); - } - - le = llentry_create (rf->rf_name, rf); - if (le == NULL) - { - pthread_mutex_unlock (&read_lock); - ERROR ("plugin_insert_read: llentry_create failed."); - return (-1); - } - - status = c_heap_insert (read_heap, rf); - if (status != 0) - { - pthread_mutex_unlock (&read_lock); - ERROR ("plugin_insert_read: c_heap_insert failed."); - llentry_destroy (le); - return (-1); - } - - /* This does not fail. */ - llist_append (read_list, le); - - /* Wake up all the read threads. */ - pthread_cond_broadcast (&read_cond); - pthread_mutex_unlock (&read_lock); - return (0); +static int plugin_insert_read(read_func_t *rf) { + int status; + llentry_t *le; + + rf->rf_next_read = cdtime(); + rf->rf_effective_interval = rf->rf_interval; + + pthread_mutex_lock(&read_lock); + + if (read_list == NULL) { + read_list = llist_create(); + if (read_list == NULL) { + pthread_mutex_unlock(&read_lock); + ERROR("plugin_insert_read: read_list failed."); + return (-1); + } + } + + if (read_heap == NULL) { + read_heap = c_heap_create(plugin_compare_read_func); + if (read_heap == NULL) { + pthread_mutex_unlock(&read_lock); + ERROR("plugin_insert_read: c_heap_create failed."); + return (-1); + } + } + + le = llist_search(read_list, rf->rf_name); + if (le != NULL) { + pthread_mutex_unlock(&read_lock); + WARNING("The read function \"%s\" is already registered. " + "Check for duplicate \"LoadPlugin\" lines " + "in your configuration!", + rf->rf_name); + return (EINVAL); + } + + le = llentry_create(rf->rf_name, rf); + if (le == NULL) { + pthread_mutex_unlock(&read_lock); + ERROR("plugin_insert_read: llentry_create failed."); + return (-1); + } + + status = c_heap_insert(read_heap, rf); + if (status != 0) { + pthread_mutex_unlock(&read_lock); + ERROR("plugin_insert_read: c_heap_insert failed."); + llentry_destroy(le); + return (-1); + } + + /* This does not fail. */ + llist_append(read_list, le); + + /* Wake up all the read threads. */ + pthread_cond_broadcast(&read_cond); + pthread_mutex_unlock(&read_lock); + return (0); } /* int plugin_insert_read */ -int plugin_register_read (const char *name, - int (*callback) (void)) -{ - read_func_t *rf; - int status; - - rf = calloc (1, sizeof (*rf)); - if (rf == NULL) - { - ERROR ("plugin_register_read: calloc failed."); - return (ENOMEM); - } - - rf->rf_callback = (void *) callback; - rf->rf_udata.data = NULL; - rf->rf_udata.free_func = NULL; - rf->rf_ctx = plugin_get_ctx (); - rf->rf_group[0] = '\0'; - rf->rf_name = strdup (name); - rf->rf_type = RF_SIMPLE; - rf->rf_interval = plugin_get_interval (); - - status = plugin_insert_read (rf); - if (status != 0) { - sfree (rf->rf_name); - sfree (rf); - } - - return (status); +int plugin_register_read(const char *name, int (*callback)(void)) { + read_func_t *rf; + int status; + + rf = calloc(1, sizeof(*rf)); + if (rf == NULL) { + ERROR("plugin_register_read: calloc failed."); + return (ENOMEM); + } + + rf->rf_callback = (void *)callback; + rf->rf_udata.data = NULL; + rf->rf_udata.free_func = NULL; + rf->rf_ctx = plugin_get_ctx(); + rf->rf_group[0] = '\0'; + rf->rf_name = strdup(name); + rf->rf_type = RF_SIMPLE; + rf->rf_interval = plugin_get_interval(); + + status = plugin_insert_read(rf); + if (status != 0) { + sfree(rf->rf_name); + sfree(rf); + } + + return (status); } /* int plugin_register_read */ -int plugin_register_complex_read (const char *group, const char *name, - plugin_read_cb callback, - cdtime_t interval, - user_data_t const *user_data) -{ - read_func_t *rf; - int status; - - rf = calloc (1,sizeof (*rf)); - if (rf == NULL) - { - ERROR ("plugin_register_complex_read: calloc failed."); - return (ENOMEM); - } - - rf->rf_callback = (void *) callback; - if (group != NULL) - sstrncpy (rf->rf_group, group, sizeof (rf->rf_group)); - else - rf->rf_group[0] = '\0'; - rf->rf_name = strdup (name); - rf->rf_type = RF_COMPLEX; - rf->rf_interval = (interval != 0) ? interval : plugin_get_interval (); - - /* Set user data */ - if (user_data == NULL) - { - rf->rf_udata.data = NULL; - rf->rf_udata.free_func = NULL; - } - else - { - rf->rf_udata = *user_data; - } - - rf->rf_ctx = plugin_get_ctx (); - - status = plugin_insert_read (rf); - if (status != 0) { - sfree (rf->rf_name); - sfree (rf); - } - - return (status); +int plugin_register_complex_read(const char *group, const char *name, + plugin_read_cb callback, cdtime_t interval, + user_data_t const *user_data) { + read_func_t *rf; + int status; + + rf = calloc(1, sizeof(*rf)); + if (rf == NULL) { + ERROR("plugin_register_complex_read: calloc failed."); + return (ENOMEM); + } + + rf->rf_callback = (void *)callback; + if (group != NULL) + sstrncpy(rf->rf_group, group, sizeof(rf->rf_group)); + else + rf->rf_group[0] = '\0'; + rf->rf_name = strdup(name); + rf->rf_type = RF_COMPLEX; + rf->rf_interval = (interval != 0) ? interval : plugin_get_interval(); + + /* Set user data */ + if (user_data == NULL) { + rf->rf_udata.data = NULL; + rf->rf_udata.free_func = NULL; + } else { + rf->rf_udata = *user_data; + } + + rf->rf_ctx = plugin_get_ctx(); + + status = plugin_insert_read(rf); + if (status != 0) { + sfree(rf->rf_name); + sfree(rf); + } + + return (status); } /* int plugin_register_complex_read */ -int plugin_register_write (const char *name, - plugin_write_cb callback, user_data_t const *ud) -{ - return (create_register_callback (&list_write, name, - (void *) callback, ud)); +int plugin_register_write(const char *name, plugin_write_cb callback, + user_data_t const *ud) { + return (create_register_callback(&list_write, name, (void *)callback, ud)); } /* int plugin_register_write */ -static int plugin_flush_timeout_callback (user_data_t *ud) -{ - flush_callback_t *cb = ud->data; +static int plugin_flush_timeout_callback(user_data_t *ud) { + flush_callback_t *cb = ud->data; - return plugin_flush (cb->name, cb->timeout, /* identifier = */ NULL); + return plugin_flush(cb->name, cb->timeout, /* identifier = */ NULL); } /* static int plugin_flush_callback */ -static void plugin_flush_timeout_callback_free (void *data) -{ - flush_callback_t *cb = data; +static void plugin_flush_timeout_callback_free(void *data) { + flush_callback_t *cb = data; - if (cb == NULL) return; + if (cb == NULL) + return; - sfree (cb->name); - sfree (cb); + sfree(cb->name); + sfree(cb); } /* static void plugin_flush_callback_free */ -static char *plugin_flush_callback_name (const char *name) -{ - const char *flush_prefix = "flush/"; - size_t prefix_size; - char *flush_name; - size_t name_size; +static char *plugin_flush_callback_name(const char *name) { + const char *flush_prefix = "flush/"; + size_t prefix_size; + char *flush_name; + size_t name_size; - prefix_size = strlen(flush_prefix); - name_size = strlen(name); + prefix_size = strlen(flush_prefix); + name_size = strlen(name); - flush_name = malloc (name_size + prefix_size + 1); - if (flush_name == NULL) - { - ERROR ("plugin_flush_callback_name: malloc failed."); - return (NULL); - } + flush_name = malloc(name_size + prefix_size + 1); + if (flush_name == NULL) { + ERROR("plugin_flush_callback_name: malloc failed."); + return (NULL); + } - sstrncpy (flush_name, flush_prefix, prefix_size + 1); - sstrncpy (flush_name + prefix_size, name, name_size + 1); + sstrncpy(flush_name, flush_prefix, prefix_size + 1); + sstrncpy(flush_name + prefix_size, name, name_size + 1); - return flush_name; + return flush_name; } /* static char *plugin_flush_callback_name */ -int plugin_register_flush (const char *name, - plugin_flush_cb callback, user_data_t const *ud) -{ - int status; - plugin_ctx_t ctx = plugin_get_ctx (); - - status = create_register_callback (&list_flush, name, - (void *) callback, ud); - if (status != 0) - return status; - - if (ctx.flush_interval != 0) - { - char *flush_name; - flush_callback_t *cb; - - flush_name = plugin_flush_callback_name (name); - if (flush_name == NULL) - return (-1); - - cb = malloc(sizeof (*cb)); - if (cb == NULL) - { - ERROR ("plugin_register_flush: malloc failed."); - sfree (flush_name); - return (-1); - } - - cb->name = strdup (name); - if (cb->name == NULL) - { - ERROR ("plugin_register_flush: strdup failed."); - sfree (cb); - sfree (flush_name); - return (-1); - } - cb->timeout = ctx.flush_timeout; - - status = plugin_register_complex_read ( - /* group = */ "flush", - /* name = */ flush_name, - /* callback = */ plugin_flush_timeout_callback, - /* interval = */ ctx.flush_interval, - /* user data = */ &(user_data_t) { - .data = cb, - .free_func = plugin_flush_timeout_callback_free, - }); - - sfree (flush_name); - if (status != 0) - { - sfree (cb->name); - sfree (cb); - return status; - } - } - - return 0; +int plugin_register_flush(const char *name, plugin_flush_cb callback, + user_data_t const *ud) { + int status; + plugin_ctx_t ctx = plugin_get_ctx(); + + status = create_register_callback(&list_flush, name, (void *)callback, ud); + if (status != 0) + return status; + + if (ctx.flush_interval != 0) { + char *flush_name; + flush_callback_t *cb; + + flush_name = plugin_flush_callback_name(name); + if (flush_name == NULL) + return (-1); + + cb = malloc(sizeof(*cb)); + if (cb == NULL) { + ERROR("plugin_register_flush: malloc failed."); + sfree(flush_name); + return (-1); + } + + cb->name = strdup(name); + if (cb->name == NULL) { + ERROR("plugin_register_flush: strdup failed."); + sfree(cb); + sfree(flush_name); + return (-1); + } + cb->timeout = ctx.flush_timeout; + + status = plugin_register_complex_read( + /* group = */ "flush", + /* name = */ flush_name, + /* callback = */ plugin_flush_timeout_callback, + /* interval = */ ctx.flush_interval, + /* user data = */ &(user_data_t){ + .data = cb, .free_func = plugin_flush_timeout_callback_free, + }); + + sfree(flush_name); + if (status != 0) { + sfree(cb->name); + sfree(cb); + return status; + } + } + + return 0; } /* int plugin_register_flush */ -int plugin_register_missing (const char *name, - plugin_missing_cb callback, user_data_t const *ud) -{ - return (create_register_callback (&list_missing, name, - (void *) callback, ud)); +int plugin_register_missing(const char *name, plugin_missing_cb callback, + user_data_t const *ud) { + return (create_register_callback(&list_missing, name, (void *)callback, ud)); } /* int plugin_register_missing */ -int plugin_register_shutdown (const char *name, - int (*callback) (void)) -{ - return (create_register_callback (&list_shutdown, name, - (void *) callback, /* user_data = */ NULL)); +int plugin_register_shutdown(const char *name, int (*callback)(void)) { + return (create_register_callback(&list_shutdown, name, (void *)callback, + /* user_data = */ NULL)); } /* int plugin_register_shutdown */ -static void plugin_free_data_sets (void) -{ - void *key; - void *value; +static void plugin_free_data_sets(void) { + void *key; + void *value; - if (data_sets == NULL) - return; + if (data_sets == NULL) + return; - while (c_avl_pick (data_sets, &key, &value) == 0) - { - data_set_t *ds = value; - /* key is a pointer to ds->type */ + while (c_avl_pick(data_sets, &key, &value) == 0) { + data_set_t *ds = value; + /* key is a pointer to ds->type */ - sfree (ds->ds); - sfree (ds); - } + sfree(ds->ds); + sfree(ds); + } - c_avl_destroy (data_sets); - data_sets = NULL; + c_avl_destroy(data_sets); + data_sets = NULL; } /* void plugin_free_data_sets */ -int plugin_register_data_set (const data_set_t *ds) -{ - data_set_t *ds_copy; - - if ((data_sets != NULL) - && (c_avl_get (data_sets, ds->type, NULL) == 0)) - { - NOTICE ("Replacing DS `%s' with another version.", ds->type); - plugin_unregister_data_set (ds->type); - } - else if (data_sets == NULL) - { - data_sets = c_avl_create ((int (*) (const void *, const void *)) strcmp); - if (data_sets == NULL) - return (-1); - } - - ds_copy = malloc (sizeof (*ds_copy)); - if (ds_copy == NULL) - return (-1); - memcpy(ds_copy, ds, sizeof (data_set_t)); - - ds_copy->ds = malloc (sizeof (*ds_copy->ds) - * ds->ds_num); - if (ds_copy->ds == NULL) - { - sfree (ds_copy); - return (-1); - } - - for (size_t i = 0; i < ds->ds_num; i++) - memcpy (ds_copy->ds + i, ds->ds + i, sizeof (data_source_t)); - - return (c_avl_insert (data_sets, (void *) ds_copy->type, (void *) ds_copy)); +int plugin_register_data_set(const data_set_t *ds) { + data_set_t *ds_copy; + + if ((data_sets != NULL) && (c_avl_get(data_sets, ds->type, NULL) == 0)) { + NOTICE("Replacing DS `%s' with another version.", ds->type); + plugin_unregister_data_set(ds->type); + } else if (data_sets == NULL) { + data_sets = c_avl_create((int (*)(const void *, const void *))strcmp); + if (data_sets == NULL) + return (-1); + } + + ds_copy = malloc(sizeof(*ds_copy)); + if (ds_copy == NULL) + return (-1); + memcpy(ds_copy, ds, sizeof(data_set_t)); + + ds_copy->ds = malloc(sizeof(*ds_copy->ds) * ds->ds_num); + if (ds_copy->ds == NULL) { + sfree(ds_copy); + return (-1); + } + + for (size_t i = 0; i < ds->ds_num; i++) + memcpy(ds_copy->ds + i, ds->ds + i, sizeof(data_source_t)); + + return (c_avl_insert(data_sets, (void *)ds_copy->type, (void *)ds_copy)); } /* int plugin_register_data_set */ -int plugin_register_log (const char *name, - plugin_log_cb callback, user_data_t const *ud) -{ - return (create_register_callback (&list_log, name, - (void *) callback, ud)); +int plugin_register_log(const char *name, plugin_log_cb callback, + user_data_t const *ud) { + return (create_register_callback(&list_log, name, (void *)callback, ud)); } /* int plugin_register_log */ -int plugin_register_notification (const char *name, - plugin_notification_cb callback, user_data_t const *ud) -{ - return (create_register_callback (&list_notification, name, - (void *) callback, ud)); +int plugin_register_notification(const char *name, + plugin_notification_cb callback, + user_data_t const *ud) { + return ( + create_register_callback(&list_notification, name, (void *)callback, ud)); } /* int plugin_register_log */ -int plugin_unregister_config (const char *name) -{ - cf_unregister (name); - return (0); +int plugin_unregister_config(const char *name) { + cf_unregister(name); + return (0); } /* int plugin_unregister_config */ -int plugin_unregister_complex_config (const char *name) -{ - cf_unregister_complex (name); - return (0); +int plugin_unregister_complex_config(const char *name) { + cf_unregister_complex(name); + return (0); } /* int plugin_unregister_complex_config */ -int plugin_unregister_init (const char *name) -{ - return (plugin_unregister (list_init, name)); +int plugin_unregister_init(const char *name) { + return (plugin_unregister(list_init, name)); } -int plugin_unregister_read (const char *name) /* {{{ */ +int plugin_unregister_read(const char *name) /* {{{ */ { - llentry_t *le; - read_func_t *rf; + llentry_t *le; + read_func_t *rf; - if (name == NULL) - return (-ENOENT); + if (name == NULL) + return (-ENOENT); - pthread_mutex_lock (&read_lock); + pthread_mutex_lock(&read_lock); - if (read_list == NULL) - { - pthread_mutex_unlock (&read_lock); - return (-ENOENT); - } + if (read_list == NULL) { + pthread_mutex_unlock(&read_lock); + return (-ENOENT); + } - le = llist_search (read_list, name); - if (le == NULL) - { - pthread_mutex_unlock (&read_lock); - WARNING ("plugin_unregister_read: No such read function: %s", - name); - return (-ENOENT); - } + le = llist_search(read_list, name); + if (le == NULL) { + pthread_mutex_unlock(&read_lock); + WARNING("plugin_unregister_read: No such read function: %s", name); + return (-ENOENT); + } - llist_remove (read_list, le); + llist_remove(read_list, le); - rf = le->value; - assert (rf != NULL); - rf->rf_type = RF_REMOVE; + rf = le->value; + assert(rf != NULL); + rf->rf_type = RF_REMOVE; - pthread_mutex_unlock (&read_lock); + pthread_mutex_unlock(&read_lock); - llentry_destroy (le); + llentry_destroy(le); - DEBUG ("plugin_unregister_read: Marked `%s' for removal.", name); + DEBUG("plugin_unregister_read: Marked `%s' for removal.", name); - return (0); + return (0); } /* }}} int plugin_unregister_read */ -void plugin_log_available_writers (void) -{ - log_list_callbacks (&list_write, "Available write targets:"); +void plugin_log_available_writers(void) { + log_list_callbacks(&list_write, "Available write targets:"); } -static int compare_read_func_group (llentry_t *e, void *ud) /* {{{ */ +static int compare_read_func_group(llentry_t *e, void *ud) /* {{{ */ { - read_func_t *rf = e->value; - char *group = ud; + read_func_t *rf = e->value; + char *group = ud; - return strcmp (rf->rf_group, (const char *)group); + return strcmp(rf->rf_group, (const char *)group); } /* }}} int compare_read_func_group */ -int plugin_unregister_read_group (const char *group) /* {{{ */ +int plugin_unregister_read_group(const char *group) /* {{{ */ { - llentry_t *le; - read_func_t *rf; + llentry_t *le; + read_func_t *rf; - int found = 0; + int found = 0; - if (group == NULL) - return (-ENOENT); + if (group == NULL) + return (-ENOENT); - pthread_mutex_lock (&read_lock); + pthread_mutex_lock(&read_lock); - if (read_list == NULL) - { - pthread_mutex_unlock (&read_lock); - return (-ENOENT); - } + if (read_list == NULL) { + pthread_mutex_unlock(&read_lock); + return (-ENOENT); + } - while (42) - { - le = llist_search_custom (read_list, - compare_read_func_group, (void *)group); + while (42) { + le = llist_search_custom(read_list, compare_read_func_group, (void *)group); - if (le == NULL) - break; + if (le == NULL) + break; - ++found; + ++found; - llist_remove (read_list, le); + llist_remove(read_list, le); - rf = le->value; - assert (rf != NULL); - rf->rf_type = RF_REMOVE; + rf = le->value; + assert(rf != NULL); + rf->rf_type = RF_REMOVE; - llentry_destroy (le); + llentry_destroy(le); - DEBUG ("plugin_unregister_read_group: " - "Marked `%s' (group `%s') for removal.", - rf->rf_name, group); - } + DEBUG("plugin_unregister_read_group: " + "Marked `%s' (group `%s') for removal.", + rf->rf_name, group); + } - pthread_mutex_unlock (&read_lock); + pthread_mutex_unlock(&read_lock); - if (found == 0) - { - WARNING ("plugin_unregister_read_group: No such " - "group of read function: %s", group); - return (-ENOENT); - } + if (found == 0) { + WARNING("plugin_unregister_read_group: No such " + "group of read function: %s", + group); + return (-ENOENT); + } - return (0); + return (0); } /* }}} int plugin_unregister_read_group */ -int plugin_unregister_write (const char *name) -{ - return (plugin_unregister (list_write, name)); +int plugin_unregister_write(const char *name) { + return (plugin_unregister(list_write, name)); } -int plugin_unregister_flush (const char *name) -{ - plugin_ctx_t ctx = plugin_get_ctx (); +int plugin_unregister_flush(const char *name) { + plugin_ctx_t ctx = plugin_get_ctx(); - if (ctx.flush_interval != 0) - { - char *flush_name; + if (ctx.flush_interval != 0) { + char *flush_name; - flush_name = plugin_flush_callback_name (name); - if (flush_name != NULL) - { - plugin_unregister_read(flush_name); - sfree (flush_name); - } - } + flush_name = plugin_flush_callback_name(name); + if (flush_name != NULL) { + plugin_unregister_read(flush_name); + sfree(flush_name); + } + } - return plugin_unregister (list_flush, name); + return plugin_unregister(list_flush, name); } -int plugin_unregister_missing (const char *name) -{ - return (plugin_unregister (list_missing, name)); +int plugin_unregister_missing(const char *name) { + return (plugin_unregister(list_missing, name)); } -int plugin_unregister_shutdown (const char *name) -{ - return (plugin_unregister (list_shutdown, name)); +int plugin_unregister_shutdown(const char *name) { + return (plugin_unregister(list_shutdown, name)); } -int plugin_unregister_data_set (const char *name) -{ - data_set_t *ds; +int plugin_unregister_data_set(const char *name) { + data_set_t *ds; - if (data_sets == NULL) - return (-1); + if (data_sets == NULL) + return (-1); - if (c_avl_remove (data_sets, name, NULL, (void *) &ds) != 0) - return (-1); + if (c_avl_remove(data_sets, name, NULL, (void *)&ds) != 0) + return (-1); - sfree (ds->ds); - sfree (ds); + sfree(ds->ds); + sfree(ds); - return (0); + return (0); } /* int plugin_unregister_data_set */ -int plugin_unregister_log (const char *name) -{ - return (plugin_unregister (list_log, name)); +int plugin_unregister_log(const char *name) { + return (plugin_unregister(list_log, name)); } -int plugin_unregister_notification (const char *name) -{ - return (plugin_unregister (list_notification, name)); +int plugin_unregister_notification(const char *name) { + return (plugin_unregister(list_notification, name)); } -int plugin_init_all (void) -{ - char const *chain_name; - llentry_t *le; - int status; - int ret = 0; - - /* Init the value cache */ - uc_init (); - - if (IS_TRUE (global_option_get ("CollectInternalStats"))) - record_statistics = 1; - - chain_name = global_option_get ("PreCacheChain"); - pre_cache_chain = fc_chain_get_by_name (chain_name); - - chain_name = global_option_get ("PostCacheChain"); - post_cache_chain = fc_chain_get_by_name (chain_name); - - write_limit_high = global_option_get_long ("WriteQueueLimitHigh", - /* default = */ 0); - if (write_limit_high < 0) - { - ERROR ("WriteQueueLimitHigh must be positive or zero."); - write_limit_high = 0; - } - - write_limit_low = global_option_get_long ("WriteQueueLimitLow", - /* default = */ write_limit_high / 2); - if (write_limit_low < 0) - { - ERROR ("WriteQueueLimitLow must be positive or zero."); - write_limit_low = write_limit_high / 2; - } - else if (write_limit_low > write_limit_high) - { - ERROR ("WriteQueueLimitLow must not be larger than " - "WriteQueueLimitHigh."); - write_limit_low = write_limit_high; - } - - write_threads_num = global_option_get_long ("WriteThreads", - /* default = */ 5); - if (write_threads_num < 1) - { - ERROR ("WriteThreads must be positive."); - write_threads_num = 5; - } - - if ((list_init == NULL) && (read_heap == NULL)) - return ret; - - /* Calling all init callbacks before checking if read callbacks - * are available allows the init callbacks to register the read - * callback. */ - le = llist_head (list_init); - while (le != NULL) - { - callback_func_t *cf; - plugin_init_cb callback; - plugin_ctx_t old_ctx; - - cf = le->value; - old_ctx = plugin_set_ctx (cf->cf_ctx); - callback = cf->cf_callback; - status = (*callback) (); - plugin_set_ctx (old_ctx); - - if (status != 0) - { - ERROR ("Initialization of plugin `%s' " - "failed with status %i. " - "Plugin will be unloaded.", - le->key, status); - /* Plugins that register read callbacks from the init - * callback should take care of appropriate error - * handling themselves. */ - /* FIXME: Unload _all_ functions */ - plugin_unregister_read (le->key); - ret = -1; - } - - le = le->next; - } - - start_write_threads ((size_t) write_threads_num); - - max_read_interval = global_option_get_time ("MaxReadInterval", - DEFAULT_MAX_READ_INTERVAL); - - /* Start read-threads */ - if (read_heap != NULL) - { - const char *rt; - int num; - - rt = global_option_get ("ReadThreads"); - num = atoi (rt); - if (num != -1) - start_read_threads ((num > 0) ? ((size_t) num) : 5); - } - return ret; +int plugin_init_all(void) { + char const *chain_name; + llentry_t *le; + int status; + int ret = 0; + + /* Init the value cache */ + uc_init(); + + if (IS_TRUE(global_option_get("CollectInternalStats"))) + record_statistics = 1; + + chain_name = global_option_get("PreCacheChain"); + pre_cache_chain = fc_chain_get_by_name(chain_name); + + chain_name = global_option_get("PostCacheChain"); + post_cache_chain = fc_chain_get_by_name(chain_name); + + write_limit_high = global_option_get_long("WriteQueueLimitHigh", + /* default = */ 0); + if (write_limit_high < 0) { + ERROR("WriteQueueLimitHigh must be positive or zero."); + write_limit_high = 0; + } + + write_limit_low = + global_option_get_long("WriteQueueLimitLow", + /* default = */ write_limit_high / 2); + if (write_limit_low < 0) { + ERROR("WriteQueueLimitLow must be positive or zero."); + write_limit_low = write_limit_high / 2; + } else if (write_limit_low > write_limit_high) { + ERROR("WriteQueueLimitLow must not be larger than " + "WriteQueueLimitHigh."); + write_limit_low = write_limit_high; + } + + write_threads_num = global_option_get_long("WriteThreads", + /* default = */ 5); + if (write_threads_num < 1) { + ERROR("WriteThreads must be positive."); + write_threads_num = 5; + } + + if ((list_init == NULL) && (read_heap == NULL)) + return ret; + + /* Calling all init callbacks before checking if read callbacks + * are available allows the init callbacks to register the read + * callback. */ + le = llist_head(list_init); + while (le != NULL) { + callback_func_t *cf; + plugin_init_cb callback; + plugin_ctx_t old_ctx; + + cf = le->value; + old_ctx = plugin_set_ctx(cf->cf_ctx); + callback = cf->cf_callback; + status = (*callback)(); + plugin_set_ctx(old_ctx); + + if (status != 0) { + ERROR("Initialization of plugin `%s' " + "failed with status %i. " + "Plugin will be unloaded.", + le->key, status); + /* Plugins that register read callbacks from the init + * callback should take care of appropriate error + * handling themselves. */ + /* FIXME: Unload _all_ functions */ + plugin_unregister_read(le->key); + ret = -1; + } + + le = le->next; + } + + start_write_threads((size_t)write_threads_num); + + max_read_interval = + global_option_get_time("MaxReadInterval", DEFAULT_MAX_READ_INTERVAL); + + /* Start read-threads */ + if (read_heap != NULL) { + const char *rt; + int num; + + rt = global_option_get("ReadThreads"); + num = atoi(rt); + if (num != -1) + start_read_threads((num > 0) ? ((size_t)num) : 5); + } + return ret; } /* void plugin_init_all */ /* TODO: Rename this function. */ -void plugin_read_all (void) -{ - if(record_statistics) { - plugin_update_internal_statistics (); - } - uc_check_timeout (); +void plugin_read_all(void) { + if (record_statistics) { + plugin_update_internal_statistics(); + } + uc_check_timeout(); - return; + return; } /* void plugin_read_all */ /* Read function called when the `-T' command line argument is given. */ -int plugin_read_all_once (void) -{ - int status; - int return_status = 0; - - if (read_heap == NULL) - { - NOTICE ("No read-functions are registered."); - return (0); - } - - while (42) - { - read_func_t *rf; - plugin_ctx_t old_ctx; - - rf = c_heap_get_root (read_heap); - if (rf == NULL) - break; - - old_ctx = plugin_set_ctx (rf->rf_ctx); - - if (rf->rf_type == RF_SIMPLE) - { - int (*callback) (void); - - callback = rf->rf_callback; - status = (*callback) (); - } - else - { - plugin_read_cb callback; - - callback = rf->rf_callback; - status = (*callback) (&rf->rf_udata); - } - - plugin_set_ctx (old_ctx); - - if (status != 0) - { - NOTICE ("read-function of plugin `%s' failed.", - rf->rf_name); - return_status = -1; - } - - sfree (rf->rf_name); - destroy_callback ((void *) rf); - } - - return (return_status); +int plugin_read_all_once(void) { + int status; + int return_status = 0; + + if (read_heap == NULL) { + NOTICE("No read-functions are registered."); + return (0); + } + + while (42) { + read_func_t *rf; + plugin_ctx_t old_ctx; + + rf = c_heap_get_root(read_heap); + if (rf == NULL) + break; + + old_ctx = plugin_set_ctx(rf->rf_ctx); + + if (rf->rf_type == RF_SIMPLE) { + int (*callback)(void); + + callback = rf->rf_callback; + status = (*callback)(); + } else { + plugin_read_cb callback; + + callback = rf->rf_callback; + status = (*callback)(&rf->rf_udata); + } + + plugin_set_ctx(old_ctx); + + if (status != 0) { + NOTICE("read-function of plugin `%s' failed.", rf->rf_name); + return_status = -1; + } + + sfree(rf->rf_name); + destroy_callback((void *)rf); + } + + return (return_status); } /* int plugin_read_all_once */ -int plugin_write (const char *plugin, /* {{{ */ - const data_set_t *ds, const value_list_t *vl) -{ +int plugin_write(const char *plugin, /* {{{ */ + const data_set_t *ds, const value_list_t *vl) { llentry_t *le; int status; @@ -1907,33 +1726,29 @@ int plugin_write (const char *plugin, /* {{{ */ if (list_write == NULL) return (ENOENT); - if (ds == NULL) - { - ds = plugin_get_ds (vl->type); - if (ds == NULL) - { - ERROR ("plugin_write: Unable to lookup type `%s'.", vl->type); + if (ds == NULL) { + ds = plugin_get_ds(vl->type); + if (ds == NULL) { + ERROR("plugin_write: Unable to lookup type `%s'.", vl->type); return (ENOENT); } } - if (plugin == NULL) - { + if (plugin == NULL) { int success = 0; int failure = 0; - le = llist_head (list_write); - while (le != NULL) - { + le = llist_head(list_write); + while (le != NULL) { callback_func_t *cf = le->value; plugin_write_cb callback; /* do not switch plugin context; rather keep the context (interval) * information of the calling read plugin */ - DEBUG ("plugin: plugin_write: Writing values via %s.", le->key); + DEBUG("plugin: plugin_write: Writing values via %s.", le->key); callback = cf->cf_callback; - status = (*callback) (ds, vl, &cf->cf_udata); + status = (*callback)(ds, vl, &cf->cf_udata); if (status != 0) failure++; else @@ -1946,16 +1761,14 @@ int plugin_write (const char *plugin, /* {{{ */ status = -1; else status = 0; - } - else /* plugin != NULL */ + } else /* plugin != NULL */ { callback_func_t *cf; plugin_write_cb callback; - le = llist_head (list_write); - while (le != NULL) - { - if (strcasecmp (plugin, le->key) == 0) + le = llist_head(list_write); + while (le != NULL) { + if (strcasecmp(plugin, le->key) == 0) break; le = le->next; @@ -1969,148 +1782,137 @@ int plugin_write (const char *plugin, /* {{{ */ /* do not switch plugin context; rather keep the context (interval) * information of the calling read plugin */ - DEBUG ("plugin: plugin_write: Writing values via %s.", le->key); + DEBUG("plugin: plugin_write: Writing values via %s.", le->key); callback = cf->cf_callback; - status = (*callback) (ds, vl, &cf->cf_udata); + status = (*callback)(ds, vl, &cf->cf_udata); } return (status); } /* }}} int plugin_write */ -int plugin_flush (const char *plugin, cdtime_t timeout, const char *identifier) -{ +int plugin_flush(const char *plugin, cdtime_t timeout, const char *identifier) { llentry_t *le; if (list_flush == NULL) return (0); - le = llist_head (list_flush); - while (le != NULL) - { + le = llist_head(list_flush); + while (le != NULL) { callback_func_t *cf; plugin_flush_cb callback; plugin_ctx_t old_ctx; - if ((plugin != NULL) - && (strcmp (plugin, le->key) != 0)) - { + if ((plugin != NULL) && (strcmp(plugin, le->key) != 0)) { le = le->next; continue; } cf = le->value; - old_ctx = plugin_set_ctx (cf->cf_ctx); + old_ctx = plugin_set_ctx(cf->cf_ctx); callback = cf->cf_callback; - (*callback) (timeout, identifier, &cf->cf_udata); + (*callback)(timeout, identifier, &cf->cf_udata); - plugin_set_ctx (old_ctx); + plugin_set_ctx(old_ctx); le = le->next; } return (0); } /* int plugin_flush */ -int plugin_shutdown_all (void) -{ - llentry_t *le; - int ret = 0; // Assume success. - - destroy_all_callbacks (&list_init); - - stop_read_threads (); - - pthread_mutex_lock (&read_lock); - llist_destroy (read_list); - read_list = NULL; - pthread_mutex_unlock (&read_lock); - - destroy_read_heap (); - - /* blocks until all write threads have shut down. */ - stop_write_threads (); - - /* ask all plugins to write out the state they kept. */ - plugin_flush (/* plugin = */ NULL, - /* timeout = */ 0, - /* identifier = */ NULL); - - le = NULL; - if (list_shutdown != NULL) - le = llist_head (list_shutdown); - - while (le != NULL) - { - callback_func_t *cf; - plugin_shutdown_cb callback; - plugin_ctx_t old_ctx; - - cf = le->value; - old_ctx = plugin_set_ctx (cf->cf_ctx); - callback = cf->cf_callback; - - /* Advance the pointer before calling the callback allows - * shutdown functions to unregister themselves. If done the - * other way around the memory `le' points to will be freed - * after callback returns. */ - le = le->next; - - if ((*callback) () != 0) - ret = -1; - - plugin_set_ctx (old_ctx); - } - - /* Write plugins which use the `user_data' pointer usually need the - * same data available to the flush callback. If this is the case, set - * the free_function to NULL when registering the flush callback and to - * the real free function when registering the write callback. This way - * the data isn't freed twice. */ - destroy_all_callbacks (&list_flush); - destroy_all_callbacks (&list_missing); - destroy_all_callbacks (&list_write); - - destroy_all_callbacks (&list_notification); - destroy_all_callbacks (&list_shutdown); - destroy_all_callbacks (&list_log); - - plugin_free_loaded (); - plugin_free_data_sets (); - return (ret); +int plugin_shutdown_all(void) { + llentry_t *le; + int ret = 0; // Assume success. + + destroy_all_callbacks(&list_init); + + stop_read_threads(); + + pthread_mutex_lock(&read_lock); + llist_destroy(read_list); + read_list = NULL; + pthread_mutex_unlock(&read_lock); + + destroy_read_heap(); + + /* blocks until all write threads have shut down. */ + stop_write_threads(); + + /* ask all plugins to write out the state they kept. */ + plugin_flush(/* plugin = */ NULL, + /* timeout = */ 0, + /* identifier = */ NULL); + + le = NULL; + if (list_shutdown != NULL) + le = llist_head(list_shutdown); + + while (le != NULL) { + callback_func_t *cf; + plugin_shutdown_cb callback; + plugin_ctx_t old_ctx; + + cf = le->value; + old_ctx = plugin_set_ctx(cf->cf_ctx); + callback = cf->cf_callback; + + /* Advance the pointer before calling the callback allows + * shutdown functions to unregister themselves. If done the + * other way around the memory `le' points to will be freed + * after callback returns. */ + le = le->next; + + if ((*callback)() != 0) + ret = -1; + + plugin_set_ctx(old_ctx); + } + + /* Write plugins which use the `user_data' pointer usually need the + * same data available to the flush callback. If this is the case, set + * the free_function to NULL when registering the flush callback and to + * the real free function when registering the write callback. This way + * the data isn't freed twice. */ + destroy_all_callbacks(&list_flush); + destroy_all_callbacks(&list_missing); + destroy_all_callbacks(&list_write); + + destroy_all_callbacks(&list_notification); + destroy_all_callbacks(&list_shutdown); + destroy_all_callbacks(&list_log); + + plugin_free_loaded(); + plugin_free_data_sets(); + return (ret); } /* void plugin_shutdown_all */ -int plugin_dispatch_missing (const value_list_t *vl) /* {{{ */ +int plugin_dispatch_missing(const value_list_t *vl) /* {{{ */ { llentry_t *le; if (list_missing == NULL) return (0); - le = llist_head (list_missing); - while (le != NULL) - { + le = llist_head(list_missing); + while (le != NULL) { callback_func_t *cf; plugin_missing_cb callback; plugin_ctx_t old_ctx; int status; cf = le->value; - old_ctx = plugin_set_ctx (cf->cf_ctx); + old_ctx = plugin_set_ctx(cf->cf_ctx); callback = cf->cf_callback; - status = (*callback) (vl, &cf->cf_udata); - plugin_set_ctx (old_ctx); - if (status != 0) - { - if (status < 0) - { - ERROR ("plugin_dispatch_missing: Callback function \"%s\" " - "failed with status %i.", - le->key, status); + status = (*callback)(vl, &cf->cf_udata); + plugin_set_ctx(old_ctx); + if (status != 0) { + if (status < 0) { + ERROR("plugin_dispatch_missing: Callback function \"%s\" " + "failed with status %i.", + le->key, status); return (status); - } - else - { + } else { return (0); } } @@ -2120,508 +1922,460 @@ int plugin_dispatch_missing (const value_list_t *vl) /* {{{ */ return (0); } /* int }}} plugin_dispatch_missing */ -static int plugin_dispatch_values_internal (value_list_t *vl) -{ - int status; - static c_complain_t no_write_complaint = C_COMPLAIN_INIT_STATIC; - - data_set_t *ds; - - _Bool free_meta_data = 0; - - assert (vl != NULL); - - /* These fields are initialized by plugin_value_list_clone() if needed: */ - assert (vl->host[0] != 0); - assert (vl->time != 0); /* The time is determined at _enqueue_ time. */ - assert (vl->interval != 0); - - if (vl->type[0] == 0 || vl->values == NULL || vl->values_len < 1) - { - ERROR ("plugin_dispatch_values: Invalid value list " - "from plugin %s.", vl->plugin); - return (-1); - } - - /* Free meta data only if the calling function didn't specify any. In - * this case matches and targets may add some and the calling function - * may not expect (and therefore free) that data. */ - if (vl->meta == NULL) - free_meta_data = 1; - - if (list_write == NULL) - c_complain_once (LOG_WARNING, &no_write_complaint, - "plugin_dispatch_values: No write callback has been " - "registered. Please load at least one output plugin, " - "if you want the collected data to be stored."); - - if (data_sets == NULL) - { - ERROR ("plugin_dispatch_values: No data sets registered. " - "Could the types database be read? Check " - "your `TypesDB' setting!"); - return (-1); - } - - if (c_avl_get (data_sets, vl->type, (void *) &ds) != 0) - { - char ident[6 * DATA_MAX_NAME_LEN]; - - FORMAT_VL (ident, sizeof (ident), vl); - INFO ("plugin_dispatch_values: Dataset not found: %s " - "(from \"%s\"), check your types.db!", - vl->type, ident); - return (-1); - } - - DEBUG ("plugin_dispatch_values: time = %.3f; interval = %.3f; " - "host = %s; " - "plugin = %s; plugin_instance = %s; " - "type = %s; type_instance = %s;", - CDTIME_T_TO_DOUBLE (vl->time), - CDTIME_T_TO_DOUBLE (vl->interval), - vl->host, - vl->plugin, vl->plugin_instance, - vl->type, vl->type_instance); +static int plugin_dispatch_values_internal(value_list_t *vl) { + int status; + static c_complain_t no_write_complaint = C_COMPLAIN_INIT_STATIC; + + data_set_t *ds; + + _Bool free_meta_data = 0; + + assert(vl != NULL); + + /* These fields are initialized by plugin_value_list_clone() if needed: */ + assert(vl->host[0] != 0); + assert(vl->time != 0); /* The time is determined at _enqueue_ time. */ + assert(vl->interval != 0); + + if (vl->type[0] == 0 || vl->values == NULL || vl->values_len < 1) { + ERROR("plugin_dispatch_values: Invalid value list " + "from plugin %s.", + vl->plugin); + return (-1); + } + + /* Free meta data only if the calling function didn't specify any. In + * this case matches and targets may add some and the calling function + * may not expect (and therefore free) that data. */ + if (vl->meta == NULL) + free_meta_data = 1; + + if (list_write == NULL) + c_complain_once(LOG_WARNING, &no_write_complaint, + "plugin_dispatch_values: No write callback has been " + "registered. Please load at least one output plugin, " + "if you want the collected data to be stored."); + + if (data_sets == NULL) { + ERROR("plugin_dispatch_values: No data sets registered. " + "Could the types database be read? Check " + "your `TypesDB' setting!"); + return (-1); + } + + if (c_avl_get(data_sets, vl->type, (void *)&ds) != 0) { + char ident[6 * DATA_MAX_NAME_LEN]; + + FORMAT_VL(ident, sizeof(ident), vl); + INFO("plugin_dispatch_values: Dataset not found: %s " + "(from \"%s\"), check your types.db!", + vl->type, ident); + return (-1); + } + + DEBUG("plugin_dispatch_values: time = %.3f; interval = %.3f; " + "host = %s; " + "plugin = %s; plugin_instance = %s; " + "type = %s; type_instance = %s;", + CDTIME_T_TO_DOUBLE(vl->time), CDTIME_T_TO_DOUBLE(vl->interval), + vl->host, vl->plugin, vl->plugin_instance, vl->type, vl->type_instance); #if COLLECT_DEBUG - assert (0 == strcmp (ds->type, vl->type)); + assert(0 == strcmp(ds->type, vl->type)); #else - if (0 != strcmp (ds->type, vl->type)) - WARNING ("plugin_dispatch_values: (ds->type = %s) != (vl->type = %s)", - ds->type, vl->type); + if (0 != strcmp(ds->type, vl->type)) + WARNING("plugin_dispatch_values: (ds->type = %s) != (vl->type = %s)", + ds->type, vl->type); #endif #if COLLECT_DEBUG - assert (ds->ds_num == vl->values_len); + assert(ds->ds_num == vl->values_len); #else - if (ds->ds_num != vl->values_len) - { - ERROR ("plugin_dispatch_values: ds->type = %s: " - "(ds->ds_num = %zu) != " - "(vl->values_len = %zu)", - ds->type, ds->ds_num, vl->values_len); - return (-1); - } + if (ds->ds_num != vl->values_len) { + ERROR("plugin_dispatch_values: ds->type = %s: " + "(ds->ds_num = %zu) != " + "(vl->values_len = %zu)", + ds->type, ds->ds_num, vl->values_len); + return (-1); + } #endif - escape_slashes (vl->host, sizeof (vl->host)); - escape_slashes (vl->plugin, sizeof (vl->plugin)); - escape_slashes (vl->plugin_instance, sizeof (vl->plugin_instance)); - escape_slashes (vl->type, sizeof (vl->type)); - escape_slashes (vl->type_instance, sizeof (vl->type_instance)); - - if (pre_cache_chain != NULL) - { - status = fc_process_chain (ds, vl, pre_cache_chain); - if (status < 0) - { - WARNING ("plugin_dispatch_values: Running the " - "pre-cache chain failed with " - "status %i (%#x).", - status, status); - } - else if (status == FC_TARGET_STOP) - return (0); - } - - /* Update the value cache */ - uc_update (ds, vl); - - if (post_cache_chain != NULL) - { - status = fc_process_chain (ds, vl, post_cache_chain); - if (status < 0) - { - WARNING ("plugin_dispatch_values: Running the " - "post-cache chain failed with " - "status %i (%#x).", - status, status); - } - } - else - fc_default_action (ds, vl); - - if ((free_meta_data != 0) && (vl->meta != NULL)) - { - meta_data_destroy (vl->meta); - vl->meta = NULL; - } - - return (0); + escape_slashes(vl->host, sizeof(vl->host)); + escape_slashes(vl->plugin, sizeof(vl->plugin)); + escape_slashes(vl->plugin_instance, sizeof(vl->plugin_instance)); + escape_slashes(vl->type, sizeof(vl->type)); + escape_slashes(vl->type_instance, sizeof(vl->type_instance)); + + if (pre_cache_chain != NULL) { + status = fc_process_chain(ds, vl, pre_cache_chain); + if (status < 0) { + WARNING("plugin_dispatch_values: Running the " + "pre-cache chain failed with " + "status %i (%#x).", + status, status); + } else if (status == FC_TARGET_STOP) + return (0); + } + + /* Update the value cache */ + uc_update(ds, vl); + + if (post_cache_chain != NULL) { + status = fc_process_chain(ds, vl, post_cache_chain); + if (status < 0) { + WARNING("plugin_dispatch_values: Running the " + "post-cache chain failed with " + "status %i (%#x).", + status, status); + } + } else + fc_default_action(ds, vl); + + if ((free_meta_data != 0) && (vl->meta != NULL)) { + meta_data_destroy(vl->meta); + vl->meta = NULL; + } + + return (0); } /* int plugin_dispatch_values_internal */ -static double get_drop_probability (void) /* {{{ */ +static double get_drop_probability(void) /* {{{ */ { - long pos; - long size; - long wql; + long pos; + long size; + long wql; - pthread_mutex_lock (&write_lock); - wql = write_queue_length; - pthread_mutex_unlock (&write_lock); + pthread_mutex_lock(&write_lock); + wql = write_queue_length; + pthread_mutex_unlock(&write_lock); - if (wql < write_limit_low) - return (0.0); - if (wql >= write_limit_high) - return (1.0); + if (wql < write_limit_low) + return (0.0); + if (wql >= write_limit_high) + return (1.0); - pos = 1 + wql - write_limit_low; - size = 1 + write_limit_high - write_limit_low; + pos = 1 + wql - write_limit_low; + size = 1 + write_limit_high - write_limit_low; - return (((double) pos) / ((double) size)); + return (((double)pos) / ((double)size)); } /* }}} double get_drop_probability */ -static _Bool check_drop_value (void) /* {{{ */ +static _Bool check_drop_value(void) /* {{{ */ { - static cdtime_t last_message_time = 0; - static pthread_mutex_t last_message_lock = PTHREAD_MUTEX_INITIALIZER; - - double p; - double q; - int status; - - if (write_limit_high == 0) - return (0); - - p = get_drop_probability (); - if (p == 0.0) - return (0); - - status = pthread_mutex_trylock (&last_message_lock); - if (status == 0) - { - cdtime_t now; - - now = cdtime (); - if ((now - last_message_time) > TIME_T_TO_CDTIME_T (1)) - { - last_message_time = now; - ERROR ("plugin_dispatch_values: Low water mark " - "reached. Dropping %.0f%% of metrics.", - 100.0 * p); - } - pthread_mutex_unlock (&last_message_lock); - } - - if (p == 1.0) - return (1); - - q = cdrand_d (); - if (q > p) - return (1); - else - return (0); + static cdtime_t last_message_time = 0; + static pthread_mutex_t last_message_lock = PTHREAD_MUTEX_INITIALIZER; + + double p; + double q; + int status; + + if (write_limit_high == 0) + return (0); + + p = get_drop_probability(); + if (p == 0.0) + return (0); + + status = pthread_mutex_trylock(&last_message_lock); + if (status == 0) { + cdtime_t now; + + now = cdtime(); + if ((now - last_message_time) > TIME_T_TO_CDTIME_T(1)) { + last_message_time = now; + ERROR("plugin_dispatch_values: Low water mark " + "reached. Dropping %.0f%% of metrics.", + 100.0 * p); + } + pthread_mutex_unlock(&last_message_lock); + } + + if (p == 1.0) + return (1); + + q = cdrand_d(); + if (q > p) + return (1); + else + return (0); } /* }}} _Bool check_drop_value */ -int plugin_dispatch_values (value_list_t const *vl) -{ - int status; - static pthread_mutex_t statistics_lock = PTHREAD_MUTEX_INITIALIZER; - - if (check_drop_value ()) { - if(record_statistics) { - pthread_mutex_lock(&statistics_lock); - stats_values_dropped++; - pthread_mutex_unlock(&statistics_lock); - } - return (0); - } - - status = plugin_write_enqueue (vl); - if (status != 0) - { - char errbuf[1024]; - ERROR ("plugin_dispatch_values: plugin_write_enqueue failed " - "with status %i (%s).", status, - sstrerror (status, errbuf, sizeof (errbuf))); - return (status); - } - - return (0); +int plugin_dispatch_values(value_list_t const *vl) { + int status; + static pthread_mutex_t statistics_lock = PTHREAD_MUTEX_INITIALIZER; + + if (check_drop_value()) { + if (record_statistics) { + pthread_mutex_lock(&statistics_lock); + stats_values_dropped++; + pthread_mutex_unlock(&statistics_lock); + } + return (0); + } + + status = plugin_write_enqueue(vl); + if (status != 0) { + char errbuf[1024]; + ERROR("plugin_dispatch_values: plugin_write_enqueue failed " + "with status %i (%s).", + status, sstrerror(status, errbuf, sizeof(errbuf))); + return (status); + } + + return (0); } -__attribute__((sentinel)) -int plugin_dispatch_multivalue (value_list_t const *template, /* {{{ */ - _Bool store_percentage, int store_type, ...) -{ - value_list_t *vl; - int failed = 0; - gauge_t sum = 0.0; - va_list ap; - - assert (template->values_len == 1); - - /* Calculate sum for Gauge to calculate percent if needed */ - if (DS_TYPE_GAUGE == store_type) { - va_start (ap, store_type); - while (42) - { - char const *name; - gauge_t value; - - name = va_arg (ap, char const *); - if (name == NULL) - break; - - value = va_arg (ap, gauge_t); - if (!isnan (value)) - sum += value; - } - va_end (ap); - } - - - vl = plugin_value_list_clone (template); - /* plugin_value_list_clone makes sure vl->time is set to non-zero. */ - if (store_percentage) - sstrncpy (vl->type, "percent", sizeof (vl->type)); - - va_start (ap, store_type); - while (42) - { - char const *name; - int status; - - /* Set the type instance. */ - name = va_arg (ap, char const *); - if (name == NULL) - break; - sstrncpy (vl->type_instance, name, sizeof (vl->type_instance)); - - /* Set the value. */ - switch (store_type) - { - case DS_TYPE_GAUGE: - vl->values[0].gauge = va_arg (ap, gauge_t); - if (store_percentage) - vl->values[0].gauge *= sum ? (100.0 / sum) : NAN; - break; - case DS_TYPE_ABSOLUTE: - vl->values[0].absolute = va_arg (ap, absolute_t); - break; - case DS_TYPE_COUNTER: - vl->values[0].counter = va_arg (ap, counter_t); - break; - case DS_TYPE_DERIVE: - vl->values[0].derive = va_arg (ap, derive_t); - break; - default: - ERROR ("plugin_dispatch_multivalue: given store_type is incorrect."); - failed++; - } - - - status = plugin_write_enqueue (vl); - if (status != 0) - failed++; - } - va_end (ap); - - plugin_value_list_free (vl); - return (failed); +__attribute__((sentinel)) int +plugin_dispatch_multivalue(value_list_t const *template, /* {{{ */ + _Bool store_percentage, int store_type, ...) { + value_list_t *vl; + int failed = 0; + gauge_t sum = 0.0; + va_list ap; + + assert(template->values_len == 1); + + /* Calculate sum for Gauge to calculate percent if needed */ + if (DS_TYPE_GAUGE == store_type) { + va_start(ap, store_type); + while (42) { + char const *name; + gauge_t value; + + name = va_arg(ap, char const *); + if (name == NULL) + break; + + value = va_arg(ap, gauge_t); + if (!isnan(value)) + sum += value; + } + va_end(ap); + } + + vl = plugin_value_list_clone(template); + /* plugin_value_list_clone makes sure vl->time is set to non-zero. */ + if (store_percentage) + sstrncpy(vl->type, "percent", sizeof(vl->type)); + + va_start(ap, store_type); + while (42) { + char const *name; + int status; + + /* Set the type instance. */ + name = va_arg(ap, char const *); + if (name == NULL) + break; + sstrncpy(vl->type_instance, name, sizeof(vl->type_instance)); + + /* Set the value. */ + switch (store_type) { + case DS_TYPE_GAUGE: + vl->values[0].gauge = va_arg(ap, gauge_t); + if (store_percentage) + vl->values[0].gauge *= sum ? (100.0 / sum) : NAN; + break; + case DS_TYPE_ABSOLUTE: + vl->values[0].absolute = va_arg(ap, absolute_t); + break; + case DS_TYPE_COUNTER: + vl->values[0].counter = va_arg(ap, counter_t); + break; + case DS_TYPE_DERIVE: + vl->values[0].derive = va_arg(ap, derive_t); + break; + default: + ERROR("plugin_dispatch_multivalue: given store_type is incorrect."); + failed++; + } + + status = plugin_write_enqueue(vl); + if (status != 0) + failed++; + } + va_end(ap); + + plugin_value_list_free(vl); + return (failed); } /* }}} int plugin_dispatch_multivalue */ -int plugin_dispatch_notification (const notification_t *notif) -{ - llentry_t *le; - /* Possible TODO: Add flap detection here */ - - DEBUG ("plugin_dispatch_notification: severity = %i; message = %s; " - "time = %.3f; host = %s;", - notif->severity, notif->message, - CDTIME_T_TO_DOUBLE (notif->time), notif->host); - - /* Nobody cares for notifications */ - if (list_notification == NULL) - return (-1); - - le = llist_head (list_notification); - while (le != NULL) - { - callback_func_t *cf; - plugin_notification_cb callback; - int status; - - /* do not switch plugin context; rather keep the context - * (interval) information of the calling plugin */ - - cf = le->value; - callback = cf->cf_callback; - status = (*callback) (notif, &cf->cf_udata); - if (status != 0) - { - WARNING ("plugin_dispatch_notification: Notification " - "callback %s returned %i.", - le->key, status); - } - - le = le->next; - } - - return (0); +int plugin_dispatch_notification(const notification_t *notif) { + llentry_t *le; + /* Possible TODO: Add flap detection here */ + + DEBUG("plugin_dispatch_notification: severity = %i; message = %s; " + "time = %.3f; host = %s;", + notif->severity, notif->message, CDTIME_T_TO_DOUBLE(notif->time), + notif->host); + + /* Nobody cares for notifications */ + if (list_notification == NULL) + return (-1); + + le = llist_head(list_notification); + while (le != NULL) { + callback_func_t *cf; + plugin_notification_cb callback; + int status; + + /* do not switch plugin context; rather keep the context + * (interval) information of the calling plugin */ + + cf = le->value; + callback = cf->cf_callback; + status = (*callback)(notif, &cf->cf_udata); + if (status != 0) { + WARNING("plugin_dispatch_notification: Notification " + "callback %s returned %i.", + le->key, status); + } + + le = le->next; + } + + return (0); } /* int plugin_dispatch_notification */ -void plugin_log (int level, const char *format, ...) -{ - char msg[1024]; - va_list ap; - llentry_t *le; +void plugin_log(int level, const char *format, ...) { + char msg[1024]; + va_list ap; + llentry_t *le; #if !COLLECT_DEBUG - if (level >= LOG_DEBUG) - return; + if (level >= LOG_DEBUG) + return; #endif - va_start (ap, format); - vsnprintf (msg, sizeof (msg), format, ap); - msg[sizeof (msg) - 1] = '\0'; - va_end (ap); + va_start(ap, format); + vsnprintf(msg, sizeof(msg), format, ap); + msg[sizeof(msg) - 1] = '\0'; + va_end(ap); - if (list_log == NULL) - { - fprintf (stderr, "%s\n", msg); - return; - } + if (list_log == NULL) { + fprintf(stderr, "%s\n", msg); + return; + } - le = llist_head (list_log); - while (le != NULL) - { - callback_func_t *cf; - plugin_log_cb callback; + le = llist_head(list_log); + while (le != NULL) { + callback_func_t *cf; + plugin_log_cb callback; - cf = le->value; - callback = cf->cf_callback; + cf = le->value; + callback = cf->cf_callback; - /* do not switch plugin context; rather keep the context - * (interval) information of the calling plugin */ + /* do not switch plugin context; rather keep the context + * (interval) information of the calling plugin */ - (*callback) (level, msg, &cf->cf_udata); + (*callback)(level, msg, &cf->cf_udata); - le = le->next; - } + le = le->next; + } } /* void plugin_log */ -int parse_log_severity (const char *severity) -{ - int log_level = -1; - - if ((0 == strcasecmp (severity, "emerg")) - || (0 == strcasecmp (severity, "alert")) - || (0 == strcasecmp (severity, "crit")) - || (0 == strcasecmp (severity, "err"))) - log_level = LOG_ERR; - else if (0 == strcasecmp (severity, "warning")) - log_level = LOG_WARNING; - else if (0 == strcasecmp (severity, "notice")) - log_level = LOG_NOTICE; - else if (0 == strcasecmp (severity, "info")) - log_level = LOG_INFO; +int parse_log_severity(const char *severity) { + int log_level = -1; + + if ((0 == strcasecmp(severity, "emerg")) || + (0 == strcasecmp(severity, "alert")) || + (0 == strcasecmp(severity, "crit")) || (0 == strcasecmp(severity, "err"))) + log_level = LOG_ERR; + else if (0 == strcasecmp(severity, "warning")) + log_level = LOG_WARNING; + else if (0 == strcasecmp(severity, "notice")) + log_level = LOG_NOTICE; + else if (0 == strcasecmp(severity, "info")) + log_level = LOG_INFO; #if COLLECT_DEBUG - else if (0 == strcasecmp (severity, "debug")) - log_level = LOG_DEBUG; + else if (0 == strcasecmp(severity, "debug")) + log_level = LOG_DEBUG; #endif /* COLLECT_DEBUG */ - return (log_level); + return (log_level); } /* int parse_log_severity */ -int parse_notif_severity (const char *severity) -{ - int notif_severity = -1; +int parse_notif_severity(const char *severity) { + int notif_severity = -1; - if (strcasecmp (severity, "FAILURE") == 0) - notif_severity = NOTIF_FAILURE; - else if (strcmp (severity, "OKAY") == 0) - notif_severity = NOTIF_OKAY; - else if ((strcmp (severity, "WARNING") == 0) - || (strcmp (severity, "WARN") == 0)) - notif_severity = NOTIF_WARNING; + if (strcasecmp(severity, "FAILURE") == 0) + notif_severity = NOTIF_FAILURE; + else if (strcmp(severity, "OKAY") == 0) + notif_severity = NOTIF_OKAY; + else if ((strcmp(severity, "WARNING") == 0) || + (strcmp(severity, "WARN") == 0)) + notif_severity = NOTIF_WARNING; - return (notif_severity); + return (notif_severity); } /* int parse_notif_severity */ -const data_set_t *plugin_get_ds (const char *name) -{ - data_set_t *ds; +const data_set_t *plugin_get_ds(const char *name) { + data_set_t *ds; - if (data_sets == NULL) - { - ERROR ("plugin_get_ds: No data sets are defined yet."); - return (NULL); - } + if (data_sets == NULL) { + ERROR("plugin_get_ds: No data sets are defined yet."); + return (NULL); + } - if (c_avl_get (data_sets, name, (void *) &ds) != 0) - { - DEBUG ("No such dataset registered: %s", name); - return (NULL); - } + if (c_avl_get(data_sets, name, (void *)&ds) != 0) { + DEBUG("No such dataset registered: %s", name); + return (NULL); + } - return (ds); + return (ds); } /* data_set_t *plugin_get_ds */ -static int plugin_notification_meta_add (notification_t *n, - const char *name, - enum notification_meta_type_e type, - const void *value) -{ +static int plugin_notification_meta_add(notification_t *n, const char *name, + enum notification_meta_type_e type, + const void *value) { notification_meta_t *meta; notification_meta_t *tail; - if ((n == NULL) || (name == NULL) || (value == NULL)) - { - ERROR ("plugin_notification_meta_add: A pointer is NULL!"); + if ((n == NULL) || (name == NULL) || (value == NULL)) { + ERROR("plugin_notification_meta_add: A pointer is NULL!"); return (-1); } - meta = calloc (1, sizeof (*meta)); - if (meta == NULL) - { - ERROR ("plugin_notification_meta_add: calloc failed."); + meta = calloc(1, sizeof(*meta)); + if (meta == NULL) { + ERROR("plugin_notification_meta_add: calloc failed."); return (-1); } - sstrncpy (meta->name, name, sizeof (meta->name)); + sstrncpy(meta->name, name, sizeof(meta->name)); meta->type = type; - switch (type) - { - case NM_TYPE_STRING: - { - meta->nm_value.nm_string = strdup ((const char *) value); - if (meta->nm_value.nm_string == NULL) - { - ERROR ("plugin_notification_meta_add: strdup failed."); - sfree (meta); - return (-1); - } - break; - } - case NM_TYPE_SIGNED_INT: - { - meta->nm_value.nm_signed_int = *((int64_t *) value); - break; - } - case NM_TYPE_UNSIGNED_INT: - { - meta->nm_value.nm_unsigned_int = *((uint64_t *) value); - break; - } - case NM_TYPE_DOUBLE: - { - meta->nm_value.nm_double = *((double *) value); - break; - } - case NM_TYPE_BOOLEAN: - { - meta->nm_value.nm_boolean = *((_Bool *) value); - break; - } - default: - { - ERROR ("plugin_notification_meta_add: Unknown type: %i", type); - sfree (meta); + switch (type) { + case NM_TYPE_STRING: { + meta->nm_value.nm_string = strdup((const char *)value); + if (meta->nm_value.nm_string == NULL) { + ERROR("plugin_notification_meta_add: strdup failed."); + sfree(meta); return (-1); } + break; + } + case NM_TYPE_SIGNED_INT: { + meta->nm_value.nm_signed_int = *((int64_t *)value); + break; + } + case NM_TYPE_UNSIGNED_INT: { + meta->nm_value.nm_unsigned_int = *((uint64_t *)value); + break; + } + case NM_TYPE_DOUBLE: { + meta->nm_value.nm_double = *((double *)value); + break; + } + case NM_TYPE_BOOLEAN: { + meta->nm_value.nm_boolean = *((_Bool *)value); + break; + } + default: { + ERROR("plugin_notification_meta_add: Unknown type: %i", type); + sfree(meta); + return (-1); + } } /* switch (type) */ meta->next = NULL; @@ -2637,97 +2391,82 @@ static int plugin_notification_meta_add (notification_t *n, return (0); } /* int plugin_notification_meta_add */ -int plugin_notification_meta_add_string (notification_t *n, - const char *name, - const char *value) -{ - return (plugin_notification_meta_add (n, name, NM_TYPE_STRING, value)); +int plugin_notification_meta_add_string(notification_t *n, const char *name, + const char *value) { + return (plugin_notification_meta_add(n, name, NM_TYPE_STRING, value)); } -int plugin_notification_meta_add_signed_int (notification_t *n, - const char *name, - int64_t value) -{ - return (plugin_notification_meta_add (n, name, NM_TYPE_SIGNED_INT, &value)); +int plugin_notification_meta_add_signed_int(notification_t *n, const char *name, + int64_t value) { + return (plugin_notification_meta_add(n, name, NM_TYPE_SIGNED_INT, &value)); } -int plugin_notification_meta_add_unsigned_int (notification_t *n, - const char *name, - uint64_t value) -{ - return (plugin_notification_meta_add (n, name, NM_TYPE_UNSIGNED_INT, &value)); +int plugin_notification_meta_add_unsigned_int(notification_t *n, + const char *name, + uint64_t value) { + return (plugin_notification_meta_add(n, name, NM_TYPE_UNSIGNED_INT, &value)); } -int plugin_notification_meta_add_double (notification_t *n, - const char *name, - double value) -{ - return (plugin_notification_meta_add (n, name, NM_TYPE_DOUBLE, &value)); +int plugin_notification_meta_add_double(notification_t *n, const char *name, + double value) { + return (plugin_notification_meta_add(n, name, NM_TYPE_DOUBLE, &value)); } -int plugin_notification_meta_add_boolean (notification_t *n, - const char *name, - _Bool value) -{ - return (plugin_notification_meta_add (n, name, NM_TYPE_BOOLEAN, &value)); +int plugin_notification_meta_add_boolean(notification_t *n, const char *name, + _Bool value) { + return (plugin_notification_meta_add(n, name, NM_TYPE_BOOLEAN, &value)); } -int plugin_notification_meta_copy (notification_t *dst, - const notification_t *src) -{ - assert (dst != NULL); - assert (src != NULL); - assert (dst != src); - assert ((src->meta == NULL) || (src->meta != dst->meta)); +int plugin_notification_meta_copy(notification_t *dst, + const notification_t *src) { + assert(dst != NULL); + assert(src != NULL); + assert(dst != src); + assert((src->meta == NULL) || (src->meta != dst->meta)); - for (notification_meta_t *meta = src->meta; meta != NULL; meta = meta->next) - { + for (notification_meta_t *meta = src->meta; meta != NULL; meta = meta->next) { if (meta->type == NM_TYPE_STRING) - plugin_notification_meta_add_string (dst, meta->name, - meta->nm_value.nm_string); + plugin_notification_meta_add_string(dst, meta->name, + meta->nm_value.nm_string); else if (meta->type == NM_TYPE_SIGNED_INT) - plugin_notification_meta_add_signed_int (dst, meta->name, - meta->nm_value.nm_signed_int); + plugin_notification_meta_add_signed_int(dst, meta->name, + meta->nm_value.nm_signed_int); else if (meta->type == NM_TYPE_UNSIGNED_INT) - plugin_notification_meta_add_unsigned_int (dst, meta->name, - meta->nm_value.nm_unsigned_int); + plugin_notification_meta_add_unsigned_int(dst, meta->name, + meta->nm_value.nm_unsigned_int); else if (meta->type == NM_TYPE_DOUBLE) - plugin_notification_meta_add_double (dst, meta->name, - meta->nm_value.nm_double); + plugin_notification_meta_add_double(dst, meta->name, + meta->nm_value.nm_double); else if (meta->type == NM_TYPE_BOOLEAN) - plugin_notification_meta_add_boolean (dst, meta->name, - meta->nm_value.nm_boolean); + plugin_notification_meta_add_boolean(dst, meta->name, + meta->nm_value.nm_boolean); } return (0); } /* int plugin_notification_meta_copy */ -int plugin_notification_meta_free (notification_meta_t *n) -{ +int plugin_notification_meta_free(notification_meta_t *n) { notification_meta_t *this; notification_meta_t *next; - if (n == NULL) - { - ERROR ("plugin_notification_meta_free: n == NULL!"); + if (n == NULL) { + ERROR("plugin_notification_meta_free: n == NULL!"); return (-1); } this = n; - while (this != NULL) - { + while (this != NULL) { next = this->next; - if (this->type == NM_TYPE_STRING) - { + if (this->type == NM_TYPE_STRING) { /* Assign to a temporary variable to work around nm_string's const * modifier. */ - void *tmp = (void *) this->nm_value.nm_string; + void *tmp = (void *)this->nm_value.nm_string; - sfree (tmp); + sfree(tmp); this->nm_value.nm_string = NULL; } - sfree (this); + sfree(this); this = next; } @@ -2735,132 +2474,123 @@ int plugin_notification_meta_free (notification_meta_t *n) return (0); } /* int plugin_notification_meta_free */ -static void plugin_ctx_destructor (void *ctx) -{ - sfree (ctx); +static void plugin_ctx_destructor(void *ctx) { + sfree(ctx); } /* void plugin_ctx_destructor */ -static plugin_ctx_t ctx_init = { /* interval = */ 0 }; +static plugin_ctx_t ctx_init = {/* interval = */ 0}; -static plugin_ctx_t *plugin_ctx_create (void) -{ - plugin_ctx_t *ctx; - - ctx = malloc (sizeof (*ctx)); - if (ctx == NULL) { - char errbuf[1024]; - ERROR ("Failed to allocate plugin context: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return NULL; - } - - *ctx = ctx_init; - assert (plugin_ctx_key_initialized); - pthread_setspecific (plugin_ctx_key, ctx); - DEBUG("Created new plugin context."); - return (ctx); +static plugin_ctx_t *plugin_ctx_create(void) { + plugin_ctx_t *ctx; + + ctx = malloc(sizeof(*ctx)); + if (ctx == NULL) { + char errbuf[1024]; + ERROR("Failed to allocate plugin context: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return NULL; + } + + *ctx = ctx_init; + assert(plugin_ctx_key_initialized); + pthread_setspecific(plugin_ctx_key, ctx); + DEBUG("Created new plugin context."); + return (ctx); } /* int plugin_ctx_create */ -void plugin_init_ctx (void) -{ - pthread_key_create (&plugin_ctx_key, plugin_ctx_destructor); - plugin_ctx_key_initialized = 1; +void plugin_init_ctx(void) { + pthread_key_create(&plugin_ctx_key, plugin_ctx_destructor); + plugin_ctx_key_initialized = 1; } /* void plugin_init_ctx */ -plugin_ctx_t plugin_get_ctx (void) -{ - plugin_ctx_t *ctx; +plugin_ctx_t plugin_get_ctx(void) { + plugin_ctx_t *ctx; - assert (plugin_ctx_key_initialized); - ctx = pthread_getspecific (plugin_ctx_key); + assert(plugin_ctx_key_initialized); + ctx = pthread_getspecific(plugin_ctx_key); - if (ctx == NULL) { - ctx = plugin_ctx_create (); - /* this must no happen -- exit() instead? */ - if (ctx == NULL) - return ctx_init; - } + if (ctx == NULL) { + ctx = plugin_ctx_create(); + /* this must no happen -- exit() instead? */ + if (ctx == NULL) + return ctx_init; + } - return (*ctx); + return (*ctx); } /* plugin_ctx_t plugin_get_ctx */ -plugin_ctx_t plugin_set_ctx (plugin_ctx_t ctx) -{ - plugin_ctx_t *c; - plugin_ctx_t old; +plugin_ctx_t plugin_set_ctx(plugin_ctx_t ctx) { + plugin_ctx_t *c; + plugin_ctx_t old; - assert (plugin_ctx_key_initialized); - c = pthread_getspecific (plugin_ctx_key); + assert(plugin_ctx_key_initialized); + c = pthread_getspecific(plugin_ctx_key); - if (c == NULL) { - c = plugin_ctx_create (); - /* this must no happen -- exit() instead? */ - if (c == NULL) - return ctx_init; - } + if (c == NULL) { + c = plugin_ctx_create(); + /* this must no happen -- exit() instead? */ + if (c == NULL) + return ctx_init; + } - old = *c; - *c = ctx; + old = *c; + *c = ctx; - return (old); + return (old); } /* void plugin_set_ctx */ -cdtime_t plugin_get_interval (void) -{ - cdtime_t interval; +cdtime_t plugin_get_interval(void) { + cdtime_t interval; - interval = plugin_get_ctx().interval; - if (interval > 0) - return interval; + interval = plugin_get_ctx().interval; + if (interval > 0) + return interval; - return cf_get_default_interval (); + return cf_get_default_interval(); } /* cdtime_t plugin_get_interval */ typedef struct { - plugin_ctx_t ctx; - void *(*start_routine) (void *); - void *arg; + plugin_ctx_t ctx; + void *(*start_routine)(void *); + void *arg; } plugin_thread_t; -static void *plugin_thread_start (void *arg) -{ - plugin_thread_t *plugin_thread = arg; +static void *plugin_thread_start(void *arg) { + plugin_thread_t *plugin_thread = arg; - void *(*start_routine) (void *) = plugin_thread->start_routine; - void *plugin_arg = plugin_thread->arg; + void *(*start_routine)(void *) = plugin_thread->start_routine; + void *plugin_arg = plugin_thread->arg; - plugin_set_ctx (plugin_thread->ctx); + plugin_set_ctx(plugin_thread->ctx); - sfree (plugin_thread); + sfree(plugin_thread); - return start_routine (plugin_arg); + return start_routine(plugin_arg); } /* void *plugin_thread_start */ -int plugin_thread_create (pthread_t *thread, const pthread_attr_t *attr, - void *(*start_routine) (void *), void *arg, char const *name) -{ - plugin_thread_t *plugin_thread; +int plugin_thread_create(pthread_t *thread, const pthread_attr_t *attr, + void *(*start_routine)(void *), void *arg, + char const *name) { + plugin_thread_t *plugin_thread; - plugin_thread = malloc (sizeof (*plugin_thread)); - if (plugin_thread == NULL) - return ENOMEM; + plugin_thread = malloc(sizeof(*plugin_thread)); + if (plugin_thread == NULL) + return ENOMEM; - plugin_thread->ctx = plugin_get_ctx (); - plugin_thread->start_routine = start_routine; - plugin_thread->arg = arg; + plugin_thread->ctx = plugin_get_ctx(); + plugin_thread->start_routine = start_routine; + plugin_thread->arg = arg; - int ret = pthread_create (thread, attr, - plugin_thread_start, plugin_thread); - if (ret != 0) - { - sfree (plugin_thread); - return ret; - } + int ret = pthread_create(thread, attr, plugin_thread_start, plugin_thread); + if (ret != 0) { + sfree(plugin_thread); + return ret; + } - if (name != NULL) - set_thread_name (*thread, name); + if (name != NULL) + set_thread_name(*thread, name); - return 0; + return 0; } /* int plugin_thread_create */ /* vim: set sw=8 ts=8 noet fdm=marker : */ diff --git a/src/daemon/plugin.h b/src/daemon/plugin.h index 9a9bf497..f6448a58 100644 --- a/src/daemon/plugin.h +++ b/src/daemon/plugin.h @@ -39,55 +39,56 @@ #define PLUGIN_FLAGS_GLOBAL 0x0001 #ifndef DATA_MAX_NAME_LEN -# define DATA_MAX_NAME_LEN 128 +#define DATA_MAX_NAME_LEN 128 #endif -#define DS_TYPE_COUNTER 0 -#define DS_TYPE_GAUGE 1 -#define DS_TYPE_DERIVE 2 +#define DS_TYPE_COUNTER 0 +#define DS_TYPE_GAUGE 1 +#define DS_TYPE_DERIVE 2 #define DS_TYPE_ABSOLUTE 3 -#define DS_TYPE_TO_STRING(t) (t == DS_TYPE_COUNTER) ? "counter" : \ - (t == DS_TYPE_GAUGE) ? "gauge" : \ - (t == DS_TYPE_DERIVE) ? "derive" : \ - (t == DS_TYPE_ABSOLUTE) ? "absolute" : \ - "unknown" - +#define DS_TYPE_TO_STRING(t) \ + (t == DS_TYPE_COUNTER) ? "counter" : (t == DS_TYPE_GAUGE) \ + ? "gauge" \ + : (t == DS_TYPE_DERIVE) \ + ? "derive" \ + : (t == DS_TYPE_ABSOLUTE) \ + ? "absolute" \ + : "unknown" #ifndef LOG_ERR -# define LOG_ERR 3 +#define LOG_ERR 3 #endif #ifndef LOG_WARNING -# define LOG_WARNING 4 +#define LOG_WARNING 4 #endif #ifndef LOG_NOTICE -# define LOG_NOTICE 5 +#define LOG_NOTICE 5 #endif #ifndef LOG_INFO -# define LOG_INFO 6 +#define LOG_INFO 6 #endif #ifndef LOG_DEBUG -# define LOG_DEBUG 7 +#define LOG_DEBUG 7 #endif #define NOTIF_MAX_MSG_LEN 256 #define NOTIF_FAILURE 1 #define NOTIF_WARNING 2 -#define NOTIF_OKAY 4 +#define NOTIF_OKAY 4 #define plugin_interval (plugin_get_ctx().interval) /* * Public data types */ -struct identifier_s -{ - char *host; - char *plugin; - char *plugin_instance; - char *type; - char *type_instance; +struct identifier_s { + char *host; + char *plugin; + char *plugin_instance; + char *type; + char *type_instance; }; typedef struct identifier_s identifier_t; @@ -96,119 +97,108 @@ typedef double gauge_t; typedef int64_t derive_t; typedef uint64_t absolute_t; -union value_u -{ - counter_t counter; - gauge_t gauge; - derive_t derive; - absolute_t absolute; +union value_u { + counter_t counter; + gauge_t gauge; + derive_t derive; + absolute_t absolute; }; typedef union value_u value_t; -struct value_list_s -{ - value_t *values; - size_t values_len; - cdtime_t time; - cdtime_t interval; - char host[DATA_MAX_NAME_LEN]; - char plugin[DATA_MAX_NAME_LEN]; - char plugin_instance[DATA_MAX_NAME_LEN]; - char type[DATA_MAX_NAME_LEN]; - char type_instance[DATA_MAX_NAME_LEN]; - meta_data_t *meta; +struct value_list_s { + value_t *values; + size_t values_len; + cdtime_t time; + cdtime_t interval; + char host[DATA_MAX_NAME_LEN]; + char plugin[DATA_MAX_NAME_LEN]; + char plugin_instance[DATA_MAX_NAME_LEN]; + char type[DATA_MAX_NAME_LEN]; + char type_instance[DATA_MAX_NAME_LEN]; + meta_data_t *meta; }; typedef struct value_list_s value_list_t; -#define VALUE_LIST_INIT { .values = NULL, .meta = NULL } +#define VALUE_LIST_INIT \ + { .values = NULL, .meta = NULL } -struct data_source_s -{ - char name[DATA_MAX_NAME_LEN]; - int type; - double min; - double max; +struct data_source_s { + char name[DATA_MAX_NAME_LEN]; + int type; + double min; + double max; }; typedef struct data_source_s data_source_t; -struct data_set_s -{ - char type[DATA_MAX_NAME_LEN]; - size_t ds_num; - data_source_t *ds; +struct data_set_s { + char type[DATA_MAX_NAME_LEN]; + size_t ds_num; + data_source_t *ds; }; typedef struct data_set_s data_set_t; -enum notification_meta_type_e -{ - NM_TYPE_STRING, - NM_TYPE_SIGNED_INT, - NM_TYPE_UNSIGNED_INT, - NM_TYPE_DOUBLE, - NM_TYPE_BOOLEAN +enum notification_meta_type_e { + NM_TYPE_STRING, + NM_TYPE_SIGNED_INT, + NM_TYPE_UNSIGNED_INT, + NM_TYPE_DOUBLE, + NM_TYPE_BOOLEAN }; -typedef struct notification_meta_s -{ - char name[DATA_MAX_NAME_LEN]; - enum notification_meta_type_e type; - union - { - const char *nm_string; - int64_t nm_signed_int; - uint64_t nm_unsigned_int; - double nm_double; - _Bool nm_boolean; - } nm_value; - struct notification_meta_s *next; +typedef struct notification_meta_s { + char name[DATA_MAX_NAME_LEN]; + enum notification_meta_type_e type; + union { + const char *nm_string; + int64_t nm_signed_int; + uint64_t nm_unsigned_int; + double nm_double; + _Bool nm_boolean; + } nm_value; + struct notification_meta_s *next; } notification_meta_t; -typedef struct notification_s -{ - int severity; - cdtime_t time; - char message[NOTIF_MAX_MSG_LEN]; - char host[DATA_MAX_NAME_LEN]; - char plugin[DATA_MAX_NAME_LEN]; - char plugin_instance[DATA_MAX_NAME_LEN]; - char type[DATA_MAX_NAME_LEN]; - char type_instance[DATA_MAX_NAME_LEN]; - notification_meta_t *meta; +typedef struct notification_s { + int severity; + cdtime_t time; + char message[NOTIF_MAX_MSG_LEN]; + char host[DATA_MAX_NAME_LEN]; + char plugin[DATA_MAX_NAME_LEN]; + char plugin_instance[DATA_MAX_NAME_LEN]; + char type[DATA_MAX_NAME_LEN]; + char type_instance[DATA_MAX_NAME_LEN]; + notification_meta_t *meta; } notification_t; -struct user_data_s -{ - void *data; - void (*free_func) (void *); +struct user_data_s { + void *data; + void (*free_func)(void *); }; typedef struct user_data_s user_data_t; -struct plugin_ctx_s -{ - cdtime_t interval; - cdtime_t flush_interval; - cdtime_t flush_timeout; +struct plugin_ctx_s { + cdtime_t interval; + cdtime_t flush_interval; + cdtime_t flush_timeout; }; typedef struct plugin_ctx_s plugin_ctx_t; /* * Callback types */ -typedef int (*plugin_init_cb) (void); -typedef int (*plugin_read_cb) (user_data_t *); -typedef int (*plugin_write_cb) (const data_set_t *, const value_list_t *, - user_data_t *); -typedef int (*plugin_flush_cb) (cdtime_t timeout, const char *identifier, - user_data_t *); +typedef int (*plugin_init_cb)(void); +typedef int (*plugin_read_cb)(user_data_t *); +typedef int (*plugin_write_cb)(const data_set_t *, const value_list_t *, + user_data_t *); +typedef int (*plugin_flush_cb)(cdtime_t timeout, const char *identifier, + user_data_t *); /* "missing" callback. Returns less than zero on failure, zero if other * callbacks should be called, greater than zero if no more callbacks should be * called. */ -typedef int (*plugin_missing_cb) (const value_list_t *, user_data_t *); -typedef void (*plugin_log_cb) (int severity, const char *message, - user_data_t *); -typedef int (*plugin_shutdown_cb) (void); -typedef int (*plugin_notification_cb) (const notification_t *, - user_data_t *); +typedef int (*plugin_missing_cb)(const value_list_t *, user_data_t *); +typedef void (*plugin_log_cb)(int severity, const char *message, user_data_t *); +typedef int (*plugin_shutdown_cb)(void); +typedef int (*plugin_notification_cb)(const notification_t *, user_data_t *); /* * NAME * plugin_set_dir @@ -222,7 +212,7 @@ typedef int (*plugin_notification_cb) (const notification_t *, * NOTES * If `dir' is NULL the compiled in default `PLUGINDIR' is used. */ -void plugin_set_dir (const char *dir); +void plugin_set_dir(const char *dir); /* * NAME @@ -246,12 +236,12 @@ void plugin_set_dir (const char *dir); * Re-loading an already loaded module is detected and zero is returned in * this case. */ -int plugin_load (const char *name, uint32_t flags); +int plugin_load(const char *name, uint32_t flags); -int plugin_init_all (void); -void plugin_read_all (void); -int plugin_read_all_once (void); -int plugin_shutdown_all (void); +int plugin_init_all(void); +void plugin_read_all(void); +int plugin_read_all_once(void); +int plugin_shutdown_all(void); /* * NAME @@ -280,57 +270,54 @@ int plugin_shutdown_all (void); * This is the function used by the `write' built-in target. May be used by * other target plugins. */ -int plugin_write (const char *plugin, - const data_set_t *ds, const value_list_t *vl); +int plugin_write(const char *plugin, const data_set_t *ds, + const value_list_t *vl); -int plugin_flush (const char *plugin, cdtime_t timeout, const char *identifier); +int plugin_flush(const char *plugin, cdtime_t timeout, const char *identifier); /* * The `plugin_register_*' functions are used to make `config', `init', * `read', `write' and `shutdown' functions known to the plugin * infrastructure. Also, the data-formats are made public like this. */ -int plugin_register_config (const char *name, - int (*callback) (const char *key, const char *val), - const char **keys, int keys_num); -int plugin_register_complex_config (const char *type, - int (*callback) (oconfig_item_t *)); -int plugin_register_init (const char *name, - plugin_init_cb callback); -int plugin_register_read (const char *name, - int (*callback) (void)); +int plugin_register_config(const char *name, + int (*callback)(const char *key, const char *val), + const char **keys, int keys_num); +int plugin_register_complex_config(const char *type, + int (*callback)(oconfig_item_t *)); +int plugin_register_init(const char *name, plugin_init_cb callback); +int plugin_register_read(const char *name, int (*callback)(void)); /* "user_data" will be freed automatically, unless * "plugin_register_complex_read" returns an error (non-zero). */ -int plugin_register_complex_read (const char *group, const char *name, - plugin_read_cb callback, - cdtime_t interval, - user_data_t const *user_data); -int plugin_register_write (const char *name, - plugin_write_cb callback, user_data_t const *user_data); -int plugin_register_flush (const char *name, - plugin_flush_cb callback, user_data_t const *user_data); -int plugin_register_missing (const char *name, - plugin_missing_cb callback, user_data_t const *user_data); -int plugin_register_shutdown (const char *name, - plugin_shutdown_cb callback); -int plugin_register_data_set (const data_set_t *ds); -int plugin_register_log (const char *name, - plugin_log_cb callback, user_data_t const *user_data); -int plugin_register_notification (const char *name, - plugin_notification_cb callback, user_data_t const *user_data); - -int plugin_unregister_config (const char *name); -int plugin_unregister_complex_config (const char *name); -int plugin_unregister_init (const char *name); -int plugin_unregister_read (const char *name); -int plugin_unregister_read_group (const char *group); -int plugin_unregister_write (const char *name); -int plugin_unregister_flush (const char *name); -int plugin_unregister_missing (const char *name); -int plugin_unregister_shutdown (const char *name); -int plugin_unregister_data_set (const char *name); -int plugin_unregister_log (const char *name); -int plugin_unregister_notification (const char *name); +int plugin_register_complex_read(const char *group, const char *name, + plugin_read_cb callback, cdtime_t interval, + user_data_t const *user_data); +int plugin_register_write(const char *name, plugin_write_cb callback, + user_data_t const *user_data); +int plugin_register_flush(const char *name, plugin_flush_cb callback, + user_data_t const *user_data); +int plugin_register_missing(const char *name, plugin_missing_cb callback, + user_data_t const *user_data); +int plugin_register_shutdown(const char *name, plugin_shutdown_cb callback); +int plugin_register_data_set(const data_set_t *ds); +int plugin_register_log(const char *name, plugin_log_cb callback, + user_data_t const *user_data); +int plugin_register_notification(const char *name, + plugin_notification_cb callback, + user_data_t const *user_data); + +int plugin_unregister_config(const char *name); +int plugin_unregister_complex_config(const char *name); +int plugin_unregister_init(const char *name); +int plugin_unregister_read(const char *name); +int plugin_unregister_read_group(const char *group); +int plugin_unregister_write(const char *name); +int plugin_unregister_flush(const char *name); +int plugin_unregister_missing(const char *name); +int plugin_unregister_shutdown(const char *name); +int plugin_unregister_data_set(const char *name); +int plugin_unregister_log(const char *name); +int plugin_unregister_notification(const char *name); /* * NAME @@ -342,7 +329,7 @@ int plugin_unregister_notification (const char *name); * Since some writers dynamically build their name it can be hard for * the configuring person to know it. This function will fill this gap. */ -void plugin_log_available_writers (void); +void plugin_log_available_writers(void); /* * NAME @@ -358,7 +345,7 @@ void plugin_log_available_writers (void); * `vl' Value list of the values that have been read by a `read' * function. */ -int plugin_dispatch_values (value_list_t const *vl); +int plugin_dispatch_values(value_list_t const *vl); /* * NAME @@ -392,62 +379,57 @@ int plugin_dispatch_values (value_list_t const *vl); * RETURNS * The number of values it failed to dispatch (zero on success). */ -__attribute__((sentinel)) -int plugin_dispatch_multivalue (value_list_t const *vl, - _Bool store_percentage, int store_type, ...); +__attribute__((sentinel)) int plugin_dispatch_multivalue(value_list_t const *vl, + _Bool store_percentage, + int store_type, ...); -int plugin_dispatch_missing (const value_list_t *vl); +int plugin_dispatch_missing(const value_list_t *vl); -int plugin_dispatch_notification (const notification_t *notif); +int plugin_dispatch_notification(const notification_t *notif); -void plugin_log (int level, const char *format, ...) - __attribute__ ((format(printf,2,3))); +void plugin_log(int level, const char *format, ...) + __attribute__((format(printf, 2, 3))); /* These functions return the parsed severity or less than zero on failure. */ -int parse_log_severity (const char *severity); -int parse_notif_severity (const char *severity); +int parse_log_severity(const char *severity); +int parse_notif_severity(const char *severity); -#define ERROR(...) plugin_log (LOG_ERR, __VA_ARGS__) -#define WARNING(...) plugin_log (LOG_WARNING, __VA_ARGS__) -#define NOTICE(...) plugin_log (LOG_NOTICE, __VA_ARGS__) -#define INFO(...) plugin_log (LOG_INFO, __VA_ARGS__) +#define ERROR(...) plugin_log(LOG_ERR, __VA_ARGS__) +#define WARNING(...) plugin_log(LOG_WARNING, __VA_ARGS__) +#define NOTICE(...) plugin_log(LOG_NOTICE, __VA_ARGS__) +#define INFO(...) plugin_log(LOG_INFO, __VA_ARGS__) #if COLLECT_DEBUG -# define DEBUG(...) plugin_log (LOG_DEBUG, __VA_ARGS__) -#else /* COLLECT_DEBUG */ -# define DEBUG(...) /* noop */ -#endif /* ! COLLECT_DEBUG */ - -const data_set_t *plugin_get_ds (const char *name); - -int plugin_notification_meta_add_string (notification_t *n, - const char *name, - const char *value); -int plugin_notification_meta_add_signed_int (notification_t *n, - const char *name, - int64_t value); -int plugin_notification_meta_add_unsigned_int (notification_t *n, - const char *name, - uint64_t value); -int plugin_notification_meta_add_double (notification_t *n, - const char *name, - double value); -int plugin_notification_meta_add_boolean (notification_t *n, - const char *name, - _Bool value); - -int plugin_notification_meta_copy (notification_t *dst, - const notification_t *src); - -int plugin_notification_meta_free (notification_meta_t *n); +#define DEBUG(...) plugin_log(LOG_DEBUG, __VA_ARGS__) +#else /* COLLECT_DEBUG */ +#define DEBUG(...) /* noop */ +#endif /* ! COLLECT_DEBUG */ + +const data_set_t *plugin_get_ds(const char *name); + +int plugin_notification_meta_add_string(notification_t *n, const char *name, + const char *value); +int plugin_notification_meta_add_signed_int(notification_t *n, const char *name, + int64_t value); +int plugin_notification_meta_add_unsigned_int(notification_t *n, + const char *name, uint64_t value); +int plugin_notification_meta_add_double(notification_t *n, const char *name, + double value); +int plugin_notification_meta_add_boolean(notification_t *n, const char *name, + _Bool value); + +int plugin_notification_meta_copy(notification_t *dst, + const notification_t *src); + +int plugin_notification_meta_free(notification_meta_t *n); /* * Plugin context management. */ -void plugin_init_ctx (void); +void plugin_init_ctx(void); -plugin_ctx_t plugin_get_ctx (void); -plugin_ctx_t plugin_set_ctx (plugin_ctx_t ctx); +plugin_ctx_t plugin_get_ctx(void); +plugin_ctx_t plugin_set_ctx(plugin_ctx_t ctx); /* * NAME @@ -458,19 +440,20 @@ plugin_ctx_t plugin_set_ctx (plugin_ctx_t ctx); * return value will be strictly greater than zero in all cases. If * everything else fails, it will fall back to 10 seconds. */ -cdtime_t plugin_get_interval (void); +cdtime_t plugin_get_interval(void); /* * Context-aware thread management. */ -int plugin_thread_create (pthread_t *thread, const pthread_attr_t *attr, - void *(*start_routine) (void *), void *arg, char const *name); +int plugin_thread_create(pthread_t *thread, const pthread_attr_t *attr, + void *(*start_routine)(void *), void *arg, + char const *name); /* * Plugins need to implement this */ -void module_register (void); +void module_register(void); #endif /* PLUGIN_H */ diff --git a/src/daemon/plugin_mock.c b/src/daemon/plugin_mock.c index e01e2569..ddfc7890 100644 --- a/src/daemon/plugin_mock.c +++ b/src/daemon/plugin_mock.c @@ -32,61 +32,49 @@ kstat_ctl_t *kc = NULL; char hostname_g[] = "example.com"; -int plugin_register_complex_config (const char *type, int (*callback) (oconfig_item_t *)) -{ +int plugin_register_complex_config(const char *type, + int (*callback)(oconfig_item_t *)) { return ENOTSUP; } -int plugin_register_init (const char *name, plugin_init_cb callback) -{ +int plugin_register_init(const char *name, plugin_init_cb callback) { return ENOTSUP; } -int plugin_register_read (const char *name, int (*callback) (void)) -{ +int plugin_register_read(const char *name, int (*callback)(void)) { return ENOTSUP; } -int plugin_register_shutdown (const char *name, int (*callback) (void)) -{ +int plugin_register_shutdown(const char *name, int (*callback)(void)) { return ENOTSUP; } -int plugin_dispatch_values (value_list_t const *vl) -{ - return ENOTSUP; -} +int plugin_dispatch_values(value_list_t const *vl) { return ENOTSUP; } -int plugin_flush (const char *plugin, cdtime_t timeout, const char *identifier) -{ +int plugin_flush(const char *plugin, cdtime_t timeout, const char *identifier) { return ENOTSUP; } -static data_source_t magic_ds[] = {{ "value", DS_TYPE_DERIVE, 0.0, NAN }}; -static data_set_t magic = { "MAGIC", 1, magic_ds }; -const data_set_t *plugin_get_ds (const char *name) -{ - if (strcmp (name, "MAGIC")) +static data_source_t magic_ds[] = {{"value", DS_TYPE_DERIVE, 0.0, NAN}}; +static data_set_t magic = {"MAGIC", 1, magic_ds}; +const data_set_t *plugin_get_ds(const char *name) { + if (strcmp(name, "MAGIC")) return NULL; return &magic; } -void plugin_log (int level, char const *format, ...) -{ +void plugin_log(int level, char const *format, ...) { char buffer[1024]; va_list ap; - va_start (ap, format); - vsnprintf (buffer, sizeof (buffer), format, ap); - va_end (ap); + va_start(ap, format); + vsnprintf(buffer, sizeof(buffer), format, ap); + va_end(ap); - printf ("plugin_log (%i, \"%s\");\n", level, buffer); + printf("plugin_log (%i, \"%s\");\n", level, buffer); } -cdtime_t plugin_get_interval (void) -{ - return TIME_T_TO_CDTIME_T (10); -} +cdtime_t plugin_get_interval(void) { return TIME_T_TO_CDTIME_T(10); } /* vim: set sw=2 sts=2 et : */ diff --git a/src/daemon/types_list.c b/src/daemon/types_list.c index 34c222c7..b1a7203c 100644 --- a/src/daemon/types_list.c +++ b/src/daemon/types_list.c @@ -28,25 +28,22 @@ #include "common.h" -#include "plugin.h" #include "configfile.h" +#include "plugin.h" #include "types_list.h" -static int parse_ds (data_source_t *dsrc, char *buf, size_t buf_len) -{ +static int parse_ds(data_source_t *dsrc, char *buf, size_t buf_len) { char *dummy; char *saveptr; char *fields[8]; - int fields_num; + int fields_num; - if (buf_len < 11) - { - ERROR ("parse_ds: (buf_len = %zu) < 11", buf_len); + if (buf_len < 11) { + ERROR("parse_ds: (buf_len = %zu) < 11", buf_len); return (-1); } - if (buf[buf_len - 1] == ',') - { + if (buf[buf_len - 1] == ',') { buf_len--; buf[buf_len] = '\0'; } @@ -55,56 +52,53 @@ static int parse_ds (data_source_t *dsrc, char *buf, size_t buf_len) saveptr = NULL; fields_num = 0; - while (fields_num < 8) - { - if ((fields[fields_num] = strtok_r (dummy, ":", &saveptr)) == NULL) + while (fields_num < 8) { + if ((fields[fields_num] = strtok_r(dummy, ":", &saveptr)) == NULL) break; dummy = NULL; fields_num++; } - if (fields_num != 4) - { - ERROR ("parse_ds: (fields_num = %i) != 4", fields_num); + if (fields_num != 4) { + ERROR("parse_ds: (fields_num = %i) != 4", fields_num); return (-1); } - sstrncpy (dsrc->name, fields[0], sizeof (dsrc->name)); + sstrncpy(dsrc->name, fields[0], sizeof(dsrc->name)); - if (strcasecmp (fields[1], "GAUGE") == 0) + if (strcasecmp(fields[1], "GAUGE") == 0) dsrc->type = DS_TYPE_GAUGE; - else if (strcasecmp (fields[1], "COUNTER") == 0) + else if (strcasecmp(fields[1], "COUNTER") == 0) dsrc->type = DS_TYPE_COUNTER; - else if (strcasecmp (fields[1], "DERIVE") == 0) + else if (strcasecmp(fields[1], "DERIVE") == 0) dsrc->type = DS_TYPE_DERIVE; - else if (strcasecmp (fields[1], "ABSOLUTE") == 0) + else if (strcasecmp(fields[1], "ABSOLUTE") == 0) dsrc->type = DS_TYPE_ABSOLUTE; - else - { - ERROR ("(fields[1] = %s) != (GAUGE || COUNTER || DERIVE || ABSOLUTE)", fields[1]); + else { + ERROR("(fields[1] = %s) != (GAUGE || COUNTER || DERIVE || ABSOLUTE)", + fields[1]); return (-1); } - if (strcasecmp (fields[2], "U") == 0) + if (strcasecmp(fields[2], "U") == 0) dsrc->min = NAN; else - dsrc->min = atof (fields[2]); + dsrc->min = atof(fields[2]); - if (strcasecmp (fields[3], "U") == 0) + if (strcasecmp(fields[3], "U") == 0) dsrc->max = NAN; else - dsrc->max = atof (fields[3]); + dsrc->max = atof(fields[3]); return (0); } /* int parse_ds */ -static void parse_line (char *buf) -{ - char *fields[64]; +static void parse_line(char *buf) { + char *fields[64]; size_t fields_num; data_set_t *ds; - fields_num = strsplit (buf, fields, 64); + fields_num = strsplit(buf, fields, 64); if (fields_num < 2) return; @@ -112,53 +106,48 @@ static void parse_line (char *buf) if (fields[0][0] == '#') return; - ds = calloc (1, sizeof (*ds)); + ds = calloc(1, sizeof(*ds)); if (ds == NULL) return; - sstrncpy (ds->type, fields[0], sizeof (ds->type)); + sstrncpy(ds->type, fields[0], sizeof(ds->type)); ds->ds_num = fields_num - 1; - ds->ds = (data_source_t *) calloc (ds->ds_num, sizeof (data_source_t)); - if (ds->ds == NULL) - { - sfree (ds); + ds->ds = (data_source_t *)calloc(ds->ds_num, sizeof(data_source_t)); + if (ds->ds == NULL) { + sfree(ds); return; } for (size_t i = 0; i < ds->ds_num; i++) - if (parse_ds (ds->ds + i, fields[i + 1], strlen (fields[i + 1])) != 0) - { - ERROR ("types_list: parse_line: Cannot parse data source #%zu " - "of data set %s", i, ds->type); - sfree (ds->ds); - sfree (ds); + if (parse_ds(ds->ds + i, fields[i + 1], strlen(fields[i + 1])) != 0) { + ERROR("types_list: parse_line: Cannot parse data source #%zu " + "of data set %s", + i, ds->type); + sfree(ds->ds); + sfree(ds); return; } - plugin_register_data_set (ds); + plugin_register_data_set(ds); - sfree (ds->ds); - sfree (ds); + sfree(ds->ds); + sfree(ds); } /* void parse_line */ -static void parse_file (FILE *fh) -{ +static void parse_file(FILE *fh) { char buf[4096]; size_t buf_len; - while (fgets (buf, sizeof (buf), fh) != NULL) - { - buf_len = strlen (buf); - - if (buf_len >= 4095) - { - NOTICE ("Skipping line with more than 4095 characters."); - do - { - if (fgets (buf, sizeof (buf), fh) == NULL) - break; - buf_len = strlen (buf); + while (fgets(buf, sizeof(buf), fh) != NULL) { + buf_len = strlen(buf); + + if (buf_len >= 4095) { + NOTICE("Skipping line with more than 4095 characters."); + do { + if (fgets(buf, sizeof(buf), fh) == NULL) + break; + buf_len = strlen(buf); } while (buf_len >= 4095); continue; } /* if (buf_len >= 4095) */ @@ -166,41 +155,39 @@ static void parse_file (FILE *fh) if ((buf_len == 0) || (buf[0] == '#')) continue; - while ((buf_len > 0) && ((buf[buf_len - 1] == '\n') - || (buf[buf_len - 1] == '\r'))) + while ((buf_len > 0) && + ((buf[buf_len - 1] == '\n') || (buf[buf_len - 1] == '\r'))) buf[--buf_len] = '\0'; if (buf_len == 0) continue; - parse_line (buf); + parse_line(buf); } /* while (fgets) */ } /* void parse_file */ -int read_types_list (const char *file) -{ +int read_types_list(const char *file) { FILE *fh; if (file == NULL) return (-1); - fh = fopen (file, "r"); - if (fh == NULL) - { + fh = fopen(file, "r"); + if (fh == NULL) { char errbuf[1024]; - fprintf (stderr, "Failed to open types database `%s': %s.\n", - file, sstrerror (errno, errbuf, sizeof (errbuf))); - ERROR ("Failed to open types database `%s': %s", - file, sstrerror (errno, errbuf, sizeof (errbuf))); + fprintf(stderr, "Failed to open types database `%s': %s.\n", file, + sstrerror(errno, errbuf, sizeof(errbuf))); + ERROR("Failed to open types database `%s': %s", file, + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } - parse_file (fh); + parse_file(fh); - fclose (fh); + fclose(fh); fh = NULL; - DEBUG ("Done parsing `%s'", file); + DEBUG("Done parsing `%s'", file); return (0); } /* int read_types_list */ diff --git a/src/daemon/types_list.h b/src/daemon/types_list.h index f375a2fb..c93ab5f3 100644 --- a/src/daemon/types_list.h +++ b/src/daemon/types_list.h @@ -27,6 +27,6 @@ #ifndef TYPES_LIST_H #define TYPES_LIST_H 1 -int read_types_list (const char *file); +int read_types_list(const char *file); #endif /* TYPES_LIST_H */ diff --git a/src/daemon/utils_avltree.c b/src/daemon/utils_avltree.c index e1c41ecf..92259ae1 100644 --- a/src/daemon/utils_avltree.c +++ b/src/daemon/utils_avltree.c @@ -24,40 +24,38 @@ * Florian octo Forster **/ -#include #include +#include #include "utils_avltree.h" -#define BALANCE(n) ((((n)->left == NULL) ? 0 : (n)->left->height) \ - - (((n)->right == NULL) ? 0 : (n)->right->height)) +#define BALANCE(n) \ + ((((n)->left == NULL) ? 0 : (n)->left->height) - \ + (((n)->right == NULL) ? 0 : (n)->right->height)) /* * private data types */ -struct c_avl_node_s -{ - void *key; - void *value; - - int height; - struct c_avl_node_s *left; - struct c_avl_node_s *right; - struct c_avl_node_s *parent; +struct c_avl_node_s { + void *key; + void *value; + + int height; + struct c_avl_node_s *left; + struct c_avl_node_s *right; + struct c_avl_node_s *parent; }; typedef struct c_avl_node_s c_avl_node_t; -struct c_avl_tree_s -{ - c_avl_node_t *root; - int (*compare) (const void *, const void *); - int size; +struct c_avl_tree_s { + c_avl_node_t *root; + int (*compare)(const void *, const void *); + int size; }; -struct c_avl_iterator_s -{ - c_avl_tree_t *tree; - c_avl_node_t *node; +struct c_avl_iterator_s { + c_avl_tree_t *tree; + c_avl_node_t *node; }; /* @@ -76,56 +74,50 @@ static void verify_tree (c_avl_node_t *n) assert ((n->parent == NULL) || (n->parent->right == n) || (n->parent->left == n)); } /* void verify_tree */ #else -# define verify_tree(n) /**/ +#define verify_tree(n) /**/ #endif -static void free_node (c_avl_node_t *n) -{ - if (n == NULL) - return; +static void free_node(c_avl_node_t *n) { + if (n == NULL) + return; - if (n->left != NULL) - free_node (n->left); - if (n->right != NULL) - free_node (n->right); + if (n->left != NULL) + free_node(n->left); + if (n->right != NULL) + free_node(n->right); - free (n); + free(n); } -static int calc_height (c_avl_node_t *n) -{ - int height_left; - int height_right; +static int calc_height(c_avl_node_t *n) { + int height_left; + int height_right; - if (n == NULL) - return (0); + if (n == NULL) + return (0); - height_left = (n->left == NULL) ? 0 : n->left->height; - height_right = (n->right == NULL) ? 0 : n->right->height; + height_left = (n->left == NULL) ? 0 : n->left->height; + height_right = (n->right == NULL) ? 0 : n->right->height; - return (((height_left > height_right) - ? height_left - : height_right) + 1); + return (((height_left > height_right) ? height_left : height_right) + 1); } /* int calc_height */ -static c_avl_node_t *search (c_avl_tree_t *t, const void *key) -{ - c_avl_node_t *n; - int cmp; - - n = t->root; - while (n != NULL) - { - cmp = t->compare (key, n->key); - if (cmp == 0) - return (n); - else if (cmp < 0) - n = n->left; - else - n = n->right; - } - - return (NULL); +static c_avl_node_t *search(c_avl_tree_t *t, const void *key) { + c_avl_node_t *n; + int cmp; + + n = t->root; + while (n != NULL) { + cmp = t->compare(key, n->key); + if (cmp == 0) + return (n); + else if (cmp < 0) + n = n->left; + else + n = n->right; + } + + return (NULL); } /* (x) (y) @@ -136,39 +128,38 @@ static c_avl_node_t *search (c_avl_tree_t *t, const void *key) * / a\ /_b\ /_b\ /_c\ * /____\ */ -static c_avl_node_t *rotate_right (c_avl_tree_t *t, c_avl_node_t *x) -{ - c_avl_node_t *p; - c_avl_node_t *y; - c_avl_node_t *b; - - assert (x != NULL); - assert (x->left != NULL); - - p = x->parent; - y = x->left; - b = y->right; - - x->left = b; - if (b != NULL) - b->parent = x; - - x->parent = y; - y->right = x; - - y->parent = p; - assert ((p == NULL) || (p->left == x) || (p->right == x)); - if (p == NULL) - t->root = y; - else if (p->left == x) - p->left = y; - else - p->right = y; - - x->height = calc_height (x); - y->height = calc_height (y); - - return (y); +static c_avl_node_t *rotate_right(c_avl_tree_t *t, c_avl_node_t *x) { + c_avl_node_t *p; + c_avl_node_t *y; + c_avl_node_t *b; + + assert(x != NULL); + assert(x->left != NULL); + + p = x->parent; + y = x->left; + b = y->right; + + x->left = b; + if (b != NULL) + b->parent = x; + + x->parent = y; + y->right = x; + + y->parent = p; + assert((p == NULL) || (p->left == x) || (p->right == x)); + if (p == NULL) + t->root = y; + else if (p->left == x) + p->left = y; + else + p->right = y; + + x->height = calc_height(x); + y->height = calc_height(y); + + return (y); } /* void rotate_right */ /* @@ -180,561 +171,476 @@ static c_avl_node_t *rotate_right (c_avl_tree_t *t, c_avl_node_t *x) * /_b\ / c\ /_a\ /_b\ * /____\ */ -static c_avl_node_t *rotate_left (c_avl_tree_t *t, c_avl_node_t *x) -{ - c_avl_node_t *p; - c_avl_node_t *y; - c_avl_node_t *b; - - assert (x != NULL); - assert (x->right != NULL); - - p = x->parent; - y = x->right; - b = y->left; - - x->right = b; - if (b != NULL) - b->parent = x; - - x->parent = y; - y->left = x; - - y->parent = p; - assert ((p == NULL) || (p->left == x) || (p->right == x)); - if (p == NULL) - t->root = y; - else if (p->left == x) - p->left = y; - else - p->right = y; - - x->height = calc_height (x); - y->height = calc_height (y); - - return (y); +static c_avl_node_t *rotate_left(c_avl_tree_t *t, c_avl_node_t *x) { + c_avl_node_t *p; + c_avl_node_t *y; + c_avl_node_t *b; + + assert(x != NULL); + assert(x->right != NULL); + + p = x->parent; + y = x->right; + b = y->left; + + x->right = b; + if (b != NULL) + b->parent = x; + + x->parent = y; + y->left = x; + + y->parent = p; + assert((p == NULL) || (p->left == x) || (p->right == x)); + if (p == NULL) + t->root = y; + else if (p->left == x) + p->left = y; + else + p->right = y; + + x->height = calc_height(x); + y->height = calc_height(y); + + return (y); } /* void rotate_left */ -static c_avl_node_t *rotate_left_right (c_avl_tree_t *t, c_avl_node_t *x) -{ - rotate_left (t, x->left); - return (rotate_right (t, x)); +static c_avl_node_t *rotate_left_right(c_avl_tree_t *t, c_avl_node_t *x) { + rotate_left(t, x->left); + return (rotate_right(t, x)); } /* void rotate_left_right */ -static c_avl_node_t *rotate_right_left (c_avl_tree_t *t, c_avl_node_t *x) -{ - rotate_right (t, x->right); - return (rotate_left (t, x)); +static c_avl_node_t *rotate_right_left(c_avl_tree_t *t, c_avl_node_t *x) { + rotate_right(t, x->right); + return (rotate_left(t, x)); } /* void rotate_right_left */ -static void rebalance (c_avl_tree_t *t, c_avl_node_t *n) -{ - int b_top; - int b_bottom; - - while (n != NULL) - { - b_top = BALANCE (n); - assert ((b_top >= -2) && (b_top <= 2)); - - if (b_top == -2) - { - assert (n->right != NULL); - b_bottom = BALANCE (n->right); - assert ((b_bottom >= -1) && (b_bottom <= 1)); - if (b_bottom == 1) - n = rotate_right_left (t, n); - else - n = rotate_left (t, n); - } - else if (b_top == 2) - { - assert (n->left != NULL); - b_bottom = BALANCE (n->left); - assert ((b_bottom >= -1) && (b_bottom <= 1)); - if (b_bottom == -1) - n = rotate_left_right (t, n); - else - n = rotate_right (t, n); - } - else - { - int height = calc_height (n); - if (height == n->height) - break; - n->height = height; - } - - assert (n->height == calc_height (n)); - - n = n->parent; - } /* while (n != NULL) */ +static void rebalance(c_avl_tree_t *t, c_avl_node_t *n) { + int b_top; + int b_bottom; + + while (n != NULL) { + b_top = BALANCE(n); + assert((b_top >= -2) && (b_top <= 2)); + + if (b_top == -2) { + assert(n->right != NULL); + b_bottom = BALANCE(n->right); + assert((b_bottom >= -1) && (b_bottom <= 1)); + if (b_bottom == 1) + n = rotate_right_left(t, n); + else + n = rotate_left(t, n); + } else if (b_top == 2) { + assert(n->left != NULL); + b_bottom = BALANCE(n->left); + assert((b_bottom >= -1) && (b_bottom <= 1)); + if (b_bottom == -1) + n = rotate_left_right(t, n); + else + n = rotate_right(t, n); + } else { + int height = calc_height(n); + if (height == n->height) + break; + n->height = height; + } + + assert(n->height == calc_height(n)); + + n = n->parent; + } /* while (n != NULL) */ } /* void rebalance */ -static c_avl_node_t *c_avl_node_next (c_avl_node_t *n) -{ - c_avl_node_t *r; /* return node */ - - if (n == NULL) - { - return (NULL); - } - - /* If we can't descent any further, we have to backtrack to the first - * parent that's bigger than we, i. e. who's _left_ child we are. */ - if (n->right == NULL) - { - r = n->parent; - while ((r != NULL) && (r->parent != NULL)) - { - if (r->left == n) - break; - n = r; - r = n->parent; - } - - /* n->right == NULL && r == NULL => t is root and has no next - * r->left != n => r->right = n => r->parent == NULL */ - if ((r == NULL) || (r->left != n)) - { - assert ((r == NULL) || (r->parent == NULL)); - return (NULL); - } - else - { - assert (r->left == n); - return (r); - } - } - else - { - r = n->right; - while (r->left != NULL) - r = r->left; - } - - return (r); +static c_avl_node_t *c_avl_node_next(c_avl_node_t *n) { + c_avl_node_t *r; /* return node */ + + if (n == NULL) { + return (NULL); + } + + /* If we can't descent any further, we have to backtrack to the first + * parent that's bigger than we, i. e. who's _left_ child we are. */ + if (n->right == NULL) { + r = n->parent; + while ((r != NULL) && (r->parent != NULL)) { + if (r->left == n) + break; + n = r; + r = n->parent; + } + + /* n->right == NULL && r == NULL => t is root and has no next + * r->left != n => r->right = n => r->parent == NULL */ + if ((r == NULL) || (r->left != n)) { + assert((r == NULL) || (r->parent == NULL)); + return (NULL); + } else { + assert(r->left == n); + return (r); + } + } else { + r = n->right; + while (r->left != NULL) + r = r->left; + } + + return (r); } /* c_avl_node_t *c_avl_node_next */ -static c_avl_node_t *c_avl_node_prev (c_avl_node_t *n) -{ - c_avl_node_t *r; /* return node */ - - if (n == NULL) - { - return (NULL); - } - - /* If we can't descent any further, we have to backtrack to the first - * parent that's smaller than we, i. e. who's _right_ child we are. */ - if (n->left == NULL) - { - r = n->parent; - while ((r != NULL) && (r->parent != NULL)) - { - if (r->right == n) - break; - n = r; - r = n->parent; - } - - /* n->left == NULL && r == NULL => t is root and has no next - * r->right != n => r->left = n => r->parent == NULL */ - if ((r == NULL) || (r->right != n)) - { - assert ((r == NULL) || (r->parent == NULL)); - return (NULL); - } - else - { - assert (r->right == n); - return (r); - } - } - else - { - r = n->left; - while (r->right != NULL) - r = r->right; - } - - return (r); +static c_avl_node_t *c_avl_node_prev(c_avl_node_t *n) { + c_avl_node_t *r; /* return node */ + + if (n == NULL) { + return (NULL); + } + + /* If we can't descent any further, we have to backtrack to the first + * parent that's smaller than we, i. e. who's _right_ child we are. */ + if (n->left == NULL) { + r = n->parent; + while ((r != NULL) && (r->parent != NULL)) { + if (r->right == n) + break; + n = r; + r = n->parent; + } + + /* n->left == NULL && r == NULL => t is root and has no next + * r->right != n => r->left = n => r->parent == NULL */ + if ((r == NULL) || (r->right != n)) { + assert((r == NULL) || (r->parent == NULL)); + return (NULL); + } else { + assert(r->right == n); + return (r); + } + } else { + r = n->left; + while (r->right != NULL) + r = r->right; + } + + return (r); } /* c_avl_node_t *c_avl_node_prev */ -static int _remove (c_avl_tree_t *t, c_avl_node_t *n) -{ - assert ((t != NULL) && (n != NULL)); - - if ((n->left != NULL) && (n->right != NULL)) - { - c_avl_node_t *r; /* replacement node */ - if (BALANCE (n) > 0) /* left subtree is higher */ - { - assert (n->left != NULL); - r = c_avl_node_prev (n); - - } - else /* right subtree is higher */ - { - assert (n->right != NULL); - r = c_avl_node_next (n); - } - - assert ((r->left == NULL) || (r->right == NULL)); - - /* copy content */ - n->key = r->key; - n->value = r->value; - - n = r; - } - - assert ((n->left == NULL) || (n->right == NULL)); - - if ((n->left == NULL) && (n->right == NULL)) - { - /* Deleting a leave is easy */ - if (n->parent == NULL) - { - assert (t->root == n); - t->root = NULL; - } - else - { - assert ((n->parent->left == n) - || (n->parent->right == n)); - if (n->parent->left == n) - n->parent->left = NULL; - else - n->parent->right = NULL; - - rebalance (t, n->parent); - } - - free_node (n); - } - else if (n->left == NULL) - { - assert (BALANCE (n) == -1); - assert ((n->parent == NULL) || (n->parent->left == n) || (n->parent->right == n)); - if (n->parent == NULL) - { - assert (t->root == n); - t->root = n->right; - } - else if (n->parent->left == n) - { - n->parent->left = n->right; - } - else - { - n->parent->right = n->right; - } - n->right->parent = n->parent; - - if (n->parent != NULL) - rebalance (t, n->parent); - - n->right = NULL; - free_node (n); - } - else if (n->right == NULL) - { - assert (BALANCE (n) == 1); - assert ((n->parent == NULL) || (n->parent->left == n) || (n->parent->right == n)); - if (n->parent == NULL) - { - assert (t->root == n); - t->root = n->left; - } - else if (n->parent->left == n) - { - n->parent->left = n->left; - } - else - { - n->parent->right = n->left; - } - n->left->parent = n->parent; - - if (n->parent != NULL) - rebalance (t, n->parent); - - n->left = NULL; - free_node (n); - } - else - { - assert (0); - } - - return (0); +static int _remove(c_avl_tree_t *t, c_avl_node_t *n) { + assert((t != NULL) && (n != NULL)); + + if ((n->left != NULL) && (n->right != NULL)) { + c_avl_node_t *r; /* replacement node */ + if (BALANCE(n) > 0) /* left subtree is higher */ + { + assert(n->left != NULL); + r = c_avl_node_prev(n); + + } else /* right subtree is higher */ + { + assert(n->right != NULL); + r = c_avl_node_next(n); + } + + assert((r->left == NULL) || (r->right == NULL)); + + /* copy content */ + n->key = r->key; + n->value = r->value; + + n = r; + } + + assert((n->left == NULL) || (n->right == NULL)); + + if ((n->left == NULL) && (n->right == NULL)) { + /* Deleting a leave is easy */ + if (n->parent == NULL) { + assert(t->root == n); + t->root = NULL; + } else { + assert((n->parent->left == n) || (n->parent->right == n)); + if (n->parent->left == n) + n->parent->left = NULL; + else + n->parent->right = NULL; + + rebalance(t, n->parent); + } + + free_node(n); + } else if (n->left == NULL) { + assert(BALANCE(n) == -1); + assert((n->parent == NULL) || (n->parent->left == n) || + (n->parent->right == n)); + if (n->parent == NULL) { + assert(t->root == n); + t->root = n->right; + } else if (n->parent->left == n) { + n->parent->left = n->right; + } else { + n->parent->right = n->right; + } + n->right->parent = n->parent; + + if (n->parent != NULL) + rebalance(t, n->parent); + + n->right = NULL; + free_node(n); + } else if (n->right == NULL) { + assert(BALANCE(n) == 1); + assert((n->parent == NULL) || (n->parent->left == n) || + (n->parent->right == n)); + if (n->parent == NULL) { + assert(t->root == n); + t->root = n->left; + } else if (n->parent->left == n) { + n->parent->left = n->left; + } else { + n->parent->right = n->left; + } + n->left->parent = n->parent; + + if (n->parent != NULL) + rebalance(t, n->parent); + + n->left = NULL; + free_node(n); + } else { + assert(0); + } + + return (0); } /* void *_remove */ /* * public functions */ -c_avl_tree_t *c_avl_create (int (*compare) (const void *, const void *)) -{ - c_avl_tree_t *t; +c_avl_tree_t *c_avl_create(int (*compare)(const void *, const void *)) { + c_avl_tree_t *t; - if (compare == NULL) - return (NULL); + if (compare == NULL) + return (NULL); - if ((t = malloc (sizeof (*t))) == NULL) - return (NULL); + if ((t = malloc(sizeof(*t))) == NULL) + return (NULL); - t->root = NULL; - t->compare = compare; - t->size = 0; + t->root = NULL; + t->compare = compare; + t->size = 0; - return (t); + return (t); } -void c_avl_destroy (c_avl_tree_t *t) -{ - if (t == NULL) - return; - free_node (t->root); - free (t); +void c_avl_destroy(c_avl_tree_t *t) { + if (t == NULL) + return; + free_node(t->root); + free(t); } -int c_avl_insert (c_avl_tree_t *t, void *key, void *value) -{ - c_avl_node_t *new; - c_avl_node_t *nptr; - int cmp; - - if ((new = malloc (sizeof (*new))) == NULL) - return (-1); - - new->key = key; - new->value = value; - new->height = 1; - new->left = NULL; - new->right = NULL; - - if (t->root == NULL) - { - new->parent = NULL; - t->root = new; - t->size = 1; - return (0); - } - - nptr = t->root; - while (42) - { - cmp = t->compare (nptr->key, new->key); - if (cmp == 0) - { - free_node (new); - return (1); - } - else if (cmp < 0) - { - /* nptr < new */ - if (nptr->right == NULL) - { - nptr->right = new; - new->parent = nptr; - rebalance (t, nptr); - break; - } - else - { - nptr = nptr->right; - } - } - else /* if (cmp > 0) */ - { - /* nptr > new */ - if (nptr->left == NULL) - { - nptr->left = new; - new->parent = nptr; - rebalance (t, nptr); - break; - } - else - { - nptr = nptr->left; - } - } - } /* while (42) */ - - verify_tree (t->root); - ++t->size; - return (0); +int c_avl_insert(c_avl_tree_t *t, void *key, void *value) { + c_avl_node_t *new; + c_avl_node_t *nptr; + int cmp; + + if ((new = malloc(sizeof(*new))) == NULL) + return (-1); + + new->key = key; + new->value = value; + new->height = 1; + new->left = NULL; + new->right = NULL; + + if (t->root == NULL) { + new->parent = NULL; + t->root = new; + t->size = 1; + return (0); + } + + nptr = t->root; + while (42) { + cmp = t->compare(nptr->key, new->key); + if (cmp == 0) { + free_node(new); + return (1); + } else if (cmp < 0) { + /* nptr < new */ + if (nptr->right == NULL) { + nptr->right = new; + new->parent = nptr; + rebalance(t, nptr); + break; + } else { + nptr = nptr->right; + } + } else /* if (cmp > 0) */ + { + /* nptr > new */ + if (nptr->left == NULL) { + nptr->left = new; + new->parent = nptr; + rebalance(t, nptr); + break; + } else { + nptr = nptr->left; + } + } + } /* while (42) */ + + verify_tree(t->root); + ++t->size; + return (0); } /* int c_avl_insert */ -int c_avl_remove (c_avl_tree_t *t, const void *key, void **rkey, void **rvalue) -{ - c_avl_node_t *n; - int status; +int c_avl_remove(c_avl_tree_t *t, const void *key, void **rkey, void **rvalue) { + c_avl_node_t *n; + int status; - assert (t != NULL); + assert(t != NULL); - n = search (t, key); - if (n == NULL) - return (-1); + n = search(t, key); + if (n == NULL) + return (-1); - if (rkey != NULL) - *rkey = n->key; - if (rvalue != NULL) - *rvalue = n->value; + if (rkey != NULL) + *rkey = n->key; + if (rvalue != NULL) + *rvalue = n->value; - status = _remove (t, n); - verify_tree (t->root); - --t->size; - return (status); + status = _remove(t, n); + verify_tree(t->root); + --t->size; + return (status); } /* void *c_avl_remove */ -int c_avl_get (c_avl_tree_t *t, const void *key, void **value) -{ - c_avl_node_t *n; +int c_avl_get(c_avl_tree_t *t, const void *key, void **value) { + c_avl_node_t *n; - assert (t != NULL); + assert(t != NULL); - n = search (t, key); - if (n == NULL) - return (-1); + n = search(t, key); + if (n == NULL) + return (-1); - if (value != NULL) - *value = n->value; + if (value != NULL) + *value = n->value; - return (0); + return (0); } -int c_avl_pick (c_avl_tree_t *t, void **key, void **value) -{ - c_avl_node_t *n; - c_avl_node_t *p; - - if ((key == NULL) || (value == NULL)) - return (-1); - if (t->root == NULL) - return (-1); - - n = t->root; - while ((n->left != NULL) || (n->right != NULL)) - { - if (n->left == NULL) - { - n = n->right; - continue; - } - else if (n->right == NULL) - { - n = n->left; - continue; - } - - if (n->left->height > n->right->height) - n = n->left; - else - n = n->right; - } - - p = n->parent; - if (p == NULL) - t->root = NULL; - else if (p->left == n) - p->left = NULL; - else - p->right = NULL; - - *key = n->key; - *value = n->value; - - free_node (n); - --t->size; - rebalance (t, p); - - return (0); +int c_avl_pick(c_avl_tree_t *t, void **key, void **value) { + c_avl_node_t *n; + c_avl_node_t *p; + + if ((key == NULL) || (value == NULL)) + return (-1); + if (t->root == NULL) + return (-1); + + n = t->root; + while ((n->left != NULL) || (n->right != NULL)) { + if (n->left == NULL) { + n = n->right; + continue; + } else if (n->right == NULL) { + n = n->left; + continue; + } + + if (n->left->height > n->right->height) + n = n->left; + else + n = n->right; + } + + p = n->parent; + if (p == NULL) + t->root = NULL; + else if (p->left == n) + p->left = NULL; + else + p->right = NULL; + + *key = n->key; + *value = n->value; + + free_node(n); + --t->size; + rebalance(t, p); + + return (0); } /* int c_avl_pick */ -c_avl_iterator_t *c_avl_get_iterator (c_avl_tree_t *t) -{ - c_avl_iterator_t *iter; +c_avl_iterator_t *c_avl_get_iterator(c_avl_tree_t *t) { + c_avl_iterator_t *iter; - if (t == NULL) - return (NULL); + if (t == NULL) + return (NULL); - iter = calloc (1, sizeof (*iter)); - if (iter == NULL) - return (NULL); - iter->tree = t; + iter = calloc(1, sizeof(*iter)); + if (iter == NULL) + return (NULL); + iter->tree = t; - return (iter); + return (iter); } /* c_avl_iterator_t *c_avl_get_iterator */ -int c_avl_iterator_next (c_avl_iterator_t *iter, void **key, void **value) -{ - c_avl_node_t *n; - - if ((iter == NULL) || (key == NULL) || (value == NULL)) - return (-1); - - if (iter->node == NULL) - { - for (n = iter->tree->root; n != NULL; n = n->left) - if (n->left == NULL) - break; - iter->node = n; - } - else - { - n = c_avl_node_next (iter->node); - } +int c_avl_iterator_next(c_avl_iterator_t *iter, void **key, void **value) { + c_avl_node_t *n; - if (n == NULL) - return (-1); + if ((iter == NULL) || (key == NULL) || (value == NULL)) + return (-1); + + if (iter->node == NULL) { + for (n = iter->tree->root; n != NULL; n = n->left) + if (n->left == NULL) + break; + iter->node = n; + } else { + n = c_avl_node_next(iter->node); + } + + if (n == NULL) + return (-1); - iter->node = n; - *key = n->key; - *value = n->value; + iter->node = n; + *key = n->key; + *value = n->value; - return (0); + return (0); } /* int c_avl_iterator_next */ -int c_avl_iterator_prev (c_avl_iterator_t *iter, void **key, void **value) -{ - c_avl_node_t *n; - - if ((iter == NULL) || (key == NULL) || (value == NULL)) - return (-1); - - if (iter->node == NULL) - { - for (n = iter->tree->root; n != NULL; n = n->left) - if (n->right == NULL) - break; - iter->node = n; - } - else - { - n = c_avl_node_prev (iter->node); - } +int c_avl_iterator_prev(c_avl_iterator_t *iter, void **key, void **value) { + c_avl_node_t *n; - if (n == NULL) - return (-1); + if ((iter == NULL) || (key == NULL) || (value == NULL)) + return (-1); + + if (iter->node == NULL) { + for (n = iter->tree->root; n != NULL; n = n->left) + if (n->right == NULL) + break; + iter->node = n; + } else { + n = c_avl_node_prev(iter->node); + } + + if (n == NULL) + return (-1); - iter->node = n; - *key = n->key; - *value = n->value; + iter->node = n; + *key = n->key; + *value = n->value; - return (0); + return (0); } /* int c_avl_iterator_prev */ -void c_avl_iterator_destroy (c_avl_iterator_t *iter) -{ - free (iter); -} +void c_avl_iterator_destroy(c_avl_iterator_t *iter) { free(iter); } -int c_avl_size (c_avl_tree_t *t) -{ - if (t == NULL) - return (0); - return (t->size); +int c_avl_size(c_avl_tree_t *t) { + if (t == NULL) + return (0); + return (t->size); } diff --git a/src/daemon/utils_avltree.h b/src/daemon/utils_avltree.h index 43e94cfb..3f52b931 100644 --- a/src/daemon/utils_avltree.h +++ b/src/daemon/utils_avltree.h @@ -51,8 +51,7 @@ typedef struct c_avl_iterator_s c_avl_iterator_t; * RETURN VALUE * A c_avl_tree_t-pointer upon success or NULL upon failure. */ -c_avl_tree_t *c_avl_create (int (*compare) (const void *, const void *)); - +c_avl_tree_t *c_avl_create(int (*compare)(const void *, const void *)); /* * NAME @@ -62,7 +61,7 @@ c_avl_tree_t *c_avl_create (int (*compare) (const void *, const void *)); * Deallocates an AVL-tree. Stored value- and key-pointer are lost, but of * course not freed. */ -void c_avl_destroy (c_avl_tree_t *t); +void c_avl_destroy(c_avl_tree_t *t); /* * NAME @@ -84,7 +83,7 @@ void c_avl_destroy (c_avl_tree_t *t); * Zero upon success, non-zero otherwise. It's less than zero if an error * occurred or greater than zero if the key is already stored in the tree. */ -int c_avl_insert (c_avl_tree_t *t, void *key, void *value); +int c_avl_insert(c_avl_tree_t *t, void *key, void *value); /* * NAME @@ -107,7 +106,7 @@ int c_avl_insert (c_avl_tree_t *t, void *key, void *value); * RETURN VALUE * Zero upon success or non-zero if the key isn't found in the tree. */ -int c_avl_remove (c_avl_tree_t *t, const void *key, void **rkey, void **rvalue); +int c_avl_remove(c_avl_tree_t *t, const void *key, void **rkey, void **rvalue); /* * NAME @@ -124,7 +123,7 @@ int c_avl_remove (c_avl_tree_t *t, const void *key, void **rkey, void **rvalue); * RETURN VALUE * Zero upon success or non-zero if the key isn't found in the tree. */ -int c_avl_get (c_avl_tree_t *t, const void *key, void **value); +int c_avl_get(c_avl_tree_t *t, const void *key, void **value); /* * NAME @@ -145,12 +144,12 @@ int c_avl_get (c_avl_tree_t *t, const void *key, void **value); * Zero upon success or non-zero if the tree is empty or key or value is * NULL. */ -int c_avl_pick (c_avl_tree_t *t, void **key, void **value); +int c_avl_pick(c_avl_tree_t *t, void **key, void **value); -c_avl_iterator_t *c_avl_get_iterator (c_avl_tree_t *t); -int c_avl_iterator_next (c_avl_iterator_t *iter, void **key, void **value); -int c_avl_iterator_prev (c_avl_iterator_t *iter, void **key, void **value); -void c_avl_iterator_destroy (c_avl_iterator_t *iter); +c_avl_iterator_t *c_avl_get_iterator(c_avl_tree_t *t); +int c_avl_iterator_next(c_avl_iterator_t *iter, void **key, void **value); +int c_avl_iterator_prev(c_avl_iterator_t *iter, void **key, void **value); +void c_avl_iterator_destroy(c_avl_iterator_t *iter); /* * NAME @@ -165,6 +164,6 @@ void c_avl_iterator_destroy (c_avl_iterator_t *iter); * RETURN VALUE * Number of nodes in the tree, 0 if the tree is empty or NULL. */ -int c_avl_size (c_avl_tree_t *t); +int c_avl_size(c_avl_tree_t *t); #endif /* UTILS_AVLTREE_H */ diff --git a/src/daemon/utils_avltree_test.c b/src/daemon/utils_avltree_test.c index 150dd1b5..0a84f6f9 100644 --- a/src/daemon/utils_avltree_test.c +++ b/src/daemon/utils_avltree_test.c @@ -31,119 +31,106 @@ #include "utils_avltree.h" static int compare_total_count = 0; -#define RESET_COUNTS() do { compare_total_count = 0; } while (0) +#define RESET_COUNTS() \ + do { \ + compare_total_count = 0; \ + } while (0) -static int compare_callback (void const *v0, void const *v1) -{ - assert (v0 != NULL); - assert (v1 != NULL); +static int compare_callback(void const *v0, void const *v1) { + assert(v0 != NULL); + assert(v1 != NULL); compare_total_count++; - return (strcmp (v0, v1)); + return (strcmp(v0, v1)); } -DEF_TEST(success) -{ +DEF_TEST(success) { struct { char *key; char *value; } cases[] = { - {"Eeph7chu", "vai1reiV"}, - {"igh3Paiz", "teegh1Ee"}, - {"caip6Uu8", "ooteQu8n"}, - {"Aech6vah", "AijeeT0l"}, - {"Xah0et2L", "gah8Taep"}, - {"BocaeB8n", "oGaig8io"}, - {"thai8AhM", "ohjeFo3f"}, - {"ohth6ieC", "hoo8ieWo"}, - {"aej7Woow", "phahuC2s"}, - {"Hai8ier2", "Yie6eimi"}, - {"phuXi3Li", "JaiF7ieb"}, - {"Shaig5ef", "aihi5Zai"}, - {"voh6Aith", "Oozaeto0"}, - {"zaiP5kie", "seep5veM"}, - {"pae7ba7D", "chie8Ojo"}, - {"Gou2ril3", "ouVoo0ha"}, - {"lo3Thee3", "ahDu4Zuj"}, - {"Rah8kohv", "ieShoc7E"}, - {"ieN5engi", "Aevou1ah"}, - {"ooTe4OhP", "aingai5Y"}, + {"Eeph7chu", "vai1reiV"}, {"igh3Paiz", "teegh1Ee"}, + {"caip6Uu8", "ooteQu8n"}, {"Aech6vah", "AijeeT0l"}, + {"Xah0et2L", "gah8Taep"}, {"BocaeB8n", "oGaig8io"}, + {"thai8AhM", "ohjeFo3f"}, {"ohth6ieC", "hoo8ieWo"}, + {"aej7Woow", "phahuC2s"}, {"Hai8ier2", "Yie6eimi"}, + {"phuXi3Li", "JaiF7ieb"}, {"Shaig5ef", "aihi5Zai"}, + {"voh6Aith", "Oozaeto0"}, {"zaiP5kie", "seep5veM"}, + {"pae7ba7D", "chie8Ojo"}, {"Gou2ril3", "ouVoo0ha"}, + {"lo3Thee3", "ahDu4Zuj"}, {"Rah8kohv", "ieShoc7E"}, + {"ieN5engi", "Aevou1ah"}, {"ooTe4OhP", "aingai5Y"}, }; c_avl_tree_t *t; - RESET_COUNTS (); - CHECK_NOT_NULL (t = c_avl_create (compare_callback)); + RESET_COUNTS(); + CHECK_NOT_NULL(t = c_avl_create(compare_callback)); /* insert */ - for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) - { + for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) { char *key; char *value; - CHECK_NOT_NULL (key = strdup (cases[i].key)); - CHECK_NOT_NULL (value = strdup (cases[i].value)); + CHECK_NOT_NULL(key = strdup(cases[i].key)); + CHECK_NOT_NULL(value = strdup(cases[i].value)); - CHECK_ZERO (c_avl_insert (t, key, value)); - EXPECT_EQ_INT ((int) (i + 1), c_avl_size (t)); + CHECK_ZERO(c_avl_insert(t, key, value)); + EXPECT_EQ_INT((int)(i + 1), c_avl_size(t)); } /* Key already exists. */ - for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) - EXPECT_EQ_INT (1, c_avl_insert (t, cases[i].key, cases[i].value)); + for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) + EXPECT_EQ_INT(1, c_avl_insert(t, cases[i].key, cases[i].value)); /* get */ - for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) - { + for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) { char *value_ret = NULL; - CHECK_ZERO (c_avl_get (t, cases[i].key, (void *) &value_ret)); - EXPECT_EQ_STR (cases[i].value, value_ret); + CHECK_ZERO(c_avl_get(t, cases[i].key, (void *)&value_ret)); + EXPECT_EQ_STR(cases[i].value, value_ret); } /* remove half */ - for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases) / 2; i++) - { + for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases) / 2; i++) { char *key = NULL; char *value = NULL; - int expected_size = (int) (STATIC_ARRAY_SIZE (cases) - (i + 1)); + int expected_size = (int)(STATIC_ARRAY_SIZE(cases) - (i + 1)); - CHECK_ZERO (c_avl_remove (t, cases[i].key, (void *) &key, (void *) &value)); + CHECK_ZERO(c_avl_remove(t, cases[i].key, (void *)&key, (void *)&value)); - EXPECT_EQ_STR (cases[i].key, key); - EXPECT_EQ_STR (cases[i].value, value); + EXPECT_EQ_STR(cases[i].key, key); + EXPECT_EQ_STR(cases[i].value, value); - free (key); - free (value); + free(key); + free(value); - EXPECT_EQ_INT (expected_size, c_avl_size (t)); + EXPECT_EQ_INT(expected_size, c_avl_size(t)); } /* pick the other half */ - for (size_t i = STATIC_ARRAY_SIZE (cases) / 2; i < STATIC_ARRAY_SIZE (cases); i++) - { + for (size_t i = STATIC_ARRAY_SIZE(cases) / 2; i < STATIC_ARRAY_SIZE(cases); + i++) { char *key = NULL; char *value = NULL; - int expected_size = (int) (STATIC_ARRAY_SIZE (cases) - (i + 1)); + int expected_size = (int)(STATIC_ARRAY_SIZE(cases) - (i + 1)); - EXPECT_EQ_INT (expected_size + 1, c_avl_size (t)); - EXPECT_EQ_INT (0, c_avl_pick (t, (void *) &key, (void *) &value)); + EXPECT_EQ_INT(expected_size + 1, c_avl_size(t)); + EXPECT_EQ_INT(0, c_avl_pick(t, (void *)&key, (void *)&value)); - free (key); - free (value); + free(key); + free(value); - EXPECT_EQ_INT (expected_size, c_avl_size (t)); + EXPECT_EQ_INT(expected_size, c_avl_size(t)); } - c_avl_destroy (t); + c_avl_destroy(t); return (0); } -int main (void) -{ +int main(void) { RUN_TEST(success); END_TEST; diff --git a/src/daemon/utils_cache.c b/src/daemon/utils_cache.c index 09298725..fe0e083e 100644 --- a/src/daemon/utils_cache.c +++ b/src/daemon/utils_cache.c @@ -29,45 +29,44 @@ #include "collectd.h" #include "common.h" +#include "meta_data.h" #include "plugin.h" #include "utils_avltree.h" #include "utils_cache.h" -#include "meta_data.h" #include -typedef struct cache_entry_s -{ - char name[6 * DATA_MAX_NAME_LEN]; - size_t values_num; - gauge_t *values_gauge; - value_t *values_raw; - /* Time contained in the package - * (for calculating rates) */ - cdtime_t last_time; - /* Time according to the local clock - * (for purging old entries) */ - cdtime_t last_update; - /* Interval in which the data is collected - * (for purging old entries) */ - cdtime_t interval; - int state; - int hits; - - /* - * +-----+-----+-----+-----+-----+-----+-----+-----+-----+---- - * ! 0 ! 1 ! 2 ! 3 ! 4 ! 5 ! 6 ! 7 ! 8 ! ... - * +-----+-----+-----+-----+-----+-----+-----+-----+-----+---- - * ! ds0 ! ds1 ! ds2 ! ds0 ! ds1 ! ds2 ! ds0 ! ds1 ! ds2 ! ... - * +-----+-----+-----+-----+-----+-----+-----+-----+-----+---- - * ! t = 0 ! t = 1 ! t = 2 ! ... - * +-----------------+-----------------+-----------------+---- - */ - gauge_t *history; - size_t history_index; /* points to the next position to write to. */ - size_t history_length; - - meta_data_t *meta; +typedef struct cache_entry_s { + char name[6 * DATA_MAX_NAME_LEN]; + size_t values_num; + gauge_t *values_gauge; + value_t *values_raw; + /* Time contained in the package + * (for calculating rates) */ + cdtime_t last_time; + /* Time according to the local clock + * (for purging old entries) */ + cdtime_t last_update; + /* Interval in which the data is collected + * (for purging old entries) */ + cdtime_t interval; + int state; + int hits; + + /* + * +-----+-----+-----+-----+-----+-----+-----+-----+-----+---- + * ! 0 ! 1 ! 2 ! 3 ! 4 ! 5 ! 6 ! 7 ! 8 ! ... + * +-----+-----+-----+-----+-----+-----+-----+-----+-----+---- + * ! ds0 ! ds1 ! ds2 ! ds0 ! ds1 ! ds2 ! ds0 ! ds1 ! ds2 ! ... + * +-----+-----+-----+-----+-----+-----+-----+-----+-----+---- + * ! t = 0 ! t = 1 ! t = 2 ! ... + * +-----------------+-----------------+-----------------+---- + */ + gauge_t *history; + size_t history_index; /* points to the next position to write to. */ + size_t history_length; + + meta_data_t *meta; } cache_entry_t; struct uc_iter_s { @@ -77,37 +76,33 @@ struct uc_iter_s { cache_entry_t *entry; }; -static c_avl_tree_t *cache_tree = NULL; +static c_avl_tree_t *cache_tree = NULL; static pthread_mutex_t cache_lock = PTHREAD_MUTEX_INITIALIZER; -static int cache_compare (const cache_entry_t *a, const cache_entry_t *b) -{ +static int cache_compare(const cache_entry_t *a, const cache_entry_t *b) { #if COLLECT_DEBUG - assert ((a != NULL) && (b != NULL)); + assert((a != NULL) && (b != NULL)); #endif - return (strcmp (a->name, b->name)); + return (strcmp(a->name, b->name)); } /* int cache_compare */ -static cache_entry_t *cache_alloc (size_t values_num) -{ +static cache_entry_t *cache_alloc(size_t values_num) { cache_entry_t *ce; - ce = calloc (1, sizeof (*ce)); - if (ce == NULL) - { - ERROR ("utils_cache: cache_alloc: calloc failed."); + ce = calloc(1, sizeof(*ce)); + if (ce == NULL) { + ERROR("utils_cache: cache_alloc: calloc failed."); return (NULL); } ce->values_num = values_num; - ce->values_gauge = calloc (values_num, sizeof (*ce->values_gauge)); - ce->values_raw = calloc (values_num, sizeof (*ce->values_raw)); - if ((ce->values_gauge == NULL) || (ce->values_raw == NULL)) - { - sfree (ce->values_gauge); - sfree (ce->values_raw); - sfree (ce); - ERROR ("utils_cache: cache_alloc: calloc failed."); + ce->values_gauge = calloc(values_num, sizeof(*ce->values_gauge)); + ce->values_raw = calloc(values_num, sizeof(*ce->values_raw)); + if ((ce->values_gauge == NULL) || (ce->values_raw == NULL)) { + sfree(ce->values_gauge); + sfree(ce->values_raw); + sfree(ce); + ERROR("utils_cache: cache_alloc: calloc failed."); return (NULL); } @@ -118,27 +113,23 @@ static cache_entry_t *cache_alloc (size_t values_num) return (ce); } /* cache_entry_t *cache_alloc */ -static void cache_free (cache_entry_t *ce) -{ +static void cache_free(cache_entry_t *ce) { if (ce == NULL) return; - sfree (ce->values_gauge); - sfree (ce->values_raw); - sfree (ce->history); - if (ce->meta != NULL) - { - meta_data_destroy (ce->meta); + sfree(ce->values_gauge); + sfree(ce->values_raw); + sfree(ce->history); + if (ce->meta != NULL) { + meta_data_destroy(ce->meta); ce->meta = NULL; } - sfree (ce); + sfree(ce); } /* void cache_free */ -static void uc_check_range (const data_set_t *ds, cache_entry_t *ce) -{ - for (size_t i = 0; i < ds->ds_num; i++) - { - if (isnan (ce->values_gauge[i])) +static void uc_check_range(const data_set_t *ds, cache_entry_t *ce) { + for (size_t i = 0; i < ds->ds_num; i++) { + if (isnan(ce->values_gauge[i])) continue; else if (ce->values_gauge[i] < ds->ds[i].min) ce->values_gauge[i] = NAN; @@ -147,98 +138,90 @@ static void uc_check_range (const data_set_t *ds, cache_entry_t *ce) } } /* void uc_check_range */ -static int uc_insert (const data_set_t *ds, const value_list_t *vl, - const char *key) -{ +static int uc_insert(const data_set_t *ds, const value_list_t *vl, + const char *key) { char *key_copy; cache_entry_t *ce; /* `cache_lock' has been locked by `uc_update' */ - key_copy = strdup (key); - if (key_copy == NULL) - { - ERROR ("uc_insert: strdup failed."); + key_copy = strdup(key); + if (key_copy == NULL) { + ERROR("uc_insert: strdup failed."); return (-1); } - ce = cache_alloc (ds->ds_num); - if (ce == NULL) - { - sfree (key_copy); - ERROR ("uc_insert: cache_alloc (%zu) failed.", ds->ds_num); + ce = cache_alloc(ds->ds_num); + if (ce == NULL) { + sfree(key_copy); + ERROR("uc_insert: cache_alloc (%zu) failed.", ds->ds_num); return (-1); } - sstrncpy (ce->name, key, sizeof (ce->name)); + sstrncpy(ce->name, key, sizeof(ce->name)); - for (size_t i = 0; i < ds->ds_num; i++) - { - switch (ds->ds[i].type) - { - case DS_TYPE_COUNTER: - ce->values_gauge[i] = NAN; - ce->values_raw[i].counter = vl->values[i].counter; - break; - - case DS_TYPE_GAUGE: - ce->values_gauge[i] = vl->values[i].gauge; - ce->values_raw[i].gauge = vl->values[i].gauge; - break; - - case DS_TYPE_DERIVE: - ce->values_gauge[i] = NAN; - ce->values_raw[i].derive = vl->values[i].derive; - break; - - case DS_TYPE_ABSOLUTE: - ce->values_gauge[i] = NAN; - if (vl->interval > 0) - ce->values_gauge[i] = ((double) vl->values[i].absolute) - / CDTIME_T_TO_DOUBLE (vl->interval); - ce->values_raw[i].absolute = vl->values[i].absolute; - break; - - default: - /* This shouldn't happen. */ - ERROR ("uc_insert: Don't know how to handle data source type %i.", - ds->ds[i].type); - sfree (key_copy); - cache_free (ce); - return (-1); + for (size_t i = 0; i < ds->ds_num; i++) { + switch (ds->ds[i].type) { + case DS_TYPE_COUNTER: + ce->values_gauge[i] = NAN; + ce->values_raw[i].counter = vl->values[i].counter; + break; + + case DS_TYPE_GAUGE: + ce->values_gauge[i] = vl->values[i].gauge; + ce->values_raw[i].gauge = vl->values[i].gauge; + break; + + case DS_TYPE_DERIVE: + ce->values_gauge[i] = NAN; + ce->values_raw[i].derive = vl->values[i].derive; + break; + + case DS_TYPE_ABSOLUTE: + ce->values_gauge[i] = NAN; + if (vl->interval > 0) + ce->values_gauge[i] = + ((double)vl->values[i].absolute) / CDTIME_T_TO_DOUBLE(vl->interval); + ce->values_raw[i].absolute = vl->values[i].absolute; + break; + + default: + /* This shouldn't happen. */ + ERROR("uc_insert: Don't know how to handle data source type %i.", + ds->ds[i].type); + sfree(key_copy); + cache_free(ce); + return (-1); } /* switch (ds->ds[i].type) */ - } /* for (i) */ + } /* for (i) */ /* Prune invalid gauge data */ - uc_check_range (ds, ce); + uc_check_range(ds, ce); ce->last_time = vl->time; - ce->last_update = cdtime (); + ce->last_update = cdtime(); ce->interval = vl->interval; ce->state = STATE_OKAY; - if (c_avl_insert (cache_tree, key_copy, ce) != 0) - { - sfree (key_copy); - ERROR ("uc_insert: c_avl_insert failed."); + if (c_avl_insert(cache_tree, key_copy, ce) != 0) { + sfree(key_copy); + ERROR("uc_insert: c_avl_insert failed."); return (-1); } - DEBUG ("uc_insert: Added %s to the cache.", key); + DEBUG("uc_insert: Added %s to the cache.", key); return (0); } /* int uc_insert */ -int uc_init (void) -{ +int uc_init(void) { if (cache_tree == NULL) - cache_tree = c_avl_create ((int (*) (const void *, const void *)) - cache_compare); + cache_tree = + c_avl_create((int (*)(const void *, const void *))cache_compare); return (0); } /* int uc_init */ -int uc_check_timeout (void) -{ +int uc_check_timeout(void) { cdtime_t now = cdtime(); struct { @@ -248,45 +231,41 @@ int uc_check_timeout (void) } *expired = NULL; size_t expired_num = 0; - pthread_mutex_lock (&cache_lock); + pthread_mutex_lock(&cache_lock); /* Build a list of entries to be flushed */ - c_avl_iterator_t *iter = c_avl_get_iterator (cache_tree); + c_avl_iterator_t *iter = c_avl_get_iterator(cache_tree); char *key = NULL; cache_entry_t *ce = NULL; - while (c_avl_iterator_next (iter, (void *) &key, (void *) &ce) == 0) - { + while (c_avl_iterator_next(iter, (void *)&key, (void *)&ce) == 0) { /* If the entry is fresh enough, continue. */ if ((now - ce->last_update) < (ce->interval * timeout_g)) continue; - void *tmp = realloc (expired, (expired_num + 1) * sizeof (*expired)); - if (tmp == NULL) - { - ERROR ("uc_check_timeout: realloc failed."); + void *tmp = realloc(expired, (expired_num + 1) * sizeof(*expired)); + if (tmp == NULL) { + ERROR("uc_check_timeout: realloc failed."); continue; } expired = tmp; - expired[expired_num].key = strdup (key); + expired[expired_num].key = strdup(key); expired[expired_num].time = ce->last_time; expired[expired_num].interval = ce->interval; - if (expired[expired_num].key == NULL) - { - ERROR ("uc_check_timeout: strdup failed."); + if (expired[expired_num].key == NULL) { + ERROR("uc_check_timeout: strdup failed."); continue; } expired_num++; } /* while (c_avl_iterator_next) */ - c_avl_iterator_destroy (iter); - pthread_mutex_unlock (&cache_lock); + c_avl_iterator_destroy(iter); + pthread_mutex_unlock(&cache_lock); - if (expired_num == 0) - { - sfree (expired); + if (expired_num == 0) { + sfree(expired); return (0); } @@ -295,198 +274,174 @@ int uc_check_timeout (void) * including plugin specific meta data, rates, history, …. This must be done * without holding the lock, otherwise we will run into a deadlock if a * plugin calls the cache interface. */ - for (size_t i = 0; i < expired_num; i++) - { + for (size_t i = 0; i < expired_num; i++) { value_list_t vl = { - .time = expired[i].time, - .interval = expired[i].interval, + .time = expired[i].time, .interval = expired[i].interval, }; - if (parse_identifier_vl (expired[i].key, &vl) != 0) - { - ERROR ("uc_check_timeout: parse_identifier_vl (\"%s\") failed.", expired[i].key); + if (parse_identifier_vl(expired[i].key, &vl) != 0) { + ERROR("uc_check_timeout: parse_identifier_vl (\"%s\") failed.", + expired[i].key); continue; } - plugin_dispatch_missing (&vl); + plugin_dispatch_missing(&vl); } /* for (i = 0; i < expired_num; i++) */ /* Now actually remove all the values from the cache. We don't re-evaluate * the timestamp again, so in theory it is possible we remove a value after * it is updated here. */ - pthread_mutex_lock (&cache_lock); - for (size_t i = 0; i < expired_num; i++) - { + pthread_mutex_lock(&cache_lock); + for (size_t i = 0; i < expired_num; i++) { char *key = NULL; cache_entry_t *value = NULL; - if (c_avl_remove (cache_tree, expired[i].key, (void *) &key, (void *) &value) != 0) - { - ERROR ("uc_check_timeout: c_avl_remove (\"%s\") failed.", expired[i].key); - sfree (expired[i].key); + if (c_avl_remove(cache_tree, expired[i].key, (void *)&key, + (void *)&value) != 0) { + ERROR("uc_check_timeout: c_avl_remove (\"%s\") failed.", expired[i].key); + sfree(expired[i].key); continue; } - sfree (key); - cache_free (value); + sfree(key); + cache_free(value); - sfree (expired[i].key); + sfree(expired[i].key); } /* for (i = 0; i < expired_num; i++) */ - pthread_mutex_unlock (&cache_lock); + pthread_mutex_unlock(&cache_lock); - sfree (expired); + sfree(expired); return (0); } /* int uc_check_timeout */ -int uc_update (const data_set_t *ds, const value_list_t *vl) -{ +int uc_update(const data_set_t *ds, const value_list_t *vl) { char name[6 * DATA_MAX_NAME_LEN]; cache_entry_t *ce = NULL; int status; - if (FORMAT_VL (name, sizeof (name), vl) != 0) - { - ERROR ("uc_update: FORMAT_VL failed."); + if (FORMAT_VL(name, sizeof(name), vl) != 0) { + ERROR("uc_update: FORMAT_VL failed."); return (-1); } - pthread_mutex_lock (&cache_lock); + pthread_mutex_lock(&cache_lock); - status = c_avl_get (cache_tree, name, (void *) &ce); + status = c_avl_get(cache_tree, name, (void *)&ce); if (status != 0) /* entry does not yet exist */ { - status = uc_insert (ds, vl, name); - pthread_mutex_unlock (&cache_lock); + status = uc_insert(ds, vl, name); + pthread_mutex_unlock(&cache_lock); return (status); } - assert (ce != NULL); - assert (ce->values_num == ds->ds_num); + assert(ce != NULL); + assert(ce->values_num == ds->ds_num); - if (ce->last_time >= vl->time) - { - pthread_mutex_unlock (&cache_lock); - 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)); + if (ce->last_time >= vl->time) { + pthread_mutex_unlock(&cache_lock); + 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); } - for (size_t i = 0; i < ds->ds_num; i++) - { - switch (ds->ds[i].type) - { - case DS_TYPE_COUNTER: - { - counter_t diff = counter_diff (ce->values_raw[i].counter, vl->values[i].counter); - ce->values_gauge[i] = ((double) diff) - / (CDTIME_T_TO_DOUBLE (vl->time - ce->last_time)); - ce->values_raw[i].counter = vl->values[i].counter; - } - break; - - case DS_TYPE_GAUGE: - ce->values_raw[i].gauge = vl->values[i].gauge; - ce->values_gauge[i] = vl->values[i].gauge; - break; - - case DS_TYPE_DERIVE: - { - derive_t diff = vl->values[i].derive - ce->values_raw[i].derive; - - ce->values_gauge[i] = ((double) diff) - / (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) - / (CDTIME_T_TO_DOUBLE (vl->time - ce->last_time)); - ce->values_raw[i].absolute = vl->values[i].absolute; - break; - - default: - /* This shouldn't happen. */ - pthread_mutex_unlock (&cache_lock); - ERROR ("uc_update: Don't know how to handle data source type %i.", - ds->ds[i].type); - return (-1); + for (size_t i = 0; i < ds->ds_num; i++) { + switch (ds->ds[i].type) { + case DS_TYPE_COUNTER: { + counter_t diff = + counter_diff(ce->values_raw[i].counter, vl->values[i].counter); + ce->values_gauge[i] = + ((double)diff) / (CDTIME_T_TO_DOUBLE(vl->time - ce->last_time)); + ce->values_raw[i].counter = vl->values[i].counter; + } break; + + case DS_TYPE_GAUGE: + ce->values_raw[i].gauge = vl->values[i].gauge; + ce->values_gauge[i] = vl->values[i].gauge; + break; + + case DS_TYPE_DERIVE: { + derive_t diff = vl->values[i].derive - ce->values_raw[i].derive; + + ce->values_gauge[i] = + ((double)diff) / (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) / + (CDTIME_T_TO_DOUBLE(vl->time - ce->last_time)); + ce->values_raw[i].absolute = vl->values[i].absolute; + break; + + default: + /* This shouldn't happen. */ + pthread_mutex_unlock(&cache_lock); + ERROR("uc_update: Don't know how to handle data source type %i.", + ds->ds[i].type); + return (-1); } /* switch (ds->ds[i].type) */ - DEBUG ("uc_update: %s: ds[%zu] = %lf", name, i, ce->values_gauge[i]); + DEBUG("uc_update: %s: ds[%zu] = %lf", name, i, ce->values_gauge[i]); } /* for (i) */ /* Update the history if it exists. */ - if (ce->history != NULL) - { - assert (ce->history_index < ce->history_length); - for (size_t i = 0; i < ce->values_num; i++) - { + if (ce->history != NULL) { + assert(ce->history_index < ce->history_length); + for (size_t i = 0; i < ce->values_num; i++) { size_t hist_idx = (ce->values_num * ce->history_index) + i; ce->history[hist_idx] = ce->values_gauge[i]; } - assert (ce->history_length > 0); + assert(ce->history_length > 0); ce->history_index = (ce->history_index + 1) % ce->history_length; } /* Prune invalid gauge data */ - uc_check_range (ds, ce); + uc_check_range(ds, ce); ce->last_time = vl->time; - ce->last_update = cdtime (); + ce->last_update = cdtime(); ce->interval = vl->interval; - pthread_mutex_unlock (&cache_lock); + pthread_mutex_unlock(&cache_lock); return (0); } /* int uc_update */ -int uc_get_rate_by_name (const char *name, gauge_t **ret_values, size_t *ret_values_num) -{ +int uc_get_rate_by_name(const char *name, gauge_t **ret_values, + size_t *ret_values_num) { gauge_t *ret = NULL; size_t ret_num = 0; cache_entry_t *ce = NULL; int status = 0; - pthread_mutex_lock (&cache_lock); + pthread_mutex_lock(&cache_lock); - if (c_avl_get (cache_tree, name, (void *) &ce) == 0) - { - assert (ce != NULL); + if (c_avl_get(cache_tree, name, (void *)&ce) == 0) { + assert(ce != NULL); /* remove missing values from getval */ - if (ce->state == STATE_MISSING) - { + if (ce->state == STATE_MISSING) { status = -1; - } - else - { + } else { ret_num = ce->values_num; - ret = malloc (ret_num * sizeof (*ret)); - if (ret == NULL) - { - ERROR ("utils_cache: uc_get_rate_by_name: malloc failed."); + ret = malloc(ret_num * sizeof(*ret)); + if (ret == NULL) { + ERROR("utils_cache: uc_get_rate_by_name: malloc failed."); status = -1; - } - else - { - memcpy (ret, ce->values_gauge, ret_num * sizeof (gauge_t)); + } else { + memcpy(ret, ce->values_gauge, ret_num * sizeof(gauge_t)); } } - } - else - { - DEBUG ("utils_cache: uc_get_rate_by_name: No such value: %s", name); + } else { + DEBUG("utils_cache: uc_get_rate_by_name: No such value: %s", name); status = -1; } - pthread_mutex_unlock (&cache_lock); + pthread_mutex_unlock(&cache_lock); - if (status == 0) - { + if (status == 0) { *ret_values = ret; *ret_values_num = ret_num; } @@ -494,49 +449,45 @@ int uc_get_rate_by_name (const char *name, gauge_t **ret_values, size_t *ret_val return (status); } /* gauge_t *uc_get_rate_by_name */ -gauge_t *uc_get_rate (const data_set_t *ds, const value_list_t *vl) -{ +gauge_t *uc_get_rate(const data_set_t *ds, const value_list_t *vl) { char name[6 * DATA_MAX_NAME_LEN]; gauge_t *ret = NULL; size_t ret_num = 0; int status; - if (FORMAT_VL (name, sizeof (name), vl) != 0) - { - ERROR ("utils_cache: uc_get_rate: FORMAT_VL failed."); + if (FORMAT_VL(name, sizeof(name), vl) != 0) { + ERROR("utils_cache: uc_get_rate: FORMAT_VL failed."); return (NULL); } - status = uc_get_rate_by_name (name, &ret, &ret_num); + status = uc_get_rate_by_name(name, &ret, &ret_num); if (status != 0) return (NULL); /* This is important - the caller has no other way of knowing how many * values are returned. */ - if (ret_num != (size_t) ds->ds_num) - { - ERROR ("utils_cache: uc_get_rate: ds[%s] has %zu values, " - "but uc_get_rate_by_name returned %zu.", - ds->type, ds->ds_num, ret_num); - sfree (ret); + if (ret_num != (size_t)ds->ds_num) { + ERROR("utils_cache: uc_get_rate: ds[%s] has %zu values, " + "but uc_get_rate_by_name returned %zu.", + ds->type, ds->ds_num, ret_num); + sfree(ret); return (NULL); } return (ret); } /* gauge_t *uc_get_rate */ -size_t uc_get_size (void) { +size_t uc_get_size(void) { size_t size_arrays = 0; - pthread_mutex_lock (&cache_lock); - size_arrays = (size_t) c_avl_size (cache_tree); - pthread_mutex_unlock (&cache_lock); + pthread_mutex_lock(&cache_lock); + size_arrays = (size_t)c_avl_size(cache_tree); + pthread_mutex_unlock(&cache_lock); return (size_arrays); } -int uc_get_names (char ***ret_names, cdtime_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; @@ -551,45 +502,41 @@ int uc_get_names (char ***ret_names, cdtime_t **ret_times, size_t *ret_number) if ((ret_names == NULL) || (ret_number == NULL)) return (-1); - pthread_mutex_lock (&cache_lock); + pthread_mutex_lock(&cache_lock); - size_arrays = (size_t) c_avl_size (cache_tree); - if (size_arrays < 1) - { + size_arrays = (size_t)c_avl_size(cache_tree); + if (size_arrays < 1) { /* Handle the "no values" case here, to avoid the error message when * calloc() returns NULL. */ - pthread_mutex_unlock (&cache_lock); + pthread_mutex_unlock(&cache_lock); return (0); } - names = calloc (size_arrays, sizeof (*names)); - times = calloc (size_arrays, sizeof (*times)); - if ((names == NULL) || (times == NULL)) - { - ERROR ("uc_get_names: calloc failed."); - sfree (names); - sfree (times); - pthread_mutex_unlock (&cache_lock); + names = calloc(size_arrays, sizeof(*names)); + times = calloc(size_arrays, sizeof(*times)); + if ((names == NULL) || (times == NULL)) { + ERROR("uc_get_names: calloc failed."); + sfree(names); + sfree(times); + pthread_mutex_unlock(&cache_lock); return (ENOMEM); } - iter = c_avl_get_iterator (cache_tree); - while (c_avl_iterator_next (iter, (void *) &key, (void *) &value) == 0) - { + iter = c_avl_get_iterator(cache_tree); + while (c_avl_iterator_next(iter, (void *)&key, (void *)&value) == 0) { /* remove missing values when list values */ if (value->state == STATE_MISSING) continue; /* c_avl_size does not return a number smaller than the number of elements * returned by c_avl_iterator_next. */ - assert (number < size_arrays); + assert(number < size_arrays); if (ret_times != NULL) times[number] = value->last_time; - names[number] = strdup (key); - if (names[number] == NULL) - { + names[number] = strdup(key); + if (names[number] == NULL) { status = -1; break; } @@ -597,17 +544,15 @@ int uc_get_names (char ***ret_names, cdtime_t **ret_times, size_t *ret_number) number++; } /* while (c_avl_iterator_next) */ - c_avl_iterator_destroy (iter); - pthread_mutex_unlock (&cache_lock); + c_avl_iterator_destroy(iter); + pthread_mutex_unlock(&cache_lock); - if (status != 0) - { - for (size_t i = 0; i < number; i++) - { - sfree (names[i]); + if (status != 0) { + for (size_t i = 0; i < number; i++) { + sfree(names[i]); } - sfree (names); - sfree (times); + sfree(names); + sfree(times); return (-1); } @@ -616,101 +561,89 @@ int uc_get_names (char ***ret_names, cdtime_t **ret_times, size_t *ret_number) if (ret_times != NULL) *ret_times = times; else - sfree (times); + sfree(times); *ret_number = number; return (0); } /* int uc_get_names */ -int uc_get_state (const data_set_t *ds, const value_list_t *vl) -{ +int uc_get_state(const data_set_t *ds, const value_list_t *vl) { char name[6 * DATA_MAX_NAME_LEN]; cache_entry_t *ce = NULL; int ret = STATE_ERROR; - if (FORMAT_VL (name, sizeof (name), vl) != 0) - { - ERROR ("uc_get_state: FORMAT_VL failed."); + if (FORMAT_VL(name, sizeof(name), vl) != 0) { + ERROR("uc_get_state: FORMAT_VL failed."); return (STATE_ERROR); } - pthread_mutex_lock (&cache_lock); + pthread_mutex_lock(&cache_lock); - if (c_avl_get (cache_tree, name, (void *) &ce) == 0) - { - assert (ce != NULL); + if (c_avl_get(cache_tree, name, (void *)&ce) == 0) { + assert(ce != NULL); ret = ce->state; } - pthread_mutex_unlock (&cache_lock); + pthread_mutex_unlock(&cache_lock); return (ret); } /* int uc_get_state */ -int uc_set_state (const data_set_t *ds, const value_list_t *vl, int state) -{ +int uc_set_state(const data_set_t *ds, const value_list_t *vl, int state) { char name[6 * DATA_MAX_NAME_LEN]; cache_entry_t *ce = NULL; int ret = -1; - if (FORMAT_VL (name, sizeof (name), vl) != 0) - { - ERROR ("uc_set_state: FORMAT_VL failed."); + if (FORMAT_VL(name, sizeof(name), vl) != 0) { + ERROR("uc_set_state: FORMAT_VL failed."); return (STATE_ERROR); } - pthread_mutex_lock (&cache_lock); + pthread_mutex_lock(&cache_lock); - if (c_avl_get (cache_tree, name, (void *) &ce) == 0) - { - assert (ce != NULL); + if (c_avl_get(cache_tree, name, (void *)&ce) == 0) { + assert(ce != NULL); ret = ce->state; ce->state = state; } - pthread_mutex_unlock (&cache_lock); + pthread_mutex_unlock(&cache_lock); return (ret); } /* int uc_set_state */ -int uc_get_history_by_name (const char *name, - gauge_t *ret_history, size_t num_steps, size_t num_ds) -{ +int uc_get_history_by_name(const char *name, gauge_t *ret_history, + size_t num_steps, size_t num_ds) { cache_entry_t *ce = NULL; int status = 0; - pthread_mutex_lock (&cache_lock); + pthread_mutex_lock(&cache_lock); - status = c_avl_get (cache_tree, name, (void *) &ce); - if (status != 0) - { - pthread_mutex_unlock (&cache_lock); + status = c_avl_get(cache_tree, name, (void *)&ce); + if (status != 0) { + pthread_mutex_unlock(&cache_lock); return (-ENOENT); } - if (((size_t) ce->values_num) != num_ds) - { - pthread_mutex_unlock (&cache_lock); + if (((size_t)ce->values_num) != num_ds) { + pthread_mutex_unlock(&cache_lock); return (-EINVAL); } /* Check if there are enough values available. If not, increase the buffer * size. */ - if (ce->history_length < num_steps) - { + if (ce->history_length < num_steps) { gauge_t *tmp; - tmp = realloc (ce->history, sizeof (*ce->history) - * num_steps * ce->values_num); - if (tmp == NULL) - { - pthread_mutex_unlock (&cache_lock); + tmp = + realloc(ce->history, sizeof(*ce->history) * num_steps * ce->values_num); + if (tmp == NULL) { + pthread_mutex_unlock(&cache_lock); return (-ENOMEM); } for (size_t i = ce->history_length * ce->values_num; - i < (num_steps * ce->values_num); - i++) + i < (num_steps * ce->values_num); i++) tmp[i] = NAN; ce->history = tmp; @@ -718,8 +651,7 @@ int uc_get_history_by_name (const char *name, } /* if (ce->history_length < num_steps) */ /* Copy the values to the output buffer. */ - for (size_t i = 0; i < num_steps; i++) - { + for (size_t i = 0; i < num_steps; i++) { size_t src_index; size_t dst_index; @@ -731,102 +663,91 @@ int uc_get_history_by_name (const char *name, dst_index = i * num_ds; - memcpy (ret_history + dst_index, ce->history + src_index, - sizeof (*ret_history) * num_ds); + memcpy(ret_history + dst_index, ce->history + src_index, + sizeof(*ret_history) * num_ds); } - pthread_mutex_unlock (&cache_lock); + pthread_mutex_unlock(&cache_lock); return (0); } /* int uc_get_history_by_name */ -int uc_get_history (const data_set_t *ds, const value_list_t *vl, - gauge_t *ret_history, size_t num_steps, size_t num_ds) -{ +int uc_get_history(const data_set_t *ds, const value_list_t *vl, + gauge_t *ret_history, size_t num_steps, size_t num_ds) { char name[6 * DATA_MAX_NAME_LEN]; - if (FORMAT_VL (name, sizeof (name), vl) != 0) - { - ERROR ("utils_cache: uc_get_history: FORMAT_VL failed."); + if (FORMAT_VL(name, sizeof(name), vl) != 0) { + ERROR("utils_cache: uc_get_history: FORMAT_VL failed."); return (-1); } - return (uc_get_history_by_name (name, ret_history, num_steps, num_ds)); + return (uc_get_history_by_name(name, ret_history, num_steps, num_ds)); } /* int uc_get_history */ -int uc_get_hits (const data_set_t *ds, const value_list_t *vl) -{ +int uc_get_hits(const data_set_t *ds, const value_list_t *vl) { char name[6 * DATA_MAX_NAME_LEN]; cache_entry_t *ce = NULL; int ret = STATE_ERROR; - if (FORMAT_VL (name, sizeof (name), vl) != 0) - { - ERROR ("uc_get_hits: FORMAT_VL failed."); + if (FORMAT_VL(name, sizeof(name), vl) != 0) { + ERROR("uc_get_hits: FORMAT_VL failed."); return (STATE_ERROR); } - pthread_mutex_lock (&cache_lock); + pthread_mutex_lock(&cache_lock); - if (c_avl_get (cache_tree, name, (void *) &ce) == 0) - { - assert (ce != NULL); + if (c_avl_get(cache_tree, name, (void *)&ce) == 0) { + assert(ce != NULL); ret = ce->hits; } - pthread_mutex_unlock (&cache_lock); + pthread_mutex_unlock(&cache_lock); return (ret); } /* int uc_get_hits */ -int uc_set_hits (const data_set_t *ds, const value_list_t *vl, int hits) -{ +int uc_set_hits(const data_set_t *ds, const value_list_t *vl, int hits) { char name[6 * DATA_MAX_NAME_LEN]; cache_entry_t *ce = NULL; int ret = -1; - if (FORMAT_VL (name, sizeof (name), vl) != 0) - { - ERROR ("uc_set_hits: FORMAT_VL failed."); + if (FORMAT_VL(name, sizeof(name), vl) != 0) { + ERROR("uc_set_hits: FORMAT_VL failed."); return (STATE_ERROR); } - pthread_mutex_lock (&cache_lock); + pthread_mutex_lock(&cache_lock); - if (c_avl_get (cache_tree, name, (void *) &ce) == 0) - { - assert (ce != NULL); + if (c_avl_get(cache_tree, name, (void *)&ce) == 0) { + assert(ce != NULL); ret = ce->hits; ce->hits = hits; } - pthread_mutex_unlock (&cache_lock); + pthread_mutex_unlock(&cache_lock); return (ret); } /* int uc_set_hits */ -int uc_inc_hits (const data_set_t *ds, const value_list_t *vl, int step) -{ +int uc_inc_hits(const data_set_t *ds, const value_list_t *vl, int step) { char name[6 * DATA_MAX_NAME_LEN]; cache_entry_t *ce = NULL; int ret = -1; - if (FORMAT_VL (name, sizeof (name), vl) != 0) - { - ERROR ("uc_inc_hits: FORMAT_VL failed."); + if (FORMAT_VL(name, sizeof(name), vl) != 0) { + ERROR("uc_inc_hits: FORMAT_VL failed."); return (STATE_ERROR); } - pthread_mutex_lock (&cache_lock); + pthread_mutex_lock(&cache_lock); - if (c_avl_get (cache_tree, name, (void *) &ce) == 0) - { - assert (ce != NULL); + if (c_avl_get(cache_tree, name, (void *)&ce) == 0) { + assert(ce != NULL); ret = ce->hits; ce->hits = ret + step; } - pthread_mutex_unlock (&cache_lock); + pthread_mutex_unlock(&cache_lock); return (ret); } /* int uc_inc_hits */ @@ -834,36 +755,32 @@ int uc_inc_hits (const data_set_t *ds, const value_list_t *vl, int step) /* * Iterator interface */ -uc_iter_t *uc_get_iterator (void) -{ +uc_iter_t *uc_get_iterator(void) { uc_iter_t *iter; - iter = (uc_iter_t *) calloc(1, sizeof (*iter)); + iter = (uc_iter_t *)calloc(1, sizeof(*iter)); if (iter == NULL) return (NULL); - pthread_mutex_lock (&cache_lock); + pthread_mutex_lock(&cache_lock); - iter->iter = c_avl_get_iterator (cache_tree); - if (iter->iter == NULL) - { - free (iter); + iter->iter = c_avl_get_iterator(cache_tree); + if (iter->iter == NULL) { + free(iter); return (NULL); } return (iter); } /* uc_iter_t *uc_get_iterator */ -int uc_iterator_next (uc_iter_t *iter, char **ret_name) -{ +int uc_iterator_next(uc_iter_t *iter, char **ret_name) { int status; if (iter == NULL) return (-1); - while ((status = c_avl_iterator_next (iter->iter, - (void *) &iter->name, (void *) &iter->entry)) == 0) - { + while ((status = c_avl_iterator_next(iter->iter, (void *)&iter->name, + (void *)&iter->entry)) == 0) { if (iter->entry->state == STATE_MISSING) continue; @@ -881,19 +798,17 @@ int uc_iterator_next (uc_iter_t *iter, char **ret_name) return (0); } /* int uc_iterator_next */ -void uc_iterator_destroy (uc_iter_t *iter) -{ +void uc_iterator_destroy(uc_iter_t *iter) { if (iter == NULL) return; - c_avl_iterator_destroy (iter->iter); - pthread_mutex_unlock (&cache_lock); + c_avl_iterator_destroy(iter->iter); + pthread_mutex_unlock(&cache_lock); - free (iter); + free(iter); } /* void uc_iterator_destroy */ -int uc_iterator_get_time (uc_iter_t *iter, cdtime_t *ret_time) -{ +int uc_iterator_get_time(uc_iter_t *iter, cdtime_t *ret_time) { if ((iter == NULL) || (iter->entry == NULL) || (ret_time == NULL)) return (-1); @@ -901,13 +816,14 @@ int uc_iterator_get_time (uc_iter_t *iter, cdtime_t *ret_time) return (0); } /* int uc_iterator_get_name */ -int uc_iterator_get_values (uc_iter_t *iter, value_t **ret_values, size_t *ret_num) -{ - if ((iter == NULL) || (iter->entry == NULL) - || (ret_values == NULL) || (ret_num == NULL)) +int uc_iterator_get_values(uc_iter_t *iter, value_t **ret_values, + size_t *ret_num) { + if ((iter == NULL) || (iter->entry == NULL) || (ret_values == NULL) || + (ret_num == NULL)) return (-1); - *ret_values = calloc (iter->entry->values_num, sizeof(*iter->entry->values_raw)); + *ret_values = + calloc(iter->entry->values_num, sizeof(*iter->entry->values_raw)); if (*ret_values == NULL) return (-1); for (size_t i = 0; i < iter->entry->values_num; ++i) @@ -918,8 +834,7 @@ int uc_iterator_get_values (uc_iter_t *iter, value_t **ret_values, size_t *ret_n return (0); } /* int uc_iterator_get_values */ -int uc_iterator_get_interval (uc_iter_t *iter, cdtime_t *ret_interval) -{ +int uc_iterator_get_interval(uc_iter_t *iter, cdtime_t *ret_interval) { if ((iter == NULL) || (iter->entry == NULL) || (ret_interval == NULL)) return (-1); @@ -931,108 +846,97 @@ int uc_iterator_get_interval (uc_iter_t *iter, cdtime_t *ret_interval) * Meta data interface */ /* XXX: This function will acquire `cache_lock' but will not free it! */ -static meta_data_t *uc_get_meta (const value_list_t *vl) /* {{{ */ +static meta_data_t *uc_get_meta(const value_list_t *vl) /* {{{ */ { char name[6 * DATA_MAX_NAME_LEN]; cache_entry_t *ce = NULL; int status; - status = FORMAT_VL (name, sizeof (name), vl); - if (status != 0) - { - ERROR ("utils_cache: uc_get_meta: FORMAT_VL failed."); + status = FORMAT_VL(name, sizeof(name), vl); + if (status != 0) { + ERROR("utils_cache: uc_get_meta: FORMAT_VL failed."); return (NULL); } - pthread_mutex_lock (&cache_lock); + pthread_mutex_lock(&cache_lock); - status = c_avl_get (cache_tree, name, (void *) &ce); - if (status != 0) - { - pthread_mutex_unlock (&cache_lock); + status = c_avl_get(cache_tree, name, (void *)&ce); + if (status != 0) { + pthread_mutex_unlock(&cache_lock); return (NULL); } - assert (ce != NULL); + assert(ce != NULL); if (ce->meta == NULL) - ce->meta = meta_data_create (); + ce->meta = meta_data_create(); if (ce->meta == NULL) - pthread_mutex_unlock (&cache_lock); + pthread_mutex_unlock(&cache_lock); return (ce->meta); } /* }}} meta_data_t *uc_get_meta */ /* Sorry about this preprocessor magic, but it really makes this file much * shorter.. */ -#define UC_WRAP(wrap_function) { \ - meta_data_t *meta; \ - int status; \ - meta = uc_get_meta (vl); \ - if (meta == NULL) return (-1); \ - status = wrap_function (meta, key); \ - pthread_mutex_unlock (&cache_lock); \ - return (status); \ -} -int uc_meta_data_exists (const value_list_t *vl, const char *key) - UC_WRAP (meta_data_exists) - -int uc_meta_data_delete (const value_list_t *vl, const char *key) - UC_WRAP (meta_data_delete) +#define UC_WRAP(wrap_function) \ + { \ + meta_data_t *meta; \ + int status; \ + meta = uc_get_meta(vl); \ + if (meta == NULL) \ + return (-1); \ + status = wrap_function(meta, key); \ + pthread_mutex_unlock(&cache_lock); \ + return (status); \ + } +int uc_meta_data_exists(const value_list_t *vl, + const char *key) UC_WRAP(meta_data_exists) + + int uc_meta_data_delete(const value_list_t *vl, + const char *key) UC_WRAP(meta_data_delete) #undef UC_WRAP /* We need a new version of this macro because the following functions take * two argumetns. */ -#define UC_WRAP(wrap_function) { \ - meta_data_t *meta; \ - int status; \ - meta = uc_get_meta (vl); \ - if (meta == NULL) return (-1); \ - status = wrap_function (meta, key, value); \ - pthread_mutex_unlock (&cache_lock); \ - return (status); \ -} -int uc_meta_data_add_string (const value_list_t *vl, - const char *key, - const char *value) - UC_WRAP(meta_data_add_string) -int uc_meta_data_add_signed_int (const value_list_t *vl, - const char *key, - int64_t value) - UC_WRAP(meta_data_add_signed_int) -int uc_meta_data_add_unsigned_int (const value_list_t *vl, - const char *key, - uint64_t value) - UC_WRAP(meta_data_add_unsigned_int) -int uc_meta_data_add_double (const value_list_t *vl, - const char *key, - double value) - UC_WRAP(meta_data_add_double) -int uc_meta_data_add_boolean (const value_list_t *vl, - const char *key, - _Bool value) - UC_WRAP(meta_data_add_boolean) - -int uc_meta_data_get_string (const value_list_t *vl, - const char *key, - char **value) - UC_WRAP(meta_data_get_string) -int uc_meta_data_get_signed_int (const value_list_t *vl, - const char *key, - int64_t *value) - UC_WRAP(meta_data_get_signed_int) -int uc_meta_data_get_unsigned_int (const value_list_t *vl, - const char *key, - uint64_t *value) - UC_WRAP(meta_data_get_unsigned_int) -int uc_meta_data_get_double (const value_list_t *vl, - const char *key, - double *value) - UC_WRAP(meta_data_get_double) -int uc_meta_data_get_boolean (const value_list_t *vl, - const char *key, - _Bool *value) - UC_WRAP(meta_data_get_boolean) +#define UC_WRAP(wrap_function) \ + { \ + meta_data_t *meta; \ + int status; \ + meta = uc_get_meta(vl); \ + if (meta == NULL) \ + return (-1); \ + status = wrap_function(meta, key, value); \ + pthread_mutex_unlock(&cache_lock); \ + return (status); \ + } + int uc_meta_data_add_string(const value_list_t *vl, const char *key, + const char *value) + UC_WRAP(meta_data_add_string) int uc_meta_data_add_signed_int( + const value_list_t *vl, const char *key, int64_t value) + UC_WRAP(meta_data_add_signed_int) int uc_meta_data_add_unsigned_int( + const value_list_t *vl, const char *key, uint64_t value) + UC_WRAP(meta_data_add_unsigned_int) int uc_meta_data_add_double( + const value_list_t *vl, const char *key, double value) + UC_WRAP(meta_data_add_double) int uc_meta_data_add_boolean( + const value_list_t *vl, const char *key, + _Bool value) UC_WRAP(meta_data_add_boolean) + + int uc_meta_data_get_string(const value_list_t *vl, + const char *key, + char **value) + UC_WRAP(meta_data_get_string) int uc_meta_data_get_signed_int( + const value_list_t *vl, const char *key, + int64_t *value) + UC_WRAP(meta_data_get_signed_int) int uc_meta_data_get_unsigned_int( + const value_list_t *vl, const char *key, + uint64_t *value) + UC_WRAP(meta_data_get_unsigned_int) int uc_meta_data_get_double( + const value_list_t *vl, + const char *key, double *value) + UC_WRAP(meta_data_get_double) int uc_meta_data_get_boolean( + const value_list_t *vl, + const char *key, _Bool *value) + UC_WRAP(meta_data_get_boolean) #undef UC_WRAP -/* vim: set sw=2 ts=8 sts=2 tw=78 : */ + /* vim: set sw=2 ts=8 sts=2 tw=78 : */ diff --git a/src/daemon/utils_cache.h b/src/daemon/utils_cache.h index e020429b..2f408734 100644 --- a/src/daemon/utils_cache.h +++ b/src/daemon/utils_cache.h @@ -31,30 +31,31 @@ #include "plugin.h" -#define STATE_OKAY 0 -#define STATE_WARNING 1 -#define STATE_ERROR 2 +#define STATE_OKAY 0 +#define STATE_WARNING 1 +#define STATE_ERROR 2 #define STATE_MISSING 15 -int uc_init (void); -int uc_check_timeout (void); -int uc_update (const data_set_t *ds, const value_list_t *vl); -int uc_get_rate_by_name (const char *name, gauge_t **ret_values, size_t *ret_values_num); -gauge_t *uc_get_rate (const data_set_t *ds, const value_list_t *vl); +int uc_init(void); +int uc_check_timeout(void); +int uc_update(const data_set_t *ds, const value_list_t *vl); +int uc_get_rate_by_name(const char *name, gauge_t **ret_values, + size_t *ret_values_num); +gauge_t *uc_get_rate(const data_set_t *ds, const value_list_t *vl); -size_t uc_get_size (void); -int uc_get_names (char ***ret_names, cdtime_t **ret_times, size_t *ret_number); +size_t uc_get_size(void); +int uc_get_names(char ***ret_names, cdtime_t **ret_times, size_t *ret_number); -int uc_get_state (const data_set_t *ds, const value_list_t *vl); -int uc_set_state (const data_set_t *ds, const value_list_t *vl, int state); -int uc_get_hits (const data_set_t *ds, const value_list_t *vl); -int uc_set_hits (const data_set_t *ds, const value_list_t *vl, int hits); -int uc_inc_hits (const data_set_t *ds, const value_list_t *vl, int step); +int uc_get_state(const data_set_t *ds, const value_list_t *vl); +int uc_set_state(const data_set_t *ds, const value_list_t *vl, int state); +int uc_get_hits(const data_set_t *ds, const value_list_t *vl); +int uc_set_hits(const data_set_t *ds, const value_list_t *vl, int hits); +int uc_inc_hits(const data_set_t *ds, const value_list_t *vl, int step); -int uc_get_history (const data_set_t *ds, const value_list_t *vl, - gauge_t *ret_history, size_t num_steps, size_t num_ds); -int uc_get_history_by_name (const char *name, - gauge_t *ret_history, size_t num_steps, size_t num_ds); +int uc_get_history(const data_set_t *ds, const value_list_t *vl, + gauge_t *ret_history, size_t num_steps, size_t num_ds); +int uc_get_history_by_name(const char *name, gauge_t *ret_history, + size_t num_steps, size_t num_ds); /* * Iterator interface @@ -73,7 +74,7 @@ typedef struct uc_iter_s uc_iter_t; * RETURN VALUE * An iterator object on success or NULL else. */ -uc_iter_t *uc_get_iterator (void); +uc_iter_t *uc_get_iterator(void); /* * NAME @@ -93,53 +94,44 @@ uc_iter_t *uc_get_iterator (void); * Zero upon success or non-zero if the iterator ie NULL or no further * values are available. */ -int uc_iterator_next (uc_iter_t *iter, char **ret_name); -void uc_iterator_destroy (uc_iter_t *iter); +int uc_iterator_next(uc_iter_t *iter, char **ret_name); +void uc_iterator_destroy(uc_iter_t *iter); /* Return the timestamp of the value at the current position. */ -int uc_iterator_get_time (uc_iter_t *iter, cdtime_t *ret_time); +int uc_iterator_get_time(uc_iter_t *iter, cdtime_t *ret_time); /* Return the (raw) value at the current position. */ -int uc_iterator_get_values (uc_iter_t *iter, value_t **ret_values, size_t *ret_num); +int uc_iterator_get_values(uc_iter_t *iter, value_t **ret_values, + size_t *ret_num); /* Return the interval of the value at the current position. */ -int uc_iterator_get_interval (uc_iter_t *iter, cdtime_t *ret_interval); +int uc_iterator_get_interval(uc_iter_t *iter, cdtime_t *ret_interval); /* * Meta data interface */ -int uc_meta_data_exists (const value_list_t *vl, const char *key); -int uc_meta_data_delete (const value_list_t *vl, const char *key); +int uc_meta_data_exists(const value_list_t *vl, const char *key); +int uc_meta_data_delete(const value_list_t *vl, const char *key); -int uc_meta_data_add_string (const value_list_t *vl, - const char *key, - const char *value); -int uc_meta_data_add_signed_int (const value_list_t *vl, - const char *key, - int64_t value); -int uc_meta_data_add_unsigned_int (const value_list_t *vl, - const char *key, - uint64_t value); -int uc_meta_data_add_double (const value_list_t *vl, - const char *key, - double value); -int uc_meta_data_add_boolean (const value_list_t *vl, - const char *key, - _Bool value); +int uc_meta_data_add_string(const value_list_t *vl, const char *key, + const char *value); +int uc_meta_data_add_signed_int(const value_list_t *vl, const char *key, + int64_t value); +int uc_meta_data_add_unsigned_int(const value_list_t *vl, const char *key, + uint64_t value); +int uc_meta_data_add_double(const value_list_t *vl, const char *key, + double value); +int uc_meta_data_add_boolean(const value_list_t *vl, const char *key, + _Bool value); -int uc_meta_data_get_string (const value_list_t *vl, - const char *key, - char **value); -int uc_meta_data_get_signed_int (const value_list_t *vl, - const char *key, - int64_t *value); -int uc_meta_data_get_unsigned_int (const value_list_t *vl, - const char *key, - uint64_t *value); -int uc_meta_data_get_double (const value_list_t *vl, - const char *key, - double *value); -int uc_meta_data_get_boolean (const value_list_t *vl, - const char *key, - _Bool *value); +int uc_meta_data_get_string(const value_list_t *vl, const char *key, + char **value); +int uc_meta_data_get_signed_int(const value_list_t *vl, const char *key, + int64_t *value); +int uc_meta_data_get_unsigned_int(const value_list_t *vl, const char *key, + uint64_t *value); +int uc_meta_data_get_double(const value_list_t *vl, const char *key, + double *value); +int uc_meta_data_get_boolean(const value_list_t *vl, const char *key, + _Bool *value); /* vim: set shiftwidth=2 softtabstop=2 tabstop=8 : */ #endif /* !UTILS_CACHE_H */ diff --git a/src/daemon/utils_cache_mock.c b/src/daemon/utils_cache_mock.c index 3a14d043..0f0077df 100644 --- a/src/daemon/utils_cache_mock.c +++ b/src/daemon/utils_cache_mock.c @@ -24,22 +24,20 @@ * Florian octo Forster */ -#include "utils_cache.h" #include +#include "utils_cache.h" -gauge_t *uc_get_rate (__attribute__((unused)) data_set_t const *ds, - __attribute__((unused)) value_list_t const *vl) -{ +gauge_t *uc_get_rate(__attribute__((unused)) data_set_t const *ds, + __attribute__((unused)) value_list_t const *vl) { errno = ENOTSUP; return (NULL); } -int uc_get_rate_by_name (const char *name, gauge_t **ret_values, size_t *ret_values_num) -{ +int uc_get_rate_by_name(const char *name, gauge_t **ret_values, + size_t *ret_values_num) { return (ENOTSUP); } -int uc_get_names (char ***ret_names, cdtime_t **ret_times, size_t *ret_number) -{ +int uc_get_names(char ***ret_names, cdtime_t **ret_times, size_t *ret_number) { return (ENOTSUP); } diff --git a/src/daemon/utils_complain.c b/src/daemon/utils_complain.c index 69909bb6..fb452431 100644 --- a/src/daemon/utils_complain.c +++ b/src/daemon/utils_complain.c @@ -28,79 +28,74 @@ #include "collectd.h" -#include "utils_complain.h" #include "plugin.h" +#include "utils_complain.h" /* vcomplain returns 0 if it did not report, 1 else */ -__attribute__ ((format (printf, 3, 0))) -static int vcomplain (int level, c_complain_t *c, - const char *format, va_list ap) -{ - cdtime_t now; - char message[512]; +__attribute__((format(printf, 3, 0))) static int +vcomplain(int level, c_complain_t *c, const char *format, va_list ap) { + cdtime_t now; + char message[512]; - now = cdtime (); + now = cdtime(); - if (c->last + c->interval > now) - return 0; + if (c->last + c->interval > now) + return 0; - c->last = now; + c->last = now; - if (c->interval < plugin_get_interval ()) - c->interval = plugin_get_interval (); - else - c->interval *= 2; + if (c->interval < plugin_get_interval()) + c->interval = plugin_get_interval(); + else + c->interval *= 2; - if (c->interval > TIME_T_TO_CDTIME_T (86400)) - c->interval = TIME_T_TO_CDTIME_T (86400); + if (c->interval > TIME_T_TO_CDTIME_T(86400)) + c->interval = TIME_T_TO_CDTIME_T(86400); - vsnprintf (message, sizeof (message), format, ap); - message[sizeof (message) - 1] = '\0'; + vsnprintf(message, sizeof(message), format, ap); + message[sizeof(message) - 1] = '\0'; - plugin_log (level, "%s", message); - return 1; + plugin_log(level, "%s", message); + return 1; } /* vcomplain */ -void c_complain (int level, c_complain_t *c, const char *format, ...) -{ - va_list ap; +void c_complain(int level, c_complain_t *c, const char *format, ...) { + va_list ap; - va_start (ap, format); - if (vcomplain (level, c, format, ap)) - c->complained_once = 1; - va_end (ap); + va_start(ap, format); + if (vcomplain(level, c, format, ap)) + c->complained_once = 1; + va_end(ap); } /* c_complain */ -void c_complain_once (int level, c_complain_t *c, const char *format, ...) -{ - va_list ap; +void c_complain_once(int level, c_complain_t *c, const char *format, ...) { + va_list ap; - if (c->complained_once) - return; + if (c->complained_once) + return; - va_start (ap, format); - if (vcomplain (level, c, format, ap)) - c->complained_once = 1; - va_end (ap); + va_start(ap, format); + if (vcomplain(level, c, format, ap)) + c->complained_once = 1; + va_end(ap); } /* c_complain_once */ -void c_do_release (int level, c_complain_t *c, const char *format, ...) -{ - char message[512]; - va_list ap; +void c_do_release(int level, c_complain_t *c, const char *format, ...) { + char message[512]; + va_list ap; - if (c->interval == 0) - return; + if (c->interval == 0) + return; - c->interval = 0; - c->complained_once = 0; + c->interval = 0; + c->complained_once = 0; - va_start (ap, format); - vsnprintf (message, sizeof (message), format, ap); - message[sizeof (message) - 1] = '\0'; - va_end (ap); + va_start(ap, format); + vsnprintf(message, sizeof(message), format, ap); + message[sizeof(message) - 1] = '\0'; + va_end(ap); - plugin_log (level, "%s", message); + plugin_log(level, "%s", message); } /* c_release */ /* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/daemon/utils_complain.h b/src/daemon/utils_complain.h index 9d96d35d..fbeea90f 100644 --- a/src/daemon/utils_complain.h +++ b/src/daemon/utils_complain.h @@ -31,24 +31,25 @@ #include "utils_time.h" -typedef struct -{ - /* time of the last report */ - cdtime_t last; +typedef struct { + /* time of the last report */ + cdtime_t last; - /* How long to wait until reporting again. - * 0 indicates that the complaint is no longer valid. */ - cdtime_t interval; + /* How long to wait until reporting again. + * 0 indicates that the complaint is no longer valid. */ + cdtime_t interval; - _Bool complained_once; + _Bool complained_once; } c_complain_t; -#define C_COMPLAIN_INIT_STATIC { 0, 0, 0 } -#define C_COMPLAIN_INIT(c) do { \ - (c)->last = 0; \ - (c)->interval = 0; \ - (c)->complained_once = 0; \ -} while (0) +#define C_COMPLAIN_INIT_STATIC \ + { 0, 0, 0 } +#define C_COMPLAIN_INIT(c) \ + do { \ + (c)->last = 0; \ + (c)->interval = 0; \ + (c)->complained_once = 0; \ + } while (0) /* * NAME @@ -66,8 +67,8 @@ typedef struct * `c' Identifier for the complaint. * `format' Message format - see the documentation of printf(3). */ -__attribute__ ((format(printf,3,4))) -void c_complain (int level, c_complain_t *c, const char *format, ...); +__attribute__((format(printf, 3, 4))) void +c_complain(int level, c_complain_t *c, const char *format, ...); /* * NAME @@ -81,8 +82,8 @@ void c_complain (int level, c_complain_t *c, const char *format, ...); * * See `c_complain' for further details and a description of the parameters. */ -__attribute__ ((format(printf,3,4))) -void c_complain_once (int level, c_complain_t *c, const char *format, ...); +__attribute__((format(printf, 3, 4))) void +c_complain_once(int level, c_complain_t *c, const char *format, ...); /* * NAME @@ -103,15 +104,14 @@ void c_complain_once (int level, c_complain_t *c, const char *format, ...); * * See `c_complain' for a description of the parameters. */ -__attribute__ ((format(printf,3,4))) -void c_do_release (int level, c_complain_t *c, const char *format, ...); -#define c_release(level, c, ...) \ - do { \ - if (c_would_release (c)) \ - c_do_release(level, c, __VA_ARGS__); \ - } while (0) +__attribute__((format(printf, 3, 4))) void +c_do_release(int level, c_complain_t *c, const char *format, ...); +#define c_release(level, c, ...) \ + do { \ + if (c_would_release(c)) \ + c_do_release(level, c, __VA_ARGS__); \ + } while (0) #endif /* UTILS_COMPLAIN_H */ /* vim: set sw=4 ts=4 tw=78 noexpandtab : */ - diff --git a/src/daemon/utils_heap.c b/src/daemon/utils_heap.c index 86375811..8dd501da 100644 --- a/src/daemon/utils_heap.c +++ b/src/daemon/utils_heap.c @@ -24,31 +24,25 @@ * Florian octo Forster **/ -#include -#include #include +#include #include +#include #include "utils_heap.h" -struct c_heap_s -{ +struct c_heap_s { pthread_mutex_t lock; - int (*compare) (const void *, const void *); + int (*compare)(const void *, const void *); void **list; - size_t list_len; /* # entries used */ + size_t list_len; /* # entries used */ size_t list_size; /* # entries allocated */ }; -enum reheap_direction -{ - DIR_UP, - DIR_DOWN -}; +enum reheap_direction { DIR_UP, DIR_DOWN }; -static void reheap (c_heap_t *h, size_t root, enum reheap_direction dir) -{ +static void reheap(c_heap_t *h, size_t root, enum reheap_direction dir) { size_t left; size_t right; size_t min; @@ -70,23 +64,20 @@ static void reheap (c_heap_t *h, size_t root, enum reheap_direction dir) min = right; else if (right == 0) min = left; - else - { - status = h->compare (h->list[left], h->list[right]); + else { + status = h->compare(h->list[left], h->list[right]); if (status > 0) min = right; else min = left; } - status = h->compare (h->list[root], h->list[min]); - if (status <= 0) - { + status = h->compare(h->list[root], h->list[min]); + if (status <= 0) { /* We didn't need to change anything, so the rest of the tree should be * okay now. */ return; - } - else /* if (status > 0) */ + } else /* if (status > 0) */ { void *tmp; @@ -99,23 +90,22 @@ static void reheap (c_heap_t *h, size_t root, enum reheap_direction dir) return; if (dir == DIR_UP) - reheap (h, (root - 1) / 2, dir); + reheap(h, (root - 1) / 2, dir); else if (dir == DIR_DOWN) - reheap (h, min, dir); + reheap(h, min, dir); } /* void reheap */ -c_heap_t *c_heap_create (int (*compare) (const void *, const void *)) -{ +c_heap_t *c_heap_create(int (*compare)(const void *, const void *)) { c_heap_t *h; if (compare == NULL) return (NULL); - h = calloc (1, sizeof (*h)); + h = calloc(1, sizeof(*h)); if (h == NULL) return (NULL); - pthread_mutex_init (&h->lock, /* attr = */ NULL); + pthread_mutex_init(&h->lock, /* attr = */ NULL); h->compare = compare; h->list = NULL; @@ -125,39 +115,35 @@ c_heap_t *c_heap_create (int (*compare) (const void *, const void *)) return (h); } /* c_heap_t *c_heap_create */ -void c_heap_destroy (c_heap_t *h) -{ +void c_heap_destroy(c_heap_t *h) { if (h == NULL) return; h->list_len = 0; h->list_size = 0; - free (h->list); + free(h->list); h->list = NULL; - pthread_mutex_destroy (&h->lock); + pthread_mutex_destroy(&h->lock); - free (h); + free(h); } /* void c_heap_destroy */ -int c_heap_insert (c_heap_t *h, void *ptr) -{ +int c_heap_insert(c_heap_t *h, void *ptr) { size_t index; if ((h == NULL) || (ptr == NULL)) return (-EINVAL); - pthread_mutex_lock (&h->lock); + pthread_mutex_lock(&h->lock); - assert (h->list_len <= h->list_size); - if (h->list_len == h->list_size) - { + assert(h->list_len <= h->list_size); + if (h->list_len == h->list_size) { void **tmp; - tmp = realloc (h->list, (h->list_size + 16) * sizeof (*h->list)); - if (tmp == NULL) - { - pthread_mutex_unlock (&h->lock); + tmp = realloc(h->list, (h->list_size + 16) * sizeof(*h->list)); + if (tmp == NULL) { + pthread_mutex_unlock(&h->lock); return (-ENOMEM); } @@ -171,56 +157,49 @@ int c_heap_insert (c_heap_t *h, void *ptr) h->list_len++; /* Reorganize the heap from bottom up. */ - reheap (h, /* parent of this node = */ (index - 1) / 2, DIR_UP); + reheap(h, /* parent of this node = */ (index - 1) / 2, DIR_UP); - pthread_mutex_unlock (&h->lock); + pthread_mutex_unlock(&h->lock); return (0); } /* int c_heap_insert */ -void *c_heap_get_root (c_heap_t *h) -{ +void *c_heap_get_root(c_heap_t *h) { void *ret = NULL; if (h == NULL) return (NULL); - pthread_mutex_lock (&h->lock); + pthread_mutex_lock(&h->lock); - if (h->list_len == 0) - { - pthread_mutex_unlock (&h->lock); + if (h->list_len == 0) { + pthread_mutex_unlock(&h->lock); return (NULL); - } - else if (h->list_len == 1) - { + } else if (h->list_len == 1) { ret = h->list[0]; h->list[0] = NULL; h->list_len = 0; - } - else /* if (h->list_len > 1) */ + } else /* if (h->list_len > 1) */ { ret = h->list[0]; h->list[0] = h->list[h->list_len - 1]; h->list[h->list_len - 1] = NULL; h->list_len--; - reheap (h, /* root = */ 0, DIR_DOWN); + reheap(h, /* root = */ 0, DIR_DOWN); } /* free some memory */ - if ((h->list_len + 32) < h->list_size) - { + if ((h->list_len + 32) < h->list_size) { void **tmp; - tmp = realloc (h->list, (h->list_len + 16) * sizeof (*h->list)); - if (tmp != NULL) - { + tmp = realloc(h->list, (h->list_len + 16) * sizeof(*h->list)); + if (tmp != NULL) { h->list = tmp; h->list_size = h->list_len + 16; } } - pthread_mutex_unlock (&h->lock); + pthread_mutex_unlock(&h->lock); return (ret); } /* void *c_heap_get_root */ diff --git a/src/daemon/utils_heap.h b/src/daemon/utils_heap.h index 243554c6..2f77cc45 100644 --- a/src/daemon/utils_heap.h +++ b/src/daemon/utils_heap.h @@ -48,7 +48,7 @@ typedef struct c_heap_s c_heap_t; * RETURN VALUE * A c_heap_t-pointer upon success or NULL upon failure. */ -c_heap_t *c_heap_create (int (*compare) (const void *, const void *)); +c_heap_t *c_heap_create(int (*compare)(const void *, const void *)); /* * NAME @@ -58,7 +58,7 @@ c_heap_t *c_heap_create (int (*compare) (const void *, const void *)); * Deallocates a heap. Stored value- and key-pointer are lost, but of course * not freed. */ -void c_heap_destroy (c_heap_t *h); +void c_heap_destroy(c_heap_t *h); /* * NAME @@ -78,7 +78,7 @@ void c_heap_destroy (c_heap_t *h); * Zero upon success, non-zero otherwise. It's less than zero if an error * occurred or greater than zero if the key is already stored in the tree. */ -int c_heap_insert (c_heap_t *h, void *ptr); +int c_heap_insert(c_heap_t *h, void *ptr); /* * NAME @@ -94,7 +94,7 @@ int c_heap_insert (c_heap_t *h, void *ptr); * The pointer passed to `c_heap_insert' or NULL if there are no more * elements in the heap (or an error occurred). */ -void *c_heap_get_root (c_heap_t *h); +void *c_heap_get_root(c_heap_t *h); #endif /* UTILS_HEAP_H */ /* vim: set sw=2 sts=2 et : */ diff --git a/src/daemon/utils_heap_test.c b/src/daemon/utils_heap_test.c index 54a9613a..8443b605 100644 --- a/src/daemon/utils_heap_test.c +++ b/src/daemon/utils_heap_test.c @@ -29,8 +29,7 @@ #include "testing.h" #include "utils_heap.h" -static int compare (void const *v0, void const *v1) -{ +static int compare(void const *v0, void const *v1) { int const *i0 = v0; int const *i1 = v1; @@ -42,30 +41,27 @@ static int compare (void const *v0, void const *v1) return 0; } -DEF_TEST(simple) -{ - int values[] = { 9, 5, 6, 1, 3, 4, 0, 8, 2, 7 }; +DEF_TEST(simple) { + int values[] = {9, 5, 6, 1, 3, 4, 0, 8, 2, 7}; c_heap_t *h; - CHECK_NOT_NULL(h = c_heap_create (compare)); + CHECK_NOT_NULL(h = c_heap_create(compare)); for (int i = 0; i < 10; i++) - CHECK_ZERO(c_heap_insert (h, &values[i])); + CHECK_ZERO(c_heap_insert(h, &values[i])); - for (int i = 0; i < 5; i++) - { + for (int i = 0; i < 5; i++) { int *ret = NULL; CHECK_NOT_NULL(ret = c_heap_get_root(h)); OK(*ret == i); } - CHECK_ZERO(c_heap_insert (h, &values[6] /* = 0 */)); - CHECK_ZERO(c_heap_insert (h, &values[3] /* = 1 */)); - CHECK_ZERO(c_heap_insert (h, &values[8] /* = 2 */)); - CHECK_ZERO(c_heap_insert (h, &values[4] /* = 3 */)); - CHECK_ZERO(c_heap_insert (h, &values[5] /* = 4 */)); + CHECK_ZERO(c_heap_insert(h, &values[6] /* = 0 */)); + CHECK_ZERO(c_heap_insert(h, &values[3] /* = 1 */)); + CHECK_ZERO(c_heap_insert(h, &values[8] /* = 2 */)); + CHECK_ZERO(c_heap_insert(h, &values[4] /* = 3 */)); + CHECK_ZERO(c_heap_insert(h, &values[5] /* = 4 */)); - for (int i = 0; i < 10; i++) - { + for (int i = 0; i < 10; i++) { int *ret = NULL; CHECK_NOT_NULL(ret = c_heap_get_root(h)); OK(*ret == i); @@ -75,8 +71,7 @@ DEF_TEST(simple) return (0); } -int main (void) -{ +int main(void) { RUN_TEST(simple); END_TEST; diff --git a/src/daemon/utils_ignorelist.c b/src/daemon/utils_ignorelist.c index ff73ad74..9cf6aa1e 100644 --- a/src/daemon/utils_ignorelist.c +++ b/src/daemon/utils_ignorelist.c @@ -49,7 +49,7 @@ **/ #if HAVE_CONFIG_H -# include "config.h" +#include "config.h" #endif #include "common.h" @@ -59,90 +59,84 @@ /* * private prototypes */ -struct ignorelist_item_s -{ +struct ignorelist_item_s { #if HAVE_REGEX_H - regex_t *rmatch; /* regular expression entry identification */ + regex_t *rmatch; /* regular expression entry identification */ #endif - char *smatch; /* string entry identification */ - struct ignorelist_item_s *next; + char *smatch; /* string entry identification */ + struct ignorelist_item_s *next; }; typedef struct ignorelist_item_s ignorelist_item_t; -struct ignorelist_s -{ - int ignore; /* ignore entries */ - ignorelist_item_t *head; /* pointer to the first entry */ +struct ignorelist_s { + int ignore; /* ignore entries */ + ignorelist_item_t *head; /* pointer to the first entry */ }; /* *** *** *** ********************************************* *** *** *** */ /* *** *** *** *** *** *** private functions *** *** *** *** *** *** */ /* *** *** *** ********************************************* *** *** *** */ -static inline void ignorelist_append (ignorelist_t *il, ignorelist_item_t *item) -{ - assert ((il != NULL) && (item != NULL)); +static inline void ignorelist_append(ignorelist_t *il, + ignorelist_item_t *item) { + assert((il != NULL) && (item != NULL)); - item->next = il->head; - il->head = item; + item->next = il->head; + il->head = item; } #if HAVE_REGEX_H -static int ignorelist_append_regex(ignorelist_t *il, const char *re_str) -{ - regex_t *re; - ignorelist_item_t *entry; - int status; - - re = calloc (1, sizeof (*re)); - if (re == NULL) - { - ERROR ("ignorelist_append_regex: calloc failed."); - return (ENOMEM); - } - - status = regcomp (re, re_str, REG_EXTENDED); - if (status != 0) - { - char errbuf[1024]; - (void) regerror (status, re, errbuf, sizeof (errbuf)); - ERROR ("utils_ignorelist: regcomp failed: %s", errbuf); - ERROR ("ignorelist_append_regex: Compiling regular expression \"%s\" failed: %s", re_str, errbuf); - sfree (re); - return (status); - } - - entry = calloc (1, sizeof (*entry)); - if (entry == NULL) - { - ERROR ("ignorelist_append_regex: calloc failed."); - regfree (re); - sfree (re); - return (ENOMEM); - } - entry->rmatch = re; - - ignorelist_append (il, entry); - return (0); +static int ignorelist_append_regex(ignorelist_t *il, const char *re_str) { + regex_t *re; + ignorelist_item_t *entry; + int status; + + re = calloc(1, sizeof(*re)); + if (re == NULL) { + ERROR("ignorelist_append_regex: calloc failed."); + return (ENOMEM); + } + + status = regcomp(re, re_str, REG_EXTENDED); + if (status != 0) { + char errbuf[1024]; + (void)regerror(status, re, errbuf, sizeof(errbuf)); + ERROR("utils_ignorelist: regcomp failed: %s", errbuf); + ERROR("ignorelist_append_regex: Compiling regular expression \"%s\" " + "failed: %s", + re_str, errbuf); + sfree(re); + return (status); + } + + entry = calloc(1, sizeof(*entry)); + if (entry == NULL) { + ERROR("ignorelist_append_regex: calloc failed."); + regfree(re); + sfree(re); + return (ENOMEM); + } + entry->rmatch = re; + + ignorelist_append(il, entry); + return (0); } /* int ignorelist_append_regex */ #endif -static int ignorelist_append_string(ignorelist_t *il, const char *entry) -{ - ignorelist_item_t *new; +static int ignorelist_append_string(ignorelist_t *il, const char *entry) { + ignorelist_item_t *new; - /* create new entry */ - if ((new = calloc(1, sizeof (*new))) == NULL ) - { - ERROR ("cannot allocate new entry"); - return (1); - } - new->smatch = sstrdup(entry); + /* create new entry */ + if ((new = calloc(1, sizeof(*new))) == NULL) { + ERROR("cannot allocate new entry"); + return (1); + } + new->smatch = sstrdup(entry); - /* append new entry */ - ignorelist_append (il, new); + /* append new entry */ + ignorelist_append(il, new); - return (0); + return (0); } /* int ignorelist_append_string(ignorelist_t *il, const char *entry) */ #if HAVE_REGEX_H @@ -150,16 +144,15 @@ static int ignorelist_append_string(ignorelist_t *il, const char *entry) * check list for entry regex match * return 1 if found */ -static int ignorelist_match_regex (ignorelist_item_t *item, const char *entry) -{ - assert ((item != NULL) && (item->rmatch != NULL) - && (entry != NULL) && (strlen (entry) > 0)); +static int ignorelist_match_regex(ignorelist_item_t *item, const char *entry) { + assert((item != NULL) && (item->rmatch != NULL) && (entry != NULL) && + (strlen(entry) > 0)); - /* match regex */ - if (regexec (item->rmatch, entry, 0, NULL, 0) == 0) - return (1); + /* match regex */ + if (regexec(item->rmatch, entry, 0, NULL, 0) == 0) + return (1); - return (0); + return (0); } /* int ignorelist_match_regex (ignorelist_item_t *item, const char *entry) */ #endif @@ -167,18 +160,16 @@ static int ignorelist_match_regex (ignorelist_item_t *item, const char *entry) * check list for entry string match * return 1 if found */ -static int ignorelist_match_string (ignorelist_item_t *item, const char *entry) -{ - assert ((item != NULL) && (item->smatch != NULL) - && (entry != NULL) && (strlen (entry) > 0)); +static int ignorelist_match_string(ignorelist_item_t *item, const char *entry) { + assert((item != NULL) && (item->smatch != NULL) && (entry != NULL) && + (strlen(entry) > 0)); - if (strcmp (entry, item->smatch) == 0) - return (1); + if (strcmp(entry, item->smatch) == 0) + return (1); - return (0); + return (0); } /* int ignorelist_match_string (ignorelist_item_t *item, const char *entry) */ - /* *** *** *** ******************************************** *** *** *** */ /* *** *** *** *** *** *** public functions *** *** *** *** *** *** */ /* *** *** *** ******************************************** *** *** *** */ @@ -187,147 +178,132 @@ static int ignorelist_match_string (ignorelist_item_t *item, const char *entry) * create the ignorelist_t with known ignore state * return pointer to ignorelist_t */ -ignorelist_t *ignorelist_create (int invert) -{ - ignorelist_t *il; +ignorelist_t *ignorelist_create(int invert) { + ignorelist_t *il; - il = calloc (1, sizeof (*il)); - if (il == NULL) - return NULL; + il = calloc(1, sizeof(*il)); + if (il == NULL) + return NULL; - /* - * ->ignore == 0 => collect - * ->ignore == 1 => ignore - */ - il->ignore = invert ? 0 : 1; + /* + * ->ignore == 0 => collect + * ->ignore == 1 => ignore + */ + il->ignore = invert ? 0 : 1; - return (il); + return (il); } /* ignorelist_t *ignorelist_create (int ignore) */ /* * free memory used by ignorelist_t */ -void ignorelist_free (ignorelist_t *il) -{ - ignorelist_item_t *this; - ignorelist_item_t *next; +void ignorelist_free(ignorelist_t *il) { + ignorelist_item_t *this; + ignorelist_item_t *next; - if (il == NULL) - return; + if (il == NULL) + return; - for (this = il->head; this != NULL; this = next) - { - next = this->next; + for (this = il->head; this != NULL; this = next) { + next = this->next; #if HAVE_REGEX_H - if (this->rmatch != NULL) - { - regfree (this->rmatch); - sfree (this->rmatch); - this->rmatch = NULL; - } + if (this->rmatch != NULL) { + regfree(this->rmatch); + sfree(this->rmatch); + this->rmatch = NULL; + } #endif - if (this->smatch != NULL) - { - sfree (this->smatch); - this->smatch = NULL; - } - sfree (this); - } - - sfree (il); + if (this->smatch != NULL) { + sfree(this->smatch); + this->smatch = NULL; + } + sfree(this); + } + + sfree(il); } /* void ignorelist_destroy (ignorelist_t *il) */ /* * set ignore state of the ignorelist_t */ -void ignorelist_set_invert (ignorelist_t *il, int invert) -{ - if (il == NULL) - { - DEBUG("ignore call with ignorelist_t == NULL"); - return; - } - - il->ignore = invert ? 0 : 1; +void ignorelist_set_invert(ignorelist_t *il, int invert) { + if (il == NULL) { + DEBUG("ignore call with ignorelist_t == NULL"); + return; + } + + il->ignore = invert ? 0 : 1; } /* void ignorelist_set_invert (ignorelist_t *il, int ignore) */ /* * append entry into ignorelist_t * return 0 for success */ -int ignorelist_add (ignorelist_t *il, const char *entry) -{ - size_t len; +int ignorelist_add(ignorelist_t *il, const char *entry) { + size_t len; - if (il == NULL) - { - DEBUG ("add called with ignorelist_t == NULL"); - return (1); - } + if (il == NULL) { + DEBUG("add called with ignorelist_t == NULL"); + return (1); + } - len = strlen (entry); + len = strlen(entry); - /* append nothing */ - if (len == 0) - { - DEBUG("not appending: empty entry"); - return (1); - } + /* append nothing */ + if (len == 0) { + DEBUG("not appending: empty entry"); + return (1); + } #if HAVE_REGEX_H - /* regex string is enclosed in "/.../" */ - if ((len > 2) && (entry[0] == '/') && entry[len - 1] == '/') - { - char *copy; - int status; - - /* skip leading slash */ - copy = strdup (entry + 1); - if (copy == NULL) - return ENOMEM; - - /* trim trailing slash */ - copy[strlen (copy) - 1] = 0; - - status = ignorelist_append_regex (il, copy); - sfree (copy); - return status; - } + /* regex string is enclosed in "/.../" */ + if ((len > 2) && (entry[0] == '/') && entry[len - 1] == '/') { + char *copy; + int status; + + /* skip leading slash */ + copy = strdup(entry + 1); + if (copy == NULL) + return ENOMEM; + + /* trim trailing slash */ + copy[strlen(copy) - 1] = 0; + + status = ignorelist_append_regex(il, copy); + sfree(copy); + return status; + } #endif - return ignorelist_append_string(il, entry); + return ignorelist_append_string(il, entry); } /* int ignorelist_add (ignorelist_t *il, const char *entry) */ /* * check list for entry * return 1 for ignored entry */ -int ignorelist_match (ignorelist_t *il, const char *entry) -{ - /* if no entries, collect all */ - if ((il == NULL) || (il->head == NULL)) - return (0); - - if ((entry == NULL) || (strlen (entry) == 0)) - return (0); - - /* traverse list and check entries */ - for (ignorelist_item_t *traverse = il->head; traverse != NULL; traverse = traverse->next) - { +int ignorelist_match(ignorelist_t *il, const char *entry) { + /* if no entries, collect all */ + if ((il == NULL) || (il->head == NULL)) + return (0); + + if ((entry == NULL) || (strlen(entry) == 0)) + return (0); + + /* traverse list and check entries */ + for (ignorelist_item_t *traverse = il->head; traverse != NULL; + traverse = traverse->next) { #if HAVE_REGEX_H - if (traverse->rmatch != NULL) - { - if (ignorelist_match_regex (traverse, entry)) - return (il->ignore); - } - else + if (traverse->rmatch != NULL) { + if (ignorelist_match_regex(traverse, entry)) + return (il->ignore); + } else #endif - { - if (ignorelist_match_string (traverse, entry)) - return (il->ignore); - } - } /* for traverse */ + { + if (ignorelist_match_string(traverse, entry)) + return (il->ignore); + } + } /* for traverse */ - return (1 - il->ignore); + return (1 - il->ignore); } /* int ignorelist_match (ignorelist_t *il, const char *entry) */ - diff --git a/src/daemon/utils_ignorelist.h b/src/daemon/utils_ignorelist.h index db7535fd..a7fa86d5 100644 --- a/src/daemon/utils_ignorelist.h +++ b/src/daemon/utils_ignorelist.h @@ -30,7 +30,7 @@ #include "collectd.h" #if HAVE_REGEX_H -# include +#include #endif /* public prototypes */ @@ -42,28 +42,28 @@ typedef struct ignorelist_s ignorelist_t; * create the ignorelist_t with known ignore state * return pointer to ignorelist_t */ -ignorelist_t *ignorelist_create (int invert); +ignorelist_t *ignorelist_create(int invert); /* * free memory used by ignorelist_t */ -void ignorelist_free (ignorelist_t *il); +void ignorelist_free(ignorelist_t *il); /* * set ignore state of the ignorelist_t */ -void ignorelist_set_invert (ignorelist_t *il, int invert); +void ignorelist_set_invert(ignorelist_t *il, int invert); /* * append entry to ignorelist_t * returns zero on success, non-zero upon failure. */ -int ignorelist_add (ignorelist_t *il, const char *entry); +int ignorelist_add(ignorelist_t *il, const char *entry); /* * check list for entry * return 1 for ignored entry */ -int ignorelist_match (ignorelist_t *il, const char *entry); +int ignorelist_match(ignorelist_t *il, const char *entry); #endif /* UTILS_IGNORELIST_H */ diff --git a/src/daemon/utils_llist.c b/src/daemon/utils_llist.c index 60273382..2ed56a02 100644 --- a/src/daemon/utils_llist.c +++ b/src/daemon/utils_llist.c @@ -32,158 +32,138 @@ /* * Private data types */ -struct llist_s -{ - llentry_t *head; - llentry_t *tail; - int size; +struct llist_s { + llentry_t *head; + llentry_t *tail; + int size; }; /* * Public functions */ -llist_t *llist_create (void) -{ - llist_t *ret; +llist_t *llist_create(void) { + llist_t *ret; - ret = calloc (1, sizeof (*ret)); - if (ret == NULL) - return (NULL); + ret = calloc(1, sizeof(*ret)); + if (ret == NULL) + return (NULL); - return (ret); + return (ret); } -void llist_destroy (llist_t *l) -{ - llentry_t *e_this; - llentry_t *e_next; +void llist_destroy(llist_t *l) { + llentry_t *e_this; + llentry_t *e_next; - if (l == NULL) - return; + if (l == NULL) + return; - for (e_this = l->head; e_this != NULL; e_this = e_next) - { - e_next = e_this->next; - llentry_destroy (e_this); - } + for (e_this = l->head; e_this != NULL; e_this = e_next) { + e_next = e_this->next; + llentry_destroy(e_this); + } - free (l); + free(l); } -llentry_t *llentry_create (char *key, void *value) -{ - llentry_t *e; +llentry_t *llentry_create(char *key, void *value) { + llentry_t *e; - e = malloc (sizeof (*e)); - if (e) - { - e->key = key; - e->value = value; - e->next = NULL; - } + e = malloc(sizeof(*e)); + if (e) { + e->key = key; + e->value = value; + e->next = NULL; + } - return (e); + return (e); } -void llentry_destroy (llentry_t *e) -{ - free (e); -} +void llentry_destroy(llentry_t *e) { free(e); } -void llist_append (llist_t *l, llentry_t *e) -{ - e->next = NULL; +void llist_append(llist_t *l, llentry_t *e) { + e->next = NULL; - if (l->tail == NULL) - l->head = e; - else - l->tail->next = e; + if (l->tail == NULL) + l->head = e; + else + l->tail->next = e; - l->tail = e; + l->tail = e; - ++(l->size); + ++(l->size); } -void llist_prepend (llist_t *l, llentry_t *e) -{ - e->next = l->head; - l->head = e; +void llist_prepend(llist_t *l, llentry_t *e) { + e->next = l->head; + l->head = e; - if (l->tail == NULL) - l->tail = e; + if (l->tail == NULL) + l->tail = e; - ++(l->size); + ++(l->size); } -void llist_remove (llist_t *l, llentry_t *e) -{ - llentry_t *prev; +void llist_remove(llist_t *l, llentry_t *e) { + llentry_t *prev; - if ((l == NULL) || (e == NULL)) - return; + if ((l == NULL) || (e == NULL)) + return; - prev = l->head; - while ((prev != NULL) && (prev->next != e)) - prev = prev->next; + prev = l->head; + while ((prev != NULL) && (prev->next != e)) + prev = prev->next; - if (prev != NULL) - prev->next = e->next; - if (l->head == e) - l->head = e->next; - if (l->tail == e) - l->tail = prev; + if (prev != NULL) + prev->next = e->next; + if (l->head == e) + l->head = e->next; + if (l->tail == e) + l->tail = prev; - --(l->size); + --(l->size); } -int llist_size (llist_t *l) -{ - return (l ? l->size : 0); -} +int llist_size(llist_t *l) { return (l ? l->size : 0); } -static int llist_strcmp (llentry_t *e, void *ud) -{ - if ((e == NULL) || (ud == NULL)) - return (-1); - return (strcmp (e->key, (const char *)ud)); +static int llist_strcmp(llentry_t *e, void *ud) { + if ((e == NULL) || (ud == NULL)) + return (-1); + return (strcmp(e->key, (const char *)ud)); } -llentry_t *llist_search (llist_t *l, const char *key) -{ - return (llist_search_custom (l, llist_strcmp, (void *)key)); +llentry_t *llist_search(llist_t *l, const char *key) { + return (llist_search_custom(l, llist_strcmp, (void *)key)); } -llentry_t *llist_search_custom (llist_t *l, - int (*compare) (llentry_t *, void *), void *user_data) -{ - llentry_t *e; +llentry_t *llist_search_custom(llist_t *l, int (*compare)(llentry_t *, void *), + void *user_data) { + llentry_t *e; - if (l == NULL) - return (NULL); + if (l == NULL) + return (NULL); - e = l->head; - while (e != NULL) { - llentry_t *next = e->next; + e = l->head; + while (e != NULL) { + llentry_t *next = e->next; - if (compare (e, user_data) == 0) - break; + if (compare(e, user_data) == 0) + break; - e = next; - } + e = next; + } - return (e); + return (e); } -llentry_t *llist_head (llist_t *l) -{ - if (l == NULL) - return (NULL); - return (l->head); +llentry_t *llist_head(llist_t *l) { + if (l == NULL) + return (NULL); + return (l->head); } -llentry_t *llist_tail (llist_t *l) -{ - if (l == NULL) - return (NULL); - return (l->tail); +llentry_t *llist_tail(llist_t *l) { + if (l == NULL) + return (NULL); + return (l->tail); } diff --git a/src/daemon/utils_llist.h b/src/daemon/utils_llist.h index 59bf2e41..5bb684a4 100644 --- a/src/daemon/utils_llist.h +++ b/src/daemon/utils_llist.h @@ -30,11 +30,10 @@ /* * Data types */ -struct llentry_s -{ - char *key; - void *value; - struct llentry_s *next; +struct llentry_s { + char *key; + void *value; + struct llentry_s *next; }; typedef struct llentry_s llentry_t; @@ -44,23 +43,23 @@ typedef struct llist_s llist_t; /* * Functions */ -llist_t *llist_create (void); -void llist_destroy (llist_t *l); +llist_t *llist_create(void); +void llist_destroy(llist_t *l); -llentry_t *llentry_create (char *key, void *value); -void llentry_destroy (llentry_t *e); +llentry_t *llentry_create(char *key, void *value); +void llentry_destroy(llentry_t *e); -void llist_append (llist_t *l, llentry_t *e); -void llist_prepend (llist_t *l, llentry_t *e); -void llist_remove (llist_t *l, llentry_t *e); +void llist_append(llist_t *l, llentry_t *e); +void llist_prepend(llist_t *l, llentry_t *e); +void llist_remove(llist_t *l, llentry_t *e); -int llist_size (llist_t *l); +int llist_size(llist_t *l); -llentry_t *llist_search (llist_t *l, const char *key); -llentry_t *llist_search_custom (llist_t *l, - int (*compare) (llentry_t *, void *), void *user_data); +llentry_t *llist_search(llist_t *l, const char *key); +llentry_t *llist_search_custom(llist_t *l, int (*compare)(llentry_t *, void *), + void *user_data); -llentry_t *llist_head (llist_t *l); -llentry_t *llist_tail (llist_t *l); +llentry_t *llist_head(llist_t *l); +llentry_t *llist_tail(llist_t *l); #endif /* UTILS_LLIST_H */ diff --git a/src/daemon/utils_match.c b/src/daemon/utils_match.c index d1be244e..2e487b59 100644 --- a/src/daemon/utils_match.c +++ b/src/daemon/utils_match.c @@ -35,118 +35,96 @@ #define UTILS_MATCH_FLAGS_EXCLUDE_REGEX 0x02 -struct cu_match_s -{ +struct cu_match_s { regex_t regex; regex_t excluderegex; int flags; - int (*callback) (const char *str, char * const *matches, size_t matches_num, - void *user_data); + int (*callback)(const char *str, char *const *matches, size_t matches_num, + void *user_data); void *user_data; - void (*free) (void *user_data); + void (*free)(void *user_data); }; /* * Private functions */ -static char *match_substr (const char *str, int begin, int end) -{ +static char *match_substr(const char *str, int begin, int end) { char *ret; size_t ret_len; if ((begin < 0) || (end < 0) || (begin >= end)) return (NULL); - if ((size_t) end > (strlen (str) + 1)) - { - ERROR ("utils_match: match_substr: `end' points after end of string."); + if ((size_t)end > (strlen(str) + 1)) { + ERROR("utils_match: match_substr: `end' points after end of string."); return (NULL); } ret_len = end - begin; - ret = malloc (ret_len + 1); - if (ret == NULL) - { - ERROR ("utils_match: match_substr: malloc failed."); + ret = malloc(ret_len + 1); + if (ret == NULL) { + ERROR("utils_match: match_substr: malloc failed."); return (NULL); } - sstrncpy (ret, str + begin, ret_len + 1); + sstrncpy(ret, str + begin, ret_len + 1); return (ret); } /* char *match_substr */ -static int default_callback (const char __attribute__((unused)) *str, - char * const *matches, size_t matches_num, void *user_data) -{ - cu_match_value_t *data = (cu_match_value_t *) user_data; +static int default_callback(const char __attribute__((unused)) * str, + char *const *matches, size_t matches_num, + void *user_data) { + cu_match_value_t *data = (cu_match_value_t *)user_data; - if (data->ds_type & UTILS_MATCH_DS_TYPE_GAUGE) - { + if (data->ds_type & UTILS_MATCH_DS_TYPE_GAUGE) { gauge_t value; char *endptr = NULL; - if (data->ds_type & UTILS_MATCH_CF_GAUGE_INC) - { - data->value.gauge = isnan (data->value.gauge) ? 1 : data->value.gauge + 1; + if (data->ds_type & UTILS_MATCH_CF_GAUGE_INC) { + data->value.gauge = isnan(data->value.gauge) ? 1 : data->value.gauge + 1; data->values_num++; - return(0); + return (0); } if (matches_num < 2) return (-1); - value = (gauge_t) strtod (matches[1], &endptr); + value = (gauge_t)strtod(matches[1], &endptr); if (matches[1] == endptr) return (-1); - if (data->ds_type & UTILS_MATCH_CF_GAUGE_DIST) - { + if (data->ds_type & UTILS_MATCH_CF_GAUGE_DIST) { latency_counter_add(data->latency, DOUBLE_TO_CDTIME_T(value)); data->values_num++; return (0); } - if ((data->values_num == 0) - || (data->ds_type & UTILS_MATCH_CF_GAUGE_LAST) - || (data->ds_type & UTILS_MATCH_CF_GAUGE_PERSIST)) - { + if ((data->values_num == 0) || + (data->ds_type & UTILS_MATCH_CF_GAUGE_LAST) || + (data->ds_type & UTILS_MATCH_CF_GAUGE_PERSIST)) { data->value.gauge = value; - } - else if (data->ds_type & UTILS_MATCH_CF_GAUGE_AVERAGE) - { - double f = ((double) data->values_num) - / ((double) (data->values_num + 1)); + } else if (data->ds_type & UTILS_MATCH_CF_GAUGE_AVERAGE) { + double f = ((double)data->values_num) / ((double)(data->values_num + 1)); data->value.gauge = (data->value.gauge * f) + (value * (1.0 - f)); - } - else if (data->ds_type & UTILS_MATCH_CF_GAUGE_MIN) - { + } else if (data->ds_type & UTILS_MATCH_CF_GAUGE_MIN) { if (data->value.gauge > value) - data->value.gauge = value; - } - else if (data->ds_type & UTILS_MATCH_CF_GAUGE_MAX) - { + data->value.gauge = value; + } else if (data->ds_type & UTILS_MATCH_CF_GAUGE_MAX) { if (data->value.gauge < value) - data->value.gauge = value; - } - else if (data->ds_type & UTILS_MATCH_CF_GAUGE_ADD) - { + data->value.gauge = value; + } else if (data->ds_type & UTILS_MATCH_CF_GAUGE_ADD) { data->value.gauge += value; - } - else - { - ERROR ("utils_match: default_callback: obj->ds_type is invalid!"); + } else { + ERROR("utils_match: default_callback: obj->ds_type is invalid!"); return (-1); } data->values_num++; - } - else if (data->ds_type & UTILS_MATCH_DS_TYPE_COUNTER) - { + } else if (data->ds_type & UTILS_MATCH_DS_TYPE_COUNTER) { counter_t value; char *endptr = NULL; - if (data->ds_type & UTILS_MATCH_CF_COUNTER_INC) - { + if (data->ds_type & UTILS_MATCH_CF_COUNTER_INC) { data->value.counter++; data->values_num++; return (0); @@ -155,7 +133,7 @@ static int default_callback (const char __attribute__((unused)) *str, if (matches_num < 2) return (-1); - value = (counter_t) strtoull (matches[1], &endptr, 0); + value = (counter_t)strtoull(matches[1], &endptr, 0); if (matches[1] == endptr) return (-1); @@ -163,21 +141,17 @@ static int default_callback (const char __attribute__((unused)) *str, data->value.counter = value; else if (data->ds_type & UTILS_MATCH_CF_COUNTER_ADD) data->value.counter += value; - else - { - ERROR ("utils_match: default_callback: obj->ds_type is invalid!"); + else { + ERROR("utils_match: default_callback: obj->ds_type is invalid!"); return (-1); } data->values_num++; - } - else if (data->ds_type & UTILS_MATCH_DS_TYPE_DERIVE) - { + } else if (data->ds_type & UTILS_MATCH_DS_TYPE_DERIVE) { derive_t value; char *endptr = NULL; - if (data->ds_type & UTILS_MATCH_CF_DERIVE_INC) - { + if (data->ds_type & UTILS_MATCH_CF_DERIVE_INC) { data->value.derive++; data->values_num++; return (0); @@ -186,7 +160,7 @@ static int default_callback (const char __attribute__((unused)) *str, if (matches_num < 2) return (-1); - value = (derive_t) strtoll (matches[1], &endptr, 0); + value = (derive_t)strtoll(matches[1], &endptr, 0); if (matches[1] == endptr) return (-1); @@ -194,88 +168,80 @@ static int default_callback (const char __attribute__((unused)) *str, data->value.derive = value; else if (data->ds_type & UTILS_MATCH_CF_DERIVE_ADD) data->value.derive += value; - else - { - ERROR ("utils_match: default_callback: obj->ds_type is invalid!"); + else { + ERROR("utils_match: default_callback: obj->ds_type is invalid!"); return (-1); } data->values_num++; - } - else if (data->ds_type & UTILS_MATCH_DS_TYPE_ABSOLUTE) - { + } else if (data->ds_type & UTILS_MATCH_DS_TYPE_ABSOLUTE) { absolute_t value; char *endptr = NULL; if (matches_num < 2) return (-1); - value = (absolute_t) strtoull (matches[1], &endptr, 0); + value = (absolute_t)strtoull(matches[1], &endptr, 0); if (matches[1] == endptr) return (-1); if (data->ds_type & UTILS_MATCH_CF_ABSOLUTE_SET) data->value.absolute = value; - else - { - ERROR ("utils_match: default_callback: obj->ds_type is invalid!"); + else { + ERROR("utils_match: default_callback: obj->ds_type is invalid!"); return (-1); } data->values_num++; - } - else - { - ERROR ("utils_match: default_callback: obj->ds_type is invalid!"); + } else { + ERROR("utils_match: default_callback: obj->ds_type is invalid!"); return (-1); } return (0); } /* int default_callback */ -static void match_simple_free (void *data) -{ - cu_match_value_t *user_data = (cu_match_value_t *) data; +static void match_simple_free(void *data) { + cu_match_value_t *user_data = (cu_match_value_t *)data; if (user_data->latency) latency_counter_destroy(user_data->latency); - free (data); + free(data); } /* void match_simple_free */ /* * Public functions */ -cu_match_t *match_create_callback (const char *regex, const char *excluderegex, - int (*callback) (const char *str, - char * const *matches, size_t matches_num, void *user_data), - void *user_data, void (*free_user_data) (void *user_data)) -{ +cu_match_t * +match_create_callback(const char *regex, const char *excluderegex, + int (*callback)(const char *str, char *const *matches, + size_t matches_num, void *user_data), + void *user_data, + void (*free_user_data)(void *user_data)) { cu_match_t *obj; int status; - DEBUG ("utils_match: match_create_callback: regex = %s, excluderegex = %s", - regex, excluderegex); + DEBUG("utils_match: match_create_callback: regex = %s, excluderegex = %s", + regex, excluderegex); - obj = calloc (1, sizeof (*obj)); + obj = calloc(1, sizeof(*obj)); if (obj == NULL) return (NULL); - status = regcomp (&obj->regex, regex, REG_EXTENDED | REG_NEWLINE); - if (status != 0) - { - ERROR ("Compiling the regular expression \"%s\" failed.", regex); - sfree (obj); + status = regcomp(&obj->regex, regex, REG_EXTENDED | REG_NEWLINE); + if (status != 0) { + ERROR("Compiling the regular expression \"%s\" failed.", regex); + sfree(obj); return (NULL); } if (excluderegex && strcmp(excluderegex, "") != 0) { - status = regcomp (&obj->excluderegex, excluderegex, REG_EXTENDED); - if (status != 0) - { - ERROR ("Compiling the excluding regular expression \"%s\" failed.", - excluderegex); - sfree (obj); - return (NULL); + status = regcomp(&obj->excluderegex, excluderegex, REG_EXTENDED); + if (status != 0) { + ERROR("Compiling the excluding regular expression \"%s\" failed.", + excluderegex); + sfree(obj); + return (NULL); } obj->flags |= UTILS_MATCH_FLAGS_EXCLUDE_REGEX; } @@ -287,81 +253,73 @@ cu_match_t *match_create_callback (const char *regex, const char *excluderegex, return (obj); } /* cu_match_t *match_create_callback */ -cu_match_t *match_create_simple (const char *regex, - const char *excluderegex, int match_ds_type) -{ +cu_match_t *match_create_simple(const char *regex, const char *excluderegex, + int match_ds_type) { cu_match_value_t *user_data; cu_match_t *obj; - user_data = calloc (1, sizeof (*user_data)); + user_data = calloc(1, sizeof(*user_data)); if (user_data == NULL) return (NULL); user_data->ds_type = match_ds_type; - if ((match_ds_type & UTILS_MATCH_DS_TYPE_GAUGE) - && (match_ds_type & UTILS_MATCH_CF_GAUGE_DIST)) - { + if ((match_ds_type & UTILS_MATCH_DS_TYPE_GAUGE) && + (match_ds_type & UTILS_MATCH_CF_GAUGE_DIST)) { user_data->latency = latency_counter_create(); - if (user_data->latency == NULL) - { - ERROR ("match_create_simple(): latency_counter_create() failed."); - free (user_data); + if (user_data->latency == NULL) { + ERROR("match_create_simple(): latency_counter_create() failed."); + free(user_data); return (NULL); } } - obj = match_create_callback (regex, excluderegex, - default_callback, user_data, match_simple_free); - if (obj == NULL) - { + obj = match_create_callback(regex, excluderegex, default_callback, user_data, + match_simple_free); + if (obj == NULL) { if (user_data->latency) latency_counter_destroy(user_data->latency); - sfree (user_data); + sfree(user_data); return (NULL); } return (obj); } /* cu_match_t *match_create_simple */ -void match_value_reset (cu_match_value_t *mv) -{ +void match_value_reset(cu_match_value_t *mv) { if (mv == NULL) return; /* Reset GAUGE metrics only and except GAUGE_PERSIST. */ - if ((mv->ds_type & UTILS_MATCH_DS_TYPE_GAUGE) - && !(mv->ds_type & UTILS_MATCH_CF_GAUGE_PERSIST)) - { + if ((mv->ds_type & UTILS_MATCH_DS_TYPE_GAUGE) && + !(mv->ds_type & UTILS_MATCH_CF_GAUGE_PERSIST)) { mv->value.gauge = NAN; mv->values_num = 0; } } /* }}} void match_value_reset */ -void match_destroy (cu_match_t *obj) -{ +void match_destroy(cu_match_t *obj) { if (obj == NULL) return; if ((obj->user_data != NULL) && (obj->free != NULL)) - (*obj->free) (obj->user_data); + (*obj->free)(obj->user_data); - sfree (obj); + sfree(obj); } /* void match_destroy */ -int match_apply (cu_match_t *obj, const char *str) -{ +int match_apply(cu_match_t *obj, const char *str) { int status; regmatch_t re_match[32]; - char *matches[32] = { 0 }; + char *matches[32] = {0}; size_t matches_num; if ((obj == NULL) || (str == NULL)) return (-1); if (obj->flags & UTILS_MATCH_FLAGS_EXCLUDE_REGEX) { - status = regexec (&obj->excluderegex, str, - STATIC_ARRAY_SIZE (re_match), re_match, - /* eflags = */ 0); + status = + regexec(&obj->excluderegex, str, STATIC_ARRAY_SIZE(re_match), re_match, + /* eflags = */ 0); /* Regex did match, so exclude this line */ if (status == 0) { DEBUG("ExludeRegex matched, don't count that line\n"); @@ -369,52 +327,43 @@ int match_apply (cu_match_t *obj, const char *str) } } - status = regexec (&obj->regex, str, - STATIC_ARRAY_SIZE (re_match), re_match, - /* eflags = */ 0); + status = regexec(&obj->regex, str, STATIC_ARRAY_SIZE(re_match), re_match, + /* eflags = */ 0); /* Regex did not match */ if (status != 0) return (0); - for (matches_num = 0; matches_num < STATIC_ARRAY_SIZE (matches); matches_num++) - { - if ((re_match[matches_num].rm_so < 0) - || (re_match[matches_num].rm_eo < 0)) + for (matches_num = 0; matches_num < STATIC_ARRAY_SIZE(matches); + matches_num++) { + if ((re_match[matches_num].rm_so < 0) || (re_match[matches_num].rm_eo < 0)) break; - matches[matches_num] = match_substr (str, - re_match[matches_num].rm_so, re_match[matches_num].rm_eo); - if (matches[matches_num] == NULL) - { + matches[matches_num] = match_substr(str, re_match[matches_num].rm_so, + re_match[matches_num].rm_eo); + if (matches[matches_num] == NULL) { status = -1; break; } } - if (status != 0) - { - ERROR ("utils_match: match_apply: match_substr failed."); - } - else - { - status = obj->callback (str, matches, matches_num, obj->user_data); - if (status != 0) - { - ERROR ("utils_match: match_apply: callback failed."); + if (status != 0) { + ERROR("utils_match: match_apply: match_substr failed."); + } else { + status = obj->callback(str, matches, matches_num, obj->user_data); + if (status != 0) { + ERROR("utils_match: match_apply: callback failed."); } } - for (size_t i = 0; i < matches_num; i++) - { - sfree (matches[i]); + for (size_t i = 0; i < matches_num; i++) { + sfree(matches[i]); } return (status); } /* int match_apply */ -void *match_get_user_data (cu_match_t *obj) -{ +void *match_get_user_data(cu_match_t *obj) { if (obj == NULL) return (NULL); return (obj->user_data); diff --git a/src/daemon/utils_match.h b/src/daemon/utils_match.h index 7b263d77..1383530c 100644 --- a/src/daemon/utils_match.h +++ b/src/daemon/utils_match.h @@ -36,31 +36,31 @@ * ^ <- Type bit * ^^^^^^^^^^^^ <- Subtype bits */ -#define UTILS_MATCH_DS_TYPE_GAUGE 0x1000 -#define UTILS_MATCH_DS_TYPE_COUNTER 0x2000 -#define UTILS_MATCH_DS_TYPE_DERIVE 0x4000 +#define UTILS_MATCH_DS_TYPE_GAUGE 0x1000 +#define UTILS_MATCH_DS_TYPE_COUNTER 0x2000 +#define UTILS_MATCH_DS_TYPE_DERIVE 0x4000 #define UTILS_MATCH_DS_TYPE_ABSOLUTE 0x8000 #define UTILS_MATCH_CF_GAUGE_AVERAGE 0x01 -#define UTILS_MATCH_CF_GAUGE_MIN 0x02 -#define UTILS_MATCH_CF_GAUGE_MAX 0x04 -#define UTILS_MATCH_CF_GAUGE_LAST 0x08 -#define UTILS_MATCH_CF_GAUGE_INC 0x10 -#define UTILS_MATCH_CF_GAUGE_ADD 0x20 +#define UTILS_MATCH_CF_GAUGE_MIN 0x02 +#define UTILS_MATCH_CF_GAUGE_MAX 0x04 +#define UTILS_MATCH_CF_GAUGE_LAST 0x08 +#define UTILS_MATCH_CF_GAUGE_INC 0x10 +#define UTILS_MATCH_CF_GAUGE_ADD 0x20 #define UTILS_MATCH_CF_GAUGE_PERSIST 0x40 -#define UTILS_MATCH_CF_GAUGE_DIST 0x80 +#define UTILS_MATCH_CF_GAUGE_DIST 0x80 -#define UTILS_MATCH_CF_COUNTER_SET 0x01 -#define UTILS_MATCH_CF_COUNTER_ADD 0x02 -#define UTILS_MATCH_CF_COUNTER_INC 0x04 +#define UTILS_MATCH_CF_COUNTER_SET 0x01 +#define UTILS_MATCH_CF_COUNTER_ADD 0x02 +#define UTILS_MATCH_CF_COUNTER_INC 0x04 -#define UTILS_MATCH_CF_DERIVE_SET 0x01 -#define UTILS_MATCH_CF_DERIVE_ADD 0x02 -#define UTILS_MATCH_CF_DERIVE_INC 0x04 +#define UTILS_MATCH_CF_DERIVE_SET 0x01 +#define UTILS_MATCH_CF_DERIVE_ADD 0x02 +#define UTILS_MATCH_CF_DERIVE_INC 0x04 -#define UTILS_MATCH_CF_ABSOLUTE_SET 0x01 -#define UTILS_MATCH_CF_ABSOLUTE_ADD 0x02 -#define UTILS_MATCH_CF_ABSOLUTE_INC 0x04 +#define UTILS_MATCH_CF_ABSOLUTE_SET 0x01 +#define UTILS_MATCH_CF_ABSOLUTE_ADD 0x02 +#define UTILS_MATCH_CF_ABSOLUTE_INC 0x04 /* * Data types @@ -68,8 +68,7 @@ struct cu_match_s; typedef struct cu_match_s cu_match_t; -struct cu_match_value_s -{ +struct cu_match_value_s { int ds_type; value_t value; unsigned int values_num; @@ -100,10 +99,11 @@ typedef struct cu_match_value_s cu_match_value_t; * When `match_destroy' is called the `user_data' pointer is freed using * the `free_user_data' callback - if it is not NULL. */ -cu_match_t *match_create_callback (const char *regex, const char *excluderegex, - int (*callback) (const char *str, - char * const *matches, size_t matches_num, void *user_data), - void *user_data, void (*free_user_data) (void *user_data)); +cu_match_t * +match_create_callback(const char *regex, const char *excluderegex, + int (*callback)(const char *str, char *const *matches, + size_t matches_num, void *user_data), + void *user_data, void (*free_user_data)(void *user_data)); /* * NAME @@ -129,8 +129,8 @@ cu_match_t *match_create_callback (const char *regex, const char *excluderegex, * The function will not search for anything in the string and increase * value.counter by one. */ -cu_match_t *match_create_simple (const char *regex, - const char *excluderegex, int ds_type); +cu_match_t *match_create_simple(const char *regex, const char *excluderegex, + int ds_type); /* * NAME @@ -141,7 +141,7 @@ cu_match_t *match_create_simple (const char *regex, * after each iteration for "simple" matches, usually after dispatching the * metrics. */ -void match_value_reset (cu_match_value_t *mv); +void match_value_reset(cu_match_value_t *mv); /* * NAME @@ -150,7 +150,7 @@ void match_value_reset (cu_match_value_t *mv); * DESCRIPTION * Destroys the object and frees all internal resources. */ -void match_destroy (cu_match_t *obj); +void match_destroy(cu_match_t *obj); /* * NAME @@ -164,7 +164,7 @@ void match_destroy (cu_match_t *obj); * automatically. The `cu_match_value_t' structure allocated by * `match_create_callback' is freed automatically. */ -int match_apply (cu_match_t *obj, const char *str); +int match_apply(cu_match_t *obj, const char *str); /* * NAME @@ -174,7 +174,7 @@ int match_apply (cu_match_t *obj, const char *str); * Returns the pointer passed to `match_create_callback' or a pointer to the * `cu_match_value_t' structure allocated by `match_create_simple'. */ -void *match_get_user_data (cu_match_t *obj); +void *match_get_user_data(cu_match_t *obj); #endif /* UTILS_MATCH_H */ diff --git a/src/daemon/utils_random.c b/src/daemon/utils_random.c index 0488f913..34cf5b80 100644 --- a/src/daemon/utils_random.c +++ b/src/daemon/utils_random.c @@ -26,18 +26,16 @@ #include "collectd.h" -#include "utils_time.h" #include "utils_random.h" +#include "utils_time.h" #include - static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; static _Bool have_seed = 0; static unsigned short seed[3]; -static void cdrand_seed (void) -{ +static void cdrand_seed(void) { cdtime_t t; if (have_seed) @@ -45,33 +43,31 @@ static void cdrand_seed (void) t = cdtime(); - seed[0] = (unsigned short) t; - seed[1] = (unsigned short) (t >> 16); - seed[2] = (unsigned short) (t >> 32); + seed[0] = (unsigned short)t; + seed[1] = (unsigned short)(t >> 16); + seed[2] = (unsigned short)(t >> 32); have_seed = 1; } -double cdrand_d (void) -{ +double cdrand_d(void) { double r; - pthread_mutex_lock (&lock); - cdrand_seed (); - r = erand48 (seed); - pthread_mutex_unlock (&lock); + pthread_mutex_lock(&lock); + cdrand_seed(); + r = erand48(seed); + pthread_mutex_unlock(&lock); return (r); } -long cdrand_range (long min, long max) -{ +long cdrand_range(long min, long max) { long range; long r; range = 1 + max - min; - r = (long) (0.5 + (cdrand_d () * range)); + r = (long)(0.5 + (cdrand_d() * range)); r += min; return (r); diff --git a/src/daemon/utils_random.h b/src/daemon/utils_random.h index b05f4c86..d56bcf6a 100644 --- a/src/daemon/utils_random.h +++ b/src/daemon/utils_random.h @@ -29,7 +29,7 @@ * * This function is thread- and reentrant-safe. */ -double cdrand_d (void); +double cdrand_d(void); /** * Returns a random long between min and max, inclusively. @@ -37,4 +37,4 @@ double cdrand_d (void); * If min is larger than max, the result may be rounded incorrectly and may be * outside the intended range. This function is thread- and reentrant-safe. */ -long cdrand_range (long min, long max); +long cdrand_range(long min, long max); diff --git a/src/daemon/utils_subst.c b/src/daemon/utils_subst.c index 1bc28f72..7056c5f0 100644 --- a/src/daemon/utils_subst.c +++ b/src/daemon/utils_subst.c @@ -33,138 +33,131 @@ #include "common.h" #include "utils_subst.h" -char *subst (char *buf, size_t buflen, const char *string, size_t off1, size_t off2, - const char *replacement) -{ - char *out = buf; - - char const *front; - char const *back; - size_t front_len; - size_t replacement_len; - size_t back_len; - - if ((NULL == buf) || (0 == buflen) || (NULL == string) || (NULL == replacement)) - return NULL; - - size_t string_len = strlen (string); - if ((off1 > string_len) || (off2 > string_len) || (off1 > off2)) - return NULL; - - front = string; - back = string + off2; - front_len = off1; - replacement_len = strlen (replacement); - back_len = strlen (back); - - if (front_len >= buflen) { - front_len = buflen - 1; - replacement_len = 0; - back_len = 0; - } else if ((front_len + replacement_len) >= buflen) { - replacement_len = buflen - (front_len + 1); - back_len = 0; - } else if ((front_len + replacement_len + back_len) >= buflen) { - back_len = buflen - (front_len + replacement_len + 1); - } else { - buflen = front_len + replacement_len + back_len + 1; - } - assert ((front_len + replacement_len + back_len) == (buflen - 1)); - - if (front_len != 0) { - sstrncpy (out, front, front_len + 1); - out += front_len; - } - - if (replacement_len != 0) { - sstrncpy (out, replacement, replacement_len + 1); - out += replacement_len; - } - - if (back_len != 0) { - sstrncpy (out, back, back_len + 1); - out += back_len; - } - - out[0] = 0; - return buf; +char *subst(char *buf, size_t buflen, const char *string, size_t off1, + size_t off2, const char *replacement) { + char *out = buf; + + char const *front; + char const *back; + size_t front_len; + size_t replacement_len; + size_t back_len; + + if ((NULL == buf) || (0 == buflen) || (NULL == string) || + (NULL == replacement)) + return NULL; + + size_t string_len = strlen(string); + if ((off1 > string_len) || (off2 > string_len) || (off1 > off2)) + return NULL; + + front = string; + back = string + off2; + front_len = off1; + replacement_len = strlen(replacement); + back_len = strlen(back); + + if (front_len >= buflen) { + front_len = buflen - 1; + replacement_len = 0; + back_len = 0; + } else if ((front_len + replacement_len) >= buflen) { + replacement_len = buflen - (front_len + 1); + back_len = 0; + } else if ((front_len + replacement_len + back_len) >= buflen) { + back_len = buflen - (front_len + replacement_len + 1); + } else { + buflen = front_len + replacement_len + back_len + 1; + } + assert((front_len + replacement_len + back_len) == (buflen - 1)); + + if (front_len != 0) { + sstrncpy(out, front, front_len + 1); + out += front_len; + } + + if (replacement_len != 0) { + sstrncpy(out, replacement, replacement_len + 1); + out += replacement_len; + } + + if (back_len != 0) { + sstrncpy(out, back, back_len + 1); + out += back_len; + } + + out[0] = 0; + return buf; } /* subst */ -char *asubst (const char *string, int off1, int off2, const char *replacement) -{ - char *buf; - int len; +char *asubst(const char *string, int off1, int off2, const char *replacement) { + char *buf; + int len; - char *ret; + char *ret; - if ((NULL == string) || (0 > off1) || (0 > off2) || (off1 > off2) - || (NULL ==replacement)) - return NULL; + if ((NULL == string) || (0 > off1) || (0 > off2) || (off1 > off2) || + (NULL == replacement)) + return NULL; - len = off1 + strlen (replacement) + strlen (string) - off2 + 1; + len = off1 + strlen(replacement) + strlen(string) - off2 + 1; - buf = malloc (len); - if (NULL == buf) - return NULL; + buf = malloc(len); + if (NULL == buf) + return NULL; - ret = subst (buf, len, string, off1, off2, replacement); - if (NULL == ret) - free (buf); - return ret; + ret = subst(buf, len, string, off1, off2, replacement); + if (NULL == ret) + free(buf); + return ret; } /* asubst */ -char *subst_string (char *buf, size_t buflen, const char *string, - const char *needle, const char *replacement) -{ - size_t needle_len; - size_t i; - - if ((buf == NULL) || (string == NULL) - || (needle == NULL) || (replacement == NULL)) - return (NULL); - - needle_len = strlen (needle); - sstrncpy (buf, string, buflen); - - /* Limit the loop to prevent endless loops. */ - for (i = 0; i < buflen; i++) - { - char temp[buflen]; - char *begin_ptr; - size_t begin; - - /* Find `needle' in `buf'. */ - begin_ptr = strstr (buf, needle); - if (begin_ptr == NULL) - break; - - /* Calculate the start offset. */ - begin = begin_ptr - buf; - - /* Substitute the region using `subst'. The result is stored in - * `temp'. */ - begin_ptr = subst (temp, buflen, buf, - begin, begin + needle_len, - replacement); - if (begin_ptr == NULL) - { - WARNING ("subst_string: subst failed."); - break; - } - - /* Copy the new string in `temp' to `buf' for the next round. */ - strncpy (buf, temp, buflen); - } - - if (i >= buflen) - { - WARNING ("subst_string: Loop exited after %zu iterations: " - "string = %s; needle = %s; replacement = %s;", - i, string, needle, replacement); - } - - return (buf); +char *subst_string(char *buf, size_t buflen, const char *string, + const char *needle, const char *replacement) { + size_t needle_len; + size_t i; + + if ((buf == NULL) || (string == NULL) || (needle == NULL) || + (replacement == NULL)) + return (NULL); + + needle_len = strlen(needle); + sstrncpy(buf, string, buflen); + + /* Limit the loop to prevent endless loops. */ + for (i = 0; i < buflen; i++) { + char temp[buflen]; + char *begin_ptr; + size_t begin; + + /* Find `needle' in `buf'. */ + begin_ptr = strstr(buf, needle); + if (begin_ptr == NULL) + break; + + /* Calculate the start offset. */ + begin = begin_ptr - buf; + + /* Substitute the region using `subst'. The result is stored in + * `temp'. */ + begin_ptr = + subst(temp, buflen, buf, begin, begin + needle_len, replacement); + if (begin_ptr == NULL) { + WARNING("subst_string: subst failed."); + break; + } + + /* Copy the new string in `temp' to `buf' for the next round. */ + strncpy(buf, temp, buflen); + } + + if (i >= buflen) { + WARNING("subst_string: Loop exited after %zu iterations: " + "string = %s; needle = %s; replacement = %s;", + i, string, needle, replacement); + } + + return (buf); } /* char *subst_string */ /* vim: set sw=4 ts=4 tw=78 noexpandtab : */ - diff --git a/src/daemon/utils_subst.h b/src/daemon/utils_subst.h index 50df9c7b..025f8d4e 100644 --- a/src/daemon/utils_subst.h +++ b/src/daemon/utils_subst.h @@ -66,8 +66,8 @@ * * The function returns 'buf' on success, NULL else. */ -char *subst (char *buf, size_t buflen, const char *string, size_t off1, size_t off2, - const char *replacement); +char *subst(char *buf, size_t buflen, const char *string, size_t off1, + size_t off2, const char *replacement); /* * asubst: @@ -78,7 +78,7 @@ char *subst (char *buf, size_t buflen, const char *string, size_t off1, size_t o * * Returns the newly allocated result string on success, NULL else. */ -char *asubst (const char *string, int off1, int off2, const char *replacement); +char *asubst(const char *string, int off1, int off2, const char *replacement); /* * subst_string: @@ -96,10 +96,9 @@ char *asubst (const char *string, int off1, int off2, const char *replacement); * and the loop is broken. A warning is printed and the function returns * success. */ -char *subst_string (char *buf, size_t buflen, const char *string, - const char *needle, const char *replacement); +char *subst_string(char *buf, size_t buflen, const char *string, + const char *needle, const char *replacement); #endif /* UTILS_SUBST_H */ /* vim: set sw=4 ts=4 tw=78 noexpandtab : */ - diff --git a/src/daemon/utils_subst_test.c b/src/daemon/utils_subst_test.c index c6caba20..e335b501 100644 --- a/src/daemon/utils_subst_test.c +++ b/src/daemon/utils_subst_test.c @@ -34,8 +34,7 @@ kstat_ctl_t *kc; #endif /* HAVE_LIBKSTAT */ -DEF_TEST(subst) -{ +DEF_TEST(subst) { struct { const char *str; int off1; @@ -43,89 +42,91 @@ DEF_TEST(subst) const char *rplmt; const char *want; } cases[] = { - {"foo_____bar", 3, 8, " - ", "foo - bar"}, /* documentation example */ - {"foo bar", 0, 2, "m", "mo bar"}, /* beginning, shorten */ - {"foo bar", 0, 1, "m", "moo bar"}, /* beginning, same length */ - {"foo bar", 0, 3, "milk", "milk bar"}, /* beginning, extend */ - {"foo bar", 3, 6, "de", "fooder"}, /* center, shorten */ - {"foo bar", 2, 6, "rste", "forster"}, /* center, same length */ - {"foo bar", 1, 3, "ish", "fish bar"}, /* center, extend */ - {"foo bar", 2, 7, "ul", "foul"}, /* end, shorten */ - {"foo bar", 3, 7, "lish", "foolish"}, /* end, same length */ - {"foo bar", 3, 7, "dwear", "foodwear"}, /* end, extend */ - /* truncation (buffer is 16 chars) */ - {"01234567890123", 8, 8, "", "01234567890123"}, - {"01234567890123", 8, 8, "*", "01234567*890123"}, - {"01234567890123", 8, 8, "**", "01234567**89012"}, - /* input > buffer */ - {"012345678901234----", 0, 0, "", "012345678901234"}, - {"012345678901234----", 17, 18, "", "012345678901234"}, - {"012345678901234----", 0, 3, "", "345678901234---"}, - {"012345678901234----", 0, 4, "", "45678901234----"}, - {"012345678901234----", 0, 5, "", "5678901234----"}, - {"012345678901234----", 8, 8, "#", "01234567#890123"}, - {"012345678901234----", 12, 12, "##", "012345678901##2"}, - {"012345678901234----", 13, 13, "##", "0123456789012##"}, - {"012345678901234----", 14, 14, "##", "01234567890123#"}, - {"012345678901234----", 15, 15, "##", "012345678901234"}, - {"012345678901234----", 16, 16, "##", "012345678901234"}, - /* error cases */ - {NULL, 3, 4, "_", NULL}, /* no input */ - {"foo bar", 3, 10, "_", NULL}, /* offset exceeds input */ - {"foo bar", 10, 13, "_", NULL}, /* offset exceeds input */ - {"foo bar", 4, 3, "_", NULL}, /* off1 > off2 */ - {"foo bar", 3, 4, NULL, NULL}, /* no replacement */ + {"foo_____bar", 3, 8, " - ", "foo - bar"}, /* documentation example */ + {"foo bar", 0, 2, "m", "mo bar"}, /* beginning, shorten */ + {"foo bar", 0, 1, "m", "moo bar"}, /* beginning, same length */ + {"foo bar", 0, 3, "milk", "milk bar"}, /* beginning, extend */ + {"foo bar", 3, 6, "de", "fooder"}, /* center, shorten */ + {"foo bar", 2, 6, "rste", "forster"}, /* center, same length */ + {"foo bar", 1, 3, "ish", "fish bar"}, /* center, extend */ + {"foo bar", 2, 7, "ul", "foul"}, /* end, shorten */ + {"foo bar", 3, 7, "lish", "foolish"}, /* end, same length */ + {"foo bar", 3, 7, "dwear", "foodwear"}, /* end, extend */ + /* truncation (buffer is 16 chars) */ + {"01234567890123", 8, 8, "", "01234567890123"}, + {"01234567890123", 8, 8, "*", "01234567*890123"}, + {"01234567890123", 8, 8, "**", "01234567**89012"}, + /* input > buffer */ + {"012345678901234----", 0, 0, "", "012345678901234"}, + {"012345678901234----", 17, 18, "", "012345678901234"}, + {"012345678901234----", 0, 3, "", "345678901234---"}, + {"012345678901234----", 0, 4, "", "45678901234----"}, + {"012345678901234----", 0, 5, "", "5678901234----"}, + {"012345678901234----", 8, 8, "#", "01234567#890123"}, + {"012345678901234----", 12, 12, "##", "012345678901##2"}, + {"012345678901234----", 13, 13, "##", "0123456789012##"}, + {"012345678901234----", 14, 14, "##", "01234567890123#"}, + {"012345678901234----", 15, 15, "##", "012345678901234"}, + {"012345678901234----", 16, 16, "##", "012345678901234"}, + /* error cases */ + {NULL, 3, 4, "_", NULL}, /* no input */ + {"foo bar", 3, 10, "_", NULL}, /* offset exceeds input */ + {"foo bar", 10, 13, "_", NULL}, /* offset exceeds input */ + {"foo bar", 4, 3, "_", NULL}, /* off1 > off2 */ + {"foo bar", 3, 4, NULL, NULL}, /* no replacement */ }; - for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) { + for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) { char buffer[16] = "!!!!!!!!!!!!!!!"; if (cases[i].want == NULL) { - OK(subst (buffer, sizeof (buffer), cases[i].str, cases[i].off1, cases[i].off2, cases[i].rplmt) == NULL); + OK(subst(buffer, sizeof(buffer), cases[i].str, cases[i].off1, + cases[i].off2, cases[i].rplmt) == NULL); continue; } - OK(subst (buffer, sizeof (buffer), cases[i].str, cases[i].off1, cases[i].off2, cases[i].rplmt) == &buffer[0]); + OK(subst(buffer, sizeof(buffer), cases[i].str, cases[i].off1, cases[i].off2, + cases[i].rplmt) == &buffer[0]); EXPECT_EQ_STR(cases[i].want, buffer); } return 0; } -DEF_TEST(subst_string) -{ +DEF_TEST(subst_string) { struct { const char *str; const char *srch; const char *rplmt; const char *want; } cases[] = { - {"Hello %{name}", "%{name}", "world", "Hello world"}, - {"abcccccc", "abc", "cab", "ccccccab"}, - {"(((()(())))())", "()", "", ""}, - {"food booth", "oo", "ee", "feed beeth"}, - {"foo bar", "baz", "qux", "foo bar"}, - {"foo bar", "oo", "oo", "foo bar"}, - {"sixteen chars", "chars", "characters", "sixteen charact"}, + {"Hello %{name}", "%{name}", "world", "Hello world"}, + {"abcccccc", "abc", "cab", "ccccccab"}, + {"(((()(())))())", "()", "", ""}, + {"food booth", "oo", "ee", "feed beeth"}, + {"foo bar", "baz", "qux", "foo bar"}, + {"foo bar", "oo", "oo", "foo bar"}, + {"sixteen chars", "chars", "characters", "sixteen charact"}, }; - for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) { + for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) { char buffer[16]; if (cases[i].want == NULL) { - OK(subst_string (buffer, sizeof (buffer), cases[i].str, cases[i].srch, cases[i].rplmt) == NULL); + OK(subst_string(buffer, sizeof(buffer), cases[i].str, cases[i].srch, + cases[i].rplmt) == NULL); continue; } - OK(subst_string (buffer, sizeof (buffer), cases[i].str, cases[i].srch, cases[i].rplmt) == buffer); + OK(subst_string(buffer, sizeof(buffer), cases[i].str, cases[i].srch, + cases[i].rplmt) == buffer); EXPECT_EQ_STR(cases[i].want, buffer); } return 0; } -int main (void) -{ +int main(void) { RUN_TEST(subst); RUN_TEST(subst_string); diff --git a/src/daemon/utils_tail.c b/src/daemon/utils_tail.c index 0d8ed7c1..565a224c 100644 --- a/src/daemon/utils_tail.c +++ b/src/daemon/utils_tail.c @@ -35,48 +35,42 @@ #include "common.h" #include "utils_tail.h" -struct cu_tail_s -{ - char *file; - FILE *fh; - struct stat stat; +struct cu_tail_s { + char *file; + FILE *fh; + struct stat stat; }; -static int cu_tail_reopen (cu_tail_t *obj) -{ +static int cu_tail_reopen(cu_tail_t *obj) { int seek_end = 0; FILE *fh; - struct stat stat_buf = { 0 }; + struct stat stat_buf = {0}; int status; - status = stat (obj->file, &stat_buf); - if (status != 0) - { + status = stat(obj->file, &stat_buf); + if (status != 0) { char errbuf[1024]; - ERROR ("utils_tail: stat (%s) failed: %s", obj->file, - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("utils_tail: stat (%s) failed: %s", obj->file, + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } /* The file is already open.. */ - if ((obj->fh != NULL) && (stat_buf.st_ino == obj->stat.st_ino)) - { + if ((obj->fh != NULL) && (stat_buf.st_ino == obj->stat.st_ino)) { /* Seek to the beginning if file was truncated */ - if (stat_buf.st_size < obj->stat.st_size) - { - INFO ("utils_tail: File `%s' was truncated.", obj->file); - status = fseek (obj->fh, 0, SEEK_SET); - if (status != 0) - { - char errbuf[1024]; - ERROR ("utils_tail: fseek (%s) failed: %s", obj->file, - sstrerror (errno, errbuf, sizeof (errbuf))); - fclose (obj->fh); - obj->fh = NULL; - return (-1); + if (stat_buf.st_size < obj->stat.st_size) { + INFO("utils_tail: File `%s' was truncated.", obj->file); + status = fseek(obj->fh, 0, SEEK_SET); + if (status != 0) { + char errbuf[1024]; + ERROR("utils_tail: fseek (%s) failed: %s", obj->file, + sstrerror(errno, errbuf, sizeof(errbuf))); + fclose(obj->fh); + obj->fh = NULL; + return (-1); } } - memcpy (&obj->stat, &stat_buf, sizeof (struct stat)); + memcpy(&obj->stat, &stat_buf, sizeof(struct stat)); return (1); } @@ -85,129 +79,114 @@ static int cu_tail_reopen (cu_tail_t *obj) if ((obj->stat.st_ino == 0) || (obj->stat.st_ino == stat_buf.st_ino)) seek_end = 1; - fh = fopen (obj->file, "r"); - if (fh == NULL) - { + fh = fopen(obj->file, "r"); + if (fh == NULL) { char errbuf[1024]; - ERROR ("utils_tail: fopen (%s) failed: %s", obj->file, - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("utils_tail: fopen (%s) failed: %s", obj->file, + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } - if (seek_end != 0) - { - status = fseek (fh, 0, SEEK_END); - if (status != 0) - { + if (seek_end != 0) { + status = fseek(fh, 0, SEEK_END); + if (status != 0) { char errbuf[1024]; - ERROR ("utils_tail: fseek (%s) failed: %s", obj->file, - sstrerror (errno, errbuf, sizeof (errbuf))); - fclose (fh); + ERROR("utils_tail: fseek (%s) failed: %s", obj->file, + sstrerror(errno, errbuf, sizeof(errbuf))); + fclose(fh); return (-1); } } if (obj->fh != NULL) - fclose (obj->fh); + fclose(obj->fh); obj->fh = fh; - memcpy (&obj->stat, &stat_buf, sizeof (struct stat)); + memcpy(&obj->stat, &stat_buf, sizeof(struct stat)); return (0); } /* int cu_tail_reopen */ -cu_tail_t *cu_tail_create (const char *file) -{ - cu_tail_t *obj; +cu_tail_t *cu_tail_create(const char *file) { + cu_tail_t *obj; - obj = calloc (1, sizeof (*obj)); - if (obj == NULL) - return (NULL); + obj = calloc(1, sizeof(*obj)); + if (obj == NULL) + return (NULL); - obj->file = strdup (file); - if (obj->file == NULL) - { - free (obj); - return (NULL); - } + obj->file = strdup(file); + if (obj->file == NULL) { + free(obj); + return (NULL); + } - obj->fh = NULL; + obj->fh = NULL; - return (obj); + return (obj); } /* cu_tail_t *cu_tail_create */ -int cu_tail_destroy (cu_tail_t *obj) -{ - if (obj->fh != NULL) - fclose (obj->fh); - free (obj->file); - free (obj); +int cu_tail_destroy(cu_tail_t *obj) { + if (obj->fh != NULL) + fclose(obj->fh); + free(obj->file); + free(obj); - return (0); + return (0); } /* int cu_tail_destroy */ -int cu_tail_readline (cu_tail_t *obj, char *buf, int buflen) -{ +int cu_tail_readline(cu_tail_t *obj, char *buf, int buflen) { int status; - if (buflen < 1) - { - ERROR ("utils_tail: cu_tail_readline: buflen too small: %i bytes.", - buflen); + if (buflen < 1) { + ERROR("utils_tail: cu_tail_readline: buflen too small: %i bytes.", buflen); return (-1); } - if (obj->fh == NULL) - { - status = cu_tail_reopen (obj); + if (obj->fh == NULL) { + status = cu_tail_reopen(obj); if (status < 0) return (status); } - assert (obj->fh != NULL); + assert(obj->fh != NULL); /* Try to read from the filehandle. If that succeeds, everything appears to * be fine and we can return. */ - clearerr (obj->fh); - if (fgets (buf, buflen, obj->fh) != NULL) - { + clearerr(obj->fh); + if (fgets(buf, buflen, obj->fh) != NULL) { buf[buflen - 1] = 0; return (0); } /* Check if we encountered an error */ - if (ferror (obj->fh) != 0) - { + if (ferror(obj->fh) != 0) { /* Jupp, error. Force `cu_tail_reopen' to reopen the file.. */ - fclose (obj->fh); + fclose(obj->fh); obj->fh = NULL; } /* else: eof -> check if the file was moved away and reopen the new file if * so.. */ - status = cu_tail_reopen (obj); + status = cu_tail_reopen(obj); /* error -> return with error */ if (status < 0) return (status); /* file end reached and file not reopened -> nothing more to read */ - else if (status > 0) - { + else if (status > 0) { buf[0] = 0; return (0); } /* If we get here: file was re-opened and there may be more to read.. Let's * try again. */ - if (fgets (buf, buflen, obj->fh) != NULL) - { + if (fgets(buf, buflen, obj->fh) != NULL) { buf[buflen - 1] = 0; return (0); } - if (ferror (obj->fh) != 0) - { + if (ferror(obj->fh) != 0) { char errbuf[1024]; - WARNING ("utils_tail: fgets (%s) returned an error: %s", obj->file, - sstrerror (errno, errbuf, sizeof (errbuf))); - fclose (obj->fh); + WARNING("utils_tail: fgets (%s) returned an error: %s", obj->file, + sstrerror(errno, errbuf, sizeof(errbuf))); + fclose(obj->fh); obj->fh = NULL; return (-1); } @@ -217,43 +196,40 @@ int cu_tail_readline (cu_tail_t *obj, char *buf, int buflen) return (0); } /* int cu_tail_readline */ -int cu_tail_read (cu_tail_t *obj, char *buf, int buflen, tailfunc_t *callback, - void *data) -{ - int status; - - while (42) - { - size_t len; - - status = cu_tail_readline (obj, buf, buflen); - if (status != 0) - { - ERROR ("utils_tail: cu_tail_read: cu_tail_readline " - "failed."); - break; - } - - /* check for EOF */ - if (buf[0] == 0) - break; - - len = strlen (buf); - while (len > 0) { - if (buf[len - 1] != '\n') - break; - buf[len - 1] = '\0'; - len--; - } - - status = callback (data, buf, buflen); - if (status != 0) - { - ERROR ("utils_tail: cu_tail_read: callback returned " - "status %i.", status); - break; - } - } - - return status; +int cu_tail_read(cu_tail_t *obj, char *buf, int buflen, tailfunc_t *callback, + void *data) { + int status; + + while (42) { + size_t len; + + status = cu_tail_readline(obj, buf, buflen); + if (status != 0) { + ERROR("utils_tail: cu_tail_read: cu_tail_readline " + "failed."); + break; + } + + /* check for EOF */ + if (buf[0] == 0) + break; + + len = strlen(buf); + while (len > 0) { + if (buf[len - 1] != '\n') + break; + buf[len - 1] = '\0'; + len--; + } + + status = callback(data, buf, buflen); + if (status != 0) { + ERROR("utils_tail: cu_tail_read: callback returned " + "status %i.", + status); + break; + } + } + + return status; } /* int cu_tail_read */ diff --git a/src/daemon/utils_tail.h b/src/daemon/utils_tail.h index 6fb70133..73a6de21 100644 --- a/src/daemon/utils_tail.h +++ b/src/daemon/utils_tail.h @@ -47,7 +47,7 @@ typedef int tailfunc_t(void *data, char *buf, int buflen); * PARAMETERS * `file' The name of the file to be tailed. */ -cu_tail_t *cu_tail_create (const char *file); +cu_tail_t *cu_tail_create(const char *file); /* * cu_tail_destroy @@ -57,7 +57,7 @@ cu_tail_t *cu_tail_create (const char *file); * * Returns 0 when successful and non-zero otherwise. */ -int cu_tail_destroy (cu_tail_t *obj); +int cu_tail_destroy(cu_tail_t *obj); /* * cu_tail_readline @@ -73,7 +73,7 @@ int cu_tail_destroy (cu_tail_t *obj); * * Returns 0 when successful and non-zero otherwise. */ -int cu_tail_readline (cu_tail_t *obj, char *buf, int buflen); +int cu_tail_readline(cu_tail_t *obj, char *buf, int buflen); /* * cu_tail_readline @@ -82,7 +82,7 @@ int cu_tail_readline (cu_tail_t *obj, char *buf, int buflen); * * Returns 0 when successful and non-zero otherwise. */ -int cu_tail_read (cu_tail_t *obj, char *buf, int buflen, tailfunc_t *callback, - void *data); +int cu_tail_read(cu_tail_t *obj, char *buf, int buflen, tailfunc_t *callback, + void *data); #endif /* UTILS_TAIL_H */ diff --git a/src/daemon/utils_tail_match.c b/src/daemon/utils_tail_match.c index a0cbc11d..505c6937 100644 --- a/src/daemon/utils_tail_match.c +++ b/src/daemon/utils_tail_match.c @@ -33,13 +33,12 @@ #include "common.h" #include "plugin.h" +#include "utils_latency_config.h" #include "utils_match.h" #include "utils_tail.h" #include "utils_tail_match.h" -#include "utils_latency_config.h" -struct cu_tail_match_simple_s -{ +struct cu_tail_match_simple_s { char plugin[DATA_MAX_NAME_LEN]; char plugin_instance[DATA_MAX_NAME_LEN]; char type[DATA_MAX_NAME_LEN]; @@ -49,17 +48,15 @@ struct cu_tail_match_simple_s }; typedef struct cu_tail_match_simple_s cu_tail_match_simple_t; -struct cu_tail_match_match_s -{ +struct cu_tail_match_match_s { cu_match_t *match; void *user_data; - int (*submit) (cu_match_t *match, void *user_data); - void (*free) (void *user_data); + int (*submit)(cu_match_t *match, void *user_data); + void (*free)(void *user_data); }; typedef struct cu_tail_match_match_s cu_tail_match_match_t; -struct cu_tail_match_s -{ +struct cu_tail_match_s { int flags; cu_tail_t *tail; @@ -71,36 +68,34 @@ struct cu_tail_match_s /* * Private functions */ -static int simple_submit_match (cu_match_t *match, void *user_data) -{ - cu_tail_match_simple_t *data = (cu_tail_match_simple_t *) user_data; +static int simple_submit_match(cu_match_t *match, void *user_data) { + cu_tail_match_simple_t *data = (cu_tail_match_simple_t *)user_data; cu_match_value_t *match_value; value_list_t vl = VALUE_LIST_INIT; value_t values[1]; - match_value = (cu_match_value_t *) match_get_user_data (match); + match_value = (cu_match_value_t *)match_get_user_data(match); if (match_value == NULL) return (-1); - if ((match_value->ds_type & UTILS_MATCH_DS_TYPE_GAUGE) - && (match_value->values_num == 0)) + if ((match_value->ds_type & UTILS_MATCH_DS_TYPE_GAUGE) && + (match_value->values_num == 0)) values[0].gauge = NAN; else values[0] = match_value->value; vl.values = values; vl.values_len = 1; - sstrncpy (vl.plugin, data->plugin, sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, data->plugin_instance, - sizeof (vl.plugin_instance)); - sstrncpy (vl.type, data->type, sizeof (vl.type)); - sstrncpy (vl.type_instance, data->type_instance, - sizeof (vl.type_instance)); + sstrncpy(vl.plugin, data->plugin, sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, data->plugin_instance, + sizeof(vl.plugin_instance)); + sstrncpy(vl.type, data->type, sizeof(vl.type)); + sstrncpy(vl.type_instance, data->type_instance, sizeof(vl.type_instance)); vl.interval = data->interval; - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); - match_value_reset (match_value); + match_value_reset(match_value); return (0); } /* int simple_submit_match */ @@ -159,9 +154,9 @@ static int latency_submit_match(cu_match_t *match, void *user_data) { data->type, lower_bound, upper_bound); vl.values = &(value_t){ - .gauge = latency_counter_get_rate(match_value->latency, - bucket.lower_bound, - bucket.upper_bound, vl.time), + .gauge = + latency_counter_get_rate(match_value->latency, bucket.lower_bound, + bucket.upper_bound, vl.time), }; vl.values_len = 1; @@ -175,91 +170,83 @@ static int latency_submit_match(cu_match_t *match, void *user_data) { return (0); } /* int latency_submit_match */ -static int tail_callback (void *data, char *buf, - int __attribute__((unused)) buflen) -{ - cu_tail_match_t *obj = (cu_tail_match_t *) data; +static int tail_callback(void *data, char *buf, + int __attribute__((unused)) buflen) { + cu_tail_match_t *obj = (cu_tail_match_t *)data; for (size_t i = 0; i < obj->matches_num; i++) - match_apply (obj->matches[i].match, buf); + match_apply(obj->matches[i].match, buf); return (0); } /* int tail_callback */ -static void tail_match_simple_free (void *data) -{ - cu_tail_match_simple_t *user_data = (cu_tail_match_simple_t *) data; +static void tail_match_simple_free(void *data) { + cu_tail_match_simple_t *user_data = (cu_tail_match_simple_t *)data; latency_config_free(user_data->latency_config); - sfree (user_data); + sfree(user_data); } /* void tail_match_simple_free */ /* * Public functions */ -cu_tail_match_t *tail_match_create (const char *filename) -{ +cu_tail_match_t *tail_match_create(const char *filename) { cu_tail_match_t *obj; - obj = calloc (1, sizeof (*obj)); + obj = calloc(1, sizeof(*obj)); if (obj == NULL) return (NULL); - obj->tail = cu_tail_create (filename); - if (obj->tail == NULL) - { - sfree (obj); + obj->tail = cu_tail_create(filename); + if (obj->tail == NULL) { + sfree(obj); return (NULL); } return (obj); } /* cu_tail_match_t *tail_match_create */ -void tail_match_destroy (cu_tail_match_t *obj) -{ +void tail_match_destroy(cu_tail_match_t *obj) { if (obj == NULL) return; - if (obj->tail != NULL) - { - cu_tail_destroy (obj->tail); + if (obj->tail != NULL) { + cu_tail_destroy(obj->tail); obj->tail = NULL; } - for (size_t i = 0; i < obj->matches_num; i++) - { + for (size_t i = 0; i < obj->matches_num; i++) { cu_tail_match_match_t *match = obj->matches + i; - if (match->match != NULL) - { - match_destroy (match->match); + if (match->match != NULL) { + match_destroy(match->match); match->match = NULL; } - if ((match->user_data != NULL) - && (match->free != NULL)) - (*match->free) (match->user_data); + if ((match->user_data != NULL) && (match->free != NULL)) + (*match->free)(match->user_data); match->user_data = NULL; } - sfree (obj->matches); - sfree (obj); + sfree(obj->matches); + sfree(obj); } /* void tail_match_destroy */ -int tail_match_add_match (cu_tail_match_t *obj, cu_match_t *match, - int (*submit_match) (cu_match_t *match, void *user_data), - void *user_data, - void (*free_user_data) (void *user_data)) -{ +int tail_match_add_match(cu_tail_match_t *obj, cu_match_t *match, + int (*submit_match)(cu_match_t *match, + void *user_data), + void *user_data, + void (*free_user_data)(void *user_data)) { cu_tail_match_match_t *temp; - temp = realloc (obj->matches, - sizeof (cu_tail_match_match_t) * (obj->matches_num + 1)); + temp = realloc(obj->matches, + sizeof(cu_tail_match_match_t) * (obj->matches_num + 1)); if (temp == NULL) return (-1); obj->matches = temp; obj->matches_num++; - DEBUG ("tail_match_add_match interval %lf", CDTIME_T_TO_DOUBLE(((cu_tail_match_simple_t *)user_data)->interval)); + DEBUG("tail_match_add_match interval %lf", + CDTIME_T_TO_DOUBLE(((cu_tail_match_simple_t *)user_data)->interval)); temp = obj->matches + (obj->matches_num - 1); temp->match = match; @@ -270,89 +257,81 @@ int tail_match_add_match (cu_tail_match_t *obj, cu_match_t *match, return (0); } /* int tail_match_add_match */ -int tail_match_add_match_simple (cu_tail_match_t *obj, - const char *regex, const char *excluderegex, int ds_type, - const char *plugin, const char *plugin_instance, - const char *type, const char *type_instance, - const latency_config_t latency_cfg, - const cdtime_t interval) -{ +int tail_match_add_match_simple(cu_tail_match_t *obj, const char *regex, + const char *excluderegex, int ds_type, + const char *plugin, const char *plugin_instance, + const char *type, const char *type_instance, + const latency_config_t latency_cfg, + const cdtime_t interval) { cu_match_t *match; cu_tail_match_simple_t *user_data; int status; - match = match_create_simple (regex, excluderegex, ds_type); + match = match_create_simple(regex, excluderegex, ds_type); if (match == NULL) return (-1); - user_data = calloc (1, sizeof (*user_data)); - if (user_data == NULL) - { - match_destroy (match); + user_data = calloc(1, sizeof(*user_data)); + if (user_data == NULL) { + match_destroy(match); return (-1); } - sstrncpy (user_data->plugin, plugin, sizeof (user_data->plugin)); + sstrncpy(user_data->plugin, plugin, sizeof(user_data->plugin)); if (plugin_instance != NULL) - sstrncpy (user_data->plugin_instance, plugin_instance, - sizeof (user_data->plugin_instance)); + sstrncpy(user_data->plugin_instance, plugin_instance, + sizeof(user_data->plugin_instance)); - sstrncpy (user_data->type, type, sizeof (user_data->type)); + sstrncpy(user_data->type, type, sizeof(user_data->type)); if (type_instance != NULL) - sstrncpy (user_data->type_instance, type_instance, - sizeof (user_data->type_instance)); + sstrncpy(user_data->type_instance, type_instance, + sizeof(user_data->type_instance)); user_data->interval = interval; - if ((ds_type & UTILS_MATCH_DS_TYPE_GAUGE) - && (ds_type & UTILS_MATCH_CF_GAUGE_DIST)) - { + if ((ds_type & UTILS_MATCH_DS_TYPE_GAUGE) && + (ds_type & UTILS_MATCH_CF_GAUGE_DIST)) { status = latency_config_copy(&user_data->latency_config, latency_cfg); - if (status != 0) - { - ERROR ("tail_match_add_match_simple: latency_config_copy() failed."); + if (status != 0) { + ERROR("tail_match_add_match_simple: latency_config_copy() failed."); status = -1; goto out; } - status = tail_match_add_match (obj, match, latency_submit_match, - user_data, tail_match_simple_free); + status = tail_match_add_match(obj, match, latency_submit_match, user_data, + tail_match_simple_free); } else { - status = tail_match_add_match (obj, match, simple_submit_match, - user_data, free); + status = + tail_match_add_match(obj, match, simple_submit_match, user_data, free); } out: - if (status != 0) - { + if (status != 0) { tail_match_simple_free(user_data); - match_destroy (match); + match_destroy(match); } return (status); } /* int tail_match_add_match_simple */ -int tail_match_read (cu_tail_match_t *obj) -{ +int tail_match_read(cu_tail_match_t *obj) { char buffer[4096]; int status; - status = cu_tail_read (obj->tail, buffer, sizeof (buffer), tail_callback, - (void *) obj); - if (status != 0) - { - ERROR ("tail_match: cu_tail_read failed."); + status = cu_tail_read(obj->tail, buffer, sizeof(buffer), tail_callback, + (void *)obj); + if (status != 0) { + ERROR("tail_match: cu_tail_read failed."); return (status); } - for (size_t i = 0; i < obj->matches_num; i++) - { + for (size_t i = 0; i < obj->matches_num; i++) { cu_tail_match_match_t *lt_match = obj->matches + i; if (lt_match->submit == NULL) continue; - (*lt_match->submit) (lt_match->match, lt_match->user_data); + (*lt_match->submit)(lt_match->match, lt_match->user_data); } return (0); diff --git a/src/daemon/utils_tail_match.h b/src/daemon/utils_tail_match.h index ffb4999b..09e3d402 100644 --- a/src/daemon/utils_tail_match.h +++ b/src/daemon/utils_tail_match.h @@ -33,8 +33,8 @@ * regular expressions. */ -#include "utils_match.h" #include "utils_latency_config.h" +#include "utils_match.h" struct cu_tail_match_s; typedef struct cu_tail_match_s cu_tail_match_t; @@ -52,7 +52,7 @@ typedef struct cu_tail_match_s cu_tail_match_t; * RETURN VALUE * Returns NULL upon failure, non-NULL otherwise. */ -cu_tail_match_t *tail_match_create (const char *filename); +cu_tail_match_t *tail_match_create(const char *filename); /* * NAME @@ -64,7 +64,7 @@ cu_tail_match_t *tail_match_create (const char *filename); * PARAMETERS * The object to destroy. */ -void tail_match_destroy (cu_tail_match_t *obj); +void tail_match_destroy(cu_tail_match_t *obj); /* * NAME @@ -79,28 +79,32 @@ void tail_match_destroy (cu_tail_match_t *obj); * matched any lines recently or not. * When `tail_match_destroy' is called the `user_data' pointer is freed using * the `free_user_data' callback - if it is not NULL. - * When using this interface the `tail_match' module doesn't dispatch any values + * When using this interface the `tail_match' module doesn't dispatch any + * values * itself - all that has to happen in either the match-callbacks or the * submit_match callback. * * RETURN VALUE * Zero upon success, non-zero otherwise. */ -int tail_match_add_match (cu_tail_match_t *obj, cu_match_t *match, - int (*submit_match) (cu_match_t *match, void *user_data), - void *user_data, - void (*free_user_data) (void *user_data)); +int tail_match_add_match(cu_tail_match_t *obj, cu_match_t *match, + int (*submit_match)(cu_match_t *match, + void *user_data), + void *user_data, + void (*free_user_data)(void *user_data)); /* * NAME * tail_match_add_match_simple * * DESCRIPTION - * A simplified version of `tail_match_add_match'. The regular expressen `regex' + * A simplified version of `tail_match_add_match'. The regular expressen + * `regex' * must match a number, which is then dispatched according to `ds_type'. See * the `match_create_simple' function in utils_match.h for a description how * this flag effects calculation of a new value. - * The values gathered are dispatched by the tail_match module in this case. The + * The values gathered are dispatched by the tail_match module in this case. + * The * passed `plugin', `plugin_instance', `type', and `type_instance' are * directly used when submitting these values. * With excluderegex it is possible to exlude lines from the match. @@ -109,11 +113,12 @@ int tail_match_add_match (cu_tail_match_t *obj, cu_match_t *match, * RETURN VALUE * Zero upon success, non-zero otherwise. */ -int tail_match_add_match_simple (cu_tail_match_t *obj, - const char *regex, const char *excluderegex, int ds_type, - const char *plugin, const char *plugin_instance, - const char *type, const char *type_instance, const latency_config_t latency_cfg, - const cdtime_t interval); +int tail_match_add_match_simple(cu_tail_match_t *obj, const char *regex, + const char *excluderegex, int ds_type, + const char *plugin, const char *plugin_instance, + const char *type, const char *type_instance, + const latency_config_t latency_cfg, + const cdtime_t interval); /* * NAME @@ -124,12 +129,13 @@ int tail_match_add_match_simple (cu_tail_match_t *obj, * from the logfile using `utils_tail' and tries to match them using all * added `utils_match' objects. * After all lines have been read and processed, the submit_match callback is - * called or, in case of tail_match_add_match_simple, the data is dispatched to + * called or, in case of tail_match_add_match_simple, the data is dispatched + * to * the daemon directly. * * RETURN VALUE * Zero on success, nonzero on failure. */ -int tail_match_read (cu_tail_match_t *obj); +int tail_match_read(cu_tail_match_t *obj); /* vim: set sw=2 sts=2 ts=8 : */ diff --git a/src/daemon/utils_threshold.c b/src/daemon/utils_threshold.c index 784e1094..ad832f54 100644 --- a/src/daemon/utils_threshold.c +++ b/src/daemon/utils_threshold.c @@ -35,7 +35,7 @@ /* * Exported symbols * {{{ */ -c_avl_tree_t *threshold_tree = NULL; +c_avl_tree_t *threshold_tree = NULL; pthread_mutex_t threshold_lock = PTHREAD_MUTEX_INITIALIZER; /* }}} */ @@ -46,20 +46,18 @@ pthread_mutex_t threshold_lock = PTHREAD_MUTEX_INITIALIZER; * matching a value_list_t, see "threshold_search" below. Returns NULL if the * specified threshold doesn't exist. */ -threshold_t *threshold_get (const char *hostname, - const char *plugin, const char *plugin_instance, - const char *type, const char *type_instance) -{ /* {{{ */ +threshold_t *threshold_get(const char *hostname, const char *plugin, + const char *plugin_instance, const char *type, + const char *type_instance) { /* {{{ */ char name[6 * DATA_MAX_NAME_LEN]; threshold_t *th = NULL; - format_name (name, sizeof (name), - (hostname == NULL) ? "" : hostname, - (plugin == NULL) ? "" : plugin, plugin_instance, - (type == NULL) ? "" : type, type_instance); - name[sizeof (name) - 1] = '\0'; + format_name(name, sizeof(name), (hostname == NULL) ? "" : hostname, + (plugin == NULL) ? "" : plugin, plugin_instance, + (type == NULL) ? "" : type, type_instance); + name[sizeof(name) - 1] = '\0'; - if (c_avl_get (threshold_tree, name, (void *) &th) == 0) + if (c_avl_get(threshold_tree, name, (void *)&th) == 0) return (th); else return (NULL); @@ -73,72 +71,65 @@ threshold_t *threshold_get (const char *hostname, * found. * XXX: This is likely the least efficient function in collectd. */ -threshold_t *threshold_search (const value_list_t *vl) -{ /* {{{ */ +threshold_t *threshold_search(const value_list_t *vl) { /* {{{ */ threshold_t *th; - if ((th = threshold_get (vl->host, vl->plugin, vl->plugin_instance, - vl->type, vl->type_instance)) != NULL) + if ((th = threshold_get(vl->host, vl->plugin, vl->plugin_instance, vl->type, + vl->type_instance)) != NULL) return (th); - else if ((th = threshold_get (vl->host, vl->plugin, vl->plugin_instance, - vl->type, NULL)) != NULL) + else if ((th = threshold_get(vl->host, vl->plugin, vl->plugin_instance, + vl->type, NULL)) != NULL) return (th); - else if ((th = threshold_get (vl->host, vl->plugin, NULL, - vl->type, vl->type_instance)) != NULL) + else if ((th = threshold_get(vl->host, vl->plugin, NULL, vl->type, + vl->type_instance)) != NULL) return (th); - else if ((th = threshold_get (vl->host, vl->plugin, NULL, - vl->type, NULL)) != NULL) + else if ((th = threshold_get(vl->host, vl->plugin, NULL, vl->type, NULL)) != + NULL) return (th); - else if ((th = threshold_get (vl->host, "", NULL, - vl->type, vl->type_instance)) != NULL) + else if ((th = threshold_get(vl->host, "", NULL, vl->type, + vl->type_instance)) != NULL) return (th); - else if ((th = threshold_get (vl->host, "", NULL, - vl->type, NULL)) != NULL) + else if ((th = threshold_get(vl->host, "", NULL, vl->type, NULL)) != NULL) return (th); - else if ((th = threshold_get ("", vl->plugin, vl->plugin_instance, - vl->type, vl->type_instance)) != NULL) + else if ((th = threshold_get("", vl->plugin, vl->plugin_instance, vl->type, + vl->type_instance)) != NULL) return (th); - else if ((th = threshold_get ("", vl->plugin, vl->plugin_instance, - vl->type, NULL)) != NULL) + else if ((th = threshold_get("", vl->plugin, vl->plugin_instance, vl->type, + NULL)) != NULL) return (th); - else if ((th = threshold_get ("", vl->plugin, NULL, - vl->type, vl->type_instance)) != NULL) + else if ((th = threshold_get("", vl->plugin, NULL, vl->type, + vl->type_instance)) != NULL) return (th); - else if ((th = threshold_get ("", vl->plugin, NULL, - vl->type, NULL)) != NULL) + else if ((th = threshold_get("", vl->plugin, NULL, vl->type, NULL)) != NULL) return (th); - else if ((th = threshold_get ("", "", NULL, - vl->type, vl->type_instance)) != NULL) + else if ((th = threshold_get("", "", NULL, vl->type, vl->type_instance)) != + NULL) return (th); - else if ((th = threshold_get ("", "", NULL, - vl->type, NULL)) != NULL) + else if ((th = threshold_get("", "", NULL, vl->type, NULL)) != NULL) return (th); return (NULL); } /* }}} threshold_t *threshold_search */ -int ut_search_threshold (const value_list_t *vl, /* {{{ */ - threshold_t *ret_threshold) -{ +int ut_search_threshold(const value_list_t *vl, /* {{{ */ + threshold_t *ret_threshold) { threshold_t *t; if (vl == NULL) return (EINVAL); /* Is this lock really necessary? */ - pthread_mutex_lock (&threshold_lock); - t = threshold_search (vl); + pthread_mutex_lock(&threshold_lock); + t = threshold_search(vl); if (t == NULL) { - pthread_mutex_unlock (&threshold_lock); + pthread_mutex_unlock(&threshold_lock); return (ENOENT); } - memcpy (ret_threshold, t, sizeof (*ret_threshold)); - pthread_mutex_unlock (&threshold_lock); + memcpy(ret_threshold, t, sizeof(*ret_threshold)); + pthread_mutex_unlock(&threshold_lock); ret_threshold->next = NULL; return (0); } /* }}} int ut_search_threshold */ - - diff --git a/src/daemon/utils_threshold.h b/src/daemon/utils_threshold.h index a5c33737..585ad12a 100644 --- a/src/daemon/utils_threshold.h +++ b/src/daemon/utils_threshold.h @@ -27,13 +27,12 @@ #ifndef UTILS_THRESHOLD_H #define UTILS_THRESHOLD_H 1 -#define UT_FLAG_INVERT 0x01 +#define UT_FLAG_INVERT 0x01 #define UT_FLAG_PERSIST 0x02 #define UT_FLAG_PERCENTAGE 0x04 #define UT_FLAG_INTERESTING 0x08 #define UT_FLAG_PERSIST_OK 0x10 -typedef struct threshold_s -{ +typedef struct threshold_s { char host[DATA_MAX_NAME_LEN]; char plugin[DATA_MAX_NAME_LEN]; char plugin_instance[DATA_MAX_NAME_LEN]; @@ -50,17 +49,16 @@ typedef struct threshold_s struct threshold_s *next; } threshold_t; -extern c_avl_tree_t *threshold_tree; +extern c_avl_tree_t *threshold_tree; extern pthread_mutex_t threshold_lock; -threshold_t *threshold_get (const char *hostname, - const char *plugin, const char *plugin_instance, - const char *type, const char *type_instance); +threshold_t *threshold_get(const char *hostname, const char *plugin, + const char *plugin_instance, const char *type, + const char *type_instance); -threshold_t *threshold_search (const value_list_t *vl); +threshold_t *threshold_search(const value_list_t *vl); -int ut_search_threshold (const value_list_t *vl, - threshold_t *ret_threshold); +int ut_search_threshold(const value_list_t *vl, threshold_t *ret_threshold); #endif /* UTILS_THRESHOLD_H */ diff --git a/src/daemon/utils_time.c b/src/daemon/utils_time.c index b24ceac4..9ba2b5a1 100644 --- a/src/daemon/utils_time.c +++ b/src/daemon/utils_time.c @@ -26,74 +26,69 @@ #include "collectd.h" -#include "utils_time.h" -#include "plugin.h" #include "common.h" +#include "plugin.h" +#include "utils_time.h" #ifndef DEFAULT_MOCK_TIME -# define DEFAULT_MOCK_TIME 1542455354518929408ULL +#define DEFAULT_MOCK_TIME 1542455354518929408ULL #endif #ifdef MOCK_TIME -cdtime_t cdtime_mock = (cdtime_t) MOCK_TIME; +cdtime_t cdtime_mock = (cdtime_t)MOCK_TIME; -cdtime_t cdtime (void) -{ - return cdtime_mock; -} +cdtime_t cdtime(void) { return cdtime_mock; } #else /* !MOCK_TIME */ -# if HAVE_CLOCK_GETTIME -cdtime_t cdtime (void) /* {{{ */ +#if HAVE_CLOCK_GETTIME +cdtime_t cdtime(void) /* {{{ */ { int status; - struct timespec ts = { 0, 0 }; + struct timespec ts = {0, 0}; - status = clock_gettime (CLOCK_REALTIME, &ts); - if (status != 0) - { + status = clock_gettime(CLOCK_REALTIME, &ts); + if (status != 0) { char errbuf[1024]; - ERROR ("cdtime: clock_gettime failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("cdtime: clock_gettime failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); return 0; } - return TIMESPEC_TO_CDTIME_T (&ts); + return TIMESPEC_TO_CDTIME_T(&ts); } /* }}} cdtime_t cdtime */ -# else /* !HAVE_CLOCK_GETTIME */ +#else /* !HAVE_CLOCK_GETTIME */ /* Work around for Mac OS X which doesn't have clock_gettime(2). *sigh* */ -cdtime_t cdtime (void) /* {{{ */ +cdtime_t cdtime(void) /* {{{ */ { int status; - struct timeval tv = { 0, 0 }; + struct timeval tv = {0, 0}; - status = gettimeofday (&tv, /* struct timezone = */ NULL); - if (status != 0) - { + status = gettimeofday(&tv, /* struct timezone = */ NULL); + if (status != 0) { char errbuf[1024]; - ERROR ("cdtime: gettimeofday failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("cdtime: gettimeofday failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); return 0; } - return TIMEVAL_TO_CDTIME_T (&tv); + return TIMEVAL_TO_CDTIME_T(&tv); } /* }}} cdtime_t cdtime */ -# endif +#endif #endif /********************************************************************** Time retrieval functions ***********************************************************************/ -static int get_utc_time (cdtime_t t, struct tm *t_tm, long *nsec) /* {{{ */ +static int get_utc_time(cdtime_t t, struct tm *t_tm, long *nsec) /* {{{ */ { - struct timespec t_spec = CDTIME_T_TO_TIMESPEC (t); - NORMALIZE_TIMESPEC (t_spec); + struct timespec t_spec = CDTIME_T_TO_TIMESPEC(t); + NORMALIZE_TIMESPEC(t_spec); - if (gmtime_r (&t_spec.tv_sec, t_tm) == NULL) { + if (gmtime_r(&t_spec.tv_sec, t_tm) == NULL) { char errbuf[1024]; int status = errno; - ERROR ("get_utc_time: gmtime_r failed: %s", - sstrerror (status, errbuf, sizeof (errbuf))); + ERROR("get_utc_time: gmtime_r failed: %s", + sstrerror(status, errbuf, sizeof(errbuf))); return status; } @@ -101,16 +96,16 @@ static int get_utc_time (cdtime_t t, struct tm *t_tm, long *nsec) /* {{{ */ return 0; } /* }}} int get_utc_time */ -static int get_local_time (cdtime_t t, struct tm *t_tm, long *nsec) /* {{{ */ +static int get_local_time(cdtime_t t, struct tm *t_tm, long *nsec) /* {{{ */ { - struct timespec t_spec = CDTIME_T_TO_TIMESPEC (t); - NORMALIZE_TIMESPEC (t_spec); + struct timespec t_spec = CDTIME_T_TO_TIMESPEC(t); + NORMALIZE_TIMESPEC(t_spec); - if (localtime_r (&t_spec.tv_sec, t_tm) == NULL) { + if (localtime_r(&t_spec.tv_sec, t_tm) == NULL) { char errbuf[1024]; int status = errno; - ERROR ("get_local_time: localtime_r failed: %s", - sstrerror (status, errbuf, sizeof (errbuf))); + ERROR("get_local_time: localtime_r failed: %s", + sstrerror(status, errbuf, sizeof(errbuf))); return status; } @@ -127,7 +122,8 @@ static const char zulu_zone[] = "Z"; /* format_zone reads time zone information from "extern long timezone", exported * by , and formats it according to RFC 3339. This differs from * strftime()'s "%z" format by including a colon between hour and minute. */ -static int format_zone (char *buffer, size_t buffer_size, struct tm const *tm) /* {{{ */ +static int format_zone(char *buffer, size_t buffer_size, + struct tm const *tm) /* {{{ */ { char tmp[7]; size_t sz; @@ -135,13 +131,12 @@ static int format_zone (char *buffer, size_t buffer_size, struct tm const *tm) / if ((buffer == NULL) || (buffer_size < 7)) return EINVAL; - sz = strftime (tmp, sizeof (tmp), "%z", tm); + sz = strftime(tmp, sizeof(tmp), "%z", tm); if (sz == 0) return ENOMEM; - if (sz != 5) - { - DEBUG ("format_zone: strftime(\"%%z\") = \"%s\", want \"+hhmm\"", tmp); - sstrncpy (buffer, tmp, buffer_size); + if (sz != 5) { + DEBUG("format_zone: strftime(\"%%z\") = \"%s\", want \"+hhmm\"", tmp); + sstrncpy(buffer, tmp, buffer_size); return 0; } @@ -156,90 +151,94 @@ static int format_zone (char *buffer, size_t buffer_size, struct tm const *tm) / return 0; } /* }}} int format_zone */ -int format_rfc3339 (char *buffer, size_t buffer_size, struct tm const *t_tm, long nsec, _Bool print_nano, char const *zone) /* {{{ */ +int format_rfc3339(char *buffer, size_t buffer_size, struct tm const *t_tm, + long nsec, _Bool print_nano, char const *zone) /* {{{ */ { int len; char *pos = buffer; size_t size_left = buffer_size; - if ((len = strftime (pos, size_left, "%Y-%m-%dT%H:%M:%S", t_tm)) == 0) + if ((len = strftime(pos, size_left, "%Y-%m-%dT%H:%M:%S", t_tm)) == 0) return ENOMEM; pos += len; size_left -= len; if (print_nano) { - if ((len = ssnprintf (pos, size_left, ".%09ld", nsec)) == 0) + if ((len = ssnprintf(pos, size_left, ".%09ld", nsec)) == 0) return ENOMEM; pos += len; size_left -= len; } - sstrncpy (pos, zone, size_left); + sstrncpy(pos, zone, size_left); return 0; } /* }}} int format_rfc3339 */ -int format_rfc3339_utc (char *buffer, size_t buffer_size, cdtime_t t, _Bool print_nano) /* {{{ */ +int format_rfc3339_utc(char *buffer, size_t buffer_size, cdtime_t t, + _Bool print_nano) /* {{{ */ { struct tm t_tm; long nsec = 0; int status; - if ((status = get_utc_time (t, &t_tm, &nsec)) != 0) - return status; /* The error should have already be reported. */ + if ((status = get_utc_time(t, &t_tm, &nsec)) != 0) + return status; /* The error should have already be reported. */ - return format_rfc3339 (buffer, buffer_size, &t_tm, nsec, print_nano, zulu_zone); + return format_rfc3339(buffer, buffer_size, &t_tm, nsec, print_nano, + zulu_zone); } /* }}} int format_rfc3339_utc */ -int format_rfc3339_local (char *buffer, size_t buffer_size, cdtime_t t, _Bool print_nano) /* {{{ */ +int format_rfc3339_local(char *buffer, size_t buffer_size, cdtime_t t, + _Bool print_nano) /* {{{ */ { struct tm t_tm; long nsec = 0; int status; - char zone[7]; /* +00:00 */ + char zone[7]; /* +00:00 */ - if ((status = get_local_time (t, &t_tm, &nsec)) != 0) - return status; /* The error should have already be reported. */ + if ((status = get_local_time(t, &t_tm, &nsec)) != 0) + return status; /* The error should have already be reported. */ - if ((status = format_zone (zone, sizeof (zone), &t_tm)) != 0) + if ((status = format_zone(zone, sizeof(zone), &t_tm)) != 0) return status; - return format_rfc3339 (buffer, buffer_size, &t_tm, nsec, print_nano, zone); + return format_rfc3339(buffer, buffer_size, &t_tm, nsec, print_nano, zone); } /* }}} int format_rfc3339_local */ /********************************************************************** Public functions ***********************************************************************/ -int rfc3339 (char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */ +int rfc3339(char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */ { if (buffer_size < RFC3339_SIZE) return ENOMEM; - return format_rfc3339_utc (buffer, buffer_size, t, 0); + return format_rfc3339_utc(buffer, buffer_size, t, 0); } /* }}} int rfc3339 */ -int rfc3339nano (char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */ +int rfc3339nano(char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */ { if (buffer_size < RFC3339NANO_SIZE) return ENOMEM; - return format_rfc3339_utc (buffer, buffer_size, t, 1); + return format_rfc3339_utc(buffer, buffer_size, t, 1); } /* }}} int rfc3339nano */ -int rfc3339_local (char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */ +int rfc3339_local(char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */ { if (buffer_size < RFC3339_SIZE) return ENOMEM; - return format_rfc3339_local (buffer, buffer_size, t, 0); + return format_rfc3339_local(buffer, buffer_size, t, 0); } /* }}} int rfc3339 */ -int rfc3339nano_local (char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */ +int rfc3339nano_local(char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */ { if (buffer_size < RFC3339NANO_SIZE) return ENOMEM; - return format_rfc3339_local (buffer, buffer_size, t, 1); + return format_rfc3339_local(buffer, buffer_size, t, 1); } /* }}} int rfc3339nano */ /* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/daemon/utils_time_test.c b/src/daemon/utils_time_test.c index e9db187e..c1c60a20 100644 --- a/src/daemon/utils_time_test.c +++ b/src/daemon/utils_time_test.c @@ -31,8 +31,7 @@ #include "testing.h" #include "utils_time.h" -DEF_TEST(conversion) -{ +DEF_TEST(conversion) { struct { cdtime_t t; double d; @@ -41,79 +40,128 @@ DEF_TEST(conversion) struct timeval tv; struct timespec ts; } cases[] = { - /* cdtime double time_t milliseconds timeval timespec */ - { 0, 0.0 , 0, 0, { 0, 0}, { 0, 0}}, - { 10737418240ULL, 10.0 , 10, 10000, { 10, 0}, { 10, 0}}, - {1542908534771941376ULL, 1436945549.0 , 1436945549, 1436945549000ULL, {1436945549, 0}, {1436945549, 0}}, - {1542908535540740522ULL, 1436945549.716, 1436945550, 1436945549716ULL, {1436945549, 716000}, {1436945549, 716000000}}, - // 1426076671.123 * 2^30 = 1531238166015458148.352 - {1531238166015458148ULL, 1426076671.123, 1426076671, 1426076671123ULL, {1426076671, 123000}, {1426076671, 123000000}}, - // 1426076681.234 * 2^30 = 1531238176872061730.816 - {1531238176872061731ULL, 1426076681.234, 1426076681, 1426076681234ULL, {1426076681, 234000}, {1426076681, 234000000}}, - // 1426083986.314 * 2^30 = 1531246020641985396.736 - {1531246020641985397ULL, 1426083986.314, 1426083986, 1426083986314ULL, {1426083986, 314000}, {1426083986, 314000000}}, - // 1426083986.494142531 * 2^30 = 1531246020835411966.5 - {1531246020835411967ULL, 1426083986.494, 1426083986, 1426083986494ULL, {1426083986, 494143}, {1426083986, 494142531}}, - // 1426083986.987410814 * 2^30 = 1531246021365054752.4 - {1531246021365054752ULL, 1426083986.987, 1426083987, 1426083986987ULL, {1426083986, 987411}, {1426083986, 987410814}}, - - /* These cases test the cdtime_t -> ns conversion rounds correctly. */ - // 1546167635576736987 / 2^30 = 1439980823.1524536265... - {1546167635576736987ULL, 1439980823.152, 1439980823, 1439980823152ULL, {1439980823, 152454}, {1439980823, 152453627}}, - // 1546167831554815222 / 2^30 = 1439981005.6712620165... - {1546167831554815222ULL, 1439981005.671, 1439981006, 1439981005671ULL, {1439981005, 671262}, {1439981005, 671262017}}, - // 1546167986577716567 / 2^30 = 1439981150.0475896215... - {1546167986577716567ULL, 1439981150.048, 1439981150, 1439981150048ULL, {1439981150, 47590}, {1439981150, 47589622}}, + /* cdtime double time_t milliseconds + timeval timespec */ + {0, 0.0, 0, 0, {0, 0}, {0, 0}}, + {10737418240ULL, 10.0, 10, 10000, {10, 0}, {10, 0}}, + {1542908534771941376ULL, + 1436945549.0, + 1436945549, + 1436945549000ULL, + {1436945549, 0}, + {1436945549, 0}}, + {1542908535540740522ULL, + 1436945549.716, + 1436945550, + 1436945549716ULL, + {1436945549, 716000}, + {1436945549, 716000000}}, + // 1426076671.123 * 2^30 = 1531238166015458148.352 + {1531238166015458148ULL, + 1426076671.123, + 1426076671, + 1426076671123ULL, + {1426076671, 123000}, + {1426076671, 123000000}}, + // 1426076681.234 * 2^30 = 1531238176872061730.816 + {1531238176872061731ULL, + 1426076681.234, + 1426076681, + 1426076681234ULL, + {1426076681, 234000}, + {1426076681, 234000000}}, + // 1426083986.314 * 2^30 = 1531246020641985396.736 + {1531246020641985397ULL, + 1426083986.314, + 1426083986, + 1426083986314ULL, + {1426083986, 314000}, + {1426083986, 314000000}}, + // 1426083986.494142531 * 2^30 = 1531246020835411966.5 + {1531246020835411967ULL, + 1426083986.494, + 1426083986, + 1426083986494ULL, + {1426083986, 494143}, + {1426083986, 494142531}}, + // 1426083986.987410814 * 2^30 = 1531246021365054752.4 + {1531246021365054752ULL, + 1426083986.987, + 1426083987, + 1426083986987ULL, + {1426083986, 987411}, + {1426083986, 987410814}}, + + /* These cases test the cdtime_t -> ns conversion rounds correctly. */ + // 1546167635576736987 / 2^30 = 1439980823.1524536265... + {1546167635576736987ULL, + 1439980823.152, + 1439980823, + 1439980823152ULL, + {1439980823, 152454}, + {1439980823, 152453627}}, + // 1546167831554815222 / 2^30 = 1439981005.6712620165... + {1546167831554815222ULL, + 1439981005.671, + 1439981006, + 1439981005671ULL, + {1439981005, 671262}, + {1439981005, 671262017}}, + // 1546167986577716567 / 2^30 = 1439981150.0475896215... + {1546167986577716567ULL, + 1439981150.048, + 1439981150, + 1439981150048ULL, + {1439981150, 47590}, + {1439981150, 47589622}}, }; - for (size_t i = 0; i < (sizeof (cases) / sizeof (cases[0])); i++) { + for (size_t i = 0; i < (sizeof(cases) / sizeof(cases[0])); i++) { // cdtime -> s - EXPECT_EQ_UINT64 (cases[i].tt, CDTIME_T_TO_TIME_T (cases[i].t)); + EXPECT_EQ_UINT64(cases[i].tt, CDTIME_T_TO_TIME_T(cases[i].t)); // cdtime -> ms - EXPECT_EQ_UINT64(cases[i].ms, CDTIME_T_TO_MS (cases[i].t)); + EXPECT_EQ_UINT64(cases[i].ms, CDTIME_T_TO_MS(cases[i].t)); // cdtime -> us - struct timeval tv = CDTIME_T_TO_TIMEVAL (cases[i].t); - EXPECT_EQ_UINT64 (cases[i].tv.tv_sec, tv.tv_sec); - EXPECT_EQ_UINT64 (cases[i].tv.tv_usec, tv.tv_usec); + struct timeval tv = CDTIME_T_TO_TIMEVAL(cases[i].t); + EXPECT_EQ_UINT64(cases[i].tv.tv_sec, tv.tv_sec); + EXPECT_EQ_UINT64(cases[i].tv.tv_usec, tv.tv_usec); // cdtime -> ns - struct timespec ts = CDTIME_T_TO_TIMESPEC (cases[i].t); - EXPECT_EQ_UINT64 (cases[i].ts.tv_sec, ts.tv_sec); - EXPECT_EQ_UINT64 (cases[i].ts.tv_nsec, ts.tv_nsec); + struct timespec ts = CDTIME_T_TO_TIMESPEC(cases[i].t); + EXPECT_EQ_UINT64(cases[i].ts.tv_sec, ts.tv_sec); + EXPECT_EQ_UINT64(cases[i].ts.tv_nsec, ts.tv_nsec); // cdtime -> double - EXPECT_EQ_DOUBLE (cases[i].d, CDTIME_T_TO_DOUBLE (cases[i].t)); + EXPECT_EQ_DOUBLE(cases[i].d, CDTIME_T_TO_DOUBLE(cases[i].t)); } return 0; } /* These cases test the ns -> cdtime_t conversion rounds correctly. */ -DEF_TEST(ns_to_cdtime) -{ +DEF_TEST(ns_to_cdtime) { struct { uint64_t ns; cdtime_t want; } cases[] = { - // 1439981652801860766 * 2^30 / 10^9 = 1546168526406004689.4 - {1439981652801860766ULL, 1546168526406004689ULL}, - // 1439981836985281914 * 2^30 / 10^9 = 1546168724171447263.4 - {1439981836985281914ULL, 1546168724171447263ULL}, - // 1439981880053705608 * 2^30 / 10^9 = 1546168770415815077.4 - {1439981880053705608ULL, 1546168770415815077ULL}, + // 1439981652801860766 * 2^30 / 10^9 = 1546168526406004689.4 + {1439981652801860766ULL, 1546168526406004689ULL}, + // 1439981836985281914 * 2^30 / 10^9 = 1546168724171447263.4 + {1439981836985281914ULL, 1546168724171447263ULL}, + // 1439981880053705608 * 2^30 / 10^9 = 1546168770415815077.4 + {1439981880053705608ULL, 1546168770415815077ULL}, }; - for (size_t i = 0; i < (sizeof (cases) / sizeof (cases[0])); i++) { - EXPECT_EQ_UINT64 (cases[i].want, NS_TO_CDTIME_T (cases[i].ns)); + for (size_t i = 0; i < (sizeof(cases) / sizeof(cases[0])); i++) { + EXPECT_EQ_UINT64(cases[i].want, NS_TO_CDTIME_T(cases[i].ns)); } return 0; } -int main (void) -{ +int main(void) { RUN_TEST(conversion); RUN_TEST(ns_to_cdtime); diff --git a/src/dbi.c b/src/dbi.c index fefbf87b..7cab1d54 100644 --- a/src/dbi.c +++ b/src/dbi.c @@ -36,12 +36,12 @@ * functions "deprecated". These macros convert the new functions to their old * counterparts for backwards compatibility. */ #if !defined(LIBDBI_VERSION) || (LIBDBI_VERSION < 900) -# define HAVE_LEGACY_LIBDBI 1 -# define dbi_initialize_r(a,inst) dbi_initialize(a) -# define dbi_shutdown_r(inst) dbi_shutdown() -# define dbi_set_verbosity_r(a,inst) dbi_set_verbosity(a) -# define dbi_driver_list_r(a,inst) dbi_driver_list(a) -# define dbi_driver_open_r(a,inst) dbi_driver_open(a) +#define HAVE_LEGACY_LIBDBI 1 +#define dbi_initialize_r(a, inst) dbi_initialize(a) +#define dbi_shutdown_r(inst) dbi_shutdown() +#define dbi_set_verbosity_r(a, inst) dbi_set_verbosity(a) +#define dbi_driver_list_r(a, inst) dbi_driver_list(a) +#define dbi_driver_open_r(a, inst) dbi_driver_open(a) #endif /* @@ -50,8 +50,7 @@ struct cdbi_driver_option_s /* {{{ */ { char *key; - union - { + union { char *string; int numeric; } value; @@ -73,7 +72,7 @@ struct cdbi_database_s /* {{{ */ udb_query_preparation_area_t **q_prep_areas; udb_query_t **queries; - size_t queries_num; + size_t queries_num; dbi_conn connection; }; @@ -83,121 +82,111 @@ typedef struct cdbi_database_s cdbi_database_t; /* }}} */ * Global variables */ #if !defined(HAVE_LEGACY_LIBDBI) || !HAVE_LEGACY_LIBDBI -static dbi_inst dbi_instance = 0; +static dbi_inst dbi_instance = 0; #endif -static udb_query_t **queries = NULL; -static size_t queries_num = 0; -static cdbi_database_t **databases = NULL; -static size_t databases_num = 0; +static udb_query_t **queries = NULL; +static size_t queries_num = 0; +static cdbi_database_t **databases = NULL; +static size_t databases_num = 0; -static int cdbi_read_database (user_data_t *ud); +static int cdbi_read_database(user_data_t *ud); /* * Functions */ -static const char *cdbi_strerror (dbi_conn conn, /* {{{ */ - char *buffer, size_t buffer_size) -{ +static const char *cdbi_strerror(dbi_conn conn, /* {{{ */ + char *buffer, size_t buffer_size) { const char *msg; int status; - if (conn == NULL) - { - sstrncpy (buffer, "connection is NULL", buffer_size); + if (conn == NULL) { + sstrncpy(buffer, "connection is NULL", buffer_size); return (buffer); } msg = NULL; - status = dbi_conn_error (conn, &msg); + status = dbi_conn_error(conn, &msg); if ((status >= 0) && (msg != NULL)) - ssnprintf (buffer, buffer_size, "%s (status %i)", msg, status); + ssnprintf(buffer, buffer_size, "%s (status %i)", msg, status); else - ssnprintf (buffer, buffer_size, "dbi_conn_error failed with status %i", - status); + ssnprintf(buffer, buffer_size, "dbi_conn_error failed with status %i", + status); return (buffer); } /* }}} const char *cdbi_conn_error */ -static int cdbi_result_get_field (dbi_result res, /* {{{ */ - unsigned int index, char *buffer, size_t buffer_size) -{ +static int cdbi_result_get_field(dbi_result res, /* {{{ */ + unsigned int index, char *buffer, + size_t buffer_size) { unsigned short src_type; - src_type = dbi_result_get_field_type_idx (res, index); - if (src_type == DBI_TYPE_ERROR) - { - ERROR ("dbi plugin: cdbi_result_get: " - "dbi_result_get_field_type_idx failed."); + src_type = dbi_result_get_field_type_idx(res, index); + if (src_type == DBI_TYPE_ERROR) { + ERROR("dbi plugin: cdbi_result_get: " + "dbi_result_get_field_type_idx failed."); return (-1); } - if (src_type == DBI_TYPE_INTEGER) - { + if (src_type == DBI_TYPE_INTEGER) { long long value; - value = dbi_result_get_longlong_idx (res, index); - ssnprintf (buffer, buffer_size, "%lli", value); - } - else if (src_type == DBI_TYPE_DECIMAL) - { + value = dbi_result_get_longlong_idx(res, index); + ssnprintf(buffer, buffer_size, "%lli", value); + } else if (src_type == DBI_TYPE_DECIMAL) { double value; - value = dbi_result_get_double_idx (res, index); - ssnprintf (buffer, buffer_size, "%63.15g", value); - } - else if (src_type == DBI_TYPE_STRING) - { + value = dbi_result_get_double_idx(res, index); + ssnprintf(buffer, buffer_size, "%63.15g", value); + } else if (src_type == DBI_TYPE_STRING) { const char *value; - value = dbi_result_get_string_idx (res, index); + value = dbi_result_get_string_idx(res, index); if (value == NULL) - sstrncpy (buffer, "", buffer_size); - else if (strcmp ("ERROR", value) == 0) + sstrncpy(buffer, "", buffer_size); + else if (strcmp("ERROR", value) == 0) return (-1); else - sstrncpy (buffer, value, buffer_size); + sstrncpy(buffer, value, buffer_size); } /* DBI_TYPE_BINARY */ /* DBI_TYPE_DATETIME */ - else - { + else { const char *field_name; - field_name = dbi_result_get_field_name (res, index); + field_name = dbi_result_get_field_name(res, index); if (field_name == NULL) field_name = ""; - ERROR ("dbi plugin: Column `%s': Don't know how to handle " - "source type %hu.", - field_name, src_type); + ERROR("dbi plugin: Column `%s': Don't know how to handle " + "source type %hu.", + field_name, src_type); return (-1); } return (0); } /* }}} int cdbi_result_get_field */ -static void cdbi_database_free (cdbi_database_t *db) /* {{{ */ +static void cdbi_database_free(cdbi_database_t *db) /* {{{ */ { if (db == NULL) return; - sfree (db->name); - sfree (db->driver); + sfree(db->name); + sfree(db->driver); - for (size_t i = 0; i < db->driver_options_num; i++) - { - sfree (db->driver_options[i].key); + for (size_t i = 0; i < db->driver_options_num; i++) { + sfree(db->driver_options[i].key); if (!db->driver_options[i].is_numeric) - sfree (db->driver_options[i].value.string); + sfree(db->driver_options[i].value.string); } - sfree (db->driver_options); + sfree(db->driver_options); if (db->q_prep_areas) for (size_t i = 0; i < db->queries_num; ++i) - udb_query_delete_preparation_area (db->q_prep_areas[i]); - free (db->q_prep_areas); + udb_query_delete_preparation_area(db->q_prep_areas[i]); + free(db->q_prep_areas); - sfree (db); + sfree(db); } /* }}} void cdbi_database_free */ /* Configuration handling functions {{{ @@ -223,54 +212,45 @@ static void cdbi_database_free (cdbi_database_t *db) /* {{{ */ * */ -static int cdbi_config_add_database_driver_option (cdbi_database_t *db, /* {{{ */ - oconfig_item_t *ci) -{ +static int cdbi_config_add_database_driver_option(cdbi_database_t *db, /* {{{ */ + oconfig_item_t *ci) { cdbi_driver_option_t *option; - if ((ci->values_num != 2) - || (ci->values[0].type != OCONFIG_TYPE_STRING) - || ((ci->values[1].type != OCONFIG_TYPE_STRING) - && (ci->values[1].type != OCONFIG_TYPE_NUMBER))) - { - WARNING ("dbi plugin: The `DriverOption' config option " - "needs exactly two arguments."); + if ((ci->values_num != 2) || (ci->values[0].type != OCONFIG_TYPE_STRING) || + ((ci->values[1].type != OCONFIG_TYPE_STRING) && + (ci->values[1].type != OCONFIG_TYPE_NUMBER))) { + WARNING("dbi plugin: The `DriverOption' config option " + "needs exactly two arguments."); return (-1); } - option = realloc (db->driver_options, - sizeof (*option) * (db->driver_options_num + 1)); - if (option == NULL) - { - ERROR ("dbi plugin: realloc failed"); + option = realloc(db->driver_options, + sizeof(*option) * (db->driver_options_num + 1)); + if (option == NULL) { + ERROR("dbi plugin: realloc failed"); return (-1); } db->driver_options = option; option = db->driver_options + db->driver_options_num; - memset (option, 0, sizeof (*option)); + memset(option, 0, sizeof(*option)); - option->key = strdup (ci->values[0].value.string); - if (option->key == NULL) - { - ERROR ("dbi plugin: strdup failed."); + option->key = strdup(ci->values[0].value.string); + if (option->key == NULL) { + ERROR("dbi plugin: strdup failed."); return (-1); } - if (ci->values[1].type == OCONFIG_TYPE_STRING) - { - option->value.string = strdup (ci->values[1].value.string); - if (option->value.string == NULL) - { - ERROR ("dbi plugin: strdup failed."); - sfree (option->key); + if (ci->values[1].type == OCONFIG_TYPE_STRING) { + option->value.string = strdup(ci->values[1].value.string); + if (option->value.string == NULL) { + ERROR("dbi plugin: strdup failed."); + sfree(option->key); return (-1); } - } - else - { - assert (ci->values[1].type == OCONFIG_TYPE_NUMBER); - option->value.numeric = (int) (ci->values[1].value.number + .5); + } else { + assert(ci->values[1].type == OCONFIG_TYPE_NUMBER); + option->value.numeric = (int)(ci->values[1].value.number + .5); option->is_numeric = 1; } @@ -278,54 +258,48 @@ static int cdbi_config_add_database_driver_option (cdbi_database_t *db, /* {{{ * return (0); } /* }}} int cdbi_config_add_database_driver_option */ -static int cdbi_config_add_database (oconfig_item_t *ci) /* {{{ */ +static int cdbi_config_add_database(oconfig_item_t *ci) /* {{{ */ { cdbi_database_t *db; int status; - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("dbi plugin: The `Database' block " - "needs exactly one string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("dbi plugin: The `Database' block " + "needs exactly one string argument."); return (-1); } - db = calloc (1, sizeof (*db)); - if (db == NULL) - { - ERROR ("dbi plugin: calloc failed."); + db = calloc(1, sizeof(*db)); + if (db == NULL) { + ERROR("dbi plugin: calloc failed."); return (-1); } - status = cf_util_get_string (ci, &db->name); - if (status != 0) - { - sfree (db); + status = cf_util_get_string(ci, &db->name); + if (status != 0) { + sfree(db); return (status); } /* Fill the `cdbi_database_t' structure.. */ - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Driver", child->key) == 0) - status = cf_util_get_string (child, &db->driver); - else if (strcasecmp ("DriverOption", child->key) == 0) - status = cdbi_config_add_database_driver_option (db, child); - else if (strcasecmp ("SelectDB", child->key) == 0) - status = cf_util_get_string (child, &db->select_db); - else if (strcasecmp ("Query", child->key) == 0) - status = udb_query_pick_from_list (child, queries, queries_num, - &db->queries, &db->queries_num); - else if (strcasecmp ("Host", child->key) == 0) - status = cf_util_get_string (child, &db->host); - else if (strcasecmp ("Interval", child->key) == 0) + if (strcasecmp("Driver", child->key) == 0) + status = cf_util_get_string(child, &db->driver); + else if (strcasecmp("DriverOption", child->key) == 0) + status = cdbi_config_add_database_driver_option(db, child); + else if (strcasecmp("SelectDB", child->key) == 0) + status = cf_util_get_string(child, &db->select_db); + else if (strcasecmp("Query", child->key) == 0) + status = udb_query_pick_from_list(child, queries, queries_num, + &db->queries, &db->queries_num); + else if (strcasecmp("Host", child->key) == 0) + status = cf_util_get_string(child, &db->host); + else if (strcasecmp("Interval", child->key) == 0) status = cf_util_get_cdtime(child, &db->interval); - else - { - WARNING ("dbi plugin: Option `%s' not allowed here.", child->key); + else { + WARNING("dbi plugin: Option `%s' not allowed here.", child->key); status = -1; } @@ -334,40 +308,33 @@ static int cdbi_config_add_database (oconfig_item_t *ci) /* {{{ */ } /* Check that all necessary options have been given. */ - while (status == 0) - { - if (db->driver == NULL) - { - WARNING ("dbi plugin: `Driver' not given for database `%s'", db->name); + while (status == 0) { + if (db->driver == NULL) { + WARNING("dbi plugin: `Driver' not given for database `%s'", db->name); status = -1; } - if (db->driver_options_num == 0) - { - WARNING ("dbi plugin: No `DriverOption' given for database `%s'. " - "This will likely not work.", db->name); + if (db->driver_options_num == 0) { + WARNING("dbi plugin: No `DriverOption' given for database `%s'. " + "This will likely not work.", + db->name); } break; } /* while (status == 0) */ - while ((status == 0) && (db->queries_num > 0)) - { - db->q_prep_areas = calloc (db->queries_num, sizeof (*db->q_prep_areas)); - if (db->q_prep_areas == NULL) - { - WARNING ("dbi plugin: calloc failed"); + while ((status == 0) && (db->queries_num > 0)) { + db->q_prep_areas = calloc(db->queries_num, sizeof(*db->q_prep_areas)); + if (db->q_prep_areas == NULL) { + WARNING("dbi plugin: calloc failed"); status = -1; break; } - for (size_t i = 0; i < db->queries_num; ++i) - { - db->q_prep_areas[i] - = udb_query_allocate_preparation_area (db->queries[i]); + for (size_t i = 0; i < db->queries_num; ++i) { + db->q_prep_areas[i] = udb_query_allocate_preparation_area(db->queries[i]); - if (db->q_prep_areas[i] == NULL) - { - WARNING ("dbi plugin: udb_query_allocate_preparation_area failed"); + if (db->q_prep_areas[i] == NULL) { + WARNING("dbi plugin: udb_query_allocate_preparation_area failed"); status = -1; break; } @@ -377,57 +344,50 @@ static int cdbi_config_add_database (oconfig_item_t *ci) /* {{{ */ } /* If all went well, add this database to the global list of databases. */ - if (status == 0) - { + if (status == 0) { cdbi_database_t **temp; - temp = realloc (databases, - sizeof (*databases) * (databases_num + 1)); - if (temp == NULL) - { - ERROR ("dbi plugin: realloc failed"); + temp = realloc(databases, sizeof(*databases) * (databases_num + 1)); + if (temp == NULL) { + ERROR("dbi plugin: realloc failed"); status = -1; - } - else - { + } else { databases = temp; databases[databases_num] = db; databases_num++; char *name = ssnprintf_alloc("dbi:%s", db->name); - plugin_register_complex_read (/* group = */ NULL, + plugin_register_complex_read( + /* group = */ NULL, /* name = */ name ? name : db->name, /* callback = */ cdbi_read_database, /* interval = */ (db->interval > 0) ? db->interval : 0, - &(user_data_t) { - .data = db, - }); - sfree (name); + &(user_data_t){ + .data = db, + }); + sfree(name); } } - if (status != 0) - { - cdbi_database_free (db); + if (status != 0) { + cdbi_database_free(db); return (-1); } return (0); } /* }}} int cdbi_config_add_database */ -static int cdbi_config (oconfig_item_t *ci) /* {{{ */ +static int cdbi_config(oconfig_item_t *ci) /* {{{ */ { - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Query", child->key) == 0) - udb_query_create (&queries, &queries_num, child, - /* callback = */ NULL); - else if (strcasecmp ("Database", child->key) == 0) - cdbi_config_add_database (child); - else - { - WARNING ("dbi plugin: Ignoring unknown config option `%s'.", child->key); + if (strcasecmp("Query", child->key) == 0) + udb_query_create(&queries, &queries_num, child, + /* callback = */ NULL); + else if (strcasecmp("Database", child->key) == 0) + cdbi_config_add_database(child); + else { + WARNING("dbi plugin: Ignoring unknown config option `%s'.", child->key); } } /* for (ci->children) */ @@ -436,7 +396,7 @@ static int cdbi_config (oconfig_item_t *ci) /* {{{ */ /* }}} End of configuration handling functions */ -static int cdbi_init (void) /* {{{ */ +static int cdbi_init(void) /* {{{ */ { static int did_init = 0; int status; @@ -444,42 +404,37 @@ static int cdbi_init (void) /* {{{ */ if (did_init != 0) return (0); - if (queries_num == 0) - { - ERROR ("dbi plugin: No blocks have been found. Without them, " - "this plugin can't do anything useful, so we will return an error."); + if (queries_num == 0) { + ERROR("dbi plugin: No blocks have been found. Without them, " + "this plugin can't do anything useful, so we will return an error."); return (-1); } - if (databases_num == 0) - { - ERROR ("dbi plugin: No blocks have been found. Without them, " - "this plugin can't do anything useful, so we will return an error."); + if (databases_num == 0) { + ERROR("dbi plugin: No blocks have been found. Without them, " + "this plugin can't do anything useful, so we will return an error."); return (-1); } - status = dbi_initialize_r (/* driverdir = */ NULL, &dbi_instance); - if (status < 0) - { - ERROR ("dbi plugin: cdbi_init: dbi_initialize_r failed with status %i.", - status); + status = dbi_initialize_r(/* driverdir = */ NULL, &dbi_instance); + if (status < 0) { + ERROR("dbi plugin: cdbi_init: dbi_initialize_r failed with status %i.", + status); return (-1); - } - else if (status == 0) - { - ERROR ("dbi plugin: `dbi_initialize_r' could not load any drivers. Please " - "install at least one `DBD' or check your installation."); + } else if (status == 0) { + ERROR("dbi plugin: `dbi_initialize_r' could not load any drivers. Please " + "install at least one `DBD' or check your installation."); return (-1); } - DEBUG ("dbi plugin: cdbi_init: dbi_initialize_r reports %i driver%s.", - status, (status == 1) ? "" : "s"); + DEBUG("dbi plugin: cdbi_init: dbi_initialize_r reports %i driver%s.", status, + (status == 1) ? "" : "s"); return (0); } /* }}} int cdbi_init */ -static int cdbi_read_database_query (cdbi_database_t *db, /* {{{ */ - udb_query_t *q, udb_query_preparation_area_t *prep_area) -{ +static int cdbi_read_database_query(cdbi_database_t *db, /* {{{ */ + udb_query_t *q, + udb_query_preparation_area_t *prep_area) { const char *statement; dbi_result res; size_t column_num; @@ -487,79 +442,81 @@ static int cdbi_read_database_query (cdbi_database_t *db, /* {{{ */ char **column_values; int status; - /* Macro that cleans up dynamically allocated memory and returns the - * specified status. */ -#define BAIL_OUT(status) \ - if (column_names != NULL) { sfree (column_names[0]); sfree (column_names); } \ - if (column_values != NULL) { sfree (column_values[0]); sfree (column_values); } \ - if (res != NULL) { dbi_result_free (res); res = NULL; } \ +/* Macro that cleans up dynamically allocated memory and returns the + * specified status. */ +#define BAIL_OUT(status) \ + if (column_names != NULL) { \ + sfree(column_names[0]); \ + sfree(column_names); \ + } \ + if (column_values != NULL) { \ + sfree(column_values[0]); \ + sfree(column_values); \ + } \ + if (res != NULL) { \ + dbi_result_free(res); \ + res = NULL; \ + } \ return (status) column_names = NULL; column_values = NULL; - statement = udb_query_get_statement (q); - assert (statement != NULL); + statement = udb_query_get_statement(q); + assert(statement != NULL); - res = dbi_conn_query (db->connection, statement); - if (res == NULL) - { + res = dbi_conn_query(db->connection, statement); + if (res == NULL) { char errbuf[1024]; - ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): " - "dbi_conn_query failed: %s", - db->name, udb_query_get_name (q), - cdbi_strerror (db->connection, errbuf, sizeof (errbuf))); - BAIL_OUT (-1); - } - else /* Get the number of columns */ + ERROR("dbi plugin: cdbi_read_database_query (%s, %s): " + "dbi_conn_query failed: %s", + db->name, udb_query_get_name(q), + cdbi_strerror(db->connection, errbuf, sizeof(errbuf))); + BAIL_OUT(-1); + } else /* Get the number of columns */ { unsigned int db_status; - db_status = dbi_result_get_numfields (res); - if (db_status == DBI_FIELD_ERROR) - { + db_status = dbi_result_get_numfields(res); + if (db_status == DBI_FIELD_ERROR) { char errbuf[1024]; - ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): " - "dbi_result_get_numfields failed: %s", - db->name, udb_query_get_name (q), - cdbi_strerror (db->connection, errbuf, sizeof (errbuf))); - BAIL_OUT (-1); + ERROR("dbi plugin: cdbi_read_database_query (%s, %s): " + "dbi_result_get_numfields failed: %s", + db->name, udb_query_get_name(q), + cdbi_strerror(db->connection, errbuf, sizeof(errbuf))); + BAIL_OUT(-1); } - column_num = (size_t) db_status; - DEBUG ("cdbi_read_database_query (%s, %s): There are %zu columns.", - db->name, udb_query_get_name (q), column_num); + column_num = (size_t)db_status; + DEBUG("cdbi_read_database_query (%s, %s): There are %zu columns.", db->name, + udb_query_get_name(q), column_num); } /* Allocate `column_names' and `column_values'. {{{ */ - column_names = calloc (column_num, sizeof (*column_names)); - if (column_names == NULL) - { - ERROR ("dbi plugin: calloc failed."); - BAIL_OUT (-1); + column_names = calloc(column_num, sizeof(*column_names)); + if (column_names == NULL) { + ERROR("dbi plugin: calloc failed."); + BAIL_OUT(-1); } - column_names[0] = calloc (column_num, DATA_MAX_NAME_LEN); - if (column_names[0] == NULL) - { - ERROR ("dbi plugin: calloc failed."); - BAIL_OUT (-1); + column_names[0] = calloc(column_num, DATA_MAX_NAME_LEN); + if (column_names[0] == NULL) { + ERROR("dbi plugin: calloc failed."); + BAIL_OUT(-1); } for (size_t i = 1; i < column_num; i++) column_names[i] = column_names[i - 1] + DATA_MAX_NAME_LEN; - column_values = calloc (column_num, sizeof (*column_values)); - if (column_values == NULL) - { - ERROR ("dbi plugin: calloc failed."); - BAIL_OUT (-1); + column_values = calloc(column_num, sizeof(*column_values)); + if (column_values == NULL) { + ERROR("dbi plugin: calloc failed."); + BAIL_OUT(-1); } - column_values[0] = calloc (column_num, DATA_MAX_NAME_LEN); - if (column_values[0] == NULL) - { - ERROR ("dbi plugin: calloc failed."); - BAIL_OUT (-1); + column_values[0] = calloc(column_num, DATA_MAX_NAME_LEN); + if (column_values[0] == NULL) { + ERROR("dbi plugin: calloc failed."); + BAIL_OUT(-1); } for (size_t i = 1; i < column_num; i++) column_values[i] = column_values[i - 1] + DATA_MAX_NAME_LEN; @@ -570,34 +527,33 @@ static int cdbi_read_database_query (cdbi_database_t *db, /* {{{ */ { const char *column_name; - column_name = dbi_result_get_field_name (res, (unsigned int) (i + 1)); - if (column_name == NULL) - { - ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): " - "Cannot retrieve name of field %zu.", - db->name, udb_query_get_name (q), i + 1); - BAIL_OUT (-1); + column_name = dbi_result_get_field_name(res, (unsigned int)(i + 1)); + if (column_name == NULL) { + ERROR("dbi plugin: cdbi_read_database_query (%s, %s): " + "Cannot retrieve name of field %zu.", + db->name, udb_query_get_name(q), i + 1); + BAIL_OUT(-1); } - sstrncpy (column_names[i], column_name, DATA_MAX_NAME_LEN); + sstrncpy(column_names[i], column_name, DATA_MAX_NAME_LEN); } /* }}} for (i = 0; i < column_num; i++) */ - udb_query_prepare_result (q, prep_area, (db->host ? db->host : hostname_g), - /* plugin = */ "dbi", db->name, - column_names, column_num, /* interval = */ (db->interval > 0) ? db->interval : 0); + udb_query_prepare_result( + q, prep_area, (db->host ? db->host : hostname_g), + /* plugin = */ "dbi", db->name, column_names, column_num, + /* interval = */ (db->interval > 0) ? db->interval : 0); /* 0 = error; 1 = success; */ - status = dbi_result_first_row (res); /* {{{ */ - if (status != 1) - { + status = dbi_result_first_row(res); /* {{{ */ + if (status != 1) { char errbuf[1024]; - ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): " - "dbi_result_first_row failed: %s. Maybe the statement didn't " - "return any rows?", - db->name, udb_query_get_name (q), - cdbi_strerror (db->connection, errbuf, sizeof (errbuf))); - udb_query_finish_result (q, prep_area); - BAIL_OUT (-1); + ERROR("dbi plugin: cdbi_read_database_query (%s, %s): " + "dbi_result_first_row failed: %s. Maybe the statement didn't " + "return any rows?", + db->name, udb_query_get_name(q), + cdbi_strerror(db->connection, errbuf, sizeof(errbuf))); + udb_query_finish_result(q, prep_area); + BAIL_OUT(-1); } /* }}} */ /* Iterate over all rows and call `udb_query_handle_result' with each list of @@ -608,14 +564,13 @@ static int cdbi_read_database_query (cdbi_database_t *db, /* {{{ */ /* Copy the value of the columns to `column_values' */ for (size_t i = 0; i < column_num; i++) /* {{{ */ { - status = cdbi_result_get_field (res, (unsigned int) (i + 1), - column_values[i], DATA_MAX_NAME_LEN); - - if (status != 0) - { - ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): " - "cdbi_result_get_field (%zu) failed.", - db->name, udb_query_get_name (q), i + 1); + status = cdbi_result_get_field(res, (unsigned int)(i + 1), + column_values[i], DATA_MAX_NAME_LEN); + + if (status != 0) { + ERROR("dbi plugin: cdbi_read_database_query (%s, %s): " + "cdbi_result_get_field (%zu) failed.", + db->name, udb_query_get_name(q), i + 1); status = -1; break; } @@ -625,76 +580,68 @@ static int cdbi_read_database_query (cdbi_database_t *db, /* {{{ */ * to dispatch the row to the daemon. */ if (status == 0) /* {{{ */ { - status = udb_query_handle_result (q, prep_area, column_values); - if (status != 0) - { - ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): " - "udb_query_handle_result failed.", - db->name, udb_query_get_name (q)); + status = udb_query_handle_result(q, prep_area, column_values); + if (status != 0) { + ERROR("dbi plugin: cdbi_read_database_query (%s, %s): " + "udb_query_handle_result failed.", + db->name, udb_query_get_name(q)); } } /* }}} */ /* Get the next row from the database. */ - status = dbi_result_next_row (res); /* {{{ */ - if (status != 1) - { - if (dbi_conn_error (db->connection, NULL) != 0) - { + status = dbi_result_next_row(res); /* {{{ */ + if (status != 1) { + if (dbi_conn_error(db->connection, NULL) != 0) { char errbuf[1024]; - WARNING ("dbi plugin: cdbi_read_database_query (%s, %s): " - "dbi_result_next_row failed: %s.", - db->name, udb_query_get_name (q), - cdbi_strerror (db->connection, errbuf, sizeof (errbuf))); + WARNING("dbi plugin: cdbi_read_database_query (%s, %s): " + "dbi_result_next_row failed: %s.", + db->name, udb_query_get_name(q), + cdbi_strerror(db->connection, errbuf, sizeof(errbuf))); } break; } /* }}} */ - } /* }}} while (42) */ + } /* }}} while (42) */ /* Tell the db query interface that we're done with this query. */ - udb_query_finish_result (q, prep_area); + udb_query_finish_result(q, prep_area); /* Clean up and return `status = 0' (success) */ - BAIL_OUT (0); + BAIL_OUT(0); #undef BAIL_OUT } /* }}} int cdbi_read_database_query */ -static int cdbi_connect_database (cdbi_database_t *db) /* {{{ */ +static int cdbi_connect_database(cdbi_database_t *db) /* {{{ */ { dbi_driver driver; dbi_conn connection; int status; - if (db->connection != NULL) - { - status = dbi_conn_ping (db->connection); + if (db->connection != NULL) { + status = dbi_conn_ping(db->connection); if (status != 0) /* connection is alive */ return (0); - dbi_conn_close (db->connection); + dbi_conn_close(db->connection); db->connection = NULL; } - driver = dbi_driver_open_r (db->driver, dbi_instance); - if (driver == NULL) - { - ERROR ("dbi plugin: cdbi_connect_database: dbi_driver_open_r (%s) failed.", - db->driver); - INFO ("dbi plugin: Maybe the driver isn't installed? " - "Known drivers are:"); - for (driver = dbi_driver_list_r (NULL, dbi_instance); - driver != NULL; - driver = dbi_driver_list_r (driver, dbi_instance)) - { - INFO ("dbi plugin: * %s", dbi_driver_get_name (driver)); + driver = dbi_driver_open_r(db->driver, dbi_instance); + if (driver == NULL) { + ERROR("dbi plugin: cdbi_connect_database: dbi_driver_open_r (%s) failed.", + db->driver); + INFO("dbi plugin: Maybe the driver isn't installed? " + "Known drivers are:"); + for (driver = dbi_driver_list_r(NULL, dbi_instance); driver != NULL; + driver = dbi_driver_list_r(driver, dbi_instance)) { + INFO("dbi plugin: * %s", dbi_driver_get_name(driver)); } return (-1); } - connection = dbi_conn_open (driver); - if (connection == NULL) - { - ERROR ("dbi plugin: cdbi_connect_database: dbi_conn_open (%s) failed.", - db->driver); + connection = dbi_conn_open(driver); + if (connection == NULL) { + ERROR("dbi plugin: cdbi_connect_database: dbi_conn_open (%s) failed.", + db->driver); return (-1); } @@ -703,75 +650,66 @@ static int cdbi_connect_database (cdbi_database_t *db) /* {{{ */ * encountered, it will get a list of options understood by the driver and * report that as `INFO'. This way, users hopefully don't have too much * trouble finding out how to configure the plugin correctly.. */ - for (size_t i = 0; i < db->driver_options_num; i++) - { - if (db->driver_options[i].is_numeric) - { - status = dbi_conn_set_option_numeric (connection, - db->driver_options[i].key, db->driver_options[i].value.numeric); - if (status != 0) - { + for (size_t i = 0; i < db->driver_options_num; i++) { + if (db->driver_options[i].is_numeric) { + status = + dbi_conn_set_option_numeric(connection, db->driver_options[i].key, + db->driver_options[i].value.numeric); + if (status != 0) { char errbuf[1024]; - ERROR ("dbi plugin: cdbi_connect_database (%s): " - "dbi_conn_set_option_numeric (\"%s\", %i) failed: %s.", - db->name, - db->driver_options[i].key, db->driver_options[i].value.numeric, - cdbi_strerror (connection, errbuf, sizeof (errbuf))); + ERROR("dbi plugin: cdbi_connect_database (%s): " + "dbi_conn_set_option_numeric (\"%s\", %i) failed: %s.", + db->name, db->driver_options[i].key, + db->driver_options[i].value.numeric, + cdbi_strerror(connection, errbuf, sizeof(errbuf))); } - } - else - { - status = dbi_conn_set_option (connection, - db->driver_options[i].key, db->driver_options[i].value.string); - if (status != 0) - { + } else { + status = dbi_conn_set_option(connection, db->driver_options[i].key, + db->driver_options[i].value.string); + if (status != 0) { char errbuf[1024]; - ERROR ("dbi plugin: cdbi_connect_database (%s): " - "dbi_conn_set_option (\"%s\", \"%s\") failed: %s.", - db->name, - db->driver_options[i].key, db->driver_options[i].value.string, - cdbi_strerror (connection, errbuf, sizeof (errbuf))); + ERROR("dbi plugin: cdbi_connect_database (%s): " + "dbi_conn_set_option (\"%s\", \"%s\") failed: %s.", + db->name, db->driver_options[i].key, + db->driver_options[i].value.string, + cdbi_strerror(connection, errbuf, sizeof(errbuf))); } } - if (status != 0) - { - INFO ("dbi plugin: This is a list of all options understood " - "by the `%s' driver:", db->driver); - for (const char *opt = dbi_conn_get_option_list (connection, NULL); - opt != NULL; - opt = dbi_conn_get_option_list (connection, opt)) - { - INFO ("dbi plugin: * %s", opt); + if (status != 0) { + INFO("dbi plugin: This is a list of all options understood " + "by the `%s' driver:", + db->driver); + for (const char *opt = dbi_conn_get_option_list(connection, NULL); + opt != NULL; opt = dbi_conn_get_option_list(connection, opt)) { + INFO("dbi plugin: * %s", opt); } - dbi_conn_close (connection); + dbi_conn_close(connection); return (-1); } } /* for (i = 0; i < db->driver_options_num; i++) */ - status = dbi_conn_connect (connection); - if (status != 0) - { + status = dbi_conn_connect(connection); + if (status != 0) { char errbuf[1024]; - ERROR ("dbi plugin: cdbi_connect_database (%s): " - "dbi_conn_connect failed: %s", - db->name, cdbi_strerror (connection, errbuf, sizeof (errbuf))); - dbi_conn_close (connection); + ERROR("dbi plugin: cdbi_connect_database (%s): " + "dbi_conn_connect failed: %s", + db->name, cdbi_strerror(connection, errbuf, sizeof(errbuf))); + dbi_conn_close(connection); return (-1); } - if (db->select_db != NULL) - { - status = dbi_conn_select_db (connection, db->select_db); - if (status != 0) - { + if (db->select_db != NULL) { + status = dbi_conn_select_db(connection, db->select_db); + if (status != 0) { char errbuf[1024]; - WARNING ("dbi plugin: cdbi_connect_database (%s): " + WARNING( + "dbi plugin: cdbi_connect_database (%s): " "dbi_conn_select_db (%s) failed: %s. Check the `SelectDB' option.", db->name, db->select_db, - cdbi_strerror (connection, errbuf, sizeof (errbuf))); - dbi_conn_close (connection); + cdbi_strerror(connection, errbuf, sizeof(errbuf))); + dbi_conn_close(connection); return (-1); } } @@ -780,72 +718,67 @@ static int cdbi_connect_database (cdbi_database_t *db) /* {{{ */ return (0); } /* }}} int cdbi_connect_database */ -static int cdbi_read_database (user_data_t *ud) /* {{{ */ +static int cdbi_read_database(user_data_t *ud) /* {{{ */ { - cdbi_database_t *db = (cdbi_database_t *) ud->data; + cdbi_database_t *db = (cdbi_database_t *)ud->data; int success; int status; unsigned int db_version; - status = cdbi_connect_database (db); + status = cdbi_connect_database(db); if (status != 0) return (status); - assert (db->connection != NULL); + assert(db->connection != NULL); - db_version = dbi_conn_get_engine_version (db->connection); + db_version = dbi_conn_get_engine_version(db->connection); /* TODO: Complain if `db_version == 0' */ success = 0; - for (size_t i = 0; i < db->queries_num; i++) - { + for (size_t i = 0; i < db->queries_num; i++) { /* Check if we know the database's version and if so, if this query applies * to that version. */ - if ((db_version != 0) - && (udb_query_check_version (db->queries[i], db_version) == 0)) + if ((db_version != 0) && + (udb_query_check_version(db->queries[i], db_version) == 0)) continue; - status = cdbi_read_database_query (db, - db->queries[i], db->q_prep_areas[i]); + status = cdbi_read_database_query(db, db->queries[i], db->q_prep_areas[i]); if (status == 0) success++; } - if (success == 0) - { - ERROR ("dbi plugin: All queries failed for database `%s'.", db->name); + if (success == 0) { + ERROR("dbi plugin: All queries failed for database `%s'.", db->name); return (-1); } return (0); } /* }}} int cdbi_read_database */ -static int cdbi_shutdown (void) /* {{{ */ +static int cdbi_shutdown(void) /* {{{ */ { - for (size_t i = 0; i < databases_num; i++) - { - if (databases[i]->connection != NULL) - { - dbi_conn_close (databases[i]->connection); + for (size_t i = 0; i < databases_num; i++) { + if (databases[i]->connection != NULL) { + dbi_conn_close(databases[i]->connection); databases[i]->connection = NULL; } - cdbi_database_free (databases[i]); + cdbi_database_free(databases[i]); } - sfree (databases); + sfree(databases); databases_num = 0; - udb_query_free (queries, queries_num); + udb_query_free(queries, queries_num); queries = NULL; queries_num = 0; return (0); } /* }}} int cdbi_shutdown */ -void module_register (void) /* {{{ */ +void module_register(void) /* {{{ */ { - plugin_register_complex_config ("dbi", cdbi_config); - plugin_register_init ("dbi", cdbi_init); - plugin_register_shutdown ("dbi", cdbi_shutdown); + plugin_register_complex_config("dbi", cdbi_config); + plugin_register_init("dbi", cdbi_init); + plugin_register_shutdown("dbi", cdbi_shutdown); } /* }}} void module_register */ /* diff --git a/src/df.c b/src/df.c index d9ffa8b1..54166052 100644 --- a/src/df.c +++ b/src/df.c @@ -25,39 +25,31 @@ #include "common.h" #include "plugin.h" -#include "utils_mount.h" #include "utils_ignorelist.h" +#include "utils_mount.h" #if HAVE_STATVFS -# if HAVE_SYS_STATVFS_H -# include -# endif -# define STATANYFS statvfs -# define STATANYFS_STR "statvfs" -# define BLOCKSIZE(s) ((s).f_frsize ? (s).f_frsize : (s).f_bsize) +#if HAVE_SYS_STATVFS_H +#include +#endif +#define STATANYFS statvfs +#define STATANYFS_STR "statvfs" +#define BLOCKSIZE(s) ((s).f_frsize ? (s).f_frsize : (s).f_bsize) #elif HAVE_STATFS -# if HAVE_SYS_STATFS_H -# include -# endif -# define STATANYFS statfs -# define STATANYFS_STR "statfs" -# define BLOCKSIZE(s) (s).f_bsize +#if HAVE_SYS_STATFS_H +#include +#endif +#define STATANYFS statfs +#define STATANYFS_STR "statfs" +#define BLOCKSIZE(s) (s).f_bsize #else -# error "No applicable input method." +#error "No applicable input method." #endif -static const char *config_keys[] = -{ - "Device", - "MountPoint", - "FSType", - "IgnoreSelected", - "ReportByDevice", - "ReportInodes", - "ValuesAbsolute", - "ValuesPercentage" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = { + "Device", "MountPoint", "FSType", "IgnoreSelected", + "ReportByDevice", "ReportInodes", "ValuesAbsolute", "ValuesPercentage"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static ignorelist_t *il_device = NULL; static ignorelist_t *il_mountpoint = NULL; @@ -68,324 +60,280 @@ static _Bool report_inodes = 0; static _Bool values_absolute = 1; static _Bool values_percentage = 0; -static int df_init (void) -{ - if (il_device == NULL) - il_device = ignorelist_create (1); - if (il_mountpoint == NULL) - il_mountpoint = ignorelist_create (1); - if (il_fstype == NULL) - il_fstype = ignorelist_create (1); +static int df_init(void) { + if (il_device == NULL) + il_device = ignorelist_create(1); + if (il_mountpoint == NULL) + il_mountpoint = ignorelist_create(1); + if (il_fstype == NULL) + il_fstype = ignorelist_create(1); - return (0); + return (0); } -static int df_config (const char *key, const char *value) -{ - df_init (); - - if (strcasecmp (key, "Device") == 0) - { - if (ignorelist_add (il_device, value)) - return (1); - return (0); - } - else if (strcasecmp (key, "MountPoint") == 0) - { - if (ignorelist_add (il_mountpoint, value)) - return (1); - return (0); - } - else if (strcasecmp (key, "FSType") == 0) - { - if (ignorelist_add (il_fstype, value)) - return (1); - return (0); - } - else if (strcasecmp (key, "IgnoreSelected") == 0) - { - if (IS_TRUE (value)) - { - ignorelist_set_invert (il_device, 0); - ignorelist_set_invert (il_mountpoint, 0); - ignorelist_set_invert (il_fstype, 0); - } - else - { - ignorelist_set_invert (il_device, 1); - ignorelist_set_invert (il_mountpoint, 1); - ignorelist_set_invert (il_fstype, 1); - } - return (0); - } - else if (strcasecmp (key, "ReportByDevice") == 0) - { - if (IS_TRUE (value)) - by_device = 1; - - return (0); - } - else if (strcasecmp (key, "ReportInodes") == 0) - { - if (IS_TRUE (value)) - report_inodes = 1; - else - report_inodes = 0; - - return (0); - } - else if (strcasecmp (key, "ValuesAbsolute") == 0) - { - if (IS_TRUE (value)) - values_absolute = 1; - else - values_absolute = 0; - - return (0); - } - else if (strcasecmp (key, "ValuesPercentage") == 0) - { - if (IS_TRUE (value)) - values_percentage = 1; - else - values_percentage = 0; - - return (0); - } - - return (-1); +static int df_config(const char *key, const char *value) { + df_init(); + + if (strcasecmp(key, "Device") == 0) { + if (ignorelist_add(il_device, value)) + return (1); + return (0); + } else if (strcasecmp(key, "MountPoint") == 0) { + if (ignorelist_add(il_mountpoint, value)) + return (1); + return (0); + } else if (strcasecmp(key, "FSType") == 0) { + if (ignorelist_add(il_fstype, value)) + return (1); + return (0); + } else if (strcasecmp(key, "IgnoreSelected") == 0) { + if (IS_TRUE(value)) { + ignorelist_set_invert(il_device, 0); + ignorelist_set_invert(il_mountpoint, 0); + ignorelist_set_invert(il_fstype, 0); + } else { + ignorelist_set_invert(il_device, 1); + ignorelist_set_invert(il_mountpoint, 1); + ignorelist_set_invert(il_fstype, 1); + } + return (0); + } else if (strcasecmp(key, "ReportByDevice") == 0) { + if (IS_TRUE(value)) + by_device = 1; + + return (0); + } else if (strcasecmp(key, "ReportInodes") == 0) { + if (IS_TRUE(value)) + report_inodes = 1; + else + report_inodes = 0; + + return (0); + } else if (strcasecmp(key, "ValuesAbsolute") == 0) { + if (IS_TRUE(value)) + values_absolute = 1; + else + values_absolute = 0; + + return (0); + } else if (strcasecmp(key, "ValuesPercentage") == 0) { + if (IS_TRUE(value)) + values_percentage = 1; + else + values_percentage = 0; + + return (0); + } + + return (-1); } -__attribute__ ((nonnull(2))) -static void df_submit_one (char *plugin_instance, - const char *type, const char *type_instance, - gauge_t value) -{ - value_list_t vl = VALUE_LIST_INIT; - - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "df", sizeof (vl.plugin)); - if (plugin_instance != NULL) - sstrncpy (vl.plugin_instance, plugin_instance, - sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, - sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); +__attribute__((nonnull(2))) static void df_submit_one(char *plugin_instance, + const char *type, + const char *type_instance, + gauge_t value) { + value_list_t vl = VALUE_LIST_INIT; + + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "df", sizeof(vl.plugin)); + if (plugin_instance != NULL) + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + if (type_instance != NULL) + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); } /* void df_submit_one */ -static int df_read (void) -{ +static int df_read(void) { #if HAVE_STATVFS - struct statvfs statbuf; + struct statvfs statbuf; #elif HAVE_STATFS - struct statfs statbuf; + struct statfs statbuf; #endif - /* struct STATANYFS statbuf; */ - cu_mount_t *mnt_list; - - mnt_list = NULL; - if (cu_mount_getlist (&mnt_list) == NULL) - { - ERROR ("df plugin: cu_mount_getlist failed."); - return (-1); - } - - for (cu_mount_t *mnt_ptr = mnt_list; mnt_ptr != NULL; mnt_ptr = mnt_ptr->next) - { - unsigned long long blocksize; - char disk_name[256]; - cu_mount_t *dup_ptr; - uint64_t blk_free; - uint64_t blk_reserved; - uint64_t blk_used; - - char const *dev = (mnt_ptr->spec_device != NULL) - ? mnt_ptr->spec_device - : mnt_ptr->device; - - if (ignorelist_match (il_device, dev)) - continue; - if (ignorelist_match (il_mountpoint, mnt_ptr->dir)) - continue; - if (ignorelist_match (il_fstype, mnt_ptr->type)) - continue; - - /* search for duplicates *in front of* the current mnt_ptr. */ - for (dup_ptr = mnt_list; dup_ptr != NULL; dup_ptr = dup_ptr->next) - { - /* No duplicate found: mnt_ptr is the first of its kind. */ - if (dup_ptr == mnt_ptr) - { - dup_ptr = NULL; - break; - } - - /* Duplicate found: leave non-NULL dup_ptr. */ - if (by_device - && (mnt_ptr->spec_device != NULL) - && (dup_ptr->spec_device != NULL) - && (strcmp (mnt_ptr->spec_device, dup_ptr->spec_device) == 0)) - break; - else if (!by_device && (strcmp (mnt_ptr->dir, dup_ptr->dir) == 0)) - break; - } - - /* ignore duplicates */ - if (dup_ptr != NULL) - continue; - - if (STATANYFS (mnt_ptr->dir, &statbuf) < 0) - { - char errbuf[1024]; - ERROR (STATANYFS_STR"(%s) failed: %s", - mnt_ptr->dir, - sstrerror (errno, errbuf, - sizeof (errbuf))); - continue; - } - - if (!statbuf.f_blocks) - continue; - - if (by_device) - { - /* eg, /dev/hda1 -- strip off the "/dev/" */ - if (strncmp (dev, "/dev/", strlen ("/dev/")) == 0) - sstrncpy (disk_name, dev + strlen ("/dev/"), sizeof (disk_name)); - else - sstrncpy (disk_name, dev, sizeof (disk_name)); - - if (strlen(disk_name) < 1) - { - DEBUG("df: no device name for mountpoint %s, skipping", mnt_ptr->dir); - continue; - } - } - else - { - if (strcmp (mnt_ptr->dir, "/") == 0) - sstrncpy (disk_name, "root", sizeof (disk_name)); - else - { - int len; - - sstrncpy (disk_name, mnt_ptr->dir + 1, sizeof (disk_name)); - len = strlen (disk_name); - - for (int i = 0; i < len; i++) - if (disk_name[i] == '/') - disk_name[i] = '-'; - } - } - - blocksize = BLOCKSIZE(statbuf); - - /* - * 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. */ + /* struct STATANYFS statbuf; */ + cu_mount_t *mnt_list; + + mnt_list = NULL; + if (cu_mount_getlist(&mnt_list) == NULL) { + ERROR("df plugin: cu_mount_getlist failed."); + return (-1); + } + + for (cu_mount_t *mnt_ptr = mnt_list; mnt_ptr != NULL; + mnt_ptr = mnt_ptr->next) { + unsigned long long blocksize; + char disk_name[256]; + cu_mount_t *dup_ptr; + uint64_t blk_free; + uint64_t blk_reserved; + uint64_t blk_used; + + char const *dev = + (mnt_ptr->spec_device != NULL) ? mnt_ptr->spec_device : mnt_ptr->device; + + if (ignorelist_match(il_device, dev)) + continue; + if (ignorelist_match(il_mountpoint, mnt_ptr->dir)) + continue; + if (ignorelist_match(il_fstype, mnt_ptr->type)) + continue; + + /* search for duplicates *in front of* the current mnt_ptr. */ + for (dup_ptr = mnt_list; dup_ptr != NULL; dup_ptr = dup_ptr->next) { + /* No duplicate found: mnt_ptr is the first of its kind. */ + if (dup_ptr == mnt_ptr) { + dup_ptr = NULL; + break; + } + + /* Duplicate found: leave non-NULL dup_ptr. */ + if (by_device && (mnt_ptr->spec_device != NULL) && + (dup_ptr->spec_device != NULL) && + (strcmp(mnt_ptr->spec_device, dup_ptr->spec_device) == 0)) + break; + else if (!by_device && (strcmp(mnt_ptr->dir, dup_ptr->dir) == 0)) + break; + } + + /* ignore duplicates */ + if (dup_ptr != NULL) + continue; + + if (STATANYFS(mnt_ptr->dir, &statbuf) < 0) { + char errbuf[1024]; + ERROR(STATANYFS_STR "(%s) failed: %s", mnt_ptr->dir, + sstrerror(errno, errbuf, sizeof(errbuf))); + continue; + } + + if (!statbuf.f_blocks) + continue; + + if (by_device) { + /* eg, /dev/hda1 -- strip off the "/dev/" */ + if (strncmp(dev, "/dev/", strlen("/dev/")) == 0) + sstrncpy(disk_name, dev + strlen("/dev/"), sizeof(disk_name)); + else + sstrncpy(disk_name, dev, sizeof(disk_name)); + + if (strlen(disk_name) < 1) { + DEBUG("df: no device name for mountpoint %s, skipping", mnt_ptr->dir); + continue; + } + } else { + if (strcmp(mnt_ptr->dir, "/") == 0) + sstrncpy(disk_name, "root", sizeof(disk_name)); + else { + int len; + + sstrncpy(disk_name, mnt_ptr->dir + 1, sizeof(disk_name)); + len = strlen(disk_name); + + for (int i = 0; i < len; i++) + if (disk_name[i] == '/') + disk_name[i] = '-'; + } + } + + blocksize = BLOCKSIZE(statbuf); + +/* + * 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); - - if (values_absolute) - { - 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)); - } - - if (values_percentage) - { - if (statbuf.f_blocks > 0) - { - df_submit_one (disk_name, "percent_bytes", "free", - (gauge_t) ((float_t)(blk_free) / statbuf.f_blocks * 100)); - df_submit_one (disk_name, "percent_bytes", "reserved", - (gauge_t) ((float_t)(blk_reserved) / statbuf.f_blocks * 100)); - df_submit_one (disk_name, "percent_bytes", "used", - (gauge_t) ((float_t)(blk_used) / statbuf.f_blocks * 100)); - } - else return (-1); - } - - /* inode handling */ - if (report_inodes && statbuf.f_files != 0 && statbuf.f_ffree != 0) - { - uint64_t inode_free; - uint64_t inode_reserved; - uint64_t inode_used; - - /* Sanity-check for the values in the struct */ - if (statbuf.f_ffree < statbuf.f_favail) - statbuf.f_ffree = statbuf.f_favail; - if (statbuf.f_files < statbuf.f_ffree) - statbuf.f_files = statbuf.f_ffree; - - inode_free = (uint64_t) statbuf.f_favail; - inode_reserved = (uint64_t) (statbuf.f_ffree - statbuf.f_favail); - inode_used = (uint64_t) (statbuf.f_files - statbuf.f_ffree); - - if (values_percentage) - { - if (statbuf.f_files > 0) - { - df_submit_one (disk_name, "percent_inodes", "free", - (gauge_t) ((float_t)(inode_free) / statbuf.f_files * 100)); - df_submit_one (disk_name, "percent_inodes", "reserved", - (gauge_t) ((float_t)(inode_reserved) / statbuf.f_files * 100)); - df_submit_one (disk_name, "percent_inodes", "used", - (gauge_t) ((float_t)(inode_used) / statbuf.f_files * 100)); - } - else return (-1); - } - if (values_absolute) - { - df_submit_one (disk_name, "df_inodes", "free", - (gauge_t) inode_free); - df_submit_one (disk_name, "df_inodes", "reserved", - (gauge_t) inode_reserved); - df_submit_one (disk_name, "df_inodes", "used", - (gauge_t) inode_used); - } - } - } - - cu_mount_freelist (mnt_list); - - return (0); + /* 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); + + if (values_absolute) { + 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)); + } + + if (values_percentage) { + if (statbuf.f_blocks > 0) { + df_submit_one(disk_name, "percent_bytes", "free", + (gauge_t)((float_t)(blk_free) / statbuf.f_blocks * 100)); + df_submit_one( + disk_name, "percent_bytes", "reserved", + (gauge_t)((float_t)(blk_reserved) / statbuf.f_blocks * 100)); + df_submit_one(disk_name, "percent_bytes", "used", + (gauge_t)((float_t)(blk_used) / statbuf.f_blocks * 100)); + } else + return (-1); + } + + /* inode handling */ + if (report_inodes && statbuf.f_files != 0 && statbuf.f_ffree != 0) { + uint64_t inode_free; + uint64_t inode_reserved; + uint64_t inode_used; + + /* Sanity-check for the values in the struct */ + if (statbuf.f_ffree < statbuf.f_favail) + statbuf.f_ffree = statbuf.f_favail; + if (statbuf.f_files < statbuf.f_ffree) + statbuf.f_files = statbuf.f_ffree; + + inode_free = (uint64_t)statbuf.f_favail; + inode_reserved = (uint64_t)(statbuf.f_ffree - statbuf.f_favail); + inode_used = (uint64_t)(statbuf.f_files - statbuf.f_ffree); + + if (values_percentage) { + if (statbuf.f_files > 0) { + df_submit_one( + disk_name, "percent_inodes", "free", + (gauge_t)((float_t)(inode_free) / statbuf.f_files * 100)); + df_submit_one( + disk_name, "percent_inodes", "reserved", + (gauge_t)((float_t)(inode_reserved) / statbuf.f_files * 100)); + df_submit_one( + disk_name, "percent_inodes", "used", + (gauge_t)((float_t)(inode_used) / statbuf.f_files * 100)); + } else + return (-1); + } + if (values_absolute) { + df_submit_one(disk_name, "df_inodes", "free", (gauge_t)inode_free); + df_submit_one(disk_name, "df_inodes", "reserved", + (gauge_t)inode_reserved); + df_submit_one(disk_name, "df_inodes", "used", (gauge_t)inode_used); + } + } + } + + cu_mount_freelist(mnt_list); + + return (0); } /* int df_read */ -void module_register (void) -{ - plugin_register_config ("df", df_config, - config_keys, config_keys_num); - plugin_register_init ("df", df_init); - plugin_register_read ("df", df_read); +void module_register(void) { + plugin_register_config("df", df_config, config_keys, config_keys_num); + plugin_register_init("df", df_init); + plugin_register_read("df", df_read); } /* void module_register */ diff --git a/src/disk.c b/src/disk.c index a07288d1..e01e1506 100644 --- a/src/disk.c +++ b/src/disk.c @@ -28,31 +28,31 @@ #include "utils_ignorelist.h" #if HAVE_MACH_MACH_TYPES_H -# include +#include #endif #if HAVE_MACH_MACH_INIT_H -# include +#include #endif #if HAVE_MACH_MACH_ERROR_H -# include +#include #endif #if HAVE_MACH_MACH_PORT_H -# include +#include #endif #if HAVE_COREFOUNDATION_COREFOUNDATION_H -# include +#include #endif #if HAVE_IOKIT_IOKITLIB_H -# include +#include #endif #if HAVE_IOKIT_IOTYPES_H -# include +#include #endif #if HAVE_IOKIT_STORAGE_IOBLOCKSTORAGEDRIVER_H -# include +#include #endif #if HAVE_IOKIT_IOBSD_H -# include +#include #endif #if KERNEL_FREEBSD #include @@ -60,22 +60,22 @@ #endif #if HAVE_LIMITS_H -# include +#include #endif #ifndef UINT_MAX -# define UINT_MAX 4294967295U +#define UINT_MAX 4294967295U #endif #if HAVE_STATGRAB_H -# include +#include #endif #if HAVE_PERFSTAT -# ifndef _AIXVERSION_610 -# include -# endif -# include -# include +#ifndef _AIXVERSION_610 +#include +#endif +#include +#include #endif #if HAVE_IOKIT_IOKITLIB_H @@ -86,32 +86,31 @@ static _Bool use_bsd_name = 0; /* #endif HAVE_IOKIT_IOKITLIB_H */ #elif KERNEL_LINUX -typedef struct diskstats -{ - char *name; +typedef struct diskstats { + char *name; - /* This overflows in roughly 1361 years */ - unsigned int poll_count; + /* This overflows in roughly 1361 years */ + unsigned int poll_count; - derive_t read_sectors; - derive_t write_sectors; + derive_t read_sectors; + derive_t write_sectors; - derive_t read_bytes; - derive_t write_bytes; + derive_t read_bytes; + derive_t write_bytes; - derive_t read_ops; - derive_t write_ops; - derive_t read_time; - derive_t write_time; + derive_t read_ops; + derive_t write_ops; + derive_t read_time; + derive_t write_time; - derive_t avg_read_time; - derive_t avg_write_time; + derive_t avg_read_time; + derive_t avg_write_time; - _Bool has_merged; - _Bool has_in_progress; - _Bool has_io_time; + _Bool has_merged; + _Bool has_in_progress; + _Bool has_io_time; - struct diskstats *next; + struct diskstats *next; } diskstats_t; static diskstats_t *disklist; @@ -131,13 +130,13 @@ static int numdisk = 0; /* #endif HAVE_LIBSTATGRAB */ #elif HAVE_PERFSTAT -static perfstat_disk_t * stat_disk; +static perfstat_disk_t *stat_disk; static int numdisk; static int pnumdisk; /* #endif HAVE_PERFSTAT */ #else -# error "No applicable input method." +#error "No applicable input method." #endif #if HAVE_LIBUDEV @@ -147,212 +146,182 @@ static char *conf_udev_name_attr = NULL; static struct udev *handle_udev; #endif -static const char *config_keys[] = -{ - "Disk", - "UseBSDName", - "IgnoreSelected", - "UdevNameAttr" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"Disk", "UseBSDName", "IgnoreSelected", + "UdevNameAttr"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static ignorelist_t *ignorelist = NULL; -static int disk_config (const char *key, const char *value) -{ +static int disk_config(const char *key, const char *value) { if (ignorelist == NULL) - ignorelist = ignorelist_create (/* invert = */ 1); + ignorelist = ignorelist_create(/* invert = */ 1); if (ignorelist == NULL) return (1); - if (strcasecmp ("Disk", key) == 0) - { - ignorelist_add (ignorelist, value); - } - else if (strcasecmp ("IgnoreSelected", key) == 0) - { + if (strcasecmp("Disk", key) == 0) { + ignorelist_add(ignorelist, value); + } else if (strcasecmp("IgnoreSelected", key) == 0) { int invert = 1; - if (IS_TRUE (value)) + if (IS_TRUE(value)) invert = 0; - ignorelist_set_invert (ignorelist, invert); - } - else if (strcasecmp ("UseBSDName", key) == 0) - { + ignorelist_set_invert(ignorelist, invert); + } else if (strcasecmp("UseBSDName", key) == 0) { #if HAVE_IOKIT_IOKITLIB_H - use_bsd_name = IS_TRUE (value) ? 1 : 0; + use_bsd_name = IS_TRUE(value) ? 1 : 0; #else - WARNING ("disk plugin: The \"UseBSDName\" option is only supported " - "on Mach / Mac OS X and will be ignored."); + WARNING("disk plugin: The \"UseBSDName\" option is only supported " + "on Mach / Mac OS X and will be ignored."); #endif - } - else if (strcasecmp ("UdevNameAttr", key) == 0) - { + } else if (strcasecmp("UdevNameAttr", key) == 0) { #if HAVE_LIBUDEV - if (conf_udev_name_attr != NULL) - { - free (conf_udev_name_attr); + if (conf_udev_name_attr != NULL) { + free(conf_udev_name_attr); conf_udev_name_attr = NULL; } - if ((conf_udev_name_attr = strdup (value)) == NULL) + if ((conf_udev_name_attr = strdup(value)) == NULL) return (1); #else - WARNING ("disk plugin: The \"UdevNameAttr\" option is only supported " - "if collectd is built with libudev support"); + WARNING("disk plugin: The \"UdevNameAttr\" option is only supported " + "if collectd is built with libudev support"); #endif - } - else - { + } else { return (-1); } return (0); } /* int disk_config */ -static int disk_init (void) -{ +static int disk_init(void) { #if HAVE_IOKIT_IOKITLIB_H - kern_return_t status; - - if (io_master_port != MACH_PORT_NULL) - { - mach_port_deallocate (mach_task_self (), - io_master_port); - io_master_port = MACH_PORT_NULL; - } - - status = IOMasterPort (MACH_PORT_NULL, &io_master_port); - if (status != kIOReturnSuccess) - { - ERROR ("IOMasterPort failed: %s", - mach_error_string (status)); - io_master_port = MACH_PORT_NULL; - return (-1); - } + kern_return_t status; + + if (io_master_port != MACH_PORT_NULL) { + mach_port_deallocate(mach_task_self(), io_master_port); + io_master_port = MACH_PORT_NULL; + } + + status = IOMasterPort(MACH_PORT_NULL, &io_master_port); + if (status != kIOReturnSuccess) { + ERROR("IOMasterPort failed: %s", mach_error_string(status)); + io_master_port = MACH_PORT_NULL; + return (-1); + } /* #endif HAVE_IOKIT_IOKITLIB_H */ #elif KERNEL_LINUX #if HAVE_LIBUDEV - if (conf_udev_name_attr != NULL) - { - handle_udev = udev_new(); - if (handle_udev == NULL) { - ERROR ("disk plugin: udev_new() failed!"); - return (-1); - } - } + if (conf_udev_name_attr != NULL) { + handle_udev = udev_new(); + if (handle_udev == NULL) { + ERROR("disk plugin: udev_new() failed!"); + return (-1); + } + } #endif /* HAVE_LIBUDEV */ /* #endif KERNEL_LINUX */ #elif KERNEL_FREEBSD - int rv; - - rv = geom_gettree(&geom_tree); - if (rv != 0) { - ERROR ("geom_gettree() failed, returned %d", rv); - return (-1); - } - rv = geom_stats_open(); - if (rv != 0) { - ERROR ("geom_stats_open() failed, returned %d", rv); - return (-1); - } + int rv; + + rv = geom_gettree(&geom_tree); + if (rv != 0) { + ERROR("geom_gettree() failed, returned %d", rv); + return (-1); + } + rv = geom_stats_open(); + if (rv != 0) { + ERROR("geom_stats_open() failed, returned %d", rv); + return (-1); + } /* #endif KERNEL_FREEBSD */ #elif HAVE_LIBKSTAT - kstat_t *ksp_chain; - - numdisk = 0; - - if (kc == NULL) - return (-1); - - for (numdisk = 0, ksp_chain = kc->kc_chain; - (numdisk < MAX_NUMDISK) && (ksp_chain != NULL); - ksp_chain = ksp_chain->ks_next) - { - if (strncmp (ksp_chain->ks_class, "disk", 4) - && strncmp (ksp_chain->ks_class, "partition", 9)) - continue; - if (ksp_chain->ks_type != KSTAT_TYPE_IO) - continue; - ksp[numdisk++] = ksp_chain; - } + kstat_t *ksp_chain; + + numdisk = 0; + + if (kc == NULL) + return (-1); + + for (numdisk = 0, ksp_chain = kc->kc_chain; + (numdisk < MAX_NUMDISK) && (ksp_chain != NULL); + ksp_chain = ksp_chain->ks_next) { + if (strncmp(ksp_chain->ks_class, "disk", 4) && + strncmp(ksp_chain->ks_class, "partition", 9)) + continue; + if (ksp_chain->ks_type != KSTAT_TYPE_IO) + continue; + ksp[numdisk++] = ksp_chain; + } #endif /* HAVE_LIBKSTAT */ - return (0); + return (0); } /* int disk_init */ -static int disk_shutdown (void) -{ +static int disk_shutdown(void) { #if KERNEL_LINUX #if HAVE_LIBUDEV - if (handle_udev != NULL) - udev_unref(handle_udev); + if (handle_udev != NULL) + udev_unref(handle_udev); #endif /* HAVE_LIBUDEV */ #endif /* KERNEL_LINUX */ - return (0); + return (0); } /* int disk_shutdown */ -static void disk_submit (const char *plugin_instance, - const char *type, - derive_t read, derive_t write) -{ - value_list_t vl = VALUE_LIST_INIT; - value_t values[] = { - { .derive = read }, - { .derive = write }, - }; - - vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - sstrncpy (vl.plugin, "disk", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, plugin_instance, - sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - - plugin_dispatch_values (&vl); +static void disk_submit(const char *plugin_instance, const char *type, + derive_t read, derive_t write) { + value_list_t vl = VALUE_LIST_INIT; + value_t values[] = { + {.derive = read}, {.derive = write}, + }; + + vl.values = values; + vl.values_len = STATIC_ARRAY_SIZE(values); + sstrncpy(vl.plugin, "disk", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + + plugin_dispatch_values(&vl); } /* void disk_submit */ #if KERNEL_FREEBSD || KERNEL_LINUX -static void submit_io_time (char const *plugin_instance, derive_t io_time, derive_t weighted_time) -{ - value_list_t vl = VALUE_LIST_INIT; - value_t values[] = { - { .derive = io_time }, - { .derive = weighted_time }, - }; - - vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - sstrncpy (vl.plugin, "disk", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, "disk_io_time", sizeof (vl.type)); - - plugin_dispatch_values (&vl); +static void submit_io_time(char const *plugin_instance, derive_t io_time, + derive_t weighted_time) { + value_list_t vl = VALUE_LIST_INIT; + value_t values[] = { + {.derive = io_time}, {.derive = weighted_time}, + }; + + vl.values = values; + vl.values_len = STATIC_ARRAY_SIZE(values); + sstrncpy(vl.plugin, "disk", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "disk_io_time", sizeof(vl.type)); + + plugin_dispatch_values(&vl); } /* void submit_io_time */ #endif /* KERNEL_FREEBSD || KERNEL_LINUX */ #if KERNEL_LINUX -static void submit_in_progress (char const *disk_name, gauge_t in_progress) -{ - value_list_t vl = VALUE_LIST_INIT; +static void submit_in_progress(char const *disk_name, gauge_t in_progress) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = in_progress }; - vl.values_len = 1; - sstrncpy (vl.plugin, "disk", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, disk_name, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, "pending_operations", sizeof (vl.type)); + vl.values = &(value_t){.gauge = in_progress}; + vl.values_len = 1; + sstrncpy(vl.plugin, "disk", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, disk_name, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "pending_operations", sizeof(vl.type)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static counter_t disk_calc_time_incr (counter_t delta_time, counter_t delta_ops) -{ - double interval = CDTIME_T_TO_DOUBLE (plugin_get_interval ()); - double avg_time = ((double) delta_time) / ((double) delta_ops); - double avg_time_incr = interval * avg_time; +static counter_t disk_calc_time_incr(counter_t delta_time, + counter_t delta_ops) { + double interval = CDTIME_T_TO_DOUBLE(plugin_get_interval()); + double avg_time = ((double)delta_time) / ((double)delta_ops); + double avg_time_incr = interval * avg_time; - return ((counter_t) (avg_time_incr + .5)); + return ((counter_t)(avg_time_incr + .5)); } #endif @@ -364,713 +333,699 @@ static counter_t disk_calc_time_incr (counter_t delta_time, counter_t delta_ops) * Otherwise it returns NULL. */ -static char *disk_udev_attr_name (struct udev *udev, char *disk_name, const char *attr) -{ - struct udev_device *dev; - const char *prop; - char *output = NULL; - - dev = udev_device_new_from_subsystem_sysname (udev, "block", disk_name); - if (dev != NULL) - { - prop = udev_device_get_property_value (dev, attr); - if (prop) { - output = strdup (prop); - DEBUG ("disk plugin: renaming %s => %s", disk_name, output); - } - udev_device_unref (dev); - } - return output; +static char *disk_udev_attr_name(struct udev *udev, char *disk_name, + const char *attr) { + struct udev_device *dev; + const char *prop; + char *output = NULL; + + dev = udev_device_new_from_subsystem_sysname(udev, "block", disk_name); + if (dev != NULL) { + prop = udev_device_get_property_value(dev, attr); + if (prop) { + output = strdup(prop); + DEBUG("disk plugin: renaming %s => %s", disk_name, output); + } + udev_device_unref(dev); + } + return output; } #endif #if HAVE_IOKIT_IOKITLIB_H -static signed long long dict_get_value (CFDictionaryRef dict, const char *key) -{ - signed long long val_int; - CFNumberRef val_obj; - CFStringRef key_obj; - - /* `key_obj' needs to be released. */ - key_obj = CFStringCreateWithCString (kCFAllocatorDefault, key, - kCFStringEncodingASCII); - if (key_obj == NULL) - { - DEBUG ("CFStringCreateWithCString (%s) failed.", key); - return (-1LL); - } - - /* get => we don't need to release (== free) the object */ - val_obj = (CFNumberRef) CFDictionaryGetValue (dict, key_obj); - - CFRelease (key_obj); - - if (val_obj == NULL) - { - DEBUG ("CFDictionaryGetValue (%s) failed.", key); - return (-1LL); - } - - if (!CFNumberGetValue (val_obj, kCFNumberSInt64Type, &val_int)) - { - DEBUG ("CFNumberGetValue (%s) failed.", key); - return (-1LL); - } - - return (val_int); +static signed long long dict_get_value(CFDictionaryRef dict, const char *key) { + signed long long val_int; + CFNumberRef val_obj; + CFStringRef key_obj; + + /* `key_obj' needs to be released. */ + key_obj = CFStringCreateWithCString(kCFAllocatorDefault, key, + kCFStringEncodingASCII); + if (key_obj == NULL) { + DEBUG("CFStringCreateWithCString (%s) failed.", key); + return (-1LL); + } + + /* get => we don't need to release (== free) the object */ + val_obj = (CFNumberRef)CFDictionaryGetValue(dict, key_obj); + + CFRelease(key_obj); + + if (val_obj == NULL) { + DEBUG("CFDictionaryGetValue (%s) failed.", key); + return (-1LL); + } + + if (!CFNumberGetValue(val_obj, kCFNumberSInt64Type, &val_int)) { + DEBUG("CFNumberGetValue (%s) failed.", key); + return (-1LL); + } + + return (val_int); } #endif /* HAVE_IOKIT_IOKITLIB_H */ -static int disk_read (void) -{ +static int disk_read(void) { #if HAVE_IOKIT_IOKITLIB_H - io_registry_entry_t disk; - io_registry_entry_t disk_child; - io_iterator_t disk_list; - CFMutableDictionaryRef props_dict, child_dict; - CFDictionaryRef stats_dict; - CFStringRef tmp_cf_string_ref; - kern_return_t status; - - signed long long read_ops, read_byt, read_tme; - signed long long write_ops, write_byt, write_tme; - - int disk_major, disk_minor; - char disk_name[DATA_MAX_NAME_LEN]; - char child_disk_name_bsd[DATA_MAX_NAME_LEN], props_disk_name_bsd[DATA_MAX_NAME_LEN]; - - /* Get the list of all disk objects. */ - if (IOServiceGetMatchingServices (io_master_port, IOServiceMatching (kIOBlockStorageDriverClass), &disk_list) != kIOReturnSuccess) { - ERROR ("disk plugin: IOServiceGetMatchingServices failed."); - return (-1); - } - - while ((disk = IOIteratorNext (disk_list)) != 0) { - props_dict = NULL; - stats_dict = NULL; - child_dict = NULL; - - /* get child of disk entry and corresponding property dictionary */ - if ((status = IORegistryEntryGetChildEntry (disk, kIOServicePlane, &disk_child)) != kIOReturnSuccess) { - /* This fails for example for DVD/CD drives, which we want to ignore anyway */ - DEBUG ("IORegistryEntryGetChildEntry (disk) failed: 0x%08x", status); - IOObjectRelease (disk); - continue; - } - if (IORegistryEntryCreateCFProperties (disk_child, (CFMutableDictionaryRef *) &child_dict, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess || child_dict == NULL) { - ERROR ("disk plugin: IORegistryEntryCreateCFProperties (disk_child) failed."); - IOObjectRelease (disk_child); - IOObjectRelease (disk); - continue; - } - - /* extract name and major/minor numbers */ - memset (child_disk_name_bsd, 0, sizeof (child_disk_name_bsd)); - tmp_cf_string_ref = (CFStringRef) CFDictionaryGetValue (child_dict, CFSTR(kIOBSDNameKey)); - if (tmp_cf_string_ref) { - assert (CFGetTypeID (tmp_cf_string_ref) == CFStringGetTypeID ()); - CFStringGetCString (tmp_cf_string_ref, child_disk_name_bsd, sizeof (child_disk_name_bsd), kCFStringEncodingUTF8); - } - disk_major = (int) dict_get_value (child_dict, kIOBSDMajorKey); - disk_minor = (int) dict_get_value (child_dict, kIOBSDMinorKey); - DEBUG ("disk plugin: child_disk_name_bsd=\"%s\" major=%d minor=%d", child_disk_name_bsd, disk_major, disk_minor); - CFRelease (child_dict); - IOObjectRelease (disk_child); - - /* get property dictionary of the disk entry itself */ - if (IORegistryEntryCreateCFProperties (disk, (CFMutableDictionaryRef *) &props_dict, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess || props_dict == NULL) { - ERROR ("disk-plugin: IORegistryEntryCreateCFProperties failed."); - IOObjectRelease (disk); - continue; - } - - /* extract name and stats dictionary */ - memset (props_disk_name_bsd, 0, sizeof (props_disk_name_bsd)); - tmp_cf_string_ref = (CFStringRef) CFDictionaryGetValue (props_dict, CFSTR(kIOBSDNameKey)); - if (tmp_cf_string_ref) { - assert (CFGetTypeID (tmp_cf_string_ref) == CFStringGetTypeID ()); - CFStringGetCString (tmp_cf_string_ref, props_disk_name_bsd, sizeof (props_disk_name_bsd), kCFStringEncodingUTF8); - } - stats_dict = (CFDictionaryRef) CFDictionaryGetValue (props_dict, CFSTR (kIOBlockStorageDriverStatisticsKey)); - if (stats_dict == NULL) { - ERROR ("disk plugin: CFDictionaryGetValue (%s) failed.", kIOBlockStorageDriverStatisticsKey); - CFRelease (props_dict); - IOObjectRelease (disk); - continue; - } - DEBUG ("disk plugin: props_disk_name_bsd=\"%s\"", props_disk_name_bsd); - - /* choose name */ - if (use_bsd_name) { - if (child_disk_name_bsd[0] != 0) - sstrncpy (disk_name, child_disk_name_bsd, sizeof (disk_name)); - else if (props_disk_name_bsd[0] != 0) - sstrncpy (disk_name, props_disk_name_bsd, sizeof (disk_name)); - else { - ERROR ("disk plugin: can't find bsd disk name."); - ssnprintf (disk_name, sizeof (disk_name), "%i-%i", disk_major, disk_minor); - } - } - else - ssnprintf (disk_name, sizeof (disk_name), "%i-%i", disk_major, disk_minor); - - DEBUG ("disk plugin: disk_name = \"%s\"", disk_name); - - /* check the name against ignore list */ - if (ignorelist_match (ignorelist, disk_name) != 0) { - CFRelease (props_dict); - IOObjectRelease (disk); - continue; - } - - /* extract the stats */ - read_ops = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsReadsKey); - read_byt = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsBytesReadKey); - read_tme = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsTotalReadTimeKey); - write_ops = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsWritesKey); - write_byt = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsBytesWrittenKey); - write_tme = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsTotalWriteTimeKey); - CFRelease (props_dict); - IOObjectRelease (disk); - - /* and submit */ - if ((read_byt != -1LL) || (write_byt != -1LL)) - disk_submit (disk_name, "disk_octets", read_byt, write_byt); - if ((read_ops != -1LL) || (write_ops != -1LL)) - disk_submit (disk_name, "disk_ops", read_ops, write_ops); - if ((read_tme != -1LL) || (write_tme != -1LL)) - disk_submit (disk_name, "disk_time", read_tme / 1000, write_tme / 1000); - - } - IOObjectRelease (disk_list); + io_registry_entry_t disk; + io_registry_entry_t disk_child; + io_iterator_t disk_list; + CFMutableDictionaryRef props_dict, child_dict; + CFDictionaryRef stats_dict; + CFStringRef tmp_cf_string_ref; + kern_return_t status; + + signed long long read_ops, read_byt, read_tme; + signed long long write_ops, write_byt, write_tme; + + int disk_major, disk_minor; + char disk_name[DATA_MAX_NAME_LEN]; + char child_disk_name_bsd[DATA_MAX_NAME_LEN], + props_disk_name_bsd[DATA_MAX_NAME_LEN]; + + /* Get the list of all disk objects. */ + if (IOServiceGetMatchingServices( + io_master_port, IOServiceMatching(kIOBlockStorageDriverClass), + &disk_list) != kIOReturnSuccess) { + ERROR("disk plugin: IOServiceGetMatchingServices failed."); + return (-1); + } + + while ((disk = IOIteratorNext(disk_list)) != 0) { + props_dict = NULL; + stats_dict = NULL; + child_dict = NULL; + + /* get child of disk entry and corresponding property dictionary */ + if ((status = IORegistryEntryGetChildEntry( + disk, kIOServicePlane, &disk_child)) != kIOReturnSuccess) { + /* This fails for example for DVD/CD drives, which we want to ignore + * anyway */ + DEBUG("IORegistryEntryGetChildEntry (disk) failed: 0x%08x", status); + IOObjectRelease(disk); + continue; + } + if (IORegistryEntryCreateCFProperties( + disk_child, (CFMutableDictionaryRef *)&child_dict, + kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess || + child_dict == NULL) { + ERROR("disk plugin: IORegistryEntryCreateCFProperties (disk_child) " + "failed."); + IOObjectRelease(disk_child); + IOObjectRelease(disk); + continue; + } + + /* extract name and major/minor numbers */ + memset(child_disk_name_bsd, 0, sizeof(child_disk_name_bsd)); + tmp_cf_string_ref = + (CFStringRef)CFDictionaryGetValue(child_dict, CFSTR(kIOBSDNameKey)); + if (tmp_cf_string_ref) { + assert(CFGetTypeID(tmp_cf_string_ref) == CFStringGetTypeID()); + CFStringGetCString(tmp_cf_string_ref, child_disk_name_bsd, + sizeof(child_disk_name_bsd), kCFStringEncodingUTF8); + } + disk_major = (int)dict_get_value(child_dict, kIOBSDMajorKey); + disk_minor = (int)dict_get_value(child_dict, kIOBSDMinorKey); + DEBUG("disk plugin: child_disk_name_bsd=\"%s\" major=%d minor=%d", + child_disk_name_bsd, disk_major, disk_minor); + CFRelease(child_dict); + IOObjectRelease(disk_child); + + /* get property dictionary of the disk entry itself */ + if (IORegistryEntryCreateCFProperties( + disk, (CFMutableDictionaryRef *)&props_dict, kCFAllocatorDefault, + kNilOptions) != kIOReturnSuccess || + props_dict == NULL) { + ERROR("disk-plugin: IORegistryEntryCreateCFProperties failed."); + IOObjectRelease(disk); + continue; + } + + /* extract name and stats dictionary */ + memset(props_disk_name_bsd, 0, sizeof(props_disk_name_bsd)); + tmp_cf_string_ref = + (CFStringRef)CFDictionaryGetValue(props_dict, CFSTR(kIOBSDNameKey)); + if (tmp_cf_string_ref) { + assert(CFGetTypeID(tmp_cf_string_ref) == CFStringGetTypeID()); + CFStringGetCString(tmp_cf_string_ref, props_disk_name_bsd, + sizeof(props_disk_name_bsd), kCFStringEncodingUTF8); + } + stats_dict = (CFDictionaryRef)CFDictionaryGetValue( + props_dict, CFSTR(kIOBlockStorageDriverStatisticsKey)); + if (stats_dict == NULL) { + ERROR("disk plugin: CFDictionaryGetValue (%s) failed.", + kIOBlockStorageDriverStatisticsKey); + CFRelease(props_dict); + IOObjectRelease(disk); + continue; + } + DEBUG("disk plugin: props_disk_name_bsd=\"%s\"", props_disk_name_bsd); + + /* choose name */ + if (use_bsd_name) { + if (child_disk_name_bsd[0] != 0) + sstrncpy(disk_name, child_disk_name_bsd, sizeof(disk_name)); + else if (props_disk_name_bsd[0] != 0) + sstrncpy(disk_name, props_disk_name_bsd, sizeof(disk_name)); + else { + ERROR("disk plugin: can't find bsd disk name."); + ssnprintf(disk_name, sizeof(disk_name), "%i-%i", disk_major, + disk_minor); + } + } else + ssnprintf(disk_name, sizeof(disk_name), "%i-%i", disk_major, disk_minor); + + DEBUG("disk plugin: disk_name = \"%s\"", disk_name); + + /* check the name against ignore list */ + if (ignorelist_match(ignorelist, disk_name) != 0) { + CFRelease(props_dict); + IOObjectRelease(disk); + continue; + } + + /* extract the stats */ + read_ops = + dict_get_value(stats_dict, kIOBlockStorageDriverStatisticsReadsKey); + read_byt = + dict_get_value(stats_dict, kIOBlockStorageDriverStatisticsBytesReadKey); + read_tme = dict_get_value(stats_dict, + kIOBlockStorageDriverStatisticsTotalReadTimeKey); + write_ops = + dict_get_value(stats_dict, kIOBlockStorageDriverStatisticsWritesKey); + write_byt = dict_get_value(stats_dict, + kIOBlockStorageDriverStatisticsBytesWrittenKey); + write_tme = dict_get_value( + stats_dict, kIOBlockStorageDriverStatisticsTotalWriteTimeKey); + CFRelease(props_dict); + IOObjectRelease(disk); + + /* and submit */ + if ((read_byt != -1LL) || (write_byt != -1LL)) + disk_submit(disk_name, "disk_octets", read_byt, write_byt); + if ((read_ops != -1LL) || (write_ops != -1LL)) + disk_submit(disk_name, "disk_ops", read_ops, write_ops); + if ((read_tme != -1LL) || (write_tme != -1LL)) + disk_submit(disk_name, "disk_time", read_tme / 1000, write_tme / 1000); + } + IOObjectRelease(disk_list); /* #endif HAVE_IOKIT_IOKITLIB_H */ #elif KERNEL_FREEBSD - int retry, dirty; - - void *snap = NULL; - struct devstat *snap_iter; - - struct gident *geom_id; - - const char *disk_name; - long double read_time, write_time, busy_time, total_duration; - - for (retry = 0, dirty = 1; retry < 5 && dirty == 1; retry++) { - if (snap != NULL) - geom_stats_snapshot_free(snap); - - /* Get a fresh copy of stats snapshot */ - snap = geom_stats_snapshot_get(); - if (snap == NULL) { - ERROR("disk plugin: geom_stats_snapshot_get() failed."); - return (-1); - } - - /* Check if we have dirty read from this snapshot */ - dirty = 0; - geom_stats_snapshot_reset(snap); - while ((snap_iter = geom_stats_snapshot_next(snap)) != NULL) { - if (snap_iter->id == NULL) - continue; - geom_id = geom_lookupid(&geom_tree, snap_iter->id); - - /* New device? refresh GEOM tree */ - if (geom_id == NULL) { - geom_deletetree(&geom_tree); - if (geom_gettree(&geom_tree) != 0) { - ERROR("disk plugin: geom_gettree() failed"); - geom_stats_snapshot_free(snap); - return (-1); - } - geom_id = geom_lookupid(&geom_tree, snap_iter->id); - } - /* - * This should be rare: the device come right before we take the - * snapshot and went away right after it. We will handle this - * case later, so don't mark dirty but silently ignore it. - */ - if (geom_id == NULL) - continue; - - /* Only collect PROVIDER data */ - if (geom_id->lg_what != ISPROVIDER) - continue; - - /* Only collect data when rank is 1 (physical devices) */ - if (((struct gprovider *)(geom_id->lg_ptr))->lg_geom->lg_rank != 1) - continue; - - /* Check if this is a dirty read quit for another try */ - if (snap_iter->sequence0 != snap_iter->sequence1) { - dirty = 1; - break; - } - } - } - - /* Reset iterator */ - geom_stats_snapshot_reset(snap); - for (;;) { - snap_iter = geom_stats_snapshot_next(snap); - if (snap_iter == NULL) - break; - - if (snap_iter->id == NULL) - continue; - geom_id = geom_lookupid(&geom_tree, snap_iter->id); - if (geom_id == NULL) - continue; - if (geom_id->lg_what != ISPROVIDER) - continue; - if (((struct gprovider *)(geom_id->lg_ptr))->lg_geom->lg_rank != 1) - continue; - /* Skip dirty reads, if present */ - if (dirty && (snap_iter->sequence0 != snap_iter->sequence1)) - continue; - - disk_name = ((struct gprovider *)geom_id->lg_ptr)->lg_name; - - if (ignorelist_match (ignorelist, disk_name) != 0) - continue; - - if ((snap_iter->bytes[DEVSTAT_READ] != 0) || (snap_iter->bytes[DEVSTAT_WRITE] != 0)) { - disk_submit(disk_name, "disk_octets", - (derive_t)snap_iter->bytes[DEVSTAT_READ], - (derive_t)snap_iter->bytes[DEVSTAT_WRITE]); - } - - if ((snap_iter->operations[DEVSTAT_READ] != 0) || (snap_iter->operations[DEVSTAT_WRITE] != 0)) { - disk_submit(disk_name, "disk_ops", - (derive_t)snap_iter->operations[DEVSTAT_READ], - (derive_t)snap_iter->operations[DEVSTAT_WRITE]); - } - - read_time = devstat_compute_etime(&snap_iter->duration[DEVSTAT_READ], NULL); - write_time = devstat_compute_etime(&snap_iter->duration[DEVSTAT_WRITE], NULL); - if ((read_time != 0) || (write_time != 0)) { - disk_submit (disk_name, "disk_time", - (derive_t)(read_time*1000), (derive_t)(write_time*1000)); - } - if (devstat_compute_statistics(snap_iter, NULL, 1.0, - DSM_TOTAL_BUSY_TIME, &busy_time, - DSM_TOTAL_DURATION, &total_duration, - DSM_NONE) != 0) { - WARNING("%s", devstat_errbuf); - } - else - { - submit_io_time(disk_name, busy_time, total_duration); - } - } - geom_stats_snapshot_free(snap); + int retry, dirty; + + void *snap = NULL; + struct devstat *snap_iter; + + struct gident *geom_id; + + const char *disk_name; + long double read_time, write_time, busy_time, total_duration; + + for (retry = 0, dirty = 1; retry < 5 && dirty == 1; retry++) { + if (snap != NULL) + geom_stats_snapshot_free(snap); + + /* Get a fresh copy of stats snapshot */ + snap = geom_stats_snapshot_get(); + if (snap == NULL) { + ERROR("disk plugin: geom_stats_snapshot_get() failed."); + return (-1); + } + + /* Check if we have dirty read from this snapshot */ + dirty = 0; + geom_stats_snapshot_reset(snap); + while ((snap_iter = geom_stats_snapshot_next(snap)) != NULL) { + if (snap_iter->id == NULL) + continue; + geom_id = geom_lookupid(&geom_tree, snap_iter->id); + + /* New device? refresh GEOM tree */ + if (geom_id == NULL) { + geom_deletetree(&geom_tree); + if (geom_gettree(&geom_tree) != 0) { + ERROR("disk plugin: geom_gettree() failed"); + geom_stats_snapshot_free(snap); + return (-1); + } + geom_id = geom_lookupid(&geom_tree, snap_iter->id); + } + /* + * This should be rare: the device come right before we take the + * snapshot and went away right after it. We will handle this + * case later, so don't mark dirty but silently ignore it. + */ + if (geom_id == NULL) + continue; + + /* Only collect PROVIDER data */ + if (geom_id->lg_what != ISPROVIDER) + continue; + + /* Only collect data when rank is 1 (physical devices) */ + if (((struct gprovider *)(geom_id->lg_ptr))->lg_geom->lg_rank != 1) + continue; + + /* Check if this is a dirty read quit for another try */ + if (snap_iter->sequence0 != snap_iter->sequence1) { + dirty = 1; + break; + } + } + } + + /* Reset iterator */ + geom_stats_snapshot_reset(snap); + for (;;) { + snap_iter = geom_stats_snapshot_next(snap); + if (snap_iter == NULL) + break; + + if (snap_iter->id == NULL) + continue; + geom_id = geom_lookupid(&geom_tree, snap_iter->id); + if (geom_id == NULL) + continue; + if (geom_id->lg_what != ISPROVIDER) + continue; + if (((struct gprovider *)(geom_id->lg_ptr))->lg_geom->lg_rank != 1) + continue; + /* Skip dirty reads, if present */ + if (dirty && (snap_iter->sequence0 != snap_iter->sequence1)) + continue; + + disk_name = ((struct gprovider *)geom_id->lg_ptr)->lg_name; + + if (ignorelist_match(ignorelist, disk_name) != 0) + continue; + + if ((snap_iter->bytes[DEVSTAT_READ] != 0) || + (snap_iter->bytes[DEVSTAT_WRITE] != 0)) { + disk_submit(disk_name, "disk_octets", + (derive_t)snap_iter->bytes[DEVSTAT_READ], + (derive_t)snap_iter->bytes[DEVSTAT_WRITE]); + } + + if ((snap_iter->operations[DEVSTAT_READ] != 0) || + (snap_iter->operations[DEVSTAT_WRITE] != 0)) { + disk_submit(disk_name, "disk_ops", + (derive_t)snap_iter->operations[DEVSTAT_READ], + (derive_t)snap_iter->operations[DEVSTAT_WRITE]); + } + + read_time = devstat_compute_etime(&snap_iter->duration[DEVSTAT_READ], NULL); + write_time = + devstat_compute_etime(&snap_iter->duration[DEVSTAT_WRITE], NULL); + if ((read_time != 0) || (write_time != 0)) { + disk_submit(disk_name, "disk_time", (derive_t)(read_time * 1000), + (derive_t)(write_time * 1000)); + } + if (devstat_compute_statistics(snap_iter, NULL, 1.0, DSM_TOTAL_BUSY_TIME, + &busy_time, DSM_TOTAL_DURATION, + &total_duration, DSM_NONE) != 0) { + WARNING("%s", devstat_errbuf); + } else { + submit_io_time(disk_name, busy_time, total_duration); + } + } + geom_stats_snapshot_free(snap); #elif KERNEL_LINUX - FILE *fh; - char buffer[1024]; - - char *fields[32]; - int numfields; - int fieldshift = 0; - - int minor = 0; - - derive_t read_sectors = 0; - derive_t write_sectors = 0; - - derive_t read_ops = 0; - derive_t read_merged = 0; - derive_t read_time = 0; - derive_t write_ops = 0; - derive_t write_merged = 0; - derive_t write_time = 0; - gauge_t in_progress = NAN; - derive_t io_time = 0; - derive_t weighted_time = 0; - int is_disk = 0; - - diskstats_t *ds, *pre_ds; - - if ((fh = fopen ("/proc/diskstats", "r")) == NULL) - { - fh = fopen ("/proc/partitions", "r"); - if (fh == NULL) - { - ERROR ("disk plugin: fopen (/proc/{diskstats,partitions}) failed."); - return (-1); - } - - /* Kernel is 2.4.* */ - fieldshift = 1; - } - - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - char *disk_name; - char *output_name; - - numfields = strsplit (buffer, fields, 32); - - if ((numfields != (14 + fieldshift)) && (numfields != 7)) - continue; - - minor = atoll (fields[1]); - - disk_name = fields[2 + fieldshift]; - - for (ds = disklist, pre_ds = disklist; ds != NULL; pre_ds = ds, ds = ds->next) - if (strcmp (disk_name, ds->name) == 0) - break; - - if (ds == NULL) - { - if ((ds = (diskstats_t *) calloc (1, sizeof (diskstats_t))) == NULL) - continue; - - if ((ds->name = strdup (disk_name)) == NULL) - { - free (ds); - continue; - } - - if (pre_ds == NULL) - disklist = ds; - else - pre_ds->next = ds; - } - - is_disk = 0; - if (numfields == 7) - { - /* Kernel 2.6, Partition */ - read_ops = atoll (fields[3]); - read_sectors = atoll (fields[4]); - write_ops = atoll (fields[5]); - write_sectors = atoll (fields[6]); - } - else if (numfields == (14 + fieldshift)) - { - read_ops = atoll (fields[3 + fieldshift]); - write_ops = atoll (fields[7 + fieldshift]); - - read_sectors = atoll (fields[5 + fieldshift]); - write_sectors = atoll (fields[9 + fieldshift]); - - if ((fieldshift == 0) || (minor == 0)) - { - is_disk = 1; - read_merged = atoll (fields[4 + fieldshift]); - read_time = atoll (fields[6 + fieldshift]); - write_merged = atoll (fields[8 + fieldshift]); - write_time = atoll (fields[10+ fieldshift]); - - in_progress = atof (fields[11 + fieldshift]); - - io_time = atof (fields[12 + fieldshift]); - weighted_time = atof (fields[13 + fieldshift]); - } - } - else - { - DEBUG ("numfields = %i; => unknown file format.", numfields); - continue; - } - - { - derive_t diff_read_sectors; - derive_t diff_write_sectors; - - /* If the counter wraps around, it's only 32 bits.. */ - if (read_sectors < ds->read_sectors) - diff_read_sectors = 1 + read_sectors - + (UINT_MAX - ds->read_sectors); - else - diff_read_sectors = read_sectors - ds->read_sectors; - if (write_sectors < ds->write_sectors) - diff_write_sectors = 1 + write_sectors - + (UINT_MAX - ds->write_sectors); - else - diff_write_sectors = write_sectors - ds->write_sectors; - - ds->read_bytes += 512 * diff_read_sectors; - ds->write_bytes += 512 * diff_write_sectors; - ds->read_sectors = read_sectors; - ds->write_sectors = write_sectors; - } - - /* Calculate the average time an io-op needs to complete */ - if (is_disk) - { - derive_t diff_read_ops; - derive_t diff_write_ops; - derive_t diff_read_time; - derive_t diff_write_time; - - if (read_ops < ds->read_ops) - diff_read_ops = 1 + read_ops - + (UINT_MAX - ds->read_ops); - else - diff_read_ops = read_ops - ds->read_ops; - DEBUG ("disk plugin: disk_name = %s; read_ops = %"PRIi64"; " - "ds->read_ops = %"PRIi64"; diff_read_ops = %"PRIi64";", - disk_name, - read_ops, ds->read_ops, diff_read_ops); - - if (write_ops < ds->write_ops) - diff_write_ops = 1 + write_ops - + (UINT_MAX - ds->write_ops); - else - diff_write_ops = write_ops - ds->write_ops; - - if (read_time < ds->read_time) - diff_read_time = 1 + read_time - + (UINT_MAX - ds->read_time); - else - diff_read_time = read_time - ds->read_time; - - if (write_time < ds->write_time) - diff_write_time = 1 + write_time - + (UINT_MAX - ds->write_time); - else - diff_write_time = write_time - ds->write_time; - - if (diff_read_ops != 0) - ds->avg_read_time += disk_calc_time_incr ( - diff_read_time, diff_read_ops); - if (diff_write_ops != 0) - ds->avg_write_time += disk_calc_time_incr ( - diff_write_time, diff_write_ops); - - ds->read_ops = read_ops; - ds->read_time = read_time; - ds->write_ops = write_ops; - ds->write_time = write_time; - - if (read_merged || write_merged) - ds->has_merged = 1; - - if (in_progress) - ds->has_in_progress = 1; - - if (io_time) - ds->has_io_time = 1; - - } /* if (is_disk) */ - - /* Don't write to the RRDs if we've just started.. */ - ds->poll_count++; - if (ds->poll_count <= 2) - { - DEBUG ("disk plugin: (ds->poll_count = %i) <= " - "(min_poll_count = 2); => Not writing.", - ds->poll_count); - continue; - } - - if ((read_ops == 0) && (write_ops == 0)) - { - DEBUG ("disk plugin: ((read_ops == 0) && " - "(write_ops == 0)); => Not writing."); - continue; - } - - output_name = disk_name; + FILE *fh; + char buffer[1024]; + + char *fields[32]; + int numfields; + int fieldshift = 0; + + int minor = 0; + + derive_t read_sectors = 0; + derive_t write_sectors = 0; + + derive_t read_ops = 0; + derive_t read_merged = 0; + derive_t read_time = 0; + derive_t write_ops = 0; + derive_t write_merged = 0; + derive_t write_time = 0; + gauge_t in_progress = NAN; + derive_t io_time = 0; + derive_t weighted_time = 0; + int is_disk = 0; + + diskstats_t *ds, *pre_ds; + + if ((fh = fopen("/proc/diskstats", "r")) == NULL) { + fh = fopen("/proc/partitions", "r"); + if (fh == NULL) { + ERROR("disk plugin: fopen (/proc/{diskstats,partitions}) failed."); + return (-1); + } + + /* Kernel is 2.4.* */ + fieldshift = 1; + } + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + char *disk_name; + char *output_name; + + numfields = strsplit(buffer, fields, 32); + + if ((numfields != (14 + fieldshift)) && (numfields != 7)) + continue; + + minor = atoll(fields[1]); + + disk_name = fields[2 + fieldshift]; + + for (ds = disklist, pre_ds = disklist; ds != NULL; + pre_ds = ds, ds = ds->next) + if (strcmp(disk_name, ds->name) == 0) + break; + + if (ds == NULL) { + if ((ds = (diskstats_t *)calloc(1, sizeof(diskstats_t))) == NULL) + continue; + + if ((ds->name = strdup(disk_name)) == NULL) { + free(ds); + continue; + } + + if (pre_ds == NULL) + disklist = ds; + else + pre_ds->next = ds; + } + + is_disk = 0; + if (numfields == 7) { + /* Kernel 2.6, Partition */ + read_ops = atoll(fields[3]); + read_sectors = atoll(fields[4]); + write_ops = atoll(fields[5]); + write_sectors = atoll(fields[6]); + } else if (numfields == (14 + fieldshift)) { + read_ops = atoll(fields[3 + fieldshift]); + write_ops = atoll(fields[7 + fieldshift]); + + read_sectors = atoll(fields[5 + fieldshift]); + write_sectors = atoll(fields[9 + fieldshift]); + + if ((fieldshift == 0) || (minor == 0)) { + is_disk = 1; + read_merged = atoll(fields[4 + fieldshift]); + read_time = atoll(fields[6 + fieldshift]); + write_merged = atoll(fields[8 + fieldshift]); + write_time = atoll(fields[10 + fieldshift]); + + in_progress = atof(fields[11 + fieldshift]); + + io_time = atof(fields[12 + fieldshift]); + weighted_time = atof(fields[13 + fieldshift]); + } + } else { + DEBUG("numfields = %i; => unknown file format.", numfields); + continue; + } + + { + derive_t diff_read_sectors; + derive_t diff_write_sectors; + + /* If the counter wraps around, it's only 32 bits.. */ + if (read_sectors < ds->read_sectors) + diff_read_sectors = 1 + read_sectors + (UINT_MAX - ds->read_sectors); + else + diff_read_sectors = read_sectors - ds->read_sectors; + if (write_sectors < ds->write_sectors) + diff_write_sectors = 1 + write_sectors + (UINT_MAX - ds->write_sectors); + else + diff_write_sectors = write_sectors - ds->write_sectors; + + ds->read_bytes += 512 * diff_read_sectors; + ds->write_bytes += 512 * diff_write_sectors; + ds->read_sectors = read_sectors; + ds->write_sectors = write_sectors; + } + + /* Calculate the average time an io-op needs to complete */ + if (is_disk) { + derive_t diff_read_ops; + derive_t diff_write_ops; + derive_t diff_read_time; + derive_t diff_write_time; + + if (read_ops < ds->read_ops) + diff_read_ops = 1 + read_ops + (UINT_MAX - ds->read_ops); + else + diff_read_ops = read_ops - ds->read_ops; + DEBUG("disk plugin: disk_name = %s; read_ops = %" PRIi64 "; " + "ds->read_ops = %" PRIi64 "; diff_read_ops = %" PRIi64 ";", + disk_name, read_ops, ds->read_ops, diff_read_ops); + + if (write_ops < ds->write_ops) + diff_write_ops = 1 + write_ops + (UINT_MAX - ds->write_ops); + else + diff_write_ops = write_ops - ds->write_ops; + + if (read_time < ds->read_time) + diff_read_time = 1 + read_time + (UINT_MAX - ds->read_time); + else + diff_read_time = read_time - ds->read_time; + + if (write_time < ds->write_time) + diff_write_time = 1 + write_time + (UINT_MAX - ds->write_time); + else + diff_write_time = write_time - ds->write_time; + + if (diff_read_ops != 0) + ds->avg_read_time += disk_calc_time_incr(diff_read_time, diff_read_ops); + if (diff_write_ops != 0) + ds->avg_write_time += + disk_calc_time_incr(diff_write_time, diff_write_ops); + + ds->read_ops = read_ops; + ds->read_time = read_time; + ds->write_ops = write_ops; + ds->write_time = write_time; + + if (read_merged || write_merged) + ds->has_merged = 1; + + if (in_progress) + ds->has_in_progress = 1; + + if (io_time) + ds->has_io_time = 1; + + } /* if (is_disk) */ + + /* Don't write to the RRDs if we've just started.. */ + ds->poll_count++; + if (ds->poll_count <= 2) { + DEBUG("disk plugin: (ds->poll_count = %i) <= " + "(min_poll_count = 2); => Not writing.", + ds->poll_count); + continue; + } + + if ((read_ops == 0) && (write_ops == 0)) { + DEBUG("disk plugin: ((read_ops == 0) && " + "(write_ops == 0)); => Not writing."); + continue; + } + + output_name = disk_name; #if HAVE_LIBUDEV - char *alt_name = NULL; - if (conf_udev_name_attr != NULL) - { - alt_name = disk_udev_attr_name (handle_udev, disk_name, conf_udev_name_attr); - if (alt_name != NULL) - output_name = alt_name; - } + char *alt_name = NULL; + if (conf_udev_name_attr != NULL) { + alt_name = + disk_udev_attr_name(handle_udev, disk_name, conf_udev_name_attr); + if (alt_name != NULL) + output_name = alt_name; + } #endif - if (ignorelist_match (ignorelist, output_name) != 0) - { + if (ignorelist_match(ignorelist, output_name) != 0) { #if HAVE_LIBUDEV - /* release udev-based alternate name, if allocated */ - sfree (alt_name); + /* release udev-based alternate name, if allocated */ + sfree(alt_name); #endif - continue; - } - - if ((ds->read_bytes != 0) || (ds->write_bytes != 0)) - disk_submit (output_name, "disk_octets", - ds->read_bytes, ds->write_bytes); - - if ((ds->read_ops != 0) || (ds->write_ops != 0)) - disk_submit (output_name, "disk_ops", - read_ops, write_ops); - - if ((ds->avg_read_time != 0) || (ds->avg_write_time != 0)) - disk_submit (output_name, "disk_time", - ds->avg_read_time, ds->avg_write_time); - - if (is_disk) - { - if (ds->has_merged) - disk_submit (output_name, "disk_merged", - read_merged, write_merged); - if (ds->has_in_progress) - submit_in_progress (output_name, in_progress); - if (ds->has_io_time) - submit_io_time (output_name, io_time, weighted_time); - } /* if (is_disk) */ + continue; + } + + if ((ds->read_bytes != 0) || (ds->write_bytes != 0)) + disk_submit(output_name, "disk_octets", ds->read_bytes, ds->write_bytes); + + if ((ds->read_ops != 0) || (ds->write_ops != 0)) + disk_submit(output_name, "disk_ops", read_ops, write_ops); + + if ((ds->avg_read_time != 0) || (ds->avg_write_time != 0)) + disk_submit(output_name, "disk_time", ds->avg_read_time, + ds->avg_write_time); + + if (is_disk) { + if (ds->has_merged) + disk_submit(output_name, "disk_merged", read_merged, write_merged); + if (ds->has_in_progress) + submit_in_progress(output_name, in_progress); + if (ds->has_io_time) + submit_io_time(output_name, io_time, weighted_time); + } /* if (is_disk) */ #if HAVE_LIBUDEV - /* release udev-based alternate name, if allocated */ - sfree (alt_name); + /* release udev-based alternate name, if allocated */ + sfree(alt_name); #endif - } /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */ - + } /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */ - fclose (fh); + fclose(fh); /* #endif defined(KERNEL_LINUX) */ #elif HAVE_LIBKSTAT -# if HAVE_KSTAT_IO_T_WRITES && HAVE_KSTAT_IO_T_NWRITES && HAVE_KSTAT_IO_T_WTIME -# define KIO_ROCTETS reads -# define KIO_WOCTETS writes -# define KIO_ROPS nreads -# define KIO_WOPS nwrites -# define KIO_RTIME rtime -# define KIO_WTIME wtime -# elif HAVE_KSTAT_IO_T_NWRITTEN && HAVE_KSTAT_IO_T_WRITES && HAVE_KSTAT_IO_T_WTIME -# define KIO_ROCTETS nread -# define KIO_WOCTETS nwritten -# define KIO_ROPS reads -# define KIO_WOPS writes -# define KIO_RTIME rtime -# define KIO_WTIME wtime -# else -# error "kstat_io_t does not have the required members" -# endif - static kstat_io_t kio; - - if (kc == NULL) - return (-1); - - for (int i = 0; i < numdisk; i++) - { - if (kstat_read (kc, ksp[i], &kio) == -1) - continue; - - if (strncmp (ksp[i]->ks_class, "disk", 4) == 0) - { - if (ignorelist_match (ignorelist, ksp[i]->ks_name) != 0) - continue; - - disk_submit (ksp[i]->ks_name, "disk_octets", - kio.KIO_ROCTETS, kio.KIO_WOCTETS); - disk_submit (ksp[i]->ks_name, "disk_ops", - kio.KIO_ROPS, kio.KIO_WOPS); - /* FIXME: Convert this to microseconds if necessary */ - disk_submit (ksp[i]->ks_name, "disk_time", - kio.KIO_RTIME, kio.KIO_WTIME); - } - else if (strncmp (ksp[i]->ks_class, "partition", 9) == 0) - { - if (ignorelist_match (ignorelist, ksp[i]->ks_name) != 0) - continue; - - disk_submit (ksp[i]->ks_name, "disk_octets", - kio.KIO_ROCTETS, kio.KIO_WOCTETS); - disk_submit (ksp[i]->ks_name, "disk_ops", - kio.KIO_ROPS, kio.KIO_WOPS); - } - } +#if HAVE_KSTAT_IO_T_WRITES && HAVE_KSTAT_IO_T_NWRITES && HAVE_KSTAT_IO_T_WTIME +#define KIO_ROCTETS reads +#define KIO_WOCTETS writes +#define KIO_ROPS nreads +#define KIO_WOPS nwrites +#define KIO_RTIME rtime +#define KIO_WTIME wtime +#elif HAVE_KSTAT_IO_T_NWRITTEN && HAVE_KSTAT_IO_T_WRITES && \ + HAVE_KSTAT_IO_T_WTIME +#define KIO_ROCTETS nread +#define KIO_WOCTETS nwritten +#define KIO_ROPS reads +#define KIO_WOPS writes +#define KIO_RTIME rtime +#define KIO_WTIME wtime +#else +#error "kstat_io_t does not have the required members" +#endif + static kstat_io_t kio; + + if (kc == NULL) + return (-1); + + for (int i = 0; i < numdisk; i++) { + if (kstat_read(kc, ksp[i], &kio) == -1) + continue; + + if (strncmp(ksp[i]->ks_class, "disk", 4) == 0) { + if (ignorelist_match(ignorelist, ksp[i]->ks_name) != 0) + continue; + + disk_submit(ksp[i]->ks_name, "disk_octets", kio.KIO_ROCTETS, + kio.KIO_WOCTETS); + disk_submit(ksp[i]->ks_name, "disk_ops", kio.KIO_ROPS, kio.KIO_WOPS); + /* FIXME: Convert this to microseconds if necessary */ + disk_submit(ksp[i]->ks_name, "disk_time", kio.KIO_RTIME, kio.KIO_WTIME); + } else if (strncmp(ksp[i]->ks_class, "partition", 9) == 0) { + if (ignorelist_match(ignorelist, ksp[i]->ks_name) != 0) + continue; + + disk_submit(ksp[i]->ks_name, "disk_octets", kio.KIO_ROCTETS, + kio.KIO_WOCTETS); + disk_submit(ksp[i]->ks_name, "disk_ops", kio.KIO_ROPS, kio.KIO_WOPS); + } + } /* #endif defined(HAVE_LIBKSTAT) */ #elif defined(HAVE_LIBSTATGRAB) - sg_disk_io_stats *ds; -# if HAVE_LIBSTATGRAB_0_90 - size_t disks; -# else - int disks; + sg_disk_io_stats *ds; +#if HAVE_LIBSTATGRAB_0_90 + size_t disks; +#else + int disks; #endif - char name[DATA_MAX_NAME_LEN]; + char name[DATA_MAX_NAME_LEN]; - if ((ds = sg_get_disk_io_stats(&disks)) == NULL) - return (0); + if ((ds = sg_get_disk_io_stats(&disks)) == NULL) + return (0); - for (int counter = 0; counter < disks; counter++) { - strncpy(name, ds->disk_name, sizeof(name)); - name[sizeof(name)-1] = '\0'; /* strncpy doesn't terminate longer strings */ + for (int counter = 0; counter < disks; counter++) { + strncpy(name, ds->disk_name, sizeof(name)); + name[sizeof(name) - 1] = + '\0'; /* strncpy doesn't terminate longer strings */ - if (ignorelist_match (ignorelist, name) != 0) { - ds++; - continue; - } + if (ignorelist_match(ignorelist, name) != 0) { + ds++; + continue; + } - disk_submit (name, "disk_octets", ds->read_bytes, ds->write_bytes); - ds++; - } + disk_submit(name, "disk_octets", ds->read_bytes, ds->write_bytes); + ds++; + } /* #endif defined(HAVE_LIBSTATGRAB) */ #elif defined(HAVE_PERFSTAT) - derive_t read_sectors; - derive_t write_sectors; - derive_t read_time; - derive_t write_time; - derive_t read_ops; - derive_t write_ops; - perfstat_id_t firstpath; - int rnumdisk; - - if ((numdisk = perfstat_disk(NULL, NULL, sizeof(perfstat_disk_t), 0)) < 0) - { - char errbuf[1024]; - WARNING ("disk plugin: perfstat_disk: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - if (numdisk != pnumdisk || stat_disk==NULL) { - if (stat_disk!=NULL) - free(stat_disk); - stat_disk = (perfstat_disk_t *)calloc(numdisk, sizeof(perfstat_disk_t)); - } - pnumdisk = numdisk; - - firstpath.name[0]='\0'; - if ((rnumdisk = perfstat_disk(&firstpath, stat_disk, sizeof(perfstat_disk_t), numdisk)) < 0) - { - char errbuf[1024]; - WARNING ("disk plugin: perfstat_disk : %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - for (int i = 0; i < rnumdisk; i++) - { - if (ignorelist_match (ignorelist, stat_disk[i].name) != 0) - continue; - - read_sectors = stat_disk[i].rblks*stat_disk[i].bsize; - write_sectors = stat_disk[i].wblks*stat_disk[i].bsize; - disk_submit (stat_disk[i].name, "disk_octets", read_sectors, write_sectors); - - read_ops = stat_disk[i].xrate; - write_ops = stat_disk[i].xfers - stat_disk[i].xrate; - disk_submit (stat_disk[i].name, "disk_ops", read_ops, write_ops); - - read_time = stat_disk[i].rserv; - read_time *= ((double)(_system_configuration.Xint)/(double)(_system_configuration.Xfrac)) / 1000000.0; - write_time = stat_disk[i].wserv; - write_time *= ((double)(_system_configuration.Xint)/(double)(_system_configuration.Xfrac)) / 1000000.0; - disk_submit (stat_disk[i].name, "disk_time", read_time, write_time); - } + derive_t read_sectors; + derive_t write_sectors; + derive_t read_time; + derive_t write_time; + derive_t read_ops; + derive_t write_ops; + perfstat_id_t firstpath; + int rnumdisk; + + if ((numdisk = perfstat_disk(NULL, NULL, sizeof(perfstat_disk_t), 0)) < 0) { + char errbuf[1024]; + WARNING("disk plugin: perfstat_disk: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + if (numdisk != pnumdisk || stat_disk == NULL) { + if (stat_disk != NULL) + free(stat_disk); + stat_disk = (perfstat_disk_t *)calloc(numdisk, sizeof(perfstat_disk_t)); + } + pnumdisk = numdisk; + + firstpath.name[0] = '\0'; + if ((rnumdisk = perfstat_disk(&firstpath, stat_disk, sizeof(perfstat_disk_t), + numdisk)) < 0) { + char errbuf[1024]; + WARNING("disk plugin: perfstat_disk : %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + for (int i = 0; i < rnumdisk; i++) { + if (ignorelist_match(ignorelist, stat_disk[i].name) != 0) + continue; + + read_sectors = stat_disk[i].rblks * stat_disk[i].bsize; + write_sectors = stat_disk[i].wblks * stat_disk[i].bsize; + disk_submit(stat_disk[i].name, "disk_octets", read_sectors, write_sectors); + + read_ops = stat_disk[i].xrate; + write_ops = stat_disk[i].xfers - stat_disk[i].xrate; + disk_submit(stat_disk[i].name, "disk_ops", read_ops, write_ops); + + read_time = stat_disk[i].rserv; + read_time *= ((double)(_system_configuration.Xint) / + (double)(_system_configuration.Xfrac)) / + 1000000.0; + write_time = stat_disk[i].wserv; + write_time *= ((double)(_system_configuration.Xint) / + (double)(_system_configuration.Xfrac)) / + 1000000.0; + disk_submit(stat_disk[i].name, "disk_time", read_time, write_time); + } #endif /* defined(HAVE_PERFSTAT) */ - return (0); + return (0); } /* int disk_read */ -void module_register (void) -{ - plugin_register_config ("disk", disk_config, - config_keys, config_keys_num); - plugin_register_init ("disk", disk_init); - plugin_register_shutdown ("disk", disk_shutdown); - plugin_register_read ("disk", disk_read); +void module_register(void) { + plugin_register_config("disk", disk_config, config_keys, config_keys_num); + plugin_register_init("disk", disk_init); + plugin_register_shutdown("disk", disk_shutdown); + plugin_register_read("disk", disk_read); } /* void module_register */ diff --git a/src/dns.c b/src/dns.c index 4a5c0fa3..e3208a68 100644 --- a/src/dns.c +++ b/src/dns.c @@ -29,430 +29,374 @@ #include "common.h" #include "plugin.h" -#include "utils_dns.h" #include +#include "utils_dns.h" #include #ifdef HAVE_SYS_CAPABILITY_H -# include +#include #endif /* * Private data types */ -struct counter_list_s -{ - unsigned int key; - unsigned int value; - struct counter_list_s *next; +struct counter_list_s { + unsigned int key; + unsigned int value; + struct counter_list_s *next; }; typedef struct counter_list_s counter_list_t; /* * Private variables */ -static const char *config_keys[] = -{ - "Interface", - "IgnoreSource", - "SelectNumericQueryTypes" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"Interface", "IgnoreSource", + "SelectNumericQueryTypes"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static int select_numeric_qtype = 1; #define PCAP_SNAPLEN 1460 -static char *pcap_device = NULL; +static char *pcap_device = NULL; -static derive_t tr_queries; -static derive_t tr_responses; +static derive_t tr_queries; +static derive_t tr_responses; static counter_list_t *qtype_list; static counter_list_t *opcode_list; static counter_list_t *rcode_list; -static pthread_t listen_thread; -static int listen_thread_init = 0; +static pthread_t listen_thread; +static int listen_thread_init = 0; /* The `traffic' mutex if for `tr_queries' and `tr_responses' */ static pthread_mutex_t traffic_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t qtype_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t opcode_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t rcode_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t qtype_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t opcode_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t rcode_mutex = PTHREAD_MUTEX_INITIALIZER; /* * Private functions */ -static counter_list_t *counter_list_search (counter_list_t **list, unsigned int key) -{ - counter_list_t *entry; +static counter_list_t *counter_list_search(counter_list_t **list, + unsigned int key) { + counter_list_t *entry; - for (entry = *list; entry != NULL; entry = entry->next) - if (entry->key == key) - break; + for (entry = *list; entry != NULL; entry = entry->next) + if (entry->key == key) + break; - return (entry); + return (entry); } -static counter_list_t *counter_list_create (counter_list_t **list, - unsigned int key, unsigned int value) -{ - counter_list_t *entry; +static counter_list_t *counter_list_create(counter_list_t **list, + unsigned int key, + unsigned int value) { + counter_list_t *entry; - entry = calloc (1, sizeof (*entry)); - if (entry == NULL) - return (NULL); + entry = calloc(1, sizeof(*entry)); + if (entry == NULL) + return (NULL); - entry->key = key; - entry->value = value; + entry->key = key; + entry->value = value; - if (*list == NULL) - { - *list = entry; - } - else - { - counter_list_t *last; + if (*list == NULL) { + *list = entry; + } else { + counter_list_t *last; - last = *list; - while (last->next != NULL) - last = last->next; + last = *list; + while (last->next != NULL) + last = last->next; - last->next = entry; - } + last->next = entry; + } - return (entry); + return (entry); } -static void counter_list_add (counter_list_t **list, - unsigned int key, unsigned int increment) -{ - counter_list_t *entry; - - entry = counter_list_search (list, key); - - if (entry != NULL) - { - entry->value += increment; - } - else - { - counter_list_create (list, key, increment); - } +static void counter_list_add(counter_list_t **list, unsigned int key, + unsigned int increment) { + counter_list_t *entry; + + entry = counter_list_search(list, key); + + if (entry != NULL) { + entry->value += increment; + } else { + counter_list_create(list, key, increment); + } } -static int dns_config (const char *key, const char *value) -{ - if (strcasecmp (key, "Interface") == 0) - { - if (pcap_device != NULL) - free (pcap_device); - if ((pcap_device = strdup (value)) == NULL) - return (1); - } - else if (strcasecmp (key, "IgnoreSource") == 0) - { - if (value != NULL) - ignore_list_add_name (value); - } - else if (strcasecmp (key, "SelectNumericQueryTypes") == 0) - { - if ((value != NULL) && IS_FALSE (value)) - select_numeric_qtype = 0; - else - select_numeric_qtype = 1; - } - else - { - return (-1); - } - - return (0); +static int dns_config(const char *key, const char *value) { + if (strcasecmp(key, "Interface") == 0) { + if (pcap_device != NULL) + free(pcap_device); + if ((pcap_device = strdup(value)) == NULL) + return (1); + } else if (strcasecmp(key, "IgnoreSource") == 0) { + if (value != NULL) + ignore_list_add_name(value); + } else if (strcasecmp(key, "SelectNumericQueryTypes") == 0) { + if ((value != NULL) && IS_FALSE(value)) + select_numeric_qtype = 0; + else + select_numeric_qtype = 1; + } else { + return (-1); + } + + return (0); } -static void dns_child_callback (const rfc1035_header_t *dns) -{ - if (dns->qr == 0) - { - /* This is a query */ - int skip = 0; - if (!select_numeric_qtype) - { - const char *str = qtype_str(dns->qtype); - if ((str == NULL) || (str[0] == '#')) - skip = 1; - } - - pthread_mutex_lock (&traffic_mutex); - tr_queries += dns->length; - pthread_mutex_unlock (&traffic_mutex); - - if (skip == 0) - { - pthread_mutex_lock (&qtype_mutex); - counter_list_add (&qtype_list, dns->qtype, 1); - pthread_mutex_unlock (&qtype_mutex); - } - } - else - { - /* This is a reply */ - pthread_mutex_lock (&traffic_mutex); - tr_responses += dns->length; - pthread_mutex_unlock (&traffic_mutex); - - pthread_mutex_lock (&rcode_mutex); - counter_list_add (&rcode_list, dns->rcode, 1); - pthread_mutex_unlock (&rcode_mutex); - } - - /* FIXME: Are queries, replies or both interesting? */ - pthread_mutex_lock (&opcode_mutex); - counter_list_add (&opcode_list, dns->opcode, 1); - pthread_mutex_unlock (&opcode_mutex); +static void dns_child_callback(const rfc1035_header_t *dns) { + if (dns->qr == 0) { + /* This is a query */ + int skip = 0; + if (!select_numeric_qtype) { + const char *str = qtype_str(dns->qtype); + if ((str == NULL) || (str[0] == '#')) + skip = 1; + } + + pthread_mutex_lock(&traffic_mutex); + tr_queries += dns->length; + pthread_mutex_unlock(&traffic_mutex); + + if (skip == 0) { + pthread_mutex_lock(&qtype_mutex); + counter_list_add(&qtype_list, dns->qtype, 1); + pthread_mutex_unlock(&qtype_mutex); + } + } else { + /* This is a reply */ + pthread_mutex_lock(&traffic_mutex); + tr_responses += dns->length; + pthread_mutex_unlock(&traffic_mutex); + + pthread_mutex_lock(&rcode_mutex); + counter_list_add(&rcode_list, dns->rcode, 1); + pthread_mutex_unlock(&rcode_mutex); + } + + /* FIXME: Are queries, replies or both interesting? */ + pthread_mutex_lock(&opcode_mutex); + counter_list_add(&opcode_list, dns->opcode, 1); + pthread_mutex_unlock(&opcode_mutex); } -static int dns_run_pcap_loop (void) -{ - pcap_t *pcap_obj; - char pcap_error[PCAP_ERRBUF_SIZE]; - struct bpf_program fp = { 0 }; - - int status; - - /* Don't block any signals */ - { - sigset_t sigmask; - sigemptyset (&sigmask); - pthread_sigmask (SIG_SETMASK, &sigmask, NULL); - } - - /* Passing `pcap_device == NULL' is okay and the same as passign "any" */ - DEBUG ("dns plugin: Creating PCAP object.."); - pcap_obj = pcap_open_live ((pcap_device != NULL) ? pcap_device : "any", - PCAP_SNAPLEN, - 0 /* Not promiscuous */, - (int) CDTIME_T_TO_MS (plugin_get_interval () / 2), - pcap_error); - if (pcap_obj == NULL) - { - ERROR ("dns plugin: Opening interface `%s' " - "failed: %s", - (pcap_device != NULL) ? pcap_device : "any", - pcap_error); - return (PCAP_ERROR); - } - - status = pcap_compile (pcap_obj, &fp, "udp port 53", 1, 0); - if (status < 0) - { - ERROR ("dns plugin: pcap_compile failed: %s", - pcap_statustostr (status)); - return (status); - } - - status = pcap_setfilter (pcap_obj, &fp); - if (status < 0) - { - ERROR ("dns plugin: pcap_setfilter failed: %s", - pcap_statustostr (status)); - return (status); - } - - DEBUG ("dns plugin: PCAP object created."); - - dnstop_set_pcap_obj (pcap_obj); - dnstop_set_callback (dns_child_callback); - - status = pcap_loop (pcap_obj, - -1 /* loop forever */, - handle_pcap /* callback */, - NULL /* user data */); - INFO ("dns plugin: pcap_loop exited with status %i.", status); - /* We need to handle "PCAP_ERROR" specially because libpcap currently - * doesn't return PCAP_ERROR_IFACE_NOT_UP for compatibility reasons. */ - if (status == PCAP_ERROR) - status = PCAP_ERROR_IFACE_NOT_UP; - - pcap_close (pcap_obj); - return (status); +static int dns_run_pcap_loop(void) { + pcap_t *pcap_obj; + char pcap_error[PCAP_ERRBUF_SIZE]; + struct bpf_program fp = {0}; + + int status; + + /* Don't block any signals */ + { + sigset_t sigmask; + sigemptyset(&sigmask); + pthread_sigmask(SIG_SETMASK, &sigmask, NULL); + } + + /* Passing `pcap_device == NULL' is okay and the same as passign "any" */ + DEBUG("dns plugin: Creating PCAP object.."); + pcap_obj = pcap_open_live((pcap_device != NULL) ? pcap_device : "any", + PCAP_SNAPLEN, 0 /* Not promiscuous */, + (int)CDTIME_T_TO_MS(plugin_get_interval() / 2), + pcap_error); + if (pcap_obj == NULL) { + ERROR("dns plugin: Opening interface `%s' " + "failed: %s", + (pcap_device != NULL) ? pcap_device : "any", pcap_error); + return (PCAP_ERROR); + } + + status = pcap_compile(pcap_obj, &fp, "udp port 53", 1, 0); + if (status < 0) { + ERROR("dns plugin: pcap_compile failed: %s", pcap_statustostr(status)); + return (status); + } + + status = pcap_setfilter(pcap_obj, &fp); + if (status < 0) { + ERROR("dns plugin: pcap_setfilter failed: %s", pcap_statustostr(status)); + return (status); + } + + DEBUG("dns plugin: PCAP object created."); + + dnstop_set_pcap_obj(pcap_obj); + dnstop_set_callback(dns_child_callback); + + status = pcap_loop(pcap_obj, -1 /* loop forever */, + handle_pcap /* callback */, NULL /* user data */); + INFO("dns plugin: pcap_loop exited with status %i.", status); + /* We need to handle "PCAP_ERROR" specially because libpcap currently + * doesn't return PCAP_ERROR_IFACE_NOT_UP for compatibility reasons. */ + if (status == PCAP_ERROR) + status = PCAP_ERROR_IFACE_NOT_UP; + + pcap_close(pcap_obj); + return (status); } /* int dns_run_pcap_loop */ -static int dns_sleep_one_interval (void) /* {{{ */ +static int dns_sleep_one_interval(void) /* {{{ */ { - struct timespec ts = CDTIME_T_TO_TIMESPEC (plugin_get_interval ()); - while (nanosleep (&ts, &ts) != 0) - { - if ((errno == EINTR) || (errno == EAGAIN)) - continue; + struct timespec ts = CDTIME_T_TO_TIMESPEC(plugin_get_interval()); + while (nanosleep(&ts, &ts) != 0) { + if ((errno == EINTR) || (errno == EAGAIN)) + continue; - return (errno); - } + return (errno); + } - return (0); + return (0); } /* }}} int dns_sleep_one_interval */ -static void *dns_child_loop (__attribute__((unused)) void *dummy) /* {{{ */ +static void *dns_child_loop(__attribute__((unused)) void *dummy) /* {{{ */ { - int status; + int status; - while (42) - { - status = dns_run_pcap_loop (); - if (status != PCAP_ERROR_IFACE_NOT_UP) - break; + while (42) { + status = dns_run_pcap_loop(); + if (status != PCAP_ERROR_IFACE_NOT_UP) + break; - dns_sleep_one_interval (); - } + dns_sleep_one_interval(); + } - if (status != PCAP_ERROR_BREAK) - ERROR ("dns plugin: PCAP returned error %s.", - pcap_statustostr (status)); + if (status != PCAP_ERROR_BREAK) + ERROR("dns plugin: PCAP returned error %s.", pcap_statustostr(status)); - listen_thread_init = 0; - return (NULL); + listen_thread_init = 0; + return (NULL); } /* }}} void *dns_child_loop */ -static int dns_init (void) -{ - /* clean up an old thread */ - int status; +static int dns_init(void) { + /* clean up an old thread */ + int status; - pthread_mutex_lock (&traffic_mutex); - tr_queries = 0; - tr_responses = 0; - pthread_mutex_unlock (&traffic_mutex); + pthread_mutex_lock(&traffic_mutex); + tr_queries = 0; + tr_responses = 0; + pthread_mutex_unlock(&traffic_mutex); - if (listen_thread_init != 0) - return (-1); + if (listen_thread_init != 0) + return (-1); - status = plugin_thread_create (&listen_thread, NULL, dns_child_loop, - (void *) 0, "dns listen"); - if (status != 0) - { - char errbuf[1024]; - ERROR ("dns plugin: pthread_create failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } + status = plugin_thread_create(&listen_thread, NULL, dns_child_loop, (void *)0, + "dns listen"); + if (status != 0) { + char errbuf[1024]; + ERROR("dns plugin: pthread_create failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } - listen_thread_init = 1; + listen_thread_init = 1; #if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_NET_RAW) - if (check_capability (CAP_NET_RAW) != 0) - { - if (getuid () == 0) - WARNING ("dns plugin: Running collectd as root, but the CAP_NET_RAW " - "capability is missing. The plugin's read function will probably " - "fail. Is your init system dropping capabilities?"); - else - WARNING ("dns plugin: collectd doesn't have the CAP_NET_RAW capability. " - "If you don't want to run collectd as root, try running \"setcap " - "cap_net_raw=ep\" on the collectd binary."); - } + if (check_capability(CAP_NET_RAW) != 0) { + if (getuid() == 0) + WARNING("dns plugin: Running collectd as root, but the CAP_NET_RAW " + "capability is missing. The plugin's read function will probably " + "fail. Is your init system dropping capabilities?"); + else + WARNING("dns plugin: collectd doesn't have the CAP_NET_RAW capability. " + "If you don't want to run collectd as root, try running \"setcap " + "cap_net_raw=ep\" on the collectd binary."); + } #endif - return (0); + return (0); } /* int dns_init */ -static void submit_derive (const char *type, const char *type_instance, - derive_t value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void submit_derive(const char *type, const char *type_instance, + derive_t value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .derive = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "dns", sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + vl.values = &(value_t){.derive = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "dns", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* void submit_derive */ -static void submit_octets (derive_t queries, derive_t responses) -{ - value_t values[] = { - { .derive = queries }, - { .derive = responses }, - }; - value_list_t vl = VALUE_LIST_INIT; - - vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - sstrncpy (vl.plugin, "dns", sizeof (vl.plugin)); - sstrncpy (vl.type, "dns_octets", sizeof (vl.type)); - - plugin_dispatch_values (&vl); +static void submit_octets(derive_t queries, derive_t responses) { + value_t values[] = { + {.derive = queries}, {.derive = responses}, + }; + value_list_t vl = VALUE_LIST_INIT; + + vl.values = values; + vl.values_len = STATIC_ARRAY_SIZE(values); + sstrncpy(vl.plugin, "dns", sizeof(vl.plugin)); + sstrncpy(vl.type, "dns_octets", sizeof(vl.type)); + + plugin_dispatch_values(&vl); } /* void submit_octets */ -static int dns_read (void) -{ - unsigned int keys[T_MAX]; - unsigned int values[T_MAX]; - int len; - - counter_list_t *ptr; - - pthread_mutex_lock (&traffic_mutex); - values[0] = tr_queries; - values[1] = tr_responses; - pthread_mutex_unlock (&traffic_mutex); - - if ((values[0] != 0) || (values[1] != 0)) - submit_octets (values[0], values[1]); - - pthread_mutex_lock (&qtype_mutex); - for (ptr = qtype_list, len = 0; - (ptr != NULL) && (len < T_MAX); - ptr = ptr->next, len++) - { - keys[len] = ptr->key; - values[len] = ptr->value; - } - pthread_mutex_unlock (&qtype_mutex); - - for (int i = 0; i < len; i++) - { - DEBUG ("dns plugin: qtype = %u; counter = %u;", keys[i], values[i]); - submit_derive ("dns_qtype", qtype_str (keys[i]), values[i]); - } - - pthread_mutex_lock (&opcode_mutex); - for (ptr = opcode_list, len = 0; - (ptr != NULL) && (len < T_MAX); - ptr = ptr->next, len++) - { - keys[len] = ptr->key; - values[len] = ptr->value; - } - pthread_mutex_unlock (&opcode_mutex); - - for (int i = 0; i < len; i++) - { - DEBUG ("dns plugin: opcode = %u; counter = %u;", keys[i], values[i]); - submit_derive ("dns_opcode", opcode_str (keys[i]), values[i]); - } - - pthread_mutex_lock (&rcode_mutex); - for (ptr = rcode_list, len = 0; - (ptr != NULL) && (len < T_MAX); - ptr = ptr->next, len++) - { - keys[len] = ptr->key; - values[len] = ptr->value; - } - pthread_mutex_unlock (&rcode_mutex); - - for (int i = 0; i < len; i++) - { - DEBUG ("dns plugin: rcode = %u; counter = %u;", keys[i], values[i]); - submit_derive ("dns_rcode", rcode_str (keys[i]), values[i]); - } - - return (0); +static int dns_read(void) { + unsigned int keys[T_MAX]; + unsigned int values[T_MAX]; + int len; + + counter_list_t *ptr; + + pthread_mutex_lock(&traffic_mutex); + values[0] = tr_queries; + values[1] = tr_responses; + pthread_mutex_unlock(&traffic_mutex); + + if ((values[0] != 0) || (values[1] != 0)) + submit_octets(values[0], values[1]); + + pthread_mutex_lock(&qtype_mutex); + for (ptr = qtype_list, len = 0; (ptr != NULL) && (len < T_MAX); + ptr = ptr->next, len++) { + keys[len] = ptr->key; + values[len] = ptr->value; + } + pthread_mutex_unlock(&qtype_mutex); + + for (int i = 0; i < len; i++) { + DEBUG("dns plugin: qtype = %u; counter = %u;", keys[i], values[i]); + submit_derive("dns_qtype", qtype_str(keys[i]), values[i]); + } + + pthread_mutex_lock(&opcode_mutex); + for (ptr = opcode_list, len = 0; (ptr != NULL) && (len < T_MAX); + ptr = ptr->next, len++) { + keys[len] = ptr->key; + values[len] = ptr->value; + } + pthread_mutex_unlock(&opcode_mutex); + + for (int i = 0; i < len; i++) { + DEBUG("dns plugin: opcode = %u; counter = %u;", keys[i], values[i]); + submit_derive("dns_opcode", opcode_str(keys[i]), values[i]); + } + + pthread_mutex_lock(&rcode_mutex); + for (ptr = rcode_list, len = 0; (ptr != NULL) && (len < T_MAX); + ptr = ptr->next, len++) { + keys[len] = ptr->key; + values[len] = ptr->value; + } + pthread_mutex_unlock(&rcode_mutex); + + for (int i = 0; i < len; i++) { + DEBUG("dns plugin: rcode = %u; counter = %u;", keys[i], values[i]); + submit_derive("dns_rcode", rcode_str(keys[i]), values[i]); + } + + return (0); } /* int dns_read */ -void module_register (void) -{ - plugin_register_config ("dns", dns_config, config_keys, config_keys_num); - plugin_register_init ("dns", dns_init); - plugin_register_read ("dns", dns_read); +void module_register(void) { + plugin_register_config("dns", dns_config, config_keys, config_keys_num); + plugin_register_init("dns", dns_init); + plugin_register_read("dns", dns_read); } /* void module_register */ diff --git a/src/drbd.c b/src/drbd.c index 40a3eb22..2ee16567 100644 --- a/src/drbd.c +++ b/src/drbd.c @@ -30,8 +30,8 @@ version: 8.3.11 (api:88/proto:86-96) srcversion: 71955441799F513ACA6DA60 0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate B r----- - ns:64363752 nr:0 dw:357799284 dr:846902273 al:34987022 bm:18062 lo:0 \ - pe:0 ua:0 ap:0 ep:1 wo:f oos:0 + ns:64363752 nr:0 dw:357799284 dr:846902273 al:34987022 bm:18062 lo:0 \ + pe:0 ua:0 ap:0 ep:1 wo:f oos:0 */ #include "collectd.h" @@ -40,134 +40,112 @@ #include "plugin.h" static const char *drbd_stats = "/proc/drbd"; -static const char *drbd_names[] = -{ - "network_send", /* ns (network send) */ - "network_recv", /* nr (network receive) */ - "disk_write", /* dw (disk write) */ - "disk_read", /* dr (disk read) */ - "activity_log", /* al (activity log) */ - "bitmap", /* bm (bit map) */ - "local_count", /* lo (local count) */ - "pending", /* pe (pending) */ - "unacknowledged", /* ua (unacknowledged) */ - "app pending", /* ap (application pending) */ - "epochs", /* ep (epochs) */ - NULL, /* wo (write order) */ - "oos" /* oos (out of sync) */ +static const char *drbd_names[] = { + "network_send", /* ns (network send) */ + "network_recv", /* nr (network receive) */ + "disk_write", /* dw (disk write) */ + "disk_read", /* dr (disk read) */ + "activity_log", /* al (activity log) */ + "bitmap", /* bm (bit map) */ + "local_count", /* lo (local count) */ + "pending", /* pe (pending) */ + "unacknowledged", /* ua (unacknowledged) */ + "app pending", /* ap (application pending) */ + "epochs", /* ep (epochs) */ + NULL, /* wo (write order) */ + "oos" /* oos (out of sync) */ }; -static size_t drbd_names_num = STATIC_ARRAY_SIZE (drbd_names); - -static int drbd_init (void) -{ - return (0); -} - - -static int drbd_submit_fields (long int resource, - char **fields, size_t fields_num) -{ - char plugin_instance[DATA_MAX_NAME_LEN]; - value_t values[fields_num]; - value_list_t vl = VALUE_LIST_INIT; - - if (resource < 0) - { - WARNING ("drbd plugin: Unable to parse resource"); - return (EINVAL); - } - - if (fields_num != drbd_names_num) - { - WARNING ("drbd plugin: Wrong number of fields for " - "r%ld statistics. Expected %zu, got %zu.", - resource, drbd_names_num, fields_num); - return (EINVAL); - } - - ssnprintf (plugin_instance, sizeof (plugin_instance), "r%ld", - resource); - - for (size_t i = 0; i < drbd_names_num; i++) - { - char *data; - /* skip non numeric wo */ - if (strncmp(fields[i], "wo", 2) == 0) - continue; - data = strchr(fields[i], ':'); - if (data == NULL) - return (EINVAL); - (void) parse_value (++data, &values[i], DS_TYPE_DERIVE); - } - - vl.values_len = 1; - sstrncpy (vl.plugin, "drbd", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, plugin_instance, - sizeof (vl.plugin_instance)); - sstrncpy (vl.type, "drbd_resource", sizeof (vl.type)); - - for (size_t i = 0; i < fields_num; i++) - { - if (drbd_names[i] == NULL) - continue; - vl.values = values + i; - sstrncpy (vl.type_instance, drbd_names[i], - sizeof (vl.type_instance)); - plugin_dispatch_values (&vl); - } - - return (0); +static size_t drbd_names_num = STATIC_ARRAY_SIZE(drbd_names); + +static int drbd_init(void) { return (0); } + +static int drbd_submit_fields(long int resource, char **fields, + size_t fields_num) { + char plugin_instance[DATA_MAX_NAME_LEN]; + value_t values[fields_num]; + value_list_t vl = VALUE_LIST_INIT; + + if (resource < 0) { + WARNING("drbd plugin: Unable to parse resource"); + return (EINVAL); + } + + if (fields_num != drbd_names_num) { + WARNING("drbd plugin: Wrong number of fields for " + "r%ld statistics. Expected %zu, got %zu.", + resource, drbd_names_num, fields_num); + return (EINVAL); + } + + ssnprintf(plugin_instance, sizeof(plugin_instance), "r%ld", resource); + + for (size_t i = 0; i < drbd_names_num; i++) { + char *data; + /* skip non numeric wo */ + if (strncmp(fields[i], "wo", 2) == 0) + continue; + data = strchr(fields[i], ':'); + if (data == NULL) + return (EINVAL); + (void)parse_value(++data, &values[i], DS_TYPE_DERIVE); + } + + vl.values_len = 1; + sstrncpy(vl.plugin, "drbd", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "drbd_resource", sizeof(vl.type)); + + for (size_t i = 0; i < fields_num; i++) { + if (drbd_names[i] == NULL) + continue; + vl.values = values + i; + sstrncpy(vl.type_instance, drbd_names[i], sizeof(vl.type_instance)); + plugin_dispatch_values(&vl); + } + + return (0); } /* drbd_submit_fields */ -static int drbd_read (void) -{ - FILE *fh; - char buffer[256]; - - long int resource = -1; - char *fields[16]; - int fields_num = 0; - - fh = fopen (drbd_stats, "r"); - if (fh == NULL) - { - WARNING ("drbd plugin: Unable to open %s", drbd_stats); - return (EINVAL); - } - - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - fields_num = strsplit (buffer, - fields, STATIC_ARRAY_SIZE (fields)); - - /* ignore headers (first two iterations) */ - if ((strcmp(fields[0], "version:") == 0) || - (strcmp(fields[0], "srcversion:") == 0) || - (strcmp(fields[0], "GIT-hash:") == 0)) - { - continue; - } - - if (isdigit(fields[0][0])) - { - /* parse the resource line, next loop iteration - will submit values for this resource */ - resource = strtol(fields[0], NULL, 10); - } - else - { - /* handle stats data for the resource defined in the - previous iteration */ - drbd_submit_fields(resource, fields, fields_num); - } - } /* while (fgets) */ - - fclose (fh); - return (0); +static int drbd_read(void) { + FILE *fh; + char buffer[256]; + + long int resource = -1; + char *fields[16]; + int fields_num = 0; + + fh = fopen(drbd_stats, "r"); + if (fh == NULL) { + WARNING("drbd plugin: Unable to open %s", drbd_stats); + return (EINVAL); + } + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + fields_num = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + + /* ignore headers (first two iterations) */ + if ((strcmp(fields[0], "version:") == 0) || + (strcmp(fields[0], "srcversion:") == 0) || + (strcmp(fields[0], "GIT-hash:") == 0)) { + continue; + } + + if (isdigit(fields[0][0])) { + /* parse the resource line, next loop iteration + will submit values for this resource */ + resource = strtol(fields[0], NULL, 10); + } else { + /* handle stats data for the resource defined in the + previous iteration */ + drbd_submit_fields(resource, fields, fields_num); + } + } /* while (fgets) */ + + fclose(fh); + return (0); } /* void drbd_read */ -void module_register (void) -{ - plugin_register_init ("drbd", drbd_init); - plugin_register_read ("drbd", drbd_read); +void module_register(void) { + plugin_register_init("drbd", drbd_init); + plugin_register_read("drbd", drbd_read); } /* void module_register */ diff --git a/src/email.c b/src/email.c index 334e8764..b406d483 100644 --- a/src/email.c +++ b/src/email.c @@ -45,87 +45,82 @@ #include -#include #include +#include /* some systems (e.g. Darwin) seem to not define UNIX_PATH_MAX at all */ #ifndef UNIX_PATH_MAX -# define UNIX_PATH_MAX sizeof (((struct sockaddr_un *)0)->sun_path) +#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *)0)->sun_path) #endif /* UNIX_PATH_MAX */ #if HAVE_GRP_H -# include +#include #endif /* HAVE_GRP_H */ -#define SOCK_PATH LOCALSTATEDIR"/run/"PACKAGE_NAME"-email" +#define SOCK_PATH LOCALSTATEDIR "/run/" PACKAGE_NAME "-email" #define MAX_CONNS 5 #define MAX_CONNS_LIMIT 16384 -#define log_debug(...) DEBUG ("email: "__VA_ARGS__) -#define log_err(...) ERROR ("email: "__VA_ARGS__) -#define log_warn(...) WARNING ("email: "__VA_ARGS__) +#define log_debug(...) DEBUG("email: "__VA_ARGS__) +#define log_err(...) ERROR("email: "__VA_ARGS__) +#define log_warn(...) WARNING("email: "__VA_ARGS__) /* * Private data structures */ /* linked list of email and check types */ typedef struct type { - char *name; - int value; - struct type *next; + char *name; + int value; + struct type *next; } type_t; typedef struct { - type_t *head; - type_t *tail; + type_t *head; + type_t *tail; } type_list_t; /* collector thread control information */ typedef struct collector { - pthread_t thread; + pthread_t thread; - /* socket descriptor of the current/last connection */ - FILE *socket; + /* socket descriptor of the current/last connection */ + FILE *socket; } collector_t; /* linked list of pending connections */ typedef struct conn { - /* socket to read data from */ - FILE *socket; + /* socket to read data from */ + FILE *socket; - /* linked list of connections */ - struct conn *next; + /* linked list of connections */ + struct conn *next; } conn_t; typedef struct { - conn_t *head; - conn_t *tail; + conn_t *head; + conn_t *tail; } conn_list_t; /* * Private variables */ /* valid configuration file keys */ -static const char *config_keys[] = -{ - "SocketFile", - "SocketGroup", - "SocketPerms", - "MaxConns" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"SocketFile", "SocketGroup", "SocketPerms", + "MaxConns"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); /* socket configuration */ -static char *sock_file = NULL; +static char *sock_file = NULL; static char *sock_group = NULL; -static int sock_perms = S_IRWXU | S_IRWXG; -static int max_conns = MAX_CONNS; +static int sock_perms = S_IRWXU | S_IRWXG; +static int max_conns = MAX_CONNS; /* state of the plugin */ static int disabled = 0; /* thread managing "client" connections */ -static pthread_t connector = (pthread_t) 0; +static pthread_t connector = (pthread_t)0; static int connector_socket = -1; /* tell the collector threads that a new connection is available */ @@ -163,605 +158,566 @@ static type_list_t list_check_copy; /* * Private functions */ -static int email_config (const char *key, const char *value) -{ - if (0 == strcasecmp (key, "SocketFile")) { - if (NULL != sock_file) - free (sock_file); - sock_file = sstrdup (value); - } - else if (0 == strcasecmp (key, "SocketGroup")) { - if (NULL != sock_group) - free (sock_group); - sock_group = sstrdup (value); - } - else if (0 == strcasecmp (key, "SocketPerms")) { - /* the user is responsible for providing reasonable values */ - sock_perms = (int)strtol (value, NULL, 8); - } - else if (0 == strcasecmp (key, "MaxConns")) { - long int tmp = strtol (value, NULL, 0); - - if (tmp < 1) { - fprintf (stderr, "email plugin: `MaxConns' was set to invalid " - "value %li, will use default %i.\n", - tmp, MAX_CONNS); - ERROR ("email plugin: `MaxConns' was set to invalid " - "value %li, will use default %i.\n", - tmp, MAX_CONNS); - max_conns = MAX_CONNS; - } - else if (tmp > MAX_CONNS_LIMIT) { - fprintf (stderr, "email plugin: `MaxConns' was set to invalid " - "value %li, will use hardcoded limit %i.\n", - tmp, MAX_CONNS_LIMIT); - ERROR ("email plugin: `MaxConns' was set to invalid " - "value %li, will use hardcoded limit %i.\n", - tmp, MAX_CONNS_LIMIT); - max_conns = MAX_CONNS_LIMIT; - } - else { - max_conns = (int)tmp; - } - } - else { - return -1; - } - return 0; +static int email_config(const char *key, const char *value) { + if (0 == strcasecmp(key, "SocketFile")) { + if (NULL != sock_file) + free(sock_file); + sock_file = sstrdup(value); + } else if (0 == strcasecmp(key, "SocketGroup")) { + if (NULL != sock_group) + free(sock_group); + sock_group = sstrdup(value); + } else if (0 == strcasecmp(key, "SocketPerms")) { + /* the user is responsible for providing reasonable values */ + sock_perms = (int)strtol(value, NULL, 8); + } else if (0 == strcasecmp(key, "MaxConns")) { + long int tmp = strtol(value, NULL, 0); + + if (tmp < 1) { + fprintf(stderr, "email plugin: `MaxConns' was set to invalid " + "value %li, will use default %i.\n", + tmp, MAX_CONNS); + ERROR("email plugin: `MaxConns' was set to invalid " + "value %li, will use default %i.\n", + tmp, MAX_CONNS); + max_conns = MAX_CONNS; + } else if (tmp > MAX_CONNS_LIMIT) { + fprintf(stderr, "email plugin: `MaxConns' was set to invalid " + "value %li, will use hardcoded limit %i.\n", + tmp, MAX_CONNS_LIMIT); + ERROR("email plugin: `MaxConns' was set to invalid " + "value %li, will use hardcoded limit %i.\n", + tmp, MAX_CONNS_LIMIT); + max_conns = MAX_CONNS_LIMIT; + } else { + max_conns = (int)tmp; + } + } else { + return -1; + } + return 0; } /* static int email_config (char *, char *) */ /* Increment the value of the given name in the given list by incr. */ -static void type_list_incr (type_list_t *list, char *name, int incr) -{ - if (NULL == list->head) { - list->head = smalloc (sizeof (*list->head)); - - list->head->name = sstrdup (name); - list->head->value = incr; - list->head->next = NULL; - - list->tail = list->head; - } - else { - type_t *ptr; - - for (ptr = list->head; NULL != ptr; ptr = ptr->next) { - if (0 == strcmp (name, ptr->name)) - break; - } - - if (NULL == ptr) { - list->tail->next = smalloc (sizeof (*list->tail->next)); - list->tail = list->tail->next; - - list->tail->name = sstrdup (name); - list->tail->value = incr; - list->tail->next = NULL; - } - else { - ptr->value += incr; - } - } - return; +static void type_list_incr(type_list_t *list, char *name, int incr) { + if (NULL == list->head) { + list->head = smalloc(sizeof(*list->head)); + + list->head->name = sstrdup(name); + list->head->value = incr; + list->head->next = NULL; + + list->tail = list->head; + } else { + type_t *ptr; + + for (ptr = list->head; NULL != ptr; ptr = ptr->next) { + if (0 == strcmp(name, ptr->name)) + break; + } + + if (NULL == ptr) { + list->tail->next = smalloc(sizeof(*list->tail->next)); + list->tail = list->tail->next; + + list->tail->name = sstrdup(name); + list->tail->value = incr; + list->tail->next = NULL; + } else { + ptr->value += incr; + } + } + return; } /* static void type_list_incr (type_list_t *, char *) */ -static void *collect (void *arg) -{ - collector_t *this = (collector_t *)arg; - - while (1) { - conn_t *connection; - - pthread_mutex_lock (&conns_mutex); - - while (NULL == conns.head) { - pthread_cond_wait (&conn_available, &conns_mutex); - } - - connection = conns.head; - conns.head = conns.head->next; - - if (NULL == conns.head) { - conns.tail = NULL; - } - - pthread_mutex_unlock (&conns_mutex); - - /* make the socket available to the global - * thread and connection management */ - this->socket = connection->socket; - - log_debug ("collect: handling connection on fd #%i", - fileno (this->socket)); - - while (42) { - /* 256 bytes ought to be enough for anybody ;-) */ - char line[256 + 1]; /* line + '\0' */ - int len = 0; - - errno = 0; - if (NULL == fgets (line, sizeof (line), this->socket)) { - if (0 != errno) { - char errbuf[1024]; - log_err ("collect: reading from socket (fd #%i) " - "failed: %s", fileno (this->socket), - sstrerror (errno, errbuf, sizeof (errbuf))); - } - break; - } - - len = strlen (line); - if (('\n' != line[len - 1]) && ('\r' != line[len - 1])) { - log_warn ("collect: line too long (> %zu characters): " - "'%s' (truncated)", sizeof (line) - 1, line); - - while (NULL != fgets (line, sizeof (line), this->socket)) - if (('\n' == line[len - 1]) || ('\r' == line[len - 1])) - break; - continue; - } - if (len < 3) { /* [a-z] ':' '\n' */ - continue; - } - - line[len - 1] = 0; - - log_debug ("collect: line = '%s'", line); - - if (':' != line[1]) { - log_err ("collect: syntax error in line '%s'", line); - continue; - } - - if ('e' == line[0]) { /* e:: */ - char *ptr = NULL; - char *type = strtok_r (line + 2, ":", &ptr); - char *tmp = strtok_r (NULL, ":", &ptr); - int bytes = 0; - - if (NULL == tmp) { - log_err ("collect: syntax error in line '%s'", line); - continue; - } - - bytes = atoi (tmp); - - pthread_mutex_lock (&count_mutex); - type_list_incr (&list_count, type, /* increment = */ 1); - pthread_mutex_unlock (&count_mutex); - - if (bytes > 0) { - pthread_mutex_lock (&size_mutex); - type_list_incr (&list_size, type, /* increment = */ bytes); - pthread_mutex_unlock (&size_mutex); - } - } - else if ('s' == line[0]) { /* s: */ - pthread_mutex_lock (&score_mutex); - score = (score * (double)score_count + atof (line + 2)) - / (double)(score_count + 1); - ++score_count; - pthread_mutex_unlock (&score_mutex); - } - else if ('c' == line[0]) { /* c:[,,...] */ - char *dummy = line + 2; - char *endptr = NULL; - char *type; - - pthread_mutex_lock (&check_mutex); - while ((type = strtok_r (dummy, ",", &endptr)) != NULL) - { - dummy = NULL; - type_list_incr (&list_check, type, /* increment = */ 1); - } - pthread_mutex_unlock (&check_mutex); - } - else { - log_err ("collect: unknown type '%c'", line[0]); - } - } /* while (42) */ - - log_debug ("Shutting down connection on fd #%i", - fileno (this->socket)); - - fclose (connection->socket); - free (connection); - - this->socket = NULL; - - pthread_mutex_lock (&available_mutex); - ++available_collectors; - pthread_mutex_unlock (&available_mutex); - - pthread_cond_signal (&collector_available); - } /* while (1) */ - - pthread_exit ((void *)0); - return ((void *) 0); +static void *collect(void *arg) { + collector_t *this = (collector_t *)arg; + + while (1) { + conn_t *connection; + + pthread_mutex_lock(&conns_mutex); + + while (NULL == conns.head) { + pthread_cond_wait(&conn_available, &conns_mutex); + } + + connection = conns.head; + conns.head = conns.head->next; + + if (NULL == conns.head) { + conns.tail = NULL; + } + + pthread_mutex_unlock(&conns_mutex); + + /* make the socket available to the global + * thread and connection management */ + this->socket = connection->socket; + + log_debug("collect: handling connection on fd #%i", fileno(this->socket)); + + while (42) { + /* 256 bytes ought to be enough for anybody ;-) */ + char line[256 + 1]; /* line + '\0' */ + int len = 0; + + errno = 0; + if (NULL == fgets(line, sizeof(line), this->socket)) { + if (0 != errno) { + char errbuf[1024]; + log_err("collect: reading from socket (fd #%i) " + "failed: %s", + fileno(this->socket), + sstrerror(errno, errbuf, sizeof(errbuf))); + } + break; + } + + len = strlen(line); + if (('\n' != line[len - 1]) && ('\r' != line[len - 1])) { + log_warn("collect: line too long (> %zu characters): " + "'%s' (truncated)", + sizeof(line) - 1, line); + + while (NULL != fgets(line, sizeof(line), this->socket)) + if (('\n' == line[len - 1]) || ('\r' == line[len - 1])) + break; + continue; + } + if (len < 3) { /* [a-z] ':' '\n' */ + continue; + } + + line[len - 1] = 0; + + log_debug("collect: line = '%s'", line); + + if (':' != line[1]) { + log_err("collect: syntax error in line '%s'", line); + continue; + } + + if ('e' == line[0]) { /* e:: */ + char *ptr = NULL; + char *type = strtok_r(line + 2, ":", &ptr); + char *tmp = strtok_r(NULL, ":", &ptr); + int bytes = 0; + + if (NULL == tmp) { + log_err("collect: syntax error in line '%s'", line); + continue; + } + + bytes = atoi(tmp); + + pthread_mutex_lock(&count_mutex); + type_list_incr(&list_count, type, /* increment = */ 1); + pthread_mutex_unlock(&count_mutex); + + if (bytes > 0) { + pthread_mutex_lock(&size_mutex); + type_list_incr(&list_size, type, /* increment = */ bytes); + pthread_mutex_unlock(&size_mutex); + } + } else if ('s' == line[0]) { /* s: */ + pthread_mutex_lock(&score_mutex); + score = (score * (double)score_count + atof(line + 2)) / + (double)(score_count + 1); + ++score_count; + pthread_mutex_unlock(&score_mutex); + } else if ('c' == line[0]) { /* c:[,,...] */ + char *dummy = line + 2; + char *endptr = NULL; + char *type; + + pthread_mutex_lock(&check_mutex); + while ((type = strtok_r(dummy, ",", &endptr)) != NULL) { + dummy = NULL; + type_list_incr(&list_check, type, /* increment = */ 1); + } + pthread_mutex_unlock(&check_mutex); + } else { + log_err("collect: unknown type '%c'", line[0]); + } + } /* while (42) */ + + log_debug("Shutting down connection on fd #%i", fileno(this->socket)); + + fclose(connection->socket); + free(connection); + + this->socket = NULL; + + pthread_mutex_lock(&available_mutex); + ++available_collectors; + pthread_mutex_unlock(&available_mutex); + + pthread_cond_signal(&collector_available); + } /* while (1) */ + + pthread_exit((void *)0); + return ((void *)0); } /* static void *collect (void *) */ -static void *open_connection (void __attribute__((unused)) *arg) -{ - struct sockaddr_un addr; - - const char *path = (NULL == sock_file) ? SOCK_PATH : sock_file; - const char *group = (NULL == sock_group) ? COLLECTD_GRP_NAME : sock_group; - - /* create UNIX socket */ - errno = 0; - if (-1 == (connector_socket = socket (PF_UNIX, SOCK_STREAM, 0))) { - char errbuf[1024]; - disabled = 1; - log_err ("socket() failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - pthread_exit ((void *)1); - } - - addr.sun_family = AF_UNIX; - sstrncpy (addr.sun_path, path, (size_t)(UNIX_PATH_MAX - 1)); - - errno = 0; - if (-1 == bind (connector_socket, (struct sockaddr *)&addr, - offsetof (struct sockaddr_un, sun_path) - + strlen(addr.sun_path))) { - char errbuf[1024]; - disabled = 1; - close (connector_socket); - connector_socket = -1; - log_err ("bind() failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - pthread_exit ((void *)1); - } - - errno = 0; - if (-1 == listen (connector_socket, 5)) { - char errbuf[1024]; - disabled = 1; - close (connector_socket); - connector_socket = -1; - log_err ("listen() failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - pthread_exit ((void *)1); - } - - { - struct group sg; - struct group *grp; - char grbuf[2048]; - int status; - - grp = NULL; - status = getgrnam_r (group, &sg, grbuf, sizeof (grbuf), &grp); - if (status != 0) - { - char errbuf[1024]; - log_warn ("getgrnam_r (%s) failed: %s", group, - sstrerror (errno, errbuf, sizeof (errbuf))); - } - else if (grp == NULL) - { - log_warn ("No such group: `%s'", group); - } - else - { - status = chown (path, (uid_t) -1, grp->gr_gid); - if (status != 0) - { - char errbuf[1024]; - log_warn ("chown (%s, -1, %i) failed: %s", - path, (int) grp->gr_gid, - sstrerror (errno, errbuf, sizeof (errbuf))); - } - } - } - - errno = 0; - if (0 != chmod (path, sock_perms)) { - char errbuf[1024]; - log_warn ("chmod() failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - } - - { /* initialize collector threads */ - pthread_attr_t ptattr; - - conns.head = NULL; - conns.tail = NULL; - - pthread_attr_init (&ptattr); - pthread_attr_setdetachstate (&ptattr, PTHREAD_CREATE_DETACHED); - - available_collectors = max_conns; - - collectors = - smalloc (max_conns * sizeof (*collectors)); - - for (int i = 0; i < max_conns; ++i) { - collectors[i] = smalloc (sizeof (*collectors[i])); - collectors[i]->socket = NULL; - - if (plugin_thread_create (&collectors[i]->thread, - &ptattr, collect, collectors[i], - "email collector") != 0) { - char errbuf[1024]; - log_err ("plugin_thread_create() failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - collectors[i]->thread = (pthread_t) 0; - } - } - - pthread_attr_destroy (&ptattr); - } - - while (1) { - int remote = 0; - - conn_t *connection; - - pthread_mutex_lock (&available_mutex); - - while (0 == available_collectors) { - pthread_cond_wait (&collector_available, &available_mutex); - } - - --available_collectors; - - pthread_mutex_unlock (&available_mutex); - - while (42) { - errno = 0; - - remote = accept (connector_socket, NULL, NULL); - if (remote == -1) { - char errbuf[1024]; - - if (errno == EINTR) - continue; - - disabled = 1; - close (connector_socket); - connector_socket = -1; - log_err ("accept() failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - pthread_exit ((void *)1); - } - - /* access() succeeded. */ - break; - } - - connection = calloc (1, sizeof (*connection)); - if (connection == NULL) - { - close (remote); - continue; - } - - connection->socket = fdopen (remote, "r"); - connection->next = NULL; - - if (NULL == connection->socket) { - close (remote); - sfree (connection); - continue; - } - - pthread_mutex_lock (&conns_mutex); - - if (NULL == conns.head) { - conns.head = connection; - conns.tail = connection; - } - else { - conns.tail->next = connection; - conns.tail = conns.tail->next; - } +static void *open_connection(void __attribute__((unused)) * arg) { + struct sockaddr_un addr; + + const char *path = (NULL == sock_file) ? SOCK_PATH : sock_file; + const char *group = (NULL == sock_group) ? COLLECTD_GRP_NAME : sock_group; + + /* create UNIX socket */ + errno = 0; + if (-1 == (connector_socket = socket(PF_UNIX, SOCK_STREAM, 0))) { + char errbuf[1024]; + disabled = 1; + log_err("socket() failed: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + pthread_exit((void *)1); + } + + addr.sun_family = AF_UNIX; + sstrncpy(addr.sun_path, path, (size_t)(UNIX_PATH_MAX - 1)); + + errno = 0; + if (-1 == + bind(connector_socket, (struct sockaddr *)&addr, + offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path))) { + char errbuf[1024]; + disabled = 1; + close(connector_socket); + connector_socket = -1; + log_err("bind() failed: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + pthread_exit((void *)1); + } + + errno = 0; + if (-1 == listen(connector_socket, 5)) { + char errbuf[1024]; + disabled = 1; + close(connector_socket); + connector_socket = -1; + log_err("listen() failed: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + pthread_exit((void *)1); + } + + { + struct group sg; + struct group *grp; + char grbuf[2048]; + int status; + + grp = NULL; + status = getgrnam_r(group, &sg, grbuf, sizeof(grbuf), &grp); + if (status != 0) { + char errbuf[1024]; + log_warn("getgrnam_r (%s) failed: %s", group, + sstrerror(errno, errbuf, sizeof(errbuf))); + } else if (grp == NULL) { + log_warn("No such group: `%s'", group); + } else { + status = chown(path, (uid_t)-1, grp->gr_gid); + if (status != 0) { + char errbuf[1024]; + log_warn("chown (%s, -1, %i) failed: %s", path, (int)grp->gr_gid, + sstrerror(errno, errbuf, sizeof(errbuf))); + } + } + } + + errno = 0; + if (0 != chmod(path, sock_perms)) { + char errbuf[1024]; + log_warn("chmod() failed: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + } + + { /* initialize collector threads */ + pthread_attr_t ptattr; + + conns.head = NULL; + conns.tail = NULL; + + pthread_attr_init(&ptattr); + pthread_attr_setdetachstate(&ptattr, PTHREAD_CREATE_DETACHED); + + available_collectors = max_conns; + + collectors = smalloc(max_conns * sizeof(*collectors)); + + for (int i = 0; i < max_conns; ++i) { + collectors[i] = smalloc(sizeof(*collectors[i])); + collectors[i]->socket = NULL; + + if (plugin_thread_create(&collectors[i]->thread, &ptattr, collect, + collectors[i], "email collector") != 0) { + char errbuf[1024]; + log_err("plugin_thread_create() failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + collectors[i]->thread = (pthread_t)0; + } + } + + pthread_attr_destroy(&ptattr); + } + + while (1) { + int remote = 0; + + conn_t *connection; + + pthread_mutex_lock(&available_mutex); + + while (0 == available_collectors) { + pthread_cond_wait(&collector_available, &available_mutex); + } + + --available_collectors; + + pthread_mutex_unlock(&available_mutex); + + while (42) { + errno = 0; + + remote = accept(connector_socket, NULL, NULL); + if (remote == -1) { + char errbuf[1024]; + + if (errno == EINTR) + continue; + + disabled = 1; + close(connector_socket); + connector_socket = -1; + log_err("accept() failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + pthread_exit((void *)1); + } + + /* access() succeeded. */ + break; + } + + connection = calloc(1, sizeof(*connection)); + if (connection == NULL) { + close(remote); + continue; + } + + connection->socket = fdopen(remote, "r"); + connection->next = NULL; + + if (NULL == connection->socket) { + close(remote); + sfree(connection); + continue; + } + + pthread_mutex_lock(&conns_mutex); + + if (NULL == conns.head) { + conns.head = connection; + conns.tail = connection; + } else { + conns.tail->next = connection; + conns.tail = conns.tail->next; + } - pthread_mutex_unlock (&conns_mutex); + pthread_mutex_unlock(&conns_mutex); - pthread_cond_signal (&conn_available); - } + pthread_cond_signal(&conn_available); + } - pthread_exit ((void *) 0); - return ((void *) 0); + pthread_exit((void *)0); + return ((void *)0); } /* static void *open_connection (void *) */ -static int email_init (void) -{ - if (plugin_thread_create (&connector, NULL, - open_connection, NULL, "email listener") != 0) { - char errbuf[1024]; - disabled = 1; - log_err ("plugin_thread_create() failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - return (0); +static int email_init(void) { + if (plugin_thread_create(&connector, NULL, open_connection, NULL, + "email listener") != 0) { + char errbuf[1024]; + disabled = 1; + log_err("plugin_thread_create() failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + return (0); } /* int email_init */ -static void type_list_free (type_list_t *t) -{ - type_t *this; +static void type_list_free(type_list_t *t) { + type_t *this; - this = t->head; - while (this != NULL) - { - type_t *next = this->next; + this = t->head; + while (this != NULL) { + type_t *next = this->next; - sfree (this->name); - sfree (this); + sfree(this->name); + sfree(this); - this = next; - } + this = next; + } - t->head = NULL; - t->tail = NULL; + t->head = NULL; + t->tail = NULL; } -static int email_shutdown (void) -{ - if (connector != ((pthread_t) 0)) { - pthread_kill (connector, SIGTERM); - connector = (pthread_t) 0; - } - - if (connector_socket >= 0) { - close (connector_socket); - connector_socket = -1; - } - - /* don't allow any more connections to be processed */ - pthread_mutex_lock (&conns_mutex); - - available_collectors = 0; - - if (collectors != NULL) { - for (int i = 0; i < max_conns; ++i) { - if (collectors[i] == NULL) - continue; - - if (collectors[i]->thread != ((pthread_t) 0)) { - pthread_kill (collectors[i]->thread, SIGTERM); - collectors[i]->thread = (pthread_t) 0; - } - - if (collectors[i]->socket != NULL) { - fclose (collectors[i]->socket); - collectors[i]->socket = NULL; - } - - sfree (collectors[i]); - } - sfree (collectors); - } /* if (collectors != NULL) */ - - pthread_mutex_unlock (&conns_mutex); - - type_list_free (&list_count); - type_list_free (&list_count_copy); - type_list_free (&list_size); - type_list_free (&list_size_copy); - type_list_free (&list_check); - type_list_free (&list_check_copy); - - unlink ((NULL == sock_file) ? SOCK_PATH : sock_file); - - sfree (sock_file); - sfree (sock_group); - return (0); +static int email_shutdown(void) { + if (connector != ((pthread_t)0)) { + pthread_kill(connector, SIGTERM); + connector = (pthread_t)0; + } + + if (connector_socket >= 0) { + close(connector_socket); + connector_socket = -1; + } + + /* don't allow any more connections to be processed */ + pthread_mutex_lock(&conns_mutex); + + available_collectors = 0; + + if (collectors != NULL) { + for (int i = 0; i < max_conns; ++i) { + if (collectors[i] == NULL) + continue; + + if (collectors[i]->thread != ((pthread_t)0)) { + pthread_kill(collectors[i]->thread, SIGTERM); + collectors[i]->thread = (pthread_t)0; + } + + if (collectors[i]->socket != NULL) { + fclose(collectors[i]->socket); + collectors[i]->socket = NULL; + } + + sfree(collectors[i]); + } + sfree(collectors); + } /* if (collectors != NULL) */ + + pthread_mutex_unlock(&conns_mutex); + + type_list_free(&list_count); + type_list_free(&list_count_copy); + type_list_free(&list_size); + type_list_free(&list_size_copy); + type_list_free(&list_check); + type_list_free(&list_check_copy); + + unlink((NULL == sock_file) ? SOCK_PATH : sock_file); + + sfree(sock_file); + sfree(sock_group); + return (0); } /* static void email_shutdown (void) */ -static void email_submit (const char *type, const char *type_instance, gauge_t value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void email_submit(const char *type, const char *type_instance, + gauge_t value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "email", sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "email", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* void email_submit */ /* Copy list l1 to list l2. l2 may partly exist already, but it is assumed * that neither the order nor the name of any element of either list is * changed and no elements are deleted. The values of l1 are reset to zero * after they have been copied to l2. */ -static void copy_type_list (type_list_t *l1, type_list_t *l2) -{ - type_t *last = NULL; - - for (type_t *ptr1 = l1->head, *ptr2 = l2->head; NULL != ptr1; - ptr1 = ptr1->next, last = ptr2, ptr2 = ptr2->next) { - if (NULL == ptr2) { - ptr2 = smalloc (sizeof (*ptr2)); - ptr2->name = NULL; - ptr2->next = NULL; - - if (NULL == last) { - l2->head = ptr2; - } - else { - last->next = ptr2; - } - - l2->tail = ptr2; - } - - if (NULL == ptr2->name) { - ptr2->name = sstrdup (ptr1->name); - } - - ptr2->value = ptr1->value; - ptr1->value = 0; - } - return; +static void copy_type_list(type_list_t *l1, type_list_t *l2) { + type_t *last = NULL; + + for (type_t *ptr1 = l1->head, *ptr2 = l2->head; NULL != ptr1; + ptr1 = ptr1->next, last = ptr2, ptr2 = ptr2->next) { + if (NULL == ptr2) { + ptr2 = smalloc(sizeof(*ptr2)); + ptr2->name = NULL; + ptr2->next = NULL; + + if (NULL == last) { + l2->head = ptr2; + } else { + last->next = ptr2; + } + + l2->tail = ptr2; + } + + if (NULL == ptr2->name) { + ptr2->name = sstrdup(ptr1->name); + } + + ptr2->value = ptr1->value; + ptr1->value = 0; + } + return; } -static int email_read (void) -{ - double score_old; - int score_count_old; +static int email_read(void) { + double score_old; + int score_count_old; - if (disabled) - return (-1); + if (disabled) + return (-1); - /* email count */ - pthread_mutex_lock (&count_mutex); + /* email count */ + pthread_mutex_lock(&count_mutex); - copy_type_list (&list_count, &list_count_copy); + copy_type_list(&list_count, &list_count_copy); - pthread_mutex_unlock (&count_mutex); + pthread_mutex_unlock(&count_mutex); - for (type_t *ptr = list_count_copy.head; NULL != ptr; ptr = ptr->next) { - email_submit ("email_count", ptr->name, ptr->value); - } + for (type_t *ptr = list_count_copy.head; NULL != ptr; ptr = ptr->next) { + email_submit("email_count", ptr->name, ptr->value); + } - /* email size */ - pthread_mutex_lock (&size_mutex); + /* email size */ + pthread_mutex_lock(&size_mutex); - copy_type_list (&list_size, &list_size_copy); + copy_type_list(&list_size, &list_size_copy); - pthread_mutex_unlock (&size_mutex); + pthread_mutex_unlock(&size_mutex); - for (type_t *ptr = list_size_copy.head; NULL != ptr; ptr = ptr->next) { - email_submit ("email_size", ptr->name, ptr->value); - } + for (type_t *ptr = list_size_copy.head; NULL != ptr; ptr = ptr->next) { + email_submit("email_size", ptr->name, ptr->value); + } - /* spam score */ - pthread_mutex_lock (&score_mutex); + /* spam score */ + pthread_mutex_lock(&score_mutex); - score_old = score; - score_count_old = score_count; - score = 0.0; - score_count = 0; + score_old = score; + score_count_old = score_count; + score = 0.0; + score_count = 0; - pthread_mutex_unlock (&score_mutex); + pthread_mutex_unlock(&score_mutex); - if (score_count_old > 0) - email_submit ("spam_score", "", score_old); + if (score_count_old > 0) + email_submit("spam_score", "", score_old); - /* spam checks */ - pthread_mutex_lock (&check_mutex); + /* spam checks */ + pthread_mutex_lock(&check_mutex); - copy_type_list (&list_check, &list_check_copy); + copy_type_list(&list_check, &list_check_copy); - pthread_mutex_unlock (&check_mutex); + pthread_mutex_unlock(&check_mutex); - for (type_t *ptr = list_check_copy.head; NULL != ptr; ptr = ptr->next) - email_submit ("spam_check", ptr->name, ptr->value); + for (type_t *ptr = list_check_copy.head; NULL != ptr; ptr = ptr->next) + email_submit("spam_check", ptr->name, ptr->value); - return (0); + return (0); } /* int email_read */ -void module_register (void) -{ - plugin_register_config ("email", email_config, config_keys, config_keys_num); - plugin_register_init ("email", email_init); - plugin_register_read ("email", email_read); - plugin_register_shutdown ("email", email_shutdown); +void module_register(void) { + plugin_register_config("email", email_config, config_keys, config_keys_num); + plugin_register_init("email", email_init); + plugin_register_read("email", email_read); + plugin_register_shutdown("email", email_shutdown); } /* void module_register */ /* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/entropy.c b/src/entropy.c index 02ea9e11..de35291c 100644 --- a/src/entropy.c +++ b/src/entropy.c @@ -30,37 +30,33 @@ #include "plugin.h" #if !KERNEL_LINUX -# error "No applicable input method." +#error "No applicable input method." #endif #define ENTROPY_FILE "/proc/sys/kernel/random/entropy_avail" -static void entropy_submit (value_t value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void entropy_submit(value_t value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &value; - vl.values_len = 1; - sstrncpy (vl.plugin, "entropy", sizeof (vl.plugin)); - sstrncpy (vl.type, "entropy", sizeof (vl.type)); + vl.values = &value; + vl.values_len = 1; + sstrncpy(vl.plugin, "entropy", sizeof(vl.plugin)); + sstrncpy(vl.type, "entropy", sizeof(vl.type)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static int entropy_read (void) -{ - value_t v; - if (parse_value_file (ENTROPY_FILE, &v, DS_TYPE_GAUGE) != 0) - { - ERROR ("entropy plugin: Reading \""ENTROPY_FILE"\" failed."); - return (-1); - } +static int entropy_read(void) { + value_t v; + if (parse_value_file(ENTROPY_FILE, &v, DS_TYPE_GAUGE) != 0) { + ERROR("entropy plugin: Reading \"" ENTROPY_FILE "\" failed."); + return (-1); + } - entropy_submit (v); - return (0); + entropy_submit(v); + return (0); } -void module_register (void) -{ - plugin_register_read ("entropy", entropy_read); +void module_register(void) { + plugin_register_read("entropy", entropy_read); } /* void module_register */ diff --git a/src/ethstat.c b/src/ethstat.c index 6dccb45f..bd55252f 100644 --- a/src/ethstat.c +++ b/src/ethstat.c @@ -30,20 +30,19 @@ #include "utils_complain.h" #if HAVE_SYS_IOCTL_H -# include +#include #endif #if HAVE_NET_IF_H -# include +#include #endif #if HAVE_LINUX_SOCKIOS_H -# include +#include #endif #if HAVE_LINUX_ETHTOOL_H -# include +#include #endif -struct value_map_s -{ +struct value_map_s { char type[DATA_MAX_NAME_LEN]; char type_instance[DATA_MAX_NAME_LEN]; }; @@ -56,160 +55,145 @@ static c_avl_tree_t *value_map = NULL; static _Bool collect_mapped_only = 0; -static int ethstat_add_interface (const oconfig_item_t *ci) /* {{{ */ +static int ethstat_add_interface(const oconfig_item_t *ci) /* {{{ */ { char **tmp; int status; - tmp = realloc (interfaces, - sizeof (*interfaces) * (interfaces_num + 1)); + tmp = realloc(interfaces, sizeof(*interfaces) * (interfaces_num + 1)); if (tmp == NULL) return (-1); interfaces = tmp; interfaces[interfaces_num] = NULL; - status = cf_util_get_string (ci, interfaces + interfaces_num); + status = cf_util_get_string(ci, interfaces + interfaces_num); if (status != 0) return (status); interfaces_num++; INFO("ethstat plugin: Registered interface %s", - interfaces[interfaces_num - 1]); + interfaces[interfaces_num - 1]); return (0); } /* }}} int ethstat_add_interface */ -static int ethstat_add_map (const oconfig_item_t *ci) /* {{{ */ +static int ethstat_add_map(const oconfig_item_t *ci) /* {{{ */ { value_map_t *map; int status; char *key; - if ((ci->values_num < 2) - || (ci->values_num > 3) - || (ci->values[0].type != OCONFIG_TYPE_STRING) - || (ci->values[1].type != OCONFIG_TYPE_STRING) - || ((ci->values_num == 3) - && (ci->values[2].type != OCONFIG_TYPE_STRING))) - { - ERROR ("ethstat plugin: The %s option requires " - "two or three string arguments.", ci->key); + if ((ci->values_num < 2) || (ci->values_num > 3) || + (ci->values[0].type != OCONFIG_TYPE_STRING) || + (ci->values[1].type != OCONFIG_TYPE_STRING) || + ((ci->values_num == 3) && (ci->values[2].type != OCONFIG_TYPE_STRING))) { + ERROR("ethstat plugin: The %s option requires " + "two or three string arguments.", + ci->key); return (-1); } - key = strdup (ci->values[0].value.string); - if (key == NULL) - { - ERROR ("ethstat plugin: strdup(3) failed."); + key = strdup(ci->values[0].value.string); + if (key == NULL) { + ERROR("ethstat plugin: strdup(3) failed."); return (ENOMEM); } - map = calloc (1, sizeof (*map)); - if (map == NULL) - { - sfree (key); - ERROR ("ethstat plugin: calloc failed."); + map = calloc(1, sizeof(*map)); + if (map == NULL) { + sfree(key); + ERROR("ethstat plugin: calloc failed."); return (ENOMEM); } - sstrncpy (map->type, ci->values[1].value.string, sizeof (map->type)); + sstrncpy(map->type, ci->values[1].value.string, sizeof(map->type)); if (ci->values_num == 3) - sstrncpy (map->type_instance, ci->values[2].value.string, - sizeof (map->type_instance)); - - if (value_map == NULL) - { - value_map = c_avl_create ((int (*) (const void *, const void *)) strcmp); - if (value_map == NULL) - { - sfree (map); - sfree (key); - ERROR ("ethstat plugin: c_avl_create() failed."); + sstrncpy(map->type_instance, ci->values[2].value.string, + sizeof(map->type_instance)); + + if (value_map == NULL) { + value_map = c_avl_create((int (*)(const void *, const void *))strcmp); + if (value_map == NULL) { + sfree(map); + sfree(key); + ERROR("ethstat plugin: c_avl_create() failed."); return (-1); } } - status = c_avl_insert (value_map, - /* key = */ key, - /* value = */ map); - if (status != 0) - { + status = c_avl_insert(value_map, + /* key = */ key, + /* value = */ map); + if (status != 0) { if (status > 0) - ERROR ("ethstat plugin: Multiple mappings for \"%s\".", key); + ERROR("ethstat plugin: Multiple mappings for \"%s\".", key); else - ERROR ("ethstat plugin: c_avl_insert(\"%s\") failed.", key); + ERROR("ethstat plugin: c_avl_insert(\"%s\") failed.", key); - sfree (map); - sfree (key); + sfree(map); + sfree(key); return (-1); } return (0); } /* }}} int ethstat_add_map */ -static int ethstat_config (oconfig_item_t *ci) /* {{{ */ +static int ethstat_config(oconfig_item_t *ci) /* {{{ */ { - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Interface", child->key) == 0) - ethstat_add_interface (child); - else if (strcasecmp ("Map", child->key) == 0) - ethstat_add_map (child); - else if (strcasecmp ("MappedOnly", child->key) == 0) - (void) cf_util_get_boolean (child, &collect_mapped_only); + if (strcasecmp("Interface", child->key) == 0) + ethstat_add_interface(child); + else if (strcasecmp("Map", child->key) == 0) + ethstat_add_map(child); + else if (strcasecmp("MappedOnly", child->key) == 0) + (void)cf_util_get_boolean(child, &collect_mapped_only); else - WARNING ("ethstat plugin: The config option \"%s\" is unknown.", - child->key); + WARNING("ethstat plugin: The config option \"%s\" is unknown.", + child->key); } return (0); } /* }}} */ -static void ethstat_submit_value (const char *device, - const char *type_instance, derive_t value) -{ +static void ethstat_submit_value(const char *device, const char *type_instance, + derive_t value) { static c_complain_t complain_no_map = C_COMPLAIN_INIT_STATIC; value_list_t vl = VALUE_LIST_INIT; value_map_t *map = NULL; if (value_map != NULL) - c_avl_get (value_map, type_instance, (void *) &map); + c_avl_get(value_map, type_instance, (void *)&map); /* If the "MappedOnly" option is specified, ignore unmapped values. */ - if (collect_mapped_only && (map == NULL)) - { + if (collect_mapped_only && (map == NULL)) { if (value_map == NULL) - c_complain (LOG_WARNING, &complain_no_map, + c_complain( + LOG_WARNING, &complain_no_map, "ethstat plugin: The \"MappedOnly\" option has been set to true, " "but no mapping has been configured. All values will be ignored!"); return; } - vl.values = &(value_t) { .derive = value }; + vl.values = &(value_t){.derive = value}; vl.values_len = 1; - sstrncpy (vl.plugin, "ethstat", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, device, sizeof (vl.plugin_instance)); - if (map != NULL) - { - sstrncpy (vl.type, map->type, sizeof (vl.type)); - sstrncpy (vl.type_instance, map->type_instance, - sizeof (vl.type_instance)); - } - else - { - sstrncpy (vl.type, "derive", sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + sstrncpy(vl.plugin, "ethstat", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, device, sizeof(vl.plugin_instance)); + if (map != NULL) { + sstrncpy(vl.type, map->type, sizeof(vl.type)); + sstrncpy(vl.type_instance, map->type_instance, sizeof(vl.type_instance)); + } else { + sstrncpy(vl.type, "derive", sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); } - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static int ethstat_read_interface (char *device) -{ +static int ethstat_read_interface(char *device) { int fd; struct ethtool_gstrings *strings; struct ethtool_stats *stats; @@ -219,55 +203,45 @@ static int ethstat_read_interface (char *device) int status; fd = socket(AF_INET, SOCK_DGRAM, /* protocol = */ 0); - if (fd < 0) - { + if (fd < 0) { char errbuf[1024]; ERROR("ethstat plugin: Failed to open control socket: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + sstrerror(errno, errbuf, sizeof(errbuf))); return 1; } - struct ethtool_drvinfo drvinfo = { - .cmd = ETHTOOL_GDRVINFO - }; + struct ethtool_drvinfo drvinfo = {.cmd = ETHTOOL_GDRVINFO}; - struct ifreq req = { - .ifr_data = (void *) &drvinfo - }; + struct ifreq req = {.ifr_data = (void *)&drvinfo}; - sstrncpy(req.ifr_name, device, sizeof (req.ifr_name)); + sstrncpy(req.ifr_name, device, sizeof(req.ifr_name)); - status = ioctl (fd, SIOCETHTOOL, &req); - if (status < 0) - { + status = ioctl(fd, SIOCETHTOOL, &req); + if (status < 0) { char errbuf[1024]; - close (fd); - ERROR ("ethstat plugin: Failed to get driver information " - "from %s: %s", device, - sstrerror (errno, errbuf, sizeof (errbuf))); + close(fd); + ERROR("ethstat plugin: Failed to get driver information " + "from %s: %s", + device, sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } - n_stats = (size_t) drvinfo.n_stats; - if (n_stats < 1) - { - close (fd); + n_stats = (size_t)drvinfo.n_stats; + if (n_stats < 1) { + close(fd); ERROR("ethstat plugin: No stats available for %s", device); return (-1); } - strings_size = sizeof (struct ethtool_gstrings) - + (n_stats * ETH_GSTRING_LEN); - stats_size = sizeof (struct ethtool_stats) - + (n_stats * sizeof (uint64_t)); - - strings = malloc (strings_size); - stats = malloc (stats_size); - if ((strings == NULL) || (stats == NULL)) - { - close (fd); - sfree (strings); - sfree (stats); + strings_size = sizeof(struct ethtool_gstrings) + (n_stats * ETH_GSTRING_LEN); + stats_size = sizeof(struct ethtool_stats) + (n_stats * sizeof(uint64_t)); + + strings = malloc(strings_size); + stats = malloc(stats_size); + if ((strings == NULL) || (stats == NULL)) { + close(fd); + sfree(strings); + sfree(stats); ERROR("ethstat plugin: malloc failed."); return (-1); } @@ -275,91 +249,81 @@ static int ethstat_read_interface (char *device) strings->cmd = ETHTOOL_GSTRINGS; strings->string_set = ETH_SS_STATS; strings->len = n_stats; - req.ifr_data = (void *) strings; - status = ioctl (fd, SIOCETHTOOL, &req); - if (status < 0) - { + req.ifr_data = (void *)strings; + status = ioctl(fd, SIOCETHTOOL, &req); + if (status < 0) { char errbuf[1024]; - close (fd); - free (strings); - free (stats); - ERROR ("ethstat plugin: Cannot get strings from %s: %s", - device, - sstrerror (errno, errbuf, sizeof (errbuf))); + close(fd); + free(strings); + free(stats); + ERROR("ethstat plugin: Cannot get strings from %s: %s", device, + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } stats->cmd = ETHTOOL_GSTATS; stats->n_stats = n_stats; - req.ifr_data = (void *) stats; - status = ioctl (fd, SIOCETHTOOL, &req); - if (status < 0) - { + req.ifr_data = (void *)stats; + status = ioctl(fd, SIOCETHTOOL, &req); + if (status < 0) { char errbuf[1024]; - close (fd); + close(fd); free(strings); free(stats); - ERROR("ethstat plugin: Reading statistics from %s failed: %s", - device, - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("ethstat plugin: Reading statistics from %s failed: %s", device, + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } - for (size_t i = 0; i < n_stats; i++) - { + for (size_t i = 0; i < n_stats; i++) { char *stat_name; - stat_name = (void *) &strings->data[i * ETH_GSTRING_LEN]; + stat_name = (void *)&strings->data[i * ETH_GSTRING_LEN]; /* Remove leading spaces in key name */ - while (isspace ((int) *stat_name)) - stat_name++; + while (isspace((int)*stat_name)) + stat_name++; - DEBUG("ethstat plugin: device = \"%s\": %s = %"PRIu64, - device, stat_name, (uint64_t) stats->data[i]); - ethstat_submit_value (device, - stat_name, (derive_t) stats->data[i]); + DEBUG("ethstat plugin: device = \"%s\": %s = %" PRIu64, device, stat_name, + (uint64_t)stats->data[i]); + ethstat_submit_value(device, stat_name, (derive_t)stats->data[i]); } - close (fd); - sfree (strings); - sfree (stats); + close(fd); + sfree(strings); + sfree(stats); return (0); } /* }}} ethstat_read_interface */ -static int ethstat_read(void) -{ +static int ethstat_read(void) { for (size_t i = 0; i < interfaces_num; i++) - ethstat_read_interface (interfaces[i]); + ethstat_read_interface(interfaces[i]); return 0; } -static int ethstat_shutdown (void) -{ +static int ethstat_shutdown(void) { void *key = NULL; void *value = NULL; if (value_map == NULL) return (0); - while (c_avl_pick (value_map, &key, &value) == 0) - { - sfree (key); - sfree (value); + while (c_avl_pick(value_map, &key, &value) == 0) { + sfree(key); + sfree(value); } - c_avl_destroy (value_map); + c_avl_destroy(value_map); value_map = NULL; return (0); } -void module_register (void) -{ - plugin_register_complex_config ("ethstat", ethstat_config); - plugin_register_read ("ethstat", ethstat_read); - plugin_register_shutdown ("ethstat", ethstat_shutdown); +void module_register(void) { + plugin_register_complex_config("ethstat", ethstat_config); + plugin_register_read("ethstat", ethstat_read); + plugin_register_shutdown("ethstat", ethstat_shutdown); } /* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/exec.c b/src/exec.c index 70b5fd04..d34f9d91 100644 --- a/src/exec.c +++ b/src/exec.c @@ -31,22 +31,22 @@ #include "common.h" #include "plugin.h" -#include "utils_cmd_putval.h" #include "utils_cmd_putnotif.h" +#include "utils_cmd_putval.h" -#include -#include #include +#include #include +#include #ifdef HAVE_SYS_CAPABILITY_H -# include +#include #endif -#define PL_NORMAL 0x01 -#define PL_NOTIF_ACTION 0x02 +#define PL_NORMAL 0x01 +#define PL_NOTIF_ACTION 0x02 -#define PL_RUNNING 0x10 +#define PL_RUNNING 0x10 /* * Private data types @@ -61,20 +61,18 @@ */ struct program_list_s; typedef struct program_list_s program_list_t; -struct program_list_s -{ - char *user; - char *group; - char *exec; - char **argv; - int pid; - int status; - int flags; +struct program_list_s { + char *user; + char *group; + char *exec; + char **argv; + int pid; + int status; + int flags; program_list_t *next; }; -typedef struct program_list_and_notification_s -{ +typedef struct program_list_and_notification_s { program_list_t *pl; notification_t n; } program_list_and_notification_t; @@ -88,12 +86,11 @@ static pthread_mutex_t pl_lock = PTHREAD_MUTEX_INITIALIZER; /* * Functions */ -static void sigchld_handler (int __attribute__((unused)) signal) /* {{{ */ +static void sigchld_handler(int __attribute__((unused)) signal) /* {{{ */ { pid_t pid; int status; - while ((pid = waitpid (-1, &status, WNOHANG)) > 0) - { + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { program_list_t *pl; for (pl = pl_head; pl != NULL; pl = pl->next) if (pl->pid == pid) @@ -103,143 +100,124 @@ static void sigchld_handler (int __attribute__((unused)) signal) /* {{{ */ } /* while (waitpid) */ } /* void sigchld_handler }}} */ -static int exec_config_exec (oconfig_item_t *ci) /* {{{ */ +static int exec_config_exec(oconfig_item_t *ci) /* {{{ */ { program_list_t *pl; char buffer[128]; int i; - if (ci->children_num != 0) - { - WARNING ("exec plugin: The config option `%s' may not be a block.", - ci->key); + if (ci->children_num != 0) { + WARNING("exec plugin: The config option `%s' may not be a block.", ci->key); return (-1); } - if (ci->values_num < 2) - { - WARNING ("exec plugin: The config option `%s' needs at least two " - "arguments.", ci->key); + if (ci->values_num < 2) { + WARNING("exec plugin: The config option `%s' needs at least two " + "arguments.", + ci->key); return (-1); } - if ((ci->values[0].type != OCONFIG_TYPE_STRING) - || (ci->values[1].type != OCONFIG_TYPE_STRING)) - { - WARNING ("exec plugin: The first two arguments to the `%s' option must " - "be string arguments.", ci->key); + if ((ci->values[0].type != OCONFIG_TYPE_STRING) || + (ci->values[1].type != OCONFIG_TYPE_STRING)) { + WARNING("exec plugin: The first two arguments to the `%s' option must " + "be string arguments.", + ci->key); return (-1); } - pl = calloc (1, sizeof (*pl)); - if (pl == NULL) - { - ERROR ("exec plugin: calloc failed."); + pl = calloc(1, sizeof(*pl)); + if (pl == NULL) { + ERROR("exec plugin: calloc failed."); return (-1); } - if (strcasecmp ("NotificationExec", ci->key) == 0) + if (strcasecmp("NotificationExec", ci->key) == 0) pl->flags |= PL_NOTIF_ACTION; else pl->flags |= PL_NORMAL; - pl->user = strdup (ci->values[0].value.string); - if (pl->user == NULL) - { - ERROR ("exec plugin: strdup failed."); - sfree (pl); + pl->user = strdup(ci->values[0].value.string); + if (pl->user == NULL) { + ERROR("exec plugin: strdup failed."); + sfree(pl); return (-1); } - pl->group = strchr (pl->user, ':'); - if (pl->group != NULL) - { + pl->group = strchr(pl->user, ':'); + if (pl->group != NULL) { *pl->group = '\0'; pl->group++; } - pl->exec = strdup (ci->values[1].value.string); - if (pl->exec == NULL) - { - ERROR ("exec plugin: strdup failed."); - sfree (pl->user); - sfree (pl); + pl->exec = strdup(ci->values[1].value.string); + if (pl->exec == NULL) { + ERROR("exec plugin: strdup failed."); + sfree(pl->user); + sfree(pl); return (-1); } - pl->argv = calloc (ci->values_num, sizeof (*pl->argv)); - if (pl->argv == NULL) - { - ERROR ("exec plugin: calloc failed."); - sfree (pl->exec); - sfree (pl->user); - sfree (pl); + pl->argv = calloc(ci->values_num, sizeof(*pl->argv)); + if (pl->argv == NULL) { + ERROR("exec plugin: calloc failed."); + sfree(pl->exec); + sfree(pl->user); + sfree(pl); return (-1); } { - char *tmp = strrchr (ci->values[1].value.string, '/'); + char *tmp = strrchr(ci->values[1].value.string, '/'); if (tmp == NULL) - sstrncpy (buffer, ci->values[1].value.string, sizeof (buffer)); + sstrncpy(buffer, ci->values[1].value.string, sizeof(buffer)); else - sstrncpy (buffer, tmp + 1, sizeof (buffer)); + sstrncpy(buffer, tmp + 1, sizeof(buffer)); } - pl->argv[0] = strdup (buffer); - if (pl->argv[0] == NULL) - { - ERROR ("exec plugin: strdup failed."); - sfree (pl->argv); - sfree (pl->exec); - sfree (pl->user); - sfree (pl); + pl->argv[0] = strdup(buffer); + if (pl->argv[0] == NULL) { + ERROR("exec plugin: strdup failed."); + sfree(pl->argv); + sfree(pl->exec); + sfree(pl->user); + sfree(pl); return (-1); } - for (i = 1; i < (ci->values_num - 1); i++) - { - if (ci->values[i + 1].type == OCONFIG_TYPE_STRING) - { - pl->argv[i] = strdup (ci->values[i + 1].value.string); - } - else - { - if (ci->values[i + 1].type == OCONFIG_TYPE_NUMBER) - { - ssnprintf (buffer, sizeof (buffer), "%lf", - ci->values[i + 1].value.number); - } - else - { + for (i = 1; i < (ci->values_num - 1); i++) { + if (ci->values[i + 1].type == OCONFIG_TYPE_STRING) { + pl->argv[i] = strdup(ci->values[i + 1].value.string); + } else { + if (ci->values[i + 1].type == OCONFIG_TYPE_NUMBER) { + ssnprintf(buffer, sizeof(buffer), "%lf", + ci->values[i + 1].value.number); + } else { if (ci->values[i + 1].value.boolean) - sstrncpy (buffer, "true", sizeof (buffer)); + sstrncpy(buffer, "true", sizeof(buffer)); else - sstrncpy (buffer, "false", sizeof (buffer)); + sstrncpy(buffer, "false", sizeof(buffer)); } - pl->argv[i] = strdup (buffer); + pl->argv[i] = strdup(buffer); } - if (pl->argv[i] == NULL) - { - ERROR ("exec plugin: strdup failed."); + if (pl->argv[i] == NULL) { + ERROR("exec plugin: strdup failed."); break; } } /* for (i) */ - if (i < (ci->values_num - 1)) - { - while ((--i) >= 0) - { - sfree (pl->argv[i]); + if (i < (ci->values_num - 1)) { + while ((--i) >= 0) { + sfree(pl->argv[i]); } - sfree (pl->argv); - sfree (pl->exec); - sfree (pl->user); - sfree (pl); + sfree(pl->argv); + sfree(pl->exec); + sfree(pl->user); + sfree(pl); return (-1); } - for (i = 0; pl->argv[i] != NULL; i++) - { - DEBUG ("exec plugin: argv[%i] = %s", i, pl->argv[i]); + for (i = 0; pl->argv[i] != NULL; i++) { + DEBUG("exec plugin: argv[%i] = %s", i, pl->argv[i]); } pl->next = pl_head; @@ -248,134 +226,125 @@ static int exec_config_exec (oconfig_item_t *ci) /* {{{ */ return (0); } /* int exec_config_exec }}} */ -static int exec_config (oconfig_item_t *ci) /* {{{ */ +static int exec_config(oconfig_item_t *ci) /* {{{ */ { - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if ((strcasecmp ("Exec", child->key) == 0) - || (strcasecmp ("NotificationExec", child->key) == 0)) - exec_config_exec (child); - else - { - WARNING ("exec plugin: Unknown config option `%s'.", child->key); + if ((strcasecmp("Exec", child->key) == 0) || + (strcasecmp("NotificationExec", child->key) == 0)) + exec_config_exec(child); + else { + WARNING("exec plugin: Unknown config option `%s'.", child->key); } } /* for (i) */ return (0); } /* int exec_config }}} */ -static void set_environment (void) /* {{{ */ +static void set_environment(void) /* {{{ */ { char buffer[1024]; #ifdef HAVE_SETENV - ssnprintf (buffer, sizeof (buffer), "%.3f", - CDTIME_T_TO_DOUBLE (plugin_get_interval ())); - setenv ("COLLECTD_INTERVAL", buffer, /* overwrite = */ 1); + ssnprintf(buffer, sizeof(buffer), "%.3f", + CDTIME_T_TO_DOUBLE(plugin_get_interval())); + setenv("COLLECTD_INTERVAL", buffer, /* overwrite = */ 1); - sstrncpy (buffer, hostname_g, sizeof (buffer)); - setenv ("COLLECTD_HOSTNAME", buffer, /* overwrite = */ 1); + sstrncpy(buffer, hostname_g, sizeof(buffer)); + setenv("COLLECTD_HOSTNAME", buffer, /* overwrite = */ 1); #else - ssnprintf (buffer, sizeof (buffer), "COLLECTD_INTERVAL=%.3f", - CDTIME_T_TO_DOUBLE (plugin_get_interval ())); - putenv (buffer); + ssnprintf(buffer, sizeof(buffer), "COLLECTD_INTERVAL=%.3f", + CDTIME_T_TO_DOUBLE(plugin_get_interval())); + putenv(buffer); - ssnprintf (buffer, sizeof (buffer), "COLLECTD_HOSTNAME=%s", hostname_g); - putenv (buffer); + ssnprintf(buffer, sizeof(buffer), "COLLECTD_HOSTNAME=%s", hostname_g); + putenv(buffer); #endif } /* }}} void set_environment */ -__attribute__((noreturn)) -static void exec_child (program_list_t *pl, int uid, int gid, int egid) /* {{{ */ +__attribute__((noreturn)) static void exec_child(program_list_t *pl, int uid, + int gid, int egid) /* {{{ */ { int status; char errbuf[1024]; #if HAVE_SETGROUPS - if (getuid () == 0) - { - gid_t glist[2]; + if (getuid() == 0) { + gid_t glist[2]; size_t glist_len; glist[0] = gid; glist_len = 1; - if ((gid != egid) && (egid != -1)) - { + if ((gid != egid) && (egid != -1)) { glist[1] = egid; glist_len = 2; } - setgroups (glist_len, glist); + setgroups(glist_len, glist); } #endif /* HAVE_SETGROUPS */ - status = setgid (gid); - if (status != 0) - { - ERROR ("exec plugin: setgid (%i) failed: %s", - gid, sstrerror (errno, errbuf, sizeof (errbuf))); - exit (-1); + status = setgid(gid); + if (status != 0) { + ERROR("exec plugin: setgid (%i) failed: %s", gid, + sstrerror(errno, errbuf, sizeof(errbuf))); + exit(-1); } - if (egid != -1) - { - status = setegid (egid); - if (status != 0) - { - ERROR ("exec plugin: setegid (%i) failed: %s", - egid, sstrerror (errno, errbuf, sizeof (errbuf))); - exit (-1); + if (egid != -1) { + status = setegid(egid); + if (status != 0) { + ERROR("exec plugin: setegid (%i) failed: %s", egid, + sstrerror(errno, errbuf, sizeof(errbuf))); + exit(-1); } } - status = setuid (uid); - if (status != 0) - { - ERROR ("exec plugin: setuid (%i) failed: %s", - uid, sstrerror (errno, errbuf, sizeof (errbuf))); - exit (-1); + status = setuid(uid); + if (status != 0) { + ERROR("exec plugin: setuid (%i) failed: %s", uid, + sstrerror(errno, errbuf, sizeof(errbuf))); + exit(-1); } - execvp (pl->exec, pl->argv); + execvp(pl->exec, pl->argv); - ERROR ("exec plugin: Failed to execute ``%s'': %s", - pl->exec, sstrerror (errno, errbuf, sizeof (errbuf))); - exit (-1); + ERROR("exec plugin: Failed to execute ``%s'': %s", pl->exec, + sstrerror(errno, errbuf, sizeof(errbuf))); + exit(-1); } /* void exec_child }}} */ -static void reset_signal_mask (void) /* {{{ */ +static void reset_signal_mask(void) /* {{{ */ { sigset_t ss; - sigemptyset (&ss); - sigprocmask (SIG_SETMASK, &ss, /* old mask = */ NULL); + sigemptyset(&ss); + sigprocmask(SIG_SETMASK, &ss, /* old mask = */ NULL); } /* }}} void reset_signal_mask */ -static int create_pipe (int fd_pipe[2]) /* {{{ */ +static int create_pipe(int fd_pipe[2]) /* {{{ */ { char errbuf[1024]; int status; - status = pipe (fd_pipe); - if (status != 0) - { - ERROR ("exec plugin: pipe failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + status = pipe(fd_pipe); + if (status != 0) { + ERROR("exec plugin: pipe failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } return 0; } /* }}} int create_pipe */ -static void close_pipe (int fd_pipe[2]) /* {{{ */ +static void close_pipe(int fd_pipe[2]) /* {{{ */ { if (fd_pipe[0] != -1) - close (fd_pipe[0]); + close(fd_pipe[0]); if (fd_pipe[1] != -1) - close (fd_pipe[1]); + close(fd_pipe[1]); } /* }}} void close_pipe */ /* @@ -384,7 +353,8 @@ static void close_pipe (int fd_pipe[2]) /* {{{ */ * the child and fd_out is connected to STDOUT and fd_err is connected to STDERR * of the child. Then is calls `exec_child'. */ -static int fork_child (program_list_t *pl, int *fd_in, int *fd_out, int *fd_err) /* {{{ */ +static int fork_child(program_list_t *pl, int *fd_in, int *fd_out, + int *fd_err) /* {{{ */ { int fd_pipe_in[2] = {-1, -1}; int fd_pipe_out[2] = {-1, -1}; @@ -404,135 +374,118 @@ static int fork_child (program_list_t *pl, int *fd_in, int *fd_out, int *fd_err) if (pl->pid != 0) return (-1); - if ((create_pipe(fd_pipe_in) == -1) - || (create_pipe(fd_pipe_out) == -1) - || (create_pipe(fd_pipe_err) == -1)) + if ((create_pipe(fd_pipe_in) == -1) || (create_pipe(fd_pipe_out) == -1) || + (create_pipe(fd_pipe_err) == -1)) goto failed; sp_ptr = NULL; - status = getpwnam_r (pl->user, &sp, nambuf, sizeof (nambuf), &sp_ptr); - if (status != 0) - { - ERROR ("exec plugin: Failed to get user information for user ``%s'': %s", - pl->user, sstrerror (errno, errbuf, sizeof (errbuf))); + status = getpwnam_r(pl->user, &sp, nambuf, sizeof(nambuf), &sp_ptr); + if (status != 0) { + ERROR("exec plugin: Failed to get user information for user ``%s'': %s", + pl->user, sstrerror(errno, errbuf, sizeof(errbuf))); goto failed; } - if (sp_ptr == NULL) - { - ERROR ("exec plugin: No such user: `%s'", pl->user); + if (sp_ptr == NULL) { + ERROR("exec plugin: No such user: `%s'", pl->user); goto failed; } uid = sp.pw_uid; gid = sp.pw_gid; - if (uid == 0) - { - ERROR ("exec plugin: Cowardly refusing to exec program as root."); + if (uid == 0) { + ERROR("exec plugin: Cowardly refusing to exec program as root."); goto failed; } /* The group configured in the configfile is set as effective group, because * this way the forked process can (re-)gain the user's primary group. */ egid = -1; - if (NULL != pl->group) - { + if (NULL != pl->group) { if ('\0' != *pl->group) { struct group *gr_ptr = NULL; struct group gr; - status = getgrnam_r (pl->group, &gr, nambuf, sizeof (nambuf), &gr_ptr); - if (0 != status) - { - ERROR ("exec plugin: Failed to get group information " - "for group ``%s'': %s", pl->group, - sstrerror (errno, errbuf, sizeof (errbuf))); + status = getgrnam_r(pl->group, &gr, nambuf, sizeof(nambuf), &gr_ptr); + if (0 != status) { + ERROR("exec plugin: Failed to get group information " + "for group ``%s'': %s", + pl->group, sstrerror(errno, errbuf, sizeof(errbuf))); goto failed; } - if (NULL == gr_ptr) - { - ERROR ("exec plugin: No such group: `%s'", pl->group); + if (NULL == gr_ptr) { + ERROR("exec plugin: No such group: `%s'", pl->group); goto failed; } egid = gr.gr_gid; - } - else - { + } else { egid = gid; } } /* if (pl->group == NULL) */ - pid = fork (); - if (pid < 0) - { - ERROR ("exec plugin: fork failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + pid = fork(); + if (pid < 0) { + ERROR("exec plugin: fork failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); goto failed; - } - else if (pid == 0) - { + } else if (pid == 0) { int fd_num; /* Close all file descriptors but the pipe end we need. */ - fd_num = getdtablesize (); - for (int fd = 0; fd < fd_num; fd++) - { - if ((fd == fd_pipe_in[0]) - || (fd == fd_pipe_out[1]) - || (fd == fd_pipe_err[1])) + fd_num = getdtablesize(); + for (int fd = 0; fd < fd_num; fd++) { + if ((fd == fd_pipe_in[0]) || (fd == fd_pipe_out[1]) || + (fd == fd_pipe_err[1])) continue; - close (fd); + close(fd); } /* Connect the `in' pipe to STDIN */ - if (fd_pipe_in[0] != STDIN_FILENO) - { - dup2 (fd_pipe_in[0], STDIN_FILENO); - close (fd_pipe_in[0]); + if (fd_pipe_in[0] != STDIN_FILENO) { + dup2(fd_pipe_in[0], STDIN_FILENO); + close(fd_pipe_in[0]); } /* Now connect the `out' pipe to STDOUT */ - if (fd_pipe_out[1] != STDOUT_FILENO) - { - dup2 (fd_pipe_out[1], STDOUT_FILENO); - close (fd_pipe_out[1]); + if (fd_pipe_out[1] != STDOUT_FILENO) { + dup2(fd_pipe_out[1], STDOUT_FILENO); + close(fd_pipe_out[1]); } /* Now connect the `err' pipe to STDERR */ - if (fd_pipe_err[1] != STDERR_FILENO) - { - dup2 (fd_pipe_err[1], STDERR_FILENO); - close (fd_pipe_err[1]); + if (fd_pipe_err[1] != STDERR_FILENO) { + dup2(fd_pipe_err[1], STDERR_FILENO); + close(fd_pipe_err[1]); } - set_environment (); + set_environment(); /* Unblock all signals */ - reset_signal_mask (); + reset_signal_mask(); - exec_child (pl, uid, gid, egid); + exec_child(pl, uid, gid, egid); /* does not return */ } - close (fd_pipe_in[0]); - close (fd_pipe_out[1]); - close (fd_pipe_err[1]); + close(fd_pipe_in[0]); + close(fd_pipe_out[1]); + close(fd_pipe_err[1]); if (fd_in != NULL) *fd_in = fd_pipe_in[1]; else - close (fd_pipe_in[1]); + close(fd_pipe_in[1]); if (fd_out != NULL) *fd_out = fd_pipe_out[0]; else - close (fd_pipe_out[0]); + close(fd_pipe_out[0]); if (fd_err != NULL) *fd_err = fd_pipe_err[0]; else - close (fd_pipe_err[0]); + close(fd_pipe_err[0]); return (pid); @@ -544,45 +497,43 @@ failed: return (-1); } /* int fork_child }}} */ -static int parse_line (char *buffer) /* {{{ */ +static int parse_line(char *buffer) /* {{{ */ { - if (strncasecmp ("PUTVAL", buffer, strlen ("PUTVAL")) == 0) - return (cmd_handle_putval (stdout, buffer)); - else if (strncasecmp ("PUTNOTIF", buffer, strlen ("PUTNOTIF")) == 0) - return (handle_putnotif (stdout, buffer)); - else - { - ERROR ("exec plugin: Unable to parse command, ignoring line: \"%s\"", - buffer); + if (strncasecmp("PUTVAL", buffer, strlen("PUTVAL")) == 0) + return (cmd_handle_putval(stdout, buffer)); + else if (strncasecmp("PUTNOTIF", buffer, strlen("PUTNOTIF")) == 0) + return (handle_putnotif(stdout, buffer)); + else { + ERROR("exec plugin: Unable to parse command, ignoring line: \"%s\"", + buffer); return (-1); } } /* int parse_line }}} */ -static void *exec_read_one (void *arg) /* {{{ */ +static void *exec_read_one(void *arg) /* {{{ */ { - program_list_t *pl = (program_list_t *) arg; + program_list_t *pl = (program_list_t *)arg; int fd, fd_err, highest_fd; fd_set fdset, copy; int status; - char buffer[1200]; /* if not completely read */ + char buffer[1200]; /* if not completely read */ char buffer_err[1024]; char *pbuffer = buffer; char *pbuffer_err = buffer_err; - status = fork_child (pl, NULL, &fd, &fd_err); - if (status < 0) - { + status = fork_child(pl, NULL, &fd, &fd_err); + if (status < 0) { /* Reset the "running" flag */ - pthread_mutex_lock (&pl_lock); + pthread_mutex_lock(&pl_lock); pl->flags &= ~PL_RUNNING; - pthread_mutex_unlock (&pl_lock); - pthread_exit ((void *) 1); + pthread_mutex_unlock(&pl_lock); + pthread_exit((void *)1); } pl->pid = status; - assert (pl->pid != 0); + assert(pl->pid != 0); - FD_ZERO( &fdset ); + FD_ZERO(&fdset); FD_SET(fd, &fdset); FD_SET(fd_err, &fdset); @@ -592,79 +543,70 @@ static void *exec_read_one (void *arg) /* {{{ */ /* We use a copy of fdset, as select modifies it */ copy = fdset; - while (1) - { + while (1) { int len; - status = select (highest_fd + 1, ©, NULL, NULL, NULL); - if (status < 0) - { + status = select(highest_fd + 1, ©, NULL, NULL, NULL); + if (status < 0) { if (errno == EINTR) continue; break; } - if (FD_ISSET(fd, ©)) - { + if (FD_ISSET(fd, ©)) { char *pnl; len = read(fd, pbuffer, sizeof(buffer) - 1 - (pbuffer - buffer)); - if (len < 0) - { - if (errno == EAGAIN || errno == EINTR) continue; + if (len < 0) { + if (errno == EAGAIN || errno == EINTR) + continue; break; - } - else if (len == 0) break; /* We've reached EOF */ + } else if (len == 0) + break; /* We've reached EOF */ pbuffer[len] = '\0'; len += pbuffer - buffer; pbuffer = buffer; - while ((pnl = strchr(pbuffer, '\n'))) - { + while ((pnl = strchr(pbuffer, '\n'))) { *pnl = '\0'; - if (*(pnl-1) == '\r' ) *(pnl-1) = '\0'; + if (*(pnl - 1) == '\r') + *(pnl - 1) = '\0'; - parse_line (pbuffer); + parse_line(pbuffer); pbuffer = ++pnl; } /* not completely read ? */ - if (pbuffer - buffer < len) - { + if (pbuffer - buffer < len) { len -= pbuffer - buffer; memmove(buffer, pbuffer, len); pbuffer = buffer + len; - } - else + } else pbuffer = buffer; - } - else if (FD_ISSET(fd_err, ©)) - { + } else if (FD_ISSET(fd_err, ©)) { char *pnl; - len = read(fd_err, pbuffer_err, sizeof(buffer_err) - 1 - (pbuffer_err - buffer_err)); + len = read(fd_err, pbuffer_err, + sizeof(buffer_err) - 1 - (pbuffer_err - buffer_err)); - if (len < 0) - { + if (len < 0) { if (errno == EAGAIN || errno == EINTR) continue; break; - } - else if (len == 0) - { + } else if (len == 0) { /* We've reached EOF */ - NOTICE ("exec plugin: Program `%s' has closed STDERR.", pl->exec); + NOTICE("exec plugin: Program `%s' has closed STDERR.", pl->exec); /* Remove file descriptor form select() set. */ - FD_CLR (fd_err, &fdset); + FD_CLR(fd_err, &fdset); copy = fdset; highest_fd = fd; /* Clean up file descriptor */ - close (fd_err); + close(fd_err); fd_err = -1; continue; } @@ -674,76 +616,73 @@ static void *exec_read_one (void *arg) /* {{{ */ len += pbuffer_err - buffer_err; pbuffer_err = buffer_err; - while ((pnl = strchr(pbuffer_err, '\n'))) - { + while ((pnl = strchr(pbuffer_err, '\n'))) { *pnl = '\0'; - if (*(pnl-1) == '\r' ) *(pnl-1) = '\0'; + if (*(pnl - 1) == '\r') + *(pnl - 1) = '\0'; - ERROR ("exec plugin: exec_read_one: error = %s", pbuffer_err); + ERROR("exec plugin: exec_read_one: error = %s", pbuffer_err); pbuffer_err = ++pnl; } /* not completely read ? */ - if (pbuffer_err - buffer_err < len) - { + if (pbuffer_err - buffer_err < len) { len -= pbuffer_err - buffer_err; memmove(buffer_err, pbuffer_err, len); pbuffer_err = buffer_err + len; - } - else + } else pbuffer_err = buffer_err; } /* reset copy */ copy = fdset; } - DEBUG ("exec plugin: exec_read_one: Waiting for `%s' to exit.", pl->exec); - if (waitpid (pl->pid, &status, 0) > 0) + DEBUG("exec plugin: exec_read_one: Waiting for `%s' to exit.", pl->exec); + if (waitpid(pl->pid, &status, 0) > 0) pl->status = status; - DEBUG ("exec plugin: Child %i exited with status %i.", - (int) pl->pid, pl->status); + DEBUG("exec plugin: Child %i exited with status %i.", (int)pl->pid, + pl->status); pl->pid = 0; - pthread_mutex_lock (&pl_lock); + pthread_mutex_lock(&pl_lock); pl->flags &= ~PL_RUNNING; - pthread_mutex_unlock (&pl_lock); + pthread_mutex_unlock(&pl_lock); - close (fd); + close(fd); if (fd_err >= 0) - close (fd_err); + close(fd_err); - pthread_exit ((void *) 0); + pthread_exit((void *)0); return (NULL); } /* void *exec_read_one }}} */ -static void *exec_notification_one (void *arg) /* {{{ */ +static void *exec_notification_one(void *arg) /* {{{ */ { - program_list_t *pl = ((program_list_and_notification_t *) arg)->pl; - notification_t *n = &((program_list_and_notification_t *) arg)->n; + program_list_t *pl = ((program_list_and_notification_t *)arg)->pl; + notification_t *n = &((program_list_and_notification_t *)arg)->n; int fd; FILE *fh; int pid; int status; const char *severity; - pid = fork_child (pl, &fd, NULL, NULL); + pid = fork_child(pl, &fd, NULL, NULL); if (pid < 0) { - sfree (arg); - pthread_exit ((void *) 1); + sfree(arg); + pthread_exit((void *)1); } - fh = fdopen (fd, "w"); - if (fh == NULL) - { + fh = fdopen(fd, "w"); + if (fh == NULL) { char errbuf[1024]; - ERROR ("exec plugin: fdopen (%i) failed: %s", fd, - sstrerror (errno, errbuf, sizeof (errbuf))); - kill (pid, SIGTERM); - close (fd); - sfree (arg); - pthread_exit ((void *) 1); + ERROR("exec plugin: fdopen (%i) failed: %s", fd, + sstrerror(errno, errbuf, sizeof(errbuf))); + kill(pid, SIGTERM); + close(fd); + sfree(arg); + pthread_exit((void *)1); } severity = "FAILURE"; @@ -752,74 +691,72 @@ static void *exec_notification_one (void *arg) /* {{{ */ else if (n->severity == NOTIF_OKAY) severity = "OKAY"; - fprintf (fh, - "Severity: %s\n" - "Time: %.3f\n", - severity, CDTIME_T_TO_DOUBLE (n->time)); + fprintf(fh, "Severity: %s\n" + "Time: %.3f\n", + severity, CDTIME_T_TO_DOUBLE(n->time)); /* Print the optional fields */ - if (strlen (n->host) > 0) - fprintf (fh, "Host: %s\n", n->host); - if (strlen (n->plugin) > 0) - fprintf (fh, "Plugin: %s\n", n->plugin); - if (strlen (n->plugin_instance) > 0) - fprintf (fh, "PluginInstance: %s\n", n->plugin_instance); - if (strlen (n->type) > 0) - fprintf (fh, "Type: %s\n", n->type); - if (strlen (n->type_instance) > 0) - fprintf (fh, "TypeInstance: %s\n", n->type_instance); - - for (notification_meta_t *meta = n->meta; meta != NULL; meta = meta->next) - { + if (strlen(n->host) > 0) + fprintf(fh, "Host: %s\n", n->host); + if (strlen(n->plugin) > 0) + fprintf(fh, "Plugin: %s\n", n->plugin); + if (strlen(n->plugin_instance) > 0) + fprintf(fh, "PluginInstance: %s\n", n->plugin_instance); + if (strlen(n->type) > 0) + fprintf(fh, "Type: %s\n", n->type); + if (strlen(n->type_instance) > 0) + fprintf(fh, "TypeInstance: %s\n", n->type_instance); + + for (notification_meta_t *meta = n->meta; meta != NULL; meta = meta->next) { if (meta->type == NM_TYPE_STRING) - fprintf (fh, "%s: %s\n", meta->name, meta->nm_value.nm_string); + fprintf(fh, "%s: %s\n", meta->name, meta->nm_value.nm_string); else if (meta->type == NM_TYPE_SIGNED_INT) - fprintf (fh, "%s: %"PRIi64"\n", meta->name, meta->nm_value.nm_signed_int); + fprintf(fh, "%s: %" PRIi64 "\n", meta->name, + meta->nm_value.nm_signed_int); else if (meta->type == NM_TYPE_UNSIGNED_INT) - fprintf (fh, "%s: %"PRIu64"\n", meta->name, meta->nm_value.nm_unsigned_int); + fprintf(fh, "%s: %" PRIu64 "\n", meta->name, + meta->nm_value.nm_unsigned_int); else if (meta->type == NM_TYPE_DOUBLE) - fprintf (fh, "%s: %e\n", meta->name, meta->nm_value.nm_double); + fprintf(fh, "%s: %e\n", meta->name, meta->nm_value.nm_double); else if (meta->type == NM_TYPE_BOOLEAN) - fprintf (fh, "%s: %s\n", meta->name, - meta->nm_value.nm_boolean ? "true" : "false"); + fprintf(fh, "%s: %s\n", meta->name, + meta->nm_value.nm_boolean ? "true" : "false"); } - fprintf (fh, "\n%s\n", n->message); + fprintf(fh, "\n%s\n", n->message); - fflush (fh); - fclose (fh); + fflush(fh); + fclose(fh); - waitpid (pid, &status, 0); + waitpid(pid, &status, 0); - DEBUG ("exec plugin: Child %i exited with status %i.", - pid, status); + DEBUG("exec plugin: Child %i exited with status %i.", pid, status); if (n->meta != NULL) - plugin_notification_meta_free (n->meta); + plugin_notification_meta_free(n->meta); n->meta = NULL; - sfree (arg); - pthread_exit ((void *) 0); + sfree(arg); + pthread_exit((void *)0); return (NULL); } /* void *exec_notification_one }}} */ -static int exec_init (void) /* {{{ */ +static int exec_init(void) /* {{{ */ { - struct sigaction sa = { - .sa_handler = sigchld_handler - }; + struct sigaction sa = {.sa_handler = sigchld_handler}; - sigaction (SIGCHLD, &sa, NULL); + sigaction(SIGCHLD, &sa, NULL); #if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_SETUID) && defined(CAP_SETGID) - if ((check_capability (CAP_SETUID) != 0) || - (check_capability (CAP_SETGID) != 0)) - { - if (getuid () == 0) - WARNING ("exec plugin: Running collectd as root, but the CAP_SETUID " + if ((check_capability(CAP_SETUID) != 0) || + (check_capability(CAP_SETGID) != 0)) { + if (getuid() == 0) + WARNING( + "exec plugin: Running collectd as root, but the CAP_SETUID " "or CAP_SETGID capabilities are missing. The plugin's read function " "will probably fail. Is your init system dropping capabilities?"); else - WARNING ("exec plugin: collectd doesn't have the CAP_SETUID or " + WARNING( + "exec plugin: collectd doesn't have the CAP_SETUID or " "CAP_SETGID capabilities. If you don't want to run collectd as root, " "try running \"setcap 'cap_setuid=ep cap_setgid=ep'\" on the " "collectd binary."); @@ -829,10 +766,9 @@ static int exec_init (void) /* {{{ */ return (0); } /* int exec_init }}} */ -static int exec_read (void) /* {{{ */ +static int exec_read(void) /* {{{ */ { - for (program_list_t *pl = pl_head; pl != NULL; pl = pl->next) - { + for (program_list_t *pl = pl_head; pl != NULL; pl = pl->next) { pthread_t t; pthread_attr_t attr; @@ -840,32 +776,29 @@ static int exec_read (void) /* {{{ */ if ((pl->flags & PL_NORMAL) == 0) continue; - pthread_mutex_lock (&pl_lock); + pthread_mutex_lock(&pl_lock); /* Skip if a child is already running. */ - if ((pl->flags & PL_RUNNING) != 0) - { - pthread_mutex_unlock (&pl_lock); + if ((pl->flags & PL_RUNNING) != 0) { + pthread_mutex_unlock(&pl_lock); continue; } pl->flags |= PL_RUNNING; - pthread_mutex_unlock (&pl_lock); + pthread_mutex_unlock(&pl_lock); - pthread_attr_init (&attr); - pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); - plugin_thread_create (&t, &attr, exec_read_one, (void *) pl, "exec read"); - pthread_attr_destroy (&attr); + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + plugin_thread_create(&t, &attr, exec_read_one, (void *)pl, "exec read"); + pthread_attr_destroy(&attr); } /* for (pl) */ return (0); } /* int exec_read }}} */ -static int exec_notification (const notification_t *n, /* {{{ */ - user_data_t __attribute__((unused)) *user_data) -{ +static int exec_notification(const notification_t *n, /* {{{ */ + user_data_t __attribute__((unused)) * user_data) { program_list_and_notification_t *pln; - for (program_list_t *pl = pl_head; pl != NULL; pl = pl->next) - { + for (program_list_t *pl = pl_head; pl != NULL; pl = pl->next) { pthread_t t; pthread_attr_t attr; @@ -877,49 +810,46 @@ static int exec_notification (const notification_t *n, /* {{{ */ if (pl->pid != 0) continue; - pln = malloc (sizeof (*pln)); - if (pln == NULL) - { - ERROR ("exec plugin: malloc failed."); + pln = malloc(sizeof(*pln)); + if (pln == NULL) { + ERROR("exec plugin: malloc failed."); continue; } pln->pl = pl; - memcpy (&pln->n, n, sizeof (notification_t)); + memcpy(&pln->n, n, sizeof(notification_t)); /* Set the `meta' member to NULL, otherwise `plugin_notification_meta_copy' * will run into an endless loop. */ pln->n.meta = NULL; - plugin_notification_meta_copy (&pln->n, n); + plugin_notification_meta_copy(&pln->n, n); - pthread_attr_init (&attr); - pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); - plugin_thread_create (&t, &attr, exec_notification_one, (void *) pln, - "exec notify"); - pthread_attr_destroy (&attr); + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + plugin_thread_create(&t, &attr, exec_notification_one, (void *)pln, + "exec notify"); + pthread_attr_destroy(&attr); } /* for (pl) */ return (0); } /* }}} int exec_notification */ -static int exec_shutdown (void) /* {{{ */ +static int exec_shutdown(void) /* {{{ */ { program_list_t *pl; program_list_t *next; pl = pl_head; - while (pl != NULL) - { + while (pl != NULL) { next = pl->next; - if (pl->pid > 0) - { - kill (pl->pid, SIGTERM); - INFO ("exec plugin: Sent SIGTERM to %hu", (unsigned short int) pl->pid); + if (pl->pid > 0) { + kill(pl->pid, SIGTERM); + INFO("exec plugin: Sent SIGTERM to %hu", (unsigned short int)pl->pid); } - sfree (pl->user); - sfree (pl); + sfree(pl->user); + sfree(pl); pl = next; } /* while (pl) */ @@ -928,14 +858,13 @@ static int exec_shutdown (void) /* {{{ */ return (0); } /* int exec_shutdown }}} */ -void module_register (void) -{ - plugin_register_complex_config ("exec", exec_config); - plugin_register_init ("exec", exec_init); - plugin_register_read ("exec", exec_read); - plugin_register_notification ("exec", exec_notification, - /* user_data = */ NULL); - plugin_register_shutdown ("exec", exec_shutdown); +void module_register(void) { + plugin_register_complex_config("exec", exec_config); + plugin_register_init("exec", exec_init); + plugin_register_read("exec", exec_read); + plugin_register_notification("exec", exec_notification, + /* user_data = */ NULL); + plugin_register_shutdown("exec", exec_shutdown); } /* void module_register */ /* diff --git a/src/fhcount.c b/src/fhcount.c index 00bd7325..92107839 100644 --- a/src/fhcount.c +++ b/src/fhcount.c @@ -22,17 +22,12 @@ #include "common.h" #include "plugin.h" - -static const char *config_keys[] = { - "ValuesAbsolute", - "ValuesPercentage" -}; +static const char *config_keys[] = {"ValuesAbsolute", "ValuesPercentage"}; static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static _Bool values_absolute = 1; static _Bool values_percentage = 0; - static int fhcount_config(const char *key, const char *value) { int ret = -1; @@ -54,15 +49,14 @@ static int fhcount_config(const char *key, const char *value) { ret = 0; } - return(ret); + return (ret); } - -static void fhcount_submit( - const char *type, const char *type_instance, gauge_t value) { +static void fhcount_submit(const char *type, const char *type_instance, + gauge_t value) { value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; + vl.values = &(value_t){.gauge = value}; vl.values_len = 1; // Compose the metric @@ -85,15 +79,15 @@ static int fhcount_read(void) { FILE *fp; // Open file - fp = fopen("/proc/sys/fs/file-nr" , "r"); + fp = fopen("/proc/sys/fs/file-nr", "r"); if (fp == NULL) { ERROR("fhcount: fopen: %s", sstrerror(errno, errbuf, sizeof(errbuf))); - return(EXIT_FAILURE); + return (EXIT_FAILURE); } if (fgets(buffer, buffer_len, fp) == NULL) { ERROR("fhcount: fgets: %s", sstrerror(errno, errbuf, sizeof(errbuf))); fclose(fp); - return(EXIT_FAILURE); + return (EXIT_FAILURE); } fclose(fp); @@ -102,33 +96,32 @@ static int fhcount_read(void) { if (numfields != 3) { ERROR("fhcount: Line doesn't contain 3 fields"); - return(EXIT_FAILURE); + return (EXIT_FAILURE); } // Define the values strtogauge(fields[0], &used); strtogauge(fields[1], &unused); strtogauge(fields[2], &max); - prc_used = (gauge_t) used/max*100; - prc_unused = (gauge_t) unused/max*100; + prc_used = (gauge_t)used / max * 100; + prc_unused = (gauge_t)unused / max * 100; // Submit values if (values_absolute) { - fhcount_submit("file_handles", "used", (gauge_t) used); - fhcount_submit("file_handles", "unused", (gauge_t) unused); - fhcount_submit("file_handles", "max", (gauge_t) max); + fhcount_submit("file_handles", "used", (gauge_t)used); + fhcount_submit("file_handles", "unused", (gauge_t)unused); + fhcount_submit("file_handles", "max", (gauge_t)max); } if (values_percentage) { - fhcount_submit("percent", "used", (gauge_t) prc_used); - fhcount_submit("percent", "unused", (gauge_t) prc_unused); + fhcount_submit("percent", "used", (gauge_t)prc_used); + fhcount_submit("percent", "unused", (gauge_t)prc_unused); } - return(0); + return (0); } - void module_register(void) { - plugin_register_config( - "fhcount", fhcount_config, config_keys, config_keys_num); + plugin_register_config("fhcount", fhcount_config, config_keys, + config_keys_num); plugin_register_read("fhcount", fhcount_read); } diff --git a/src/filecount.c b/src/filecount.c index 74bc5fb3..a78b8800 100644 --- a/src/filecount.c +++ b/src/filecount.c @@ -26,17 +26,16 @@ #include "common.h" #include "plugin.h" -#include -#include -#include #include +#include #include +#include +#include #define FC_RECURSIVE 1 #define FC_HIDDEN 2 -struct fc_directory_conf_s -{ +struct fc_directory_conf_s { char *path; char *instance; @@ -59,22 +58,21 @@ typedef struct fc_directory_conf_s fc_directory_conf_t; static fc_directory_conf_t **directories = NULL; static size_t directories_num = 0; -static void fc_submit_dir (const fc_directory_conf_t *dir) -{ +static void fc_submit_dir(const fc_directory_conf_t *dir) { value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = (gauge_t) dir->files_num }; + vl.values = &(value_t){.gauge = (gauge_t)dir->files_num}; vl.values_len = 1; - sstrncpy (vl.plugin, "filecount", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, dir->instance, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, "files", sizeof (vl.type)); + sstrncpy(vl.plugin, "filecount", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, dir->instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "files", sizeof(vl.type)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); - vl.values = &(value_t) { .gauge = (gauge_t) dir->files_size }; - sstrncpy (vl.type, "bytes", sizeof (vl.type)); + vl.values = &(value_t){.gauge = (gauge_t)dir->files_size}; + sstrncpy(vl.type, "bytes", sizeof(vl.type)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* void fc_submit_dir */ /* @@ -93,13 +91,12 @@ static void fc_submit_dir (const fc_directory_conf_t *dir) * - Total size */ -static int fc_config_set_instance (fc_directory_conf_t *dir, const char *str) -{ +static int fc_config_set_instance(fc_directory_conf_t *dir, const char *str) { char buffer[1024]; char *ptr; char *copy; - sstrncpy (buffer, str, sizeof (buffer)); + sstrncpy(buffer, str, sizeof(buffer)); for (ptr = buffer; *ptr != 0; ptr++) if (*ptr == '/') *ptr = '_'; @@ -110,212 +107,190 @@ static int fc_config_set_instance (fc_directory_conf_t *dir, const char *str) if (*ptr == 0) return (-1); - copy = strdup (ptr); + copy = strdup(ptr); if (copy == NULL) return (-1); - sfree (dir->instance); + sfree(dir->instance); dir->instance = copy; return (0); } /* int fc_config_set_instance */ -static int fc_config_add_dir_instance (fc_directory_conf_t *dir, - oconfig_item_t *ci) -{ - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("filecount plugin: The `Instance' config option needs exactly " - "one string argument."); +static int fc_config_add_dir_instance(fc_directory_conf_t *dir, + oconfig_item_t *ci) { + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("filecount plugin: The `Instance' config option needs exactly " + "one string argument."); return (-1); } - return (fc_config_set_instance (dir, ci->values[0].value.string)); + return (fc_config_set_instance(dir, ci->values[0].value.string)); } /* int fc_config_add_dir_instance */ -static int fc_config_add_dir_name (fc_directory_conf_t *dir, - oconfig_item_t *ci) -{ +static int fc_config_add_dir_name(fc_directory_conf_t *dir, + oconfig_item_t *ci) { char *temp; - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("filecount plugin: The `Name' config option needs exactly one " - "string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("filecount plugin: The `Name' config option needs exactly one " + "string argument."); return (-1); } - temp = strdup (ci->values[0].value.string); - if (temp == NULL) - { - ERROR ("filecount plugin: strdup failed."); + temp = strdup(ci->values[0].value.string); + if (temp == NULL) { + ERROR("filecount plugin: strdup failed."); return (-1); } - sfree (dir->name); + sfree(dir->name); dir->name = temp; return (0); } /* int fc_config_add_dir_name */ -static int fc_config_add_dir_mtime (fc_directory_conf_t *dir, - oconfig_item_t *ci) -{ +static int fc_config_add_dir_mtime(fc_directory_conf_t *dir, + oconfig_item_t *ci) { char *endptr; double temp; - if ((ci->values_num != 1) - || ((ci->values[0].type != OCONFIG_TYPE_STRING) - && (ci->values[0].type != OCONFIG_TYPE_NUMBER))) - { - WARNING ("filecount plugin: The `MTime' config option needs exactly one " - "string or numeric argument."); + if ((ci->values_num != 1) || ((ci->values[0].type != OCONFIG_TYPE_STRING) && + (ci->values[0].type != OCONFIG_TYPE_NUMBER))) { + WARNING("filecount plugin: The `MTime' config option needs exactly one " + "string or numeric argument."); return (-1); } - if (ci->values[0].type == OCONFIG_TYPE_NUMBER) - { - dir->mtime = (int64_t) ci->values[0].value.number; + if (ci->values[0].type == OCONFIG_TYPE_NUMBER) { + dir->mtime = (int64_t)ci->values[0].value.number; return (0); } errno = 0; endptr = NULL; - temp = strtod (ci->values[0].value.string, &endptr); - if ((errno != 0) || (endptr == NULL) - || (endptr == ci->values[0].value.string)) - { - WARNING ("filecount plugin: Converting `%s' to a number failed.", - ci->values[0].value.string); + temp = strtod(ci->values[0].value.string, &endptr); + if ((errno != 0) || (endptr == NULL) || + (endptr == ci->values[0].value.string)) { + WARNING("filecount plugin: Converting `%s' to a number failed.", + ci->values[0].value.string); return (-1); } - switch (*endptr) - { - case 0: - case 's': - case 'S': - break; - - case 'm': - case 'M': - temp *= 60; - break; - - case 'h': - case 'H': - temp *= 3600; - break; - - case 'd': - case 'D': - temp *= 86400; - break; - - case 'w': - case 'W': - temp *= 7 * 86400; - break; - - case 'y': - case 'Y': - temp *= 31557600; /* == 365.25 * 86400 */ - break; - - default: - WARNING ("filecount plugin: Invalid suffix for `MTime': `%c'", *endptr); - return (-1); + switch (*endptr) { + case 0: + case 's': + case 'S': + break; + + case 'm': + case 'M': + temp *= 60; + break; + + case 'h': + case 'H': + temp *= 3600; + break; + + case 'd': + case 'D': + temp *= 86400; + break; + + case 'w': + case 'W': + temp *= 7 * 86400; + break; + + case 'y': + case 'Y': + temp *= 31557600; /* == 365.25 * 86400 */ + break; + + default: + WARNING("filecount plugin: Invalid suffix for `MTime': `%c'", *endptr); + return (-1); } /* switch (*endptr) */ - dir->mtime = (int64_t) temp; + dir->mtime = (int64_t)temp; return (0); } /* int fc_config_add_dir_mtime */ -static int fc_config_add_dir_size (fc_directory_conf_t *dir, - oconfig_item_t *ci) -{ +static int fc_config_add_dir_size(fc_directory_conf_t *dir, + oconfig_item_t *ci) { char *endptr; double temp; - if ((ci->values_num != 1) - || ((ci->values[0].type != OCONFIG_TYPE_STRING) - && (ci->values[0].type != OCONFIG_TYPE_NUMBER))) - { - WARNING ("filecount plugin: The `Size' config option needs exactly one " - "string or numeric argument."); + if ((ci->values_num != 1) || ((ci->values[0].type != OCONFIG_TYPE_STRING) && + (ci->values[0].type != OCONFIG_TYPE_NUMBER))) { + WARNING("filecount plugin: The `Size' config option needs exactly one " + "string or numeric argument."); return (-1); } - if (ci->values[0].type == OCONFIG_TYPE_NUMBER) - { - dir->size = (int64_t) ci->values[0].value.number; + if (ci->values[0].type == OCONFIG_TYPE_NUMBER) { + dir->size = (int64_t)ci->values[0].value.number; return (0); } errno = 0; endptr = NULL; - temp = strtod (ci->values[0].value.string, &endptr); - if ((errno != 0) || (endptr == NULL) - || (endptr == ci->values[0].value.string)) - { - WARNING ("filecount plugin: Converting `%s' to a number failed.", - ci->values[0].value.string); + temp = strtod(ci->values[0].value.string, &endptr); + if ((errno != 0) || (endptr == NULL) || + (endptr == ci->values[0].value.string)) { + WARNING("filecount plugin: Converting `%s' to a number failed.", + ci->values[0].value.string); return (-1); } - switch (*endptr) - { - case 0: - case 'b': - case 'B': - break; - - case 'k': - case 'K': - temp *= 1000.0; - break; - - case 'm': - case 'M': - temp *= 1000.0 * 1000.0; - break; - - case 'g': - case 'G': - temp *= 1000.0 * 1000.0 * 1000.0; - break; - - case 't': - case 'T': - temp *= 1000.0 * 1000.0 * 1000.0 * 1000.0; - break; - - case 'p': - case 'P': - temp *= 1000.0 * 1000.0 * 1000.0 * 1000.0 * 1000.0; - break; - - default: - WARNING ("filecount plugin: Invalid suffix for `Size': `%c'", *endptr); - return (-1); + switch (*endptr) { + case 0: + case 'b': + case 'B': + break; + + case 'k': + case 'K': + temp *= 1000.0; + break; + + case 'm': + case 'M': + temp *= 1000.0 * 1000.0; + break; + + case 'g': + case 'G': + temp *= 1000.0 * 1000.0 * 1000.0; + break; + + case 't': + case 'T': + temp *= 1000.0 * 1000.0 * 1000.0 * 1000.0; + break; + + case 'p': + case 'P': + temp *= 1000.0 * 1000.0 * 1000.0 * 1000.0 * 1000.0; + break; + + default: + WARNING("filecount plugin: Invalid suffix for `Size': `%c'", *endptr); + return (-1); } /* switch (*endptr) */ - dir->size = (int64_t) temp; + dir->size = (int64_t)temp; return (0); } /* int fc_config_add_dir_size */ -static int fc_config_add_dir_option (fc_directory_conf_t *dir, - oconfig_item_t *ci, int bit) -{ - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) - { - WARNING ("filecount plugin: The `Recursive' config options needs exactly " - "one boolean argument."); +static int fc_config_add_dir_option(fc_directory_conf_t *dir, + oconfig_item_t *ci, int bit) { + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) { + WARNING("filecount plugin: The `Recursive' config options needs exactly " + "one boolean argument."); return (-1); } @@ -327,35 +302,31 @@ static int fc_config_add_dir_option (fc_directory_conf_t *dir, return (0); } /* int fc_config_add_dir_option */ -static int fc_config_add_dir (oconfig_item_t *ci) -{ +static int fc_config_add_dir(oconfig_item_t *ci) { fc_directory_conf_t *dir; int status; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("filecount plugin: `Directory' needs exactly one string " - "argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("filecount plugin: `Directory' needs exactly one string " + "argument."); return (-1); } /* Initialize `dir' */ - dir = calloc (1, sizeof (*dir)); - if (dir == NULL) - { - ERROR ("filecount plugin: calloc failed."); + dir = calloc(1, sizeof(*dir)); + if (dir == NULL) { + ERROR("filecount plugin: calloc failed."); return (-1); } - dir->path = strdup (ci->values[0].value.string); - if (dir->path == NULL) - { - ERROR ("filecount plugin: strdup failed."); - sfree (dir); + dir->path = strdup(ci->values[0].value.string); + if (dir->path == NULL) { + ERROR("filecount plugin: strdup failed."); + sfree(dir); return (-1); } - fc_config_set_instance (dir, dir->path); + fc_config_set_instance(dir, dir->path); dir->options = FC_RECURSIVE; @@ -364,26 +335,25 @@ static int fc_config_add_dir (oconfig_item_t *ci) dir->size = 0; status = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; - if (strcasecmp ("Instance", option->key) == 0) - status = fc_config_add_dir_instance (dir, option); - else if (strcasecmp ("Name", option->key) == 0) - status = fc_config_add_dir_name (dir, option); - else if (strcasecmp ("MTime", option->key) == 0) - status = fc_config_add_dir_mtime (dir, option); - else if (strcasecmp ("Size", option->key) == 0) - status = fc_config_add_dir_size (dir, option); - else if (strcasecmp ("Recursive", option->key) == 0) - status = fc_config_add_dir_option (dir, option, FC_RECURSIVE); - else if (strcasecmp ("IncludeHidden", option->key) == 0) - status = fc_config_add_dir_option (dir, option, FC_HIDDEN); - else - { - WARNING ("filecount plugin: fc_config_add_dir: " - "Option `%s' not allowed here.", option->key); + if (strcasecmp("Instance", option->key) == 0) + status = fc_config_add_dir_instance(dir, option); + else if (strcasecmp("Name", option->key) == 0) + status = fc_config_add_dir_name(dir, option); + else if (strcasecmp("MTime", option->key) == 0) + status = fc_config_add_dir_mtime(dir, option); + else if (strcasecmp("Size", option->key) == 0) + status = fc_config_add_dir_size(dir, option); + else if (strcasecmp("Recursive", option->key) == 0) + status = fc_config_add_dir_option(dir, option, FC_RECURSIVE); + else if (strcasecmp("IncludeHidden", option->key) == 0) + status = fc_config_add_dir_option(dir, option, FC_HIDDEN); + else { + WARNING("filecount plugin: fc_config_add_dir: " + "Option `%s' not allowed here.", + option->key); status = -1; } @@ -391,68 +361,56 @@ static int fc_config_add_dir (oconfig_item_t *ci) break; } /* for (ci->children) */ - if (status == 0) - { + if (status == 0) { fc_directory_conf_t **temp; - temp = realloc (directories, - sizeof (*directories) * (directories_num + 1)); - if (temp == NULL) - { - ERROR ("filecount plugin: realloc failed."); + temp = realloc(directories, sizeof(*directories) * (directories_num + 1)); + if (temp == NULL) { + ERROR("filecount plugin: realloc failed."); status = -1; - } - else - { + } else { directories = temp; directories[directories_num] = dir; directories_num++; } } - if (status != 0) - { - sfree (dir->name); - sfree (dir->instance); - sfree (dir->path); - sfree (dir); + if (status != 0) { + sfree(dir->name); + sfree(dir->instance); + sfree(dir->path); + sfree(dir); return (-1); } return (0); } /* int fc_config_add_dir */ -static int fc_config (oconfig_item_t *ci) -{ - for (int i = 0; i < ci->children_num; i++) - { +static int fc_config(oconfig_item_t *ci) { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Directory", child->key) == 0) - fc_config_add_dir (child); - else - { - WARNING ("filecount plugin: Ignoring unknown config option `%s'.", - child->key); + if (strcasecmp("Directory", child->key) == 0) + fc_config_add_dir(child); + else { + WARNING("filecount plugin: Ignoring unknown config option `%s'.", + child->key); } } /* for (ci->children) */ return (0); } /* int fc_config */ -static int fc_init (void) -{ - if (directories_num < 1) - { - WARNING ("filecount plugin: No directories have been configured."); +static int fc_init(void) { + if (directories_num < 1) { + WARNING("filecount plugin: No directories have been configured."); return (-1); } return (0); } /* int fc_init */ -static int fc_read_dir_callback (const char *dirname, const char *filename, - void *user_data) -{ +static int fc_read_dir_callback(const char *dirname, const char *filename, + void *user_data) { fc_directory_conf_t *dir = user_data; char abs_path[PATH_MAX]; struct stat statbuf; @@ -461,35 +419,30 @@ static int fc_read_dir_callback (const char *dirname, const char *filename, if (dir == NULL) return (-1); - ssnprintf (abs_path, sizeof (abs_path), "%s/%s", dirname, filename); + ssnprintf(abs_path, sizeof(abs_path), "%s/%s", dirname, filename); - status = lstat (abs_path, &statbuf); - if (status != 0) - { - ERROR ("filecount plugin: stat (%s) failed.", abs_path); + status = lstat(abs_path, &statbuf); + if (status != 0) { + ERROR("filecount plugin: stat (%s) failed.", abs_path); return (-1); } - if (S_ISDIR (statbuf.st_mode) && (dir->options & FC_RECURSIVE)) - { - status = walk_directory (abs_path, fc_read_dir_callback, dir, + if (S_ISDIR(statbuf.st_mode) && (dir->options & FC_RECURSIVE)) { + status = walk_directory( + abs_path, fc_read_dir_callback, dir, /* include hidden = */ (dir->options & FC_HIDDEN) ? 1 : 0); return (status); - } - else if (!S_ISREG (statbuf.st_mode)) - { + } else if (!S_ISREG(statbuf.st_mode)) { return (0); } - if (dir->name != NULL) - { - status = fnmatch (dir->name, filename, /* flags = */ 0); + if (dir->name != NULL) { + status = fnmatch(dir->name, filename, /* flags = */ 0); if (status != 0) return (0); } - if (dir->mtime != 0) - { + if (dir->mtime != 0) { time_t mtime = dir->now; if (dir->mtime < 0) @@ -497,71 +450,66 @@ static int fc_read_dir_callback (const char *dirname, const char *filename, else mtime -= dir->mtime; - DEBUG ("filecount plugin: Only collecting files that were touched %s %u.", - (dir->mtime < 0) ? "after" : "before", - (unsigned int) mtime); + DEBUG("filecount plugin: Only collecting files that were touched %s %u.", + (dir->mtime < 0) ? "after" : "before", (unsigned int)mtime); - if (((dir->mtime < 0) && (statbuf.st_mtime < mtime)) - || ((dir->mtime > 0) && (statbuf.st_mtime > mtime))) + if (((dir->mtime < 0) && (statbuf.st_mtime < mtime)) || + ((dir->mtime > 0) && (statbuf.st_mtime > mtime))) return (0); } - if (dir->size != 0) - { + if (dir->size != 0) { off_t size; if (dir->size < 0) - size = (off_t) ((-1) * dir->size); + size = (off_t)((-1) * dir->size); else - size = (off_t) dir->size; + size = (off_t)dir->size; - if (((dir->size < 0) && (statbuf.st_size > size)) - || ((dir->size > 0) && (statbuf.st_size < size))) + if (((dir->size < 0) && (statbuf.st_size > size)) || + ((dir->size > 0) && (statbuf.st_size < size))) return (0); } dir->files_num++; - dir->files_size += (uint64_t) statbuf.st_size; + dir->files_size += (uint64_t)statbuf.st_size; return (0); } /* int fc_read_dir_callback */ -static int fc_read_dir (fc_directory_conf_t *dir) -{ +static int fc_read_dir(fc_directory_conf_t *dir) { int status; dir->files_num = 0; dir->files_size = 0; if (dir->mtime != 0) - dir->now = time (NULL); + dir->now = time(NULL); - status = walk_directory (dir->path, fc_read_dir_callback, dir, - /* include hidden */ (dir->options & FC_HIDDEN) ? 1 : 0); - if (status != 0) - { - WARNING ("filecount plugin: walk_directory (%s) failed.", dir->path); + status = + walk_directory(dir->path, fc_read_dir_callback, dir, + /* include hidden */ (dir->options & FC_HIDDEN) ? 1 : 0); + if (status != 0) { + WARNING("filecount plugin: walk_directory (%s) failed.", dir->path); return (-1); } - fc_submit_dir (dir); + fc_submit_dir(dir); return (0); } /* int fc_read_dir */ -static int fc_read (void) -{ +static int fc_read(void) { for (size_t i = 0; i < directories_num; i++) - fc_read_dir (directories[i]); + fc_read_dir(directories[i]); return (0); } /* int fc_read */ -void module_register (void) -{ - plugin_register_complex_config ("filecount", fc_config); - plugin_register_init ("filecount", fc_init); - plugin_register_read ("filecount", fc_read); +void module_register(void) { + plugin_register_complex_config("filecount", fc_config); + plugin_register_init("filecount", fc_init); + plugin_register_read("filecount", fc_read); } /* void module_register */ /* diff --git a/src/fscache.c b/src/fscache.c index 3a5baf5b..c410ea39 100644 --- a/src/fscache.c +++ b/src/fscache.c @@ -21,15 +21,14 @@ #include "collectd.h" -#include "common.h" -#include "plugin.h" #include /* a header needed for FILE */ -#include /* a header needed for scanf function */ #include /* used for atoi */ - +#include /* a header needed for scanf function */ +#include "common.h" +#include "plugin.h" #if !KERNEL_LINUX -# error "This module only supports the Linux implementation of fscache" +#error "This module only supports the Linux implementation of fscache" #endif #define BUFSIZE 1024 @@ -107,123 +106,116 @@ Ops pend=N Number of times async ops added to pending queues 63 events to collect in 13 groups */ -static void fscache_submit (const char *section, const char *name, - value_t value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void fscache_submit(const char *section, const char *name, + value_t value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &value; - vl.values_len = 1; + vl.values = &value; + vl.values_len = 1; - sstrncpy(vl.plugin, "fscache", sizeof (vl.plugin)); - sstrncpy(vl.plugin_instance, section, sizeof (vl.plugin_instance)); - sstrncpy(vl.type, "fscache_stat", sizeof(vl.type)); - sstrncpy(vl.type_instance, name, sizeof(vl.type_instance)); + sstrncpy(vl.plugin, "fscache", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, section, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "fscache_stat", sizeof(vl.type)); + sstrncpy(vl.type_instance, name, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static void fscache_read_stats_file (FILE *fh) -{ - char section[DATA_MAX_NAME_LEN]; - size_t section_len; +static void fscache_read_stats_file(FILE *fh) { + char section[DATA_MAX_NAME_LEN]; + size_t section_len; + + char linebuffer[BUFSIZE]; + + /* + * cat /proc/fs/fscache/stats + * FS-Cache statistics + * Cookies: idx=2 dat=0 spc=0 + * Objects: alc=0 nal=0 avl=0 ded=0 + * ChkAux : non=0 ok=0 upd=0 obs=0 + * Pages : mrk=0 unc=0 + * Acquire: n=2 nul=0 noc=0 ok=2 nbf=0 oom=0 + * Lookups: n=0 neg=0 pos=0 crt=0 + * Updates: n=0 nul=0 run=0 + * Relinqs: n=0 nul=0 wcr=0 + * AttrChg: n=0 ok=0 nbf=0 oom=0 run=0 + * Allocs : n=0 ok=0 wt=0 nbf=0 + * Allocs : ops=0 owt=0 + * Retrvls: n=0 ok=0 wt=0 nod=0 nbf=0 int=0 oom=0 + * Retrvls: ops=0 owt=0 + * Stores : n=0 ok=0 agn=0 nbf=0 oom=0 + * Stores : ops=0 run=0 + * Ops : pend=0 run=0 enq=0 + * Ops : dfr=0 rel=0 gc=0 + */ + + /* Read file line by line */ + while (fgets(linebuffer, sizeof(linebuffer), fh) != NULL) { + char *lineptr; + char *fields[32]; + int fields_num; + + /* Find the colon and replace it with a null byte */ + lineptr = strchr(linebuffer, ':'); + if (lineptr == NULL) + continue; + *lineptr = 0; + lineptr++; + + /* Copy and clean up the section name */ + sstrncpy(section, linebuffer, sizeof(section)); + section_len = strlen(section); + while ((section_len > 0) && isspace((int)section[section_len - 1])) { + section_len--; + section[section_len] = 0; + } + if (section_len == 0) + continue; - char linebuffer[BUFSIZE]; + fields_num = strsplit(lineptr, fields, STATIC_ARRAY_SIZE(fields)); + if (fields_num <= 0) + continue; -/* - * cat /proc/fs/fscache/stats - * FS-Cache statistics - * Cookies: idx=2 dat=0 spc=0 - * Objects: alc=0 nal=0 avl=0 ded=0 - * ChkAux : non=0 ok=0 upd=0 obs=0 - * Pages : mrk=0 unc=0 - * Acquire: n=2 nul=0 noc=0 ok=2 nbf=0 oom=0 - * Lookups: n=0 neg=0 pos=0 crt=0 - * Updates: n=0 nul=0 run=0 - * Relinqs: n=0 nul=0 wcr=0 - * AttrChg: n=0 ok=0 nbf=0 oom=0 run=0 - * Allocs : n=0 ok=0 wt=0 nbf=0 - * Allocs : ops=0 owt=0 - * Retrvls: n=0 ok=0 wt=0 nod=0 nbf=0 int=0 oom=0 - * Retrvls: ops=0 owt=0 - * Stores : n=0 ok=0 agn=0 nbf=0 oom=0 - * Stores : ops=0 run=0 - * Ops : pend=0 run=0 enq=0 - * Ops : dfr=0 rel=0 gc=0 - */ - - /* Read file line by line */ - while (fgets (linebuffer, sizeof (linebuffer), fh) != NULL) - { - char *lineptr; - char *fields[32]; - int fields_num; - - /* Find the colon and replace it with a null byte */ - lineptr = strchr (linebuffer, ':'); - if (lineptr == NULL) - continue; - *lineptr = 0; - lineptr++; - - /* Copy and clean up the section name */ - sstrncpy (section, linebuffer, sizeof (section)); - section_len = strlen (section); - while ((section_len > 0) && isspace ((int) section[section_len - 1])) - { - section_len--; - section[section_len] = 0; - } - if (section_len == 0) - continue; - - fields_num = strsplit (lineptr, fields, STATIC_ARRAY_SIZE (fields)); - if (fields_num <= 0) - continue; - - for (int i = 0; i < fields_num; i++) - { - char *field_name; - char *field_value_str; - value_t field_value_cnt; - int status; - - field_name = fields[i]; - assert (field_name != NULL); - - field_value_str = strchr (field_name, '='); - if (field_value_str == NULL) - continue; - *field_value_str = 0; - field_value_str++; - - status = parse_value (field_value_str, &field_value_cnt, - DS_TYPE_DERIVE); - if (status != 0) - continue; - - fscache_submit (section, field_name, field_value_cnt); - } - } /* while (fgets) */ -} /* void fscache_read_stats_file */ + for (int i = 0; i < fields_num; i++) { + char *field_name; + char *field_value_str; + value_t field_value_cnt; + int status; + + field_name = fields[i]; + assert(field_name != NULL); -static int fscache_read (void){ - FILE *fh; - fh = fopen("/proc/fs/fscache/stats", "r"); - if (fh != NULL){ - fscache_read_stats_file(fh); - fclose(fh); + field_value_str = strchr(field_name, '='); + if (field_value_str == NULL) + continue; + *field_value_str = 0; + field_value_str++; - }else{ - printf("cant open file\n"); - return (-1); + status = parse_value(field_value_str, &field_value_cnt, DS_TYPE_DERIVE); + if (status != 0) + continue; + + fscache_submit(section, field_name, field_value_cnt); } - return (0); + } /* while (fgets) */ +} /* void fscache_read_stats_file */ + +static int fscache_read(void) { + FILE *fh; + fh = fopen("/proc/fs/fscache/stats", "r"); + if (fh != NULL) { + fscache_read_stats_file(fh); + fclose(fh); + + } else { + printf("cant open file\n"); + return (-1); + } + return (0); } -void module_register (void) -{ - plugin_register_read ("fscache", fscache_read); +void module_register(void) { + plugin_register_read("fscache", fscache_read); } /* void module_register */ /* vim: set sw=4 sts=4 et : */ diff --git a/src/gmond.c b/src/gmond.c index 0743d8e1..fc9a2326 100644 --- a/src/gmond.c +++ b/src/gmond.c @@ -26,113 +26,109 @@ #include "collectd.h" -#include "plugin.h" #include "common.h" +#include "plugin.h" #include "utils_avltree.h" #if HAVE_NETDB_H -# include +#include #endif #if HAVE_NETINET_IN_H -# include +#include #endif #if HAVE_ARPA_INET_H -# include +#include #endif #if HAVE_POLL_H -# include +#include #endif #include #ifndef IPV6_ADD_MEMBERSHIP -# ifdef IPV6_JOIN_GROUP -# define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP -# else -# error "Neither IP_ADD_MEMBERSHIP nor IPV6_JOIN_GROUP is defined" -# endif +#ifdef IPV6_JOIN_GROUP +#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP +#else +#error "Neither IP_ADD_MEMBERSHIP nor IPV6_JOIN_GROUP is defined" +#endif #endif /* !IP_ADD_MEMBERSHIP */ #ifdef GANGLIA_MAX_MESSAGE_LEN -# define BUFF_SIZE GANGLIA_MAX_MESSAGE_LEN +#define BUFF_SIZE GANGLIA_MAX_MESSAGE_LEN #else -# define BUFF_SIZE 1400 +#define BUFF_SIZE 1400 #endif -struct socket_entry_s -{ - int fd; +struct socket_entry_s { + int fd; struct sockaddr_storage addr; - socklen_t addrlen; + socklen_t addrlen; }; typedef struct socket_entry_s socket_entry_t; -struct staging_entry_s -{ +struct staging_entry_s { char key[2 * DATA_MAX_NAME_LEN]; value_list_t vl; int flags; }; typedef struct staging_entry_s staging_entry_t; -struct metric_map_s -{ - char *ganglia_name; - char *type; - char *type_instance; - char *ds_name; - int ds_type; +struct metric_map_s { + char *ganglia_name; + char *type; + char *type_instance; + char *ds_name; + int ds_type; size_t ds_index; }; typedef struct metric_map_s metric_map_t; #define MC_RECEIVE_GROUP_DEFAULT "239.2.11.71" -static char *mc_receive_group = NULL; +static char *mc_receive_group = NULL; #define MC_RECEIVE_PORT_DEFAULT "8649" -static char *mc_receive_port = NULL; +static char *mc_receive_port = NULL; static struct pollfd *mc_receive_sockets = NULL; -static size_t mc_receive_sockets_num = 0; +static size_t mc_receive_sockets_num = 0; -static socket_entry_t *mc_send_sockets = NULL; -static size_t mc_send_sockets_num = 0; -static pthread_mutex_t mc_send_sockets_lock = PTHREAD_MUTEX_INITIALIZER; +static socket_entry_t *mc_send_sockets = NULL; +static size_t mc_send_sockets_num = 0; +static pthread_mutex_t mc_send_sockets_lock = PTHREAD_MUTEX_INITIALIZER; -static int mc_receive_thread_loop = 0; -static int mc_receive_thread_running = 0; -static pthread_t mc_receive_thread_id; +static int mc_receive_thread_loop = 0; +static int mc_receive_thread_running = 0; +static pthread_t mc_receive_thread_id; static metric_map_t metric_map_default[] = -{ /*---------------+-------------+-----------+-------------+------+-----* - * ganglia_name ! type ! type_inst ! data_source ! type ! idx * - *---------------+-------------+-----------+-------------+------+-----*/ - { "load_one", "load", "", "shortterm", -1, -1 }, - { "load_five", "load", "", "midterm", -1, -1 }, - { "load_fifteen", "load", "", "longterm", -1, -1 }, - { "cpu_user", "cpu", "user", "value", -1, -1 }, - { "cpu_system", "cpu", "system", "value", -1, -1 }, - { "cpu_idle", "cpu", "idle", "value", -1, -1 }, - { "cpu_nice", "cpu", "nice", "value", -1, -1 }, - { "cpu_wio", "cpu", "wait", "value", -1, -1 }, - { "mem_free", "memory", "free", "value", -1, -1 }, - { "mem_shared", "memory", "shared", "value", -1, -1 }, - { "mem_buffers", "memory", "buffered", "value", -1, -1 }, - { "mem_cached", "memory", "cached", "value", -1, -1 }, - { "mem_total", "memory", "total", "value", -1, -1 }, - { "bytes_in", "if_octets", "", "rx", -1, -1 }, - { "bytes_out", "if_octets", "", "tx", -1, -1 }, - { "pkts_in", "if_packets", "", "rx", -1, -1 }, - { "pkts_out", "if_packets", "", "tx", -1, -1 } -}; -static size_t metric_map_len_default = STATIC_ARRAY_SIZE (metric_map_default); + {/*---------------+-------------+-----------+-------------+------+-----* + * ganglia_name ! type ! type_inst ! data_source ! type ! idx * + *---------------+-------------+-----------+-------------+------+-----*/ + {"load_one", "load", "", "shortterm", -1, -1}, + {"load_five", "load", "", "midterm", -1, -1}, + {"load_fifteen", "load", "", "longterm", -1, -1}, + {"cpu_user", "cpu", "user", "value", -1, -1}, + {"cpu_system", "cpu", "system", "value", -1, -1}, + {"cpu_idle", "cpu", "idle", "value", -1, -1}, + {"cpu_nice", "cpu", "nice", "value", -1, -1}, + {"cpu_wio", "cpu", "wait", "value", -1, -1}, + {"mem_free", "memory", "free", "value", -1, -1}, + {"mem_shared", "memory", "shared", "value", -1, -1}, + {"mem_buffers", "memory", "buffered", "value", -1, -1}, + {"mem_cached", "memory", "cached", "value", -1, -1}, + {"mem_total", "memory", "total", "value", -1, -1}, + {"bytes_in", "if_octets", "", "rx", -1, -1}, + {"bytes_out", "if_octets", "", "tx", -1, -1}, + {"pkts_in", "if_packets", "", "rx", -1, -1}, + {"pkts_out", "if_packets", "", "tx", -1, -1}}; +static size_t metric_map_len_default = STATIC_ARRAY_SIZE(metric_map_default); static metric_map_t *metric_map = NULL; -static size_t metric_map_len = 0; +static size_t metric_map_len = 0; -static c_avl_tree_t *staging_tree; +static c_avl_tree_t *staging_tree; static pthread_mutex_t staging_lock = PTHREAD_MUTEX_INITIALIZER; -static metric_map_t *metric_lookup (const char *key) /* {{{ */ +static metric_map_t *metric_lookup(const char *key) /* {{{ */ { metric_map_t *map; size_t map_len; @@ -142,17 +138,16 @@ static metric_map_t *metric_lookup (const char *key) /* {{{ */ map = metric_map; map_len = metric_map_len; for (i = 0; i < map_len; i++) - if (strcmp (map[i].ganglia_name, key) == 0) + if (strcmp(map[i].ganglia_name, key) == 0) break; /* .. and fall back to the built-in table if nothing is found. */ - if (i >= map_len) - { + if (i >= map_len) { map = metric_map_default; map_len = metric_map_len_default; for (i = 0; i < map_len; i++) - if (strcmp (map[i].ganglia_name, key) == 0) + if (strcmp(map[i].ganglia_name, key) == 0) break; } @@ -164,38 +159,32 @@ static metric_map_t *metric_lookup (const char *key) /* {{{ */ { const data_set_t *ds; - ds = plugin_get_ds (map[i].type); - if (ds == NULL) - { - WARNING ("gmond plugin: Type not defined: %s", map[i].type); + ds = plugin_get_ds(map[i].type); + if (ds == NULL) { + WARNING("gmond plugin: Type not defined: %s", map[i].type); return (NULL); } - if ((map[i].ds_name == NULL) && (ds->ds_num != 1)) - { - WARNING ("gmond plugin: No data source name defined for metric %s, " - "but type %s has more than one data source.", - map[i].ganglia_name, map[i].type); + if ((map[i].ds_name == NULL) && (ds->ds_num != 1)) { + WARNING("gmond plugin: No data source name defined for metric %s, " + "but type %s has more than one data source.", + map[i].ganglia_name, map[i].type); return (NULL); } - if (map[i].ds_name == NULL) - { + if (map[i].ds_name == NULL) { map[i].ds_index = 0; - } - else - { + } else { size_t j; for (j = 0; j < ds->ds_num; j++) - if (strcasecmp (ds->ds[j].name, map[i].ds_name) == 0) + if (strcasecmp(ds->ds[j].name, map[i].ds_name) == 0) break; - if (j >= ds->ds_num) - { - WARNING ("gmond plugin: There is no data source " - "named `%s' in type `%s'.", - map[i].ds_name, ds->type); + if (j >= ds->ds_num) { + WARNING("gmond plugin: There is no data source " + "named `%s' in type `%s'.", + map[i].ds_name, ds->type); return (NULL); } map[i].ds_index = j; @@ -207,181 +196,158 @@ static metric_map_t *metric_lookup (const char *key) /* {{{ */ return (map + i); } /* }}} metric_map_t *metric_lookup */ -static int create_sockets (socket_entry_t **ret_sockets, /* {{{ */ - size_t *ret_sockets_num, - const char *node, const char *service, int listen) -{ +static int create_sockets(socket_entry_t **ret_sockets, /* {{{ */ + size_t *ret_sockets_num, const char *node, + const char *service, int listen) { struct addrinfo *ai_list; - int ai_return; + int ai_return; socket_entry_t *sockets = NULL; - size_t sockets_num = 0; + size_t sockets_num = 0; int status; if (*ret_sockets != NULL) return (EINVAL); - struct addrinfo ai_hints = { - .ai_family = AF_UNSPEC, - .ai_flags = AI_ADDRCONFIG | AI_PASSIVE, - .ai_protocol = IPPROTO_UDP, - .ai_socktype = SOCK_DGRAM - }; + struct addrinfo ai_hints = {.ai_family = AF_UNSPEC, + .ai_flags = AI_ADDRCONFIG | AI_PASSIVE, + .ai_protocol = IPPROTO_UDP, + .ai_socktype = SOCK_DGRAM}; - ai_return = getaddrinfo (node, service, &ai_hints, &ai_list); - if (ai_return != 0) - { + ai_return = getaddrinfo(node, service, &ai_hints, &ai_list); + if (ai_return != 0) { char errbuf[1024]; - ERROR ("gmond plugin: getaddrinfo (%s, %s) failed: %s", - (node == NULL) ? "(null)" : node, - (service == NULL) ? "(null)" : service, - (ai_return == EAI_SYSTEM) - ? sstrerror (errno, errbuf, sizeof (errbuf)) - : gai_strerror (ai_return)); + ERROR("gmond plugin: getaddrinfo (%s, %s) failed: %s", + (node == NULL) ? "(null)" : node, + (service == NULL) ? "(null)" : service, + (ai_return == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf)) + : gai_strerror(ai_return)); return (-1); } - for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) /* {{{ */ + for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; + ai_ptr = ai_ptr->ai_next) /* {{{ */ { socket_entry_t *tmp; - tmp = realloc (sockets, (sockets_num + 1) * sizeof (*sockets)); - if (tmp == NULL) - { - ERROR ("gmond plugin: realloc failed."); + tmp = realloc(sockets, (sockets_num + 1) * sizeof(*sockets)); + if (tmp == NULL) { + ERROR("gmond plugin: realloc failed."); continue; } sockets = tmp; - sockets[sockets_num].fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, - ai_ptr->ai_protocol); - if (sockets[sockets_num].fd < 0) - { + sockets[sockets_num].fd = + socket(ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); + if (sockets[sockets_num].fd < 0) { char errbuf[1024]; - ERROR ("gmond plugin: socket failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("gmond plugin: socket failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); continue; } - assert (sizeof (sockets[sockets_num].addr) >= ai_ptr->ai_addrlen); - memcpy (&sockets[sockets_num].addr, ai_ptr->ai_addr, ai_ptr->ai_addrlen); + assert(sizeof(sockets[sockets_num].addr) >= ai_ptr->ai_addrlen); + memcpy(&sockets[sockets_num].addr, ai_ptr->ai_addr, ai_ptr->ai_addrlen); sockets[sockets_num].addrlen = ai_ptr->ai_addrlen; /* Sending socket: Open only one socket and don't bind it. */ - if (listen == 0) - { + if (listen == 0) { sockets_num++; break; - } - else - { + } else { int yes = 1; - status = setsockopt (sockets[sockets_num].fd, SOL_SOCKET, SO_REUSEADDR, - (void *) &yes, sizeof (yes)); - if (status != 0) - { + status = setsockopt(sockets[sockets_num].fd, SOL_SOCKET, SO_REUSEADDR, + (void *)&yes, sizeof(yes)); + if (status != 0) { char errbuf[1024]; - WARNING ("gmond plugin: setsockopt(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + WARNING("gmond plugin: setsockopt(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); } } - status = bind (sockets[sockets_num].fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); - if (status != 0) - { + status = bind(sockets[sockets_num].fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); + if (status != 0) { char errbuf[1024]; - ERROR ("gmond plugin: bind failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - close (sockets[sockets_num].fd); + ERROR("gmond plugin: bind failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(sockets[sockets_num].fd); continue; } - if (ai_ptr->ai_family == AF_INET) - { + if (ai_ptr->ai_family == AF_INET) { struct sockaddr_in *addr; int loop; - addr = (struct sockaddr_in *) ai_ptr->ai_addr; + addr = (struct sockaddr_in *)ai_ptr->ai_addr; - if (!IN_MULTICAST (ntohl (addr->sin_addr.s_addr))) - { + if (!IN_MULTICAST(ntohl(addr->sin_addr.s_addr))) { sockets_num++; continue; } loop = 1; - status = setsockopt (sockets[sockets_num].fd, IPPROTO_IP, IP_MULTICAST_LOOP, - (void *) &loop, sizeof (loop)); - if (status != 0) - { + status = setsockopt(sockets[sockets_num].fd, IPPROTO_IP, + IP_MULTICAST_LOOP, (void *)&loop, sizeof(loop)); + if (status != 0) { char errbuf[1024]; - WARNING ("gmond plugin: setsockopt(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + WARNING("gmond plugin: setsockopt(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); } - struct ip_mreq mreq = { - .imr_multiaddr.s_addr = addr->sin_addr.s_addr, - .imr_interface.s_addr = htonl (INADDR_ANY) - }; + struct ip_mreq mreq = {.imr_multiaddr.s_addr = addr->sin_addr.s_addr, + .imr_interface.s_addr = htonl(INADDR_ANY)}; - status = setsockopt (sockets[sockets_num].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, - (void *) &mreq, sizeof (mreq)); - if (status != 0) - { + status = setsockopt(sockets[sockets_num].fd, IPPROTO_IP, + IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof(mreq)); + if (status != 0) { char errbuf[1024]; - WARNING ("gmond plugin: setsockopt(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + WARNING("gmond plugin: setsockopt(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); } } /* if (ai_ptr->ai_family == AF_INET) */ - else if (ai_ptr->ai_family == AF_INET6) - { + else if (ai_ptr->ai_family == AF_INET6) { struct sockaddr_in6 *addr; int loop; - addr = (struct sockaddr_in6 *) ai_ptr->ai_addr; + addr = (struct sockaddr_in6 *)ai_ptr->ai_addr; - if (!IN6_IS_ADDR_MULTICAST (&addr->sin6_addr)) - { + if (!IN6_IS_ADDR_MULTICAST(&addr->sin6_addr)) { sockets_num++; continue; } loop = 1; - status = setsockopt (sockets[sockets_num].fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, - (void *) &loop, sizeof (loop)); - if (status != 0) - { + status = setsockopt(sockets[sockets_num].fd, IPPROTO_IPV6, + IPV6_MULTICAST_LOOP, (void *)&loop, sizeof(loop)); + if (status != 0) { char errbuf[1024]; - WARNING ("gmond plugin: setsockopt(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + WARNING("gmond plugin: setsockopt(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); } struct ipv6_mreq mreq = { - .ipv6mr_interface = 0 /* any */ + .ipv6mr_interface = 0 /* any */ }; - memcpy (&mreq.ipv6mr_multiaddr, - &addr->sin6_addr, sizeof (addr->sin6_addr)); - status = setsockopt (sockets[sockets_num].fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, - (void *) &mreq, sizeof (mreq)); - if (status != 0) - { + memcpy(&mreq.ipv6mr_multiaddr, &addr->sin6_addr, sizeof(addr->sin6_addr)); + status = setsockopt(sockets[sockets_num].fd, IPPROTO_IPV6, + IPV6_ADD_MEMBERSHIP, (void *)&mreq, sizeof(mreq)); + if (status != 0) { char errbuf[1024]; - WARNING ("gmond plugin: setsockopt(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + WARNING("gmond plugin: setsockopt(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); } } /* if (ai_ptr->ai_family == AF_INET6) */ sockets_num++; } /* }}} for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) */ - freeaddrinfo (ai_list); + freeaddrinfo(ai_list); - if (sockets_num == 0) - { - sfree (sockets); + if (sockets_num == 0) { + sfree(sockets); return (-1); } @@ -390,66 +356,60 @@ static int create_sockets (socket_entry_t **ret_sockets, /* {{{ */ return (0); } /* }}} int create_sockets */ -static int request_meta_data (const char *host, const char *name) /* {{{ */ +static int request_meta_data(const char *host, const char *name) /* {{{ */ { - Ganglia_metadata_msg msg = { 0 }; - char buffer[BUFF_SIZE] = { 0 }; + Ganglia_metadata_msg msg = {0}; + char buffer[BUFF_SIZE] = {0}; unsigned int buffer_size; XDR xdr; msg.id = gmetadata_request; - msg.Ganglia_metadata_msg_u.grequest.metric_id.host = strdup (host); - msg.Ganglia_metadata_msg_u.grequest.metric_id.name = strdup (name); + msg.Ganglia_metadata_msg_u.grequest.metric_id.host = strdup(host); + msg.Ganglia_metadata_msg_u.grequest.metric_id.name = strdup(name); - if ((msg.Ganglia_metadata_msg_u.grequest.metric_id.host == NULL) - || (msg.Ganglia_metadata_msg_u.grequest.metric_id.name == NULL)) - { - sfree (msg.Ganglia_metadata_msg_u.grequest.metric_id.host); - sfree (msg.Ganglia_metadata_msg_u.grequest.metric_id.name); + if ((msg.Ganglia_metadata_msg_u.grequest.metric_id.host == NULL) || + (msg.Ganglia_metadata_msg_u.grequest.metric_id.name == NULL)) { + sfree(msg.Ganglia_metadata_msg_u.grequest.metric_id.host); + sfree(msg.Ganglia_metadata_msg_u.grequest.metric_id.name); return (-1); } - xdrmem_create (&xdr, buffer, sizeof (buffer), XDR_ENCODE); + xdrmem_create(&xdr, buffer, sizeof(buffer), XDR_ENCODE); - if (!xdr_Ganglia_metadata_msg (&xdr, &msg)) - { - sfree (msg.Ganglia_metadata_msg_u.grequest.metric_id.host); - sfree (msg.Ganglia_metadata_msg_u.grequest.metric_id.name); + if (!xdr_Ganglia_metadata_msg(&xdr, &msg)) { + sfree(msg.Ganglia_metadata_msg_u.grequest.metric_id.host); + sfree(msg.Ganglia_metadata_msg_u.grequest.metric_id.name); return (-1); } - buffer_size = xdr_getpos (&xdr); + buffer_size = xdr_getpos(&xdr); - DEBUG ("gmond plugin: Requesting meta data for %s/%s.", - host, name); + DEBUG("gmond plugin: Requesting meta data for %s/%s.", host, name); - pthread_mutex_lock (&mc_send_sockets_lock); - for (size_t i = 0; i < mc_send_sockets_num; i++) - { - ssize_t status = sendto (mc_send_sockets[i].fd, buffer, (size_t) buffer_size, - /* flags = */ 0, - (struct sockaddr *) &mc_send_sockets[i].addr, - mc_send_sockets[i].addrlen); - if (status == -1) - { + pthread_mutex_lock(&mc_send_sockets_lock); + for (size_t i = 0; i < mc_send_sockets_num; i++) { + ssize_t status = + sendto(mc_send_sockets[i].fd, buffer, (size_t)buffer_size, + /* flags = */ 0, (struct sockaddr *)&mc_send_sockets[i].addr, + mc_send_sockets[i].addrlen); + if (status == -1) { char errbuf[1024]; - ERROR ("gmond plugin: sendto(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("gmond plugin: sendto(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); continue; } } - pthread_mutex_unlock (&mc_send_sockets_lock); + pthread_mutex_unlock(&mc_send_sockets_lock); - sfree (msg.Ganglia_metadata_msg_u.grequest.metric_id.host); - sfree (msg.Ganglia_metadata_msg_u.grequest.metric_id.name); + sfree(msg.Ganglia_metadata_msg_u.grequest.metric_id.host); + sfree(msg.Ganglia_metadata_msg_u.grequest.metric_id.name); return (0); } /* }}} int request_meta_data */ -static staging_entry_t *staging_entry_get (const char *host, /* {{{ */ - const char *name, - const char *type, const char *type_instance, - int values_len) -{ +static staging_entry_t *staging_entry_get(const char *host, /* {{{ */ + const char *name, const char *type, + const char *type_instance, + int values_len) { char key[2 * DATA_MAX_NAME_LEN]; staging_entry_t *se; int status; @@ -457,84 +417,76 @@ static staging_entry_t *staging_entry_get (const char *host, /* {{{ */ if (staging_tree == NULL) return (NULL); - ssnprintf (key, sizeof (key), "%s/%s/%s", host, type, - (type_instance != NULL) ? type_instance : ""); + ssnprintf(key, sizeof(key), "%s/%s/%s", host, type, + (type_instance != NULL) ? type_instance : ""); se = NULL; - status = c_avl_get (staging_tree, key, (void *) &se); + status = c_avl_get(staging_tree, key, (void *)&se); if (status == 0) return (se); /* insert new entry */ - se = calloc (1, sizeof (*se)); + se = calloc(1, sizeof(*se)); if (se == NULL) return (NULL); - sstrncpy (se->key, key, sizeof (se->key)); + sstrncpy(se->key, key, sizeof(se->key)); se->flags = 0; - se->vl.values = (value_t *) calloc (values_len, sizeof (*se->vl.values)); - if (se->vl.values == NULL) - { - sfree (se); + se->vl.values = (value_t *)calloc(values_len, sizeof(*se->vl.values)); + if (se->vl.values == NULL) { + sfree(se); return (NULL); } se->vl.values_len = values_len; se->vl.time = 0; se->vl.interval = 0; - sstrncpy (se->vl.host, host, sizeof (se->vl.host)); - sstrncpy (se->vl.plugin, "gmond", sizeof (se->vl.plugin)); - sstrncpy (se->vl.type, type, sizeof (se->vl.type)); + sstrncpy(se->vl.host, host, sizeof(se->vl.host)); + sstrncpy(se->vl.plugin, "gmond", sizeof(se->vl.plugin)); + sstrncpy(se->vl.type, type, sizeof(se->vl.type)); if (type_instance != NULL) - sstrncpy (se->vl.type_instance, type_instance, - sizeof (se->vl.type_instance)); + sstrncpy(se->vl.type_instance, type_instance, sizeof(se->vl.type_instance)); - status = c_avl_insert (staging_tree, se->key, se); - if (status != 0) - { - ERROR ("gmond plugin: c_avl_insert failed."); - sfree (se->vl.values); - sfree (se); + status = c_avl_insert(staging_tree, se->key, se); + if (status != 0) { + ERROR("gmond plugin: c_avl_insert failed."); + sfree(se->vl.values); + sfree(se); return (NULL); } return (se); } /* }}} staging_entry_t *staging_entry_get */ -static int staging_entry_update (const char *host, const char *name, /* {{{ */ - const char *type, const char *type_instance, - size_t ds_index, int ds_type, value_t value) -{ +static int staging_entry_update(const char *host, const char *name, /* {{{ */ + const char *type, const char *type_instance, + size_t ds_index, int ds_type, value_t value) { const data_set_t *ds; staging_entry_t *se; - ds = plugin_get_ds (type); - if (ds == NULL) - { - ERROR ("gmond plugin: Looking up type %s failed.", type); + ds = plugin_get_ds(type); + if (ds == NULL) { + ERROR("gmond plugin: Looking up type %s failed.", type); return (-1); } - if (ds->ds_num <= ds_index) - { - ERROR ("gmond plugin: Invalid index %zu: %s has only %zu data source(s).", - ds_index, ds->type, ds->ds_num); + if (ds->ds_num <= ds_index) { + ERROR("gmond plugin: Invalid index %zu: %s has only %zu data source(s).", + ds_index, ds->type, ds->ds_num); return (-1); } - pthread_mutex_lock (&staging_lock); + pthread_mutex_lock(&staging_lock); - se = staging_entry_get (host, name, type, type_instance, ds->ds_num); - if (se == NULL) - { - pthread_mutex_unlock (&staging_lock); - ERROR ("gmond plugin: staging_entry_get failed."); + se = staging_entry_get(host, name, type, type_instance, ds->ds_num); + if (se == NULL) { + pthread_mutex_unlock(&staging_lock); + ERROR("gmond plugin: staging_entry_get failed."); return (-1); } - if (se->vl.values_len != ds->ds_num) - { - pthread_mutex_unlock (&staging_lock); + if (se->vl.values_len != ds->ds_num) { + pthread_mutex_unlock(&staging_lock); return (-1); } @@ -547,38 +499,36 @@ static int staging_entry_update (const char *host, const char *name, /* {{{ */ else if (ds_type == DS_TYPE_ABSOLUTE) se->vl.values[ds_index].absolute = value.absolute; else - assert (23 == 42); + assert(23 == 42); se->flags |= (0x01 << ds_index); /* Check if all data sources have been set. If not, return here. */ - if (se->flags != ((0x01 << se->vl.values_len) - 1)) - { - pthread_mutex_unlock (&staging_lock); + if (se->flags != ((0x01 << se->vl.values_len) - 1)) { + pthread_mutex_unlock(&staging_lock); return (0); } /* Check if the interval of this metric is known. If not, request meta data * and return. */ - if (se->vl.interval == 0) - { + if (se->vl.interval == 0) { /* No meta data has been received for this metric yet. */ se->flags = 0; - pthread_mutex_unlock (&staging_lock); + pthread_mutex_unlock(&staging_lock); - request_meta_data (host, name); + request_meta_data(host, name); return (0); } - plugin_dispatch_values (&se->vl); + plugin_dispatch_values(&se->vl); se->flags = 0; - pthread_mutex_unlock (&staging_lock); + pthread_mutex_unlock(&staging_lock); return (0); } /* }}} int staging_entry_update */ -static int mc_handle_value_msg (Ganglia_value_msg *msg) /* {{{ */ +static int mc_handle_value_msg(Ganglia_value_msg *msg) /* {{{ */ { const char *host; const char *name; @@ -592,297 +542,268 @@ static int mc_handle_value_msg (Ganglia_value_msg *msg) /* {{{ */ * the value type, or return with an error. */ switch (msg->id) /* {{{ */ { - case gmetric_uint: - { - Ganglia_gmetric_uint msg_uint; + case gmetric_uint: { + Ganglia_gmetric_uint msg_uint; - msg_uint = msg->Ganglia_value_msg_u.gu_int; + msg_uint = msg->Ganglia_value_msg_u.gu_int; - host = msg_uint.metric_id.host; - name = msg_uint.metric_id.name; - value_counter.counter = (counter_t) msg_uint.ui; - value_gauge.gauge = (gauge_t) msg_uint.ui; - value_derive.derive = (derive_t) msg_uint.ui; - break; - } + host = msg_uint.metric_id.host; + name = msg_uint.metric_id.name; + value_counter.counter = (counter_t)msg_uint.ui; + value_gauge.gauge = (gauge_t)msg_uint.ui; + value_derive.derive = (derive_t)msg_uint.ui; + break; + } - case gmetric_string: - { - Ganglia_gmetric_string msg_string; - int status; + case gmetric_string: { + Ganglia_gmetric_string msg_string; + int status; - msg_string = msg->Ganglia_value_msg_u.gstr; + msg_string = msg->Ganglia_value_msg_u.gstr; - host = msg_string.metric_id.host; - name = msg_string.metric_id.name; + host = msg_string.metric_id.host; + name = msg_string.metric_id.name; - status = parse_value (msg_string.str, &value_derive, DS_TYPE_DERIVE); - if (status != 0) - value_derive.derive = -1; + status = parse_value(msg_string.str, &value_derive, DS_TYPE_DERIVE); + if (status != 0) + value_derive.derive = -1; - status = parse_value (msg_string.str, &value_gauge, DS_TYPE_GAUGE); - if (status != 0) - value_gauge.gauge = NAN; + status = parse_value(msg_string.str, &value_gauge, DS_TYPE_GAUGE); + if (status != 0) + value_gauge.gauge = NAN; - status = parse_value (msg_string.str, &value_counter, DS_TYPE_COUNTER); - if (status != 0) - value_counter.counter = 0; + status = parse_value(msg_string.str, &value_counter, DS_TYPE_COUNTER); + if (status != 0) + value_counter.counter = 0; - break; - } + break; + } - case gmetric_float: - { - Ganglia_gmetric_float msg_float; + case gmetric_float: { + Ganglia_gmetric_float msg_float; - msg_float = msg->Ganglia_value_msg_u.gf; + msg_float = msg->Ganglia_value_msg_u.gf; - host = msg_float.metric_id.host; - name = msg_float.metric_id.name; - value_counter.counter = (counter_t) msg_float.f; - value_gauge.gauge = (gauge_t) msg_float.f; - value_derive.derive = (derive_t) msg_float.f; - break; - } + host = msg_float.metric_id.host; + name = msg_float.metric_id.name; + value_counter.counter = (counter_t)msg_float.f; + value_gauge.gauge = (gauge_t)msg_float.f; + value_derive.derive = (derive_t)msg_float.f; + break; + } - case gmetric_double: - { - Ganglia_gmetric_double msg_double; + case gmetric_double: { + Ganglia_gmetric_double msg_double; - msg_double = msg->Ganglia_value_msg_u.gd; + msg_double = msg->Ganglia_value_msg_u.gd; - host = msg_double.metric_id.host; - name = msg_double.metric_id.name; - value_counter.counter = (counter_t) msg_double.d; - value_gauge.gauge = (gauge_t) msg_double.d; - value_derive.derive = (derive_t) msg_double.d; - break; - } - default: - DEBUG ("gmond plugin: Value type not handled: %i", msg->id); - return (-1); + host = msg_double.metric_id.host; + name = msg_double.metric_id.name; + value_counter.counter = (counter_t)msg_double.d; + value_gauge.gauge = (gauge_t)msg_double.d; + value_derive.derive = (derive_t)msg_double.d; + break; + } + default: + DEBUG("gmond plugin: Value type not handled: %i", msg->id); + return (-1); } /* }}} switch (msg->id) */ - assert (host != NULL); - assert (name != NULL); + assert(host != NULL); + assert(name != NULL); - map = metric_lookup (name); - if (map != NULL) - { + map = metric_lookup(name); + if (map != NULL) { value_t val_copy; - if ((map->ds_type == DS_TYPE_COUNTER) - || (map->ds_type == DS_TYPE_ABSOLUTE)) + if ((map->ds_type == DS_TYPE_COUNTER) || (map->ds_type == DS_TYPE_ABSOLUTE)) val_copy = value_counter; else if (map->ds_type == DS_TYPE_GAUGE) val_copy = value_gauge; else if (map->ds_type == DS_TYPE_DERIVE) val_copy = value_derive; else - assert (23 == 42); + assert(23 == 42); - return (staging_entry_update (host, name, - map->type, map->type_instance, - map->ds_index, map->ds_type, - val_copy)); + return (staging_entry_update(host, name, map->type, map->type_instance, + map->ds_index, map->ds_type, val_copy)); } - DEBUG ("gmond plugin: Cannot find a translation for %s.", name); + DEBUG("gmond plugin: Cannot find a translation for %s.", name); return (-1); } /* }}} int mc_handle_value_msg */ -static int mc_handle_metadata_msg (Ganglia_metadata_msg *msg) /* {{{ */ +static int mc_handle_metadata_msg(Ganglia_metadata_msg *msg) /* {{{ */ { - switch (msg->id) - { - case gmetadata_full: - { - Ganglia_metadatadef msg_meta; - staging_entry_t *se; - const data_set_t *ds; - metric_map_t *map; - - msg_meta = msg->Ganglia_metadata_msg_u.gfull; - - if (msg_meta.metric.tmax == 0) - return (-1); - - map = metric_lookup (msg_meta.metric_id.name); - if (map == NULL) - { - DEBUG ("gmond plugin: Not handling meta data %s.", - msg_meta.metric_id.name); - return (0); - } + switch (msg->id) { + case gmetadata_full: { + Ganglia_metadatadef msg_meta; + staging_entry_t *se; + const data_set_t *ds; + metric_map_t *map; - ds = plugin_get_ds (map->type); - if (ds == NULL) - { - WARNING ("gmond plugin: Could not find data set %s.", map->type); - return (-1); - } + msg_meta = msg->Ganglia_metadata_msg_u.gfull; - DEBUG ("gmond plugin: Received meta data for %s/%s.", - msg_meta.metric_id.host, msg_meta.metric_id.name); + if (msg_meta.metric.tmax == 0) + return (-1); - pthread_mutex_lock (&staging_lock); - se = staging_entry_get (msg_meta.metric_id.host, - msg_meta.metric_id.name, - map->type, map->type_instance, - ds->ds_num); - if (se != NULL) - se->vl.interval = TIME_T_TO_CDTIME_T (msg_meta.metric.tmax); - pthread_mutex_unlock (&staging_lock); - - if (se == NULL) - { - ERROR ("gmond plugin: staging_entry_get failed."); - return (-1); - } + map = metric_lookup(msg_meta.metric_id.name); + if (map == NULL) { + DEBUG("gmond plugin: Not handling meta data %s.", + msg_meta.metric_id.name); + return (0); + } - break; + ds = plugin_get_ds(map->type); + if (ds == NULL) { + WARNING("gmond plugin: Could not find data set %s.", map->type); + return (-1); } - default: - { + DEBUG("gmond plugin: Received meta data for %s/%s.", + msg_meta.metric_id.host, msg_meta.metric_id.name); + + pthread_mutex_lock(&staging_lock); + se = staging_entry_get(msg_meta.metric_id.host, msg_meta.metric_id.name, + map->type, map->type_instance, ds->ds_num); + if (se != NULL) + se->vl.interval = TIME_T_TO_CDTIME_T(msg_meta.metric.tmax); + pthread_mutex_unlock(&staging_lock); + + if (se == NULL) { + ERROR("gmond plugin: staging_entry_get failed."); return (-1); } + + break; + } + + default: { return (-1); } } return (0); } /* }}} int mc_handle_metadata_msg */ -static int mc_handle_metric (void *buffer, size_t buffer_size) /* {{{ */ +static int mc_handle_metric(void *buffer, size_t buffer_size) /* {{{ */ { XDR xdr; Ganglia_msg_formats format; - xdrmem_create (&xdr, buffer, buffer_size, XDR_DECODE); + xdrmem_create(&xdr, buffer, buffer_size, XDR_DECODE); - xdr_Ganglia_msg_formats (&xdr, &format); - xdr_setpos (&xdr, 0); + xdr_Ganglia_msg_formats(&xdr, &format); + xdr_setpos(&xdr, 0); - switch (format) - { - case gmetric_ushort: - case gmetric_short: - case gmetric_int: - case gmetric_uint: - case gmetric_string: - case gmetric_float: - case gmetric_double: - { - Ganglia_value_msg msg = { 0 }; - - if (xdr_Ganglia_value_msg (&xdr, &msg)) - mc_handle_value_msg (&msg); - break; - } + switch (format) { + case gmetric_ushort: + case gmetric_short: + case gmetric_int: + case gmetric_uint: + case gmetric_string: + case gmetric_float: + case gmetric_double: { + Ganglia_value_msg msg = {0}; - case gmetadata_full: - case gmetadata_request: - { - Ganglia_metadata_msg msg = { 0 }; - if (xdr_Ganglia_metadata_msg (&xdr, &msg)) - mc_handle_metadata_msg (&msg); - break; - } + if (xdr_Ganglia_value_msg(&xdr, &msg)) + mc_handle_value_msg(&msg); + break; + } - default: - DEBUG ("gmond plugin: Unknown format: %i", format); - return (-1); - } /* switch (format) */ + case gmetadata_full: + case gmetadata_request: { + Ganglia_metadata_msg msg = {0}; + if (xdr_Ganglia_metadata_msg(&xdr, &msg)) + mc_handle_metadata_msg(&msg); + break; + } + default: + DEBUG("gmond plugin: Unknown format: %i", format); + return (-1); + } /* switch (format) */ return (0); } /* }}} int mc_handle_metric */ -static int mc_handle_socket (struct pollfd *p) /* {{{ */ +static int mc_handle_socket(struct pollfd *p) /* {{{ */ { char buffer[BUFF_SIZE]; ssize_t buffer_size; - if ((p->revents & (POLLIN | POLLPRI)) == 0) - { + if ((p->revents & (POLLIN | POLLPRI)) == 0) { p->revents = 0; return (-1); } - buffer_size = recv (p->fd, buffer, sizeof (buffer), /* flags = */ 0); - if (buffer_size <= 0) - { + buffer_size = recv(p->fd, buffer, sizeof(buffer), /* flags = */ 0); + if (buffer_size <= 0) { char errbuf[1024]; - ERROR ("gmond plugin: recv failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("gmond plugin: recv failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); p->revents = 0; return (-1); } - mc_handle_metric (buffer, (size_t) buffer_size); + mc_handle_metric(buffer, (size_t)buffer_size); return (0); } /* }}} int mc_handle_socket */ -static void *mc_receive_thread (void *arg) /* {{{ */ +static void *mc_receive_thread(void *arg) /* {{{ */ { socket_entry_t *mc_receive_socket_entries; int status; mc_receive_socket_entries = NULL; - status = create_sockets (&mc_receive_socket_entries, &mc_receive_sockets_num, + status = create_sockets( + &mc_receive_socket_entries, &mc_receive_sockets_num, (mc_receive_group != NULL) ? mc_receive_group : MC_RECEIVE_GROUP_DEFAULT, (mc_receive_port != NULL) ? mc_receive_port : MC_RECEIVE_PORT_DEFAULT, /* listen = */ 1); - if (status != 0) - { - ERROR ("gmond plugin: create_sockets failed."); - return ((void *) -1); + if (status != 0) { + ERROR("gmond plugin: create_sockets failed."); + return ((void *)-1); } - mc_receive_sockets = (struct pollfd *) calloc (mc_receive_sockets_num, - sizeof (*mc_receive_sockets)); - if (mc_receive_sockets == NULL) - { - ERROR ("gmond plugin: calloc failed."); + mc_receive_sockets = (struct pollfd *)calloc(mc_receive_sockets_num, + sizeof(*mc_receive_sockets)); + if (mc_receive_sockets == NULL) { + ERROR("gmond plugin: calloc failed."); for (size_t i = 0; i < mc_receive_sockets_num; i++) - close (mc_receive_socket_entries[i].fd); - free (mc_receive_socket_entries); + close(mc_receive_socket_entries[i].fd); + free(mc_receive_socket_entries); mc_receive_socket_entries = NULL; mc_receive_sockets_num = 0; - return ((void *) -1); + return ((void *)-1); } - for (size_t i = 0; i < mc_receive_sockets_num; i++) - { + for (size_t i = 0; i < mc_receive_sockets_num; i++) { mc_receive_sockets[i].fd = mc_receive_socket_entries[i].fd; mc_receive_sockets[i].events = POLLIN | POLLPRI; mc_receive_sockets[i].revents = 0; } - while (mc_receive_thread_loop != 0) - { - status = poll (mc_receive_sockets, mc_receive_sockets_num, -1); - if (status <= 0) - { + while (mc_receive_thread_loop != 0) { + status = poll(mc_receive_sockets, mc_receive_sockets_num, -1); + if (status <= 0) { char errbuf[1024]; if (errno == EINTR) continue; - ERROR ("gmond plugin: poll failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("gmond plugin: poll failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); break; } - for (size_t i = 0; i < mc_receive_sockets_num; i++) - { + for (size_t i = 0; i < mc_receive_sockets_num; i++) { if (mc_receive_sockets[i].revents != 0) - mc_handle_socket (mc_receive_sockets + i); + mc_handle_socket(mc_receive_sockets + i); } } /* while (mc_receive_thread_loop != 0) */ - free (mc_receive_socket_entries); - return ((void *) 0); + free(mc_receive_socket_entries); + return ((void *)0); } /* }}} void *mc_receive_thread */ -static int mc_receive_thread_start (void) /* {{{ */ +static int mc_receive_thread_start(void) /* {{{ */ { int status; @@ -891,11 +812,11 @@ static int mc_receive_thread_start (void) /* {{{ */ mc_receive_thread_loop = 1; - status = plugin_thread_create (&mc_receive_thread_id, /* attr = */ NULL, - mc_receive_thread, /* args = */ NULL, "gmond recv"); - if (status != 0) - { - ERROR ("gmond plugin: Starting receive thread failed."); + status = + plugin_thread_create(&mc_receive_thread_id, /* attr = */ NULL, + mc_receive_thread, /* args = */ NULL, "gmond recv"); + if (status != 0) { + ERROR("gmond plugin: Starting receive thread failed."); mc_receive_thread_loop = 0; return (-1); } @@ -904,17 +825,17 @@ static int mc_receive_thread_start (void) /* {{{ */ return (0); } /* }}} int start_receive_thread */ -static int mc_receive_thread_stop (void) /* {{{ */ +static int mc_receive_thread_stop(void) /* {{{ */ { if (mc_receive_thread_running == 0) return (-1); mc_receive_thread_loop = 0; - INFO ("gmond plugin: Stopping receive thread."); - pthread_kill (mc_receive_thread_id, SIGTERM); - pthread_join (mc_receive_thread_id, /* return value = */ NULL); - memset (&mc_receive_thread_id, 0, sizeof (mc_receive_thread_id)); + INFO("gmond plugin: Stopping receive thread."); + pthread_kill(mc_receive_thread_id, SIGTERM); + pthread_join(mc_receive_thread_id, /* return value = */ NULL); + memset(&mc_receive_thread_id, 0, sizeof(mc_receive_thread_id)); mc_receive_thread_running = 0; @@ -933,85 +854,77 @@ static int mc_receive_thread_stop (void) /* {{{ */ * * */ -static int gmond_config_set_string (oconfig_item_t *ci, char **str) /* {{{ */ +static int gmond_config_set_string(oconfig_item_t *ci, char **str) /* {{{ */ { char *tmp; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("gmond plugin: The `%s' option needs " - "exactly one string argument.", ci->key); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("gmond plugin: The `%s' option needs " + "exactly one string argument.", + ci->key); return (-1); } - tmp = strdup (ci->values[0].value.string); - if (tmp == NULL) - { - ERROR ("gmond plugin: strdup failed."); + tmp = strdup(ci->values[0].value.string); + if (tmp == NULL) { + ERROR("gmond plugin: strdup failed."); return (-1); } - sfree (*str); + sfree(*str); *str = tmp; return (0); } /* }}} int gmond_config_set_string */ -static int gmond_config_add_metric (oconfig_item_t *ci) /* {{{ */ +static int gmond_config_add_metric(oconfig_item_t *ci) /* {{{ */ { metric_map_t *map; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("gmond plugin: `Metric' blocks need " - "exactly one string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("gmond plugin: `Metric' blocks need " + "exactly one string argument."); return (-1); } - map = realloc (metric_map, (metric_map_len + 1) * sizeof (*metric_map)); - if (map == NULL) - { - ERROR ("gmond plugin: realloc failed."); + map = realloc(metric_map, (metric_map_len + 1) * sizeof(*metric_map)); + if (map == NULL) { + ERROR("gmond plugin: realloc failed."); return (-1); } metric_map = map; map = metric_map + metric_map_len; - memset (map, 0, sizeof (*map)); + memset(map, 0, sizeof(*map)); map->type = NULL; map->type_instance = NULL; map->ds_name = NULL; map->ds_type = -1; map->ds_index = -1; - map->ganglia_name = strdup (ci->values[0].value.string); - if (map->ganglia_name == NULL) - { - ERROR ("gmond plugin: strdup failed."); + map->ganglia_name = strdup(ci->values[0].value.string); + if (map->ganglia_name == NULL) { + ERROR("gmond plugin: strdup failed."); return (-1); } - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Type", child->key) == 0) - gmond_config_set_string (child, &map->type); - else if (strcasecmp ("TypeInstance", child->key) == 0) - gmond_config_set_string (child, &map->type_instance); - else if (strcasecmp ("DataSource", child->key) == 0) - gmond_config_set_string (child, &map->ds_name); - else - { - WARNING ("gmond plugin: Unknown configuration option `%s' ignored.", - child->key); + if (strcasecmp("Type", child->key) == 0) + gmond_config_set_string(child, &map->type); + else if (strcasecmp("TypeInstance", child->key) == 0) + gmond_config_set_string(child, &map->type_instance); + else if (strcasecmp("DataSource", child->key) == 0) + gmond_config_set_string(child, &map->ds_name); + else { + WARNING("gmond plugin: Unknown configuration option `%s' ignored.", + child->key); } } - if (map->type == NULL) - { - ERROR ("gmond plugin: No type is set for metric %s.", - map->ganglia_name); - sfree (map->ganglia_name); - sfree (map->type_instance); + if (map->type == NULL) { + ERROR("gmond plugin: No type is set for metric %s.", map->ganglia_name); + sfree(map->ganglia_name); + sfree(map->type_instance); return (-1); } @@ -1019,45 +932,40 @@ static int gmond_config_add_metric (oconfig_item_t *ci) /* {{{ */ return (0); } /* }}} int gmond_config_add_metric */ -static int gmond_config_set_address (oconfig_item_t *ci, /* {{{ */ - char **ret_addr, char **ret_port) -{ +static int gmond_config_set_address(oconfig_item_t *ci, /* {{{ */ + char **ret_addr, char **ret_port) { char *addr; char *port; - if ((ci->values_num != 1) && (ci->values_num != 2)) - { - WARNING ("gmond plugin: The `%s' config option needs " - "one or two string arguments.", - ci->key); + if ((ci->values_num != 1) && (ci->values_num != 2)) { + WARNING("gmond plugin: The `%s' config option needs " + "one or two string arguments.", + ci->key); return (-1); } - if ((ci->values[0].type != OCONFIG_TYPE_STRING) - || ((ci->values_num == 2) - && (ci->values[1].type != OCONFIG_TYPE_STRING))) - { - WARNING ("gmond plugin: The `%s' config option needs " - "one or two string arguments.", - ci->key); + if ((ci->values[0].type != OCONFIG_TYPE_STRING) || + ((ci->values_num == 2) && (ci->values[1].type != OCONFIG_TYPE_STRING))) { + WARNING("gmond plugin: The `%s' config option needs " + "one or two string arguments.", + ci->key); return (-1); } - addr = strdup (ci->values[0].value.string); + addr = strdup(ci->values[0].value.string); if (ci->values_num == 2) - port = strdup (ci->values[1].value.string); + port = strdup(ci->values[1].value.string); else port = NULL; - if ((addr == NULL) || ((ci->values_num == 2) && (port == NULL))) - { - ERROR ("gmond plugin: strdup failed."); - sfree (addr); - sfree (port); + if ((addr == NULL) || ((ci->values_num == 2) && (port == NULL))) { + ERROR("gmond plugin: strdup failed."); + sfree(addr); + sfree(port); return (-1); } - sfree (*ret_addr); - sfree (*ret_port); + sfree(*ret_addr); + sfree(*ret_port); *ret_addr = addr; *ret_port = port; @@ -1065,67 +973,62 @@ static int gmond_config_set_address (oconfig_item_t *ci, /* {{{ */ return (0); } /* }}} int gmond_config_set_address */ -static int gmond_config (oconfig_item_t *ci) /* {{{ */ +static int gmond_config(oconfig_item_t *ci) /* {{{ */ { - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("MCReceiveFrom", child->key) == 0) - gmond_config_set_address (child, &mc_receive_group, &mc_receive_port); - else if (strcasecmp ("Metric", child->key) == 0) - gmond_config_add_metric (child); - else - { - WARNING ("gmond plugin: Unknown configuration option `%s' ignored.", - child->key); + if (strcasecmp("MCReceiveFrom", child->key) == 0) + gmond_config_set_address(child, &mc_receive_group, &mc_receive_port); + else if (strcasecmp("Metric", child->key) == 0) + gmond_config_add_metric(child); + else { + WARNING("gmond plugin: Unknown configuration option `%s' ignored.", + child->key); } } return (0); } /* }}} int gmond_config */ -static int gmond_init (void) /* {{{ */ +static int gmond_init(void) /* {{{ */ { - create_sockets (&mc_send_sockets, &mc_send_sockets_num, + create_sockets( + &mc_send_sockets, &mc_send_sockets_num, (mc_receive_group != NULL) ? mc_receive_group : MC_RECEIVE_GROUP_DEFAULT, (mc_receive_port != NULL) ? mc_receive_port : MC_RECEIVE_PORT_DEFAULT, /* listen = */ 0); - staging_tree = c_avl_create ((int (*) (const void *, const void *)) strcmp); - if (staging_tree == NULL) - { - ERROR ("gmond plugin: c_avl_create failed."); + staging_tree = c_avl_create((int (*)(const void *, const void *))strcmp); + if (staging_tree == NULL) { + ERROR("gmond plugin: c_avl_create failed."); return (-1); } - mc_receive_thread_start (); + mc_receive_thread_start(); return (0); } /* }}} int gmond_init */ -static int gmond_shutdown (void) /* {{{ */ +static int gmond_shutdown(void) /* {{{ */ { - mc_receive_thread_stop (); + mc_receive_thread_stop(); - pthread_mutex_lock (&mc_send_sockets_lock); - for (size_t i = 0; i < mc_send_sockets_num; i++) - { - close (mc_send_sockets[i].fd); + pthread_mutex_lock(&mc_send_sockets_lock); + for (size_t i = 0; i < mc_send_sockets_num; i++) { + close(mc_send_sockets[i].fd); mc_send_sockets[i].fd = -1; } - sfree (mc_send_sockets); + sfree(mc_send_sockets); mc_send_sockets_num = 0; - pthread_mutex_unlock (&mc_send_sockets_lock); - + pthread_mutex_unlock(&mc_send_sockets_lock); return (0); } /* }}} int gmond_shutdown */ -void module_register (void) -{ - plugin_register_complex_config ("gmond", gmond_config); - plugin_register_init ("gmond", gmond_init); - plugin_register_shutdown ("gmond", gmond_shutdown); +void module_register(void) { + plugin_register_complex_config("gmond", gmond_config); + plugin_register_init("gmond", gmond_init); + plugin_register_shutdown("gmond", gmond_shutdown); } /* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/gps.c b/src/gps.c index 81056e3c..a4b3e2e7 100644 --- a/src/gps.c +++ b/src/gps.c @@ -26,19 +26,19 @@ * Marc Fournier **/ -#include "collectd.h" #include "common.h" #include "plugin.h" #include "utils_time.h" +#include "collectd.h" -#define CGPS_TRUE 1 -#define CGPS_FALSE 0 -#define CGPS_DEFAULT_HOST "localhost" -#define CGPS_DEFAULT_PORT "2947" /* DEFAULT_GPSD_PORT */ -#define CGPS_DEFAULT_TIMEOUT MS_TO_CDTIME_T (15) -#define CGPS_DEFAULT_PAUSE_CONNECT TIME_T_TO_CDTIME_T (5) -#define CGPS_MAX_ERROR 100 -#define CGPS_CONFIG "?WATCH={\"enable\":true,\"json\":true,\"nmea\":false}\r\n" +#define CGPS_TRUE 1 +#define CGPS_FALSE 0 +#define CGPS_DEFAULT_HOST "localhost" +#define CGPS_DEFAULT_PORT "2947" /* DEFAULT_GPSD_PORT */ +#define CGPS_DEFAULT_TIMEOUT MS_TO_CDTIME_T(15) +#define CGPS_DEFAULT_PAUSE_CONNECT TIME_T_TO_CDTIME_T(5) +#define CGPS_MAX_ERROR 100 +#define CGPS_CONFIG "?WATCH={\"enable\":true,\"json\":true,\"nmea\":false}\r\n" #include #include @@ -62,108 +62,98 @@ static cgps_config_t cgps_config_data; static cgps_data_t cgps_data = {NAN, NAN, NAN, NAN}; static pthread_t cgps_thread_id; -static pthread_mutex_t cgps_data_lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t cgps_thread_lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t cgps_thread_cond = PTHREAD_COND_INITIALIZER; +static pthread_mutex_t cgps_data_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t cgps_thread_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t cgps_thread_cond = PTHREAD_COND_INITIALIZER; static int cgps_thread_shutdown = CGPS_FALSE; static int cgps_thread_running = CGPS_FALSE; /** * Non blocking pause for the thread. */ -static int cgps_thread_pause(cdtime_t pTime) -{ +static int cgps_thread_pause(cdtime_t pTime) { cdtime_t until = cdtime() + pTime; - pthread_mutex_lock (&cgps_thread_lock); - pthread_cond_timedwait (&cgps_thread_cond, &cgps_thread_lock, - &CDTIME_T_TO_TIMESPEC (until)); + pthread_mutex_lock(&cgps_thread_lock); + pthread_cond_timedwait(&cgps_thread_cond, &cgps_thread_lock, + &CDTIME_T_TO_TIMESPEC(until)); int ret = !cgps_thread_shutdown; - pthread_mutex_lock (&cgps_thread_lock); + pthread_mutex_lock(&cgps_thread_lock); return ret; } /** * Thread reading from gpsd. */ -static void * cgps_thread (void * pData) -{ +static void *cgps_thread(void *pData) { struct gps_data_t gpsd_conn; unsigned int err_count; cgps_thread_running = CGPS_TRUE; - while (CGPS_TRUE) - { - pthread_mutex_lock (&cgps_thread_lock); - if (cgps_thread_shutdown == CGPS_TRUE) - { + while (CGPS_TRUE) { + pthread_mutex_lock(&cgps_thread_lock); + if (cgps_thread_shutdown == CGPS_TRUE) { goto quit; } - pthread_mutex_unlock (&cgps_thread_lock); + pthread_mutex_unlock(&cgps_thread_lock); err_count = 0; #if GPSD_API_MAJOR_VERSION > 4 - int status = gps_open (cgps_config_data.host, cgps_config_data.port, &gpsd_conn); + int status = + gps_open(cgps_config_data.host, cgps_config_data.port, &gpsd_conn); #else - int status = gps_open_r (cgps_config_data.host, cgps_config_data.port, &gpsd_conn); + int status = + gps_open_r(cgps_config_data.host, cgps_config_data.port, &gpsd_conn); #endif - if (status < 0) - { - WARNING ("gps plugin: connecting to %s:%s failed: %s", - cgps_config_data.host, cgps_config_data.port, gps_errstr (status)); + if (status < 0) { + WARNING("gps plugin: connecting to %s:%s failed: %s", + cgps_config_data.host, cgps_config_data.port, gps_errstr(status)); // Here we make a pause until a new tentative to connect, we check also if // the thread does not need to stop. - if (cgps_thread_pause(cgps_config_data.pause_connect) == CGPS_FALSE) - { + if (cgps_thread_pause(cgps_config_data.pause_connect) == CGPS_FALSE) { goto quit; } continue; } - gps_stream (&gpsd_conn, WATCH_ENABLE | WATCH_JSON | WATCH_NEWSTYLE, NULL); - gps_send (&gpsd_conn, CGPS_CONFIG); + gps_stream(&gpsd_conn, WATCH_ENABLE | WATCH_JSON | WATCH_NEWSTYLE, NULL); + gps_send(&gpsd_conn, CGPS_CONFIG); - while (CGPS_TRUE) - { - pthread_mutex_lock (&cgps_thread_lock); - if (cgps_thread_shutdown == CGPS_TRUE) - { + while (CGPS_TRUE) { + pthread_mutex_lock(&cgps_thread_lock); + if (cgps_thread_shutdown == CGPS_TRUE) { goto stop; } - pthread_mutex_unlock (&cgps_thread_lock); + pthread_mutex_unlock(&cgps_thread_lock); #if GPSD_API_MAJOR_VERSION > 4 - long timeout_us = CDTIME_T_TO_US (cgps_config_data.timeout); - if (!gps_waiting (&gpsd_conn, (int) timeout_us )) + long timeout_us = CDTIME_T_TO_US(cgps_config_data.timeout); + if (!gps_waiting(&gpsd_conn, (int)timeout_us)) #else - if (!gps_waiting (&gpsd_conn)) + if (!gps_waiting(&gpsd_conn)) #endif { continue; } - if (gps_read (&gpsd_conn) == -1) - { - WARNING ("gps plugin: incorrect data! (err_count: %d)", err_count); + if (gps_read(&gpsd_conn) == -1) { + WARNING("gps plugin: incorrect data! (err_count: %d)", err_count); err_count++; - if (err_count > CGPS_MAX_ERROR) - { + if (err_count > CGPS_MAX_ERROR) { // Server is not responding ... - if (gps_send (&gpsd_conn, CGPS_CONFIG) == -1) - { - WARNING ("gps plugin: gpsd seems to be down, reconnecting"); - gps_close (&gpsd_conn); + if (gps_send(&gpsd_conn, CGPS_CONFIG) == -1) { + WARNING("gps plugin: gpsd seems to be down, reconnecting"); + gps_close(&gpsd_conn); break; } // Server is responding ... - else - { + else { err_count = 0; } } @@ -171,71 +161,70 @@ static void * cgps_thread (void * pData) continue; } - pthread_mutex_lock (&cgps_data_lock); + pthread_mutex_lock(&cgps_data_lock); // Number of sats in view: - cgps_data.sats_used = (gauge_t) gpsd_conn.satellites_used; - cgps_data.sats_visible = (gauge_t) gpsd_conn.satellites_visible; + cgps_data.sats_used = (gauge_t)gpsd_conn.satellites_used; + cgps_data.sats_visible = (gauge_t)gpsd_conn.satellites_visible; // dilution of precision: cgps_data.vdop = NAN; cgps_data.hdop = NAN; - if (cgps_data.sats_used > 0) - { + if (cgps_data.sats_used > 0) { cgps_data.hdop = gpsd_conn.dop.hdop; cgps_data.vdop = gpsd_conn.dop.vdop; } - DEBUG ("gps plugin: %.0f sats used (of %.0f visible), hdop = %.3f, vdop = %.3f", - cgps_data.sats_used, cgps_data.sats_visible, cgps_data.hdop, cgps_data.vdop); + DEBUG("gps plugin: %.0f sats used (of %.0f visible), hdop = %.3f, vdop = " + "%.3f", + cgps_data.sats_used, cgps_data.sats_visible, cgps_data.hdop, + cgps_data.vdop); - pthread_mutex_unlock (&cgps_data_lock); + pthread_mutex_unlock(&cgps_data_lock); } } stop: - DEBUG ("gps plugin: thread closing gpsd connection ... "); - gps_stream (&gpsd_conn, WATCH_DISABLE, NULL); - gps_close (&gpsd_conn); + DEBUG("gps plugin: thread closing gpsd connection ... "); + gps_stream(&gpsd_conn, WATCH_DISABLE, NULL); + gps_close(&gpsd_conn); quit: - DEBUG ("gps plugin: thread shutting down ... "); + DEBUG("gps plugin: thread shutting down ... "); cgps_thread_running = CGPS_FALSE; - pthread_mutex_unlock (&cgps_thread_lock); - pthread_exit (NULL); + pthread_mutex_unlock(&cgps_thread_lock); + pthread_exit(NULL); } - /** * Submit a piece of the data. */ -static void cgps_submit (const char *type, gauge_t value, const char *type_instance) -{ +static void cgps_submit(const char *type, gauge_t value, + const char *type_instance) { value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; + vl.values = &(value_t){.gauge = value}; vl.values_len = 1; - sstrncpy (vl.plugin, "gps", sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + sstrncpy(vl.plugin, "gps", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /** * Read the data and submit by piece. */ -static int cgps_read (void) -{ +static int cgps_read(void) { cgps_data_t data_copy; - pthread_mutex_lock (&cgps_data_lock); + pthread_mutex_lock(&cgps_data_lock); data_copy = cgps_data; - pthread_mutex_unlock (&cgps_data_lock); + pthread_mutex_unlock(&cgps_data_lock); - cgps_submit ("dilution_of_precision", data_copy.hdop, "horizontal"); - cgps_submit ("dilution_of_precision", data_copy.vdop, "vertical"); - cgps_submit ("satellites", data_copy.sats_used, "used"); - cgps_submit ("satellites", data_copy.sats_visible, "visible"); + cgps_submit("dilution_of_precision", data_copy.hdop, "horizontal"); + cgps_submit("dilution_of_precision", data_copy.vdop, "vertical"); + cgps_submit("satellites", data_copy.sats_used, "used"); + cgps_submit("satellites", data_copy.sats_visible, "visible"); return (0); } @@ -243,39 +232,33 @@ static int cgps_read (void) /** * Read configuration. */ -static int cgps_config (oconfig_item_t *ci) -{ +static int cgps_config(oconfig_item_t *ci) { int i; - for (i = 0; i < ci->children_num; i++) - { + for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Host", child->key) == 0) - cf_util_get_string (child, &cgps_config_data.host); - else if (strcasecmp ("Port", child->key) == 0) - cf_util_get_service (child, &cgps_config_data.port); - else if (strcasecmp ("Timeout", child->key) == 0) - cf_util_get_cdtime (child, &cgps_config_data.timeout); - else if (strcasecmp ("PauseConnect", child->key) == 0) - cf_util_get_cdtime (child, &cgps_config_data.pause_connect); + if (strcasecmp("Host", child->key) == 0) + cf_util_get_string(child, &cgps_config_data.host); + else if (strcasecmp("Port", child->key) == 0) + cf_util_get_service(child, &cgps_config_data.port); + else if (strcasecmp("Timeout", child->key) == 0) + cf_util_get_cdtime(child, &cgps_config_data.timeout); + else if (strcasecmp("PauseConnect", child->key) == 0) + cf_util_get_cdtime(child, &cgps_config_data.pause_connect); else - WARNING ("gps plugin: Ignoring unknown config option \"%s\".", child->key); + WARNING("gps plugin: Ignoring unknown config option \"%s\".", child->key); } // Controlling the value for timeout: - // If set too high it blocks the reading (> 5 s), too low it gets not reading (< 500 us). + // If set too high it blocks the reading (> 5 s), too low it gets not reading + // (< 500 us). // To avoid any issues we replace "out of range" value by the default value. - if ( - cgps_config_data.timeout > TIME_T_TO_CDTIME_T(5) - || - cgps_config_data.timeout < US_TO_CDTIME_T(500) - ) - { - WARNING ("gps plugin: timeout set to %.6f sec. setting to default (%.6f).", - CDTIME_T_TO_DOUBLE(cgps_config_data.timeout), - CDTIME_T_TO_DOUBLE(CGPS_DEFAULT_TIMEOUT) - ); + if (cgps_config_data.timeout > TIME_T_TO_CDTIME_T(5) || + cgps_config_data.timeout < US_TO_CDTIME_T(500)) { + WARNING("gps plugin: timeout set to %.6f sec. setting to default (%.6f).", + CDTIME_T_TO_DOUBLE(cgps_config_data.timeout), + CDTIME_T_TO_DOUBLE(CGPS_DEFAULT_TIMEOUT)); cgps_config_data.timeout = CGPS_DEFAULT_TIMEOUT; } @@ -285,25 +268,24 @@ static int cgps_config (oconfig_item_t *ci) /** * Init. */ -static int cgps_init (void) -{ +static int cgps_init(void) { int status; - if (cgps_thread_running == CGPS_TRUE) - { - DEBUG ("gps plugin: error gps thread already running ... "); + if (cgps_thread_running == CGPS_TRUE) { + DEBUG("gps plugin: error gps thread already running ... "); return 0; } - DEBUG ("gps plugin: config{host: \"%s\", port: \"%s\", timeout: %.6f sec., pause connect: %.3f sec.}", - cgps_config_data.host, cgps_config_data.port, - CDTIME_T_TO_DOUBLE (cgps_config_data.timeout), - CDTIME_T_TO_DOUBLE (cgps_config_data.pause_connect)); + DEBUG("gps plugin: config{host: \"%s\", port: \"%s\", timeout: %.6f sec., " + "pause connect: %.3f sec.}", + cgps_config_data.host, cgps_config_data.port, + CDTIME_T_TO_DOUBLE(cgps_config_data.timeout), + CDTIME_T_TO_DOUBLE(cgps_config_data.pause_connect)); - status = plugin_thread_create (&cgps_thread_id, NULL, cgps_thread, NULL, "gps"); - if (status != 0) - { - ERROR ("gps plugin: pthread_create() failed."); + status = + plugin_thread_create(&cgps_thread_id, NULL, cgps_thread, NULL, "gps"); + if (status != 0) { + ERROR("gps plugin: pthread_create() failed."); return (-1); } @@ -313,14 +295,13 @@ static int cgps_init (void) /** * Shutdown. */ -static int cgps_shutdown (void) -{ - void * res; +static int cgps_shutdown(void) { + void *res; - pthread_mutex_lock (&cgps_thread_lock); + pthread_mutex_lock(&cgps_thread_lock); cgps_thread_shutdown = CGPS_TRUE; - pthread_cond_broadcast (&cgps_thread_cond); - pthread_mutex_unlock (&cgps_thread_lock); + pthread_cond_broadcast(&cgps_thread_cond); + pthread_mutex_unlock(&cgps_thread_lock); pthread_join(cgps_thread_id, &res); free(res); @@ -331,8 +312,8 @@ static int cgps_shutdown (void) pthread_mutex_unlock(&cgps_data_lock); pthread_mutex_destroy(&cgps_data_lock); - sfree (cgps_config_data.port); - sfree (cgps_config_data.host); + sfree(cgps_config_data.port); + sfree(cgps_config_data.host); return (0); } @@ -340,15 +321,14 @@ static int cgps_shutdown (void) /** * Register the module. */ -void module_register (void) -{ - cgps_config_data.host = sstrdup (CGPS_DEFAULT_HOST); - cgps_config_data.port = sstrdup (CGPS_DEFAULT_PORT); +void module_register(void) { + cgps_config_data.host = sstrdup(CGPS_DEFAULT_HOST); + cgps_config_data.port = sstrdup(CGPS_DEFAULT_PORT); cgps_config_data.timeout = CGPS_DEFAULT_TIMEOUT; cgps_config_data.pause_connect = CGPS_DEFAULT_PAUSE_CONNECT; - plugin_register_complex_config ("gps", cgps_config); - plugin_register_init ("gps", cgps_init); - plugin_register_read ("gps", cgps_read); - plugin_register_shutdown ("gps", cgps_shutdown); + plugin_register_complex_config("gps", cgps_config); + plugin_register_init("gps", cgps_init); + plugin_register_read("gps", cgps_read); + plugin_register_shutdown("gps", cgps_shutdown); } diff --git a/src/hddtemp.c b/src/hddtemp.c index cb6f6d25..321c1652 100644 --- a/src/hddtemp.c +++ b/src/hddtemp.c @@ -36,26 +36,22 @@ #include "common.h" #include "plugin.h" -# include -# include -# include -# include /* for basename */ -# include +#include +#include /* for basename */ +#include +#include +#include #if HAVE_LINUX_MAJOR_H -# include +#include #endif #define HDDTEMP_DEF_HOST "127.0.0.1" #define HDDTEMP_DEF_PORT "7634" #define HDDTEMP_MAX_RECV_BUF (1 << 20) -static const char *config_keys[] = -{ - "Host", - "Port" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"Host", "Port"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static char *hddtemp_host = NULL; static char hddtemp_port[16]; @@ -83,238 +79,210 @@ static char hddtemp_port[16]; * we need to create a new socket each time. Is there another way? * Hm, maybe we can re-use the `sockaddr' structure? -octo */ -static char *hddtemp_query_daemon (void) -{ - int fd; - ssize_t status; - - char *buffer; - int buffer_size; - int buffer_fill; - char *new_buffer; - - const char *host; - const char *port; - - struct addrinfo *ai_list; - int ai_return; - - host = hddtemp_host; - if (host == NULL) - host = HDDTEMP_DEF_HOST; - - port = hddtemp_port; - if (strlen (port) == 0) - port = HDDTEMP_DEF_PORT; - - struct addrinfo ai_hints = { - .ai_flags = AI_ADDRCONFIG, - .ai_family = AF_UNSPEC, - .ai_protocol = IPPROTO_TCP, - .ai_socktype = SOCK_STREAM - }; - - if ((ai_return = getaddrinfo (host, port, &ai_hints, &ai_list)) != 0) - { - char errbuf[1024]; - ERROR ("hddtemp plugin: getaddrinfo (%s, %s): %s", - host, port, - (ai_return == EAI_SYSTEM) - ? sstrerror (errno, errbuf, sizeof (errbuf)) - : gai_strerror (ai_return)); - return (NULL); - } - - fd = -1; - for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) - { - /* create our socket descriptor */ - fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, - ai_ptr->ai_protocol); - if (fd < 0) - { - char errbuf[1024]; - ERROR ("hddtemp plugin: socket: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - continue; - } - - /* connect to the hddtemp daemon */ - if (connect (fd, (struct sockaddr *) ai_ptr->ai_addr, - ai_ptr->ai_addrlen)) - { - char errbuf[1024]; - INFO ("hddtemp plugin: connect (%s, %s) failed: %s", - host, port, - sstrerror (errno, errbuf, sizeof (errbuf))); - close (fd); - fd = -1; - continue; - } - - /* A socket could be opened and connecting succeeded. We're - * done. */ - break; - } - - freeaddrinfo (ai_list); - - if (fd < 0) - { - ERROR ("hddtemp plugin: Could not connect to daemon."); - return (NULL); - } - - /* receive data from the hddtemp daemon */ - buffer = NULL; - buffer_size = 0; - buffer_fill = 0; - while (1) - { - if ((buffer_size == 0) || (buffer_fill >= buffer_size - 1)) - { - if (buffer_size == 0) - buffer_size = 1024; - else - buffer_size *= 2; - if (buffer_size > HDDTEMP_MAX_RECV_BUF) - { - WARNING ("hddtemp plugin: Message from hddtemp has been " - "truncated."); - break; - } - new_buffer = realloc (buffer, buffer_size); - if (new_buffer == NULL) { - close (fd); - free (buffer); - ERROR ("hddtemp plugin: Allocation failed."); - return (NULL); - } - buffer = new_buffer; - } - status = read (fd, buffer + buffer_fill, buffer_size - buffer_fill - 1); - if (status == 0) { - break; - } - else if (status == -1) - { - char errbuf[1024]; - - if ((errno == EAGAIN) || (errno == EINTR)) - continue; - - ERROR ("hddtemp plugin: Error reading from socket: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - close (fd); - free (buffer); - return (NULL); - } - buffer_fill += status; - } - - if (buffer_fill == 0) - { - WARNING ("hddtemp plugin: Peer has unexpectedly shut down " - "the socket. Buffer: `%s'", buffer); - close (fd); - free (buffer); - return (NULL); - } - - assert (buffer_fill < buffer_size); - buffer[buffer_fill] = '\0'; - close (fd); - return (buffer); +static char *hddtemp_query_daemon(void) { + int fd; + ssize_t status; + + char *buffer; + int buffer_size; + int buffer_fill; + char *new_buffer; + + const char *host; + const char *port; + + struct addrinfo *ai_list; + int ai_return; + + host = hddtemp_host; + if (host == NULL) + host = HDDTEMP_DEF_HOST; + + port = hddtemp_port; + if (strlen(port) == 0) + port = HDDTEMP_DEF_PORT; + + struct addrinfo ai_hints = {.ai_flags = AI_ADDRCONFIG, + .ai_family = AF_UNSPEC, + .ai_protocol = IPPROTO_TCP, + .ai_socktype = SOCK_STREAM}; + + if ((ai_return = getaddrinfo(host, port, &ai_hints, &ai_list)) != 0) { + char errbuf[1024]; + ERROR("hddtemp plugin: getaddrinfo (%s, %s): %s", host, port, + (ai_return == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf)) + : gai_strerror(ai_return)); + return (NULL); + } + + fd = -1; + for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; + ai_ptr = ai_ptr->ai_next) { + /* create our socket descriptor */ + fd = socket(ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); + if (fd < 0) { + char errbuf[1024]; + ERROR("hddtemp plugin: socket: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + continue; + } + + /* connect to the hddtemp daemon */ + if (connect(fd, (struct sockaddr *)ai_ptr->ai_addr, ai_ptr->ai_addrlen)) { + char errbuf[1024]; + INFO("hddtemp plugin: connect (%s, %s) failed: %s", host, port, + sstrerror(errno, errbuf, sizeof(errbuf))); + close(fd); + fd = -1; + continue; + } + + /* A socket could be opened and connecting succeeded. We're + * done. */ + break; + } + + freeaddrinfo(ai_list); + + if (fd < 0) { + ERROR("hddtemp plugin: Could not connect to daemon."); + return (NULL); + } + + /* receive data from the hddtemp daemon */ + buffer = NULL; + buffer_size = 0; + buffer_fill = 0; + while (1) { + if ((buffer_size == 0) || (buffer_fill >= buffer_size - 1)) { + if (buffer_size == 0) + buffer_size = 1024; + else + buffer_size *= 2; + if (buffer_size > HDDTEMP_MAX_RECV_BUF) { + WARNING("hddtemp plugin: Message from hddtemp has been " + "truncated."); + break; + } + new_buffer = realloc(buffer, buffer_size); + if (new_buffer == NULL) { + close(fd); + free(buffer); + ERROR("hddtemp plugin: Allocation failed."); + return (NULL); + } + buffer = new_buffer; + } + status = read(fd, buffer + buffer_fill, buffer_size - buffer_fill - 1); + if (status == 0) { + break; + } else if (status == -1) { + char errbuf[1024]; + + if ((errno == EAGAIN) || (errno == EINTR)) + continue; + + ERROR("hddtemp plugin: Error reading from socket: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(fd); + free(buffer); + return (NULL); + } + buffer_fill += status; + } + + if (buffer_fill == 0) { + WARNING("hddtemp plugin: Peer has unexpectedly shut down " + "the socket. Buffer: `%s'", + buffer); + close(fd); + free(buffer); + return (NULL); + } + + assert(buffer_fill < buffer_size); + buffer[buffer_fill] = '\0'; + close(fd); + return (buffer); } -static int hddtemp_config (const char *key, const char *value) -{ - if (strcasecmp (key, "Host") == 0) - { - if (hddtemp_host != NULL) - free (hddtemp_host); - hddtemp_host = strdup (value); - } - else if (strcasecmp (key, "Port") == 0) - { - int port = (int) (atof (value)); - if ((port > 0) && (port <= 65535)) - ssnprintf (hddtemp_port, sizeof (hddtemp_port), - "%i", port); - else - sstrncpy (hddtemp_port, value, sizeof (hddtemp_port)); - } - else - { - return (-1); - } - - return (0); +static int hddtemp_config(const char *key, const char *value) { + if (strcasecmp(key, "Host") == 0) { + if (hddtemp_host != NULL) + free(hddtemp_host); + hddtemp_host = strdup(value); + } else if (strcasecmp(key, "Port") == 0) { + int port = (int)(atof(value)); + if ((port > 0) && (port <= 65535)) + ssnprintf(hddtemp_port, sizeof(hddtemp_port), "%i", port); + else + sstrncpy(hddtemp_port, value, sizeof(hddtemp_port)); + } else { + return (-1); + } + + return (0); } -static void hddtemp_submit (char *type_instance, double value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void hddtemp_submit(char *type_instance, double value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "hddtemp", sizeof (vl.plugin)); - sstrncpy (vl.type, "temperature", sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "hddtemp", sizeof(vl.plugin)); + sstrncpy(vl.type, "temperature", sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static int hddtemp_read (void) -{ - char *buf; - char *ptr; - char *saveptr; - char *name; - char *model; - char *temperature; - char *mode; - - /* get data from daemon */ - buf = hddtemp_query_daemon (); - if (buf == NULL) - return (-1); - - /* NB: strtok_r will eat up "||" and leading "|"'s */ - ptr = buf; - saveptr = NULL; - while ((name = strtok_r (ptr, "|", &saveptr)) != NULL && - (model = strtok_r (NULL, "|", &saveptr)) != NULL && - (temperature = strtok_r (NULL, "|", &saveptr)) != NULL && - (mode = strtok_r (NULL, "|", &saveptr)) != NULL) - { - double temperature_value; - - ptr = NULL; - - /* Skip non-temperature information */ - if (mode[0] != 'C' && mode[0] != 'F') - continue; - - name = basename (name); - temperature_value = atof (temperature); - - /* Convert farenheit to celsius */ - if (mode[0] == 'F') - temperature_value = (temperature_value - 32.0) * 5.0 / 9.0; - - hddtemp_submit (name, temperature_value); - } - - free (buf); - return (0); +static int hddtemp_read(void) { + char *buf; + char *ptr; + char *saveptr; + char *name; + char *model; + char *temperature; + char *mode; + + /* get data from daemon */ + buf = hddtemp_query_daemon(); + if (buf == NULL) + return (-1); + + /* NB: strtok_r will eat up "||" and leading "|"'s */ + ptr = buf; + saveptr = NULL; + while ((name = strtok_r(ptr, "|", &saveptr)) != NULL && + (model = strtok_r(NULL, "|", &saveptr)) != NULL && + (temperature = strtok_r(NULL, "|", &saveptr)) != NULL && + (mode = strtok_r(NULL, "|", &saveptr)) != NULL) { + double temperature_value; + + ptr = NULL; + + /* Skip non-temperature information */ + if (mode[0] != 'C' && mode[0] != 'F') + continue; + + name = basename(name); + temperature_value = atof(temperature); + + /* Convert farenheit to celsius */ + if (mode[0] == 'F') + temperature_value = (temperature_value - 32.0) * 5.0 / 9.0; + + hddtemp_submit(name, temperature_value); + } + + free(buf); + return (0); } /* int hddtemp_read */ /* module_register Register collectd plugin. */ -void module_register (void) -{ - plugin_register_config ("hddtemp", hddtemp_config, - config_keys, config_keys_num); - plugin_register_read ("hddtemp", hddtemp_read); +void module_register(void) { + plugin_register_config("hddtemp", hddtemp_config, config_keys, + config_keys_num); + plugin_register_read("hddtemp", hddtemp_read); } diff --git a/src/hugepages.c b/src/hugepages.c index 1eb8b0c2..f23a6e2a 100644 --- a/src/hugepages.c +++ b/src/hugepages.c @@ -82,7 +82,7 @@ static int hp_config(oconfig_item_t *ci) { static void submit_hp(const struct entry_info *info) { value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = NAN }; + vl.values = &(value_t){.gauge = NAN}; vl.values_len = 1; sstrncpy(vl.plugin, g_plugin_name, sizeof(vl.plugin)); diff --git a/src/intel_rdt.c b/src/intel_rdt.c index 21f3a206..2ef65f57 100644 --- a/src/intel_rdt.c +++ b/src/intel_rdt.c @@ -25,8 +25,8 @@ * Serhiy Pshyk **/ -#include "collectd.h" #include "common.h" +#include "collectd.h" #include diff --git a/src/interface.c b/src/interface.c index c0021d33..b7c6f90e 100644 --- a/src/interface.c +++ b/src/interface.c @@ -29,30 +29,30 @@ #include "utils_ignorelist.h" #if HAVE_SYS_TYPES_H -# include +#include #endif /* One cannot include both. This sucks. */ #if HAVE_LINUX_IF_H -# include +#include #elif HAVE_NET_IF_H -# include +#include #endif #if HAVE_LINUX_NETDEVICE_H -# include +#include #endif #if HAVE_IFADDRS_H -# include +#include #endif #if HAVE_STATGRAB_H -# include +#include #endif #if HAVE_PERFSTAT -# include -# include +#include +#include #endif /* @@ -62,9 +62,9 @@ * of the configure script. -octo */ #if KERNEL_LINUX -# if !COLLECT_GETIFADDRS -# undef HAVE_GETIFADDRS -# endif /* !COLLECT_GETIFADDRS */ +#if !COLLECT_GETIFADDRS +#undef HAVE_GETIFADDRS +#endif /* !COLLECT_GETIFADDRS */ #endif /* KERNEL_LINUX */ #if HAVE_PERFSTAT @@ -73,20 +73,18 @@ static int nif; static int pnif; #endif /* HAVE_PERFSTAT */ -#if !HAVE_GETIFADDRS && !KERNEL_LINUX && !HAVE_LIBKSTAT && !HAVE_LIBSTATGRAB && !HAVE_PERFSTAT -# error "No applicable input method." +#if !HAVE_GETIFADDRS && !KERNEL_LINUX && !HAVE_LIBKSTAT && \ + !HAVE_LIBSTATGRAB && !HAVE_PERFSTAT +#error "No applicable input method." #endif /* * (Module-)Global variables */ -static const char *config_keys[] = -{ - "Interface", - "IgnoreSelected", - "ReportInactive", +static const char *config_keys[] = { + "Interface", "IgnoreSelected", "ReportInactive", }; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static ignorelist_t *ignorelist = NULL; @@ -100,320 +98,301 @@ static int numif = 0; static _Bool unique_name = 0; #endif /* HAVE_LIBKSTAT */ -static int interface_config (const char *key, const char *value) -{ - if (ignorelist == NULL) - ignorelist = ignorelist_create (/* invert = */ 1); - - if (strcasecmp (key, "Interface") == 0) - { - ignorelist_add (ignorelist, value); - } - else if (strcasecmp (key, "IgnoreSelected") == 0) - { - int invert = 1; - if (IS_TRUE (value)) - invert = 0; - ignorelist_set_invert (ignorelist, invert); - } - else if (strcasecmp (key, "ReportInactive") == 0) - report_inactive = IS_TRUE (value); - else if (strcasecmp (key, "UniqueName") == 0) - { - #ifdef HAVE_LIBKSTAT - if (IS_TRUE (value)) - unique_name = 1; - #else - WARNING ("interface plugin: the \"UniqueName\" option is only valid on Solaris."); - #endif /* HAVE_LIBKSTAT */ - } - else - { - return (-1); - } - - return (0); +static int interface_config(const char *key, const char *value) { + if (ignorelist == NULL) + ignorelist = ignorelist_create(/* invert = */ 1); + + if (strcasecmp(key, "Interface") == 0) { + ignorelist_add(ignorelist, value); + } else if (strcasecmp(key, "IgnoreSelected") == 0) { + int invert = 1; + if (IS_TRUE(value)) + invert = 0; + ignorelist_set_invert(ignorelist, invert); + } else if (strcasecmp(key, "ReportInactive") == 0) + report_inactive = IS_TRUE(value); + else if (strcasecmp(key, "UniqueName") == 0) { +#ifdef HAVE_LIBKSTAT + if (IS_TRUE(value)) + unique_name = 1; +#else + WARNING("interface plugin: the \"UniqueName\" option is only valid on " + "Solaris."); +#endif /* HAVE_LIBKSTAT */ + } else { + return (-1); + } + + return (0); } #if HAVE_LIBKSTAT -static int interface_init (void) -{ - kstat_t *ksp_chain; - - numif = 0; - - if (kc == NULL) - return (-1); - - for (numif = 0, ksp_chain = kc->kc_chain; - (numif < MAX_NUMIF) && (ksp_chain != NULL); - ksp_chain = ksp_chain->ks_next) - { - if (strncmp (ksp_chain->ks_class, "net", 3)) - continue; - if (ksp_chain->ks_type != KSTAT_TYPE_NAMED) - continue; - if (kstat_read (kc, ksp_chain, NULL) == -1) - continue; - if (get_kstat_value (ksp_chain, "obytes") == -1LL) - continue; - ksp[numif++] = ksp_chain; - } - - return (0); +static int interface_init(void) { + kstat_t *ksp_chain; + + numif = 0; + + if (kc == NULL) + return (-1); + + for (numif = 0, ksp_chain = kc->kc_chain; + (numif < MAX_NUMIF) && (ksp_chain != NULL); + ksp_chain = ksp_chain->ks_next) { + if (strncmp(ksp_chain->ks_class, "net", 3)) + continue; + if (ksp_chain->ks_type != KSTAT_TYPE_NAMED) + continue; + if (kstat_read(kc, ksp_chain, NULL) == -1) + continue; + if (get_kstat_value(ksp_chain, "obytes") == -1LL) + continue; + ksp[numif++] = ksp_chain; + } + + return (0); } /* int interface_init */ #endif /* HAVE_LIBKSTAT */ -static void if_submit (const char *dev, const char *type, - derive_t rx, - derive_t tx) -{ - value_list_t vl = VALUE_LIST_INIT; - value_t values[] = { - { .derive = rx }, - { .derive = tx }, - }; - - if (ignorelist_match (ignorelist, dev) != 0) - return; - - vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - sstrncpy (vl.plugin, "interface", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - - plugin_dispatch_values (&vl); +static void if_submit(const char *dev, const char *type, derive_t rx, + derive_t tx) { + value_list_t vl = VALUE_LIST_INIT; + value_t values[] = { + {.derive = rx}, {.derive = tx}, + }; + + if (ignorelist_match(ignorelist, dev) != 0) + return; + + vl.values = values; + vl.values_len = STATIC_ARRAY_SIZE(values); + sstrncpy(vl.plugin, "interface", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, dev, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + + plugin_dispatch_values(&vl); } /* void if_submit */ -static int interface_read (void) -{ +static int interface_read(void) { #if HAVE_GETIFADDRS - struct ifaddrs *if_list; + struct ifaddrs *if_list; /* Darwin/Mac OS X and possible other *BSDs */ #if HAVE_STRUCT_IF_DATA -# define IFA_DATA if_data -# define IFA_RX_BYTES ifi_ibytes -# define IFA_TX_BYTES ifi_obytes -# define IFA_RX_PACKT ifi_ipackets -# define IFA_TX_PACKT ifi_opackets -# define IFA_RX_ERROR ifi_ierrors -# define IFA_TX_ERROR ifi_oerrors +#define IFA_DATA if_data +#define IFA_RX_BYTES ifi_ibytes +#define IFA_TX_BYTES ifi_obytes +#define IFA_RX_PACKT ifi_ipackets +#define IFA_TX_PACKT ifi_opackets +#define IFA_RX_ERROR ifi_ierrors +#define IFA_TX_ERROR ifi_oerrors /* #endif HAVE_STRUCT_IF_DATA */ #elif HAVE_STRUCT_NET_DEVICE_STATS -# define IFA_DATA net_device_stats -# define IFA_RX_BYTES rx_bytes -# define IFA_TX_BYTES tx_bytes -# define IFA_RX_PACKT rx_packets -# define IFA_TX_PACKT tx_packets -# define IFA_RX_ERROR rx_errors -# define IFA_TX_ERROR tx_errors +#define IFA_DATA net_device_stats +#define IFA_RX_BYTES rx_bytes +#define IFA_TX_BYTES tx_bytes +#define IFA_RX_PACKT rx_packets +#define IFA_TX_PACKT tx_packets +#define IFA_RX_ERROR rx_errors +#define IFA_TX_ERROR tx_errors #else -# error "No suitable type for `struct ifaddrs->ifa_data' found." +#error "No suitable type for `struct ifaddrs->ifa_data' found." #endif - struct IFA_DATA *if_data; + struct IFA_DATA *if_data; - if (getifaddrs (&if_list) != 0) - return (-1); + if (getifaddrs(&if_list) != 0) + return (-1); - for (struct ifaddrs *if_ptr = if_list; if_ptr != NULL; if_ptr = if_ptr->ifa_next) - { - if (if_ptr->ifa_addr != NULL && if_ptr->ifa_addr->sa_family == AF_LINK) { - if_data = (struct IFA_DATA *) if_ptr->ifa_data; + for (struct ifaddrs *if_ptr = if_list; if_ptr != NULL; + if_ptr = if_ptr->ifa_next) { + if (if_ptr->ifa_addr != NULL && if_ptr->ifa_addr->sa_family == AF_LINK) { + if_data = (struct IFA_DATA *)if_ptr->ifa_data; - if (!report_inactive && if_data->IFA_RX_PACKT == 0 && if_data->IFA_TX_PACKT == 0) - continue; + if (!report_inactive && if_data->IFA_RX_PACKT == 0 && + if_data->IFA_TX_PACKT == 0) + continue; - if_submit (if_ptr->ifa_name, "if_octets", - if_data->IFA_RX_BYTES, - if_data->IFA_TX_BYTES); - if_submit (if_ptr->ifa_name, "if_packets", - if_data->IFA_RX_PACKT, - if_data->IFA_TX_PACKT); - if_submit (if_ptr->ifa_name, "if_errors", - if_data->IFA_RX_ERROR, - if_data->IFA_TX_ERROR); - } - } + if_submit(if_ptr->ifa_name, "if_octets", if_data->IFA_RX_BYTES, + if_data->IFA_TX_BYTES); + if_submit(if_ptr->ifa_name, "if_packets", if_data->IFA_RX_PACKT, + if_data->IFA_TX_PACKT); + if_submit(if_ptr->ifa_name, "if_errors", if_data->IFA_RX_ERROR, + if_data->IFA_TX_ERROR); + } + } - freeifaddrs (if_list); + freeifaddrs(if_list); /* #endif HAVE_GETIFADDRS */ #elif KERNEL_LINUX - FILE *fh; - char buffer[1024]; - derive_t incoming, outgoing; - char *device; - - char *dummy; - char *fields[16]; - int numfields; - - if ((fh = fopen ("/proc/net/dev", "r")) == NULL) - { - char errbuf[1024]; - WARNING ("interface plugin: fopen: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - while (fgets (buffer, 1024, fh) != NULL) - { - if (!(dummy = strchr(buffer, ':'))) - continue; - dummy[0] = '\0'; - dummy++; - - device = buffer; - while (device[0] == ' ') - device++; - - if (device[0] == '\0') - continue; - - numfields = strsplit (dummy, fields, 16); - - if (numfields < 11) - continue; - - incoming = atoll (fields[1]); - outgoing = atoll (fields[9]); - if (!report_inactive && incoming == 0 && outgoing == 0) - continue; - - if_submit (device, "if_packets", incoming, outgoing); - - incoming = atoll (fields[0]); - outgoing = atoll (fields[8]); - if_submit (device, "if_octets", incoming, outgoing); - - incoming = atoll (fields[2]); - outgoing = atoll (fields[10]); - if_submit (device, "if_errors", incoming, outgoing); - - incoming = atoll (fields[3]); - outgoing = atoll (fields[11]); - if_submit (device, "if_dropped", incoming, outgoing); - } - - fclose (fh); + FILE *fh; + char buffer[1024]; + derive_t incoming, outgoing; + char *device; + + char *dummy; + char *fields[16]; + int numfields; + + if ((fh = fopen("/proc/net/dev", "r")) == NULL) { + char errbuf[1024]; + WARNING("interface plugin: fopen: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + while (fgets(buffer, 1024, fh) != NULL) { + if (!(dummy = strchr(buffer, ':'))) + continue; + dummy[0] = '\0'; + dummy++; + + device = buffer; + while (device[0] == ' ') + device++; + + if (device[0] == '\0') + continue; + + numfields = strsplit(dummy, fields, 16); + + if (numfields < 11) + continue; + + incoming = atoll(fields[1]); + outgoing = atoll(fields[9]); + if (!report_inactive && incoming == 0 && outgoing == 0) + continue; + + if_submit(device, "if_packets", incoming, outgoing); + + incoming = atoll(fields[0]); + outgoing = atoll(fields[8]); + if_submit(device, "if_octets", incoming, outgoing); + + incoming = atoll(fields[2]); + outgoing = atoll(fields[10]); + if_submit(device, "if_errors", incoming, outgoing); + + incoming = atoll(fields[3]); + outgoing = atoll(fields[11]); + if_submit(device, "if_dropped", incoming, outgoing); + } + + fclose(fh); /* #endif KERNEL_LINUX */ #elif HAVE_LIBKSTAT - derive_t rx; - derive_t tx; - char iname[DATA_MAX_NAME_LEN]; - - if (kc == NULL) - return (-1); - - for (int i = 0; i < numif; i++) - { - if (kstat_read (kc, ksp[i], NULL) == -1) - continue; - - if (unique_name) - ssnprintf(iname, sizeof(iname), "%s_%d_%s", ksp[i]->ks_module, ksp[i]->ks_instance, ksp[i]->ks_name); - else - sstrncpy(iname, ksp[i]->ks_name, sizeof(iname)); - - /* try to get 64bit counters */ - rx = get_kstat_value (ksp[i], "ipackets64"); - tx = get_kstat_value (ksp[i], "opackets64"); - /* or fallback to 32bit */ - if (rx == -1LL) - rx = get_kstat_value (ksp[i], "ipackets"); - if (tx == -1LL) - tx = get_kstat_value (ksp[i], "opackets"); - if (!report_inactive && rx == 0 && tx == 0) - continue; - if ((rx != -1LL) || (tx != -1LL)) - if_submit (iname, "if_packets", rx, tx); - - /* try to get 64bit counters */ - rx = get_kstat_value (ksp[i], "rbytes64"); - tx = get_kstat_value (ksp[i], "obytes64"); - /* or fallback to 32bit */ - if (rx == -1LL) - rx = get_kstat_value (ksp[i], "rbytes"); - if (tx == -1LL) - tx = get_kstat_value (ksp[i], "obytes"); - if ((rx != -1LL) || (tx != -1LL)) - if_submit (iname, "if_octets", rx, tx); - - /* no 64bit error counters yet */ - rx = get_kstat_value (ksp[i], "ierrors"); - tx = get_kstat_value (ksp[i], "oerrors"); - if ((rx != -1LL) || (tx != -1LL)) - if_submit (iname, "if_errors", rx, tx); - } + derive_t rx; + derive_t tx; + char iname[DATA_MAX_NAME_LEN]; + + if (kc == NULL) + return (-1); + + for (int i = 0; i < numif; i++) { + if (kstat_read(kc, ksp[i], NULL) == -1) + continue; + + if (unique_name) + ssnprintf(iname, sizeof(iname), "%s_%d_%s", ksp[i]->ks_module, + ksp[i]->ks_instance, ksp[i]->ks_name); + else + sstrncpy(iname, ksp[i]->ks_name, sizeof(iname)); + + /* try to get 64bit counters */ + rx = get_kstat_value(ksp[i], "ipackets64"); + tx = get_kstat_value(ksp[i], "opackets64"); + /* or fallback to 32bit */ + if (rx == -1LL) + rx = get_kstat_value(ksp[i], "ipackets"); + if (tx == -1LL) + tx = get_kstat_value(ksp[i], "opackets"); + if (!report_inactive && rx == 0 && tx == 0) + continue; + if ((rx != -1LL) || (tx != -1LL)) + if_submit(iname, "if_packets", rx, tx); + + /* try to get 64bit counters */ + rx = get_kstat_value(ksp[i], "rbytes64"); + tx = get_kstat_value(ksp[i], "obytes64"); + /* or fallback to 32bit */ + if (rx == -1LL) + rx = get_kstat_value(ksp[i], "rbytes"); + if (tx == -1LL) + tx = get_kstat_value(ksp[i], "obytes"); + if ((rx != -1LL) || (tx != -1LL)) + if_submit(iname, "if_octets", rx, tx); + + /* no 64bit error counters yet */ + rx = get_kstat_value(ksp[i], "ierrors"); + tx = get_kstat_value(ksp[i], "oerrors"); + if ((rx != -1LL) || (tx != -1LL)) + if_submit(iname, "if_errors", rx, tx); + } /* #endif HAVE_LIBKSTAT */ #elif defined(HAVE_LIBSTATGRAB) - sg_network_io_stats *ios; - int num; + sg_network_io_stats *ios; + int num; - ios = sg_get_network_io_stats (&num); + ios = sg_get_network_io_stats(&num); - for (int i = 0; i < num; i++) { - if (!report_inactive && ios[i].rx == 0 && ios[i].tx == 0) - continue; - if_submit (ios[i].interface_name, "if_octets", ios[i].rx, ios[i].tx); - } + for (int i = 0; i < num; i++) { + if (!report_inactive && ios[i].rx == 0 && ios[i].tx == 0) + continue; + if_submit(ios[i].interface_name, "if_octets", ios[i].rx, ios[i].tx); + } /* #endif HAVE_LIBSTATGRAB */ #elif defined(HAVE_PERFSTAT) - perfstat_id_t id; - int ifs; - - if ((nif = perfstat_netinterface(NULL, NULL, sizeof(perfstat_netinterface_t), 0)) < 0) - { - char errbuf[1024]; - WARNING ("interface plugin: perfstat_netinterface: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - if (pnif != nif || ifstat == NULL) - { - free(ifstat); - ifstat = malloc(nif * sizeof (*ifstat)); - } - pnif = nif; - - id.name[0]='\0'; - if ((ifs = perfstat_netinterface(&id, ifstat, sizeof(perfstat_netinterface_t), nif)) < 0) - { - char errbuf[1024]; - WARNING ("interface plugin: perfstat_netinterface (interfaces=%d): %s", - nif, sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - for (int i = 0; i < ifs; i++) - { - if (!report_inactive && ifstat[i].ipackets == 0 && ifstat[i].opackets == 0) - continue; - - if_submit (ifstat[i].name, "if_octets", ifstat[i].ibytes, ifstat[i].obytes); - if_submit (ifstat[i].name, "if_packets", ifstat[i].ipackets ,ifstat[i].opackets); - if_submit (ifstat[i].name, "if_errors", ifstat[i].ierrors, ifstat[i].oerrors ); - } + perfstat_id_t id; + int ifs; + + if ((nif = perfstat_netinterface(NULL, NULL, sizeof(perfstat_netinterface_t), + 0)) < 0) { + char errbuf[1024]; + WARNING("interface plugin: perfstat_netinterface: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + if (pnif != nif || ifstat == NULL) { + free(ifstat); + ifstat = malloc(nif * sizeof(*ifstat)); + } + pnif = nif; + + id.name[0] = '\0'; + if ((ifs = perfstat_netinterface(&id, ifstat, sizeof(perfstat_netinterface_t), + nif)) < 0) { + char errbuf[1024]; + WARNING("interface plugin: perfstat_netinterface (interfaces=%d): %s", nif, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + for (int i = 0; i < ifs; i++) { + if (!report_inactive && ifstat[i].ipackets == 0 && ifstat[i].opackets == 0) + continue; + + if_submit(ifstat[i].name, "if_octets", ifstat[i].ibytes, ifstat[i].obytes); + if_submit(ifstat[i].name, "if_packets", ifstat[i].ipackets, + ifstat[i].opackets); + if_submit(ifstat[i].name, "if_errors", ifstat[i].ierrors, + ifstat[i].oerrors); + } #endif /* HAVE_PERFSTAT */ - return (0); + return (0); } /* int interface_read */ -void module_register (void) -{ - plugin_register_config ("interface", interface_config, - config_keys, config_keys_num); +void module_register(void) { + plugin_register_config("interface", interface_config, config_keys, + config_keys_num); #if HAVE_LIBKSTAT - plugin_register_init ("interface", interface_init); + plugin_register_init("interface", interface_init); #endif - plugin_register_read ("interface", interface_read); + plugin_register_read("interface", interface_read); } /* void module_register */ - diff --git a/src/ipc.c b/src/ipc.c index 7f909e26..c9fb003e 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -32,100 +32,97 @@ #include "plugin.h" #if KERNEL_LINUX - /* _GNU_SOURCE is needed for struct shm_info.used_ids on musl libc */ -# define _GNU_SOURCE - - /* X/OPEN tells us to use for semctl() */ - /* X/OPEN tells us to use for msgctl() */ - /* X/OPEN tells us to use for shmctl() */ -# include -# include -# include -# include -# include - - /* For older kernels the same holds for the defines below */ -# ifndef MSG_STAT -# define MSG_STAT 11 -# define MSG_INFO 12 -# endif - -# ifndef SHM_STAT -# define SHM_STAT 13 -# define SHM_INFO 14 - struct shm_info { - int used_ids; - ulong shm_tot; /* total allocated shm */ - ulong shm_rss; /* total resident shm */ - ulong shm_swp; /* total swapped shm */ - ulong swap_attempts; - ulong swap_successes; - }; -# endif - -# ifndef SEM_STAT -# define SEM_STAT 18 -# define SEM_INFO 19 -# endif - - /* The last arg of semctl is a union semun, but where is it defined? - X/OPEN tells us to define it ourselves, but until recently - Linux include files would also define it. */ -# if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) - /* union semun is defined by including */ -# else - /* according to X/OPEN we have to define it ourselves */ - union semun { - int val; - struct semid_ds *buf; - unsigned short *array; - struct seminfo *__buf; - }; -# endif +/* _GNU_SOURCE is needed for struct shm_info.used_ids on musl libc */ +#define _GNU_SOURCE + +/* X/OPEN tells us to use for semctl() */ +/* X/OPEN tells us to use for msgctl() */ +/* X/OPEN tells us to use for shmctl() */ +#include +#include +#include +#include +#include + +/* For older kernels the same holds for the defines below */ +#ifndef MSG_STAT +#define MSG_STAT 11 +#define MSG_INFO 12 +#endif + +#ifndef SHM_STAT +#define SHM_STAT 13 +#define SHM_INFO 14 +struct shm_info { + int used_ids; + ulong shm_tot; /* total allocated shm */ + ulong shm_rss; /* total resident shm */ + ulong shm_swp; /* total swapped shm */ + ulong swap_attempts; + ulong swap_successes; +}; +#endif + +#ifndef SEM_STAT +#define SEM_STAT 18 +#define SEM_INFO 19 +#endif + +/* The last arg of semctl is a union semun, but where is it defined? + X/OPEN tells us to define it ourselves, but until recently + Linux include files would also define it. */ +#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) +/* union semun is defined by including */ +#else +/* according to X/OPEN we have to define it ourselves */ +union semun { + int val; + struct semid_ds *buf; + unsigned short *array; + struct seminfo *__buf; +}; +#endif static long pagesize_g; /* #endif KERNEL_LINUX */ #elif KERNEL_AIX -# include +#include /* #endif KERNEL_AIX */ #else -# error "No applicable input method." +#error "No applicable input method." #endif -__attribute__ ((nonnull(1))) -static void ipc_submit_g (const char *plugin_instance, - const char *type, - const char *type_instance, - gauge_t value) /* {{{ */ +__attribute__((nonnull(1))) static void +ipc_submit_g(const char *plugin_instance, const char *type, + const char *type_instance, gauge_t value) /* {{{ */ { value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; + vl.values = &(value_t){.gauge = value}; vl.values_len = 1; - sstrncpy (vl.plugin, "ipc", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); + sstrncpy(vl.plugin, "ipc", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* }}} */ #if KERNEL_LINUX -static int ipc_read_sem (void) /* {{{ */ +static int ipc_read_sem(void) /* {{{ */ { struct seminfo seminfo; union semun arg; int status; - arg.array = (void *) &seminfo; + arg.array = (void *)&seminfo; - status = semctl (/* id = */ 0, /* num = */ 0, SEM_INFO, arg); - if (status == -1) - { + status = semctl(/* id = */ 0, /* num = */ 0, SEM_INFO, arg); + if (status == -1) { char errbuf[1024]; ERROR("ipc plugin: semctl(2) failed: %s. " - "Maybe the kernel is not configured for semaphores?", - sstrerror (errno, errbuf, sizeof (errbuf))); + "Maybe the kernel is not configured for semaphores?", + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } @@ -135,18 +132,17 @@ static int ipc_read_sem (void) /* {{{ */ return (0); } /* }}} int ipc_read_sem */ -static int ipc_read_shm (void) /* {{{ */ +static int ipc_read_shm(void) /* {{{ */ { struct shm_info shm_info; int status; - status = shmctl (/* id = */ 0, SHM_INFO, (void *) &shm_info); - if (status == -1) - { + status = shmctl(/* id = */ 0, SHM_INFO, (void *)&shm_info); + if (status == -1) { char errbuf[1024]; ERROR("ipc plugin: shmctl(2) failed: %s. " - "Maybe the kernel is not configured for shared memory?", - sstrerror (errno, errbuf, sizeof (errbuf))); + "Maybe the kernel is not configured for shared memory?", + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } @@ -158,12 +154,11 @@ static int ipc_read_shm (void) /* {{{ */ } /* }}} int ipc_read_shm */ -static int ipc_read_msg (void) /* {{{ */ +static int ipc_read_msg(void) /* {{{ */ { struct msginfo msginfo; - if ( msgctl(0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo) < 0 ) - { + if (msgctl(0, MSG_INFO, (struct msqid_ds *)(void *)&msginfo) < 0) { ERROR("Kernel is not configured for message queues"); return (-1); } @@ -175,7 +170,7 @@ static int ipc_read_msg (void) /* {{{ */ } /* }}} int ipc_read_msg */ -static int ipc_init (void) /* {{{ */ +static int ipc_init(void) /* {{{ */ { pagesize_g = sysconf(_SC_PAGESIZE); return (0); @@ -184,17 +179,17 @@ static int ipc_init (void) /* {{{ */ /* #endif KERNEL_LINUX */ #elif KERNEL_AIX -static caddr_t ipc_get_info (cid_t cid, int cmd, int version, int stsize, int *nmemb) /* {{{ */ +static caddr_t ipc_get_info(cid_t cid, int cmd, int version, int stsize, + int *nmemb) /* {{{ */ { int size = 0; caddr_t buff = NULL; - if (get_ipc_info(cid, cmd, version, buff, &size) < 0) - { + if (get_ipc_info(cid, cmd, version, buff, &size) < 0) { if (errno != ENOSPC) { char errbuf[1024]; - WARNING ("ipc plugin: get_ipc_info: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + WARNING("ipc plugin: get_ipc_info: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); return (NULL); } } @@ -203,23 +198,22 @@ static caddr_t ipc_get_info (cid_t cid, int cmd, int version, int stsize, int *n return NULL; if (size % stsize) { - ERROR ("ipc plugin: ipc_get_info: missmatch struct size and buffer size"); + ERROR("ipc plugin: ipc_get_info: missmatch struct size and buffer size"); return (NULL); } *nmemb = size / stsize; - buff = malloc (size); - if (buff == NULL) { - ERROR ("ipc plugin: ipc_get_info malloc failed."); + buff = malloc(size); + if (buff == NULL) { + ERROR("ipc plugin: ipc_get_info malloc failed."); return (NULL); } - if (get_ipc_info(cid, cmd, version, buff, &size) < 0) - { + if (get_ipc_info(cid, cmd, version, buff, &size) < 0) { char errbuf[1024]; - WARNING ("ipc plugin: get_ipc_info: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + WARNING("ipc plugin: get_ipc_info: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); free(buff); return (NULL); } @@ -227,19 +221,19 @@ static caddr_t ipc_get_info (cid_t cid, int cmd, int version, int stsize, int *n return buff; } /* }}} */ -static int ipc_read_sem (void) /* {{{ */ +static int ipc_read_sem(void) /* {{{ */ { ipcinfo_sem_t *ipcinfo_sem; - unsigned short sem_nsems=0; - unsigned short sems=0; + unsigned short sem_nsems = 0; + unsigned short sems = 0; int n; - ipcinfo_sem = (ipcinfo_sem_t *)ipc_get_info(0, - GET_IPCINFO_SEM_ALL, IPCINFO_SEM_VERSION, sizeof(ipcinfo_sem_t), &n); + ipcinfo_sem = (ipcinfo_sem_t *)ipc_get_info( + 0, GET_IPCINFO_SEM_ALL, IPCINFO_SEM_VERSION, sizeof(ipcinfo_sem_t), &n); if (ipcinfo_sem == NULL) return -1; - for (int i=0; ishm_segsz; } @@ -277,20 +271,20 @@ static int ipc_read_shm (void) /* {{{ */ } /* }}} int ipc_read_shm */ -static int ipc_read_msg (void) /* {{{ */ +static int ipc_read_msg(void) /* {{{ */ { ipcinfo_msg_t *ipcinfo_msg; - uint32_t msg_used_space=0; - uint32_t msg_alloc_queues=0; - msgqnum32_t msg_qnum=0; + uint32_t msg_used_space = 0; + uint32_t msg_alloc_queues = 0; + msgqnum32_t msg_qnum = 0; int n; - ipcinfo_msg = (ipcinfo_msg_t *)ipc_get_info(0, - GET_IPCINFO_MSG_ALL, IPCINFO_MSG_VERSION, sizeof(ipcinfo_msg_t), &n); + ipcinfo_msg = (ipcinfo_msg_t *)ipc_get_info( + 0, GET_IPCINFO_MSG_ALL, IPCINFO_MSG_VERSION, sizeof(ipcinfo_msg_t), &n); if (ipcinfo_msg == NULL) return -1; - for (int i=0; i +#include #include #include -#include #include +#include /* * Private data types @@ -41,8 +41,7 @@ struct c_ipmi_sensor_list_s; typedef struct c_ipmi_sensor_list_s c_ipmi_sensor_list_t; -struct c_ipmi_sensor_list_s -{ +struct c_ipmi_sensor_list_s { ipmi_sensor_id_t sensor_id; char sensor_name[DATA_MAX_NAME_LEN]; char sensor_type[DATA_MAX_NAME_LEN]; @@ -58,17 +57,12 @@ static c_ipmi_sensor_list_t *sensor_list = NULL; static int c_ipmi_init_in_progress = 0; static int c_ipmi_active = 0; -static pthread_t thread_id = (pthread_t) 0; - -static const char *config_keys[] = -{ - "Sensor", - "IgnoreSelected", - "NotifySensorAdd", - "NotifySensorRemove", - "NotifySensorNotPresent" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static pthread_t thread_id = (pthread_t)0; + +static const char *config_keys[] = {"Sensor", "IgnoreSelected", + "NotifySensorAdd", "NotifySensorRemove", + "NotifySensorNotPresent"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static ignorelist_t *ignorelist = NULL; @@ -79,157 +73,139 @@ static int c_ipmi_nofiy_notpresent = 0; /* * Misc private functions */ -static void c_ipmi_error (const char *func, int status) -{ - char errbuf[4096] = { 0 }; +static void c_ipmi_error(const char *func, int status) { + char errbuf[4096] = {0}; - if (IPMI_IS_OS_ERR (status)) - { - sstrerror (IPMI_GET_OS_ERR (status), errbuf, sizeof (errbuf)); - } - else if (IPMI_IS_IPMI_ERR (status)) - { - ipmi_get_error_string (IPMI_GET_IPMI_ERR (status), errbuf, sizeof (errbuf)); + if (IPMI_IS_OS_ERR(status)) { + sstrerror(IPMI_GET_OS_ERR(status), errbuf, sizeof(errbuf)); + } else if (IPMI_IS_IPMI_ERR(status)) { + ipmi_get_error_string(IPMI_GET_IPMI_ERR(status), errbuf, sizeof(errbuf)); } - if (errbuf[0] == 0) - { - ssnprintf (errbuf, sizeof (errbuf), "Unknown error %#x", status); + if (errbuf[0] == 0) { + ssnprintf(errbuf, sizeof(errbuf), "Unknown error %#x", status); } - errbuf[sizeof (errbuf) - 1] = 0; + errbuf[sizeof(errbuf) - 1] = 0; - ERROR ("ipmi plugin: %s failed: %s", func, errbuf); + ERROR("ipmi plugin: %s failed: %s", func, errbuf); } /* void c_ipmi_error */ /* * Sensor handlers */ /* Prototype for sensor_list_remove, so sensor_read_handler can call it. */ -static int sensor_list_remove (ipmi_sensor_t *sensor); - -static void sensor_read_handler (ipmi_sensor_t *sensor, - int err, - enum ipmi_value_present_e value_present, - unsigned int __attribute__((unused)) raw_value, - double value, - ipmi_states_t __attribute__((unused)) *states, - void *user_data) -{ +static int sensor_list_remove(ipmi_sensor_t *sensor); + +static void sensor_read_handler(ipmi_sensor_t *sensor, int err, + enum ipmi_value_present_e value_present, + unsigned int __attribute__((unused)) raw_value, + double value, + ipmi_states_t __attribute__((unused)) * states, + void *user_data) { value_list_t vl = VALUE_LIST_INIT; c_ipmi_sensor_list_t *list_item = (c_ipmi_sensor_list_t *)user_data; - if (err != 0) - { - if ((err & 0xff) == IPMI_NOT_PRESENT_CC) - { - if (list_item->sensor_not_present == 0) - { + if (err != 0) { + if ((err & 0xff) == IPMI_NOT_PRESENT_CC) { + if (list_item->sensor_not_present == 0) { list_item->sensor_not_present = 1; - INFO ("ipmi plugin: sensor_read_handler: sensor %s " - "not present.", list_item->sensor_name); + INFO("ipmi plugin: sensor_read_handler: sensor %s " + "not present.", + list_item->sensor_name); - if (c_ipmi_nofiy_notpresent) - { - notification_t n = { NOTIF_WARNING, cdtime (), "", "", "ipmi", - "", "", "", NULL }; + if (c_ipmi_nofiy_notpresent) { + notification_t n = { + NOTIF_WARNING, cdtime(), "", "", "ipmi", "", "", "", NULL}; - sstrncpy (n.host, hostname_g, sizeof (n.host)); - sstrncpy (n.type_instance, list_item->sensor_name, - sizeof (n.type_instance)); - sstrncpy (n.type, list_item->sensor_type, sizeof (n.type)); - ssnprintf (n.message, sizeof (n.message), - "sensor %s not present", list_item->sensor_name); + sstrncpy(n.host, hostname_g, sizeof(n.host)); + sstrncpy(n.type_instance, list_item->sensor_name, + sizeof(n.type_instance)); + sstrncpy(n.type, list_item->sensor_type, sizeof(n.type)); + ssnprintf(n.message, sizeof(n.message), "sensor %s not present", + list_item->sensor_name); - plugin_dispatch_notification (&n); + plugin_dispatch_notification(&n); } } - } - else if (IPMI_IS_IPMI_ERR(err) && IPMI_GET_IPMI_ERR(err) == IPMI_NOT_SUPPORTED_IN_PRESENT_STATE_CC) - { - INFO ("ipmi plugin: sensor_read_handler: Sensor %s not ready", - list_item->sensor_name); - } - else - { + } else if (IPMI_IS_IPMI_ERR(err) && + IPMI_GET_IPMI_ERR(err) == + IPMI_NOT_SUPPORTED_IN_PRESENT_STATE_CC) { + INFO("ipmi plugin: sensor_read_handler: Sensor %s not ready", + list_item->sensor_name); + } else { if (IPMI_IS_IPMI_ERR(err)) - INFO ("ipmi plugin: sensor_read_handler: Removing sensor %s, " - "because it failed with IPMI error %#x.", - list_item->sensor_name, IPMI_GET_IPMI_ERR(err)); + INFO("ipmi plugin: sensor_read_handler: Removing sensor %s, " + "because it failed with IPMI error %#x.", + list_item->sensor_name, IPMI_GET_IPMI_ERR(err)); else if (IPMI_IS_OS_ERR(err)) - INFO ("ipmi plugin: sensor_read_handler: Removing sensor %s, " - "because it failed with OS error %#x.", - list_item->sensor_name, IPMI_GET_OS_ERR(err)); + INFO("ipmi plugin: sensor_read_handler: Removing sensor %s, " + "because it failed with OS error %#x.", + list_item->sensor_name, IPMI_GET_OS_ERR(err)); else if (IPMI_IS_RMCPP_ERR(err)) - INFO ("ipmi plugin: sensor_read_handler: Removing sensor %s, " - "because it failed with RMCPP error %#x.", - list_item->sensor_name, IPMI_GET_RMCPP_ERR(err)); + INFO("ipmi plugin: sensor_read_handler: Removing sensor %s, " + "because it failed with RMCPP error %#x.", + list_item->sensor_name, IPMI_GET_RMCPP_ERR(err)); else if (IPMI_IS_SOL_ERR(err)) - INFO ("ipmi plugin: sensor_read_handler: Removing sensor %s, " - "because it failed with RMCPP error %#x.", - list_item->sensor_name, IPMI_GET_SOL_ERR(err)); + INFO("ipmi plugin: sensor_read_handler: Removing sensor %s, " + "because it failed with RMCPP error %#x.", + list_item->sensor_name, IPMI_GET_SOL_ERR(err)); else - INFO ("ipmi plugin: sensor_read_handler: Removing sensor %s, " - "because it failed with error %#x. of class %#x", - list_item->sensor_name, err & 0xff, err & 0xffffff00); - sensor_list_remove (sensor); + INFO("ipmi plugin: sensor_read_handler: Removing sensor %s, " + "because it failed with error %#x. of class %#x", + list_item->sensor_name, err & 0xff, err & 0xffffff00); + sensor_list_remove(sensor); } return; - } - else if (list_item->sensor_not_present == 1) - { + } else if (list_item->sensor_not_present == 1) { list_item->sensor_not_present = 0; - INFO ("ipmi plugin: sensor_read_handler: sensor %s present.", - list_item->sensor_name); + INFO("ipmi plugin: sensor_read_handler: sensor %s present.", + list_item->sensor_name); - if (c_ipmi_nofiy_notpresent) - { - notification_t n = { NOTIF_OKAY, cdtime (), "", "", "ipmi", - "", "", "", NULL }; + if (c_ipmi_nofiy_notpresent) { + notification_t n = {NOTIF_OKAY, cdtime(), "", "", "ipmi", + "", "", "", NULL}; - sstrncpy (n.host, hostname_g, sizeof (n.host)); - sstrncpy (n.type_instance, list_item->sensor_name, - sizeof (n.type_instance)); - sstrncpy (n.type, list_item->sensor_type, sizeof (n.type)); - ssnprintf (n.message, sizeof (n.message), - "sensor %s present", list_item->sensor_name); + sstrncpy(n.host, hostname_g, sizeof(n.host)); + sstrncpy(n.type_instance, list_item->sensor_name, + sizeof(n.type_instance)); + sstrncpy(n.type, list_item->sensor_type, sizeof(n.type)); + ssnprintf(n.message, sizeof(n.message), "sensor %s present", + list_item->sensor_name); - plugin_dispatch_notification (&n); + plugin_dispatch_notification(&n); } } - if (value_present != IPMI_BOTH_VALUES_PRESENT) - { - INFO ("ipmi plugin: sensor_read_handler: Removing sensor %s, " - "because it provides %s. If you need this sensor, " - "please file a bug report.", - list_item->sensor_name, - (value_present == IPMI_RAW_VALUE_PRESENT) - ? "only the raw value" - : "no value"); - sensor_list_remove (sensor); + if (value_present != IPMI_BOTH_VALUES_PRESENT) { + INFO("ipmi plugin: sensor_read_handler: Removing sensor %s, " + "because it provides %s. If you need this sensor, " + "please file a bug report.", + list_item->sensor_name, + (value_present == IPMI_RAW_VALUE_PRESENT) ? "only the raw value" + : "no value"); + sensor_list_remove(sensor); return; } - vl.values = &(value_t) { .gauge = value }; + vl.values = &(value_t){.gauge = value}; vl.values_len = 1; - sstrncpy (vl.plugin, "ipmi", sizeof (vl.plugin)); - sstrncpy (vl.type, list_item->sensor_type, sizeof (vl.type)); - sstrncpy (vl.type_instance, list_item->sensor_name, sizeof (vl.type_instance)); + sstrncpy(vl.plugin, "ipmi", sizeof(vl.plugin)); + sstrncpy(vl.type, list_item->sensor_type, sizeof(vl.type)); + sstrncpy(vl.type_instance, list_item->sensor_name, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* void sensor_read_handler */ -static int sensor_list_add (ipmi_sensor_t *sensor) -{ +static int sensor_list_add(ipmi_sensor_t *sensor) { ipmi_sensor_id_t sensor_id; c_ipmi_sensor_list_t *list_item; c_ipmi_sensor_list_t *list_prev; - char buffer[DATA_MAX_NAME_LEN] = { 0 }; + char buffer[DATA_MAX_NAME_LEN] = {0}; const char *entity_id_string; char sensor_name[DATA_MAX_NAME_LEN]; char *sensor_name_ptr; @@ -237,23 +213,22 @@ static int sensor_list_add (ipmi_sensor_t *sensor) const char *type; ipmi_entity_t *ent = ipmi_sensor_get_entity(sensor); - sensor_id = ipmi_sensor_convert_to_id (sensor); + sensor_id = ipmi_sensor_convert_to_id(sensor); - ipmi_sensor_get_name (sensor, buffer, sizeof (buffer)); - buffer[sizeof (buffer) - 1] = 0; + ipmi_sensor_get_name(sensor, buffer, sizeof(buffer)); + buffer[sizeof(buffer) - 1] = 0; - entity_id_string = ipmi_entity_get_entity_id_string (ent); + entity_id_string = ipmi_entity_get_entity_id_string(ent); if (entity_id_string == NULL) - sstrncpy (sensor_name, buffer, sizeof (sensor_name)); + sstrncpy(sensor_name, buffer, sizeof(sensor_name)); else - ssnprintf (sensor_name, sizeof (sensor_name), - "%s %s", buffer, entity_id_string); + ssnprintf(sensor_name, sizeof(sensor_name), "%s %s", buffer, + entity_id_string); - sstrncpy (buffer, sensor_name, sizeof (buffer)); - sensor_name_ptr = strstr (buffer, ")."); - if (sensor_name_ptr != NULL) - { + sstrncpy(buffer, sensor_name, sizeof(buffer)); + sensor_name_ptr = strstr(buffer, ")."); + if (sensor_name_ptr != NULL) { /* If name is something like "foo (123).bar", * change that to "bar (123)". * Both, sensor_name_ptr and sensor_id_ptr point to memory within the @@ -266,134 +241,120 @@ static int sensor_list_add (ipmi_sensor_t *sensor) sensor_name_ptr += 2; /* `sensor_name_ptr' now points to "bar". */ - sensor_id_ptr = strstr (buffer, "("); - if (sensor_id_ptr != NULL) - { + sensor_id_ptr = strstr(buffer, "("); + if (sensor_id_ptr != NULL) { /* `sensor_id_ptr' now points to "(123)". */ - ssnprintf (sensor_name, sizeof (sensor_name), - "%s %s", sensor_name_ptr, sensor_id_ptr); + ssnprintf(sensor_name, sizeof(sensor_name), "%s %s", sensor_name_ptr, + sensor_id_ptr); } /* else: don't touch sensor_name. */ } sensor_name_ptr = sensor_name; /* Both `ignorelist' and `plugin_instance' may be NULL. */ - if (ignorelist_match (ignorelist, sensor_name_ptr) != 0) + if (ignorelist_match(ignorelist, sensor_name_ptr) != 0) return (0); /* FIXME: Use rate unit or base unit to scale the value */ - sensor_type = ipmi_sensor_get_sensor_type (sensor); - switch (sensor_type) - { - case IPMI_SENSOR_TYPE_TEMPERATURE: - type = "temperature"; - break; + sensor_type = ipmi_sensor_get_sensor_type(sensor); + switch (sensor_type) { + case IPMI_SENSOR_TYPE_TEMPERATURE: + type = "temperature"; + break; - case IPMI_SENSOR_TYPE_VOLTAGE: - type = "voltage"; - break; + case IPMI_SENSOR_TYPE_VOLTAGE: + type = "voltage"; + break; - case IPMI_SENSOR_TYPE_CURRENT: - type = "current"; - break; + case IPMI_SENSOR_TYPE_CURRENT: + type = "current"; + break; - case IPMI_SENSOR_TYPE_FAN: - type = "fanspeed"; - break; + case IPMI_SENSOR_TYPE_FAN: + type = "fanspeed"; + break; - default: - { - const char *sensor_type_str; + default: { + const char *sensor_type_str; - sensor_type_str = ipmi_sensor_get_sensor_type_string (sensor); - INFO ("ipmi plugin: sensor_list_add: Ignore sensor %s, " - "because I don't know how to handle its type (%#x, %s). " - "If you need this sensor, please file a bug report.", - sensor_name_ptr, sensor_type, sensor_type_str); - return (-1); - } + sensor_type_str = ipmi_sensor_get_sensor_type_string(sensor); + INFO("ipmi plugin: sensor_list_add: Ignore sensor %s, " + "because I don't know how to handle its type (%#x, %s). " + "If you need this sensor, please file a bug report.", + sensor_name_ptr, sensor_type, sensor_type_str); + return (-1); + } } /* switch (sensor_type) */ - pthread_mutex_lock (&sensor_list_lock); + pthread_mutex_lock(&sensor_list_lock); list_prev = NULL; - for (list_item = sensor_list; - list_item != NULL; - list_item = list_item->next) - { - if (ipmi_cmp_sensor_id (sensor_id, list_item->sensor_id) == 0) + for (list_item = sensor_list; list_item != NULL; + list_item = list_item->next) { + if (ipmi_cmp_sensor_id(sensor_id, list_item->sensor_id) == 0) break; list_prev = list_item; } /* for (list_item) */ - if (list_item != NULL) - { - pthread_mutex_unlock (&sensor_list_lock); + if (list_item != NULL) { + pthread_mutex_unlock(&sensor_list_lock); return (0); } - list_item = (c_ipmi_sensor_list_t *) calloc (1, sizeof (c_ipmi_sensor_list_t)); - if (list_item == NULL) - { - pthread_mutex_unlock (&sensor_list_lock); + list_item = (c_ipmi_sensor_list_t *)calloc(1, sizeof(c_ipmi_sensor_list_t)); + if (list_item == NULL) { + pthread_mutex_unlock(&sensor_list_lock); return (-1); } - list_item->sensor_id = ipmi_sensor_convert_to_id (sensor); + list_item->sensor_id = ipmi_sensor_convert_to_id(sensor); if (list_prev != NULL) list_prev->next = list_item; else sensor_list = list_item; - sstrncpy (list_item->sensor_name, sensor_name_ptr, - sizeof (list_item->sensor_name)); - sstrncpy (list_item->sensor_type, type, sizeof (list_item->sensor_type)); + sstrncpy(list_item->sensor_name, sensor_name_ptr, + sizeof(list_item->sensor_name)); + sstrncpy(list_item->sensor_type, type, sizeof(list_item->sensor_type)); - pthread_mutex_unlock (&sensor_list_lock); + pthread_mutex_unlock(&sensor_list_lock); - if (c_ipmi_nofiy_add && (c_ipmi_init_in_progress == 0)) - { - notification_t n = { NOTIF_OKAY, cdtime (), "", "", "ipmi", - "", "", "", NULL }; + if (c_ipmi_nofiy_add && (c_ipmi_init_in_progress == 0)) { + notification_t n = {NOTIF_OKAY, cdtime(), "", "", "ipmi", "", "", "", NULL}; - sstrncpy (n.host, hostname_g, sizeof (n.host)); - sstrncpy (n.type_instance, list_item->sensor_name, - sizeof (n.type_instance)); - sstrncpy (n.type, list_item->sensor_type, sizeof (n.type)); - ssnprintf (n.message, sizeof (n.message), - "sensor %s added", list_item->sensor_name); + sstrncpy(n.host, hostname_g, sizeof(n.host)); + sstrncpy(n.type_instance, list_item->sensor_name, sizeof(n.type_instance)); + sstrncpy(n.type, list_item->sensor_type, sizeof(n.type)); + ssnprintf(n.message, sizeof(n.message), "sensor %s added", + list_item->sensor_name); - plugin_dispatch_notification (&n); + plugin_dispatch_notification(&n); } return (0); } /* int sensor_list_add */ -static int sensor_list_remove (ipmi_sensor_t *sensor) -{ +static int sensor_list_remove(ipmi_sensor_t *sensor) { ipmi_sensor_id_t sensor_id; c_ipmi_sensor_list_t *list_item; c_ipmi_sensor_list_t *list_prev; - sensor_id = ipmi_sensor_convert_to_id (sensor); + sensor_id = ipmi_sensor_convert_to_id(sensor); - pthread_mutex_lock (&sensor_list_lock); + pthread_mutex_lock(&sensor_list_lock); list_prev = NULL; - for (list_item = sensor_list; - list_item != NULL; - list_item = list_item->next) - { - if (ipmi_cmp_sensor_id (sensor_id, list_item->sensor_id) == 0) + for (list_item = sensor_list; list_item != NULL; + list_item = list_item->next) { + if (ipmi_cmp_sensor_id(sensor_id, list_item->sensor_id) == 0) break; list_prev = list_item; } /* for (list_item) */ - if (list_item == NULL) - { - pthread_mutex_unlock (&sensor_list_lock); + if (list_item == NULL) { + pthread_mutex_unlock(&sensor_list_lock); return (-1); } @@ -405,60 +366,53 @@ static int sensor_list_remove (ipmi_sensor_t *sensor) list_prev = NULL; list_item->next = NULL; - pthread_mutex_unlock (&sensor_list_lock); + pthread_mutex_unlock(&sensor_list_lock); - if (c_ipmi_nofiy_remove && c_ipmi_active) - { - notification_t n = { NOTIF_WARNING, cdtime (), "", "", - "ipmi", "", "", "", NULL }; + if (c_ipmi_nofiy_remove && c_ipmi_active) { + notification_t n = {NOTIF_WARNING, cdtime(), "", "", "ipmi", "", "", "", + NULL}; - sstrncpy (n.host, hostname_g, sizeof (n.host)); - sstrncpy (n.type_instance, list_item->sensor_name, - sizeof (n.type_instance)); - sstrncpy (n.type, list_item->sensor_type, sizeof (n.type)); - ssnprintf (n.message, sizeof (n.message), - "sensor %s removed", list_item->sensor_name); + sstrncpy(n.host, hostname_g, sizeof(n.host)); + sstrncpy(n.type_instance, list_item->sensor_name, sizeof(n.type_instance)); + sstrncpy(n.type, list_item->sensor_type, sizeof(n.type)); + ssnprintf(n.message, sizeof(n.message), "sensor %s removed", + list_item->sensor_name); - plugin_dispatch_notification (&n); + plugin_dispatch_notification(&n); } - free (list_item); + free(list_item); return (0); } /* int sensor_list_remove */ -static int sensor_list_read_all (void) -{ - pthread_mutex_lock (&sensor_list_lock); +static int sensor_list_read_all(void) { + pthread_mutex_lock(&sensor_list_lock); - for (c_ipmi_sensor_list_t *list_item = sensor_list; - list_item != NULL; - list_item = list_item->next) - { - ipmi_sensor_id_get_reading (list_item->sensor_id, - sensor_read_handler, /* user data = */ list_item); + for (c_ipmi_sensor_list_t *list_item = sensor_list; list_item != NULL; + list_item = list_item->next) { + ipmi_sensor_id_get_reading(list_item->sensor_id, sensor_read_handler, + /* user data = */ list_item); } /* for (list_item) */ - pthread_mutex_unlock (&sensor_list_lock); + pthread_mutex_unlock(&sensor_list_lock); return (0); } /* int sensor_list_read_all */ -static int sensor_list_remove_all (void) -{ +static int sensor_list_remove_all(void) { c_ipmi_sensor_list_t *list_item; - pthread_mutex_lock (&sensor_list_lock); + pthread_mutex_lock(&sensor_list_lock); list_item = sensor_list; sensor_list = NULL; - pthread_mutex_unlock (&sensor_list_lock); + pthread_mutex_unlock(&sensor_list_lock); - while (list_item != NULL) - { + while (list_item != NULL) { c_ipmi_sensor_list_t *list_next = list_item->next; - free (list_item); + free(list_item); list_item = list_next; } /* while (list_item) */ @@ -469,117 +423,92 @@ static int sensor_list_remove_all (void) /* * Entity handlers */ -static void entity_sensor_update_handler (enum ipmi_update_e op, - ipmi_entity_t __attribute__((unused)) *entity, - ipmi_sensor_t *sensor, - void __attribute__((unused)) *user_data) -{ +static void entity_sensor_update_handler( + enum ipmi_update_e op, ipmi_entity_t __attribute__((unused)) * entity, + ipmi_sensor_t *sensor, void __attribute__((unused)) * user_data) { /* TODO: Ignore sensors we cannot read */ - if ((op == IPMI_ADDED) || (op == IPMI_CHANGED)) - { + if ((op == IPMI_ADDED) || (op == IPMI_CHANGED)) { /* Will check for duplicate entries.. */ - sensor_list_add (sensor); - } - else if (op == IPMI_DELETED) - { - sensor_list_remove (sensor); + sensor_list_add(sensor); + } else if (op == IPMI_DELETED) { + sensor_list_remove(sensor); } } /* void entity_sensor_update_handler */ /* * Domain handlers */ -static void domain_entity_update_handler (enum ipmi_update_e op, - ipmi_domain_t __attribute__((unused)) *domain, - ipmi_entity_t *entity, - void __attribute__((unused)) *user_data) -{ +static void domain_entity_update_handler( + enum ipmi_update_e op, ipmi_domain_t __attribute__((unused)) * domain, + ipmi_entity_t *entity, void __attribute__((unused)) * user_data) { int status; - if (op == IPMI_ADDED) - { - status = ipmi_entity_add_sensor_update_handler (entity, - entity_sensor_update_handler, /* user data = */ NULL); - if (status != 0) - { - c_ipmi_error ("ipmi_entity_add_sensor_update_handler", status); + if (op == IPMI_ADDED) { + status = ipmi_entity_add_sensor_update_handler( + entity, entity_sensor_update_handler, /* user data = */ NULL); + if (status != 0) { + c_ipmi_error("ipmi_entity_add_sensor_update_handler", status); } - } - else if (op == IPMI_DELETED) - { - status = ipmi_entity_remove_sensor_update_handler (entity, - entity_sensor_update_handler, /* user data = */ NULL); - if (status != 0) - { - c_ipmi_error ("ipmi_entity_remove_sensor_update_handler", status); + } else if (op == IPMI_DELETED) { + status = ipmi_entity_remove_sensor_update_handler( + entity, entity_sensor_update_handler, /* user data = */ NULL); + if (status != 0) { + c_ipmi_error("ipmi_entity_remove_sensor_update_handler", status); } } } /* void domain_entity_update_handler */ -static void domain_connection_change_handler (ipmi_domain_t *domain, - int err, - unsigned int conn_num, - unsigned int port_num, - int still_connected, - void *user_data) -{ +static void domain_connection_change_handler(ipmi_domain_t *domain, int err, + unsigned int conn_num, + unsigned int port_num, + int still_connected, + void *user_data) { int status; - DEBUG ("domain_connection_change_handler (domain = %p, err = %i, " - "conn_num = %u, port_num = %u, still_connected = %i, " - "user_data = %p);\n", - (void *) domain, err, conn_num, port_num, still_connected, user_data); + DEBUG("domain_connection_change_handler (domain = %p, err = %i, " + "conn_num = %u, port_num = %u, still_connected = %i, " + "user_data = %p);\n", + (void *)domain, err, conn_num, port_num, still_connected, user_data); - status = ipmi_domain_add_entity_update_handler (domain, - domain_entity_update_handler, /* user data = */ NULL); - if (status != 0) - { - c_ipmi_error ("ipmi_domain_add_entity_update_handler", status); + status = ipmi_domain_add_entity_update_handler( + domain, domain_entity_update_handler, /* user data = */ NULL); + if (status != 0) { + c_ipmi_error("ipmi_domain_add_entity_update_handler", status); } } /* void domain_connection_change_handler */ -static int thread_init (os_handler_t **ret_os_handler) -{ +static int thread_init(os_handler_t **ret_os_handler) { os_handler_t *os_handler; ipmi_con_t *smi_connection = NULL; ipmi_domain_id_t domain_id; int status; - os_handler = ipmi_posix_thread_setup_os_handler (SIGIO); - if (os_handler == NULL) - { - ERROR ("ipmi plugin: ipmi_posix_thread_setup_os_handler failed."); + os_handler = ipmi_posix_thread_setup_os_handler(SIGIO); + if (os_handler == NULL) { + ERROR("ipmi plugin: ipmi_posix_thread_setup_os_handler failed."); return (-1); } - ipmi_init (os_handler); + ipmi_init(os_handler); - status = ipmi_smi_setup_con (/* if_num = */ 0, - os_handler, - /* user data = */ NULL, - &smi_connection); - if (status != 0) - { - c_ipmi_error ("ipmi_smi_setup_con", status); + status = ipmi_smi_setup_con(/* if_num = */ 0, os_handler, + /* user data = */ NULL, &smi_connection); + if (status != 0) { + c_ipmi_error("ipmi_smi_setup_con", status); return (-1); } - ipmi_open_option_t open_option[1] = { - [0] = { - .option = IPMI_OPEN_OPTION_ALL, - { .ival = 1 } - } - }; + ipmi_open_option_t open_option[1] = {[0] = {.option = IPMI_OPEN_OPTION_ALL, + {.ival = 1}}}; - status = ipmi_open_domain ("mydomain", &smi_connection, /* num_con = */ 1, + status = ipmi_open_domain( + "mydomain", &smi_connection, /* num_con = */ 1, domain_connection_change_handler, /* user data = */ NULL, - /* domain_fully_up_handler = */ NULL, /* user data = */ NULL, - open_option, sizeof (open_option) / sizeof (open_option[0]), - &domain_id); - if (status != 0) - { - c_ipmi_error ("ipmi_open_domain", status); + /* domain_fully_up_handler = */ NULL, /* user data = */ NULL, open_option, + sizeof(open_option) / sizeof(open_option[0]), &domain_id); + if (status != 0) { + c_ipmi_error("ipmi_open_domain", status); return (-1); } @@ -587,102 +516,83 @@ static int thread_init (os_handler_t **ret_os_handler) return (0); } /* int thread_init */ -static void *thread_main (void __attribute__((unused)) *user_data) -{ +static void *thread_main(void __attribute__((unused)) * user_data) { int status; os_handler_t *os_handler = NULL; - status = thread_init (&os_handler); - if (status != 0) - { - ERROR ("ipmi plugin: thread_init failed.\n"); - return ((void *) -1); + status = thread_init(&os_handler); + if (status != 0) { + ERROR("ipmi plugin: thread_init failed.\n"); + return ((void *)-1); } - while (c_ipmi_active != 0) - { - struct timeval tv = { 1, 0 }; - os_handler->perform_one_op (os_handler, &tv); + while (c_ipmi_active != 0) { + struct timeval tv = {1, 0}; + os_handler->perform_one_op(os_handler, &tv); } - ipmi_posix_thread_free_os_handler (os_handler); + ipmi_posix_thread_free_os_handler(os_handler); - return ((void *) 0); + return ((void *)0); } /* void *thread_main */ -static int c_ipmi_config (const char *key, const char *value) -{ +static int c_ipmi_config(const char *key, const char *value) { if (ignorelist == NULL) - ignorelist = ignorelist_create (/* invert = */ 1); + ignorelist = ignorelist_create(/* invert = */ 1); if (ignorelist == NULL) return (1); - if (strcasecmp ("Sensor", key) == 0) - { - ignorelist_add (ignorelist, value); - } - else if (strcasecmp ("IgnoreSelected", key) == 0) - { + if (strcasecmp("Sensor", key) == 0) { + ignorelist_add(ignorelist, value); + } else if (strcasecmp("IgnoreSelected", key) == 0) { int invert = 1; - if (IS_TRUE (value)) + if (IS_TRUE(value)) invert = 0; - ignorelist_set_invert (ignorelist, invert); - } - else if (strcasecmp ("NotifySensorAdd", key) == 0) - { - if (IS_TRUE (value)) + ignorelist_set_invert(ignorelist, invert); + } else if (strcasecmp("NotifySensorAdd", key) == 0) { + if (IS_TRUE(value)) c_ipmi_nofiy_add = 1; - } - else if (strcasecmp ("NotifySensorRemove", key) == 0) - { - if (IS_TRUE (value)) + } else if (strcasecmp("NotifySensorRemove", key) == 0) { + if (IS_TRUE(value)) c_ipmi_nofiy_remove = 1; - } - else if (strcasecmp ("NotifySensorNotPresent", key) == 0) - { - if (IS_TRUE (value)) + } else if (strcasecmp("NotifySensorNotPresent", key) == 0) { + if (IS_TRUE(value)) c_ipmi_nofiy_notpresent = 1; - } - else - { + } else { return (-1); } return (0); } /* int c_ipmi_config */ -static int c_ipmi_init (void) -{ +static int c_ipmi_init(void) { int status; /* Don't send `ADD' notifications during startup (~ 1 minute) */ - time_t iv = CDTIME_T_TO_TIME_T (plugin_get_interval ()); + time_t iv = CDTIME_T_TO_TIME_T(plugin_get_interval()); c_ipmi_init_in_progress = 1 + (60 / iv); c_ipmi_active = 1; - status = plugin_thread_create (&thread_id, /* attr = */ NULL, thread_main, - /* user data = */ NULL, "ipmi"); - if (status != 0) - { + status = plugin_thread_create(&thread_id, /* attr = */ NULL, thread_main, + /* user data = */ NULL, "ipmi"); + if (status != 0) { c_ipmi_active = 0; - thread_id = (pthread_t) 0; - ERROR ("ipmi plugin: pthread_create failed."); + thread_id = (pthread_t)0; + ERROR("ipmi plugin: pthread_create failed."); return (-1); } return (0); } /* int c_ipmi_init */ -static int c_ipmi_read (void) -{ - if ((c_ipmi_active == 0) || (thread_id == (pthread_t) 0)) - { - INFO ("ipmi plugin: c_ipmi_read: I'm not active, returning false."); +static int c_ipmi_read(void) { + if ((c_ipmi_active == 0) || (thread_id == (pthread_t)0)) { + INFO("ipmi plugin: c_ipmi_read: I'm not active, returning false."); return (-1); } - sensor_list_read_all (); + sensor_list_read_all(); if (c_ipmi_init_in_progress > 0) c_ipmi_init_in_progress--; @@ -692,28 +602,24 @@ static int c_ipmi_read (void) return (0); } /* int c_ipmi_read */ -static int c_ipmi_shutdown (void) -{ +static int c_ipmi_shutdown(void) { c_ipmi_active = 0; - if (thread_id != (pthread_t) 0) - { - pthread_join (thread_id, NULL); - thread_id = (pthread_t) 0; + if (thread_id != (pthread_t)0) { + pthread_join(thread_id, NULL); + thread_id = (pthread_t)0; } - sensor_list_remove_all (); + sensor_list_remove_all(); return (0); } /* int c_ipmi_shutdown */ -void module_register (void) -{ - plugin_register_config ("ipmi", c_ipmi_config, - config_keys, config_keys_num); - plugin_register_init ("ipmi", c_ipmi_init); - plugin_register_read ("ipmi", c_ipmi_read); - plugin_register_shutdown ("ipmi", c_ipmi_shutdown); +void module_register(void) { + plugin_register_config("ipmi", c_ipmi_config, config_keys, config_keys_num); + plugin_register_init("ipmi", c_ipmi_init); + plugin_register_read("ipmi", c_ipmi_read); + plugin_register_shutdown("ipmi", c_ipmi_shutdown); } /* void module_register */ /* vim: set sw=2 sts=2 ts=8 fdm=marker et : */ diff --git a/src/iptables.c b/src/iptables.c index 657b6ba0..bf17cfbd 100644 --- a/src/iptables.c +++ b/src/iptables.c @@ -29,11 +29,11 @@ #include "common.h" #include "plugin.h" -#include #include +#include #ifdef HAVE_SYS_CAPABILITY_H -# include +#include #endif /* @@ -63,463 +63,385 @@ typedef struct ip6tc_handle ip6tc_handle_t; * Config format should be `Chain table chainname', * e. g. `Chain mangle incoming' */ -static const char *config_keys[] = -{ - "Chain", - "Chain6" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); -enum protocol_version_e -{ - IPV4, - IPV6 -}; +static const char *config_keys[] = {"Chain", "Chain6"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); +enum protocol_version_e { IPV4, IPV6 }; typedef enum protocol_version_e protocol_version_t; /* * Each table/chain combo that will be queried goes into this list */ #ifndef XT_TABLE_MAXNAMELEN -# define XT_TABLE_MAXNAMELEN 32 +#define XT_TABLE_MAXNAMELEN 32 #endif typedef struct { - protocol_version_t ip_version; - char table[XT_TABLE_MAXNAMELEN]; - char chain[XT_TABLE_MAXNAMELEN]; - union - { - int num; - char *comment; - } rule; - enum - { - RTYPE_NUM, - RTYPE_COMMENT, - RTYPE_COMMENT_ALL - } rule_type; - char name[64]; + protocol_version_t ip_version; + char table[XT_TABLE_MAXNAMELEN]; + char chain[XT_TABLE_MAXNAMELEN]; + union { + int num; + char *comment; + } rule; + enum { RTYPE_NUM, RTYPE_COMMENT, RTYPE_COMMENT_ALL } rule_type; + char name[64]; } ip_chain_t; static ip_chain_t **chain_list = NULL; static int chain_num = 0; -static int iptables_config (const char *key, const char *value) -{ - /* int ip_value; */ - protocol_version_t ip_version = 0; - - if (strcasecmp (key, "Chain") == 0) - ip_version = IPV4; - else if (strcasecmp (key, "Chain6") == 0) - ip_version = IPV6; - else - return (1); - - ip_chain_t temp = { 0 }; - ip_chain_t *final, **list; - char *table; - int table_len; - char *chain; - int chain_len; - - char *value_copy; - char *fields[4]; - int fields_num; - - value_copy = strdup (value); - if (value_copy == NULL) - { - char errbuf[1024]; - ERROR ("strdup failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (1); - } - - /* - * Time to fill the temp element - * Examine value string, it should look like: - * Chain[6] [ [name]] - */ - - /* set IPv4 or IPv6 */ - temp.ip_version = ip_version; - - /* Chain
[ [name]] */ - fields_num = strsplit (value_copy, fields, 4); - if (fields_num < 2) - { - free (value_copy); - return (1); - } - - table = fields[0]; - chain = fields[1]; - - table_len = strlen (table) + 1; - if ((unsigned int)table_len > sizeof(temp.table)) - { - ERROR ("Table `%s' too long.", table); - free (value_copy); +static int iptables_config(const char *key, const char *value) { + /* int ip_value; */ + protocol_version_t ip_version = 0; + + if (strcasecmp(key, "Chain") == 0) + ip_version = IPV4; + else if (strcasecmp(key, "Chain6") == 0) + ip_version = IPV6; + else + return (1); + + ip_chain_t temp = {0}; + ip_chain_t * final, **list; + char *table; + int table_len; + char *chain; + int chain_len; + + char *value_copy; + char *fields[4]; + int fields_num; + + value_copy = strdup(value); + if (value_copy == NULL) { + char errbuf[1024]; + ERROR("strdup failed: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + return (1); + } + + /* + * Time to fill the temp element + * Examine value string, it should look like: + * Chain[6]
[ [name]] + */ + + /* set IPv4 or IPv6 */ + temp.ip_version = ip_version; + + /* Chain
[ [name]] */ + fields_num = strsplit(value_copy, fields, 4); + if (fields_num < 2) { + free(value_copy); + return (1); + } + + table = fields[0]; + chain = fields[1]; + + table_len = strlen(table) + 1; + if ((unsigned int)table_len > sizeof(temp.table)) { + ERROR("Table `%s' too long.", table); + free(value_copy); + return (1); + } + sstrncpy(temp.table, table, table_len); + + chain_len = strlen(chain) + 1; + if ((unsigned int)chain_len > sizeof(temp.chain)) { + ERROR("Chain `%s' too long.", chain); + free(value_copy); + return (1); + } + sstrncpy(temp.chain, chain, chain_len); + + if (fields_num >= 3) { + char *comment = fields[2]; + int rule = atoi(comment); + + if (rule) { + temp.rule.num = rule; + temp.rule_type = RTYPE_NUM; + } else { + temp.rule.comment = strdup(comment); + if (temp.rule.comment == NULL) { + free(value_copy); return (1); + } + temp.rule_type = RTYPE_COMMENT; } - sstrncpy (temp.table, table, table_len); - - chain_len = strlen (chain) + 1; - if ((unsigned int)chain_len > sizeof(temp.chain)) - { - ERROR ("Chain `%s' too long.", chain); - free (value_copy); - return (1); - } - sstrncpy (temp.chain, chain, chain_len); - - if (fields_num >= 3) - { - char *comment = fields[2]; - int rule = atoi (comment); - - if (rule) - { - temp.rule.num = rule; - temp.rule_type = RTYPE_NUM; - } - else - { - temp.rule.comment = strdup (comment); - if (temp.rule.comment == NULL) - { - free (value_copy); - return (1); - } - temp.rule_type = RTYPE_COMMENT; - } - } - else - { - temp.rule_type = RTYPE_COMMENT_ALL; - } - - if (fields_num >= 4) - sstrncpy (temp.name, fields[3], sizeof (temp.name)); - - free (value_copy); - value_copy = NULL; - table = NULL; - chain = NULL; - - list = realloc (chain_list, (chain_num + 1) * sizeof (ip_chain_t *)); - if (list == NULL) - { - char errbuf[1024]; - ERROR ("realloc failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - sfree (temp.rule.comment); - return (1); - } - - chain_list = list; - final = malloc(sizeof (*final)); - if (final == NULL) - { - char errbuf[1024]; - ERROR ("malloc failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - sfree (temp.rule.comment); - return (1); - } - memcpy (final, &temp, sizeof (temp)); - chain_list[chain_num] = final; - chain_num++; - - DEBUG ("Chain #%i: table = %s; chain = %s;", chain_num, final->table, final->chain); - - return (0); + } else { + temp.rule_type = RTYPE_COMMENT_ALL; + } + + if (fields_num >= 4) + sstrncpy(temp.name, fields[3], sizeof(temp.name)); + + free(value_copy); + value_copy = NULL; + table = NULL; + chain = NULL; + + list = realloc(chain_list, (chain_num + 1) * sizeof(ip_chain_t *)); + if (list == NULL) { + char errbuf[1024]; + ERROR("realloc failed: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + sfree(temp.rule.comment); + return (1); + } + + chain_list = list; + final = malloc(sizeof(* final)); + if (final == NULL) { + char errbuf[1024]; + ERROR("malloc failed: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + sfree(temp.rule.comment); + return (1); + } + memcpy(final, &temp, sizeof(temp)); + chain_list[chain_num] = final; + chain_num++; + + DEBUG("Chain #%i: table = %s; chain = %s;", chain_num, final->table, + final->chain); + + return (0); } /* int iptables_config */ -static int submit6_match (const struct ip6t_entry_match *match, - const struct ip6t_entry *entry, - const ip_chain_t *chain, - int rule_num) -{ - int status; - value_list_t vl = VALUE_LIST_INIT; +static int submit6_match(const struct ip6t_entry_match *match, + const struct ip6t_entry *entry, + const ip_chain_t *chain, int rule_num) { + int status; + value_list_t vl = VALUE_LIST_INIT; + + /* Select the rules to collect */ + if (chain->rule_type == RTYPE_NUM) { + if (chain->rule.num != rule_num) + return (0); + } else { + if (strcmp(match->u.user.name, "comment") != 0) + return (0); + if ((chain->rule_type == RTYPE_COMMENT) && + (strcmp(chain->rule.comment, (char *)match->data) != 0)) + return (0); + } + + sstrncpy(vl.plugin, "ip6tables", sizeof(vl.plugin)); + + status = ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%s", + chain->table, chain->chain); + if ((status < 1) || ((unsigned int)status >= sizeof(vl.plugin_instance))) + return (0); - /* Select the rules to collect */ + if (chain->name[0] != '\0') { + sstrncpy(vl.type_instance, chain->name, sizeof(vl.type_instance)); + } else { if (chain->rule_type == RTYPE_NUM) - { - if (chain->rule.num != rule_num) - return (0); - } - else - { - if (strcmp (match->u.user.name, "comment") != 0) - return (0); - if ((chain->rule_type == RTYPE_COMMENT) - && (strcmp (chain->rule.comment, (char *) match->data) != 0)) - return (0); - } - - sstrncpy (vl.plugin, "ip6tables", sizeof (vl.plugin)); - - status = ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), - "%s-%s", chain->table, chain->chain); - if ((status < 1) || ((unsigned int)status >= sizeof (vl.plugin_instance))) - return (0); - - if (chain->name[0] != '\0') - { - sstrncpy (vl.type_instance, chain->name, sizeof (vl.type_instance)); - } + ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%i", + chain->rule.num); else - { - if (chain->rule_type == RTYPE_NUM) - ssnprintf (vl.type_instance, sizeof (vl.type_instance), - "%i", chain->rule.num); - else - sstrncpy (vl.type_instance, (char *) match->data, - sizeof (vl.type_instance)); - } + sstrncpy(vl.type_instance, (char *)match->data, sizeof(vl.type_instance)); + } - sstrncpy (vl.type, "ipt_bytes", sizeof (vl.type)); - vl.values = &(value_t) { .derive = (derive_t) entry->counters.bcnt }; - vl.values_len = 1; - plugin_dispatch_values (&vl); + sstrncpy(vl.type, "ipt_bytes", sizeof(vl.type)); + vl.values = &(value_t){.derive = (derive_t)entry->counters.bcnt}; + vl.values_len = 1; + plugin_dispatch_values(&vl); - sstrncpy (vl.type, "ipt_packets", sizeof (vl.type)); - vl.values = &(value_t) { .derive = (derive_t) entry->counters.pcnt }; - plugin_dispatch_values (&vl); + sstrncpy(vl.type, "ipt_packets", sizeof(vl.type)); + vl.values = &(value_t){.derive = (derive_t)entry->counters.pcnt}; + plugin_dispatch_values(&vl); - return (0); + return (0); } /* int submit6_match */ /* This needs to return `int' for IPT_MATCH_ITERATE to work. */ -static int submit_match (const struct ipt_entry_match *match, - const struct ipt_entry *entry, - const ip_chain_t *chain, - int rule_num) -{ - int status; - value_list_t vl = VALUE_LIST_INIT; - - /* Select the rules to collect */ - if (chain->rule_type == RTYPE_NUM) - { - if (chain->rule.num != rule_num) - return (0); - } - else - { - if (strcmp (match->u.user.name, "comment") != 0) - return (0); - if ((chain->rule_type == RTYPE_COMMENT) - && (strcmp (chain->rule.comment, (char *) match->data) != 0)) - return (0); - } - - sstrncpy (vl.plugin, "iptables", sizeof (vl.plugin)); - - status = ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), - "%s-%s", chain->table, chain->chain); - if ((status < 1) || ((unsigned int)status >= sizeof (vl.plugin_instance))) - return (0); +static int submit_match(const struct ipt_entry_match *match, + const struct ipt_entry *entry, const ip_chain_t *chain, + int rule_num) { + int status; + value_list_t vl = VALUE_LIST_INIT; + + /* Select the rules to collect */ + if (chain->rule_type == RTYPE_NUM) { + if (chain->rule.num != rule_num) + return (0); + } else { + if (strcmp(match->u.user.name, "comment") != 0) + return (0); + if ((chain->rule_type == RTYPE_COMMENT) && + (strcmp(chain->rule.comment, (char *)match->data) != 0)) + return (0); + } + + sstrncpy(vl.plugin, "iptables", sizeof(vl.plugin)); + + status = ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%s", + chain->table, chain->chain); + if ((status < 1) || ((unsigned int)status >= sizeof(vl.plugin_instance))) + return (0); - if (chain->name[0] != '\0') - { - sstrncpy (vl.type_instance, chain->name, sizeof (vl.type_instance)); - } + if (chain->name[0] != '\0') { + sstrncpy(vl.type_instance, chain->name, sizeof(vl.type_instance)); + } else { + if (chain->rule_type == RTYPE_NUM) + ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%i", + chain->rule.num); else - { - if (chain->rule_type == RTYPE_NUM) - ssnprintf (vl.type_instance, sizeof (vl.type_instance), - "%i", chain->rule.num); - else - sstrncpy (vl.type_instance, (char *) match->data, - sizeof (vl.type_instance)); - } + sstrncpy(vl.type_instance, (char *)match->data, sizeof(vl.type_instance)); + } - sstrncpy (vl.type, "ipt_bytes", sizeof (vl.type)); - vl.values = &(value_t) { .derive = (derive_t) entry->counters.bcnt }; - vl.values_len = 1; - plugin_dispatch_values (&vl); + sstrncpy(vl.type, "ipt_bytes", sizeof(vl.type)); + vl.values = &(value_t){.derive = (derive_t)entry->counters.bcnt}; + vl.values_len = 1; + plugin_dispatch_values(&vl); - sstrncpy (vl.type, "ipt_packets", sizeof (vl.type)); - vl.values = &(value_t) { .derive = (derive_t) entry->counters.pcnt }; - plugin_dispatch_values (&vl); + sstrncpy(vl.type, "ipt_packets", sizeof(vl.type)); + vl.values = &(value_t){.derive = (derive_t)entry->counters.pcnt}; + plugin_dispatch_values(&vl); - return (0); + return (0); } /* int submit_match */ - /* ipv6 submit_chain */ -static void submit6_chain (ip6tc_handle_t *handle, ip_chain_t *chain) -{ - const struct ip6t_entry *entry; - int rule_num; - - /* Find first rule for chain and use the iterate macro */ - entry = ip6tc_first_rule( chain->chain, handle ); - if (entry == NULL) - { - DEBUG ("ip6tc_first_rule failed: %s", ip6tc_strerror (errno)); - return; +static void submit6_chain(ip6tc_handle_t *handle, ip_chain_t *chain) { + const struct ip6t_entry *entry; + int rule_num; + + /* Find first rule for chain and use the iterate macro */ + entry = ip6tc_first_rule(chain->chain, handle); + if (entry == NULL) { + DEBUG("ip6tc_first_rule failed: %s", ip6tc_strerror(errno)); + return; + } + + rule_num = 1; + while (entry) { + if (chain->rule_type == RTYPE_NUM) { + submit6_match(NULL, entry, chain, rule_num); + } else { + IP6T_MATCH_ITERATE(entry, submit6_match, entry, chain, rule_num); } - rule_num = 1; - while (entry) - { - if (chain->rule_type == RTYPE_NUM) - { - submit6_match (NULL, entry, chain, rule_num); - } - else - { - IP6T_MATCH_ITERATE( entry, submit6_match, entry, chain, rule_num ); - } - - entry = ip6tc_next_rule( entry, handle ); - rule_num++; - } /* while (entry) */ + entry = ip6tc_next_rule(entry, handle); + rule_num++; + } /* while (entry) */ } - /* ipv4 submit_chain */ -static void submit_chain (iptc_handle_t *handle, ip_chain_t *chain) -{ - const struct ipt_entry *entry; - int rule_num; - - /* Find first rule for chain and use the iterate macro */ - entry = iptc_first_rule( chain->chain, handle ); - if (entry == NULL) - { - DEBUG ("iptc_first_rule failed: %s", iptc_strerror (errno)); - return; +static void submit_chain(iptc_handle_t *handle, ip_chain_t *chain) { + const struct ipt_entry *entry; + int rule_num; + + /* Find first rule for chain and use the iterate macro */ + entry = iptc_first_rule(chain->chain, handle); + if (entry == NULL) { + DEBUG("iptc_first_rule failed: %s", iptc_strerror(errno)); + return; + } + + rule_num = 1; + while (entry) { + if (chain->rule_type == RTYPE_NUM) { + submit_match(NULL, entry, chain, rule_num); + } else { + IPT_MATCH_ITERATE(entry, submit_match, entry, chain, rule_num); } - rule_num = 1; - while (entry) - { - if (chain->rule_type == RTYPE_NUM) - { - submit_match (NULL, entry, chain, rule_num); - } - else - { - IPT_MATCH_ITERATE( entry, submit_match, entry, chain, rule_num ); - } - - entry = iptc_next_rule( entry, handle ); - rule_num++; - } /* while (entry) */ + entry = iptc_next_rule(entry, handle); + rule_num++; + } /* while (entry) */ } +static int iptables_read(void) { + int num_failures = 0; + ip_chain_t *chain; -static int iptables_read (void) -{ - int num_failures = 0; - ip_chain_t *chain; + /* Init the iptc handle structure and query the correct table */ + for (int i = 0; i < chain_num; i++) { + chain = chain_list[i]; - /* Init the iptc handle structure and query the correct table */ - for (int i = 0; i < chain_num; i++) - { - chain = chain_list[i]; - - if (!chain) - { - DEBUG ("iptables plugin: chain == NULL"); - continue; - } + if (!chain) { + DEBUG("iptables plugin: chain == NULL"); + continue; + } - if ( chain->ip_version == IPV4 ) - { + if (chain->ip_version == IPV4) { #ifdef HAVE_IPTC_HANDLE_T - iptc_handle_t _handle; - iptc_handle_t *handle = &_handle; + iptc_handle_t _handle; + iptc_handle_t *handle = &_handle; - *handle = iptc_init (chain->table); + *handle = iptc_init(chain->table); #else - iptc_handle_t *handle; - handle = iptc_init (chain->table); + iptc_handle_t *handle; + handle = iptc_init(chain->table); #endif - if (!handle) - { - ERROR ("iptables plugin: iptc_init (%s) failed: %s", - chain->table, iptc_strerror (errno)); - num_failures++; - continue; - } - - submit_chain (handle, chain); - iptc_free (handle); - } - else if ( chain->ip_version == IPV6 ) - { + if (!handle) { + ERROR("iptables plugin: iptc_init (%s) failed: %s", chain->table, + iptc_strerror(errno)); + num_failures++; + continue; + } + + submit_chain(handle, chain); + iptc_free(handle); + } else if (chain->ip_version == IPV6) { #ifdef HAVE_IP6TC_HANDLE_T - ip6tc_handle_t _handle; - ip6tc_handle_t *handle = &_handle; + ip6tc_handle_t _handle; + ip6tc_handle_t *handle = &_handle; - *handle = ip6tc_init (chain->table); + *handle = ip6tc_init(chain->table); #else - ip6tc_handle_t *handle; - handle = ip6tc_init (chain->table); + ip6tc_handle_t *handle; + handle = ip6tc_init(chain->table); #endif - if (!handle) - { - ERROR ("iptables plugin: ip6tc_init (%s) failed: %s", - chain->table, ip6tc_strerror (errno)); - num_failures++; - continue; - } - - submit6_chain (handle, chain); - ip6tc_free (handle); - } - else - num_failures++; - } /* for (i = 0 .. chain_num) */ - - return ((num_failures < chain_num) ? 0 : -1); + if (!handle) { + ERROR("iptables plugin: ip6tc_init (%s) failed: %s", chain->table, + ip6tc_strerror(errno)); + num_failures++; + continue; + } + + submit6_chain(handle, chain); + ip6tc_free(handle); + } else + num_failures++; + } /* for (i = 0 .. chain_num) */ + + return ((num_failures < chain_num) ? 0 : -1); } /* int iptables_read */ -static int iptables_shutdown (void) -{ - for (int i = 0; i < chain_num; i++) - { - if ((chain_list[i] != NULL) && (chain_list[i]->rule_type == RTYPE_COMMENT)) - sfree (chain_list[i]->rule.comment); - sfree (chain_list[i]); - } - sfree (chain_list); +static int iptables_shutdown(void) { + for (int i = 0; i < chain_num; i++) { + if ((chain_list[i] != NULL) && (chain_list[i]->rule_type == RTYPE_COMMENT)) + sfree(chain_list[i]->rule.comment); + sfree(chain_list[i]); + } + sfree(chain_list); - return (0); + return (0); } /* int iptables_shutdown */ -static int iptables_init (void) -{ +static int iptables_init(void) { #if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_NET_ADMIN) - if (check_capability (CAP_NET_ADMIN) != 0) - { - if (getuid () == 0) - WARNING ("iptables plugin: Running collectd as root, but the " - "CAP_NET_ADMIN capability is missing. The plugin's read " - "function will probably fail. Is your init system dropping " - "capabilities?"); - else - WARNING ("iptables plugin: collectd doesn't have the CAP_NET_ADMIN " - "capability. If you don't want to run collectd as root, try " - "running \"setcap cap_net_admin=ep\" on the collectd binary."); - } + if (check_capability(CAP_NET_ADMIN) != 0) { + if (getuid() == 0) + WARNING("iptables plugin: Running collectd as root, but the " + "CAP_NET_ADMIN capability is missing. The plugin's read " + "function will probably fail. Is your init system dropping " + "capabilities?"); + else + WARNING("iptables plugin: collectd doesn't have the CAP_NET_ADMIN " + "capability. If you don't want to run collectd as root, try " + "running \"setcap cap_net_admin=ep\" on the collectd binary."); + } #endif - return (0); + return (0); } /* int iptables_init */ -void module_register (void) -{ - plugin_register_config ("iptables", iptables_config, - config_keys, config_keys_num); - plugin_register_init ("iptables", iptables_init); - plugin_register_read ("iptables", iptables_read); - plugin_register_shutdown ("iptables", iptables_shutdown); +void module_register(void) { + plugin_register_config("iptables", iptables_config, config_keys, + config_keys_num); + plugin_register_init("iptables", iptables_init); + plugin_register_read("iptables", iptables_read); + plugin_register_shutdown("iptables", iptables_shutdown); } /* void module_register */ - diff --git a/src/ipvs.c b/src/ipvs.c index 6bd868eb..2446bd13 100644 --- a/src/ipvs.c +++ b/src/ipvs.c @@ -32,27 +32,27 @@ #include "collectd.h" -#include "plugin.h" #include "common.h" +#include "plugin.h" #if HAVE_ARPA_INET_H -# include +#include #endif /* HAVE_ARPA_INET_H */ #if HAVE_NETINET_IN_H -# include +#include #endif /* HAVE_NETINET_IN_H */ /* this can probably only be found in the kernel sources */ #if HAVE_LINUX_IP_VS_H -# include +#include #elif HAVE_NET_IP_VS_H -# include +#include #elif HAVE_IP_VS_H -# include +#include #endif /* HAVE_IP_VS_H */ -#define log_err(...) ERROR ("ipvs: " __VA_ARGS__) -#define log_info(...) INFO ("ipvs: " __VA_ARGS__) +#define log_err(...) ERROR("ipvs: " __VA_ARGS__) +#define log_info(...) INFO("ipvs: " __VA_ARGS__) /* * private variables @@ -62,115 +62,111 @@ static int sockfd = -1; /* * libipvs API */ -static struct ip_vs_get_services *ipvs_get_services (void) -{ - struct ip_vs_getinfo ipvs_info; - struct ip_vs_get_services *ret; - - socklen_t len; - - len = sizeof (ipvs_info); - - if (0 != getsockopt (sockfd, IPPROTO_IP, IP_VS_SO_GET_INFO, - (void *)&ipvs_info, &len)) { - char errbuf[1024]; - log_err ("ip_vs_get_services: getsockopt() failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return NULL; - } - - len = sizeof (*ret) + - sizeof (struct ip_vs_service_entry) * ipvs_info.num_services; - - if (NULL == (ret = malloc (len))) { - log_err ("ipvs_get_services: Out of memory."); - exit (3); - } - - ret->num_services = ipvs_info.num_services; - - if (0 != getsockopt (sockfd, IPPROTO_IP, IP_VS_SO_GET_SERVICES, - (void *)ret, &len)) { - char errbuf[1024]; - log_err ("ipvs_get_services: getsockopt failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - - free(ret); - return NULL; - } - return ret; +static struct ip_vs_get_services *ipvs_get_services(void) { + struct ip_vs_getinfo ipvs_info; + struct ip_vs_get_services *ret; + + socklen_t len; + + len = sizeof(ipvs_info); + + if (0 != getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_INFO, (void *)&ipvs_info, + &len)) { + char errbuf[1024]; + log_err("ip_vs_get_services: getsockopt() failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return NULL; + } + + len = sizeof(*ret) + + sizeof(struct ip_vs_service_entry) * ipvs_info.num_services; + + if (NULL == (ret = malloc(len))) { + log_err("ipvs_get_services: Out of memory."); + exit(3); + } + + ret->num_services = ipvs_info.num_services; + + if (0 != getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_SERVICES, (void *)ret, + &len)) { + char errbuf[1024]; + log_err("ipvs_get_services: getsockopt failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + + free(ret); + return NULL; + } + return ret; } /* ipvs_get_services */ -static struct ip_vs_get_dests *ipvs_get_dests (struct ip_vs_service_entry *se) -{ - struct ip_vs_get_dests *ret; - socklen_t len; - - len = sizeof (*ret) + sizeof (struct ip_vs_dest_entry) * se->num_dests; - - if (NULL == (ret = malloc (len))) { - log_err ("ipvs_get_dests: Out of memory."); - exit (3); - } - - ret->fwmark = se->fwmark; - ret->protocol = se->protocol; - ret->addr = se->addr; - ret->port = se->port; - ret->num_dests = se->num_dests; - - if (0 != getsockopt (sockfd, IPPROTO_IP, IP_VS_SO_GET_DESTS, - (void *)ret, &len)) { - char errbuf[1024]; - log_err ("ipvs_get_dests: getsockopt() failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - free (ret); - return NULL; - } - return ret; +static struct ip_vs_get_dests *ipvs_get_dests(struct ip_vs_service_entry *se) { + struct ip_vs_get_dests *ret; + socklen_t len; + + len = sizeof(*ret) + sizeof(struct ip_vs_dest_entry) * se->num_dests; + + if (NULL == (ret = malloc(len))) { + log_err("ipvs_get_dests: Out of memory."); + exit(3); + } + + ret->fwmark = se->fwmark; + ret->protocol = se->protocol; + ret->addr = se->addr; + ret->port = se->port; + ret->num_dests = se->num_dests; + + if (0 != + getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_DESTS, (void *)ret, &len)) { + char errbuf[1024]; + log_err("ipvs_get_dests: getsockopt() failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + free(ret); + return NULL; + } + return ret; } /* ip_vs_get_dests */ /* * collectd plugin API and helper functions */ -static int cipvs_init (void) -{ - struct ip_vs_getinfo ipvs_info; - - socklen_t len; - - if (-1 == (sockfd = socket (AF_INET, SOCK_RAW, IPPROTO_RAW))) { - char errbuf[1024]; - log_err ("cipvs_init: socket() failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return -1; - } - - len = sizeof (ipvs_info); - - if (0 != getsockopt (sockfd, IPPROTO_IP, IP_VS_SO_GET_INFO, - (void *)&ipvs_info, &len)) { - char errbuf[1024]; - log_err ("cipvs_init: getsockopt() failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - close (sockfd); - sockfd = -1; - return -1; - } - - /* we need IPVS >= 1.1.4 */ - if (ipvs_info.version < ((1 << 16) + (1 << 8) + 4)) { - log_err ("cipvs_init: IPVS version too old (%d.%d.%d < %d.%d.%d)", - NVERSION (ipvs_info.version), 1, 1, 4); - close (sockfd); - sockfd = -1; - return -1; - } - else { - log_info ("Successfully connected to IPVS %d.%d.%d", - NVERSION (ipvs_info.version)); - } - return 0; +static int cipvs_init(void) { + struct ip_vs_getinfo ipvs_info; + + socklen_t len; + + if (-1 == (sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW))) { + char errbuf[1024]; + log_err("cipvs_init: socket() failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return -1; + } + + len = sizeof(ipvs_info); + + if (0 != getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_INFO, (void *)&ipvs_info, + &len)) { + char errbuf[1024]; + log_err("cipvs_init: getsockopt() failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(sockfd); + sockfd = -1; + return -1; + } + + /* we need IPVS >= 1.1.4 */ + if (ipvs_info.version < ((1 << 16) + (1 << 8) + 4)) { + log_err("cipvs_init: IPVS version too old (%d.%d.%d < %d.%d.%d)", + NVERSION(ipvs_info.version), 1, 1, 4); + close(sockfd); + sockfd = -1; + return -1; + } else { + log_info("Successfully connected to IPVS %d.%d.%d", + NVERSION(ipvs_info.version)); + } + return 0; } /* cipvs_init */ /* @@ -179,163 +175,151 @@ static int cipvs_init (void) */ /* plugin instance */ -static int get_pi (struct ip_vs_service_entry *se, char *pi, size_t size) -{ - struct in_addr addr; - int len = 0; - - if ((NULL == se) || (NULL == pi)) - return 0; - - addr.s_addr = se->addr; - - /* inet_ntoa() returns a pointer to a statically allocated buffer - * I hope non-glibc systems behave the same */ - len = ssnprintf (pi, size, "%s_%s%u", inet_ntoa (addr), - (se->protocol == IPPROTO_TCP) ? "TCP" : "UDP", - ntohs (se->port)); - - if ((0 > len) || (size <= ((size_t) len))) { - log_err ("plugin instance truncated: %s", pi); - return -1; - } - return 0; +static int get_pi(struct ip_vs_service_entry *se, char *pi, size_t size) { + struct in_addr addr; + int len = 0; + + if ((NULL == se) || (NULL == pi)) + return 0; + + addr.s_addr = se->addr; + + /* inet_ntoa() returns a pointer to a statically allocated buffer + * I hope non-glibc systems behave the same */ + len = + ssnprintf(pi, size, "%s_%s%u", inet_ntoa(addr), + (se->protocol == IPPROTO_TCP) ? "TCP" : "UDP", ntohs(se->port)); + + if ((0 > len) || (size <= ((size_t)len))) { + log_err("plugin instance truncated: %s", pi); + return -1; + } + return 0; } /* get_pi */ /* type instance */ -static int get_ti (struct ip_vs_dest_entry *de, char *ti, size_t size) -{ - struct in_addr addr; - int len = 0; - - if ((NULL == de) || (NULL == ti)) - return 0; - - addr.s_addr = de->addr; - - /* inet_ntoa() returns a pointer to a statically allocated buffer - * I hope non-glibc systems behave the same */ - len = ssnprintf (ti, size, "%s_%u", inet_ntoa (addr), - ntohs (de->port)); - - if ((0 > len) || (size <= ((size_t) len))) { - log_err ("type instance truncated: %s", ti); - return -1; - } - return 0; +static int get_ti(struct ip_vs_dest_entry *de, char *ti, size_t size) { + struct in_addr addr; + int len = 0; + + if ((NULL == de) || (NULL == ti)) + return 0; + + addr.s_addr = de->addr; + + /* inet_ntoa() returns a pointer to a statically allocated buffer + * I hope non-glibc systems behave the same */ + len = ssnprintf(ti, size, "%s_%u", inet_ntoa(addr), ntohs(de->port)); + + if ((0 > len) || (size <= ((size_t)len))) { + log_err("type instance truncated: %s", ti); + return -1; + } + return 0; } /* get_ti */ -static void cipvs_submit_connections (const char *pi, const char *ti, - derive_t value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void cipvs_submit_connections(const char *pi, const char *ti, + derive_t value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .derive = value }; - vl.values_len = 1; + vl.values = &(value_t){.derive = value}; + vl.values_len = 1; - sstrncpy (vl.plugin, "ipvs", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, pi, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, "connections", sizeof (vl.type)); - sstrncpy (vl.type_instance, (NULL != ti) ? ti : "total", - sizeof (vl.type_instance)); + sstrncpy(vl.plugin, "ipvs", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, pi, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "connections", sizeof(vl.type)); + sstrncpy(vl.type_instance, (NULL != ti) ? ti : "total", + sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); - return; + plugin_dispatch_values(&vl); + return; } /* cipvs_submit_connections */ -static void cipvs_submit_if (const char *pi, const char *t, const char *ti, - derive_t rx, derive_t tx) -{ - value_t values[] = { - { .derive = rx }, - { .derive = tx }, - }; - value_list_t vl = VALUE_LIST_INIT; - - vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - - sstrncpy (vl.plugin, "ipvs", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, pi, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, t, sizeof (vl.type)); - sstrncpy (vl.type_instance, (NULL != ti) ? ti : "total", - sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); - return; +static void cipvs_submit_if(const char *pi, const char *t, const char *ti, + derive_t rx, derive_t tx) { + value_t values[] = { + {.derive = rx}, {.derive = tx}, + }; + value_list_t vl = VALUE_LIST_INIT; + + vl.values = values; + vl.values_len = STATIC_ARRAY_SIZE(values); + + sstrncpy(vl.plugin, "ipvs", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, pi, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, t, sizeof(vl.type)); + sstrncpy(vl.type_instance, (NULL != ti) ? ti : "total", + sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); + return; } /* cipvs_submit_if */ -static void cipvs_submit_dest (const char *pi, struct ip_vs_dest_entry *de) -{ - struct ip_vs_stats_user stats = de->stats; +static void cipvs_submit_dest(const char *pi, struct ip_vs_dest_entry *de) { + struct ip_vs_stats_user stats = de->stats; - char ti[DATA_MAX_NAME_LEN]; + char ti[DATA_MAX_NAME_LEN]; - if (0 != get_ti (de, ti, sizeof (ti))) - return; + if (0 != get_ti(de, ti, sizeof(ti))) + return; - cipvs_submit_connections (pi, ti, stats.conns); - cipvs_submit_if (pi, "if_packets", ti, stats.inpkts, stats.outpkts); - cipvs_submit_if (pi, "if_octets", ti, stats.inbytes, stats.outbytes); - return; + cipvs_submit_connections(pi, ti, stats.conns); + cipvs_submit_if(pi, "if_packets", ti, stats.inpkts, stats.outpkts); + cipvs_submit_if(pi, "if_octets", ti, stats.inbytes, stats.outbytes); + return; } /* cipvs_submit_dest */ -static void cipvs_submit_service (struct ip_vs_service_entry *se) -{ - struct ip_vs_stats_user stats = se->stats; - struct ip_vs_get_dests *dests = ipvs_get_dests (se); +static void cipvs_submit_service(struct ip_vs_service_entry *se) { + struct ip_vs_stats_user stats = se->stats; + struct ip_vs_get_dests *dests = ipvs_get_dests(se); - char pi[DATA_MAX_NAME_LEN]; + char pi[DATA_MAX_NAME_LEN]; - if (0 != get_pi (se, pi, sizeof (pi))) - { - free (dests); - return; - } + if (0 != get_pi(se, pi, sizeof(pi))) { + free(dests); + return; + } - cipvs_submit_connections (pi, NULL, stats.conns); - cipvs_submit_if (pi, "if_packets", NULL, stats.inpkts, stats.outpkts); - cipvs_submit_if (pi, "if_octets", NULL, stats.inbytes, stats.outbytes); + cipvs_submit_connections(pi, NULL, stats.conns); + cipvs_submit_if(pi, "if_packets", NULL, stats.inpkts, stats.outpkts); + cipvs_submit_if(pi, "if_octets", NULL, stats.inbytes, stats.outbytes); - for (size_t i = 0; i < dests->num_dests; ++i) - cipvs_submit_dest (pi, &dests->entrytable[i]); + for (size_t i = 0; i < dests->num_dests; ++i) + cipvs_submit_dest(pi, &dests->entrytable[i]); - free (dests); - return; + free(dests); + return; } /* cipvs_submit_service */ -static int cipvs_read (void) -{ - struct ip_vs_get_services *services = NULL; +static int cipvs_read(void) { + struct ip_vs_get_services *services = NULL; - if (sockfd < 0) - return (-1); + if (sockfd < 0) + return (-1); - if (NULL == (services = ipvs_get_services ())) - return -1; + if (NULL == (services = ipvs_get_services())) + return -1; - for (size_t i = 0; i < services->num_services; ++i) - cipvs_submit_service (&services->entrytable[i]); + for (size_t i = 0; i < services->num_services; ++i) + cipvs_submit_service(&services->entrytable[i]); - free (services); - return 0; + free(services); + return 0; } /* cipvs_read */ -static int cipvs_shutdown (void) -{ - if (sockfd >= 0) - close (sockfd); - sockfd = -1; +static int cipvs_shutdown(void) { + if (sockfd >= 0) + close(sockfd); + sockfd = -1; - return 0; + return 0; } /* cipvs_shutdown */ -void module_register (void) -{ - plugin_register_init ("ipvs", cipvs_init); - plugin_register_read ("ipvs", cipvs_read); - plugin_register_shutdown ("ipvs", cipvs_shutdown); - return; +void module_register(void) { + plugin_register_init("ipvs", cipvs_init); + plugin_register_read("ipvs", cipvs_read); + plugin_register_shutdown("ipvs", cipvs_shutdown); + return; } /* module_register */ /* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/irq.c b/src/irq.c index 06c50ff3..371ba645 100644 --- a/src/irq.c +++ b/src/irq.c @@ -28,166 +28,147 @@ #include "utils_ignorelist.h" #if !KERNEL_LINUX -# error "No applicable input method." +#error "No applicable input method." #endif /* * (Module-)Global variables */ -static const char *config_keys[] = -{ - "Irq", - "IgnoreSelected" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"Irq", "IgnoreSelected"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static ignorelist_t *ignorelist = NULL; /* * Private functions */ -static int irq_config (const char *key, const char *value) -{ - if (ignorelist == NULL) - ignorelist = ignorelist_create (/* invert = */ 1); - - if (strcasecmp (key, "Irq") == 0) - { - ignorelist_add (ignorelist, value); - } - else if (strcasecmp (key, "IgnoreSelected") == 0) - { - int invert = 1; - if (IS_TRUE (value)) - invert = 0; - ignorelist_set_invert (ignorelist, invert); - } - else - { - return (-1); - } - - return (0); +static int irq_config(const char *key, const char *value) { + if (ignorelist == NULL) + ignorelist = ignorelist_create(/* invert = */ 1); + + if (strcasecmp(key, "Irq") == 0) { + ignorelist_add(ignorelist, value); + } else if (strcasecmp(key, "IgnoreSelected") == 0) { + int invert = 1; + if (IS_TRUE(value)) + invert = 0; + ignorelist_set_invert(ignorelist, invert); + } else { + return (-1); + } + + return (0); } -static void irq_submit (const char *irq_name, derive_t value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void irq_submit(const char *irq_name, derive_t value) { + value_list_t vl = VALUE_LIST_INIT; - if (ignorelist_match (ignorelist, irq_name) != 0) - return; + if (ignorelist_match(ignorelist, irq_name) != 0) + return; - vl.values = &(value_t) { .derive = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "irq", sizeof (vl.plugin)); - sstrncpy (vl.type, "irq", sizeof (vl.type)); - sstrncpy (vl.type_instance, irq_name, sizeof (vl.type_instance)); + vl.values = &(value_t){.derive = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "irq", sizeof(vl.plugin)); + sstrncpy(vl.type, "irq", sizeof(vl.type)); + sstrncpy(vl.type_instance, irq_name, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* void irq_submit */ -static int irq_read (void) -{ - FILE *fh; - char buffer[1024]; - int cpu_count; - char *fields[256]; - - /* - * Example content: - * CPU0 CPU1 CPU2 CPU3 - * 0: 2574 1 3 2 IO-APIC-edge timer - * 1: 102553 158669 218062 70587 IO-APIC-edge i8042 - * 8: 0 0 0 1 IO-APIC-edge rtc0 - */ - fh = fopen ("/proc/interrupts", "r"); - if (fh == NULL) - { - char errbuf[1024]; - ERROR ("irq plugin: fopen (/proc/interrupts): %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - /* Get CPU count from the first line */ - if(fgets (buffer, sizeof (buffer), fh) != NULL) { - cpu_count = strsplit (buffer, fields, - STATIC_ARRAY_SIZE (fields)); - } else { - ERROR ("irq plugin: unable to get CPU count from first line " - "of /proc/interrupts"); - fclose (fh); - return (-1); - } - - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - char *irq_name; - size_t irq_name_len; - derive_t irq_value; - int i; - int fields_num; - int irq_values_to_parse; - - fields_num = strsplit (buffer, fields, - STATIC_ARRAY_SIZE (fields)); - if (fields_num < 2) - continue; - - /* Parse this many numeric fields, skip the rest - * (+1 because first there is a name of irq in each line) */ - if (fields_num >= cpu_count + 1) - irq_values_to_parse = cpu_count; - else - irq_values_to_parse = fields_num - 1; - - /* First field is irq name and colon */ - irq_name = fields[0]; - irq_name_len = strlen (irq_name); - if (irq_name_len < 2) - continue; - - /* Check if irq name ends with colon. - * Otherwise it's a header. */ - if (irq_name[irq_name_len - 1] != ':') - continue; - - /* Is it the the ARM fast interrupt (FIQ)? */ - if (irq_name_len == 4 && (strncmp(irq_name, "FIQ:", 4) == 0)) - continue; - - irq_name[irq_name_len - 1] = 0; - irq_name_len--; - - irq_value = 0; - for (i = 1; i <= irq_values_to_parse; i++) - { - /* Per-CPU value */ - value_t v; - int status; - - status = parse_value (fields[i], &v, DS_TYPE_DERIVE); - if (status != 0) - break; - - irq_value += v.derive; - } /* for (i) */ - - /* No valid fields -> do not submit anything. */ - if (i <= 1) - continue; - - irq_submit (irq_name, irq_value); - } - - fclose (fh); - - return (0); +static int irq_read(void) { + FILE *fh; + char buffer[1024]; + int cpu_count; + char *fields[256]; + + /* + * Example content: + * CPU0 CPU1 CPU2 CPU3 + * 0: 2574 1 3 2 IO-APIC-edge timer + * 1: 102553 158669 218062 70587 IO-APIC-edge i8042 + * 8: 0 0 0 1 IO-APIC-edge rtc0 + */ + fh = fopen("/proc/interrupts", "r"); + if (fh == NULL) { + char errbuf[1024]; + ERROR("irq plugin: fopen (/proc/interrupts): %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + /* Get CPU count from the first line */ + if (fgets(buffer, sizeof(buffer), fh) != NULL) { + cpu_count = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + } else { + ERROR("irq plugin: unable to get CPU count from first line " + "of /proc/interrupts"); + fclose(fh); + return (-1); + } + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + char *irq_name; + size_t irq_name_len; + derive_t irq_value; + int i; + int fields_num; + int irq_values_to_parse; + + fields_num = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + if (fields_num < 2) + continue; + + /* Parse this many numeric fields, skip the rest + * (+1 because first there is a name of irq in each line) */ + if (fields_num >= cpu_count + 1) + irq_values_to_parse = cpu_count; + else + irq_values_to_parse = fields_num - 1; + + /* First field is irq name and colon */ + irq_name = fields[0]; + irq_name_len = strlen(irq_name); + if (irq_name_len < 2) + continue; + + /* Check if irq name ends with colon. + * Otherwise it's a header. */ + if (irq_name[irq_name_len - 1] != ':') + continue; + + /* Is it the the ARM fast interrupt (FIQ)? */ + if (irq_name_len == 4 && (strncmp(irq_name, "FIQ:", 4) == 0)) + continue; + + irq_name[irq_name_len - 1] = 0; + irq_name_len--; + + irq_value = 0; + for (i = 1; i <= irq_values_to_parse; i++) { + /* Per-CPU value */ + value_t v; + int status; + + status = parse_value(fields[i], &v, DS_TYPE_DERIVE); + if (status != 0) + break; + + irq_value += v.derive; + } /* for (i) */ + + /* No valid fields -> do not submit anything. */ + if (i <= 1) + continue; + + irq_submit(irq_name, irq_value); + } + + fclose(fh); + + return (0); } /* int irq_read */ -void module_register (void) -{ - plugin_register_config ("irq", irq_config, - config_keys, config_keys_num); - plugin_register_read ("irq", irq_read); +void module_register(void) { + plugin_register_config("irq", irq_config, config_keys, config_keys_num); + plugin_register_read("irq", irq_read); } /* void module_register */ diff --git a/src/java.c b/src/java.c index cd173c58..63b5e317 100644 --- a/src/java.c +++ b/src/java.c @@ -23,14 +23,14 @@ #include "collectd.h" -#include "plugin.h" #include "common.h" #include "filter_chain.h" +#include "plugin.h" #include #if !defined(JNI_VERSION_1_2) -# error "Need JNI 1.2 compatible interface!" +#error "Need JNI 1.2 compatible interface!" #endif /* @@ -46,29 +46,29 @@ typedef struct cjni_jvm_env_s cjni_jvm_env_t; struct java_plugin_class_s /* {{{ */ { - char *name; - jclass class; - jobject object; + char *name; + jclass class; + jobject object; }; typedef struct java_plugin_class_s java_plugin_class_t; /* }}} */ -#define CB_TYPE_CONFIG 1 -#define CB_TYPE_INIT 2 -#define CB_TYPE_READ 3 -#define CB_TYPE_WRITE 4 -#define CB_TYPE_FLUSH 5 -#define CB_TYPE_SHUTDOWN 6 -#define CB_TYPE_LOG 7 +#define CB_TYPE_CONFIG 1 +#define CB_TYPE_INIT 2 +#define CB_TYPE_READ 3 +#define CB_TYPE_WRITE 4 +#define CB_TYPE_FLUSH 5 +#define CB_TYPE_SHUTDOWN 6 +#define CB_TYPE_LOG 7 #define CB_TYPE_NOTIFICATION 8 -#define CB_TYPE_MATCH 9 -#define CB_TYPE_TARGET 10 +#define CB_TYPE_MATCH 9 +#define CB_TYPE_TARGET 10 struct cjni_callback_info_s /* {{{ */ { - char *name; - int type; - jclass class; - jobject object; + char *name; + int type; + jclass class; + jobject object; jmethodID method; }; typedef struct cjni_callback_info_s cjni_callback_info_t; @@ -85,15 +85,15 @@ static char **jvm_argv = NULL; static size_t jvm_argc = 0; /* List of class names to load */ -static java_plugin_class_t *java_classes_list = NULL; -static size_t java_classes_list_len; +static java_plugin_class_t *java_classes_list = NULL; +static size_t java_classes_list_len; /* List of config, init, and shutdown callbacks. */ -static cjni_callback_info_t *java_callbacks = NULL; -static size_t java_callbacks_num = 0; -static pthread_mutex_t java_callbacks_lock = PTHREAD_MUTEX_INITIALIZER; +static cjni_callback_info_t *java_callbacks = NULL; +static size_t java_callbacks_num = 0; +static pthread_mutex_t java_callbacks_lock = PTHREAD_MUTEX_INITIALIZER; -static oconfig_item_t *config_block = NULL; +static oconfig_item_t *config_block = NULL; /* * Prototypes @@ -101,296 +101,268 @@ static oconfig_item_t *config_block = NULL; * Mostly functions that are needed by the Java interface (``native'') * functions. */ -static void cjni_callback_info_destroy (void *arg); -static cjni_callback_info_t *cjni_callback_info_create (JNIEnv *jvm_env, - jobject o_name, jobject o_callback, int type); -static int cjni_callback_register (JNIEnv *jvm_env, jobject o_name, - jobject o_callback, int type); -static int cjni_read (user_data_t *user_data); -static int cjni_write (const data_set_t *ds, const value_list_t *vl, - user_data_t *ud); -static int cjni_flush (cdtime_t timeout, const char *identifier, user_data_t *ud); -static void cjni_log (int severity, const char *message, user_data_t *ud); -static int cjni_notification (const notification_t *n, user_data_t *ud); +static void cjni_callback_info_destroy(void *arg); +static cjni_callback_info_t *cjni_callback_info_create(JNIEnv *jvm_env, + jobject o_name, + jobject o_callback, + int type); +static int cjni_callback_register(JNIEnv *jvm_env, jobject o_name, + jobject o_callback, int type); +static int cjni_read(user_data_t *user_data); +static int cjni_write(const data_set_t *ds, const value_list_t *vl, + user_data_t *ud); +static int cjni_flush(cdtime_t timeout, const char *identifier, + user_data_t *ud); +static void cjni_log(int severity, const char *message, user_data_t *ud); +static int cjni_notification(const notification_t *n, user_data_t *ud); /* Create, destroy, and match/invoke functions, used by both, matches AND * targets. */ -static int cjni_match_target_create (const oconfig_item_t *ci, void **user_data); -static int cjni_match_target_destroy (void **user_data); -static int cjni_match_target_invoke (const data_set_t *ds, value_list_t *vl, - notification_meta_t **meta, void **user_data); +static int cjni_match_target_create(const oconfig_item_t *ci, void **user_data); +static int cjni_match_target_destroy(void **user_data); +static int cjni_match_target_invoke(const data_set_t *ds, value_list_t *vl, + notification_meta_t **meta, + void **user_data); /* * C to Java conversion functions */ -static int ctoj_string (JNIEnv *jvm_env, /* {{{ */ - const char *string, - jclass class_ptr, jobject object_ptr, const char *method_name) -{ +static int ctoj_string(JNIEnv *jvm_env, /* {{{ */ + const char *string, jclass class_ptr, jobject object_ptr, + const char *method_name) { jmethodID m_set; jstring o_string; /* Create a java.lang.String */ - o_string = (*jvm_env)->NewStringUTF (jvm_env, - (string != NULL) ? string : ""); - if (o_string == NULL) - { - ERROR ("java plugin: ctoj_string: NewStringUTF failed."); + o_string = (*jvm_env)->NewStringUTF(jvm_env, (string != NULL) ? string : ""); + if (o_string == NULL) { + ERROR("java plugin: ctoj_string: NewStringUTF failed."); return (-1); } /* Search for the `void setFoo (String s)' method. */ - m_set = (*jvm_env)->GetMethodID (jvm_env, class_ptr, - method_name, "(Ljava/lang/String;)V"); - if (m_set == NULL) - { - ERROR ("java plugin: ctoj_string: Cannot find method `void %s (String)'.", - method_name); - (*jvm_env)->DeleteLocalRef (jvm_env, o_string); + m_set = (*jvm_env)->GetMethodID(jvm_env, class_ptr, method_name, + "(Ljava/lang/String;)V"); + if (m_set == NULL) { + ERROR("java plugin: ctoj_string: Cannot find method `void %s (String)'.", + method_name); + (*jvm_env)->DeleteLocalRef(jvm_env, o_string); return (-1); } /* Call the method. */ - (*jvm_env)->CallVoidMethod (jvm_env, object_ptr, m_set, o_string); + (*jvm_env)->CallVoidMethod(jvm_env, object_ptr, m_set, o_string); /* Decrease reference counter on the java.lang.String object. */ - (*jvm_env)->DeleteLocalRef (jvm_env, o_string); + (*jvm_env)->DeleteLocalRef(jvm_env, o_string); return (0); } /* }}} int ctoj_string */ -static jstring ctoj_output_string (JNIEnv *jvm_env, /* {{{ */ - const char *string) -{ +static jstring ctoj_output_string(JNIEnv *jvm_env, /* {{{ */ + const char *string) { jstring o_string; /* Create a java.lang.String */ - o_string = (*jvm_env)->NewStringUTF (jvm_env, - (string != NULL) ? string : ""); - if (o_string == NULL) - { - ERROR ("java plugin: ctoj_output_string: NewStringUTF failed."); + o_string = (*jvm_env)->NewStringUTF(jvm_env, (string != NULL) ? string : ""); + if (o_string == NULL) { + ERROR("java plugin: ctoj_output_string: NewStringUTF failed."); return NULL; } return (o_string); } /* }}} int ctoj_output_string */ -static int ctoj_int (JNIEnv *jvm_env, /* {{{ */ - jint value, - jclass class_ptr, jobject object_ptr, const char *method_name) -{ +static int ctoj_int(JNIEnv *jvm_env, /* {{{ */ + jint value, jclass class_ptr, jobject object_ptr, + const char *method_name) { jmethodID m_set; /* Search for the `void setFoo (int i)' method. */ - m_set = (*jvm_env)->GetMethodID (jvm_env, class_ptr, - method_name, "(I)V"); - if (m_set == NULL) - { - ERROR ("java plugin: ctoj_int: Cannot find method `void %s (int)'.", - method_name); + m_set = (*jvm_env)->GetMethodID(jvm_env, class_ptr, method_name, "(I)V"); + if (m_set == NULL) { + ERROR("java plugin: ctoj_int: Cannot find method `void %s (int)'.", + method_name); return (-1); } - (*jvm_env)->CallVoidMethod (jvm_env, object_ptr, m_set, value); + (*jvm_env)->CallVoidMethod(jvm_env, object_ptr, m_set, value); return (0); } /* }}} int ctoj_int */ -static int ctoj_long (JNIEnv *jvm_env, /* {{{ */ - jlong value, - jclass class_ptr, jobject object_ptr, const char *method_name) -{ +static int ctoj_long(JNIEnv *jvm_env, /* {{{ */ + jlong value, jclass class_ptr, jobject object_ptr, + const char *method_name) { jmethodID m_set; /* Search for the `void setFoo (long l)' method. */ - m_set = (*jvm_env)->GetMethodID (jvm_env, class_ptr, - method_name, "(J)V"); - if (m_set == NULL) - { - ERROR ("java plugin: ctoj_long: Cannot find method `void %s (long)'.", - method_name); + m_set = (*jvm_env)->GetMethodID(jvm_env, class_ptr, method_name, "(J)V"); + if (m_set == NULL) { + ERROR("java plugin: ctoj_long: Cannot find method `void %s (long)'.", + method_name); return (-1); } - (*jvm_env)->CallVoidMethod (jvm_env, object_ptr, m_set, value); + (*jvm_env)->CallVoidMethod(jvm_env, object_ptr, m_set, value); return (0); } /* }}} int ctoj_long */ -static int ctoj_double (JNIEnv *jvm_env, /* {{{ */ - jdouble value, - jclass class_ptr, jobject object_ptr, const char *method_name) -{ +static int ctoj_double(JNIEnv *jvm_env, /* {{{ */ + jdouble value, jclass class_ptr, jobject object_ptr, + const char *method_name) { jmethodID m_set; /* Search for the `void setFoo (double d)' method. */ - m_set = (*jvm_env)->GetMethodID (jvm_env, class_ptr, - method_name, "(D)V"); - if (m_set == NULL) - { - ERROR ("java plugin: ctoj_double: Cannot find method `void %s (double)'.", - method_name); + m_set = (*jvm_env)->GetMethodID(jvm_env, class_ptr, method_name, "(D)V"); + if (m_set == NULL) { + ERROR("java plugin: ctoj_double: Cannot find method `void %s (double)'.", + method_name); return (-1); } - (*jvm_env)->CallVoidMethod (jvm_env, object_ptr, m_set, value); + (*jvm_env)->CallVoidMethod(jvm_env, object_ptr, m_set, value); return (0); } /* }}} int ctoj_double */ /* Convert a jlong to a java.lang.Number */ -static jobject ctoj_jlong_to_number (JNIEnv *jvm_env, jlong value) /* {{{ */ +static jobject ctoj_jlong_to_number(JNIEnv *jvm_env, jlong value) /* {{{ */ { jclass c_long; jmethodID m_long_constructor; /* Look up the java.lang.Long class */ - c_long = (*jvm_env)->FindClass (jvm_env, "java/lang/Long"); - if (c_long == NULL) - { - ERROR ("java plugin: ctoj_jlong_to_number: Looking up the " - "java.lang.Long class failed."); + c_long = (*jvm_env)->FindClass(jvm_env, "java/lang/Long"); + if (c_long == NULL) { + ERROR("java plugin: ctoj_jlong_to_number: Looking up the " + "java.lang.Long class failed."); return (NULL); } - m_long_constructor = (*jvm_env)->GetMethodID (jvm_env, - c_long, "", "(J)V"); - if (m_long_constructor == NULL) - { - ERROR ("java plugin: ctoj_jlong_to_number: Looking up the " - "`Long (long)' constructor failed."); + m_long_constructor = + (*jvm_env)->GetMethodID(jvm_env, c_long, "", "(J)V"); + if (m_long_constructor == NULL) { + ERROR("java plugin: ctoj_jlong_to_number: Looking up the " + "`Long (long)' constructor failed."); return (NULL); } - return ((*jvm_env)->NewObject (jvm_env, - c_long, m_long_constructor, value)); + return ((*jvm_env)->NewObject(jvm_env, c_long, m_long_constructor, value)); } /* }}} jobject ctoj_jlong_to_number */ /* Convert a jdouble to a java.lang.Number */ -static jobject ctoj_jdouble_to_number (JNIEnv *jvm_env, jdouble value) /* {{{ */ +static jobject ctoj_jdouble_to_number(JNIEnv *jvm_env, jdouble value) /* {{{ */ { jclass c_double; jmethodID m_double_constructor; /* Look up the java.lang.Long class */ - c_double = (*jvm_env)->FindClass (jvm_env, "java/lang/Double"); - if (c_double == NULL) - { - ERROR ("java plugin: ctoj_jdouble_to_number: Looking up the " - "java.lang.Double class failed."); + c_double = (*jvm_env)->FindClass(jvm_env, "java/lang/Double"); + if (c_double == NULL) { + ERROR("java plugin: ctoj_jdouble_to_number: Looking up the " + "java.lang.Double class failed."); return (NULL); } - m_double_constructor = (*jvm_env)->GetMethodID (jvm_env, - c_double, "", "(D)V"); - if (m_double_constructor == NULL) - { - ERROR ("java plugin: ctoj_jdouble_to_number: Looking up the " - "`Double (double)' constructor failed."); + m_double_constructor = + (*jvm_env)->GetMethodID(jvm_env, c_double, "", "(D)V"); + if (m_double_constructor == NULL) { + ERROR("java plugin: ctoj_jdouble_to_number: Looking up the " + "`Double (double)' constructor failed."); return (NULL); } - return ((*jvm_env)->NewObject (jvm_env, - c_double, m_double_constructor, value)); + return ( + (*jvm_env)->NewObject(jvm_env, c_double, m_double_constructor, value)); } /* }}} jobject ctoj_jdouble_to_number */ /* Convert a value_t to a java.lang.Number */ -static jobject ctoj_value_to_number (JNIEnv *jvm_env, /* {{{ */ - value_t value, int ds_type) -{ +static jobject ctoj_value_to_number(JNIEnv *jvm_env, /* {{{ */ + value_t value, int ds_type) { if (ds_type == DS_TYPE_COUNTER) - return (ctoj_jlong_to_number (jvm_env, (jlong) value.counter)); + return (ctoj_jlong_to_number(jvm_env, (jlong)value.counter)); else if (ds_type == DS_TYPE_GAUGE) - return (ctoj_jdouble_to_number (jvm_env, (jdouble) value.gauge)); + return (ctoj_jdouble_to_number(jvm_env, (jdouble)value.gauge)); if (ds_type == DS_TYPE_DERIVE) - return (ctoj_jlong_to_number (jvm_env, (jlong) value.derive)); + return (ctoj_jlong_to_number(jvm_env, (jlong)value.derive)); if (ds_type == DS_TYPE_ABSOLUTE) - return (ctoj_jlong_to_number (jvm_env, (jlong) value.absolute)); + return (ctoj_jlong_to_number(jvm_env, (jlong)value.absolute)); else return (NULL); } /* }}} jobject ctoj_value_to_number */ /* Convert a data_source_t to a org/collectd/api/DataSource */ -static jobject ctoj_data_source (JNIEnv *jvm_env, /* {{{ */ - const data_source_t *dsrc) -{ +static jobject ctoj_data_source(JNIEnv *jvm_env, /* {{{ */ + const data_source_t *dsrc) { jclass c_datasource; jmethodID m_datasource_constructor; jobject o_datasource; int status; /* Look up the DataSource class */ - c_datasource = (*jvm_env)->FindClass (jvm_env, - "org/collectd/api/DataSource"); - if (c_datasource == NULL) - { - ERROR ("java plugin: ctoj_data_source: " - "FindClass (org/collectd/api/DataSource) failed."); + c_datasource = (*jvm_env)->FindClass(jvm_env, "org/collectd/api/DataSource"); + if (c_datasource == NULL) { + ERROR("java plugin: ctoj_data_source: " + "FindClass (org/collectd/api/DataSource) failed."); return (NULL); } /* Lookup the `ValueList ()' constructor. */ - m_datasource_constructor = (*jvm_env)->GetMethodID (jvm_env, c_datasource, - "", "()V"); - if (m_datasource_constructor == NULL) - { - ERROR ("java plugin: ctoj_data_source: Cannot find the " - "`DataSource ()' constructor."); + m_datasource_constructor = + (*jvm_env)->GetMethodID(jvm_env, c_datasource, "", "()V"); + if (m_datasource_constructor == NULL) { + ERROR("java plugin: ctoj_data_source: Cannot find the " + "`DataSource ()' constructor."); return (NULL); } /* Create a new instance. */ - o_datasource = (*jvm_env)->NewObject (jvm_env, c_datasource, - m_datasource_constructor); - if (o_datasource == NULL) - { - ERROR ("java plugin: ctoj_data_source: " - "Creating a new DataSource instance failed."); + o_datasource = + (*jvm_env)->NewObject(jvm_env, c_datasource, m_datasource_constructor); + if (o_datasource == NULL) { + ERROR("java plugin: ctoj_data_source: " + "Creating a new DataSource instance failed."); return (NULL); } /* Set name via `void setName (String name)' */ - status = ctoj_string (jvm_env, dsrc->name, - c_datasource, o_datasource, "setName"); - if (status != 0) - { - ERROR ("java plugin: ctoj_data_source: " - "ctoj_string (setName) failed."); - (*jvm_env)->DeleteLocalRef (jvm_env, o_datasource); + status = + ctoj_string(jvm_env, dsrc->name, c_datasource, o_datasource, "setName"); + if (status != 0) { + ERROR("java plugin: ctoj_data_source: " + "ctoj_string (setName) failed."); + (*jvm_env)->DeleteLocalRef(jvm_env, o_datasource); return (NULL); } /* Set type via `void setType (int type)' */ - status = ctoj_int (jvm_env, dsrc->type, - c_datasource, o_datasource, "setType"); - if (status != 0) - { - ERROR ("java plugin: ctoj_data_source: " - "ctoj_int (setType) failed."); - (*jvm_env)->DeleteLocalRef (jvm_env, o_datasource); + status = ctoj_int(jvm_env, dsrc->type, c_datasource, o_datasource, "setType"); + if (status != 0) { + ERROR("java plugin: ctoj_data_source: " + "ctoj_int (setType) failed."); + (*jvm_env)->DeleteLocalRef(jvm_env, o_datasource); return (NULL); } /* Set min via `void setMin (double min)' */ - status = ctoj_double (jvm_env, dsrc->min, - c_datasource, o_datasource, "setMin"); - if (status != 0) - { - ERROR ("java plugin: ctoj_data_source: " - "ctoj_double (setMin) failed."); - (*jvm_env)->DeleteLocalRef (jvm_env, o_datasource); + status = + ctoj_double(jvm_env, dsrc->min, c_datasource, o_datasource, "setMin"); + if (status != 0) { + ERROR("java plugin: ctoj_data_source: " + "ctoj_double (setMin) failed."); + (*jvm_env)->DeleteLocalRef(jvm_env, o_datasource); return (NULL); } /* Set max via `void setMax (double max)' */ - status = ctoj_double (jvm_env, dsrc->max, - c_datasource, o_datasource, "setMax"); - if (status != 0) - { - ERROR ("java plugin: ctoj_data_source: " - "ctoj_double (setMax) failed."); - (*jvm_env)->DeleteLocalRef (jvm_env, o_datasource); + status = + ctoj_double(jvm_env, dsrc->max, c_datasource, o_datasource, "setMax"); + if (status != 0) { + ERROR("java plugin: ctoj_data_source: " + "ctoj_double (setMax) failed."); + (*jvm_env)->DeleteLocalRef(jvm_env, o_datasource); return (NULL); } @@ -398,9 +370,8 @@ static jobject ctoj_data_source (JNIEnv *jvm_env, /* {{{ */ } /* }}} jobject ctoj_data_source */ /* Convert a oconfig_value_t to a org/collectd/api/OConfigValue */ -static jobject ctoj_oconfig_value (JNIEnv *jvm_env, /* {{{ */ - oconfig_value_t ocvalue) -{ +static jobject ctoj_oconfig_value(JNIEnv *jvm_env, /* {{{ */ + oconfig_value_t ocvalue) { jclass c_ocvalue; jmethodID m_ocvalue_constructor; jobject o_argument; @@ -409,98 +380,82 @@ static jobject ctoj_oconfig_value (JNIEnv *jvm_env, /* {{{ */ m_ocvalue_constructor = NULL; o_argument = NULL; - c_ocvalue = (*jvm_env)->FindClass (jvm_env, - "org/collectd/api/OConfigValue"); - if (c_ocvalue == NULL) - { - ERROR ("java plugin: ctoj_oconfig_value: " - "FindClass (org/collectd/api/OConfigValue) failed."); + c_ocvalue = (*jvm_env)->FindClass(jvm_env, "org/collectd/api/OConfigValue"); + if (c_ocvalue == NULL) { + ERROR("java plugin: ctoj_oconfig_value: " + "FindClass (org/collectd/api/OConfigValue) failed."); return (NULL); } - if (ocvalue.type == OCONFIG_TYPE_BOOLEAN) - { + if (ocvalue.type == OCONFIG_TYPE_BOOLEAN) { jboolean tmp_boolean; tmp_boolean = (ocvalue.value.boolean == 0) ? JNI_FALSE : JNI_TRUE; - m_ocvalue_constructor = (*jvm_env)->GetMethodID (jvm_env, c_ocvalue, - "", "(Z)V"); - if (m_ocvalue_constructor == NULL) - { - ERROR ("java plugin: ctoj_oconfig_value: Cannot find the " - "`OConfigValue (boolean)' constructor."); + m_ocvalue_constructor = + (*jvm_env)->GetMethodID(jvm_env, c_ocvalue, "", "(Z)V"); + if (m_ocvalue_constructor == NULL) { + ERROR("java plugin: ctoj_oconfig_value: Cannot find the " + "`OConfigValue (boolean)' constructor."); return (NULL); } - return ((*jvm_env)->NewObject (jvm_env, - c_ocvalue, m_ocvalue_constructor, tmp_boolean)); + return ((*jvm_env)->NewObject(jvm_env, c_ocvalue, m_ocvalue_constructor, + tmp_boolean)); } /* if (ocvalue.type == OCONFIG_TYPE_BOOLEAN) */ - else if (ocvalue.type == OCONFIG_TYPE_STRING) - { - m_ocvalue_constructor = (*jvm_env)->GetMethodID (jvm_env, c_ocvalue, - "", "(Ljava/lang/String;)V"); - if (m_ocvalue_constructor == NULL) - { - ERROR ("java plugin: ctoj_oconfig_value: Cannot find the " - "`OConfigValue (String)' constructor."); + else if (ocvalue.type == OCONFIG_TYPE_STRING) { + m_ocvalue_constructor = (*jvm_env)->GetMethodID( + jvm_env, c_ocvalue, "", "(Ljava/lang/String;)V"); + if (m_ocvalue_constructor == NULL) { + ERROR("java plugin: ctoj_oconfig_value: Cannot find the " + "`OConfigValue (String)' constructor."); return (NULL); } - o_argument = (*jvm_env)->NewStringUTF (jvm_env, ocvalue.value.string); - if (o_argument == NULL) - { - ERROR ("java plugin: ctoj_oconfig_value: " - "Creating a String object failed."); + o_argument = (*jvm_env)->NewStringUTF(jvm_env, ocvalue.value.string); + if (o_argument == NULL) { + ERROR("java plugin: ctoj_oconfig_value: " + "Creating a String object failed."); return (NULL); } - } - else if (ocvalue.type == OCONFIG_TYPE_NUMBER) - { - m_ocvalue_constructor = (*jvm_env)->GetMethodID (jvm_env, c_ocvalue, - "", "(Ljava/lang/Number;)V"); - if (m_ocvalue_constructor == NULL) - { - ERROR ("java plugin: ctoj_oconfig_value: Cannot find the " - "`OConfigValue (Number)' constructor."); + } else if (ocvalue.type == OCONFIG_TYPE_NUMBER) { + m_ocvalue_constructor = (*jvm_env)->GetMethodID( + jvm_env, c_ocvalue, "", "(Ljava/lang/Number;)V"); + if (m_ocvalue_constructor == NULL) { + ERROR("java plugin: ctoj_oconfig_value: Cannot find the " + "`OConfigValue (Number)' constructor."); return (NULL); } - o_argument = ctoj_jdouble_to_number (jvm_env, - (jdouble) ocvalue.value.number); - if (o_argument == NULL) - { - ERROR ("java plugin: ctoj_oconfig_value: " - "Creating a Number object failed."); + o_argument = ctoj_jdouble_to_number(jvm_env, (jdouble)ocvalue.value.number); + if (o_argument == NULL) { + ERROR("java plugin: ctoj_oconfig_value: " + "Creating a Number object failed."); return (NULL); } - } - else - { + } else { return (NULL); } - assert (m_ocvalue_constructor != NULL); - assert (o_argument != NULL); + assert(m_ocvalue_constructor != NULL); + assert(o_argument != NULL); - o_ocvalue = (*jvm_env)->NewObject (jvm_env, - c_ocvalue, m_ocvalue_constructor, o_argument); - if (o_ocvalue == NULL) - { - ERROR ("java plugin: ctoj_oconfig_value: " - "Creating an OConfigValue object failed."); - (*jvm_env)->DeleteLocalRef (jvm_env, o_argument); + o_ocvalue = (*jvm_env)->NewObject(jvm_env, c_ocvalue, m_ocvalue_constructor, + o_argument); + if (o_ocvalue == NULL) { + ERROR("java plugin: ctoj_oconfig_value: " + "Creating an OConfigValue object failed."); + (*jvm_env)->DeleteLocalRef(jvm_env, o_argument); return (NULL); } - (*jvm_env)->DeleteLocalRef (jvm_env, o_argument); + (*jvm_env)->DeleteLocalRef(jvm_env, o_argument); return (o_ocvalue); } /* }}} jobject ctoj_oconfig_value */ /* Convert a oconfig_item_t to a org/collectd/api/OConfigItem */ -static jobject ctoj_oconfig_item (JNIEnv *jvm_env, /* {{{ */ - const oconfig_item_t *ci) -{ +static jobject ctoj_oconfig_item(JNIEnv *jvm_env, /* {{{ */ + const oconfig_item_t *ci) { jclass c_ocitem; jmethodID m_ocitem_constructor; jmethodID m_addvalue; @@ -508,84 +463,77 @@ static jobject ctoj_oconfig_item (JNIEnv *jvm_env, /* {{{ */ jobject o_key; jobject o_ocitem; - c_ocitem = (*jvm_env)->FindClass (jvm_env, "org/collectd/api/OConfigItem"); - if (c_ocitem == NULL) - { - ERROR ("java plugin: ctoj_oconfig_item: " - "FindClass (org/collectd/api/OConfigItem) failed."); + c_ocitem = (*jvm_env)->FindClass(jvm_env, "org/collectd/api/OConfigItem"); + if (c_ocitem == NULL) { + ERROR("java plugin: ctoj_oconfig_item: " + "FindClass (org/collectd/api/OConfigItem) failed."); return (NULL); } /* Get the required methods: m_ocitem_constructor, m_addvalue, and m_addchild * {{{ */ - m_ocitem_constructor = (*jvm_env)->GetMethodID (jvm_env, c_ocitem, - "", "(Ljava/lang/String;)V"); - if (m_ocitem_constructor == NULL) - { - ERROR ("java plugin: ctoj_oconfig_item: Cannot find the " - "`OConfigItem (String)' constructor."); + m_ocitem_constructor = (*jvm_env)->GetMethodID(jvm_env, c_ocitem, "", + "(Ljava/lang/String;)V"); + if (m_ocitem_constructor == NULL) { + ERROR("java plugin: ctoj_oconfig_item: Cannot find the " + "`OConfigItem (String)' constructor."); return (NULL); } - m_addvalue = (*jvm_env)->GetMethodID (jvm_env, c_ocitem, - "addValue", "(Lorg/collectd/api/OConfigValue;)V"); - if (m_addvalue == NULL) - { - ERROR ("java plugin: ctoj_oconfig_item: Cannot find the " - "`addValue (OConfigValue)' method."); + m_addvalue = (*jvm_env)->GetMethodID(jvm_env, c_ocitem, "addValue", + "(Lorg/collectd/api/OConfigValue;)V"); + if (m_addvalue == NULL) { + ERROR("java plugin: ctoj_oconfig_item: Cannot find the " + "`addValue (OConfigValue)' method."); return (NULL); } - m_addchild = (*jvm_env)->GetMethodID (jvm_env, c_ocitem, - "addChild", "(Lorg/collectd/api/OConfigItem;)V"); - if (m_addchild == NULL) - { - ERROR ("java plugin: ctoj_oconfig_item: Cannot find the " - "`addChild (OConfigItem)' method."); + m_addchild = (*jvm_env)->GetMethodID(jvm_env, c_ocitem, "addChild", + "(Lorg/collectd/api/OConfigItem;)V"); + if (m_addchild == NULL) { + ERROR("java plugin: ctoj_oconfig_item: Cannot find the " + "`addChild (OConfigItem)' method."); return (NULL); } /* }}} */ /* Create a String object with the key. * Needed for calling the constructor. */ - o_key = (*jvm_env)->NewStringUTF (jvm_env, ci->key); - if (o_key == NULL) - { - ERROR ("java plugin: ctoj_oconfig_item: " - "Creating String object failed."); + o_key = (*jvm_env)->NewStringUTF(jvm_env, ci->key); + if (o_key == NULL) { + ERROR("java plugin: ctoj_oconfig_item: " + "Creating String object failed."); return (NULL); } /* Create an OConfigItem object */ - o_ocitem = (*jvm_env)->NewObject (jvm_env, - c_ocitem, m_ocitem_constructor, o_key); - if (o_ocitem == NULL) - { - ERROR ("java plugin: ctoj_oconfig_item: " - "Creating an OConfigItem object failed."); - (*jvm_env)->DeleteLocalRef (jvm_env, o_key); + o_ocitem = + (*jvm_env)->NewObject(jvm_env, c_ocitem, m_ocitem_constructor, o_key); + if (o_ocitem == NULL) { + ERROR("java plugin: ctoj_oconfig_item: " + "Creating an OConfigItem object failed."); + (*jvm_env)->DeleteLocalRef(jvm_env, o_key); return (NULL); } /* We don't need the String object any longer.. */ - (*jvm_env)->DeleteLocalRef (jvm_env, o_key); + (*jvm_env)->DeleteLocalRef(jvm_env, o_key); /* Call OConfigItem.addValue for each value */ for (int i = 0; i < ci->values_num; i++) /* {{{ */ { jobject o_value; - o_value = ctoj_oconfig_value (jvm_env, ci->values[i]); - if (o_value == NULL) - { - ERROR ("java plugin: ctoj_oconfig_item: " - "Creating an OConfigValue object failed."); - (*jvm_env)->DeleteLocalRef (jvm_env, o_ocitem); + o_value = ctoj_oconfig_value(jvm_env, ci->values[i]); + if (o_value == NULL) { + ERROR("java plugin: ctoj_oconfig_item: " + "Creating an OConfigValue object failed."); + (*jvm_env)->DeleteLocalRef(jvm_env, o_ocitem); return (NULL); } - (*jvm_env)->CallVoidMethod (jvm_env, o_ocitem, m_addvalue, o_value); - (*jvm_env)->DeleteLocalRef (jvm_env, o_value); + (*jvm_env)->CallVoidMethod(jvm_env, o_ocitem, m_addvalue, o_value); + (*jvm_env)->DeleteLocalRef(jvm_env, o_value); } /* }}} for (i = 0; i < ci->values_num; i++) */ /* Call OConfigItem.addChild for each child */ @@ -593,24 +541,23 @@ static jobject ctoj_oconfig_item (JNIEnv *jvm_env, /* {{{ */ { jobject o_child; - o_child = ctoj_oconfig_item (jvm_env, ci->children + i); - if (o_child == NULL) - { - ERROR ("java plugin: ctoj_oconfig_item: " - "Creating an OConfigItem object failed."); - (*jvm_env)->DeleteLocalRef (jvm_env, o_ocitem); + o_child = ctoj_oconfig_item(jvm_env, ci->children + i); + if (o_child == NULL) { + ERROR("java plugin: ctoj_oconfig_item: " + "Creating an OConfigItem object failed."); + (*jvm_env)->DeleteLocalRef(jvm_env, o_ocitem); return (NULL); } - (*jvm_env)->CallVoidMethod (jvm_env, o_ocitem, m_addchild, o_child); - (*jvm_env)->DeleteLocalRef (jvm_env, o_child); + (*jvm_env)->CallVoidMethod(jvm_env, o_ocitem, m_addchild, o_child); + (*jvm_env)->DeleteLocalRef(jvm_env, o_child); } /* }}} for (i = 0; i < ci->children_num; i++) */ return (o_ocitem); } /* }}} jobject ctoj_oconfig_item */ /* Convert a data_set_t to a org/collectd/api/DataSet */ -static jobject ctoj_data_set (JNIEnv *jvm_env, const data_set_t *ds) /* {{{ */ +static jobject ctoj_data_set(JNIEnv *jvm_env, const data_set_t *ds) /* {{{ */ { jclass c_dataset; jmethodID m_constructor; @@ -619,144 +566,130 @@ static jobject ctoj_data_set (JNIEnv *jvm_env, const data_set_t *ds) /* {{{ */ jobject o_dataset; /* Look up the org/collectd/api/DataSet class */ - c_dataset = (*jvm_env)->FindClass (jvm_env, "org/collectd/api/DataSet"); - if (c_dataset == NULL) - { - ERROR ("java plugin: ctoj_data_set: Looking up the " - "org/collectd/api/DataSet class failed."); + c_dataset = (*jvm_env)->FindClass(jvm_env, "org/collectd/api/DataSet"); + if (c_dataset == NULL) { + ERROR("java plugin: ctoj_data_set: Looking up the " + "org/collectd/api/DataSet class failed."); return (NULL); } /* Search for the `DataSet (String type)' constructor. */ - m_constructor = (*jvm_env)->GetMethodID (jvm_env, - c_dataset, "", "(Ljava/lang/String;)V"); - if (m_constructor == NULL) - { - ERROR ("java plugin: ctoj_data_set: Looking up the " - "`DataSet (String)' constructor failed."); + m_constructor = (*jvm_env)->GetMethodID(jvm_env, c_dataset, "", + "(Ljava/lang/String;)V"); + if (m_constructor == NULL) { + ERROR("java plugin: ctoj_data_set: Looking up the " + "`DataSet (String)' constructor failed."); return (NULL); } /* Search for the `void addDataSource (DataSource)' method. */ - m_add = (*jvm_env)->GetMethodID (jvm_env, - c_dataset, "addDataSource", "(Lorg/collectd/api/DataSource;)V"); - if (m_add == NULL) - { - ERROR ("java plugin: ctoj_data_set: Looking up the " - "`addDataSource (DataSource)' method failed."); + m_add = (*jvm_env)->GetMethodID(jvm_env, c_dataset, "addDataSource", + "(Lorg/collectd/api/DataSource;)V"); + if (m_add == NULL) { + ERROR("java plugin: ctoj_data_set: Looking up the " + "`addDataSource (DataSource)' method failed."); return (NULL); } - o_type = (*jvm_env)->NewStringUTF (jvm_env, ds->type); - if (o_type == NULL) - { - ERROR ("java plugin: ctoj_data_set: Creating a String object failed."); + o_type = (*jvm_env)->NewStringUTF(jvm_env, ds->type); + if (o_type == NULL) { + ERROR("java plugin: ctoj_data_set: Creating a String object failed."); return (NULL); } - o_dataset = (*jvm_env)->NewObject (jvm_env, - c_dataset, m_constructor, o_type); - if (o_dataset == NULL) - { - ERROR ("java plugin: ctoj_data_set: Creating a DataSet object failed."); - (*jvm_env)->DeleteLocalRef (jvm_env, o_type); + o_dataset = (*jvm_env)->NewObject(jvm_env, c_dataset, m_constructor, o_type); + if (o_dataset == NULL) { + ERROR("java plugin: ctoj_data_set: Creating a DataSet object failed."); + (*jvm_env)->DeleteLocalRef(jvm_env, o_type); return (NULL); } /* Decrease reference counter on the java.lang.String object. */ - (*jvm_env)->DeleteLocalRef (jvm_env, o_type); + (*jvm_env)->DeleteLocalRef(jvm_env, o_type); - for (size_t i = 0; i < ds->ds_num; i++) - { + for (size_t i = 0; i < ds->ds_num; i++) { jobject o_datasource; - o_datasource = ctoj_data_source (jvm_env, ds->ds + i); - if (o_datasource == NULL) - { - ERROR ("java plugin: ctoj_data_set: ctoj_data_source (%s.%s) failed", - ds->type, ds->ds[i].name); - (*jvm_env)->DeleteLocalRef (jvm_env, o_dataset); + o_datasource = ctoj_data_source(jvm_env, ds->ds + i); + if (o_datasource == NULL) { + ERROR("java plugin: ctoj_data_set: ctoj_data_source (%s.%s) failed", + ds->type, ds->ds[i].name); + (*jvm_env)->DeleteLocalRef(jvm_env, o_dataset); return (NULL); } - (*jvm_env)->CallVoidMethod (jvm_env, o_dataset, m_add, o_datasource); + (*jvm_env)->CallVoidMethod(jvm_env, o_dataset, m_add, o_datasource); - (*jvm_env)->DeleteLocalRef (jvm_env, o_datasource); + (*jvm_env)->DeleteLocalRef(jvm_env, o_datasource); } /* for (i = 0; i < ds->ds_num; i++) */ return (o_dataset); } /* }}} jobject ctoj_data_set */ -static int ctoj_value_list_add_value (JNIEnv *jvm_env, /* {{{ */ - value_t value, int ds_type, - jclass class_ptr, jobject object_ptr) -{ +static int ctoj_value_list_add_value(JNIEnv *jvm_env, /* {{{ */ + value_t value, int ds_type, + jclass class_ptr, jobject object_ptr) { jmethodID m_addvalue; jobject o_number; - m_addvalue = (*jvm_env)->GetMethodID (jvm_env, class_ptr, - "addValue", "(Ljava/lang/Number;)V"); - if (m_addvalue == NULL) - { - ERROR ("java plugin: ctoj_value_list_add_value: " - "Cannot find method `void addValue (Number)'."); + m_addvalue = (*jvm_env)->GetMethodID(jvm_env, class_ptr, "addValue", + "(Ljava/lang/Number;)V"); + if (m_addvalue == NULL) { + ERROR("java plugin: ctoj_value_list_add_value: " + "Cannot find method `void addValue (Number)'."); return (-1); } - o_number = ctoj_value_to_number (jvm_env, value, ds_type); - if (o_number == NULL) - { - ERROR ("java plugin: ctoj_value_list_add_value: " - "ctoj_value_to_number failed."); + o_number = ctoj_value_to_number(jvm_env, value, ds_type); + if (o_number == NULL) { + ERROR("java plugin: ctoj_value_list_add_value: " + "ctoj_value_to_number failed."); return (-1); } - (*jvm_env)->CallVoidMethod (jvm_env, object_ptr, m_addvalue, o_number); + (*jvm_env)->CallVoidMethod(jvm_env, object_ptr, m_addvalue, o_number); - (*jvm_env)->DeleteLocalRef (jvm_env, o_number); + (*jvm_env)->DeleteLocalRef(jvm_env, o_number); return (0); } /* }}} int ctoj_value_list_add_value */ -static int ctoj_value_list_add_data_set (JNIEnv *jvm_env, /* {{{ */ - jclass c_valuelist, jobject o_valuelist, const data_set_t *ds) -{ +static int ctoj_value_list_add_data_set(JNIEnv *jvm_env, /* {{{ */ + jclass c_valuelist, jobject o_valuelist, + const data_set_t *ds) { jmethodID m_setdataset; jobject o_dataset; /* Look for the `void setDataSource (List ds)' method. */ - m_setdataset = (*jvm_env)->GetMethodID (jvm_env, c_valuelist, - "setDataSet", "(Lorg/collectd/api/DataSet;)V"); - if (m_setdataset == NULL) - { - ERROR ("java plugin: ctoj_value_list_add_data_set: " - "Cannot find the `void setDataSet (DataSet)' method."); + m_setdataset = (*jvm_env)->GetMethodID(jvm_env, c_valuelist, "setDataSet", + "(Lorg/collectd/api/DataSet;)V"); + if (m_setdataset == NULL) { + ERROR("java plugin: ctoj_value_list_add_data_set: " + "Cannot find the `void setDataSet (DataSet)' method."); return (-1); } /* Create a DataSet object. */ - o_dataset = ctoj_data_set (jvm_env, ds); - if (o_dataset == NULL) - { - ERROR ("java plugin: ctoj_value_list_add_data_set: " - "ctoj_data_set (%s) failed.", ds->type); + o_dataset = ctoj_data_set(jvm_env, ds); + if (o_dataset == NULL) { + ERROR("java plugin: ctoj_value_list_add_data_set: " + "ctoj_data_set (%s) failed.", + ds->type); return (-1); } /* Actually call the method. */ - (*jvm_env)->CallVoidMethod (jvm_env, - o_valuelist, m_setdataset, o_dataset); + (*jvm_env)->CallVoidMethod(jvm_env, o_valuelist, m_setdataset, o_dataset); /* Decrease reference counter on the List object. */ - (*jvm_env)->DeleteLocalRef (jvm_env, o_dataset); + (*jvm_env)->DeleteLocalRef(jvm_env, o_dataset); return (0); } /* }}} int ctoj_value_list_add_data_set */ /* Convert a value_list_t (and data_set_t) to a org/collectd/api/ValueList */ -static jobject ctoj_value_list (JNIEnv *jvm_env, /* {{{ */ - const data_set_t *ds, const value_list_t *vl) -{ +static jobject ctoj_value_list(JNIEnv *jvm_env, /* {{{ */ + const data_set_t *ds, const value_list_t *vl) { jclass c_valuelist; jmethodID m_valuelist_constructor; jobject o_valuelist; @@ -764,94 +697,84 @@ static jobject ctoj_value_list (JNIEnv *jvm_env, /* {{{ */ /* First, create a new ValueList instance.. * Look up the class.. */ - c_valuelist = (*jvm_env)->FindClass (jvm_env, - "org/collectd/api/ValueList"); - if (c_valuelist == NULL) - { - ERROR ("java plugin: ctoj_value_list: " - "FindClass (org/collectd/api/ValueList) failed."); + c_valuelist = (*jvm_env)->FindClass(jvm_env, "org/collectd/api/ValueList"); + if (c_valuelist == NULL) { + ERROR("java plugin: ctoj_value_list: " + "FindClass (org/collectd/api/ValueList) failed."); return (NULL); } /* Lookup the `ValueList ()' constructor. */ - m_valuelist_constructor = (*jvm_env)->GetMethodID (jvm_env, c_valuelist, - "", "()V"); - if (m_valuelist_constructor == NULL) - { - ERROR ("java plugin: ctoj_value_list: Cannot find the " - "`ValueList ()' constructor."); + m_valuelist_constructor = + (*jvm_env)->GetMethodID(jvm_env, c_valuelist, "", "()V"); + if (m_valuelist_constructor == NULL) { + ERROR("java plugin: ctoj_value_list: Cannot find the " + "`ValueList ()' constructor."); return (NULL); } /* Create a new instance. */ - o_valuelist = (*jvm_env)->NewObject (jvm_env, c_valuelist, - m_valuelist_constructor); - if (o_valuelist == NULL) - { - ERROR ("java plugin: ctoj_value_list: Creating a new ValueList instance " - "failed."); + o_valuelist = + (*jvm_env)->NewObject(jvm_env, c_valuelist, m_valuelist_constructor); + if (o_valuelist == NULL) { + ERROR("java plugin: ctoj_value_list: Creating a new ValueList instance " + "failed."); return (NULL); } - status = ctoj_value_list_add_data_set (jvm_env, - c_valuelist, o_valuelist, ds); - if (status != 0) - { - ERROR ("java plugin: ctoj_value_list: " - "ctoj_value_list_add_data_set failed."); - (*jvm_env)->DeleteLocalRef (jvm_env, o_valuelist); + status = ctoj_value_list_add_data_set(jvm_env, c_valuelist, o_valuelist, ds); + if (status != 0) { + ERROR("java plugin: ctoj_value_list: " + "ctoj_value_list_add_data_set failed."); + (*jvm_env)->DeleteLocalRef(jvm_env, o_valuelist); return (NULL); } - /* Set the strings.. */ -#define SET_STRING(str,method_name) do { \ - status = ctoj_string (jvm_env, str, \ - c_valuelist, o_valuelist, method_name); \ - if (status != 0) { \ - ERROR ("java plugin: ctoj_value_list: ctoj_string (%s) failed.", \ - method_name); \ - (*jvm_env)->DeleteLocalRef (jvm_env, o_valuelist); \ - return (NULL); \ - } } while (0) - - SET_STRING (vl->host, "setHost"); - SET_STRING (vl->plugin, "setPlugin"); - SET_STRING (vl->plugin_instance, "setPluginInstance"); - SET_STRING (vl->type, "setType"); - SET_STRING (vl->type_instance, "setTypeInstance"); +/* Set the strings.. */ +#define SET_STRING(str, method_name) \ + do { \ + status = ctoj_string(jvm_env, str, c_valuelist, o_valuelist, method_name); \ + if (status != 0) { \ + ERROR("java plugin: ctoj_value_list: ctoj_string (%s) failed.", \ + method_name); \ + (*jvm_env)->DeleteLocalRef(jvm_env, o_valuelist); \ + return (NULL); \ + } \ + } while (0) + + SET_STRING(vl->host, "setHost"); + SET_STRING(vl->plugin, "setPlugin"); + SET_STRING(vl->plugin_instance, "setPluginInstance"); + SET_STRING(vl->type, "setType"); + SET_STRING(vl->type_instance, "setTypeInstance"); #undef SET_STRING /* Set the `time' member. Java stores time in milliseconds. */ - status = ctoj_long (jvm_env, (jlong) CDTIME_T_TO_MS (vl->time), - c_valuelist, o_valuelist, "setTime"); - if (status != 0) - { - ERROR ("java plugin: ctoj_value_list: ctoj_long (setTime) failed."); - (*jvm_env)->DeleteLocalRef (jvm_env, o_valuelist); + status = ctoj_long(jvm_env, (jlong)CDTIME_T_TO_MS(vl->time), c_valuelist, + o_valuelist, "setTime"); + if (status != 0) { + ERROR("java plugin: ctoj_value_list: ctoj_long (setTime) failed."); + (*jvm_env)->DeleteLocalRef(jvm_env, o_valuelist); return (NULL); } /* Set the `interval' member.. */ - status = ctoj_long (jvm_env, - (jlong) CDTIME_T_TO_MS (vl->interval), - c_valuelist, o_valuelist, "setInterval"); - if (status != 0) - { - ERROR ("java plugin: ctoj_value_list: ctoj_long (setInterval) failed."); - (*jvm_env)->DeleteLocalRef (jvm_env, o_valuelist); + status = ctoj_long(jvm_env, (jlong)CDTIME_T_TO_MS(vl->interval), c_valuelist, + o_valuelist, "setInterval"); + if (status != 0) { + ERROR("java plugin: ctoj_value_list: ctoj_long (setInterval) failed."); + (*jvm_env)->DeleteLocalRef(jvm_env, o_valuelist); return (NULL); } - for (size_t i = 0; i < vl->values_len; i++) - { - status = ctoj_value_list_add_value (jvm_env, vl->values[i], ds->ds[i].type, - c_valuelist, o_valuelist); - if (status != 0) - { - ERROR ("java plugin: ctoj_value_list: " - "ctoj_value_list_add_value failed."); - (*jvm_env)->DeleteLocalRef (jvm_env, o_valuelist); + for (size_t i = 0; i < vl->values_len; i++) { + status = ctoj_value_list_add_value(jvm_env, vl->values[i], ds->ds[i].type, + c_valuelist, o_valuelist); + if (status != 0) { + ERROR("java plugin: ctoj_value_list: " + "ctoj_value_list_add_value failed."); + (*jvm_env)->DeleteLocalRef(jvm_env, o_valuelist); return (NULL); } } @@ -860,9 +783,8 @@ static jobject ctoj_value_list (JNIEnv *jvm_env, /* {{{ */ } /* }}} jobject ctoj_value_list */ /* Convert a notification_t to a org/collectd/api/Notification */ -static jobject ctoj_notification (JNIEnv *jvm_env, /* {{{ */ - const notification_t *n) -{ +static jobject ctoj_notification(JNIEnv *jvm_env, /* {{{ */ + const notification_t *n) { jclass c_notification; jmethodID m_constructor; jobject o_notification; @@ -870,72 +792,69 @@ static jobject ctoj_notification (JNIEnv *jvm_env, /* {{{ */ /* First, create a new Notification instance.. * Look up the class.. */ - c_notification = (*jvm_env)->FindClass (jvm_env, - "org/collectd/api/Notification"); - if (c_notification == NULL) - { - ERROR ("java plugin: ctoj_notification: " - "FindClass (org/collectd/api/Notification) failed."); + c_notification = + (*jvm_env)->FindClass(jvm_env, "org/collectd/api/Notification"); + if (c_notification == NULL) { + ERROR("java plugin: ctoj_notification: " + "FindClass (org/collectd/api/Notification) failed."); return (NULL); } /* Lookup the `Notification ()' constructor. */ - m_constructor = (*jvm_env)->GetMethodID (jvm_env, c_notification, - "", "()V"); - if (m_constructor == NULL) - { - ERROR ("java plugin: ctoj_notification: Cannot find the " - "`Notification ()' constructor."); + m_constructor = + (*jvm_env)->GetMethodID(jvm_env, c_notification, "", "()V"); + if (m_constructor == NULL) { + ERROR("java plugin: ctoj_notification: Cannot find the " + "`Notification ()' constructor."); return (NULL); } /* Create a new instance. */ - o_notification = (*jvm_env)->NewObject (jvm_env, c_notification, - m_constructor); - if (o_notification == NULL) - { - ERROR ("java plugin: ctoj_notification: Creating a new Notification " - "instance failed."); + o_notification = + (*jvm_env)->NewObject(jvm_env, c_notification, m_constructor); + if (o_notification == NULL) { + ERROR("java plugin: ctoj_notification: Creating a new Notification " + "instance failed."); return (NULL); } - /* Set the strings.. */ -#define SET_STRING(str,method_name) do { \ - status = ctoj_string (jvm_env, str, \ - c_notification, o_notification, method_name); \ - if (status != 0) { \ - ERROR ("java plugin: ctoj_notification: ctoj_string (%s) failed.", \ - method_name); \ - (*jvm_env)->DeleteLocalRef (jvm_env, o_notification); \ - return (NULL); \ - } } while (0) - - SET_STRING (n->host, "setHost"); - SET_STRING (n->plugin, "setPlugin"); - SET_STRING (n->plugin_instance, "setPluginInstance"); - SET_STRING (n->type, "setType"); - SET_STRING (n->type_instance, "setTypeInstance"); - SET_STRING (n->message, "setMessage"); +/* Set the strings.. */ +#define SET_STRING(str, method_name) \ + do { \ + status = ctoj_string(jvm_env, str, c_notification, o_notification, \ + method_name); \ + if (status != 0) { \ + ERROR("java plugin: ctoj_notification: ctoj_string (%s) failed.", \ + method_name); \ + (*jvm_env)->DeleteLocalRef(jvm_env, o_notification); \ + return (NULL); \ + } \ + } while (0) + + SET_STRING(n->host, "setHost"); + SET_STRING(n->plugin, "setPlugin"); + SET_STRING(n->plugin_instance, "setPluginInstance"); + SET_STRING(n->type, "setType"); + SET_STRING(n->type_instance, "setTypeInstance"); + SET_STRING(n->message, "setMessage"); #undef SET_STRING /* Set the `time' member. Java stores time in milliseconds. */ - status = ctoj_long (jvm_env, (jlong) CDTIME_T_TO_MS (n->time), - c_notification, o_notification, "setTime"); - if (status != 0) - { - ERROR ("java plugin: ctoj_notification: ctoj_long (setTime) failed."); - (*jvm_env)->DeleteLocalRef (jvm_env, o_notification); + status = ctoj_long(jvm_env, (jlong)CDTIME_T_TO_MS(n->time), c_notification, + o_notification, "setTime"); + if (status != 0) { + ERROR("java plugin: ctoj_notification: ctoj_long (setTime) failed."); + (*jvm_env)->DeleteLocalRef(jvm_env, o_notification); return (NULL); } /* Set the `severity' member.. */ - status = ctoj_int (jvm_env, (jint) n->severity, - c_notification, o_notification, "setSeverity"); - if (status != 0) - { - ERROR ("java plugin: ctoj_notification: ctoj_int (setSeverity) failed."); - (*jvm_env)->DeleteLocalRef (jvm_env, o_notification); + status = ctoj_int(jvm_env, (jint)n->severity, c_notification, o_notification, + "setSeverity"); + if (status != 0) { + ERROR("java plugin: ctoj_notification: ctoj_int (setSeverity) failed."); + (*jvm_env)->DeleteLocalRef(jvm_env, o_notification); return (NULL); } @@ -946,156 +865,135 @@ static jobject ctoj_notification (JNIEnv *jvm_env, /* {{{ */ * Java to C conversion functions */ /* Call a `String ()' method. */ -static int jtoc_string (JNIEnv *jvm_env, /* {{{ */ - char *buffer, size_t buffer_size, int empty_okay, - jclass class_ptr, jobject object_ptr, const char *method_name) -{ +static int jtoc_string(JNIEnv *jvm_env, /* {{{ */ + char *buffer, size_t buffer_size, int empty_okay, + jclass class_ptr, jobject object_ptr, + const char *method_name) { jmethodID method_id; jobject string_obj; const char *c_str; - method_id = (*jvm_env)->GetMethodID (jvm_env, class_ptr, - method_name, "()Ljava/lang/String;"); - if (method_id == NULL) - { - ERROR ("java plugin: jtoc_string: Cannot find method `String %s ()'.", - method_name); + method_id = (*jvm_env)->GetMethodID(jvm_env, class_ptr, method_name, + "()Ljava/lang/String;"); + if (method_id == NULL) { + ERROR("java plugin: jtoc_string: Cannot find method `String %s ()'.", + method_name); return (-1); } - string_obj = (*jvm_env)->CallObjectMethod (jvm_env, object_ptr, method_id); - if ((string_obj == NULL) && (empty_okay == 0)) - { - ERROR ("java plugin: jtoc_string: CallObjectMethod (%s) failed.", - method_name); + string_obj = (*jvm_env)->CallObjectMethod(jvm_env, object_ptr, method_id); + if ((string_obj == NULL) && (empty_okay == 0)) { + ERROR("java plugin: jtoc_string: CallObjectMethod (%s) failed.", + method_name); return (-1); - } - else if ((string_obj == NULL) && (empty_okay != 0)) - { - memset (buffer, 0, buffer_size); + } else if ((string_obj == NULL) && (empty_okay != 0)) { + memset(buffer, 0, buffer_size); return (0); } - c_str = (*jvm_env)->GetStringUTFChars (jvm_env, string_obj, 0); - if (c_str == NULL) - { - ERROR ("java plugin: jtoc_string: GetStringUTFChars failed."); - (*jvm_env)->DeleteLocalRef (jvm_env, string_obj); + c_str = (*jvm_env)->GetStringUTFChars(jvm_env, string_obj, 0); + if (c_str == NULL) { + ERROR("java plugin: jtoc_string: GetStringUTFChars failed."); + (*jvm_env)->DeleteLocalRef(jvm_env, string_obj); return (-1); } - sstrncpy (buffer, c_str, buffer_size); + sstrncpy(buffer, c_str, buffer_size); - (*jvm_env)->ReleaseStringUTFChars (jvm_env, string_obj, c_str); - (*jvm_env)->DeleteLocalRef (jvm_env, string_obj); + (*jvm_env)->ReleaseStringUTFChars(jvm_env, string_obj, c_str); + (*jvm_env)->DeleteLocalRef(jvm_env, string_obj); return (0); } /* }}} int jtoc_string */ /* Call an `int ()' method. */ -static int jtoc_int (JNIEnv *jvm_env, /* {{{ */ - jint *ret_value, - jclass class_ptr, jobject object_ptr, const char *method_name) -{ +static int jtoc_int(JNIEnv *jvm_env, /* {{{ */ + jint *ret_value, jclass class_ptr, jobject object_ptr, + const char *method_name) { jmethodID method_id; - method_id = (*jvm_env)->GetMethodID (jvm_env, class_ptr, - method_name, "()I"); - if (method_id == NULL) - { - ERROR ("java plugin: jtoc_int: Cannot find method `int %s ()'.", - method_name); + method_id = (*jvm_env)->GetMethodID(jvm_env, class_ptr, method_name, "()I"); + if (method_id == NULL) { + ERROR("java plugin: jtoc_int: Cannot find method `int %s ()'.", + method_name); return (-1); } - *ret_value = (*jvm_env)->CallIntMethod (jvm_env, object_ptr, method_id); + *ret_value = (*jvm_env)->CallIntMethod(jvm_env, object_ptr, method_id); return (0); } /* }}} int jtoc_int */ /* Call a `long ()' method. */ -static int jtoc_long (JNIEnv *jvm_env, /* {{{ */ - jlong *ret_value, - jclass class_ptr, jobject object_ptr, const char *method_name) -{ +static int jtoc_long(JNIEnv *jvm_env, /* {{{ */ + jlong *ret_value, jclass class_ptr, jobject object_ptr, + const char *method_name) { jmethodID method_id; - method_id = (*jvm_env)->GetMethodID (jvm_env, class_ptr, - method_name, "()J"); - if (method_id == NULL) - { - ERROR ("java plugin: jtoc_long: Cannot find method `long %s ()'.", - method_name); + method_id = (*jvm_env)->GetMethodID(jvm_env, class_ptr, method_name, "()J"); + if (method_id == NULL) { + ERROR("java plugin: jtoc_long: Cannot find method `long %s ()'.", + method_name); return (-1); } - *ret_value = (*jvm_env)->CallLongMethod (jvm_env, object_ptr, method_id); + *ret_value = (*jvm_env)->CallLongMethod(jvm_env, object_ptr, method_id); return (0); } /* }}} int jtoc_long */ /* Call a `double ()' method. */ -static int jtoc_double (JNIEnv *jvm_env, /* {{{ */ - jdouble *ret_value, - jclass class_ptr, jobject object_ptr, const char *method_name) -{ +static int jtoc_double(JNIEnv *jvm_env, /* {{{ */ + jdouble *ret_value, jclass class_ptr, jobject object_ptr, + const char *method_name) { jmethodID method_id; - method_id = (*jvm_env)->GetMethodID (jvm_env, class_ptr, - method_name, "()D"); - if (method_id == NULL) - { - ERROR ("java plugin: jtoc_double: Cannot find method `double %s ()'.", - method_name); + method_id = (*jvm_env)->GetMethodID(jvm_env, class_ptr, method_name, "()D"); + if (method_id == NULL) { + ERROR("java plugin: jtoc_double: Cannot find method `double %s ()'.", + method_name); return (-1); } - *ret_value = (*jvm_env)->CallDoubleMethod (jvm_env, object_ptr, method_id); + *ret_value = (*jvm_env)->CallDoubleMethod(jvm_env, object_ptr, method_id); return (0); } /* }}} int jtoc_double */ -static int jtoc_value (JNIEnv *jvm_env, /* {{{ */ - value_t *ret_value, int ds_type, jobject object_ptr) -{ +static int jtoc_value(JNIEnv *jvm_env, /* {{{ */ + value_t *ret_value, int ds_type, jobject object_ptr) { jclass class_ptr; int status; - class_ptr = (*jvm_env)->GetObjectClass (jvm_env, object_ptr); + class_ptr = (*jvm_env)->GetObjectClass(jvm_env, object_ptr); - if (ds_type == DS_TYPE_GAUGE) - { + if (ds_type == DS_TYPE_GAUGE) { jdouble tmp_double; - status = jtoc_double (jvm_env, &tmp_double, - class_ptr, object_ptr, "doubleValue"); - if (status != 0) - { - ERROR ("java plugin: jtoc_value: " - "jtoc_double failed."); + status = + jtoc_double(jvm_env, &tmp_double, class_ptr, object_ptr, "doubleValue"); + if (status != 0) { + ERROR("java plugin: jtoc_value: " + "jtoc_double failed."); return (-1); } - (*ret_value).gauge = (gauge_t) tmp_double; - } - else - { + (*ret_value).gauge = (gauge_t)tmp_double; + } else { jlong tmp_long; - status = jtoc_long (jvm_env, &tmp_long, - class_ptr, object_ptr, "longValue"); - if (status != 0) - { - ERROR ("java plugin: jtoc_value: " - "jtoc_long failed."); + status = jtoc_long(jvm_env, &tmp_long, class_ptr, object_ptr, "longValue"); + if (status != 0) { + ERROR("java plugin: jtoc_value: " + "jtoc_long failed."); return (-1); } if (ds_type == DS_TYPE_DERIVE) - (*ret_value).derive = (derive_t) tmp_long; + (*ret_value).derive = (derive_t)tmp_long; else if (ds_type == DS_TYPE_ABSOLUTE) - (*ret_value).absolute = (absolute_t) tmp_long; + (*ret_value).absolute = (absolute_t)tmp_long; else - (*ret_value).counter = (counter_t) tmp_long; + (*ret_value).counter = (counter_t)tmp_long; } return (0); @@ -1103,10 +1001,9 @@ static int jtoc_value (JNIEnv *jvm_env, /* {{{ */ /* Read a List, convert it to `value_t' and add it to the given * `value_list_t'. */ -static int jtoc_values_array (JNIEnv *jvm_env, /* {{{ */ - const data_set_t *ds, value_list_t *vl, - jclass class_ptr, jobject object_ptr) -{ +static int jtoc_values_array(JNIEnv *jvm_env, /* {{{ */ + const data_set_t *ds, value_list_t *vl, + jclass class_ptr, jobject object_ptr) { jmethodID m_getvalues; jmethodID m_toarray; jobject o_list; @@ -1121,78 +1018,72 @@ static int jtoc_values_array (JNIEnv *jvm_env, /* {{{ */ o_number_array = NULL; o_list = NULL; -#define BAIL_OUT(status) \ - free (values); \ - if (o_number_array != NULL) \ - (*jvm_env)->DeleteLocalRef (jvm_env, o_number_array); \ - if (o_list != NULL) \ - (*jvm_env)->DeleteLocalRef (jvm_env, o_list); \ +#define BAIL_OUT(status) \ + free(values); \ + if (o_number_array != NULL) \ + (*jvm_env)->DeleteLocalRef(jvm_env, o_number_array); \ + if (o_list != NULL) \ + (*jvm_env)->DeleteLocalRef(jvm_env, o_list); \ return (status); /* Call: List ValueList.getValues () */ - m_getvalues = (*jvm_env)->GetMethodID (jvm_env, class_ptr, - "getValues", "()Ljava/util/List;"); - if (m_getvalues == NULL) - { - ERROR ("java plugin: jtoc_values_array: " - "Cannot find method `List getValues ()'."); - BAIL_OUT (-1); + m_getvalues = (*jvm_env)->GetMethodID(jvm_env, class_ptr, "getValues", + "()Ljava/util/List;"); + if (m_getvalues == NULL) { + ERROR("java plugin: jtoc_values_array: " + "Cannot find method `List getValues ()'."); + BAIL_OUT(-1); } - o_list = (*jvm_env)->CallObjectMethod (jvm_env, object_ptr, m_getvalues); - if (o_list == NULL) - { - ERROR ("java plugin: jtoc_values_array: " - "CallObjectMethod (getValues) failed."); - BAIL_OUT (-1); + o_list = (*jvm_env)->CallObjectMethod(jvm_env, object_ptr, m_getvalues); + if (o_list == NULL) { + ERROR("java plugin: jtoc_values_array: " + "CallObjectMethod (getValues) failed."); + BAIL_OUT(-1); } /* Call: Number[] List.toArray () */ - m_toarray = (*jvm_env)->GetMethodID (jvm_env, - (*jvm_env)->GetObjectClass (jvm_env, o_list), - "toArray", "()[Ljava/lang/Object;"); - if (m_toarray == NULL) - { - ERROR ("java plugin: jtoc_values_array: " - "Cannot find method `Object[] toArray ()'."); - BAIL_OUT (-1); + m_toarray = (*jvm_env)->GetMethodID( + jvm_env, (*jvm_env)->GetObjectClass(jvm_env, o_list), "toArray", + "()[Ljava/lang/Object;"); + if (m_toarray == NULL) { + ERROR("java plugin: jtoc_values_array: " + "Cannot find method `Object[] toArray ()'."); + BAIL_OUT(-1); } - o_number_array = (*jvm_env)->CallObjectMethod (jvm_env, o_list, m_toarray); - if (o_number_array == NULL) - { - ERROR ("java plugin: jtoc_values_array: " - "CallObjectMethod (toArray) failed."); - BAIL_OUT (-1); + o_number_array = (*jvm_env)->CallObjectMethod(jvm_env, o_list, m_toarray); + if (o_number_array == NULL) { + ERROR("java plugin: jtoc_values_array: " + "CallObjectMethod (toArray) failed."); + BAIL_OUT(-1); } - values = (value_t *) calloc (values_num, sizeof (value_t)); - if (values == NULL) - { - ERROR ("java plugin: jtoc_values_array: calloc failed."); - BAIL_OUT (-1); + values = (value_t *)calloc(values_num, sizeof(value_t)); + if (values == NULL) { + ERROR("java plugin: jtoc_values_array: calloc failed."); + BAIL_OUT(-1); } - for (int i = 0; i < values_num; i++) - { + for (int i = 0; i < values_num; i++) { jobject o_number; int status; - o_number = (*jvm_env)->GetObjectArrayElement (jvm_env, - o_number_array, (jsize) i); - if (o_number == NULL) - { - ERROR ("java plugin: jtoc_values_array: " - "GetObjectArrayElement (%i) failed.", i); - BAIL_OUT (-1); + o_number = + (*jvm_env)->GetObjectArrayElement(jvm_env, o_number_array, (jsize)i); + if (o_number == NULL) { + ERROR("java plugin: jtoc_values_array: " + "GetObjectArrayElement (%i) failed.", + i); + BAIL_OUT(-1); } - status = jtoc_value (jvm_env, values + i, ds->ds[i].type, o_number); - if (status != 0) - { - ERROR ("java plugin: jtoc_values_array: " - "jtoc_value (%i) failed.", i); - BAIL_OUT (-1); + status = jtoc_value(jvm_env, values + i, ds->ds[i].type, o_number); + if (status != 0) { + ERROR("java plugin: jtoc_values_array: " + "jtoc_value (%i) failed.", + i); + BAIL_OUT(-1); } } /* for (i = 0; i < values_num; i++) */ @@ -1200,77 +1091,71 @@ static int jtoc_values_array (JNIEnv *jvm_env, /* {{{ */ vl->values_len = values_num; #undef BAIL_OUT - (*jvm_env)->DeleteLocalRef (jvm_env, o_number_array); - (*jvm_env)->DeleteLocalRef (jvm_env, o_list); + (*jvm_env)->DeleteLocalRef(jvm_env, o_number_array); + (*jvm_env)->DeleteLocalRef(jvm_env, o_list); return (0); } /* }}} int jtoc_values_array */ /* Convert a org/collectd/api/ValueList to a value_list_t. */ -static int jtoc_value_list (JNIEnv *jvm_env, value_list_t *vl, /* {{{ */ - jobject object_ptr) -{ +static int jtoc_value_list(JNIEnv *jvm_env, value_list_t *vl, /* {{{ */ + jobject object_ptr) { jclass class_ptr; int status; jlong tmp_long; const data_set_t *ds; - class_ptr = (*jvm_env)->GetObjectClass (jvm_env, object_ptr); - if (class_ptr == NULL) - { - ERROR ("java plugin: jtoc_value_list: GetObjectClass failed."); + class_ptr = (*jvm_env)->GetObjectClass(jvm_env, object_ptr); + if (class_ptr == NULL) { + ERROR("java plugin: jtoc_value_list: GetObjectClass failed."); return (-1); } - /* eo == empty okay */ -#define SET_STRING(buffer,method, eo) do { \ - status = jtoc_string (jvm_env, buffer, sizeof (buffer), eo, \ - class_ptr, object_ptr, method); \ - if (status != 0) { \ - ERROR ("java plugin: jtoc_value_list: jtoc_string (%s) failed.", \ - method); \ - return (-1); \ - } } while (0) +/* eo == empty okay */ +#define SET_STRING(buffer, method, eo) \ + do { \ + status = jtoc_string(jvm_env, buffer, sizeof(buffer), eo, class_ptr, \ + object_ptr, method); \ + if (status != 0) { \ + ERROR("java plugin: jtoc_value_list: jtoc_string (%s) failed.", method); \ + return (-1); \ + } \ + } while (0) SET_STRING(vl->type, "getType", /* empty = */ 0); - ds = plugin_get_ds (vl->type); - if (ds == NULL) - { - ERROR ("java plugin: jtoc_value_list: Data-set `%s' is not defined. " - "Please consult the types.db(5) manpage for mor information.", - vl->type); + ds = plugin_get_ds(vl->type); + if (ds == NULL) { + ERROR("java plugin: jtoc_value_list: Data-set `%s' is not defined. " + "Please consult the types.db(5) manpage for mor information.", + vl->type); return (-1); } - SET_STRING(vl->host, "getHost", /* empty = */ 0); - SET_STRING(vl->plugin, "getPlugin", /* empty = */ 0); + SET_STRING(vl->host, "getHost", /* empty = */ 0); + SET_STRING(vl->plugin, "getPlugin", /* empty = */ 0); SET_STRING(vl->plugin_instance, "getPluginInstance", /* empty = */ 1); - SET_STRING(vl->type_instance, "getTypeInstance", /* empty = */ 1); + SET_STRING(vl->type_instance, "getTypeInstance", /* empty = */ 1); #undef SET_STRING - status = jtoc_long (jvm_env, &tmp_long, class_ptr, object_ptr, "getTime"); - if (status != 0) - { - ERROR ("java plugin: jtoc_value_list: jtoc_long (getTime) failed."); + status = jtoc_long(jvm_env, &tmp_long, class_ptr, object_ptr, "getTime"); + if (status != 0) { + ERROR("java plugin: jtoc_value_list: jtoc_long (getTime) failed."); return (-1); } /* Java measures time in milliseconds. */ - vl->time = MS_TO_CDTIME_T (tmp_long); + vl->time = MS_TO_CDTIME_T(tmp_long); - status = jtoc_long (jvm_env, &tmp_long, - class_ptr, object_ptr, "getInterval"); - if (status != 0) - { - ERROR ("java plugin: jtoc_value_list: jtoc_long (getInterval) failed."); + status = jtoc_long(jvm_env, &tmp_long, class_ptr, object_ptr, "getInterval"); + if (status != 0) { + ERROR("java plugin: jtoc_value_list: jtoc_long (getInterval) failed."); return (-1); } - vl->interval = MS_TO_CDTIME_T (tmp_long); + vl->interval = MS_TO_CDTIME_T(tmp_long); - status = jtoc_values_array (jvm_env, ds, vl, class_ptr, object_ptr); - if (status != 0) - { - ERROR ("java plugin: jtoc_value_list: jtoc_values_array failed."); + status = jtoc_values_array(jvm_env, ds, vl, class_ptr, object_ptr); + if (status != 0) { + ERROR("java plugin: jtoc_value_list: jtoc_values_array failed."); return (-1); } @@ -1278,342 +1163,331 @@ static int jtoc_value_list (JNIEnv *jvm_env, value_list_t *vl, /* {{{ */ } /* }}} int jtoc_value_list */ /* Convert a org/collectd/api/Notification to a notification_t. */ -static int jtoc_notification (JNIEnv *jvm_env, notification_t *n, /* {{{ */ - jobject object_ptr) -{ +static int jtoc_notification(JNIEnv *jvm_env, notification_t *n, /* {{{ */ + jobject object_ptr) { jclass class_ptr; int status; jlong tmp_long; jint tmp_int; - class_ptr = (*jvm_env)->GetObjectClass (jvm_env, object_ptr); - if (class_ptr == NULL) - { - ERROR ("java plugin: jtoc_notification: GetObjectClass failed."); + class_ptr = (*jvm_env)->GetObjectClass(jvm_env, object_ptr); + if (class_ptr == NULL) { + ERROR("java plugin: jtoc_notification: GetObjectClass failed."); return (-1); } - /* eo == empty okay */ -#define SET_STRING(buffer,method, eo) do { \ - status = jtoc_string (jvm_env, buffer, sizeof (buffer), eo, \ - class_ptr, object_ptr, method); \ - if (status != 0) { \ - ERROR ("java plugin: jtoc_notification: jtoc_string (%s) failed.", \ - method); \ - return (-1); \ - } } while (0) +/* eo == empty okay */ +#define SET_STRING(buffer, method, eo) \ + do { \ + status = jtoc_string(jvm_env, buffer, sizeof(buffer), eo, class_ptr, \ + object_ptr, method); \ + if (status != 0) { \ + ERROR("java plugin: jtoc_notification: jtoc_string (%s) failed.", \ + method); \ + return (-1); \ + } \ + } while (0) - SET_STRING (n->host, "getHost", /* empty = */ 1); - SET_STRING (n->plugin, "getPlugin", /* empty = */ 1); - SET_STRING (n->plugin_instance, "getPluginInstance", /* empty = */ 1); - SET_STRING (n->type, "getType", /* empty = */ 1); - SET_STRING (n->type_instance, "getTypeInstance", /* empty = */ 1); - SET_STRING (n->message, "getMessage", /* empty = */ 0); + SET_STRING(n->host, "getHost", /* empty = */ 1); + SET_STRING(n->plugin, "getPlugin", /* empty = */ 1); + SET_STRING(n->plugin_instance, "getPluginInstance", /* empty = */ 1); + SET_STRING(n->type, "getType", /* empty = */ 1); + SET_STRING(n->type_instance, "getTypeInstance", /* empty = */ 1); + SET_STRING(n->message, "getMessage", /* empty = */ 0); #undef SET_STRING - status = jtoc_long (jvm_env, &tmp_long, class_ptr, object_ptr, "getTime"); - if (status != 0) - { - ERROR ("java plugin: jtoc_notification: jtoc_long (getTime) failed."); + status = jtoc_long(jvm_env, &tmp_long, class_ptr, object_ptr, "getTime"); + if (status != 0) { + ERROR("java plugin: jtoc_notification: jtoc_long (getTime) failed."); return (-1); } /* Java measures time in milliseconds. */ n->time = MS_TO_CDTIME_T(tmp_long); - status = jtoc_int (jvm_env, &tmp_int, - class_ptr, object_ptr, "getSeverity"); - if (status != 0) - { - ERROR ("java plugin: jtoc_notification: jtoc_int (getSeverity) failed."); + status = jtoc_int(jvm_env, &tmp_int, class_ptr, object_ptr, "getSeverity"); + if (status != 0) { + ERROR("java plugin: jtoc_notification: jtoc_int (getSeverity) failed."); return (-1); } - n->severity = (int) tmp_int; + n->severity = (int)tmp_int; return (0); } /* }}} int jtoc_notification */ -/* - * Functions accessible from Java - */ -static jint JNICALL cjni_api_dispatch_values (JNIEnv *jvm_env, /* {{{ */ - jobject this, jobject java_vl) -{ + /* + * Functions accessible from Java + */ +static jint JNICALL cjni_api_dispatch_values(JNIEnv *jvm_env, /* {{{ */ + jobject this, jobject java_vl) { value_list_t vl = VALUE_LIST_INIT; int status; - DEBUG ("cjni_api_dispatch_values: java_vl = %p;", (void *) java_vl); + DEBUG("cjni_api_dispatch_values: java_vl = %p;", (void *)java_vl); - status = jtoc_value_list (jvm_env, &vl, java_vl); - if (status != 0) - { - ERROR ("java plugin: cjni_api_dispatch_values: jtoc_value_list failed."); + status = jtoc_value_list(jvm_env, &vl, java_vl); + if (status != 0) { + ERROR("java plugin: cjni_api_dispatch_values: jtoc_value_list failed."); return (-1); } - status = plugin_dispatch_values (&vl); + status = plugin_dispatch_values(&vl); - sfree (vl.values); + sfree(vl.values); return (status); } /* }}} jint cjni_api_dispatch_values */ -static jint JNICALL cjni_api_dispatch_notification (JNIEnv *jvm_env, /* {{{ */ - jobject this, jobject o_notification) -{ - notification_t n = { 0 }; +static jint JNICALL cjni_api_dispatch_notification(JNIEnv *jvm_env, /* {{{ */ + jobject this, + jobject o_notification) { + notification_t n = {0}; int status; - status = jtoc_notification (jvm_env, &n, o_notification); - if (status != 0) - { - ERROR ("java plugin: cjni_api_dispatch_notification: jtoc_notification failed."); + status = jtoc_notification(jvm_env, &n, o_notification); + if (status != 0) { + ERROR("java plugin: cjni_api_dispatch_notification: jtoc_notification " + "failed."); return (-1); } - status = plugin_dispatch_notification (&n); + status = plugin_dispatch_notification(&n); return (status); } /* }}} jint cjni_api_dispatch_notification */ -static jobject JNICALL cjni_api_get_ds (JNIEnv *jvm_env, /* {{{ */ - jobject this, jobject o_string_type) -{ +static jobject JNICALL cjni_api_get_ds(JNIEnv *jvm_env, /* {{{ */ + jobject this, jobject o_string_type) { const char *ds_name; const data_set_t *ds; jobject o_dataset; - ds_name = (*jvm_env)->GetStringUTFChars (jvm_env, o_string_type, 0); - if (ds_name == NULL) - { - ERROR ("java plugin: cjni_api_get_ds: GetStringUTFChars failed."); + ds_name = (*jvm_env)->GetStringUTFChars(jvm_env, o_string_type, 0); + if (ds_name == NULL) { + ERROR("java plugin: cjni_api_get_ds: GetStringUTFChars failed."); return (NULL); } - ds = plugin_get_ds (ds_name); - DEBUG ("java plugin: cjni_api_get_ds: " - "plugin_get_ds (%s) = %p;", ds_name, (void *) ds); + ds = plugin_get_ds(ds_name); + DEBUG("java plugin: cjni_api_get_ds: " + "plugin_get_ds (%s) = %p;", + ds_name, (void *)ds); - (*jvm_env)->ReleaseStringUTFChars (jvm_env, o_string_type, ds_name); + (*jvm_env)->ReleaseStringUTFChars(jvm_env, o_string_type, ds_name); if (ds == NULL) return (NULL); - o_dataset = ctoj_data_set (jvm_env, ds); + o_dataset = ctoj_data_set(jvm_env, ds); return (o_dataset); } /* }}} jint cjni_api_get_ds */ -static jint JNICALL cjni_api_register_config (JNIEnv *jvm_env, /* {{{ */ - jobject this, jobject o_name, jobject o_config) -{ - return (cjni_callback_register (jvm_env, o_name, o_config, CB_TYPE_CONFIG)); +static jint JNICALL cjni_api_register_config(JNIEnv *jvm_env, /* {{{ */ + jobject this, jobject o_name, + jobject o_config) { + return (cjni_callback_register(jvm_env, o_name, o_config, CB_TYPE_CONFIG)); } /* }}} jint cjni_api_register_config */ -static jint JNICALL cjni_api_register_init (JNIEnv *jvm_env, /* {{{ */ - jobject this, jobject o_name, jobject o_config) -{ - return (cjni_callback_register (jvm_env, o_name, o_config, CB_TYPE_INIT)); +static jint JNICALL cjni_api_register_init(JNIEnv *jvm_env, /* {{{ */ + jobject this, jobject o_name, + jobject o_config) { + return (cjni_callback_register(jvm_env, o_name, o_config, CB_TYPE_INIT)); } /* }}} jint cjni_api_register_init */ -static jint JNICALL cjni_api_register_read (JNIEnv *jvm_env, /* {{{ */ - jobject this, jobject o_name, jobject o_read) -{ +static jint JNICALL cjni_api_register_read(JNIEnv *jvm_env, /* {{{ */ + jobject this, jobject o_name, + jobject o_read) { cjni_callback_info_t *cbi; - cbi = cjni_callback_info_create (jvm_env, o_name, o_read, CB_TYPE_READ); + cbi = cjni_callback_info_create(jvm_env, o_name, o_read, CB_TYPE_READ); if (cbi == NULL) return (-1); - DEBUG ("java plugin: Registering new read callback: %s", cbi->name); + DEBUG("java plugin: Registering new read callback: %s", cbi->name); - plugin_register_complex_read (/* group = */ NULL, cbi->name, cjni_read, - /* interval = */ 0, &(user_data_t) { - .data = cbi, - .free_func = cjni_callback_info_destroy, + plugin_register_complex_read( + /* group = */ NULL, cbi->name, cjni_read, + /* interval = */ 0, + &(user_data_t){ + .data = cbi, .free_func = cjni_callback_info_destroy, }); - (*jvm_env)->DeleteLocalRef (jvm_env, o_read); + (*jvm_env)->DeleteLocalRef(jvm_env, o_read); return (0); } /* }}} jint cjni_api_register_read */ -static jint JNICALL cjni_api_register_write (JNIEnv *jvm_env, /* {{{ */ - jobject this, jobject o_name, jobject o_write) -{ +static jint JNICALL cjni_api_register_write(JNIEnv *jvm_env, /* {{{ */ + jobject this, jobject o_name, + jobject o_write) { cjni_callback_info_t *cbi; - cbi = cjni_callback_info_create (jvm_env, o_name, o_write, CB_TYPE_WRITE); + cbi = cjni_callback_info_create(jvm_env, o_name, o_write, CB_TYPE_WRITE); if (cbi == NULL) return (-1); - DEBUG ("java plugin: Registering new write callback: %s", cbi->name); + DEBUG("java plugin: Registering new write callback: %s", cbi->name); - plugin_register_write (cbi->name, cjni_write, &(user_data_t) { - .data = cbi, - .free_func = cjni_callback_info_destroy, + plugin_register_write( + cbi->name, cjni_write, + &(user_data_t){ + .data = cbi, .free_func = cjni_callback_info_destroy, }); - (*jvm_env)->DeleteLocalRef (jvm_env, o_write); + (*jvm_env)->DeleteLocalRef(jvm_env, o_write); return (0); } /* }}} jint cjni_api_register_write */ -static jint JNICALL cjni_api_register_flush (JNIEnv *jvm_env, /* {{{ */ - jobject this, jobject o_name, jobject o_flush) -{ +static jint JNICALL cjni_api_register_flush(JNIEnv *jvm_env, /* {{{ */ + jobject this, jobject o_name, + jobject o_flush) { cjni_callback_info_t *cbi; - cbi = cjni_callback_info_create (jvm_env, o_name, o_flush, CB_TYPE_FLUSH); + cbi = cjni_callback_info_create(jvm_env, o_name, o_flush, CB_TYPE_FLUSH); if (cbi == NULL) return (-1); - DEBUG ("java plugin: Registering new flush callback: %s", cbi->name); + DEBUG("java plugin: Registering new flush callback: %s", cbi->name); - plugin_register_flush (cbi->name, cjni_flush, &(user_data_t) { - .data = cbi, - .free_func = cjni_callback_info_destroy, + plugin_register_flush( + cbi->name, cjni_flush, + &(user_data_t){ + .data = cbi, .free_func = cjni_callback_info_destroy, }); - (*jvm_env)->DeleteLocalRef (jvm_env, o_flush); + (*jvm_env)->DeleteLocalRef(jvm_env, o_flush); return (0); } /* }}} jint cjni_api_register_flush */ -static jint JNICALL cjni_api_register_shutdown (JNIEnv *jvm_env, /* {{{ */ - jobject this, jobject o_name, jobject o_shutdown) -{ - return (cjni_callback_register (jvm_env, o_name, o_shutdown, - CB_TYPE_SHUTDOWN)); +static jint JNICALL cjni_api_register_shutdown(JNIEnv *jvm_env, /* {{{ */ + jobject this, jobject o_name, + jobject o_shutdown) { + return ( + cjni_callback_register(jvm_env, o_name, o_shutdown, CB_TYPE_SHUTDOWN)); } /* }}} jint cjni_api_register_shutdown */ -static jint JNICALL cjni_api_register_log (JNIEnv *jvm_env, /* {{{ */ - jobject this, jobject o_name, jobject o_log) -{ +static jint JNICALL cjni_api_register_log(JNIEnv *jvm_env, /* {{{ */ + jobject this, jobject o_name, + jobject o_log) { cjni_callback_info_t *cbi; - cbi = cjni_callback_info_create (jvm_env, o_name, o_log, CB_TYPE_LOG); + cbi = cjni_callback_info_create(jvm_env, o_name, o_log, CB_TYPE_LOG); if (cbi == NULL) return (-1); - DEBUG ("java plugin: Registering new log callback: %s", cbi->name); + DEBUG("java plugin: Registering new log callback: %s", cbi->name); - plugin_register_log (cbi->name, cjni_log, &(user_data_t) { - .data = cbi, - .free_func = cjni_callback_info_destroy, - }); + plugin_register_log(cbi->name, cjni_log, + &(user_data_t){ + .data = cbi, .free_func = cjni_callback_info_destroy, + }); - (*jvm_env)->DeleteLocalRef (jvm_env, o_log); + (*jvm_env)->DeleteLocalRef(jvm_env, o_log); return (0); } /* }}} jint cjni_api_register_log */ -static jint JNICALL cjni_api_register_notification (JNIEnv *jvm_env, /* {{{ */ - jobject this, jobject o_name, jobject o_notification) -{ +static jint JNICALL cjni_api_register_notification(JNIEnv *jvm_env, /* {{{ */ + jobject this, jobject o_name, + jobject o_notification) { cjni_callback_info_t *cbi; - cbi = cjni_callback_info_create (jvm_env, o_name, o_notification, - CB_TYPE_NOTIFICATION); + cbi = cjni_callback_info_create(jvm_env, o_name, o_notification, + CB_TYPE_NOTIFICATION); if (cbi == NULL) return (-1); - DEBUG ("java plugin: Registering new notification callback: %s", cbi->name); + DEBUG("java plugin: Registering new notification callback: %s", cbi->name); - plugin_register_notification (cbi->name, cjni_notification, &(user_data_t) { - .data = cbi, - .free_func = cjni_callback_info_destroy, + plugin_register_notification( + cbi->name, cjni_notification, + &(user_data_t){ + .data = cbi, .free_func = cjni_callback_info_destroy, }); - (*jvm_env)->DeleteLocalRef (jvm_env, o_notification); + (*jvm_env)->DeleteLocalRef(jvm_env, o_notification); return (0); } /* }}} jint cjni_api_register_notification */ -static jint JNICALL cjni_api_register_match_target (JNIEnv *jvm_env, /* {{{ */ - jobject this, jobject o_name, jobject o_match, int type) -{ +static jint JNICALL cjni_api_register_match_target(JNIEnv *jvm_env, /* {{{ */ + jobject this, jobject o_name, + jobject o_match, int type) { int status; const char *c_name; - c_name = (*jvm_env)->GetStringUTFChars (jvm_env, o_name, 0); - if (c_name == NULL) - { - ERROR ("java plugin: cjni_api_register_match_target: " - "GetStringUTFChars failed."); + c_name = (*jvm_env)->GetStringUTFChars(jvm_env, o_name, 0); + if (c_name == NULL) { + ERROR("java plugin: cjni_api_register_match_target: " + "GetStringUTFChars failed."); return (-1); } - status = cjni_callback_register (jvm_env, o_name, o_match, type); - if (status != 0) - { - (*jvm_env)->ReleaseStringUTFChars (jvm_env, o_name, c_name); + status = cjni_callback_register(jvm_env, o_name, o_match, type); + if (status != 0) { + (*jvm_env)->ReleaseStringUTFChars(jvm_env, o_name, c_name); return (-1); } - if (type == CB_TYPE_MATCH) - { - match_proc_t m_proc = { 0 }; + if (type == CB_TYPE_MATCH) { + match_proc_t m_proc = {0}; - m_proc.create = cjni_match_target_create; + m_proc.create = cjni_match_target_create; m_proc.destroy = cjni_match_target_destroy; - m_proc.match = (void *) cjni_match_target_invoke; + m_proc.match = (void *)cjni_match_target_invoke; - status = fc_register_match (c_name, m_proc); - } - else if (type == CB_TYPE_TARGET) - { - target_proc_t t_proc = { 0 }; + status = fc_register_match(c_name, m_proc); + } else if (type == CB_TYPE_TARGET) { + target_proc_t t_proc = {0}; - t_proc.create = cjni_match_target_create; + t_proc.create = cjni_match_target_create; t_proc.destroy = cjni_match_target_destroy; - t_proc.invoke = cjni_match_target_invoke; + t_proc.invoke = cjni_match_target_invoke; - status = fc_register_target (c_name, t_proc); - } - else - { - ERROR ("java plugin: cjni_api_register_match_target: " - "Don't know whether to create a match or a target."); - (*jvm_env)->ReleaseStringUTFChars (jvm_env, o_name, c_name); + status = fc_register_target(c_name, t_proc); + } else { + ERROR("java plugin: cjni_api_register_match_target: " + "Don't know whether to create a match or a target."); + (*jvm_env)->ReleaseStringUTFChars(jvm_env, o_name, c_name); return (-1); } - if (status != 0) - { - ERROR ("java plugin: cjni_api_register_match_target: " - "%s failed.", - (type == CB_TYPE_MATCH) ? "fc_register_match" : "fc_register_target"); - (*jvm_env)->ReleaseStringUTFChars (jvm_env, o_name, c_name); + if (status != 0) { + ERROR("java plugin: cjni_api_register_match_target: " + "%s failed.", + (type == CB_TYPE_MATCH) ? "fc_register_match" : "fc_register_target"); + (*jvm_env)->ReleaseStringUTFChars(jvm_env, o_name, c_name); return (-1); } - (*jvm_env)->ReleaseStringUTFChars (jvm_env, o_name, c_name); + (*jvm_env)->ReleaseStringUTFChars(jvm_env, o_name, c_name); return (0); } /* }}} jint cjni_api_register_match_target */ -static jint JNICALL cjni_api_register_match (JNIEnv *jvm_env, /* {{{ */ - jobject this, jobject o_name, jobject o_match) -{ - return (cjni_api_register_match_target (jvm_env, this, o_name, o_match, - CB_TYPE_MATCH)); +static jint JNICALL cjni_api_register_match(JNIEnv *jvm_env, /* {{{ */ + jobject this, jobject o_name, + jobject o_match) { + return (cjni_api_register_match_target(jvm_env, this, o_name, o_match, + CB_TYPE_MATCH)); } /* }}} jint cjni_api_register_match */ -static jint JNICALL cjni_api_register_target (JNIEnv *jvm_env, /* {{{ */ - jobject this, jobject o_name, jobject o_target) -{ - return (cjni_api_register_match_target (jvm_env, this, o_name, o_target, - CB_TYPE_TARGET)); +static jint JNICALL cjni_api_register_target(JNIEnv *jvm_env, /* {{{ */ + jobject this, jobject o_name, + jobject o_target) { + return (cjni_api_register_match_target(jvm_env, this, o_name, o_target, + CB_TYPE_TARGET)); } /* }}} jint cjni_api_register_target */ -static void JNICALL cjni_api_log (JNIEnv *jvm_env, /* {{{ */ - jobject this, jint severity, jobject o_message) -{ +static void JNICALL cjni_api_log(JNIEnv *jvm_env, /* {{{ */ + jobject this, jint severity, + jobject o_message) { const char *c_str; - c_str = (*jvm_env)->GetStringUTFChars (jvm_env, o_message, 0); - if (c_str == NULL) - { - ERROR ("java plugin: cjni_api_log: GetStringUTFChars failed."); + c_str = (*jvm_env)->GetStringUTFChars(jvm_env, o_message, 0); + if (c_str == NULL) { + ERROR("java plugin: cjni_api_log: GetStringUTFChars failed."); return; } @@ -1622,83 +1496,75 @@ static void JNICALL cjni_api_log (JNIEnv *jvm_env, /* {{{ */ if (severity > LOG_DEBUG) severity = LOG_DEBUG; - plugin_log (severity, "%s", c_str); + plugin_log(severity, "%s", c_str); - (*jvm_env)->ReleaseStringUTFChars (jvm_env, o_message, c_str); + (*jvm_env)->ReleaseStringUTFChars(jvm_env, o_message, c_str); } /* }}} void cjni_api_log */ -static jstring JNICALL cjni_api_get_hostname (JNIEnv *jvm_env, jobject this) -{ - return ctoj_output_string(jvm_env, hostname_g); +static jstring JNICALL cjni_api_get_hostname(JNIEnv *jvm_env, jobject this) { + return ctoj_output_string(jvm_env, hostname_g); } /* List of ``native'' functions, i. e. C-functions that can be called from * Java. */ static JNINativeMethod jni_api_functions[] = /* {{{ */ -{ - { "dispatchValues", - "(Lorg/collectd/api/ValueList;)I", - cjni_api_dispatch_values }, + { + {"dispatchValues", "(Lorg/collectd/api/ValueList;)I", + cjni_api_dispatch_values}, - { "dispatchNotification", - "(Lorg/collectd/api/Notification;)I", - cjni_api_dispatch_notification }, + {"dispatchNotification", "(Lorg/collectd/api/Notification;)I", + cjni_api_dispatch_notification}, - { "getDS", - "(Ljava/lang/String;)Lorg/collectd/api/DataSet;", - cjni_api_get_ds }, + {"getDS", "(Ljava/lang/String;)Lorg/collectd/api/DataSet;", + cjni_api_get_ds}, - { "registerConfig", - "(Ljava/lang/String;Lorg/collectd/api/CollectdConfigInterface;)I", - cjni_api_register_config }, + {"registerConfig", + "(Ljava/lang/String;Lorg/collectd/api/CollectdConfigInterface;)I", + cjni_api_register_config}, - { "registerInit", - "(Ljava/lang/String;Lorg/collectd/api/CollectdInitInterface;)I", - cjni_api_register_init }, + {"registerInit", + "(Ljava/lang/String;Lorg/collectd/api/CollectdInitInterface;)I", + cjni_api_register_init}, - { "registerRead", - "(Ljava/lang/String;Lorg/collectd/api/CollectdReadInterface;)I", - cjni_api_register_read }, + {"registerRead", + "(Ljava/lang/String;Lorg/collectd/api/CollectdReadInterface;)I", + cjni_api_register_read}, - { "registerWrite", - "(Ljava/lang/String;Lorg/collectd/api/CollectdWriteInterface;)I", - cjni_api_register_write }, + {"registerWrite", + "(Ljava/lang/String;Lorg/collectd/api/CollectdWriteInterface;)I", + cjni_api_register_write}, - { "registerFlush", - "(Ljava/lang/String;Lorg/collectd/api/CollectdFlushInterface;)I", - cjni_api_register_flush }, + {"registerFlush", + "(Ljava/lang/String;Lorg/collectd/api/CollectdFlushInterface;)I", + cjni_api_register_flush}, - { "registerShutdown", - "(Ljava/lang/String;Lorg/collectd/api/CollectdShutdownInterface;)I", - cjni_api_register_shutdown }, + {"registerShutdown", + "(Ljava/lang/String;Lorg/collectd/api/CollectdShutdownInterface;)I", + cjni_api_register_shutdown}, - { "registerLog", - "(Ljava/lang/String;Lorg/collectd/api/CollectdLogInterface;)I", - cjni_api_register_log }, + {"registerLog", + "(Ljava/lang/String;Lorg/collectd/api/CollectdLogInterface;)I", + cjni_api_register_log}, - { "registerNotification", - "(Ljava/lang/String;Lorg/collectd/api/CollectdNotificationInterface;)I", - cjni_api_register_notification }, + {"registerNotification", "(Ljava/lang/String;Lorg/collectd/api/" + "CollectdNotificationInterface;)I", + cjni_api_register_notification}, - { "registerMatch", - "(Ljava/lang/String;Lorg/collectd/api/CollectdMatchFactoryInterface;)I", - cjni_api_register_match }, + {"registerMatch", "(Ljava/lang/String;Lorg/collectd/api/" + "CollectdMatchFactoryInterface;)I", + cjni_api_register_match}, - { "registerTarget", - "(Ljava/lang/String;Lorg/collectd/api/CollectdTargetFactoryInterface;)I", - cjni_api_register_target }, + {"registerTarget", "(Ljava/lang/String;Lorg/collectd/api/" + "CollectdTargetFactoryInterface;)I", + cjni_api_register_target}, - { "log", - "(ILjava/lang/String;)V", - cjni_api_log }, + {"log", "(ILjava/lang/String;)V", cjni_api_log}, - { "getHostname", - "()Ljava/lang/String;", - cjni_api_get_hostname }, + {"getHostname", "()Ljava/lang/String;", cjni_api_get_hostname}, }; -static size_t jni_api_functions_num = sizeof (jni_api_functions) - / sizeof (jni_api_functions[0]); +static size_t jni_api_functions_num = + sizeof(jni_api_functions) / sizeof(jni_api_functions[0]); /* }}} */ /* @@ -1706,132 +1572,124 @@ static size_t jni_api_functions_num = sizeof (jni_api_functions) */ /* Allocate a `cjni_callback_info_t' given the type and objects necessary for * all registration functions. */ -static cjni_callback_info_t *cjni_callback_info_create (JNIEnv *jvm_env, /* {{{ */ - jobject o_name, jobject o_callback, int type) -{ +static cjni_callback_info_t * +cjni_callback_info_create(JNIEnv *jvm_env, /* {{{ */ + jobject o_name, jobject o_callback, int type) { const char *c_name; cjni_callback_info_t *cbi; const char *method_name; const char *method_signature; - switch (type) - { - case CB_TYPE_CONFIG: - method_name = "config"; - method_signature = "(Lorg/collectd/api/OConfigItem;)I"; - break; - - case CB_TYPE_INIT: - method_name = "init"; - method_signature = "()I"; - break; - - case CB_TYPE_READ: - method_name = "read"; - method_signature = "()I"; - break; - - case CB_TYPE_WRITE: - method_name = "write"; - method_signature = "(Lorg/collectd/api/ValueList;)I"; - break; - - case CB_TYPE_FLUSH: - method_name = "flush"; - method_signature = "(Ljava/lang/Number;Ljava/lang/String;)I"; - break; - - case CB_TYPE_SHUTDOWN: - method_name = "shutdown"; - method_signature = "()I"; - break; - - case CB_TYPE_LOG: - method_name = "log"; - method_signature = "(ILjava/lang/String;)V"; - break; - - case CB_TYPE_NOTIFICATION: - method_name = "notification"; - method_signature = "(Lorg/collectd/api/Notification;)I"; - break; - - case CB_TYPE_MATCH: - method_name = "createMatch"; - method_signature = "(Lorg/collectd/api/OConfigItem;)" - "Lorg/collectd/api/CollectdMatchInterface;"; - break; - - case CB_TYPE_TARGET: - method_name = "createTarget"; - method_signature = "(Lorg/collectd/api/OConfigItem;)" - "Lorg/collectd/api/CollectdTargetInterface;"; - break; - - default: - ERROR ("java plugin: cjni_callback_info_create: Unknown type: %#x", - type); - return (NULL); + switch (type) { + case CB_TYPE_CONFIG: + method_name = "config"; + method_signature = "(Lorg/collectd/api/OConfigItem;)I"; + break; + + case CB_TYPE_INIT: + method_name = "init"; + method_signature = "()I"; + break; + + case CB_TYPE_READ: + method_name = "read"; + method_signature = "()I"; + break; + + case CB_TYPE_WRITE: + method_name = "write"; + method_signature = "(Lorg/collectd/api/ValueList;)I"; + break; + + case CB_TYPE_FLUSH: + method_name = "flush"; + method_signature = "(Ljava/lang/Number;Ljava/lang/String;)I"; + break; + + case CB_TYPE_SHUTDOWN: + method_name = "shutdown"; + method_signature = "()I"; + break; + + case CB_TYPE_LOG: + method_name = "log"; + method_signature = "(ILjava/lang/String;)V"; + break; + + case CB_TYPE_NOTIFICATION: + method_name = "notification"; + method_signature = "(Lorg/collectd/api/Notification;)I"; + break; + + case CB_TYPE_MATCH: + method_name = "createMatch"; + method_signature = "(Lorg/collectd/api/OConfigItem;)" + "Lorg/collectd/api/CollectdMatchInterface;"; + break; + + case CB_TYPE_TARGET: + method_name = "createTarget"; + method_signature = "(Lorg/collectd/api/OConfigItem;)" + "Lorg/collectd/api/CollectdTargetInterface;"; + break; + + default: + ERROR("java plugin: cjni_callback_info_create: Unknown type: %#x", type); + return (NULL); } - c_name = (*jvm_env)->GetStringUTFChars (jvm_env, o_name, 0); - if (c_name == NULL) - { - ERROR ("java plugin: cjni_callback_info_create: " - "GetStringUTFChars failed."); + c_name = (*jvm_env)->GetStringUTFChars(jvm_env, o_name, 0); + if (c_name == NULL) { + ERROR("java plugin: cjni_callback_info_create: " + "GetStringUTFChars failed."); return (NULL); } - cbi = calloc (1, sizeof (*cbi)); - if (cbi == NULL) - { - ERROR ("java plugin: cjni_callback_info_create: calloc failed."); - (*jvm_env)->ReleaseStringUTFChars (jvm_env, o_name, c_name); + cbi = calloc(1, sizeof(*cbi)); + if (cbi == NULL) { + ERROR("java plugin: cjni_callback_info_create: calloc failed."); + (*jvm_env)->ReleaseStringUTFChars(jvm_env, o_name, c_name); return (NULL); } cbi->type = type; - cbi->name = strdup (c_name); - if (cbi->name == NULL) - { - pthread_mutex_unlock (&java_callbacks_lock); - ERROR ("java plugin: cjni_callback_info_create: strdup failed."); - (*jvm_env)->ReleaseStringUTFChars (jvm_env, o_name, c_name); - sfree (cbi); + cbi->name = strdup(c_name); + if (cbi->name == NULL) { + pthread_mutex_unlock(&java_callbacks_lock); + ERROR("java plugin: cjni_callback_info_create: strdup failed."); + (*jvm_env)->ReleaseStringUTFChars(jvm_env, o_name, c_name); + sfree(cbi); return (NULL); } - (*jvm_env)->ReleaseStringUTFChars (jvm_env, o_name, c_name); + (*jvm_env)->ReleaseStringUTFChars(jvm_env, o_name, c_name); - cbi->object = (*jvm_env)->NewGlobalRef (jvm_env, o_callback); - if (cbi->object == NULL) - { - ERROR ("java plugin: cjni_callback_info_create: NewGlobalRef failed."); - sfree (cbi->name); - sfree (cbi); + cbi->object = (*jvm_env)->NewGlobalRef(jvm_env, o_callback); + if (cbi->object == NULL) { + ERROR("java plugin: cjni_callback_info_create: NewGlobalRef failed."); + sfree(cbi->name); + sfree(cbi); return (NULL); } - cbi->class = (*jvm_env)->GetObjectClass (jvm_env, cbi->object); - if (cbi->class == NULL) - { - ERROR ("java plugin: cjni_callback_info_create: GetObjectClass failed."); - (*jvm_env)->DeleteGlobalRef (jvm_env, cbi->object); - sfree (cbi->name); - sfree (cbi); + cbi->class = (*jvm_env)->GetObjectClass(jvm_env, cbi->object); + if (cbi->class == NULL) { + ERROR("java plugin: cjni_callback_info_create: GetObjectClass failed."); + (*jvm_env)->DeleteGlobalRef(jvm_env, cbi->object); + sfree(cbi->name); + sfree(cbi); return (NULL); } - cbi->method = (*jvm_env)->GetMethodID (jvm_env, cbi->class, - method_name, method_signature); - if (cbi->method == NULL) - { - ERROR ("java plugin: cjni_callback_info_create: " - "Cannot find the `%s' method with signature `%s'.", - method_name, method_signature); - (*jvm_env)->DeleteGlobalRef (jvm_env, cbi->object); - sfree (cbi->name); - sfree (cbi); + cbi->method = (*jvm_env)->GetMethodID(jvm_env, cbi->class, method_name, + method_signature); + if (cbi->method == NULL) { + ERROR("java plugin: cjni_callback_info_create: " + "Cannot find the `%s' method with signature `%s'.", + method_name, method_signature); + (*jvm_env)->DeleteGlobalRef(jvm_env, cbi->object); + sfree(cbi->name); + sfree(cbi); return (NULL); } @@ -1841,60 +1699,57 @@ static cjni_callback_info_t *cjni_callback_info_create (JNIEnv *jvm_env, /* {{{ /* Allocate a `cjni_callback_info_t' via `cjni_callback_info_create' and add it * to the global `java_callbacks' variable. This is used for `config', `init', * and `shutdown' callbacks. */ -static int cjni_callback_register (JNIEnv *jvm_env, /* {{{ */ - jobject o_name, jobject o_callback, int type) -{ +static int cjni_callback_register(JNIEnv *jvm_env, /* {{{ */ + jobject o_name, jobject o_callback, + int type) { cjni_callback_info_t *cbi; cjni_callback_info_t *tmp; #if COLLECT_DEBUG const char *type_str; #endif - cbi = cjni_callback_info_create (jvm_env, o_name, o_callback, type); + cbi = cjni_callback_info_create(jvm_env, o_name, o_callback, type); if (cbi == NULL) return (-1); #if COLLECT_DEBUG - switch (type) - { - case CB_TYPE_CONFIG: - type_str = "config"; - break; + switch (type) { + case CB_TYPE_CONFIG: + type_str = "config"; + break; - case CB_TYPE_INIT: - type_str = "init"; - break; + case CB_TYPE_INIT: + type_str = "init"; + break; - case CB_TYPE_SHUTDOWN: - type_str = "shutdown"; - break; + case CB_TYPE_SHUTDOWN: + type_str = "shutdown"; + break; - case CB_TYPE_MATCH: - type_str = "match"; - break; + case CB_TYPE_MATCH: + type_str = "match"; + break; - case CB_TYPE_TARGET: - type_str = "target"; - break; + case CB_TYPE_TARGET: + type_str = "target"; + break; - default: - type_str = ""; + default: + type_str = ""; } - DEBUG ("java plugin: Registering new %s callback: %s", - type_str, cbi->name); + DEBUG("java plugin: Registering new %s callback: %s", type_str, cbi->name); #endif - pthread_mutex_lock (&java_callbacks_lock); + pthread_mutex_lock(&java_callbacks_lock); - tmp = realloc (java_callbacks, - (java_callbacks_num + 1) * sizeof (*java_callbacks)); - if (tmp == NULL) - { - pthread_mutex_unlock (&java_callbacks_lock); - ERROR ("java plugin: cjni_callback_register: realloc failed."); + tmp = realloc(java_callbacks, + (java_callbacks_num + 1) * sizeof(*java_callbacks)); + if (tmp == NULL) { + pthread_mutex_unlock(&java_callbacks_lock); + ERROR("java plugin: cjni_callback_register: realloc failed."); - (*jvm_env)->DeleteGlobalRef (jvm_env, cbi->object); - free (cbi); + (*jvm_env)->DeleteGlobalRef(jvm_env, cbi->object); + free(cbi); return (-1); } @@ -1902,60 +1757,57 @@ static int cjni_callback_register (JNIEnv *jvm_env, /* {{{ */ java_callbacks[java_callbacks_num] = *cbi; java_callbacks_num++; - pthread_mutex_unlock (&java_callbacks_lock); + pthread_mutex_unlock(&java_callbacks_lock); - free (cbi); + free(cbi); return (0); } /* }}} int cjni_callback_register */ /* Callback for `pthread_key_create'. It frees the data contained in * `jvm_env_key' and prints a warning if the reference counter is not zero. */ -static void cjni_jvm_env_destroy (void *args) /* {{{ */ +static void cjni_jvm_env_destroy(void *args) /* {{{ */ { cjni_jvm_env_t *cjni_env; if (args == NULL) return; - cjni_env = (cjni_jvm_env_t *) args; + cjni_env = (cjni_jvm_env_t *)args; - if (cjni_env->reference_counter > 0) - { - ERROR ("java plugin: cjni_jvm_env_destroy: " - "cjni_env->reference_counter = %i;", cjni_env->reference_counter); + if (cjni_env->reference_counter > 0) { + ERROR("java plugin: cjni_jvm_env_destroy: " + "cjni_env->reference_counter = %i;", + cjni_env->reference_counter); } - if (cjni_env->jvm_env != NULL) - { - ERROR ("java plugin: cjni_jvm_env_destroy: cjni_env->jvm_env = %p;", - (void *) cjni_env->jvm_env); + if (cjni_env->jvm_env != NULL) { + ERROR("java plugin: cjni_jvm_env_destroy: cjni_env->jvm_env = %p;", + (void *)cjni_env->jvm_env); } /* The pointer is allocated in `cjni_thread_attach' */ - free (cjni_env); + free(cjni_env); } /* }}} void cjni_jvm_env_destroy */ /* Register ``native'' functions with the JVM. Native functions are C-functions * that can be called by Java code. */ -static int cjni_init_native (JNIEnv *jvm_env) /* {{{ */ +static int cjni_init_native(JNIEnv *jvm_env) /* {{{ */ { jclass api_class_ptr; int status; - api_class_ptr = (*jvm_env)->FindClass (jvm_env, "org/collectd/api/Collectd"); - if (api_class_ptr == NULL) - { - ERROR ("cjni_init_native: Cannot find the API class \"org.collectd.api" - ".Collectd\". Please set the correct class path " - "using 'JVMArg \"-Djava.class.path=...\"'."); + api_class_ptr = (*jvm_env)->FindClass(jvm_env, "org/collectd/api/Collectd"); + if (api_class_ptr == NULL) { + ERROR("cjni_init_native: Cannot find the API class \"org.collectd.api" + ".Collectd\". Please set the correct class path " + "using 'JVMArg \"-Djava.class.path=...\"'."); return (-1); } - status = (*jvm_env)->RegisterNatives (jvm_env, api_class_ptr, - jni_api_functions, (jint) jni_api_functions_num); - if (status != 0) - { - ERROR ("cjni_init_native: RegisterNatives failed with status %i.", status); + status = (*jvm_env)->RegisterNatives( + jvm_env, api_class_ptr, jni_api_functions, (jint)jni_api_functions_num); + if (status != 0) { + ERROR("cjni_init_native: RegisterNatives failed with status %i.", status); return (-1); } @@ -1964,10 +1816,10 @@ static int cjni_init_native (JNIEnv *jvm_env) /* {{{ */ /* Create the JVM. This is called when the first thread tries to access the JVM * via cjni_thread_attach. */ -static int cjni_create_jvm (void) /* {{{ */ +static int cjni_create_jvm(void) /* {{{ */ { JNIEnv *jvm_env; - JavaVMInitArgs vm_args = { 0 }; + JavaVMInitArgs vm_args = {0}; JavaVMOption vm_options[jvm_argc]; int status; @@ -1975,11 +1827,11 @@ static int cjni_create_jvm (void) /* {{{ */ if (jvm != NULL) return (0); - status = pthread_key_create (&jvm_env_key, cjni_jvm_env_destroy); - if (status != 0) - { - ERROR ("java plugin: cjni_create_jvm: pthread_key_create failed " - "with status %i.", status); + status = pthread_key_create(&jvm_env_key, cjni_jvm_env_destroy); + if (status != 0) { + ERROR("java plugin: cjni_create_jvm: pthread_key_create failed " + "with status %i.", + status); return (-1); } @@ -1987,95 +1839,84 @@ static int cjni_create_jvm (void) /* {{{ */ vm_args.version = JNI_VERSION_1_2; vm_args.options = vm_options; - vm_args.nOptions = (jint) jvm_argc; + vm_args.nOptions = (jint)jvm_argc; - for (size_t i = 0; i < jvm_argc; i++) - { - DEBUG ("java plugin: cjni_create_jvm: jvm_argv[%zu] = %s", - i, jvm_argv[i]); + for (size_t i = 0; i < jvm_argc; i++) { + DEBUG("java plugin: cjni_create_jvm: jvm_argv[%zu] = %s", i, jvm_argv[i]); vm_args.options[i].optionString = jvm_argv[i]; } - status = JNI_CreateJavaVM (&jvm, (void *) &jvm_env, (void *) &vm_args); - if (status != 0) - { - ERROR ("java plugin: cjni_create_jvm: " - "JNI_CreateJavaVM failed with status %i.", - status); + status = JNI_CreateJavaVM(&jvm, (void *)&jvm_env, (void *)&vm_args); + if (status != 0) { + ERROR("java plugin: cjni_create_jvm: " + "JNI_CreateJavaVM failed with status %i.", + status); return (-1); } - assert (jvm != NULL); - assert (jvm_env != NULL); + assert(jvm != NULL); + assert(jvm_env != NULL); /* Call RegisterNatives */ - status = cjni_init_native (jvm_env); - if (status != 0) - { - ERROR ("java plugin: cjni_create_jvm: cjni_init_native failed."); + status = cjni_init_native(jvm_env); + if (status != 0) { + ERROR("java plugin: cjni_create_jvm: cjni_init_native failed."); return (-1); } - DEBUG ("java plugin: The JVM has been created."); + DEBUG("java plugin: The JVM has been created."); return (0); } /* }}} int cjni_create_jvm */ /* Increase the reference counter to the JVM for this thread. If it was zero, * attach the JVM first. */ -static JNIEnv *cjni_thread_attach (void) /* {{{ */ +static JNIEnv *cjni_thread_attach(void) /* {{{ */ { cjni_jvm_env_t *cjni_env; JNIEnv *jvm_env; /* If we're the first thread to access the JVM, we'll have to create it * first.. */ - if (jvm == NULL) - { + if (jvm == NULL) { int status; - status = cjni_create_jvm (); - if (status != 0) - { - ERROR ("java plugin: cjni_thread_attach: cjni_create_jvm failed."); + status = cjni_create_jvm(); + if (status != 0) { + ERROR("java plugin: cjni_thread_attach: cjni_create_jvm failed."); return (NULL); } } - assert (jvm != NULL); + assert(jvm != NULL); - cjni_env = pthread_getspecific (jvm_env_key); - if (cjni_env == NULL) - { + cjni_env = pthread_getspecific(jvm_env_key); + if (cjni_env == NULL) { /* This pointer is free'd in `cjni_jvm_env_destroy'. */ - cjni_env = calloc (1, sizeof (*cjni_env)); - if (cjni_env == NULL) - { - ERROR ("java plugin: cjni_thread_attach: calloc failed."); + cjni_env = calloc(1, sizeof(*cjni_env)); + if (cjni_env == NULL) { + ERROR("java plugin: cjni_thread_attach: calloc failed."); return (NULL); } cjni_env->reference_counter = 0; cjni_env->jvm_env = NULL; - pthread_setspecific (jvm_env_key, cjni_env); + pthread_setspecific(jvm_env_key, cjni_env); } - if (cjni_env->reference_counter > 0) - { + if (cjni_env->reference_counter > 0) { cjni_env->reference_counter++; jvm_env = cjni_env->jvm_env; - } - else - { + } else { int status; - JavaVMAttachArgs args = { 0 }; + JavaVMAttachArgs args = {0}; - assert (cjni_env->jvm_env == NULL); + assert(cjni_env->jvm_env == NULL); args.version = JNI_VERSION_1_2; - status = (*jvm)->AttachCurrentThread (jvm, (void *) &jvm_env, (void *) &args); - if (status != 0) - { - ERROR ("java plugin: cjni_thread_attach: AttachCurrentThread failed " - "with status %i.", status); + status = (*jvm)->AttachCurrentThread(jvm, (void *)&jvm_env, (void *)&args); + if (status != 0) { + ERROR("java plugin: cjni_thread_attach: AttachCurrentThread failed " + "with status %i.", + status); return (NULL); } @@ -2083,41 +1924,40 @@ static JNIEnv *cjni_thread_attach (void) /* {{{ */ cjni_env->jvm_env = jvm_env; } - DEBUG ("java plugin: cjni_thread_attach: cjni_env->reference_counter = %i", - cjni_env->reference_counter); - assert (jvm_env != NULL); + DEBUG("java plugin: cjni_thread_attach: cjni_env->reference_counter = %i", + cjni_env->reference_counter); + assert(jvm_env != NULL); return (jvm_env); } /* }}} JNIEnv *cjni_thread_attach */ /* Decrease the reference counter of this thread. If it reaches zero, detach * from the JVM. */ -static int cjni_thread_detach (void) /* {{{ */ +static int cjni_thread_detach(void) /* {{{ */ { cjni_jvm_env_t *cjni_env; int status; - cjni_env = pthread_getspecific (jvm_env_key); - if (cjni_env == NULL) - { - ERROR ("java plugin: cjni_thread_detach: pthread_getspecific failed."); + cjni_env = pthread_getspecific(jvm_env_key); + if (cjni_env == NULL) { + ERROR("java plugin: cjni_thread_detach: pthread_getspecific failed."); return (-1); } - assert (cjni_env->reference_counter > 0); - assert (cjni_env->jvm_env != NULL); + assert(cjni_env->reference_counter > 0); + assert(cjni_env->jvm_env != NULL); cjni_env->reference_counter--; - DEBUG ("java plugin: cjni_thread_detach: cjni_env->reference_counter = %i", - cjni_env->reference_counter); + DEBUG("java plugin: cjni_thread_detach: cjni_env->reference_counter = %i", + cjni_env->reference_counter); if (cjni_env->reference_counter > 0) return (0); - status = (*jvm)->DetachCurrentThread (jvm); - if (status != 0) - { - ERROR ("java plugin: cjni_thread_detach: DetachCurrentThread failed " - "with status %i.", status); + status = (*jvm)->DetachCurrentThread(jvm); + if (status != 0) { + ERROR("java plugin: cjni_thread_detach: DetachCurrentThread failed " + "with status %i.", + status); } cjni_env->reference_counter = 0; @@ -2126,37 +1966,33 @@ static int cjni_thread_detach (void) /* {{{ */ return (0); } /* }}} int cjni_thread_detach */ -static int cjni_config_add_jvm_arg (oconfig_item_t *ci) /* {{{ */ +static int cjni_config_add_jvm_arg(oconfig_item_t *ci) /* {{{ */ { char **tmp; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("java plugin: `JVMArg' needs exactly one string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("java plugin: `JVMArg' needs exactly one string argument."); return (-1); } - if (jvm != NULL) - { - ERROR ("java plugin: All `JVMArg' options MUST appear before all " - "`LoadPlugin' options! The JVM is already started and I have to " - "ignore this argument: %s", - ci->values[0].value.string); + if (jvm != NULL) { + ERROR("java plugin: All `JVMArg' options MUST appear before all " + "`LoadPlugin' options! The JVM is already started and I have to " + "ignore this argument: %s", + ci->values[0].value.string); return (-1); } - tmp = realloc (jvm_argv, sizeof (char *) * (jvm_argc + 1)); - if (tmp == NULL) - { - ERROR ("java plugin: realloc failed."); + tmp = realloc(jvm_argv, sizeof(char *) * (jvm_argc + 1)); + if (tmp == NULL) { + ERROR("java plugin: realloc failed."); return (-1); } jvm_argv = tmp; - jvm_argv[jvm_argc] = strdup (ci->values[0].value.string); - if (jvm_argv[jvm_argc] == NULL) - { - ERROR ("java plugin: strdup failed."); + jvm_argv[jvm_argc] = strdup(ci->values[0].value.string); + if (jvm_argv[jvm_argc] == NULL) { + ERROR("java plugin: strdup failed."); return (-1); } jvm_argc++; @@ -2164,40 +2000,37 @@ static int cjni_config_add_jvm_arg (oconfig_item_t *ci) /* {{{ */ return (0); } /* }}} int cjni_config_add_jvm_arg */ -static int cjni_config_load_plugin (oconfig_item_t *ci) /* {{{ */ +static int cjni_config_load_plugin(oconfig_item_t *ci) /* {{{ */ { JNIEnv *jvm_env; java_plugin_class_t *class; jmethodID constructor_id; jobject tmp_object; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("java plugin: `LoadPlugin' needs exactly one string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("java plugin: `LoadPlugin' needs exactly one string argument."); return (-1); } - jvm_env = cjni_thread_attach (); + jvm_env = cjni_thread_attach(); if (jvm_env == NULL) return (-1); - class = realloc (java_classes_list, - (java_classes_list_len + 1) * sizeof (*java_classes_list)); - if (class == NULL) - { - ERROR ("java plugin: realloc failed."); - cjni_thread_detach (); + class = realloc(java_classes_list, + (java_classes_list_len + 1) * sizeof(*java_classes_list)); + if (class == NULL) { + ERROR("java plugin: realloc failed."); + cjni_thread_detach(); return (-1); } java_classes_list = class; class = java_classes_list + java_classes_list_len; - memset (class, 0, sizeof (*class)); - class->name = strdup (ci->values[0].value.string); - if (class->name == NULL) - { - ERROR ("java plugin: strdup failed."); - cjni_thread_detach (); + memset(class, 0, sizeof(*class)); + class->name = strdup(ci->values[0].value.string); + if (class->name == NULL) { + ERROR("java plugin: strdup failed."); + cjni_thread_detach(); return (-1); } class->class = NULL; @@ -2211,54 +2044,50 @@ static int cjni_config_load_plugin (oconfig_item_t *ci) /* {{{ */ class->name[i] = '/'; } - DEBUG ("java plugin: Loading class %s", class->name); + DEBUG("java plugin: Loading class %s", class->name); - class->class = (*jvm_env)->FindClass (jvm_env, class->name); - if (class->class == NULL) - { - ERROR ("java plugin: cjni_config_load_plugin: FindClass (%s) failed.", - class->name); - cjni_thread_detach (); - free (class->name); + class->class = (*jvm_env)->FindClass(jvm_env, class->name); + if (class->class == NULL) { + ERROR("java plugin: cjni_config_load_plugin: FindClass (%s) failed.", + class->name); + cjni_thread_detach(); + free(class->name); return (-1); } - constructor_id = (*jvm_env)->GetMethodID (jvm_env, class->class, - "", "()V"); - if (constructor_id == NULL) - { - ERROR ("java plugin: cjni_config_load_plugin: " - "Could not find the constructor for `%s'.", - class->name); - cjni_thread_detach (); - free (class->name); + constructor_id = + (*jvm_env)->GetMethodID(jvm_env, class->class, "", "()V"); + if (constructor_id == NULL) { + ERROR("java plugin: cjni_config_load_plugin: " + "Could not find the constructor for `%s'.", + class->name); + cjni_thread_detach(); + free(class->name); return (-1); } - tmp_object = (*jvm_env)->NewObject (jvm_env, class->class, - constructor_id); + tmp_object = (*jvm_env)->NewObject(jvm_env, class->class, constructor_id); if (tmp_object != NULL) - class->object = (*jvm_env)->NewGlobalRef (jvm_env, tmp_object); + class->object = (*jvm_env)->NewGlobalRef(jvm_env, tmp_object); else class->object = NULL; - if (class->object == NULL) - { - ERROR ("java plugin: cjni_config_load_plugin: " - "Could create a new `%s' object.", - class->name); - cjni_thread_detach (); - free (class->name); + if (class->object == NULL) { + ERROR("java plugin: cjni_config_load_plugin: " + "Could create a new `%s' object.", + class->name); + cjni_thread_detach(); + free(class->name); return (-1); } - cjni_thread_detach (); + cjni_thread_detach(); java_classes_list_len++; return (0); } /* }}} int cjni_config_load_plugin */ -static int cjni_config_plugin_block (oconfig_item_t *ci) /* {{{ */ +static int cjni_config_plugin_block(oconfig_item_t *ci) /* {{{ */ { JNIEnv *jvm_env; cjni_callback_info_t *cbi; @@ -2268,64 +2097,59 @@ static int cjni_config_plugin_block (oconfig_item_t *ci) /* {{{ */ jclass class; jmethodID method; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("java plugin: `Plugin' blocks " - "need exactly one string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("java plugin: `Plugin' blocks " + "need exactly one string argument."); return (-1); } name = ci->values[0].value.string; cbi = NULL; - for (size_t i = 0; i < java_callbacks_num; i++) - { + for (size_t i = 0; i < java_callbacks_num; i++) { if (java_callbacks[i].type != CB_TYPE_CONFIG) continue; - if (strcmp (name, java_callbacks[i].name) != 0) + if (strcmp(name, java_callbacks[i].name) != 0) continue; cbi = java_callbacks + i; break; } - if (cbi == NULL) - { - NOTICE ("java plugin: Configuration block for `%s' found, but no such " - "configuration callback has been registered. Please make sure, the " - "`LoadPlugin' lines precede the `Plugin' blocks.", - name); + if (cbi == NULL) { + NOTICE("java plugin: Configuration block for `%s' found, but no such " + "configuration callback has been registered. Please make sure, the " + "`LoadPlugin' lines precede the `Plugin' blocks.", + name); return (0); } - DEBUG ("java plugin: Configuring %s", name); + DEBUG("java plugin: Configuring %s", name); - jvm_env = cjni_thread_attach (); + jvm_env = cjni_thread_attach(); if (jvm_env == NULL) return (-1); - o_ocitem = ctoj_oconfig_item (jvm_env, ci); - if (o_ocitem == NULL) - { - ERROR ("java plugin: cjni_config_plugin_block: ctoj_oconfig_item failed."); - cjni_thread_detach (); + o_ocitem = ctoj_oconfig_item(jvm_env, ci); + if (o_ocitem == NULL) { + ERROR("java plugin: cjni_config_plugin_block: ctoj_oconfig_item failed."); + cjni_thread_detach(); return (-1); } - class = (*jvm_env)->GetObjectClass (jvm_env, cbi->object); - method = (*jvm_env)->GetMethodID (jvm_env, class, - "config", "(Lorg/collectd/api/OConfigItem;)I"); + class = (*jvm_env)->GetObjectClass(jvm_env, cbi->object); + method = (*jvm_env)->GetMethodID(jvm_env, class, "config", + "(Lorg/collectd/api/OConfigItem;)I"); - (*jvm_env)->CallIntMethod (jvm_env, - cbi->object, method, o_ocitem); + (*jvm_env)->CallIntMethod(jvm_env, cbi->object, method, o_ocitem); - (*jvm_env)->DeleteLocalRef (jvm_env, o_ocitem); - cjni_thread_detach (); + (*jvm_env)->DeleteLocalRef(jvm_env, o_ocitem); + cjni_thread_detach(); return (0); } /* }}} int cjni_config_plugin_block */ -static int cjni_config_perform (oconfig_item_t *ci) /* {{{ */ +static int cjni_config_perform(oconfig_item_t *ci) /* {{{ */ { int success; int errors; @@ -2334,47 +2158,38 @@ static int cjni_config_perform (oconfig_item_t *ci) /* {{{ */ success = 0; errors = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("JVMArg", child->key) == 0) - { - status = cjni_config_add_jvm_arg (child); + if (strcasecmp("JVMArg", child->key) == 0) { + status = cjni_config_add_jvm_arg(child); if (status == 0) success++; else errors++; - } - else if (strcasecmp ("LoadPlugin", child->key) == 0) - { - status = cjni_config_load_plugin (child); + } else if (strcasecmp("LoadPlugin", child->key) == 0) { + status = cjni_config_load_plugin(child); if (status == 0) success++; else errors++; - } - else if (strcasecmp ("Plugin", child->key) == 0) - { - status = cjni_config_plugin_block (child); + } else if (strcasecmp("Plugin", child->key) == 0) { + status = cjni_config_plugin_block(child); if (status == 0) success++; else errors++; - } - else - { - WARNING ("java plugin: Option `%s' not allowed here.", child->key); + } else { + WARNING("java plugin: Option `%s' not allowed here.", child->key); errors++; } } - DEBUG ("java plugin: jvm_argc = %zu;", jvm_argc); - DEBUG ("java plugin: java_classes_list_len = %zu;", java_classes_list_len); + DEBUG("java plugin: jvm_argc = %zu;", jvm_argc); + DEBUG("java plugin: java_classes_list_len = %zu;", java_classes_list_len); - if ((success == 0) && (errors > 0)) - { - ERROR ("java plugin: All statements failed."); + if ((success == 0) && (errors > 0)) { + ERROR("java plugin: All statements failed."); return (-1); } @@ -2382,50 +2197,47 @@ static int cjni_config_perform (oconfig_item_t *ci) /* {{{ */ } /* }}} int cjni_config_perform */ /* Copy the children of `ci' to the global `config_block' variable. */ -static int cjni_config_callback (oconfig_item_t *ci) /* {{{ */ +static int cjni_config_callback(oconfig_item_t *ci) /* {{{ */ { oconfig_item_t *ci_copy; oconfig_item_t *tmp; - assert (ci != NULL); + assert(ci != NULL); if (ci->children_num == 0) return (0); /* nothing to do */ - ci_copy = oconfig_clone (ci); - if (ci_copy == NULL) - { - ERROR ("java plugin: oconfig_clone failed."); + ci_copy = oconfig_clone(ci); + if (ci_copy == NULL) { + ERROR("java plugin: oconfig_clone failed."); return (-1); } - if (config_block == NULL) - { + if (config_block == NULL) { config_block = ci_copy; return (0); } - tmp = realloc (config_block->children, - (config_block->children_num + ci_copy->children_num) * sizeof (*tmp)); - if (tmp == NULL) - { - ERROR ("java plugin: realloc failed."); - oconfig_free (ci_copy); + tmp = realloc(config_block->children, + (config_block->children_num + ci_copy->children_num) * + sizeof(*tmp)); + if (tmp == NULL) { + ERROR("java plugin: realloc failed."); + oconfig_free(ci_copy); return (-1); } config_block->children = tmp; /* Copy the pointers */ - memcpy (config_block->children + config_block->children_num, - ci_copy->children, - ci_copy->children_num * sizeof (*ci_copy->children)); + memcpy(config_block->children + config_block->children_num, ci_copy->children, + ci_copy->children_num * sizeof(*ci_copy->children)); config_block->children_num += ci_copy->children_num; /* Delete the pointers from the copy, so `oconfig_free' can't free them. */ - memset (ci_copy->children, 0, - ci_copy->children_num * sizeof (*ci_copy->children)); + memset(ci_copy->children, 0, + ci_copy->children_num * sizeof(*ci_copy->children)); ci_copy->children_num = 0; - oconfig_free (ci_copy); + oconfig_free(ci_copy); return (0); } /* }}} int cjni_config_callback */ @@ -2433,183 +2245,168 @@ static int cjni_config_callback (oconfig_item_t *ci) /* {{{ */ /* Free the data contained in the `user_data_t' pointer passed to `cjni_read' * and `cjni_write'. In particular, delete the global reference to the Java * object. */ -static void cjni_callback_info_destroy (void *arg) /* {{{ */ +static void cjni_callback_info_destroy(void *arg) /* {{{ */ { JNIEnv *jvm_env; cjni_callback_info_t *cbi; - DEBUG ("java plugin: cjni_callback_info_destroy (arg = %p);", arg); + DEBUG("java plugin: cjni_callback_info_destroy (arg = %p);", arg); - cbi = (cjni_callback_info_t *) arg; + cbi = (cjni_callback_info_t *)arg; /* This condition can occur when shutting down. */ - if (jvm == NULL) - { - sfree (cbi); + if (jvm == NULL) { + sfree(cbi); return; } if (arg == NULL) return; - jvm_env = cjni_thread_attach (); - if (jvm_env == NULL) - { - ERROR ("java plugin: cjni_callback_info_destroy: cjni_thread_attach failed."); + jvm_env = cjni_thread_attach(); + if (jvm_env == NULL) { + ERROR( + "java plugin: cjni_callback_info_destroy: cjni_thread_attach failed."); return; } - (*jvm_env)->DeleteGlobalRef (jvm_env, cbi->object); + (*jvm_env)->DeleteGlobalRef(jvm_env, cbi->object); cbi->method = NULL; cbi->object = NULL; - cbi->class = NULL; - free (cbi); + cbi->class = NULL; + free(cbi); - cjni_thread_detach (); + cjni_thread_detach(); } /* }}} void cjni_callback_info_destroy */ /* Call the CB_TYPE_READ callback pointed to by the `user_data_t' pointer. */ -static int cjni_read (user_data_t *ud) /* {{{ */ +static int cjni_read(user_data_t *ud) /* {{{ */ { JNIEnv *jvm_env; cjni_callback_info_t *cbi; int ret_status; - if (jvm == NULL) - { - ERROR ("java plugin: cjni_read: jvm == NULL"); + if (jvm == NULL) { + ERROR("java plugin: cjni_read: jvm == NULL"); return (-1); } - if ((ud == NULL) || (ud->data == NULL)) - { - ERROR ("java plugin: cjni_read: Invalid user data."); + if ((ud == NULL) || (ud->data == NULL)) { + ERROR("java plugin: cjni_read: Invalid user data."); return (-1); } - jvm_env = cjni_thread_attach (); + jvm_env = cjni_thread_attach(); if (jvm_env == NULL) return (-1); - cbi = (cjni_callback_info_t *) ud->data; + cbi = (cjni_callback_info_t *)ud->data; - ret_status = (*jvm_env)->CallIntMethod (jvm_env, cbi->object, - cbi->method); + ret_status = (*jvm_env)->CallIntMethod(jvm_env, cbi->object, cbi->method); - cjni_thread_detach (); + cjni_thread_detach(); return (ret_status); } /* }}} int cjni_read */ /* Call the CB_TYPE_WRITE callback pointed to by the `user_data_t' pointer. */ -static int cjni_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */ - user_data_t *ud) -{ +static int cjni_write(const data_set_t *ds, const value_list_t *vl, /* {{{ */ + user_data_t *ud) { JNIEnv *jvm_env; cjni_callback_info_t *cbi; jobject vl_java; int ret_status; - if (jvm == NULL) - { - ERROR ("java plugin: cjni_write: jvm == NULL"); + if (jvm == NULL) { + ERROR("java plugin: cjni_write: jvm == NULL"); return (-1); } - if ((ud == NULL) || (ud->data == NULL)) - { - ERROR ("java plugin: cjni_write: Invalid user data."); + if ((ud == NULL) || (ud->data == NULL)) { + ERROR("java plugin: cjni_write: Invalid user data."); return (-1); } - jvm_env = cjni_thread_attach (); + jvm_env = cjni_thread_attach(); if (jvm_env == NULL) return (-1); - cbi = (cjni_callback_info_t *) ud->data; + cbi = (cjni_callback_info_t *)ud->data; - vl_java = ctoj_value_list (jvm_env, ds, vl); - if (vl_java == NULL) - { - ERROR ("java plugin: cjni_write: ctoj_value_list failed."); - cjni_thread_detach (); + vl_java = ctoj_value_list(jvm_env, ds, vl); + if (vl_java == NULL) { + ERROR("java plugin: cjni_write: ctoj_value_list failed."); + cjni_thread_detach(); return (-1); } - ret_status = (*jvm_env)->CallIntMethod (jvm_env, - cbi->object, cbi->method, vl_java); + ret_status = + (*jvm_env)->CallIntMethod(jvm_env, cbi->object, cbi->method, vl_java); - (*jvm_env)->DeleteLocalRef (jvm_env, vl_java); + (*jvm_env)->DeleteLocalRef(jvm_env, vl_java); - cjni_thread_detach (); + cjni_thread_detach(); return (ret_status); } /* }}} int cjni_write */ /* Call the CB_TYPE_FLUSH callback pointed to by the `user_data_t' pointer. */ -static int cjni_flush (cdtime_t timeout, const char *identifier, /* {{{ */ - user_data_t *ud) -{ +static int cjni_flush(cdtime_t timeout, const char *identifier, /* {{{ */ + user_data_t *ud) { JNIEnv *jvm_env; cjni_callback_info_t *cbi; jobject o_timeout; jobject o_identifier; int ret_status; - if (jvm == NULL) - { - ERROR ("java plugin: cjni_flush: jvm == NULL"); + if (jvm == NULL) { + ERROR("java plugin: cjni_flush: jvm == NULL"); return (-1); } - if ((ud == NULL) || (ud->data == NULL)) - { - ERROR ("java plugin: cjni_flush: Invalid user data."); + if ((ud == NULL) || (ud->data == NULL)) { + ERROR("java plugin: cjni_flush: Invalid user data."); return (-1); } - jvm_env = cjni_thread_attach (); + jvm_env = cjni_thread_attach(); if (jvm_env == NULL) return (-1); - cbi = (cjni_callback_info_t *) ud->data; + cbi = (cjni_callback_info_t *)ud->data; - o_timeout = ctoj_jdouble_to_number (jvm_env, - (jdouble) CDTIME_T_TO_DOUBLE (timeout)); - if (o_timeout == NULL) - { - ERROR ("java plugin: cjni_flush: Converting double " - "to Number object failed."); - cjni_thread_detach (); + o_timeout = + ctoj_jdouble_to_number(jvm_env, (jdouble)CDTIME_T_TO_DOUBLE(timeout)); + if (o_timeout == NULL) { + ERROR("java plugin: cjni_flush: Converting double " + "to Number object failed."); + cjni_thread_detach(); return (-1); } o_identifier = NULL; - if (identifier != NULL) - { - o_identifier = (*jvm_env)->NewStringUTF (jvm_env, identifier); - if (o_identifier == NULL) - { - (*jvm_env)->DeleteLocalRef (jvm_env, o_timeout); - ERROR ("java plugin: cjni_flush: NewStringUTF failed."); - cjni_thread_detach (); + if (identifier != NULL) { + o_identifier = (*jvm_env)->NewStringUTF(jvm_env, identifier); + if (o_identifier == NULL) { + (*jvm_env)->DeleteLocalRef(jvm_env, o_timeout); + ERROR("java plugin: cjni_flush: NewStringUTF failed."); + cjni_thread_detach(); return (-1); } } - ret_status = (*jvm_env)->CallIntMethod (jvm_env, - cbi->object, cbi->method, o_timeout, o_identifier); + ret_status = (*jvm_env)->CallIntMethod(jvm_env, cbi->object, cbi->method, + o_timeout, o_identifier); - (*jvm_env)->DeleteLocalRef (jvm_env, o_identifier); - (*jvm_env)->DeleteLocalRef (jvm_env, o_timeout); + (*jvm_env)->DeleteLocalRef(jvm_env, o_identifier); + (*jvm_env)->DeleteLocalRef(jvm_env, o_timeout); - cjni_thread_detach (); + cjni_thread_detach(); return (ret_status); } /* }}} int cjni_flush */ /* Call the CB_TYPE_LOG callback pointed to by the `user_data_t' pointer. */ -static void cjni_log (int severity, const char *message, /* {{{ */ - user_data_t *ud) -{ +static void cjni_log(int severity, const char *message, /* {{{ */ + user_data_t *ud) { JNIEnv *jvm_env; cjni_callback_info_t *cbi; jobject o_message; @@ -2620,76 +2417,70 @@ static void cjni_log (int severity, const char *message, /* {{{ */ if ((ud == NULL) || (ud->data == NULL)) return; - jvm_env = cjni_thread_attach (); + jvm_env = cjni_thread_attach(); if (jvm_env == NULL) return; - cbi = (cjni_callback_info_t *) ud->data; + cbi = (cjni_callback_info_t *)ud->data; - o_message = (*jvm_env)->NewStringUTF (jvm_env, message); - if (o_message == NULL) - { - cjni_thread_detach (); + o_message = (*jvm_env)->NewStringUTF(jvm_env, message); + if (o_message == NULL) { + cjni_thread_detach(); return; } - (*jvm_env)->CallVoidMethod (jvm_env, - cbi->object, cbi->method, (jint) severity, o_message); + (*jvm_env)->CallVoidMethod(jvm_env, cbi->object, cbi->method, (jint)severity, + o_message); - (*jvm_env)->DeleteLocalRef (jvm_env, o_message); + (*jvm_env)->DeleteLocalRef(jvm_env, o_message); - cjni_thread_detach (); + cjni_thread_detach(); } /* }}} void cjni_log */ /* Call the CB_TYPE_NOTIFICATION callback pointed to by the `user_data_t' * pointer. */ -static int cjni_notification (const notification_t *n, /* {{{ */ - user_data_t *ud) -{ +static int cjni_notification(const notification_t *n, /* {{{ */ + user_data_t *ud) { JNIEnv *jvm_env; cjni_callback_info_t *cbi; jobject o_notification; int ret_status; - if (jvm == NULL) - { - ERROR ("java plugin: cjni_read: jvm == NULL"); + if (jvm == NULL) { + ERROR("java plugin: cjni_read: jvm == NULL"); return (-1); } - if ((ud == NULL) || (ud->data == NULL)) - { - ERROR ("java plugin: cjni_read: Invalid user data."); + if ((ud == NULL) || (ud->data == NULL)) { + ERROR("java plugin: cjni_read: Invalid user data."); return (-1); } - jvm_env = cjni_thread_attach (); + jvm_env = cjni_thread_attach(); if (jvm_env == NULL) return (-1); - cbi = (cjni_callback_info_t *) ud->data; + cbi = (cjni_callback_info_t *)ud->data; - o_notification = ctoj_notification (jvm_env, n); - if (o_notification == NULL) - { - ERROR ("java plugin: cjni_notification: ctoj_notification failed."); - cjni_thread_detach (); + o_notification = ctoj_notification(jvm_env, n); + if (o_notification == NULL) { + ERROR("java plugin: cjni_notification: ctoj_notification failed."); + cjni_thread_detach(); return (-1); } - ret_status = (*jvm_env)->CallIntMethod (jvm_env, - cbi->object, cbi->method, o_notification); + ret_status = (*jvm_env)->CallIntMethod(jvm_env, cbi->object, cbi->method, + o_notification); - (*jvm_env)->DeleteLocalRef (jvm_env, o_notification); + (*jvm_env)->DeleteLocalRef(jvm_env, o_notification); - cjni_thread_detach (); + cjni_thread_detach(); return (ret_status); } /* }}} int cjni_notification */ /* Callbacks for matches implemented in Java */ -static int cjni_match_target_create (const oconfig_item_t *ci, /* {{{ */ - void **user_data) -{ +static int cjni_match_target_create(const oconfig_item_t *ci, /* {{{ */ + void **user_data) { JNIEnv *jvm_env; cjni_callback_info_t *cbi_ret; cjni_callback_info_t *cbi_factory; @@ -2702,38 +2493,36 @@ static int cjni_match_target_create (const oconfig_item_t *ci, /* {{{ */ o_ci = NULL; jvm_env = NULL; -#define BAIL_OUT(status) \ - if (cbi_ret != NULL) { \ - free (cbi_ret->name); \ - if ((jvm_env != NULL) && (cbi_ret->object != NULL)) \ - (*jvm_env)->DeleteLocalRef (jvm_env, cbi_ret->object); \ - } \ - free (cbi_ret); \ - if (o_ci != NULL) \ - (*jvm_env)->DeleteLocalRef (jvm_env, o_ci); \ - cjni_thread_detach (); \ +#define BAIL_OUT(status) \ + if (cbi_ret != NULL) { \ + free(cbi_ret->name); \ + if ((jvm_env != NULL) && (cbi_ret->object != NULL)) \ + (*jvm_env)->DeleteLocalRef(jvm_env, cbi_ret->object); \ + } \ + free(cbi_ret); \ + if (o_ci != NULL) \ + (*jvm_env)->DeleteLocalRef(jvm_env, o_ci); \ + cjni_thread_detach(); \ return (status) - if (jvm == NULL) - { - ERROR ("java plugin: cjni_read: jvm == NULL"); + if (jvm == NULL) { + ERROR("java plugin: cjni_read: jvm == NULL"); return (-1); } - jvm_env = cjni_thread_attach (); + jvm_env = cjni_thread_attach(); if (jvm_env == NULL) return (-1); /* Find out whether to create a match or a target. */ - if (strcasecmp ("Match", ci->key) == 0) + if (strcasecmp("Match", ci->key) == 0) type = CB_TYPE_MATCH; - else if (strcasecmp ("Target", ci->key) == 0) + else if (strcasecmp("Target", ci->key) == 0) type = CB_TYPE_TARGET; - else - { - ERROR ("java plugin: cjni_match_target_create: Can't figure out whether " - "to create a match or a target."); - BAIL_OUT (-1); + else { + ERROR("java plugin: cjni_match_target_create: Can't figure out whether " + "to create a match or a target."); + BAIL_OUT(-1); } /* This is the name of the match we should create. */ @@ -2741,12 +2530,11 @@ static int cjni_match_target_create (const oconfig_item_t *ci, /* {{{ */ /* Lets see if we have a matching factory here.. */ cbi_factory = NULL; - for (size_t i = 0; i < java_callbacks_num; i++) - { + for (size_t i = 0; i < java_callbacks_num; i++) { if (java_callbacks[i].type != type) continue; - if (strcmp (name, java_callbacks[i].name) != 0) + if (strcmp(name, java_callbacks[i].name) != 0) continue; cbi_factory = java_callbacks + i; @@ -2754,103 +2542,97 @@ static int cjni_match_target_create (const oconfig_item_t *ci, /* {{{ */ } /* Nope, no factory for that name.. */ - if (cbi_factory == NULL) - { - ERROR ("java plugin: cjni_match_target_create: " - "No such match factory registered: %s", - name); - BAIL_OUT (-1); + if (cbi_factory == NULL) { + ERROR("java plugin: cjni_match_target_create: " + "No such match factory registered: %s", + name); + BAIL_OUT(-1); } /* We convert `ci' to its Java equivalent.. */ - o_ci = ctoj_oconfig_item (jvm_env, ci); - if (o_ci == NULL) - { - ERROR ("java plugin: cjni_match_target_create: " - "ctoj_oconfig_item failed."); - BAIL_OUT (-1); + o_ci = ctoj_oconfig_item(jvm_env, ci); + if (o_ci == NULL) { + ERROR("java plugin: cjni_match_target_create: " + "ctoj_oconfig_item failed."); + BAIL_OUT(-1); } /* Allocate a new callback info structure. This is going to be our user_data * pointer. */ - cbi_ret = calloc (1, sizeof (*cbi_ret)); - if (cbi_ret == NULL) - { - ERROR ("java plugin: cjni_match_target_create: calloc failed."); - BAIL_OUT (-1); + cbi_ret = calloc(1, sizeof(*cbi_ret)); + if (cbi_ret == NULL) { + ERROR("java plugin: cjni_match_target_create: calloc failed."); + BAIL_OUT(-1); } cbi_ret->object = NULL; cbi_ret->type = type; /* Lets fill the callback info structure.. First, the name: */ - cbi_ret->name = strdup (name); - if (cbi_ret->name == NULL) - { - ERROR ("java plugin: cjni_match_target_create: strdup failed."); - BAIL_OUT (-1); + cbi_ret->name = strdup(name); + if (cbi_ret->name == NULL) { + ERROR("java plugin: cjni_match_target_create: strdup failed."); + BAIL_OUT(-1); } /* Then call the factory method so it creates a new object for us. */ - o_tmp = (*jvm_env)->CallObjectMethod (jvm_env, - cbi_factory->object, cbi_factory->method, o_ci); - if (o_tmp == NULL) - { - ERROR ("java plugin: cjni_match_target_create: CallObjectMethod failed."); - BAIL_OUT (-1); + o_tmp = (*jvm_env)->CallObjectMethod(jvm_env, cbi_factory->object, + cbi_factory->method, o_ci); + if (o_tmp == NULL) { + ERROR("java plugin: cjni_match_target_create: CallObjectMethod failed."); + BAIL_OUT(-1); } - cbi_ret->object = (*jvm_env)->NewGlobalRef (jvm_env, o_tmp); - if (o_tmp == NULL) - { - ERROR ("java plugin: cjni_match_target_create: NewGlobalRef failed."); - BAIL_OUT (-1); + cbi_ret->object = (*jvm_env)->NewGlobalRef(jvm_env, o_tmp); + if (o_tmp == NULL) { + ERROR("java plugin: cjni_match_target_create: NewGlobalRef failed."); + BAIL_OUT(-1); } /* This is the class of the match. It is possibly different from the class of * the match-factory! */ - cbi_ret->class = (*jvm_env)->GetObjectClass (jvm_env, cbi_ret->object); - if (cbi_ret->class == NULL) - { - ERROR ("java plugin: cjni_match_target_create: GetObjectClass failed."); - BAIL_OUT (-1); + cbi_ret->class = (*jvm_env)->GetObjectClass(jvm_env, cbi_ret->object); + if (cbi_ret->class == NULL) { + ERROR("java plugin: cjni_match_target_create: GetObjectClass failed."); + BAIL_OUT(-1); } /* Lookup the `int match (DataSet, ValueList)' method. */ - cbi_ret->method = (*jvm_env)->GetMethodID (jvm_env, cbi_ret->class, + cbi_ret->method = (*jvm_env)->GetMethodID( + jvm_env, cbi_ret->class, /* method name = */ (type == CB_TYPE_MATCH) ? "match" : "invoke", "(Lorg/collectd/api/DataSet;Lorg/collectd/api/ValueList;)I"); - if (cbi_ret->method == NULL) - { - ERROR ("java plugin: cjni_match_target_create: GetMethodID failed."); - BAIL_OUT (-1); + if (cbi_ret->method == NULL) { + ERROR("java plugin: cjni_match_target_create: GetMethodID failed."); + BAIL_OUT(-1); } /* Return the newly created match via the user_data pointer. */ - *user_data = (void *) cbi_ret; + *user_data = (void *)cbi_ret; - cjni_thread_detach (); + cjni_thread_detach(); - DEBUG ("java plugin: cjni_match_target_create: " - "Successfully created a `%s' %s.", - cbi_ret->name, (type == CB_TYPE_MATCH) ? "match" : "target"); + DEBUG("java plugin: cjni_match_target_create: " + "Successfully created a `%s' %s.", + cbi_ret->name, (type == CB_TYPE_MATCH) ? "match" : "target"); /* Success! */ return (0); #undef BAIL_OUT } /* }}} int cjni_match_target_create */ -static int cjni_match_target_destroy (void **user_data) /* {{{ */ +static int cjni_match_target_destroy(void **user_data) /* {{{ */ { - cjni_callback_info_destroy (*user_data); + cjni_callback_info_destroy(*user_data); *user_data = NULL; return (0); } /* }}} int cjni_match_target_destroy */ -static int cjni_match_target_invoke (const data_set_t *ds, /* {{{ */ - value_list_t *vl, notification_meta_t **meta, void **user_data) -{ +static int cjni_match_target_invoke(const data_set_t *ds, /* {{{ */ + value_list_t *vl, + notification_meta_t **meta, + void **user_data) { JNIEnv *jvm_env; cjni_callback_info_t *cbi; jobject o_vl; @@ -2858,87 +2640,80 @@ static int cjni_match_target_invoke (const data_set_t *ds, /* {{{ */ int ret_status; int status; - if (jvm == NULL) - { - ERROR ("java plugin: cjni_match_target_invoke: jvm == NULL"); + if (jvm == NULL) { + ERROR("java plugin: cjni_match_target_invoke: jvm == NULL"); return (-1); } - jvm_env = cjni_thread_attach (); + jvm_env = cjni_thread_attach(); if (jvm_env == NULL) return (-1); - cbi = (cjni_callback_info_t *) *user_data; + cbi = (cjni_callback_info_t *)*user_data; - o_vl = ctoj_value_list (jvm_env, ds, vl); - if (o_vl == NULL) - { - ERROR ("java plugin: cjni_match_target_invoke: ctoj_value_list failed."); - cjni_thread_detach (); + o_vl = ctoj_value_list(jvm_env, ds, vl); + if (o_vl == NULL) { + ERROR("java plugin: cjni_match_target_invoke: ctoj_value_list failed."); + cjni_thread_detach(); return (-1); } - o_ds = ctoj_data_set (jvm_env, ds); - if (o_ds == NULL) - { - ERROR ("java plugin: cjni_match_target_invoke: ctoj_value_list failed."); - cjni_thread_detach (); + o_ds = ctoj_data_set(jvm_env, ds); + if (o_ds == NULL) { + ERROR("java plugin: cjni_match_target_invoke: ctoj_value_list failed."); + cjni_thread_detach(); return (-1); } - ret_status = (*jvm_env)->CallIntMethod (jvm_env, cbi->object, cbi->method, - o_ds, o_vl); + ret_status = + (*jvm_env)->CallIntMethod(jvm_env, cbi->object, cbi->method, o_ds, o_vl); - DEBUG ("java plugin: cjni_match_target_invoke: Method returned %i.", ret_status); + DEBUG("java plugin: cjni_match_target_invoke: Method returned %i.", + ret_status); /* If we're executing a target, copy the `ValueList' back to our * `value_list_t'. */ - if (cbi->type == CB_TYPE_TARGET) - { - value_list_t new_vl = { 0 }; - - status = jtoc_value_list (jvm_env, &new_vl, o_vl); - if (status != 0) - { - ERROR ("java plugin: cjni_match_target_invoke: " - "jtoc_value_list failed."); - } - else /* if (status == 0) */ + if (cbi->type == CB_TYPE_TARGET) { + value_list_t new_vl = {0}; + + status = jtoc_value_list(jvm_env, &new_vl, o_vl); + if (status != 0) { + ERROR("java plugin: cjni_match_target_invoke: " + "jtoc_value_list failed."); + } else /* if (status == 0) */ { /* plugin_dispatch_values assures that this is dynamically allocated * memory. */ - sfree (vl->values); + sfree(vl->values); /* This will replace the vl->values pointer to a new, dynamically * allocated piece of memory. */ - memcpy (vl, &new_vl, sizeof (*vl)); + memcpy(vl, &new_vl, sizeof(*vl)); } } /* if (cbi->type == CB_TYPE_TARGET) */ - cjni_thread_detach (); + cjni_thread_detach(); return (ret_status); } /* }}} int cjni_match_target_invoke */ /* Iterate over `java_callbacks' and call all CB_TYPE_INIT callbacks. */ -static int cjni_init_plugins (JNIEnv *jvm_env) /* {{{ */ +static int cjni_init_plugins(JNIEnv *jvm_env) /* {{{ */ { int status; - for (size_t i = 0; i < java_callbacks_num; i++) - { + for (size_t i = 0; i < java_callbacks_num; i++) { if (java_callbacks[i].type != CB_TYPE_INIT) continue; - DEBUG ("java plugin: Initializing %s", java_callbacks[i].name); + DEBUG("java plugin: Initializing %s", java_callbacks[i].name); - status = (*jvm_env)->CallIntMethod (jvm_env, - java_callbacks[i].object, java_callbacks[i].method); - if (status != 0) - { - ERROR ("java plugin: Initializing `%s' failed with status %i. " - "Removing read function.", - java_callbacks[i].name, status); - plugin_unregister_read (java_callbacks[i].name); + status = (*jvm_env)->CallIntMethod(jvm_env, java_callbacks[i].object, + java_callbacks[i].method); + if (status != 0) { + ERROR("java plugin: Initializing `%s' failed with status %i. " + "Removing read function.", + java_callbacks[i].name, status); + plugin_unregister_read(java_callbacks[i].name); } } @@ -2946,34 +2721,31 @@ static int cjni_init_plugins (JNIEnv *jvm_env) /* {{{ */ } /* }}} int cjni_init_plugins */ /* Iterate over `java_callbacks' and call all CB_TYPE_SHUTDOWN callbacks. */ -static int cjni_shutdown_plugins (JNIEnv *jvm_env) /* {{{ */ +static int cjni_shutdown_plugins(JNIEnv *jvm_env) /* {{{ */ { int status; - for (size_t i = 0; i < java_callbacks_num; i++) - { + for (size_t i = 0; i < java_callbacks_num; i++) { if (java_callbacks[i].type != CB_TYPE_SHUTDOWN) continue; - DEBUG ("java plugin: Shutting down %s", java_callbacks[i].name); + DEBUG("java plugin: Shutting down %s", java_callbacks[i].name); - status = (*jvm_env)->CallIntMethod (jvm_env, - java_callbacks[i].object, java_callbacks[i].method); - if (status != 0) - { - ERROR ("java plugin: Shutting down `%s' failed with status %i. ", - java_callbacks[i].name, status); + status = (*jvm_env)->CallIntMethod(jvm_env, java_callbacks[i].object, + java_callbacks[i].method); + if (status != 0) { + ERROR("java plugin: Shutting down `%s' failed with status %i. ", + java_callbacks[i].name, status); } } return (0); } /* }}} int cjni_shutdown_plugins */ - -static int cjni_shutdown (void) /* {{{ */ +static int cjni_shutdown(void) /* {{{ */ { JNIEnv *jvm_env; - JavaVMAttachArgs args = { 0 }; + JavaVMAttachArgs args = {0}; int status; if (jvm == NULL) @@ -2982,100 +2754,92 @@ static int cjni_shutdown (void) /* {{{ */ jvm_env = NULL; args.version = JNI_VERSION_1_2; - status = (*jvm)->AttachCurrentThread (jvm, (void *) &jvm_env, &args); - if (status != 0) - { - ERROR ("java plugin: cjni_shutdown: AttachCurrentThread failed with status %i.", - status); + status = (*jvm)->AttachCurrentThread(jvm, (void *)&jvm_env, &args); + if (status != 0) { + ERROR("java plugin: cjni_shutdown: AttachCurrentThread failed with status " + "%i.", + status); return (-1); } /* Execute all the shutdown functions registered by plugins. */ - cjni_shutdown_plugins (jvm_env); + cjni_shutdown_plugins(jvm_env); /* Release all the global references to callback functions */ - for (size_t i = 0; i < java_callbacks_num; i++) - { - if (java_callbacks[i].object != NULL) - { - (*jvm_env)->DeleteGlobalRef (jvm_env, java_callbacks[i].object); + for (size_t i = 0; i < java_callbacks_num; i++) { + if (java_callbacks[i].object != NULL) { + (*jvm_env)->DeleteGlobalRef(jvm_env, java_callbacks[i].object); java_callbacks[i].object = NULL; } - sfree (java_callbacks[i].name); + sfree(java_callbacks[i].name); } java_callbacks_num = 0; - sfree (java_callbacks); + sfree(java_callbacks); /* Release all the global references to directly loaded classes. */ - for (size_t i = 0; i < java_classes_list_len; i++) - { - if (java_classes_list[i].object != NULL) - { - (*jvm_env)->DeleteGlobalRef (jvm_env, java_classes_list[i].object); + for (size_t i = 0; i < java_classes_list_len; i++) { + if (java_classes_list[i].object != NULL) { + (*jvm_env)->DeleteGlobalRef(jvm_env, java_classes_list[i].object); java_classes_list[i].object = NULL; } - sfree (java_classes_list[i].name); + sfree(java_classes_list[i].name); } java_classes_list_len = 0; - sfree (java_classes_list); + sfree(java_classes_list); /* Destroy the JVM */ - DEBUG ("java plugin: Destroying the JVM."); - (*jvm)->DestroyJavaVM (jvm); + DEBUG("java plugin: Destroying the JVM."); + (*jvm)->DestroyJavaVM(jvm); jvm = NULL; jvm_env = NULL; - pthread_key_delete (jvm_env_key); + pthread_key_delete(jvm_env_key); /* Free the JVM argument list */ for (size_t i = 0; i < jvm_argc; i++) - sfree (jvm_argv[i]); + sfree(jvm_argv[i]); jvm_argc = 0; - sfree (jvm_argv); + sfree(jvm_argv); return (0); } /* }}} int cjni_shutdown */ /* Initialization: Create a JVM, load all configured classes and call their * `config' and `init' callback methods. */ -static int cjni_init (void) /* {{{ */ +static int cjni_init(void) /* {{{ */ { JNIEnv *jvm_env; - if ((config_block == NULL) && (jvm == NULL)) - { - ERROR ("java plugin: cjni_init: No configuration block for " - "the java plugin was found."); + if ((config_block == NULL) && (jvm == NULL)) { + ERROR("java plugin: cjni_init: No configuration block for " + "the java plugin was found."); return (-1); } - if (config_block != NULL) - { - cjni_config_perform (config_block); - oconfig_free (config_block); + if (config_block != NULL) { + cjni_config_perform(config_block); + oconfig_free(config_block); } - if (jvm == NULL) - { - ERROR ("java plugin: cjni_init: jvm == NULL"); + if (jvm == NULL) { + ERROR("java plugin: cjni_init: jvm == NULL"); return (-1); } - jvm_env = cjni_thread_attach (); + jvm_env = cjni_thread_attach(); if (jvm_env == NULL) return (-1); - cjni_init_plugins (jvm_env); + cjni_init_plugins(jvm_env); - cjni_thread_detach (); + cjni_thread_detach(); return (0); } /* }}} int cjni_init */ -void module_register (void) -{ - plugin_register_complex_config ("java", cjni_config_callback); - plugin_register_init ("java", cjni_init); - plugin_register_shutdown ("java", cjni_shutdown); +void module_register(void) { + plugin_register_complex_config("java", cjni_config_callback); + plugin_register_init("java", cjni_init); + plugin_register_shutdown("java", cjni_shutdown); } /* void module_register (void) */ /* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/libcollectdclient/client.c b/src/libcollectdclient/client.c index 4dbee1e8..f61e9678 100644 --- a/src/libcollectdclient/client.c +++ b/src/libcollectdclient/client.c @@ -25,84 +25,85 @@ **/ #if HAVE_CONFIG_H -# include "config.h" +#include "config.h" #endif #if !defined(__GNUC__) || !__GNUC__ -# define __attribute__(x) /**/ +#define __attribute__(x) /**/ #endif #include "collectd/lcc_features.h" -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include "collectd/client.h" /* NI_MAXHOST has been obsoleted by RFC 3493 which is a reason for SunOS 5.11 * to no longer define it. We'll use the old, RFC 2553 value here. */ #ifndef NI_MAXHOST -# define NI_MAXHOST 1025 +#define NI_MAXHOST 1025 #endif /* OpenBSD doesn't have EPROTO, FreeBSD doesn't have EILSEQ. Oh what joy! */ #ifndef EILSEQ -# ifdef EPROTO -# define EILSEQ EPROTO -# else -# define EILSEQ EINVAL -# endif +#ifdef EPROTO +#define EILSEQ EPROTO +#else +#define EILSEQ EINVAL +#endif #endif /* Secure/static macros. They work like `strcpy' and `strcat', but assure null * termination. They work for static buffers only, because they use `sizeof'. * The `SSTRCATF' combines the functionality of `snprintf' and `strcat' which * is very useful to add formatted stuff to the end of a buffer. */ -#define SSTRCPY(d,s) do { \ - strncpy ((d), (s), sizeof (d)); \ - (d)[sizeof (d) - 1] = 0; \ +#define SSTRCPY(d, s) \ + do { \ + strncpy((d), (s), sizeof(d)); \ + (d)[sizeof(d) - 1] = 0; \ } while (0) -#define SSTRCAT(d,s) do { \ - size_t _l = strlen (d); \ - strncpy ((d) + _l, (s), sizeof (d) - _l); \ - (d)[sizeof (d) - 1] = 0; \ +#define SSTRCAT(d, s) \ + do { \ + size_t _l = strlen(d); \ + strncpy((d) + _l, (s), sizeof(d) - _l); \ + (d)[sizeof(d) - 1] = 0; \ } while (0) -#define SSTRCATF(d, ...) do { \ - char _b[sizeof (d)]; \ - snprintf (_b, sizeof (_b), __VA_ARGS__); \ - _b[sizeof (_b) - 1] = 0; \ - SSTRCAT ((d), _b); \ +#define SSTRCATF(d, ...) \ + do { \ + char _b[sizeof(d)]; \ + snprintf(_b, sizeof(_b), __VA_ARGS__); \ + _b[sizeof(_b) - 1] = 0; \ + SSTRCAT((d), _b); \ } while (0) - -#define LCC_SET_ERRSTR(c, ...) do { \ - snprintf ((c)->errbuf, sizeof ((c)->errbuf), __VA_ARGS__); \ - (c)->errbuf[sizeof ((c)->errbuf) - 1] = 0; \ -} while (0) +#define LCC_SET_ERRSTR(c, ...) \ + do { \ + snprintf((c)->errbuf, sizeof((c)->errbuf), __VA_ARGS__); \ + (c)->errbuf[sizeof((c)->errbuf) - 1] = 0; \ + } while (0) /* * Types */ -struct lcc_connection_s -{ +struct lcc_connection_s { FILE *fh; char errbuf[1024]; }; -struct lcc_response_s -{ +struct lcc_response_s { int status; char message[1024]; char **lines; @@ -113,19 +114,18 @@ typedef struct lcc_response_s lcc_response_t; /* * Private functions */ -__attribute__ ((format (printf, 1, 0))) -static int lcc_tracef(char const *format, ...) -{ +__attribute__((format(printf, 1, 0))) static int lcc_tracef(char const *format, + ...) { va_list ap; int status; - char const *trace = getenv (LCC_TRACE_ENV); - if (!trace || (strcmp ("", trace) == 0) || (strcmp ("0", trace) == 0)) + char const *trace = getenv(LCC_TRACE_ENV); + if (!trace || (strcmp("", trace) == 0) || (strcmp("0", trace) == 0)) return 0; - va_start (ap, format); - status = vprintf (format, ap); - va_end (ap); + va_start(ap, format); + status = vprintf(format, ap); + va_end(ap); return status; } @@ -133,35 +133,33 @@ static int lcc_tracef(char const *format, ...) /* Even though Posix requires "strerror_r" to return an "int", * some systems (e.g. the GNU libc) return a "char *" _and_ * ignore the second argument ... -tokkee */ -static char *sstrerror (int errnum, char *buf, size_t buflen) -{ +static char *sstrerror(int errnum, char *buf, size_t buflen) { buf[0] = 0; #if !HAVE_STRERROR_R - snprintf (buf, buflen, "Error #%i; strerror_r is not available.", errnum); + snprintf(buf, buflen, "Error #%i; strerror_r is not available.", errnum); /* #endif !HAVE_STRERROR_R */ #elif STRERROR_R_CHAR_P { char *temp; - temp = strerror_r (errnum, buf, buflen); - if (buf[0] == 0) - { + temp = strerror_r(errnum, buf, buflen); + if (buf[0] == 0) { if ((temp != NULL) && (temp != buf) && (temp[0] != 0)) - strncpy (buf, temp, buflen); + strncpy(buf, temp, buflen); else - strncpy (buf, "strerror_r did not return " - "an error message", buflen); + strncpy(buf, "strerror_r did not return " + "an error message", + buflen); } } /* #endif STRERROR_R_CHAR_P */ #else - if (strerror_r (errnum, buf, buflen) != 0) - { - snprintf (buf, buflen, "Error #%i; " - "Additionally, strerror_r failed.", - errnum); + if (strerror_r(errnum, buf, buflen) != 0) { + snprintf(buf, buflen, "Error #%i; " + "Additionally, strerror_r failed.", + errnum); } #endif /* STRERROR_R_CHAR_P */ @@ -170,18 +168,19 @@ static char *sstrerror (int errnum, char *buf, size_t buflen) return (buf); } /* char *sstrerror */ -static int lcc_set_errno (lcc_connection_t *c, int err) /* {{{ */ +static int lcc_set_errno(lcc_connection_t *c, int err) /* {{{ */ { if (c == NULL) return (-1); - sstrerror (err, c->errbuf, sizeof (c->errbuf)); - c->errbuf[sizeof (c->errbuf) - 1] = 0; + sstrerror(err, c->errbuf, sizeof(c->errbuf)); + c->errbuf[sizeof(c->errbuf) - 1] = 0; return (0); } /* }}} int lcc_set_errno */ -static char *lcc_strescape (char *dest, const char *src, size_t dest_size) /* {{{ */ +static char *lcc_strescape(char *dest, const char *src, + size_t dest_size) /* {{{ */ { size_t dest_pos; size_t src_pos; @@ -192,19 +191,16 @@ static char *lcc_strescape (char *dest, const char *src, size_t dest_size) /* {{ dest_pos = 0; src_pos = 0; - assert (dest_size >= 3); + assert(dest_size >= 3); dest[dest_pos] = '"'; dest_pos++; - while (42) - { - if ((dest_pos == (dest_size - 2)) - || (src[src_pos] == 0)) + while (42) { + if ((dest_pos == (dest_size - 2)) || (src[src_pos] == 0)) break; - if ((src[src_pos] == '"') || (src[src_pos] == '\\')) - { + if ((src[src_pos] == '"') || (src[src_pos] == '\\')) { /* Check if there is enough space for both characters.. */ if (dest_pos == (dest_size - 3)) break; @@ -218,7 +214,7 @@ static char *lcc_strescape (char *dest, const char *src, size_t dest_size) /* {{ src_pos++; } - assert (dest_pos <= (dest_size - 2)); + assert(dest_pos <= (dest_size - 2)); dest[dest_pos] = '"'; dest_pos++; @@ -231,13 +227,12 @@ static char *lcc_strescape (char *dest, const char *src, size_t dest_size) /* {{ } /* }}} char *lcc_strescape */ /* lcc_chomp: Removes all control-characters at the end of a string. */ -static void lcc_chomp (char *str) /* {{{ */ +static void lcc_chomp(char *str) /* {{{ */ { size_t str_len; - str_len = strlen (str); - while (str_len > 0) - { + str_len = strlen(str); + while (str_len > 0) { if (str[str_len - 1] >= 32) break; str[str_len - 1] = 0; @@ -245,27 +240,26 @@ static void lcc_chomp (char *str) /* {{{ */ } } /* }}} void lcc_chomp */ -static void lcc_response_free (lcc_response_t *res) /* {{{ */ +static void lcc_response_free(lcc_response_t *res) /* {{{ */ { if (res == NULL) return; for (size_t i = 0; i < res->lines_num; i++) - free (res->lines[i]); - free (res->lines); + free(res->lines[i]); + free(res->lines); res->lines = NULL; } /* }}} void lcc_response_free */ -static int lcc_send (lcc_connection_t *c, const char *command) /* {{{ */ +static int lcc_send(lcc_connection_t *c, const char *command) /* {{{ */ { int status; - lcc_tracef ("send: --> %s\n", command); + lcc_tracef("send: --> %s\n", command); - status = fprintf (c->fh, "%s\r\n", command); - if (status < 0) - { - lcc_set_errno (c, errno); + status = fprintf(c->fh, "%s\r\n", command); + if (status < 0) { + lcc_set_errno(c, errno); return (-1); } fflush(c->fh); @@ -273,32 +267,29 @@ static int lcc_send (lcc_connection_t *c, const char *command) /* {{{ */ return (0); } /* }}} int lcc_send */ -static int lcc_receive (lcc_connection_t *c, /* {{{ */ - lcc_response_t *ret_res) -{ - lcc_response_t res = { 0 }; +static int lcc_receive(lcc_connection_t *c, /* {{{ */ + lcc_response_t *ret_res) { + lcc_response_t res = {0}; char *ptr; char buffer[4096]; size_t i; /* Read the first line, containing the status and a message */ - ptr = fgets (buffer, sizeof (buffer), c->fh); - if (ptr == NULL) - { - lcc_set_errno (c, errno); + ptr = fgets(buffer, sizeof(buffer), c->fh); + if (ptr == NULL) { + lcc_set_errno(c, errno); return (-1); } - lcc_chomp (buffer); - lcc_tracef ("receive: <-- %s\n", buffer); + lcc_chomp(buffer); + lcc_tracef("receive: <-- %s\n", buffer); /* Convert the leading status to an integer and make `ptr' to point to the * beginning of the message. */ ptr = NULL; errno = 0; - res.status = (int) strtol (buffer, &ptr, 0); - if ((errno != 0) || (ptr == &buffer[0])) - { - lcc_set_errno (c, errno); + res.status = (int)strtol(buffer, &ptr, 0); + if ((errno != 0) || (ptr == &buffer[0])) { + lcc_set_errno(c, errno); return (-1); } @@ -307,129 +298,116 @@ static int lcc_receive (lcc_connection_t *c, /* {{{ */ ptr++; /* Now copy the message. */ - strncpy (res.message, ptr, sizeof (res.message)); - res.message[sizeof (res.message) - 1] = 0; + strncpy(res.message, ptr, sizeof(res.message)); + res.message[sizeof(res.message) - 1] = 0; /* Error or no lines follow: We're done. */ - if (res.status <= 0) - { - memcpy (ret_res, &res, sizeof (res)); + if (res.status <= 0) { + memcpy(ret_res, &res, sizeof(res)); return (0); } /* Allocate space for the char-pointers */ - res.lines_num = (size_t) res.status; + res.lines_num = (size_t)res.status; res.status = 0; - res.lines = malloc (res.lines_num * sizeof (*res.lines)); - if (res.lines == NULL) - { - lcc_set_errno (c, ENOMEM); + res.lines = malloc(res.lines_num * sizeof(*res.lines)); + if (res.lines == NULL) { + lcc_set_errno(c, ENOMEM); return (-1); } /* Now receive all the lines */ - for (i = 0; i < res.lines_num; i++) - { - ptr = fgets (buffer, sizeof (buffer), c->fh); - if (ptr == NULL) - { - lcc_set_errno (c, errno); + for (i = 0; i < res.lines_num; i++) { + ptr = fgets(buffer, sizeof(buffer), c->fh); + if (ptr == NULL) { + lcc_set_errno(c, errno); break; } - lcc_chomp (buffer); - lcc_tracef ("receive: <-- %s\n", buffer); + lcc_chomp(buffer); + lcc_tracef("receive: <-- %s\n", buffer); - res.lines[i] = strdup (buffer); - if (res.lines[i] == NULL) - { - lcc_set_errno (c, ENOMEM); + res.lines[i] = strdup(buffer); + if (res.lines[i] == NULL) { + lcc_set_errno(c, ENOMEM); break; } } /* Check if the for-loop exited with an error. */ - if (i < res.lines_num) - { - while (i > 0) - { + if (i < res.lines_num) { + while (i > 0) { i--; - free (res.lines[i]); + free(res.lines[i]); } - free (res.lines); + free(res.lines); return (-1); } - memcpy (ret_res, &res, sizeof (res)); + memcpy(ret_res, &res, sizeof(res)); return (0); } /* }}} int lcc_receive */ -static int lcc_sendreceive (lcc_connection_t *c, /* {{{ */ - const char *command, lcc_response_t *ret_res) -{ - lcc_response_t res = { 0 }; +static int lcc_sendreceive(lcc_connection_t *c, /* {{{ */ + const char *command, lcc_response_t *ret_res) { + lcc_response_t res = {0}; int status; - if (c->fh == NULL) - { - lcc_set_errno (c, EBADF); + if (c->fh == NULL) { + lcc_set_errno(c, EBADF); return (-1); } - status = lcc_send (c, command); + status = lcc_send(c, command); if (status != 0) return (status); - status = lcc_receive (c, &res); + status = lcc_receive(c, &res); if (status == 0) - memcpy (ret_res, &res, sizeof (*ret_res)); + memcpy(ret_res, &res, sizeof(*ret_res)); return (status); } /* }}} int lcc_sendreceive */ -static int lcc_open_unixsocket (lcc_connection_t *c, const char *path) /* {{{ */ +static int lcc_open_unixsocket(lcc_connection_t *c, const char *path) /* {{{ */ { - struct sockaddr_un sa = { 0 }; + struct sockaddr_un sa = {0}; int fd; int status; - assert (c != NULL); - assert (c->fh == NULL); - assert (path != NULL); + assert(c != NULL); + assert(c->fh == NULL); + assert(path != NULL); /* Don't use PF_UNIX here, because it's broken on Mac OS X (10.4, possibly * others). */ - fd = socket (AF_UNIX, SOCK_STREAM, /* protocol = */ 0); - if (fd < 0) - { - lcc_set_errno (c, errno); + fd = socket(AF_UNIX, SOCK_STREAM, /* protocol = */ 0); + if (fd < 0) { + lcc_set_errno(c, errno); return (-1); } sa.sun_family = AF_UNIX; - strncpy (sa.sun_path, path, sizeof (sa.sun_path) - 1); + strncpy(sa.sun_path, path, sizeof(sa.sun_path) - 1); - status = connect (fd, (struct sockaddr *) &sa, sizeof (sa)); - if (status != 0) - { - lcc_set_errno (c, errno); - close (fd); + status = connect(fd, (struct sockaddr *)&sa, sizeof(sa)); + if (status != 0) { + lcc_set_errno(c, errno); + close(fd); return (-1); } - c->fh = fdopen (fd, "r+"); - if (c->fh == NULL) - { - lcc_set_errno (c, errno); - close (fd); + c->fh = fdopen(fd, "r+"); + if (c->fh == NULL) { + lcc_set_errno(c, errno); + close(fd); return (-1); } return (0); } /* }}} int lcc_open_unixsocket */ -static int lcc_open_netsocket (lcc_connection_t *c, /* {{{ */ - const char *addr_orig) -{ +static int lcc_open_netsocket(lcc_connection_t *c, /* {{{ */ + const char *addr_orig) { struct addrinfo *ai_res; char addr_copy[NI_MAXHOST]; char *addr; @@ -437,9 +415,9 @@ static int lcc_open_netsocket (lcc_connection_t *c, /* {{{ */ int fd; int status; - assert (c != NULL); - assert (c->fh == NULL); - assert (addr_orig != NULL); + assert(c != NULL); + assert(c->fh == NULL); + assert(addr_orig != NULL); strncpy(addr_copy, addr_orig, sizeof(addr_copy)); addr_copy[sizeof(addr_copy) - 1] = '\0'; @@ -451,10 +429,9 @@ static int lcc_open_netsocket (lcc_connection_t *c, /* {{{ */ /* `addr' is something like "[2001:780:104:2:211:24ff:feab:26f8]:12345" */ addr++; - port = strchr (addr, ']'); - if (port == NULL) - { - LCC_SET_ERRSTR (c, "malformed address: %s", addr_orig); + port = strchr(addr, ']'); + if (port == NULL) { + LCC_SET_ERRSTR(c, "malformed address: %s", addr_orig); return (-1); } *port = 0; @@ -464,94 +441,84 @@ static int lcc_open_netsocket (lcc_connection_t *c, /* {{{ */ port++; else if (*port == 0) port = NULL; - else - { - LCC_SET_ERRSTR (c, "garbage after address: %s", port); + else { + LCC_SET_ERRSTR(c, "garbage after address: %s", port); return (-1); } - } /* if (*addr = ']') */ - else if (strchr (addr, '.') != NULL) /* Hostname or IPv4 */ + } /* if (*addr = ']') */ + else if (strchr(addr, '.') != NULL) /* Hostname or IPv4 */ { - port = strrchr (addr, ':'); - if (port != NULL) - { + port = strrchr(addr, ':'); + if (port != NULL) { *port = 0; port++; } } - struct addrinfo ai_hints = { - .ai_family = AF_UNSPEC, - .ai_flags = AI_ADDRCONFIG, - .ai_socktype = SOCK_STREAM - }; + struct addrinfo ai_hints = {.ai_family = AF_UNSPEC, + .ai_flags = AI_ADDRCONFIG, + .ai_socktype = SOCK_STREAM}; - status = getaddrinfo (addr, - port == NULL ? LCC_DEFAULT_PORT : port, - &ai_hints, &ai_res); - if (status != 0) - { - LCC_SET_ERRSTR (c, "getaddrinfo: %s", gai_strerror (status)); + status = getaddrinfo(addr, port == NULL ? LCC_DEFAULT_PORT : port, &ai_hints, + &ai_res); + if (status != 0) { + LCC_SET_ERRSTR(c, "getaddrinfo: %s", gai_strerror(status)); return (-1); } - for (struct addrinfo *ai_ptr = ai_res; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) - { - fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); - if (fd < 0) - { + for (struct addrinfo *ai_ptr = ai_res; ai_ptr != NULL; + ai_ptr = ai_ptr->ai_next) { + fd = socket(ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); + if (fd < 0) { status = errno; continue; } - status = connect (fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); - if (status != 0) - { + status = connect(fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); + if (status != 0) { status = errno; - close (fd); + close(fd); continue; } - c->fh = fdopen (fd, "r+"); - if (c->fh == NULL) - { + c->fh = fdopen(fd, "r+"); + if (c->fh == NULL) { status = errno; - close (fd); + close(fd); continue; } - assert (status == 0); + assert(status == 0); break; } /* for (ai_ptr) */ - if (status != 0) - { - lcc_set_errno (c, status); - freeaddrinfo (ai_res); + if (status != 0) { + lcc_set_errno(c, status); + freeaddrinfo(ai_res); return (-1); } - freeaddrinfo (ai_res); + freeaddrinfo(ai_res); return (0); } /* }}} int lcc_open_netsocket */ -static int lcc_open_socket (lcc_connection_t *c, const char *addr) /* {{{ */ +static int lcc_open_socket(lcc_connection_t *c, const char *addr) /* {{{ */ { int status = 0; if (addr == NULL) return (-1); - assert (c != NULL); - assert (c->fh == NULL); - assert (addr != NULL); + assert(c != NULL); + assert(c->fh == NULL); + assert(addr != NULL); - if (strncmp ("unix:", addr, strlen ("unix:")) == 0) - status = lcc_open_unixsocket (c, addr + strlen ("unix:")); + if (strncmp("unix:", addr, strlen("unix:")) == 0) + status = lcc_open_unixsocket(c, addr + strlen("unix:")); else if (addr[0] == '/') - status = lcc_open_unixsocket (c, addr); + status = lcc_open_unixsocket(c, addr); else - status = lcc_open_netsocket (c, addr); + status = lcc_open_netsocket(c, addr); return (status); } /* }}} int lcc_open_socket */ @@ -559,22 +526,22 @@ static int lcc_open_socket (lcc_connection_t *c, const char *addr) /* {{{ */ /* * Public functions */ -unsigned int lcc_version (void) /* {{{ */ +unsigned int lcc_version(void) /* {{{ */ { return (LCC_VERSION); } /* }}} unsigned int lcc_version */ -const char *lcc_version_string (void) /* {{{ */ +const char *lcc_version_string(void) /* {{{ */ { return (LCC_VERSION_STRING); } /* }}} const char *lcc_version_string */ -const char *lcc_version_extra (void) /* {{{ */ +const char *lcc_version_extra(void) /* {{{ */ { return (LCC_VERSION_EXTRA); } /* }}} const char *lcc_version_extra */ -int lcc_connect (const char *address, lcc_connection_t **ret_con) /* {{{ */ +int lcc_connect(const char *address, lcc_connection_t **ret_con) /* {{{ */ { lcc_connection_t *c; int status; @@ -585,14 +552,13 @@ int lcc_connect (const char *address, lcc_connection_t **ret_con) /* {{{ */ if (ret_con == NULL) return (-1); - c = calloc (1, sizeof (*c)); + c = calloc(1, sizeof(*c)); if (c == NULL) return (-1); - status = lcc_open_socket (c, address); - if (status != 0) - { - lcc_disconnect (c); + status = lcc_open_socket(c, address); + if (status != 0) { + lcc_disconnect(c); return (status); } @@ -600,32 +566,31 @@ int lcc_connect (const char *address, lcc_connection_t **ret_con) /* {{{ */ return (0); } /* }}} int lcc_connect */ -int lcc_disconnect (lcc_connection_t *c) /* {{{ */ +int lcc_disconnect(lcc_connection_t *c) /* {{{ */ { if (c == NULL) return (-1); - if (c->fh != NULL) - { - fclose (c->fh); + if (c->fh != NULL) { + fclose(c->fh); c->fh = NULL; } - free (c); + free(c); return (0); } /* }}} int lcc_disconnect */ -int lcc_getval (lcc_connection_t *c, lcc_identifier_t *ident, /* {{{ */ - size_t *ret_values_num, gauge_t **ret_values, char ***ret_values_names) -{ +int lcc_getval(lcc_connection_t *c, lcc_identifier_t *ident, /* {{{ */ + size_t *ret_values_num, gauge_t **ret_values, + char ***ret_values_names) { char ident_str[6 * LCC_NAME_LEN]; char ident_esc[12 * LCC_NAME_LEN]; char command[14 * LCC_NAME_LEN]; lcc_response_t res; - size_t values_num; + size_t values_num; gauge_t *values = NULL; - char **values_names = NULL; + char **values_names = NULL; size_t i; int status; @@ -633,101 +598,94 @@ int lcc_getval (lcc_connection_t *c, lcc_identifier_t *ident, /* {{{ */ if (c == NULL) return (-1); - if (ident == NULL) - { - lcc_set_errno (c, EINVAL); + if (ident == NULL) { + lcc_set_errno(c, EINVAL); return (-1); } /* Build a commend with an escaped version of the identifier string. */ - status = lcc_identifier_to_string (c, ident_str, sizeof (ident_str), ident); + status = lcc_identifier_to_string(c, ident_str, sizeof(ident_str), ident); if (status != 0) return (status); - snprintf (command, sizeof (command), "GETVAL %s", - lcc_strescape (ident_esc, ident_str, sizeof (ident_esc))); - command[sizeof (command) - 1] = 0; + snprintf(command, sizeof(command), "GETVAL %s", + lcc_strescape(ident_esc, ident_str, sizeof(ident_esc))); + command[sizeof(command) - 1] = 0; /* Send talk to the daemon.. */ - status = lcc_sendreceive (c, command, &res); + status = lcc_sendreceive(c, command, &res); if (status != 0) return (status); - if (res.status != 0) - { - LCC_SET_ERRSTR (c, "Server error: %s", res.message); - lcc_response_free (&res); + if (res.status != 0) { + LCC_SET_ERRSTR(c, "Server error: %s", res.message); + lcc_response_free(&res); return (-1); } values_num = res.lines_num; -#define BAIL_OUT(e) do { \ - lcc_set_errno (c, (e)); \ - free (values); \ - if (values_names != NULL) { \ - for (i = 0; i < values_num; i++) { \ - free (values_names[i]); \ - } \ - } \ - free (values_names); \ - lcc_response_free (&res); \ - return (-1); \ -} while (0) +#define BAIL_OUT(e) \ + do { \ + lcc_set_errno(c, (e)); \ + free(values); \ + if (values_names != NULL) { \ + for (i = 0; i < values_num; i++) { \ + free(values_names[i]); \ + } \ + } \ + free(values_names); \ + lcc_response_free(&res); \ + return (-1); \ + } while (0) /* If neither the values nor the names are requested, return here.. */ - if ((ret_values == NULL) && (ret_values_names == NULL)) - { + if ((ret_values == NULL) && (ret_values_names == NULL)) { if (ret_values_num != NULL) *ret_values_num = values_num; - lcc_response_free (&res); + lcc_response_free(&res); return (0); } /* Allocate space for the values */ - if (ret_values != NULL) - { - values = malloc (values_num * sizeof (*values)); + if (ret_values != NULL) { + values = malloc(values_num * sizeof(*values)); if (values == NULL) - BAIL_OUT (ENOMEM); + BAIL_OUT(ENOMEM); } - if (ret_values_names != NULL) - { - values_names = calloc (values_num, sizeof (*values_names)); + if (ret_values_names != NULL) { + values_names = calloc(values_num, sizeof(*values_names)); if (values_names == NULL) - BAIL_OUT (ENOMEM); + BAIL_OUT(ENOMEM); } - for (i = 0; i < res.lines_num; i++) - { + for (i = 0; i < res.lines_num; i++) { char *key; char *value; char *endptr; key = res.lines[i]; - value = strchr (key, '='); + value = strchr(key, '='); if (value == NULL) - BAIL_OUT (EILSEQ); + BAIL_OUT(EILSEQ); *value = 0; value++; - if (values != NULL) - { + if (values != NULL) { endptr = NULL; errno = 0; - values[i] = strtod (value, &endptr); + values[i] = strtod(value, &endptr); if ((endptr == value) || (errno != 0)) - BAIL_OUT (errno); + BAIL_OUT(errno); } - if (values_names != NULL) - { - values_names[i] = strdup (key); + if (values_names != NULL) { + values_names[i] = strdup(key); if (values_names[i] == NULL) - BAIL_OUT (ENOMEM); + BAIL_OUT(ENOMEM); } } /* for (i = 0; i < res.lines_num; i++) */ @@ -738,12 +696,12 @@ int lcc_getval (lcc_connection_t *c, lcc_identifier_t *ident, /* {{{ */ if (ret_values_names != NULL) *ret_values_names = values_names; - lcc_response_free (&res); + lcc_response_free(&res); return (0); } /* }}} int lcc_getval */ -int lcc_putval (lcc_connection_t *c, const lcc_value_list_t *vl) /* {{{ */ +int lcc_putval(lcc_connection_t *c, const lcc_value_list_t *vl) /* {{{ */ { char ident_str[6 * LCC_NAME_LEN]; char ident_esc[12 * LCC_NAME_LEN]; @@ -751,120 +709,109 @@ int lcc_putval (lcc_connection_t *c, const lcc_value_list_t *vl) /* {{{ */ lcc_response_t res; int status; - if ((c == NULL) || (vl == NULL) || (vl->values_len < 1) - || (vl->values == NULL) || (vl->values_types == NULL)) - { - lcc_set_errno (c, EINVAL); + if ((c == NULL) || (vl == NULL) || (vl->values_len < 1) || + (vl->values == NULL) || (vl->values_types == NULL)) { + lcc_set_errno(c, EINVAL); return (-1); } - status = lcc_identifier_to_string (c, ident_str, sizeof (ident_str), - &vl->identifier); + status = lcc_identifier_to_string(c, ident_str, sizeof(ident_str), + &vl->identifier); if (status != 0) return (status); - SSTRCATF (command, "PUTVAL %s", - lcc_strescape (ident_esc, ident_str, sizeof (ident_esc))); + SSTRCATF(command, "PUTVAL %s", + lcc_strescape(ident_esc, ident_str, sizeof(ident_esc))); if (vl->interval > 0.0) - SSTRCATF (command, " interval=%.3f", vl->interval); + SSTRCATF(command, " interval=%.3f", vl->interval); if (vl->time > 0.0) - SSTRCATF (command, " %.3f", vl->time); + SSTRCATF(command, " %.3f", vl->time); else - SSTRCAT (command, " N"); + SSTRCAT(command, " N"); - for (size_t i = 0; i < vl->values_len; i++) - { + for (size_t i = 0; i < vl->values_len; i++) { if (vl->values_types[i] == LCC_TYPE_COUNTER) - SSTRCATF (command, ":%"PRIu64, vl->values[i].counter); - else if (vl->values_types[i] == LCC_TYPE_GAUGE) - { - if (isnan (vl->values[i].gauge)) - SSTRCATF (command, ":U"); + SSTRCATF(command, ":%" PRIu64, vl->values[i].counter); + else if (vl->values_types[i] == LCC_TYPE_GAUGE) { + if (isnan(vl->values[i].gauge)) + SSTRCATF(command, ":U"); else - SSTRCATF (command, ":%g", vl->values[i].gauge); - } - else if (vl->values_types[i] == LCC_TYPE_DERIVE) - SSTRCATF (command, ":%"PRIu64, vl->values[i].derive); + SSTRCATF(command, ":%g", vl->values[i].gauge); + } else if (vl->values_types[i] == LCC_TYPE_DERIVE) + SSTRCATF(command, ":%" PRIu64, vl->values[i].derive); else if (vl->values_types[i] == LCC_TYPE_ABSOLUTE) - SSTRCATF (command, ":%"PRIu64, vl->values[i].absolute); + SSTRCATF(command, ":%" PRIu64, vl->values[i].absolute); } /* for (i = 0; i < vl->values_len; i++) */ - status = lcc_sendreceive (c, command, &res); + status = lcc_sendreceive(c, command, &res); if (status != 0) return (status); - if (res.status != 0) - { - LCC_SET_ERRSTR (c, "Server error: %s", res.message); - lcc_response_free (&res); + if (res.status != 0) { + LCC_SET_ERRSTR(c, "Server error: %s", res.message); + lcc_response_free(&res); return (-1); } - lcc_response_free (&res); + lcc_response_free(&res); return (0); } /* }}} int lcc_putval */ -int lcc_flush (lcc_connection_t *c, const char *plugin, /* {{{ */ - lcc_identifier_t *ident, int timeout) -{ +int lcc_flush(lcc_connection_t *c, const char *plugin, /* {{{ */ + lcc_identifier_t *ident, int timeout) { char command[1024] = ""; lcc_response_t res; int status; - if (c == NULL) - { - lcc_set_errno (c, EINVAL); + if (c == NULL) { + lcc_set_errno(c, EINVAL); return (-1); } - SSTRCPY (command, "FLUSH"); + SSTRCPY(command, "FLUSH"); if (timeout > 0) - SSTRCATF (command, " timeout=%i", timeout); + SSTRCATF(command, " timeout=%i", timeout); - if (plugin != NULL) - { + if (plugin != NULL) { char buffer[2 * LCC_NAME_LEN]; - SSTRCATF (command, " plugin=%s", - lcc_strescape (buffer, plugin, sizeof (buffer))); + SSTRCATF(command, " plugin=%s", + lcc_strescape(buffer, plugin, sizeof(buffer))); } - if (ident != NULL) - { + if (ident != NULL) { char ident_str[6 * LCC_NAME_LEN]; char ident_esc[12 * LCC_NAME_LEN]; - status = lcc_identifier_to_string (c, ident_str, sizeof (ident_str), ident); + status = lcc_identifier_to_string(c, ident_str, sizeof(ident_str), ident); if (status != 0) return (status); - SSTRCATF (command, " identifier=%s", - lcc_strescape (ident_esc, ident_str, sizeof (ident_esc))); + SSTRCATF(command, " identifier=%s", + lcc_strescape(ident_esc, ident_str, sizeof(ident_esc))); } - status = lcc_sendreceive (c, command, &res); + status = lcc_sendreceive(c, command, &res); if (status != 0) return (status); - if (res.status != 0) - { - LCC_SET_ERRSTR (c, "Server error: %s", res.message); - lcc_response_free (&res); + if (res.status != 0) { + LCC_SET_ERRSTR(c, "Server error: %s", res.message); + lcc_response_free(&res); return (-1); } - lcc_response_free (&res); + lcc_response_free(&res); return (0); } /* }}} int lcc_flush */ /* TODO: Implement lcc_putnotif */ -int lcc_listval (lcc_connection_t *c, /* {{{ */ - lcc_identifier_t **ret_ident, size_t *ret_ident_num) -{ +int lcc_listval(lcc_connection_t *c, /* {{{ */ + lcc_identifier_t **ret_ident, size_t *ret_ident_num) { lcc_response_t res; int status; @@ -874,34 +821,30 @@ int lcc_listval (lcc_connection_t *c, /* {{{ */ if (c == NULL) return (-1); - if ((ret_ident == NULL) || (ret_ident_num == NULL)) - { - lcc_set_errno (c, EINVAL); + if ((ret_ident == NULL) || (ret_ident_num == NULL)) { + lcc_set_errno(c, EINVAL); return (-1); } - status = lcc_sendreceive (c, "LISTVAL", &res); + status = lcc_sendreceive(c, "LISTVAL", &res); if (status != 0) return (status); - if (res.status != 0) - { - LCC_SET_ERRSTR (c, "Server error: %s", res.message); - lcc_response_free (&res); + if (res.status != 0) { + LCC_SET_ERRSTR(c, "Server error: %s", res.message); + lcc_response_free(&res); return (-1); } ident_num = res.lines_num; - ident = malloc (ident_num * sizeof (*ident)); - if (ident == NULL) - { - lcc_response_free (&res); - lcc_set_errno (c, ENOMEM); + ident = malloc(ident_num * sizeof(*ident)); + if (ident == NULL) { + lcc_response_free(&res); + lcc_set_errno(c, ENOMEM); return (-1); } - for (size_t i = 0; i < res.lines_num; i++) - { + for (size_t i = 0; i < res.lines_num; i++) { char *time_str; char *ident_str; @@ -912,29 +855,26 @@ int lcc_listval (lcc_connection_t *c, /* {{{ */ ident_str = time_str; while ((*ident_str != ' ') && (*ident_str != '\t') && (*ident_str != 0)) ident_str++; - while ((*ident_str == ' ') || (*ident_str == '\t')) - { + while ((*ident_str == ' ') || (*ident_str == '\t')) { *ident_str = 0; ident_str++; } - if (*ident_str == 0) - { - lcc_set_errno (c, EILSEQ); + if (*ident_str == 0) { + lcc_set_errno(c, EILSEQ); status = -1; break; } - status = lcc_string_to_identifier (c, ident + i, ident_str); + status = lcc_string_to_identifier(c, ident + i, ident_str); if (status != 0) break; } - lcc_response_free (&res); + lcc_response_free(&res); - if (status != 0) - { - free (ident); + if (status != 0) { + free(ident); return (-1); } @@ -944,60 +884,44 @@ int lcc_listval (lcc_connection_t *c, /* {{{ */ return (0); } /* }}} int lcc_listval */ -const char *lcc_strerror (lcc_connection_t *c) /* {{{ */ +const char *lcc_strerror(lcc_connection_t *c) /* {{{ */ { if (c == NULL) return ("Invalid object"); return (c->errbuf); } /* }}} const char *lcc_strerror */ -int lcc_identifier_to_string (lcc_connection_t *c, /* {{{ */ - char *string, size_t string_size, const lcc_identifier_t *ident) -{ - if ((string == NULL) || (string_size < 6) || (ident == NULL)) - { - lcc_set_errno (c, EINVAL); +int lcc_identifier_to_string(lcc_connection_t *c, /* {{{ */ + char *string, size_t string_size, + const lcc_identifier_t *ident) { + if ((string == NULL) || (string_size < 6) || (ident == NULL)) { + lcc_set_errno(c, EINVAL); return (-1); } - if (ident->plugin_instance[0] == 0) - { + if (ident->plugin_instance[0] == 0) { if (ident->type_instance[0] == 0) - snprintf (string, string_size, "%s/%s/%s", - ident->host, - ident->plugin, - ident->type); + snprintf(string, string_size, "%s/%s/%s", ident->host, ident->plugin, + ident->type); else - snprintf (string, string_size, "%s/%s/%s-%s", - ident->host, - ident->plugin, - ident->type, - ident->type_instance); - } - else - { + snprintf(string, string_size, "%s/%s/%s-%s", ident->host, ident->plugin, + ident->type, ident->type_instance); + } else { if (ident->type_instance[0] == 0) - snprintf (string, string_size, "%s/%s-%s/%s", - ident->host, - ident->plugin, - ident->plugin_instance, - ident->type); + snprintf(string, string_size, "%s/%s-%s/%s", ident->host, ident->plugin, + ident->plugin_instance, ident->type); else - snprintf (string, string_size, "%s/%s-%s/%s-%s", - ident->host, - ident->plugin, - ident->plugin_instance, - ident->type, - ident->type_instance); + snprintf(string, string_size, "%s/%s-%s/%s-%s", ident->host, + ident->plugin, ident->plugin_instance, ident->type, + ident->type_instance); } string[string_size - 1] = 0; return (0); } /* }}} int lcc_identifier_to_string */ -int lcc_string_to_identifier (lcc_connection_t *c, /* {{{ */ - lcc_identifier_t *ident, const char *string) -{ +int lcc_string_to_identifier(lcc_connection_t *c, /* {{{ */ + lcc_identifier_t *ident, const char *string) { char *string_copy; char *host; char *plugin; @@ -1005,65 +929,59 @@ int lcc_string_to_identifier (lcc_connection_t *c, /* {{{ */ char *type; char *type_instance; - string_copy = strdup (string); - if (string_copy == NULL) - { - lcc_set_errno (c, ENOMEM); + string_copy = strdup(string); + if (string_copy == NULL) { + lcc_set_errno(c, ENOMEM); return (-1); } host = string_copy; - plugin = strchr (host, '/'); - if (plugin == NULL) - { - LCC_SET_ERRSTR (c, "Malformed identifier string: %s", string); - free (string_copy); + plugin = strchr(host, '/'); + if (plugin == NULL) { + LCC_SET_ERRSTR(c, "Malformed identifier string: %s", string); + free(string_copy); return (-1); } *plugin = 0; plugin++; - type = strchr (plugin, '/'); - if (type == NULL) - { - LCC_SET_ERRSTR (c, "Malformed identifier string: %s", string); - free (string_copy); + type = strchr(plugin, '/'); + if (type == NULL) { + LCC_SET_ERRSTR(c, "Malformed identifier string: %s", string); + free(string_copy); return (-1); } *type = 0; type++; - plugin_instance = strchr (plugin, '-'); - if (plugin_instance != NULL) - { + plugin_instance = strchr(plugin, '-'); + if (plugin_instance != NULL) { *plugin_instance = 0; plugin_instance++; } - type_instance = strchr (type, '-'); - if (type_instance != NULL) - { + type_instance = strchr(type, '-'); + if (type_instance != NULL) { *type_instance = 0; type_instance++; } - memset (ident, 0, sizeof (*ident)); + memset(ident, 0, sizeof(*ident)); - SSTRCPY (ident->host, host); - SSTRCPY (ident->plugin, plugin); + SSTRCPY(ident->host, host); + SSTRCPY(ident->plugin, plugin); if (plugin_instance != NULL) - SSTRCPY (ident->plugin_instance, plugin_instance); - SSTRCPY (ident->type, type); + SSTRCPY(ident->plugin_instance, plugin_instance); + SSTRCPY(ident->type, type); if (type_instance != NULL) - SSTRCPY (ident->type_instance, type_instance); + SSTRCPY(ident->type_instance, type_instance); - free (string_copy); + free(string_copy); return (0); } /* }}} int lcc_string_to_identifier */ -int lcc_identifier_compare (const void *a, /* {{{ */ - const void *b) -{ +int lcc_identifier_compare(const void *a, /* {{{ */ + const void *b) { const lcc_identifier_t *i0 = a; const lcc_identifier_t *i1 = b; int status; @@ -1075,34 +993,32 @@ int lcc_identifier_compare (const void *a, /* {{{ */ else if (i1 == NULL) return (1); -#define CMP_FIELD(f) do { \ - status = strcmp (i0->f, i1->f); \ - if (status != 0) \ - return (status); \ -} while (0); +#define CMP_FIELD(f) \ + do { \ + status = strcmp(i0->f, i1->f); \ + if (status != 0) \ + return (status); \ + } while (0); - CMP_FIELD (host); - CMP_FIELD (plugin); - CMP_FIELD (plugin_instance); - CMP_FIELD (type); - CMP_FIELD (type_instance); + CMP_FIELD(host); + CMP_FIELD(plugin); + CMP_FIELD(plugin_instance); + CMP_FIELD(type); + CMP_FIELD(type_instance); #undef CMP_FIELD - return (0); + return (0); } /* }}} int lcc_identifier_compare */ -int lcc_sort_identifiers (lcc_connection_t *c, /* {{{ */ - lcc_identifier_t *idents, size_t idents_num) -{ - if (idents == NULL) - { - lcc_set_errno (c, EINVAL); +int lcc_sort_identifiers(lcc_connection_t *c, /* {{{ */ + lcc_identifier_t *idents, size_t idents_num) { + if (idents == NULL) { + lcc_set_errno(c, EINVAL); return (-1); } - qsort (idents, idents_num, sizeof (*idents), - lcc_identifier_compare); + qsort(idents, idents_num, sizeof(*idents), lcc_identifier_compare); return (0); } /* }}} int lcc_sort_identifiers */ diff --git a/src/libcollectdclient/collectd/client.h b/src/libcollectdclient/collectd/client.h index 47462a6b..36aaf921 100644 --- a/src/libcollectdclient/collectd/client.h +++ b/src/libcollectdclient/collectd/client.h @@ -33,14 +33,14 @@ * set to something non-zero, all lines sent to / received from the daemon are * printed to STDOUT. */ #ifndef LCC_TRACE_ENV -# define LCC_TRACE_ENV "COLLECTD_TRACE" +#define LCC_TRACE_ENV "COLLECTD_TRACE" #endif /* * Includes (for data types) */ #if HAVE_STDINT_H -# include +#include #endif #include #include @@ -55,9 +55,9 @@ * Types */ #define LCC_TYPE_COUNTER 0 -#define LCC_TYPE_GAUGE 1 -#define LCC_TYPE_DERIVE 2 -#define LCC_TYPE_ABSOLUTE 3 +#define LCC_TYPE_GAUGE 1 +#define LCC_TYPE_DERIVE 2 +#define LCC_TYPE_ABSOLUTE 3 LCC_BEGIN_DECLS @@ -66,17 +66,15 @@ typedef double gauge_t; typedef uint64_t derive_t; typedef uint64_t absolute_t; -union value_u -{ +union value_u { counter_t counter; - gauge_t gauge; - derive_t derive; + gauge_t gauge; + derive_t derive; absolute_t absolute; }; typedef union value_u value_t; -struct lcc_identifier_s -{ +struct lcc_identifier_s { char host[LCC_NAME_LEN]; char plugin[LCC_NAME_LEN]; char plugin_instance[LCC_NAME_LEN]; @@ -84,19 +82,20 @@ struct lcc_identifier_s char type_instance[LCC_NAME_LEN]; }; typedef struct lcc_identifier_s lcc_identifier_t; -#define LCC_IDENTIFIER_INIT { "localhost", "", "", "", "" } +#define LCC_IDENTIFIER_INIT \ + { "localhost", "", "", "", "" } -struct lcc_value_list_s -{ +struct lcc_value_list_s { value_t *values; - int *values_types; - size_t values_len; - double time; - double interval; + int *values_types; + size_t values_len; + double time; + double interval; lcc_identifier_t identifier; }; typedef struct lcc_value_list_s lcc_value_list_t; -#define LCC_VALUE_LIST_INIT { NULL, NULL, 0, 0, 0, LCC_IDENTIFIER_INIT } +#define LCC_VALUE_LIST_INIT \ + { NULL, NULL, 0, 0, 0, LCC_IDENTIFIER_INIT } struct lcc_connection_s; typedef struct lcc_connection_s lcc_connection_t; @@ -104,37 +103,41 @@ typedef struct lcc_connection_s lcc_connection_t; /* * Functions */ -int lcc_connect (const char *address, lcc_connection_t **ret_con); -int lcc_disconnect (lcc_connection_t *c); -#define LCC_DESTROY(c) do { lcc_disconnect (c); (c) = NULL; } while (0) +int lcc_connect(const char *address, lcc_connection_t **ret_con); +int lcc_disconnect(lcc_connection_t *c); +#define LCC_DESTROY(c) \ + do { \ + lcc_disconnect(c); \ + (c) = NULL; \ + } while (0) -int lcc_getval (lcc_connection_t *c, lcc_identifier_t *ident, - size_t *ret_values_num, gauge_t **ret_values, char ***ret_values_names); +int lcc_getval(lcc_connection_t *c, lcc_identifier_t *ident, + size_t *ret_values_num, gauge_t **ret_values, + char ***ret_values_names); -int lcc_putval (lcc_connection_t *c, const lcc_value_list_t *vl); +int lcc_putval(lcc_connection_t *c, const lcc_value_list_t *vl); -int lcc_flush (lcc_connection_t *c, const char *plugin, - lcc_identifier_t *ident, int timeout); +int lcc_flush(lcc_connection_t *c, const char *plugin, lcc_identifier_t *ident, + int timeout); -int lcc_listval (lcc_connection_t *c, - lcc_identifier_t **ret_ident, size_t *ret_ident_num); +int lcc_listval(lcc_connection_t *c, lcc_identifier_t **ret_ident, + size_t *ret_ident_num); /* TODO: putnotif */ -const char *lcc_strerror (lcc_connection_t *c); +const char *lcc_strerror(lcc_connection_t *c); -int lcc_identifier_to_string (lcc_connection_t *c, - char *string, size_t string_size, const lcc_identifier_t *ident); -int lcc_string_to_identifier (lcc_connection_t *c, - lcc_identifier_t *ident, const char *string); +int lcc_identifier_to_string(lcc_connection_t *c, char *string, + size_t string_size, const lcc_identifier_t *ident); +int lcc_string_to_identifier(lcc_connection_t *c, lcc_identifier_t *ident, + const char *string); /* Compares the identifiers "i0" and "i1" and returns less than zero or greater * than zero if "i0" is smaller than or greater than "i1", respectively. If * "i0" and "i1" are identical, zero is returned. */ -int lcc_identifier_compare (const void *i0, - const void *i1); -int lcc_sort_identifiers (lcc_connection_t *c, - lcc_identifier_t *idents, size_t idents_num); +int lcc_identifier_compare(const void *i0, const void *i1); +int lcc_sort_identifiers(lcc_connection_t *c, lcc_identifier_t *idents, + size_t idents_num); LCC_END_DECLS diff --git a/src/libcollectdclient/collectd/network.h b/src/libcollectdclient/collectd/network.h index 64cf9c93..fdb9b33f 100644 --- a/src/libcollectdclient/collectd/network.h +++ b/src/libcollectdclient/collectd/network.h @@ -27,14 +27,14 @@ #ifndef LIBCOLLECTDCLIENT_NETWORK_H #define LIBCOLLECTDCLIENT_NETWORK_H 1 -#include #include +#include #include "client.h" #define NET_DEFAULT_V4_ADDR "239.192.74.66" #define NET_DEFAULT_V6_ADDR "ff18::efc0:4a42" -#define NET_DEFAULT_PORT "25826" +#define NET_DEFAULT_PORT "25826" struct lcc_network_s; typedef struct lcc_network_s lcc_network_t; @@ -42,39 +42,32 @@ typedef struct lcc_network_s lcc_network_t; struct lcc_server_s; typedef struct lcc_server_s lcc_server_t; -enum lcc_security_level_e -{ - NONE, - SIGN, - ENCRYPT -}; +enum lcc_security_level_e { NONE, SIGN, ENCRYPT }; typedef enum lcc_security_level_e lcc_security_level_t; /* * Create / destroy object */ -lcc_network_t *lcc_network_create (void); -void lcc_network_destroy (lcc_network_t *net); +lcc_network_t *lcc_network_create(void); +void lcc_network_destroy(lcc_network_t *net); /* * Add servers */ -lcc_server_t *lcc_server_create (lcc_network_t *net, - const char *node, const char *service); -int lcc_server_destroy (lcc_network_t *net, lcc_server_t *srv); +lcc_server_t *lcc_server_create(lcc_network_t *net, const char *node, + const char *service); +int lcc_server_destroy(lcc_network_t *net, lcc_server_t *srv); /* Configure servers */ -int lcc_server_set_ttl (lcc_server_t *srv, uint8_t ttl); -int lcc_server_set_interface (lcc_server_t *srv, char const *interface); -int lcc_server_set_security_level (lcc_server_t *srv, - lcc_security_level_t level, - const char *username, const char *password); +int lcc_server_set_ttl(lcc_server_t *srv, uint8_t ttl); +int lcc_server_set_interface(lcc_server_t *srv, char const *interface); +int lcc_server_set_security_level(lcc_server_t *srv, lcc_security_level_t level, + const char *username, const char *password); /* * Send data */ -int lcc_network_values_send (lcc_network_t *net, - const lcc_value_list_t *vl); +int lcc_network_values_send(lcc_network_t *net, const lcc_value_list_t *vl); #if 0 int lcc_network_notification_send (lcc_network_t *net, const lcc_notification_t *notif); diff --git a/src/libcollectdclient/collectd/network_buffer.h b/src/libcollectdclient/collectd/network_buffer.h index edf49ff1..5612458b 100644 --- a/src/libcollectdclient/collectd/network_buffer.h +++ b/src/libcollectdclient/collectd/network_buffer.h @@ -37,21 +37,22 @@ struct lcc_network_buffer_s; typedef struct lcc_network_buffer_s lcc_network_buffer_t; -lcc_network_buffer_t *lcc_network_buffer_create (size_t size); -void lcc_network_buffer_destroy (lcc_network_buffer_t *nb); +lcc_network_buffer_t *lcc_network_buffer_create(size_t size); +void lcc_network_buffer_destroy(lcc_network_buffer_t *nb); -int lcc_network_buffer_set_security_level (lcc_network_buffer_t *nb, - lcc_security_level_t level, - const char *user, const char *password); +int lcc_network_buffer_set_security_level(lcc_network_buffer_t *nb, + lcc_security_level_t level, + const char *user, + const char *password); -int lcc_network_buffer_initialize (lcc_network_buffer_t *nb); -int lcc_network_buffer_finalize (lcc_network_buffer_t *nb); +int lcc_network_buffer_initialize(lcc_network_buffer_t *nb); +int lcc_network_buffer_finalize(lcc_network_buffer_t *nb); -int lcc_network_buffer_add_value (lcc_network_buffer_t *nb, - const lcc_value_list_t *vl); +int lcc_network_buffer_add_value(lcc_network_buffer_t *nb, + const lcc_value_list_t *vl); -int lcc_network_buffer_get (lcc_network_buffer_t *nb, - void *buffer, size_t *buffer_size); +int lcc_network_buffer_get(lcc_network_buffer_t *nb, void *buffer, + size_t *buffer_size); #endif /* LIBCOLLECTDCLIENT_NETWORK_BUFFER_H */ /* vim: set sw=2 sts=2 et : */ diff --git a/src/libcollectdclient/network.c b/src/libcollectdclient/network.c index 16293ca0..a21799c2 100644 --- a/src/libcollectdclient/network.c +++ b/src/libcollectdclient/network.c @@ -28,23 +28,23 @@ #include "collectd.h" -#include +#include +#include #include -#include +#include #include -#include -#include +#include -#include -#include #include +#include +#include #if HAVE_NETINET_IN_H -# include +#include #endif #if HAVE_NET_IF_H -# include +#include #endif #include "collectd/network.h" @@ -53,13 +53,11 @@ /* * Private data types */ -struct lcc_network_s -{ +struct lcc_network_s { lcc_server_t *servers; }; -struct lcc_server_s -{ +struct lcc_server_s { char *node; char *service; @@ -80,7 +78,7 @@ struct lcc_server_s /* * Private functions */ -static int server_close_socket (lcc_server_t *srv) /* {{{ */ +static int server_close_socket(lcc_server_t *srv) /* {{{ */ { if (srv == NULL) return (EINVAL); @@ -88,36 +86,36 @@ static int server_close_socket (lcc_server_t *srv) /* {{{ */ if (srv->fd < 0) return (0); - close (srv->fd); + close(srv->fd); srv->fd = -1; - free (srv->sa); + free(srv->sa); srv->sa = NULL; srv->sa_len = 0; return (0); } /* }}} int server_close_socket */ -static void int_server_destroy (lcc_server_t *srv) /* {{{ */ +static void int_server_destroy(lcc_server_t *srv) /* {{{ */ { lcc_server_t *next; if (srv == NULL) return; - server_close_socket (srv); + server_close_socket(srv); next = srv->next; - free (srv->node); - free (srv->service); - free (srv->username); - free (srv->password); - free (srv); + free(srv->node); + free(srv->service); + free(srv->username); + free(srv->password); + free(srv); - int_server_destroy (next); + int_server_destroy(next); } /* }}} void int_server_destroy */ -static int server_open_socket (lcc_server_t *srv) /* {{{ */ +static int server_open_socket(lcc_server_t *srv) /* {{{ */ { struct addrinfo *ai_list; int status; @@ -126,117 +124,109 @@ static int server_open_socket (lcc_server_t *srv) /* {{{ */ return (EINVAL); if (srv->fd >= 0) - server_close_socket (srv); + server_close_socket(srv); - struct addrinfo ai_hints = { - .ai_family = AF_UNSPEC, - .ai_flags = AI_ADDRCONFIG, - .ai_socktype = SOCK_DGRAM - }; + struct addrinfo ai_hints = {.ai_family = AF_UNSPEC, + .ai_flags = AI_ADDRCONFIG, + .ai_socktype = SOCK_DGRAM}; - status = getaddrinfo (srv->node, srv->service, &ai_hints, &ai_list); + status = getaddrinfo(srv->node, srv->service, &ai_hints, &ai_list); if (status != 0) return (status); - assert (ai_list != NULL); + assert(ai_list != NULL); - for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) - { - srv->fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); + for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; + ai_ptr = ai_ptr->ai_next) { + srv->fd = + socket(ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); if (srv->fd < 0) continue; - if (ai_ptr->ai_family == AF_INET) - { - struct sockaddr_in *addr = (struct sockaddr_in *) ai_ptr->ai_addr; + if (ai_ptr->ai_family == AF_INET) { + struct sockaddr_in *addr = (struct sockaddr_in *)ai_ptr->ai_addr; int optname; - if (IN_MULTICAST (ntohl (addr->sin_addr.s_addr))) + if (IN_MULTICAST(ntohl(addr->sin_addr.s_addr))) optname = IP_MULTICAST_TTL; else optname = IP_TTL; - status = setsockopt (srv->fd, IPPROTO_IP, optname, - &srv->ttl, sizeof (srv->ttl)); - } - else if (ai_ptr->ai_family == AF_INET6) - { - /* Useful example: http://gsyc.escet.urjc.es/~eva/IPv6-web/examples/mcast.html */ - struct sockaddr_in6 *addr = (struct sockaddr_in6 *) ai_ptr->ai_addr; + status = + setsockopt(srv->fd, IPPROTO_IP, optname, &srv->ttl, sizeof(srv->ttl)); + } else if (ai_ptr->ai_family == AF_INET6) { + /* Useful example: + * http://gsyc.escet.urjc.es/~eva/IPv6-web/examples/mcast.html */ + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)ai_ptr->ai_addr; int optname; - if (IN6_IS_ADDR_MULTICAST (&addr->sin6_addr)) + if (IN6_IS_ADDR_MULTICAST(&addr->sin6_addr)) optname = IPV6_MULTICAST_HOPS; else optname = IPV6_UNICAST_HOPS; - status = setsockopt (srv->fd, IPPROTO_IPV6, optname, - &srv->ttl, sizeof (srv->ttl)); + status = setsockopt(srv->fd, IPPROTO_IPV6, optname, &srv->ttl, + sizeof(srv->ttl)); } - if (status != 0) - { + if (status != 0) { /* setsockopt failed. */ - close (srv->fd); + close(srv->fd); srv->fd = -1; continue; } - srv->sa = malloc (ai_ptr->ai_addrlen); - if (srv->sa == NULL) - { - close (srv->fd); + srv->sa = malloc(ai_ptr->ai_addrlen); + if (srv->sa == NULL) { + close(srv->fd); srv->fd = -1; continue; } - memcpy (srv->sa, ai_ptr->ai_addr, ai_ptr->ai_addrlen); + memcpy(srv->sa, ai_ptr->ai_addr, ai_ptr->ai_addrlen); srv->sa_len = ai_ptr->ai_addrlen; break; } - freeaddrinfo (ai_list); + freeaddrinfo(ai_list); if (srv->fd < 0) return (-1); return (0); } /* }}} int server_open_socket */ -static int server_send_buffer (lcc_server_t *srv) /* {{{ */ +static int server_send_buffer(lcc_server_t *srv) /* {{{ */ { - char buffer[LCC_NETWORK_BUFFER_SIZE_DEFAULT] = { 0 }; + char buffer[LCC_NETWORK_BUFFER_SIZE_DEFAULT] = {0}; size_t buffer_size; int status; - if (srv->fd < 0) - { - status = server_open_socket (srv); + if (srv->fd < 0) { + status = server_open_socket(srv); if (status != 0) return (status); } - buffer_size = sizeof (buffer); + buffer_size = sizeof(buffer); - status = lcc_network_buffer_finalize (srv->buffer); - if (status != 0) - { - lcc_network_buffer_initialize (srv->buffer); + status = lcc_network_buffer_finalize(srv->buffer); + if (status != 0) { + lcc_network_buffer_initialize(srv->buffer); return (status); } - status = lcc_network_buffer_get (srv->buffer, buffer, &buffer_size); - lcc_network_buffer_initialize (srv->buffer); + status = lcc_network_buffer_get(srv->buffer, buffer, &buffer_size); + lcc_network_buffer_initialize(srv->buffer); if (status != 0) return (status); - if (buffer_size > sizeof (buffer)) - buffer_size = sizeof (buffer); + if (buffer_size > sizeof(buffer)) + buffer_size = sizeof(buffer); - while (42) - { - assert (srv->fd >= 0); - assert (srv->sa != NULL); - status = (int) sendto (srv->fd, buffer, buffer_size, /* flags = */ 0, - srv->sa, srv->sa_len); + while (42) { + assert(srv->fd >= 0); + assert(srv->sa != NULL); + status = (int)sendto(srv->fd, buffer, buffer_size, /* flags = */ 0, srv->sa, + srv->sa_len); if ((status < 0) && ((errno == EINTR) || (errno == EAGAIN))) continue; @@ -248,27 +238,26 @@ static int server_send_buffer (lcc_server_t *srv) /* {{{ */ return (0); } /* }}} int server_send_buffer */ -static int server_value_add (lcc_server_t *srv, /* {{{ */ - const lcc_value_list_t *vl) -{ +static int server_value_add(lcc_server_t *srv, /* {{{ */ + const lcc_value_list_t *vl) { int status; - status = lcc_network_buffer_add_value (srv->buffer, vl); + status = lcc_network_buffer_add_value(srv->buffer, vl); if (status == 0) return (0); - server_send_buffer (srv); - return (lcc_network_buffer_add_value (srv->buffer, vl)); + server_send_buffer(srv); + return (lcc_network_buffer_add_value(srv->buffer, vl)); } /* }}} int server_value_add */ /* * Public functions */ -lcc_network_t *lcc_network_create (void) /* {{{ */ +lcc_network_t *lcc_network_create(void) /* {{{ */ { lcc_network_t *net; - net = calloc (1, sizeof (*net)); + net = calloc(1, sizeof(*net)); if (net == NULL) return (NULL); @@ -277,17 +266,16 @@ lcc_network_t *lcc_network_create (void) /* {{{ */ return (net); } /* }}} lcc_network_t *lcc_network_create */ -void lcc_network_destroy (lcc_network_t *net) /* {{{ */ +void lcc_network_destroy(lcc_network_t *net) /* {{{ */ { if (net == NULL) return; - int_server_destroy (net->servers); - free (net); + int_server_destroy(net->servers); + free(net); } /* }}} void lcc_network_destroy */ -lcc_server_t *lcc_server_create (lcc_network_t *net, /* {{{ */ - const char *node, const char *service) -{ +lcc_server_t *lcc_server_create(lcc_network_t *net, /* {{{ */ + const char *node, const char *service) { lcc_server_t *srv; if ((net == NULL) || (node == NULL)) @@ -295,7 +283,7 @@ lcc_server_t *lcc_server_create (lcc_network_t *net, /* {{{ */ if (service == NULL) service = NET_DEFAULT_PORT; - srv = calloc (1, sizeof (*srv)); + srv = calloc(1, sizeof(*srv)); if (srv == NULL) return (NULL); @@ -305,36 +293,30 @@ lcc_server_t *lcc_server_create (lcc_network_t *net, /* {{{ */ srv->password = NULL; srv->next = NULL; - srv->node = strdup (node); - if (srv->node == NULL) - { - free (srv); + srv->node = strdup(node); + if (srv->node == NULL) { + free(srv); return (NULL); } - srv->service = strdup (service); - if (srv->service == NULL) - { - free (srv->node); - free (srv); + srv->service = strdup(service); + if (srv->service == NULL) { + free(srv->node); + free(srv); return (NULL); } - srv->buffer = lcc_network_buffer_create (/* size = */ 0); - if (srv->buffer == NULL) - { - free (srv->service); - free (srv->node); - free (srv); + srv->buffer = lcc_network_buffer_create(/* size = */ 0); + if (srv->buffer == NULL) { + free(srv->service); + free(srv->node); + free(srv); return (NULL); } - if (net->servers == NULL) - { + if (net->servers == NULL) { net->servers = srv; - } - else - { + } else { lcc_server_t *last = net->servers; while (last->next != NULL) @@ -346,18 +328,15 @@ lcc_server_t *lcc_server_create (lcc_network_t *net, /* {{{ */ return (srv); } /* }}} lcc_server_t *lcc_server_create */ -int lcc_server_destroy (lcc_network_t *net, lcc_server_t *srv) /* {{{ */ +int lcc_server_destroy(lcc_network_t *net, lcc_server_t *srv) /* {{{ */ { if ((net == NULL) || (srv == NULL)) return (EINVAL); - if (net->servers == srv) - { + if (net->servers == srv) { net->servers = srv->next; srv->next = NULL; - } - else - { + } else { lcc_server_t *prev = net->servers; while ((prev != NULL) && (prev->next != srv)) @@ -370,22 +349,22 @@ int lcc_server_destroy (lcc_network_t *net, lcc_server_t *srv) /* {{{ */ srv->next = NULL; } - int_server_destroy (srv); + int_server_destroy(srv); return (0); } /* }}} int lcc_server_destroy */ -int lcc_server_set_ttl (lcc_server_t *srv, uint8_t ttl) /* {{{ */ +int lcc_server_set_ttl(lcc_server_t *srv, uint8_t ttl) /* {{{ */ { if (srv == NULL) return (EINVAL); - srv->ttl = (int) ttl; + srv->ttl = (int)ttl; return (0); } /* }}} int lcc_server_set_ttl */ -int lcc_server_set_interface (lcc_server_t *srv, char const *interface) /* {{{ */ +int lcc_server_set_interface(lcc_server_t *srv, char const *interface) /* {{{ */ { unsigned int if_index; int status; @@ -393,37 +372,31 @@ int lcc_server_set_interface (lcc_server_t *srv, char const *interface) /* {{{ * if ((srv == NULL) || (interface == NULL)) return (EINVAL); - if_index = if_nametoindex (interface); + if_index = if_nametoindex(interface); if (if_index == 0) return (ENOENT); /* IPv4 multicast */ - if (srv->sa->sa_family == AF_INET) - { - struct sockaddr_in *addr = (struct sockaddr_in *) srv->sa; + if (srv->sa->sa_family == AF_INET) { + struct sockaddr_in *addr = (struct sockaddr_in *)srv->sa; - if (IN_MULTICAST (ntohl (addr->sin_addr.s_addr))) - { + if (IN_MULTICAST(ntohl(addr->sin_addr.s_addr))) { #if HAVE_STRUCT_IP_MREQN_IMR_IFINDEX /* If possible, use the "ip_mreqn" structure which has * an "interface index" member. Using the interface * index is preferred here, because of its similarity * to the way IPv6 handles this. Unfortunately, it * appears not to be portable. */ - struct ip_mreqn mreq = { - .imr_multiaddr.s_addr = addr->sin_addr.s_addr, - .imr_address.s_addr = ntohl (INADDR_ANY), - .imr_ifindex = (int) if_index - }; + struct ip_mreqn mreq = {.imr_multiaddr.s_addr = addr->sin_addr.s_addr, + .imr_address.s_addr = ntohl(INADDR_ANY), + .imr_ifindex = (int)if_index}; #else - struct ip_mreq mreq = { - .imr_multiaddr.s_addr = addr->sin_addr.s_addr, - .imr_interface.s_addr = ntohl (INADDR_ANY) - }; + struct ip_mreq mreq = {.imr_multiaddr.s_addr = addr->sin_addr.s_addr, + .imr_interface.s_addr = ntohl(INADDR_ANY)}; #endif - status = setsockopt (srv->fd, IPPROTO_IP, IP_MULTICAST_IF, - &mreq, sizeof (mreq)); + status = + setsockopt(srv->fd, IPPROTO_IP, IP_MULTICAST_IF, &mreq, sizeof(mreq)); if (status != 0) return (status); @@ -432,14 +405,12 @@ int lcc_server_set_interface (lcc_server_t *srv, char const *interface) /* {{{ * } /* IPv6 multicast */ - if (srv->sa->sa_family == AF_INET6) - { - struct sockaddr_in6 *addr = (struct sockaddr_in6 *) srv->sa; - - if (IN6_IS_ADDR_MULTICAST (&addr->sin6_addr)) - { - status = setsockopt (srv->fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, - &if_index, sizeof (if_index)); + if (srv->sa->sa_family == AF_INET6) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)srv->sa; + + if (IN6_IS_ADDR_MULTICAST(&addr->sin6_addr)) { + status = setsockopt(srv->fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &if_index, + sizeof(if_index)); if (status != 0) return (status); @@ -447,10 +418,10 @@ int lcc_server_set_interface (lcc_server_t *srv, char const *interface) /* {{{ * } } - /* else: Not a multicast interface. */ +/* else: Not a multicast interface. */ #if defined(SO_BINDTODEVICE) - status = setsockopt (srv->fd, SOL_SOCKET, SO_BINDTODEVICE, interface, - (socklen_t) (strlen (interface) + 1)); + status = setsockopt(srv->fd, SOL_SOCKET, SO_BINDTODEVICE, interface, + (socklen_t)(strlen(interface) + 1)); if (status != 0) return (-1); #endif @@ -458,22 +429,20 @@ int lcc_server_set_interface (lcc_server_t *srv, char const *interface) /* {{{ * return (0); } /* }}} int lcc_server_set_interface */ -int lcc_server_set_security_level (lcc_server_t *srv, /* {{{ */ - lcc_security_level_t level, - const char *username, const char *password) -{ - return (lcc_network_buffer_set_security_level (srv->buffer, - level, username, password)); +int lcc_server_set_security_level(lcc_server_t *srv, /* {{{ */ + lcc_security_level_t level, + const char *username, const char *password) { + return (lcc_network_buffer_set_security_level(srv->buffer, level, username, + password)); } /* }}} int lcc_server_set_security_level */ -int lcc_network_values_send (lcc_network_t *net, /* {{{ */ - const lcc_value_list_t *vl) -{ +int lcc_network_values_send(lcc_network_t *net, /* {{{ */ + const lcc_value_list_t *vl) { if ((net == NULL) || (vl == NULL)) return (EINVAL); for (lcc_server_t *srv = net->servers; srv != NULL; srv = srv->next) - server_value_add (srv, vl); + server_value_add(srv, vl); return (0); } /* }}} int lcc_network_values_send */ diff --git a/src/libcollectdclient/network_buffer.c b/src/libcollectdclient/network_buffer.c index 2c6277c8..aa4941d8 100644 --- a/src/libcollectdclient/network_buffer.c +++ b/src/libcollectdclient/network_buffer.c @@ -26,76 +26,75 @@ #include "config.h" -#include -#include -#include +#include /* htons */ #include #include -#include /* htons */ +#include +#include +#include #include #if HAVE_LIBGCRYPT -# if defined __APPLE__ +#if defined __APPLE__ /* default xcode compiler throws warnings even when deprecated functionality * is not used. -Werror breaks the build because of erroneous warnings. * http://stackoverflow.com/questions/10556299/compiler-warnings-with-libgcrypt-v1-5-0/12830209#12830209 */ -# pragma GCC diagnostic ignored "-Wdeprecated-declarations" -# endif +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif /* FreeBSD's copy of libgcrypt extends the existing GCRYPT_NO_DEPRECATED * to properly hide all deprecated functionality. * http://svnweb.freebsd.org/ports/head/security/libgcrypt/files/patch-src__gcrypt.h.in */ -# define GCRYPT_NO_DEPRECATED -# include -# if defined __APPLE__ +#define GCRYPT_NO_DEPRECATED +#include +#if defined __APPLE__ /* Re enable deprecation warnings */ -# pragma GCC diagnostic warning "-Wdeprecated-declarations" -# endif -# if GCRYPT_VERSION_NUMBER < 0x010600 +#pragma GCC diagnostic warning "-Wdeprecated-declarations" +#endif +#if GCRYPT_VERSION_NUMBER < 0x010600 GCRY_THREAD_OPTION_PTHREAD_IMPL; -# endif +#endif #endif #include "collectd/network_buffer.h" -#define TYPE_HOST 0x0000 -#define TYPE_TIME 0x0001 -#define TYPE_TIME_HR 0x0008 -#define TYPE_PLUGIN 0x0002 +#define TYPE_HOST 0x0000 +#define TYPE_TIME 0x0001 +#define TYPE_TIME_HR 0x0008 +#define TYPE_PLUGIN 0x0002 #define TYPE_PLUGIN_INSTANCE 0x0003 -#define TYPE_TYPE 0x0004 -#define TYPE_TYPE_INSTANCE 0x0005 -#define TYPE_VALUES 0x0006 -#define TYPE_INTERVAL 0x0007 -#define TYPE_INTERVAL_HR 0x0009 +#define TYPE_TYPE 0x0004 +#define TYPE_TYPE_INSTANCE 0x0005 +#define TYPE_VALUES 0x0006 +#define TYPE_INTERVAL 0x0007 +#define TYPE_INTERVAL_HR 0x0009 /* Types to transmit notifications */ -#define TYPE_MESSAGE 0x0100 -#define TYPE_SEVERITY 0x0101 +#define TYPE_MESSAGE 0x0100 +#define TYPE_SEVERITY 0x0101 -#define TYPE_SIGN_SHA256 0x0200 -#define TYPE_ENCR_AES256 0x0210 +#define TYPE_SIGN_SHA256 0x0200 +#define TYPE_ENCR_AES256 0x0210 #define PART_SIGNATURE_SHA256_SIZE 36 #define PART_ENCRYPTION_AES256_SIZE 42 -#define ADD_GENERIC(nb,srcptr,size) do { \ - assert ((size) <= (nb)->free); \ - memcpy ((nb)->ptr, (srcptr), (size)); \ - (nb)->ptr += (size); \ - (nb)->free -= (size); \ -} while (0) +#define ADD_GENERIC(nb, srcptr, size) \ + do { \ + assert((size) <= (nb)->free); \ + memcpy((nb)->ptr, (srcptr), (size)); \ + (nb)->ptr += (size); \ + (nb)->free -= (size); \ + } while (0) -#define ADD_STATIC(nb,var) \ - ADD_GENERIC(nb,&(var),sizeof(var)); +#define ADD_STATIC(nb, var) ADD_GENERIC(nb, &(var), sizeof(var)); /* * Data types */ -struct lcc_network_buffer_s -{ +struct lcc_network_buffer_s { char *buffer; size_t size; @@ -114,15 +113,16 @@ struct lcc_network_buffer_s #endif }; -#define SSTRNCPY(dst,src,sz) do { \ - strncpy ((dst), (src), (sz)); \ - (dst)[(sz) - 1] = 0; \ -} while (0) +#define SSTRNCPY(dst, src, sz) \ + do { \ + strncpy((dst), (src), (sz)); \ + (dst)[(sz)-1] = 0; \ + } while (0) /* * Private functions */ -static _Bool have_gcrypt (void) /* {{{ */ +static _Bool have_gcrypt(void) /* {{{ */ { static _Bool result = 0; static _Bool need_init = 1; @@ -132,38 +132,37 @@ static _Bool have_gcrypt (void) /* {{{ */ need_init = 0; #if HAVE_LIBGCRYPT -# if GCRYPT_VERSION_NUMBER < 0x010600 - if (gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread)) +#if GCRYPT_VERSION_NUMBER < 0x010600 + if (gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread)) return (0); -# endif +#endif - if (!gcry_check_version (GCRYPT_VERSION)) + if (!gcry_check_version(GCRYPT_VERSION)) return (0); - if (!gcry_control (GCRYCTL_INIT_SECMEM, 32768, 0)) + if (!gcry_control(GCRYCTL_INIT_SECMEM, 32768, 0)) return (0); - gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); result = 1; return (1); #else - return(0); + return (0); #endif } /* }}} _Bool have_gcrypt */ #ifndef HAVE_HTONLL -static uint64_t htonll (uint64_t val) /* {{{ */ +static uint64_t htonll(uint64_t val) /* {{{ */ { static int config = 0; uint32_t hi; uint32_t lo; - if (config == 0) - { + if (config == 0) { uint16_t h = 0x1234; - uint16_t n = htons (h); + uint16_t n = htons(h); if (h == n) config = 1; @@ -174,61 +173,59 @@ static uint64_t htonll (uint64_t val) /* {{{ */ if (config == 1) return (val); - hi = (uint32_t) (val >> 32); - lo = (uint32_t) (val & 0x00000000FFFFFFFF); + hi = (uint32_t)(val >> 32); + lo = (uint32_t)(val & 0x00000000FFFFFFFF); - hi = htonl (hi); - lo = htonl (lo); + hi = htonl(hi); + lo = htonl(lo); - return ((((uint64_t) lo) << 32) | ((uint64_t) hi)); + return ((((uint64_t)lo) << 32) | ((uint64_t)hi)); } /* }}} uint64_t htonll */ #endif -static double htond (double val) /* {{{ */ +static double htond(double val) /* {{{ */ { static int config = 0; - union { uint8_t byte[8]; double floating; } in; - union { uint8_t byte[8]; double floating; } out; + union { + uint8_t byte[8]; + double floating; + } in; + union { + uint8_t byte[8]; + double floating; + } out; - if (config == 0) - { + if (config == 0) { double d = 8.642135e130; uint8_t c[8]; - memcpy (c, &d, 8); + memcpy(c, &d, 8); - if ((c[0] == 0x2f) && (c[1] == 0x25) - && (c[2] == 0xc0) && (c[3] == 0xc7) - && (c[4] == 0x43) && (c[5] == 0x2b) - && (c[6] == 0x1f) && (c[7] == 0x5b)) + if ((c[0] == 0x2f) && (c[1] == 0x25) && (c[2] == 0xc0) && (c[3] == 0xc7) && + (c[4] == 0x43) && (c[5] == 0x2b) && (c[6] == 0x1f) && (c[7] == 0x5b)) config = 1; /* need nothing */ - else if ((c[7] == 0x2f) && (c[6] == 0x25) - && (c[5] == 0xc0) && (c[4] == 0xc7) - && (c[3] == 0x43) && (c[2] == 0x2b) - && (c[1] == 0x1f) && (c[0] == 0x5b)) + else if ((c[7] == 0x2f) && (c[6] == 0x25) && (c[5] == 0xc0) && + (c[4] == 0xc7) && (c[3] == 0x43) && (c[2] == 0x2b) && + (c[1] == 0x1f) && (c[0] == 0x5b)) config = 2; /* endian flip */ - else if ((c[4] == 0x2f) && (c[5] == 0x25) - && (c[6] == 0xc0) && (c[7] == 0xc7) - && (c[0] == 0x43) && (c[1] == 0x2b) - && (c[2] == 0x1f) && (c[3] == 0x5b)) + else if ((c[4] == 0x2f) && (c[5] == 0x25) && (c[6] == 0xc0) && + (c[7] == 0xc7) && (c[0] == 0x43) && (c[1] == 0x2b) && + (c[2] == 0x1f) && (c[3] == 0x5b)) config = 3; /* int swap */ else config = 4; } - if (isnan (val)) - { + if (isnan(val)) { out.byte[0] = out.byte[1] = out.byte[2] = out.byte[3] = 0x00; out.byte[4] = out.byte[5] = 0x00; out.byte[6] = 0xf8; out.byte[7] = 0x7f; return (out.floating); - } - else if (config == 1) + } else if (config == 1) return (val); - else if (config == 2) - { + else if (config == 2) { in.floating = val; out.byte[0] = in.byte[7]; out.byte[1] = in.byte[6]; @@ -239,9 +236,7 @@ static double htond (double val) /* {{{ */ out.byte[6] = in.byte[1]; out.byte[7] = in.byte[0]; return (out.floating); - } - else if (config == 3) - { + } else if (config == 3) { in.floating = val; out.byte[0] = in.byte[4]; out.byte[1] = in.byte[5]; @@ -252,66 +247,58 @@ static double htond (double val) /* {{{ */ out.byte[6] = in.byte[2]; out.byte[7] = in.byte[3]; return (out.floating); - } - else - { + } else { /* If in doubt, just copy the value back to the caller. */ return (val); } } /* }}} double htond */ -static int nb_add_values (char **ret_buffer, /* {{{ */ - size_t *ret_buffer_len, - const lcc_value_list_t *vl) -{ +static int nb_add_values(char **ret_buffer, /* {{{ */ + size_t *ret_buffer_len, const lcc_value_list_t *vl) { char *packet_ptr; size_t packet_len; - uint16_t pkg_type; - uint16_t pkg_length; - uint16_t pkg_num_values; - uint8_t pkg_values_types[vl->values_len]; - value_t pkg_values[vl->values_len]; + uint16_t pkg_type; + uint16_t pkg_length; + uint16_t pkg_num_values; + uint8_t pkg_values_types[vl->values_len]; + value_t pkg_values[vl->values_len]; size_t offset; - packet_len = sizeof (pkg_type) + sizeof (pkg_length) - + sizeof (pkg_num_values) - + sizeof (pkg_values_types) - + sizeof (pkg_values); + packet_len = sizeof(pkg_type) + sizeof(pkg_length) + sizeof(pkg_num_values) + + sizeof(pkg_values_types) + sizeof(pkg_values); if (*ret_buffer_len < packet_len) return (ENOMEM); - pkg_type = htons (TYPE_VALUES); - pkg_length = htons ((uint16_t) packet_len); - pkg_num_values = htons ((uint16_t) vl->values_len); + pkg_type = htons(TYPE_VALUES); + pkg_length = htons((uint16_t)packet_len); + pkg_num_values = htons((uint16_t)vl->values_len); - for (size_t i = 0; i < vl->values_len; i++) - { - pkg_values_types[i] = (uint8_t) vl->values_types[i]; - switch (vl->values_types[i]) - { - case LCC_TYPE_COUNTER: - pkg_values[i].counter = (counter_t) htonll (vl->values[i].counter); - break; - - case LCC_TYPE_GAUGE: - pkg_values[i].gauge = (gauge_t) htond (vl->values[i].gauge); - break; - - case LCC_TYPE_DERIVE: - pkg_values[i].derive = (derive_t) htonll (vl->values[i].derive); - break; - - case LCC_TYPE_ABSOLUTE: - pkg_values[i].absolute = (absolute_t) htonll (vl->values[i].absolute); - break; - - default: - return (EINVAL); + for (size_t i = 0; i < vl->values_len; i++) { + pkg_values_types[i] = (uint8_t)vl->values_types[i]; + switch (vl->values_types[i]) { + case LCC_TYPE_COUNTER: + pkg_values[i].counter = (counter_t)htonll(vl->values[i].counter); + break; + + case LCC_TYPE_GAUGE: + pkg_values[i].gauge = (gauge_t)htond(vl->values[i].gauge); + break; + + case LCC_TYPE_DERIVE: + pkg_values[i].derive = (derive_t)htonll(vl->values[i].derive); + break; + + case LCC_TYPE_ABSOLUTE: + pkg_values[i].absolute = (absolute_t)htonll(vl->values[i].absolute); + break; + + default: + return (EINVAL); } /* switch (vl->values_types[i]) */ - } /* for (vl->values_len) */ + } /* for (vl->values_len) */ /* * Use `memcpy' to write everything to the buffer, because the pointer @@ -320,28 +307,27 @@ static int nb_add_values (char **ret_buffer, /* {{{ */ */ packet_ptr = *ret_buffer; offset = 0; - memcpy (packet_ptr + offset, &pkg_type, sizeof (pkg_type)); - offset += sizeof (pkg_type); - memcpy (packet_ptr + offset, &pkg_length, sizeof (pkg_length)); - offset += sizeof (pkg_length); - memcpy (packet_ptr + offset, &pkg_num_values, sizeof (pkg_num_values)); - offset += sizeof (pkg_num_values); - memcpy (packet_ptr + offset, pkg_values_types, sizeof (pkg_values_types)); - offset += sizeof (pkg_values_types); - memcpy (packet_ptr + offset, pkg_values, sizeof (pkg_values)); - offset += sizeof (pkg_values); - - assert (offset == packet_len); + memcpy(packet_ptr + offset, &pkg_type, sizeof(pkg_type)); + offset += sizeof(pkg_type); + memcpy(packet_ptr + offset, &pkg_length, sizeof(pkg_length)); + offset += sizeof(pkg_length); + memcpy(packet_ptr + offset, &pkg_num_values, sizeof(pkg_num_values)); + offset += sizeof(pkg_num_values); + memcpy(packet_ptr + offset, pkg_values_types, sizeof(pkg_values_types)); + offset += sizeof(pkg_values_types); + memcpy(packet_ptr + offset, pkg_values, sizeof(pkg_values)); + offset += sizeof(pkg_values); + + assert(offset == packet_len); *ret_buffer = packet_ptr + packet_len; *ret_buffer_len -= packet_len; return (0); } /* }}} int nb_add_values */ -static int nb_add_number (char **ret_buffer, /* {{{ */ - size_t *ret_buffer_len, - uint16_t type, uint64_t value) -{ +static int nb_add_number(char **ret_buffer, /* {{{ */ + size_t *ret_buffer_len, uint16_t type, + uint64_t value) { char *packet_ptr; size_t packet_len; @@ -351,46 +337,41 @@ static int nb_add_number (char **ret_buffer, /* {{{ */ size_t offset; - packet_len = sizeof (pkg_type) - + sizeof (pkg_length) - + sizeof (pkg_value); + packet_len = sizeof(pkg_type) + sizeof(pkg_length) + sizeof(pkg_value); if (*ret_buffer_len < packet_len) return (ENOMEM); - pkg_type = htons (type); - pkg_length = htons ((uint16_t) packet_len); - pkg_value = htonll (value); + pkg_type = htons(type); + pkg_length = htons((uint16_t)packet_len); + pkg_value = htonll(value); packet_ptr = *ret_buffer; offset = 0; - memcpy (packet_ptr + offset, &pkg_type, sizeof (pkg_type)); - offset += sizeof (pkg_type); - memcpy (packet_ptr + offset, &pkg_length, sizeof (pkg_length)); - offset += sizeof (pkg_length); - memcpy (packet_ptr + offset, &pkg_value, sizeof (pkg_value)); - offset += sizeof (pkg_value); + memcpy(packet_ptr + offset, &pkg_type, sizeof(pkg_type)); + offset += sizeof(pkg_type); + memcpy(packet_ptr + offset, &pkg_length, sizeof(pkg_length)); + offset += sizeof(pkg_length); + memcpy(packet_ptr + offset, &pkg_value, sizeof(pkg_value)); + offset += sizeof(pkg_value); - assert (offset == packet_len); + assert(offset == packet_len); *ret_buffer = packet_ptr + packet_len; *ret_buffer_len -= packet_len; return (0); } /* }}} int nb_add_number */ -static int nb_add_time (char **ret_buffer, /* {{{ */ - size_t *ret_buffer_len, - uint16_t type, double value) -{ +static int nb_add_time(char **ret_buffer, /* {{{ */ + size_t *ret_buffer_len, uint16_t type, double value) { /* Convert to collectd's "cdtime" representation. */ - uint64_t cdtime_value = (uint64_t) (value * 1073741824.0); - return (nb_add_number (ret_buffer, ret_buffer_len, type, cdtime_value)); + uint64_t cdtime_value = (uint64_t)(value * 1073741824.0); + return (nb_add_number(ret_buffer, ret_buffer_len, type, cdtime_value)); } /* }}} int nb_add_time */ -static int nb_add_string (char **ret_buffer, /* {{{ */ - size_t *ret_buffer_len, - uint16_t type, const char *str, size_t str_len) -{ +static int nb_add_string(char **ret_buffer, /* {{{ */ + size_t *ret_buffer_len, uint16_t type, const char *str, + size_t str_len) { char *packet_ptr; size_t packet_len; @@ -399,36 +380,33 @@ static int nb_add_string (char **ret_buffer, /* {{{ */ size_t offset; - packet_len = sizeof (pkg_type) - + sizeof (pkg_length) - + str_len + 1; + packet_len = sizeof(pkg_type) + sizeof(pkg_length) + str_len + 1; if (*ret_buffer_len < packet_len) return (ENOMEM); - pkg_type = htons (type); - pkg_length = htons ((uint16_t) packet_len); + pkg_type = htons(type); + pkg_length = htons((uint16_t)packet_len); packet_ptr = *ret_buffer; offset = 0; - memcpy (packet_ptr + offset, &pkg_type, sizeof (pkg_type)); - offset += sizeof (pkg_type); - memcpy (packet_ptr + offset, &pkg_length, sizeof (pkg_length)); - offset += sizeof (pkg_length); - memcpy (packet_ptr + offset, str, str_len); + memcpy(packet_ptr + offset, &pkg_type, sizeof(pkg_type)); + offset += sizeof(pkg_type); + memcpy(packet_ptr + offset, &pkg_length, sizeof(pkg_length)); + offset += sizeof(pkg_length); + memcpy(packet_ptr + offset, str, str_len); offset += str_len; - memset (packet_ptr + offset, 0, 1); + memset(packet_ptr + offset, 0, 1); offset += 1; - assert (offset == packet_len); + assert(offset == packet_len); *ret_buffer = packet_ptr + packet_len; *ret_buffer_len -= packet_len; return (0); } /* }}} int nb_add_string */ -static int nb_add_value_list (lcc_network_buffer_t *nb, /* {{{ */ - const lcc_value_list_t *vl) -{ +static int nb_add_value_list(lcc_network_buffer_t *nb, /* {{{ */ + const lcc_value_list_t *vl) { char *buffer = nb->ptr; size_t buffer_size = nb->free; @@ -438,68 +416,58 @@ static int nb_add_value_list (lcc_network_buffer_t *nb, /* {{{ */ ident_src = &vl->identifier; ident_dst = &nb->state.identifier; - if (strcmp (ident_dst->host, ident_src->host) != 0) - { - if (nb_add_string (&buffer, &buffer_size, TYPE_HOST, - ident_src->host, strlen (ident_src->host)) != 0) + if (strcmp(ident_dst->host, ident_src->host) != 0) { + if (nb_add_string(&buffer, &buffer_size, TYPE_HOST, ident_src->host, + strlen(ident_src->host)) != 0) return (-1); - SSTRNCPY (ident_dst->host, ident_src->host, sizeof (ident_dst->host)); + SSTRNCPY(ident_dst->host, ident_src->host, sizeof(ident_dst->host)); } - if (strcmp (ident_dst->plugin, ident_src->plugin) != 0) - { - if (nb_add_string (&buffer, &buffer_size, TYPE_PLUGIN, - ident_src->plugin, strlen (ident_src->plugin)) != 0) + if (strcmp(ident_dst->plugin, ident_src->plugin) != 0) { + if (nb_add_string(&buffer, &buffer_size, TYPE_PLUGIN, ident_src->plugin, + strlen(ident_src->plugin)) != 0) return (-1); - SSTRNCPY (ident_dst->plugin, ident_src->plugin, - sizeof (ident_dst->plugin)); + SSTRNCPY(ident_dst->plugin, ident_src->plugin, sizeof(ident_dst->plugin)); } - if (strcmp (ident_dst->plugin_instance, - ident_src->plugin_instance) != 0) - { - if (nb_add_string (&buffer, &buffer_size, TYPE_PLUGIN_INSTANCE, - ident_src->plugin_instance, - strlen (ident_src->plugin_instance)) != 0) + if (strcmp(ident_dst->plugin_instance, ident_src->plugin_instance) != 0) { + if (nb_add_string(&buffer, &buffer_size, TYPE_PLUGIN_INSTANCE, + ident_src->plugin_instance, + strlen(ident_src->plugin_instance)) != 0) return (-1); - SSTRNCPY (ident_dst->plugin_instance, ident_src->plugin_instance, - sizeof (ident_dst->plugin_instance)); + SSTRNCPY(ident_dst->plugin_instance, ident_src->plugin_instance, + sizeof(ident_dst->plugin_instance)); } - if (strcmp (ident_dst->type, ident_src->type) != 0) - { - if (nb_add_string (&buffer, &buffer_size, TYPE_TYPE, - ident_src->type, strlen (ident_src->type)) != 0) + if (strcmp(ident_dst->type, ident_src->type) != 0) { + if (nb_add_string(&buffer, &buffer_size, TYPE_TYPE, ident_src->type, + strlen(ident_src->type)) != 0) return (-1); - SSTRNCPY (ident_dst->type, ident_src->type, sizeof (ident_dst->type)); + SSTRNCPY(ident_dst->type, ident_src->type, sizeof(ident_dst->type)); } - if (strcmp (ident_dst->type_instance, - ident_src->type_instance) != 0) - { - if (nb_add_string (&buffer, &buffer_size, TYPE_TYPE_INSTANCE, - ident_src->type_instance, - strlen (ident_src->type_instance)) != 0) + if (strcmp(ident_dst->type_instance, ident_src->type_instance) != 0) { + if (nb_add_string(&buffer, &buffer_size, TYPE_TYPE_INSTANCE, + ident_src->type_instance, + strlen(ident_src->type_instance)) != 0) return (-1); - SSTRNCPY (ident_dst->type_instance, ident_src->type_instance, - sizeof (ident_dst->type_instance)); + SSTRNCPY(ident_dst->type_instance, ident_src->type_instance, + sizeof(ident_dst->type_instance)); } - if (nb->state.time != vl->time) - { - if (nb_add_time (&buffer, &buffer_size, TYPE_TIME_HR, vl->time)) + if (nb->state.time != vl->time) { + if (nb_add_time(&buffer, &buffer_size, TYPE_TIME_HR, vl->time)) return (-1); nb->state.time = vl->time; } - if (nb->state.interval != vl->interval) - { - if (nb_add_time (&buffer, &buffer_size, TYPE_INTERVAL_HR, vl->interval)) + if (nb->state.interval != vl->interval) { + if (nb_add_time(&buffer, &buffer_size, TYPE_INTERVAL_HR, vl->interval)) return (-1); nb->state.interval = vl->interval; } - if (nb_add_values (&buffer, &buffer_size, vl) != 0) + if (nb_add_values(&buffer, &buffer_size, vl) != 0) return (-1); nb->ptr = buffer; @@ -508,7 +476,7 @@ static int nb_add_value_list (lcc_network_buffer_t *nb, /* {{{ */ } /* }}} int nb_add_value_list */ #if HAVE_LIBGCRYPT -static int nb_add_signature (lcc_network_buffer_t *nb) /* {{{ */ +static int nb_add_signature(lcc_network_buffer_t *nb) /* {{{ */ { char *buffer; size_t buffer_size; @@ -523,38 +491,36 @@ static int nb_add_signature (lcc_network_buffer_t *nb) /* {{{ */ * the username and the data and add the hash value to the buffer. */ buffer = nb->buffer + PART_SIGNATURE_SHA256_SIZE; - assert (nb->size >= (nb->free + PART_SIGNATURE_SHA256_SIZE)); + assert(nb->size >= (nb->free + PART_SIGNATURE_SHA256_SIZE)); buffer_size = nb->size - (nb->free + PART_SIGNATURE_SHA256_SIZE); hd = NULL; - err = gcry_md_open (&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); + err = gcry_md_open(&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); if (err != 0) return (-1); - assert (nb->password != NULL); - err = gcry_md_setkey (hd, nb->password, strlen (nb->password)); - if (err != 0) - { - gcry_md_close (hd); + assert(nb->password != NULL); + err = gcry_md_setkey(hd, nb->password, strlen(nb->password)); + if (err != 0) { + gcry_md_close(hd); return (-1); } - gcry_md_write (hd, buffer, buffer_size); - hash = gcry_md_read (hd, GCRY_MD_SHA256); - if (hash == NULL) - { - gcry_md_close (hd); + gcry_md_write(hd, buffer, buffer_size); + hash = gcry_md_read(hd, GCRY_MD_SHA256); + if (hash == NULL) { + gcry_md_close(hd); return (-1); } - assert (((2 * sizeof (uint16_t)) + hash_length) == PART_SIGNATURE_SHA256_SIZE); - memcpy (nb->buffer + (2 * sizeof (uint16_t)), hash, hash_length); + assert(((2 * sizeof(uint16_t)) + hash_length) == PART_SIGNATURE_SHA256_SIZE); + memcpy(nb->buffer + (2 * sizeof(uint16_t)), hash, hash_length); - gcry_md_close (hd); + gcry_md_close(hd); return (0); } /* }}} int nb_add_signature */ -static int nb_add_encryption (lcc_network_buffer_t *nb) /* {{{ */ +static int nb_add_encryption(lcc_network_buffer_t *nb) /* {{{ */ { size_t package_length; char *encr_ptr; /* pointer to data being encrypted */ @@ -569,65 +535,58 @@ static int nb_add_encryption (lcc_network_buffer_t *nb) /* {{{ */ /* Fill in the package length */ package_length = nb->size - nb->free; - pkg_length = htons ((uint16_t) package_length); - memcpy (nb->buffer + 2, &pkg_length, sizeof (pkg_length)); + pkg_length = htons((uint16_t)package_length); + memcpy(nb->buffer + 2, &pkg_length, sizeof(pkg_length)); /* Calculate what to hash */ hash_ptr = nb->buffer + PART_ENCRYPTION_AES256_SIZE; hash_size = package_length - nb->encr_header_len; /* Calculate what to encrypt */ - encr_ptr = hash_ptr - sizeof (hash); - encr_size = hash_size + sizeof (hash); + encr_ptr = hash_ptr - sizeof(hash); + encr_size = hash_size + sizeof(hash); /* Calculate the SHA-1 hash */ - gcry_md_hash_buffer (GCRY_MD_SHA1, hash, hash_ptr, hash_size); - memcpy (encr_ptr, hash, sizeof (hash)); + gcry_md_hash_buffer(GCRY_MD_SHA1, hash, hash_ptr, hash_size); + memcpy(encr_ptr, hash, sizeof(hash)); - if (nb->encr_cypher == NULL) - { + if (nb->encr_cypher == NULL) { unsigned char password_hash[32]; - err = gcry_cipher_open (&nb->encr_cypher, - GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB, /* flags = */ 0); + err = gcry_cipher_open(&nb->encr_cypher, GCRY_CIPHER_AES256, + GCRY_CIPHER_MODE_OFB, /* flags = */ 0); if (err != 0) return (-1); /* Calculate our 256bit key used for AES */ - gcry_md_hash_buffer (GCRY_MD_SHA256, password_hash, - nb->password, strlen (nb->password)); + gcry_md_hash_buffer(GCRY_MD_SHA256, password_hash, nb->password, + strlen(nb->password)); - err = gcry_cipher_setkey (nb->encr_cypher, - password_hash, sizeof (password_hash)); - if (err != 0) - { - gcry_cipher_close (nb->encr_cypher); + err = gcry_cipher_setkey(nb->encr_cypher, password_hash, + sizeof(password_hash)); + if (err != 0) { + gcry_cipher_close(nb->encr_cypher); nb->encr_cypher = NULL; return (-1); } - } - else /* if (nb->encr_cypher != NULL) */ + } else /* if (nb->encr_cypher != NULL) */ { - gcry_cipher_reset (nb->encr_cypher); + gcry_cipher_reset(nb->encr_cypher); } /* Set the initialization vector */ - err = gcry_cipher_setiv (nb->encr_cypher, - nb->encr_iv, sizeof (nb->encr_iv)); - if (err != 0) - { - gcry_cipher_close (nb->encr_cypher); + err = gcry_cipher_setiv(nb->encr_cypher, nb->encr_iv, sizeof(nb->encr_iv)); + if (err != 0) { + gcry_cipher_close(nb->encr_cypher); nb->encr_cypher = NULL; return (-1); } /* Encrypt the buffer in-place */ - err = gcry_cipher_encrypt (nb->encr_cypher, - encr_ptr, encr_size, - /* in = */ NULL, /* in len = */ 0); - if (err != 0) - { - gcry_cipher_close (nb->encr_cypher); + err = gcry_cipher_encrypt(nb->encr_cypher, encr_ptr, encr_size, + /* in = */ NULL, /* in len = */ 0); + if (err != 0) { + gcry_cipher_close(nb->encr_cypher); nb->encr_cypher = NULL; return (-1); } @@ -639,28 +598,26 @@ static int nb_add_encryption (lcc_network_buffer_t *nb) /* {{{ */ /* * Public functions */ -lcc_network_buffer_t *lcc_network_buffer_create (size_t size) /* {{{ */ +lcc_network_buffer_t *lcc_network_buffer_create(size_t size) /* {{{ */ { lcc_network_buffer_t *nb; if (size == 0) size = LCC_NETWORK_BUFFER_SIZE_DEFAULT; - if (size < 128) - { + if (size < 128) { errno = EINVAL; return (NULL); } - nb = calloc (1, sizeof (*nb)); + nb = calloc(1, sizeof(*nb)); if (nb == NULL) return (NULL); nb->size = size; - nb->buffer = calloc (1, nb->size); - if (nb->buffer == NULL) - { - free (nb); + nb->buffer = calloc(1, nb->size); + if (nb->buffer == NULL) { + free(nb); return (NULL); } @@ -674,158 +631,151 @@ lcc_network_buffer_t *lcc_network_buffer_create (size_t size) /* {{{ */ return (nb); } /* }}} lcc_network_buffer_t *lcc_network_buffer_create */ -void lcc_network_buffer_destroy (lcc_network_buffer_t *nb) /* {{{ */ +void lcc_network_buffer_destroy(lcc_network_buffer_t *nb) /* {{{ */ { if (nb == NULL) return; - free (nb->buffer); - free (nb); + free(nb->buffer); + free(nb); } /* }}} void lcc_network_buffer_destroy */ -int lcc_network_buffer_set_security_level (lcc_network_buffer_t *nb, /* {{{ */ - lcc_security_level_t level, - const char *username, const char *password) -{ +int lcc_network_buffer_set_security_level(lcc_network_buffer_t *nb, /* {{{ */ + lcc_security_level_t level, + const char *username, + const char *password) { char *username_copy; char *password_copy; - if (level == NONE) - { - free (nb->username); - free (nb->password); + if (level == NONE) { + free(nb->username); + free(nb->password); nb->username = NULL; nb->password = NULL; nb->seclevel = NONE; - lcc_network_buffer_initialize (nb); + lcc_network_buffer_initialize(nb); return (0); } - if (!have_gcrypt ()) + if (!have_gcrypt()) return (ENOTSUP); - username_copy = strdup (username); - password_copy = strdup (password); - if ((username_copy == NULL) || (password_copy == NULL)) - { - free (username_copy); - free (password_copy); + username_copy = strdup(username); + password_copy = strdup(password); + if ((username_copy == NULL) || (password_copy == NULL)) { + free(username_copy); + free(password_copy); return (ENOMEM); } - free (nb->username); - free (nb->password); + free(nb->username); + free(nb->password); nb->username = username_copy; nb->password = password_copy; nb->seclevel = level; - lcc_network_buffer_initialize (nb); + lcc_network_buffer_initialize(nb); return (0); } /* }}} int lcc_network_buffer_set_security_level */ -int lcc_network_buffer_initialize (lcc_network_buffer_t *nb) /* {{{ */ +int lcc_network_buffer_initialize(lcc_network_buffer_t *nb) /* {{{ */ { if (nb == NULL) return (EINVAL); - memset (nb->buffer, 0, nb->size); - memset (&nb->state, 0, sizeof (nb->state)); + memset(nb->buffer, 0, nb->size); + memset(&nb->state, 0, sizeof(nb->state)); nb->ptr = nb->buffer; nb->free = nb->size; #if HAVE_LIBGCRYPT - if (nb->seclevel == SIGN) - { + if (nb->seclevel == SIGN) { size_t username_len; - uint16_t pkg_type = htons (TYPE_SIGN_SHA256); + uint16_t pkg_type = htons(TYPE_SIGN_SHA256); uint16_t pkg_length = PART_SIGNATURE_SHA256_SIZE; - assert (nb->username != NULL); - username_len = strlen (nb->username); - pkg_length = htons (pkg_length + ((uint16_t) username_len)); + assert(nb->username != NULL); + username_len = strlen(nb->username); + pkg_length = htons(pkg_length + ((uint16_t)username_len)); /* Fill in everything but the hash value here. */ - memcpy (nb->ptr, &pkg_type, sizeof (pkg_type)); - memcpy (nb->ptr + sizeof (pkg_type), &pkg_length, sizeof (pkg_length)); + memcpy(nb->ptr, &pkg_type, sizeof(pkg_type)); + memcpy(nb->ptr + sizeof(pkg_type), &pkg_length, sizeof(pkg_length)); nb->ptr += PART_SIGNATURE_SHA256_SIZE; nb->free -= PART_SIGNATURE_SHA256_SIZE; - memcpy (nb->ptr, nb->username, username_len); + memcpy(nb->ptr, nb->username, username_len); nb->ptr += username_len; nb->free -= username_len; - } - else if (nb->seclevel == ENCRYPT) - { - size_t username_length = strlen (nb->username); - uint16_t pkg_type = htons (TYPE_ENCR_AES256); + } else if (nb->seclevel == ENCRYPT) { + size_t username_length = strlen(nb->username); + uint16_t pkg_type = htons(TYPE_ENCR_AES256); uint16_t pkg_length = 0; /* Filled in in finalize. */ - uint16_t pkg_user_len = htons ((uint16_t) username_length); + uint16_t pkg_user_len = htons((uint16_t)username_length); /* Filled in in finalize. */ - char hash[20] = { 0 }; + char hash[20] = {0}; nb->encr_header_len = username_length; nb->encr_header_len += PART_ENCRYPTION_AES256_SIZE; - gcry_randomize ((void *) &nb->encr_iv, sizeof (nb->encr_iv), - GCRY_STRONG_RANDOM); + gcry_randomize((void *)&nb->encr_iv, sizeof(nb->encr_iv), + GCRY_STRONG_RANDOM); - ADD_STATIC (nb, pkg_type); - ADD_STATIC (nb, pkg_length); - ADD_STATIC (nb, pkg_user_len); - ADD_GENERIC (nb, nb->username, username_length); - ADD_GENERIC (nb, nb->encr_iv, sizeof (nb->encr_iv)); - ADD_GENERIC (nb, hash, sizeof (hash)); - assert ((nb->encr_header_len + nb->free) == nb->size); + ADD_STATIC(nb, pkg_type); + ADD_STATIC(nb, pkg_length); + ADD_STATIC(nb, pkg_user_len); + ADD_GENERIC(nb, nb->username, username_length); + ADD_GENERIC(nb, nb->encr_iv, sizeof(nb->encr_iv)); + ADD_GENERIC(nb, hash, sizeof(hash)); + assert((nb->encr_header_len + nb->free) == nb->size); } #endif return (0); } /* }}} int lcc_network_buffer_initialize */ -int lcc_network_buffer_finalize (lcc_network_buffer_t *nb) /* {{{ */ +int lcc_network_buffer_finalize(lcc_network_buffer_t *nb) /* {{{ */ { if (nb == NULL) return (EINVAL); #if HAVE_LIBGCRYPT if (nb->seclevel == SIGN) - return nb_add_signature (nb); + return nb_add_signature(nb); else if (nb->seclevel == ENCRYPT) - return nb_add_encryption (nb); + return nb_add_encryption(nb); #endif return (0); } /* }}} int lcc_network_buffer_finalize */ -int lcc_network_buffer_add_value (lcc_network_buffer_t *nb, /* {{{ */ - const lcc_value_list_t *vl) -{ +int lcc_network_buffer_add_value(lcc_network_buffer_t *nb, /* {{{ */ + const lcc_value_list_t *vl) { int status; if ((nb == NULL) || (vl == NULL)) return (EINVAL); - status = nb_add_value_list (nb, vl); + status = nb_add_value_list(nb, vl); return (status); } /* }}} int lcc_network_buffer_add_value */ -int lcc_network_buffer_get (lcc_network_buffer_t *nb, /* {{{ */ - void *buffer, size_t *buffer_size) -{ +int lcc_network_buffer_get(lcc_network_buffer_t *nb, /* {{{ */ + void *buffer, size_t *buffer_size) { size_t sz_required; size_t sz_available; if ((nb == NULL) || (buffer_size == NULL)) return (EINVAL); - assert (nb->size >= nb->free); + assert(nb->size >= nb->free); sz_required = nb->size - nb->free; sz_available = *buffer_size; *buffer_size = sz_required; if (buffer != NULL) - memcpy (buffer, nb->buffer, - (sz_available < sz_required) ? sz_available : sz_required); + memcpy(buffer, nb->buffer, + (sz_available < sz_required) ? sz_available : sz_required); return (0); } /* }}} int lcc_network_buffer_get */ diff --git a/src/liboconfig/oconfig.c b/src/liboconfig/oconfig.c index d6f07446..76134dbe 100644 --- a/src/liboconfig/oconfig.c +++ b/src/liboconfig/oconfig.c @@ -24,50 +24,44 @@ * Florian Forster **/ -#include -#include -#include #include #include +#include +#include +#include #include "oconfig.h" extern FILE *yyin; -extern int yyparse (void); +extern int yyparse(void); oconfig_item_t *ci_root; -const char *c_file; +const char *c_file; -static void yyset_in (FILE *fd) -{ - yyin = fd; -} /* void yyset_in */ +static void yyset_in(FILE *fd) { yyin = fd; } /* void yyset_in */ -static oconfig_item_t *oconfig_parse_fh (FILE *fh) -{ +static oconfig_item_t *oconfig_parse_fh(FILE *fh) { int status; oconfig_item_t *ret; char file[10]; - yyset_in (fh); + yyset_in(fh); if (NULL == c_file) { - status = snprintf (file, sizeof (file), "", fileno (fh)); + status = snprintf(file, sizeof(file), "", fileno(fh)); - if ((status < 0) || (((size_t) status) >= sizeof (file))) { + if ((status < 0) || (((size_t)status) >= sizeof(file))) { c_file = ""; - } - else { - file[sizeof (file) - 1] = '\0'; + } else { + file[sizeof(file) - 1] = '\0'; c_file = file; } } - status = yyparse (); - if (status != 0) - { - fprintf (stderr, "yyparse returned error #%i\n", status); + status = yyparse(); + if (status != 0) { + fprintf(stderr, "yyparse returned error #%i\n", status); return (NULL); } @@ -75,146 +69,132 @@ static oconfig_item_t *oconfig_parse_fh (FILE *fh) ret = ci_root; ci_root = NULL; - yyset_in ((FILE *) 0); + yyset_in((FILE *)0); return (ret); } /* oconfig_item_t *oconfig_parse_fh */ -oconfig_item_t *oconfig_parse_file (const char *file) -{ +oconfig_item_t *oconfig_parse_file(const char *file) { FILE *fh; oconfig_item_t *ret; c_file = file; - fh = fopen (file, "r"); - if (fh == NULL) - { - fprintf (stderr, "fopen (%s) failed: %s\n", file, strerror (errno)); + fh = fopen(file, "r"); + if (fh == NULL) { + fprintf(stderr, "fopen (%s) failed: %s\n", file, strerror(errno)); return (NULL); } - ret = oconfig_parse_fh (fh); - fclose (fh); + ret = oconfig_parse_fh(fh); + fclose(fh); c_file = NULL; return (ret); } /* oconfig_item_t *oconfig_parse_file */ -oconfig_item_t *oconfig_clone (const oconfig_item_t *ci_orig) -{ +oconfig_item_t *oconfig_clone(const oconfig_item_t *ci_orig) { oconfig_item_t *ci_copy; - ci_copy = calloc (1, sizeof (*ci_copy)); - if (ci_copy == NULL) - { - fprintf (stderr, "calloc failed.\n"); + ci_copy = calloc(1, sizeof(*ci_copy)); + if (ci_copy == NULL) { + fprintf(stderr, "calloc failed.\n"); return (NULL); } ci_copy->values = NULL; ci_copy->parent = NULL; ci_copy->children = NULL; - ci_copy->key = strdup (ci_orig->key); - if (ci_copy->key == NULL) - { - fprintf (stderr, "strdup failed.\n"); - free (ci_copy); + ci_copy->key = strdup(ci_orig->key); + if (ci_copy->key == NULL) { + fprintf(stderr, "strdup failed.\n"); + free(ci_copy); return (NULL); } if (ci_orig->values_num > 0) /* {{{ */ { - ci_copy->values = (oconfig_value_t *) calloc ((size_t) ci_orig->values_num, - sizeof (*ci_copy->values)); - if (ci_copy->values == NULL) - { - fprintf (stderr, "calloc failed.\n"); - free (ci_copy->key); - free (ci_copy); + ci_copy->values = (oconfig_value_t *)calloc((size_t)ci_orig->values_num, + sizeof(*ci_copy->values)); + if (ci_copy->values == NULL) { + fprintf(stderr, "calloc failed.\n"); + free(ci_copy->key); + free(ci_copy); return (NULL); } ci_copy->values_num = ci_orig->values_num; - for (int i = 0; i < ci_copy->values_num; i++) - { - ci_copy->values[i].type = ci_orig->values[i].type; - if (ci_copy->values[i].type == OCONFIG_TYPE_STRING) - { - ci_copy->values[i].value.string = strdup (ci_orig->values[i].value.string); - if (ci_copy->values[i].value.string == NULL) - { - fprintf (stderr, "strdup failed.\n"); - oconfig_free (ci_copy); - return (NULL); - } - } - else /* ci_copy->values[i].type != OCONFIG_TYPE_STRING) */ - { - ci_copy->values[i].value = ci_orig->values[i].value; - } + for (int i = 0; i < ci_copy->values_num; i++) { + ci_copy->values[i].type = ci_orig->values[i].type; + if (ci_copy->values[i].type == OCONFIG_TYPE_STRING) { + ci_copy->values[i].value.string = + strdup(ci_orig->values[i].value.string); + if (ci_copy->values[i].value.string == NULL) { + fprintf(stderr, "strdup failed.\n"); + oconfig_free(ci_copy); + return (NULL); + } + } else /* ci_copy->values[i].type != OCONFIG_TYPE_STRING) */ + { + ci_copy->values[i].value = ci_orig->values[i].value; + } } } /* }}} if (ci_orig->values_num > 0) */ if (ci_orig->children_num > 0) /* {{{ */ { - ci_copy->children = (oconfig_item_t *) calloc ((size_t) ci_orig->children_num, - sizeof (*ci_copy->children)); - if (ci_copy->children == NULL) - { - fprintf (stderr, "calloc failed.\n"); - oconfig_free (ci_copy); + ci_copy->children = (oconfig_item_t *)calloc((size_t)ci_orig->children_num, + sizeof(*ci_copy->children)); + if (ci_copy->children == NULL) { + fprintf(stderr, "calloc failed.\n"); + oconfig_free(ci_copy); return (NULL); } ci_copy->children_num = ci_orig->children_num; - for (int i = 0; i < ci_copy->children_num; i++) - { + for (int i = 0; i < ci_copy->children_num; i++) { oconfig_item_t *child; - child = oconfig_clone (ci_orig->children + i); - if (child == NULL) - { - oconfig_free (ci_copy); - return (NULL); + child = oconfig_clone(ci_orig->children + i); + if (child == NULL) { + oconfig_free(ci_copy); + return (NULL); } child->parent = ci_copy; ci_copy->children[i] = *child; - free (child); + free(child); } /* for (i = 0; i < ci_copy->children_num; i++) */ - } /* }}} if (ci_orig->children_num > 0) */ + } /* }}} if (ci_orig->children_num > 0) */ return (ci_copy); } /* oconfig_item_t *oconfig_clone */ -static void oconfig_free_all (oconfig_item_t *ci) -{ +static void oconfig_free_all(oconfig_item_t *ci) { if (ci == NULL) return; if (ci->key != NULL) - free (ci->key); + free(ci->key); for (int i = 0; i < ci->values_num; i++) - if ((ci->values[i].type == OCONFIG_TYPE_STRING) - && (NULL != ci->values[i].value.string)) - free (ci->values[i].value.string); + if ((ci->values[i].type == OCONFIG_TYPE_STRING) && + (NULL != ci->values[i].value.string)) + free(ci->values[i].value.string); if (ci->values != NULL) - free (ci->values); + free(ci->values); for (int i = 0; i < ci->children_num; i++) - oconfig_free_all (ci->children + i); + oconfig_free_all(ci->children + i); if (ci->children != NULL) - free (ci->children); + free(ci->children); } -void oconfig_free (oconfig_item_t *ci) -{ - oconfig_free_all (ci); - free (ci); +void oconfig_free(oconfig_item_t *ci) { + oconfig_free_all(ci); + free(ci); } /* diff --git a/src/liboconfig/oconfig.h b/src/liboconfig/oconfig.h index 24045de0..d27f6f53 100644 --- a/src/liboconfig/oconfig.h +++ b/src/liboconfig/oconfig.h @@ -32,17 +32,15 @@ /* * Types */ -#define OCONFIG_TYPE_STRING 0 -#define OCONFIG_TYPE_NUMBER 1 +#define OCONFIG_TYPE_STRING 0 +#define OCONFIG_TYPE_NUMBER 1 #define OCONFIG_TYPE_BOOLEAN 2 -struct oconfig_value_s -{ - union - { - char *string; +struct oconfig_value_s { + union { + char *string; double number; - int boolean; + int boolean; } value; int type; }; @@ -50,25 +48,24 @@ typedef struct oconfig_value_s oconfig_value_t; struct oconfig_item_s; typedef struct oconfig_item_s oconfig_item_t; -struct oconfig_item_s -{ - char *key; +struct oconfig_item_s { + char *key; oconfig_value_t *values; - int values_num; + int values_num; - oconfig_item_t *parent; - oconfig_item_t *children; - int children_num; + oconfig_item_t *parent; + oconfig_item_t *children; + int children_num; }; /* * Functions */ -oconfig_item_t *oconfig_parse_file (const char *file); +oconfig_item_t *oconfig_parse_file(const char *file); -oconfig_item_t *oconfig_clone (const oconfig_item_t *ci); +oconfig_item_t *oconfig_clone(const oconfig_item_t *ci); -void oconfig_free (oconfig_item_t *ci); +void oconfig_free(oconfig_item_t *ci); /* * vim: shiftwidth=2:tabstop=8:softtabstop=2 diff --git a/src/load.c b/src/load.c index 53854d14..c7388605 100644 --- a/src/load.c +++ b/src/load.c @@ -38,183 +38,165 @@ #endif #if HAVE_STATGRAB_H -# include +#include #endif #ifdef HAVE_GETLOADAVG #if !defined(LOADAVG_1MIN) || !defined(LOADAVG_5MIN) || !defined(LOADAVG_15MIN) -#define LOADAVG_1MIN 0 -#define LOADAVG_5MIN 1 +#define LOADAVG_1MIN 0 +#define LOADAVG_5MIN 1 #define LOADAVG_15MIN 2 #endif #endif /* defined(HAVE_GETLOADAVG) */ #ifdef HAVE_PERFSTAT -# include /* AIX 5 */ -# include -# include +#include +#include /* AIX 5 */ +#include #endif /* HAVE_PERFSTAT */ static _Bool report_relative_load = 0; -static const char *config_keys[] = -{ - "ReportRelative" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"ReportRelative"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); -static int load_config (const char *key, const char *value) -{ - if (strcasecmp (key, "ReportRelative") == 0) +static int load_config(const char *key, const char *value) { + if (strcasecmp(key, "ReportRelative") == 0) #ifdef _SC_NPROCESSORS_ONLN - report_relative_load = IS_TRUE (value) ? 1 : 0; + report_relative_load = IS_TRUE(value) ? 1 : 0; #else - WARNING ("load plugin: The \"ReportRelative\" configuration " - "is not available, because I can't determine the " - "number of CPUS on this system. Sorry."); + WARNING("load plugin: The \"ReportRelative\" configuration " + "is not available, because I can't determine the " + "number of CPUS on this system. Sorry."); #endif - return (-1); - + return (-1); } -static void load_submit (gauge_t snum, gauge_t mnum, gauge_t lnum) -{ - int cores = 0; - char errbuf[1024]; - -#ifdef _SC_NPROCESSORS_ONLN - if (report_relative_load) { - if ((cores = sysconf(_SC_NPROCESSORS_ONLN)) < 1) { - WARNING ("load: sysconf failed : %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - } - } +static void load_submit(gauge_t snum, gauge_t mnum, gauge_t lnum) { + int cores = 0; + char errbuf[1024]; + +#ifdef _SC_NPROCESSORS_ONLN + if (report_relative_load) { + if ((cores = sysconf(_SC_NPROCESSORS_ONLN)) < 1) { + WARNING("load: sysconf failed : %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + } + } #endif - if (cores > 0) { - snum /= cores; - mnum /= cores; - lnum /= cores; - } - - value_list_t vl = VALUE_LIST_INIT; - value_t values[] = { - { .gauge = snum }, - { .gauge = mnum }, - { .gauge = lnum }, - }; - - vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - - sstrncpy (vl.plugin, "load", sizeof (vl.plugin)); - sstrncpy (vl.type, "load", sizeof (vl.type)); - - if (cores > 0) { - sstrncpy(vl.type_instance, "relative", - sizeof (vl.type_instance)); - } - - plugin_dispatch_values (&vl); + if (cores > 0) { + snum /= cores; + mnum /= cores; + lnum /= cores; + } + + value_list_t vl = VALUE_LIST_INIT; + value_t values[] = { + {.gauge = snum}, {.gauge = mnum}, {.gauge = lnum}, + }; + + vl.values = values; + vl.values_len = STATIC_ARRAY_SIZE(values); + + sstrncpy(vl.plugin, "load", sizeof(vl.plugin)); + sstrncpy(vl.type, "load", sizeof(vl.type)); + + if (cores > 0) { + sstrncpy(vl.type_instance, "relative", sizeof(vl.type_instance)); + } + + plugin_dispatch_values(&vl); } -static int load_read (void) -{ +static int load_read(void) { #if defined(HAVE_GETLOADAVG) - double load[3]; - - if (getloadavg (load, 3) == 3) - load_submit (load[LOADAVG_1MIN], load[LOADAVG_5MIN], load[LOADAVG_15MIN]); - else - { - char errbuf[1024]; - WARNING ("load: getloadavg failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - } + double load[3]; + + if (getloadavg(load, 3) == 3) + load_submit(load[LOADAVG_1MIN], load[LOADAVG_5MIN], load[LOADAVG_15MIN]); + else { + char errbuf[1024]; + WARNING("load: getloadavg failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + } /* #endif HAVE_GETLOADAVG */ #elif defined(KERNEL_LINUX) - gauge_t snum, mnum, lnum; - FILE *loadavg; - char buffer[16]; - - char *fields[8]; - int numfields; - - if ((loadavg = fopen ("/proc/loadavg", "r")) == NULL) - { - char errbuf[1024]; - WARNING ("load: fopen: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - if (fgets (buffer, 16, loadavg) == NULL) - { - char errbuf[1024]; - WARNING ("load: fgets: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - fclose (loadavg); - return (-1); - } - - if (fclose (loadavg)) - { - char errbuf[1024]; - WARNING ("load: fclose: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - } - - numfields = strsplit (buffer, fields, 8); - - if (numfields < 3) - return (-1); - - snum = atof (fields[0]); - mnum = atof (fields[1]); - lnum = atof (fields[2]); - - load_submit(snum, mnum, lnum); + gauge_t snum, mnum, lnum; + FILE *loadavg; + char buffer[16]; + + char *fields[8]; + int numfields; + + if ((loadavg = fopen("/proc/loadavg", "r")) == NULL) { + char errbuf[1024]; + WARNING("load: fopen: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + if (fgets(buffer, 16, loadavg) == NULL) { + char errbuf[1024]; + WARNING("load: fgets: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + fclose(loadavg); + return (-1); + } + + if (fclose(loadavg)) { + char errbuf[1024]; + WARNING("load: fclose: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + } + + numfields = strsplit(buffer, fields, 8); + + if (numfields < 3) + return (-1); + + snum = atof(fields[0]); + mnum = atof(fields[1]); + lnum = atof(fields[2]); + + load_submit(snum, mnum, lnum); /* #endif KERNEL_LINUX */ #elif HAVE_LIBSTATGRAB - gauge_t snum, mnum, lnum; - sg_load_stats *ls; + gauge_t snum, mnum, lnum; + sg_load_stats *ls; - if ((ls = sg_get_load_stats ()) == NULL) - return; + if ((ls = sg_get_load_stats()) == NULL) + return; - snum = ls->min1; - mnum = ls->min5; - lnum = ls->min15; - load_submit(snum, mnum, lnum); + snum = ls->min1; + mnum = ls->min5; + lnum = ls->min15; + load_submit(snum, mnum, lnum); /* #endif HAVE_LIBSTATGRAB */ #elif HAVE_PERFSTAT - gauge_t snum, mnum, lnum; - perfstat_cpu_total_t cputotal; - - if (perfstat_cpu_total(NULL, &cputotal, sizeof(perfstat_cpu_total_t), 1) < 0) - { - char errbuf[1024]; - WARNING ("load: perfstat_cpu : %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - snum = (float)cputotal.loadavg[0]/(float)(1< #include #if HAVE_YAJL_YAJL_VERSION_H -# include +#include #endif #if defined(YAJL_MAJOR) && (YAJL_MAJOR > 1) -# define HAVE_YAJL_V2 1 +#define HAVE_YAJL_V2 1 #endif -#define DEFAULT_LOGFILE LOCALSTATEDIR"/log/"PACKAGE_NAME".json.log" +#define DEFAULT_LOGFILE LOCALSTATEDIR "/log/" PACKAGE_NAME ".json.log" #if COLLECT_DEBUG static int log_level = LOG_DEBUG; @@ -53,330 +53,295 @@ static pthread_mutex_t file_lock = PTHREAD_MUTEX_INITIALIZER; static char *log_file = NULL; -static const char *config_keys[] = -{ - "LogLevel", - "File" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); - -static int log_logstash_config (const char *key, const char *value) -{ - - if (0 == strcasecmp (key, "LogLevel")) { - log_level = parse_log_severity(value); - if (log_level < 0) { - log_level = LOG_INFO; - ERROR("log_logstash: invalid loglevel [%s] defaulting to 'info'", - value); - return 1; - } - } - else if (0 == strcasecmp (key, "File")) { - sfree (log_file); - log_file = strdup (value); - } - else { - return -1; - } - return 0; +static const char *config_keys[] = {"LogLevel", "File"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); + +static int log_logstash_config(const char *key, const char *value) { + + if (0 == strcasecmp(key, "LogLevel")) { + log_level = parse_log_severity(value); + if (log_level < 0) { + log_level = LOG_INFO; + ERROR("log_logstash: invalid loglevel [%s] defaulting to 'info'", value); + return 1; + } + } else if (0 == strcasecmp(key, "File")) { + sfree(log_file); + log_file = strdup(value); + } else { + return -1; + } + return 0; } /* int log_logstash_config (const char *, const char *) */ -static void log_logstash_print (yajl_gen g, int severity, - cdtime_t timestamp_time) -{ - FILE *fh; - _Bool do_close = 0; - struct tm timestamp_tm; - char timestamp_str[64]; - const unsigned char *buf; +static void log_logstash_print(yajl_gen g, int severity, + cdtime_t timestamp_time) { + FILE *fh; + _Bool do_close = 0; + struct tm timestamp_tm; + char timestamp_str[64]; + const unsigned char *buf; #if HAVE_YAJL_V2 - size_t len; + size_t len; #else - unsigned int len; + unsigned int len; #endif - if (yajl_gen_string(g, (u_char *)"level", strlen("level")) != - yajl_gen_status_ok) - goto err; - - switch (severity) { - case LOG_ERR: - if (yajl_gen_string(g, (u_char *)"error", strlen("error")) != - yajl_gen_status_ok) - goto err; - break; - case LOG_WARNING: - if (yajl_gen_string(g, (u_char *)"warning", - strlen("warning")) != - yajl_gen_status_ok) - goto err; - break; - case LOG_NOTICE: - if (yajl_gen_string(g, (u_char *)"notice", strlen("notice")) != - yajl_gen_status_ok) - goto err; - break; - case LOG_INFO: - if (yajl_gen_string(g, (u_char *)"info", strlen("info")) != - yajl_gen_status_ok) - goto err; - break; - case LOG_DEBUG: - if (yajl_gen_string(g, (u_char *)"debug", strlen("debug")) != - yajl_gen_status_ok) - goto err; - break; - default: - if (yajl_gen_string(g, (u_char *)"unknown", - strlen("unknown")) != - yajl_gen_status_ok) - goto err; - break; - } - - if (yajl_gen_string(g, (u_char *)"@timestamp", strlen("@timestamp")) != - yajl_gen_status_ok) - goto err; - - gmtime_r (&CDTIME_T_TO_TIME_T (timestamp_time), ×tamp_tm); - - /* - * format time as a UTC ISO 8601 compliant string - */ - strftime (timestamp_str, sizeof (timestamp_str), - "%Y-%m-%dT%H:%M:%SZ", ×tamp_tm); - timestamp_str[sizeof (timestamp_str) - 1] = '\0'; - - if (yajl_gen_string(g, (u_char *)timestamp_str, - strlen(timestamp_str)) != - yajl_gen_status_ok) - goto err; - - if (yajl_gen_map_close(g) != yajl_gen_status_ok) - goto err; - - if (yajl_gen_get_buf(g, &buf, &len) != yajl_gen_status_ok) - goto err; - pthread_mutex_lock (&file_lock); - - if (log_file == NULL) - { - fh = fopen (DEFAULT_LOGFILE, "a"); - do_close = 1; - } else if (strcasecmp(log_file, "stdout") == 0) { - fh = stdout; - do_close = 0; - } else if (strcasecmp(log_file, "stderr") == 0) { - fh = stderr; - do_close = 0; - } else { - fh = fopen (log_file, "a"); - do_close = 1; - } - - if (fh == NULL) - { - char errbuf[1024]; - fprintf (stderr, "log_logstash plugin: fopen (%s) failed: %s\n", - (log_file == NULL) ? DEFAULT_LOGFILE : log_file, - sstrerror (errno, errbuf, sizeof (errbuf))); - } - else - { - fprintf(fh, "%s\n", buf); - if (do_close) { - fclose (fh); - } else { - fflush(fh); - } - } - pthread_mutex_unlock (&file_lock); - yajl_gen_free(g); - return; - - err: - yajl_gen_free(g); - fprintf(stderr, "Could not correctly generate JSON message\n"); - return; + if (yajl_gen_string(g, (u_char *)"level", strlen("level")) != + yajl_gen_status_ok) + goto err; + + switch (severity) { + case LOG_ERR: + if (yajl_gen_string(g, (u_char *)"error", strlen("error")) != + yajl_gen_status_ok) + goto err; + break; + case LOG_WARNING: + if (yajl_gen_string(g, (u_char *)"warning", strlen("warning")) != + yajl_gen_status_ok) + goto err; + break; + case LOG_NOTICE: + if (yajl_gen_string(g, (u_char *)"notice", strlen("notice")) != + yajl_gen_status_ok) + goto err; + break; + case LOG_INFO: + if (yajl_gen_string(g, (u_char *)"info", strlen("info")) != + yajl_gen_status_ok) + goto err; + break; + case LOG_DEBUG: + if (yajl_gen_string(g, (u_char *)"debug", strlen("debug")) != + yajl_gen_status_ok) + goto err; + break; + default: + if (yajl_gen_string(g, (u_char *)"unknown", strlen("unknown")) != + yajl_gen_status_ok) + goto err; + break; + } + + if (yajl_gen_string(g, (u_char *)"@timestamp", strlen("@timestamp")) != + yajl_gen_status_ok) + goto err; + + gmtime_r(&CDTIME_T_TO_TIME_T(timestamp_time), ×tamp_tm); + + /* + * format time as a UTC ISO 8601 compliant string + */ + strftime(timestamp_str, sizeof(timestamp_str), "%Y-%m-%dT%H:%M:%SZ", + ×tamp_tm); + timestamp_str[sizeof(timestamp_str) - 1] = '\0'; + + if (yajl_gen_string(g, (u_char *)timestamp_str, strlen(timestamp_str)) != + yajl_gen_status_ok) + goto err; + + if (yajl_gen_map_close(g) != yajl_gen_status_ok) + goto err; + + if (yajl_gen_get_buf(g, &buf, &len) != yajl_gen_status_ok) + goto err; + pthread_mutex_lock(&file_lock); + + if (log_file == NULL) { + fh = fopen(DEFAULT_LOGFILE, "a"); + do_close = 1; + } else if (strcasecmp(log_file, "stdout") == 0) { + fh = stdout; + do_close = 0; + } else if (strcasecmp(log_file, "stderr") == 0) { + fh = stderr; + do_close = 0; + } else { + fh = fopen(log_file, "a"); + do_close = 1; + } + + if (fh == NULL) { + char errbuf[1024]; + fprintf(stderr, "log_logstash plugin: fopen (%s) failed: %s\n", + (log_file == NULL) ? DEFAULT_LOGFILE : log_file, + sstrerror(errno, errbuf, sizeof(errbuf))); + } else { + fprintf(fh, "%s\n", buf); + if (do_close) { + fclose(fh); + } else { + fflush(fh); + } + } + pthread_mutex_unlock(&file_lock); + yajl_gen_free(g); + return; + +err: + yajl_gen_free(g); + fprintf(stderr, "Could not correctly generate JSON message\n"); + return; } /* void log_logstash_print */ -static void log_logstash_log (int severity, const char *msg, - user_data_t __attribute__((unused)) *user_data) -{ - yajl_gen g; +static void log_logstash_log(int severity, const char *msg, + user_data_t __attribute__((unused)) * user_data) { + yajl_gen g; #if !defined(HAVE_YAJL_V2) - yajl_gen_config conf = {}; + yajl_gen_config conf = {}; - conf.beautify = 0; + conf.beautify = 0; #endif - if (severity > log_level) - return; + if (severity > log_level) + return; #if HAVE_YAJL_V2 - g = yajl_gen_alloc(NULL); + g = yajl_gen_alloc(NULL); #else - g = yajl_gen_alloc(&conf, NULL); + g = yajl_gen_alloc(&conf, NULL); #endif - if (g == NULL) { - fprintf(stderr, "Could not allocate JSON generator.\n"); - return; - } - - if (yajl_gen_map_open(g) != yajl_gen_status_ok) - goto err; - if (yajl_gen_string(g, (u_char *)"message", strlen("message")) != - yajl_gen_status_ok) - goto err; - if (yajl_gen_string(g, (u_char *)msg, strlen(msg)) != - yajl_gen_status_ok) - goto err; - - log_logstash_print (g, severity, cdtime ()); - return; - err: - yajl_gen_free(g); - fprintf(stderr, "Could not generate JSON message preamble\n"); - return; + if (g == NULL) { + fprintf(stderr, "Could not allocate JSON generator.\n"); + return; + } + + if (yajl_gen_map_open(g) != yajl_gen_status_ok) + goto err; + if (yajl_gen_string(g, (u_char *)"message", strlen("message")) != + yajl_gen_status_ok) + goto err; + if (yajl_gen_string(g, (u_char *)msg, strlen(msg)) != yajl_gen_status_ok) + goto err; + + log_logstash_print(g, severity, cdtime()); + return; +err: + yajl_gen_free(g); + fprintf(stderr, "Could not generate JSON message preamble\n"); + return; } /* void log_logstash_log (int, const char *) */ -static int log_logstash_notification (const notification_t *n, - user_data_t __attribute__((unused)) *user_data) -{ - yajl_gen g; +static int log_logstash_notification(const notification_t *n, + user_data_t __attribute__((unused)) * + user_data) { + yajl_gen g; #if HAVE_YAJL_V2 - g = yajl_gen_alloc(NULL); + g = yajl_gen_alloc(NULL); #else - yajl_gen_config conf = {}; + yajl_gen_config conf = {}; - conf.beautify = 0; - g = yajl_gen_alloc(&conf, NULL); + conf.beautify = 0; + g = yajl_gen_alloc(&conf, NULL); #endif - if (g == NULL) { - fprintf(stderr, "Could not allocate JSON generator.\n"); - return (0); - } - - if (yajl_gen_map_open(g) != yajl_gen_status_ok) - goto err; - if (yajl_gen_string(g, (u_char *)"message", strlen("message")) != - yajl_gen_status_ok) - goto err; - if (strlen(n->message) > 0) { - if (yajl_gen_string(g, (u_char *)n->message, - strlen(n->message)) != - yajl_gen_status_ok) - goto err; - } else { - if (yajl_gen_string(g, (u_char *)"notification without a message", - strlen("notification without a message")) != - yajl_gen_status_ok) - goto err; - } - - if (strlen(n->host) > 0) { - if (yajl_gen_string(g, (u_char *)"host", strlen("host")) != - yajl_gen_status_ok) - goto err; - if (yajl_gen_string(g, (u_char *)n->host, strlen(n->host)) != - yajl_gen_status_ok) - goto err; - - } - if (strlen(n->plugin) > 0) { - if (yajl_gen_string(g, (u_char *)"plugin", strlen("plugin")) != - yajl_gen_status_ok) - goto err; - if (yajl_gen_string(g, (u_char *)n->plugin, strlen(n->plugin)) != - yajl_gen_status_ok) - goto err; - } - if (strlen(n->plugin_instance) > 0) { - if (yajl_gen_string(g, (u_char *)"plugin_instance", - strlen("plugin_instance")) != - yajl_gen_status_ok) - goto err; - if (yajl_gen_string(g, (u_char *)n->plugin_instance, - strlen(n->plugin_instance)) != - yajl_gen_status_ok) - goto err; - } - if (strlen(n->type) > 0) { - if (yajl_gen_string(g, (u_char *)"type", strlen("type")) != - yajl_gen_status_ok) - goto err; - if (yajl_gen_string(g, (u_char *)n->type, strlen(n->type)) != - yajl_gen_status_ok) - goto err; - } - if (strlen(n->type_instance) > 0) { - if (yajl_gen_string(g, (u_char *)"type_instance", - strlen("type_instance")) != - yajl_gen_status_ok) - goto err; - if (yajl_gen_string(g, (u_char *)n->type_instance, - strlen(n->type_instance)) != - yajl_gen_status_ok) - goto err; - } - - if (yajl_gen_string(g, (u_char *)"severity", - strlen("severity")) != - yajl_gen_status_ok) - goto err; - - switch (n->severity) { - case NOTIF_FAILURE: - if (yajl_gen_string(g, (u_char *)"failure", - strlen("failure")) != - yajl_gen_status_ok) - goto err; - break; - case NOTIF_WARNING: - if (yajl_gen_string(g, (u_char *)"warning", - strlen("warning")) != - yajl_gen_status_ok) - goto err; - break; - case NOTIF_OKAY: - if (yajl_gen_string(g, (u_char *)"ok", - strlen("ok")) != - yajl_gen_status_ok) - goto err; - break; - default: - if (yajl_gen_string(g, (u_char *)"unknown", - strlen("unknown")) != - yajl_gen_status_ok) - goto err; - break; - } - - log_logstash_print (g, LOG_INFO, (n->time != 0) ? n->time : cdtime ()); - return (0); - - err: - yajl_gen_free(g); - fprintf(stderr, "Could not correctly generate JSON notification\n"); - return (0); + if (g == NULL) { + fprintf(stderr, "Could not allocate JSON generator.\n"); + return (0); + } + + if (yajl_gen_map_open(g) != yajl_gen_status_ok) + goto err; + if (yajl_gen_string(g, (u_char *)"message", strlen("message")) != + yajl_gen_status_ok) + goto err; + if (strlen(n->message) > 0) { + if (yajl_gen_string(g, (u_char *)n->message, strlen(n->message)) != + yajl_gen_status_ok) + goto err; + } else { + if (yajl_gen_string(g, (u_char *)"notification without a message", + strlen("notification without a message")) != + yajl_gen_status_ok) + goto err; + } + + if (strlen(n->host) > 0) { + if (yajl_gen_string(g, (u_char *)"host", strlen("host")) != + yajl_gen_status_ok) + goto err; + if (yajl_gen_string(g, (u_char *)n->host, strlen(n->host)) != + yajl_gen_status_ok) + goto err; + } + if (strlen(n->plugin) > 0) { + if (yajl_gen_string(g, (u_char *)"plugin", strlen("plugin")) != + yajl_gen_status_ok) + goto err; + if (yajl_gen_string(g, (u_char *)n->plugin, strlen(n->plugin)) != + yajl_gen_status_ok) + goto err; + } + if (strlen(n->plugin_instance) > 0) { + if (yajl_gen_string(g, (u_char *)"plugin_instance", + strlen("plugin_instance")) != yajl_gen_status_ok) + goto err; + if (yajl_gen_string(g, (u_char *)n->plugin_instance, + strlen(n->plugin_instance)) != yajl_gen_status_ok) + goto err; + } + if (strlen(n->type) > 0) { + if (yajl_gen_string(g, (u_char *)"type", strlen("type")) != + yajl_gen_status_ok) + goto err; + if (yajl_gen_string(g, (u_char *)n->type, strlen(n->type)) != + yajl_gen_status_ok) + goto err; + } + if (strlen(n->type_instance) > 0) { + if (yajl_gen_string(g, (u_char *)"type_instance", + strlen("type_instance")) != yajl_gen_status_ok) + goto err; + if (yajl_gen_string(g, (u_char *)n->type_instance, + strlen(n->type_instance)) != yajl_gen_status_ok) + goto err; + } + + if (yajl_gen_string(g, (u_char *)"severity", strlen("severity")) != + yajl_gen_status_ok) + goto err; + + switch (n->severity) { + case NOTIF_FAILURE: + if (yajl_gen_string(g, (u_char *)"failure", strlen("failure")) != + yajl_gen_status_ok) + goto err; + break; + case NOTIF_WARNING: + if (yajl_gen_string(g, (u_char *)"warning", strlen("warning")) != + yajl_gen_status_ok) + goto err; + break; + case NOTIF_OKAY: + if (yajl_gen_string(g, (u_char *)"ok", strlen("ok")) != yajl_gen_status_ok) + goto err; + break; + default: + if (yajl_gen_string(g, (u_char *)"unknown", strlen("unknown")) != + yajl_gen_status_ok) + goto err; + break; + } + + log_logstash_print(g, LOG_INFO, (n->time != 0) ? n->time : cdtime()); + return (0); + +err: + yajl_gen_free(g); + fprintf(stderr, "Could not correctly generate JSON notification\n"); + return (0); } /* int log_logstash_notification */ -void module_register (void) -{ - plugin_register_config ("log_logstash", - log_logstash_config, - config_keys, - config_keys_num); - plugin_register_log ("log_logstash", - log_logstash_log, - /* user_data = */ NULL); - plugin_register_notification ("log_logstash", - log_logstash_notification, - /* user_data = */ NULL); +void module_register(void) { + plugin_register_config("log_logstash", log_logstash_config, config_keys, + config_keys_num); + plugin_register_log("log_logstash", log_logstash_log, + /* user_data = */ NULL); + plugin_register_notification("log_logstash", log_logstash_notification, + /* user_data = */ NULL); } /* void module_register (void) */ /* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/logfile.c b/src/logfile.c index 6d555842..db122915 100644 --- a/src/logfile.c +++ b/src/logfile.c @@ -31,7 +31,7 @@ #include "common.h" #include "plugin.h" -#define DEFAULT_LOGFILE LOCALSTATEDIR"/log/collectd.log" +#define DEFAULT_LOGFILE LOCALSTATEDIR "/log/collectd.log" #if COLLECT_DEBUG static int log_level = LOG_DEBUG; @@ -45,189 +45,168 @@ static char *log_file = NULL; static int print_timestamp = 1; static int print_severity = 0; -static const char *config_keys[] = -{ - "LogLevel", - "File", - "Timestamp", - "PrintSeverity" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); - -static int logfile_config (const char *key, const char *value) -{ - if (0 == strcasecmp (key, "LogLevel")) { - log_level = parse_log_severity(value); - if (log_level < 0) { - log_level = LOG_INFO; - ERROR ("logfile: invalid loglevel [%s] defaulting to 'info'", value); - return (1); - } - } - else if (0 == strcasecmp (key, "File")) { - sfree (log_file); - log_file = strdup (value); - } - else if (0 == strcasecmp (key, "Timestamp")) { - if (IS_FALSE (value)) - print_timestamp = 0; - else - print_timestamp = 1; - } else if (0 == strcasecmp(key, "PrintSeverity")) { - if (IS_FALSE (value)) - print_severity = 0; - else - print_severity = 1; - } - else { - return -1; - } - return 0; +static const char *config_keys[] = {"LogLevel", "File", "Timestamp", + "PrintSeverity"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); + +static int logfile_config(const char *key, const char *value) { + if (0 == strcasecmp(key, "LogLevel")) { + log_level = parse_log_severity(value); + if (log_level < 0) { + log_level = LOG_INFO; + ERROR("logfile: invalid loglevel [%s] defaulting to 'info'", value); + return (1); + } + } else if (0 == strcasecmp(key, "File")) { + sfree(log_file); + log_file = strdup(value); + } else if (0 == strcasecmp(key, "Timestamp")) { + if (IS_FALSE(value)) + print_timestamp = 0; + else + print_timestamp = 1; + } else if (0 == strcasecmp(key, "PrintSeverity")) { + if (IS_FALSE(value)) + print_severity = 0; + else + print_severity = 1; + } else { + return -1; + } + return 0; } /* int logfile_config (const char *, const char *) */ -static void logfile_print (const char *msg, int severity, - cdtime_t timestamp_time) -{ - FILE *fh; - _Bool do_close = 0; - char timestamp_str[64]; - char level_str[16] = ""; - - if (print_severity) - { - switch (severity) - { - case LOG_ERR: - snprintf(level_str, sizeof (level_str), "[error] "); - break; - case LOG_WARNING: - snprintf(level_str, sizeof (level_str), "[warning] "); - break; - case LOG_NOTICE: - snprintf(level_str, sizeof (level_str), "[notice] "); - break; - case LOG_INFO: - snprintf(level_str, sizeof (level_str), "[info] "); - break; - case LOG_DEBUG: - snprintf(level_str, sizeof (level_str), "[debug] "); - break; - default: - break; - } - } - - if (print_timestamp) - { - struct tm timestamp_tm; - localtime_r (&CDTIME_T_TO_TIME_T (timestamp_time), ×tamp_tm); - - strftime (timestamp_str, sizeof (timestamp_str), "%Y-%m-%d %H:%M:%S", - ×tamp_tm); - timestamp_str[sizeof (timestamp_str) - 1] = '\0'; - } - - pthread_mutex_lock (&file_lock); - - if (log_file == NULL) - { - fh = fopen (DEFAULT_LOGFILE, "a"); - do_close = 1; - } - else if (strcasecmp (log_file, "stderr") == 0) - fh = stderr; - else if (strcasecmp (log_file, "stdout") == 0) - fh = stdout; - else - { - fh = fopen (log_file, "a"); - do_close = 1; - } - - if (fh == NULL) - { - char errbuf[1024]; - fprintf (stderr, "logfile plugin: fopen (%s) failed: %s\n", - (log_file == NULL) ? DEFAULT_LOGFILE : log_file, - sstrerror (errno, errbuf, sizeof (errbuf))); - } - else - { - if (print_timestamp) - fprintf (fh, "[%s] %s%s\n", timestamp_str, level_str, msg); - else - fprintf (fh, "%s%s\n", level_str, msg); - - if (do_close) { - fclose (fh); - } else { - fflush(fh); - } - } - - pthread_mutex_unlock (&file_lock); - - return; +static void logfile_print(const char *msg, int severity, + cdtime_t timestamp_time) { + FILE *fh; + _Bool do_close = 0; + char timestamp_str[64]; + char level_str[16] = ""; + + if (print_severity) { + switch (severity) { + case LOG_ERR: + snprintf(level_str, sizeof(level_str), "[error] "); + break; + case LOG_WARNING: + snprintf(level_str, sizeof(level_str), "[warning] "); + break; + case LOG_NOTICE: + snprintf(level_str, sizeof(level_str), "[notice] "); + break; + case LOG_INFO: + snprintf(level_str, sizeof(level_str), "[info] "); + break; + case LOG_DEBUG: + snprintf(level_str, sizeof(level_str), "[debug] "); + break; + default: + break; + } + } + + if (print_timestamp) { + struct tm timestamp_tm; + localtime_r(&CDTIME_T_TO_TIME_T(timestamp_time), ×tamp_tm); + + strftime(timestamp_str, sizeof(timestamp_str), "%Y-%m-%d %H:%M:%S", + ×tamp_tm); + timestamp_str[sizeof(timestamp_str) - 1] = '\0'; + } + + pthread_mutex_lock(&file_lock); + + if (log_file == NULL) { + fh = fopen(DEFAULT_LOGFILE, "a"); + do_close = 1; + } else if (strcasecmp(log_file, "stderr") == 0) + fh = stderr; + else if (strcasecmp(log_file, "stdout") == 0) + fh = stdout; + else { + fh = fopen(log_file, "a"); + do_close = 1; + } + + if (fh == NULL) { + char errbuf[1024]; + fprintf(stderr, "logfile plugin: fopen (%s) failed: %s\n", + (log_file == NULL) ? DEFAULT_LOGFILE : log_file, + sstrerror(errno, errbuf, sizeof(errbuf))); + } else { + if (print_timestamp) + fprintf(fh, "[%s] %s%s\n", timestamp_str, level_str, msg); + else + fprintf(fh, "%s%s\n", level_str, msg); + + if (do_close) { + fclose(fh); + } else { + fflush(fh); + } + } + + pthread_mutex_unlock(&file_lock); + + return; } /* void logfile_print */ -static void logfile_log (int severity, const char *msg, - user_data_t __attribute__((unused)) *user_data) -{ - if (severity > log_level) - return; +static void logfile_log(int severity, const char *msg, + user_data_t __attribute__((unused)) * user_data) { + if (severity > log_level) + return; - logfile_print (msg, severity, cdtime ()); + logfile_print(msg, severity, cdtime()); } /* void logfile_log (int, const char *) */ -static int logfile_notification (const notification_t *n, - user_data_t __attribute__((unused)) *user_data) -{ - char buf[1024] = ""; - char *buf_ptr = buf; - int buf_len = sizeof (buf); - int status; - - status = ssnprintf (buf_ptr, buf_len, "Notification: severity = %s", - (n->severity == NOTIF_FAILURE) ? "FAILURE" - : ((n->severity == NOTIF_WARNING) ? "WARNING" - : ((n->severity == NOTIF_OKAY) ? "OKAY" : "UNKNOWN"))); - if (status > 0) - { - buf_ptr += status; - buf_len -= status; - } - -#define APPEND(bufptr, buflen, key, value) \ - if ((buflen > 0) && (strlen (value) > 0)) { \ - status = ssnprintf (bufptr, buflen, ", %s = %s", key, value); \ - if (status > 0) { \ - bufptr += status; \ - buflen -= status; \ - } \ - } - APPEND (buf_ptr, buf_len, "host", n->host); - APPEND (buf_ptr, buf_len, "plugin", n->plugin); - APPEND (buf_ptr, buf_len, "plugin_instance", n->plugin_instance); - APPEND (buf_ptr, buf_len, "type", n->type); - APPEND (buf_ptr, buf_len, "type_instance", n->type_instance); - APPEND (buf_ptr, buf_len, "message", n->message); - - buf[sizeof (buf) - 1] = '\0'; - - logfile_print (buf, LOG_INFO, - (n->time != 0) ? n->time : cdtime ()); - - return (0); +static int logfile_notification(const notification_t *n, + user_data_t __attribute__((unused)) * + user_data) { + char buf[1024] = ""; + char *buf_ptr = buf; + int buf_len = sizeof(buf); + int status; + + status = ssnprintf( + buf_ptr, buf_len, "Notification: severity = %s", + (n->severity == NOTIF_FAILURE) + ? "FAILURE" + : ((n->severity == NOTIF_WARNING) + ? "WARNING" + : ((n->severity == NOTIF_OKAY) ? "OKAY" : "UNKNOWN"))); + if (status > 0) { + buf_ptr += status; + buf_len -= status; + } + +#define APPEND(bufptr, buflen, key, value) \ + if ((buflen > 0) && (strlen(value) > 0)) { \ + status = ssnprintf(bufptr, buflen, ", %s = %s", key, value); \ + if (status > 0) { \ + bufptr += status; \ + buflen -= status; \ + } \ + } + APPEND(buf_ptr, buf_len, "host", n->host); + APPEND(buf_ptr, buf_len, "plugin", n->plugin); + APPEND(buf_ptr, buf_len, "plugin_instance", n->plugin_instance); + APPEND(buf_ptr, buf_len, "type", n->type); + APPEND(buf_ptr, buf_len, "type_instance", n->type_instance); + APPEND(buf_ptr, buf_len, "message", n->message); + + buf[sizeof(buf) - 1] = '\0'; + + logfile_print(buf, LOG_INFO, (n->time != 0) ? n->time : cdtime()); + + return (0); } /* int logfile_notification */ -void module_register (void) -{ - plugin_register_config ("logfile", logfile_config, - config_keys, config_keys_num); - plugin_register_log ("logfile", logfile_log, /* user_data = */ NULL); - plugin_register_notification ("logfile", logfile_notification, - /* user_data = */ NULL); +void module_register(void) { + plugin_register_config("logfile", logfile_config, config_keys, + config_keys_num); + plugin_register_log("logfile", logfile_log, /* user_data = */ NULL); + plugin_register_notification("logfile", logfile_notification, + /* user_data = */ NULL); } /* void module_register (void) */ /* vim: set sw=4 ts=4 tw=78 noexpandtab : */ - diff --git a/src/lpar.c b/src/lpar.c index 69a56e1c..df4424c8 100644 --- a/src/lpar.c +++ b/src/lpar.c @@ -24,25 +24,21 @@ #include "common.h" #include "plugin.h" -#include #include +#include #include /* XINTFRAC was defined in libperfstat.h somewhere between AIX 5.3 and 6.1 */ #ifndef XINTFRAC -# include -# define XINTFRAC ((double)(_system_configuration.Xint) / \ - (double)(_system_configuration.Xfrac)) +#include +#define XINTFRAC \ + ((double)(_system_configuration.Xint) / (double)(_system_configuration.Xfrac)) #endif #define CLOCKTICKS_TO_TICKS(cticks) ((cticks) / XINTFRAC) -static const char *config_keys[] = -{ - "CpuPoolStats", - "ReportBySerial" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"CpuPoolStats", "ReportBySerial"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static _Bool pool_stats = 0; static _Bool report_by_serial = 0; @@ -53,215 +49,199 @@ static char serial[SYS_NMLN]; static perfstat_partition_total_t lparstats_old; -static int lpar_config (const char *key, const char *value) -{ - if (strcasecmp ("CpuPoolStats", key) == 0) - { - if (IS_TRUE (value)) - pool_stats = 1; - else - pool_stats = 0; - } - else if (strcasecmp ("ReportBySerial", key) == 0) - { - if (IS_TRUE (value)) - report_by_serial = 1; - else - report_by_serial = 0; - } - else - { - return (-1); - } - - return (0); +static int lpar_config(const char *key, const char *value) { + if (strcasecmp("CpuPoolStats", key) == 0) { + if (IS_TRUE(value)) + pool_stats = 1; + else + pool_stats = 0; + } else if (strcasecmp("ReportBySerial", key) == 0) { + if (IS_TRUE(value)) + report_by_serial = 1; + else + report_by_serial = 0; + } else { + return (-1); + } + + return (0); } /* int lpar_config */ -static int lpar_init (void) -{ - int status; - - /* Retrieve the initial metrics. Returns the number of structures filled. */ - status = perfstat_partition_total (/* name = */ NULL, /* (must be NULL) */ - &lparstats_old, sizeof (perfstat_partition_total_t), - /* number = */ 1 /* (must be 1) */); - if (status != 1) - { - char errbuf[1024]; - ERROR ("lpar plugin: perfstat_partition_total failed: %s (%i)", - sstrerror (errno, errbuf, sizeof (errbuf)), - status); - return (-1); - } +static int lpar_init(void) { + int status; + + /* Retrieve the initial metrics. Returns the number of structures filled. */ + status = perfstat_partition_total(/* name = */ NULL, /* (must be NULL) */ + &lparstats_old, + sizeof(perfstat_partition_total_t), + /* number = */ 1 /* (must be 1) */); + if (status != 1) { + char errbuf[1024]; + ERROR("lpar plugin: perfstat_partition_total failed: %s (%i)", + sstrerror(errno, errbuf, sizeof(errbuf)), status); + return (-1); + } #if PERFSTAT_SUPPORTS_DONATION - if (!lparstats_old.type.b.shared_enabled - && lparstats_old.type.b.donate_enabled) - { - donate_flag = 1; - } + if (!lparstats_old.type.b.shared_enabled && + lparstats_old.type.b.donate_enabled) { + donate_flag = 1; + } #endif - if (pool_stats && !lparstats_old.type.b.pool_util_authority) - { - WARNING ("lpar plugin: This partition does not have pool authority. " - "Disabling CPU pool statistics collection."); - pool_stats = 0; - } + if (pool_stats && !lparstats_old.type.b.pool_util_authority) { + WARNING("lpar plugin: This partition does not have pool authority. " + "Disabling CPU pool statistics collection."); + pool_stats = 0; + } - return (0); + return (0); } /* int lpar_init */ -static void lpar_submit (const char *type_instance, double value) -{ - value_list_t vl = VALUE_LIST_INIT; - - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - if (report_by_serial) - { - sstrncpy (vl.host, serial, sizeof (vl.host)); - sstrncpy (vl.plugin_instance, hostname_g, sizeof (vl.plugin)); - } - sstrncpy (vl.plugin, "lpar", sizeof (vl.plugin)); - sstrncpy (vl.type, "vcpu", sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); +static void lpar_submit(const char *type_instance, double value) { + value_list_t vl = VALUE_LIST_INIT; + + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + if (report_by_serial) { + sstrncpy(vl.host, serial, sizeof(vl.host)); + sstrncpy(vl.plugin_instance, hostname_g, sizeof(vl.plugin)); + } + sstrncpy(vl.plugin, "lpar", sizeof(vl.plugin)); + sstrncpy(vl.type, "vcpu", sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); } /* void lpar_submit */ -static int lpar_read (void) -{ - perfstat_partition_total_t lparstats; - int status; - struct utsname name; - u_longlong_t ticks; - u_longlong_t user_ticks, syst_ticks, wait_ticks, idle_ticks; - u_longlong_t consumed_ticks; - double entitled_proc_capacity; - - /* An LPAR has the same serial number as the physical system it is currently - running on. It is a convenient way of tracking LPARs as they are moved - from chassis to chassis through Live Partition Mobility (LPM). */ - if (uname (&name) != 0) - { - ERROR ("lpar plugin: uname failed."); - return (-1); - } - sstrncpy (serial, name.machine, sizeof (serial)); - - /* Retrieve the current metrics. Returns the number of structures filled. */ - status = perfstat_partition_total (/* name = */ NULL, /* (must be NULL) */ - &lparstats, sizeof (perfstat_partition_total_t), - /* number = */ 1 /* (must be 1) */); - if (status != 1) - { - char errbuf[1024]; - ERROR ("lpar plugin: perfstat_partition_total failed: %s (%i)", - sstrerror (errno, errbuf, sizeof (errbuf)), - status); - return (-1); - } - - /* Number of ticks since we last run. */ - ticks = lparstats.timebase_last - lparstats_old.timebase_last; - if (ticks == 0) - { - /* The stats have not been updated. Return now to avoid - * dividing by zero */ - return (0); - } - - /* - * On a shared partition, we're "entitled" to a certain amount of - * processing power, for example 250/100 of a physical CPU. Processing - * capacity not used by the partition may be assigned to a different - * partition by the hypervisor, so "idle" is hopefully a very small - * number. - * - * A dedicated partition may donate its CPUs to another partition and - * may steal ticks from somewhere else (another partition or maybe the - * shared pool, I don't know --octo). - */ - - /* entitled_proc_capacity is in 1/100th of a CPU */ - entitled_proc_capacity = 0.01 * ((double) lparstats.entitled_proc_capacity); - lpar_submit ("entitled", entitled_proc_capacity); - - /* The number of ticks actually spent in the various states */ - user_ticks = lparstats.puser - lparstats_old.puser; - syst_ticks = lparstats.psys - lparstats_old.psys; - wait_ticks = lparstats.pwait - lparstats_old.pwait; - idle_ticks = lparstats.pidle - lparstats_old.pidle; - consumed_ticks = user_ticks + syst_ticks + wait_ticks + idle_ticks; - - lpar_submit ("user", (double) user_ticks / (double) ticks); - lpar_submit ("system", (double) syst_ticks / (double) ticks); - lpar_submit ("wait", (double) wait_ticks / (double) ticks); - lpar_submit ("idle", (double) idle_ticks / (double) ticks); +static int lpar_read(void) { + perfstat_partition_total_t lparstats; + int status; + struct utsname name; + u_longlong_t ticks; + u_longlong_t user_ticks, syst_ticks, wait_ticks, idle_ticks; + u_longlong_t consumed_ticks; + double entitled_proc_capacity; + + /* An LPAR has the same serial number as the physical system it is currently + running on. It is a convenient way of tracking LPARs as they are moved + from chassis to chassis through Live Partition Mobility (LPM). */ + if (uname(&name) != 0) { + ERROR("lpar plugin: uname failed."); + return (-1); + } + sstrncpy(serial, name.machine, sizeof(serial)); + + /* Retrieve the current metrics. Returns the number of structures filled. */ + status = + perfstat_partition_total(/* name = */ NULL, /* (must be NULL) */ + &lparstats, sizeof(perfstat_partition_total_t), + /* number = */ 1 /* (must be 1) */); + if (status != 1) { + char errbuf[1024]; + ERROR("lpar plugin: perfstat_partition_total failed: %s (%i)", + sstrerror(errno, errbuf, sizeof(errbuf)), status); + return (-1); + } + + /* Number of ticks since we last run. */ + ticks = lparstats.timebase_last - lparstats_old.timebase_last; + if (ticks == 0) { + /* The stats have not been updated. Return now to avoid + * dividing by zero */ + return (0); + } + + /* + * On a shared partition, we're "entitled" to a certain amount of + * processing power, for example 250/100 of a physical CPU. Processing + * capacity not used by the partition may be assigned to a different + * partition by the hypervisor, so "idle" is hopefully a very small + * number. + * + * A dedicated partition may donate its CPUs to another partition and + * may steal ticks from somewhere else (another partition or maybe the + * shared pool, I don't know --octo). + */ + + /* entitled_proc_capacity is in 1/100th of a CPU */ + entitled_proc_capacity = 0.01 * ((double)lparstats.entitled_proc_capacity); + lpar_submit("entitled", entitled_proc_capacity); + + /* The number of ticks actually spent in the various states */ + user_ticks = lparstats.puser - lparstats_old.puser; + syst_ticks = lparstats.psys - lparstats_old.psys; + wait_ticks = lparstats.pwait - lparstats_old.pwait; + idle_ticks = lparstats.pidle - lparstats_old.pidle; + consumed_ticks = user_ticks + syst_ticks + wait_ticks + idle_ticks; + + lpar_submit("user", (double)user_ticks / (double)ticks); + lpar_submit("system", (double)syst_ticks / (double)ticks); + lpar_submit("wait", (double)wait_ticks / (double)ticks); + lpar_submit("idle", (double)idle_ticks / (double)ticks); #if PERFSTAT_SUPPORTS_DONATION - if (donate_flag) - { - /* donated => ticks given to another partition - * stolen => ticks received from another partition */ - u_longlong_t idle_donated_ticks, busy_donated_ticks; - u_longlong_t idle_stolen_ticks, busy_stolen_ticks; - - /* FYI: PURR == Processor Utilization of Resources Register - * SPURR == Scaled PURR */ - idle_donated_ticks = lparstats.idle_donated_purr - lparstats_old.idle_donated_purr; - busy_donated_ticks = lparstats.busy_donated_purr - lparstats_old.busy_donated_purr; - idle_stolen_ticks = lparstats.idle_stolen_purr - lparstats_old.idle_stolen_purr; - busy_stolen_ticks = lparstats.busy_stolen_purr - lparstats_old.busy_stolen_purr; - - lpar_submit ("idle_donated", (double) idle_donated_ticks / (double) ticks); - lpar_submit ("busy_donated", (double) busy_donated_ticks / (double) ticks); - lpar_submit ("idle_stolen", (double) idle_stolen_ticks / (double) ticks); - lpar_submit ("busy_stolen", (double) busy_stolen_ticks / (double) ticks); - - /* Donated ticks will be accounted for as stolen ticks in other LPARs */ - consumed_ticks += idle_stolen_ticks + busy_stolen_ticks; - } + if (donate_flag) { + /* donated => ticks given to another partition + * stolen => ticks received from another partition */ + u_longlong_t idle_donated_ticks, busy_donated_ticks; + u_longlong_t idle_stolen_ticks, busy_stolen_ticks; + + /* FYI: PURR == Processor Utilization of Resources Register + * SPURR == Scaled PURR */ + idle_donated_ticks = + lparstats.idle_donated_purr - lparstats_old.idle_donated_purr; + busy_donated_ticks = + lparstats.busy_donated_purr - lparstats_old.busy_donated_purr; + idle_stolen_ticks = + lparstats.idle_stolen_purr - lparstats_old.idle_stolen_purr; + busy_stolen_ticks = + lparstats.busy_stolen_purr - lparstats_old.busy_stolen_purr; + + lpar_submit("idle_donated", (double)idle_donated_ticks / (double)ticks); + lpar_submit("busy_donated", (double)busy_donated_ticks / (double)ticks); + lpar_submit("idle_stolen", (double)idle_stolen_ticks / (double)ticks); + lpar_submit("busy_stolen", (double)busy_stolen_ticks / (double)ticks); + + /* Donated ticks will be accounted for as stolen ticks in other LPARs */ + consumed_ticks += idle_stolen_ticks + busy_stolen_ticks; + } #endif - lpar_submit ("consumed", (double) consumed_ticks / (double) ticks); + lpar_submit("consumed", (double)consumed_ticks / (double)ticks); - if (pool_stats) - { - char typinst[DATA_MAX_NAME_LEN]; - u_longlong_t pool_idle_cticks; - double pool_idle_cpus; - double pool_busy_cpus; + if (pool_stats) { + char typinst[DATA_MAX_NAME_LEN]; + u_longlong_t pool_idle_cticks; + double pool_idle_cpus; + double pool_busy_cpus; - /* We're calculating "busy" from "idle" and the total number of - * CPUs, because the "busy" member didn't exist in early versions - * of libperfstat. It was added somewhere between AIX 5.3 ML5 and ML9. */ - pool_idle_cticks = lparstats.pool_idle_time - lparstats_old.pool_idle_time; - pool_idle_cpus = CLOCKTICKS_TO_TICKS ((double) pool_idle_cticks) / (double) ticks; - pool_busy_cpus = ((double) lparstats.phys_cpus_pool) - pool_idle_cpus; - if (pool_busy_cpus < 0.0) - pool_busy_cpus = 0.0; + /* We're calculating "busy" from "idle" and the total number of + * CPUs, because the "busy" member didn't exist in early versions + * of libperfstat. It was added somewhere between AIX 5.3 ML5 and ML9. */ + pool_idle_cticks = lparstats.pool_idle_time - lparstats_old.pool_idle_time; + pool_idle_cpus = + CLOCKTICKS_TO_TICKS((double)pool_idle_cticks) / (double)ticks; + pool_busy_cpus = ((double)lparstats.phys_cpus_pool) - pool_idle_cpus; + if (pool_busy_cpus < 0.0) + pool_busy_cpus = 0.0; - ssnprintf (typinst, sizeof (typinst), "pool-%X-busy", lparstats.pool_id); - lpar_submit (typinst, pool_busy_cpus); + ssnprintf(typinst, sizeof(typinst), "pool-%X-busy", lparstats.pool_id); + lpar_submit(typinst, pool_busy_cpus); - ssnprintf (typinst, sizeof (typinst), "pool-%X-idle", lparstats.pool_id); - lpar_submit (typinst, pool_idle_cpus); - } + ssnprintf(typinst, sizeof(typinst), "pool-%X-idle", lparstats.pool_id); + lpar_submit(typinst, pool_idle_cpus); + } - memcpy (&lparstats_old, &lparstats, sizeof (lparstats_old)); + memcpy(&lparstats_old, &lparstats, sizeof(lparstats_old)); - return (0); + return (0); } /* int lpar_read */ -void module_register (void) -{ - plugin_register_config ("lpar", lpar_config, - config_keys, config_keys_num); - plugin_register_init ("lpar", lpar_init); - plugin_register_read ("lpar", lpar_read); +void module_register(void) { + plugin_register_config("lpar", lpar_config, config_keys, config_keys_num); + plugin_register_init("lpar", lpar_init); + plugin_register_read("lpar", lpar_read); } /* void module_register */ /* vim: set sw=8 noet : */ - diff --git a/src/lua.c b/src/lua.c index 45fd7d5a..2bd56a16 100644 --- a/src/lua.c +++ b/src/lua.c @@ -32,15 +32,15 @@ * GCC will complain about the macro definition. */ #define DONT_POISON_SPRINTF_YET -#include "collectd.h" #include "common.h" #include "plugin.h" +#include "collectd.h" /* Include the Lua API header files. */ -#include "utils_lua.h" #include #include #include +#include "utils_lua.h" #include @@ -306,10 +306,9 @@ static int lua_cb_register_read(lua_State *L) /* {{{ */ int status = plugin_register_complex_read(/* group = */ "lua", /* name = */ function_name, /* callback = */ clua_read, - /* interval = */ 0, - &(user_data_t) { - .data = cb, - }); + /* interval = */ 0, &(user_data_t){ + .data = cb, + }); if (status != 0) return luaL_error(L, "%s", "plugin_register_complex_read failed"); @@ -347,11 +346,11 @@ static int lua_cb_register_write(lua_State *L) /* {{{ */ cb->lua_function_name = strdup(function_name); pthread_mutex_init(&cb->lock, NULL); - int status = plugin_register_write(/* name = */ function_name, - /* callback = */ clua_write, - &(user_data_t) { - .data = cb, - }); + int status = + plugin_register_write(/* name = */ function_name, + /* callback = */ clua_write, &(user_data_t){ + .data = cb, + }); if (status != 0) return luaL_error(L, "%s", "plugin_register_write failed"); @@ -367,8 +366,7 @@ static const luaL_Reg collectdlib[] = { {"dispatch_values", lua_cb_dispatch_values}, {"register_read", lua_cb_register_read}, {"register_write", lua_cb_register_write}, - {NULL, NULL} -}; + {NULL, NULL}}; static int open_collectd(lua_State *L) /* {{{ */ { @@ -412,7 +410,7 @@ static int lua_script_init(lua_script_t *script) /* {{{ */ /* Open up all the standard Lua libraries. */ luaL_openlibs(script->lua_state); - /* Load the 'collectd' library */ +/* Load the 'collectd' library */ #if LUA_VERSION_NUM < 502 lua_pushcfunction(script->lua_state, open_collectd); lua_pushstring(script->lua_state, "collectd"); diff --git a/src/lvm.c b/src/lvm.c index 5e130d80..3a84a6d8 100644 --- a/src/lvm.c +++ b/src/lvm.c @@ -31,168 +31,159 @@ #define NO_VALUE UINT64_MAX #define PERCENT_SCALE_FACTOR 1e-8 -static uint64_t get_lv_property_int(lv_t lv, char const *property) -{ - lvm_property_value_t v; - - v = lvm_lv_get_property(lv, property); - if (!v.is_valid || !v.is_integer) - return NO_VALUE; - /* May be NO_VALUE if @property does not apply to this LV */ - return v.value.integer; +static uint64_t get_lv_property_int(lv_t lv, char const *property) { + lvm_property_value_t v; + + v = lvm_lv_get_property(lv, property); + if (!v.is_valid || !v.is_integer) + return NO_VALUE; + /* May be NO_VALUE if @property does not apply to this LV */ + return v.value.integer; } -static char const *get_lv_property_string(lv_t lv, char const *property) -{ - lvm_property_value_t v; +static char const *get_lv_property_string(lv_t lv, char const *property) { + lvm_property_value_t v; - v = lvm_lv_get_property(lv, property); - if (!v.is_valid || !v.is_string) - return NULL; - return v.value.string; + v = lvm_lv_get_property(lv, property); + if (!v.is_valid || !v.is_string) + return NULL; + return v.value.string; } -static void lvm_submit (char const *plugin_instance, char const *type_instance, - uint64_t ivalue) -{ - value_list_t vl = VALUE_LIST_INIT; +static void lvm_submit(char const *plugin_instance, char const *type_instance, + uint64_t ivalue) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = (gauge_t) ivalue }; - vl.values_len = 1; + vl.values = &(value_t){.gauge = (gauge_t)ivalue}; + vl.values_len = 1; - sstrncpy(vl.plugin, "lvm", sizeof (vl.plugin)); - sstrncpy(vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); - sstrncpy(vl.type, "df_complex", sizeof (vl.type)); - sstrncpy(vl.type_instance, type_instance, sizeof (vl.type_instance)); + sstrncpy(vl.plugin, "lvm", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "df_complex", sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } static void report_lv_utilization(lv_t lv, char const *vg_name, - char const *lv_name, uint64_t lv_size, - char const *used_percent_property) -{ - uint64_t used_percent_unscaled; - uint64_t used_bytes; - char plugin_instance[DATA_MAX_NAME_LEN]; - - used_percent_unscaled = get_lv_property_int(lv, used_percent_property); - if (used_percent_unscaled == NO_VALUE) - return; - used_bytes = lv_size * (used_percent_unscaled * PERCENT_SCALE_FACTOR); - - ssnprintf(plugin_instance, sizeof(plugin_instance), "%s-%s", - vg_name, lv_name); - lvm_submit(plugin_instance, "used", used_bytes); - lvm_submit(plugin_instance, "free", lv_size - used_bytes); + char const *lv_name, uint64_t lv_size, + char const *used_percent_property) { + uint64_t used_percent_unscaled; + uint64_t used_bytes; + char plugin_instance[DATA_MAX_NAME_LEN]; + + used_percent_unscaled = get_lv_property_int(lv, used_percent_property); + if (used_percent_unscaled == NO_VALUE) + return; + used_bytes = lv_size * (used_percent_unscaled * PERCENT_SCALE_FACTOR); + + ssnprintf(plugin_instance, sizeof(plugin_instance), "%s-%s", vg_name, + lv_name); + lvm_submit(plugin_instance, "used", used_bytes); + lvm_submit(plugin_instance, "free", lv_size - used_bytes); } static void report_thin_pool_utilization(lv_t lv, char const *vg_name, - uint64_t lv_size) -{ - char const *data_lv; - char const *metadata_lv; - uint64_t metadata_size; - - data_lv = get_lv_property_string(lv, "data_lv"); - metadata_lv = get_lv_property_string(lv, "metadata_lv"); - metadata_size = get_lv_property_int(lv, "lv_metadata_size"); - if (data_lv == NULL || metadata_lv == NULL || metadata_size == NO_VALUE) - return; - - report_lv_utilization(lv, vg_name, data_lv, lv_size, "data_percent"); - report_lv_utilization(lv, vg_name, metadata_lv, metadata_size, - "metadata_percent"); + uint64_t lv_size) { + char const *data_lv; + char const *metadata_lv; + uint64_t metadata_size; + + data_lv = get_lv_property_string(lv, "data_lv"); + metadata_lv = get_lv_property_string(lv, "metadata_lv"); + metadata_size = get_lv_property_int(lv, "lv_metadata_size"); + if (data_lv == NULL || metadata_lv == NULL || metadata_size == NO_VALUE) + return; + + report_lv_utilization(lv, vg_name, data_lv, lv_size, "data_percent"); + report_lv_utilization(lv, vg_name, metadata_lv, metadata_size, + "metadata_percent"); } -static void vg_read(vg_t vg, char const *vg_name) -{ - struct dm_list *lvs; - struct lvm_lv_list *lvl; - char const *name; - char const *attrs; - uint64_t size; - - lvm_submit (vg_name, "free", lvm_vg_get_free_size(vg)); - - lvs = lvm_vg_list_lvs(vg); - if (!lvs) { - /* no VGs are defined, which is not an error per se */ - return; - } - - dm_list_iterate_items(lvl, lvs) { - name = lvm_lv_get_name(lvl->lv); - attrs = get_lv_property_string(lvl->lv, "lv_attr"); - size = lvm_lv_get_size(lvl->lv); - if (name == NULL || attrs == NULL || size == NO_VALUE) - continue; - - /* Condition on volume type. We want the reported sizes in the - volume group to sum to the size of the volume group, so we ignore - virtual volumes. */ - switch (attrs[0]) { - case 's': - case 'S': - /* Snapshot. Also report used/free space. */ - report_lv_utilization(lvl->lv, vg_name, name, size, - "data_percent"); - break; - case 't': - /* Thin pool virtual volume. We report the underlying data - and metadata volumes, not this one. Report used/free - space, then ignore. */ - report_thin_pool_utilization(lvl->lv, vg_name, size); - continue; - case 'v': - /* Virtual volume. Ignore. */ - continue; - case 'V': - /* Thin volume or thin snapshot. Ignore. */ - continue; - } - lvm_submit(vg_name, name, size); +static void vg_read(vg_t vg, char const *vg_name) { + struct dm_list *lvs; + struct lvm_lv_list *lvl; + char const *name; + char const *attrs; + uint64_t size; + + lvm_submit(vg_name, "free", lvm_vg_get_free_size(vg)); + + lvs = lvm_vg_list_lvs(vg); + if (!lvs) { + /* no VGs are defined, which is not an error per se */ + return; + } + + dm_list_iterate_items(lvl, lvs) { + name = lvm_lv_get_name(lvl->lv); + attrs = get_lv_property_string(lvl->lv, "lv_attr"); + size = lvm_lv_get_size(lvl->lv); + if (name == NULL || attrs == NULL || size == NO_VALUE) + continue; + + /* Condition on volume type. We want the reported sizes in the + volume group to sum to the size of the volume group, so we ignore + virtual volumes. */ + switch (attrs[0]) { + case 's': + case 'S': + /* Snapshot. Also report used/free space. */ + report_lv_utilization(lvl->lv, vg_name, name, size, "data_percent"); + break; + case 't': + /* Thin pool virtual volume. We report the underlying data + and metadata volumes, not this one. Report used/free + space, then ignore. */ + report_thin_pool_utilization(lvl->lv, vg_name, size); + continue; + case 'v': + /* Virtual volume. Ignore. */ + continue; + case 'V': + /* Thin volume or thin snapshot. Ignore. */ + continue; } + lvm_submit(vg_name, name, size); + } } -static int lvm_read(void) -{ - lvm_t lvm; - struct dm_list *vg_names; - struct lvm_str_list *name_list; - - lvm = lvm_init(NULL); - if (!lvm) { - ERROR("lvm plugin: lvm_init failed."); - return (-1); - } +static int lvm_read(void) { + lvm_t lvm; + struct dm_list *vg_names; + struct lvm_str_list *name_list; - vg_names = lvm_list_vg_names(lvm); - if (!vg_names) { - ERROR("lvm plugin lvm_list_vg_name failed %s", lvm_errmsg(lvm)); - lvm_quit(lvm); - return (-1); - } + lvm = lvm_init(NULL); + if (!lvm) { + ERROR("lvm plugin: lvm_init failed."); + return (-1); + } - dm_list_iterate_items(name_list, vg_names) { - vg_t vg; + vg_names = lvm_list_vg_names(lvm); + if (!vg_names) { + ERROR("lvm plugin lvm_list_vg_name failed %s", lvm_errmsg(lvm)); + lvm_quit(lvm); + return (-1); + } - vg = lvm_vg_open(lvm, name_list->str, "r", 0); - if (!vg) { - ERROR ("lvm plugin: lvm_vg_open (%s) failed: %s", - name_list->str, lvm_errmsg(lvm)); - continue; - } + dm_list_iterate_items(name_list, vg_names) { + vg_t vg; - vg_read(vg, name_list->str); - lvm_vg_close(vg); + vg = lvm_vg_open(lvm, name_list->str, "r", 0); + if (!vg) { + ERROR("lvm plugin: lvm_vg_open (%s) failed: %s", name_list->str, + lvm_errmsg(lvm)); + continue; } - lvm_quit(lvm); - return (0); + vg_read(vg, name_list->str); + lvm_vg_close(vg); + } + + lvm_quit(lvm); + return (0); } /*lvm_read */ -void module_register(void) -{ - plugin_register_read("lvm", lvm_read); +void module_register(void) { + plugin_register_read("lvm", lvm_read); } /* void module_register */ diff --git a/src/madwifi.c b/src/madwifi.c index 82c7e2fa..99e42243 100644 --- a/src/madwifi.c +++ b/src/madwifi.c @@ -21,7 +21,6 @@ * based on some code from interfaces.c (collectd) and Madwifi driver **/ - /** * There are several data streams provided by Madwifi plugin, some are * connected to network interface, some are connected to each node @@ -87,7 +86,6 @@ * `Interface', to limit found interfaces to madwifi interfaces only. **/ - #include "collectd.h" #include "common.h" @@ -98,24 +96,21 @@ #include #if !KERNEL_LINUX -# error "No applicable input method." +#error "No applicable input method." #endif #include #include "madwifi.h" - - struct stat_spec { - uint16_t flags; - uint16_t offset; - const char *name; + uint16_t flags; + uint16_t offset; + const char *name; }; +#define OFFSETOF(s, i) ((size_t) & ((s *)0)->i) -#define OFFSETOF(s, i) ((size_t)&((s *)0)->i) - -#define FLAG(i) (((uint32_t) 1) << ((i) % 32)) +#define FLAG(i) (((uint32_t)1) << ((i) % 32)) #define SPC_STAT 0 #define NOD_STAT 1 @@ -132,208 +127,211 @@ struct stat_spec { /* By default, the item is summed with other such items and logged together */ #define SU 8 -#define SS_STAT(flags, name) { flags | SPC_STAT, 0, #name } -#define NS_STAT(flags, name) { flags | NOD_STAT, OFFSETOF(struct ieee80211_nodestats, name), #name } -#define IS_STAT(flags, name) { flags | IFA_STAT, OFFSETOF(struct ieee80211_stats, name), #name } -#define AS_STAT(flags, name) { flags | ATH_STAT, OFFSETOF(struct ath_stats, name), #name } - +#define SS_STAT(flags, name) \ + { flags | SPC_STAT, 0, #name } +#define NS_STAT(flags, name) \ + { flags | NOD_STAT, OFFSETOF(struct ieee80211_nodestats, name), #name } +#define IS_STAT(flags, name) \ + { flags | IFA_STAT, OFFSETOF(struct ieee80211_stats, name), #name } +#define AS_STAT(flags, name) \ + { flags | ATH_STAT, OFFSETOF(struct ath_stats, name), #name } /* * (Module-)Global variables */ /* Indices of special stats in specs array */ -#define STAT_NODE_OCTETS 0 -#define STAT_NODE_RSSI 1 -#define STAT_NODE_TX_RATE 2 -#define STAT_ATH_NODES 3 -#define STAT_NS_RX_BEACONS 4 -#define STAT_AST_ANT_RX 5 -#define STAT_AST_ANT_TX 6 +#define STAT_NODE_OCTETS 0 +#define STAT_NODE_RSSI 1 +#define STAT_NODE_TX_RATE 2 +#define STAT_ATH_NODES 3 +#define STAT_NS_RX_BEACONS 4 +#define STAT_AST_ANT_RX 5 +#define STAT_AST_ANT_TX 6 static struct stat_spec specs[] = { -/* Special statistics */ -SS_STAT(LOG, node_octets), /* rx and tx data count (bytes) */ -SS_STAT(LOG, node_rssi), /* received RSSI of the node */ -SS_STAT(LOG, node_tx_rate), /* used tx rate to the node */ -SS_STAT(LOG, ath_nodes), /* the number of associated nodes */ -SS_STAT(D, ns_rx_beacons), /* rx beacon frames */ -SS_STAT(LOG, ast_ant_rx), /* rx frames with antenna */ -SS_STAT(LOG, ast_ant_tx), /* tx frames with antenna */ - -/* Node statistics */ -NS_STAT(LOG, ns_rx_data), /* rx data frames */ -NS_STAT(LOG, ns_rx_mgmt), /* rx management frames */ -NS_STAT(LOG, ns_rx_ctrl), /* rx control frames */ -NS_STAT(D, ns_rx_ucast), /* rx unicast frames */ -NS_STAT(D, ns_rx_mcast), /* rx multi/broadcast frames */ -NS_STAT(D, ns_rx_proberesp), /* rx probe response frames */ -NS_STAT(LOG, ns_rx_dup), /* rx discard because it's a dup */ -NS_STAT(SU, ns_rx_noprivacy), /* rx w/ wep but privacy off */ -NS_STAT(SU, ns_rx_wepfail), /* rx wep processing failed */ -NS_STAT(SU, ns_rx_demicfail), /* rx demic failed */ -NS_STAT(SU, ns_rx_decap), /* rx decapsulation failed */ -NS_STAT(SU, ns_rx_defrag), /* rx defragmentation failed */ -NS_STAT(D, ns_rx_disassoc), /* rx disassociation */ -NS_STAT(D, ns_rx_deauth), /* rx deauthentication */ -NS_STAT(SU, ns_rx_decryptcrc), /* rx decrypt failed on crc */ -NS_STAT(SU, ns_rx_unauth), /* rx on unauthorized port */ -NS_STAT(SU, ns_rx_unencrypted), /* rx unecrypted w/ privacy */ -NS_STAT(LOG, ns_tx_data), /* tx data frames */ -NS_STAT(LOG, ns_tx_mgmt), /* tx management frames */ -NS_STAT(D, ns_tx_ucast), /* tx unicast frames */ -NS_STAT(D, ns_tx_mcast), /* tx multi/broadcast frames */ -NS_STAT(D, ns_tx_probereq), /* tx probe request frames */ -NS_STAT(D, ns_tx_uapsd), /* tx on uapsd queue */ -NS_STAT(SU, ns_tx_novlantag), /* tx discard due to no tag */ -NS_STAT(SU, ns_tx_vlanmismatch), /* tx discard due to of bad tag */ -NS_STAT(D, ns_tx_eosplost), /* uapsd EOSP retried out */ -NS_STAT(D, ns_ps_discard), /* ps discard due to of age */ -NS_STAT(D, ns_uapsd_triggers), /* uapsd triggers */ -NS_STAT(LOG, ns_tx_assoc), /* [re]associations */ -NS_STAT(LOG, ns_tx_auth), /* [re]authentications */ -NS_STAT(D, ns_tx_deauth), /* deauthentications */ -NS_STAT(D, ns_tx_disassoc), /* disassociations */ -NS_STAT(D, ns_psq_drops), /* power save queue drops */ - -/* Iface statistics */ -IS_STAT(SU, is_rx_badversion), /* rx frame with bad version */ -IS_STAT(SU, is_rx_tooshort), /* rx frame too short */ -IS_STAT(LOG, is_rx_wrongbss), /* rx from wrong bssid */ -IS_STAT(LOG, is_rx_dup), /* rx discard due to it's a dup */ -IS_STAT(SU, is_rx_wrongdir), /* rx w/ wrong direction */ -IS_STAT(D, is_rx_mcastecho), /* rx discard due to of mcast echo */ -IS_STAT(SU, is_rx_notassoc), /* rx discard due to sta !assoc */ -IS_STAT(SU, is_rx_noprivacy), /* rx w/ wep but privacy off */ -IS_STAT(SU, is_rx_unencrypted), /* rx w/o wep and privacy on */ -IS_STAT(SU, is_rx_wepfail), /* rx wep processing failed */ -IS_STAT(SU, is_rx_decap), /* rx decapsulation failed */ -IS_STAT(D, is_rx_mgtdiscard), /* rx discard mgt frames */ -IS_STAT(D, is_rx_ctl), /* rx discard ctrl frames */ -IS_STAT(D, is_rx_beacon), /* rx beacon frames */ -IS_STAT(D, is_rx_rstoobig), /* rx rate set truncated */ -IS_STAT(SU, is_rx_elem_missing), /* rx required element missing*/ -IS_STAT(SU, is_rx_elem_toobig), /* rx element too big */ -IS_STAT(SU, is_rx_elem_toosmall), /* rx element too small */ -IS_STAT(LOG, is_rx_elem_unknown), /* rx element unknown */ -IS_STAT(SU, is_rx_badchan), /* rx frame w/ invalid chan */ -IS_STAT(SU, is_rx_chanmismatch), /* rx frame chan mismatch */ -IS_STAT(SU, is_rx_nodealloc), /* rx frame dropped */ -IS_STAT(LOG, is_rx_ssidmismatch), /* rx frame ssid mismatch */ -IS_STAT(SU, is_rx_auth_unsupported), /* rx w/ unsupported auth alg */ -IS_STAT(SU, is_rx_auth_fail), /* rx sta auth failure */ -IS_STAT(SU, is_rx_auth_countermeasures),/* rx auth discard due to CM */ -IS_STAT(SU, is_rx_assoc_bss), /* rx assoc from wrong bssid */ -IS_STAT(SU, is_rx_assoc_notauth), /* rx assoc w/o auth */ -IS_STAT(SU, is_rx_assoc_capmismatch), /* rx assoc w/ cap mismatch */ -IS_STAT(SU, is_rx_assoc_norate), /* rx assoc w/ no rate match */ -IS_STAT(SU, is_rx_assoc_badwpaie), /* rx assoc w/ bad WPA IE */ -IS_STAT(LOG, is_rx_deauth), /* rx deauthentication */ -IS_STAT(LOG, is_rx_disassoc), /* rx disassociation */ -IS_STAT(SU, is_rx_badsubtype), /* rx frame w/ unknown subtype*/ -IS_STAT(SU, is_rx_nobuf), /* rx failed for lack of buf */ -IS_STAT(SU, is_rx_decryptcrc), /* rx decrypt failed on crc */ -IS_STAT(D, is_rx_ahdemo_mgt), /* rx discard ahdemo mgt frame*/ -IS_STAT(SU, is_rx_bad_auth), /* rx bad auth request */ -IS_STAT(SU, is_rx_unauth), /* rx on unauthorized port */ -IS_STAT(SU, is_rx_badkeyid), /* rx w/ incorrect keyid */ -IS_STAT(D, is_rx_ccmpreplay), /* rx seq# violation (CCMP), */ -IS_STAT(D, is_rx_ccmpformat), /* rx format bad (CCMP), */ -IS_STAT(D, is_rx_ccmpmic), /* rx MIC check failed (CCMP), */ -IS_STAT(D, is_rx_tkipreplay), /* rx seq# violation (TKIP), */ -IS_STAT(D, is_rx_tkipformat), /* rx format bad (TKIP), */ -IS_STAT(D, is_rx_tkipmic), /* rx MIC check failed (TKIP), */ -IS_STAT(D, is_rx_tkipicv), /* rx ICV check failed (TKIP), */ -IS_STAT(D, is_rx_badcipher), /* rx failed due to of key type */ -IS_STAT(D, is_rx_nocipherctx), /* rx failed due to key !setup */ -IS_STAT(D, is_rx_acl), /* rx discard due to of acl policy */ -IS_STAT(D, is_rx_ffcnt), /* rx fast frames */ -IS_STAT(SU, is_rx_badathtnl), /* driver key alloc failed */ -IS_STAT(SU, is_tx_nobuf), /* tx failed for lack of buf */ -IS_STAT(SU, is_tx_nonode), /* tx failed for no node */ -IS_STAT(SU, is_tx_unknownmgt), /* tx of unknown mgt frame */ -IS_STAT(SU, is_tx_badcipher), /* tx failed due to of key type */ -IS_STAT(SU, is_tx_nodefkey), /* tx failed due to no defkey */ -IS_STAT(SU, is_tx_noheadroom), /* tx failed due to no space */ -IS_STAT(D, is_tx_ffokcnt), /* tx fast frames sent success */ -IS_STAT(D, is_tx_fferrcnt), /* tx fast frames sent success */ -IS_STAT(D, is_scan_active), /* active scans started */ -IS_STAT(D, is_scan_passive), /* passive scans started */ -IS_STAT(D, is_node_timeout), /* nodes timed out inactivity */ -IS_STAT(D, is_crypto_nomem), /* no memory for crypto ctx */ -IS_STAT(D, is_crypto_tkip), /* tkip crypto done in s/w */ -IS_STAT(D, is_crypto_tkipenmic), /* tkip en-MIC done in s/w */ -IS_STAT(D, is_crypto_tkipdemic), /* tkip de-MIC done in s/w */ -IS_STAT(D, is_crypto_tkipcm), /* tkip counter measures */ -IS_STAT(D, is_crypto_ccmp), /* ccmp crypto done in s/w */ -IS_STAT(D, is_crypto_wep), /* wep crypto done in s/w */ -IS_STAT(D, is_crypto_setkey_cipher), /* cipher rejected key */ -IS_STAT(D, is_crypto_setkey_nokey), /* no key index for setkey */ -IS_STAT(D, is_crypto_delkey), /* driver key delete failed */ -IS_STAT(D, is_crypto_badcipher), /* unknown cipher */ -IS_STAT(D, is_crypto_nocipher), /* cipher not available */ -IS_STAT(D, is_crypto_attachfail), /* cipher attach failed */ -IS_STAT(D, is_crypto_swfallback), /* cipher fallback to s/w */ -IS_STAT(D, is_crypto_keyfail), /* driver key alloc failed */ -IS_STAT(D, is_crypto_enmicfail), /* en-MIC failed */ -IS_STAT(SU, is_ibss_capmismatch), /* merge failed-cap mismatch */ -IS_STAT(SU, is_ibss_norate), /* merge failed-rate mismatch */ -IS_STAT(D, is_ps_unassoc), /* ps-poll for unassoc. sta */ -IS_STAT(D, is_ps_badaid), /* ps-poll w/ incorrect aid */ -IS_STAT(D, is_ps_qempty), /* ps-poll w/ nothing to send */ - -/* Atheros statistics */ -AS_STAT(D, ast_watchdog), /* device reset by watchdog */ -AS_STAT(D, ast_hardware), /* fatal hardware error interrupts */ -AS_STAT(D, ast_bmiss), /* beacon miss interrupts */ -AS_STAT(D, ast_rxorn), /* rx overrun interrupts */ -AS_STAT(D, ast_rxeol), /* rx eol interrupts */ -AS_STAT(D, ast_txurn), /* tx underrun interrupts */ -AS_STAT(D, ast_mib), /* mib interrupts */ -AS_STAT(D, ast_tx_packets), /* packet sent on the interface */ -AS_STAT(D, ast_tx_mgmt), /* management frames transmitted */ -AS_STAT(LOG, ast_tx_discard), /* frames discarded prior to assoc */ -AS_STAT(SU, ast_tx_invalid), /* frames discarded due to is device gone */ -AS_STAT(SU, ast_tx_qstop), /* tx queue stopped because it's full */ -AS_STAT(SU, ast_tx_encap), /* tx encapsulation failed */ -AS_STAT(SU, ast_tx_nonode), /* tx failed due to of no node */ -AS_STAT(SU, ast_tx_nobuf), /* tx failed due to of no tx buffer (data), */ -AS_STAT(SU, ast_tx_nobufmgt), /* tx failed due to of no tx buffer (mgmt),*/ -AS_STAT(LOG, ast_tx_xretries), /* tx failed due to of too many retries */ -AS_STAT(SU, ast_tx_fifoerr), /* tx failed due to of FIFO underrun */ -AS_STAT(SU, ast_tx_filtered), /* tx failed due to xmit filtered */ -AS_STAT(LOG, ast_tx_shortretry), /* tx on-chip retries (short), */ -AS_STAT(LOG, ast_tx_longretry), /* tx on-chip retries (long), */ -AS_STAT(SU, ast_tx_badrate), /* tx failed due to of bogus xmit rate */ -AS_STAT(D, ast_tx_noack), /* tx frames with no ack marked */ -AS_STAT(D, ast_tx_rts), /* tx frames with rts enabled */ -AS_STAT(D, ast_tx_cts), /* tx frames with cts enabled */ -AS_STAT(D, ast_tx_shortpre), /* tx frames with short preamble */ -AS_STAT(LOG, ast_tx_altrate), /* tx frames with alternate rate */ -AS_STAT(D, ast_tx_protect), /* tx frames with protection */ -AS_STAT(SU, ast_rx_orn), /* rx failed due to of desc overrun */ -AS_STAT(LOG, ast_rx_crcerr), /* rx failed due to of bad CRC */ -AS_STAT(SU, ast_rx_fifoerr), /* rx failed due to of FIFO overrun */ -AS_STAT(SU, ast_rx_badcrypt), /* rx failed due to of decryption */ -AS_STAT(SU, ast_rx_badmic), /* rx failed due to of MIC failure */ -AS_STAT(LOG, ast_rx_phyerr), /* rx PHY error summary count */ -AS_STAT(SU, ast_rx_tooshort), /* rx discarded due to frame too short */ -AS_STAT(SU, ast_rx_toobig), /* rx discarded due to frame too large */ -AS_STAT(SU, ast_rx_nobuf), /* rx setup failed due to of no skbuff */ -AS_STAT(D, ast_rx_packets), /* packet recv on the interface */ -AS_STAT(D, ast_rx_mgt), /* management frames received */ -AS_STAT(D, ast_rx_ctl), /* control frames received */ -AS_STAT(D, ast_be_xmit), /* beacons transmitted */ -AS_STAT(SU, ast_be_nobuf), /* no skbuff available for beacon */ -AS_STAT(D, ast_per_cal), /* periodic calibration calls */ -AS_STAT(D, ast_per_calfail), /* periodic calibration failed */ -AS_STAT(D, ast_per_rfgain), /* periodic calibration rfgain reset */ -AS_STAT(D, ast_rate_calls), /* rate control checks */ -AS_STAT(D, ast_rate_raise), /* rate control raised xmit rate */ -AS_STAT(D, ast_rate_drop), /* rate control dropped xmit rate */ -AS_STAT(D, ast_ant_defswitch), /* rx/default antenna switches */ -AS_STAT(D, ast_ant_txswitch) /* tx antenna switches */ + /* Special statistics */ + SS_STAT(LOG, node_octets), /* rx and tx data count (bytes) */ + SS_STAT(LOG, node_rssi), /* received RSSI of the node */ + SS_STAT(LOG, node_tx_rate), /* used tx rate to the node */ + SS_STAT(LOG, ath_nodes), /* the number of associated nodes */ + SS_STAT(D, ns_rx_beacons), /* rx beacon frames */ + SS_STAT(LOG, ast_ant_rx), /* rx frames with antenna */ + SS_STAT(LOG, ast_ant_tx), /* tx frames with antenna */ + + /* Node statistics */ + NS_STAT(LOG, ns_rx_data), /* rx data frames */ + NS_STAT(LOG, ns_rx_mgmt), /* rx management frames */ + NS_STAT(LOG, ns_rx_ctrl), /* rx control frames */ + NS_STAT(D, ns_rx_ucast), /* rx unicast frames */ + NS_STAT(D, ns_rx_mcast), /* rx multi/broadcast frames */ + NS_STAT(D, ns_rx_proberesp), /* rx probe response frames */ + NS_STAT(LOG, ns_rx_dup), /* rx discard because it's a dup */ + NS_STAT(SU, ns_rx_noprivacy), /* rx w/ wep but privacy off */ + NS_STAT(SU, ns_rx_wepfail), /* rx wep processing failed */ + NS_STAT(SU, ns_rx_demicfail), /* rx demic failed */ + NS_STAT(SU, ns_rx_decap), /* rx decapsulation failed */ + NS_STAT(SU, ns_rx_defrag), /* rx defragmentation failed */ + NS_STAT(D, ns_rx_disassoc), /* rx disassociation */ + NS_STAT(D, ns_rx_deauth), /* rx deauthentication */ + NS_STAT(SU, ns_rx_decryptcrc), /* rx decrypt failed on crc */ + NS_STAT(SU, ns_rx_unauth), /* rx on unauthorized port */ + NS_STAT(SU, ns_rx_unencrypted), /* rx unecrypted w/ privacy */ + NS_STAT(LOG, ns_tx_data), /* tx data frames */ + NS_STAT(LOG, ns_tx_mgmt), /* tx management frames */ + NS_STAT(D, ns_tx_ucast), /* tx unicast frames */ + NS_STAT(D, ns_tx_mcast), /* tx multi/broadcast frames */ + NS_STAT(D, ns_tx_probereq), /* tx probe request frames */ + NS_STAT(D, ns_tx_uapsd), /* tx on uapsd queue */ + NS_STAT(SU, ns_tx_novlantag), /* tx discard due to no tag */ + NS_STAT(SU, ns_tx_vlanmismatch), /* tx discard due to of bad tag */ + NS_STAT(D, ns_tx_eosplost), /* uapsd EOSP retried out */ + NS_STAT(D, ns_ps_discard), /* ps discard due to of age */ + NS_STAT(D, ns_uapsd_triggers), /* uapsd triggers */ + NS_STAT(LOG, ns_tx_assoc), /* [re]associations */ + NS_STAT(LOG, ns_tx_auth), /* [re]authentications */ + NS_STAT(D, ns_tx_deauth), /* deauthentications */ + NS_STAT(D, ns_tx_disassoc), /* disassociations */ + NS_STAT(D, ns_psq_drops), /* power save queue drops */ + + /* Iface statistics */ + IS_STAT(SU, is_rx_badversion), /* rx frame with bad version */ + IS_STAT(SU, is_rx_tooshort), /* rx frame too short */ + IS_STAT(LOG, is_rx_wrongbss), /* rx from wrong bssid */ + IS_STAT(LOG, is_rx_dup), /* rx discard due to it's a dup */ + IS_STAT(SU, is_rx_wrongdir), /* rx w/ wrong direction */ + IS_STAT(D, is_rx_mcastecho), /* rx discard due to of mcast echo */ + IS_STAT(SU, is_rx_notassoc), /* rx discard due to sta !assoc */ + IS_STAT(SU, is_rx_noprivacy), /* rx w/ wep but privacy off */ + IS_STAT(SU, is_rx_unencrypted), /* rx w/o wep and privacy on */ + IS_STAT(SU, is_rx_wepfail), /* rx wep processing failed */ + IS_STAT(SU, is_rx_decap), /* rx decapsulation failed */ + IS_STAT(D, is_rx_mgtdiscard), /* rx discard mgt frames */ + IS_STAT(D, is_rx_ctl), /* rx discard ctrl frames */ + IS_STAT(D, is_rx_beacon), /* rx beacon frames */ + IS_STAT(D, is_rx_rstoobig), /* rx rate set truncated */ + IS_STAT(SU, is_rx_elem_missing), /* rx required element missing*/ + IS_STAT(SU, is_rx_elem_toobig), /* rx element too big */ + IS_STAT(SU, is_rx_elem_toosmall), /* rx element too small */ + IS_STAT(LOG, is_rx_elem_unknown), /* rx element unknown */ + IS_STAT(SU, is_rx_badchan), /* rx frame w/ invalid chan */ + IS_STAT(SU, is_rx_chanmismatch), /* rx frame chan mismatch */ + IS_STAT(SU, is_rx_nodealloc), /* rx frame dropped */ + IS_STAT(LOG, is_rx_ssidmismatch), /* rx frame ssid mismatch */ + IS_STAT(SU, is_rx_auth_unsupported), /* rx w/ unsupported auth alg */ + IS_STAT(SU, is_rx_auth_fail), /* rx sta auth failure */ + IS_STAT(SU, is_rx_auth_countermeasures), /* rx auth discard due to CM */ + IS_STAT(SU, is_rx_assoc_bss), /* rx assoc from wrong bssid */ + IS_STAT(SU, is_rx_assoc_notauth), /* rx assoc w/o auth */ + IS_STAT(SU, is_rx_assoc_capmismatch), /* rx assoc w/ cap mismatch */ + IS_STAT(SU, is_rx_assoc_norate), /* rx assoc w/ no rate match */ + IS_STAT(SU, is_rx_assoc_badwpaie), /* rx assoc w/ bad WPA IE */ + IS_STAT(LOG, is_rx_deauth), /* rx deauthentication */ + IS_STAT(LOG, is_rx_disassoc), /* rx disassociation */ + IS_STAT(SU, is_rx_badsubtype), /* rx frame w/ unknown subtype*/ + IS_STAT(SU, is_rx_nobuf), /* rx failed for lack of buf */ + IS_STAT(SU, is_rx_decryptcrc), /* rx decrypt failed on crc */ + IS_STAT(D, is_rx_ahdemo_mgt), /* rx discard ahdemo mgt frame*/ + IS_STAT(SU, is_rx_bad_auth), /* rx bad auth request */ + IS_STAT(SU, is_rx_unauth), /* rx on unauthorized port */ + IS_STAT(SU, is_rx_badkeyid), /* rx w/ incorrect keyid */ + IS_STAT(D, is_rx_ccmpreplay), /* rx seq# violation (CCMP), */ + IS_STAT(D, is_rx_ccmpformat), /* rx format bad (CCMP), */ + IS_STAT(D, is_rx_ccmpmic), /* rx MIC check failed (CCMP), */ + IS_STAT(D, is_rx_tkipreplay), /* rx seq# violation (TKIP), */ + IS_STAT(D, is_rx_tkipformat), /* rx format bad (TKIP), */ + IS_STAT(D, is_rx_tkipmic), /* rx MIC check failed (TKIP), */ + IS_STAT(D, is_rx_tkipicv), /* rx ICV check failed (TKIP), */ + IS_STAT(D, is_rx_badcipher), /* rx failed due to of key type */ + IS_STAT(D, is_rx_nocipherctx), /* rx failed due to key !setup */ + IS_STAT(D, is_rx_acl), /* rx discard due to of acl policy */ + IS_STAT(D, is_rx_ffcnt), /* rx fast frames */ + IS_STAT(SU, is_rx_badathtnl), /* driver key alloc failed */ + IS_STAT(SU, is_tx_nobuf), /* tx failed for lack of buf */ + IS_STAT(SU, is_tx_nonode), /* tx failed for no node */ + IS_STAT(SU, is_tx_unknownmgt), /* tx of unknown mgt frame */ + IS_STAT(SU, is_tx_badcipher), /* tx failed due to of key type */ + IS_STAT(SU, is_tx_nodefkey), /* tx failed due to no defkey */ + IS_STAT(SU, is_tx_noheadroom), /* tx failed due to no space */ + IS_STAT(D, is_tx_ffokcnt), /* tx fast frames sent success */ + IS_STAT(D, is_tx_fferrcnt), /* tx fast frames sent success */ + IS_STAT(D, is_scan_active), /* active scans started */ + IS_STAT(D, is_scan_passive), /* passive scans started */ + IS_STAT(D, is_node_timeout), /* nodes timed out inactivity */ + IS_STAT(D, is_crypto_nomem), /* no memory for crypto ctx */ + IS_STAT(D, is_crypto_tkip), /* tkip crypto done in s/w */ + IS_STAT(D, is_crypto_tkipenmic), /* tkip en-MIC done in s/w */ + IS_STAT(D, is_crypto_tkipdemic), /* tkip de-MIC done in s/w */ + IS_STAT(D, is_crypto_tkipcm), /* tkip counter measures */ + IS_STAT(D, is_crypto_ccmp), /* ccmp crypto done in s/w */ + IS_STAT(D, is_crypto_wep), /* wep crypto done in s/w */ + IS_STAT(D, is_crypto_setkey_cipher), /* cipher rejected key */ + IS_STAT(D, is_crypto_setkey_nokey), /* no key index for setkey */ + IS_STAT(D, is_crypto_delkey), /* driver key delete failed */ + IS_STAT(D, is_crypto_badcipher), /* unknown cipher */ + IS_STAT(D, is_crypto_nocipher), /* cipher not available */ + IS_STAT(D, is_crypto_attachfail), /* cipher attach failed */ + IS_STAT(D, is_crypto_swfallback), /* cipher fallback to s/w */ + IS_STAT(D, is_crypto_keyfail), /* driver key alloc failed */ + IS_STAT(D, is_crypto_enmicfail), /* en-MIC failed */ + IS_STAT(SU, is_ibss_capmismatch), /* merge failed-cap mismatch */ + IS_STAT(SU, is_ibss_norate), /* merge failed-rate mismatch */ + IS_STAT(D, is_ps_unassoc), /* ps-poll for unassoc. sta */ + IS_STAT(D, is_ps_badaid), /* ps-poll w/ incorrect aid */ + IS_STAT(D, is_ps_qempty), /* ps-poll w/ nothing to send */ + + /* Atheros statistics */ + AS_STAT(D, ast_watchdog), /* device reset by watchdog */ + AS_STAT(D, ast_hardware), /* fatal hardware error interrupts */ + AS_STAT(D, ast_bmiss), /* beacon miss interrupts */ + AS_STAT(D, ast_rxorn), /* rx overrun interrupts */ + AS_STAT(D, ast_rxeol), /* rx eol interrupts */ + AS_STAT(D, ast_txurn), /* tx underrun interrupts */ + AS_STAT(D, ast_mib), /* mib interrupts */ + AS_STAT(D, ast_tx_packets), /* packet sent on the interface */ + AS_STAT(D, ast_tx_mgmt), /* management frames transmitted */ + AS_STAT(LOG, ast_tx_discard), /* frames discarded prior to assoc */ + AS_STAT(SU, ast_tx_invalid), /* frames discarded due to is device gone */ + AS_STAT(SU, ast_tx_qstop), /* tx queue stopped because it's full */ + AS_STAT(SU, ast_tx_encap), /* tx encapsulation failed */ + AS_STAT(SU, ast_tx_nonode), /* tx failed due to of no node */ + AS_STAT(SU, ast_tx_nobuf), /* tx failed due to of no tx buffer (data), */ + AS_STAT(SU, ast_tx_nobufmgt), /* tx failed due to of no tx buffer (mgmt),*/ + AS_STAT(LOG, ast_tx_xretries), /* tx failed due to of too many retries */ + AS_STAT(SU, ast_tx_fifoerr), /* tx failed due to of FIFO underrun */ + AS_STAT(SU, ast_tx_filtered), /* tx failed due to xmit filtered */ + AS_STAT(LOG, ast_tx_shortretry), /* tx on-chip retries (short), */ + AS_STAT(LOG, ast_tx_longretry), /* tx on-chip retries (long), */ + AS_STAT(SU, ast_tx_badrate), /* tx failed due to of bogus xmit rate */ + AS_STAT(D, ast_tx_noack), /* tx frames with no ack marked */ + AS_STAT(D, ast_tx_rts), /* tx frames with rts enabled */ + AS_STAT(D, ast_tx_cts), /* tx frames with cts enabled */ + AS_STAT(D, ast_tx_shortpre), /* tx frames with short preamble */ + AS_STAT(LOG, ast_tx_altrate), /* tx frames with alternate rate */ + AS_STAT(D, ast_tx_protect), /* tx frames with protection */ + AS_STAT(SU, ast_rx_orn), /* rx failed due to of desc overrun */ + AS_STAT(LOG, ast_rx_crcerr), /* rx failed due to of bad CRC */ + AS_STAT(SU, ast_rx_fifoerr), /* rx failed due to of FIFO overrun */ + AS_STAT(SU, ast_rx_badcrypt), /* rx failed due to of decryption */ + AS_STAT(SU, ast_rx_badmic), /* rx failed due to of MIC failure */ + AS_STAT(LOG, ast_rx_phyerr), /* rx PHY error summary count */ + AS_STAT(SU, ast_rx_tooshort), /* rx discarded due to frame too short */ + AS_STAT(SU, ast_rx_toobig), /* rx discarded due to frame too large */ + AS_STAT(SU, ast_rx_nobuf), /* rx setup failed due to of no skbuff */ + AS_STAT(D, ast_rx_packets), /* packet recv on the interface */ + AS_STAT(D, ast_rx_mgt), /* management frames received */ + AS_STAT(D, ast_rx_ctl), /* control frames received */ + AS_STAT(D, ast_be_xmit), /* beacons transmitted */ + AS_STAT(SU, ast_be_nobuf), /* no skbuff available for beacon */ + AS_STAT(D, ast_per_cal), /* periodic calibration calls */ + AS_STAT(D, ast_per_calfail), /* periodic calibration failed */ + AS_STAT(D, ast_per_rfgain), /* periodic calibration rfgain reset */ + AS_STAT(D, ast_rate_calls), /* rate control checks */ + AS_STAT(D, ast_rate_raise), /* rate control raised xmit rate */ + AS_STAT(D, ast_rate_drop), /* rate control dropped xmit rate */ + AS_STAT(D, ast_ant_defswitch), /* rx/default antenna switches */ + AS_STAT(D, ast_ant_txswitch) /* tx antenna switches */ }; /* Bounds between SS, NS, IS and AS stats in stats array */ @@ -344,626 +342,551 @@ static int bounds[4]; static uint32_t watch_items[WL_LEN]; static uint32_t misc_items[WL_LEN]; - -static const char *config_keys[] = -{ - "Interface", - "IgnoreSelected", - "Source", - "WatchAdd", - "WatchRemove", - "WatchSet", - "MiscAdd", - "MiscRemove", - "MiscSet" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"Interface", "IgnoreSelected", "Source", + "WatchAdd", "WatchRemove", "WatchSet", + "MiscAdd", "MiscRemove", "MiscSet"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static ignorelist_t *ignorelist = NULL; static int use_sysfs = 1; static int init_state = 0; -static inline int item_watched(int i) -{ - assert (i >= 0); - assert ((size_t) i < (STATIC_ARRAY_SIZE (watch_items) * 32)); - return watch_items[i / 32] & FLAG (i); +static inline int item_watched(int i) { + assert(i >= 0); + assert((size_t)i < (STATIC_ARRAY_SIZE(watch_items) * 32)); + return watch_items[i / 32] & FLAG(i); } -static inline int item_summed(int i) -{ - assert (i >= 0); - assert ((size_t) i < (STATIC_ARRAY_SIZE (misc_items) * 32)); - return misc_items[i / 32] & FLAG (i); +static inline int item_summed(int i) { + assert(i >= 0); + assert((size_t)i < (STATIC_ARRAY_SIZE(misc_items) * 32)); + return misc_items[i / 32] & FLAG(i); } -static inline void watchlist_add (uint32_t *wl, int item) -{ - assert (item >= 0); - assert (item < WL_LEN * 32); - wl[item / 32] |= FLAG (item); +static inline void watchlist_add(uint32_t *wl, int item) { + assert(item >= 0); + assert(item < WL_LEN * 32); + wl[item / 32] |= FLAG(item); } -static inline void watchlist_remove (uint32_t *wl, int item) -{ - assert (item >= 0); - assert (item < WL_LEN * 32); - wl[item / 32] &= ~FLAG (item); +static inline void watchlist_remove(uint32_t *wl, int item) { + assert(item >= 0); + assert(item < WL_LEN * 32); + wl[item / 32] &= ~FLAG(item); } -static inline void watchlist_set (uint32_t *wl, uint32_t val) -{ - for (int i = 0; i < WL_LEN; i++) - wl[i] = val; +static inline void watchlist_set(uint32_t *wl, uint32_t val) { + for (int i = 0; i < WL_LEN; i++) + wl[i] = val; } /* This is horribly inefficient, but it is called only during configuration */ -static int watchitem_find (const char *name) -{ - int max = STATIC_ARRAY_SIZE (specs); +static int watchitem_find(const char *name) { + int max = STATIC_ARRAY_SIZE(specs); - for (int i = 0; i < max; i++) - if (strcasecmp (name, specs[i].name) == 0) - return i; + for (int i = 0; i < max; i++) + if (strcasecmp(name, specs[i].name) == 0) + return i; - return -1; + return -1; } - /* Collectd hooks */ /* We need init function called before madwifi_config */ -static int madwifi_real_init (void) -{ - size_t max = STATIC_ARRAY_SIZE (specs); +static int madwifi_real_init(void) { + size_t max = STATIC_ARRAY_SIZE(specs); - for (size_t i = 0; i < STATIC_ARRAY_SIZE (bounds); i++) - bounds[i] = 0; + for (size_t i = 0; i < STATIC_ARRAY_SIZE(bounds); i++) + bounds[i] = 0; - watchlist_set(watch_items, 0); - watchlist_set(misc_items, 0); + watchlist_set(watch_items, 0); + watchlist_set(misc_items, 0); - for (size_t i = 0; i < max; i++) - { - bounds[specs[i].flags & SRC_MASK] = i; + for (size_t i = 0; i < max; i++) { + bounds[specs[i].flags & SRC_MASK] = i; - if (specs[i].flags & LOG) - watch_items[i / 32] |= FLAG (i); + if (specs[i].flags & LOG) + watch_items[i / 32] |= FLAG(i); - if (specs[i].flags & SU) - misc_items[i / 32] |= FLAG (i); - } + if (specs[i].flags & SU) + misc_items[i / 32] |= FLAG(i); + } - for (size_t i = 0; i < STATIC_ARRAY_SIZE (bounds); i++) - bounds[i]++; + for (size_t i = 0; i < STATIC_ARRAY_SIZE(bounds); i++) + bounds[i]++; - return (0); + return (0); } -static int madwifi_config (const char *key, const char *value) -{ - if (init_state != 1) - madwifi_real_init(); - init_state = 1; - - if (ignorelist == NULL) - ignorelist = ignorelist_create (/* invert = */ 1); - - if (strcasecmp (key, "Interface") == 0) - ignorelist_add (ignorelist, value); - - else if (strcasecmp (key, "IgnoreSelected") == 0) - ignorelist_set_invert (ignorelist, IS_TRUE (value) ? 0 : 1); - - else if (strcasecmp (key, "Source") == 0) - { - if (strcasecmp (value, "ProcFS") == 0) - use_sysfs = 0; - else if (strcasecmp (value, "SysFS") == 0) - use_sysfs = 1; - else - { - ERROR ("madwifi plugin: The argument of the `Source' " - "option must either be `SysFS' or " - "`ProcFS'."); - return -1; - } - } - - else if (strcasecmp (key, "WatchSet") == 0) - { - if (strcasecmp (value, "All") == 0) - watchlist_set (watch_items, 0xFFFFFFFF); - else if (strcasecmp (value, "None") == 0) - watchlist_set (watch_items, 0); - else return -1; - } - - else if (strcasecmp (key, "WatchAdd") == 0) - { - int id = watchitem_find (value); - - if (id < 0) - return (-1); - else - watchlist_add (watch_items, id); - } - - else if (strcasecmp (key, "WatchRemove") == 0) - { - int id = watchitem_find (value); - - if (id < 0) - return (-1); - else - watchlist_remove (watch_items, id); - } - - else if (strcasecmp (key, "MiscSet") == 0) - { - if (strcasecmp (value, "All") == 0) - watchlist_set (misc_items, 0xFFFFFFFF); - else if (strcasecmp (value, "None") == 0) - watchlist_set (misc_items, 0); - else return -1; - } - - else if (strcasecmp (key, "MiscAdd") == 0) - { - int id = watchitem_find (value); - - if (id < 0) - return (-1); - else - watchlist_add (misc_items, id); - } - - else if (strcasecmp (key, "MiscRemove") == 0) - { - int id = watchitem_find (value); - - if (id < 0) - return (-1); - else - watchlist_remove (misc_items, id); - } - - else - return (-1); - - return (0); +static int madwifi_config(const char *key, const char *value) { + if (init_state != 1) + madwifi_real_init(); + init_state = 1; + + if (ignorelist == NULL) + ignorelist = ignorelist_create(/* invert = */ 1); + + if (strcasecmp(key, "Interface") == 0) + ignorelist_add(ignorelist, value); + + else if (strcasecmp(key, "IgnoreSelected") == 0) + ignorelist_set_invert(ignorelist, IS_TRUE(value) ? 0 : 1); + + else if (strcasecmp(key, "Source") == 0) { + if (strcasecmp(value, "ProcFS") == 0) + use_sysfs = 0; + else if (strcasecmp(value, "SysFS") == 0) + use_sysfs = 1; + else { + ERROR("madwifi plugin: The argument of the `Source' " + "option must either be `SysFS' or " + "`ProcFS'."); + return -1; + } + } + + else if (strcasecmp(key, "WatchSet") == 0) { + if (strcasecmp(value, "All") == 0) + watchlist_set(watch_items, 0xFFFFFFFF); + else if (strcasecmp(value, "None") == 0) + watchlist_set(watch_items, 0); + else + return -1; + } + + else if (strcasecmp(key, "WatchAdd") == 0) { + int id = watchitem_find(value); + + if (id < 0) + return (-1); + else + watchlist_add(watch_items, id); + } + + else if (strcasecmp(key, "WatchRemove") == 0) { + int id = watchitem_find(value); + + if (id < 0) + return (-1); + else + watchlist_remove(watch_items, id); + } + + else if (strcasecmp(key, "MiscSet") == 0) { + if (strcasecmp(value, "All") == 0) + watchlist_set(misc_items, 0xFFFFFFFF); + else if (strcasecmp(value, "None") == 0) + watchlist_set(misc_items, 0); + else + return -1; + } + + else if (strcasecmp(key, "MiscAdd") == 0) { + int id = watchitem_find(value); + + if (id < 0) + return (-1); + else + watchlist_add(misc_items, id); + } + + else if (strcasecmp(key, "MiscRemove") == 0) { + int id = watchitem_find(value); + + if (id < 0) + return (-1); + else + watchlist_remove(misc_items, id); + } + + else + return (-1); + + return (0); } +static void submit(const char *dev, const char *type, const char *ti1, + const char *ti2, value_t *val, size_t len) { + value_list_t vl = VALUE_LIST_INIT; -static void submit (const char *dev, const char *type, const char *ti1, - const char *ti2, value_t *val, size_t len) -{ - value_list_t vl = VALUE_LIST_INIT; - - vl.values = val; - vl.values_len = len; - sstrncpy (vl.plugin, "madwifi", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); + vl.values = val; + vl.values_len = len; + sstrncpy(vl.plugin, "madwifi", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, dev, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); - if ((ti1 != NULL) && (ti2 != NULL)) - ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%s-%s", ti1, ti2); - else if ((ti1 != NULL) && (ti2 == NULL)) - sstrncpy (vl.type_instance, ti1, sizeof (vl.type_instance)); + if ((ti1 != NULL) && (ti2 != NULL)) + ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s-%s", ti1, ti2); + else if ((ti1 != NULL) && (ti2 == NULL)) + sstrncpy(vl.type_instance, ti1, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static void submit_derive (const char *dev, const char *type, const char *ti1, - const char *ti2, derive_t value) -{ - submit (dev, type, ti1, ti2, &(value_t) { .derive = value }, 1); +static void submit_derive(const char *dev, const char *type, const char *ti1, + const char *ti2, derive_t value) { + submit(dev, type, ti1, ti2, &(value_t){.derive = value}, 1); } -static void submit_derive2 (const char *dev, const char *type, const char *ti1, - const char *ti2, derive_t val1, derive_t val2) -{ - value_t values[] = { - { .derive = val1 }, - { .derive = val2 }, - }; +static void submit_derive2(const char *dev, const char *type, const char *ti1, + const char *ti2, derive_t val1, derive_t val2) { + value_t values[] = { + {.derive = val1}, {.derive = val2}, + }; - submit (dev, type, ti1, ti2, values, STATIC_ARRAY_SIZE (values)); + submit(dev, type, ti1, ti2, values, STATIC_ARRAY_SIZE(values)); } -static void submit_gauge (const char *dev, const char *type, const char *ti1, - const char *ti2, gauge_t value) -{ - submit (dev, type, ti1, ti2, &(value_t) { .gauge = value }, 1); +static void submit_gauge(const char *dev, const char *type, const char *ti1, + const char *ti2, gauge_t value) { + submit(dev, type, ti1, ti2, &(value_t){.gauge = value}, 1); } -static void submit_antx (const char *dev, const char *name, - u_int32_t *vals, int vals_num) -{ - char ti2[16]; +static void submit_antx(const char *dev, const char *name, u_int32_t *vals, + int vals_num) { + char ti2[16]; - for (int i = 0; i < vals_num; i++) - { - if (vals[i] == 0) - continue; + for (int i = 0; i < vals_num; i++) { + if (vals[i] == 0) + continue; - ssnprintf (ti2, sizeof (ti2), "%i", i); - submit_derive (dev, "ath_stat", name, ti2, - (derive_t) vals[i]); - } + ssnprintf(ti2, sizeof(ti2), "%i", i); + submit_derive(dev, "ath_stat", name, ti2, (derive_t)vals[i]); + } } -static inline void -macaddr_to_str (char *buf, size_t bufsize, const uint8_t mac[IEEE80211_ADDR_LEN]) -{ - ssnprintf (buf, bufsize, "%02x:%02x:%02x:%02x:%02x:%02x", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); +static inline void macaddr_to_str(char *buf, size_t bufsize, + const uint8_t mac[IEEE80211_ADDR_LEN]) { + ssnprintf(buf, bufsize, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], + mac[2], mac[3], mac[4], mac[5]); } -static void -process_stat_struct (int which, const void *ptr, const char *dev, const char *mac, - const char *type_name, const char *misc_name) -{ - uint32_t misc = 0; +static void process_stat_struct(int which, const void *ptr, const char *dev, + const char *mac, const char *type_name, + const char *misc_name) { + uint32_t misc = 0; - assert (which >= 1); - assert (((size_t) which) < STATIC_ARRAY_SIZE (bounds)); + assert(which >= 1); + assert(((size_t)which) < STATIC_ARRAY_SIZE(bounds)); - for (int i = bounds[which - 1]; i < bounds[which]; i++) - { - uint32_t val = *(uint32_t *)(((char *) ptr) + specs[i].offset) ; + for (int i = bounds[which - 1]; i < bounds[which]; i++) { + uint32_t val = *(uint32_t *)(((char *)ptr) + specs[i].offset); - if (item_watched (i) && (val != 0)) - submit_derive (dev, type_name, specs[i].name, mac, val); + if (item_watched(i) && (val != 0)) + submit_derive(dev, type_name, specs[i].name, mac, val); - if (item_summed (i)) - misc += val; - } - - if (misc != 0) - submit_derive (dev, type_name, misc_name, mac, misc); + if (item_summed(i)) + misc += val; + } + if (misc != 0) + submit_derive(dev, type_name, misc_name, mac, misc); } -static int -process_athstats (int sk, const char *dev) -{ - struct ifreq ifr; - struct ath_stats stats; - int status; - - sstrncpy (ifr.ifr_name, dev, sizeof (ifr.ifr_name)); - ifr.ifr_data = (void *) &stats; - status = ioctl (sk, SIOCGATHSTATS, &ifr); - if (status < 0) - { - /* Silent, because not all interfaces support all ioctls. */ - DEBUG ("madwifi plugin: Sending IO-control " - "SIOCGATHSTATS to device %s " - "failed with status %i.", - dev, status); - return (status); - } - - /* These stats are handled as a special case, because they are - eight values each */ - - if (item_watched (STAT_AST_ANT_RX)) - submit_antx (dev, "ast_ant_rx", stats.ast_ant_rx, - STATIC_ARRAY_SIZE (stats.ast_ant_rx)); - - if (item_watched (STAT_AST_ANT_TX)) - submit_antx (dev, "ast_ant_tx", stats.ast_ant_tx, - STATIC_ARRAY_SIZE (stats.ast_ant_tx)); - - /* All other ath statistics */ - process_stat_struct (ATH_STAT, &stats, dev, NULL, "ath_stat", "ast_misc"); - return (0); +static int process_athstats(int sk, const char *dev) { + struct ifreq ifr; + struct ath_stats stats; + int status; + + sstrncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); + ifr.ifr_data = (void *)&stats; + status = ioctl(sk, SIOCGATHSTATS, &ifr); + if (status < 0) { + /* Silent, because not all interfaces support all ioctls. */ + DEBUG("madwifi plugin: Sending IO-control " + "SIOCGATHSTATS to device %s " + "failed with status %i.", + dev, status); + return (status); + } + + /* These stats are handled as a special case, because they are + eight values each */ + + if (item_watched(STAT_AST_ANT_RX)) + submit_antx(dev, "ast_ant_rx", stats.ast_ant_rx, + STATIC_ARRAY_SIZE(stats.ast_ant_rx)); + + if (item_watched(STAT_AST_ANT_TX)) + submit_antx(dev, "ast_ant_tx", stats.ast_ant_tx, + STATIC_ARRAY_SIZE(stats.ast_ant_tx)); + + /* All other ath statistics */ + process_stat_struct(ATH_STAT, &stats, dev, NULL, "ath_stat", "ast_misc"); + return (0); } -static int -process_80211stats (int sk, const char *dev) -{ - struct ifreq ifr; - struct ieee80211_stats stats; - int status; - - sstrncpy (ifr.ifr_name, dev, sizeof (ifr.ifr_name)); - ifr.ifr_data = (void *) &stats; - status = ioctl(sk, SIOCG80211STATS, &ifr); - if (status < 0) - { - /* Silent, because not all interfaces support all ioctls. */ - DEBUG ("madwifi plugin: Sending IO-control " - "SIOCG80211STATS to device %s " - "failed with status %i.", - dev, status); - return (status); - } - - process_stat_struct (IFA_STAT, &stats, dev, NULL, "ath_stat", "is_misc"); - return (0); +static int process_80211stats(int sk, const char *dev) { + struct ifreq ifr; + struct ieee80211_stats stats; + int status; + + sstrncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); + ifr.ifr_data = (void *)&stats; + status = ioctl(sk, SIOCG80211STATS, &ifr); + if (status < 0) { + /* Silent, because not all interfaces support all ioctls. */ + DEBUG("madwifi plugin: Sending IO-control " + "SIOCG80211STATS to device %s " + "failed with status %i.", + dev, status); + return (status); + } + + process_stat_struct(IFA_STAT, &stats, dev, NULL, "ath_stat", "is_misc"); + return (0); } - -static int -process_station (int sk, const char *dev, struct ieee80211req_sta_info *si) -{ - static char mac[DATA_MAX_NAME_LEN]; - struct ieee80211req_sta_stats stats; - const struct ieee80211_nodestats *ns = &stats.is_stats; - int status; - - macaddr_to_str (mac, sizeof (mac), si->isi_macaddr); - - if (item_watched (STAT_NODE_TX_RATE)) - submit_gauge (dev, "node_tx_rate", mac, NULL, - (si->isi_rates[si->isi_txrate] & IEEE80211_RATE_VAL) / 2); - - if (item_watched (STAT_NODE_RSSI)) - submit_gauge (dev, "node_rssi", mac, NULL, si->isi_rssi); - - struct iwreq iwr = { - .u.data.pointer = (void *) &stats, - .u.data.length = sizeof (stats) - }; - sstrncpy(iwr.ifr_name, dev, sizeof (iwr.ifr_name)); - - memcpy(stats.is_u.macaddr, si->isi_macaddr, IEEE80211_ADDR_LEN); - status = ioctl(sk, IEEE80211_IOCTL_STA_STATS, &iwr); - if (status < 0) - { - /* Silent, because not all interfaces support all ioctls. */ - DEBUG ("madwifi plugin: Sending IO-control " - "IEEE80211_IOCTL_STA_STATS to device %s " - "failed with status %i.", - dev, status); - return (status); - } - - /* These two stats are handled as a special case as they are - a pair of 64bit values */ - if (item_watched (STAT_NODE_OCTETS)) - submit_derive2 (dev, "node_octets", mac, NULL, - ns->ns_rx_bytes, ns->ns_tx_bytes); - - /* This stat is handled as a special case, because it is stored - as uin64_t, but we will ignore upper half */ - if (item_watched (STAT_NS_RX_BEACONS)) - submit_derive (dev, "node_stat", "ns_rx_beacons", mac, - (ns->ns_rx_beacons & 0xFFFFFFFF)); - - /* All other node statistics */ - process_stat_struct (NOD_STAT, ns, dev, mac, "node_stat", "ns_misc"); - return (0); +static int process_station(int sk, const char *dev, + struct ieee80211req_sta_info *si) { + static char mac[DATA_MAX_NAME_LEN]; + struct ieee80211req_sta_stats stats; + const struct ieee80211_nodestats *ns = &stats.is_stats; + int status; + + macaddr_to_str(mac, sizeof(mac), si->isi_macaddr); + + if (item_watched(STAT_NODE_TX_RATE)) + submit_gauge(dev, "node_tx_rate", mac, NULL, + (si->isi_rates[si->isi_txrate] & IEEE80211_RATE_VAL) / 2); + + if (item_watched(STAT_NODE_RSSI)) + submit_gauge(dev, "node_rssi", mac, NULL, si->isi_rssi); + + struct iwreq iwr = {.u.data.pointer = (void *)&stats, + .u.data.length = sizeof(stats)}; + sstrncpy(iwr.ifr_name, dev, sizeof(iwr.ifr_name)); + + memcpy(stats.is_u.macaddr, si->isi_macaddr, IEEE80211_ADDR_LEN); + status = ioctl(sk, IEEE80211_IOCTL_STA_STATS, &iwr); + if (status < 0) { + /* Silent, because not all interfaces support all ioctls. */ + DEBUG("madwifi plugin: Sending IO-control " + "IEEE80211_IOCTL_STA_STATS to device %s " + "failed with status %i.", + dev, status); + return (status); + } + + /* These two stats are handled as a special case as they are + a pair of 64bit values */ + if (item_watched(STAT_NODE_OCTETS)) + submit_derive2(dev, "node_octets", mac, NULL, ns->ns_rx_bytes, + ns->ns_tx_bytes); + + /* This stat is handled as a special case, because it is stored + as uin64_t, but we will ignore upper half */ + if (item_watched(STAT_NS_RX_BEACONS)) + submit_derive(dev, "node_stat", "ns_rx_beacons", mac, + (ns->ns_rx_beacons & 0xFFFFFFFF)); + + /* All other node statistics */ + process_stat_struct(NOD_STAT, ns, dev, mac, "node_stat", "ns_misc"); + return (0); } -static int -process_stations (int sk, const char *dev) -{ - uint8_t buf[24*1024] = { 0 }; - uint8_t *cp; - int nodes; - size_t len; - int status; - - struct iwreq iwr = { - .u.data.pointer = (void *) buf, - .u.data.length = sizeof (buf) - }; - sstrncpy (iwr.ifr_name, dev, sizeof (iwr.ifr_name)); - - status = ioctl (sk, IEEE80211_IOCTL_STA_INFO, &iwr); - if (status < 0) - { - /* Silent, because not all interfaces support all ioctls. */ - DEBUG ("madwifi plugin: Sending IO-control " - "IEEE80211_IOCTL_STA_INFO to device %s " - "failed with status %i.", - dev, status); - return (status); - } - - len = iwr.u.data.length; - - cp = buf; - nodes = 0; - while (len >= sizeof (struct ieee80211req_sta_info)) - { - struct ieee80211req_sta_info *si = (void *) cp; - process_station(sk, dev, si); - cp += si->isi_len; - len -= si->isi_len; - nodes++; - } - - if (item_watched (STAT_ATH_NODES)) - submit_gauge (dev, "ath_nodes", NULL, NULL, nodes); - return (0); +static int process_stations(int sk, const char *dev) { + uint8_t buf[24 * 1024] = {0}; + uint8_t *cp; + int nodes; + size_t len; + int status; + + struct iwreq iwr = {.u.data.pointer = (void *)buf, + .u.data.length = sizeof(buf)}; + sstrncpy(iwr.ifr_name, dev, sizeof(iwr.ifr_name)); + + status = ioctl(sk, IEEE80211_IOCTL_STA_INFO, &iwr); + if (status < 0) { + /* Silent, because not all interfaces support all ioctls. */ + DEBUG("madwifi plugin: Sending IO-control " + "IEEE80211_IOCTL_STA_INFO to device %s " + "failed with status %i.", + dev, status); + return (status); + } + + len = iwr.u.data.length; + + cp = buf; + nodes = 0; + while (len >= sizeof(struct ieee80211req_sta_info)) { + struct ieee80211req_sta_info *si = (void *)cp; + process_station(sk, dev, si); + cp += si->isi_len; + len -= si->isi_len; + nodes++; + } + + if (item_watched(STAT_ATH_NODES)) + submit_gauge(dev, "ath_nodes", NULL, NULL, nodes); + return (0); } -static int -process_device (int sk, const char *dev) -{ - int num_success = 0; - int status; +static int process_device(int sk, const char *dev) { + int num_success = 0; + int status; - status = process_athstats (sk, dev); - if (status == 0) - num_success++; + status = process_athstats(sk, dev); + if (status == 0) + num_success++; - status = process_80211stats (sk, dev); - if (status == 0) - num_success++; + status = process_80211stats(sk, dev); + if (status == 0) + num_success++; - status = process_stations (sk, dev); - if (status == 0) - num_success++; + status = process_stations(sk, dev); + if (status == 0) + num_success++; - return ((num_success == 0) ? -1 : 0); + return ((num_success == 0) ? -1 : 0); } -static int -check_devname (const char *dev) -{ - char buf[PATH_MAX]; - char buf2[PATH_MAX]; - int i; +static int check_devname(const char *dev) { + char buf[PATH_MAX]; + char buf2[PATH_MAX]; + int i; - if (dev[0] == '.') - return 0; + if (dev[0] == '.') + return 0; - ssnprintf (buf, sizeof (buf), "/sys/class/net/%s/device/driver", dev); - buf[sizeof (buf) - 1] = '\0'; + ssnprintf(buf, sizeof(buf), "/sys/class/net/%s/device/driver", dev); + buf[sizeof(buf) - 1] = '\0'; - i = readlink (buf, buf2, sizeof (buf2) - 1); - if (i < 0) - return 0; + i = readlink(buf, buf2, sizeof(buf2) - 1); + if (i < 0) + return 0; - buf2[i] = '\0'; + buf2[i] = '\0'; - if (strstr (buf2, "/drivers/ath_") == NULL) - return 0; - return 1; + if (strstr(buf2, "/drivers/ath_") == NULL) + return 0; + return 1; } -static int -sysfs_iterate(int sk) -{ - struct dirent *de; - DIR *nets; - int status; - int num_success; - int num_fail; - - nets = opendir ("/sys/class/net/"); - if (nets == NULL) - { - WARNING ("madwifi plugin: opening /sys/class/net failed"); - return (-1); - } - - num_success = 0; - num_fail = 0; - while ((de = readdir (nets))) - { - if (check_devname (de->d_name) == 0) - continue; - - if (ignorelist_match (ignorelist, de->d_name) != 0) - continue; - - status = process_device (sk, de->d_name); - if (status != 0) - { - ERROR ("madwifi plugin: Processing interface " - "%s failed.", de->d_name); - num_fail++; - } - else - { - num_success++; - } - } /* while (readdir) */ - - closedir(nets); - - if ((num_success == 0) && (num_fail != 0)) - return (-1); - return (0); +static int sysfs_iterate(int sk) { + struct dirent *de; + DIR *nets; + int status; + int num_success; + int num_fail; + + nets = opendir("/sys/class/net/"); + if (nets == NULL) { + WARNING("madwifi plugin: opening /sys/class/net failed"); + return (-1); + } + + num_success = 0; + num_fail = 0; + while ((de = readdir(nets))) { + if (check_devname(de->d_name) == 0) + continue; + + if (ignorelist_match(ignorelist, de->d_name) != 0) + continue; + + status = process_device(sk, de->d_name); + if (status != 0) { + ERROR("madwifi plugin: Processing interface " + "%s failed.", + de->d_name); + num_fail++; + } else { + num_success++; + } + } /* while (readdir) */ + + closedir(nets); + + if ((num_success == 0) && (num_fail != 0)) + return (-1); + return (0); } -static int -procfs_iterate(int sk) -{ - char buffer[1024]; - char *device, *dummy; - FILE *fh; - int status; - int num_success; - int num_fail; - - if ((fh = fopen ("/proc/net/dev", "r")) == NULL) - { - WARNING ("madwifi plugin: opening /proc/net/dev failed"); - return (-1); - } - - num_success = 0; - num_fail = 0; - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - dummy = strchr(buffer, ':'); - if (dummy == NULL) - continue; - dummy[0] = 0; - - device = buffer; - while (device[0] == ' ') - device++; - - if (device[0] == 0) - continue; - - if (ignorelist_match (ignorelist, device) != 0) - continue; - - status = process_device (sk, device); - if (status != 0) - { - ERROR ("madwifi plugin: Processing interface " - "%s failed.", device); - num_fail++; - } - else - { - num_success++; - } - } /* while (fgets) */ - - fclose(fh); - - if ((num_success == 0) && (num_fail != 0)) - return (-1); - return 0; +static int procfs_iterate(int sk) { + char buffer[1024]; + char *device, *dummy; + FILE *fh; + int status; + int num_success; + int num_fail; + + if ((fh = fopen("/proc/net/dev", "r")) == NULL) { + WARNING("madwifi plugin: opening /proc/net/dev failed"); + return (-1); + } + + num_success = 0; + num_fail = 0; + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + dummy = strchr(buffer, ':'); + if (dummy == NULL) + continue; + dummy[0] = 0; + + device = buffer; + while (device[0] == ' ') + device++; + + if (device[0] == 0) + continue; + + if (ignorelist_match(ignorelist, device) != 0) + continue; + + status = process_device(sk, device); + if (status != 0) { + ERROR("madwifi plugin: Processing interface " + "%s failed.", + device); + num_fail++; + } else { + num_success++; + } + } /* while (fgets) */ + + fclose(fh); + + if ((num_success == 0) && (num_fail != 0)) + return (-1); + return 0; } -static int madwifi_read (void) -{ - int rv; - int sk; - - if (init_state == 0) - madwifi_real_init(); - init_state = 2; +static int madwifi_read(void) { + int rv; + int sk; - sk = socket(AF_INET, SOCK_DGRAM, 0); - if (sk < 0) - return (-1); + if (init_state == 0) + madwifi_real_init(); + init_state = 2; + sk = socket(AF_INET, SOCK_DGRAM, 0); + if (sk < 0) + return (-1); -/* procfs iteration is not safe because it does not check whether given - interface is madwifi interface and there are private ioctls used, which - may do something completely different on non-madwifi devices. - Therefore, it is not used unless explicitly enabled (and should be used - together with ignorelist). */ + /* procfs iteration is not safe because it does not check whether given + interface is madwifi interface and there are private ioctls used, which + may do something completely different on non-madwifi devices. + Therefore, it is not used unless explicitly enabled (and should be used + together with ignorelist). */ - if (use_sysfs) - rv = sysfs_iterate(sk); - else - rv = procfs_iterate(sk); + if (use_sysfs) + rv = sysfs_iterate(sk); + else + rv = procfs_iterate(sk); - close(sk); + close(sk); - return rv; + return rv; } -void module_register (void) -{ - plugin_register_config ("madwifi", madwifi_config, - config_keys, config_keys_num); +void module_register(void) { + plugin_register_config("madwifi", madwifi_config, config_keys, + config_keys_num); - plugin_register_read ("madwifi", madwifi_read); + plugin_register_read("madwifi", madwifi_read); } diff --git a/src/match_empty_counter.c b/src/match_empty_counter.c index 80a29ac7..67c55789 100644 --- a/src/match_empty_counter.c +++ b/src/match_empty_counter.c @@ -32,40 +32,37 @@ /* * internal helper functions */ -static int mec_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ +static int mec_create(const oconfig_item_t *ci, void **user_data) /* {{{ */ { - if (ci->children_num != 0) - { - ERROR ("empty_counter match: This match does not take any additional " - "configuration."); + if (ci->children_num != 0) { + ERROR("empty_counter match: This match does not take any additional " + "configuration."); } *user_data = NULL; return (0); } /* }}} int mec_create */ -static int mec_destroy (__attribute__((unused)) void **user_data) /* {{{ */ +static int mec_destroy(__attribute__((unused)) void **user_data) /* {{{ */ { return (0); } /* }}} int mec_destroy */ -static int mec_match (__attribute__((unused)) const data_set_t *ds, /* {{{ */ - const value_list_t *vl, - __attribute__((unused)) notification_meta_t **meta, - __attribute__((unused)) void **user_data) -{ +static int mec_match(__attribute__((unused)) const data_set_t *ds, /* {{{ */ + const value_list_t *vl, + __attribute__((unused)) notification_meta_t **meta, + __attribute__((unused)) void **user_data) { int num_counters = 0; int num_empty = 0; - for (size_t i = 0; i < ds->ds_num; i++) - { - if ((ds->ds[i].type != DS_TYPE_DERIVE) - && (ds->ds[i].type != DS_TYPE_COUNTER)) + for (size_t i = 0; i < ds->ds_num; i++) { + if ((ds->ds[i].type != DS_TYPE_DERIVE) && + (ds->ds[i].type != DS_TYPE_COUNTER)) continue; num_counters++; - if (((ds->ds[i].type == DS_TYPE_DERIVE) && (vl->values[i].derive == 0)) - || ((ds->ds[i].type == DS_TYPE_COUNTER) && (vl->values[i].counter == 0))) + if (((ds->ds[i].type == DS_TYPE_DERIVE) && (vl->values[i].derive == 0)) || + ((ds->ds[i].type == DS_TYPE_COUNTER) && (vl->values[i].counter == 0))) num_empty++; } @@ -75,13 +72,12 @@ static int mec_match (__attribute__((unused)) const data_set_t *ds, /* {{{ */ return (FC_MATCH_NO_MATCH); } /* }}} int mec_match */ -void module_register (void) -{ - fc_register_match ("empty_counter", (match_proc_t) { - .create = mec_create, - .destroy = mec_destroy, - .match = mec_match, - }); +void module_register(void) { + fc_register_match( + "empty_counter", + (match_proc_t){ + .create = mec_create, .destroy = mec_destroy, .match = mec_match, + }); } /* module_register */ /* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ diff --git a/src/match_hashed.c b/src/match_hashed.c index c4983c2e..fad52718 100644 --- a/src/match_hashed.c +++ b/src/match_hashed.c @@ -32,8 +32,7 @@ /* * private data types */ -struct mh_hash_match_s -{ +struct mh_hash_match_s { uint32_t match; uint32_t total; }; @@ -41,87 +40,76 @@ typedef struct mh_hash_match_s mh_hash_match_t; struct mh_match_s; typedef struct mh_match_s mh_match_t; -struct mh_match_s -{ +struct mh_match_s { mh_hash_match_t *matches; - size_t matches_num; + size_t matches_num; }; /* * internal helper functions */ -static int mh_config_match (const oconfig_item_t *ci, /* {{{ */ - mh_match_t *m) -{ +static int mh_config_match(const oconfig_item_t *ci, /* {{{ */ + mh_match_t *m) { mh_hash_match_t *tmp; - if ((ci->values_num != 2) - || (ci->values[0].type != OCONFIG_TYPE_NUMBER) - || (ci->values[1].type != OCONFIG_TYPE_NUMBER)) - { - ERROR ("hashed match: The `Match' option requires " - "exactly two numeric arguments."); + if ((ci->values_num != 2) || (ci->values[0].type != OCONFIG_TYPE_NUMBER) || + (ci->values[1].type != OCONFIG_TYPE_NUMBER)) { + ERROR("hashed match: The `Match' option requires " + "exactly two numeric arguments."); return (-1); } - if ((ci->values[0].value.number < 0) - || (ci->values[1].value.number < 0)) - { - ERROR ("hashed match: The arguments of the `Match' " - "option must be positive."); + if ((ci->values[0].value.number < 0) || (ci->values[1].value.number < 0)) { + ERROR("hashed match: The arguments of the `Match' " + "option must be positive."); return (-1); } - tmp = realloc (m->matches, sizeof (*tmp) * (m->matches_num + 1)); - if (tmp == NULL) - { - ERROR ("hashed match: realloc failed."); + tmp = realloc(m->matches, sizeof(*tmp) * (m->matches_num + 1)); + if (tmp == NULL) { + ERROR("hashed match: realloc failed."); return (-1); } m->matches = tmp; tmp = m->matches + m->matches_num; - tmp->match = (uint32_t) (ci->values[0].value.number + .5); - tmp->total = (uint32_t) (ci->values[1].value.number + .5); + tmp->match = (uint32_t)(ci->values[0].value.number + .5); + tmp->total = (uint32_t)(ci->values[1].value.number + .5); - if (tmp->match >= tmp->total) - { - ERROR ("hashed match: The first argument of the `Match' option " - "must be smaller than the second argument."); + if (tmp->match >= tmp->total) { + ERROR("hashed match: The first argument of the `Match' option " + "must be smaller than the second argument."); return (-1); } - assert (tmp->total != 0); + assert(tmp->total != 0); m->matches_num++; return (0); } /* }}} int mh_config_match */ -static int mh_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ +static int mh_create(const oconfig_item_t *ci, void **user_data) /* {{{ */ { mh_match_t *m; - m = calloc (1, sizeof (*m)); - if (m == NULL) - { - ERROR ("mh_create: calloc failed."); + m = calloc(1, sizeof(*m)); + if (m == NULL) { + ERROR("mh_create: calloc failed."); return (-ENOMEM); } - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Match", child->key) == 0) - mh_config_match (child, m); + if (strcasecmp("Match", child->key) == 0) + mh_config_match(child, m); else - ERROR ("hashed match: No such config option: %s", child->key); + ERROR("hashed match: No such config option: %s", child->key); } - if (m->matches_num == 0) - { - sfree (m->matches); - sfree (m); - ERROR ("hashed match: No matches were configured. Not creating match."); + if (m->matches_num == 0) { + sfree(m->matches); + sfree(m); + ERROR("hashed match: No matches were configured. Not creating match."); return (-1); } @@ -129,7 +117,7 @@ static int mh_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ return (0); } /* }}} int mh_create */ -static int mh_destroy (void **user_data) /* {{{ */ +static int mh_destroy(void **user_data) /* {{{ */ { mh_match_t *mh; @@ -137,16 +125,16 @@ static int mh_destroy (void **user_data) /* {{{ */ return (0); mh = *user_data; - sfree (mh->matches); - sfree (mh); + sfree(mh->matches); + sfree(mh); return (0); } /* }}} int mh_destroy */ -static int mh_match (const data_set_t __attribute__((unused)) *ds, /* {{{ */ - const value_list_t *vl, - notification_meta_t __attribute__((unused)) **meta, void **user_data) -{ +static int mh_match(const data_set_t __attribute__((unused)) * ds, /* {{{ */ + const value_list_t *vl, + notification_meta_t __attribute__((unused)) * *meta, + void **user_data) { mh_match_t *m; uint32_t hash_val; @@ -157,12 +145,11 @@ static int mh_match (const data_set_t __attribute__((unused)) *ds, /* {{{ */ hash_val = 0; - for (const char *host_ptr = vl->host; *host_ptr != 0; host_ptr++) - { + for (const char *host_ptr = vl->host; *host_ptr != 0; host_ptr++) { /* 2184401929 is some appropriately sized prime number. */ - hash_val = (hash_val * UINT32_C (2184401929)) + ((uint32_t) *host_ptr); + hash_val = (hash_val * UINT32_C(2184401929)) + ((uint32_t)*host_ptr); } - DEBUG ("hashed match: host = %s; hash_val = %"PRIu32";", vl->host, hash_val); + DEBUG("hashed match: host = %s; hash_val = %" PRIu32 ";", vl->host, hash_val); for (size_t i = 0; i < m->matches_num; i++) if ((hash_val % m->matches[i].total) == m->matches[i].match) @@ -171,14 +158,13 @@ static int mh_match (const data_set_t __attribute__((unused)) *ds, /* {{{ */ return (FC_MATCH_NO_MATCH); } /* }}} int mh_match */ -void module_register (void) -{ - match_proc_t mproc = { 0 }; +void module_register(void) { + match_proc_t mproc = {0}; - mproc.create = mh_create; + mproc.create = mh_create; mproc.destroy = mh_destroy; - mproc.match = mh_match; - fc_register_match ("hashed", mproc); + mproc.match = mh_match; + fc_register_match("hashed", mproc); } /* module_register */ /* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ diff --git a/src/match_regex.c b/src/match_regex.c index dd8319ea..209f7736 100644 --- a/src/match_regex.c +++ b/src/match_regex.c @@ -38,11 +38,11 @@ #include "meta_data.h" #include "utils_llist.h" -#include #include +#include -#define log_err(...) ERROR ("`regex' match: " __VA_ARGS__) -#define log_warn(...) WARNING ("`regex' match: " __VA_ARGS__) +#define log_err(...) ERROR("`regex' match: " __VA_ARGS__) +#define log_warn(...) WARNING("`regex' match: " __VA_ARGS__) /* * private data types @@ -50,360 +50,319 @@ struct mr_regex_s; typedef struct mr_regex_s mr_regex_t; -struct mr_regex_s -{ - regex_t re; - char *re_str; +struct mr_regex_s { + regex_t re; + char *re_str; - mr_regex_t *next; + mr_regex_t *next; }; struct mr_match_s; typedef struct mr_match_s mr_match_t; -struct mr_match_s -{ - mr_regex_t *host; - mr_regex_t *plugin; - mr_regex_t *plugin_instance; - mr_regex_t *type; - mr_regex_t *type_instance; - llist_t *meta; /* Maps each meta key into mr_regex_t* */ - _Bool invert; +struct mr_match_s { + mr_regex_t *host; + mr_regex_t *plugin; + mr_regex_t *plugin_instance; + mr_regex_t *type; + mr_regex_t *type_instance; + llist_t *meta; /* Maps each meta key into mr_regex_t* */ + _Bool invert; }; /* * internal helper functions */ -static void mr_free_regex (mr_regex_t *r) /* {{{ */ +static void mr_free_regex(mr_regex_t *r) /* {{{ */ { - if (r == NULL) - return; + if (r == NULL) + return; - regfree (&r->re); - memset (&r->re, 0, sizeof (r->re)); - sfree (r->re_str); + regfree(&r->re); + memset(&r->re, 0, sizeof(r->re)); + sfree(r->re_str); - if (r->next != NULL) - mr_free_regex (r->next); + if (r->next != NULL) + mr_free_regex(r->next); } /* }}} void mr_free_regex */ -static void mr_free_match (mr_match_t *m) /* {{{ */ +static void mr_free_match(mr_match_t *m) /* {{{ */ { - if (m == NULL) - return; - - mr_free_regex (m->host); - mr_free_regex (m->plugin); - mr_free_regex (m->plugin_instance); - mr_free_regex (m->type); - mr_free_regex (m->type_instance); - for (llentry_t *e = llist_head(m->meta); e != NULL; e = e->next) - { - sfree (e->key); - mr_free_regex ((mr_regex_t *) e->value); - } - llist_destroy (m->meta); - - sfree (m); + if (m == NULL) + return; + + mr_free_regex(m->host); + mr_free_regex(m->plugin); + mr_free_regex(m->plugin_instance); + mr_free_regex(m->type); + mr_free_regex(m->type_instance); + for (llentry_t *e = llist_head(m->meta); e != NULL; e = e->next) { + sfree(e->key); + mr_free_regex((mr_regex_t *)e->value); + } + llist_destroy(m->meta); + + sfree(m); } /* }}} void mr_free_match */ -static int mr_match_regexen (mr_regex_t *re_head, /* {{{ */ - const char *string) -{ - if (re_head == NULL) - return (FC_MATCH_MATCHES); - - for (mr_regex_t *re = re_head; re != NULL; re = re->next) - { - int status; - - status = regexec (&re->re, string, - /* nmatch = */ 0, /* pmatch = */ NULL, - /* eflags = */ 0); - if (status == 0) - { - DEBUG ("regex match: Regular expression `%s' matches `%s'.", - re->re_str, string); - } - else - { - DEBUG ("regex match: Regular expression `%s' does not match `%s'.", - re->re_str, string); - return (FC_MATCH_NO_MATCH); - } - - } - - return (FC_MATCH_MATCHES); +static int mr_match_regexen(mr_regex_t *re_head, /* {{{ */ + const char *string) { + if (re_head == NULL) + return (FC_MATCH_MATCHES); + + for (mr_regex_t *re = re_head; re != NULL; re = re->next) { + int status; + + status = regexec(&re->re, string, + /* nmatch = */ 0, /* pmatch = */ NULL, + /* eflags = */ 0); + if (status == 0) { + DEBUG("regex match: Regular expression `%s' matches `%s'.", re->re_str, + string); + } else { + DEBUG("regex match: Regular expression `%s' does not match `%s'.", + re->re_str, string); + return (FC_MATCH_NO_MATCH); + } + } + + return (FC_MATCH_MATCHES); } /* }}} int mr_match_regexen */ -static int mr_add_regex (mr_regex_t **re_head, const char *re_str, /* {{{ */ - const char *option) -{ - mr_regex_t *re; - int status; - - re = calloc (1, sizeof (*re)); - if (re == NULL) - { - log_err ("mr_add_regex: calloc failed."); - return (-1); - } - re->next = NULL; - - re->re_str = strdup (re_str); - if (re->re_str == NULL) - { - sfree (re); - log_err ("mr_add_regex: strdup failed."); - return (-1); - } - - status = regcomp (&re->re, re->re_str, REG_EXTENDED | REG_NOSUB); - if (status != 0) - { - char errmsg[1024]; - regerror (status, &re->re, errmsg, sizeof (errmsg)); - errmsg[sizeof (errmsg) - 1] = 0; - log_err ("Compiling regex `%s' for `%s' failed: %s.", - re->re_str, option, errmsg); - sfree (re->re_str); - sfree (re); - return (-1); - } - - if (*re_head == NULL) - { - *re_head = re; - } - else - { - mr_regex_t *ptr; - - ptr = *re_head; - while (ptr->next != NULL) - ptr = ptr->next; - - ptr->next = re; - } - - return (0); +static int mr_add_regex(mr_regex_t **re_head, const char *re_str, /* {{{ */ + const char *option) { + mr_regex_t *re; + int status; + + re = calloc(1, sizeof(*re)); + if (re == NULL) { + log_err("mr_add_regex: calloc failed."); + return (-1); + } + re->next = NULL; + + re->re_str = strdup(re_str); + if (re->re_str == NULL) { + sfree(re); + log_err("mr_add_regex: strdup failed."); + return (-1); + } + + status = regcomp(&re->re, re->re_str, REG_EXTENDED | REG_NOSUB); + if (status != 0) { + char errmsg[1024]; + regerror(status, &re->re, errmsg, sizeof(errmsg)); + errmsg[sizeof(errmsg) - 1] = 0; + log_err("Compiling regex `%s' for `%s' failed: %s.", re->re_str, option, + errmsg); + sfree(re->re_str); + sfree(re); + return (-1); + } + + if (*re_head == NULL) { + *re_head = re; + } else { + mr_regex_t *ptr; + + ptr = *re_head; + while (ptr->next != NULL) + ptr = ptr->next; + + ptr->next = re; + } + + return (0); } /* }}} int mr_add_regex */ -static int mr_config_add_regex (mr_regex_t **re_head, /* {{{ */ - oconfig_item_t *ci) -{ - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - log_warn ("`%s' needs exactly one string argument.", ci->key); - return (-1); - } +static int mr_config_add_regex(mr_regex_t **re_head, /* {{{ */ + oconfig_item_t *ci) { + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + log_warn("`%s' needs exactly one string argument.", ci->key); + return (-1); + } - return mr_add_regex (re_head, ci->values[0].value.string, ci->key); + return mr_add_regex(re_head, ci->values[0].value.string, ci->key); } /* }}} int mr_config_add_regex */ -static int mr_config_add_meta_regex (llist_t **meta, /* {{{ */ - oconfig_item_t *ci) -{ - char *meta_key; - llentry_t *entry; - mr_regex_t *re_head; - int status; - char buffer[1024]; - - if ((ci->values_num != 2) - || (ci->values[0].type != OCONFIG_TYPE_STRING) - || (ci->values[1].type != OCONFIG_TYPE_STRING)) - { - log_warn ("`%s' needs exactly two string arguments.", ci->key); - return (-1); - } - - if (*meta == NULL) - { - *meta = llist_create(); - if (*meta == NULL) - { - log_err ("mr_config_add_meta_regex: llist_create failed."); - return (-1); - } - } - - meta_key = ci->values[0].value.string; - entry = llist_search (*meta, meta_key); - if (entry == NULL) - { - meta_key = strdup (meta_key); - if (meta_key == NULL) - { - log_err ("mr_config_add_meta_regex: strdup failed."); - return (-1); - } - entry = llentry_create (meta_key, NULL); - if (entry == NULL) - { - log_err ("mr_config_add_meta_regex: llentry_create failed."); - sfree (meta_key); - return (-1); - } - /* meta_key and entry will now be freed by mr_free_match(). */ - llist_append (*meta, entry); - } - - ssnprintf (buffer, sizeof (buffer), "%s `%s'", ci->key, meta_key); - /* Can't pass &entry->value into mr_add_regex, so copy in/out. */ - re_head = entry->value; - status = mr_add_regex (&re_head, ci->values[1].value.string, buffer); - if (status == 0) { - entry->value = re_head; - } - return status; +static int mr_config_add_meta_regex(llist_t **meta, /* {{{ */ + oconfig_item_t *ci) { + char *meta_key; + llentry_t *entry; + mr_regex_t *re_head; + int status; + char buffer[1024]; + + if ((ci->values_num != 2) || (ci->values[0].type != OCONFIG_TYPE_STRING) || + (ci->values[1].type != OCONFIG_TYPE_STRING)) { + log_warn("`%s' needs exactly two string arguments.", ci->key); + return (-1); + } + + if (*meta == NULL) { + *meta = llist_create(); + if (*meta == NULL) { + log_err("mr_config_add_meta_regex: llist_create failed."); + return (-1); + } + } + + meta_key = ci->values[0].value.string; + entry = llist_search(*meta, meta_key); + if (entry == NULL) { + meta_key = strdup(meta_key); + if (meta_key == NULL) { + log_err("mr_config_add_meta_regex: strdup failed."); + return (-1); + } + entry = llentry_create(meta_key, NULL); + if (entry == NULL) { + log_err("mr_config_add_meta_regex: llentry_create failed."); + sfree(meta_key); + return (-1); + } + /* meta_key and entry will now be freed by mr_free_match(). */ + llist_append(*meta, entry); + } + + ssnprintf(buffer, sizeof(buffer), "%s `%s'", ci->key, meta_key); + /* Can't pass &entry->value into mr_add_regex, so copy in/out. */ + re_head = entry->value; + status = mr_add_regex(&re_head, ci->values[1].value.string, buffer); + if (status == 0) { + entry->value = re_head; + } + return status; } /* }}} int mr_config_add_meta_regex */ -static int mr_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ +static int mr_create(const oconfig_item_t *ci, void **user_data) /* {{{ */ { - mr_match_t *m; - int status; - - m = calloc (1, sizeof (*m)); - if (m == NULL) - { - log_err ("mr_create: calloc failed."); - return (-ENOMEM); - } - - m->invert = 0; - - status = 0; - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if ((strcasecmp ("Host", child->key) == 0) - || (strcasecmp ("Hostname", child->key) == 0)) - status = mr_config_add_regex (&m->host, child); - else if (strcasecmp ("Plugin", child->key) == 0) - status = mr_config_add_regex (&m->plugin, child); - else if (strcasecmp ("PluginInstance", child->key) == 0) - status = mr_config_add_regex (&m->plugin_instance, child); - else if (strcasecmp ("Type", child->key) == 0) - status = mr_config_add_regex (&m->type, child); - else if (strcasecmp ("TypeInstance", child->key) == 0) - status = mr_config_add_regex (&m->type_instance, child); - else if (strcasecmp ("MetaData", child->key) == 0) - status = mr_config_add_meta_regex (&m->meta, child); - else if (strcasecmp ("Invert", child->key) == 0) - status = cf_util_get_boolean(child, &m->invert); - else - { - log_err ("The `%s' configuration option is not understood and " - "will be ignored.", child->key); - status = 0; - } - - if (status != 0) - break; - } - - /* Additional sanity-checking */ - while (status == 0) - { - if ((m->host == NULL) - && (m->plugin == NULL) - && (m->plugin_instance == NULL) - && (m->type == NULL) - && (m->type_instance == NULL) - && (m->meta == NULL)) - { - log_err ("No (valid) regular expressions have been configured. " - "This match will be ignored."); - status = -1; - } - - break; - } - - if (status != 0) - { - mr_free_match (m); - return (status); - } - - *user_data = m; - return (0); + mr_match_t *m; + int status; + + m = calloc(1, sizeof(*m)); + if (m == NULL) { + log_err("mr_create: calloc failed."); + return (-ENOMEM); + } + + m->invert = 0; + + status = 0; + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if ((strcasecmp("Host", child->key) == 0) || + (strcasecmp("Hostname", child->key) == 0)) + status = mr_config_add_regex(&m->host, child); + else if (strcasecmp("Plugin", child->key) == 0) + status = mr_config_add_regex(&m->plugin, child); + else if (strcasecmp("PluginInstance", child->key) == 0) + status = mr_config_add_regex(&m->plugin_instance, child); + else if (strcasecmp("Type", child->key) == 0) + status = mr_config_add_regex(&m->type, child); + else if (strcasecmp("TypeInstance", child->key) == 0) + status = mr_config_add_regex(&m->type_instance, child); + else if (strcasecmp("MetaData", child->key) == 0) + status = mr_config_add_meta_regex(&m->meta, child); + else if (strcasecmp("Invert", child->key) == 0) + status = cf_util_get_boolean(child, &m->invert); + else { + log_err("The `%s' configuration option is not understood and " + "will be ignored.", + child->key); + status = 0; + } + + if (status != 0) + break; + } + + /* Additional sanity-checking */ + while (status == 0) { + if ((m->host == NULL) && (m->plugin == NULL) && + (m->plugin_instance == NULL) && (m->type == NULL) && + (m->type_instance == NULL) && (m->meta == NULL)) { + log_err("No (valid) regular expressions have been configured. " + "This match will be ignored."); + status = -1; + } + + break; + } + + if (status != 0) { + mr_free_match(m); + return (status); + } + + *user_data = m; + return (0); } /* }}} int mr_create */ -static int mr_destroy (void **user_data) /* {{{ */ +static int mr_destroy(void **user_data) /* {{{ */ { - if ((user_data != NULL) && (*user_data != NULL)) - mr_free_match (*user_data); - return (0); + if ((user_data != NULL) && (*user_data != NULL)) + mr_free_match(*user_data); + return (0); } /* }}} int mr_destroy */ -static int mr_match (const data_set_t __attribute__((unused)) *ds, /* {{{ */ - const value_list_t *vl, - notification_meta_t __attribute__((unused)) **meta, - void **user_data) -{ - mr_match_t *m; - int match_value = FC_MATCH_MATCHES; - int nomatch_value = FC_MATCH_NO_MATCH; - - if ((user_data == NULL) || (*user_data == NULL)) - return (-1); - - m = *user_data; - - if (m->invert) - { - match_value = FC_MATCH_NO_MATCH; - nomatch_value = FC_MATCH_MATCHES; - } - - if (mr_match_regexen (m->host, vl->host) == FC_MATCH_NO_MATCH) - return (nomatch_value); - if (mr_match_regexen (m->plugin, vl->plugin) == FC_MATCH_NO_MATCH) - return (nomatch_value); - if (mr_match_regexen (m->plugin_instance, - vl->plugin_instance) == FC_MATCH_NO_MATCH) - return (nomatch_value); - if (mr_match_regexen (m->type, vl->type) == FC_MATCH_NO_MATCH) - return (nomatch_value); - if (mr_match_regexen (m->type_instance, - vl->type_instance) == FC_MATCH_NO_MATCH) - return (nomatch_value); - if (vl->meta != NULL) - { - for (llentry_t *e = llist_head(m->meta); e != NULL; e = e->next) - { - mr_regex_t *meta_re = (mr_regex_t *) e->value; - char *value; - int status = meta_data_get_string (vl->meta, e->key, &value); - if (status == (-ENOENT)) /* key is not present */ - return (nomatch_value); - if (status != 0) /* some other problem */ - continue; /* error will have already been printed. */ - if (mr_match_regexen (meta_re, value) == FC_MATCH_NO_MATCH) - { - sfree (value); - return (nomatch_value); - } - sfree (value); - } - } - - return (match_value); +static int mr_match(const data_set_t __attribute__((unused)) * ds, /* {{{ */ + const value_list_t *vl, + notification_meta_t __attribute__((unused)) * *meta, + void **user_data) { + mr_match_t *m; + int match_value = FC_MATCH_MATCHES; + int nomatch_value = FC_MATCH_NO_MATCH; + + if ((user_data == NULL) || (*user_data == NULL)) + return (-1); + + m = *user_data; + + if (m->invert) { + match_value = FC_MATCH_NO_MATCH; + nomatch_value = FC_MATCH_MATCHES; + } + + if (mr_match_regexen(m->host, vl->host) == FC_MATCH_NO_MATCH) + return (nomatch_value); + if (mr_match_regexen(m->plugin, vl->plugin) == FC_MATCH_NO_MATCH) + return (nomatch_value); + if (mr_match_regexen(m->plugin_instance, vl->plugin_instance) == + FC_MATCH_NO_MATCH) + return (nomatch_value); + if (mr_match_regexen(m->type, vl->type) == FC_MATCH_NO_MATCH) + return (nomatch_value); + if (mr_match_regexen(m->type_instance, vl->type_instance) == + FC_MATCH_NO_MATCH) + return (nomatch_value); + if (vl->meta != NULL) { + for (llentry_t *e = llist_head(m->meta); e != NULL; e = e->next) { + mr_regex_t *meta_re = (mr_regex_t *)e->value; + char *value; + int status = meta_data_get_string(vl->meta, e->key, &value); + if (status == (-ENOENT)) /* key is not present */ + return (nomatch_value); + if (status != 0) /* some other problem */ + continue; /* error will have already been printed. */ + if (mr_match_regexen(meta_re, value) == FC_MATCH_NO_MATCH) { + sfree(value); + return (nomatch_value); + } + sfree(value); + } + } + + return (match_value); } /* }}} int mr_match */ -void module_register (void) -{ - match_proc_t mproc = { 0 }; +void module_register(void) { + match_proc_t mproc = {0}; - mproc.create = mr_create; - mproc.destroy = mr_destroy; - mproc.match = mr_match; - fc_register_match ("regex", mproc); + mproc.create = mr_create; + mproc.destroy = mr_destroy; + mproc.match = mr_match; + fc_register_match("regex", mproc); } /* module_register */ /* vim: set sw=4 ts=4 tw=78 noexpandtab fdm=marker : */ - diff --git a/src/match_timediff.c b/src/match_timediff.c index 00fdd0c1..6d00ed29 100644 --- a/src/match_timediff.c +++ b/src/match_timediff.c @@ -37,8 +37,7 @@ */ struct mt_match_s; typedef struct mt_match_s mt_match_t; -struct mt_match_s -{ +struct mt_match_s { cdtime_t future; cdtime_t past; }; @@ -46,15 +45,14 @@ struct mt_match_s /* * internal helper functions */ -static int mt_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ +static int mt_create(const oconfig_item_t *ci, void **user_data) /* {{{ */ { mt_match_t *m; int status; - m = calloc (1, sizeof (*m)); - if (m == NULL) - { - ERROR ("mt_create: calloc failed."); + m = calloc(1, sizeof(*m)); + if (m == NULL) { + ERROR("mt_create: calloc failed."); return (-ENOMEM); } @@ -62,18 +60,17 @@ static int mt_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ m->past = 0; status = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Future", child->key) == 0) - status = cf_util_get_cdtime (child, &m->future); - else if (strcasecmp ("Past", child->key) == 0) - status = cf_util_get_cdtime (child, &m->past); - else - { - ERROR ("timediff match: The `%s' configuration option is not " - "understood and will be ignored.", child->key); + if (strcasecmp("Future", child->key) == 0) + status = cf_util_get_cdtime(child, &m->future); + else if (strcasecmp("Past", child->key) == 0) + status = cf_util_get_cdtime(child, &m->past); + else { + ERROR("timediff match: The `%s' configuration option is not " + "understood and will be ignored.", + child->key); status = 0; } @@ -82,21 +79,18 @@ static int mt_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ } /* Additional sanity-checking */ - while (status == 0) - { - if ((m->future == 0) && (m->past == 0)) - { - ERROR ("timediff match: Either `Future' or `Past' must be configured. " - "This match will be ignored."); + while (status == 0) { + if ((m->future == 0) && (m->past == 0)) { + ERROR("timediff match: Either `Future' or `Past' must be configured. " + "This match will be ignored."); status = -1; } break; } - if (status != 0) - { - free (m); + if (status != 0) { + free(m); return (status); } @@ -104,20 +98,19 @@ static int mt_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ return (0); } /* }}} int mt_create */ -static int mt_destroy (void **user_data) /* {{{ */ +static int mt_destroy(void **user_data) /* {{{ */ { - if (user_data != NULL) - { - sfree (*user_data); + if (user_data != NULL) { + sfree(*user_data); } return (0); } /* }}} int mt_destroy */ -static int mt_match (const data_set_t __attribute__((unused)) *ds, /* {{{ */ - const value_list_t *vl, - notification_meta_t __attribute__((unused)) **meta, void **user_data) -{ +static int mt_match(const data_set_t __attribute__((unused)) * ds, /* {{{ */ + const value_list_t *vl, + notification_meta_t __attribute__((unused)) * *meta, + void **user_data) { mt_match_t *m; cdtime_t now; @@ -125,16 +118,14 @@ static int mt_match (const data_set_t __attribute__((unused)) *ds, /* {{{ */ return (-1); m = *user_data; - now = cdtime (); + now = cdtime(); - if (m->future != 0) - { + if (m->future != 0) { if (vl->time >= (now + m->future)) return (FC_MATCH_MATCHES); } - if (m->past != 0) - { + if (m->past != 0) { if (vl->time <= (now - m->past)) return (FC_MATCH_MATCHES); } @@ -142,14 +133,13 @@ static int mt_match (const data_set_t __attribute__((unused)) *ds, /* {{{ */ return (FC_MATCH_NO_MATCH); } /* }}} int mt_match */ -void module_register (void) -{ - match_proc_t mproc = { 0 }; +void module_register(void) { + match_proc_t mproc = {0}; - mproc.create = mt_create; + mproc.create = mt_create; mproc.destroy = mt_destroy; - mproc.match = mt_match; - fc_register_match ("timediff", mproc); + mproc.match = mt_match; + fc_register_match("timediff", mproc); } /* module_register */ /* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ diff --git a/src/match_value.c b/src/match_value.c index 54ddba28..3c943757 100644 --- a/src/match_value.c +++ b/src/match_value.c @@ -32,8 +32,8 @@ #include "collectd.h" #include "common.h" -#include "utils_cache.h" #include "filter_chain.h" +#include "utils_cache.h" #define SATISFY_ALL 0 #define SATISFY_ANY 1 @@ -43,8 +43,7 @@ */ struct mv_match_s; typedef struct mv_match_s mv_match_t; -struct mv_match_s -{ +struct mv_match_s { gauge_t min; gauge_t max; int invert; @@ -57,96 +56,83 @@ struct mv_match_s /* * internal helper functions */ -static void mv_free_match (mv_match_t *m) /* {{{ */ +static void mv_free_match(mv_match_t *m) /* {{{ */ { if (m == NULL) return; - if (m->data_sources != NULL) - { + if (m->data_sources != NULL) { for (size_t i = 0; i < m->data_sources_num; ++i) free(m->data_sources[i]); free(m->data_sources); } - free (m); + free(m); } /* }}} void mv_free_match */ -static int mv_config_add_satisfy (mv_match_t *m, /* {{{ */ - oconfig_item_t *ci) -{ - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - ERROR ("`value' match: `%s' needs exactly one string argument.", - ci->key); +static int mv_config_add_satisfy(mv_match_t *m, /* {{{ */ + oconfig_item_t *ci) { + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + ERROR("`value' match: `%s' needs exactly one string argument.", ci->key); return (-1); } - if (strcasecmp ("All", ci->values[0].value.string) == 0) + if (strcasecmp("All", ci->values[0].value.string) == 0) m->satisfy = SATISFY_ALL; - else if (strcasecmp ("Any", ci->values[0].value.string) == 0) + else if (strcasecmp("Any", ci->values[0].value.string) == 0) m->satisfy = SATISFY_ANY; - else - { - ERROR ("`value' match: Passing `%s' to the `%s' option is invalid. " - "The argument must either be `All' or `Any'.", - ci->values[0].value.string, ci->key); + else { + ERROR("`value' match: Passing `%s' to the `%s' option is invalid. " + "The argument must either be `All' or `Any'.", + ci->values[0].value.string, ci->key); return (-1); } return (0); } /* }}} int mv_config_add_satisfy */ -static int mv_config_add_data_source (mv_match_t *m, /* {{{ */ - oconfig_item_t *ci) -{ +static int mv_config_add_data_source(mv_match_t *m, /* {{{ */ + oconfig_item_t *ci) { size_t new_data_sources_num; char **temp; /* Check number of arbuments. */ - if (ci->values_num < 1) - { - ERROR ("`value' match: `%s' needs at least one argument.", - ci->key); + if (ci->values_num < 1) { + ERROR("`value' match: `%s' needs at least one argument.", ci->key); return (-1); } /* Check type of arguments */ - for (int i = 0; i < ci->values_num; i++) - { + for (int i = 0; i < ci->values_num; i++) { if (ci->values[i].type == OCONFIG_TYPE_STRING) continue; - ERROR ("`value' match: `%s' accepts only string arguments " - "(argument %i is a %s).", - ci->key, i + 1, - (ci->values[i].type == OCONFIG_TYPE_BOOLEAN) - ? "truth value" : "number"); + ERROR("`value' match: `%s' accepts only string arguments " + "(argument %i is a %s).", + ci->key, i + 1, + (ci->values[i].type == OCONFIG_TYPE_BOOLEAN) ? "truth value" + : "number"); return (-1); } /* Allocate space for the char pointers */ - new_data_sources_num = m->data_sources_num + ((size_t) ci->values_num); - temp = realloc (m->data_sources, - new_data_sources_num * sizeof (char *)); - if (temp == NULL) - { - ERROR ("`value' match: realloc failed."); + new_data_sources_num = m->data_sources_num + ((size_t)ci->values_num); + temp = realloc(m->data_sources, new_data_sources_num * sizeof(char *)); + if (temp == NULL) { + ERROR("`value' match: realloc failed."); return (-1); } m->data_sources = temp; /* Copy the strings, allocating memory as needed. */ - for (int i = 0; i < ci->values_num; i++) - { + for (int i = 0; i < ci->values_num; i++) { /* If we get here, there better be memory for us to write to. */ - assert (m->data_sources_num < new_data_sources_num); + assert(m->data_sources_num < new_data_sources_num); size_t j = m->data_sources_num; - m->data_sources[j] = sstrdup (ci->values[i].value.string); - if (m->data_sources[j] == NULL) - { - ERROR ("`value' match: sstrdup failed."); + m->data_sources[j] = sstrdup(ci->values[i].value.string); + if (m->data_sources[j] == NULL) { + ERROR("`value' match: sstrdup failed."); continue; } m->data_sources_num++; @@ -155,14 +141,11 @@ static int mv_config_add_data_source (mv_match_t *m, /* {{{ */ return (0); } /* }}} int mv_config_add_data_source */ -static int mv_config_add_gauge (gauge_t *ret_value, /* {{{ */ - oconfig_item_t *ci) -{ +static int mv_config_add_gauge(gauge_t *ret_value, /* {{{ */ + oconfig_item_t *ci) { - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) - { - ERROR ("`value' match: `%s' needs exactly one numeric argument.", - ci->key); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) { + ERROR("`value' match: `%s' needs exactly one numeric argument.", ci->key); return (-1); } @@ -171,14 +154,11 @@ static int mv_config_add_gauge (gauge_t *ret_value, /* {{{ */ return (0); } /* }}} int mv_config_add_gauge */ -static int mv_config_add_boolean (int *ret_value, /* {{{ */ - oconfig_item_t *ci) -{ +static int mv_config_add_boolean(int *ret_value, /* {{{ */ + oconfig_item_t *ci) { - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) - { - ERROR ("`value' match: `%s' needs exactly one boolean argument.", - ci->key); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) { + ERROR("`value' match: `%s' needs exactly one boolean argument.", ci->key); return (-1); } @@ -190,15 +170,14 @@ static int mv_config_add_boolean (int *ret_value, /* {{{ */ return (0); } /* }}} int mv_config_add_boolean */ -static int mv_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ +static int mv_create(const oconfig_item_t *ci, void **user_data) /* {{{ */ { mv_match_t *m; int status; - m = calloc (1, sizeof (*m)); - if (m == NULL) - { - ERROR ("mv_create: calloc failed."); + m = calloc(1, sizeof(*m)); + if (m == NULL) { + ERROR("mv_create: calloc failed."); return (-ENOMEM); } @@ -210,24 +189,23 @@ static int mv_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ m->data_sources_num = 0; status = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Min", child->key) == 0) - status = mv_config_add_gauge (&m->min, child); - else if (strcasecmp ("Max", child->key) == 0) - status = mv_config_add_gauge (&m->max, child); - else if (strcasecmp ("Invert", child->key) == 0) - status = mv_config_add_boolean (&m->invert, child); - else if (strcasecmp ("Satisfy", child->key) == 0) - status = mv_config_add_satisfy (m, child); - else if (strcasecmp ("DataSource", child->key) == 0) - status = mv_config_add_data_source (m, child); - else - { - ERROR ("`value' match: The `%s' configuration option is not " - "understood and will be ignored.", child->key); + if (strcasecmp("Min", child->key) == 0) + status = mv_config_add_gauge(&m->min, child); + else if (strcasecmp("Max", child->key) == 0) + status = mv_config_add_gauge(&m->max, child); + else if (strcasecmp("Invert", child->key) == 0) + status = mv_config_add_boolean(&m->invert, child); + else if (strcasecmp("Satisfy", child->key) == 0) + status = mv_config_add_satisfy(m, child); + else if (strcasecmp("DataSource", child->key) == 0) + status = mv_config_add_data_source(m, child); + else { + ERROR("`value' match: The `%s' configuration option is not " + "understood and will be ignored.", + child->key); status = 0; } @@ -236,21 +214,18 @@ static int mv_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ } /* Additional sanity-checking */ - while (status == 0) - { - if (isnan (m->min) && isnan (m->max)) - { - ERROR ("`value' match: Neither minimum nor maximum are defined. " - "This match will be ignored."); + while (status == 0) { + if (isnan(m->min) && isnan(m->max)) { + ERROR("`value' match: Neither minimum nor maximum are defined. " + "This match will be ignored."); status = -1; } break; } - if (status != 0) - { - mv_free_match (m); + if (status != 0) { + mv_free_match(m); return (status); } @@ -258,16 +233,16 @@ static int mv_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ return (0); } /* }}} int mv_create */ -static int mv_destroy (void **user_data) /* {{{ */ +static int mv_destroy(void **user_data) /* {{{ */ { if ((user_data != NULL) && (*user_data != NULL)) - mv_free_match (*user_data); + mv_free_match(*user_data); return (0); } /* }}} int mv_destroy */ -static int mv_match (const data_set_t *ds, const value_list_t *vl, /* {{{ */ - notification_meta_t __attribute__((unused)) **meta, void **user_data) -{ +static int mv_match(const data_set_t *ds, const value_list_t *vl, /* {{{ */ + notification_meta_t __attribute__((unused)) * *meta, + void **user_data) { mv_match_t *m; gauge_t *values; int status; @@ -277,79 +252,69 @@ static int mv_match (const data_set_t *ds, const value_list_t *vl, /* {{{ */ m = *user_data; - values = uc_get_rate (ds, vl); - if (values == NULL) - { - ERROR ("`value' match: Retrieving the current rate from the cache " - "failed."); + values = uc_get_rate(ds, vl); + if (values == NULL) { + ERROR("`value' match: Retrieving the current rate from the cache " + "failed."); return (-1); } status = FC_MATCH_NO_MATCH; - for (size_t i = 0; i < ds->ds_num; i++) - { + for (size_t i = 0; i < ds->ds_num; i++) { int value_matches = 0; /* Check if this data source is relevant. */ - if (m->data_sources != NULL) - { + if (m->data_sources != NULL) { size_t j; for (j = 0; j < m->data_sources_num; j++) - if (strcasecmp (ds->ds[i].name, m->data_sources[j]) == 0) + if (strcasecmp(ds->ds[i].name, m->data_sources[j]) == 0) break; /* No match, ignore this data source. */ - if (j >= m->data_sources_num) + if (j >= m->data_sources_num) continue; } - DEBUG ("`value' match: current = %g; min = %g; max = %g; invert = %s;", - values[i], m->min, m->max, - m->invert ? "true" : "false"); + DEBUG("`value' match: current = %g; min = %g; max = %g; invert = %s;", + values[i], m->min, m->max, m->invert ? "true" : "false"); - if ((!isnan (m->min) && (values[i] < m->min)) - || (!isnan (m->max) && (values[i] > m->max))) + if ((!isnan(m->min) && (values[i] < m->min)) || + (!isnan(m->max) && (values[i] > m->max))) value_matches = 0; else value_matches = 1; - if (m->invert) - { + if (m->invert) { if (value_matches) value_matches = 0; else value_matches = 1; } - if (value_matches != 0) - { + if (value_matches != 0) { status = FC_MATCH_MATCHES; if (m->satisfy == SATISFY_ANY) break; - } - else - { + } else { status = FC_MATCH_NO_MATCH; if (m->satisfy == SATISFY_ALL) break; } } /* for (i = 0; i < ds->ds_num; i++) */ - free (values); + free(values); return (status); } /* }}} int mv_match */ -void module_register (void) -{ - match_proc_t mproc = { 0 }; +void module_register(void) { + match_proc_t mproc = {0}; - mproc.create = mv_create; + mproc.create = mv_create; mproc.destroy = mv_destroy; - mproc.match = mv_match; - fc_register_match ("value", mproc); + mproc.match = mv_match; + fc_register_match("value", mproc); } /* module_register */ /* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ - diff --git a/src/mbmon.c b/src/mbmon.c index 87e54fa1..aa593a03 100644 --- a/src/mbmon.c +++ b/src/mbmon.c @@ -35,12 +35,7 @@ #define MBMON_DEF_HOST "127.0.0.1" #define MBMON_DEF_PORT "411" /* the default for Debian */ -static const char *config_keys[] = -{ - "Host", - "Port", - NULL -}; +static const char *config_keys[] = {"Host", "Port", NULL}; static int config_keys_num = 2; static char *mbmon_host = NULL; @@ -75,230 +70,196 @@ static char *mbmon_port = NULL; * we need to create a new socket each time. Is there another way? * Hm, maybe we can re-use the `sockaddr' structure? -octo */ -static int mbmon_query_daemon (char *buffer, int buffer_size) -{ - int fd; - ssize_t status; - int buffer_fill; - - const char *host; - const char *port; - - struct addrinfo *ai_list; - int ai_return; - - host = mbmon_host; - if (host == NULL) - host = MBMON_DEF_HOST; - - port = mbmon_port; - if (port == NULL) - port = MBMON_DEF_PORT; - - struct addrinfo ai_hints = { - .ai_family = AF_UNSPEC, - .ai_flags = AI_ADDRCONFIG, - .ai_protocol = IPPROTO_TCP, - .ai_socktype = SOCK_STREAM - }; - - if ((ai_return = getaddrinfo (host, port, &ai_hints, &ai_list)) != 0) - { - char errbuf[1024]; - ERROR ("mbmon: getaddrinfo (%s, %s): %s", - host, port, - (ai_return == EAI_SYSTEM) - ? sstrerror (errno, errbuf, sizeof (errbuf)) - : gai_strerror (ai_return)); - return (-1); - } - - fd = -1; - for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) - { - /* create our socket descriptor */ - if ((fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol)) < 0) - { - char errbuf[1024]; - ERROR ("mbmon: socket: %s", - sstrerror (errno, errbuf, - sizeof (errbuf))); - continue; - } - - /* connect to the mbmon daemon */ - if (connect (fd, (struct sockaddr *) ai_ptr->ai_addr, ai_ptr->ai_addrlen)) - { - char errbuf[1024]; - INFO ("mbmon: connect (%s, %s): %s", host, port, - sstrerror (errno, errbuf, - sizeof (errbuf))); - close (fd); - fd = -1; - continue; - } - - /* A socket could be opened and connecting succeeded. We're - * done. */ - break; - } - - freeaddrinfo (ai_list); - - if (fd < 0) - { - ERROR ("mbmon: Could not connect to daemon."); - return (-1); - } - - /* receive data from the mbmon daemon */ - memset (buffer, '\0', buffer_size); - - buffer_fill = 0; - while ((status = read (fd, buffer + buffer_fill, buffer_size - buffer_fill)) != 0) - { - if (status == -1) - { - char errbuf[1024]; - - if ((errno == EAGAIN) || (errno == EINTR)) - continue; - - ERROR ("mbmon: Error reading from socket: %s", - sstrerror (errno, errbuf, - sizeof (errbuf))); - close (fd); - return (-1); - } - buffer_fill += status; - - if (buffer_fill >= buffer_size) - break; - } - - if (buffer_fill >= buffer_size) - { - buffer[buffer_size - 1] = '\0'; - WARNING ("mbmon: Message from mbmon has been truncated."); - } - else if (buffer_fill == 0) - { - WARNING ("mbmon: Peer has unexpectedly shut down the socket. " - "Buffer: `%s'", buffer); - close (fd); - return (-1); - } - - close (fd); - return (0); +static int mbmon_query_daemon(char *buffer, int buffer_size) { + int fd; + ssize_t status; + int buffer_fill; + + const char *host; + const char *port; + + struct addrinfo *ai_list; + int ai_return; + + host = mbmon_host; + if (host == NULL) + host = MBMON_DEF_HOST; + + port = mbmon_port; + if (port == NULL) + port = MBMON_DEF_PORT; + + struct addrinfo ai_hints = {.ai_family = AF_UNSPEC, + .ai_flags = AI_ADDRCONFIG, + .ai_protocol = IPPROTO_TCP, + .ai_socktype = SOCK_STREAM}; + + if ((ai_return = getaddrinfo(host, port, &ai_hints, &ai_list)) != 0) { + char errbuf[1024]; + ERROR("mbmon: getaddrinfo (%s, %s): %s", host, port, + (ai_return == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf)) + : gai_strerror(ai_return)); + return (-1); + } + + fd = -1; + for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; + ai_ptr = ai_ptr->ai_next) { + /* create our socket descriptor */ + if ((fd = socket(ai_ptr->ai_family, ai_ptr->ai_socktype, + ai_ptr->ai_protocol)) < 0) { + char errbuf[1024]; + ERROR("mbmon: socket: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + continue; + } + + /* connect to the mbmon daemon */ + if (connect(fd, (struct sockaddr *)ai_ptr->ai_addr, ai_ptr->ai_addrlen)) { + char errbuf[1024]; + INFO("mbmon: connect (%s, %s): %s", host, port, + sstrerror(errno, errbuf, sizeof(errbuf))); + close(fd); + fd = -1; + continue; + } + + /* A socket could be opened and connecting succeeded. We're + * done. */ + break; + } + + freeaddrinfo(ai_list); + + if (fd < 0) { + ERROR("mbmon: Could not connect to daemon."); + return (-1); + } + + /* receive data from the mbmon daemon */ + memset(buffer, '\0', buffer_size); + + buffer_fill = 0; + while ((status = read(fd, buffer + buffer_fill, buffer_size - buffer_fill)) != + 0) { + if (status == -1) { + char errbuf[1024]; + + if ((errno == EAGAIN) || (errno == EINTR)) + continue; + + ERROR("mbmon: Error reading from socket: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(fd); + return (-1); + } + buffer_fill += status; + + if (buffer_fill >= buffer_size) + break; + } + + if (buffer_fill >= buffer_size) { + buffer[buffer_size - 1] = '\0'; + WARNING("mbmon: Message from mbmon has been truncated."); + } else if (buffer_fill == 0) { + WARNING("mbmon: Peer has unexpectedly shut down the socket. " + "Buffer: `%s'", + buffer); + close(fd); + return (-1); + } + + close(fd); + return (0); } -static int mbmon_config (const char *key, const char *value) -{ - if (strcasecmp (key, "host") == 0) - { - if (mbmon_host != NULL) - free (mbmon_host); - mbmon_host = strdup (value); - } - else if (strcasecmp (key, "port") == 0) - { - if (mbmon_port != NULL) - free (mbmon_port); - mbmon_port = strdup (value); - } - else - { - return (-1); - } - - return (0); +static int mbmon_config(const char *key, const char *value) { + if (strcasecmp(key, "host") == 0) { + if (mbmon_host != NULL) + free(mbmon_host); + mbmon_host = strdup(value); + } else if (strcasecmp(key, "port") == 0) { + if (mbmon_port != NULL) + free(mbmon_port); + mbmon_port = strdup(value); + } else { + return (-1); + } + + return (0); } -static void mbmon_submit (const char *type, const char *type_instance, - double value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void mbmon_submit(const char *type, const char *type_instance, + double value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "mbmon", sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "mbmon", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* void mbmon_submit */ /* Trim trailing whitespace from a string. */ -static void trim_spaces (char *s) -{ - for (size_t l = strlen (s) - 1; (l > 0) && isspace ((int) s[l]); l--) - s[l] = '\0'; +static void trim_spaces(char *s) { + for (size_t l = strlen(s) - 1; (l > 0) && isspace((int)s[l]); l--) + s[l] = '\0'; } -static int mbmon_read (void) -{ - char buf[1024]; - char *s, *t; - - /* get data from daemon */ - if (mbmon_query_daemon (buf, sizeof (buf)) < 0) - return (-1); - - s = buf; - while ((t = strchr (s, ':')) != NULL) - { - double value; - char *nextc; - - const char *type; - const char *inst; - - *t++ = '\0'; - trim_spaces (s); - - value = strtod (t, &nextc); - if ((*nextc != '\n') && (*nextc != '\0')) - { - ERROR ("mbmon: value for `%s' contains invalid characters: `%s'", s, t); - break; - } - - if (strncmp (s, "TEMP", 4) == 0) - { - inst = s + 4; - type = "temperature"; - } - else if (strncmp (s, "FAN", 3) == 0) - { - inst = s + 3; - type = "fanspeed"; - } - else if (strncmp (s, "V", 1) == 0) - { - inst = s + 1; - type = "voltage"; - } - else - { - continue; - } - - mbmon_submit (type, inst, value); - - if (*nextc == '\0') - break; - - s = nextc + 1; - } - - return (0); +static int mbmon_read(void) { + char buf[1024]; + char *s, *t; + + /* get data from daemon */ + if (mbmon_query_daemon(buf, sizeof(buf)) < 0) + return (-1); + + s = buf; + while ((t = strchr(s, ':')) != NULL) { + double value; + char *nextc; + + const char *type; + const char *inst; + + *t++ = '\0'; + trim_spaces(s); + + value = strtod(t, &nextc); + if ((*nextc != '\n') && (*nextc != '\0')) { + ERROR("mbmon: value for `%s' contains invalid characters: `%s'", s, t); + break; + } + + if (strncmp(s, "TEMP", 4) == 0) { + inst = s + 4; + type = "temperature"; + } else if (strncmp(s, "FAN", 3) == 0) { + inst = s + 3; + type = "fanspeed"; + } else if (strncmp(s, "V", 1) == 0) { + inst = s + 1; + type = "voltage"; + } else { + continue; + } + + mbmon_submit(type, inst, value); + + if (*nextc == '\0') + break; + + s = nextc + 1; + } + + return (0); } /* void mbmon_read */ /* module_register Register collectd plugin. */ -void module_register (void) -{ - plugin_register_config ("mbmon", mbmon_config, config_keys, config_keys_num); - plugin_register_read ("mbmon", mbmon_read); +void module_register(void) { + plugin_register_config("mbmon", mbmon_config, config_keys, config_keys_num); + plugin_register_read("mbmon", mbmon_read); } /* void module_register */ diff --git a/src/md.c b/src/md.c index 793b1722..5e6b3ac7 100644 --- a/src/md.c +++ b/src/md.c @@ -37,104 +37,85 @@ #define PROC_DISKSTATS "/proc/diskstats" #define DEV_DIR "/dev" -static const char *config_keys[] = -{ - "Device", - "IgnoreSelected" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"Device", "IgnoreSelected"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static ignorelist_t *ignorelist = NULL; -static int md_config (const char *key, const char *value) -{ +static int md_config(const char *key, const char *value) { if (ignorelist == NULL) - ignorelist = ignorelist_create (/* invert = */ 1); + ignorelist = ignorelist_create(/* invert = */ 1); if (ignorelist == NULL) return (1); - if (strcasecmp (key, "Device") == 0) - { - ignorelist_add (ignorelist, value); - } - else if (strcasecmp (key, "IgnoreSelected") == 0) - { - ignorelist_set_invert (ignorelist, IS_TRUE (value) ? 0 : 1); - } - else - { + if (strcasecmp(key, "Device") == 0) { + ignorelist_add(ignorelist, value); + } else if (strcasecmp(key, "IgnoreSelected") == 0) { + ignorelist_set_invert(ignorelist, IS_TRUE(value) ? 0 : 1); + } else { return (-1); } return (0); } -static void md_submit (const int minor, const char *type_instance, - gauge_t value) -{ +static void md_submit(const int minor, const char *type_instance, + gauge_t value) { value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; + vl.values = &(value_t){.gauge = value}; vl.values_len = 1; - sstrncpy (vl.plugin, "md", sizeof (vl.plugin)); - ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), - "%i", minor); - sstrncpy (vl.type, "md_disks", sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, - sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); + sstrncpy(vl.plugin, "md", sizeof(vl.plugin)); + ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", minor); + sstrncpy(vl.type, "md_disks", sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); } /* void md_submit */ -static void md_process (const int minor, const char *path) -{ +static void md_process(const int minor, const char *path) { char errbuf[1024]; int fd; struct stat st; mdu_array_info_t array; gauge_t disks_missing; - fd = open (path, O_RDONLY); - if (fd < 0) - { - WARNING ("md: open(%s): %s", path, - sstrerror (errno, errbuf, sizeof (errbuf))); + fd = open(path, O_RDONLY); + if (fd < 0) { + WARNING("md: open(%s): %s", path, sstrerror(errno, errbuf, sizeof(errbuf))); return; } - if (fstat (fd, &st) < 0) - { - WARNING ("md: Unable to fstat file descriptor for %s: %s", path, - sstrerror (errno, errbuf, sizeof (errbuf))); - close (fd); + if (fstat(fd, &st) < 0) { + WARNING("md: Unable to fstat file descriptor for %s: %s", path, + sstrerror(errno, errbuf, sizeof(errbuf))); + close(fd); return; } - if (! S_ISBLK (st.st_mode)) - { - WARNING ("md: %s is no block device", path); - close (fd); + if (!S_ISBLK(st.st_mode)) { + WARNING("md: %s is no block device", path); + close(fd); return; } - if (st.st_rdev != makedev (MD_MAJOR, minor)) - { - WARNING ("md: Major/minor of %s are %i:%i, should be %i:%i", - path, (int)major(st.st_rdev), (int)minor(st.st_rdev), - (int)MD_MAJOR, minor); - close (fd); + if (st.st_rdev != makedev(MD_MAJOR, minor)) { + WARNING("md: Major/minor of %s are %i:%i, should be %i:%i", path, + (int)major(st.st_rdev), (int)minor(st.st_rdev), (int)MD_MAJOR, + minor); + close(fd); return; } /* Retrieve md information */ - if (ioctl (fd, GET_ARRAY_INFO, &array) < 0) { - WARNING ("md: Unable to retrieve array info from %s: %s", path, - sstrerror (errno, errbuf, sizeof (errbuf))); - close (fd); + if (ioctl(fd, GET_ARRAY_INFO, &array) < 0) { + WARNING("md: Unable to retrieve array info from %s: %s", path, + sstrerror(errno, errbuf, sizeof(errbuf))); + close(fd); return; } - close (fd); + close(fd); /* * The mdu_array_info_t structure contains numbers of disks in the array. @@ -149,51 +130,48 @@ static void md_process (const int minor, const char *path) * disks are missing and smaller than "nr" when spare disks are * around. */ - md_submit (minor, "active", (gauge_t) array.active_disks); - md_submit (minor, "failed", (gauge_t) array.failed_disks); - md_submit (minor, "spare", (gauge_t) array.spare_disks); + md_submit(minor, "active", (gauge_t)array.active_disks); + md_submit(minor, "failed", (gauge_t)array.failed_disks); + md_submit(minor, "spare", (gauge_t)array.spare_disks); disks_missing = 0.0; if (array.raid_disks > array.nr_disks) - disks_missing = (gauge_t) (array.raid_disks - array.nr_disks); - md_submit (minor, "missing", disks_missing); + disks_missing = (gauge_t)(array.raid_disks - array.nr_disks); + md_submit(minor, "missing", disks_missing); } /* void md_process */ -static int md_read (void) -{ +static int md_read(void) { FILE *fh; char buffer[1024]; - fh = fopen (PROC_DISKSTATS, "r"); + fh = fopen(PROC_DISKSTATS, "r"); if (fh == NULL) { char errbuf[1024]; - WARNING ("md: Unable to open %s: %s", - PROC_DISKSTATS , - sstrerror (errno, errbuf, sizeof (errbuf))); + WARNING("md: Unable to open %s: %s", PROC_DISKSTATS, + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } /* Iterate md devices */ - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { + while (fgets(buffer, sizeof(buffer), fh) != NULL) { char path[PATH_MAX]; char *fields[4]; char *name; int major, minor; /* Extract interesting fields */ - if (strsplit (buffer, fields, STATIC_ARRAY_SIZE(fields)) < 3) + if (strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)) < 3) continue; - major = atoi (fields[0]); + major = atoi(fields[0]); if (major != MD_MAJOR) continue; - minor = atoi (fields[1]); + minor = atoi(fields[1]); name = fields[2]; - if (ignorelist_match (ignorelist, name)) + if (ignorelist_match(ignorelist, name)) continue; /* FIXME: Don't hardcode path. Walk /dev collecting major, @@ -202,18 +180,17 @@ static int md_read (void) * major/minor, but that again can be tricky if the filesystem * with the device file is mounted using the "nodev" option. */ - ssnprintf (path, sizeof (path), "%s/%s", DEV_DIR, name); + ssnprintf(path, sizeof(path), "%s/%s", DEV_DIR, name); - md_process (minor, path); + md_process(minor, path); } - fclose (fh); + fclose(fh); return (0); } /* int md_read */ -void module_register (void) -{ - plugin_register_config ("md", md_config, config_keys, config_keys_num); - plugin_register_read ("md", md_read); +void module_register(void) { + plugin_register_config("md", md_config, config_keys, config_keys_num); + plugin_register_read("md", md_read); } /* void module_register */ diff --git a/src/memcachec.c b/src/memcachec.c index 766637b7..bebbe401 100644 --- a/src/memcachec.c +++ b/src/memcachec.c @@ -72,20 +72,20 @@ static web_page_t *pages_g = NULL; /* * Private functions */ -static void cmc_web_match_free (web_match_t *wm) /* {{{ */ +static void cmc_web_match_free(web_match_t *wm) /* {{{ */ { if (wm == NULL) return; - sfree (wm->regex); - sfree (wm->type); - sfree (wm->instance); - match_destroy (wm->match); - cmc_web_match_free (wm->next); - sfree (wm); + sfree(wm->regex); + sfree(wm->type); + sfree(wm->instance); + match_destroy(wm->match); + cmc_web_match_free(wm->next); + sfree(wm); } /* }}} void cmc_web_match_free */ -static void cmc_web_page_free (web_page_t *wp) /* {{{ */ +static void cmc_web_page_free(web_page_t *wp) /* {{{ */ { if (wp == NULL) return; @@ -94,99 +94,87 @@ static void cmc_web_page_free (web_page_t *wp) /* {{{ */ memcached_free(wp->memc); wp->memc = NULL; - sfree (wp->instance); - sfree (wp->server); - sfree (wp->key); - sfree (wp->buffer); + sfree(wp->instance); + sfree(wp->server); + sfree(wp->key); + sfree(wp->buffer); - cmc_web_match_free (wp->matches); - cmc_web_page_free (wp->next); - sfree (wp); + cmc_web_match_free(wp->matches); + cmc_web_page_free(wp->next); + sfree(wp); } /* }}} void cmc_web_page_free */ -static int cmc_page_init_memc (web_page_t *wp) /* {{{ */ +static int cmc_page_init_memc(web_page_t *wp) /* {{{ */ { memcached_server_st *server; wp->memc = memcached_create(NULL); - if (wp->memc == NULL) - { - ERROR ("memcachec plugin: memcached_create failed."); + if (wp->memc == NULL) { + ERROR("memcachec plugin: memcached_create failed."); return (-1); } - server = memcached_servers_parse (wp->server); - memcached_server_push (wp->memc, server); - memcached_server_list_free (server); + server = memcached_servers_parse(wp->server); + memcached_server_push(wp->memc, server); + memcached_server_list_free(server); return (0); } /* }}} int cmc_page_init_memc */ -static int cmc_config_add_string (const char *name, char **dest, /* {{{ */ - oconfig_item_t *ci) -{ - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("memcachec plugin: `%s' needs exactly one string argument.", name); +static int cmc_config_add_string(const char *name, char **dest, /* {{{ */ + oconfig_item_t *ci) { + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("memcachec plugin: `%s' needs exactly one string argument.", name); return (-1); } - sfree (*dest); - *dest = strdup (ci->values[0].value.string); + sfree(*dest); + *dest = strdup(ci->values[0].value.string); if (*dest == NULL) return (-1); return (0); } /* }}} int cmc_config_add_string */ -static int cmc_config_add_match_dstype (int *dstype_ret, /* {{{ */ - oconfig_item_t *ci) -{ +static int cmc_config_add_match_dstype(int *dstype_ret, /* {{{ */ + oconfig_item_t *ci) { int dstype; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("memcachec plugin: `DSType' needs exactly one string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("memcachec plugin: `DSType' needs exactly one string argument."); return (-1); } - if (strncasecmp ("Gauge", ci->values[0].value.string, - strlen ("Gauge")) == 0) - { + if (strncasecmp("Gauge", ci->values[0].value.string, strlen("Gauge")) == 0) { dstype = UTILS_MATCH_DS_TYPE_GAUGE; - if (strcasecmp ("GaugeAverage", ci->values[0].value.string) == 0) + if (strcasecmp("GaugeAverage", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_GAUGE_AVERAGE; - else if (strcasecmp ("GaugeMin", ci->values[0].value.string) == 0) + else if (strcasecmp("GaugeMin", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_GAUGE_MIN; - else if (strcasecmp ("GaugeMax", ci->values[0].value.string) == 0) + else if (strcasecmp("GaugeMax", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_GAUGE_MAX; - else if (strcasecmp ("GaugeLast", ci->values[0].value.string) == 0) + else if (strcasecmp("GaugeLast", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_GAUGE_LAST; else dstype = 0; - } - else if (strncasecmp ("Counter", ci->values[0].value.string, - strlen ("Counter")) == 0) - { + } else if (strncasecmp("Counter", ci->values[0].value.string, + strlen("Counter")) == 0) { dstype = UTILS_MATCH_DS_TYPE_COUNTER; - if (strcasecmp ("CounterSet", ci->values[0].value.string) == 0) + if (strcasecmp("CounterSet", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_COUNTER_SET; - else if (strcasecmp ("CounterAdd", ci->values[0].value.string) == 0) + else if (strcasecmp("CounterAdd", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_COUNTER_ADD; - else if (strcasecmp ("CounterInc", ci->values[0].value.string) == 0) + else if (strcasecmp("CounterInc", ci->values[0].value.string) == 0) dstype |= UTILS_MATCH_CF_COUNTER_INC; else dstype = 0; - } - else - { + } else { dstype = 0; } - if (dstype == 0) - { - WARNING ("memcachec plugin: `%s' is not a valid argument to `DSType'.", - ci->values[0].value.string); + if (dstype == 0) { + WARNING("memcachec plugin: `%s' is not a valid argument to `DSType'.", + ci->values[0].value.string); return (-1); } @@ -194,42 +182,38 @@ static int cmc_config_add_match_dstype (int *dstype_ret, /* {{{ */ return (0); } /* }}} int cmc_config_add_match_dstype */ -static int cmc_config_add_match (web_page_t *page, /* {{{ */ - oconfig_item_t *ci) -{ +static int cmc_config_add_match(web_page_t *page, /* {{{ */ + oconfig_item_t *ci) { web_match_t *match; int status; - if (ci->values_num != 0) - { - WARNING ("memcachec plugin: Ignoring arguments for the `Match' block."); + if (ci->values_num != 0) { + WARNING("memcachec plugin: Ignoring arguments for the `Match' block."); } - match = calloc (1, sizeof (*match)); - if (match == NULL) - { - ERROR ("memcachec plugin: calloc failed."); + match = calloc(1, sizeof(*match)); + if (match == NULL) { + ERROR("memcachec plugin: calloc failed."); return (-1); } status = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Regex", child->key) == 0) - status = cmc_config_add_string ("Regex", &match->regex, child); - else if (strcasecmp ("ExcludeRegex", child->key) == 0) - status = cmc_config_add_string ("ExcludeRegex", &match->exclude_regex, child); - else if (strcasecmp ("DSType", child->key) == 0) - status = cmc_config_add_match_dstype (&match->dstype, child); - else if (strcasecmp ("Type", child->key) == 0) - status = cmc_config_add_string ("Type", &match->type, child); - else if (strcasecmp ("Instance", child->key) == 0) - status = cmc_config_add_string ("Instance", &match->instance, child); - else - { - WARNING ("memcachec plugin: Option `%s' not allowed here.", child->key); + if (strcasecmp("Regex", child->key) == 0) + status = cmc_config_add_string("Regex", &match->regex, child); + else if (strcasecmp("ExcludeRegex", child->key) == 0) + status = + cmc_config_add_string("ExcludeRegex", &match->exclude_regex, child); + else if (strcasecmp("DSType", child->key) == 0) + status = cmc_config_add_match_dstype(&match->dstype, child); + else if (strcasecmp("Type", child->key) == 0) + status = cmc_config_add_string("Type", &match->type, child); + else if (strcasecmp("Instance", child->key) == 0) + status = cmc_config_add_string("Instance", &match->instance, child); + else { + WARNING("memcachec plugin: Option `%s' not allowed here.", child->key); status = -1; } @@ -237,45 +221,37 @@ static int cmc_config_add_match (web_page_t *page, /* {{{ */ break; } /* for (i = 0; i < ci->children_num; i++) */ - while (status == 0) - { - if (match->regex == NULL) - { - WARNING ("memcachec plugin: `Regex' missing in `Match' block."); + while (status == 0) { + if (match->regex == NULL) { + WARNING("memcachec plugin: `Regex' missing in `Match' block."); status = -1; } - if (match->type == NULL) - { - WARNING ("memcachec plugin: `Type' missing in `Match' block."); + if (match->type == NULL) { + WARNING("memcachec plugin: `Type' missing in `Match' block."); status = -1; } - if (match->dstype == 0) - { - WARNING ("memcachec plugin: `DSType' missing in `Match' block."); + if (match->dstype == 0) { + WARNING("memcachec plugin: `DSType' missing in `Match' block."); status = -1; } break; } /* while (status == 0) */ - if (status != 0) - { - cmc_web_match_free (match); + if (status != 0) { + cmc_web_match_free(match); return (status); } - match->match = match_create_simple (match->regex, match->exclude_regex, - match->dstype); - if (match->match == NULL) - { - ERROR ("memcachec plugin: match_create_simple failed."); - cmc_web_match_free (match); + match->match = + match_create_simple(match->regex, match->exclude_regex, match->dstype); + if (match->match == NULL) { + ERROR("memcachec plugin: match_create_simple failed."); + cmc_web_match_free(match); return (-1); - } - else - { + } else { web_match_t *prev; prev = page->matches; @@ -291,50 +267,46 @@ static int cmc_config_add_match (web_page_t *page, /* {{{ */ return (0); } /* }}} int cmc_config_add_match */ -static int cmc_config_add_page (oconfig_item_t *ci) /* {{{ */ +static int cmc_config_add_page(oconfig_item_t *ci) /* {{{ */ { web_page_t *page; int status; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("memcachec plugin: `Page' blocks need exactly one string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING( + "memcachec plugin: `Page' blocks need exactly one string argument."); return (-1); } - page = calloc (1, sizeof (*page)); - if (page == NULL) - { - ERROR ("memcachec plugin: calloc failed."); + page = calloc(1, sizeof(*page)); + if (page == NULL) { + ERROR("memcachec plugin: calloc failed."); return (-1); } page->server = NULL; page->key = NULL; - page->instance = strdup (ci->values[0].value.string); - if (page->instance == NULL) - { - ERROR ("memcachec plugin: strdup failed."); - sfree (page); + page->instance = strdup(ci->values[0].value.string); + if (page->instance == NULL) { + ERROR("memcachec plugin: strdup failed."); + sfree(page); return (-1); } /* Process all children */ status = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Server", child->key) == 0) - status = cmc_config_add_string ("Server", &page->server, child); - else if (strcasecmp ("Key", child->key) == 0) - status = cmc_config_add_string ("Key", &page->key, child); - else if (strcasecmp ("Match", child->key) == 0) + if (strcasecmp("Server", child->key) == 0) + status = cmc_config_add_string("Server", &page->server, child); + 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'. */ - cmc_config_add_match (page, child); - else - { - WARNING ("memcachec plugin: Option `%s' not allowed here.", child->key); + cmc_config_add_match(page, child); + else { + WARNING("memcachec plugin: Option `%s' not allowed here.", child->key); status = -1; } @@ -343,45 +315,40 @@ static int cmc_config_add_page (oconfig_item_t *ci) /* {{{ */ } /* for (i = 0; i < ci->children_num; i++) */ /* Additionial sanity checks and libmemcached initialization. */ - while (status == 0) - { - if (page->server == NULL) - { - WARNING ("memcachec plugin: `Server' missing in `Page' block."); + while (status == 0) { + if (page->server == NULL) { + WARNING("memcachec plugin: `Server' missing in `Page' block."); status = -1; } - if (page->key == NULL) - { - WARNING ("memcachec plugin: `Key' missing in `Page' block."); + if (page->key == NULL) { + WARNING("memcachec plugin: `Key' missing in `Page' block."); status = -1; } - if (page->matches == NULL) - { - assert (page->instance != NULL); - WARNING ("memcachec plugin: No (valid) `Match' block " - "within `Page' block `%s'.", page->instance); + if (page->matches == NULL) { + assert(page->instance != NULL); + WARNING("memcachec plugin: No (valid) `Match' block " + "within `Page' block `%s'.", + page->instance); status = -1; } if (status == 0) - status = cmc_page_init_memc (page); + status = cmc_page_init_memc(page); break; } /* while (status == 0) */ - if (status != 0) - { - cmc_web_page_free (page); + if (status != 0) { + cmc_web_page_free(page); return (status); } /* Add the new page to the linked list */ if (pages_g == NULL) pages_g = page; - else - { + else { web_page_t *prev; prev = pages_g; @@ -393,7 +360,7 @@ static int cmc_config_add_page (oconfig_item_t *ci) /* {{{ */ return (0); } /* }}} int cmc_config_add_page */ -static int cmc_config (oconfig_item_t *ci) /* {{{ */ +static int cmc_config(oconfig_item_t *ci) /* {{{ */ { int success; int errors; @@ -402,60 +369,53 @@ static int cmc_config (oconfig_item_t *ci) /* {{{ */ success = 0; errors = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Page", child->key) == 0) - { - status = cmc_config_add_page (child); + if (strcasecmp("Page", child->key) == 0) { + status = cmc_config_add_page(child); if (status == 0) success++; else errors++; - } - else - { - WARNING ("memcachec plugin: Option `%s' not allowed here.", child->key); + } else { + WARNING("memcachec plugin: Option `%s' not allowed here.", child->key); errors++; } } - if ((success == 0) && (errors > 0)) - { - ERROR ("memcachec plugin: All statements failed."); + if ((success == 0) && (errors > 0)) { + ERROR("memcachec plugin: All statements failed."); return (-1); } return (0); } /* }}} int cmc_config */ -static int cmc_init (void) /* {{{ */ +static int cmc_init(void) /* {{{ */ { - if (pages_g == NULL) - { - INFO ("memcachec plugin: No pages have been defined."); + if (pages_g == NULL) { + INFO("memcachec plugin: No pages have been defined."); return (-1); } return (0); } /* }}} int cmc_init */ -static void cmc_submit (const web_page_t *wp, const web_match_t *wm, /* {{{ */ - value_t value) -{ +static void cmc_submit(const web_page_t *wp, const web_match_t *wm, /* {{{ */ + value_t value) { value_list_t vl = VALUE_LIST_INIT; vl.values = &value; vl.values_len = 1; - sstrncpy (vl.plugin, "memcachec", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, wp->instance, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, wm->type, sizeof (vl.type)); - sstrncpy (vl.type_instance, wm->instance, sizeof (vl.type_instance)); + sstrncpy(vl.plugin, "memcachec", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, wp->instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, wm->type, sizeof(vl.type)); + sstrncpy(vl.type_instance, wm->instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* }}} void cmc_submit */ -static int cmc_read_page (web_page_t *wp) /* {{{ */ +static int cmc_read_page(web_page_t *wp) /* {{{ */ { memcached_return rc; size_t string_length; @@ -465,64 +425,59 @@ static int cmc_read_page (web_page_t *wp) /* {{{ */ if (wp->memc == NULL) return (-1); - wp->buffer = memcached_get (wp->memc, wp->key, strlen (wp->key), - &string_length, &flags, &rc); - if (rc != MEMCACHED_SUCCESS) - { - ERROR ("memcachec plugin: memcached_get failed: %s", - memcached_strerror (wp->memc, rc)); + wp->buffer = memcached_get(wp->memc, wp->key, strlen(wp->key), &string_length, + &flags, &rc); + if (rc != MEMCACHED_SUCCESS) { + ERROR("memcachec plugin: memcached_get failed: %s", + memcached_strerror(wp->memc, rc)); return (-1); } - for (web_match_t *wm = wp->matches; wm != NULL; wm = wm->next) - { + for (web_match_t *wm = wp->matches; wm != NULL; wm = wm->next) { cu_match_value_t *mv; - status = match_apply (wm->match, wp->buffer); - if (status != 0) - { - WARNING ("memcachec plugin: match_apply failed."); + status = match_apply(wm->match, wp->buffer); + if (status != 0) { + WARNING("memcachec plugin: match_apply failed."); continue; } - mv = match_get_user_data (wm->match); - if (mv == NULL) - { - WARNING ("memcachec plugin: match_get_user_data returned NULL."); + mv = match_get_user_data(wm->match); + if (mv == NULL) { + WARNING("memcachec plugin: match_get_user_data returned NULL."); continue; } - cmc_submit (wp, wm, mv->value); - match_value_reset (mv); + cmc_submit(wp, wm, mv->value); + match_value_reset(mv); } /* for (wm = wp->matches; wm != NULL; wm = wm->next) */ - sfree (wp->buffer); + sfree(wp->buffer); return (0); } /* }}} int cmc_read_page */ -static int cmc_read (void) /* {{{ */ +static int cmc_read(void) /* {{{ */ { for (web_page_t *wp = pages_g; wp != NULL; wp = wp->next) - cmc_read_page (wp); + cmc_read_page(wp); return (0); } /* }}} int cmc_read */ -static int cmc_shutdown (void) /* {{{ */ +static int cmc_shutdown(void) /* {{{ */ { - cmc_web_page_free (pages_g); + cmc_web_page_free(pages_g); pages_g = NULL; return (0); } /* }}} int cmc_shutdown */ -void module_register (void) -{ - plugin_register_complex_config ("memcachec", cmc_config); - plugin_register_init ("memcachec", cmc_init); - plugin_register_read ("memcachec", cmc_read); - plugin_register_shutdown ("memcachec", cmc_shutdown); +void module_register(void) { + plugin_register_complex_config("memcachec", cmc_config); + plugin_register_init("memcachec", cmc_init); + plugin_register_read("memcachec", cmc_read); + plugin_register_shutdown("memcachec", cmc_shutdown); } /* void module_register */ /* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/memcached.c b/src/memcached.c index 765a0fd3..79c38a79 100644 --- a/src/memcached.c +++ b/src/memcached.c @@ -34,15 +34,14 @@ #include "plugin.h" #include -#include #include #include +#include #define MEMCACHED_DEF_HOST "127.0.0.1" #define MEMCACHED_DEF_PORT "11211" -struct memcached_s -{ +struct memcached_s { char *name; char *host; char *socket; @@ -53,95 +52,83 @@ typedef struct memcached_s memcached_t; static _Bool memcached_have_instances = 0; -static void memcached_free (void *arg) -{ +static void memcached_free(void *arg) { memcached_t *st = arg; if (st == NULL) return; - sfree (st->name); - sfree (st->host); - sfree (st->socket); - sfree (st->connhost); - sfree (st->connport); - sfree (st); + sfree(st->name); + sfree(st->host); + sfree(st->socket); + sfree(st->connhost); + sfree(st->connport); + sfree(st); } -static int memcached_connect_unix (memcached_t *st) -{ - struct sockaddr_un serv_addr = { 0 }; +static int memcached_connect_unix(memcached_t *st) { + struct sockaddr_un serv_addr = {0}; int fd; serv_addr.sun_family = AF_UNIX; - sstrncpy (serv_addr.sun_path, st->socket, - sizeof (serv_addr.sun_path)); + sstrncpy(serv_addr.sun_path, st->socket, sizeof(serv_addr.sun_path)); /* create our socket descriptor */ - fd = socket (AF_UNIX, SOCK_STREAM, 0); - if (fd < 0) - { + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) { char errbuf[1024]; - ERROR ("memcached plugin: memcached_connect_unix: socket(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("memcached plugin: memcached_connect_unix: socket(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } /* connect to the memcached daemon */ - int status = connect (fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); - if (status != 0) - { - shutdown (fd, SHUT_RDWR); - close (fd); - fd = -1; + int status = connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); + if (status != 0) { + shutdown(fd, SHUT_RDWR); + close(fd); + fd = -1; } return (fd); } /* int memcached_connect_unix */ -static int memcached_connect_inet (memcached_t *st) -{ +static int memcached_connect_inet(memcached_t *st) { struct addrinfo *ai_list; int status; int fd = -1; - struct addrinfo ai_hints = { - .ai_family = AF_UNSPEC, - .ai_flags = AI_ADDRCONFIG, - .ai_socktype = SOCK_STREAM - }; + struct addrinfo ai_hints = {.ai_family = AF_UNSPEC, + .ai_flags = AI_ADDRCONFIG, + .ai_socktype = SOCK_STREAM}; - status = getaddrinfo (st->connhost, st->connport, &ai_hints, &ai_list); - if (status != 0) - { + status = getaddrinfo(st->connhost, st->connport, &ai_hints, &ai_list); + if (status != 0) { char errbuf[1024]; - ERROR ("memcached plugin: memcached_connect_inet: " - "getaddrinfo(%s,%s) failed: %s", - st->connhost, st->connport, - (status == EAI_SYSTEM) - ? sstrerror (errno, errbuf, sizeof (errbuf)) - : gai_strerror (status)); + ERROR("memcached plugin: memcached_connect_inet: " + "getaddrinfo(%s,%s) failed: %s", + st->connhost, st->connport, + (status == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf)) + : gai_strerror(status)); return (-1); } - for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) - { + for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; + ai_ptr = ai_ptr->ai_next) { /* create our socket descriptor */ - fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); - if (fd < 0) - { + fd = socket(ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); + if (fd < 0) { char errbuf[1024]; - WARNING ("memcached plugin: memcached_connect_inet: " - "socket(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + WARNING("memcached plugin: memcached_connect_inet: " + "socket(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); continue; } /* connect to the memcached daemon */ - status = (int) connect (fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); - if (status != 0) - { - shutdown (fd, SHUT_RDWR); - close (fd); + status = (int)connect(fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); + if (status != 0) { + shutdown(fd, SHUT_RDWR); + close(fd); fd = -1; continue; } @@ -150,81 +137,76 @@ static int memcached_connect_inet (memcached_t *st) break; } - freeaddrinfo (ai_list); + freeaddrinfo(ai_list); return (fd); } /* int memcached_connect_inet */ -static int memcached_connect (memcached_t *st) -{ +static int memcached_connect(memcached_t *st) { if (st->socket != NULL) - return (memcached_connect_unix (st)); + return (memcached_connect_unix(st)); else - return (memcached_connect_inet (st)); + return (memcached_connect_inet(st)); } -static int memcached_query_daemon (char *buffer, size_t buffer_size, memcached_t *st) -{ +static int memcached_query_daemon(char *buffer, size_t buffer_size, + memcached_t *st) { int fd, status; size_t buffer_fill; - fd = memcached_connect (st); + fd = memcached_connect(st); if (fd < 0) { - ERROR ("memcached plugin: Instance \"%s\" could not connect to daemon.", - st->name); + ERROR("memcached plugin: Instance \"%s\" could not connect to daemon.", + st->name); return -1; } - status = (int) swrite (fd, "stats\r\n", strlen ("stats\r\n")); - if (status != 0) - { + status = (int)swrite(fd, "stats\r\n", strlen("stats\r\n")); + if (status != 0) { char errbuf[1024]; - ERROR ("memcached plugin: write(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("memcached plugin: write(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); shutdown(fd, SHUT_RDWR); - close (fd); + close(fd); return (-1); } /* receive data from the memcached daemon */ - memset (buffer, 0, buffer_size); + memset(buffer, 0, buffer_size); buffer_fill = 0; - while ((status = (int) recv (fd, buffer + buffer_fill, - buffer_size - buffer_fill, /* flags = */ 0)) != 0) - { + while ((status = (int)recv(fd, buffer + buffer_fill, + buffer_size - buffer_fill, /* flags = */ 0)) != + 0) { char const end_token[5] = {'E', 'N', 'D', '\r', '\n'}; - if (status < 0) - { + if (status < 0) { char errbuf[1024]; if ((errno == EAGAIN) || (errno == EINTR)) - continue; + continue; - ERROR ("memcached: Error reading from socket: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("memcached: Error reading from socket: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); shutdown(fd, SHUT_RDWR); - close (fd); + close(fd); return (-1); } - buffer_fill += (size_t) status; - if (buffer_fill > buffer_size) - { + buffer_fill += (size_t)status; + if (buffer_fill > buffer_size) { buffer_fill = buffer_size; - WARNING ("memcached plugin: Message was truncated."); + WARNING("memcached plugin: Message was truncated."); break; } /* If buffer ends in end_token, we have all the data. */ - if (memcmp (buffer + buffer_fill - sizeof (end_token), - end_token, sizeof (end_token)) == 0) + if (memcmp(buffer + buffer_fill - sizeof(end_token), end_token, + sizeof(end_token)) == 0) break; } /* while (recv) */ status = 0; - if (buffer_fill == 0) - { - WARNING ("memcached plugin: No data returned by memcached."); + if (buffer_fill == 0) { + WARNING("memcached plugin: No data returned by memcached."); status = -1; } @@ -233,85 +215,77 @@ static int memcached_query_daemon (char *buffer, size_t buffer_size, memcached_t return (status); } /* int memcached_query_daemon */ -static void memcached_init_vl (value_list_t *vl, memcached_t const *st) -{ - sstrncpy (vl->plugin, "memcached", sizeof (vl->plugin)); +static void memcached_init_vl(value_list_t *vl, memcached_t const *st) { + sstrncpy(vl->plugin, "memcached", sizeof(vl->plugin)); if (st->host != NULL) - sstrncpy (vl->host, st->host, sizeof (vl->host)); + sstrncpy(vl->host, st->host, sizeof(vl->host)); if (st->name != NULL) - sstrncpy (vl->plugin_instance, st->name, sizeof (vl->plugin_instance)); + sstrncpy(vl->plugin_instance, st->name, sizeof(vl->plugin_instance)); } -static void submit_derive (const char *type, const char *type_inst, - derive_t value, memcached_t *st) -{ +static void submit_derive(const char *type, const char *type_inst, + derive_t value, memcached_t *st) { value_list_t vl = VALUE_LIST_INIT; - memcached_init_vl (&vl, st); - vl.values = &(value_t) { .derive = value }; + memcached_init_vl(&vl, st); + vl.values = &(value_t){.derive = value}; vl.values_len = 1; - sstrncpy (vl.type, type, sizeof (vl.type)); + sstrncpy(vl.type, type, sizeof(vl.type)); if (type_inst != NULL) - sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, type_inst, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static void submit_derive2 (const char *type, const char *type_inst, - derive_t value0, derive_t value1, memcached_t *st) -{ +static void submit_derive2(const char *type, const char *type_inst, + derive_t value0, derive_t value1, memcached_t *st) { value_list_t vl = VALUE_LIST_INIT; value_t values[] = { - { .derive = value0 }, - { .derive = value1 }, + {.derive = value0}, {.derive = value1}, }; - memcached_init_vl (&vl, st); + memcached_init_vl(&vl, st); vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - sstrncpy (vl.type, type, sizeof (vl.type)); + vl.values_len = STATIC_ARRAY_SIZE(values); + sstrncpy(vl.type, type, sizeof(vl.type)); if (type_inst != NULL) - sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, type_inst, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static void submit_gauge (const char *type, const char *type_inst, - gauge_t value, memcached_t *st) -{ +static void submit_gauge(const char *type, const char *type_inst, gauge_t value, + memcached_t *st) { value_list_t vl = VALUE_LIST_INIT; - memcached_init_vl (&vl, st); - vl.values = &(value_t) { .gauge = value }; + memcached_init_vl(&vl, st); + vl.values = &(value_t){.gauge = value}; vl.values_len = 1; - sstrncpy (vl.type, type, sizeof (vl.type)); + sstrncpy(vl.type, type, sizeof(vl.type)); if (type_inst != NULL) - sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, type_inst, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static void submit_gauge2 (const char *type, const char *type_inst, - gauge_t value0, gauge_t value1, memcached_t *st) -{ +static void submit_gauge2(const char *type, const char *type_inst, + gauge_t value0, gauge_t value1, memcached_t *st) { value_list_t vl = VALUE_LIST_INIT; value_t values[] = { - { .gauge = value0 }, - { .gauge = value1 }, + {.gauge = value0}, {.gauge = value1}, }; - memcached_init_vl (&vl, st); + memcached_init_vl(&vl, st); vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - sstrncpy (vl.type, type, sizeof (vl.type)); + vl.values_len = STATIC_ARRAY_SIZE(values); + sstrncpy(vl.type, type, sizeof(vl.type)); if (type_inst != NULL) - sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, type_inst, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static int memcached_read (user_data_t *user_data) -{ +static int memcached_read(user_data_t *user_data) { char buf[4096]; char *fields[3]; char *ptr; @@ -336,17 +310,16 @@ static int memcached_read (user_data_t *user_data) st = user_data->data; /* get data from daemon */ - if (memcached_query_daemon (buf, sizeof (buf), st) < 0) { + if (memcached_query_daemon(buf, sizeof(buf), st) < 0) { return -1; } -#define FIELD_IS(cnst) \ - (((sizeof(cnst) - 1) == name_len) && (strcmp (cnst, fields[1]) == 0)) +#define FIELD_IS(cnst) \ + (((sizeof(cnst) - 1) == name_len) && (strcmp(cnst, fields[1]) == 0)) ptr = buf; saveptr = NULL; - while ((line = strtok_r (ptr, "\n\r", &saveptr)) != NULL) - { + while ((line = strtok_r(ptr, "\n\r", &saveptr)) != NULL) { int name_len; ptr = NULL; @@ -367,169 +340,139 @@ static int memcached_read (user_data_t *user_data) /* * CPU time consumed by the memcached process */ - if (FIELD_IS ("rusage_user")) - { - rusage_user = atoll (fields[2]); - } - else if (FIELD_IS ("rusage_system")) - { + if (FIELD_IS("rusage_user")) { + rusage_user = atoll(fields[2]); + } else if (FIELD_IS("rusage_system")) { rusage_syst = atoll(fields[2]); } /* * Number of threads of this instance */ - else if (FIELD_IS ("threads")) - { - submit_gauge2 ("ps_count", NULL, NAN, atof (fields[2]), st); + else if (FIELD_IS("threads")) { + submit_gauge2("ps_count", NULL, NAN, atof(fields[2]), st); } /* * Number of items stored */ - else if (FIELD_IS ("curr_items")) - { - submit_gauge ("memcached_items", "current", atof (fields[2]), st); + else if (FIELD_IS("curr_items")) { + submit_gauge("memcached_items", "current", atof(fields[2]), st); } /* * Number of bytes used and available (total - used) */ - else if (FIELD_IS ("bytes")) - { - bytes_used = atof (fields[2]); - } - else if (FIELD_IS ("limit_maxbytes")) - { + else if (FIELD_IS("bytes")) { + bytes_used = atof(fields[2]); + } else if (FIELD_IS("limit_maxbytes")) { bytes_total = atof(fields[2]); } /* * Connections */ - else if (FIELD_IS ("curr_connections")) - { - submit_gauge ("memcached_connections", "current", atof (fields[2]), st); - } - else if (FIELD_IS ("listen_disabled_num")) - { - submit_derive ("connections", "listen_disabled", atof (fields[2]), st); + else if (FIELD_IS("curr_connections")) { + submit_gauge("memcached_connections", "current", atof(fields[2]), st); + } else if (FIELD_IS("listen_disabled_num")) { + submit_derive("connections", "listen_disabled", atof(fields[2]), st); } /* * Commands */ - else if ((name_len > 4) && (strncmp (fields[1], "cmd_", 4) == 0)) - { + else if ((name_len > 4) && (strncmp(fields[1], "cmd_", 4) == 0)) { const char *name = fields[1] + 4; - submit_derive ("memcached_command", name, atoll (fields[2]), st); - if (strcmp (name, "get") == 0) - gets = atof (fields[2]); + submit_derive("memcached_command", name, atoll(fields[2]), st); + if (strcmp(name, "get") == 0) + gets = atof(fields[2]); } /* * Increment/Decrement */ - else if (FIELD_IS("incr_misses")) - { - derive_t incr_count = atoll (fields[2]); - submit_derive ("memcached_ops", "incr_misses", incr_count, st); + else if (FIELD_IS("incr_misses")) { + derive_t incr_count = atoll(fields[2]); + submit_derive("memcached_ops", "incr_misses", incr_count, st); incr += incr_count; - } - else if (FIELD_IS ("incr_hits")) - { - derive_t incr_count = atoll (fields[2]); - submit_derive ("memcached_ops", "incr_hits", incr_count, st); - incr_hits = atof (fields[2]); + } else if (FIELD_IS("incr_hits")) { + derive_t incr_count = atoll(fields[2]); + submit_derive("memcached_ops", "incr_hits", incr_count, st); + incr_hits = atof(fields[2]); incr += incr_count; - } - else if (FIELD_IS ("decr_misses")) - { - derive_t decr_count = atoll (fields[2]); - submit_derive ("memcached_ops", "decr_misses", decr_count, st); + } else if (FIELD_IS("decr_misses")) { + derive_t decr_count = atoll(fields[2]); + submit_derive("memcached_ops", "decr_misses", decr_count, st); decr += decr_count; - } - else if (FIELD_IS ("decr_hits")) - { - derive_t decr_count = atoll (fields[2]); - submit_derive ("memcached_ops", "decr_hits", decr_count, st); - decr_hits = atof (fields[2]); + } else if (FIELD_IS("decr_hits")) { + derive_t decr_count = atoll(fields[2]); + submit_derive("memcached_ops", "decr_hits", decr_count, st); + decr_hits = atof(fields[2]); decr += decr_count; } /* - * Operations on the cache, i. e. cache hits, cache misses and evictions of items + * Operations on the cache, i. e. cache hits, cache misses and evictions of + * items */ - else if (FIELD_IS ("get_hits")) - { - submit_derive ("memcached_ops", "hits", atoll (fields[2]), st); - hits = atof (fields[2]); - } - else if (FIELD_IS ("get_misses")) - { - submit_derive ("memcached_ops", "misses", atoll (fields[2]), st); - } - else if (FIELD_IS ("evictions")) - { - submit_derive ("memcached_ops", "evictions", atoll (fields[2]), st); + else if (FIELD_IS("get_hits")) { + submit_derive("memcached_ops", "hits", atoll(fields[2]), st); + hits = atof(fields[2]); + } else if (FIELD_IS("get_misses")) { + submit_derive("memcached_ops", "misses", atoll(fields[2]), st); + } else if (FIELD_IS("evictions")) { + submit_derive("memcached_ops", "evictions", atoll(fields[2]), st); } /* * Network traffic */ - else if (FIELD_IS ("bytes_read")) - { - octets_rx = atoll (fields[2]); - } - else if (FIELD_IS ("bytes_written")) - { - octets_tx = atoll (fields[2]); + else if (FIELD_IS("bytes_read")) { + octets_rx = atoll(fields[2]); + } else if (FIELD_IS("bytes_written")) { + octets_tx = atoll(fields[2]); } } /* while ((line = strtok_r (ptr, "\n\r", &saveptr)) != NULL) */ - if (!isnan (bytes_used) && !isnan (bytes_total) && (bytes_used <= bytes_total)) - submit_gauge2 ("df", "cache", bytes_used, bytes_total - bytes_used, st); + if (!isnan(bytes_used) && !isnan(bytes_total) && (bytes_used <= bytes_total)) + submit_gauge2("df", "cache", bytes_used, bytes_total - bytes_used, st); if ((rusage_user != 0) || (rusage_syst != 0)) - submit_derive2 ("ps_cputime", NULL, rusage_user, rusage_syst, st); + submit_derive2("ps_cputime", NULL, rusage_user, rusage_syst, st); if ((octets_rx != 0) || (octets_tx != 0)) - submit_derive2 ("memcached_octets", NULL, octets_rx, octets_tx, st); + submit_derive2("memcached_octets", NULL, octets_rx, octets_tx, st); - if (!isnan (gets) && !isnan (hits)) - { + if (!isnan(gets) && !isnan(hits)) { gauge_t rate = NAN; if (gets != 0.0) rate = 100.0 * hits / gets; - submit_gauge ("percent", "hitratio", rate, st); + submit_gauge("percent", "hitratio", rate, st); } - if (!isnan (incr_hits) && incr != 0) - { + if (!isnan(incr_hits) && incr != 0) { gauge_t incr_rate = 100.0 * incr_hits / incr; - submit_gauge ("percent", "incr_hitratio", incr_rate, st); - submit_derive ("memcached_ops", "incr", incr, st); + submit_gauge("percent", "incr_hitratio", incr_rate, st); + submit_derive("memcached_ops", "incr", incr, st); } - if (!isnan (decr_hits) && decr != 0) - { + if (!isnan(decr_hits) && decr != 0) { gauge_t decr_rate = 100.0 * decr_hits / decr; - submit_gauge ("percent", "decr_hitratio", decr_rate, st); - submit_derive ("memcached_ops", "decr", decr, st); + submit_gauge("percent", "decr_hitratio", decr_rate, st); + submit_derive("memcached_ops", "decr", decr, st); } return 0; } /* int memcached_read */ -static int memcached_add_read_callback (memcached_t *st) -{ - char callback_name[3*DATA_MAX_NAME_LEN]; +static int memcached_add_read_callback(memcached_t *st) { + char callback_name[3 * DATA_MAX_NAME_LEN]; int status; - ssnprintf (callback_name, sizeof (callback_name), "memcached/%s", - (st->name != NULL) ? st->name : "__legacy__"); + ssnprintf(callback_name, sizeof(callback_name), "memcached/%s", + (st->name != NULL) ? st->name : "__legacy__"); /* If no
used then: * - Connect to the destination specified by , if present. @@ -542,44 +485,38 @@ static int memcached_add_read_callback (memcached_t *st) * If
used then host may be set to "localhost" or "127.0.0.1" * explicitly. */ - if (st->connhost == NULL) - { - if (st->host) - { + if (st->connhost == NULL) { + if (st->host) { st->connhost = strdup(st->host); if (st->connhost == NULL) return (ENOMEM); - if ((strcmp ("127.0.0.1", st->host) == 0) - || (strcmp ("localhost", st->host) == 0)) + if ((strcmp("127.0.0.1", st->host) == 0) || + (strcmp("localhost", st->host) == 0)) sfree(st->host); - } - else - { + } else { st->connhost = strdup(MEMCACHED_DEF_HOST); if (st->connhost == NULL) return (ENOMEM); } } - if (st->connport == NULL) - { - st->connport = strdup(MEMCACHED_DEF_PORT); - if (st->connport == NULL) - return (ENOMEM); + if (st->connport == NULL) { + st->connport = strdup(MEMCACHED_DEF_PORT); + if (st->connport == NULL) + return (ENOMEM); } - assert (st->connhost != NULL); - assert (st->connport != NULL); + assert(st->connhost != NULL); + assert(st->connport != NULL); - status = plugin_register_complex_read (/* group = */ "memcached", + status = plugin_register_complex_read( + /* group = */ "memcached", /* name = */ callback_name, /* callback = */ memcached_read, - /* interval = */ 0, - &(user_data_t) { - .data = st, - .free_func = memcached_free, - }); + /* interval = */ 0, &(user_data_t){ + .data = st, .free_func = memcached_free, + }); return (status); } /* int memcached_add_read_callback */ @@ -593,18 +530,16 @@ static int memcached_add_read_callback (memcached_t *st) * * */ -static int config_add_instance(oconfig_item_t *ci) -{ +static int config_add_instance(oconfig_item_t *ci) { memcached_t *st; int status = 0; /* Disable automatic generation of default instance in the init callback. */ memcached_have_instances = 1; - st = calloc (1, sizeof (*st)); - if (st == NULL) - { - ERROR ("memcached plugin: calloc failed."); + st = calloc(1, sizeof(*st)); + if (st == NULL) { + ERROR("memcached plugin: calloc failed."); return (ENOMEM); } @@ -614,31 +549,27 @@ static int config_add_instance(oconfig_item_t *ci) st->connhost = NULL; st->connport = NULL; - if (strcasecmp (ci->key, "Instance") == 0) - status = cf_util_get_string (ci, &st->name); + if (strcasecmp(ci->key, "Instance") == 0) + status = cf_util_get_string(ci, &st->name); - if (status != 0) - { - sfree (st); + if (status != 0) { + sfree(st); return (status); } - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Socket", child->key) == 0) - status = cf_util_get_string (child, &st->socket); - else if (strcasecmp ("Host", child->key) == 0) - status = cf_util_get_string (child, &st->host); - else if (strcasecmp ("Address", child->key) == 0) - status = cf_util_get_string (child, &st->connhost); - else if (strcasecmp ("Port", child->key) == 0) - status = cf_util_get_service (child, &st->connport); - else - { - WARNING ("memcached plugin: Option `%s' not allowed here.", - child->key); + if (strcasecmp("Socket", child->key) == 0) + status = cf_util_get_string(child, &st->socket); + else if (strcasecmp("Host", child->key) == 0) + status = cf_util_get_string(child, &st->host); + else if (strcasecmp("Address", child->key) == 0) + status = cf_util_get_string(child, &st->connhost); + else if (strcasecmp("Port", child->key) == 0) + status = cf_util_get_service(child, &st->connport); + else { + WARNING("memcached plugin: Option `%s' not allowed here.", child->key); status = -1; } @@ -647,10 +578,9 @@ static int config_add_instance(oconfig_item_t *ci) } if (status == 0) - status = memcached_add_read_callback (st); + status = memcached_add_read_callback(st); - if (status != 0) - { + if (status != 0) { memcached_free(st); return (-1); } @@ -658,39 +588,32 @@ static int config_add_instance(oconfig_item_t *ci) return (0); } -static int memcached_config (oconfig_item_t *ci) -{ +static int memcached_config(oconfig_item_t *ci) { int status = 0; _Bool have_instance_block = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Instance", child->key) == 0) - { - config_add_instance (child); + if (strcasecmp("Instance", child->key) == 0) { + config_add_instance(child); have_instance_block = 1; - } - else if (!have_instance_block) - { + } else if (!have_instance_block) { /* Non-instance option: Assume legacy configuration (without * blocks) and call config_add_instance() with the block. */ - return (config_add_instance (ci)); - } - else - WARNING ("memcached plugin: The configuration option " - "\"%s\" is not allowed here. Did you " - "forget to add an block " - "around the configuration?", - child->key); + return (config_add_instance(ci)); + } else + WARNING("memcached plugin: The configuration option " + "\"%s\" is not allowed here. Did you " + "forget to add an block " + "around the configuration?", + child->key); } /* for (ci->children) */ return (status); } -static int memcached_init (void) -{ +static int memcached_init(void) { memcached_t *st; int status; @@ -698,7 +621,7 @@ static int memcached_init (void) return (0); /* No instances were configured, lets start a default instance. */ - st = calloc (1, sizeof (*st)); + st = calloc(1, sizeof(*st)); if (st == NULL) return (ENOMEM); st->name = NULL; @@ -707,17 +630,16 @@ static int memcached_init (void) st->connhost = NULL; st->connport = NULL; - status = memcached_add_read_callback (st); + status = memcached_add_read_callback(st); if (status == 0) memcached_have_instances = 1; else - memcached_free (st); + memcached_free(st); return (status); } /* int memcached_init */ -void module_register (void) -{ - plugin_register_complex_config ("memcached", memcached_config); - plugin_register_init ("memcached", memcached_init); +void module_register(void) { + plugin_register_complex_config("memcached", memcached_config); + plugin_register_init("memcached", memcached_init); } diff --git a/src/memory.c b/src/memory.c index 55e7de16..14b35599 100644 --- a/src/memory.c +++ b/src/memory.c @@ -29,35 +29,35 @@ #include "plugin.h" #ifdef HAVE_SYS_SYSCTL_H -# include +#include #endif #ifdef HAVE_SYS_VMMETER_H -# include +#include #endif #ifdef HAVE_MACH_KERN_RETURN_H -# include +#include #endif #ifdef HAVE_MACH_MACH_INIT_H -# include +#include #endif #ifdef HAVE_MACH_MACH_HOST_H -# include +#include #endif #ifdef HAVE_MACH_HOST_PRIV_H -# include +#include #endif #ifdef HAVE_MACH_VM_STATISTICS_H -# include +#include #endif #if HAVE_STATGRAB_H -# include +#include #endif #if HAVE_PERFSTAT -# include -# include +#include +#include #endif /* HAVE_PERFSTAT */ /* vm_statistics_data_t */ @@ -91,34 +91,33 @@ static int pagesize; static int pagesize; /* endif HAVE_PERFSTAT */ #else -# error "No applicable input method." +#error "No applicable input method." #endif static _Bool values_absolute = 1; static _Bool values_percentage = 0; -static int memory_config (oconfig_item_t *ci) /* {{{ */ +static int memory_config(oconfig_item_t *ci) /* {{{ */ { - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - if (strcasecmp ("ValuesAbsolute", child->key) == 0) - cf_util_get_boolean (child, &values_absolute); - else if (strcasecmp ("ValuesPercentage", child->key) == 0) - cf_util_get_boolean (child, &values_percentage); - else - ERROR ("memory plugin: Invalid configuration option: " - "\"%s\".", child->key); - } - - return (0); + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + if (strcasecmp("ValuesAbsolute", child->key) == 0) + cf_util_get_boolean(child, &values_absolute); + else if (strcasecmp("ValuesPercentage", child->key) == 0) + cf_util_get_boolean(child, &values_percentage); + else + ERROR("memory plugin: Invalid configuration option: " + "\"%s\".", + child->key); + } + + return (0); } /* }}} int memory_config */ -static int memory_init (void) -{ +static int memory_init(void) { #if HAVE_HOST_STATISTICS - port_host = mach_host_self (); - host_page_size (port_host, &pagesize); + port_host = mach_host_self(); + host_page_size(port_host, &pagesize); /* #endif HAVE_HOST_STATISTICS */ #elif HAVE_SYSCTLBYNAME @@ -130,28 +129,25 @@ static int memory_init (void) /* #endif KERNEL_LINUX */ #elif defined(HAVE_LIBKSTAT) - /* getpagesize(3C) tells me this does not fail.. */ - pagesize = getpagesize (); - if (get_kstat (&ksp, "unix", 0, "system_pages") != 0) - { - ksp = NULL; - return (-1); - } - if (get_kstat (&ksz, "zfs", 0, "arcstats") != 0) - { - ksz = NULL; - return (-1); - } + /* getpagesize(3C) tells me this does not fail.. */ + pagesize = getpagesize(); + if (get_kstat(&ksp, "unix", 0, "system_pages") != 0) { + ksp = NULL; + return (-1); + } + if (get_kstat(&ksz, "zfs", 0, "arcstats") != 0) { + ksz = NULL; + return (-1); + } /* #endif HAVE_LIBKSTAT */ #elif HAVE_SYSCTL - pagesize = getpagesize (); - if (pagesize <= 0) - { - ERROR ("memory plugin: Invalid pagesize: %i", pagesize); - return (-1); - } + pagesize = getpagesize(); + if (pagesize <= 0) { + ERROR("memory plugin: Invalid pagesize: %i", pagesize); + return (-1); + } /* #endif HAVE_SYSCTL */ #elif HAVE_LIBSTATGRAB @@ -159,384 +155,343 @@ static int memory_init (void) /* #endif HAVE_LIBSTATGRAB */ #elif HAVE_PERFSTAT - pagesize = getpagesize (); + pagesize = getpagesize(); #endif /* HAVE_PERFSTAT */ - return (0); + return (0); } /* int memory_init */ -#define MEMORY_SUBMIT(...) do { \ - if (values_absolute) \ - plugin_dispatch_multivalue (vl, 0, DS_TYPE_GAUGE, __VA_ARGS__, NULL); \ - if (values_percentage) \ - plugin_dispatch_multivalue (vl, 1, DS_TYPE_GAUGE, __VA_ARGS__, NULL); \ -} while (0) +#define MEMORY_SUBMIT(...) \ + do { \ + if (values_absolute) \ + plugin_dispatch_multivalue(vl, 0, DS_TYPE_GAUGE, __VA_ARGS__, NULL); \ + if (values_percentage) \ + plugin_dispatch_multivalue(vl, 1, DS_TYPE_GAUGE, __VA_ARGS__, NULL); \ + } while (0) -static int memory_read_internal (value_list_t *vl) -{ +static int memory_read_internal(value_list_t *vl) { #if HAVE_HOST_STATISTICS - kern_return_t status; - vm_statistics_data_t vm_data; - mach_msg_type_number_t vm_data_len; - - gauge_t wired; - gauge_t active; - gauge_t inactive; - gauge_t free; - - if (!port_host || !pagesize) - return (-1); - - vm_data_len = sizeof (vm_data) / sizeof (natural_t); - if ((status = host_statistics (port_host, HOST_VM_INFO, - (host_info_t) &vm_data, - &vm_data_len)) != KERN_SUCCESS) - { - ERROR ("memory-plugin: host_statistics failed and returned the value %i", (int) status); - return (-1); - } - - /* - * From : - * - * Wired memory - * This information can't be cached to disk, so it must stay in RAM. - * The amount depends on what applications you are using. - * - * Active memory - * This information is currently in RAM and actively being used. - * - * Inactive memory - * This information is no longer being used and has been cached to - * disk, but it will remain in RAM until another application needs - * the space. Leaving this information in RAM is to your advantage if - * you (or a client of your computer) come back to it later. - * - * Free memory - * This memory is not being used. - */ - - wired = (gauge_t) (((uint64_t) vm_data.wire_count) * ((uint64_t) pagesize)); - active = (gauge_t) (((uint64_t) vm_data.active_count) * ((uint64_t) pagesize)); - inactive = (gauge_t) (((uint64_t) vm_data.inactive_count) * ((uint64_t) pagesize)); - free = (gauge_t) (((uint64_t) vm_data.free_count) * ((uint64_t) pagesize)); - - MEMORY_SUBMIT ("wired", wired, - "active", active, - "inactive", inactive, - "free", free); + kern_return_t status; + vm_statistics_data_t vm_data; + mach_msg_type_number_t vm_data_len; + + gauge_t wired; + gauge_t active; + gauge_t inactive; + gauge_t free; + + if (!port_host || !pagesize) + return (-1); + + vm_data_len = sizeof(vm_data) / sizeof(natural_t); + if ((status = host_statistics(port_host, HOST_VM_INFO, (host_info_t)&vm_data, + &vm_data_len)) != KERN_SUCCESS) { + ERROR("memory-plugin: host_statistics failed and returned the value %i", + (int)status); + return (-1); + } + + /* + * From : + * + * Wired memory + * This information can't be cached to disk, so it must stay in RAM. + * The amount depends on what applications you are using. + * + * Active memory + * This information is currently in RAM and actively being used. + * + * Inactive memory + * This information is no longer being used and has been cached to + * disk, but it will remain in RAM until another application needs + * the space. Leaving this information in RAM is to your advantage if + * you (or a client of your computer) come back to it later. + * + * Free memory + * This memory is not being used. + */ + + wired = (gauge_t)(((uint64_t)vm_data.wire_count) * ((uint64_t)pagesize)); + active = (gauge_t)(((uint64_t)vm_data.active_count) * ((uint64_t)pagesize)); + inactive = + (gauge_t)(((uint64_t)vm_data.inactive_count) * ((uint64_t)pagesize)); + free = (gauge_t)(((uint64_t)vm_data.free_count) * ((uint64_t)pagesize)); + + MEMORY_SUBMIT("wired", wired, "active", active, "inactive", inactive, "free", + free); /* #endif HAVE_HOST_STATISTICS */ #elif HAVE_SYSCTLBYNAME - /* - * vm.stats.vm.v_page_size: 4096 - * vm.stats.vm.v_page_count: 246178 - * vm.stats.vm.v_free_count: 28760 - * vm.stats.vm.v_wire_count: 37526 - * vm.stats.vm.v_active_count: 55239 - * vm.stats.vm.v_inactive_count: 113730 - * vm.stats.vm.v_cache_count: 10809 - */ - const char *sysctl_keys[8] = - { - "vm.stats.vm.v_page_size", - "vm.stats.vm.v_page_count", - "vm.stats.vm.v_free_count", - "vm.stats.vm.v_wire_count", - "vm.stats.vm.v_active_count", - "vm.stats.vm.v_inactive_count", - "vm.stats.vm.v_cache_count", - NULL - }; - double sysctl_vals[8]; - - for (int i = 0; sysctl_keys[i] != NULL; i++) - { - int value; - size_t value_len = sizeof (value); - - if (sysctlbyname (sysctl_keys[i], (void *) &value, &value_len, - NULL, 0) == 0) - { - sysctl_vals[i] = value; - DEBUG ("memory plugin: %26s: %g", sysctl_keys[i], sysctl_vals[i]); - } - else - { - sysctl_vals[i] = NAN; - } - } /* for (sysctl_keys) */ - - /* multiply all all page counts with the pagesize */ - for (int i = 1; sysctl_keys[i] != NULL; i++) - if (!isnan (sysctl_vals[i])) - sysctl_vals[i] *= sysctl_vals[0]; - - MEMORY_SUBMIT ("free", (gauge_t) sysctl_vals[2], - "wired", (gauge_t) sysctl_vals[3], - "active", (gauge_t) sysctl_vals[4], - "inactive", (gauge_t) sysctl_vals[5], - "cache", (gauge_t) sysctl_vals[6]); + /* + * vm.stats.vm.v_page_size: 4096 + * vm.stats.vm.v_page_count: 246178 + * vm.stats.vm.v_free_count: 28760 + * vm.stats.vm.v_wire_count: 37526 + * vm.stats.vm.v_active_count: 55239 + * vm.stats.vm.v_inactive_count: 113730 + * vm.stats.vm.v_cache_count: 10809 + */ + const char *sysctl_keys[8] = { + "vm.stats.vm.v_page_size", "vm.stats.vm.v_page_count", + "vm.stats.vm.v_free_count", "vm.stats.vm.v_wire_count", + "vm.stats.vm.v_active_count", "vm.stats.vm.v_inactive_count", + "vm.stats.vm.v_cache_count", NULL}; + double sysctl_vals[8]; + + for (int i = 0; sysctl_keys[i] != NULL; i++) { + int value; + size_t value_len = sizeof(value); + + if (sysctlbyname(sysctl_keys[i], (void *)&value, &value_len, NULL, 0) == + 0) { + sysctl_vals[i] = value; + DEBUG("memory plugin: %26s: %g", sysctl_keys[i], sysctl_vals[i]); + } else { + sysctl_vals[i] = NAN; + } + } /* for (sysctl_keys) */ + + /* multiply all all page counts with the pagesize */ + for (int i = 1; sysctl_keys[i] != NULL; i++) + if (!isnan(sysctl_vals[i])) + sysctl_vals[i] *= sysctl_vals[0]; + + MEMORY_SUBMIT("free", (gauge_t)sysctl_vals[2], "wired", + (gauge_t)sysctl_vals[3], "active", (gauge_t)sysctl_vals[4], + "inactive", (gauge_t)sysctl_vals[5], "cache", + (gauge_t)sysctl_vals[6]); /* #endif HAVE_SYSCTLBYNAME */ #elif KERNEL_LINUX - FILE *fh; - char buffer[1024]; - - char *fields[8]; - int numfields; - - _Bool detailed_slab_info = 0; - - gauge_t mem_total = 0; - gauge_t mem_used = 0; - gauge_t mem_buffered = 0; - gauge_t mem_cached = 0; - gauge_t mem_free = 0; - gauge_t mem_slab_total = 0; - gauge_t mem_slab_reclaimable = 0; - gauge_t mem_slab_unreclaimable = 0; - - if ((fh = fopen ("/proc/meminfo", "r")) == NULL) - { - char errbuf[1024]; - WARNING ("memory: fopen: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - gauge_t *val = NULL; - - if (strncasecmp (buffer, "MemTotal:", 9) == 0) - val = &mem_total; - else if (strncasecmp (buffer, "MemFree:", 8) == 0) - val = &mem_free; - else if (strncasecmp (buffer, "Buffers:", 8) == 0) - val = &mem_buffered; - else if (strncasecmp (buffer, "Cached:", 7) == 0) - val = &mem_cached; - else if (strncasecmp (buffer, "Slab:", 5) == 0) - val = &mem_slab_total; - else if (strncasecmp (buffer, "SReclaimable:", 13) == 0) { - val = &mem_slab_reclaimable; - detailed_slab_info = 1; - } - else if (strncasecmp (buffer, "SUnreclaim:", 11) == 0) { - val = &mem_slab_unreclaimable; - detailed_slab_info = 1; - } - else - continue; - - numfields = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields)); - if (numfields < 2) - continue; - - *val = 1024.0 * atof (fields[1]); - } - - if (fclose (fh)) - { - char errbuf[1024]; - WARNING ("memory: fclose: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - } - - if (mem_total < (mem_free + mem_buffered + mem_cached + mem_slab_total)) - return (-1); - - mem_used = mem_total - (mem_free + mem_buffered + mem_cached + mem_slab_total); - - /* SReclaimable and SUnreclaim were introduced in kernel 2.6.19 - * They sum up to the value of Slab, which is available on older & newer - * kernels. So SReclaimable/SUnreclaim are submitted if available, and Slab - * if not. */ - if (detailed_slab_info) - MEMORY_SUBMIT ("used", mem_used, - "buffered", mem_buffered, - "cached", mem_cached, - "free", mem_free, - "slab_unrecl", mem_slab_unreclaimable, - "slab_recl", mem_slab_reclaimable); - else - MEMORY_SUBMIT ("used", mem_used, - "buffered", mem_buffered, - "cached", mem_cached, - "free", mem_free, - "slab", mem_slab_total); + FILE *fh; + char buffer[1024]; + + char *fields[8]; + int numfields; + + _Bool detailed_slab_info = 0; + + gauge_t mem_total = 0; + gauge_t mem_used = 0; + gauge_t mem_buffered = 0; + gauge_t mem_cached = 0; + gauge_t mem_free = 0; + gauge_t mem_slab_total = 0; + gauge_t mem_slab_reclaimable = 0; + gauge_t mem_slab_unreclaimable = 0; + + if ((fh = fopen("/proc/meminfo", "r")) == NULL) { + char errbuf[1024]; + WARNING("memory: fopen: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + gauge_t *val = NULL; + + if (strncasecmp(buffer, "MemTotal:", 9) == 0) + val = &mem_total; + else if (strncasecmp(buffer, "MemFree:", 8) == 0) + val = &mem_free; + else if (strncasecmp(buffer, "Buffers:", 8) == 0) + val = &mem_buffered; + else if (strncasecmp(buffer, "Cached:", 7) == 0) + val = &mem_cached; + else if (strncasecmp(buffer, "Slab:", 5) == 0) + val = &mem_slab_total; + else if (strncasecmp(buffer, "SReclaimable:", 13) == 0) { + val = &mem_slab_reclaimable; + detailed_slab_info = 1; + } else if (strncasecmp(buffer, "SUnreclaim:", 11) == 0) { + val = &mem_slab_unreclaimable; + detailed_slab_info = 1; + } else + continue; + + numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + if (numfields < 2) + continue; + + *val = 1024.0 * atof(fields[1]); + } + + if (fclose(fh)) { + char errbuf[1024]; + WARNING("memory: fclose: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + } + + if (mem_total < (mem_free + mem_buffered + mem_cached + mem_slab_total)) + return (-1); + + mem_used = + mem_total - (mem_free + mem_buffered + mem_cached + mem_slab_total); + + /* SReclaimable and SUnreclaim were introduced in kernel 2.6.19 + * They sum up to the value of Slab, which is available on older & newer + * kernels. So SReclaimable/SUnreclaim are submitted if available, and Slab + * if not. */ + if (detailed_slab_info) + MEMORY_SUBMIT("used", mem_used, "buffered", mem_buffered, "cached", + mem_cached, "free", mem_free, "slab_unrecl", + mem_slab_unreclaimable, "slab_recl", mem_slab_reclaimable); + else + MEMORY_SUBMIT("used", mem_used, "buffered", mem_buffered, "cached", + mem_cached, "free", mem_free, "slab", mem_slab_total); /* #endif KERNEL_LINUX */ #elif HAVE_LIBKSTAT - /* Most of the additions here were taken as-is from the k9toolkit from - * Brendan Gregg and are subject to change I guess */ - long long mem_used; - long long mem_free; - long long mem_lock; - long long mem_kern; - long long mem_unus; - long long arcsize; - - - long long pp_kernel; - long long physmem; - long long availrmem; - - if (ksp == NULL) - return (-1); - if (ksz == NULL) - return (-1); - - mem_used = get_kstat_value (ksp, "pagestotal"); - mem_free = get_kstat_value (ksp, "pagesfree"); - mem_lock = get_kstat_value (ksp, "pageslocked"); - arcsize = get_kstat_value (ksz, "size"); - pp_kernel = get_kstat_value (ksp, "pp_kernel"); - physmem = get_kstat_value (ksp, "physmem"); - availrmem = get_kstat_value (ksp, "availrmem"); - - mem_kern = 0; - mem_unus = 0; - - if ((mem_used < 0LL) || (mem_free < 0LL) || (mem_lock < 0LL)) - { - WARNING ("memory plugin: one of used, free or locked is negative."); - return (-1); - } - - mem_unus = physmem - mem_used; - - if (mem_used < (mem_free + mem_lock)) - { - /* source: http://wesunsolve.net/bugid/id/4909199 - * this seems to happen when swap space is small, e.g. 2G on a 32G system - * we will make some assumptions here - * educated solaris internals help welcome here */ - DEBUG ("memory plugin: pages total is smaller than \"free\" " - "+ \"locked\". This is probably due to small " - "swap space"); - mem_free = availrmem; - mem_used = 0; - } - else - { - mem_used -= mem_free + mem_lock; - } - - /* mem_kern is accounted for in mem_lock */ - if (pp_kernel < mem_lock) - { - mem_kern = pp_kernel; - mem_lock -= pp_kernel; - } - else - { - mem_kern = mem_lock; - mem_lock = 0; - } - - mem_used *= pagesize; /* If this overflows you have some serious */ - mem_free *= pagesize; /* memory.. Why not call me up and give me */ - mem_lock *= pagesize; /* some? ;) */ - mem_kern *= pagesize; /* it's 2011 RAM is cheap */ - mem_unus *= pagesize; - mem_kern -= arcsize; - - - MEMORY_SUBMIT ("used", (gauge_t) mem_used, - "free", (gauge_t) mem_free, - "locked", (gauge_t) mem_lock, - "kernel", (gauge_t) mem_kern, - "arc", (gauge_t) arcsize, - "unusable", (gauge_t) mem_unus); + /* Most of the additions here were taken as-is from the k9toolkit from + * Brendan Gregg and are subject to change I guess */ + long long mem_used; + long long mem_free; + long long mem_lock; + long long mem_kern; + long long mem_unus; + long long arcsize; + + long long pp_kernel; + long long physmem; + long long availrmem; + + if (ksp == NULL) + return (-1); + if (ksz == NULL) + return (-1); + + mem_used = get_kstat_value(ksp, "pagestotal"); + mem_free = get_kstat_value(ksp, "pagesfree"); + mem_lock = get_kstat_value(ksp, "pageslocked"); + arcsize = get_kstat_value(ksz, "size"); + pp_kernel = get_kstat_value(ksp, "pp_kernel"); + physmem = get_kstat_value(ksp, "physmem"); + availrmem = get_kstat_value(ksp, "availrmem"); + + mem_kern = 0; + mem_unus = 0; + + if ((mem_used < 0LL) || (mem_free < 0LL) || (mem_lock < 0LL)) { + WARNING("memory plugin: one of used, free or locked is negative."); + return (-1); + } + + mem_unus = physmem - mem_used; + + if (mem_used < (mem_free + mem_lock)) { + /* source: http://wesunsolve.net/bugid/id/4909199 + * this seems to happen when swap space is small, e.g. 2G on a 32G system + * we will make some assumptions here + * educated solaris internals help welcome here */ + DEBUG("memory plugin: pages total is smaller than \"free\" " + "+ \"locked\". This is probably due to small " + "swap space"); + mem_free = availrmem; + mem_used = 0; + } else { + mem_used -= mem_free + mem_lock; + } + + /* mem_kern is accounted for in mem_lock */ + if (pp_kernel < mem_lock) { + mem_kern = pp_kernel; + mem_lock -= pp_kernel; + } else { + mem_kern = mem_lock; + mem_lock = 0; + } + + mem_used *= pagesize; /* If this overflows you have some serious */ + mem_free *= pagesize; /* memory.. Why not call me up and give me */ + mem_lock *= pagesize; /* some? ;) */ + mem_kern *= pagesize; /* it's 2011 RAM is cheap */ + mem_unus *= pagesize; + mem_kern -= arcsize; + + MEMORY_SUBMIT("used", (gauge_t)mem_used, "free", (gauge_t)mem_free, "locked", + (gauge_t)mem_lock, "kernel", (gauge_t)mem_kern, "arc", + (gauge_t)arcsize, "unusable", (gauge_t)mem_unus); /* #endif HAVE_LIBKSTAT */ #elif HAVE_SYSCTL - int mib[] = {CTL_VM, VM_METER}; - struct vmtotal vmtotal = { 0 }; - gauge_t mem_active; - gauge_t mem_inactive; - gauge_t mem_free; - size_t size; - - size = sizeof (vmtotal); - - if (sysctl (mib, 2, &vmtotal, &size, NULL, 0) < 0) { - char errbuf[1024]; - WARNING ("memory plugin: sysctl failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - assert (pagesize > 0); - mem_active = (gauge_t) (vmtotal.t_arm * pagesize); - mem_inactive = (gauge_t) ((vmtotal.t_rm - vmtotal.t_arm) * pagesize); - mem_free = (gauge_t) (vmtotal.t_free * pagesize); - - MEMORY_SUBMIT ("active", mem_active, - "inactive", mem_inactive, - "free", mem_free); + int mib[] = {CTL_VM, VM_METER}; + struct vmtotal vmtotal = {0}; + gauge_t mem_active; + gauge_t mem_inactive; + gauge_t mem_free; + size_t size; + + size = sizeof(vmtotal); + + if (sysctl(mib, 2, &vmtotal, &size, NULL, 0) < 0) { + char errbuf[1024]; + WARNING("memory plugin: sysctl failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + assert(pagesize > 0); + mem_active = (gauge_t)(vmtotal.t_arm * pagesize); + mem_inactive = (gauge_t)((vmtotal.t_rm - vmtotal.t_arm) * pagesize); + mem_free = (gauge_t)(vmtotal.t_free * pagesize); + + MEMORY_SUBMIT("active", mem_active, "inactive", mem_inactive, "free", + mem_free); /* #endif HAVE_SYSCTL */ #elif HAVE_LIBSTATGRAB - sg_mem_stats *ios; + sg_mem_stats *ios; - ios = sg_get_mem_stats (); - if (ios == NULL) - return (-1); + ios = sg_get_mem_stats(); + if (ios == NULL) + return (-1); - MEMORY_SUBMIT ("used", (gauge_t) ios->used, - "cached", (gauge_t) ios->cache, - "free", (gauge_t) ios->free); + MEMORY_SUBMIT("used", (gauge_t)ios->used, "cached", (gauge_t)ios->cache, + "free", (gauge_t)ios->free); /* #endif HAVE_LIBSTATGRAB */ #elif HAVE_PERFSTAT - perfstat_memory_total_t pmemory = { 0 }; - - if (perfstat_memory_total(NULL, &pmemory, sizeof(pmemory), 1) < 0) - { - char errbuf[1024]; - WARNING ("memory plugin: perfstat_memory_total failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - /* Unfortunately, the AIX documentation is not very clear on how these - * numbers relate to one another. The only thing is states explcitly - * is: - * real_total = real_process + real_free + numperm + real_system - * - * Another segmentation, which would be closer to the numbers reported - * by the "svmon" utility, would be: - * real_total = real_free + real_inuse - * real_inuse = "active" + real_pinned + numperm - */ - MEMORY_SUBMIT ("free", (gauge_t) (pmemory.real_free * pagesize), - "cached", (gauge_t) (pmemory.numperm * pagesize), - "system", (gauge_t) (pmemory.real_system * pagesize), - "user", (gauge_t) (pmemory.real_process * pagesize)); + perfstat_memory_total_t pmemory = {0}; + + if (perfstat_memory_total(NULL, &pmemory, sizeof(pmemory), 1) < 0) { + char errbuf[1024]; + WARNING("memory plugin: perfstat_memory_total failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + /* Unfortunately, the AIX documentation is not very clear on how these + * numbers relate to one another. The only thing is states explcitly + * is: + * real_total = real_process + real_free + numperm + real_system + * + * Another segmentation, which would be closer to the numbers reported + * by the "svmon" utility, would be: + * real_total = real_free + real_inuse + * real_inuse = "active" + real_pinned + numperm + */ + MEMORY_SUBMIT("free", (gauge_t)(pmemory.real_free * pagesize), "cached", + (gauge_t)(pmemory.numperm * pagesize), "system", + (gauge_t)(pmemory.real_system * pagesize), "user", + (gauge_t)(pmemory.real_process * pagesize)); #endif /* HAVE_PERFSTAT */ - return (0); + return (0); } /* }}} int memory_read_internal */ -static int memory_read (void) /* {{{ */ +static int memory_read(void) /* {{{ */ { - value_t v[1]; - value_list_t vl = VALUE_LIST_INIT; + value_t v[1]; + value_list_t vl = VALUE_LIST_INIT; - vl.values = v; - vl.values_len = STATIC_ARRAY_SIZE (v); - sstrncpy (vl.plugin, "memory", sizeof (vl.plugin)); - sstrncpy (vl.type, "memory", sizeof (vl.type)); - vl.time = cdtime (); + vl.values = v; + vl.values_len = STATIC_ARRAY_SIZE(v); + sstrncpy(vl.plugin, "memory", sizeof(vl.plugin)); + sstrncpy(vl.type, "memory", sizeof(vl.type)); + vl.time = cdtime(); - return (memory_read_internal (&vl)); + return (memory_read_internal(&vl)); } /* }}} int memory_read */ -void module_register (void) -{ - plugin_register_complex_config ("memory", memory_config); - plugin_register_init ("memory", memory_init); - plugin_register_read ("memory", memory_read); +void module_register(void) { + plugin_register_complex_config("memory", memory_config); + plugin_register_init("memory", memory_init); + plugin_register_read("memory", memory_read); } /* void module_register */ diff --git a/src/mic.c b/src/mic.c index 51e67759..ab5ffd1b 100644 --- a/src/mic.c +++ b/src/mic.c @@ -21,15 +21,15 @@ #include "collectd.h" -#include "plugin.h" #include "common.h" +#include "plugin.h" #include "utils_ignorelist.h" -#include -#include #include -#include +#include +#include #include +#include #define MAX_MICS 32 #define MAX_CORES 256 @@ -39,25 +39,16 @@ static U32 num_mics = 0; static HANDLE mic_handle = NULL; static int const therm_ids[] = { - eMicThermalDie, eMicThermalDevMem, eMicThermalFin, eMicThermalFout, - eMicThermalVccp, eMicThermalVddg, eMicThermalVddq }; -static char const * const therm_names[] = { - "die", "devmem", "fin", "fout", - "vccp", "vddg", "vddq" }; - -static const char *config_keys[] = -{ - "ShowCPU", - "ShowCPUCores", - "ShowMemory", - "ShowTemperatures", - "Temperature", - "IgnoreSelectedTemperature", - "ShowPower", - "Power", - "IgnoreSelectedPower" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); + eMicThermalDie, eMicThermalDevMem, eMicThermalFin, eMicThermalFout, + eMicThermalVccp, eMicThermalVddg, eMicThermalVddq}; +static char const *const therm_names[] = {"die", "devmem", "fin", "fout", + "vccp", "vddg", "vddq"}; + +static const char *config_keys[] = { + "ShowCPU", "ShowCPUCores", "ShowMemory", + "ShowTemperatures", "Temperature", "IgnoreSelectedTemperature", + "ShowPower", "Power", "IgnoreSelectedPower"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static _Bool show_cpu = 1; static _Bool show_cpu_cores = 1; @@ -67,335 +58,313 @@ static ignorelist_t *temp_ignore = NULL; static _Bool show_power = 1; static ignorelist_t *power_ignore = NULL; -static int mic_init (void) -{ - U32 ret; - U32 mic_count; - - if (mic_handle) - return (0); - - mic_count = (U32) STATIC_ARRAY_SIZE(mics); - ret = MicInitAPI(&mic_handle, eTARGET_SCIF_DRIVER, mics, &mic_count); - if (ret != MIC_ACCESS_API_SUCCESS) { - ERROR("mic plugin: Problem initializing MicAccessAPI: %s", - MicGetErrorString(ret)); - } - DEBUG("mic plugin: found: %"PRIu32" MIC(s)",mic_count); - - if (mic_count<0 || mic_count>=MAX_MICS) { - ERROR("mic plugin: No Intel MICs in system"); - return (1); - } - else { - num_mics = mic_count; - return (0); - } +static int mic_init(void) { + U32 ret; + U32 mic_count; + + if (mic_handle) + return (0); + + mic_count = (U32)STATIC_ARRAY_SIZE(mics); + ret = MicInitAPI(&mic_handle, eTARGET_SCIF_DRIVER, mics, &mic_count); + if (ret != MIC_ACCESS_API_SUCCESS) { + ERROR("mic plugin: Problem initializing MicAccessAPI: %s", + MicGetErrorString(ret)); + } + DEBUG("mic plugin: found: %" PRIu32 " MIC(s)", mic_count); + + if (mic_count < 0 || mic_count >= MAX_MICS) { + ERROR("mic plugin: No Intel MICs in system"); + return (1); + } else { + num_mics = mic_count; + return (0); + } } -static int mic_config (const char *key, const char *value) { - if (temp_ignore == NULL) - temp_ignore = ignorelist_create(1); - if (power_ignore == NULL) - power_ignore = ignorelist_create(1); - if (temp_ignore == NULL || power_ignore == NULL) - return (1); - - if (strcasecmp("ShowCPU",key) == 0) - { - show_cpu = IS_TRUE(value); - } - else if (strcasecmp("ShowCPUCores",key) == 0) - { - show_cpu_cores = IS_TRUE(value); - } - else if (strcasecmp("ShowTemperatures",key) == 0) - { - show_temps = IS_TRUE(value); - } - else if (strcasecmp("ShowMemory",key) == 0) - { - show_memory = IS_TRUE(value); - } - else if (strcasecmp("ShowPower",key) == 0) - { - show_power = IS_TRUE(value); - } - else if (strcasecmp("Temperature",key) == 0) - { - ignorelist_add(temp_ignore,value); - } - else if (strcasecmp("IgnoreSelectedTemperature",key) == 0) - { - int invert = 1; - if (IS_TRUE(value)) - invert = 0; - ignorelist_set_invert(temp_ignore,invert); - } - else if (strcasecmp("Power",key) == 0) - { - ignorelist_add(power_ignore,value); - } - else if (strcasecmp("IgnoreSelectedPower",key) == 0) - { - int invert = 1; - if (IS_TRUE(value)) - invert = 0; - ignorelist_set_invert(power_ignore,invert); - } - else - { - return (-1); - } - return (0); +static int mic_config(const char *key, const char *value) { + if (temp_ignore == NULL) + temp_ignore = ignorelist_create(1); + if (power_ignore == NULL) + power_ignore = ignorelist_create(1); + if (temp_ignore == NULL || power_ignore == NULL) + return (1); + + if (strcasecmp("ShowCPU", key) == 0) { + show_cpu = IS_TRUE(value); + } else if (strcasecmp("ShowCPUCores", key) == 0) { + show_cpu_cores = IS_TRUE(value); + } else if (strcasecmp("ShowTemperatures", key) == 0) { + show_temps = IS_TRUE(value); + } else if (strcasecmp("ShowMemory", key) == 0) { + show_memory = IS_TRUE(value); + } else if (strcasecmp("ShowPower", key) == 0) { + show_power = IS_TRUE(value); + } else if (strcasecmp("Temperature", key) == 0) { + ignorelist_add(temp_ignore, value); + } else if (strcasecmp("IgnoreSelectedTemperature", key) == 0) { + int invert = 1; + if (IS_TRUE(value)) + invert = 0; + ignorelist_set_invert(temp_ignore, invert); + } else if (strcasecmp("Power", key) == 0) { + ignorelist_add(power_ignore, value); + } else if (strcasecmp("IgnoreSelectedPower", key) == 0) { + int invert = 1; + if (IS_TRUE(value)) + invert = 0; + ignorelist_set_invert(power_ignore, invert); + } else { + return (-1); + } + return (0); } -static void mic_submit_memory_use(int micnumber, const char *type_instance, U32 value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void mic_submit_memory_use(int micnumber, const char *type_instance, + U32 value) { + value_list_t vl = VALUE_LIST_INIT; - /* MicAccessAPI reports KB's of memory, adjust for this */ - DEBUG("mic plugin: Memory Value Report; %u %lf",value,((gauge_t)value)*1024.0); + /* MicAccessAPI reports KB's of memory, adjust for this */ + DEBUG("mic plugin: Memory Value Report; %u %lf", value, + ((gauge_t)value) * 1024.0); - vl.values = &(value_t) { .gauge = ((gauge_t)value) * 1024.0 }; - vl.values_len = 1; + vl.values = &(value_t){.gauge = ((gauge_t)value) * 1024.0}; + vl.values_len = 1; - strncpy (vl.plugin, "mic", sizeof (vl.plugin)); - ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), "%i", micnumber); - strncpy (vl.type, "memory", sizeof (vl.type)); - strncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + strncpy(vl.plugin, "mic", sizeof(vl.plugin)); + ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", micnumber); + strncpy(vl.type, "memory", sizeof(vl.type)); + strncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* Gather memory Utilization */ -static int mic_read_memory(int mic) -{ - U32 ret; - U32 mem_total,mem_free,mem_bufs; - - ret = MicGetMemoryUtilization(mic_handle,&mem_total,&mem_free,&mem_bufs); - if (ret != MIC_ACCESS_API_SUCCESS) { - ERROR("mic plugin: Problem getting Memory Utilization: %s", - MicGetErrorString(ret)); - return (1); - } - mic_submit_memory_use(mic,"free",mem_free); - mic_submit_memory_use(mic,"used",mem_total-mem_free-mem_bufs); - mic_submit_memory_use(mic,"buffered",mem_bufs); - DEBUG("mic plugin: Memory Read: %u %u %u",mem_total,mem_free,mem_bufs); - return (0); +static int mic_read_memory(int mic) { + U32 ret; + U32 mem_total, mem_free, mem_bufs; + + ret = MicGetMemoryUtilization(mic_handle, &mem_total, &mem_free, &mem_bufs); + if (ret != MIC_ACCESS_API_SUCCESS) { + ERROR("mic plugin: Problem getting Memory Utilization: %s", + MicGetErrorString(ret)); + return (1); + } + mic_submit_memory_use(mic, "free", mem_free); + mic_submit_memory_use(mic, "used", mem_total - mem_free - mem_bufs); + mic_submit_memory_use(mic, "buffered", mem_bufs); + DEBUG("mic plugin: Memory Read: %u %u %u", mem_total, mem_free, mem_bufs); + return (0); } -static void mic_submit_temp(int micnumber, const char *type, gauge_t value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void mic_submit_temp(int micnumber, const char *type, gauge_t value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; - strncpy (vl.host, hostname_g, sizeof (vl.host)); - strncpy (vl.plugin, "mic", sizeof (vl.plugin)); - ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), - "%i", micnumber); - strncpy (vl.type, "temperature", sizeof (vl.type)); - strncpy (vl.type_instance, type, sizeof (vl.type_instance)); + strncpy(vl.host, hostname_g, sizeof(vl.host)); + strncpy(vl.plugin, "mic", sizeof(vl.plugin)); + ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", micnumber); + strncpy(vl.type, "temperature", sizeof(vl.type)); + strncpy(vl.type_instance, type, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* Gather Temperature Information */ -static int mic_read_temps(int mic) -{ - size_t num_therms = STATIC_ARRAY_SIZE(therm_ids); - - for (size_t j = 0; j < num_therms; j++) { - U32 status; - U32 temp_buffer; - U32 buffer_size = (U32)sizeof(temp_buffer); - char const *name = therm_names[j]; - - if (ignorelist_match(temp_ignore, name) != 0) - continue; - - status = MicGetTemperature(mic_handle, therm_ids[j], - &temp_buffer, &buffer_size); - if (status != MIC_ACCESS_API_SUCCESS) { - ERROR("mic plugin: Error reading temperature \"%s\": " - "%s", name, MicGetErrorString(status)); - return (1); - } - mic_submit_temp(mic, name, temp_buffer); - } - return (0); +static int mic_read_temps(int mic) { + size_t num_therms = STATIC_ARRAY_SIZE(therm_ids); + + for (size_t j = 0; j < num_therms; j++) { + U32 status; + U32 temp_buffer; + U32 buffer_size = (U32)sizeof(temp_buffer); + char const *name = therm_names[j]; + + if (ignorelist_match(temp_ignore, name) != 0) + continue; + + status = + MicGetTemperature(mic_handle, therm_ids[j], &temp_buffer, &buffer_size); + if (status != MIC_ACCESS_API_SUCCESS) { + ERROR("mic plugin: Error reading temperature \"%s\": " + "%s", + name, MicGetErrorString(status)); + return (1); + } + mic_submit_temp(mic, name, temp_buffer); + } + return (0); } -static void mic_submit_cpu(int micnumber, const char *type_instance, - int core, derive_t value) -{ - value_list_t vl = VALUE_LIST_INIT; - - vl.values = &(value_t) { .derive = value }; - vl.values_len = 1; - - strncpy (vl.host, hostname_g, sizeof (vl.host)); - strncpy (vl.plugin, "mic", sizeof (vl.plugin)); - if (core < 0) /* global aggregation */ - ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), - "%i", micnumber); - else /* per-core statistics */ - ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), - "%i-cpu-%i", micnumber, core); - strncpy (vl.type, "cpu", sizeof (vl.type)); - strncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); +static void mic_submit_cpu(int micnumber, const char *type_instance, int core, + derive_t value) { + value_list_t vl = VALUE_LIST_INIT; + + vl.values = &(value_t){.derive = value}; + vl.values_len = 1; + + strncpy(vl.host, hostname_g, sizeof(vl.host)); + strncpy(vl.plugin, "mic", sizeof(vl.plugin)); + if (core < 0) /* global aggregation */ + ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", micnumber); + else /* per-core statistics */ + ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i-cpu-%i", + micnumber, core); + strncpy(vl.type, "cpu", sizeof(vl.type)); + strncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); } /*Gather CPU Utilization Information */ -static int mic_read_cpu(int mic) -{ - MicCoreUtil core_util; - MicCoreJiff core_jiffs[MAX_CORES]; - U32 core_jiffs_size; - U32 status; - - core_jiffs_size = MAX_CORES * sizeof(MicCoreJiff); - status = MicGetCoreUtilization(mic_handle, &core_util, - core_jiffs, &core_jiffs_size); - if (status != MIC_ACCESS_API_SUCCESS) { - ERROR("mic plugin: Problem getting CPU utilization: %s", - MicGetErrorString(status)); - return(-1); - } - - if (show_cpu) { - mic_submit_cpu(mic, "user", -1, core_util.sum.user); - mic_submit_cpu(mic, "sys", -1, core_util.sum.sys); - mic_submit_cpu(mic, "nice", -1, core_util.sum.nice); - mic_submit_cpu(mic, "idle", -1, core_util.sum.idle); - } - - if (show_cpu_cores) { - for (int j = 0; j < core_util.core; j++) { - mic_submit_cpu(mic, "user", j, core_jiffs[j].user); - mic_submit_cpu(mic, "sys", j, core_jiffs[j].sys); - mic_submit_cpu(mic, "nice", j, core_jiffs[j].nice); - mic_submit_cpu(mic, "idle", j, core_jiffs[j].idle); - } - } - return (0); +static int mic_read_cpu(int mic) { + MicCoreUtil core_util; + MicCoreJiff core_jiffs[MAX_CORES]; + U32 core_jiffs_size; + U32 status; + + core_jiffs_size = MAX_CORES * sizeof(MicCoreJiff); + status = MicGetCoreUtilization(mic_handle, &core_util, core_jiffs, + &core_jiffs_size); + if (status != MIC_ACCESS_API_SUCCESS) { + ERROR("mic plugin: Problem getting CPU utilization: %s", + MicGetErrorString(status)); + return (-1); + } + + if (show_cpu) { + mic_submit_cpu(mic, "user", -1, core_util.sum.user); + mic_submit_cpu(mic, "sys", -1, core_util.sum.sys); + mic_submit_cpu(mic, "nice", -1, core_util.sum.nice); + mic_submit_cpu(mic, "idle", -1, core_util.sum.idle); + } + + if (show_cpu_cores) { + for (int j = 0; j < core_util.core; j++) { + mic_submit_cpu(mic, "user", j, core_jiffs[j].user); + mic_submit_cpu(mic, "sys", j, core_jiffs[j].sys); + mic_submit_cpu(mic, "nice", j, core_jiffs[j].nice); + mic_submit_cpu(mic, "idle", j, core_jiffs[j].idle); + } + } + return (0); } -static void mic_submit_power(int micnumber, const char *type, const char *type_instance, gauge_t value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void mic_submit_power(int micnumber, const char *type, + const char *type_instance, gauge_t value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; - strncpy (vl.host, hostname_g, sizeof (vl.host)); - strncpy (vl.plugin, "mic", sizeof (vl.plugin)); - ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), "%i", micnumber); - strncpy (vl.type, type, sizeof (vl.type)); - strncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + strncpy(vl.host, hostname_g, sizeof(vl.host)); + strncpy(vl.plugin, "mic", sizeof(vl.plugin)); + ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", micnumber); + strncpy(vl.type, type, sizeof(vl.type)); + strncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* Gather Power Information */ -static int mic_read_power(int mic) -{ - U32 ret; - MicPwrUsage power_use; - - ret = MicGetPowerUsage(mic_handle,&power_use); - if (ret != MIC_ACCESS_API_SUCCESS) { - ERROR("mic plugin: Problem getting Power Usage: %s", - MicGetErrorString(ret)); - return (1); - } - - /* power is in uWatts, current in mA, voltage in uVolts.. convert to - * base unit */ - #define SUB_POWER(name) do { if (ignorelist_match(power_ignore,#name)==0) \ - mic_submit_power(mic,"power",#name,(gauge_t)power_use.name.prr*0.000001); \ - } while(0) - #define SUB_VOLTS(name) do { if (ignorelist_match(power_ignore,#name)==0) {\ - mic_submit_power(mic,"power",#name,(gauge_t)(power_use.name.pwr*0.000001)); \ - mic_submit_power(mic,"current",#name,(gauge_t)(power_use.name.cur*0.001)); \ - mic_submit_power(mic,"voltage",#name,(gauge_t)(power_use.name.volt*0.000001)); \ - }} while(0) - - SUB_POWER(total0); - SUB_POWER(total1); - SUB_POWER(inst); - SUB_POWER(imax); - SUB_POWER(pcie); - SUB_POWER(c2x3); - SUB_POWER(c2x4); - SUB_VOLTS(vccp); - SUB_VOLTS(vddg); - SUB_VOLTS(vddq); - - return (0); +static int mic_read_power(int mic) { + U32 ret; + MicPwrUsage power_use; + + ret = MicGetPowerUsage(mic_handle, &power_use); + if (ret != MIC_ACCESS_API_SUCCESS) { + ERROR("mic plugin: Problem getting Power Usage: %s", + MicGetErrorString(ret)); + return (1); + } + +/* power is in uWatts, current in mA, voltage in uVolts.. convert to + * base unit */ +#define SUB_POWER(name) \ + do { \ + if (ignorelist_match(power_ignore, #name) == 0) \ + mic_submit_power(mic, "power", #name, \ + (gauge_t)power_use.name.prr * 0.000001); \ + } while (0) +#define SUB_VOLTS(name) \ + do { \ + if (ignorelist_match(power_ignore, #name) == 0) { \ + mic_submit_power(mic, "power", #name, \ + (gauge_t)(power_use.name.pwr * 0.000001)); \ + mic_submit_power(mic, "current", #name, \ + (gauge_t)(power_use.name.cur * 0.001)); \ + mic_submit_power(mic, "voltage", #name, \ + (gauge_t)(power_use.name.volt * 0.000001)); \ + } \ + } while (0) + + SUB_POWER(total0); + SUB_POWER(total1); + SUB_POWER(inst); + SUB_POWER(imax); + SUB_POWER(pcie); + SUB_POWER(c2x3); + SUB_POWER(c2x4); + SUB_VOLTS(vccp); + SUB_VOLTS(vddg); + SUB_VOLTS(vddq); + + return (0); } -static int mic_read (void) -{ - U32 ret; - int error; - - error = 0; - for (int i = 0;inext) - if (strcasecmp (ptr->name, name) == 0) + if (strcasecmp(ptr->name, name) == 0) return (ptr); return (NULL); } /* }}} mb_data_t *data_get_by_name */ -static int data_append (mb_data_t **dst, mb_data_t *src) /* {{{ */ +static int data_append(mb_data_t **dst, mb_data_t *src) /* {{{ */ { mb_data_t *ptr; @@ -181,8 +174,7 @@ static int data_append (mb_data_t **dst, mb_data_t *src) /* {{{ */ ptr = *dst; - if (ptr == NULL) - { + if (ptr == NULL) { *dst = src; return (0); } @@ -196,7 +188,7 @@ static int data_append (mb_data_t **dst, mb_data_t *src) /* {{{ */ } /* }}} int data_append */ /* Copy a single mb_data_t and append it to another list. */ -static int data_copy (mb_data_t **dst, const mb_data_t *src) /* {{{ */ +static int data_copy(mb_data_t **dst, const mb_data_t *src) /* {{{ */ { mb_data_t *tmp; int status; @@ -204,25 +196,23 @@ static int data_copy (mb_data_t **dst, const mb_data_t *src) /* {{{ */ if ((dst == NULL) || (src == NULL)) return (EINVAL); - tmp = malloc (sizeof (*tmp)); + tmp = malloc(sizeof(*tmp)); if (tmp == NULL) return (ENOMEM); - memcpy (tmp, src, sizeof (*tmp)); + memcpy(tmp, src, sizeof(*tmp)); tmp->name = NULL; tmp->next = NULL; - tmp->name = strdup (src->name); - if (tmp->name == NULL) - { - sfree (tmp); + tmp->name = strdup(src->name); + if (tmp->name == NULL) { + sfree(tmp); return (ENOMEM); } - status = data_append (dst, tmp); - if (status != 0) - { - sfree (tmp->name); - sfree (tmp); + status = data_append(dst, tmp); + if (status != 0) { + sfree(tmp->name); + sfree(tmp); return (status); } @@ -231,54 +221,50 @@ static int data_copy (mb_data_t **dst, const mb_data_t *src) /* {{{ */ /* Lookup a single mb_data_t instance, copy it and append the copy to another * list. */ -static int data_copy_by_name (mb_data_t **dst, mb_data_t *src, /* {{{ */ - const char *name) -{ +static int data_copy_by_name(mb_data_t **dst, mb_data_t *src, /* {{{ */ + const char *name) { mb_data_t *ptr; if ((dst == NULL) || (src == NULL) || (name == NULL)) return (EINVAL); - ptr = data_get_by_name (src, name); + ptr = data_get_by_name(src, name); if (ptr == NULL) return (ENOENT); - return (data_copy (dst, ptr)); + return (data_copy(dst, ptr)); } /* }}} int data_copy_by_name */ /* Read functions */ -static int mb_submit (mb_host_t *host, mb_slave_t *slave, /* {{{ */ - mb_data_t *data, value_t value) -{ +static int mb_submit(mb_host_t *host, mb_slave_t *slave, /* {{{ */ + mb_data_t *data, value_t value) { value_list_t vl = VALUE_LIST_INIT; if ((host == NULL) || (slave == NULL) || (data == NULL)) return (EINVAL); if (host->interval == 0) - host->interval = plugin_get_interval (); + host->interval = plugin_get_interval(); if (slave->instance[0] == 0) - ssnprintf (slave->instance, sizeof (slave->instance), "slave_%i", - slave->id); + ssnprintf(slave->instance, sizeof(slave->instance), "slave_%i", slave->id); vl.values = &value; vl.values_len = 1; vl.interval = host->interval; - sstrncpy (vl.host, host->host, sizeof (vl.host)); - sstrncpy (vl.plugin, "modbus", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, slave->instance, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, data->type, sizeof (vl.type)); - sstrncpy (vl.type_instance, data->instance, sizeof (vl.type_instance)); + sstrncpy(vl.host, host->host, sizeof(vl.host)); + sstrncpy(vl.plugin, "modbus", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, slave->instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, data->type, sizeof(vl.type)); + sstrncpy(vl.type_instance, data->instance, sizeof(vl.type_instance)); - return (plugin_dispatch_values (&vl)); + return (plugin_dispatch_values(&vl)); } /* }}} int mb_submit */ -static float mb_register_to_float (uint16_t hi, uint16_t lo) /* {{{ */ +static float mb_register_to_float(uint16_t hi, uint16_t lo) /* {{{ */ { - union - { + union { uint8_t b[4]; uint16_t s[2]; float f; @@ -302,7 +288,7 @@ static float mb_register_to_float (uint16_t hi, uint16_t lo) /* {{{ */ #if LEGACY_LIBMODBUS /* Version 2.0.3 */ -static int mb_init_connection (mb_host_t *host) /* {{{ */ +static int mb_init_connection(mb_host_t *host) /* {{{ */ { int status; @@ -310,39 +296,35 @@ static int mb_init_connection (mb_host_t *host) /* {{{ */ return (EINVAL); #if COLLECT_DEBUG - modbus_set_debug (&host->connection, 1); + modbus_set_debug(&host->connection, 1); #endif /* We'll do the error handling ourselves. */ - modbus_set_error_handling (&host->connection, NOP_ON_ERROR); + modbus_set_error_handling(&host->connection, NOP_ON_ERROR); - if (host->conntype == MBCONN_TCP) - { + if (host->conntype == MBCONN_TCP) { if ((host->port < 1) || (host->port > 65535)) host->port = MODBUS_TCP_DEFAULT_PORT; - DEBUG ("Modbus plugin: Trying to connect to \"%s\", port %i.", - host->node, host->port); + DEBUG("Modbus plugin: Trying to connect to \"%s\", port %i.", host->node, + host->port); - modbus_init_tcp (&host->connection, - /* host = */ host->node, - /* port = */ host->port); - } - else /* MBCONN_RTU */ + modbus_init_tcp(&host->connection, + /* host = */ host->node, + /* port = */ host->port); + } else /* MBCONN_RTU */ { - DEBUG ("Modbus plugin: Trying to connect to \"%s\".", host->node); + DEBUG("Modbus plugin: Trying to connect to \"%s\".", host->node); - modbus_init_rtu (&host->connection, - /* device = */ host->node, - /* baudrate = */ host->baudrate, - 'N', 8, 1, 0); + modbus_init_rtu(&host->connection, + /* device = */ host->node, + /* baudrate = */ host->baudrate, 'N', 8, 1, 0); } - status = modbus_connect (&host->connection); - if (status != 0) - { - ERROR ("Modbus plugin: modbus_connect (%s, %i) failed with status %i.", - host->node, host->port ? host->port : host->baudrate, status); + status = modbus_connect(&host->connection); + if (status != 0) { + ERROR("Modbus plugin: modbus_connect (%s, %i) failed with status %i.", + host->node, host->port ? host->port : host->baudrate, status); return (status); } @@ -353,7 +335,7 @@ static int mb_init_connection (mb_host_t *host) /* {{{ */ #else /* if !LEGACY_LIBMODBUS */ /* Version 2.9.2 */ -static int mb_init_connection (mb_host_t *host) /* {{{ */ +static int mb_init_connection(mb_host_t *host) /* {{{ */ { int status; @@ -363,47 +345,41 @@ static int mb_init_connection (mb_host_t *host) /* {{{ */ if (host->connection != NULL) return (0); - if (host->conntype == MBCONN_TCP) - { + if (host->conntype == MBCONN_TCP) { if ((host->port < 1) || (host->port > 65535)) host->port = MODBUS_TCP_DEFAULT_PORT; - DEBUG ("Modbus plugin: Trying to connect to \"%s\", port %i.", - host->node, host->port); + DEBUG("Modbus plugin: Trying to connect to \"%s\", port %i.", host->node, + host->port); - host->connection = modbus_new_tcp (host->node, host->port); - if (host->connection == NULL) - { - ERROR ("Modbus plugin: Creating new Modbus/TCP object failed."); + host->connection = modbus_new_tcp(host->node, host->port); + if (host->connection == NULL) { + ERROR("Modbus plugin: Creating new Modbus/TCP object failed."); return (-1); } - } - else - { - DEBUG ("Modbus plugin: Trying to connect to \"%s\", baudrate %i.", - host->node, host->baudrate); + } else { + DEBUG("Modbus plugin: Trying to connect to \"%s\", baudrate %i.", + host->node, host->baudrate); - host->connection = modbus_new_rtu (host->node, host->baudrate, 'N', 8, 1); - if (host->connection == NULL) - { - ERROR ("Modbus plugin: Creating new Modbus/RTU object failed."); + host->connection = modbus_new_rtu(host->node, host->baudrate, 'N', 8, 1); + if (host->connection == NULL) { + ERROR("Modbus plugin: Creating new Modbus/RTU object failed."); return (-1); } } #if COLLECT_DEBUG - modbus_set_debug (host->connection, 1); + modbus_set_debug(host->connection, 1); #endif /* We'll do the error handling ourselves. */ - modbus_set_error_recovery (host->connection, 0); + modbus_set_error_recovery(host->connection, 0); - status = modbus_connect (host->connection); - if (status != 0) - { - ERROR ("Modbus plugin: modbus_connect (%s, %i) failed with status %i.", - host->node, host->port ? host->port : host->baudrate, status); - modbus_free (host->connection); + status = modbus_connect(host->connection); + if (status != 0) { + ERROR("Modbus plugin: modbus_connect (%s, %i) failed with status %i.", + host->node, host->port ? host->port : host->baudrate, status); + modbus_free(host->connection); host->connection = NULL; return (status); } @@ -412,21 +388,21 @@ static int mb_init_connection (mb_host_t *host) /* {{{ */ } /* }}} int mb_init_connection */ #endif /* !LEGACY_LIBMODBUS */ -#define CAST_TO_VALUE_T(ds,vt,raw) do { \ - if ((ds)->ds[0].type == DS_TYPE_COUNTER) \ - (vt).counter = (counter_t) (raw); \ - else if ((ds)->ds[0].type == DS_TYPE_GAUGE) \ - (vt).gauge = (gauge_t) (raw); \ - else if ((ds)->ds[0].type == DS_TYPE_DERIVE) \ - (vt).derive = (derive_t) (raw); \ - else /* if (ds->ds[0].type == DS_TYPE_ABSOLUTE) */ \ - (vt).absolute = (absolute_t) (raw); \ -} while (0) - -static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */ - mb_data_t *data) -{ - uint16_t values[2] = { 0 }; +#define CAST_TO_VALUE_T(ds, vt, raw) \ + do { \ + if ((ds)->ds[0].type == DS_TYPE_COUNTER) \ + (vt).counter = (counter_t)(raw); \ + else if ((ds)->ds[0].type == DS_TYPE_GAUGE) \ + (vt).gauge = (gauge_t)(raw); \ + else if ((ds)->ds[0].type == DS_TYPE_DERIVE) \ + (vt).derive = (derive_t)(raw); \ + else /* if (ds->ds[0].type == DS_TYPE_ABSOLUTE) */ \ + (vt).absolute = (absolute_t)(raw); \ + } while (0) + +static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ + mb_data_t *data) { + uint16_t values[2] = {0}; int values_num; const data_set_t *ds; int status = 0; @@ -434,190 +410,175 @@ static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */ if ((host == NULL) || (slave == NULL) || (data == NULL)) return (EINVAL); - ds = plugin_get_ds (data->type); - if (ds == NULL) - { - ERROR ("Modbus plugin: Type \"%s\" is not defined.", data->type); + ds = plugin_get_ds(data->type); + if (ds == NULL) { + ERROR("Modbus plugin: Type \"%s\" is not defined.", data->type); return (-1); } - if (ds->ds_num != 1) - { - ERROR ("Modbus plugin: The type \"%s\" has %zu data sources. " - "I can only handle data sets with only one data source.", - data->type, ds->ds_num); + if (ds->ds_num != 1) { + ERROR("Modbus plugin: The type \"%s\" has %zu data sources. " + "I can only handle data sets with only one data source.", + data->type, ds->ds_num); return (-1); } - if ((ds->ds[0].type != DS_TYPE_GAUGE) - && (data->register_type != REG_TYPE_INT32) - && (data->register_type != REG_TYPE_UINT32)) - { - NOTICE ("Modbus plugin: The data source of type \"%s\" is %s, not gauge. " + if ((ds->ds[0].type != DS_TYPE_GAUGE) && + (data->register_type != REG_TYPE_INT32) && + (data->register_type != REG_TYPE_UINT32)) { + NOTICE( + "Modbus plugin: The data source of type \"%s\" is %s, not gauge. " "This will most likely result in problems, because the register type " - "is not UINT32.", data->type, DS_TYPE_TO_STRING (ds->ds[0].type)); + "is not UINT32.", + data->type, DS_TYPE_TO_STRING(ds->ds[0].type)); } - if ((data->register_type == REG_TYPE_INT32) - || (data->register_type == REG_TYPE_UINT32) - || (data->register_type == REG_TYPE_FLOAT)) + if ((data->register_type == REG_TYPE_INT32) || + (data->register_type == REG_TYPE_UINT32) || + (data->register_type == REG_TYPE_FLOAT)) values_num = 2; else values_num = 1; - if (host->connection == NULL) - { + if (host->connection == NULL) { status = EBADF; - } - else if (host->conntype == MBCONN_TCP) - { + } else if (host->conntype == MBCONN_TCP) { /* getpeername() is used only to determine if the socket is connected, not * because we're really interested in the peer's IP address. */ - if (getpeername (modbus_get_socket (host->connection), - (void *) &(struct sockaddr_storage) {0}, - &(socklen_t) {sizeof(struct sockaddr_storage)}) != 0) + if (getpeername(modbus_get_socket(host->connection), + (void *)&(struct sockaddr_storage){0}, + &(socklen_t){sizeof(struct sockaddr_storage)}) != 0) status = errno; } - if ((status == EBADF) || (status == ENOTSOCK) || (status == ENOTCONN)) - { - status = mb_init_connection (host); - if (status != 0) - { - ERROR ("Modbus plugin: mb_init_connection (%s/%s) failed. ", - host->host, host->node); + if ((status == EBADF) || (status == ENOTSOCK) || (status == ENOTCONN)) { + status = mb_init_connection(host); + if (status != 0) { + ERROR("Modbus plugin: mb_init_connection (%s/%s) failed. ", host->host, + host->node); host->is_connected = 0; host->connection = NULL; return (-1); } - } - else if (status != 0) - { + } else if (status != 0) { #if LEGACY_LIBMODBUS - modbus_close (&host->connection); + modbus_close(&host->connection); #else - modbus_close (host->connection); - modbus_free (host->connection); + modbus_close(host->connection); + modbus_free(host->connection); #endif } #if LEGACY_LIBMODBUS - /* Version 2.0.3: Pass the connection struct as a pointer and pass the slave - * id to each call of "read_holding_registers". */ -# define modbus_read_registers(ctx, addr, nb, dest) \ - read_holding_registers (&(ctx), slave->id, (addr), (nb), (dest)) +/* Version 2.0.3: Pass the connection struct as a pointer and pass the slave + * id to each call of "read_holding_registers". */ +#define modbus_read_registers(ctx, addr, nb, dest) \ + read_holding_registers(&(ctx), slave->id, (addr), (nb), (dest)) #else /* if !LEGACY_LIBMODBUS */ /* Version 2.9.2: Set the slave id once before querying the registers. */ - status = modbus_set_slave (host->connection, slave->id); - if (status != 0) - { - ERROR ("Modbus plugin: modbus_set_slave (%i) failed with status %i.", - slave->id, status); + status = modbus_set_slave(host->connection, slave->id); + if (status != 0) { + ERROR("Modbus plugin: modbus_set_slave (%i) failed with status %i.", + slave->id, status); return (-1); } #endif - if (data->modbus_register_type == MREG_INPUT){ - status = modbus_read_input_registers (host->connection, - /* start_addr = */ data->register_base, - /* num_registers = */ values_num, /* buffer = */ values); - } - else{ - status = modbus_read_registers (host->connection, - /* start_addr = */ data->register_base, - /* num_registers = */ values_num, /* buffer = */ values); - } - if (status != values_num) - { - ERROR ("Modbus plugin: modbus read function (%s/%s) failed. " - " status = %i, values_num = %i. Giving up.", - host->host, host->node, status, values_num); + if (data->modbus_register_type == MREG_INPUT) { + status = modbus_read_input_registers(host->connection, + /* start_addr = */ data->register_base, + /* num_registers = */ values_num, + /* buffer = */ values); + } else { + status = modbus_read_registers(host->connection, + /* start_addr = */ data->register_base, + /* num_registers = */ values_num, + /* buffer = */ values); + } + if (status != values_num) { + ERROR("Modbus plugin: modbus read function (%s/%s) failed. " + " status = %i, values_num = %i. Giving up.", + host->host, host->node, status, values_num); #if LEGACY_LIBMODBUS - modbus_close (&host->connection); + modbus_close(&host->connection); #else - modbus_close (host->connection); - modbus_free (host->connection); + modbus_close(host->connection); + modbus_free(host->connection); #endif host->connection = NULL; return (-1); } - DEBUG ("Modbus plugin: mb_read_data: Success! " - "modbus_read_registers returned with status %i.", status); + DEBUG("Modbus plugin: mb_read_data: Success! " + "modbus_read_registers returned with status %i.", + status); - if (data->register_type == REG_TYPE_FLOAT) - { + if (data->register_type == REG_TYPE_FLOAT) { float float_value; value_t vt; - float_value = mb_register_to_float (values[0], values[1]); - DEBUG ("Modbus plugin: mb_read_data: " - "Returned float value is %g", (double) float_value); + float_value = mb_register_to_float(values[0], values[1]); + DEBUG("Modbus plugin: mb_read_data: " + "Returned float value is %g", + (double)float_value); - CAST_TO_VALUE_T (ds, vt, float_value); - mb_submit (host, slave, data, vt); - } - else if (data->register_type == REG_TYPE_INT32) - { - union - { + CAST_TO_VALUE_T(ds, vt, float_value); + mb_submit(host, slave, data, vt); + } else if (data->register_type == REG_TYPE_INT32) { + union { uint32_t u32; - int32_t i32; + int32_t i32; } v; value_t vt; - v.u32 = (((uint32_t) values[0]) << 16) - | ((uint32_t) values[1]); - DEBUG ("Modbus plugin: mb_read_data: " - "Returned int32 value is %"PRIi32, v.i32); + v.u32 = (((uint32_t)values[0]) << 16) | ((uint32_t)values[1]); + DEBUG("Modbus plugin: mb_read_data: " + "Returned int32 value is %" PRIi32, + v.i32); - CAST_TO_VALUE_T (ds, vt, v.i32); - mb_submit (host, slave, data, vt); - } - else if (data->register_type == REG_TYPE_INT16) - { - union - { + CAST_TO_VALUE_T(ds, vt, v.i32); + mb_submit(host, slave, data, vt); + } else if (data->register_type == REG_TYPE_INT16) { + union { uint16_t u16; - int16_t i16; + int16_t i16; } v; value_t vt; v.u16 = values[0]; - DEBUG ("Modbus plugin: mb_read_data: " - "Returned int16 value is %"PRIi16, v.i16); + DEBUG("Modbus plugin: mb_read_data: " + "Returned int16 value is %" PRIi16, + v.i16); - CAST_TO_VALUE_T (ds, vt, v.i16); - mb_submit (host, slave, data, vt); - } - else if (data->register_type == REG_TYPE_UINT32) - { + CAST_TO_VALUE_T(ds, vt, v.i16); + mb_submit(host, slave, data, vt); + } else if (data->register_type == REG_TYPE_UINT32) { uint32_t v32; value_t vt; - v32 = (((uint32_t) values[0]) << 16) - | ((uint32_t) values[1]); - DEBUG ("Modbus plugin: mb_read_data: " - "Returned uint32 value is %"PRIu32, v32); + v32 = (((uint32_t)values[0]) << 16) | ((uint32_t)values[1]); + DEBUG("Modbus plugin: mb_read_data: " + "Returned uint32 value is %" PRIu32, + v32); - CAST_TO_VALUE_T (ds, vt, v32); - mb_submit (host, slave, data, vt); - } - else /* if (data->register_type == REG_TYPE_UINT16) */ + CAST_TO_VALUE_T(ds, vt, v32); + mb_submit(host, slave, data, vt); + } else /* if (data->register_type == REG_TYPE_UINT16) */ { value_t vt; - DEBUG ("Modbus plugin: mb_read_data: " - "Returned uint16 value is %"PRIu16, values[0]); + DEBUG("Modbus plugin: mb_read_data: " + "Returned uint16 value is %" PRIu16, + values[0]); - CAST_TO_VALUE_T (ds, vt, values[0]); - mb_submit (host, slave, data, vt); + CAST_TO_VALUE_T(ds, vt, values[0]); + mb_submit(host, slave, data, vt); } return (0); } /* }}} int mb_read_data */ -static int mb_read_slave (mb_host_t *host, mb_slave_t *slave) /* {{{ */ +static int mb_read_slave(mb_host_t *host, mb_slave_t *slave) /* {{{ */ { int success; int status; @@ -626,9 +587,8 @@ static int mb_read_slave (mb_host_t *host, mb_slave_t *slave) /* {{{ */ return (EINVAL); success = 0; - for (mb_data_t *data = slave->collect; data != NULL; data = data->next) - { - status = mb_read_data (host, slave, data); + for (mb_data_t *data = slave->collect; data != NULL; data = data->next) { + status = mb_read_data(host, slave, data); if (status == 0) success++; } @@ -639,7 +599,7 @@ static int mb_read_slave (mb_host_t *host, mb_slave_t *slave) /* {{{ */ return (0); } /* }}} int mb_read_slave */ -static int mb_read (user_data_t *user_data) /* {{{ */ +static int mb_read(user_data_t *user_data) /* {{{ */ { mb_host_t *host; int success; @@ -651,9 +611,8 @@ static int mb_read (user_data_t *user_data) /* {{{ */ host = user_data->data; success = 0; - for (size_t i = 0; i < host->slaves_num; i++) - { - status = mb_read_slave (host, host->slaves + i); + for (size_t i = 0; i < host->slaves_num; i++) { + status = mb_read_slave(host, host->slaves + i); if (status == 0) success++; } @@ -666,16 +625,16 @@ static int mb_read (user_data_t *user_data) /* {{{ */ /* Free functions */ -static void data_free_one (mb_data_t *data) /* {{{ */ +static void data_free_one(mb_data_t *data) /* {{{ */ { if (data == NULL) return; - sfree (data->name); - sfree (data); + sfree(data->name); + sfree(data); } /* }}} void data_free_one */ -static void data_free_all (mb_data_t *data) /* {{{ */ +static void data_free_all(mb_data_t *data) /* {{{ */ { mb_data_t *next; @@ -683,106 +642,97 @@ static void data_free_all (mb_data_t *data) /* {{{ */ return; next = data->next; - data_free_one (data); + data_free_one(data); - data_free_all (next); + data_free_all(next); } /* }}} void data_free_all */ -static void slaves_free_all (mb_slave_t *slaves, size_t slaves_num) /* {{{ */ +static void slaves_free_all(mb_slave_t *slaves, size_t slaves_num) /* {{{ */ { if (slaves == NULL) return; for (size_t i = 0; i < slaves_num; i++) - data_free_all (slaves[i].collect); - sfree (slaves); + data_free_all(slaves[i].collect); + sfree(slaves); } /* }}} void slaves_free_all */ -static void host_free (void *void_host) /* {{{ */ +static void host_free(void *void_host) /* {{{ */ { mb_host_t *host = void_host; if (host == NULL) return; - slaves_free_all (host->slaves, host->slaves_num); - sfree (host); + slaves_free_all(host->slaves, host->slaves_num); + sfree(host); } /* }}} void host_free */ /* Config functions */ -static int mb_config_add_data (oconfig_item_t *ci) /* {{{ */ +static int mb_config_add_data(oconfig_item_t *ci) /* {{{ */ { - mb_data_t data = { 0 }; + mb_data_t data = {0}; int status; data.name = NULL; data.register_type = REG_TYPE_UINT16; data.next = NULL; - status = cf_util_get_string (ci, &data.name); + status = cf_util_get_string(ci, &data.name); if (status != 0) return (status); - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Type", child->key) == 0) - status = cf_util_get_string_buffer (child, - data.type, sizeof (data.type)); - else if (strcasecmp ("Instance", child->key) == 0) - status = cf_util_get_string_buffer (child, - data.instance, sizeof (data.instance)); - else if (strcasecmp ("RegisterBase", child->key) == 0) - status = cf_util_get_int (child, &data.register_base); - else if (strcasecmp ("RegisterType", child->key) == 0) - { + if (strcasecmp("Type", child->key) == 0) + status = cf_util_get_string_buffer(child, data.type, sizeof(data.type)); + else if (strcasecmp("Instance", child->key) == 0) + status = cf_util_get_string_buffer(child, data.instance, + sizeof(data.instance)); + else if (strcasecmp("RegisterBase", child->key) == 0) + status = cf_util_get_int(child, &data.register_base); + else if (strcasecmp("RegisterType", child->key) == 0) { char tmp[16]; - status = cf_util_get_string_buffer (child, tmp, sizeof (tmp)); + status = cf_util_get_string_buffer(child, tmp, sizeof(tmp)); if (status != 0) /* do nothing */; - else if (strcasecmp ("Int16", tmp) == 0) + else if (strcasecmp("Int16", tmp) == 0) data.register_type = REG_TYPE_INT16; - else if (strcasecmp ("Int32", tmp) == 0) + else if (strcasecmp("Int32", tmp) == 0) data.register_type = REG_TYPE_INT32; - else if (strcasecmp ("Uint16", tmp) == 0) + else if (strcasecmp("Uint16", tmp) == 0) data.register_type = REG_TYPE_UINT16; - else if (strcasecmp ("Uint32", tmp) == 0) + else if (strcasecmp("Uint32", tmp) == 0) data.register_type = REG_TYPE_UINT32; - else if (strcasecmp ("Float", tmp) == 0) + else if (strcasecmp("Float", tmp) == 0) data.register_type = REG_TYPE_FLOAT; - else - { - ERROR ("Modbus plugin: The register type \"%s\" is unknown.", tmp); + else { + ERROR("Modbus plugin: The register type \"%s\" is unknown.", tmp); status = -1; } - } - else if (strcasecmp ("RegisterCmd", child->key) == 0) - { + } else if (strcasecmp("RegisterCmd", child->key) == 0) { #if LEGACY_LIBMODBUS ERROR("Modbus plugin: RegisterCmd parameter can not be used " "with your libmodbus version"); #else char tmp[16]; - status = cf_util_get_string_buffer (child, tmp, sizeof (tmp)); + status = cf_util_get_string_buffer(child, tmp, sizeof(tmp)); if (status != 0) /* do nothing */; - else if (strcasecmp ("ReadHolding", tmp) == 0) + else if (strcasecmp("ReadHolding", tmp) == 0) data.modbus_register_type = MREG_HOLDING; - else if (strcasecmp ("ReadInput", tmp) == 0) + else if (strcasecmp("ReadInput", tmp) == 0) data.modbus_register_type = MREG_INPUT; - else - { - ERROR ("Modbus plugin: The modbus_register_type \"%s\" is unknown.", - tmp); + else { + ERROR("Modbus plugin: The modbus_register_type \"%s\" is unknown.", + tmp); status = -1; } #endif - } - else - { - ERROR ("Modbus plugin: Unknown configuration option: %s", child->key); + } else { + ERROR("Modbus plugin: Unknown configuration option: %s", child->key); status = -1; } @@ -790,73 +740,67 @@ static int mb_config_add_data (oconfig_item_t *ci) /* {{{ */ break; } /* for (i = 0; i < ci->children_num; i++) */ - assert (data.name != NULL); - if (data.type[0] == 0) - { - ERROR ("Modbus plugin: Data block \"%s\": No type has been specified.", - data.name); + assert(data.name != NULL); + if (data.type[0] == 0) { + ERROR("Modbus plugin: Data block \"%s\": No type has been specified.", + data.name); status = -1; } if (status == 0) - data_copy (&data_definitions, &data); + data_copy(&data_definitions, &data); - sfree (data.name); + sfree(data.name); return (status); } /* }}} int mb_config_add_data */ -static int mb_config_set_host_address (mb_host_t *host, /* {{{ */ - const char *address) -{ +static int mb_config_set_host_address(mb_host_t *host, /* {{{ */ + const char *address) { struct addrinfo *ai_list; int status; if ((host == NULL) || (address == NULL)) return (EINVAL); - struct addrinfo ai_hints = { - /* XXX: libmodbus can only handle IPv4 addresses. */ - .ai_family = AF_INET, - .ai_flags = AI_ADDRCONFIG - }; + struct addrinfo ai_hints = { + /* XXX: libmodbus can only handle IPv4 addresses. */ + .ai_family = AF_INET, + .ai_flags = AI_ADDRCONFIG}; - status = getaddrinfo (address, /* service = */ NULL, - &ai_hints, &ai_list); - if (status != 0) - { + status = getaddrinfo(address, /* service = */ NULL, &ai_hints, &ai_list); + if (status != 0) { char errbuf[1024]; - ERROR ("Modbus plugin: getaddrinfo failed: %s", - (status == EAI_SYSTEM) - ? sstrerror (errno, errbuf, sizeof (errbuf)) - : gai_strerror (status)); + ERROR("Modbus plugin: getaddrinfo failed: %s", + (status == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf)) + : gai_strerror(status)); return (status); } - for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) - { - status = getnameinfo (ai_ptr->ai_addr, ai_ptr->ai_addrlen, - host->node, sizeof (host->node), - /* service = */ NULL, /* length = */ 0, - /* flags = */ NI_NUMERICHOST); + for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; + ai_ptr = ai_ptr->ai_next) { + status = getnameinfo(ai_ptr->ai_addr, ai_ptr->ai_addrlen, host->node, + sizeof(host->node), + /* service = */ NULL, /* length = */ 0, + /* flags = */ NI_NUMERICHOST); if (status == 0) break; } /* for (ai_ptr) */ - freeaddrinfo (ai_list); + freeaddrinfo(ai_list); if (status != 0) - ERROR ("Modbus plugin: Unable to translate node name: \"%s\"", address); + ERROR("Modbus plugin: Unable to translate node name: \"%s\"", address); else /* if (status == 0) */ { - DEBUG ("Modbus plugin: mb_config_set_host_address: %s -> %s", - address, host->node); + DEBUG("Modbus plugin: mb_config_set_host_address: %s -> %s", address, + host->node); } return (status); } /* }}} int mb_config_set_host_address */ -static int mb_config_add_slave (mb_host_t *host, oconfig_item_t *ci) /* {{{ */ +static int mb_config_add_slave(mb_host_t *host, oconfig_item_t *ci) /* {{{ */ { mb_slave_t *slave; int status; @@ -864,36 +808,32 @@ static int mb_config_add_slave (mb_host_t *host, oconfig_item_t *ci) /* {{{ */ if ((host == NULL) || (ci == NULL)) return (EINVAL); - slave = realloc (host->slaves, sizeof (*slave) * (host->slaves_num + 1)); + slave = realloc(host->slaves, sizeof(*slave) * (host->slaves_num + 1)); if (slave == NULL) return (ENOMEM); host->slaves = slave; slave = host->slaves + host->slaves_num; - memset (slave, 0, sizeof (*slave)); + memset(slave, 0, sizeof(*slave)); slave->collect = NULL; - status = cf_util_get_int (ci, &slave->id); + status = cf_util_get_int(ci, &slave->id); if (status != 0) return (status); - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Instance", child->key) == 0) - status = cf_util_get_string_buffer (child, - slave->instance, sizeof (slave->instance)); - else if (strcasecmp ("Collect", child->key) == 0) - { + if (strcasecmp("Instance", child->key) == 0) + status = cf_util_get_string_buffer(child, slave->instance, + sizeof(slave->instance)); + else if (strcasecmp("Collect", child->key) == 0) { char buffer[1024]; - status = cf_util_get_string_buffer (child, buffer, sizeof (buffer)); + status = cf_util_get_string_buffer(child, buffer, sizeof(buffer)); if (status == 0) - data_copy_by_name (&slave->collect, data_definitions, buffer); + data_copy_by_name(&slave->collect, data_definitions, buffer); status = 0; /* continue after failure. */ - } - else - { - ERROR ("Modbus plugin: Unknown configuration option: %s", child->key); + } else { + ERROR("Modbus plugin: Unknown configuration option: %s", child->key); status = -1; } @@ -910,69 +850,59 @@ static int mb_config_add_slave (mb_host_t *host, oconfig_item_t *ci) /* {{{ */ if (status == 0) host->slaves_num++; else /* if (status != 0) */ - data_free_all (slave->collect); + data_free_all(slave->collect); return (status); } /* }}} int mb_config_add_slave */ -static int mb_config_add_host (oconfig_item_t *ci) /* {{{ */ +static int mb_config_add_host(oconfig_item_t *ci) /* {{{ */ { mb_host_t *host; int status; - host = calloc (1, sizeof (*host)); + host = calloc(1, sizeof(*host)); if (host == NULL) return (ENOMEM); host->slaves = NULL; - status = cf_util_get_string_buffer (ci, host->host, sizeof (host->host)); - if (status != 0) - { - sfree (host); + status = cf_util_get_string_buffer(ci, host->host, sizeof(host->host)); + if (status != 0) { + sfree(host); return (status); } - if (host->host[0] == 0) - { - sfree (host); + if (host->host[0] == 0) { + sfree(host); return (EINVAL); } - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; status = 0; - if (strcasecmp ("Address", child->key) == 0) - { + if (strcasecmp("Address", child->key) == 0) { char buffer[NI_MAXHOST]; - status = cf_util_get_string_buffer (child, buffer, sizeof (buffer)); + status = cf_util_get_string_buffer(child, buffer, sizeof(buffer)); if (status == 0) - status = mb_config_set_host_address (host, buffer); + status = mb_config_set_host_address(host, buffer); if (status == 0) host->conntype = MBCONN_TCP; - } - else if (strcasecmp ("Port", child->key) == 0) - { - host->port = cf_util_get_port_number (child); + } else if (strcasecmp("Port", child->key) == 0) { + host->port = cf_util_get_port_number(child); if (host->port <= 0) status = -1; - } - else if (strcasecmp ("Device", child->key) == 0) - { - status = cf_util_get_string_buffer (child, host->node, sizeof (host->node)); + } else if (strcasecmp("Device", child->key) == 0) { + status = cf_util_get_string_buffer(child, host->node, sizeof(host->node)); if (status == 0) host->conntype = MBCONN_RTU; - } - else if (strcasecmp ("Baudrate", child->key) == 0) + } else if (strcasecmp("Baudrate", child->key) == 0) status = cf_util_get_int(child, &host->baudrate); - else if (strcasecmp ("Interval", child->key) == 0) - status = cf_util_get_cdtime (child, &host->interval); - else if (strcasecmp ("Slave", child->key) == 0) + else if (strcasecmp("Interval", child->key) == 0) + status = cf_util_get_cdtime(child, &host->interval); + else if (strcasecmp("Slave", child->key) == 0) /* Don't set status: Gracefully continue if a slave fails. */ - mb_config_add_slave (host, child); - else - { - ERROR ("Modbus plugin: Unknown configuration option: %s", child->key); + mb_config_add_slave(host, child); + else { + ERROR("Modbus plugin: Unknown configuration option: %s", child->key); status = -1; } @@ -980,64 +910,59 @@ static int mb_config_add_host (oconfig_item_t *ci) /* {{{ */ break; } /* for (i = 0; i < ci->children_num; i++) */ - assert (host->host[0] != 0); - if (host->node[0] == 0) - { - ERROR ("Modbus plugin: Data block \"%s\": No address or device has been specified.", - host->host); + assert(host->host[0] != 0); + if (host->node[0] == 0) { + ERROR("Modbus plugin: Data block \"%s\": No address or device has been " + "specified.", + host->host); status = -1; } - if (host->conntype == MBCONN_RTU && !host->baudrate) - { - ERROR ("Modbus plugin: Data block \"%s\": No serial baudrate has been specified.", - host->host); + if (host->conntype == MBCONN_RTU && !host->baudrate) { + ERROR("Modbus plugin: Data block \"%s\": No serial baudrate has been " + "specified.", + host->host); status = -1; } if ((host->conntype == MBCONN_TCP && host->baudrate) || - (host->conntype == MBCONN_RTU && host->port)) - { - ERROR ("Modbus plugin: Data block \"%s\": You've mixed up RTU and TCP options.", - host->host); + (host->conntype == MBCONN_RTU && host->port)) { + ERROR("Modbus plugin: Data block \"%s\": You've mixed up RTU and TCP " + "options.", + host->host); status = -1; } - if (status == 0) - { + if (status == 0) { char name[1024]; - ssnprintf (name, sizeof (name), "modbus-%s", host->host); + ssnprintf(name, sizeof(name), "modbus-%s", host->host); - plugin_register_complex_read (/* group = */ NULL, name, - /* callback = */ mb_read, - /* interval = */ host->interval, - &(user_data_t) { - .data = host, - .free_func = host_free, - }); - } - else - { - host_free (host); + plugin_register_complex_read(/* group = */ NULL, name, + /* callback = */ mb_read, + /* interval = */ host->interval, + &(user_data_t){ + .data = host, .free_func = host_free, + }); + } else { + host_free(host); } return (status); } /* }}} int mb_config_add_host */ -static int mb_config (oconfig_item_t *ci) /* {{{ */ +static int mb_config(oconfig_item_t *ci) /* {{{ */ { if (ci == NULL) return (EINVAL); - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Data", child->key) == 0) - mb_config_add_data (child); - else if (strcasecmp ("Host", child->key) == 0) - mb_config_add_host (child); + if (strcasecmp("Data", child->key) == 0) + mb_config_add_data(child); + else if (strcasecmp("Host", child->key) == 0) + mb_config_add_host(child); else - ERROR ("Modbus plugin: Unknown configuration option: %s", child->key); + ERROR("Modbus plugin: Unknown configuration option: %s", child->key); } return (0); @@ -1045,18 +970,17 @@ static int mb_config (oconfig_item_t *ci) /* {{{ */ /* ========= */ -static int mb_shutdown (void) /* {{{ */ +static int mb_shutdown(void) /* {{{ */ { - data_free_all (data_definitions); + data_free_all(data_definitions); data_definitions = NULL; return (0); } /* }}} int mb_shutdown */ -void module_register (void) -{ - plugin_register_complex_config ("modbus", mb_config); - plugin_register_shutdown ("modbus", mb_shutdown); +void module_register(void) { + plugin_register_complex_config("modbus", mb_config); + plugin_register_shutdown("modbus", mb_shutdown); } /* void module_register */ /* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/mqtt.c b/src/mqtt.c index 32304f0c..b578b99b 100644 --- a/src/mqtt.c +++ b/src/mqtt.c @@ -29,7 +29,6 @@ // Reference: http://mosquitto.org/api/files/mosquitto-h.html - #include "collectd.h" #include "common.h" @@ -38,56 +37,54 @@ #include -#define MQTT_MAX_TOPIC_SIZE 1024 -#define MQTT_MAX_MESSAGE_SIZE MQTT_MAX_TOPIC_SIZE + 1024 -#define MQTT_DEFAULT_HOST "localhost" -#define MQTT_DEFAULT_PORT 1883 -#define MQTT_DEFAULT_TOPIC_PREFIX "collectd" -#define MQTT_DEFAULT_TOPIC "collectd/#" +#define MQTT_MAX_TOPIC_SIZE 1024 +#define MQTT_MAX_MESSAGE_SIZE MQTT_MAX_TOPIC_SIZE + 1024 +#define MQTT_DEFAULT_HOST "localhost" +#define MQTT_DEFAULT_PORT 1883 +#define MQTT_DEFAULT_TOPIC_PREFIX "collectd" +#define MQTT_DEFAULT_TOPIC "collectd/#" #ifndef MQTT_KEEPALIVE -# define MQTT_KEEPALIVE 60 +#define MQTT_KEEPALIVE 60 #endif #ifndef SSL_VERIFY_PEER -# define SSL_VERIFY_PEER 1 +#define SSL_VERIFY_PEER 1 #endif - /* * Data types */ -struct mqtt_client_conf -{ - _Bool publish; - char *name; - - struct mosquitto *mosq; - _Bool connected; - - char *host; - int port; - char *client_id; - char *username; - char *password; - int qos; - char *cacertificatefile; - char *certificatefile; - char *certificatekeyfile; - char *tlsprotocol; - char *ciphersuite; - - /* For publishing */ - char *topic_prefix; - _Bool store_rates; - _Bool retain; - - /* For subscribing */ - pthread_t thread; - _Bool loop; - char *topic; - _Bool clean_session; - - c_complain_t complaint_cantpublish; - pthread_mutex_t lock; +struct mqtt_client_conf { + _Bool publish; + char *name; + + struct mosquitto *mosq; + _Bool connected; + + char *host; + int port; + char *client_id; + char *username; + char *password; + int qos; + char *cacertificatefile; + char *certificatefile; + char *certificatekeyfile; + char *tlsprotocol; + char *ciphersuite; + + /* For publishing */ + char *topic_prefix; + _Bool store_rates; + _Bool retain; + + /* For subscribing */ + pthread_t thread; + _Bool loop; + char *topic; + _Bool clean_session; + + c_complain_t complaint_cantpublish; + pthread_mutex_t lock; }; typedef struct mqtt_client_conf mqtt_client_conf_t; @@ -98,433 +95,417 @@ static size_t subscribers_num = 0; * Functions */ #if LIBMOSQUITTO_MAJOR == 0 -static char const *mosquitto_strerror (int code) -{ - switch (code) - { - case MOSQ_ERR_SUCCESS: return "MOSQ_ERR_SUCCESS"; - case MOSQ_ERR_NOMEM: return "MOSQ_ERR_NOMEM"; - case MOSQ_ERR_PROTOCOL: return "MOSQ_ERR_PROTOCOL"; - case MOSQ_ERR_INVAL: return "MOSQ_ERR_INVAL"; - case MOSQ_ERR_NO_CONN: return "MOSQ_ERR_NO_CONN"; - case MOSQ_ERR_CONN_REFUSED: return "MOSQ_ERR_CONN_REFUSED"; - case MOSQ_ERR_NOT_FOUND: return "MOSQ_ERR_NOT_FOUND"; - case MOSQ_ERR_CONN_LOST: return "MOSQ_ERR_CONN_LOST"; - case MOSQ_ERR_SSL: return "MOSQ_ERR_SSL"; - case MOSQ_ERR_PAYLOAD_SIZE: return "MOSQ_ERR_PAYLOAD_SIZE"; - case MOSQ_ERR_NOT_SUPPORTED: return "MOSQ_ERR_NOT_SUPPORTED"; - case MOSQ_ERR_AUTH: return "MOSQ_ERR_AUTH"; - case MOSQ_ERR_ACL_DENIED: return "MOSQ_ERR_ACL_DENIED"; - case MOSQ_ERR_UNKNOWN: return "MOSQ_ERR_UNKNOWN"; - case MOSQ_ERR_ERRNO: return "MOSQ_ERR_ERRNO"; - } - - return "UNKNOWN ERROR CODE"; +static char const *mosquitto_strerror(int code) { + switch (code) { + case MOSQ_ERR_SUCCESS: + return "MOSQ_ERR_SUCCESS"; + case MOSQ_ERR_NOMEM: + return "MOSQ_ERR_NOMEM"; + case MOSQ_ERR_PROTOCOL: + return "MOSQ_ERR_PROTOCOL"; + case MOSQ_ERR_INVAL: + return "MOSQ_ERR_INVAL"; + case MOSQ_ERR_NO_CONN: + return "MOSQ_ERR_NO_CONN"; + case MOSQ_ERR_CONN_REFUSED: + return "MOSQ_ERR_CONN_REFUSED"; + case MOSQ_ERR_NOT_FOUND: + return "MOSQ_ERR_NOT_FOUND"; + case MOSQ_ERR_CONN_LOST: + return "MOSQ_ERR_CONN_LOST"; + case MOSQ_ERR_SSL: + return "MOSQ_ERR_SSL"; + case MOSQ_ERR_PAYLOAD_SIZE: + return "MOSQ_ERR_PAYLOAD_SIZE"; + case MOSQ_ERR_NOT_SUPPORTED: + return "MOSQ_ERR_NOT_SUPPORTED"; + case MOSQ_ERR_AUTH: + return "MOSQ_ERR_AUTH"; + case MOSQ_ERR_ACL_DENIED: + return "MOSQ_ERR_ACL_DENIED"; + case MOSQ_ERR_UNKNOWN: + return "MOSQ_ERR_UNKNOWN"; + case MOSQ_ERR_ERRNO: + return "MOSQ_ERR_ERRNO"; + } + + return "UNKNOWN ERROR CODE"; } #else /* provided by libmosquitto */ #endif -static void mqtt_free (mqtt_client_conf_t *conf) -{ - if (conf == NULL) - return; - - if (conf->connected) - (void) mosquitto_disconnect (conf->mosq); - conf->connected = 0; - (void) mosquitto_destroy (conf->mosq); - - sfree (conf->host); - sfree (conf->username); - sfree (conf->password); - sfree (conf->client_id); - sfree (conf->topic_prefix); - sfree (conf); +static void mqtt_free(mqtt_client_conf_t *conf) { + if (conf == NULL) + return; + + if (conf->connected) + (void)mosquitto_disconnect(conf->mosq); + conf->connected = 0; + (void)mosquitto_destroy(conf->mosq); + + sfree(conf->host); + sfree(conf->username); + sfree(conf->password); + sfree(conf->client_id); + sfree(conf->topic_prefix); + sfree(conf); } -static char *strip_prefix (char *topic) -{ - size_t num = 0; +static char *strip_prefix(char *topic) { + size_t num = 0; - for (size_t i = 0; topic[i] != 0; i++) - if (topic[i] == '/') - num++; + for (size_t i = 0; topic[i] != 0; i++) + if (topic[i] == '/') + num++; - if (num < 2) - return (NULL); + if (num < 2) + return (NULL); - while (num > 2) - { - char *tmp = strchr (topic, '/'); - if (tmp == NULL) - return (NULL); - topic = tmp + 1; - num--; - } + while (num > 2) { + char *tmp = strchr(topic, '/'); + if (tmp == NULL) + return (NULL); + topic = tmp + 1; + num--; + } - return (topic); + return (topic); } -static void on_message ( +static void on_message( #if LIBMOSQUITTO_MAJOR == 0 #else - __attribute__((unused)) struct mosquitto *m, + __attribute__((unused)) struct mosquitto *m, #endif - __attribute__((unused)) void *arg, - const struct mosquitto_message *msg) -{ - value_list_t vl = VALUE_LIST_INIT; - data_set_t const *ds; - char *topic; - char *name; - char *payload; - int status; - - if (msg->payloadlen <= 0) { - DEBUG ("mqtt plugin: message has empty payload"); - return; - } - - topic = strdup (msg->topic); - name = strip_prefix (topic); - - status = parse_identifier_vl (name, &vl); - if (status != 0) - { - ERROR ("mqtt plugin: Unable to parse topic \"%s\".", topic); - sfree (topic); - return; - } - sfree (topic); - - ds = plugin_get_ds (vl.type); - if (ds == NULL) - { - ERROR ("mqtt plugin: Unknown type: \"%s\".", vl.type); - return; - } - - vl.values = calloc (ds->ds_num, sizeof (*vl.values)); - if (vl.values == NULL) - { - ERROR ("mqtt plugin: calloc failed."); - return; - } - vl.values_len = ds->ds_num; - - payload = malloc (msg->payloadlen+1); - if (payload == NULL) - { - ERROR ("mqtt plugin: malloc for payload buffer failed."); - sfree (vl.values); - return; - } - memmove (payload, msg->payload, msg->payloadlen); - payload[msg->payloadlen] = 0; - - DEBUG ("mqtt plugin: payload = \"%s\"", payload); - status = parse_values (payload, &vl, ds); - if (status != 0) - { - ERROR ("mqtt plugin: Unable to parse payload \"%s\".", payload); - sfree (payload); - sfree (vl.values); - return; - } - sfree (payload); - - plugin_dispatch_values (&vl); - sfree (vl.values); + __attribute__((unused)) void *arg, const struct mosquitto_message *msg) { + value_list_t vl = VALUE_LIST_INIT; + data_set_t const *ds; + char *topic; + char *name; + char *payload; + int status; + + if (msg->payloadlen <= 0) { + DEBUG("mqtt plugin: message has empty payload"); + return; + } + + topic = strdup(msg->topic); + name = strip_prefix(topic); + + status = parse_identifier_vl(name, &vl); + if (status != 0) { + ERROR("mqtt plugin: Unable to parse topic \"%s\".", topic); + sfree(topic); + return; + } + sfree(topic); + + ds = plugin_get_ds(vl.type); + if (ds == NULL) { + ERROR("mqtt plugin: Unknown type: \"%s\".", vl.type); + return; + } + + vl.values = calloc(ds->ds_num, sizeof(*vl.values)); + if (vl.values == NULL) { + ERROR("mqtt plugin: calloc failed."); + return; + } + vl.values_len = ds->ds_num; + + payload = malloc(msg->payloadlen + 1); + if (payload == NULL) { + ERROR("mqtt plugin: malloc for payload buffer failed."); + sfree(vl.values); + return; + } + memmove(payload, msg->payload, msg->payloadlen); + payload[msg->payloadlen] = 0; + + DEBUG("mqtt plugin: payload = \"%s\"", payload); + status = parse_values(payload, &vl, ds); + if (status != 0) { + ERROR("mqtt plugin: Unable to parse payload \"%s\".", payload); + sfree(payload); + sfree(vl.values); + return; + } + sfree(payload); + + plugin_dispatch_values(&vl); + sfree(vl.values); } /* void on_message */ /* must hold conf->lock when calling. */ -static int mqtt_reconnect (mqtt_client_conf_t *conf) -{ - int status; +static int mqtt_reconnect(mqtt_client_conf_t *conf) { + int status; - if (conf->connected) - return (0); - - status = mosquitto_reconnect (conf->mosq); - if (status != MOSQ_ERR_SUCCESS) - { - char errbuf[1024]; - ERROR ("mqtt_connect_broker: mosquitto_connect failed: %s", - (status == MOSQ_ERR_ERRNO) - ? sstrerror(errno, errbuf, sizeof (errbuf)) - : mosquitto_strerror (status)); - return (-1); - } + if (conf->connected) + return (0); + + status = mosquitto_reconnect(conf->mosq); + if (status != MOSQ_ERR_SUCCESS) { + char errbuf[1024]; + ERROR("mqtt_connect_broker: mosquitto_connect failed: %s", + (status == MOSQ_ERR_ERRNO) ? sstrerror(errno, errbuf, sizeof(errbuf)) + : mosquitto_strerror(status)); + return (-1); + } - conf->connected = 1; + conf->connected = 1; - c_release (LOG_INFO, - &conf->complaint_cantpublish, + c_release(LOG_INFO, &conf->complaint_cantpublish, "mqtt plugin: successfully reconnected to broker \"%s:%d\"", conf->host, conf->port); - return (0); + return (0); } /* mqtt_reconnect */ /* must hold conf->lock when calling. */ -static int mqtt_connect (mqtt_client_conf_t *conf) -{ - char const *client_id; - int status; +static int mqtt_connect(mqtt_client_conf_t *conf) { + char const *client_id; + int status; - if (conf->mosq != NULL) - return mqtt_reconnect (conf); + if (conf->mosq != NULL) + return mqtt_reconnect(conf); - if (conf->client_id) - client_id = conf->client_id; - else - client_id = hostname_g; + if (conf->client_id) + client_id = conf->client_id; + else + client_id = hostname_g; #if LIBMOSQUITTO_MAJOR == 0 - conf->mosq = mosquitto_new (client_id, /* user data = */ conf); + conf->mosq = mosquitto_new(client_id, /* user data = */ conf); #else - conf->mosq = mosquitto_new (client_id, conf->clean_session, /* user data = */ conf); + conf->mosq = + mosquitto_new(client_id, conf->clean_session, /* user data = */ conf); #endif - if (conf->mosq == NULL) - { - ERROR ("mqtt plugin: mosquitto_new failed"); - return (-1); - } + if (conf->mosq == NULL) { + ERROR("mqtt plugin: mosquitto_new failed"); + return (-1); + } #if LIBMOSQUITTO_MAJOR != 0 - if (conf->cacertificatefile) { - status = mosquitto_tls_set(conf->mosq, conf->cacertificatefile, NULL, - conf->certificatefile, conf->certificatekeyfile, /* pw_callback */NULL); - if (status != MOSQ_ERR_SUCCESS) { - ERROR ("mqtt plugin: cannot mosquitto_tls_set: %s", mosquitto_strerror(status)); - mosquitto_destroy (conf->mosq); - conf->mosq = NULL; - return (-1); - } - - status = mosquitto_tls_opts_set(conf->mosq, SSL_VERIFY_PEER, conf->tlsprotocol, conf->ciphersuite); - if (status != MOSQ_ERR_SUCCESS) { - ERROR ("mqtt plugin: cannot mosquitto_tls_opts_set: %s", mosquitto_strerror(status)); - mosquitto_destroy (conf->mosq); - conf->mosq = NULL; - return (-1); - } - - status = mosquitto_tls_insecure_set(conf->mosq, false); - if (status != MOSQ_ERR_SUCCESS) { - ERROR ("mqtt plugin: cannot mosquitto_tls_insecure_set: %s", mosquitto_strerror(status)); - mosquitto_destroy (conf->mosq); - conf->mosq = NULL; - return (-1); - } + if (conf->cacertificatefile) { + status = mosquitto_tls_set(conf->mosq, conf->cacertificatefile, NULL, + conf->certificatefile, conf->certificatekeyfile, + /* pw_callback */ NULL); + if (status != MOSQ_ERR_SUCCESS) { + ERROR("mqtt plugin: cannot mosquitto_tls_set: %s", + mosquitto_strerror(status)); + mosquitto_destroy(conf->mosq); + conf->mosq = NULL; + return (-1); + } + + status = mosquitto_tls_opts_set(conf->mosq, SSL_VERIFY_PEER, + conf->tlsprotocol, conf->ciphersuite); + if (status != MOSQ_ERR_SUCCESS) { + ERROR("mqtt plugin: cannot mosquitto_tls_opts_set: %s", + mosquitto_strerror(status)); + mosquitto_destroy(conf->mosq); + conf->mosq = NULL; + return (-1); + } + + status = mosquitto_tls_insecure_set(conf->mosq, false); + if (status != MOSQ_ERR_SUCCESS) { + ERROR("mqtt plugin: cannot mosquitto_tls_insecure_set: %s", + mosquitto_strerror(status)); + mosquitto_destroy(conf->mosq); + conf->mosq = NULL; + return (-1); } + } #endif - if (conf->username && conf->password) - { - status = mosquitto_username_pw_set (conf->mosq, conf->username, conf->password); - if (status != MOSQ_ERR_SUCCESS) - { - char errbuf[1024]; - ERROR ("mqtt plugin: mosquitto_username_pw_set failed: %s", - (status == MOSQ_ERR_ERRNO) - ? sstrerror (errno, errbuf, sizeof (errbuf)) - : mosquitto_strerror (status)); - - mosquitto_destroy (conf->mosq); - conf->mosq = NULL; - return (-1); - } + if (conf->username && conf->password) { + status = + mosquitto_username_pw_set(conf->mosq, conf->username, conf->password); + if (status != MOSQ_ERR_SUCCESS) { + char errbuf[1024]; + ERROR("mqtt plugin: mosquitto_username_pw_set failed: %s", + (status == MOSQ_ERR_ERRNO) + ? sstrerror(errno, errbuf, sizeof(errbuf)) + : mosquitto_strerror(status)); + + mosquitto_destroy(conf->mosq); + conf->mosq = NULL; + return (-1); } + } #if LIBMOSQUITTO_MAJOR == 0 - status = mosquitto_connect (conf->mosq, conf->host, conf->port, - /* keepalive = */ MQTT_KEEPALIVE, /* clean session = */ conf->clean_session); + status = mosquitto_connect(conf->mosq, conf->host, conf->port, + /* keepalive = */ MQTT_KEEPALIVE, + /* clean session = */ conf->clean_session); #else - status = mosquitto_connect (conf->mosq, conf->host, conf->port, MQTT_KEEPALIVE); + status = + mosquitto_connect(conf->mosq, conf->host, conf->port, MQTT_KEEPALIVE); #endif - if (status != MOSQ_ERR_SUCCESS) - { - char errbuf[1024]; - ERROR ("mqtt plugin: mosquitto_connect failed: %s", - (status == MOSQ_ERR_ERRNO) - ? sstrerror (errno, errbuf, sizeof (errbuf)) - : mosquitto_strerror (status)); - - mosquitto_destroy (conf->mosq); - conf->mosq = NULL; - return (-1); - } - - if (!conf->publish) - { - mosquitto_message_callback_set (conf->mosq, on_message); - - status = mosquitto_subscribe (conf->mosq, - /* message_id = */ NULL, - conf->topic, conf->qos); - if (status != MOSQ_ERR_SUCCESS) - { - ERROR ("mqtt plugin: Subscribing to \"%s\" failed: %s", - conf->topic, mosquitto_strerror (status)); - - mosquitto_disconnect (conf->mosq); - mosquitto_destroy (conf->mosq); - conf->mosq = NULL; - return (-1); - } + if (status != MOSQ_ERR_SUCCESS) { + char errbuf[1024]; + ERROR("mqtt plugin: mosquitto_connect failed: %s", + (status == MOSQ_ERR_ERRNO) ? sstrerror(errno, errbuf, sizeof(errbuf)) + : mosquitto_strerror(status)); + + mosquitto_destroy(conf->mosq); + conf->mosq = NULL; + return (-1); + } + + if (!conf->publish) { + mosquitto_message_callback_set(conf->mosq, on_message); + + status = + mosquitto_subscribe(conf->mosq, + /* message_id = */ NULL, conf->topic, conf->qos); + if (status != MOSQ_ERR_SUCCESS) { + ERROR("mqtt plugin: Subscribing to \"%s\" failed: %s", conf->topic, + mosquitto_strerror(status)); + + mosquitto_disconnect(conf->mosq); + mosquitto_destroy(conf->mosq); + conf->mosq = NULL; + return (-1); } + } - conf->connected = 1; - return (0); + conf->connected = 1; + return (0); } /* mqtt_connect */ -static void *subscribers_thread (void *arg) -{ - mqtt_client_conf_t *conf = arg; - int status; +static void *subscribers_thread(void *arg) { + mqtt_client_conf_t *conf = arg; + int status; - conf->loop = 1; + conf->loop = 1; - while (conf->loop) - { - status = mqtt_connect (conf); - if (status != 0) - { - sleep (1); - continue; - } + while (conf->loop) { + status = mqtt_connect(conf); + if (status != 0) { + sleep(1); + continue; + } - /* The documentation says "0" would map to the default (1000ms), but - * that does not work on some versions. */ +/* The documentation says "0" would map to the default (1000ms), but + * that does not work on some versions. */ #if LIBMOSQUITTO_MAJOR == 0 - status = mosquitto_loop (conf->mosq, /* timeout = */ 1000 /* ms */); + status = mosquitto_loop(conf->mosq, /* timeout = */ 1000 /* ms */); #else - status = mosquitto_loop (conf->mosq, - /* timeout[ms] = */ 1000, - /* max_packets = */ 100); + status = mosquitto_loop(conf->mosq, + /* timeout[ms] = */ 1000, + /* max_packets = */ 100); #endif - if (status == MOSQ_ERR_CONN_LOST) - { - conf->connected = 0; - continue; - } - else if (status != MOSQ_ERR_SUCCESS) - { - ERROR ("mqtt plugin: mosquitto_loop failed: %s", - mosquitto_strerror (status)); - mosquitto_destroy (conf->mosq); - conf->mosq = NULL; - conf->connected = 0; - continue; - } - - DEBUG ("mqtt plugin: mosquitto_loop succeeded."); - } /* while (conf->loop) */ - - pthread_exit (0); + if (status == MOSQ_ERR_CONN_LOST) { + conf->connected = 0; + continue; + } else if (status != MOSQ_ERR_SUCCESS) { + ERROR("mqtt plugin: mosquitto_loop failed: %s", + mosquitto_strerror(status)); + mosquitto_destroy(conf->mosq); + conf->mosq = NULL; + conf->connected = 0; + continue; + } + + DEBUG("mqtt plugin: mosquitto_loop succeeded."); + } /* while (conf->loop) */ + + pthread_exit(0); } /* void *subscribers_thread */ -static int publish (mqtt_client_conf_t *conf, char const *topic, - void const *payload, size_t payload_len) -{ - int status; +static int publish(mqtt_client_conf_t *conf, char const *topic, + void const *payload, size_t payload_len) { + int status; - pthread_mutex_lock (&conf->lock); + pthread_mutex_lock(&conf->lock); - status = mqtt_connect (conf); - if (status != 0) { - pthread_mutex_unlock (&conf->lock); - ERROR ("mqtt plugin: unable to reconnect to broker"); - return (status); - } + status = mqtt_connect(conf); + if (status != 0) { + pthread_mutex_unlock(&conf->lock); + ERROR("mqtt plugin: unable to reconnect to broker"); + return (status); + } - status = mosquitto_publish(conf->mosq, /* message_id */ NULL, topic, + status = mosquitto_publish(conf->mosq, /* message_id */ NULL, topic, #if LIBMOSQUITTO_MAJOR == 0 - (uint32_t) payload_len, payload, + (uint32_t)payload_len, payload, #else - (int) payload_len, payload, + (int)payload_len, payload, #endif - conf->qos, conf->retain); - if (status != MOSQ_ERR_SUCCESS) - { - char errbuf[1024]; - c_complain (LOG_ERR, - &conf->complaint_cantpublish, - "mqtt plugin: mosquitto_publish failed: %s", - (status == MOSQ_ERR_ERRNO) - ? sstrerror(errno, errbuf, sizeof (errbuf)) - : mosquitto_strerror(status)); - /* Mark our connection "down" regardless of the error as a safety - * measure; we will try to reconnect the next time we have to publish a - * message */ - conf->connected = 0; - - pthread_mutex_unlock (&conf->lock); - return (-1); - } + conf->qos, conf->retain); + if (status != MOSQ_ERR_SUCCESS) { + char errbuf[1024]; + c_complain(LOG_ERR, &conf->complaint_cantpublish, + "mqtt plugin: mosquitto_publish failed: %s", + (status == MOSQ_ERR_ERRNO) + ? sstrerror(errno, errbuf, sizeof(errbuf)) + : mosquitto_strerror(status)); + /* Mark our connection "down" regardless of the error as a safety + * measure; we will try to reconnect the next time we have to publish a + * message */ + conf->connected = 0; - pthread_mutex_unlock (&conf->lock); - return (0); + pthread_mutex_unlock(&conf->lock); + return (-1); + } + + pthread_mutex_unlock(&conf->lock); + return (0); } /* int publish */ -static int format_topic (char *buf, size_t buf_len, - data_set_t const *ds, value_list_t const *vl, - mqtt_client_conf_t *conf) -{ - char name[MQTT_MAX_TOPIC_SIZE]; - int status; +static int format_topic(char *buf, size_t buf_len, data_set_t const *ds, + value_list_t const *vl, mqtt_client_conf_t *conf) { + char name[MQTT_MAX_TOPIC_SIZE]; + int status; - if ((conf->topic_prefix == NULL) || (conf->topic_prefix[0] == 0)) - return (FORMAT_VL (buf, buf_len, vl)); + if ((conf->topic_prefix == NULL) || (conf->topic_prefix[0] == 0)) + return (FORMAT_VL(buf, buf_len, vl)); - status = FORMAT_VL (name, sizeof (name), vl); - if (status != 0) - return (status); + status = FORMAT_VL(name, sizeof(name), vl); + if (status != 0) + return (status); - status = ssnprintf (buf, buf_len, "%s/%s", conf->topic_prefix, name); - if ((status < 0) || (((size_t) status) >= buf_len)) - return (ENOMEM); + status = ssnprintf(buf, buf_len, "%s/%s", conf->topic_prefix, name); + if ((status < 0) || (((size_t)status) >= buf_len)) + return (ENOMEM); - return (0); + return (0); } /* int format_topic */ -static int mqtt_write (const data_set_t *ds, const value_list_t *vl, - user_data_t *user_data) -{ - mqtt_client_conf_t *conf; - char topic[MQTT_MAX_TOPIC_SIZE]; - char payload[MQTT_MAX_MESSAGE_SIZE]; - int status = 0; - - if ((user_data == NULL) || (user_data->data == NULL)) - return (EINVAL); - conf = user_data->data; - - status = format_topic (topic, sizeof (topic), ds, vl, conf); - if (status != 0) - { - ERROR ("mqtt plugin: format_topic failed with status %d.", status); - return (status); - } +static int mqtt_write(const data_set_t *ds, const value_list_t *vl, + user_data_t *user_data) { + mqtt_client_conf_t *conf; + char topic[MQTT_MAX_TOPIC_SIZE]; + char payload[MQTT_MAX_MESSAGE_SIZE]; + int status = 0; - status = format_values (payload, sizeof (payload), - ds, vl, conf->store_rates); - if (status != 0) - { - ERROR ("mqtt plugin: format_values failed with status %d.", status); - return (status); - } + if ((user_data == NULL) || (user_data->data == NULL)) + return (EINVAL); + conf = user_data->data; - status = publish (conf, topic, payload, strlen (payload) + 1); - if (status != 0) - { - ERROR ("mqtt plugin: publish failed: %s", mosquitto_strerror (status)); - return (status); - } + status = format_topic(topic, sizeof(topic), ds, vl, conf); + if (status != 0) { + ERROR("mqtt plugin: format_topic failed with status %d.", status); + return (status); + } + + status = format_values(payload, sizeof(payload), ds, vl, conf->store_rates); + if (status != 0) { + ERROR("mqtt plugin: format_values failed with status %d.", status); + return (status); + } + status = publish(conf, topic, payload, strlen(payload) + 1); + if (status != 0) { + ERROR("mqtt plugin: publish failed: %s", mosquitto_strerror(status)); return (status); + } + + return (status); } /* mqtt_write */ /* @@ -544,97 +525,88 @@ static int mqtt_write (const data_set_t *ds, const value_list_t *vl, * TLSProtocol "tlsv1.2" optional * */ -static int mqtt_config_publisher (oconfig_item_t *ci) -{ - mqtt_client_conf_t *conf; - char cb_name[1024]; - int status; - - conf = calloc (1, sizeof (*conf)); - if (conf == NULL) - { - ERROR ("mqtt plugin: calloc failed."); - return (-1); - } - conf->publish = 1; - - conf->name = NULL; - status = cf_util_get_string (ci, &conf->name); - if (status != 0) - { - mqtt_free (conf); - return (status); - } - - conf->host = strdup (MQTT_DEFAULT_HOST); - conf->port = MQTT_DEFAULT_PORT; - conf->client_id = NULL; - conf->qos = 0; - conf->topic_prefix = strdup (MQTT_DEFAULT_TOPIC_PREFIX); - conf->store_rates = 1; - - status = pthread_mutex_init (&conf->lock, NULL); - if (status != 0) - { - mqtt_free (conf); - return (status); - } - - C_COMPLAIN_INIT (&conf->complaint_cantpublish); - - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Host", child->key) == 0) - cf_util_get_string (child, &conf->host); - else if (strcasecmp ("Port", child->key) == 0) - { - int tmp = cf_util_get_port_number (child); - if (tmp < 0) - ERROR ("mqtt plugin: Invalid port number."); - else - conf->port = tmp; - } - else if (strcasecmp ("ClientId", child->key) == 0) - cf_util_get_string (child, &conf->client_id); - else if (strcasecmp ("User", child->key) == 0) - cf_util_get_string (child, &conf->username); - else if (strcasecmp ("Password", child->key) == 0) - cf_util_get_string (child, &conf->password); - else if (strcasecmp ("QoS", child->key) == 0) - { - int tmp = -1; - status = cf_util_get_int (child, &tmp); - if ((status != 0) || (tmp < 0) || (tmp > 2)) - ERROR ("mqtt plugin: Not a valid QoS setting."); - else - conf->qos = tmp; - } - else if (strcasecmp ("Prefix", child->key) == 0) - cf_util_get_string (child, &conf->topic_prefix); - else if (strcasecmp ("StoreRates", child->key) == 0) - cf_util_get_boolean (child, &conf->store_rates); - else if (strcasecmp ("Retain", child->key) == 0) - cf_util_get_boolean (child, &conf->retain); - else if (strcasecmp ("CACert", child->key) == 0) - cf_util_get_string (child, &conf->cacertificatefile); - else if (strcasecmp ("CertificateFile", child->key) == 0) - cf_util_get_string (child, &conf->certificatefile); - else if (strcasecmp ("CertificateKeyFile", child->key) == 0) - cf_util_get_string (child, &conf->certificatekeyfile); - else if (strcasecmp ("TLSProtocol", child->key) == 0) - cf_util_get_string (child, &conf->tlsprotocol); - else if (strcasecmp ("CipherSuite", child->key) == 0) - cf_util_get_string (child, &conf->ciphersuite); - else - ERROR ("mqtt plugin: Unknown config option: %s", child->key); - } - - ssnprintf (cb_name, sizeof (cb_name), "mqtt/%s", conf->name); - plugin_register_write (cb_name, mqtt_write, &(user_data_t) { - .data = conf, - }); - return (0); +static int mqtt_config_publisher(oconfig_item_t *ci) { + mqtt_client_conf_t *conf; + char cb_name[1024]; + int status; + + conf = calloc(1, sizeof(*conf)); + if (conf == NULL) { + ERROR("mqtt plugin: calloc failed."); + return (-1); + } + conf->publish = 1; + + conf->name = NULL; + status = cf_util_get_string(ci, &conf->name); + if (status != 0) { + mqtt_free(conf); + return (status); + } + + conf->host = strdup(MQTT_DEFAULT_HOST); + conf->port = MQTT_DEFAULT_PORT; + conf->client_id = NULL; + conf->qos = 0; + conf->topic_prefix = strdup(MQTT_DEFAULT_TOPIC_PREFIX); + conf->store_rates = 1; + + status = pthread_mutex_init(&conf->lock, NULL); + if (status != 0) { + mqtt_free(conf); + return (status); + } + + C_COMPLAIN_INIT(&conf->complaint_cantpublish); + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + if (strcasecmp("Host", child->key) == 0) + cf_util_get_string(child, &conf->host); + else if (strcasecmp("Port", child->key) == 0) { + int tmp = cf_util_get_port_number(child); + if (tmp < 0) + ERROR("mqtt plugin: Invalid port number."); + else + conf->port = tmp; + } else if (strcasecmp("ClientId", child->key) == 0) + cf_util_get_string(child, &conf->client_id); + else if (strcasecmp("User", child->key) == 0) + cf_util_get_string(child, &conf->username); + else if (strcasecmp("Password", child->key) == 0) + cf_util_get_string(child, &conf->password); + else if (strcasecmp("QoS", child->key) == 0) { + int tmp = -1; + status = cf_util_get_int(child, &tmp); + if ((status != 0) || (tmp < 0) || (tmp > 2)) + ERROR("mqtt plugin: Not a valid QoS setting."); + else + conf->qos = tmp; + } else if (strcasecmp("Prefix", child->key) == 0) + cf_util_get_string(child, &conf->topic_prefix); + else if (strcasecmp("StoreRates", child->key) == 0) + cf_util_get_boolean(child, &conf->store_rates); + else if (strcasecmp("Retain", child->key) == 0) + cf_util_get_boolean(child, &conf->retain); + else if (strcasecmp("CACert", child->key) == 0) + cf_util_get_string(child, &conf->cacertificatefile); + else if (strcasecmp("CertificateFile", child->key) == 0) + cf_util_get_string(child, &conf->certificatefile); + else if (strcasecmp("CertificateKeyFile", child->key) == 0) + cf_util_get_string(child, &conf->certificatekeyfile); + else if (strcasecmp("TLSProtocol", child->key) == 0) + cf_util_get_string(child, &conf->tlsprotocol); + else if (strcasecmp("CipherSuite", child->key) == 0) + cf_util_get_string(child, &conf->ciphersuite); + else + ERROR("mqtt plugin: Unknown config option: %s", child->key); + } + + ssnprintf(cb_name, sizeof(cb_name), "mqtt/%s", conf->name); + plugin_register_write(cb_name, mqtt_write, &(user_data_t){ + .data = conf, + }); + return (0); } /* mqtt_config_publisher */ /* @@ -647,92 +619,82 @@ static int mqtt_config_publisher (oconfig_item_t *ci) * Topic "collectd/#" * */ -static int mqtt_config_subscriber (oconfig_item_t *ci) -{ - mqtt_client_conf_t **tmp; - mqtt_client_conf_t *conf; - int status; - - conf = calloc (1, sizeof (*conf)); - if (conf == NULL) - { - ERROR ("mqtt plugin: calloc failed."); - return (-1); - } - conf->publish = 0; - - conf->name = NULL; - status = cf_util_get_string (ci, &conf->name); - if (status != 0) - { - mqtt_free (conf); - return (status); - } - - conf->host = strdup (MQTT_DEFAULT_HOST); - conf->port = MQTT_DEFAULT_PORT; - conf->client_id = NULL; - conf->qos = 2; - conf->topic = strdup (MQTT_DEFAULT_TOPIC); - conf->clean_session = 1; - - status = pthread_mutex_init (&conf->lock, NULL); - if (status != 0) - { - mqtt_free (conf); - return (status); - } - - C_COMPLAIN_INIT (&conf->complaint_cantpublish); - - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Host", child->key) == 0) - cf_util_get_string (child, &conf->host); - else if (strcasecmp ("Port", child->key) == 0) - { - status = cf_util_get_port_number (child); - if (status < 0) - ERROR ("mqtt plugin: Invalid port number."); - else - conf->port = status; - } - else if (strcasecmp ("ClientId", child->key) == 0) - cf_util_get_string (child, &conf->client_id); - else if (strcasecmp ("User", child->key) == 0) - cf_util_get_string (child, &conf->username); - else if (strcasecmp ("Password", child->key) == 0) - cf_util_get_string (child, &conf->password); - else if (strcasecmp ("QoS", child->key) == 0) - { - int qos = -1; - status = cf_util_get_int (child, &qos); - if ((status != 0) || (qos < 0) || (qos > 2)) - ERROR ("mqtt plugin: Not a valid QoS setting."); - else - conf->qos = qos; - } - else if (strcasecmp ("Topic", child->key) == 0) - cf_util_get_string (child, &conf->topic); - else if (strcasecmp ("CleanSession", child->key) == 0) - cf_util_get_boolean (child, &conf->clean_session); - else - ERROR ("mqtt plugin: Unknown config option: %s", child->key); - } - - tmp = realloc (subscribers, sizeof (*subscribers) * (subscribers_num + 1) ); - if (tmp == NULL) - { - ERROR ("mqtt plugin: realloc failed."); - mqtt_free (conf); - return (-1); - } - subscribers = tmp; - subscribers[subscribers_num] = conf; - subscribers_num++; - - return (0); +static int mqtt_config_subscriber(oconfig_item_t *ci) { + mqtt_client_conf_t **tmp; + mqtt_client_conf_t *conf; + int status; + + conf = calloc(1, sizeof(*conf)); + if (conf == NULL) { + ERROR("mqtt plugin: calloc failed."); + return (-1); + } + conf->publish = 0; + + conf->name = NULL; + status = cf_util_get_string(ci, &conf->name); + if (status != 0) { + mqtt_free(conf); + return (status); + } + + conf->host = strdup(MQTT_DEFAULT_HOST); + conf->port = MQTT_DEFAULT_PORT; + conf->client_id = NULL; + conf->qos = 2; + conf->topic = strdup(MQTT_DEFAULT_TOPIC); + conf->clean_session = 1; + + status = pthread_mutex_init(&conf->lock, NULL); + if (status != 0) { + mqtt_free(conf); + return (status); + } + + C_COMPLAIN_INIT(&conf->complaint_cantpublish); + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + if (strcasecmp("Host", child->key) == 0) + cf_util_get_string(child, &conf->host); + else if (strcasecmp("Port", child->key) == 0) { + status = cf_util_get_port_number(child); + if (status < 0) + ERROR("mqtt plugin: Invalid port number."); + else + conf->port = status; + } else if (strcasecmp("ClientId", child->key) == 0) + cf_util_get_string(child, &conf->client_id); + else if (strcasecmp("User", child->key) == 0) + cf_util_get_string(child, &conf->username); + else if (strcasecmp("Password", child->key) == 0) + cf_util_get_string(child, &conf->password); + else if (strcasecmp("QoS", child->key) == 0) { + int qos = -1; + status = cf_util_get_int(child, &qos); + if ((status != 0) || (qos < 0) || (qos > 2)) + ERROR("mqtt plugin: Not a valid QoS setting."); + else + conf->qos = qos; + } else if (strcasecmp("Topic", child->key) == 0) + cf_util_get_string(child, &conf->topic); + else if (strcasecmp("CleanSession", child->key) == 0) + cf_util_get_boolean(child, &conf->clean_session); + else + ERROR("mqtt plugin: Unknown config option: %s", child->key); + } + + tmp = realloc(subscribers, sizeof(*subscribers) * (subscribers_num + 1)); + if (tmp == NULL) { + ERROR("mqtt plugin: realloc failed."); + mqtt_free(conf); + return (-1); + } + subscribers = tmp; + subscribers[subscribers_num] = conf; + subscribers_num++; + + return (0); } /* mqtt_config_subscriber */ /* @@ -745,55 +707,49 @@ static int mqtt_config_subscriber (oconfig_item_t *ci) * * */ -static int mqtt_config (oconfig_item_t *ci) -{ - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("Publish", child->key) == 0) - mqtt_config_publisher (child); - else if (strcasecmp ("Subscribe", child->key) == 0) - mqtt_config_subscriber (child); - else - ERROR ("mqtt plugin: Unknown config option: %s", child->key); - } +static int mqtt_config(oconfig_item_t *ci) { + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Publish", child->key) == 0) + mqtt_config_publisher(child); + else if (strcasecmp("Subscribe", child->key) == 0) + mqtt_config_subscriber(child); + else + ERROR("mqtt plugin: Unknown config option: %s", child->key); + } - return (0); + return (0); } /* int mqtt_config */ -static int mqtt_init (void) -{ - mosquitto_lib_init (); - - for (size_t i = 0; i < subscribers_num; i++) - { - int status; - - if (subscribers[i]->loop) - continue; - - status = plugin_thread_create (&subscribers[i]->thread, - /* attrs = */ NULL, - /* func = */ subscribers_thread, - /* args = */ subscribers[i], - /* name = */ "mqtt"); - if (status != 0) - { - char errbuf[1024]; - ERROR ("mqtt plugin: pthread_create failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - continue; - } +static int mqtt_init(void) { + mosquitto_lib_init(); + + for (size_t i = 0; i < subscribers_num; i++) { + int status; + + if (subscribers[i]->loop) + continue; + + status = plugin_thread_create(&subscribers[i]->thread, + /* attrs = */ NULL, + /* func = */ subscribers_thread, + /* args = */ subscribers[i], + /* name = */ "mqtt"); + if (status != 0) { + char errbuf[1024]; + ERROR("mqtt plugin: pthread_create failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + continue; } + } - return (0); + return (0); } /* mqtt_init */ -void module_register (void) -{ - plugin_register_complex_config ("mqtt", mqtt_config); - plugin_register_init ("mqtt", mqtt_init); +void module_register(void) { + plugin_register_complex_config("mqtt", mqtt_config); + plugin_register_init("mqtt", mqtt_init); } /* void module_register */ /* vim: set sw=4 sts=4 et fdm=marker : */ diff --git a/src/multimeter.c b/src/multimeter.c index 9321daf8..913e277e 100644 --- a/src/multimeter.c +++ b/src/multimeter.c @@ -28,209 +28,197 @@ #include "plugin.h" #if HAVE_TERMIOS_H && HAVE_SYS_IOCTL_H && HAVE_MATH_H -# include -# include -# include +#include +#include +#include #else -# error "No applicable input method." +#error "No applicable input method." #endif static int fd = -1; #define LINE_LENGTH 14 -static int multimeter_read_value(double *value) -{ - int retry = 3; /* sometimes we receive garbadge */ - - do - { - struct timeval time_end; - - tcflush(fd, TCIFLUSH); - - if (gettimeofday (&time_end, NULL) < 0) - { - char errbuf[1024]; - ERROR ("multimeter plugin: gettimeofday failed: %s", - sstrerror (errno, errbuf, - sizeof (errbuf))); - return (-1); - } - time_end.tv_sec++; - - while (1) - { - char buf[LINE_LENGTH]; - char *range; - int status; - fd_set rfds; - struct timeval timeout; - struct timeval time_now; - - status = swrite (fd, "D", 1); - if (status < 0) - { - ERROR ("multimeter plugin: swrite failed."); - return (-1); - } - - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - - if (gettimeofday (&time_now, NULL) < 0) - { - char errbuf[1024]; - ERROR ("multimeter plugin: " - "gettimeofday failed: %s", - sstrerror (errno, errbuf, - sizeof (errbuf))); - return (-1); - } - if (timeval_cmp (time_end, time_now, &timeout) < 0) - break; - - status = select(fd+1, &rfds, NULL, NULL, &timeout); - - if (status > 0) /* usually we succeed */ - { - status = read(fd, buf, LINE_LENGTH); - - if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) - continue; - - /* Format: "DC 00.000mV \r" */ - if (status > 0 && status == LINE_LENGTH) - { - *value = strtod(buf + 2, &range); - - if ( range > (buf + 6) ) - { - range = buf + 9; - - switch ( *range ) - { - case 'p': *value *= 1.0E-12; break; - case 'n': *value *= 1.0E-9; break; - case 'u': *value *= 1.0E-6; break; - case 'm': *value *= 1.0E-3; break; - case 'k': *value *= 1.0E3; break; - case 'M': *value *= 1.0E6; break; - case 'G': *value *= 1.0E9; break; - } - } - else - return (-1); /* Overflow */ - - return (0); /* value received */ - } - else break; - } - else if (!status) /* Timeout */ - { - break; - } - else if ((status == -1) && ((errno == EAGAIN) || (errno == EINTR))) - { - continue; - } - else /* status == -1 */ - { - char errbuf[1024]; - ERROR ("multimeter plugin: " - "select failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - break; - } - } - } while (--retry); - - return (-2); /* no value received */ +static int multimeter_read_value(double *value) { + int retry = 3; /* sometimes we receive garbadge */ + + do { + struct timeval time_end; + + tcflush(fd, TCIFLUSH); + + if (gettimeofday(&time_end, NULL) < 0) { + char errbuf[1024]; + ERROR("multimeter plugin: gettimeofday failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + time_end.tv_sec++; + + while (1) { + char buf[LINE_LENGTH]; + char *range; + int status; + fd_set rfds; + struct timeval timeout; + struct timeval time_now; + + status = swrite(fd, "D", 1); + if (status < 0) { + ERROR("multimeter plugin: swrite failed."); + return (-1); + } + + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + + if (gettimeofday(&time_now, NULL) < 0) { + char errbuf[1024]; + ERROR("multimeter plugin: " + "gettimeofday failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + if (timeval_cmp(time_end, time_now, &timeout) < 0) + break; + + status = select(fd + 1, &rfds, NULL, NULL, &timeout); + + if (status > 0) /* usually we succeed */ + { + status = read(fd, buf, LINE_LENGTH); + + if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) + continue; + + /* Format: "DC 00.000mV \r" */ + if (status > 0 && status == LINE_LENGTH) { + *value = strtod(buf + 2, &range); + + if (range > (buf + 6)) { + range = buf + 9; + + switch (*range) { + case 'p': + *value *= 1.0E-12; + break; + case 'n': + *value *= 1.0E-9; + break; + case 'u': + *value *= 1.0E-6; + break; + case 'm': + *value *= 1.0E-3; + break; + case 'k': + *value *= 1.0E3; + break; + case 'M': + *value *= 1.0E6; + break; + case 'G': + *value *= 1.0E9; + break; + } + } else + return (-1); /* Overflow */ + + return (0); /* value received */ + } else + break; + } else if (!status) /* Timeout */ + { + break; + } else if ((status == -1) && ((errno == EAGAIN) || (errno == EINTR))) { + continue; + } else /* status == -1 */ + { + char errbuf[1024]; + ERROR("multimeter plugin: " + "select failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + break; + } + } + } while (--retry); + + return (-2); /* no value received */ } /* int multimeter_read_value */ -static int multimeter_init (void) -{ - char device[] = "/dev/ttyS "; - - for (int i = 0; i < 10; i++) - { - device[strlen(device)-1] = i + '0'; - - if ((fd = open(device, O_RDWR | O_NOCTTY)) != -1) - { - struct termios tios = { 0 }; - int rts = TIOCM_RTS; - double value; - - tios.c_cflag = B1200 | CS7 | CSTOPB | CREAD | CLOCAL; - tios.c_iflag = IGNBRK | IGNPAR; - tios.c_oflag = 0; - tios.c_lflag = 0; - tios.c_cc[VTIME] = 3; - tios.c_cc[VMIN] = LINE_LENGTH; - - tcflush(fd, TCIFLUSH); - tcsetattr(fd, TCSANOW, &tios); - ioctl(fd, TIOCMBIC, &rts); - - if (multimeter_read_value (&value) < -1) - { - close (fd); - fd = -1; - } - else - { - INFO ("multimeter plugin: Device " - "found at %s", device); - return (0); - } - } - } - - ERROR ("multimeter plugin: No device found"); - return (-1); +static int multimeter_init(void) { + char device[] = "/dev/ttyS "; + + for (int i = 0; i < 10; i++) { + device[strlen(device) - 1] = i + '0'; + + if ((fd = open(device, O_RDWR | O_NOCTTY)) != -1) { + struct termios tios = {0}; + int rts = TIOCM_RTS; + double value; + + tios.c_cflag = B1200 | CS7 | CSTOPB | CREAD | CLOCAL; + tios.c_iflag = IGNBRK | IGNPAR; + tios.c_oflag = 0; + tios.c_lflag = 0; + tios.c_cc[VTIME] = 3; + tios.c_cc[VMIN] = LINE_LENGTH; + + tcflush(fd, TCIFLUSH); + tcsetattr(fd, TCSANOW, &tios); + ioctl(fd, TIOCMBIC, &rts); + + if (multimeter_read_value(&value) < -1) { + close(fd); + fd = -1; + } else { + INFO("multimeter plugin: Device " + "found at %s", + device); + return (0); + } + } + } + + ERROR("multimeter plugin: No device found"); + return (-1); } #undef LINE_LENGTH -static void multimeter_submit (double value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void multimeter_submit(double value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "multimeter", sizeof (vl.plugin)); - sstrncpy (vl.type, "multimeter", sizeof (vl.type)); + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "multimeter", sizeof(vl.plugin)); + sstrncpy(vl.type, "multimeter", sizeof(vl.type)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static int multimeter_read (void) -{ - double value; +static int multimeter_read(void) { + double value; - if (fd < 0) - return (-1); + if (fd < 0) + return (-1); - if (multimeter_read_value (&value) != 0) - return (-1); + if (multimeter_read_value(&value) != 0) + return (-1); - multimeter_submit (value); - return (0); + multimeter_submit(value); + return (0); } /* int multimeter_read */ -static int multimeter_shutdown (void) -{ - if (fd >= 0) - { - close (fd); - fd = -1; - } +static int multimeter_shutdown(void) { + if (fd >= 0) { + close(fd); + fd = -1; + } - return (0); + return (0); } -void module_register (void) -{ - plugin_register_init ("multimeter", multimeter_init); - plugin_register_read ("multimeter", multimeter_read); - plugin_register_shutdown ("multimeter", multimeter_shutdown); +void module_register(void) { + plugin_register_init("multimeter", multimeter_init); + plugin_register_read("multimeter", multimeter_read); + plugin_register_shutdown("multimeter", multimeter_shutdown); } /* void module_register */ diff --git a/src/mysql.c b/src/mysql.c index a64b0e5b..8409d1b6 100644 --- a/src/mysql.c +++ b/src/mysql.c @@ -40,67 +40,67 @@ struct mysql_database_s /* {{{ */ { - char *instance; - char *alias; - char *host; - char *user; - char *pass; - char *database; - - /* mysql_ssl_set params */ - char *key; - char *cert; - char *ca; - char *capath; - char *cipher; - - char *socket; - int port; - int timeout; - - _Bool master_stats; - _Bool slave_stats; - _Bool innodb_stats; - _Bool wsrep_stats; - - _Bool slave_notif; - _Bool slave_io_running; - _Bool slave_sql_running; - - MYSQL *con; - _Bool is_connected; + char *instance; + char *alias; + char *host; + char *user; + char *pass; + char *database; + + /* mysql_ssl_set params */ + char *key; + char *cert; + char *ca; + char *capath; + char *cipher; + + char *socket; + int port; + int timeout; + + _Bool master_stats; + _Bool slave_stats; + _Bool innodb_stats; + _Bool wsrep_stats; + + _Bool slave_notif; + _Bool slave_io_running; + _Bool slave_sql_running; + + MYSQL *con; + _Bool is_connected; }; typedef struct mysql_database_s mysql_database_t; /* }}} */ -static int mysql_read (user_data_t *ud); +static int mysql_read(user_data_t *ud); -static void mysql_database_free (void *arg) /* {{{ */ +static void mysql_database_free(void *arg) /* {{{ */ { - mysql_database_t *db; - - DEBUG ("mysql plugin: mysql_database_free (arg = %p);", arg); - - db = arg; - - if (db == NULL) - return; - - if (db->con != NULL) - mysql_close (db->con); - - sfree (db->alias); - sfree (db->host); - sfree (db->user); - sfree (db->pass); - sfree (db->socket); - sfree (db->instance); - sfree (db->database); - sfree (db->key); - sfree (db->cert); - sfree (db->ca); - sfree (db->capath); - sfree (db->cipher); - sfree (db); + mysql_database_t *db; + + DEBUG("mysql plugin: mysql_database_free (arg = %p);", arg); + + db = arg; + + if (db == NULL) + return; + + if (db->con != NULL) + mysql_close(db->con); + + sfree(db->alias); + sfree(db->host); + sfree(db->user); + sfree(db->pass); + sfree(db->socket); + sfree(db->instance); + sfree(db->database); + sfree(db->key); + sfree(db->cert); + sfree(db->ca); + sfree(db->capath); + sfree(db->cipher); + sfree(db); } /* }}} void mysql_database_free */ /* Configuration handling functions {{{ @@ -113,932 +113,834 @@ static void mysql_database_free (void *arg) /* {{{ */ * * */ -static int mysql_config_database (oconfig_item_t *ci) /* {{{ */ +static int mysql_config_database(oconfig_item_t *ci) /* {{{ */ { - mysql_database_t *db; - int status = 0; - - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("mysql plugin: The `Database' block " - "needs exactly one string argument."); - return (-1); - } - - db = calloc (1, sizeof (*db)); - if (db == NULL) - { - ERROR ("mysql plugin: calloc failed."); - return (-1); - } - - /* initialize all the pointers */ - db->alias = NULL; - db->host = NULL; - db->user = NULL; - db->pass = NULL; - db->database = NULL; - db->key = NULL; - db->cert = NULL; - db->ca = NULL; - db->capath = NULL; - db->cipher = NULL; - - db->socket = NULL; - db->con = NULL; - db->timeout = 0; - - /* trigger a notification, if it's not running */ - db->slave_io_running = 1; - db->slave_sql_running = 1; - - status = cf_util_get_string (ci, &db->instance); - if (status != 0) - { - sfree (db); - return (status); - } - assert (db->instance != NULL); - - /* Fill the `mysql_database_t' structure.. */ - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("Alias", child->key) == 0) - status = cf_util_get_string (child, &db->alias); - else if (strcasecmp ("Host", child->key) == 0) - status = cf_util_get_string (child, &db->host); - else if (strcasecmp ("User", child->key) == 0) - status = cf_util_get_string (child, &db->user); - else if (strcasecmp ("Password", child->key) == 0) - status = cf_util_get_string (child, &db->pass); - else if (strcasecmp ("Port", child->key) == 0) - { - status = cf_util_get_port_number (child); - if (status > 0) - { - db->port = status; - status = 0; - } - } - else if (strcasecmp ("Socket", child->key) == 0) - status = cf_util_get_string (child, &db->socket); - else if (strcasecmp ("Database", child->key) == 0) - status = cf_util_get_string (child, &db->database); - else if (strcasecmp ("SSLKey", child->key) == 0) - status = cf_util_get_string (child, &db->key); - else if (strcasecmp ("SSLCert", child->key) == 0) - status = cf_util_get_string (child, &db->cert); - else if (strcasecmp ("SSLCA", child->key) == 0) - status = cf_util_get_string (child, &db->ca); - else if (strcasecmp ("SSLCAPath", child->key) == 0) - status = cf_util_get_string (child, &db->capath); - else if (strcasecmp ("SSLCipher", child->key) == 0) - status = cf_util_get_string (child, &db->cipher); - else if (strcasecmp ("ConnectTimeout", child->key) == 0) - status = cf_util_get_int (child, &db->timeout); - else if (strcasecmp ("MasterStats", child->key) == 0) - status = cf_util_get_boolean (child, &db->master_stats); - else if (strcasecmp ("SlaveStats", child->key) == 0) - status = cf_util_get_boolean (child, &db->slave_stats); - else if (strcasecmp ("SlaveNotifications", child->key) == 0) - status = cf_util_get_boolean (child, &db->slave_notif); - else if (strcasecmp ("InnodbStats", child->key) == 0) - status = cf_util_get_boolean (child, &db->innodb_stats); - else if (strcasecmp ("WsrepStats", child->key) == 0) - status = cf_util_get_boolean (child, &db->wsrep_stats); - else - { - WARNING ("mysql plugin: Option `%s' not allowed here.", child->key); - status = -1; - } - - if (status != 0) - break; - } - - /* If all went well, register this database for reading */ - if (status == 0) - { - char cb_name[DATA_MAX_NAME_LEN]; - - DEBUG ("mysql plugin: Registering new read callback: %s", - (db->database != NULL) ? db->database : ""); - - if (db->instance != NULL) - ssnprintf (cb_name, sizeof (cb_name), "mysql-%s", - db->instance); - else - sstrncpy (cb_name, "mysql", sizeof (cb_name)); - - plugin_register_complex_read (/* group = */ NULL, cb_name, - mysql_read, /* interval = */ 0, &(user_data_t) { - .data = db, - .free_func = mysql_database_free, - }); - } - else - { - mysql_database_free (db); - return (-1); - } - - return (0); + mysql_database_t *db; + int status = 0; + + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("mysql plugin: The `Database' block " + "needs exactly one string argument."); + return (-1); + } + + db = calloc(1, sizeof(*db)); + if (db == NULL) { + ERROR("mysql plugin: calloc failed."); + return (-1); + } + + /* initialize all the pointers */ + db->alias = NULL; + db->host = NULL; + db->user = NULL; + db->pass = NULL; + db->database = NULL; + db->key = NULL; + db->cert = NULL; + db->ca = NULL; + db->capath = NULL; + db->cipher = NULL; + + db->socket = NULL; + db->con = NULL; + db->timeout = 0; + + /* trigger a notification, if it's not running */ + db->slave_io_running = 1; + db->slave_sql_running = 1; + + status = cf_util_get_string(ci, &db->instance); + if (status != 0) { + sfree(db); + return (status); + } + assert(db->instance != NULL); + + /* Fill the `mysql_database_t' structure.. */ + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Alias", child->key) == 0) + status = cf_util_get_string(child, &db->alias); + else if (strcasecmp("Host", child->key) == 0) + status = cf_util_get_string(child, &db->host); + else if (strcasecmp("User", child->key) == 0) + status = cf_util_get_string(child, &db->user); + else if (strcasecmp("Password", child->key) == 0) + status = cf_util_get_string(child, &db->pass); + else if (strcasecmp("Port", child->key) == 0) { + status = cf_util_get_port_number(child); + if (status > 0) { + db->port = status; + status = 0; + } + } else if (strcasecmp("Socket", child->key) == 0) + status = cf_util_get_string(child, &db->socket); + else if (strcasecmp("Database", child->key) == 0) + status = cf_util_get_string(child, &db->database); + else if (strcasecmp("SSLKey", child->key) == 0) + status = cf_util_get_string(child, &db->key); + else if (strcasecmp("SSLCert", child->key) == 0) + status = cf_util_get_string(child, &db->cert); + else if (strcasecmp("SSLCA", child->key) == 0) + status = cf_util_get_string(child, &db->ca); + else if (strcasecmp("SSLCAPath", child->key) == 0) + status = cf_util_get_string(child, &db->capath); + else if (strcasecmp("SSLCipher", child->key) == 0) + status = cf_util_get_string(child, &db->cipher); + else if (strcasecmp("ConnectTimeout", child->key) == 0) + status = cf_util_get_int(child, &db->timeout); + else if (strcasecmp("MasterStats", child->key) == 0) + status = cf_util_get_boolean(child, &db->master_stats); + else if (strcasecmp("SlaveStats", child->key) == 0) + status = cf_util_get_boolean(child, &db->slave_stats); + else if (strcasecmp("SlaveNotifications", child->key) == 0) + status = cf_util_get_boolean(child, &db->slave_notif); + else if (strcasecmp("InnodbStats", child->key) == 0) + status = cf_util_get_boolean(child, &db->innodb_stats); + else if (strcasecmp("WsrepStats", child->key) == 0) + status = cf_util_get_boolean(child, &db->wsrep_stats); + else { + WARNING("mysql plugin: Option `%s' not allowed here.", child->key); + status = -1; + } + + if (status != 0) + break; + } + + /* If all went well, register this database for reading */ + if (status == 0) { + char cb_name[DATA_MAX_NAME_LEN]; + + DEBUG("mysql plugin: Registering new read callback: %s", + (db->database != NULL) ? db->database : ""); + + if (db->instance != NULL) + ssnprintf(cb_name, sizeof(cb_name), "mysql-%s", db->instance); + else + sstrncpy(cb_name, "mysql", sizeof(cb_name)); + + plugin_register_complex_read( + /* group = */ NULL, cb_name, mysql_read, /* interval = */ 0, + &(user_data_t){ + .data = db, .free_func = mysql_database_free, + }); + } else { + mysql_database_free(db); + return (-1); + } + + return (0); } /* }}} int mysql_config_database */ -static int mysql_config (oconfig_item_t *ci) /* {{{ */ +static int mysql_config(oconfig_item_t *ci) /* {{{ */ { - if (ci == NULL) - return (EINVAL); - - /* Fill the `mysql_database_t' structure.. */ - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("Database", child->key) == 0) - mysql_config_database (child); - else - WARNING ("mysql plugin: Option \"%s\" not allowed here.", - child->key); - } - - return (0); + if (ci == NULL) + return (EINVAL); + + /* Fill the `mysql_database_t' structure.. */ + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Database", child->key) == 0) + mysql_config_database(child); + else + WARNING("mysql plugin: Option \"%s\" not allowed here.", child->key); + } + + return (0); } /* }}} int mysql_config */ /* }}} End of configuration handling functions */ -static MYSQL *getconnection (mysql_database_t *db) -{ - const char *cipher; - - if (db->is_connected) - { - int status; - - status = mysql_ping (db->con); - if (status == 0) - return (db->con); - - WARNING ("mysql plugin: Lost connection to instance \"%s\": %s", - db->instance, mysql_error (db->con)); - } - db->is_connected = 0; - - if (db->con == NULL) - { - db->con = mysql_init (NULL); - if (db->con == NULL) - { - ERROR ("mysql plugin: mysql_init failed: %s", - mysql_error (db->con)); - return (NULL); - } - } - - /* Configure TCP connect timeout (default: 0) */ - db->con->options.connect_timeout = db->timeout; - - mysql_ssl_set (db->con, db->key, db->cert, db->ca, db->capath, db->cipher); - - if (mysql_real_connect (db->con, db->host, db->user, db->pass, - db->database, db->port, db->socket, 0) == NULL) - { - ERROR ("mysql plugin: Failed to connect to database %s " - "at server %s: %s", - (db->database != NULL) ? db->database : "", - (db->host != NULL) ? db->host : "localhost", - mysql_error (db->con)); - return (NULL); - } - - cipher = mysql_get_ssl_cipher (db->con); - - INFO ("mysql plugin: Successfully connected to database %s " - "at server %s with cipher %s " - "(server version: %s, protocol version: %d) ", - (db->database != NULL) ? db->database : "", - mysql_get_host_info (db->con), - (cipher != NULL) ? cipher : "", - mysql_get_server_info (db->con), - mysql_get_proto_info (db->con)); - - db->is_connected = 1; - return (db->con); +static MYSQL *getconnection(mysql_database_t *db) { + const char *cipher; + + if (db->is_connected) { + int status; + + status = mysql_ping(db->con); + if (status == 0) + return (db->con); + + WARNING("mysql plugin: Lost connection to instance \"%s\": %s", + db->instance, mysql_error(db->con)); + } + db->is_connected = 0; + + if (db->con == NULL) { + db->con = mysql_init(NULL); + if (db->con == NULL) { + ERROR("mysql plugin: mysql_init failed: %s", mysql_error(db->con)); + return (NULL); + } + } + + /* Configure TCP connect timeout (default: 0) */ + db->con->options.connect_timeout = db->timeout; + + mysql_ssl_set(db->con, db->key, db->cert, db->ca, db->capath, db->cipher); + + if (mysql_real_connect(db->con, db->host, db->user, db->pass, db->database, + db->port, db->socket, 0) == NULL) { + ERROR("mysql plugin: Failed to connect to database %s " + "at server %s: %s", + (db->database != NULL) ? db->database : "", + (db->host != NULL) ? db->host : "localhost", mysql_error(db->con)); + return (NULL); + } + + cipher = mysql_get_ssl_cipher(db->con); + + INFO("mysql plugin: Successfully connected to database %s " + "at server %s with cipher %s " + "(server version: %s, protocol version: %d) ", + (db->database != NULL) ? db->database : "", + mysql_get_host_info(db->con), (cipher != NULL) ? cipher : "", + mysql_get_server_info(db->con), mysql_get_proto_info(db->con)); + + db->is_connected = 1; + return (db->con); } /* static MYSQL *getconnection (mysql_database_t *db) */ -static void set_host (mysql_database_t *db, char *buf, size_t buflen) -{ - if (db->alias) - sstrncpy (buf, db->alias, buflen); - else if ((db->host == NULL) - || (strcmp ("", db->host) == 0) - || (strcmp ("127.0.0.1", db->host) == 0) - || (strcmp ("localhost", db->host) == 0)) - sstrncpy (buf, hostname_g, buflen); - else - sstrncpy (buf, db->host, buflen); +static void set_host(mysql_database_t *db, char *buf, size_t buflen) { + if (db->alias) + sstrncpy(buf, db->alias, buflen); + else if ((db->host == NULL) || (strcmp("", db->host) == 0) || + (strcmp("127.0.0.1", db->host) == 0) || + (strcmp("localhost", db->host) == 0)) + sstrncpy(buf, hostname_g, buflen); + else + sstrncpy(buf, db->host, buflen); } /* void set_host */ -static void submit (const char *type, const char *type_instance, - value_t *values, size_t values_len, mysql_database_t *db) -{ - value_list_t vl = VALUE_LIST_INIT; +static void submit(const char *type, const char *type_instance, value_t *values, + size_t values_len, mysql_database_t *db) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = values; - vl.values_len = values_len; + vl.values = values; + vl.values_len = values_len; - set_host (db, vl.host, sizeof (vl.host)); + set_host(db, vl.host, sizeof(vl.host)); - sstrncpy (vl.plugin, "mysql", sizeof (vl.plugin)); + sstrncpy(vl.plugin, "mysql", sizeof(vl.plugin)); - /* Assured by "mysql_config_database" */ - assert (db->instance != NULL); - sstrncpy (vl.plugin_instance, db->instance, sizeof (vl.plugin_instance)); + /* Assured by "mysql_config_database" */ + assert(db->instance != NULL); + sstrncpy(vl.plugin_instance, db->instance, sizeof(vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + if (type_instance != NULL) + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* submit */ -static void gauge_submit (const char *type, const char *type_instance, - gauge_t value, mysql_database_t *db) -{ - submit (type, type_instance, &(value_t) { .gauge = value }, 1, db); +static void gauge_submit(const char *type, const char *type_instance, + gauge_t value, mysql_database_t *db) { + submit(type, type_instance, &(value_t){.gauge = value}, 1, db); } /* void gauge_submit */ -static void derive_submit (const char *type, const char *type_instance, - derive_t value, mysql_database_t *db) -{ - submit (type, type_instance, &(value_t) { .derive = value }, 1, db); +static void derive_submit(const char *type, const char *type_instance, + derive_t value, mysql_database_t *db) { + submit(type, type_instance, &(value_t){.derive = value}, 1, db); } /* void derive_submit */ -static void traffic_submit (derive_t rx, derive_t tx, mysql_database_t *db) -{ - value_t values[] = { - { .derive = rx }, - { .derive = tx }, - }; +static void traffic_submit(derive_t rx, derive_t tx, mysql_database_t *db) { + value_t values[] = { + {.derive = rx}, {.derive = tx}, + }; - submit ("mysql_octets", NULL, values, STATIC_ARRAY_SIZE (values), db); + submit("mysql_octets", NULL, values, STATIC_ARRAY_SIZE(values), db); } /* void traffic_submit */ -static MYSQL_RES *exec_query (MYSQL *con, const char *query) -{ - MYSQL_RES *res; - - int query_len = strlen (query); - - if (mysql_real_query (con, query, query_len)) - { - ERROR ("mysql plugin: Failed to execute query: %s", - mysql_error (con)); - INFO ("mysql plugin: SQL query was: %s", query); - return (NULL); - } - - res = mysql_store_result (con); - if (res == NULL) - { - ERROR ("mysql plugin: Failed to store query result: %s", - mysql_error (con)); - INFO ("mysql plugin: SQL query was: %s", query); - return (NULL); - } - - return (res); +static MYSQL_RES *exec_query(MYSQL *con, const char *query) { + MYSQL_RES *res; + + int query_len = strlen(query); + + if (mysql_real_query(con, query, query_len)) { + ERROR("mysql plugin: Failed to execute query: %s", mysql_error(con)); + INFO("mysql plugin: SQL query was: %s", query); + return (NULL); + } + + res = mysql_store_result(con); + if (res == NULL) { + ERROR("mysql plugin: Failed to store query result: %s", mysql_error(con)); + INFO("mysql plugin: SQL query was: %s", query); + return (NULL); + } + + return (res); } /* exec_query */ -static int mysql_read_master_stats (mysql_database_t *db, MYSQL *con) -{ - MYSQL_RES *res; - MYSQL_ROW row; - - const char *query; - int field_num; - unsigned long long position; - - query = "SHOW MASTER STATUS"; - - res = exec_query (con, query); - if (res == NULL) - return (-1); - - row = mysql_fetch_row (res); - if (row == NULL) - { - ERROR ("mysql plugin: Failed to get master statistics: " - "`%s' did not return any rows.", query); - mysql_free_result (res); - return (-1); - } - - field_num = mysql_num_fields (res); - if (field_num < 2) - { - ERROR ("mysql plugin: Failed to get master statistics: " - "`%s' returned less than two columns.", query); - mysql_free_result (res); - return (-1); - } - - position = atoll (row[1]); - derive_submit ("mysql_log_position", "master-bin", position, db); - - row = mysql_fetch_row (res); - if (row != NULL) - WARNING ("mysql plugin: `%s' returned more than one row - " - "ignoring further results.", query); - - mysql_free_result (res); - - return (0); +static int mysql_read_master_stats(mysql_database_t *db, MYSQL *con) { + MYSQL_RES *res; + MYSQL_ROW row; + + const char *query; + int field_num; + unsigned long long position; + + query = "SHOW MASTER STATUS"; + + res = exec_query(con, query); + if (res == NULL) + return (-1); + + row = mysql_fetch_row(res); + if (row == NULL) { + ERROR("mysql plugin: Failed to get master statistics: " + "`%s' did not return any rows.", + query); + mysql_free_result(res); + return (-1); + } + + field_num = mysql_num_fields(res); + if (field_num < 2) { + ERROR("mysql plugin: Failed to get master statistics: " + "`%s' returned less than two columns.", + query); + mysql_free_result(res); + return (-1); + } + + position = atoll(row[1]); + derive_submit("mysql_log_position", "master-bin", position, db); + + row = mysql_fetch_row(res); + if (row != NULL) + WARNING("mysql plugin: `%s' returned more than one row - " + "ignoring further results.", + query); + + mysql_free_result(res); + + return (0); } /* mysql_read_master_stats */ -static int mysql_read_slave_stats (mysql_database_t *db, MYSQL *con) -{ - MYSQL_RES *res; - MYSQL_ROW row; - - const char *query; - int field_num; - - /* WTF? libmysqlclient does not seem to provide any means to - * translate a column name to a column index ... :-/ */ - const int READ_MASTER_LOG_POS_IDX = 6; - const int SLAVE_IO_RUNNING_IDX = 10; - const int SLAVE_SQL_RUNNING_IDX = 11; - const int EXEC_MASTER_LOG_POS_IDX = 21; - const int SECONDS_BEHIND_MASTER_IDX = 32; - - query = "SHOW SLAVE STATUS"; - - res = exec_query (con, query); - if (res == NULL) - return (-1); - - row = mysql_fetch_row (res); - if (row == NULL) - { - ERROR ("mysql plugin: Failed to get slave statistics: " - "`%s' did not return any rows.", query); - mysql_free_result (res); - return (-1); - } - - field_num = mysql_num_fields (res); - if (field_num < 33) - { - ERROR ("mysql plugin: Failed to get slave statistics: " - "`%s' returned less than 33 columns.", query); - mysql_free_result (res); - return (-1); - } - - if (db->slave_stats) - { - unsigned long long counter; - double gauge; - - counter = atoll (row[READ_MASTER_LOG_POS_IDX]); - derive_submit ("mysql_log_position", "slave-read", counter, db); - - counter = atoll (row[EXEC_MASTER_LOG_POS_IDX]); - derive_submit ("mysql_log_position", "slave-exec", counter, db); - - if (row[SECONDS_BEHIND_MASTER_IDX] != NULL) - { - gauge = atof (row[SECONDS_BEHIND_MASTER_IDX]); - gauge_submit ("time_offset", NULL, gauge, db); - } - } - - if (db->slave_notif) - { - notification_t n = { 0, cdtime (), "", "", - "mysql", "", "time_offset", "", NULL }; - - char *io, *sql; - - io = row[SLAVE_IO_RUNNING_IDX]; - sql = row[SLAVE_SQL_RUNNING_IDX]; - - set_host (db, n.host, sizeof (n.host)); - - /* Assured by "mysql_config_database" */ - assert (db->instance != NULL); - sstrncpy (n.plugin_instance, db->instance, sizeof (n.plugin_instance)); - - if (((io == NULL) || (strcasecmp (io, "yes") != 0)) - && (db->slave_io_running)) - { - n.severity = NOTIF_WARNING; - ssnprintf (n.message, sizeof (n.message), - "slave I/O thread not started or not connected to master"); - plugin_dispatch_notification (&n); - db->slave_io_running = 0; - } - else if (((io != NULL) && (strcasecmp (io, "yes") == 0)) - && (! db->slave_io_running)) - { - n.severity = NOTIF_OKAY; - ssnprintf (n.message, sizeof (n.message), - "slave I/O thread started and connected to master"); - plugin_dispatch_notification (&n); - db->slave_io_running = 1; - } - - if (((sql == NULL) || (strcasecmp (sql, "yes") != 0)) - && (db->slave_sql_running)) - { - n.severity = NOTIF_WARNING; - ssnprintf (n.message, sizeof (n.message), - "slave SQL thread not started"); - plugin_dispatch_notification (&n); - db->slave_sql_running = 0; - } - else if (((sql != NULL) && (strcasecmp (sql, "yes") == 0)) - && (! db->slave_sql_running)) - { - n.severity = NOTIF_OKAY; - ssnprintf (n.message, sizeof (n.message), - "slave SQL thread started"); - plugin_dispatch_notification (&n); - db->slave_sql_running = 1; - } - } - - row = mysql_fetch_row (res); - if (row != NULL) - WARNING ("mysql plugin: `%s' returned more than one row - " - "ignoring further results.", query); - - mysql_free_result (res); - - return (0); +static int mysql_read_slave_stats(mysql_database_t *db, MYSQL *con) { + MYSQL_RES *res; + MYSQL_ROW row; + + const char *query; + int field_num; + + /* WTF? libmysqlclient does not seem to provide any means to + * translate a column name to a column index ... :-/ */ + const int READ_MASTER_LOG_POS_IDX = 6; + const int SLAVE_IO_RUNNING_IDX = 10; + const int SLAVE_SQL_RUNNING_IDX = 11; + const int EXEC_MASTER_LOG_POS_IDX = 21; + const int SECONDS_BEHIND_MASTER_IDX = 32; + + query = "SHOW SLAVE STATUS"; + + res = exec_query(con, query); + if (res == NULL) + return (-1); + + row = mysql_fetch_row(res); + if (row == NULL) { + ERROR("mysql plugin: Failed to get slave statistics: " + "`%s' did not return any rows.", + query); + mysql_free_result(res); + return (-1); + } + + field_num = mysql_num_fields(res); + if (field_num < 33) { + ERROR("mysql plugin: Failed to get slave statistics: " + "`%s' returned less than 33 columns.", + query); + mysql_free_result(res); + return (-1); + } + + if (db->slave_stats) { + unsigned long long counter; + double gauge; + + counter = atoll(row[READ_MASTER_LOG_POS_IDX]); + derive_submit("mysql_log_position", "slave-read", counter, db); + + counter = atoll(row[EXEC_MASTER_LOG_POS_IDX]); + derive_submit("mysql_log_position", "slave-exec", counter, db); + + if (row[SECONDS_BEHIND_MASTER_IDX] != NULL) { + gauge = atof(row[SECONDS_BEHIND_MASTER_IDX]); + gauge_submit("time_offset", NULL, gauge, db); + } + } + + if (db->slave_notif) { + notification_t n = {0, cdtime(), "", "", "mysql", + "", "time_offset", "", NULL}; + + char *io, *sql; + + io = row[SLAVE_IO_RUNNING_IDX]; + sql = row[SLAVE_SQL_RUNNING_IDX]; + + set_host(db, n.host, sizeof(n.host)); + + /* Assured by "mysql_config_database" */ + assert(db->instance != NULL); + sstrncpy(n.plugin_instance, db->instance, sizeof(n.plugin_instance)); + + if (((io == NULL) || (strcasecmp(io, "yes") != 0)) && + (db->slave_io_running)) { + n.severity = NOTIF_WARNING; + ssnprintf(n.message, sizeof(n.message), + "slave I/O thread not started or not connected to master"); + plugin_dispatch_notification(&n); + db->slave_io_running = 0; + } else if (((io != NULL) && (strcasecmp(io, "yes") == 0)) && + (!db->slave_io_running)) { + n.severity = NOTIF_OKAY; + ssnprintf(n.message, sizeof(n.message), + "slave I/O thread started and connected to master"); + plugin_dispatch_notification(&n); + db->slave_io_running = 1; + } + + if (((sql == NULL) || (strcasecmp(sql, "yes") != 0)) && + (db->slave_sql_running)) { + n.severity = NOTIF_WARNING; + ssnprintf(n.message, sizeof(n.message), "slave SQL thread not started"); + plugin_dispatch_notification(&n); + db->slave_sql_running = 0; + } else if (((sql != NULL) && (strcasecmp(sql, "yes") == 0)) && + (!db->slave_sql_running)) { + n.severity = NOTIF_OKAY; + ssnprintf(n.message, sizeof(n.message), "slave SQL thread started"); + plugin_dispatch_notification(&n); + db->slave_sql_running = 1; + } + } + + row = mysql_fetch_row(res); + if (row != NULL) + WARNING("mysql plugin: `%s' returned more than one row - " + "ignoring further results.", + query); + + mysql_free_result(res); + + return (0); } /* mysql_read_slave_stats */ -static int mysql_read_innodb_stats (mysql_database_t *db, MYSQL *con) -{ - MYSQL_RES *res; - MYSQL_ROW row; - - const char *query; - struct { - const char *key; - const char *type; - int ds_type; - } metrics[] = { - { "metadata_mem_pool_size", "bytes", DS_TYPE_GAUGE }, - { "lock_deadlocks", "mysql_locks", DS_TYPE_DERIVE }, - { "lock_timeouts", "mysql_locks", DS_TYPE_DERIVE }, - { "lock_row_lock_current_waits", "mysql_locks", DS_TYPE_DERIVE }, - { "buffer_pool_size", "bytes", DS_TYPE_GAUGE }, - - { "os_log_bytes_written", "operations", DS_TYPE_DERIVE }, - { "os_log_pending_fsyncs", "operations", DS_TYPE_DERIVE }, - { "os_log_pending_writes", "operations", DS_TYPE_DERIVE }, - - { "trx_rseg_history_len", "gauge", DS_TYPE_GAUGE }, - - { "adaptive_hash_searches", "operations", DS_TYPE_DERIVE }, - - { "file_num_open_files", "gauge", DS_TYPE_GAUGE }, - - { "ibuf_merges_insert", "operations", DS_TYPE_DERIVE }, - { "ibuf_merges_delete_mark", "operations", DS_TYPE_DERIVE }, - { "ibuf_merges_delete", "operations", DS_TYPE_DERIVE }, - { "ibuf_merges_discard_insert", "operations", DS_TYPE_DERIVE }, - { "ibuf_merges_discard_delete_mark", "operations", DS_TYPE_DERIVE }, - { "ibuf_merges_discard_delete", "operations", DS_TYPE_DERIVE }, - { "ibuf_merges_discard_merges", "operations", DS_TYPE_DERIVE }, - { "ibuf_size", "bytes", DS_TYPE_GAUGE }, - - { "innodb_activity_count", "gauge", DS_TYPE_GAUGE }, - - { "innodb_rwlock_s_spin_waits", "operations", DS_TYPE_DERIVE }, - { "innodb_rwlock_x_spin_waits", "operations", DS_TYPE_DERIVE }, - { "innodb_rwlock_s_spin_rounds", "operations", DS_TYPE_DERIVE }, - { "innodb_rwlock_x_spin_rounds", "operations", DS_TYPE_DERIVE }, - { "innodb_rwlock_s_os_waits", "operations", DS_TYPE_DERIVE }, - { "innodb_rwlock_x_os_waits", "operations", DS_TYPE_DERIVE }, - - { "dml_reads", "operations", DS_TYPE_DERIVE }, - { "dml_inserts", "operations", DS_TYPE_DERIVE }, - { "dml_deletes", "operations", DS_TYPE_DERIVE }, - { "dml_updates", "operations", DS_TYPE_DERIVE }, - - { NULL, NULL, 0} - }; - - query = "SELECT name, count, type FROM information_schema.innodb_metrics WHERE status = 'enabled'"; - - res = exec_query (con, query); - if (res == NULL) - return (-1); - - while ((row = mysql_fetch_row (res))) - { - int i; - char *key; - unsigned long long val; - - key = row[0]; - val = atoll (row[1]); - - for (i = 0; metrics[i].key != NULL && strcmp(metrics[i].key, key) != 0; i++) - ; - - if (metrics[i].key == NULL) - continue; - - switch (metrics[i].ds_type) { - case DS_TYPE_COUNTER: - derive_submit(metrics[i].type, key, (counter_t)val, db); - break; - case DS_TYPE_GAUGE: - gauge_submit(metrics[i].type, key, (gauge_t)val, db); - break; - case DS_TYPE_DERIVE: - derive_submit(metrics[i].type, key, (derive_t)val, db); - break; - } - } - - mysql_free_result(res); - return (0); +static int mysql_read_innodb_stats(mysql_database_t *db, MYSQL *con) { + MYSQL_RES *res; + MYSQL_ROW row; + + const char *query; + struct { + const char *key; + const char *type; + int ds_type; + } metrics[] = { + {"metadata_mem_pool_size", "bytes", DS_TYPE_GAUGE}, + {"lock_deadlocks", "mysql_locks", DS_TYPE_DERIVE}, + {"lock_timeouts", "mysql_locks", DS_TYPE_DERIVE}, + {"lock_row_lock_current_waits", "mysql_locks", DS_TYPE_DERIVE}, + {"buffer_pool_size", "bytes", DS_TYPE_GAUGE}, + + {"os_log_bytes_written", "operations", DS_TYPE_DERIVE}, + {"os_log_pending_fsyncs", "operations", DS_TYPE_DERIVE}, + {"os_log_pending_writes", "operations", DS_TYPE_DERIVE}, + + {"trx_rseg_history_len", "gauge", DS_TYPE_GAUGE}, + + {"adaptive_hash_searches", "operations", DS_TYPE_DERIVE}, + + {"file_num_open_files", "gauge", DS_TYPE_GAUGE}, + + {"ibuf_merges_insert", "operations", DS_TYPE_DERIVE}, + {"ibuf_merges_delete_mark", "operations", DS_TYPE_DERIVE}, + {"ibuf_merges_delete", "operations", DS_TYPE_DERIVE}, + {"ibuf_merges_discard_insert", "operations", DS_TYPE_DERIVE}, + {"ibuf_merges_discard_delete_mark", "operations", DS_TYPE_DERIVE}, + {"ibuf_merges_discard_delete", "operations", DS_TYPE_DERIVE}, + {"ibuf_merges_discard_merges", "operations", DS_TYPE_DERIVE}, + {"ibuf_size", "bytes", DS_TYPE_GAUGE}, + + {"innodb_activity_count", "gauge", DS_TYPE_GAUGE}, + + {"innodb_rwlock_s_spin_waits", "operations", DS_TYPE_DERIVE}, + {"innodb_rwlock_x_spin_waits", "operations", DS_TYPE_DERIVE}, + {"innodb_rwlock_s_spin_rounds", "operations", DS_TYPE_DERIVE}, + {"innodb_rwlock_x_spin_rounds", "operations", DS_TYPE_DERIVE}, + {"innodb_rwlock_s_os_waits", "operations", DS_TYPE_DERIVE}, + {"innodb_rwlock_x_os_waits", "operations", DS_TYPE_DERIVE}, + + {"dml_reads", "operations", DS_TYPE_DERIVE}, + {"dml_inserts", "operations", DS_TYPE_DERIVE}, + {"dml_deletes", "operations", DS_TYPE_DERIVE}, + {"dml_updates", "operations", DS_TYPE_DERIVE}, + + {NULL, NULL, 0}}; + + query = "SELECT name, count, type FROM information_schema.innodb_metrics " + "WHERE status = 'enabled'"; + + res = exec_query(con, query); + if (res == NULL) + return (-1); + + while ((row = mysql_fetch_row(res))) { + int i; + char *key; + unsigned long long val; + + key = row[0]; + val = atoll(row[1]); + + for (i = 0; metrics[i].key != NULL && strcmp(metrics[i].key, key) != 0; i++) + ; + + if (metrics[i].key == NULL) + continue; + + switch (metrics[i].ds_type) { + case DS_TYPE_COUNTER: + derive_submit(metrics[i].type, key, (counter_t)val, db); + break; + case DS_TYPE_GAUGE: + gauge_submit(metrics[i].type, key, (gauge_t)val, db); + break; + case DS_TYPE_DERIVE: + derive_submit(metrics[i].type, key, (derive_t)val, db); + break; + } + } + + mysql_free_result(res); + return (0); } -static int mysql_read_wsrep_stats (mysql_database_t *db, MYSQL *con) -{ - MYSQL_RES *res; - MYSQL_ROW row; - - const char *query; - struct { - const char *key; - const char *type; - int ds_type; - } metrics[] = { - - { "wsrep_apply_oooe", "operations", DS_TYPE_DERIVE }, - { "wsrep_apply_oool", "operations", DS_TYPE_DERIVE }, - { "wsrep_causal_reads", "operations", DS_TYPE_DERIVE }, - { "wsrep_commit_oooe", "operations", DS_TYPE_DERIVE }, - { "wsrep_commit_oool", "operations", DS_TYPE_DERIVE }, - { "wsrep_flow_control_recv", "operations", DS_TYPE_DERIVE }, - { "wsrep_flow_control_sent", "operations", DS_TYPE_DERIVE }, - { "wsrep_flow_control_paused", "operations", DS_TYPE_DERIVE }, - { "wsrep_local_bf_aborts", "operations", DS_TYPE_DERIVE }, - { "wsrep_local_cert_failures", "operations", DS_TYPE_DERIVE }, - { "wsrep_local_commits", "operations", DS_TYPE_DERIVE }, - { "wsrep_local_replays", "operations", DS_TYPE_DERIVE }, - { "wsrep_received", "operations", DS_TYPE_DERIVE }, - { "wsrep_replicated", "operations", DS_TYPE_DERIVE }, - - { "wsrep_received_bytes", "total_bytes", DS_TYPE_DERIVE }, - { "wsrep_replicated_bytes", "total_bytes", DS_TYPE_DERIVE }, - - { "wsrep_apply_window", "gauge", DS_TYPE_GAUGE }, - { "wsrep_commit_window", "gauge", DS_TYPE_GAUGE }, - - { "wsrep_cluster_size", "gauge", DS_TYPE_GAUGE }, - { "wsrep_cert_deps_distance", "gauge", DS_TYPE_GAUGE }, - - { "wsrep_local_recv_queue", "queue_length", DS_TYPE_GAUGE }, - { "wsrep_local_send_queue", "queue_length", DS_TYPE_GAUGE }, - - { NULL, NULL, 0} - - }; - - query = "SHOW GLOBAL STATUS LIKE 'wsrep_%'"; - - res = exec_query (con, query); - if (res == NULL) - return (-1); - - row = mysql_fetch_row (res); - if (row == NULL) - { - ERROR ("mysql plugin: Failed to get wsrep statistics: " - "`%s' did not return any rows.", query); - mysql_free_result (res); - return (-1); - } - - while ((row = mysql_fetch_row (res))) - { - int i; - char *key; - unsigned long long val; - - key = row[0]; - val = atoll (row[1]); - - for (i = 0; metrics[i].key != NULL && strcmp(metrics[i].key, key) != 0; i++) - ; - - if (metrics[i].key == NULL) - continue; - - switch (metrics[i].ds_type) { - case DS_TYPE_GAUGE: - gauge_submit(metrics[i].type, key, (gauge_t)val, db); - break; - case DS_TYPE_DERIVE: - derive_submit(metrics[i].type, key, (derive_t)val, db); - break; - } - } - - mysql_free_result(res); - return (0); +static int mysql_read_wsrep_stats(mysql_database_t *db, MYSQL *con) { + MYSQL_RES *res; + MYSQL_ROW row; + + const char *query; + struct { + const char *key; + const char *type; + int ds_type; + } metrics[] = { + + {"wsrep_apply_oooe", "operations", DS_TYPE_DERIVE}, + {"wsrep_apply_oool", "operations", DS_TYPE_DERIVE}, + {"wsrep_causal_reads", "operations", DS_TYPE_DERIVE}, + {"wsrep_commit_oooe", "operations", DS_TYPE_DERIVE}, + {"wsrep_commit_oool", "operations", DS_TYPE_DERIVE}, + {"wsrep_flow_control_recv", "operations", DS_TYPE_DERIVE}, + {"wsrep_flow_control_sent", "operations", DS_TYPE_DERIVE}, + {"wsrep_flow_control_paused", "operations", DS_TYPE_DERIVE}, + {"wsrep_local_bf_aborts", "operations", DS_TYPE_DERIVE}, + {"wsrep_local_cert_failures", "operations", DS_TYPE_DERIVE}, + {"wsrep_local_commits", "operations", DS_TYPE_DERIVE}, + {"wsrep_local_replays", "operations", DS_TYPE_DERIVE}, + {"wsrep_received", "operations", DS_TYPE_DERIVE}, + {"wsrep_replicated", "operations", DS_TYPE_DERIVE}, + + {"wsrep_received_bytes", "total_bytes", DS_TYPE_DERIVE}, + {"wsrep_replicated_bytes", "total_bytes", DS_TYPE_DERIVE}, + + {"wsrep_apply_window", "gauge", DS_TYPE_GAUGE}, + {"wsrep_commit_window", "gauge", DS_TYPE_GAUGE}, + + {"wsrep_cluster_size", "gauge", DS_TYPE_GAUGE}, + {"wsrep_cert_deps_distance", "gauge", DS_TYPE_GAUGE}, + + {"wsrep_local_recv_queue", "queue_length", DS_TYPE_GAUGE}, + {"wsrep_local_send_queue", "queue_length", DS_TYPE_GAUGE}, + + {NULL, NULL, 0} + + }; + + query = "SHOW GLOBAL STATUS LIKE 'wsrep_%'"; + + res = exec_query(con, query); + if (res == NULL) + return (-1); + + row = mysql_fetch_row(res); + if (row == NULL) { + ERROR("mysql plugin: Failed to get wsrep statistics: " + "`%s' did not return any rows.", + query); + mysql_free_result(res); + return (-1); + } + + while ((row = mysql_fetch_row(res))) { + int i; + char *key; + unsigned long long val; + + key = row[0]; + val = atoll(row[1]); + + for (i = 0; metrics[i].key != NULL && strcmp(metrics[i].key, key) != 0; i++) + ; + + if (metrics[i].key == NULL) + continue; + + switch (metrics[i].ds_type) { + case DS_TYPE_GAUGE: + gauge_submit(metrics[i].type, key, (gauge_t)val, db); + break; + case DS_TYPE_DERIVE: + derive_submit(metrics[i].type, key, (derive_t)val, db); + break; + } + } + + mysql_free_result(res); + return (0); } /* mysql_read_wsrep_stats */ -static int mysql_read (user_data_t *ud) -{ - mysql_database_t *db; - MYSQL *con; - MYSQL_RES *res; - MYSQL_ROW row; - const char *query; - - derive_t qcache_hits = 0; - derive_t qcache_inserts = 0; - derive_t qcache_not_cached = 0; - derive_t qcache_lowmem_prunes = 0; - gauge_t qcache_queries_in_cache = NAN; - - gauge_t threads_running = NAN; - gauge_t threads_connected = NAN; - gauge_t threads_cached = NAN; - derive_t threads_created = 0; - - unsigned long long traffic_incoming = 0ULL; - unsigned long long traffic_outgoing = 0ULL; - unsigned long mysql_version = 0ULL; - - if ((ud == NULL) || (ud->data == NULL)) - { - ERROR ("mysql plugin: mysql_database_read: Invalid user data."); - return (-1); - } - - db = (mysql_database_t *) ud->data; - - /* An error message will have been printed in this case */ - if ((con = getconnection (db)) == NULL) - return (-1); - - mysql_version = mysql_get_server_version(con); - - query = "SHOW STATUS"; - if (mysql_version >= 50002) - query = "SHOW GLOBAL STATUS"; - - res = exec_query (con, query); - if (res == NULL) - return (-1); - - while ((row = mysql_fetch_row (res))) - { - char *key; - unsigned long long val; - - key = row[0]; - val = atoll (row[1]); - - if (strncmp (key, "Com_", - strlen ("Com_")) == 0) - { - if (val == 0ULL) - continue; - - /* Ignore `prepared statements' */ - if (strncmp (key, "Com_stmt_", strlen ("Com_stmt_")) != 0) - derive_submit ("mysql_commands", - key + strlen ("Com_"), - val, db); - } - else if (strncmp (key, "Handler_", - strlen ("Handler_")) == 0) - { - if (val == 0ULL) - continue; - - derive_submit ("mysql_handler", - key + strlen ("Handler_"), - val, db); - } - else if (strncmp (key, "Qcache_", - strlen ("Qcache_")) == 0) - { - if (strcmp (key, "Qcache_hits") == 0) - qcache_hits = (derive_t) val; - else if (strcmp (key, "Qcache_inserts") == 0) - qcache_inserts = (derive_t) val; - else if (strcmp (key, "Qcache_not_cached") == 0) - qcache_not_cached = (derive_t) val; - else if (strcmp (key, "Qcache_lowmem_prunes") == 0) - qcache_lowmem_prunes = (derive_t) val; - else if (strcmp (key, "Qcache_queries_in_cache") == 0) - qcache_queries_in_cache = (gauge_t) val; - } - else if (strncmp (key, "Bytes_", - strlen ("Bytes_")) == 0) - { - if (strcmp (key, "Bytes_received") == 0) - traffic_incoming += val; - else if (strcmp (key, "Bytes_sent") == 0) - traffic_outgoing += val; - } - else if (strncmp (key, "Threads_", - strlen ("Threads_")) == 0) - { - if (strcmp (key, "Threads_running") == 0) - threads_running = (gauge_t) val; - else if (strcmp (key, "Threads_connected") == 0) - threads_connected = (gauge_t) val; - else if (strcmp (key, "Threads_cached") == 0) - threads_cached = (gauge_t) val; - else if (strcmp (key, "Threads_created") == 0) - threads_created = (derive_t) val; - } - else if (strncmp (key, "Table_locks_", - strlen ("Table_locks_")) == 0) - { - derive_submit ("mysql_locks", - key + strlen ("Table_locks_"), - val, db); - } - else if (db->innodb_stats && strncmp (key, "Innodb_", strlen ("Innodb_")) == 0) - { - /* buffer pool */ - if (strcmp (key, "Innodb_buffer_pool_pages_data") == 0) - gauge_submit ("mysql_bpool_pages", "data", val, db); - else if (strcmp (key, "Innodb_buffer_pool_pages_dirty") == 0) - gauge_submit ("mysql_bpool_pages", "dirty", val, db); - else if (strcmp (key, "Innodb_buffer_pool_pages_flushed") == 0) - derive_submit ("mysql_bpool_counters", "pages_flushed", val, db); - else if (strcmp (key, "Innodb_buffer_pool_pages_free") == 0) - gauge_submit ("mysql_bpool_pages", "free", val, db); - else if (strcmp (key, "Innodb_buffer_pool_pages_misc") == 0) - gauge_submit ("mysql_bpool_pages", "misc", val, db); - else if (strcmp (key, "Innodb_buffer_pool_pages_total") == 0) - gauge_submit ("mysql_bpool_pages", "total", val, db); - else if (strcmp (key, "Innodb_buffer_pool_read_ahead_rnd") == 0) - derive_submit ("mysql_bpool_counters", "read_ahead_rnd", val, db); - else if (strcmp (key, "Innodb_buffer_pool_read_ahead") == 0) - derive_submit ("mysql_bpool_counters", "read_ahead", val, db); - else if (strcmp (key, "Innodb_buffer_pool_read_ahead_evicted") == 0) - derive_submit ("mysql_bpool_counters", "read_ahead_evicted", val, db); - else if (strcmp (key, "Innodb_buffer_pool_read_requests") == 0) - derive_submit ("mysql_bpool_counters", "read_requests", val, db); - else if (strcmp (key, "Innodb_buffer_pool_reads") == 0) - derive_submit ("mysql_bpool_counters", "reads", val, db); - else if (strcmp (key, "Innodb_buffer_pool_wait_free") == 0) - derive_submit ("mysql_bpool_counters", "wait_free", val, db); - else if (strcmp (key, "Innodb_buffer_pool_write_requests") == 0) - derive_submit ("mysql_bpool_counters", "write_requests", val, db); - else if (strcmp (key, "Innodb_buffer_pool_bytes_data") == 0) - gauge_submit ("mysql_bpool_bytes", "data", val, db); - else if (strcmp (key, "Innodb_buffer_pool_bytes_dirty") == 0) - gauge_submit ("mysql_bpool_bytes", "dirty", val, db); - - /* data */ - if (strcmp (key, "Innodb_data_fsyncs") == 0) - derive_submit ("mysql_innodb_data", "fsyncs", val, db); - else if (strcmp (key, "Innodb_data_read") == 0) - derive_submit ("mysql_innodb_data", "read", val, db); - else if (strcmp (key, "Innodb_data_reads") == 0) - derive_submit ("mysql_innodb_data", "reads", val, db); - else if (strcmp (key, "Innodb_data_writes") == 0) - derive_submit ("mysql_innodb_data", "writes", val, db); - else if (strcmp (key, "Innodb_data_written") == 0) - derive_submit ("mysql_innodb_data", "written", val, db); - - /* double write */ - else if (strcmp (key, "Innodb_dblwr_writes") == 0) - derive_submit ("mysql_innodb_dblwr", "writes", val, db); - else if (strcmp (key, "Innodb_dblwr_pages_written") == 0) - derive_submit ("mysql_innodb_dblwr", "written", val, db); - else if (strcmp (key, "Innodb_dblwr_page_size") == 0) - gauge_submit ("mysql_innodb_dblwr", "page_size", val, db); - - /* log */ - else if (strcmp (key, "Innodb_log_waits") == 0) - derive_submit ("mysql_innodb_log", "waits", val, db); - else if (strcmp (key, "Innodb_log_write_requests") == 0) - derive_submit ("mysql_innodb_log", "write_requests", val, db); - else if (strcmp (key, "Innodb_log_writes") == 0) - derive_submit ("mysql_innodb_log", "writes", val, db); - else if (strcmp (key, "Innodb_os_log_fsyncs") == 0) - derive_submit ("mysql_innodb_log", "fsyncs", val, db); - else if (strcmp (key, "Innodb_os_log_written") == 0) - derive_submit ("mysql_innodb_log", "written", val, db); - - /* pages */ - else if (strcmp (key, "Innodb_pages_created") == 0) - derive_submit ("mysql_innodb_pages", "created", val, db); - else if (strcmp (key, "Innodb_pages_read") == 0) - derive_submit ("mysql_innodb_pages", "read", val, db); - else if (strcmp (key, "Innodb_pages_written") == 0) - derive_submit ("mysql_innodb_pages", "written", val, db); - - /* row lock */ - else if (strcmp (key, "Innodb_row_lock_time") == 0) - derive_submit ("mysql_innodb_row_lock", "time", val, db); - else if (strcmp (key, "Innodb_row_lock_waits") == 0) - derive_submit ("mysql_innodb_row_lock", "waits", val, db); - - /* rows */ - else if (strcmp (key, "Innodb_rows_deleted") == 0) - derive_submit ("mysql_innodb_rows", "deleted", val, db); - else if (strcmp (key, "Innodb_rows_inserted") == 0) - derive_submit ("mysql_innodb_rows", "inserted", val, db); - else if (strcmp (key, "Innodb_rows_read") == 0) - derive_submit ("mysql_innodb_rows", "read", val, db); - else if (strcmp (key, "Innodb_rows_updated") == 0) - derive_submit ("mysql_innodb_rows", "updated", val, db); - } - else if (strncmp (key, "Select_", strlen ("Select_")) == 0) - { - derive_submit ("mysql_select", key + strlen ("Select_"), - val, db); - } - else if (strncmp (key, "Sort_", strlen ("Sort_")) == 0) - { - if (strcmp (key, "Sort_merge_passes") == 0) - derive_submit ("mysql_sort_merge_passes", NULL, val, db); - else if (strcmp (key, "Sort_rows") == 0) - derive_submit ("mysql_sort_rows", NULL, val, db); - else if (strcmp (key, "Sort_range") == 0) - derive_submit ("mysql_sort", "range", val, db); - else if (strcmp (key, "Sort_scan") == 0) - derive_submit ("mysql_sort", "scan", val, db); - - } - else if (strncmp (key, "Slow_queries", strlen ("Slow_queries")) == 0) - { - derive_submit ("mysql_slow_queries", NULL , val, db); - } - } - mysql_free_result (res); res = NULL; - - if ((qcache_hits != 0) - || (qcache_inserts != 0) - || (qcache_not_cached != 0) - || (qcache_lowmem_prunes != 0)) - { - derive_submit ("cache_result", "qcache-hits", - qcache_hits, db); - derive_submit ("cache_result", "qcache-inserts", - qcache_inserts, db); - derive_submit ("cache_result", "qcache-not_cached", - qcache_not_cached, db); - derive_submit ("cache_result", "qcache-prunes", - qcache_lowmem_prunes, db); - - gauge_submit ("cache_size", "qcache", - qcache_queries_in_cache, db); - } - - if (threads_created != 0) - { - gauge_submit ("threads", "running", - threads_running, db); - gauge_submit ("threads", "connected", - threads_connected, db); - gauge_submit ("threads", "cached", - threads_cached, db); - - derive_submit ("total_threads", "created", - threads_created, db); - } - - traffic_submit (traffic_incoming, traffic_outgoing, db); - - if (mysql_version >= 50600 && db->innodb_stats) - mysql_read_innodb_stats (db, con); - - if (db->master_stats) - mysql_read_master_stats (db, con); - - if ((db->slave_stats) || (db->slave_notif)) - mysql_read_slave_stats (db, con); - - if (db->wsrep_stats) - mysql_read_wsrep_stats (db, con); - - return (0); +static int mysql_read(user_data_t *ud) { + mysql_database_t *db; + MYSQL *con; + MYSQL_RES *res; + MYSQL_ROW row; + const char *query; + + derive_t qcache_hits = 0; + derive_t qcache_inserts = 0; + derive_t qcache_not_cached = 0; + derive_t qcache_lowmem_prunes = 0; + gauge_t qcache_queries_in_cache = NAN; + + gauge_t threads_running = NAN; + gauge_t threads_connected = NAN; + gauge_t threads_cached = NAN; + derive_t threads_created = 0; + + unsigned long long traffic_incoming = 0ULL; + unsigned long long traffic_outgoing = 0ULL; + unsigned long mysql_version = 0ULL; + + if ((ud == NULL) || (ud->data == NULL)) { + ERROR("mysql plugin: mysql_database_read: Invalid user data."); + return (-1); + } + + db = (mysql_database_t *)ud->data; + + /* An error message will have been printed in this case */ + if ((con = getconnection(db)) == NULL) + return (-1); + + mysql_version = mysql_get_server_version(con); + + query = "SHOW STATUS"; + if (mysql_version >= 50002) + query = "SHOW GLOBAL STATUS"; + + res = exec_query(con, query); + if (res == NULL) + return (-1); + + while ((row = mysql_fetch_row(res))) { + char *key; + unsigned long long val; + + key = row[0]; + val = atoll(row[1]); + + if (strncmp(key, "Com_", strlen("Com_")) == 0) { + if (val == 0ULL) + continue; + + /* Ignore `prepared statements' */ + if (strncmp(key, "Com_stmt_", strlen("Com_stmt_")) != 0) + derive_submit("mysql_commands", key + strlen("Com_"), val, db); + } else if (strncmp(key, "Handler_", strlen("Handler_")) == 0) { + if (val == 0ULL) + continue; + + derive_submit("mysql_handler", key + strlen("Handler_"), val, db); + } else if (strncmp(key, "Qcache_", strlen("Qcache_")) == 0) { + if (strcmp(key, "Qcache_hits") == 0) + qcache_hits = (derive_t)val; + else if (strcmp(key, "Qcache_inserts") == 0) + qcache_inserts = (derive_t)val; + else if (strcmp(key, "Qcache_not_cached") == 0) + qcache_not_cached = (derive_t)val; + else if (strcmp(key, "Qcache_lowmem_prunes") == 0) + qcache_lowmem_prunes = (derive_t)val; + else if (strcmp(key, "Qcache_queries_in_cache") == 0) + qcache_queries_in_cache = (gauge_t)val; + } else if (strncmp(key, "Bytes_", strlen("Bytes_")) == 0) { + if (strcmp(key, "Bytes_received") == 0) + traffic_incoming += val; + else if (strcmp(key, "Bytes_sent") == 0) + traffic_outgoing += val; + } else if (strncmp(key, "Threads_", strlen("Threads_")) == 0) { + if (strcmp(key, "Threads_running") == 0) + threads_running = (gauge_t)val; + else if (strcmp(key, "Threads_connected") == 0) + threads_connected = (gauge_t)val; + else if (strcmp(key, "Threads_cached") == 0) + threads_cached = (gauge_t)val; + else if (strcmp(key, "Threads_created") == 0) + threads_created = (derive_t)val; + } else if (strncmp(key, "Table_locks_", strlen("Table_locks_")) == 0) { + derive_submit("mysql_locks", key + strlen("Table_locks_"), val, db); + } else if (db->innodb_stats && + strncmp(key, "Innodb_", strlen("Innodb_")) == 0) { + /* buffer pool */ + if (strcmp(key, "Innodb_buffer_pool_pages_data") == 0) + gauge_submit("mysql_bpool_pages", "data", val, db); + else if (strcmp(key, "Innodb_buffer_pool_pages_dirty") == 0) + gauge_submit("mysql_bpool_pages", "dirty", val, db); + else if (strcmp(key, "Innodb_buffer_pool_pages_flushed") == 0) + derive_submit("mysql_bpool_counters", "pages_flushed", val, db); + else if (strcmp(key, "Innodb_buffer_pool_pages_free") == 0) + gauge_submit("mysql_bpool_pages", "free", val, db); + else if (strcmp(key, "Innodb_buffer_pool_pages_misc") == 0) + gauge_submit("mysql_bpool_pages", "misc", val, db); + else if (strcmp(key, "Innodb_buffer_pool_pages_total") == 0) + gauge_submit("mysql_bpool_pages", "total", val, db); + else if (strcmp(key, "Innodb_buffer_pool_read_ahead_rnd") == 0) + derive_submit("mysql_bpool_counters", "read_ahead_rnd", val, db); + else if (strcmp(key, "Innodb_buffer_pool_read_ahead") == 0) + derive_submit("mysql_bpool_counters", "read_ahead", val, db); + else if (strcmp(key, "Innodb_buffer_pool_read_ahead_evicted") == 0) + derive_submit("mysql_bpool_counters", "read_ahead_evicted", val, db); + else if (strcmp(key, "Innodb_buffer_pool_read_requests") == 0) + derive_submit("mysql_bpool_counters", "read_requests", val, db); + else if (strcmp(key, "Innodb_buffer_pool_reads") == 0) + derive_submit("mysql_bpool_counters", "reads", val, db); + else if (strcmp(key, "Innodb_buffer_pool_wait_free") == 0) + derive_submit("mysql_bpool_counters", "wait_free", val, db); + else if (strcmp(key, "Innodb_buffer_pool_write_requests") == 0) + derive_submit("mysql_bpool_counters", "write_requests", val, db); + else if (strcmp(key, "Innodb_buffer_pool_bytes_data") == 0) + gauge_submit("mysql_bpool_bytes", "data", val, db); + else if (strcmp(key, "Innodb_buffer_pool_bytes_dirty") == 0) + gauge_submit("mysql_bpool_bytes", "dirty", val, db); + + /* data */ + if (strcmp(key, "Innodb_data_fsyncs") == 0) + derive_submit("mysql_innodb_data", "fsyncs", val, db); + else if (strcmp(key, "Innodb_data_read") == 0) + derive_submit("mysql_innodb_data", "read", val, db); + else if (strcmp(key, "Innodb_data_reads") == 0) + derive_submit("mysql_innodb_data", "reads", val, db); + else if (strcmp(key, "Innodb_data_writes") == 0) + derive_submit("mysql_innodb_data", "writes", val, db); + else if (strcmp(key, "Innodb_data_written") == 0) + derive_submit("mysql_innodb_data", "written", val, db); + + /* double write */ + else if (strcmp(key, "Innodb_dblwr_writes") == 0) + derive_submit("mysql_innodb_dblwr", "writes", val, db); + else if (strcmp(key, "Innodb_dblwr_pages_written") == 0) + derive_submit("mysql_innodb_dblwr", "written", val, db); + else if (strcmp(key, "Innodb_dblwr_page_size") == 0) + gauge_submit("mysql_innodb_dblwr", "page_size", val, db); + + /* log */ + else if (strcmp(key, "Innodb_log_waits") == 0) + derive_submit("mysql_innodb_log", "waits", val, db); + else if (strcmp(key, "Innodb_log_write_requests") == 0) + derive_submit("mysql_innodb_log", "write_requests", val, db); + else if (strcmp(key, "Innodb_log_writes") == 0) + derive_submit("mysql_innodb_log", "writes", val, db); + else if (strcmp(key, "Innodb_os_log_fsyncs") == 0) + derive_submit("mysql_innodb_log", "fsyncs", val, db); + else if (strcmp(key, "Innodb_os_log_written") == 0) + derive_submit("mysql_innodb_log", "written", val, db); + + /* pages */ + else if (strcmp(key, "Innodb_pages_created") == 0) + derive_submit("mysql_innodb_pages", "created", val, db); + else if (strcmp(key, "Innodb_pages_read") == 0) + derive_submit("mysql_innodb_pages", "read", val, db); + else if (strcmp(key, "Innodb_pages_written") == 0) + derive_submit("mysql_innodb_pages", "written", val, db); + + /* row lock */ + else if (strcmp(key, "Innodb_row_lock_time") == 0) + derive_submit("mysql_innodb_row_lock", "time", val, db); + else if (strcmp(key, "Innodb_row_lock_waits") == 0) + derive_submit("mysql_innodb_row_lock", "waits", val, db); + + /* rows */ + else if (strcmp(key, "Innodb_rows_deleted") == 0) + derive_submit("mysql_innodb_rows", "deleted", val, db); + else if (strcmp(key, "Innodb_rows_inserted") == 0) + derive_submit("mysql_innodb_rows", "inserted", val, db); + else if (strcmp(key, "Innodb_rows_read") == 0) + derive_submit("mysql_innodb_rows", "read", val, db); + else if (strcmp(key, "Innodb_rows_updated") == 0) + derive_submit("mysql_innodb_rows", "updated", val, db); + } else if (strncmp(key, "Select_", strlen("Select_")) == 0) { + derive_submit("mysql_select", key + strlen("Select_"), val, db); + } else if (strncmp(key, "Sort_", strlen("Sort_")) == 0) { + if (strcmp(key, "Sort_merge_passes") == 0) + derive_submit("mysql_sort_merge_passes", NULL, val, db); + else if (strcmp(key, "Sort_rows") == 0) + derive_submit("mysql_sort_rows", NULL, val, db); + else if (strcmp(key, "Sort_range") == 0) + derive_submit("mysql_sort", "range", val, db); + else if (strcmp(key, "Sort_scan") == 0) + derive_submit("mysql_sort", "scan", val, db); + + } else if (strncmp(key, "Slow_queries", strlen("Slow_queries")) == 0) { + derive_submit("mysql_slow_queries", NULL, val, db); + } + } + mysql_free_result(res); + res = NULL; + + if ((qcache_hits != 0) || (qcache_inserts != 0) || (qcache_not_cached != 0) || + (qcache_lowmem_prunes != 0)) { + derive_submit("cache_result", "qcache-hits", qcache_hits, db); + derive_submit("cache_result", "qcache-inserts", qcache_inserts, db); + derive_submit("cache_result", "qcache-not_cached", qcache_not_cached, db); + derive_submit("cache_result", "qcache-prunes", qcache_lowmem_prunes, db); + + gauge_submit("cache_size", "qcache", qcache_queries_in_cache, db); + } + + if (threads_created != 0) { + gauge_submit("threads", "running", threads_running, db); + gauge_submit("threads", "connected", threads_connected, db); + gauge_submit("threads", "cached", threads_cached, db); + + derive_submit("total_threads", "created", threads_created, db); + } + + traffic_submit(traffic_incoming, traffic_outgoing, db); + + if (mysql_version >= 50600 && db->innodb_stats) + mysql_read_innodb_stats(db, con); + + if (db->master_stats) + mysql_read_master_stats(db, con); + + if ((db->slave_stats) || (db->slave_notif)) + mysql_read_slave_stats(db, con); + + if (db->wsrep_stats) + mysql_read_wsrep_stats(db, con); + + return (0); } /* int mysql_read */ -void module_register (void) -{ - plugin_register_complex_config ("mysql", mysql_config); +void module_register(void) { + plugin_register_complex_config("mysql", mysql_config); } /* void module_register */ diff --git a/src/netapp.c b/src/netapp.c index c5320626..4d458793 100644 --- a/src/netapp.c +++ b/src/netapp.c @@ -34,21 +34,22 @@ #include #include -#define HAS_ALL_FLAGS(has,needs) (((has) & (needs)) == (needs)) +#define HAS_ALL_FLAGS(has, needs) (((has) & (needs)) == (needs)) typedef struct host_config_s host_config_t; -typedef void service_handler_t(host_config_t *host, na_elem_t *result, void *data); +typedef void service_handler_t(host_config_t *host, na_elem_t *result, + void *data); -struct cna_interval_s -{ - cdtime_t interval; - cdtime_t last_read; +struct cna_interval_s { + cdtime_t interval; + cdtime_t last_read; }; typedef struct cna_interval_s cna_interval_t; /*! Data types for WAFL statistics {{{ * - * \brief Persistent data for WAFL performance counters. (a.k.a. cache performance) + * \brief Persistent data for WAFL performance counters. (a.k.a. cache + * performance) * * The cache counters use old counter values to calculate a hit ratio for each * counter. The "cfg_wafl_t" struct therefore contains old counter values along @@ -59,38 +60,40 @@ typedef struct cna_interval_s cna_interval_t; * That function calculates the hit ratios, submits the calculated values and * updates the old counter values for the next iteration. */ -#define CFG_WAFL_NAME_CACHE 0x0001 -#define CFG_WAFL_DIR_CACHE 0x0002 -#define CFG_WAFL_BUF_CACHE 0x0004 -#define CFG_WAFL_INODE_CACHE 0x0008 -#define CFG_WAFL_ALL 0x000F -#define HAVE_WAFL_NAME_CACHE_HIT 0x0100 -#define HAVE_WAFL_NAME_CACHE_MISS 0x0200 -#define HAVE_WAFL_NAME_CACHE (HAVE_WAFL_NAME_CACHE_HIT | HAVE_WAFL_NAME_CACHE_MISS) -#define HAVE_WAFL_FIND_DIR_HIT 0x0400 -#define HAVE_WAFL_FIND_DIR_MISS 0x0800 -#define HAVE_WAFL_FIND_DIR (HAVE_WAFL_FIND_DIR_HIT | HAVE_WAFL_FIND_DIR_MISS) -#define HAVE_WAFL_BUF_HASH_HIT 0x1000 -#define HAVE_WAFL_BUF_HASH_MISS 0x2000 -#define HAVE_WAFL_BUF_HASH (HAVE_WAFL_BUF_HASH_HIT | HAVE_WAFL_BUF_HASH_MISS) -#define HAVE_WAFL_INODE_CACHE_HIT 0x4000 +#define CFG_WAFL_NAME_CACHE 0x0001 +#define CFG_WAFL_DIR_CACHE 0x0002 +#define CFG_WAFL_BUF_CACHE 0x0004 +#define CFG_WAFL_INODE_CACHE 0x0008 +#define CFG_WAFL_ALL 0x000F +#define HAVE_WAFL_NAME_CACHE_HIT 0x0100 +#define HAVE_WAFL_NAME_CACHE_MISS 0x0200 +#define HAVE_WAFL_NAME_CACHE \ + (HAVE_WAFL_NAME_CACHE_HIT | HAVE_WAFL_NAME_CACHE_MISS) +#define HAVE_WAFL_FIND_DIR_HIT 0x0400 +#define HAVE_WAFL_FIND_DIR_MISS 0x0800 +#define HAVE_WAFL_FIND_DIR (HAVE_WAFL_FIND_DIR_HIT | HAVE_WAFL_FIND_DIR_MISS) +#define HAVE_WAFL_BUF_HASH_HIT 0x1000 +#define HAVE_WAFL_BUF_HASH_MISS 0x2000 +#define HAVE_WAFL_BUF_HASH (HAVE_WAFL_BUF_HASH_HIT | HAVE_WAFL_BUF_HASH_MISS) +#define HAVE_WAFL_INODE_CACHE_HIT 0x4000 #define HAVE_WAFL_INODE_CACHE_MISS 0x8000 -#define HAVE_WAFL_INODE_CACHE (HAVE_WAFL_INODE_CACHE_HIT | HAVE_WAFL_INODE_CACHE_MISS) -#define HAVE_WAFL_ALL 0xff00 +#define HAVE_WAFL_INODE_CACHE \ + (HAVE_WAFL_INODE_CACHE_HIT | HAVE_WAFL_INODE_CACHE_MISS) +#define HAVE_WAFL_ALL 0xff00 typedef struct { - uint32_t flags; - cna_interval_t interval; - na_elem_t *query; - - cdtime_t timestamp; - uint64_t name_cache_hit; - uint64_t name_cache_miss; - uint64_t find_dir_hit; - uint64_t find_dir_miss; - uint64_t buf_hash_hit; - uint64_t buf_hash_miss; - uint64_t inode_cache_hit; - uint64_t inode_cache_miss; + uint32_t flags; + cna_interval_t interval; + na_elem_t *query; + + cdtime_t timestamp; + uint64_t name_cache_hit; + uint64_t name_cache_miss; + uint64_t find_dir_hit; + uint64_t find_dir_miss; + uint64_t buf_hash_hit; + uint64_t buf_hash_miss; + uint64_t inode_cache_hit; + uint64_t inode_cache_miss; } cfg_wafl_t; /* }}} cfg_wafl_t */ @@ -101,26 +104,26 @@ typedef struct { * A disk doesn't have any more information than its name at the moment. * The name includes the "disk_" prefix. */ -#define HAVE_DISK_BUSY 0x10 -#define HAVE_DISK_BASE 0x20 -#define HAVE_DISK_ALL 0x30 +#define HAVE_DISK_BUSY 0x10 +#define HAVE_DISK_BASE 0x20 +#define HAVE_DISK_ALL 0x30 typedef struct disk_s { - char *name; - uint32_t flags; - cdtime_t timestamp; - uint64_t disk_busy; - uint64_t base_for_disk_busy; - double disk_busy_percent; - struct disk_s *next; + char *name; + uint32_t flags; + cdtime_t timestamp; + uint64_t disk_busy; + uint64_t base_for_disk_busy; + double disk_busy_percent; + struct disk_s *next; } disk_t; #define CFG_DISK_BUSIEST 0x01 -#define CFG_DISK_ALL 0x01 +#define CFG_DISK_ALL 0x01 typedef struct { - uint32_t flags; - cna_interval_t interval; - na_elem_t *query; - disk_t *disks; + uint32_t flags; + cna_interval_t interval; + na_elem_t *query; + disk_t *disks; } cfg_disk_t; /* }}} cfg_disk_t */ @@ -139,44 +142,44 @@ typedef struct { * function, the per-operation latency is calculated and dispatched, then the * old counters are updated. */ -#define CFG_VOLUME_PERF_INIT 0x0001 -#define CFG_VOLUME_PERF_IO 0x0002 -#define CFG_VOLUME_PERF_OPS 0x0003 -#define CFG_VOLUME_PERF_LATENCY 0x0008 -#define CFG_VOLUME_PERF_ALL 0x000F -#define HAVE_VOLUME_PERF_BYTES_READ 0x0010 -#define HAVE_VOLUME_PERF_BYTES_WRITE 0x0020 -#define HAVE_VOLUME_PERF_OPS_READ 0x0040 -#define HAVE_VOLUME_PERF_OPS_WRITE 0x0080 -#define HAVE_VOLUME_PERF_LATENCY_READ 0x0100 +#define CFG_VOLUME_PERF_INIT 0x0001 +#define CFG_VOLUME_PERF_IO 0x0002 +#define CFG_VOLUME_PERF_OPS 0x0003 +#define CFG_VOLUME_PERF_LATENCY 0x0008 +#define CFG_VOLUME_PERF_ALL 0x000F +#define HAVE_VOLUME_PERF_BYTES_READ 0x0010 +#define HAVE_VOLUME_PERF_BYTES_WRITE 0x0020 +#define HAVE_VOLUME_PERF_OPS_READ 0x0040 +#define HAVE_VOLUME_PERF_OPS_WRITE 0x0080 +#define HAVE_VOLUME_PERF_LATENCY_READ 0x0100 #define HAVE_VOLUME_PERF_LATENCY_WRITE 0x0200 -#define HAVE_VOLUME_PERF_ALL 0x03F0 +#define HAVE_VOLUME_PERF_ALL 0x03F0 struct data_volume_perf_s; typedef struct data_volume_perf_s data_volume_perf_t; struct data_volume_perf_s { - char *name; - uint32_t flags; - cdtime_t timestamp; - - uint64_t read_bytes; - uint64_t write_bytes; - uint64_t read_ops; - uint64_t write_ops; - uint64_t read_latency; - uint64_t write_latency; - - data_volume_perf_t *next; + char *name; + uint32_t flags; + cdtime_t timestamp; + + uint64_t read_bytes; + uint64_t write_bytes; + uint64_t read_ops; + uint64_t write_ops; + uint64_t read_latency; + uint64_t write_latency; + + data_volume_perf_t *next; }; typedef struct { - cna_interval_t interval; - na_elem_t *query; + cna_interval_t interval; + na_elem_t *query; - ignorelist_t *il_octets; - ignorelist_t *il_operations; - ignorelist_t *il_latency; + ignorelist_t *il_octets; + ignorelist_t *il_operations; + ignorelist_t *il_latency; - data_volume_perf_t *volumes; + data_volume_perf_t *volumes; } cfg_volume_perf_t; /* }}} data_volume_perf_t */ @@ -184,45 +187,45 @@ typedef struct { * * \brief Configuration struct for volume usage data (free / used). */ -#define CFG_VOLUME_USAGE_DF 0x0002 -#define CFG_VOLUME_USAGE_SNAP 0x0004 -#define CFG_VOLUME_USAGE_ALL 0x0006 -#define HAVE_VOLUME_USAGE_NORM_FREE 0x0010 -#define HAVE_VOLUME_USAGE_NORM_USED 0x0020 -#define HAVE_VOLUME_USAGE_SNAP_RSVD 0x0040 -#define HAVE_VOLUME_USAGE_SNAP_USED 0x0080 -#define HAVE_VOLUME_USAGE_SIS_SAVED 0x0100 +#define CFG_VOLUME_USAGE_DF 0x0002 +#define CFG_VOLUME_USAGE_SNAP 0x0004 +#define CFG_VOLUME_USAGE_ALL 0x0006 +#define HAVE_VOLUME_USAGE_NORM_FREE 0x0010 +#define HAVE_VOLUME_USAGE_NORM_USED 0x0020 +#define HAVE_VOLUME_USAGE_SNAP_RSVD 0x0040 +#define HAVE_VOLUME_USAGE_SNAP_USED 0x0080 +#define HAVE_VOLUME_USAGE_SIS_SAVED 0x0100 #define HAVE_VOLUME_USAGE_COMPRESS_SAVED 0x0200 -#define HAVE_VOLUME_USAGE_DEDUP_SAVED 0x0400 -#define HAVE_VOLUME_USAGE_ALL 0x07f0 -#define IS_VOLUME_USAGE_OFFLINE 0x0800 +#define HAVE_VOLUME_USAGE_DEDUP_SAVED 0x0400 +#define HAVE_VOLUME_USAGE_ALL 0x07f0 +#define IS_VOLUME_USAGE_OFFLINE 0x0800 struct data_volume_usage_s; typedef struct data_volume_usage_s data_volume_usage_t; struct data_volume_usage_s { - char *name; - uint32_t flags; + char *name; + uint32_t flags; - na_elem_t *snap_query; + na_elem_t *snap_query; - uint64_t norm_free; - uint64_t norm_used; - uint64_t snap_reserved; - uint64_t snap_used; - uint64_t sis_saved; - uint64_t compress_saved; - uint64_t dedup_saved; + uint64_t norm_free; + uint64_t norm_used; + uint64_t snap_reserved; + uint64_t snap_used; + uint64_t sis_saved; + uint64_t compress_saved; + uint64_t dedup_saved; - data_volume_usage_t *next; + data_volume_usage_t *next; }; typedef struct { - cna_interval_t interval; - na_elem_t *query; + cna_interval_t interval; + na_elem_t *query; - ignorelist_t *il_capacity; - ignorelist_t *il_snapshot; + ignorelist_t *il_capacity; + ignorelist_t *il_snapshot; - data_volume_usage_t *volumes; + data_volume_usage_t *volumes; } cfg_volume_usage_t; /* }}} cfg_volume_usage_t */ @@ -231,8 +234,8 @@ typedef struct { * \brief Persistent data for quota statistics */ typedef struct { - cna_interval_t interval; - na_elem_t *query; + cna_interval_t interval; + na_elem_t *query; } cfg_quota_t; /* }}} cfg_quota_t */ @@ -241,8 +244,8 @@ typedef struct { * \brief Persistent data for SnapVault(R) statistics */ typedef struct { - cna_interval_t interval; - na_elem_t *query; + cna_interval_t interval; + na_elem_t *query; } cfg_snapvault_t; /* }}} cfg_snapvault_t */ @@ -250,38 +253,38 @@ typedef struct { * * \brief Persistent data for system performance counters */ -#define CFG_SYSTEM_CPU 0x01 -#define CFG_SYSTEM_NET 0x02 -#define CFG_SYSTEM_OPS 0x04 +#define CFG_SYSTEM_CPU 0x01 +#define CFG_SYSTEM_NET 0x02 +#define CFG_SYSTEM_OPS 0x04 #define CFG_SYSTEM_DISK 0x08 -#define CFG_SYSTEM_ALL 0x0F +#define CFG_SYSTEM_ALL 0x0F typedef struct { - uint32_t flags; - cna_interval_t interval; - na_elem_t *query; + uint32_t flags; + cna_interval_t interval; + na_elem_t *query; } cfg_system_t; /* }}} cfg_system_t */ struct host_config_s { - char *name; - na_server_transport_t protocol; - char *host; - int port; - char *username; - char *password; - char *vfiler; - cdtime_t interval; - - na_server_t *srv; - cfg_wafl_t *cfg_wafl; - cfg_disk_t *cfg_disk; - cfg_volume_perf_t *cfg_volume_perf; - cfg_volume_usage_t *cfg_volume_usage; - cfg_quota_t *cfg_quota; - cfg_snapvault_t *cfg_snapvault; - cfg_system_t *cfg_system; - - struct host_config_s *next; + char *name; + na_server_transport_t protocol; + char *host; + int port; + char *username; + char *password; + char *vfiler; + cdtime_t interval; + + na_server_t *srv; + cfg_wafl_t *cfg_wafl; + cfg_disk_t *cfg_disk; + cfg_volume_perf_t *cfg_volume_perf; + cfg_volume_usage_t *cfg_volume_usage; + cfg_quota_t *cfg_quota; + cfg_snapvault_t *cfg_snapvault; + cfg_system_t *cfg_system; + + struct host_config_s *next; }; /* @@ -289,163 +292,161 @@ struct host_config_s { * * Used to free the various structures above. */ -static void free_disk (disk_t *disk) /* {{{ */ +static void free_disk(disk_t *disk) /* {{{ */ { - disk_t *next; + disk_t *next; - if (disk == NULL) - return; + if (disk == NULL) + return; - next = disk->next; + next = disk->next; - sfree (disk->name); - sfree (disk); + sfree(disk->name); + sfree(disk); - free_disk (next); + free_disk(next); } /* }}} void free_disk */ -static void free_cfg_wafl (cfg_wafl_t *cw) /* {{{ */ +static void free_cfg_wafl(cfg_wafl_t *cw) /* {{{ */ { - if (cw == NULL) - return; + if (cw == NULL) + return; - if (cw->query != NULL) - na_elem_free (cw->query); + if (cw->query != NULL) + na_elem_free(cw->query); - sfree (cw); + sfree(cw); } /* }}} void free_cfg_wafl */ -static void free_cfg_disk (cfg_disk_t *cfg_disk) /* {{{ */ +static void free_cfg_disk(cfg_disk_t *cfg_disk) /* {{{ */ { - if (cfg_disk == NULL) - return; + if (cfg_disk == NULL) + return; - if (cfg_disk->query != NULL) - na_elem_free (cfg_disk->query); + if (cfg_disk->query != NULL) + na_elem_free(cfg_disk->query); - free_disk (cfg_disk->disks); - sfree (cfg_disk); + free_disk(cfg_disk->disks); + sfree(cfg_disk); } /* }}} void free_cfg_disk */ -static void free_cfg_volume_perf (cfg_volume_perf_t *cvp) /* {{{ */ +static void free_cfg_volume_perf(cfg_volume_perf_t *cvp) /* {{{ */ { - data_volume_perf_t *data; - - if (cvp == NULL) - return; - - /* Free the ignorelists */ - ignorelist_free (cvp->il_octets); - ignorelist_free (cvp->il_operations); - ignorelist_free (cvp->il_latency); - - /* Free the linked list of volumes */ - data = cvp->volumes; - while (data != NULL) - { - data_volume_perf_t *next = data->next; - sfree (data->name); - sfree (data); - data = next; - } - - if (cvp->query != NULL) - na_elem_free (cvp->query); - - sfree (cvp); + data_volume_perf_t *data; + + if (cvp == NULL) + return; + + /* Free the ignorelists */ + ignorelist_free(cvp->il_octets); + ignorelist_free(cvp->il_operations); + ignorelist_free(cvp->il_latency); + + /* Free the linked list of volumes */ + data = cvp->volumes; + while (data != NULL) { + data_volume_perf_t *next = data->next; + sfree(data->name); + sfree(data); + data = next; + } + + if (cvp->query != NULL) + na_elem_free(cvp->query); + + sfree(cvp); } /* }}} void free_cfg_volume_perf */ -static void free_cfg_volume_usage (cfg_volume_usage_t *cvu) /* {{{ */ +static void free_cfg_volume_usage(cfg_volume_usage_t *cvu) /* {{{ */ { - data_volume_usage_t *data; - - if (cvu == NULL) - return; - - /* Free the ignorelists */ - ignorelist_free (cvu->il_capacity); - ignorelist_free (cvu->il_snapshot); - - /* Free the linked list of volumes */ - data = cvu->volumes; - while (data != NULL) - { - data_volume_usage_t *next = data->next; - sfree (data->name); - if (data->snap_query != NULL) - na_elem_free(data->snap_query); - sfree (data); - data = next; - } - - if (cvu->query != NULL) - na_elem_free (cvu->query); - - sfree (cvu); + data_volume_usage_t *data; + + if (cvu == NULL) + return; + + /* Free the ignorelists */ + ignorelist_free(cvu->il_capacity); + ignorelist_free(cvu->il_snapshot); + + /* Free the linked list of volumes */ + data = cvu->volumes; + while (data != NULL) { + data_volume_usage_t *next = data->next; + sfree(data->name); + if (data->snap_query != NULL) + na_elem_free(data->snap_query); + sfree(data); + data = next; + } + + if (cvu->query != NULL) + na_elem_free(cvu->query); + + sfree(cvu); } /* }}} void free_cfg_volume_usage */ -static void free_cfg_quota (cfg_quota_t *q) /* {{{ */ +static void free_cfg_quota(cfg_quota_t *q) /* {{{ */ { - if (q == NULL) - return; + if (q == NULL) + return; - if (q->query != NULL) - na_elem_free (q->query); + if (q->query != NULL) + na_elem_free(q->query); - sfree (q); + sfree(q); } /* }}} void free_cfg_quota */ -static void free_cfg_snapvault (cfg_snapvault_t *sv) /* {{{ */ +static void free_cfg_snapvault(cfg_snapvault_t *sv) /* {{{ */ { - if (sv == NULL) - return; + if (sv == NULL) + return; - if (sv->query != NULL) - na_elem_free (sv->query); + if (sv->query != NULL) + na_elem_free(sv->query); - sfree (sv); + sfree(sv); } /* }}} void free_cfg_snapvault */ -static void free_cfg_system (cfg_system_t *cs) /* {{{ */ +static void free_cfg_system(cfg_system_t *cs) /* {{{ */ { - if (cs == NULL) - return; + if (cs == NULL) + return; - if (cs->query != NULL) - na_elem_free (cs->query); + if (cs->query != NULL) + na_elem_free(cs->query); - sfree (cs); + sfree(cs); } /* }}} void free_cfg_system */ -static void free_host_config (host_config_t *hc) /* {{{ */ +static void free_host_config(host_config_t *hc) /* {{{ */ { - host_config_t *next; + host_config_t *next; - if (hc == NULL) - return; + if (hc == NULL) + return; - next = hc->next; + next = hc->next; - sfree (hc->name); - sfree (hc->host); - sfree (hc->username); - sfree (hc->password); - sfree (hc->vfiler); + sfree(hc->name); + sfree(hc->host); + sfree(hc->username); + sfree(hc->password); + sfree(hc->vfiler); - free_cfg_disk (hc->cfg_disk); - free_cfg_wafl (hc->cfg_wafl); - free_cfg_volume_perf (hc->cfg_volume_perf); - free_cfg_volume_usage (hc->cfg_volume_usage); - free_cfg_quota (hc->cfg_quota); - free_cfg_snapvault (hc->cfg_snapvault); - free_cfg_system (hc->cfg_system); + free_cfg_disk(hc->cfg_disk); + free_cfg_wafl(hc->cfg_wafl); + free_cfg_volume_perf(hc->cfg_volume_perf); + free_cfg_volume_usage(hc->cfg_volume_usage); + free_cfg_quota(hc->cfg_quota); + free_cfg_snapvault(hc->cfg_snapvault); + free_cfg_system(hc->cfg_system); - if (hc->srv != NULL) - na_server_close (hc->srv); + if (hc->srv != NULL) + na_server_close(hc->srv); - sfree (hc); + sfree(hc); - free_host_config (next); + free_host_config(next); } /* }}} void free_host_config */ /* @@ -455,157 +456,151 @@ static void free_host_config (host_config_t *hc) /* {{{ */ */ static disk_t *get_disk(cfg_disk_t *cd, const char *name) /* {{{ */ { - disk_t *d; + disk_t *d; - if ((cd == NULL) || (name == NULL)) - return (NULL); + if ((cd == NULL) || (name == NULL)) + return (NULL); - for (d = cd->disks; d != NULL; d = d->next) { - if (strcmp(d->name, name) == 0) - return d; - } + for (d = cd->disks; d != NULL; d = d->next) { + if (strcmp(d->name, name) == 0) + return d; + } - d = calloc (1, sizeof (*d)); - if (d == NULL) - return (NULL); - d->next = NULL; + d = calloc(1, sizeof(*d)); + if (d == NULL) + return (NULL); + d->next = NULL; - d->name = strdup(name); - if (d->name == NULL) { - sfree (d); - return (NULL); - } + d->name = strdup(name); + if (d->name == NULL) { + sfree(d); + return (NULL); + } - d->next = cd->disks; - cd->disks = d; + d->next = cd->disks; + cd->disks = d; - return d; + return d; } /* }}} disk_t *get_disk */ -static data_volume_usage_t *get_volume_usage (cfg_volume_usage_t *cvu, /* {{{ */ - const char *name) -{ - data_volume_usage_t *last; - data_volume_usage_t *new; - - int ignore_capacity = 0; - int ignore_snapshot = 0; - - if ((cvu == NULL) || (name == NULL)) - return (NULL); - - last = cvu->volumes; - while (last != NULL) - { - if (strcmp (last->name, name) == 0) - return (last); - - if (last->next == NULL) - break; - - last = last->next; - } - - /* Check the ignorelists. If *both* tell us to ignore a volume, return NULL. */ - ignore_capacity = ignorelist_match (cvu->il_capacity, name); - ignore_snapshot = ignorelist_match (cvu->il_snapshot, name); - if ((ignore_capacity != 0) && (ignore_snapshot != 0)) - return (NULL); - - /* Not found: allocate. */ - new = calloc (1, sizeof (*new)); - if (new == NULL) - return (NULL); - new->next = NULL; - - new->name = strdup (name); - if (new->name == NULL) - { - sfree (new); - return (NULL); - } - - if (ignore_capacity == 0) - new->flags |= CFG_VOLUME_USAGE_DF; - if (ignore_snapshot == 0) { - new->flags |= CFG_VOLUME_USAGE_SNAP; - new->snap_query = na_elem_new ("snapshot-list-info"); - na_child_add_string(new->snap_query, "target-type", "volume"); - na_child_add_string(new->snap_query, "target-name", name); - } else { - new->snap_query = NULL; - } - - /* Add to end of list. */ - if (last == NULL) - cvu->volumes = new; - else - last->next = new; - - return (new); +static data_volume_usage_t *get_volume_usage(cfg_volume_usage_t *cvu, /* {{{ */ + const char *name) { + data_volume_usage_t *last; + data_volume_usage_t *new; + + int ignore_capacity = 0; + int ignore_snapshot = 0; + + if ((cvu == NULL) || (name == NULL)) + return (NULL); + + last = cvu->volumes; + while (last != NULL) { + if (strcmp(last->name, name) == 0) + return (last); + + if (last->next == NULL) + break; + + last = last->next; + } + + /* Check the ignorelists. If *both* tell us to ignore a volume, return NULL. + */ + ignore_capacity = ignorelist_match(cvu->il_capacity, name); + ignore_snapshot = ignorelist_match(cvu->il_snapshot, name); + if ((ignore_capacity != 0) && (ignore_snapshot != 0)) + return (NULL); + + /* Not found: allocate. */ + new = calloc(1, sizeof(*new)); + if (new == NULL) + return (NULL); + new->next = NULL; + + new->name = strdup(name); + if (new->name == NULL) { + sfree(new); + return (NULL); + } + + if (ignore_capacity == 0) + new->flags |= CFG_VOLUME_USAGE_DF; + if (ignore_snapshot == 0) { + new->flags |= CFG_VOLUME_USAGE_SNAP; + new->snap_query = na_elem_new("snapshot-list-info"); + na_child_add_string(new->snap_query, "target-type", "volume"); + na_child_add_string(new->snap_query, "target-name", name); + } else { + new->snap_query = NULL; + } + + /* Add to end of list. */ + if (last == NULL) + cvu->volumes = new; + else + last->next = new; + + return (new); } /* }}} data_volume_usage_t *get_volume_usage */ -static data_volume_perf_t *get_volume_perf (cfg_volume_perf_t *cvp, /* {{{ */ - const char *name) -{ - data_volume_perf_t *last; - data_volume_perf_t *new; - - int ignore_octets = 0; - int ignore_operations = 0; - int ignore_latency = 0; - - if ((cvp == NULL) || (name == NULL)) - return (NULL); - - last = cvp->volumes; - while (last != NULL) - { - if (strcmp (last->name, name) == 0) - return (last); - - if (last->next == NULL) - break; - - last = last->next; - } - - /* Check the ignorelists. If *all three* tell us to ignore a volume, return - * NULL. */ - ignore_octets = ignorelist_match (cvp->il_octets, name); - ignore_operations = ignorelist_match (cvp->il_operations, name); - ignore_latency = ignorelist_match (cvp->il_latency, name); - if ((ignore_octets != 0) || (ignore_operations != 0) - || (ignore_latency != 0)) - return (NULL); - - /* Not found: allocate. */ - new = calloc (1, sizeof (*new)); - if (new == NULL) - return (NULL); - new->next = NULL; - - new->name = strdup (name); - if (new->name == NULL) - { - sfree (new); - return (NULL); - } - - if (ignore_octets == 0) - new->flags |= CFG_VOLUME_PERF_IO; - if (ignore_operations == 0) - new->flags |= CFG_VOLUME_PERF_OPS; - if (ignore_latency == 0) - new->flags |= CFG_VOLUME_PERF_LATENCY; - - /* Add to end of list. */ - if (last == NULL) - cvp->volumes = new; - else - last->next = new; - - return (new); +static data_volume_perf_t *get_volume_perf(cfg_volume_perf_t *cvp, /* {{{ */ + const char *name) { + data_volume_perf_t *last; + data_volume_perf_t *new; + + int ignore_octets = 0; + int ignore_operations = 0; + int ignore_latency = 0; + + if ((cvp == NULL) || (name == NULL)) + return (NULL); + + last = cvp->volumes; + while (last != NULL) { + if (strcmp(last->name, name) == 0) + return (last); + + if (last->next == NULL) + break; + + last = last->next; + } + + /* Check the ignorelists. If *all three* tell us to ignore a volume, return + * NULL. */ + ignore_octets = ignorelist_match(cvp->il_octets, name); + ignore_operations = ignorelist_match(cvp->il_operations, name); + ignore_latency = ignorelist_match(cvp->il_latency, name); + if ((ignore_octets != 0) || (ignore_operations != 0) || (ignore_latency != 0)) + return (NULL); + + /* Not found: allocate. */ + new = calloc(1, sizeof(*new)); + if (new == NULL) + return (NULL); + new->next = NULL; + + new->name = strdup(name); + if (new->name == NULL) { + sfree(new); + return (NULL); + } + + if (ignore_octets == 0) + new->flags |= CFG_VOLUME_PERF_IO; + if (ignore_operations == 0) + new->flags |= CFG_VOLUME_PERF_OPS; + if (ignore_latency == 0) + new->flags |= CFG_VOLUME_PERF_LATENCY; + + /* Add to end of list. */ + if (last == NULL) + cvp->volumes = new; + else + last->next = new; + + return (new); } /* }}} data_volume_perf_t *get_volume_perf */ /* @@ -614,260 +609,262 @@ static data_volume_perf_t *get_volume_perf (cfg_volume_perf_t *cvp, /* {{{ */ * They all eventually call "submit_values" which creates a value_list_t and * dispatches it to the daemon. */ -static int submit_values (const char *host, /* {{{ */ - const char *plugin_inst, - const char *type, const char *type_inst, - value_t *values, size_t values_len, - cdtime_t timestamp, cdtime_t interval) -{ - value_list_t vl = VALUE_LIST_INIT; - - vl.values = values; - vl.values_len = values_len; - - if (timestamp > 0) - vl.time = timestamp; - - if (interval > 0) - vl.interval = interval; - - if (host != NULL) - sstrncpy (vl.host, host, sizeof (vl.host)); - sstrncpy (vl.plugin, "netapp", sizeof (vl.plugin)); - if (plugin_inst != NULL) - sstrncpy (vl.plugin_instance, plugin_inst, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - if (type_inst != NULL) - sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance)); - - return (plugin_dispatch_values (&vl)); +static int submit_values(const char *host, /* {{{ */ + const char *plugin_inst, const char *type, + const char *type_inst, value_t *values, + size_t values_len, cdtime_t timestamp, + cdtime_t interval) { + value_list_t vl = VALUE_LIST_INIT; + + vl.values = values; + vl.values_len = values_len; + + if (timestamp > 0) + vl.time = timestamp; + + if (interval > 0) + vl.interval = interval; + + if (host != NULL) + sstrncpy(vl.host, host, sizeof(vl.host)); + sstrncpy(vl.plugin, "netapp", sizeof(vl.plugin)); + if (plugin_inst != NULL) + sstrncpy(vl.plugin_instance, plugin_inst, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + if (type_inst != NULL) + sstrncpy(vl.type_instance, type_inst, sizeof(vl.type_instance)); + + return (plugin_dispatch_values(&vl)); } /* }}} int submit_uint64 */ -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[] = { - { .derive = val0 }, - { .derive = val1 }, - }; - - return (submit_values (host, plugin_inst, type, type_inst, - values, STATIC_ARRAY_SIZE (values), timestamp, 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[] = { + {.derive = val0}, {.derive = val1}, + }; + + return (submit_values(host, plugin_inst, type, type_inst, values, + STATIC_ARRAY_SIZE(values), timestamp, interval)); } /* }}} int submit_two_derive */ -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) -{ - return (submit_values (host, plugin_inst, type, type_inst, - &(value_t) { .derive = counter }, 1, timestamp, 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) { + return (submit_values(host, plugin_inst, type, type_inst, + &(value_t){.derive = counter}, 1, timestamp, interval)); } /* }}} 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, - cdtime_t timestamp, cdtime_t interval) -{ - value_t values[] = { - { .gauge = val0 }, - { .gauge = val1 }, - }; +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, cdtime_t timestamp, + cdtime_t interval) { + value_t values[] = { + {.gauge = val0}, {.gauge = val1}, + }; - return (submit_values (host, plugin_inst, type, type_inst, - values, STATIC_ARRAY_SIZE (values), timestamp, interval)); + return (submit_values(host, plugin_inst, type, type_inst, values, + STATIC_ARRAY_SIZE(values), 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, - cdtime_t timestamp, cdtime_t interval) -{ - return (submit_values (host, plugin_inst, type, type_inst, - &(value_t) { .gauge = counter }, 1, timestamp, interval)); +static int submit_double(const char *host, const char *plugin_inst, /* {{{ */ + const char *type, const char *type_inst, double d, + cdtime_t timestamp, cdtime_t interval) { + return (submit_values(host, plugin_inst, type, type_inst, + &(value_t){.gauge = counter}, 1, timestamp, interval)); } /* }}} int submit_uint64 */ /* Calculate hit ratio from old and new counters and submit the resulting * percentage. Used by "submit_wafl_data". */ -static int submit_cache_ratio (const char *host, /* {{{ */ - const char *plugin_inst, - const char *type_inst, - uint64_t new_hits, - uint64_t new_misses, - uint64_t old_hits, - uint64_t old_misses, - cdtime_t timestamp, - cdtime_t interval) -{ - value_t v = { .gauge = NAN }; +static int submit_cache_ratio(const char *host, /* {{{ */ + const char *plugin_inst, const char *type_inst, + uint64_t new_hits, uint64_t new_misses, + uint64_t old_hits, uint64_t old_misses, + cdtime_t timestamp, cdtime_t interval) { + value_t v = {.gauge = NAN}; - if ((new_hits >= old_hits) && (new_misses >= old_misses)) { - uint64_t hits; - uint64_t misses; + if ((new_hits >= old_hits) && (new_misses >= old_misses)) { + uint64_t hits; + uint64_t misses; - hits = new_hits - old_hits; - misses = new_misses - old_misses; + hits = new_hits - old_hits; + misses = new_misses - old_misses; - v.gauge = 100.0 * ((gauge_t) hits) / ((gauge_t) (hits + misses)); - } + v.gauge = 100.0 * ((gauge_t)hits) / ((gauge_t)(hits + misses)); + } - return (submit_values (host, plugin_inst, "cache_ratio", type_inst, - &v, 1, timestamp, interval)); + return (submit_values(host, plugin_inst, "cache_ratio", type_inst, &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, cdtime_t interval) -{ - /* Submit requested counters */ - if (HAS_ALL_FLAGS (old_data->flags, CFG_WAFL_NAME_CACHE | HAVE_WAFL_NAME_CACHE) - && HAS_ALL_FLAGS (new_data->flags, 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, 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, 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, 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, interval); - - /* Clear old HAVE_* flags */ - old_data->flags &= ~HAVE_WAFL_ALL; - - /* Copy all counters */ - old_data->timestamp = new_data->timestamp; - old_data->name_cache_hit = new_data->name_cache_hit; - old_data->name_cache_miss = new_data->name_cache_miss; - old_data->find_dir_hit = new_data->find_dir_hit; - old_data->find_dir_miss = new_data->find_dir_miss; - old_data->buf_hash_hit = new_data->buf_hash_hit; - old_data->buf_hash_miss = new_data->buf_hash_miss; - old_data->inode_cache_hit = new_data->inode_cache_hit; - old_data->inode_cache_miss = new_data->inode_cache_miss; - - /* Copy HAVE_* flags */ - old_data->flags |= (new_data->flags & HAVE_WAFL_ALL); - - return (0); +static int submit_wafl_data(const char *hostname, + const char *instance, /* {{{ */ + cfg_wafl_t *old_data, const cfg_wafl_t *new_data, + cdtime_t interval) { + /* Submit requested counters */ + if (HAS_ALL_FLAGS(old_data->flags, + CFG_WAFL_NAME_CACHE | HAVE_WAFL_NAME_CACHE) && + HAS_ALL_FLAGS(new_data->flags, 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, 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, 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, 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, interval); + + /* Clear old HAVE_* flags */ + old_data->flags &= ~HAVE_WAFL_ALL; + + /* Copy all counters */ + old_data->timestamp = new_data->timestamp; + old_data->name_cache_hit = new_data->name_cache_hit; + old_data->name_cache_miss = new_data->name_cache_miss; + old_data->find_dir_hit = new_data->find_dir_hit; + old_data->find_dir_miss = new_data->find_dir_miss; + old_data->buf_hash_hit = new_data->buf_hash_hit; + old_data->buf_hash_miss = new_data->buf_hash_miss; + old_data->inode_cache_hit = new_data->inode_cache_hit; + old_data->inode_cache_miss = new_data->inode_cache_miss; + + /* Copy HAVE_* flags */ + old_data->flags |= (new_data->flags & HAVE_WAFL_ALL); + + return (0); } /* }}} int submit_wafl_data */ /* Submits volume performance data to the daemon, taking care to honor and * 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, int interval) -{ - char plugin_instance[DATA_MAX_NAME_LEN]; - - if ((hostname == NULL) || (old_data == NULL) || (new_data == NULL)) - return (-1); - - ssnprintf (plugin_instance, sizeof (plugin_instance), - "volume-%s", old_data->name); - - /* Check for and submit disk-octet values */ - 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_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_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 */ - if (HAS_ALL_FLAGS (old_data->flags, CFG_VOLUME_PERF_LATENCY - | HAVE_VOLUME_PERF_OPS_READ | HAVE_VOLUME_PERF_OPS_WRITE - | HAVE_VOLUME_PERF_LATENCY_READ | HAVE_VOLUME_PERF_LATENCY_WRITE) - && HAS_ALL_FLAGS (new_data->flags, HAVE_VOLUME_PERF_OPS_READ | HAVE_VOLUME_PERF_OPS_WRITE - | HAVE_VOLUME_PERF_LATENCY_READ | HAVE_VOLUME_PERF_LATENCY_WRITE)) - { - gauge_t latency_per_op_read; - gauge_t latency_per_op_write; - - latency_per_op_read = NAN; - latency_per_op_write = NAN; - - /* Check if a counter wrapped around. */ - if ((new_data->read_ops > old_data->read_ops) - && (new_data->read_latency > old_data->read_latency)) - { - uint64_t diff_ops_read; - uint64_t diff_latency_read; - - diff_ops_read = new_data->read_ops - old_data->read_ops; - diff_latency_read = new_data->read_latency - old_data->read_latency; - - if (diff_ops_read > 0) - latency_per_op_read = ((gauge_t) diff_latency_read) / ((gauge_t) diff_ops_read); - } - - if ((new_data->write_ops > old_data->write_ops) - && (new_data->write_latency > old_data->write_latency)) - { - uint64_t diff_ops_write; - uint64_t diff_latency_write; - - diff_ops_write = new_data->write_ops - old_data->write_ops; - diff_latency_write = new_data->write_latency - old_data->write_latency; - - if (diff_ops_write > 0) - latency_per_op_write = ((gauge_t) diff_latency_write) / ((gauge_t) diff_ops_write); - } - - submit_two_gauge (hostname, plugin_instance, "disk_latency", /* type instance = */ NULL, - latency_per_op_read, latency_per_op_write, new_data->timestamp, interval); - } - - /* Clear all HAVE_* flags. */ - old_data->flags &= ~HAVE_VOLUME_PERF_ALL; - - /* Copy all counters */ - old_data->timestamp = new_data->timestamp; - old_data->read_bytes = new_data->read_bytes; - old_data->write_bytes = new_data->write_bytes; - old_data->read_ops = new_data->read_ops; - old_data->write_ops = new_data->write_ops; - old_data->read_latency = new_data->read_latency; - old_data->write_latency = new_data->write_latency; - - /* Copy the HAVE_* flags */ - old_data->flags |= (new_data->flags & HAVE_VOLUME_PERF_ALL); - - return (0); +static int submit_volume_perf_data(const char *hostname, /* {{{ */ + data_volume_perf_t *old_data, + const data_volume_perf_t *new_data, + int interval) { + char plugin_instance[DATA_MAX_NAME_LEN]; + + if ((hostname == NULL) || (old_data == NULL) || (new_data == NULL)) + return (-1); + + ssnprintf(plugin_instance, sizeof(plugin_instance), "volume-%s", + old_data->name); + + /* Check for and submit disk-octet values */ + 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_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_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 */ + if (HAS_ALL_FLAGS(old_data->flags, CFG_VOLUME_PERF_LATENCY | + HAVE_VOLUME_PERF_OPS_READ | + HAVE_VOLUME_PERF_OPS_WRITE | + HAVE_VOLUME_PERF_LATENCY_READ | + HAVE_VOLUME_PERF_LATENCY_WRITE) && + HAS_ALL_FLAGS(new_data->flags, HAVE_VOLUME_PERF_OPS_READ | + HAVE_VOLUME_PERF_OPS_WRITE | + HAVE_VOLUME_PERF_LATENCY_READ | + HAVE_VOLUME_PERF_LATENCY_WRITE)) { + gauge_t latency_per_op_read; + gauge_t latency_per_op_write; + + latency_per_op_read = NAN; + latency_per_op_write = NAN; + + /* Check if a counter wrapped around. */ + if ((new_data->read_ops > old_data->read_ops) && + (new_data->read_latency > old_data->read_latency)) { + uint64_t diff_ops_read; + uint64_t diff_latency_read; + + diff_ops_read = new_data->read_ops - old_data->read_ops; + diff_latency_read = new_data->read_latency - old_data->read_latency; + + if (diff_ops_read > 0) + latency_per_op_read = + ((gauge_t)diff_latency_read) / ((gauge_t)diff_ops_read); + } + + if ((new_data->write_ops > old_data->write_ops) && + (new_data->write_latency > old_data->write_latency)) { + uint64_t diff_ops_write; + uint64_t diff_latency_write; + + diff_ops_write = new_data->write_ops - old_data->write_ops; + diff_latency_write = new_data->write_latency - old_data->write_latency; + + if (diff_ops_write > 0) + latency_per_op_write = + ((gauge_t)diff_latency_write) / ((gauge_t)diff_ops_write); + } + + submit_two_gauge(hostname, plugin_instance, "disk_latency", + /* type instance = */ NULL, latency_per_op_read, + latency_per_op_write, new_data->timestamp, interval); + } + + /* Clear all HAVE_* flags. */ + old_data->flags &= ~HAVE_VOLUME_PERF_ALL; + + /* Copy all counters */ + old_data->timestamp = new_data->timestamp; + old_data->read_bytes = new_data->read_bytes; + old_data->write_bytes = new_data->write_bytes; + old_data->read_ops = new_data->read_ops; + old_data->write_ops = new_data->write_ops; + old_data->read_latency = new_data->read_latency; + old_data->write_latency = new_data->write_latency; + + /* Copy the HAVE_* flags */ + old_data->flags |= (new_data->flags & HAVE_VOLUME_PERF_ALL); + + return (0); } /* }}} int submit_volume_perf_data */ -static cdtime_t cna_child_get_cdtime (na_elem_t *data) /* {{{ */ +static cdtime_t cna_child_get_cdtime(na_elem_t *data) /* {{{ */ { - time_t t; + time_t t; - t = (time_t) na_child_get_uint64 (data, "timestamp", /* default = */ 0); + t = (time_t)na_child_get_uint64(data, "timestamp", /* default = */ 0); - return (TIME_T_TO_CDTIME_T (t)); + return (TIME_T_TO_CDTIME_T(t)); } /* }}} cdtime_t cna_child_get_cdtime */ - /* * Query functions * @@ -875,1374 +872,1351 @@ static cdtime_t cna_child_get_cdtime (na_elem_t *data) /* {{{ */ * interface which is parsed and submitted with the above functions. */ /* Data corresponding to */ -static int cna_handle_wafl_data (const char *hostname, cfg_wafl_t *cfg_wafl, /* {{{ */ - na_elem_t *data, cdtime_t interval) -{ - cfg_wafl_t perf_data = { 0 }; - const char *plugin_inst; - - na_elem_t *instances; - na_elem_iter_t counter_iter; - - perf_data.timestamp = cna_child_get_cdtime (data); - - instances = na_elem_child(na_elem_child (data, "instances"), "instance-data"); - if (instances == NULL) - { - ERROR ("netapp plugin: cna_handle_wafl_data: " - "na_elem_child (\"instances\") failed " - "for host %s.", hostname); - return (-1); - } - - plugin_inst = na_child_get_string(instances, "name"); - if (plugin_inst == NULL) - { - ERROR ("netapp plugin: cna_handle_wafl_data: " - "na_child_get_string (\"name\") failed " - "for host %s.", hostname); - return (-1); - } - - /* Iterate over all counters */ - counter_iter = na_child_iterator (na_elem_child (instances, "counters")); - for (na_elem_t *counter = na_iterator_next (&counter_iter); - counter != NULL; - counter = na_iterator_next (&counter_iter)) - { - const char *name; - uint64_t value; - - name = na_child_get_string(counter, "name"); - if (name == NULL) - continue; - - value = na_child_get_uint64(counter, "value", UINT64_MAX); - if (value == UINT64_MAX) - continue; - - if (!strcmp(name, "name_cache_hit")) { - perf_data.name_cache_hit = value; - perf_data.flags |= HAVE_WAFL_NAME_CACHE_HIT; - } else if (!strcmp(name, "name_cache_miss")) { - perf_data.name_cache_miss = value; - perf_data.flags |= HAVE_WAFL_NAME_CACHE_MISS; - } else if (!strcmp(name, "find_dir_hit")) { - perf_data.find_dir_hit = value; - perf_data.flags |= HAVE_WAFL_FIND_DIR_HIT; - } else if (!strcmp(name, "find_dir_miss")) { - perf_data.find_dir_miss = value; - perf_data.flags |= HAVE_WAFL_FIND_DIR_MISS; - } else if (!strcmp(name, "buf_hash_hit")) { - perf_data.buf_hash_hit = value; - perf_data.flags |= HAVE_WAFL_BUF_HASH_HIT; - } else if (!strcmp(name, "buf_hash_miss")) { - perf_data.buf_hash_miss = value; - perf_data.flags |= HAVE_WAFL_BUF_HASH_MISS; - } else if (!strcmp(name, "inode_cache_hit")) { - perf_data.inode_cache_hit = value; - perf_data.flags |= HAVE_WAFL_INODE_CACHE_HIT; - } else if (!strcmp(name, "inode_cache_miss")) { - perf_data.inode_cache_miss = value; - perf_data.flags |= HAVE_WAFL_INODE_CACHE_MISS; - } else { - DEBUG("netapp plugin: cna_handle_wafl_data: " - "Found unexpected child: %s " - "for host %s.", name, hostname); - } - } - - return (submit_wafl_data (hostname, plugin_inst, cfg_wafl, &perf_data, interval)); +static int cna_handle_wafl_data(const char *hostname, + cfg_wafl_t *cfg_wafl, /* {{{ */ + na_elem_t *data, cdtime_t interval) { + cfg_wafl_t perf_data = {0}; + const char *plugin_inst; + + na_elem_t *instances; + na_elem_iter_t counter_iter; + + perf_data.timestamp = cna_child_get_cdtime(data); + + instances = na_elem_child(na_elem_child(data, "instances"), "instance-data"); + if (instances == NULL) { + ERROR("netapp plugin: cna_handle_wafl_data: " + "na_elem_child (\"instances\") failed " + "for host %s.", + hostname); + return (-1); + } + + plugin_inst = na_child_get_string(instances, "name"); + if (plugin_inst == NULL) { + ERROR("netapp plugin: cna_handle_wafl_data: " + "na_child_get_string (\"name\") failed " + "for host %s.", + hostname); + return (-1); + } + + /* Iterate over all counters */ + counter_iter = na_child_iterator(na_elem_child(instances, "counters")); + for (na_elem_t *counter = na_iterator_next(&counter_iter); counter != NULL; + counter = na_iterator_next(&counter_iter)) { + const char *name; + uint64_t value; + + name = na_child_get_string(counter, "name"); + if (name == NULL) + continue; + + value = na_child_get_uint64(counter, "value", UINT64_MAX); + if (value == UINT64_MAX) + continue; + + if (!strcmp(name, "name_cache_hit")) { + perf_data.name_cache_hit = value; + perf_data.flags |= HAVE_WAFL_NAME_CACHE_HIT; + } else if (!strcmp(name, "name_cache_miss")) { + perf_data.name_cache_miss = value; + perf_data.flags |= HAVE_WAFL_NAME_CACHE_MISS; + } else if (!strcmp(name, "find_dir_hit")) { + perf_data.find_dir_hit = value; + perf_data.flags |= HAVE_WAFL_FIND_DIR_HIT; + } else if (!strcmp(name, "find_dir_miss")) { + perf_data.find_dir_miss = value; + perf_data.flags |= HAVE_WAFL_FIND_DIR_MISS; + } else if (!strcmp(name, "buf_hash_hit")) { + perf_data.buf_hash_hit = value; + perf_data.flags |= HAVE_WAFL_BUF_HASH_HIT; + } else if (!strcmp(name, "buf_hash_miss")) { + perf_data.buf_hash_miss = value; + perf_data.flags |= HAVE_WAFL_BUF_HASH_MISS; + } else if (!strcmp(name, "inode_cache_hit")) { + perf_data.inode_cache_hit = value; + perf_data.flags |= HAVE_WAFL_INODE_CACHE_HIT; + } else if (!strcmp(name, "inode_cache_miss")) { + perf_data.inode_cache_miss = value; + perf_data.flags |= HAVE_WAFL_INODE_CACHE_MISS; + } else { + DEBUG("netapp plugin: cna_handle_wafl_data: " + "Found unexpected child: %s " + "for host %s.", + name, hostname); + } + } + + 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) /* {{{ */ -{ - na_elem_t *e; - - if (cw == NULL) - return (EINVAL); - - if (cw->query != NULL) - return (0); - - cw->query = na_elem_new("perf-object-get-instances"); - if (cw->query == NULL) - { - ERROR ("netapp plugin: na_elem_new failed."); - return (-1); - } - na_child_add_string (cw->query, "objectname", "wafl"); - - e = na_elem_new("counters"); - if (e == NULL) - { - na_elem_free (cw->query); - cw->query = NULL; - ERROR ("netapp plugin: na_elem_new failed."); - return (-1); - } - na_child_add_string(e, "counter", "name_cache_hit"); - na_child_add_string(e, "counter", "name_cache_miss"); - na_child_add_string(e, "counter", "find_dir_hit"); - na_child_add_string(e, "counter", "find_dir_miss"); - na_child_add_string(e, "counter", "buf_hash_hit"); - na_child_add_string(e, "counter", "buf_hash_miss"); - na_child_add_string(e, "counter", "inode_cache_hit"); - na_child_add_string(e, "counter", "inode_cache_miss"); - - na_child_add(cw->query, e); - - return (0); +static int cna_setup_wafl(cfg_wafl_t *cw) /* {{{ */ +{ + na_elem_t *e; + + if (cw == NULL) + return (EINVAL); + + if (cw->query != NULL) + return (0); + + cw->query = na_elem_new("perf-object-get-instances"); + if (cw->query == NULL) { + ERROR("netapp plugin: na_elem_new failed."); + return (-1); + } + na_child_add_string(cw->query, "objectname", "wafl"); + + e = na_elem_new("counters"); + if (e == NULL) { + na_elem_free(cw->query); + cw->query = NULL; + ERROR("netapp plugin: na_elem_new failed."); + return (-1); + } + na_child_add_string(e, "counter", "name_cache_hit"); + na_child_add_string(e, "counter", "name_cache_miss"); + na_child_add_string(e, "counter", "find_dir_hit"); + na_child_add_string(e, "counter", "find_dir_miss"); + na_child_add_string(e, "counter", "buf_hash_hit"); + na_child_add_string(e, "counter", "buf_hash_miss"); + na_child_add_string(e, "counter", "inode_cache_hit"); + na_child_add_string(e, "counter", "inode_cache_miss"); + + na_child_add(cw->query, e); + + return (0); } /* }}} int cna_setup_wafl */ -static int cna_query_wafl (host_config_t *host) /* {{{ */ +static int cna_query_wafl(host_config_t *host) /* {{{ */ { - na_elem_t *data; - int status; - cdtime_t now; - - if (host == NULL) - return (EINVAL); - - /* If WAFL was not configured, return without doing anything. */ - if (host->cfg_wafl == NULL) - return (0); - - now = cdtime (); - if ((host->cfg_wafl->interval.interval + host->cfg_wafl->interval.last_read) > now) - return (0); - - status = cna_setup_wafl (host->cfg_wafl); - if (status != 0) - return (status); - assert (host->cfg_wafl->query != NULL); - - data = na_server_invoke_elem(host->srv, host->cfg_wafl->query); - if (na_results_status (data) != NA_OK) - { - ERROR ("netapp plugin: cna_query_wafl: na_server_invoke_elem failed for host %s: %s", - host->name, na_results_reason (data)); - na_elem_free (data); - return (-1); - } - - status = cna_handle_wafl_data (host->name, host->cfg_wafl, data, - host->cfg_wafl->interval.interval); - - if (status == 0) - host->cfg_wafl->interval.last_read = now; - - na_elem_free (data); - return (status); + na_elem_t *data; + int status; + cdtime_t now; + + if (host == NULL) + return (EINVAL); + + /* If WAFL was not configured, return without doing anything. */ + if (host->cfg_wafl == NULL) + return (0); + + now = cdtime(); + if ((host->cfg_wafl->interval.interval + host->cfg_wafl->interval.last_read) > + now) + return (0); + + status = cna_setup_wafl(host->cfg_wafl); + if (status != 0) + return (status); + assert(host->cfg_wafl->query != NULL); + + data = na_server_invoke_elem(host->srv, host->cfg_wafl->query); + if (na_results_status(data) != NA_OK) { + ERROR("netapp plugin: cna_query_wafl: na_server_invoke_elem failed for " + "host %s: %s", + host->name, na_results_reason(data)); + na_elem_free(data); + return (-1); + } + + status = cna_handle_wafl_data(host->name, host->cfg_wafl, data, + host->cfg_wafl->interval.interval); + + if (status == 0) + host->cfg_wafl->interval.last_read = now; + + na_elem_free(data); + return (status); } /* }}} int cna_query_wafl */ /* Data corresponding to */ -static int cna_handle_disk_data (const char *hostname, /* {{{ */ - cfg_disk_t *cfg_disk, na_elem_t *data, cdtime_t interval) -{ - cdtime_t timestamp; - na_elem_t *instances; - na_elem_iter_t instance_iter; - disk_t *worst_disk = NULL; - - if ((cfg_disk == NULL) || (data == NULL)) - return (EINVAL); - - timestamp = cna_child_get_cdtime (data); - - instances = na_elem_child (data, "instances"); - if (instances == NULL) - { - ERROR ("netapp plugin: cna_handle_disk_data: " - "na_elem_child (\"instances\") failed " - "for host %s.", hostname); - return (-1); - } - - /* Iterate over all children */ - instance_iter = na_child_iterator (instances); - for (na_elem_t *instance = na_iterator_next (&instance_iter); - instance != NULL; - instance = na_iterator_next(&instance_iter)) - { - disk_t *old_data; - disk_t new_data = { 0 }; - - na_elem_iter_t counter_iterator; - - new_data.timestamp = timestamp; - new_data.disk_busy_percent = NAN; - - old_data = get_disk(cfg_disk, na_child_get_string (instance, "name")); - if (old_data == NULL) - continue; - - /* Look for the "disk_busy" and "base_for_disk_busy" counters */ - counter_iterator = na_child_iterator(na_elem_child(instance, "counters")); - for (na_elem_t *counter = na_iterator_next(&counter_iterator); - counter != NULL; - counter = na_iterator_next(&counter_iterator)) - { - const char *name; - uint64_t value; - - name = na_child_get_string(counter, "name"); - if (name == NULL) - continue; - - value = na_child_get_uint64(counter, "value", UINT64_MAX); - if (value == UINT64_MAX) - continue; - - if (strcmp(name, "disk_busy") == 0) - { - new_data.disk_busy = value; - new_data.flags |= HAVE_DISK_BUSY; - } - else if (strcmp(name, "base_for_disk_busy") == 0) - { - new_data.base_for_disk_busy = value; - new_data.flags |= HAVE_DISK_BASE; - } - else - { - DEBUG ("netapp plugin: cna_handle_disk_data: " - "Counter not handled: %s = %"PRIu64, - name, value); - } - } - - /* If all required counters are available and did not just wrap around, - * calculate the busy percentage. Otherwise, the value is initialized to - * NAN at the top of the for-loop. */ - if (HAS_ALL_FLAGS (old_data->flags, HAVE_DISK_BUSY | HAVE_DISK_BASE) - && HAS_ALL_FLAGS (new_data.flags, HAVE_DISK_BUSY | HAVE_DISK_BASE) - && (new_data.disk_busy >= old_data->disk_busy) - && (new_data.base_for_disk_busy > old_data->base_for_disk_busy)) - { - uint64_t busy_diff; - uint64_t base_diff; - - busy_diff = new_data.disk_busy - old_data->disk_busy; - base_diff = new_data.base_for_disk_busy - old_data->base_for_disk_busy; - - new_data.disk_busy_percent = 100.0 - * ((gauge_t) busy_diff) / ((gauge_t) base_diff); - } - - /* Clear HAVE_* flags */ - old_data->flags &= ~HAVE_DISK_ALL; - - /* Copy data */ - old_data->timestamp = new_data.timestamp; - old_data->disk_busy = new_data.disk_busy; - old_data->base_for_disk_busy = new_data.base_for_disk_busy; - old_data->disk_busy_percent = new_data.disk_busy_percent; - - /* Copy flags */ - old_data->flags |= (new_data.flags & HAVE_DISK_ALL); - - if ((worst_disk == NULL) - || (worst_disk->disk_busy_percent < old_data->disk_busy_percent)) - worst_disk = old_data; - } /* for (all disks) */ - - if ((cfg_disk->flags & CFG_DISK_BUSIEST) && (worst_disk != NULL)) - submit_double (hostname, "system", "percent", "disk_busy", - worst_disk->disk_busy_percent, timestamp, interval); - - return (0); +static int cna_handle_disk_data(const char *hostname, /* {{{ */ + cfg_disk_t *cfg_disk, na_elem_t *data, + cdtime_t interval) { + cdtime_t timestamp; + na_elem_t *instances; + na_elem_iter_t instance_iter; + disk_t *worst_disk = NULL; + + if ((cfg_disk == NULL) || (data == NULL)) + return (EINVAL); + + timestamp = cna_child_get_cdtime(data); + + instances = na_elem_child(data, "instances"); + if (instances == NULL) { + ERROR("netapp plugin: cna_handle_disk_data: " + "na_elem_child (\"instances\") failed " + "for host %s.", + hostname); + return (-1); + } + + /* Iterate over all children */ + instance_iter = na_child_iterator(instances); + for (na_elem_t *instance = na_iterator_next(&instance_iter); instance != NULL; + instance = na_iterator_next(&instance_iter)) { + disk_t *old_data; + disk_t new_data = {0}; + + na_elem_iter_t counter_iterator; + + new_data.timestamp = timestamp; + new_data.disk_busy_percent = NAN; + + old_data = get_disk(cfg_disk, na_child_get_string(instance, "name")); + if (old_data == NULL) + continue; + + /* Look for the "disk_busy" and "base_for_disk_busy" counters */ + counter_iterator = na_child_iterator(na_elem_child(instance, "counters")); + for (na_elem_t *counter = na_iterator_next(&counter_iterator); + counter != NULL; counter = na_iterator_next(&counter_iterator)) { + const char *name; + uint64_t value; + + name = na_child_get_string(counter, "name"); + if (name == NULL) + continue; + + value = na_child_get_uint64(counter, "value", UINT64_MAX); + if (value == UINT64_MAX) + continue; + + if (strcmp(name, "disk_busy") == 0) { + new_data.disk_busy = value; + new_data.flags |= HAVE_DISK_BUSY; + } else if (strcmp(name, "base_for_disk_busy") == 0) { + new_data.base_for_disk_busy = value; + new_data.flags |= HAVE_DISK_BASE; + } else { + DEBUG("netapp plugin: cna_handle_disk_data: " + "Counter not handled: %s = %" PRIu64, + name, value); + } + } + + /* If all required counters are available and did not just wrap around, + * calculate the busy percentage. Otherwise, the value is initialized to + * NAN at the top of the for-loop. */ + if (HAS_ALL_FLAGS(old_data->flags, HAVE_DISK_BUSY | HAVE_DISK_BASE) && + HAS_ALL_FLAGS(new_data.flags, HAVE_DISK_BUSY | HAVE_DISK_BASE) && + (new_data.disk_busy >= old_data->disk_busy) && + (new_data.base_for_disk_busy > old_data->base_for_disk_busy)) { + uint64_t busy_diff; + uint64_t base_diff; + + busy_diff = new_data.disk_busy - old_data->disk_busy; + base_diff = new_data.base_for_disk_busy - old_data->base_for_disk_busy; + + new_data.disk_busy_percent = + 100.0 * ((gauge_t)busy_diff) / ((gauge_t)base_diff); + } + + /* Clear HAVE_* flags */ + old_data->flags &= ~HAVE_DISK_ALL; + + /* Copy data */ + old_data->timestamp = new_data.timestamp; + old_data->disk_busy = new_data.disk_busy; + old_data->base_for_disk_busy = new_data.base_for_disk_busy; + old_data->disk_busy_percent = new_data.disk_busy_percent; + + /* Copy flags */ + old_data->flags |= (new_data.flags & HAVE_DISK_ALL); + + if ((worst_disk == NULL) || + (worst_disk->disk_busy_percent < old_data->disk_busy_percent)) + worst_disk = old_data; + } /* for (all disks) */ + + if ((cfg_disk->flags & CFG_DISK_BUSIEST) && (worst_disk != NULL)) + submit_double(hostname, "system", "percent", "disk_busy", + worst_disk->disk_busy_percent, timestamp, interval); + + return (0); } /* }}} int cna_handle_disk_data */ -static int cna_setup_disk (cfg_disk_t *cd) /* {{{ */ +static int cna_setup_disk(cfg_disk_t *cd) /* {{{ */ { - na_elem_t *e; - - if (cd == NULL) - return (EINVAL); - - if (cd->query != NULL) - return (0); - - cd->query = na_elem_new ("perf-object-get-instances"); - if (cd->query == NULL) - { - ERROR ("netapp plugin: na_elem_new failed."); - return (-1); - } - na_child_add_string (cd->query, "objectname", "disk"); - - e = na_elem_new("counters"); - if (e == NULL) - { - na_elem_free (cd->query); - cd->query = NULL; - ERROR ("netapp plugin: na_elem_new failed."); - return (-1); - } - na_child_add_string(e, "counter", "disk_busy"); - na_child_add_string(e, "counter", "base_for_disk_busy"); - na_child_add(cd->query, e); - - return (0); + na_elem_t *e; + + if (cd == NULL) + return (EINVAL); + + if (cd->query != NULL) + return (0); + + cd->query = na_elem_new("perf-object-get-instances"); + if (cd->query == NULL) { + ERROR("netapp plugin: na_elem_new failed."); + return (-1); + } + na_child_add_string(cd->query, "objectname", "disk"); + + e = na_elem_new("counters"); + if (e == NULL) { + na_elem_free(cd->query); + cd->query = NULL; + ERROR("netapp plugin: na_elem_new failed."); + return (-1); + } + na_child_add_string(e, "counter", "disk_busy"); + na_child_add_string(e, "counter", "base_for_disk_busy"); + na_child_add(cd->query, e); + + return (0); } /* }}} int cna_setup_disk */ -static int cna_query_disk (host_config_t *host) /* {{{ */ +static int cna_query_disk(host_config_t *host) /* {{{ */ { - na_elem_t *data; - int status; - cdtime_t now; - - if (host == NULL) - return (EINVAL); - - /* If the user did not configure disk statistics, return without doing - * anything. */ - if (host->cfg_disk == NULL) - return (0); - - now = cdtime (); - if ((host->cfg_disk->interval.interval + host->cfg_disk->interval.last_read) > now) - return (0); - - status = cna_setup_disk (host->cfg_disk); - if (status != 0) - return (status); - assert (host->cfg_disk->query != NULL); - - data = na_server_invoke_elem(host->srv, host->cfg_disk->query); - if (na_results_status (data) != NA_OK) - { - ERROR ("netapp plugin: cna_query_disk: na_server_invoke_elem failed for host %s: %s", - host->name, na_results_reason (data)); - na_elem_free (data); - return (-1); - } - - status = cna_handle_disk_data (host->name, host->cfg_disk, data, - host->cfg_disk->interval.interval); - - if (status == 0) - host->cfg_disk->interval.last_read = now; - - na_elem_free (data); - return (status); + na_elem_t *data; + int status; + cdtime_t now; + + if (host == NULL) + return (EINVAL); + + /* If the user did not configure disk statistics, return without doing + * anything. */ + if (host->cfg_disk == NULL) + return (0); + + now = cdtime(); + if ((host->cfg_disk->interval.interval + host->cfg_disk->interval.last_read) > + now) + return (0); + + status = cna_setup_disk(host->cfg_disk); + if (status != 0) + return (status); + assert(host->cfg_disk->query != NULL); + + data = na_server_invoke_elem(host->srv, host->cfg_disk->query); + if (na_results_status(data) != NA_OK) { + ERROR("netapp plugin: cna_query_disk: na_server_invoke_elem failed for " + "host %s: %s", + host->name, na_results_reason(data)); + na_elem_free(data); + return (-1); + } + + status = cna_handle_disk_data(host->name, host->cfg_disk, data, + host->cfg_disk->interval.interval); + + if (status == 0) + host->cfg_disk->interval.last_read = now; + + na_elem_free(data); + return (status); } /* }}} int cna_query_disk */ /* Data corresponding to */ -static int cna_handle_volume_perf_data (const char *hostname, /* {{{ */ - cfg_volume_perf_t *cvp, na_elem_t *data, cdtime_t interval) -{ - cdtime_t timestamp; - na_elem_t *elem_instances; - na_elem_iter_t iter_instances; - - timestamp = cna_child_get_cdtime (data); - - elem_instances = na_elem_child(data, "instances"); - if (elem_instances == NULL) - { - ERROR ("netapp plugin: handle_volume_perf_data: " - "na_elem_child (\"instances\") failed " - "for host %s.", hostname); - return (-1); - } - - iter_instances = na_child_iterator (elem_instances); - for (na_elem_t *elem_instance = na_iterator_next(&iter_instances); - elem_instance != NULL; - elem_instance = na_iterator_next(&iter_instances)) - { - const char *name; - - data_volume_perf_t perf_data = { 0 }; - data_volume_perf_t *v; - - na_elem_t *elem_counters; - na_elem_iter_t iter_counters; - - perf_data.timestamp = timestamp; - - name = na_child_get_string (elem_instance, "name"); - if (name == NULL) - continue; - - /* get_volume_perf may return NULL if this volume is to be ignored. */ - v = get_volume_perf (cvp, name); - if (v == NULL) - continue; - - elem_counters = na_elem_child (elem_instance, "counters"); - if (elem_counters == NULL) - continue; - - iter_counters = na_child_iterator (elem_counters); - for (na_elem_t *elem_counter = na_iterator_next(&iter_counters); - elem_counter != NULL; - elem_counter = na_iterator_next(&iter_counters)) - { - const char *name; - uint64_t value; - - name = na_child_get_string (elem_counter, "name"); - if (name == NULL) - continue; - - value = na_child_get_uint64 (elem_counter, "value", UINT64_MAX); - if (value == UINT64_MAX) - continue; - - if (!strcmp(name, "read_data")) { - perf_data.read_bytes = value; - perf_data.flags |= HAVE_VOLUME_PERF_BYTES_READ; - } else if (!strcmp(name, "write_data")) { - perf_data.write_bytes = value; - perf_data.flags |= HAVE_VOLUME_PERF_BYTES_WRITE; - } else if (!strcmp(name, "read_ops")) { - perf_data.read_ops = value; - perf_data.flags |= HAVE_VOLUME_PERF_OPS_READ; - } else if (!strcmp(name, "write_ops")) { - perf_data.write_ops = value; - perf_data.flags |= HAVE_VOLUME_PERF_OPS_WRITE; - } else if (!strcmp(name, "read_latency")) { - perf_data.read_latency = value; - perf_data.flags |= HAVE_VOLUME_PERF_LATENCY_READ; - } else if (!strcmp(name, "write_latency")) { - perf_data.write_latency = value; - perf_data.flags |= HAVE_VOLUME_PERF_LATENCY_WRITE; - } - } /* for (elem_counter) */ - - submit_volume_perf_data (hostname, v, &perf_data, interval); - } /* for (volume) */ - - return (0); +static int cna_handle_volume_perf_data(const char *hostname, /* {{{ */ + cfg_volume_perf_t *cvp, na_elem_t *data, + cdtime_t interval) { + cdtime_t timestamp; + na_elem_t *elem_instances; + na_elem_iter_t iter_instances; + + timestamp = cna_child_get_cdtime(data); + + elem_instances = na_elem_child(data, "instances"); + if (elem_instances == NULL) { + ERROR("netapp plugin: handle_volume_perf_data: " + "na_elem_child (\"instances\") failed " + "for host %s.", + hostname); + return (-1); + } + + iter_instances = na_child_iterator(elem_instances); + for (na_elem_t *elem_instance = na_iterator_next(&iter_instances); + elem_instance != NULL; + elem_instance = na_iterator_next(&iter_instances)) { + const char *name; + + data_volume_perf_t perf_data = {0}; + data_volume_perf_t *v; + + na_elem_t *elem_counters; + na_elem_iter_t iter_counters; + + perf_data.timestamp = timestamp; + + name = na_child_get_string(elem_instance, "name"); + if (name == NULL) + continue; + + /* get_volume_perf may return NULL if this volume is to be ignored. */ + v = get_volume_perf(cvp, name); + if (v == NULL) + continue; + + elem_counters = na_elem_child(elem_instance, "counters"); + if (elem_counters == NULL) + continue; + + iter_counters = na_child_iterator(elem_counters); + for (na_elem_t *elem_counter = na_iterator_next(&iter_counters); + elem_counter != NULL; + elem_counter = na_iterator_next(&iter_counters)) { + const char *name; + uint64_t value; + + name = na_child_get_string(elem_counter, "name"); + if (name == NULL) + continue; + + value = na_child_get_uint64(elem_counter, "value", UINT64_MAX); + if (value == UINT64_MAX) + continue; + + if (!strcmp(name, "read_data")) { + perf_data.read_bytes = value; + perf_data.flags |= HAVE_VOLUME_PERF_BYTES_READ; + } else if (!strcmp(name, "write_data")) { + perf_data.write_bytes = value; + perf_data.flags |= HAVE_VOLUME_PERF_BYTES_WRITE; + } else if (!strcmp(name, "read_ops")) { + perf_data.read_ops = value; + perf_data.flags |= HAVE_VOLUME_PERF_OPS_READ; + } else if (!strcmp(name, "write_ops")) { + perf_data.write_ops = value; + perf_data.flags |= HAVE_VOLUME_PERF_OPS_WRITE; + } else if (!strcmp(name, "read_latency")) { + perf_data.read_latency = value; + perf_data.flags |= HAVE_VOLUME_PERF_LATENCY_READ; + } else if (!strcmp(name, "write_latency")) { + perf_data.write_latency = value; + perf_data.flags |= HAVE_VOLUME_PERF_LATENCY_WRITE; + } + } /* for (elem_counter) */ + + submit_volume_perf_data(hostname, v, &perf_data, interval); + } /* for (volume) */ + + return (0); } /* }}} int cna_handle_volume_perf_data */ -static int cna_setup_volume_perf (cfg_volume_perf_t *cd) /* {{{ */ -{ - na_elem_t *e; - - if (cd == NULL) - return (EINVAL); - - if (cd->query != NULL) - return (0); - - cd->query = na_elem_new ("perf-object-get-instances"); - if (cd->query == NULL) - { - ERROR ("netapp plugin: na_elem_new failed."); - return (-1); - } - na_child_add_string (cd->query, "objectname", "volume"); - - e = na_elem_new("counters"); - if (e == NULL) - { - na_elem_free (cd->query); - cd->query = NULL; - ERROR ("netapp plugin: na_elem_new failed."); - return (-1); - } - na_child_add_string(e, "counter", "read_ops"); - na_child_add_string(e, "counter", "write_ops"); - na_child_add_string(e, "counter", "read_data"); - na_child_add_string(e, "counter", "write_data"); - na_child_add_string(e, "counter", "read_latency"); - na_child_add_string(e, "counter", "write_latency"); - na_child_add(cd->query, e); - - return (0); +static int cna_setup_volume_perf(cfg_volume_perf_t *cd) /* {{{ */ +{ + na_elem_t *e; + + if (cd == NULL) + return (EINVAL); + + if (cd->query != NULL) + return (0); + + cd->query = na_elem_new("perf-object-get-instances"); + if (cd->query == NULL) { + ERROR("netapp plugin: na_elem_new failed."); + return (-1); + } + na_child_add_string(cd->query, "objectname", "volume"); + + e = na_elem_new("counters"); + if (e == NULL) { + na_elem_free(cd->query); + cd->query = NULL; + ERROR("netapp plugin: na_elem_new failed."); + return (-1); + } + na_child_add_string(e, "counter", "read_ops"); + na_child_add_string(e, "counter", "write_ops"); + na_child_add_string(e, "counter", "read_data"); + na_child_add_string(e, "counter", "write_data"); + na_child_add_string(e, "counter", "read_latency"); + na_child_add_string(e, "counter", "write_latency"); + na_child_add(cd->query, e); + + return (0); } /* }}} int cna_setup_volume_perf */ -static int cna_query_volume_perf (host_config_t *host) /* {{{ */ +static int cna_query_volume_perf(host_config_t *host) /* {{{ */ { - na_elem_t *data; - int status; - cdtime_t now; - - if (host == NULL) - return (EINVAL); - - /* If the user did not configure volume performance statistics, return - * without doing anything. */ - if (host->cfg_volume_perf == NULL) - return (0); - - now = cdtime (); - if ((host->cfg_volume_perf->interval.interval + host->cfg_volume_perf->interval.last_read) > now) - return (0); - - status = cna_setup_volume_perf (host->cfg_volume_perf); - if (status != 0) - return (status); - assert (host->cfg_volume_perf->query != NULL); - - data = na_server_invoke_elem (host->srv, host->cfg_volume_perf->query); - if (na_results_status (data) != NA_OK) - { - ERROR ("netapp plugin: cna_query_volume_perf: na_server_invoke_elem failed for host %s: %s", - host->name, na_results_reason (data)); - na_elem_free (data); - return (-1); - } - - status = cna_handle_volume_perf_data (host->name, host->cfg_volume_perf, data, - host->cfg_volume_perf->interval.interval); - - if (status == 0) - host->cfg_volume_perf->interval.last_read = now; - - na_elem_free (data); - return (status); + na_elem_t *data; + int status; + cdtime_t now; + + if (host == NULL) + return (EINVAL); + + /* If the user did not configure volume performance statistics, return + * without doing anything. */ + if (host->cfg_volume_perf == NULL) + return (0); + + now = cdtime(); + if ((host->cfg_volume_perf->interval.interval + + host->cfg_volume_perf->interval.last_read) > now) + return (0); + + status = cna_setup_volume_perf(host->cfg_volume_perf); + if (status != 0) + return (status); + assert(host->cfg_volume_perf->query != NULL); + + data = na_server_invoke_elem(host->srv, host->cfg_volume_perf->query); + if (na_results_status(data) != NA_OK) { + ERROR("netapp plugin: cna_query_volume_perf: na_server_invoke_elem failed " + "for host %s: %s", + host->name, na_results_reason(data)); + na_elem_free(data); + return (-1); + } + + status = + cna_handle_volume_perf_data(host->name, host->cfg_volume_perf, data, + host->cfg_volume_perf->interval.interval); + + if (status == 0) + host->cfg_volume_perf->interval.last_read = now; + + na_elem_free(data); + return (status); } /* }}} int cna_query_volume_perf */ /* Data corresponding to */ -static int cna_submit_volume_usage_data (const char *hostname, /* {{{ */ - cfg_volume_usage_t *cfg_volume, int interval) -{ - for (data_volume_usage_t *v = cfg_volume->volumes; v != NULL; v = v->next) - { - char plugin_instance[DATA_MAX_NAME_LEN]; - - uint64_t norm_used = v->norm_used; - uint64_t norm_free = v->norm_free; - uint64_t sis_saved = v->sis_saved; - uint64_t compress_saved = v->compress_saved; - uint64_t dedup_saved = v->dedup_saved; - uint64_t snap_reserve_used = 0; - uint64_t snap_reserve_free = v->snap_reserved; - uint64_t snap_norm_used = v->snap_used; - - ssnprintf (plugin_instance, sizeof (plugin_instance), - "volume-%s", v->name); - - if (HAS_ALL_FLAGS (v->flags, HAVE_VOLUME_USAGE_SNAP_USED | HAVE_VOLUME_USAGE_SNAP_RSVD)) { - if (v->snap_reserved > v->snap_used) { - snap_reserve_free = v->snap_reserved - v->snap_used; - snap_reserve_used = v->snap_used; - snap_norm_used = 0; - } else { - snap_reserve_free = 0; - snap_reserve_used = v->snap_reserved; - snap_norm_used = v->snap_used - v->snap_reserved; - } - } - - /* The space used by snapshots but not reserved for them is included in - * both, norm_used and snap_norm_used. If possible, subtract this here. */ - if (HAS_ALL_FLAGS (v->flags, HAVE_VOLUME_USAGE_NORM_USED | HAVE_VOLUME_USAGE_SNAP_USED)) - { - if (norm_used >= snap_norm_used) - norm_used -= snap_norm_used; - else - { - ERROR ("netapp plugin: (norm_used = %"PRIu64") < (snap_norm_used = " - "%"PRIu64") for host %s. Invalidating both.", - norm_used, snap_norm_used, hostname); - v->flags &= ~(HAVE_VOLUME_USAGE_NORM_USED | HAVE_VOLUME_USAGE_SNAP_USED); - } - } - - 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, 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, interval); - - if (HAS_ALL_FLAGS (v->flags, HAVE_VOLUME_USAGE_COMPRESS_SAVED)) - submit_double (hostname, /* plugin instance = */ plugin_instance, - "df_complex", "compression_saved", - (double) compress_saved, /* timestamp = */ 0, interval); - - if (HAS_ALL_FLAGS (v->flags, HAVE_VOLUME_USAGE_DEDUP_SAVED)) - submit_double (hostname, /* plugin instance = */ plugin_instance, - "df_complex", "dedup_saved", - (double) dedup_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, 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, 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, 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, interval); - - /* Clear all the HAVE_* flags */ - v->flags &= ~HAVE_VOLUME_USAGE_ALL; - } /* for (v = cfg_volume->volumes) */ - - return (0); +static int cna_submit_volume_usage_data(const char *hostname, /* {{{ */ + cfg_volume_usage_t *cfg_volume, + int interval) { + for (data_volume_usage_t *v = cfg_volume->volumes; v != NULL; v = v->next) { + char plugin_instance[DATA_MAX_NAME_LEN]; + + uint64_t norm_used = v->norm_used; + uint64_t norm_free = v->norm_free; + uint64_t sis_saved = v->sis_saved; + uint64_t compress_saved = v->compress_saved; + uint64_t dedup_saved = v->dedup_saved; + uint64_t snap_reserve_used = 0; + uint64_t snap_reserve_free = v->snap_reserved; + uint64_t snap_norm_used = v->snap_used; + + ssnprintf(plugin_instance, sizeof(plugin_instance), "volume-%s", v->name); + + if (HAS_ALL_FLAGS(v->flags, HAVE_VOLUME_USAGE_SNAP_USED | + HAVE_VOLUME_USAGE_SNAP_RSVD)) { + if (v->snap_reserved > v->snap_used) { + snap_reserve_free = v->snap_reserved - v->snap_used; + snap_reserve_used = v->snap_used; + snap_norm_used = 0; + } else { + snap_reserve_free = 0; + snap_reserve_used = v->snap_reserved; + snap_norm_used = v->snap_used - v->snap_reserved; + } + } + + /* The space used by snapshots but not reserved for them is included in + * both, norm_used and snap_norm_used. If possible, subtract this here. */ + if (HAS_ALL_FLAGS(v->flags, HAVE_VOLUME_USAGE_NORM_USED | + HAVE_VOLUME_USAGE_SNAP_USED)) { + if (norm_used >= snap_norm_used) + norm_used -= snap_norm_used; + else { + ERROR("netapp plugin: (norm_used = %" PRIu64 ") < (snap_norm_used = " + "%" PRIu64 ") for host %s. Invalidating both.", + norm_used, snap_norm_used, hostname); + v->flags &= + ~(HAVE_VOLUME_USAGE_NORM_USED | HAVE_VOLUME_USAGE_SNAP_USED); + } + } + + 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, 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, interval); + + if (HAS_ALL_FLAGS(v->flags, HAVE_VOLUME_USAGE_COMPRESS_SAVED)) + submit_double(hostname, /* plugin instance = */ plugin_instance, + "df_complex", "compression_saved", (double)compress_saved, + /* timestamp = */ 0, interval); + + if (HAS_ALL_FLAGS(v->flags, HAVE_VOLUME_USAGE_DEDUP_SAVED)) + submit_double(hostname, /* plugin instance = */ plugin_instance, + "df_complex", "dedup_saved", (double)dedup_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, 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, 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, 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, interval); + + /* Clear all the HAVE_* flags */ + v->flags &= ~HAVE_VOLUME_USAGE_ALL; + } /* for (v = cfg_volume->volumes) */ + + return (0); } /* }}} int cna_submit_volume_usage_data */ /* Switch the state of a volume between online and offline and send out a * notification. */ -static int cna_change_volume_status (const char *hostname, /* {{{ */ - data_volume_usage_t *v) -{ - notification_t n = { 0 }; - - 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)); - - if ((v->flags & IS_VOLUME_USAGE_OFFLINE) != 0) { - n.severity = NOTIF_OKAY; - ssnprintf (n.message, sizeof (n.message), - "Volume %s is now online.", v->name); - v->flags &= ~IS_VOLUME_USAGE_OFFLINE; - } else { - n.severity = NOTIF_WARNING; - ssnprintf (n.message, sizeof (n.message), - "Volume %s is now offline.", v->name); - v->flags |= IS_VOLUME_USAGE_OFFLINE; - } - - return (plugin_dispatch_notification (&n)); +static int cna_change_volume_status(const char *hostname, /* {{{ */ + data_volume_usage_t *v) { + notification_t n = {0}; + + 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)); + + if ((v->flags & IS_VOLUME_USAGE_OFFLINE) != 0) { + n.severity = NOTIF_OKAY; + ssnprintf(n.message, sizeof(n.message), "Volume %s is now online.", + v->name); + v->flags &= ~IS_VOLUME_USAGE_OFFLINE; + } else { + n.severity = NOTIF_WARNING; + ssnprintf(n.message, sizeof(n.message), "Volume %s is now offline.", + v->name); + v->flags |= IS_VOLUME_USAGE_OFFLINE; + } + + return (plugin_dispatch_notification(&n)); } /* }}} int cna_change_volume_status */ static void cna_handle_volume_snap_usage(const host_config_t *host, /* {{{ */ - data_volume_usage_t *v) -{ - uint64_t snap_used = 0, value; - na_elem_t *data, *elem_snapshots; - na_elem_iter_t iter_snap; - - data = na_server_invoke_elem(host->srv, v->snap_query); - if (na_results_status(data) != NA_OK) - { - if (na_results_errno(data) == EVOLUMEOFFLINE) { - if ((v->flags & IS_VOLUME_USAGE_OFFLINE) == 0) - cna_change_volume_status (host->name, v); - } else { - ERROR ("netapp plugin: cna_handle_volume_snap_usage: na_server_invoke_elem for " - "volume \"%s\" on host %s failed with error %d: %s", v->name, - host->name, na_results_errno(data), na_results_reason(data)); - } - na_elem_free(data); - return; - } - - if ((v->flags & IS_VOLUME_USAGE_OFFLINE) != 0) - cna_change_volume_status (host->name, v); - - elem_snapshots = na_elem_child (data, "snapshots"); - if (elem_snapshots == NULL) - { - ERROR ("netapp plugin: cna_handle_volume_snap_usage: " - "na_elem_child (\"snapshots\") failed " - "for host %s.", host->name); - na_elem_free(data); - return; - } - - iter_snap = na_child_iterator (elem_snapshots); - for (na_elem_t *elem_snap = na_iterator_next (&iter_snap); - elem_snap != NULL; - elem_snap = na_iterator_next (&iter_snap)) - { - value = na_child_get_uint64(elem_snap, "cumulative-total", 0); - /* "cumulative-total" is the total size of the oldest snapshot plus all - * newer ones in blocks (1KB). We therefore are looking for the highest - * number of all snapshots - that's the size required for the snapshots. */ - if (value > snap_used) - snap_used = value; - } - na_elem_free (data); - /* snap_used is in 1024 byte blocks */ - v->snap_used = snap_used * 1024; - v->flags |= HAVE_VOLUME_USAGE_SNAP_USED; + data_volume_usage_t *v) { + uint64_t snap_used = 0, value; + na_elem_t *data, *elem_snapshots; + na_elem_iter_t iter_snap; + + data = na_server_invoke_elem(host->srv, v->snap_query); + if (na_results_status(data) != NA_OK) { + if (na_results_errno(data) == EVOLUMEOFFLINE) { + if ((v->flags & IS_VOLUME_USAGE_OFFLINE) == 0) + cna_change_volume_status(host->name, v); + } else { + ERROR("netapp plugin: cna_handle_volume_snap_usage: " + "na_server_invoke_elem for " + "volume \"%s\" on host %s failed with error %d: %s", + v->name, host->name, na_results_errno(data), + na_results_reason(data)); + } + na_elem_free(data); + return; + } + + if ((v->flags & IS_VOLUME_USAGE_OFFLINE) != 0) + cna_change_volume_status(host->name, v); + + elem_snapshots = na_elem_child(data, "snapshots"); + if (elem_snapshots == NULL) { + ERROR("netapp plugin: cna_handle_volume_snap_usage: " + "na_elem_child (\"snapshots\") failed " + "for host %s.", + host->name); + na_elem_free(data); + return; + } + + iter_snap = na_child_iterator(elem_snapshots); + for (na_elem_t *elem_snap = na_iterator_next(&iter_snap); elem_snap != NULL; + elem_snap = na_iterator_next(&iter_snap)) { + value = na_child_get_uint64(elem_snap, "cumulative-total", 0); + /* "cumulative-total" is the total size of the oldest snapshot plus all + * newer ones in blocks (1KB). We therefore are looking for the highest + * number of all snapshots - that's the size required for the snapshots. */ + if (value > snap_used) + snap_used = value; + } + na_elem_free(data); + /* snap_used is in 1024 byte blocks */ + v->snap_used = snap_used * 1024; + v->flags |= HAVE_VOLUME_USAGE_SNAP_USED; } /* }}} void cna_handle_volume_snap_usage */ -static void cna_handle_volume_sis_data (const host_config_t *host, /* {{{ */ - data_volume_usage_t *v, na_elem_t *sis) -{ - const char *sis_state; - uint64_t sis_saved_reported; - - if (na_elem_child(sis, "sis-info")) - sis = na_elem_child(sis, "sis-info"); - - sis_state = na_child_get_string(sis, "state"); - if (sis_state == NULL) - return; - - /* If SIS is not enabled, there's nothing left to do for this volume. */ - if (strcmp ("enabled", sis_state) != 0) - return; - - sis_saved_reported = na_child_get_uint64(sis, "size-saved", UINT64_MAX); - if (sis_saved_reported == UINT64_MAX) - return; - - /* size-saved is actually a 32 bit number, so ... time for some guesswork. */ - if ((sis_saved_reported >> 32) != 0) { - /* In case they ever fix this bug. */ - v->sis_saved = sis_saved_reported; - v->flags |= HAVE_VOLUME_USAGE_SIS_SAVED; - } else { /* really hacky work-around code. {{{ */ - uint64_t sis_saved_percent; - uint64_t sis_saved_guess; - uint64_t overflow_guess; - uint64_t guess1, guess2, guess3; - - /* Check if we have v->norm_used. Without it, we cannot calculate - * sis_saved_guess. */ - if ((v->flags & HAVE_VOLUME_USAGE_NORM_USED) == 0) - return; - - sis_saved_percent = na_child_get_uint64(sis, "percentage-saved", UINT64_MAX); - if (sis_saved_percent > 100) - return; - - /* The "size-saved" value is a 32bit unsigned integer. This is a bug and - * will hopefully be fixed in later versions. To work around the bug, try - * to figure out how often the 32bit integer wrapped around by using the - * "percentage-saved" value. Because the percentage is in the range - * [0-100], this should work as long as the saved space does not exceed - * 400 GBytes. */ - /* percentage-saved = size-saved / (size-saved + size-used) */ - if (sis_saved_percent < 100) - sis_saved_guess = v->norm_used * sis_saved_percent / (100 - sis_saved_percent); - else - sis_saved_guess = v->norm_used; - - overflow_guess = sis_saved_guess >> 32; - guess1 = overflow_guess ? ((overflow_guess - 1) << 32) + sis_saved_reported : sis_saved_reported; - guess2 = (overflow_guess << 32) + sis_saved_reported; - guess3 = ((overflow_guess + 1) << 32) + sis_saved_reported; - - if (sis_saved_guess < guess2) { - if ((sis_saved_guess - guess1) < (guess2 - sis_saved_guess)) - v->sis_saved = guess1; - else - v->sis_saved = guess2; - } else { - if ((sis_saved_guess - guess2) < (guess3 - sis_saved_guess)) - v->sis_saved = guess2; - else - v->sis_saved = guess3; - } - v->flags |= HAVE_VOLUME_USAGE_SIS_SAVED; - } /* }}} end of 32-bit workaround */ +static void cna_handle_volume_sis_data(const host_config_t *host, /* {{{ */ + data_volume_usage_t *v, na_elem_t *sis) { + const char *sis_state; + uint64_t sis_saved_reported; + + if (na_elem_child(sis, "sis-info")) + sis = na_elem_child(sis, "sis-info"); + + sis_state = na_child_get_string(sis, "state"); + if (sis_state == NULL) + return; + + /* If SIS is not enabled, there's nothing left to do for this volume. */ + if (strcmp("enabled", sis_state) != 0) + return; + + sis_saved_reported = na_child_get_uint64(sis, "size-saved", UINT64_MAX); + if (sis_saved_reported == UINT64_MAX) + return; + + /* size-saved is actually a 32 bit number, so ... time for some guesswork. */ + if ((sis_saved_reported >> 32) != 0) { + /* In case they ever fix this bug. */ + v->sis_saved = sis_saved_reported; + v->flags |= HAVE_VOLUME_USAGE_SIS_SAVED; + } else { /* really hacky work-around code. {{{ */ + uint64_t sis_saved_percent; + uint64_t sis_saved_guess; + uint64_t overflow_guess; + uint64_t guess1, guess2, guess3; + + /* Check if we have v->norm_used. Without it, we cannot calculate + * sis_saved_guess. */ + if ((v->flags & HAVE_VOLUME_USAGE_NORM_USED) == 0) + return; + + sis_saved_percent = + na_child_get_uint64(sis, "percentage-saved", UINT64_MAX); + if (sis_saved_percent > 100) + return; + + /* The "size-saved" value is a 32bit unsigned integer. This is a bug and + * will hopefully be fixed in later versions. To work around the bug, try + * to figure out how often the 32bit integer wrapped around by using the + * "percentage-saved" value. Because the percentage is in the range + * [0-100], this should work as long as the saved space does not exceed + * 400 GBytes. */ + /* percentage-saved = size-saved / (size-saved + size-used) */ + if (sis_saved_percent < 100) + sis_saved_guess = + v->norm_used * sis_saved_percent / (100 - sis_saved_percent); + else + sis_saved_guess = v->norm_used; + + overflow_guess = sis_saved_guess >> 32; + guess1 = overflow_guess ? ((overflow_guess - 1) << 32) + sis_saved_reported + : sis_saved_reported; + guess2 = (overflow_guess << 32) + sis_saved_reported; + guess3 = ((overflow_guess + 1) << 32) + sis_saved_reported; + + if (sis_saved_guess < guess2) { + if ((sis_saved_guess - guess1) < (guess2 - sis_saved_guess)) + v->sis_saved = guess1; + else + v->sis_saved = guess2; + } else { + if ((sis_saved_guess - guess2) < (guess3 - sis_saved_guess)) + v->sis_saved = guess2; + else + v->sis_saved = guess3; + } + v->flags |= HAVE_VOLUME_USAGE_SIS_SAVED; + } /* }}} end of 32-bit workaround */ } /* }}} void cna_handle_volume_sis_data */ /* ONTAP >= 8.1 uses SIS for managing dedup and compression */ -static void cna_handle_volume_sis_saved (const host_config_t *host, /* {{{ */ - data_volume_usage_t *v, na_elem_t *sis) -{ - uint64_t saved; - - if (na_elem_child(sis, "sis-info")) - sis = na_elem_child(sis, "sis-info"); - - saved = na_child_get_uint64(sis, "compress-saved", UINT64_MAX); - if (saved != UINT64_MAX) { - v->compress_saved = saved; - v->flags |= HAVE_VOLUME_USAGE_COMPRESS_SAVED; - } - - saved = na_child_get_uint64(sis, "dedup-saved", UINT64_MAX); - if (saved != UINT64_MAX) { - v->dedup_saved = saved; - v->flags |= HAVE_VOLUME_USAGE_DEDUP_SAVED; - } +static void cna_handle_volume_sis_saved(const host_config_t *host, /* {{{ */ + data_volume_usage_t *v, + na_elem_t *sis) { + uint64_t saved; + + if (na_elem_child(sis, "sis-info")) + sis = na_elem_child(sis, "sis-info"); + + saved = na_child_get_uint64(sis, "compress-saved", UINT64_MAX); + if (saved != UINT64_MAX) { + v->compress_saved = saved; + v->flags |= HAVE_VOLUME_USAGE_COMPRESS_SAVED; + } + + saved = na_child_get_uint64(sis, "dedup-saved", UINT64_MAX); + if (saved != UINT64_MAX) { + v->dedup_saved = saved; + v->flags |= HAVE_VOLUME_USAGE_DEDUP_SAVED; + } } /* }}} void cna_handle_volume_sis_saved */ -static int cna_handle_volume_usage_data (const host_config_t *host, /* {{{ */ - cfg_volume_usage_t *cfg_volume, na_elem_t *data) -{ - na_elem_t *elem_volumes; - na_elem_iter_t iter_volume; - - elem_volumes = na_elem_child (data, "volumes"); - if (elem_volumes == NULL) - { - ERROR ("netapp plugin: cna_handle_volume_usage_data: " - "na_elem_child (\"volumes\") failed " - "for host %s.", host->name); - return (-1); - } - - iter_volume = na_child_iterator (elem_volumes); - for (na_elem_t *elem_volume = na_iterator_next (&iter_volume); - elem_volume != NULL; - elem_volume = na_iterator_next (&iter_volume)) - { - const char *volume_name, *state; - - data_volume_usage_t *v; - uint64_t value; - - na_elem_t *sis; - - volume_name = na_child_get_string (elem_volume, "name"); - if (volume_name == NULL) - continue; - - state = na_child_get_string (elem_volume, "state"); - if ((state == NULL) || (strcmp(state, "online") != 0)) - continue; - - /* get_volume_usage may return NULL if the volume is to be ignored. */ - v = get_volume_usage (cfg_volume, volume_name); - if (v == NULL) - continue; - - if ((v->flags & CFG_VOLUME_USAGE_SNAP) != 0) - cna_handle_volume_snap_usage(host, v); - - if ((v->flags & CFG_VOLUME_USAGE_DF) == 0) - continue; - - /* 2^4 exa-bytes? This will take a while ;) */ - value = na_child_get_uint64(elem_volume, "size-available", UINT64_MAX); - if (value != UINT64_MAX) { - v->norm_free = value; - v->flags |= HAVE_VOLUME_USAGE_NORM_FREE; - } - - value = na_child_get_uint64(elem_volume, "size-used", UINT64_MAX); - if (value != UINT64_MAX) { - v->norm_used = value; - v->flags |= HAVE_VOLUME_USAGE_NORM_USED; - } - - value = na_child_get_uint64(elem_volume, "snapshot-blocks-reserved", UINT64_MAX); - if (value != UINT64_MAX) { - /* 1 block == 1024 bytes as per API docs */ - v->snap_reserved = 1024 * value; - v->flags |= HAVE_VOLUME_USAGE_SNAP_RSVD; - } - - sis = na_elem_child(elem_volume, "sis"); - if (sis != NULL) { - cna_handle_volume_sis_data (host, v, sis); - cna_handle_volume_sis_saved (host, v, sis); - } - } /* for (elem_volume) */ - - return (cna_submit_volume_usage_data (host->name, cfg_volume, - host->cfg_volume_usage->interval.interval)); +static int cna_handle_volume_usage_data(const host_config_t *host, /* {{{ */ + cfg_volume_usage_t *cfg_volume, + na_elem_t *data) { + na_elem_t *elem_volumes; + na_elem_iter_t iter_volume; + + elem_volumes = na_elem_child(data, "volumes"); + if (elem_volumes == NULL) { + ERROR("netapp plugin: cna_handle_volume_usage_data: " + "na_elem_child (\"volumes\") failed " + "for host %s.", + host->name); + return (-1); + } + + iter_volume = na_child_iterator(elem_volumes); + for (na_elem_t *elem_volume = na_iterator_next(&iter_volume); + elem_volume != NULL; elem_volume = na_iterator_next(&iter_volume)) { + const char *volume_name, *state; + + data_volume_usage_t *v; + uint64_t value; + + na_elem_t *sis; + + volume_name = na_child_get_string(elem_volume, "name"); + if (volume_name == NULL) + continue; + + state = na_child_get_string(elem_volume, "state"); + if ((state == NULL) || (strcmp(state, "online") != 0)) + continue; + + /* get_volume_usage may return NULL if the volume is to be ignored. */ + v = get_volume_usage(cfg_volume, volume_name); + if (v == NULL) + continue; + + if ((v->flags & CFG_VOLUME_USAGE_SNAP) != 0) + cna_handle_volume_snap_usage(host, v); + + if ((v->flags & CFG_VOLUME_USAGE_DF) == 0) + continue; + + /* 2^4 exa-bytes? This will take a while ;) */ + value = na_child_get_uint64(elem_volume, "size-available", UINT64_MAX); + if (value != UINT64_MAX) { + v->norm_free = value; + v->flags |= HAVE_VOLUME_USAGE_NORM_FREE; + } + + value = na_child_get_uint64(elem_volume, "size-used", UINT64_MAX); + if (value != UINT64_MAX) { + v->norm_used = value; + v->flags |= HAVE_VOLUME_USAGE_NORM_USED; + } + + value = na_child_get_uint64(elem_volume, "snapshot-blocks-reserved", + UINT64_MAX); + if (value != UINT64_MAX) { + /* 1 block == 1024 bytes as per API docs */ + v->snap_reserved = 1024 * value; + v->flags |= HAVE_VOLUME_USAGE_SNAP_RSVD; + } + + sis = na_elem_child(elem_volume, "sis"); + if (sis != NULL) { + cna_handle_volume_sis_data(host, v, sis); + cna_handle_volume_sis_saved(host, v, sis); + } + } /* for (elem_volume) */ + + return (cna_submit_volume_usage_data( + host->name, cfg_volume, host->cfg_volume_usage->interval.interval)); } /* }}} int cna_handle_volume_usage_data */ -static int cna_setup_volume_usage (cfg_volume_usage_t *cvu) /* {{{ */ +static int cna_setup_volume_usage(cfg_volume_usage_t *cvu) /* {{{ */ { - if (cvu == NULL) - return (EINVAL); + if (cvu == NULL) + return (EINVAL); - if (cvu->query != NULL) - return (0); + if (cvu->query != NULL) + return (0); - cvu->query = na_elem_new ("volume-list-info"); - if (cvu->query == NULL) - { - ERROR ("netapp plugin: na_elem_new failed."); - return (-1); - } + cvu->query = na_elem_new("volume-list-info"); + if (cvu->query == NULL) { + ERROR("netapp plugin: na_elem_new failed."); + return (-1); + } - return (0); + return (0); } /* }}} int cna_setup_volume_usage */ -static int cna_query_volume_usage (host_config_t *host) /* {{{ */ +static int cna_query_volume_usage(host_config_t *host) /* {{{ */ { - na_elem_t *data; - int status; - cdtime_t now; - - if (host == NULL) - return (EINVAL); - - /* If the user did not configure volume_usage statistics, return without - * doing anything. */ - if (host->cfg_volume_usage == NULL) - return (0); - - now = cdtime (); - if ((host->cfg_volume_usage->interval.interval + host->cfg_volume_usage->interval.last_read) > now) - return (0); - - status = cna_setup_volume_usage (host->cfg_volume_usage); - if (status != 0) - return (status); - assert (host->cfg_volume_usage->query != NULL); - - data = na_server_invoke_elem(host->srv, host->cfg_volume_usage->query); - if (na_results_status (data) != NA_OK) - { - ERROR ("netapp plugin: cna_query_volume_usage: na_server_invoke_elem failed for host %s: %s", - host->name, na_results_reason (data)); - na_elem_free (data); - return (-1); - } - - status = cna_handle_volume_usage_data (host, host->cfg_volume_usage, data); - - if (status == 0) - host->cfg_volume_usage->interval.last_read = now; - - na_elem_free (data); - return (status); + na_elem_t *data; + int status; + cdtime_t now; + + if (host == NULL) + return (EINVAL); + + /* If the user did not configure volume_usage statistics, return without + * doing anything. */ + if (host->cfg_volume_usage == NULL) + return (0); + + now = cdtime(); + if ((host->cfg_volume_usage->interval.interval + + host->cfg_volume_usage->interval.last_read) > now) + return (0); + + status = cna_setup_volume_usage(host->cfg_volume_usage); + if (status != 0) + return (status); + assert(host->cfg_volume_usage->query != NULL); + + data = na_server_invoke_elem(host->srv, host->cfg_volume_usage->query); + if (na_results_status(data) != NA_OK) { + ERROR("netapp plugin: cna_query_volume_usage: na_server_invoke_elem failed " + "for host %s: %s", + host->name, na_results_reason(data)); + na_elem_free(data); + return (-1); + } + + status = cna_handle_volume_usage_data(host, host->cfg_volume_usage, data); + + if (status == 0) + host->cfg_volume_usage->interval.last_read = now; + + na_elem_free(data); + return (status); } /* }}} int cna_query_volume_usage */ /* Data corresponding to */ -static int cna_handle_quota_data (const host_config_t *host, /* {{{ */ - cfg_quota_t *cfg_quota, na_elem_t *data) -{ - na_elem_t *elem_quotas; - na_elem_iter_t iter_quota; - - elem_quotas = na_elem_child (data, "quotas"); - if (elem_quotas == NULL) - { - ERROR ("netapp plugin: cna_handle_quota_data: " - "na_elem_child (\"quotas\") failed " - "for host %s.", host->name); - return (-1); - } - - iter_quota = na_child_iterator (elem_quotas); - for (na_elem_t *elem_quota = na_iterator_next (&iter_quota); - elem_quota != NULL; - elem_quota = na_iterator_next (&iter_quota)) - { - const char *quota_type, *volume_name, *tree_name; - uint64_t value; - - char plugin_instance[DATA_MAX_NAME_LEN]; - - quota_type = na_child_get_string (elem_quota, "quota-type"); - if (quota_type == NULL) - continue; - - /* possible TODO: support other types as well */ - if (strcmp (quota_type, "tree") != 0) - continue; - - tree_name = na_child_get_string (elem_quota, "tree"); - if ((tree_name == NULL) || (*tree_name == '\0')) - continue; - - volume_name = na_child_get_string (elem_quota, "volume"); - if (volume_name == NULL) - continue; - - ssnprintf (plugin_instance, sizeof (plugin_instance), - "quota-%s-%s", volume_name, tree_name); - - value = na_child_get_uint64 (elem_quota, "disk-used", UINT64_MAX); - if (value != UINT64_MAX) { - value *= 1024; /* disk-used reports kilobytes */ - submit_double (host->name, plugin_instance, - /* type = */ "df_complex", /* type instance = */ NULL, - (double)value, /* timestamp = */ 0, - host->cfg_quota->interval.interval); - } - - value = na_child_get_uint64 (elem_quota, "files-used", UINT64_MAX); - if (value != UINT64_MAX) { - submit_double (host->name, plugin_instance, - /* type = */ "files", /* type instance = */ NULL, - (double)value, /* timestamp = */ 0, - host->cfg_quota->interval.interval); - } - } /* for (elem_quota) */ - - return (0); +static int cna_handle_quota_data(const host_config_t *host, /* {{{ */ + cfg_quota_t *cfg_quota, na_elem_t *data) { + na_elem_t *elem_quotas; + na_elem_iter_t iter_quota; + + elem_quotas = na_elem_child(data, "quotas"); + if (elem_quotas == NULL) { + ERROR("netapp plugin: cna_handle_quota_data: " + "na_elem_child (\"quotas\") failed " + "for host %s.", + host->name); + return (-1); + } + + iter_quota = na_child_iterator(elem_quotas); + for (na_elem_t *elem_quota = na_iterator_next(&iter_quota); + elem_quota != NULL; elem_quota = na_iterator_next(&iter_quota)) { + const char *quota_type, *volume_name, *tree_name; + uint64_t value; + + char plugin_instance[DATA_MAX_NAME_LEN]; + + quota_type = na_child_get_string(elem_quota, "quota-type"); + if (quota_type == NULL) + continue; + + /* possible TODO: support other types as well */ + if (strcmp(quota_type, "tree") != 0) + continue; + + tree_name = na_child_get_string(elem_quota, "tree"); + if ((tree_name == NULL) || (*tree_name == '\0')) + continue; + + volume_name = na_child_get_string(elem_quota, "volume"); + if (volume_name == NULL) + continue; + + ssnprintf(plugin_instance, sizeof(plugin_instance), "quota-%s-%s", + volume_name, tree_name); + + value = na_child_get_uint64(elem_quota, "disk-used", UINT64_MAX); + if (value != UINT64_MAX) { + value *= 1024; /* disk-used reports kilobytes */ + submit_double(host->name, plugin_instance, + /* type = */ "df_complex", /* type instance = */ NULL, + (double)value, /* timestamp = */ 0, + host->cfg_quota->interval.interval); + } + + value = na_child_get_uint64(elem_quota, "files-used", UINT64_MAX); + if (value != UINT64_MAX) { + submit_double(host->name, plugin_instance, + /* type = */ "files", /* type instance = */ NULL, + (double)value, /* timestamp = */ 0, + host->cfg_quota->interval.interval); + } + } /* for (elem_quota) */ + + return (0); } /* }}} int cna_handle_volume_usage_data */ -static int cna_setup_quota (cfg_quota_t *cq) /* {{{ */ +static int cna_setup_quota(cfg_quota_t *cq) /* {{{ */ { - if (cq == NULL) - return (EINVAL); + if (cq == NULL) + return (EINVAL); - if (cq->query != NULL) - return (0); + if (cq->query != NULL) + return (0); - cq->query = na_elem_new ("quota-report"); - if (cq->query == NULL) - { - ERROR ("netapp plugin: na_elem_new failed."); - return (-1); - } + cq->query = na_elem_new("quota-report"); + if (cq->query == NULL) { + ERROR("netapp plugin: na_elem_new failed."); + return (-1); + } - return (0); + return (0); } /* }}} int cna_setup_quota */ -static int cna_query_quota (host_config_t *host) /* {{{ */ +static int cna_query_quota(host_config_t *host) /* {{{ */ { - na_elem_t *data; - int status; - cdtime_t now; - - if (host == NULL) - return (EINVAL); - - /* If the user did not configure quota statistics, return without - * doing anything. */ - if (host->cfg_quota == NULL) - return (0); - - now = cdtime (); - if ((host->cfg_quota->interval.interval + host->cfg_quota->interval.last_read) > now) - return (0); - - status = cna_setup_quota (host->cfg_quota); - if (status != 0) - return (status); - assert (host->cfg_quota->query != NULL); - - data = na_server_invoke_elem (host->srv, host->cfg_quota->query); - if (na_results_status (data) != NA_OK) - { - ERROR ("netapp plugin: cna_query_quota: na_server_invoke_elem failed for host %s: %s", - host->name, na_results_reason (data)); - na_elem_free (data); - return (-1); - } - - status = cna_handle_quota_data (host, host->cfg_quota, data); - - if (status == 0) - host->cfg_quota->interval.last_read = now; - - na_elem_free (data); - return (status); + na_elem_t *data; + int status; + cdtime_t now; + + if (host == NULL) + return (EINVAL); + + /* If the user did not configure quota statistics, return without + * doing anything. */ + if (host->cfg_quota == NULL) + return (0); + + now = cdtime(); + if ((host->cfg_quota->interval.interval + + host->cfg_quota->interval.last_read) > now) + return (0); + + status = cna_setup_quota(host->cfg_quota); + if (status != 0) + return (status); + assert(host->cfg_quota->query != NULL); + + data = na_server_invoke_elem(host->srv, host->cfg_quota->query); + if (na_results_status(data) != NA_OK) { + ERROR("netapp plugin: cna_query_quota: na_server_invoke_elem failed for " + "host %s: %s", + host->name, na_results_reason(data)); + na_elem_free(data); + return (-1); + } + + status = cna_handle_quota_data(host, host->cfg_quota, data); + + if (status == 0) + host->cfg_quota->interval.last_read = now; + + na_elem_free(data); + return (status); } /* }}} int cna_query_quota */ /* Data corresponding to */ -static int cna_handle_snapvault_data (const char *hostname, /* {{{ */ - cfg_snapvault_t *cfg_snapvault, na_elem_t *data, cdtime_t interval) -{ - na_elem_iter_t status_iter; - - status = na_elem_child (data, "status-list"); - if (! status) { - ERROR ("netapp plugin: SnapVault status record missing status-list"); - return (0); - } - - status_iter = na_child_iterator (status); - for (na_elem_t *status = na_iterator_next (&status_iter); - status != NULL; - status = na_iterator_next (&status_iter)) - { - const char *dest_sys, *dest_path, *src_sys, *src_path; - char plugin_instance[DATA_MAX_NAME_LEN]; - uint64_t value; - - dest_sys = na_child_get_string (status, "destination-system"); - dest_path = na_child_get_string (status, "destination-path"); - src_sys = na_child_get_string (status, "source-system"); - src_path = na_child_get_string (status, "source-path"); - - if ((! dest_sys) || (! dest_path) || (! src_sys) || (! src_path)) - continue; - - value = na_child_get_uint64 (status, "lag-time", UINT64_MAX); - if (value == UINT64_MAX) /* no successful baseline transfer yet */ - continue; - - /* possible TODO: make plugin instance configurable */ - ssnprintf (plugin_instance, sizeof (plugin_instance), - "snapvault-%s", dest_path); - submit_double (hostname, plugin_instance, /* type = */ "delay", NULL, - (double)value, /* timestamp = */ 0, interval); - - value = na_child_get_uint64 (status, "last-transfer-duration", UINT64_MAX); - if (value != UINT64_MAX) - submit_double (hostname, plugin_instance, /* type = */ "duration", "last_transfer", - (double)value, /* timestamp = */ 0, interval); - - value = na_child_get_uint64 (status, "transfer-progress", UINT64_MAX); - if (value == UINT64_MAX) - value = na_child_get_uint64 (status, "last-transfer-size", UINT64_MAX); - if (value != UINT64_MAX) { - value *= 1024; /* this is kilobytes */ - submit_derive (hostname, plugin_instance, /* type = */ "if_rx_octets", "transferred", - value, /* timestamp = */ 0, interval); - } - } /* for (status) */ - - return (0); +static int cna_handle_snapvault_data(const char *hostname, /* {{{ */ + cfg_snapvault_t *cfg_snapvault, + na_elem_t *data, cdtime_t interval) { + na_elem_iter_t status_iter; + + status = na_elem_child(data, "status-list"); + if (!status) { + ERROR("netapp plugin: SnapVault status record missing status-list"); + return (0); + } + + status_iter = na_child_iterator(status); + for (na_elem_t *status = na_iterator_next(&status_iter); status != NULL; + status = na_iterator_next(&status_iter)) { + const char *dest_sys, *dest_path, *src_sys, *src_path; + char plugin_instance[DATA_MAX_NAME_LEN]; + uint64_t value; + + dest_sys = na_child_get_string(status, "destination-system"); + dest_path = na_child_get_string(status, "destination-path"); + src_sys = na_child_get_string(status, "source-system"); + src_path = na_child_get_string(status, "source-path"); + + if ((!dest_sys) || (!dest_path) || (!src_sys) || (!src_path)) + continue; + + value = na_child_get_uint64(status, "lag-time", UINT64_MAX); + if (value == UINT64_MAX) /* no successful baseline transfer yet */ + continue; + + /* possible TODO: make plugin instance configurable */ + ssnprintf(plugin_instance, sizeof(plugin_instance), "snapvault-%s", + dest_path); + submit_double(hostname, plugin_instance, /* type = */ "delay", NULL, + (double)value, /* timestamp = */ 0, interval); + + value = na_child_get_uint64(status, "last-transfer-duration", UINT64_MAX); + if (value != UINT64_MAX) + submit_double(hostname, plugin_instance, /* type = */ "duration", + "last_transfer", (double)value, /* timestamp = */ 0, + interval); + + value = na_child_get_uint64(status, "transfer-progress", UINT64_MAX); + if (value == UINT64_MAX) + value = na_child_get_uint64(status, "last-transfer-size", UINT64_MAX); + if (value != UINT64_MAX) { + value *= 1024; /* this is kilobytes */ + submit_derive(hostname, plugin_instance, /* type = */ "if_rx_octets", + "transferred", value, /* timestamp = */ 0, interval); + } + } /* for (status) */ + + return (0); } /* }}} int cna_handle_snapvault_data */ -static int cna_handle_snapvault_iter (host_config_t *host, /* {{{ */ - na_elem_t *data) -{ - const char *tag; +static int cna_handle_snapvault_iter(host_config_t *host, /* {{{ */ + na_elem_t *data) { + const char *tag; - uint32_t records_count; + uint32_t records_count; - records_count = na_child_get_uint32 (data, "records", UINT32_MAX); - if (records_count == UINT32_MAX) - return 0; + records_count = na_child_get_uint32(data, "records", UINT32_MAX); + if (records_count == UINT32_MAX) + return 0; - tag = na_child_get_string (data, "tag"); - if (! tag) - return 0; + tag = na_child_get_string(data, "tag"); + if (!tag) + return 0; - DEBUG ("netapp plugin: Iterating %u SV records (tag = %s)", records_count, tag); + DEBUG("netapp plugin: Iterating %u SV records (tag = %s)", records_count, + tag); - for (uint32_t i = 0; i < records_count; ++i) { - na_elem_t *elem; + for (uint32_t i = 0; i < records_count; ++i) { + na_elem_t *elem; - elem = na_server_invoke (host->srv, - "snapvault-secondary-relationship-status-list-iter-next", - "maximum", "1", "tag", tag, NULL); + elem = na_server_invoke( + host->srv, "snapvault-secondary-relationship-status-list-iter-next", + "maximum", "1", "tag", tag, NULL); - if (na_results_status (elem) != NA_OK) - { - ERROR ("netapp plugin: cna_handle_snapvault_iter: " - "na_server_invoke failed for host %s: %s", - host->name, na_results_reason (data)); - na_elem_free (elem); - return (-1); - } + if (na_results_status(elem) != NA_OK) { + ERROR("netapp plugin: cna_handle_snapvault_iter: " + "na_server_invoke failed for host %s: %s", + host->name, na_results_reason(data)); + na_elem_free(elem); + return (-1); + } - cna_handle_snapvault_data (host->name, host->cfg_snapvault, elem, - host->cfg_snapvault->interval.interval); - na_elem_free (elem); - } + cna_handle_snapvault_data(host->name, host->cfg_snapvault, elem, + host->cfg_snapvault->interval.interval); + na_elem_free(elem); + } - na_elem_free (na_server_invoke (host->srv, - "snapvault-secondary-relationship-status-list-iter-end", - "tag", tag, NULL)); - return (0); + na_elem_free(na_server_invoke( + host->srv, "snapvault-secondary-relationship-status-list-iter-end", "tag", + tag, NULL)); + return (0); } /* }}} int cna_handle_snapvault_iter */ -static int cna_setup_snapvault (cfg_snapvault_t *sv) /* {{{ */ +static int cna_setup_snapvault(cfg_snapvault_t *sv) /* {{{ */ { - if (sv == NULL) - return (EINVAL); + if (sv == NULL) + return (EINVAL); - if (sv->query != NULL) - return (0); + if (sv->query != NULL) + return (0); - sv->query = na_elem_new ("snapvault-secondary-relationship-status-list-iter-start"); - if (sv->query == NULL) - { - ERROR ("netapp plugin: na_elem_new failed."); - return (-1); - } + sv->query = + na_elem_new("snapvault-secondary-relationship-status-list-iter-start"); + if (sv->query == NULL) { + ERROR("netapp plugin: na_elem_new failed."); + return (-1); + } - return (0); + return (0); } /* }}} int cna_setup_snapvault */ -static int cna_query_snapvault (host_config_t *host) /* {{{ */ +static int cna_query_snapvault(host_config_t *host) /* {{{ */ { - na_elem_t *data; - int status; - cdtime_t now; + na_elem_t *data; + int status; + cdtime_t now; - if (host == NULL) - return EINVAL; + if (host == NULL) + return EINVAL; - if (host->cfg_snapvault == NULL) - return 0; + if (host->cfg_snapvault == NULL) + return 0; - now = cdtime (); - if ((host->cfg_snapvault->interval.interval + host->cfg_snapvault->interval.last_read) > now) - return (0); + now = cdtime(); + if ((host->cfg_snapvault->interval.interval + + host->cfg_snapvault->interval.last_read) > now) + return (0); - status = cna_setup_snapvault (host->cfg_snapvault); - if (status != 0) - return (status); - assert (host->cfg_snapvault->query != NULL); + status = cna_setup_snapvault(host->cfg_snapvault); + if (status != 0) + return (status); + assert(host->cfg_snapvault->query != NULL); - data = na_server_invoke_elem (host->srv, host->cfg_snapvault->query); - if (na_results_status (data) != NA_OK) - { - ERROR ("netapp plugin: cna_query_snapvault: na_server_invoke_elem failed for host %s: %s", - host->name, na_results_reason (data)); - na_elem_free (data); - return (-1); - } + data = na_server_invoke_elem(host->srv, host->cfg_snapvault->query); + if (na_results_status(data) != NA_OK) { + ERROR("netapp plugin: cna_query_snapvault: na_server_invoke_elem failed " + "for host %s: %s", + host->name, na_results_reason(data)); + na_elem_free(data); + return (-1); + } - status = cna_handle_snapvault_iter (host, data); + status = cna_handle_snapvault_iter(host, data); - if (status == 0) - host->cfg_snapvault->interval.last_read = now; + if (status == 0) + host->cfg_snapvault->interval.last_read = now; - na_elem_free (data); - return (status); + na_elem_free(data); + return (status); } /* }}} int cna_query_snapvault */ /* Data corresponding to */ -static int cna_handle_system_data (const char *hostname, /* {{{ */ - cfg_system_t *cfg_system, na_elem_t *data, int interval) -{ - na_elem_t *instances; - na_elem_iter_t counter_iter; - - 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; - cdtime_t timestamp; - - timestamp = cna_child_get_cdtime (data); - - instances = na_elem_child(na_elem_child (data, "instances"), "instance-data"); - if (instances == NULL) - { - ERROR ("netapp plugin: cna_handle_system_data: " - "na_elem_child (\"instances\") failed " - "for host %s.", hostname); - return (-1); - } - - instance = na_child_get_string (instances, "name"); - if (instance == NULL) - { - ERROR ("netapp plugin: cna_handle_system_data: " - "na_child_get_string (\"name\") failed " - "for host %s.", hostname); - return (-1); - } - - counter_iter = na_child_iterator (na_elem_child (instances, "counters")); - for (na_elem_t *counter = na_iterator_next (&counter_iter); - counter != NULL; - counter = na_iterator_next (&counter_iter)) - { - const char *name; - uint64_t value; - - name = na_child_get_string(counter, "name"); - if (name == NULL) - continue; - - value = na_child_get_uint64(counter, "value", UINT64_MAX); - if (value == UINT64_MAX) - continue; - - if (!strcmp(name, "disk_data_read")) { - disk_read = (derive_t) (value * 1024); - counter_flags |= 0x01; - } else if (!strcmp(name, "disk_data_written")) { - disk_written = (derive_t) (value * 1024); - counter_flags |= 0x02; - } else if (!strcmp(name, "net_data_recv")) { - net_recv = (derive_t) (value * 1024); - counter_flags |= 0x04; - } else if (!strcmp(name, "net_data_sent")) { - net_sent = (derive_t) (value * 1024); - counter_flags |= 0x08; - } else if (!strcmp(name, "cpu_busy")) { - cpu_busy = (derive_t) value; - counter_flags |= 0x10; - } else if (!strcmp(name, "cpu_elapsed_time")) { - 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_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_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_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_derive (hostname, instance, "cpu", "system", - cpu_busy, timestamp, interval); - submit_derive (hostname, instance, "cpu", "idle", - cpu_total - cpu_busy, timestamp, interval); - } - - return (0); +static int cna_handle_system_data(const char *hostname, /* {{{ */ + cfg_system_t *cfg_system, na_elem_t *data, + int interval) { + na_elem_t *instances; + na_elem_iter_t counter_iter; + + 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; + cdtime_t timestamp; + + timestamp = cna_child_get_cdtime(data); + + instances = na_elem_child(na_elem_child(data, "instances"), "instance-data"); + if (instances == NULL) { + ERROR("netapp plugin: cna_handle_system_data: " + "na_elem_child (\"instances\") failed " + "for host %s.", + hostname); + return (-1); + } + + instance = na_child_get_string(instances, "name"); + if (instance == NULL) { + ERROR("netapp plugin: cna_handle_system_data: " + "na_child_get_string (\"name\") failed " + "for host %s.", + hostname); + return (-1); + } + + counter_iter = na_child_iterator(na_elem_child(instances, "counters")); + for (na_elem_t *counter = na_iterator_next(&counter_iter); counter != NULL; + counter = na_iterator_next(&counter_iter)) { + const char *name; + uint64_t value; + + name = na_child_get_string(counter, "name"); + if (name == NULL) + continue; + + value = na_child_get_uint64(counter, "value", UINT64_MAX); + if (value == UINT64_MAX) + continue; + + if (!strcmp(name, "disk_data_read")) { + disk_read = (derive_t)(value * 1024); + counter_flags |= 0x01; + } else if (!strcmp(name, "disk_data_written")) { + disk_written = (derive_t)(value * 1024); + counter_flags |= 0x02; + } else if (!strcmp(name, "net_data_recv")) { + net_recv = (derive_t)(value * 1024); + counter_flags |= 0x04; + } else if (!strcmp(name, "net_data_sent")) { + net_sent = (derive_t)(value * 1024); + counter_flags |= 0x08; + } else if (!strcmp(name, "cpu_busy")) { + cpu_busy = (derive_t)value; + counter_flags |= 0x10; + } else if (!strcmp(name, "cpu_elapsed_time")) { + 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_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_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_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_derive(hostname, instance, "cpu", "system", cpu_busy, timestamp, + interval); + submit_derive(hostname, instance, "cpu", "idle", cpu_total - cpu_busy, + timestamp, interval); + } + + return (0); } /* }}} int cna_handle_system_data */ -static int cna_setup_system (cfg_system_t *cs) /* {{{ */ +static int cna_setup_system(cfg_system_t *cs) /* {{{ */ { - if (cs == NULL) - return (EINVAL); + if (cs == NULL) + return (EINVAL); - if (cs->query != NULL) - return (0); + if (cs->query != NULL) + return (0); - cs->query = na_elem_new ("perf-object-get-instances"); - if (cs->query == NULL) - { - ERROR ("netapp plugin: na_elem_new failed."); - return (-1); - } - na_child_add_string (cs->query, "objectname", "system"); + cs->query = na_elem_new("perf-object-get-instances"); + if (cs->query == NULL) { + ERROR("netapp plugin: na_elem_new failed."); + return (-1); + } + na_child_add_string(cs->query, "objectname", "system"); - return (0); + return (0); } /* }}} int cna_setup_system */ -static int cna_query_system (host_config_t *host) /* {{{ */ +static int cna_query_system(host_config_t *host) /* {{{ */ { - na_elem_t *data; - int status; - cdtime_t now; - - if (host == NULL) - return (EINVAL); - - /* If system statistics were not configured, return without doing anything. */ - if (host->cfg_system == NULL) - return (0); - - now = cdtime (); - if ((host->cfg_system->interval.interval + host->cfg_system->interval.last_read) > now) - return (0); - - status = cna_setup_system (host->cfg_system); - if (status != 0) - return (status); - assert (host->cfg_system->query != NULL); - - data = na_server_invoke_elem(host->srv, host->cfg_system->query); - if (na_results_status (data) != NA_OK) - { - ERROR ("netapp plugin: cna_query_system: na_server_invoke_elem failed for host %s: %s", - host->name, na_results_reason (data)); - na_elem_free (data); - return (-1); - } - - status = cna_handle_system_data (host->name, host->cfg_system, data, - host->cfg_system->interval.interval); - - if (status == 0) - host->cfg_system->interval.last_read = now; - - na_elem_free (data); - return (status); + na_elem_t *data; + int status; + cdtime_t now; + + if (host == NULL) + return (EINVAL); + + /* If system statistics were not configured, return without doing anything. */ + if (host->cfg_system == NULL) + return (0); + + now = cdtime(); + if ((host->cfg_system->interval.interval + + host->cfg_system->interval.last_read) > now) + return (0); + + status = cna_setup_system(host->cfg_system); + if (status != 0) + return (status); + assert(host->cfg_system->query != NULL); + + data = na_server_invoke_elem(host->srv, host->cfg_system->query); + if (na_results_status(data) != NA_OK) { + ERROR("netapp plugin: cna_query_system: na_server_invoke_elem failed for " + "host %s: %s", + host->name, na_results_reason(data)); + na_elem_free(data); + return (-1); + } + + status = cna_handle_system_data(host->name, host->cfg_system, data, + host->cfg_system->interval.interval); + + if (status == 0) + host->cfg_system->interval.last_read = now; + + na_elem_free(data); + return (status); } /* }}} int cna_query_system */ /* @@ -2250,100 +2224,95 @@ static int cna_query_system (host_config_t *host) /* {{{ */ */ /* Sets a given flag if the boolean argument is true and unsets the flag if it * is false. On error, the flag-field is not changed. */ -static int cna_config_bool_to_flag (const oconfig_item_t *ci, /* {{{ */ - uint32_t *flags, uint32_t flag) -{ - if ((ci == NULL) || (flags == NULL)) - return (EINVAL); - - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) - { - WARNING ("netapp plugin: The %s option needs exactly one boolean argument.", - ci->key); - return (-1); - } - - if (ci->values[0].value.boolean) - *flags |= flag; - else - *flags &= ~flag; - - return (0); +static int cna_config_bool_to_flag(const oconfig_item_t *ci, /* {{{ */ + uint32_t *flags, uint32_t flag) { + if ((ci == NULL) || (flags == NULL)) + return (EINVAL); + + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) { + WARNING("netapp plugin: The %s option needs exactly one boolean argument.", + ci->key); + return (-1); + } + + if (ci->values[0].value.boolean) + *flags |= flag; + else + *flags &= ~flag; + + return (0); } /* }}} int cna_config_bool_to_flag */ /* Handling of the "Interval" option which is allowed in every block. */ -static int cna_config_get_interval (const oconfig_item_t *ci, /* {{{ */ - cna_interval_t *out_interval) -{ - cdtime_t tmp = 0; - int status; +static int cna_config_get_interval(const oconfig_item_t *ci, /* {{{ */ + cna_interval_t *out_interval) { + cdtime_t tmp = 0; + int status; - status = cf_util_get_cdtime (ci, &tmp); - if (status != 0) - return (status); + status = cf_util_get_cdtime(ci, &tmp); + if (status != 0) + return (status); - out_interval->interval = tmp; - out_interval->last_read = 0; + out_interval->interval = tmp; + out_interval->last_read = 0; - return (0); + return (0); } /* }}} int cna_config_get_interval */ /* Handling of the "GetIO", "GetOps" and "GetLatency" options within a * block. */ -static void cna_config_volume_perf_option (cfg_volume_perf_t *cvp, /* {{{ */ - const oconfig_item_t *ci) -{ - char *name; - ignorelist_t * il; - - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("netapp plugin: The %s option requires exactly one string argument.", - ci->key); - return; - } - - name = ci->values[0].value.string; - - if (strcasecmp ("GetIO", ci->key) == 0) - il = cvp->il_octets; - else if (strcasecmp ("GetOps", ci->key) == 0) - il = cvp->il_operations; - else if (strcasecmp ("GetLatency", ci->key) == 0) - il = cvp->il_latency; - else - return; - - ignorelist_add (il, name); +static void cna_config_volume_perf_option(cfg_volume_perf_t *cvp, /* {{{ */ + const oconfig_item_t *ci) { + char *name; + ignorelist_t *il; + + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING( + "netapp plugin: The %s option requires exactly one string argument.", + ci->key); + return; + } + + name = ci->values[0].value.string; + + if (strcasecmp("GetIO", ci->key) == 0) + il = cvp->il_octets; + else if (strcasecmp("GetOps", ci->key) == 0) + il = cvp->il_operations; + else if (strcasecmp("GetLatency", ci->key) == 0) + il = cvp->il_latency; + else + return; + + ignorelist_add(il, name); } /* }}} void cna_config_volume_perf_option */ /* Handling of the "IgnoreSelectedIO", "IgnoreSelectedOps" and * "IgnoreSelectedLatency" options within a block. */ -static void cna_config_volume_perf_default (cfg_volume_perf_t *cvp, /* {{{ */ - const oconfig_item_t *ci) -{ - ignorelist_t *il; - - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) - { - WARNING ("netapp plugin: The %s option requires exactly one string argument.", - ci->key); - return; - } - - if (strcasecmp ("IgnoreSelectedIO", ci->key) == 0) - il = cvp->il_octets; - else if (strcasecmp ("IgnoreSelectedOps", ci->key) == 0) - il = cvp->il_operations; - else if (strcasecmp ("IgnoreSelectedLatency", ci->key) == 0) - il = cvp->il_latency; - else - return; - - if (ci->values[0].value.boolean) - ignorelist_set_invert (il, /* invert = */ 0); - else - ignorelist_set_invert (il, /* invert = */ 1); +static void cna_config_volume_perf_default(cfg_volume_perf_t *cvp, /* {{{ */ + const oconfig_item_t *ci) { + ignorelist_t *il; + + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) { + WARNING( + "netapp plugin: The %s option requires exactly one string argument.", + ci->key); + return; + } + + if (strcasecmp("IgnoreSelectedIO", ci->key) == 0) + il = cvp->il_octets; + else if (strcasecmp("IgnoreSelectedOps", ci->key) == 0) + il = cvp->il_operations; + else if (strcasecmp("IgnoreSelectedLatency", ci->key) == 0) + il = cvp->il_latency; + else + return; + + if (ci->values[0].value.boolean) + ignorelist_set_invert(il, /* invert = */ 0); + else + ignorelist_set_invert(il, /* invert = */ 1); } /* }}} void cna_config_volume_perf_default */ /* Corresponds to a block */ @@ -2363,255 +2332,246 @@ static void cna_config_volume_perf_default (cfg_volume_perf_t *cvp, /* {{{ */ * */ /* Corresponds to a block */ -static int cna_config_volume_performance (host_config_t *host, /* {{{ */ - const oconfig_item_t *ci) -{ - cfg_volume_perf_t *cfg_volume_perf; - - if ((host == NULL) || (ci == NULL)) - return (EINVAL); - - if (host->cfg_volume_perf == NULL) - { - cfg_volume_perf = calloc (1, sizeof (*cfg_volume_perf)); - if (cfg_volume_perf == NULL) - return (ENOMEM); - - /* Set default flags */ - cfg_volume_perf->query = NULL; - cfg_volume_perf->volumes = NULL; - - cfg_volume_perf->il_octets = ignorelist_create (/* invert = */ 1); - if (cfg_volume_perf->il_octets == NULL) - { - sfree (cfg_volume_perf); - return (ENOMEM); - } - - cfg_volume_perf->il_operations = ignorelist_create (/* invert = */ 1); - if (cfg_volume_perf->il_operations == NULL) - { - ignorelist_free (cfg_volume_perf->il_octets); - sfree (cfg_volume_perf); - return (ENOMEM); - } - - cfg_volume_perf->il_latency = ignorelist_create (/* invert = */ 1); - if (cfg_volume_perf->il_latency == NULL) - { - ignorelist_free (cfg_volume_perf->il_octets); - ignorelist_free (cfg_volume_perf->il_operations); - sfree (cfg_volume_perf); - return (ENOMEM); - } - - host->cfg_volume_perf = cfg_volume_perf; - } - cfg_volume_perf = host->cfg_volume_perf; - - for (int i = 0; i < ci->children_num; ++i) { - oconfig_item_t *item = ci->children + i; - - /* if (!item || !item->key || !*item->key) continue; */ - if (strcasecmp(item->key, "Interval") == 0) - cna_config_get_interval (item, &cfg_volume_perf->interval); - else if (!strcasecmp(item->key, "GetIO")) - cna_config_volume_perf_option (cfg_volume_perf, item); - else if (!strcasecmp(item->key, "GetOps")) - cna_config_volume_perf_option (cfg_volume_perf, item); - else if (!strcasecmp(item->key, "GetLatency")) - cna_config_volume_perf_option (cfg_volume_perf, item); - else if (!strcasecmp(item->key, "IgnoreSelectedIO")) - cna_config_volume_perf_default (cfg_volume_perf, item); - else if (!strcasecmp(item->key, "IgnoreSelectedOps")) - cna_config_volume_perf_default (cfg_volume_perf, item); - else if (!strcasecmp(item->key, "IgnoreSelectedLatency")) - cna_config_volume_perf_default (cfg_volume_perf, item); - else - WARNING ("netapp plugin: The option %s is not allowed within " - "`VolumePerf' blocks.", item->key); - } - - return (0); +static int cna_config_volume_performance(host_config_t *host, /* {{{ */ + const oconfig_item_t *ci) { + cfg_volume_perf_t *cfg_volume_perf; + + if ((host == NULL) || (ci == NULL)) + return (EINVAL); + + if (host->cfg_volume_perf == NULL) { + cfg_volume_perf = calloc(1, sizeof(*cfg_volume_perf)); + if (cfg_volume_perf == NULL) + return (ENOMEM); + + /* Set default flags */ + cfg_volume_perf->query = NULL; + cfg_volume_perf->volumes = NULL; + + cfg_volume_perf->il_octets = ignorelist_create(/* invert = */ 1); + if (cfg_volume_perf->il_octets == NULL) { + sfree(cfg_volume_perf); + return (ENOMEM); + } + + cfg_volume_perf->il_operations = ignorelist_create(/* invert = */ 1); + if (cfg_volume_perf->il_operations == NULL) { + ignorelist_free(cfg_volume_perf->il_octets); + sfree(cfg_volume_perf); + return (ENOMEM); + } + + cfg_volume_perf->il_latency = ignorelist_create(/* invert = */ 1); + if (cfg_volume_perf->il_latency == NULL) { + ignorelist_free(cfg_volume_perf->il_octets); + ignorelist_free(cfg_volume_perf->il_operations); + sfree(cfg_volume_perf); + return (ENOMEM); + } + + host->cfg_volume_perf = cfg_volume_perf; + } + cfg_volume_perf = host->cfg_volume_perf; + + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *item = ci->children + i; + + /* if (!item || !item->key || !*item->key) continue; */ + if (strcasecmp(item->key, "Interval") == 0) + cna_config_get_interval(item, &cfg_volume_perf->interval); + else if (!strcasecmp(item->key, "GetIO")) + cna_config_volume_perf_option(cfg_volume_perf, item); + else if (!strcasecmp(item->key, "GetOps")) + cna_config_volume_perf_option(cfg_volume_perf, item); + else if (!strcasecmp(item->key, "GetLatency")) + cna_config_volume_perf_option(cfg_volume_perf, item); + else if (!strcasecmp(item->key, "IgnoreSelectedIO")) + cna_config_volume_perf_default(cfg_volume_perf, item); + else if (!strcasecmp(item->key, "IgnoreSelectedOps")) + cna_config_volume_perf_default(cfg_volume_perf, item); + else if (!strcasecmp(item->key, "IgnoreSelectedLatency")) + cna_config_volume_perf_default(cfg_volume_perf, item); + else + WARNING("netapp plugin: The option %s is not allowed within " + "`VolumePerf' blocks.", + item->key); + } + + return (0); } /* }}} int cna_config_volume_performance */ /* Handling of the "GetCapacity" and "GetSnapshot" options within a * block. */ -static void cna_config_volume_usage_option (cfg_volume_usage_t *cvu, /* {{{ */ - const oconfig_item_t *ci) -{ - char *name; - ignorelist_t * il; - - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("netapp plugin: The %s option requires exactly one string argument.", - ci->key); - return; - } - - name = ci->values[0].value.string; - - if (strcasecmp ("GetCapacity", ci->key) == 0) - il = cvu->il_capacity; - else if (strcasecmp ("GetSnapshot", ci->key) == 0) - il = cvu->il_snapshot; - else - return; - - ignorelist_add (il, name); +static void cna_config_volume_usage_option(cfg_volume_usage_t *cvu, /* {{{ */ + const oconfig_item_t *ci) { + char *name; + ignorelist_t *il; + + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING( + "netapp plugin: The %s option requires exactly one string argument.", + ci->key); + return; + } + + name = ci->values[0].value.string; + + if (strcasecmp("GetCapacity", ci->key) == 0) + il = cvu->il_capacity; + else if (strcasecmp("GetSnapshot", ci->key) == 0) + il = cvu->il_snapshot; + else + return; + + ignorelist_add(il, name); } /* }}} void cna_config_volume_usage_option */ /* Handling of the "IgnoreSelectedCapacity" and "IgnoreSelectedSnapshot" * options within a block. */ -static void cna_config_volume_usage_default (cfg_volume_usage_t *cvu, /* {{{ */ - const oconfig_item_t *ci) -{ - ignorelist_t *il; - - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) - { - WARNING ("netapp plugin: The %s option requires exactly one string argument.", - ci->key); - return; - } - - if (strcasecmp ("IgnoreSelectedCapacity", ci->key) == 0) - il = cvu->il_capacity; - else if (strcasecmp ("IgnoreSelectedSnapshot", ci->key) == 0) - il = cvu->il_snapshot; - else - return; - - if (ci->values[0].value.boolean) - ignorelist_set_invert (il, /* invert = */ 0); - else - ignorelist_set_invert (il, /* invert = */ 1); +static void cna_config_volume_usage_default(cfg_volume_usage_t *cvu, /* {{{ */ + const oconfig_item_t *ci) { + ignorelist_t *il; + + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) { + WARNING( + "netapp plugin: The %s option requires exactly one string argument.", + ci->key); + return; + } + + if (strcasecmp("IgnoreSelectedCapacity", ci->key) == 0) + il = cvu->il_capacity; + else if (strcasecmp("IgnoreSelectedSnapshot", ci->key) == 0) + il = cvu->il_snapshot; + else + return; + + if (ci->values[0].value.boolean) + ignorelist_set_invert(il, /* invert = */ 0); + else + ignorelist_set_invert(il, /* invert = */ 1); } /* }}} void cna_config_volume_usage_default */ /* Corresponds to a block */ -static int cna_config_quota (host_config_t *host, oconfig_item_t *ci) /* {{{ */ +static int cna_config_quota(host_config_t *host, oconfig_item_t *ci) /* {{{ */ { - cfg_quota_t *cfg_quota; + cfg_quota_t *cfg_quota; - if ((host == NULL) || (ci == NULL)) - return (EINVAL); + if ((host == NULL) || (ci == NULL)) + return (EINVAL); - if (host->cfg_quota == NULL) - { - cfg_quota = calloc (1, sizeof (*cfg_quota)); - if (cfg_quota == NULL) - return (ENOMEM); - cfg_quota->query = NULL; + if (host->cfg_quota == NULL) { + cfg_quota = calloc(1, sizeof(*cfg_quota)); + if (cfg_quota == NULL) + return (ENOMEM); + cfg_quota->query = NULL; - host->cfg_quota = cfg_quota; - } - cfg_quota = host->cfg_quota; + host->cfg_quota = cfg_quota; + } + cfg_quota = host->cfg_quota; - for (int i = 0; i < ci->children_num; ++i) { - oconfig_item_t *item = ci->children + i; + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *item = ci->children + i; - if (strcasecmp (item->key, "Interval") == 0) - cna_config_get_interval (item, &cfg_quota->interval); - else - WARNING ("netapp plugin: The option %s is not allowed within " - "`Quota' blocks.", item->key); - } + if (strcasecmp(item->key, "Interval") == 0) + cna_config_get_interval(item, &cfg_quota->interval); + else + WARNING("netapp plugin: The option %s is not allowed within " + "`Quota' blocks.", + item->key); + } - return (0); + return (0); } /* }}} int cna_config_quota */ /* Corresponds to a block */ static int cna_config_disk(host_config_t *host, oconfig_item_t *ci) { /* {{{ */ - cfg_disk_t *cfg_disk; - - if ((host == NULL) || (ci == NULL)) - return (EINVAL); - - if (host->cfg_disk == NULL) - { - cfg_disk = calloc (1, sizeof (*cfg_disk)); - if (cfg_disk == NULL) - return (ENOMEM); - - /* Set default flags */ - cfg_disk->flags = CFG_DISK_ALL; - cfg_disk->query = NULL; - cfg_disk->disks = NULL; - - host->cfg_disk = cfg_disk; - } - cfg_disk = host->cfg_disk; - - for (int i = 0; i < ci->children_num; ++i) { - oconfig_item_t *item = ci->children + i; - - /* if (!item || !item->key || !*item->key) continue; */ - if (strcasecmp(item->key, "Interval") == 0) - cna_config_get_interval (item, &cfg_disk->interval); - else if (strcasecmp(item->key, "GetBusy") == 0) - cna_config_bool_to_flag (item, &cfg_disk->flags, CFG_DISK_BUSIEST); - } - - if ((cfg_disk->flags & CFG_DISK_ALL) == 0) - { - NOTICE ("netapp plugin: All disk related values have been disabled. " - "Collection of per-disk data will be disabled entirely."); - free_cfg_disk (host->cfg_disk); - host->cfg_disk = NULL; - } - - return (0); + cfg_disk_t *cfg_disk; + + if ((host == NULL) || (ci == NULL)) + return (EINVAL); + + if (host->cfg_disk == NULL) { + cfg_disk = calloc(1, sizeof(*cfg_disk)); + if (cfg_disk == NULL) + return (ENOMEM); + + /* Set default flags */ + cfg_disk->flags = CFG_DISK_ALL; + cfg_disk->query = NULL; + cfg_disk->disks = NULL; + + host->cfg_disk = cfg_disk; + } + cfg_disk = host->cfg_disk; + + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *item = ci->children + i; + + /* if (!item || !item->key || !*item->key) continue; */ + if (strcasecmp(item->key, "Interval") == 0) + cna_config_get_interval(item, &cfg_disk->interval); + else if (strcasecmp(item->key, "GetBusy") == 0) + cna_config_bool_to_flag(item, &cfg_disk->flags, CFG_DISK_BUSIEST); + } + + if ((cfg_disk->flags & CFG_DISK_ALL) == 0) { + NOTICE("netapp plugin: All disk related values have been disabled. " + "Collection of per-disk data will be disabled entirely."); + free_cfg_disk(host->cfg_disk); + host->cfg_disk = NULL; + } + + return (0); } /* }}} int cna_config_disk */ /* Corresponds to a block */ static int cna_config_wafl(host_config_t *host, oconfig_item_t *ci) /* {{{ */ { - cfg_wafl_t *cfg_wafl; - - if ((host == NULL) || (ci == NULL)) - return (EINVAL); - - if (host->cfg_wafl == NULL) - { - cfg_wafl = calloc (1, sizeof (*cfg_wafl)); - if (cfg_wafl == NULL) - return (ENOMEM); - - /* Set default flags */ - cfg_wafl->flags = CFG_WAFL_ALL; - - host->cfg_wafl = cfg_wafl; - } - cfg_wafl = host->cfg_wafl; - - for (int i = 0; i < ci->children_num; ++i) { - oconfig_item_t *item = ci->children + i; - - if (strcasecmp(item->key, "Interval") == 0) - cna_config_get_interval (item, &cfg_wafl->interval); - else if (!strcasecmp(item->key, "GetNameCache")) - cna_config_bool_to_flag (item, &cfg_wafl->flags, CFG_WAFL_NAME_CACHE); - else if (!strcasecmp(item->key, "GetDirCache")) - cna_config_bool_to_flag (item, &cfg_wafl->flags, CFG_WAFL_DIR_CACHE); - else if (!strcasecmp(item->key, "GetBufferCache")) - cna_config_bool_to_flag (item, &cfg_wafl->flags, CFG_WAFL_BUF_CACHE); - else if (!strcasecmp(item->key, "GetInodeCache")) - cna_config_bool_to_flag (item, &cfg_wafl->flags, CFG_WAFL_INODE_CACHE); - else - WARNING ("netapp plugin: The %s config option is not allowed within " - "`WAFL' blocks.", item->key); - } - - if ((cfg_wafl->flags & CFG_WAFL_ALL) == 0) - { - NOTICE ("netapp plugin: All WAFL related values have been disabled. " - "Collection of WAFL data will be disabled entirely."); - free_cfg_wafl (host->cfg_wafl); - host->cfg_wafl = NULL; - } - - return (0); + cfg_wafl_t *cfg_wafl; + + if ((host == NULL) || (ci == NULL)) + return (EINVAL); + + if (host->cfg_wafl == NULL) { + cfg_wafl = calloc(1, sizeof(*cfg_wafl)); + if (cfg_wafl == NULL) + return (ENOMEM); + + /* Set default flags */ + cfg_wafl->flags = CFG_WAFL_ALL; + + host->cfg_wafl = cfg_wafl; + } + cfg_wafl = host->cfg_wafl; + + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *item = ci->children + i; + + if (strcasecmp(item->key, "Interval") == 0) + cna_config_get_interval(item, &cfg_wafl->interval); + else if (!strcasecmp(item->key, "GetNameCache")) + cna_config_bool_to_flag(item, &cfg_wafl->flags, CFG_WAFL_NAME_CACHE); + else if (!strcasecmp(item->key, "GetDirCache")) + cna_config_bool_to_flag(item, &cfg_wafl->flags, CFG_WAFL_DIR_CACHE); + else if (!strcasecmp(item->key, "GetBufferCache")) + cna_config_bool_to_flag(item, &cfg_wafl->flags, CFG_WAFL_BUF_CACHE); + else if (!strcasecmp(item->key, "GetInodeCache")) + cna_config_bool_to_flag(item, &cfg_wafl->flags, CFG_WAFL_INODE_CACHE); + else + WARNING("netapp plugin: The %s config option is not allowed within " + "`WAFL' blocks.", + item->key); + } + + if ((cfg_wafl->flags & CFG_WAFL_ALL) == 0) { + NOTICE("netapp plugin: All WAFL related values have been disabled. " + "Collection of WAFL data will be disabled entirely."); + free_cfg_wafl(host->cfg_wafl); + host->cfg_wafl = NULL; + } + + return (0); } /* }}} int cna_config_wafl */ /* @@ -2632,359 +2592,364 @@ static int cna_config_wafl(host_config_t *host, oconfig_item_t *ci) /* {{{ */ */ /* Corresponds to a block */ static int cna_config_volume_usage(host_config_t *host, /* {{{ */ - const oconfig_item_t *ci) -{ - cfg_volume_usage_t *cfg_volume_usage; - - if ((host == NULL) || (ci == NULL)) - return (EINVAL); - - if (host->cfg_volume_usage == NULL) - { - cfg_volume_usage = calloc (1, sizeof (*cfg_volume_usage)); - if (cfg_volume_usage == NULL) - return (ENOMEM); - - /* Set default flags */ - cfg_volume_usage->query = NULL; - cfg_volume_usage->volumes = NULL; - - cfg_volume_usage->il_capacity = ignorelist_create (/* invert = */ 1); - if (cfg_volume_usage->il_capacity == NULL) - { - sfree (cfg_volume_usage); - return (ENOMEM); - } - - cfg_volume_usage->il_snapshot = ignorelist_create (/* invert = */ 1); - if (cfg_volume_usage->il_snapshot == NULL) - { - ignorelist_free (cfg_volume_usage->il_capacity); - sfree (cfg_volume_usage); - return (ENOMEM); - } - - host->cfg_volume_usage = cfg_volume_usage; - } - cfg_volume_usage = host->cfg_volume_usage; - - for (int i = 0; i < ci->children_num; ++i) { - oconfig_item_t *item = ci->children + i; - - /* if (!item || !item->key || !*item->key) continue; */ - if (strcasecmp(item->key, "Interval") == 0) - cna_config_get_interval (item, &cfg_volume_usage->interval); - else if (!strcasecmp(item->key, "GetCapacity")) - cna_config_volume_usage_option (cfg_volume_usage, item); - else if (!strcasecmp(item->key, "GetSnapshot")) - cna_config_volume_usage_option (cfg_volume_usage, item); - else if (!strcasecmp(item->key, "IgnoreSelectedCapacity")) - cna_config_volume_usage_default (cfg_volume_usage, item); - else if (!strcasecmp(item->key, "IgnoreSelectedSnapshot")) - cna_config_volume_usage_default (cfg_volume_usage, item); - else - WARNING ("netapp plugin: The option %s is not allowed within " - "`VolumeUsage' blocks.", item->key); - } - - return (0); + const oconfig_item_t *ci) { + cfg_volume_usage_t *cfg_volume_usage; + + if ((host == NULL) || (ci == NULL)) + return (EINVAL); + + if (host->cfg_volume_usage == NULL) { + cfg_volume_usage = calloc(1, sizeof(*cfg_volume_usage)); + if (cfg_volume_usage == NULL) + return (ENOMEM); + + /* Set default flags */ + cfg_volume_usage->query = NULL; + cfg_volume_usage->volumes = NULL; + + cfg_volume_usage->il_capacity = ignorelist_create(/* invert = */ 1); + if (cfg_volume_usage->il_capacity == NULL) { + sfree(cfg_volume_usage); + return (ENOMEM); + } + + cfg_volume_usage->il_snapshot = ignorelist_create(/* invert = */ 1); + if (cfg_volume_usage->il_snapshot == NULL) { + ignorelist_free(cfg_volume_usage->il_capacity); + sfree(cfg_volume_usage); + return (ENOMEM); + } + + host->cfg_volume_usage = cfg_volume_usage; + } + cfg_volume_usage = host->cfg_volume_usage; + + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *item = ci->children + i; + + /* if (!item || !item->key || !*item->key) continue; */ + if (strcasecmp(item->key, "Interval") == 0) + cna_config_get_interval(item, &cfg_volume_usage->interval); + else if (!strcasecmp(item->key, "GetCapacity")) + cna_config_volume_usage_option(cfg_volume_usage, item); + else if (!strcasecmp(item->key, "GetSnapshot")) + cna_config_volume_usage_option(cfg_volume_usage, item); + else if (!strcasecmp(item->key, "IgnoreSelectedCapacity")) + cna_config_volume_usage_default(cfg_volume_usage, item); + else if (!strcasecmp(item->key, "IgnoreSelectedSnapshot")) + cna_config_volume_usage_default(cfg_volume_usage, item); + else + WARNING("netapp plugin: The option %s is not allowed within " + "`VolumeUsage' blocks.", + item->key); + } + + return (0); } /* }}} int cna_config_volume_usage */ /* Corresponds to a block */ -static int cna_config_snapvault (host_config_t *host, /* {{{ */ - const oconfig_item_t *ci) -{ - cfg_snapvault_t *cfg_snapvault; +static int cna_config_snapvault(host_config_t *host, /* {{{ */ + const oconfig_item_t *ci) { + cfg_snapvault_t *cfg_snapvault; - if ((host == NULL) || (ci == NULL)) - return EINVAL; + if ((host == NULL) || (ci == NULL)) + return EINVAL; - if (host->cfg_snapvault == NULL) - { - cfg_snapvault = calloc (1, sizeof (*cfg_snapvault)); - if (cfg_snapvault == NULL) - return ENOMEM; - cfg_snapvault->query = NULL; + if (host->cfg_snapvault == NULL) { + cfg_snapvault = calloc(1, sizeof(*cfg_snapvault)); + if (cfg_snapvault == NULL) + return ENOMEM; + cfg_snapvault->query = NULL; - host->cfg_snapvault = cfg_snapvault; - } + host->cfg_snapvault = cfg_snapvault; + } - cfg_snapvault = host->cfg_snapvault; + cfg_snapvault = host->cfg_snapvault; - for (int i = 0; i < ci->children_num; ++i) { - oconfig_item_t *item = ci->children + i; + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *item = ci->children + i; - if (strcasecmp (item->key, "Interval") == 0) - cna_config_get_interval (item, &cfg_snapvault->interval); - else - WARNING ("netapp plugin: The option %s is not allowed within " - "`SnapVault' blocks.", item->key); - } + if (strcasecmp(item->key, "Interval") == 0) + cna_config_get_interval(item, &cfg_snapvault->interval); + else + WARNING("netapp plugin: The option %s is not allowed within " + "`SnapVault' blocks.", + item->key); + } - return 0; + return 0; } /* }}} int cna_config_snapvault */ /* Corresponds to a block */ -static int cna_config_system (host_config_t *host, /* {{{ */ - oconfig_item_t *ci) -{ - cfg_system_t *cfg_system; - - if ((host == NULL) || (ci == NULL)) - return (EINVAL); - - if (host->cfg_system == NULL) - { - cfg_system = calloc (1, sizeof (*cfg_system)); - if (cfg_system == NULL) - return (ENOMEM); - - /* Set default flags */ - cfg_system->flags = CFG_SYSTEM_ALL; - cfg_system->query = NULL; - - host->cfg_system = cfg_system; - } - cfg_system = host->cfg_system; - - for (int i = 0; i < ci->children_num; ++i) { - oconfig_item_t *item = ci->children + i; - - if (strcasecmp(item->key, "Interval") == 0) { - cna_config_get_interval (item, &cfg_system->interval); - } else if (!strcasecmp(item->key, "GetCPULoad")) { - cna_config_bool_to_flag (item, &cfg_system->flags, CFG_SYSTEM_CPU); - } else if (!strcasecmp(item->key, "GetInterfaces")) { - cna_config_bool_to_flag (item, &cfg_system->flags, CFG_SYSTEM_NET); - } else if (!strcasecmp(item->key, "GetDiskOps")) { - cna_config_bool_to_flag (item, &cfg_system->flags, CFG_SYSTEM_OPS); - } else if (!strcasecmp(item->key, "GetDiskIO")) { - cna_config_bool_to_flag (item, &cfg_system->flags, CFG_SYSTEM_DISK); - } else { - WARNING ("netapp plugin: The %s config option is not allowed within " - "`System' blocks.", item->key); - } - } - - if ((cfg_system->flags & CFG_SYSTEM_ALL) == 0) - { - NOTICE ("netapp plugin: All system related values have been disabled. " - "Collection of system data will be disabled entirely."); - free_cfg_system (host->cfg_system); - host->cfg_system = NULL; - } - - return (0); +static int cna_config_system(host_config_t *host, /* {{{ */ + oconfig_item_t *ci) { + cfg_system_t *cfg_system; + + if ((host == NULL) || (ci == NULL)) + return (EINVAL); + + if (host->cfg_system == NULL) { + cfg_system = calloc(1, sizeof(*cfg_system)); + if (cfg_system == NULL) + return (ENOMEM); + + /* Set default flags */ + cfg_system->flags = CFG_SYSTEM_ALL; + cfg_system->query = NULL; + + host->cfg_system = cfg_system; + } + cfg_system = host->cfg_system; + + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *item = ci->children + i; + + if (strcasecmp(item->key, "Interval") == 0) { + cna_config_get_interval(item, &cfg_system->interval); + } else if (!strcasecmp(item->key, "GetCPULoad")) { + cna_config_bool_to_flag(item, &cfg_system->flags, CFG_SYSTEM_CPU); + } else if (!strcasecmp(item->key, "GetInterfaces")) { + cna_config_bool_to_flag(item, &cfg_system->flags, CFG_SYSTEM_NET); + } else if (!strcasecmp(item->key, "GetDiskOps")) { + cna_config_bool_to_flag(item, &cfg_system->flags, CFG_SYSTEM_OPS); + } else if (!strcasecmp(item->key, "GetDiskIO")) { + cna_config_bool_to_flag(item, &cfg_system->flags, CFG_SYSTEM_DISK); + } else { + WARNING("netapp plugin: The %s config option is not allowed within " + "`System' blocks.", + item->key); + } + } + + if ((cfg_system->flags & CFG_SYSTEM_ALL) == 0) { + NOTICE("netapp plugin: All system related values have been disabled. " + "Collection of system data will be disabled entirely."); + free_cfg_system(host->cfg_system); + host->cfg_system = NULL; + } + + return (0); } /* }}} int cna_config_system */ /* Corresponds to a block. */ -static host_config_t *cna_alloc_host (void) /* {{{ */ -{ - host_config_t *host; - - host = calloc (1, sizeof (*host)); - if (host == NULL) - return (NULL); - - host->name = NULL; - host->protocol = NA_SERVER_TRANSPORT_HTTPS; - host->host = NULL; - host->username = NULL; - host->password = NULL; - host->vfiler = NULL; - host->srv = NULL; - host->cfg_wafl = NULL; - host->cfg_disk = NULL; - host->cfg_volume_perf = NULL; - host->cfg_volume_usage = NULL; - host->cfg_quota = NULL; - host->cfg_snapvault = NULL; - host->cfg_system = NULL; - - return (host); +static host_config_t *cna_alloc_host(void) /* {{{ */ +{ + host_config_t *host; + + host = calloc(1, sizeof(*host)); + if (host == NULL) + return (NULL); + + host->name = NULL; + host->protocol = NA_SERVER_TRANSPORT_HTTPS; + host->host = NULL; + host->username = NULL; + host->password = NULL; + host->vfiler = NULL; + host->srv = NULL; + host->cfg_wafl = NULL; + host->cfg_disk = NULL; + host->cfg_volume_perf = NULL; + host->cfg_volume_usage = NULL; + host->cfg_quota = NULL; + host->cfg_snapvault = NULL; + host->cfg_system = NULL; + + return (host); } /* }}} host_config_t *cna_alloc_host */ -static host_config_t *cna_shallow_clone_host (host_config_t *host) /* {{{ */ -{ - host_config_t *clone; - - if (host == NULL) - return (NULL); - - clone = cna_alloc_host (); - if (clone == NULL) - return (NULL); - - if (host->name != NULL) { - clone->name = strdup (host->name); - if (clone->name == NULL) { - free_host_config (clone); - return NULL; - } - } - - clone->protocol = host->protocol; - - if (host->host != NULL) { - clone->host = strdup (host->host); - if (clone->host == NULL) { - free_host_config (clone); - return NULL; - } - } - - clone->port = host->port; - - if (host->username != NULL) { - clone->username = strdup (host->username); - if (clone->username == NULL) { - free_host_config (clone); - return NULL; - } - } - if (host->password != NULL) { - clone->password = strdup (host->password); - if (clone->password == NULL) { - free_host_config (clone); - return NULL; - } - } - - clone->interval = host->interval; - - return (clone); +static host_config_t *cna_shallow_clone_host(host_config_t *host) /* {{{ */ +{ + host_config_t *clone; + + if (host == NULL) + return (NULL); + + clone = cna_alloc_host(); + if (clone == NULL) + return (NULL); + + if (host->name != NULL) { + clone->name = strdup(host->name); + if (clone->name == NULL) { + free_host_config(clone); + return NULL; + } + } + + clone->protocol = host->protocol; + + if (host->host != NULL) { + clone->host = strdup(host->host); + if (clone->host == NULL) { + free_host_config(clone); + return NULL; + } + } + + clone->port = host->port; + + if (host->username != NULL) { + clone->username = strdup(host->username); + if (clone->username == NULL) { + free_host_config(clone); + return NULL; + } + } + if (host->password != NULL) { + clone->password = strdup(host->password); + if (clone->password == NULL) { + free_host_config(clone); + return NULL; + } + } + + clone->interval = host->interval; + + return (clone); } /* }}} host_config_t *cna_shallow_clone_host */ -static int cna_read (user_data_t *ud); +static int cna_read(user_data_t *ud); -static int cna_register_host (host_config_t *host) /* {{{ */ +static int cna_register_host(host_config_t *host) /* {{{ */ { - char cb_name[256]; - - if (host->vfiler) - ssnprintf (cb_name, sizeof (cb_name), "netapp-%s-%s", - host->name, host->vfiler); - else - ssnprintf (cb_name, sizeof (cb_name), "netapp-%s", host->name); - - plugin_register_complex_read (/* group = */ NULL, cb_name, - /* callback = */ cna_read, - /* interval = */ host->interval, - &(user_data_t) { - .data = host, - .free_func = (void *) free_host_config, - }); - - return (0); + char cb_name[256]; + + if (host->vfiler) + ssnprintf(cb_name, sizeof(cb_name), "netapp-%s-%s", host->name, + host->vfiler); + else + ssnprintf(cb_name, sizeof(cb_name), "netapp-%s", host->name); + + plugin_register_complex_read( + /* group = */ NULL, cb_name, + /* callback = */ cna_read, + /* interval = */ host->interval, + &(user_data_t){ + .data = host, .free_func = (void *)free_host_config, + }); + + return (0); } /* }}} int cna_register_host */ -static int cna_config_host (host_config_t *host, /* {{{ */ - const oconfig_item_t *ci) -{ - oconfig_item_t *item; - _Bool is_vfiler = 0; - int status; - - if (! strcasecmp (ci->key, "VFiler")) - is_vfiler = 1; - - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { - WARNING ("netapp plugin: \"%s\" needs exactly one string argument. Ignoring host block.", ci->key); - return (1); - } - - status = cf_util_get_string (ci, &host->name); - if (status != 0) - return (1); - - for (int i = 0; i < ci->children_num; ++i) { - item = ci->children + i; - - status = 0; - - if (!strcasecmp(item->key, "Address")) { - status = cf_util_get_string (item, &host->host); - } else if (!strcasecmp(item->key, "Port")) { - int tmp; - - tmp = cf_util_get_port_number (item); - if (tmp > 0) - host->port = tmp; - } else if (!strcasecmp(item->key, "Protocol")) { - if ((item->values_num != 1) || (item->values[0].type != OCONFIG_TYPE_STRING) || (strcasecmp(item->values[0].value.string, "http") && strcasecmp(item->values[0].value.string, "https"))) { - WARNING("netapp plugin: \"Protocol\" needs to be either \"http\" or \"https\". Ignoring host block \"%s\".", ci->values[0].value.string); - return (1); - } - if (!strcasecmp(item->values[0].value.string, "http")) host->protocol = NA_SERVER_TRANSPORT_HTTP; - else host->protocol = NA_SERVER_TRANSPORT_HTTPS; - } else if (!strcasecmp(item->key, "User")) { - status = cf_util_get_string (item, &host->username); - } else if (!strcasecmp(item->key, "Password")) { - status = cf_util_get_string (item, &host->password); - } else if (!strcasecmp(item->key, "Interval")) { - 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")) { - cna_config_disk(host, item); - } else if (!strcasecmp(item->key, "VolumePerf")) { - cna_config_volume_performance(host, item); - } else if (!strcasecmp(item->key, "VolumeUsage")) { - cna_config_volume_usage(host, item); - } else if (!strcasecmp(item->key, "Quota")) { - cna_config_quota(host, item); - } else if (!strcasecmp(item->key, "SnapVault")) { - cna_config_snapvault(host, item); - } else if (!strcasecmp(item->key, "System")) { - cna_config_system(host, item); - } else if ((!strcasecmp(item->key, "VFiler")) && (! is_vfiler)) { - host_config_t *vfiler; - - vfiler = cna_shallow_clone_host (host); - if (! vfiler) { - ERROR ("netapp plugin: Failed to allocate host object for vfiler."); - continue; - } - - if (cna_config_host (vfiler, item)) { - free_host_config (vfiler); - continue; - } - - cna_register_host (vfiler); - } else if ((!strcasecmp(item->key, "VFilerName")) && is_vfiler) { - status = cf_util_get_string (item, &host->vfiler); - } else { - WARNING ("netapp plugin: Ignoring unknown config option \"%s\" in %s block \"%s\".", - item->key, is_vfiler ? "vfiler" : "host", ci->values[0].value.string); - } - - if (status != 0) - break; - } - - if (host->host == NULL) - host->host = strdup (host->name); - - if (is_vfiler && (! host->vfiler)) - host->vfiler = strdup (host->name); - - if (host->host == NULL) - status = -1; - - if (host->port <= 0) - host->port = (host->protocol == NA_SERVER_TRANSPORT_HTTP) ? 80 : 443; - - if ((host->username == NULL) || (host->password == NULL)) { - WARNING("netapp plugin: Please supply login information for host \"%s\". " - "Ignoring host block.", host->name); - status = -1; - } - - if (status != 0) - return status; - - return (0); +static int cna_config_host(host_config_t *host, /* {{{ */ + const oconfig_item_t *ci) { + oconfig_item_t *item; + _Bool is_vfiler = 0; + int status; + + if (!strcasecmp(ci->key, "VFiler")) + is_vfiler = 1; + + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("netapp plugin: \"%s\" needs exactly one string argument. Ignoring " + "host block.", + ci->key); + return (1); + } + + status = cf_util_get_string(ci, &host->name); + if (status != 0) + return (1); + + for (int i = 0; i < ci->children_num; ++i) { + item = ci->children + i; + + status = 0; + + if (!strcasecmp(item->key, "Address")) { + status = cf_util_get_string(item, &host->host); + } else if (!strcasecmp(item->key, "Port")) { + int tmp; + + tmp = cf_util_get_port_number(item); + if (tmp > 0) + host->port = tmp; + } else if (!strcasecmp(item->key, "Protocol")) { + if ((item->values_num != 1) || + (item->values[0].type != OCONFIG_TYPE_STRING) || + (strcasecmp(item->values[0].value.string, "http") && + strcasecmp(item->values[0].value.string, "https"))) { + WARNING("netapp plugin: \"Protocol\" needs to be either \"http\" or " + "\"https\". Ignoring host block \"%s\".", + ci->values[0].value.string); + return (1); + } + if (!strcasecmp(item->values[0].value.string, "http")) + host->protocol = NA_SERVER_TRANSPORT_HTTP; + else + host->protocol = NA_SERVER_TRANSPORT_HTTPS; + } else if (!strcasecmp(item->key, "User")) { + status = cf_util_get_string(item, &host->username); + } else if (!strcasecmp(item->key, "Password")) { + status = cf_util_get_string(item, &host->password); + } else if (!strcasecmp(item->key, "Interval")) { + 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")) { + cna_config_disk(host, item); + } else if (!strcasecmp(item->key, "VolumePerf")) { + cna_config_volume_performance(host, item); + } else if (!strcasecmp(item->key, "VolumeUsage")) { + cna_config_volume_usage(host, item); + } else if (!strcasecmp(item->key, "Quota")) { + cna_config_quota(host, item); + } else if (!strcasecmp(item->key, "SnapVault")) { + cna_config_snapvault(host, item); + } else if (!strcasecmp(item->key, "System")) { + cna_config_system(host, item); + } else if ((!strcasecmp(item->key, "VFiler")) && (!is_vfiler)) { + host_config_t *vfiler; + + vfiler = cna_shallow_clone_host(host); + if (!vfiler) { + ERROR("netapp plugin: Failed to allocate host object for vfiler."); + continue; + } + + if (cna_config_host(vfiler, item)) { + free_host_config(vfiler); + continue; + } + + cna_register_host(vfiler); + } else if ((!strcasecmp(item->key, "VFilerName")) && is_vfiler) { + status = cf_util_get_string(item, &host->vfiler); + } else { + WARNING("netapp plugin: Ignoring unknown config option \"%s\" in %s " + "block \"%s\".", + item->key, is_vfiler ? "vfiler" : "host", + ci->values[0].value.string); + } + + if (status != 0) + break; + } + + if (host->host == NULL) + host->host = strdup(host->name); + + if (is_vfiler && (!host->vfiler)) + host->vfiler = strdup(host->name); + + if (host->host == NULL) + status = -1; + + if (host->port <= 0) + host->port = (host->protocol == NA_SERVER_TRANSPORT_HTTP) ? 80 : 443; + + if ((host->username == NULL) || (host->password == NULL)) { + WARNING("netapp plugin: Please supply login information for host \"%s\". " + "Ignoring host block.", + host->name); + status = -1; + } + + if (status != 0) + return status; + + return (0); } /* }}} host_config_t *cna_config_host */ /* @@ -2992,162 +2957,159 @@ static int cna_config_host (host_config_t *host, /* {{{ */ * * Pretty standard stuff here. */ -static int cna_init_host (host_config_t *host) /* {{{ */ -{ - /* Request version 1.1 of the ONTAP API */ - int major_version = 1, minor_version = 1; - - if (host == NULL) - return (EINVAL); - - if (host->srv != NULL) - return (0); - - if (host->vfiler != NULL) /* Request version 1.7 of the ONTAP API */ - minor_version = 7; - - host->srv = na_server_open (host->host, major_version, minor_version); - if (host->srv == NULL) { - ERROR ("netapp plugin: na_server_open (%s) failed.", host->host); - return (-1); - } - - na_server_set_transport_type(host->srv, host->protocol, - /* transportarg = */ NULL); - na_server_set_port(host->srv, host->port); - na_server_style(host->srv, NA_STYLE_LOGIN_PASSWORD); - na_server_adminuser(host->srv, host->username, host->password); - na_server_set_timeout(host->srv, 5 /* seconds */); - - if (host->vfiler != NULL) { - if (! na_server_set_vfiler (host->srv, host->vfiler)) { - ERROR ("netapp plugin: Failed to connect to VFiler '%s' on host '%s'.", - host->vfiler, host->host); - return (-1); - } - else { - INFO ("netapp plugin: Connected to VFiler '%s' on host '%s'.", - host->vfiler, host->host); - } - } - - return (0); +static int cna_init_host(host_config_t *host) /* {{{ */ +{ + /* Request version 1.1 of the ONTAP API */ + int major_version = 1, minor_version = 1; + + if (host == NULL) + return (EINVAL); + + if (host->srv != NULL) + return (0); + + if (host->vfiler != NULL) /* Request version 1.7 of the ONTAP API */ + minor_version = 7; + + host->srv = na_server_open(host->host, major_version, minor_version); + if (host->srv == NULL) { + ERROR("netapp plugin: na_server_open (%s) failed.", host->host); + return (-1); + } + + na_server_set_transport_type(host->srv, host->protocol, + /* transportarg = */ NULL); + na_server_set_port(host->srv, host->port); + na_server_style(host->srv, NA_STYLE_LOGIN_PASSWORD); + na_server_adminuser(host->srv, host->username, host->password); + na_server_set_timeout(host->srv, 5 /* seconds */); + + if (host->vfiler != NULL) { + if (!na_server_set_vfiler(host->srv, host->vfiler)) { + ERROR("netapp plugin: Failed to connect to VFiler '%s' on host '%s'.", + host->vfiler, host->host); + return (-1); + } else { + INFO("netapp plugin: Connected to VFiler '%s' on host '%s'.", + host->vfiler, host->host); + } + } + + return (0); } /* }}} int cna_init_host */ -static int cna_init (void) /* {{{ */ +static int cna_init(void) /* {{{ */ { - char err[256] = { 0 }; + char err[256] = {0}; - if (!na_startup(err, sizeof(err))) { - err[sizeof (err) - 1] = 0; - ERROR("netapp plugin: Error initializing netapp API: %s", err); - return 1; - } + if (!na_startup(err, sizeof(err))) { + err[sizeof(err) - 1] = 0; + ERROR("netapp plugin: Error initializing netapp API: %s", err); + return 1; + } - return (0); + return (0); } /* }}} cna_init */ -static int cna_read_internal (host_config_t *host) { /* {{{ */ - int status; +static int cna_read_internal(host_config_t *host) { /* {{{ */ + int status; - status = cna_query_wafl (host); - if (status != 0) - return (status); + status = cna_query_wafl(host); + if (status != 0) + return (status); - status = cna_query_disk (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_perf(host); + if (status != 0) + return (status); - status = cna_query_volume_usage (host); - if (status != 0) - return (status); + status = cna_query_volume_usage(host); + if (status != 0) + return (status); - status = cna_query_quota (host); - if (status != 0) - return (status); + status = cna_query_quota(host); + if (status != 0) + return (status); - status = cna_query_snapvault (host); - if (status != 0) - return (status); + status = cna_query_snapvault(host); + if (status != 0) + return (status); - status = cna_query_system (host); - if (status != 0) - return (status); + status = cna_query_system(host); + if (status != 0) + return (status); - return 0; + return 0; } /* }}} int cna_read_internal */ -static int cna_read (user_data_t *ud) { /* {{{ */ - host_config_t *host; - int status; +static int cna_read(user_data_t *ud) { /* {{{ */ + host_config_t *host; + int status; - if ((ud == NULL) || (ud->data == NULL)) - return (-1); + if ((ud == NULL) || (ud->data == NULL)) + return (-1); - host = ud->data; + host = ud->data; - status = cna_init_host (host); - if (status != 0) - return (status); + status = cna_init_host(host); + if (status != 0) + return (status); - status = cna_read_internal (host); - if (status != 0) - { - if (host->srv != NULL) - na_server_close (host->srv); - host->srv = NULL; - } + status = cna_read_internal(host); + if (status != 0) { + if (host->srv != NULL) + na_server_close(host->srv); + host->srv = NULL; + } - return 0; + return 0; } /* }}} int cna_read */ -static int cna_config (oconfig_item_t *ci) { /* {{{ */ - oconfig_item_t *item; - - for (int i = 0; i < ci->children_num; ++i) { - item = ci->children + i; - - if (strcasecmp(item->key, "Host") == 0) - { - host_config_t *host; - - host = cna_alloc_host (); - if (host == NULL) { - ERROR ("netapp plugin: Failed to allocate host object."); - continue; - } - - if (cna_config_host (host, item) != 0) { - free_host_config (host); - continue; - } - - cna_register_host (host); - } - else /* if (item->key != "Host") */ - { - WARNING("netapp plugin: Ignoring unknown config option \"%s\".", item->key); - } - } - return 0; +static int cna_config(oconfig_item_t *ci) { /* {{{ */ + oconfig_item_t *item; + + for (int i = 0; i < ci->children_num; ++i) { + item = ci->children + i; + + if (strcasecmp(item->key, "Host") == 0) { + host_config_t *host; + + host = cna_alloc_host(); + if (host == NULL) { + ERROR("netapp plugin: Failed to allocate host object."); + continue; + } + + if (cna_config_host(host, item) != 0) { + free_host_config(host); + continue; + } + + cna_register_host(host); + } else /* if (item->key != "Host") */ + { + WARNING("netapp plugin: Ignoring unknown config option \"%s\".", + item->key); + } + } + return 0; } /* }}} int cna_config */ -static int cna_shutdown (void) /* {{{ */ +static int cna_shutdown(void) /* {{{ */ { - /* Clean up system resources and stuff. */ - na_shutdown (); + /* Clean up system resources and stuff. */ + na_shutdown(); - return (0); + return (0); } /* }}} int cna_shutdown */ void module_register(void) { - plugin_register_complex_config("netapp", cna_config); - plugin_register_init("netapp", cna_init); - plugin_register_shutdown("netapp", cna_shutdown); + plugin_register_complex_config("netapp", cna_config); + plugin_register_init("netapp", cna_init); + plugin_register_shutdown("netapp", cna_shutdown); } /* vim: set sw=2 ts=2 noet fdm=marker : */ diff --git a/src/netlink.c b/src/netlink.c index 70c10c9d..8076c1fa 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -27,18 +27,18 @@ #include "collectd.h" -#include "plugin.h" #include "common.h" +#include "plugin.h" #include #include #include #if HAVE_LINUX_GEN_STATS_H -# include +#include #endif #if HAVE_LINUX_PKT_SCHED_H -# include +#include #endif #include @@ -78,8 +78,7 @@ union ir_link_stats_u { #endif }; -typedef struct ir_ignorelist_s -{ +typedef struct ir_ignorelist_s { char *device; char *type; char *inst; @@ -94,52 +93,39 @@ static struct mnl_socket *nl; static char **iflist = NULL; static size_t iflist_len = 0; -static const char *config_keys[] = -{ - "Interface", - "VerboseInterface", - "QDisc", - "Class", - "Filter", - "IgnoreSelected" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"Interface", "VerboseInterface", + "QDisc", "Class", + "Filter", "IgnoreSelected"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); -static int add_ignorelist (const char *dev, const char *type, - const char *inst) -{ +static int add_ignorelist(const char *dev, const char *type, const char *inst) { ir_ignorelist_t *entry; - entry = calloc (1, sizeof (*entry)); + entry = calloc(1, sizeof(*entry)); if (entry == NULL) return (-1); - if (strcasecmp (dev, "All") != 0) - { - entry->device = strdup (dev); - if (entry->device == NULL) - { - sfree (entry); + if (strcasecmp(dev, "All") != 0) { + entry->device = strdup(dev); + if (entry->device == NULL) { + sfree(entry); return (-1); } } - entry->type = strdup (type); - if (entry->type == NULL) - { - sfree (entry->device); - sfree (entry); + entry->type = strdup(type); + if (entry->type == NULL) { + sfree(entry->device); + sfree(entry); return (-1); } - if (inst != NULL) - { - entry->inst = strdup (inst); - if (entry->inst == NULL) - { - sfree (entry->type); - sfree (entry->device); - sfree (entry); + if (inst != NULL) { + entry->inst = strdup(inst); + if (entry->inst == NULL) { + sfree(entry->type); + sfree(entry->device); + sfree(entry); return (-1); } } @@ -154,36 +140,31 @@ static int add_ignorelist (const char *dev, const char *type, * Checks wether a data set should be ignored. Returns `true' is the value * should be ignored, `false' otherwise. */ -static int check_ignorelist (const char *dev, - const char *type, const char *type_instance) -{ - assert ((dev != NULL) && (type != NULL)); +static int check_ignorelist(const char *dev, const char *type, + const char *type_instance) { + assert((dev != NULL) && (type != NULL)); if (ir_ignorelist_head == NULL) return (ir_ignorelist_invert ? 0 : 1); - for (ir_ignorelist_t *i = ir_ignorelist_head; i != NULL; i = i->next) - { + for (ir_ignorelist_t *i = ir_ignorelist_head; i != NULL; i = i->next) { /* i->device == NULL => match all devices */ - if ((i->device != NULL) - && (strcasecmp (i->device, dev) != 0)) + if ((i->device != NULL) && (strcasecmp(i->device, dev) != 0)) continue; - if (strcasecmp (i->type, type) != 0) + if (strcasecmp(i->type, type) != 0) continue; - if ((i->inst != NULL) && (type_instance != NULL) - && (strcasecmp (i->inst, type_instance) != 0)) + if ((i->inst != NULL) && (type_instance != NULL) && + (strcasecmp(i->inst, type_instance) != 0)) continue; - DEBUG ("netlink plugin: check_ignorelist: " - "(dev = %s; type = %s; inst = %s) matched " - "(dev = %s; type = %s; inst = %s)", - dev, type, - type_instance == NULL ? "(nil)" : type_instance, - i->device == NULL ? "(nil)" : i->device, - i->type, - i->inst == NULL ? "(nil)" : i->inst); + DEBUG("netlink plugin: check_ignorelist: " + "(dev = %s; type = %s; inst = %s) matched " + "(dev = %s; type = %s; inst = %s)", + dev, type, type_instance == NULL ? "(nil)" : type_instance, + i->device == NULL ? "(nil)" : i->device, i->type, + i->inst == NULL ? "(nil)" : i->inst); return (ir_ignorelist_invert ? 0 : 1); } /* for i */ @@ -191,259 +172,234 @@ static int check_ignorelist (const char *dev, return (ir_ignorelist_invert); } /* int check_ignorelist */ -static void submit_one (const char *dev, const char *type, - const char *type_instance, derive_t value) -{ +static void submit_one(const char *dev, const char *type, + const char *type_instance, derive_t value) { value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .derive = value }; + vl.values = &(value_t){.derive = value}; vl.values_len = 1; - sstrncpy (vl.plugin, "netlink", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); + sstrncpy(vl.plugin, "netlink", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, dev, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* void submit_one */ -static void submit_two (const char *dev, const char *type, - const char *type_instance, - derive_t rx, derive_t tx) -{ +static void submit_two(const char *dev, const char *type, + const char *type_instance, derive_t rx, derive_t tx) { value_list_t vl = VALUE_LIST_INIT; value_t values[] = { - { .derive = rx }, - { .derive = tx }, + {.derive = rx}, {.derive = tx}, }; vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - sstrncpy (vl.plugin, "netlink", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); + vl.values_len = STATIC_ARRAY_SIZE(values); + sstrncpy(vl.plugin, "netlink", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, dev, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* void submit_two */ -static int update_iflist (struct ifinfomsg *msg, const char *dev) -{ +static int update_iflist(struct ifinfomsg *msg, const char *dev) { /* Update the `iflist'. It's used to know which interfaces exist and query * them later for qdiscs and classes. */ - if ((msg->ifi_index >= 0) && ((size_t) msg->ifi_index >= iflist_len)) - { + if ((msg->ifi_index >= 0) && ((size_t)msg->ifi_index >= iflist_len)) { char **temp; - temp = realloc (iflist, (msg->ifi_index + 1) * sizeof (char *)); - if (temp == NULL) - { - ERROR ("netlink plugin: update_iflist: realloc failed."); + temp = realloc(iflist, (msg->ifi_index + 1) * sizeof(char *)); + if (temp == NULL) { + ERROR("netlink plugin: update_iflist: realloc failed."); return (-1); } - memset (temp + iflist_len, '\0', - (msg->ifi_index + 1 - iflist_len) * sizeof (char *)); + memset(temp + iflist_len, '\0', + (msg->ifi_index + 1 - iflist_len) * sizeof(char *)); iflist = temp; iflist_len = msg->ifi_index + 1; } - if ((iflist[msg->ifi_index] == NULL) - || (strcmp (iflist[msg->ifi_index], dev) != 0)) - { - sfree (iflist[msg->ifi_index]); - iflist[msg->ifi_index] = strdup (dev); + if ((iflist[msg->ifi_index] == NULL) || + (strcmp(iflist[msg->ifi_index], dev) != 0)) { + sfree(iflist[msg->ifi_index]); + iflist[msg->ifi_index] = strdup(dev); } return (0); } /* int update_iflist */ -static void check_ignorelist_and_submit (const char *dev, - struct ir_link_stats_storage_s *stats) -{ +static void check_ignorelist_and_submit(const char *dev, + struct ir_link_stats_storage_s *stats) { - if (check_ignorelist (dev, "interface", NULL) == 0) - { - submit_two (dev, "if_octets", NULL, stats->rx_bytes, stats->tx_bytes); - submit_two (dev, "if_packets", NULL, stats->rx_packets, stats->tx_packets); - submit_two (dev, "if_errors", NULL, stats->rx_errors, stats->tx_errors); - } - else - { - DEBUG ("netlink plugin: Ignoring %s/interface.", dev); + if (check_ignorelist(dev, "interface", NULL) == 0) { + submit_two(dev, "if_octets", NULL, stats->rx_bytes, stats->tx_bytes); + submit_two(dev, "if_packets", NULL, stats->rx_packets, stats->tx_packets); + submit_two(dev, "if_errors", NULL, stats->rx_errors, stats->tx_errors); + } else { + DEBUG("netlink plugin: Ignoring %s/interface.", dev); } - if (check_ignorelist (dev, "if_detail", NULL) == 0) - { - submit_two (dev, "if_dropped", NULL, stats->rx_dropped, stats->tx_dropped); - submit_one (dev, "if_multicast", NULL, stats->multicast); - submit_one (dev, "if_collisions", NULL, stats->collisions); - - submit_one (dev, "if_rx_errors", "length", stats->rx_length_errors); - submit_one (dev, "if_rx_errors", "over", stats->rx_over_errors); - submit_one (dev, "if_rx_errors", "crc", stats->rx_crc_errors); - submit_one (dev, "if_rx_errors", "frame", stats->rx_frame_errors); - submit_one (dev, "if_rx_errors", "fifo", stats->rx_fifo_errors); - submit_one (dev, "if_rx_errors", "missed", stats->rx_missed_errors); - - submit_one (dev, "if_tx_errors", "aborted", stats->tx_aborted_errors); - submit_one (dev, "if_tx_errors", "carrier", stats->tx_carrier_errors); - submit_one (dev, "if_tx_errors", "fifo", stats->tx_fifo_errors); - submit_one (dev, "if_tx_errors", "heartbeat", stats->tx_heartbeat_errors); - submit_one (dev, "if_tx_errors", "window", stats->tx_window_errors); - } - else - { - DEBUG ("netlink plugin: Ignoring %s/if_detail.", dev); + if (check_ignorelist(dev, "if_detail", NULL) == 0) { + submit_two(dev, "if_dropped", NULL, stats->rx_dropped, stats->tx_dropped); + submit_one(dev, "if_multicast", NULL, stats->multicast); + submit_one(dev, "if_collisions", NULL, stats->collisions); + + submit_one(dev, "if_rx_errors", "length", stats->rx_length_errors); + submit_one(dev, "if_rx_errors", "over", stats->rx_over_errors); + submit_one(dev, "if_rx_errors", "crc", stats->rx_crc_errors); + submit_one(dev, "if_rx_errors", "frame", stats->rx_frame_errors); + submit_one(dev, "if_rx_errors", "fifo", stats->rx_fifo_errors); + submit_one(dev, "if_rx_errors", "missed", stats->rx_missed_errors); + + submit_one(dev, "if_tx_errors", "aborted", stats->tx_aborted_errors); + submit_one(dev, "if_tx_errors", "carrier", stats->tx_carrier_errors); + submit_one(dev, "if_tx_errors", "fifo", stats->tx_fifo_errors); + submit_one(dev, "if_tx_errors", "heartbeat", stats->tx_heartbeat_errors); + submit_one(dev, "if_tx_errors", "window", stats->tx_window_errors); + } else { + DEBUG("netlink plugin: Ignoring %s/if_detail.", dev); } } /* void check_ignorelist_and_submit */ -#define COPY_RTNL_LINK_VALUE(dst_stats, src_stats, value_name) \ +#define COPY_RTNL_LINK_VALUE(dst_stats, src_stats, value_name) \ (dst_stats)->value_name = (src_stats)->value_name -#define COPY_RTNL_LINK_STATS(dst_stats, src_stats) \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_packets); \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, tx_packets); \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_bytes); \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, tx_bytes); \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_errors); \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, tx_errors); \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_dropped); \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, tx_dropped); \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, multicast); \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, collisions); \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_length_errors); \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_over_errors); \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_crc_errors); \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_frame_errors); \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_fifo_errors); \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_missed_errors); \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, tx_aborted_errors); \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, tx_carrier_errors); \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, tx_fifo_errors); \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, tx_heartbeat_errors); \ - COPY_RTNL_LINK_VALUE (dst_stats, src_stats, tx_window_errors) +#define COPY_RTNL_LINK_STATS(dst_stats, src_stats) \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, rx_packets); \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, tx_packets); \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, rx_bytes); \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, tx_bytes); \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, rx_errors); \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, tx_errors); \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, rx_dropped); \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, tx_dropped); \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, multicast); \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, collisions); \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, rx_length_errors); \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, rx_over_errors); \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, rx_crc_errors); \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, rx_frame_errors); \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, rx_fifo_errors); \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, rx_missed_errors); \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, tx_aborted_errors); \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, tx_carrier_errors); \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, tx_fifo_errors); \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, tx_heartbeat_errors); \ + COPY_RTNL_LINK_VALUE(dst_stats, src_stats, tx_window_errors) #ifdef HAVE_RTNL_LINK_STATS64 -static void check_ignorelist_and_submit64 (const char *dev, - struct rtnl_link_stats64 *stats) -{ +static void check_ignorelist_and_submit64(const char *dev, + struct rtnl_link_stats64 *stats) { struct ir_link_stats_storage_s s; - COPY_RTNL_LINK_STATS (&s, stats); + COPY_RTNL_LINK_STATS(&s, stats); - check_ignorelist_and_submit (dev, &s); + check_ignorelist_and_submit(dev, &s); } #endif -static void check_ignorelist_and_submit32 (const char *dev, - struct rtnl_link_stats *stats) -{ +static void check_ignorelist_and_submit32(const char *dev, + struct rtnl_link_stats *stats) { struct ir_link_stats_storage_s s; COPY_RTNL_LINK_STATS(&s, stats); - check_ignorelist_and_submit (dev, &s); + check_ignorelist_and_submit(dev, &s); } -static int link_filter_cb (const struct nlmsghdr *nlh, - void *args __attribute__((unused))) -{ - struct ifinfomsg *ifm = mnl_nlmsg_get_payload (nlh); +static int link_filter_cb(const struct nlmsghdr *nlh, + void *args __attribute__((unused))) { + struct ifinfomsg *ifm = mnl_nlmsg_get_payload(nlh); struct nlattr *attr; const char *dev = NULL; union ir_link_stats_u stats; - if (nlh->nlmsg_type != RTM_NEWLINK) - { - ERROR ("netlink plugin: link_filter_cb: Don't know how to handle type %i.", - nlh->nlmsg_type); + if (nlh->nlmsg_type != RTM_NEWLINK) { + ERROR("netlink plugin: link_filter_cb: Don't know how to handle type %i.", + nlh->nlmsg_type); return MNL_CB_ERROR; } /* Scan attribute list for device name. */ - mnl_attr_for_each (attr, nlh, sizeof (*ifm)) - { - if (mnl_attr_get_type (attr) != IFLA_IFNAME) + mnl_attr_for_each(attr, nlh, sizeof(*ifm)) { + if (mnl_attr_get_type(attr) != IFLA_IFNAME) continue; - if (mnl_attr_validate (attr, MNL_TYPE_STRING) < 0) - { - ERROR ("netlink plugin: link_filter_cb: IFLA_IFNAME mnl_attr_validate failed."); + if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) { + ERROR("netlink plugin: link_filter_cb: IFLA_IFNAME mnl_attr_validate " + "failed."); return MNL_CB_ERROR; } - dev = mnl_attr_get_str (attr); - if (update_iflist (ifm, dev) < 0) + dev = mnl_attr_get_str(attr); + if (update_iflist(ifm, dev) < 0) return MNL_CB_ERROR; break; } - if (dev == NULL) - { - ERROR ("netlink plugin: link_filter_cb: dev == NULL"); + if (dev == NULL) { + ERROR("netlink plugin: link_filter_cb: dev == NULL"); return MNL_CB_ERROR; } #ifdef HAVE_RTNL_LINK_STATS64 - mnl_attr_for_each (attr, nlh, sizeof (*ifm)) - { - if (mnl_attr_get_type (attr) != IFLA_STATS64) + mnl_attr_for_each(attr, nlh, sizeof(*ifm)) { + if (mnl_attr_get_type(attr) != IFLA_STATS64) continue; - if (mnl_attr_validate2 (attr, MNL_TYPE_UNSPEC, sizeof (*stats.stats64)) < 0) - { - ERROR ("netlink plugin: link_filter_cb: IFLA_STATS64 mnl_attr_validate2 failed."); + if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(*stats.stats64)) < 0) { + ERROR("netlink plugin: link_filter_cb: IFLA_STATS64 mnl_attr_validate2 " + "failed."); return MNL_CB_ERROR; } - stats.stats64 = mnl_attr_get_payload (attr); + stats.stats64 = mnl_attr_get_payload(attr); - check_ignorelist_and_submit64 (dev, stats.stats64); + check_ignorelist_and_submit64(dev, stats.stats64); return MNL_CB_OK; } #endif - mnl_attr_for_each (attr, nlh, sizeof (*ifm)) - { - if (mnl_attr_get_type (attr) != IFLA_STATS) + mnl_attr_for_each(attr, nlh, sizeof(*ifm)) { + if (mnl_attr_get_type(attr) != IFLA_STATS) continue; - if (mnl_attr_validate2 (attr, MNL_TYPE_UNSPEC, sizeof (*stats.stats32)) < 0) - { - ERROR ("netlink plugin: link_filter_cb: IFLA_STATS mnl_attr_validate2 failed."); + if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(*stats.stats32)) < 0) { + ERROR("netlink plugin: link_filter_cb: IFLA_STATS mnl_attr_validate2 " + "failed."); return MNL_CB_ERROR; } - stats.stats32 = mnl_attr_get_payload (attr); + stats.stats32 = mnl_attr_get_payload(attr); - check_ignorelist_and_submit32 (dev, stats.stats32); + check_ignorelist_and_submit32(dev, stats.stats32); return MNL_CB_OK; } - DEBUG ("netlink plugin: link_filter: No statistics for interface %s.", dev); + DEBUG("netlink plugin: link_filter: No statistics for interface %s.", dev); return MNL_CB_OK; } /* int link_filter_cb */ #if HAVE_TCA_STATS2 -static int qos_attr_cb (const struct nlattr *attr, void *data) -{ +static int qos_attr_cb(const struct nlattr *attr, void *data) { struct gnet_stats_basic **bs = (struct gnet_stats_basic **)data; /* skip unsupported attribute in user-space */ - if (mnl_attr_type_valid (attr, TCA_STATS_MAX) < 0) + if (mnl_attr_type_valid(attr, TCA_STATS_MAX) < 0) return MNL_CB_OK; - if (mnl_attr_get_type (attr) == TCA_STATS_BASIC) - { - if (mnl_attr_validate2 (attr, MNL_TYPE_UNSPEC, sizeof (**bs)) < 0) - { - ERROR ("netlink plugin: qos_attr_cb: TCA_STATS_BASIC mnl_attr_validate2 failed."); + if (mnl_attr_get_type(attr) == TCA_STATS_BASIC) { + if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(**bs)) < 0) { + ERROR("netlink plugin: qos_attr_cb: TCA_STATS_BASIC mnl_attr_validate2 " + "failed."); return MNL_CB_ERROR; } - *bs = mnl_attr_get_payload (attr); + *bs = mnl_attr_get_payload(attr); return MNL_CB_STOP; } @@ -451,12 +407,11 @@ static int qos_attr_cb (const struct nlattr *attr, void *data) } /* qos_attr_cb */ #endif -static int qos_filter_cb (const struct nlmsghdr *nlh, void *args) -{ - struct tcmsg *tm = mnl_nlmsg_get_payload (nlh); +static int qos_filter_cb(const struct nlmsghdr *nlh, void *args) { + struct tcmsg *tm = mnl_nlmsg_get_payload(nlh); struct nlattr *attr; - int wanted_ifindex = *((int *) args); + int wanted_ifindex = *((int *)args); const char *dev; const char *kind = NULL; @@ -473,56 +428,48 @@ static int qos_filter_cb (const struct nlmsghdr *nlh, void *args) tc_type = "class"; else if (nlh->nlmsg_type == RTM_NEWTFILTER) tc_type = "filter"; - else - { - ERROR ("netlink plugin: qos_filter_cb: Don't know how to handle type %i.", - nlh->nlmsg_type); + else { + ERROR("netlink plugin: qos_filter_cb: Don't know how to handle type %i.", + nlh->nlmsg_type); return MNL_CB_ERROR; } - if (tm->tcm_ifindex != wanted_ifindex) - { - DEBUG ("netlink plugin: qos_filter_cb: Got %s for interface #%i, " - "but expected #%i.", - tc_type, tm->tcm_ifindex, wanted_ifindex); + if (tm->tcm_ifindex != wanted_ifindex) { + DEBUG("netlink plugin: qos_filter_cb: Got %s for interface #%i, " + "but expected #%i.", + tc_type, tm->tcm_ifindex, wanted_ifindex); return MNL_CB_OK; } - if ((tm->tcm_ifindex >= 0) - && ((size_t) tm->tcm_ifindex >= iflist_len)) - { - ERROR ("netlink plugin: qos_filter_cb: tm->tcm_ifindex = %i " - ">= iflist_len = %zu", - tm->tcm_ifindex, iflist_len); + if ((tm->tcm_ifindex >= 0) && ((size_t)tm->tcm_ifindex >= iflist_len)) { + ERROR("netlink plugin: qos_filter_cb: tm->tcm_ifindex = %i " + ">= iflist_len = %zu", + tm->tcm_ifindex, iflist_len); return MNL_CB_ERROR; } dev = iflist[tm->tcm_ifindex]; - if (dev == NULL) - { - ERROR ("netlink plugin: qos_filter_cb: iflist[%i] == NULL", - tm->tcm_ifindex); + if (dev == NULL) { + ERROR("netlink plugin: qos_filter_cb: iflist[%i] == NULL", tm->tcm_ifindex); return MNL_CB_ERROR; } - mnl_attr_for_each (attr, nlh, sizeof (*tm)) - { - if (mnl_attr_get_type (attr) != TCA_KIND) + mnl_attr_for_each(attr, nlh, sizeof(*tm)) { + if (mnl_attr_get_type(attr) != TCA_KIND) continue; - if (mnl_attr_validate (attr, MNL_TYPE_STRING) < 0) - { - ERROR ("netlink plugin: qos_filter_cb: TCA_KIND mnl_attr_validate failed."); + if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) { + ERROR( + "netlink plugin: qos_filter_cb: TCA_KIND mnl_attr_validate failed."); return MNL_CB_ERROR; } - kind = mnl_attr_get_str (attr); + kind = mnl_attr_get_str(attr); break; } - if (kind == NULL) - { - ERROR ("netlink plugin: qos_filter_cb: kind == NULL"); + if (kind == NULL) { + ERROR("netlink plugin: qos_filter_cb: kind == NULL"); return (-1); } @@ -530,48 +477,44 @@ static int qos_filter_cb (const struct nlmsghdr *nlh, void *args) uint32_t numberic_id; numberic_id = tm->tcm_handle; - if (strcmp (tc_type, "filter") == 0) + if (strcmp(tc_type, "filter") == 0) numberic_id = tm->tcm_parent; - ssnprintf (tc_inst, sizeof (tc_inst), "%s-%x:%x", - kind, - numberic_id >> 16, - numberic_id & 0x0000FFFF); + ssnprintf(tc_inst, sizeof(tc_inst), "%s-%x:%x", kind, numberic_id >> 16, + numberic_id & 0x0000FFFF); } - DEBUG ("netlink plugin: qos_filter_cb: got %s for %s (%i).", - tc_type, dev, tm->tcm_ifindex); + DEBUG("netlink plugin: qos_filter_cb: got %s for %s (%i).", tc_type, dev, + tm->tcm_ifindex); - if (check_ignorelist (dev, tc_type, tc_inst)) + if (check_ignorelist(dev, tc_type, tc_inst)) return MNL_CB_OK; #if HAVE_TCA_STATS2 - mnl_attr_for_each (attr, nlh, sizeof (*tm)) - { + mnl_attr_for_each(attr, nlh, sizeof(*tm)) { struct gnet_stats_basic *bs = NULL; - if (mnl_attr_get_type (attr) != TCA_STATS2) + if (mnl_attr_get_type(attr) != TCA_STATS2) continue; - if (mnl_attr_validate (attr, MNL_TYPE_NESTED) < 0) - { - ERROR ("netlink plugin: qos_filter_cb: TCA_STATS2 mnl_attr_validate failed."); + if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) { + ERROR("netlink plugin: qos_filter_cb: TCA_STATS2 mnl_attr_validate " + "failed."); return MNL_CB_ERROR; } - mnl_attr_parse_nested (attr, qos_attr_cb, &bs); + mnl_attr_parse_nested(attr, qos_attr_cb, &bs); - if (bs != NULL) - { + if (bs != NULL) { char type_instance[DATA_MAX_NAME_LEN]; stats_submitted = 1; - ssnprintf (type_instance, sizeof (type_instance), "%s-%s", - tc_type, tc_inst); + ssnprintf(type_instance, sizeof(type_instance), "%s-%s", tc_type, + tc_inst); - submit_one (dev, "ipt_bytes", type_instance, bs->bytes); - submit_one (dev, "ipt_packets", type_instance, bs->packets); + submit_one(dev, "ipt_bytes", type_instance, bs->bytes); + submit_one(dev, "ipt_packets", type_instance, bs->packets); } break; @@ -579,29 +522,27 @@ static int qos_filter_cb (const struct nlmsghdr *nlh, void *args) #endif /* TCA_STATS2 */ #if HAVE_TCA_STATS - mnl_attr_for_each (attr, nlh, sizeof (*tm)) - { + mnl_attr_for_each(attr, nlh, sizeof(*tm)) { struct tc_stats *ts = NULL; - if (mnl_attr_get_type (attr) != TCA_STATS) + if (mnl_attr_get_type(attr) != TCA_STATS) continue; - if (mnl_attr_validate2 (attr, MNL_TYPE_UNSPEC, sizeof (*ts)) < 0) - { - ERROR ("netlink plugin: qos_filter_cb: TCA_STATS mnl_attr_validate2 failed."); + if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(*ts)) < 0) { + ERROR("netlink plugin: qos_filter_cb: TCA_STATS mnl_attr_validate2 " + "failed."); return MNL_CB_ERROR; } - ts = mnl_attr_get_payload (attr); + ts = mnl_attr_get_payload(attr); - if (!stats_submitted && ts != NULL) - { + if (!stats_submitted && ts != NULL) { char type_instance[DATA_MAX_NAME_LEN]; - ssnprintf (type_instance, sizeof (type_instance), "%s-%s", - tc_type, tc_inst); + ssnprintf(type_instance, sizeof(type_instance), "%s-%s", tc_type, + tc_inst); - submit_one (dev, "ipt_bytes", type_instance, ts->bytes); - submit_one (dev, "ipt_packets", type_instance, ts->packets); + submit_one(dev, "ipt_bytes", type_instance, ts->bytes); + submit_one(dev, "ipt_packets", type_instance, ts->packets); } break; @@ -610,76 +551,62 @@ static int qos_filter_cb (const struct nlmsghdr *nlh, void *args) #endif /* TCA_STATS */ #if !(HAVE_TCA_STATS && HAVE_TCA_STATS2) - DEBUG ("netlink plugin: qos_filter_cb: Have neither TCA_STATS2 nor " - "TCA_STATS."); + DEBUG("netlink plugin: qos_filter_cb: Have neither TCA_STATS2 nor " + "TCA_STATS."); #endif return MNL_CB_OK; } /* int qos_filter_cb */ -static int ir_config (const char *key, const char *value) -{ +static int ir_config(const char *key, const char *value) { char *new_val; char *fields[8]; int fields_num; int status = 1; - new_val = strdup (value); + new_val = strdup(value); if (new_val == NULL) return (-1); - fields_num = strsplit (new_val, fields, STATIC_ARRAY_SIZE (fields)); - if ((fields_num < 1) || (fields_num > 8)) - { - sfree (new_val); + fields_num = strsplit(new_val, fields, STATIC_ARRAY_SIZE(fields)); + if ((fields_num < 1) || (fields_num > 8)) { + sfree(new_val); return (-1); } - if ((strcasecmp (key, "Interface") == 0) - || (strcasecmp (key, "VerboseInterface") == 0)) - { - if (fields_num != 1) - { - ERROR ("netlink plugin: Invalid number of fields for option " - "`%s'. Got %i, expected 1.", key, fields_num); + if ((strcasecmp(key, "Interface") == 0) || + (strcasecmp(key, "VerboseInterface") == 0)) { + if (fields_num != 1) { + ERROR("netlink plugin: Invalid number of fields for option " + "`%s'. Got %i, expected 1.", + key, fields_num); status = -1; - } - else - { - add_ignorelist (fields[0], "interface", NULL); - if (strcasecmp (key, "VerboseInterface") == 0) - add_ignorelist (fields[0], "if_detail", NULL); + } else { + add_ignorelist(fields[0], "interface", NULL); + if (strcasecmp(key, "VerboseInterface") == 0) + add_ignorelist(fields[0], "if_detail", NULL); status = 0; } - } - else if ((strcasecmp (key, "QDisc") == 0) - || (strcasecmp (key, "Class") == 0) - || (strcasecmp (key, "Filter") == 0)) - { - if ((fields_num < 1) || (fields_num > 2)) - { - ERROR ("netlink plugin: Invalid number of fields for option " - "`%s'. Got %i, expected 1 or 2.", key, fields_num); + } else if ((strcasecmp(key, "QDisc") == 0) || + (strcasecmp(key, "Class") == 0) || + (strcasecmp(key, "Filter") == 0)) { + if ((fields_num < 1) || (fields_num > 2)) { + ERROR("netlink plugin: Invalid number of fields for option " + "`%s'. Got %i, expected 1 or 2.", + key, fields_num); return (-1); - } - else - { - add_ignorelist (fields[0], key, - (fields_num == 2) ? fields[1] : NULL); + } else { + add_ignorelist(fields[0], key, (fields_num == 2) ? fields[1] : NULL); status = 0; } - } - else if (strcasecmp (key, "IgnoreSelected") == 0) - { - if (fields_num != 1) - { - ERROR ("netlink plugin: Invalid number of fields for option " - "`IgnoreSelected'. Got %i, expected 1.", fields_num); + } else if (strcasecmp(key, "IgnoreSelected") == 0) { + if (fields_num != 1) { + ERROR("netlink plugin: Invalid number of fields for option " + "`IgnoreSelected'. Got %i, expected 1.", + fields_num); status = -1; - } - else - { - if (IS_TRUE (fields[0])) + } else { + if (IS_TRUE(fields[0])) ir_ignorelist_invert = 0; else ir_ignorelist_invert = 1; @@ -687,141 +614,127 @@ static int ir_config (const char *key, const char *value) } } - sfree (new_val); + sfree(new_val); return (status); } /* int ir_config */ -static int ir_init (void) -{ - nl = mnl_socket_open (NETLINK_ROUTE); - if (nl == NULL) - { - ERROR ("netlink plugin: ir_init: mnl_socket_open failed."); +static int ir_init(void) { + nl = mnl_socket_open(NETLINK_ROUTE); + if (nl == NULL) { + ERROR("netlink plugin: ir_init: mnl_socket_open failed."); return (-1); } - if (mnl_socket_bind (nl, 0, MNL_SOCKET_AUTOPID) < 0) - { - ERROR ("netlink plugin: ir_init: mnl_socket_bind failed."); + if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { + ERROR("netlink plugin: ir_init: mnl_socket_bind failed."); return (-1); } return (0); } /* int ir_init */ -static int ir_read (void) -{ +static int ir_read(void) { char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; struct rtgenmsg *rt; int ret; unsigned int seq, portid; - static const int type_id[] = { RTM_GETQDISC, RTM_GETTCLASS, RTM_GETTFILTER }; - static const char *type_name[] = { "qdisc", "class", "filter" }; + static const int type_id[] = {RTM_GETQDISC, RTM_GETTCLASS, RTM_GETTFILTER}; + static const char *type_name[] = {"qdisc", "class", "filter"}; - portid = mnl_socket_get_portid (nl); + portid = mnl_socket_get_portid(nl); - nlh = mnl_nlmsg_put_header (buf); + nlh = mnl_nlmsg_put_header(buf); nlh->nlmsg_type = RTM_GETLINK; nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; - nlh->nlmsg_seq = seq = time (NULL); - rt = mnl_nlmsg_put_extra_header (nlh, sizeof (*rt)); + nlh->nlmsg_seq = seq = time(NULL); + rt = mnl_nlmsg_put_extra_header(nlh, sizeof(*rt)); rt->rtgen_family = AF_PACKET; - if (mnl_socket_sendto (nl, nlh, nlh->nlmsg_len) < 0) - { - ERROR ("netlink plugin: ir_read: rtnl_wilddump_request failed."); + if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { + ERROR("netlink plugin: ir_read: rtnl_wilddump_request failed."); return (-1); } - ret = mnl_socket_recvfrom (nl, buf, sizeof (buf)); - while (ret > 0) - { - ret = mnl_cb_run (buf, ret, seq, portid, link_filter_cb, NULL); + ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); + while (ret > 0) { + ret = mnl_cb_run(buf, ret, seq, portid, link_filter_cb, NULL); if (ret <= MNL_CB_STOP) break; - ret = mnl_socket_recvfrom (nl, buf, sizeof (buf)); + ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); } - if (ret < 0) - { - ERROR ("netlink plugin: ir_read: mnl_socket_recvfrom failed."); + if (ret < 0) { + ERROR("netlink plugin: ir_read: mnl_socket_recvfrom failed."); return (-1); } /* `link_filter_cb' will update `iflist' which is used here to iterate * over all interfaces. */ - for (size_t ifindex = 1; ifindex < iflist_len; ifindex++) - { + for (size_t ifindex = 1; ifindex < iflist_len; ifindex++) { struct tcmsg *tm; if (iflist[ifindex] == NULL) continue; - for (size_t type_index = 0; type_index < STATIC_ARRAY_SIZE (type_id); type_index++) - { - if (check_ignorelist (iflist[ifindex], type_name[type_index], NULL)) - { - DEBUG ("netlink plugin: ir_read: check_ignorelist (%s, %s, (nil)) " - "== TRUE", iflist[ifindex], type_name[type_index]); + for (size_t type_index = 0; type_index < STATIC_ARRAY_SIZE(type_id); + type_index++) { + if (check_ignorelist(iflist[ifindex], type_name[type_index], NULL)) { + DEBUG("netlink plugin: ir_read: check_ignorelist (%s, %s, (nil)) " + "== TRUE", + iflist[ifindex], type_name[type_index]); continue; } - DEBUG ("netlink plugin: ir_read: querying %s from %s (%zu).", - type_name[type_index], iflist[ifindex], ifindex); + DEBUG("netlink plugin: ir_read: querying %s from %s (%zu).", + type_name[type_index], iflist[ifindex], ifindex); - nlh = mnl_nlmsg_put_header (buf); + nlh = mnl_nlmsg_put_header(buf); nlh->nlmsg_type = type_id[type_index]; nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; - nlh->nlmsg_seq = seq = time (NULL); - tm = mnl_nlmsg_put_extra_header (nlh, sizeof (*tm)); + nlh->nlmsg_seq = seq = time(NULL); + tm = mnl_nlmsg_put_extra_header(nlh, sizeof(*tm)); tm->tcm_family = AF_PACKET; tm->tcm_ifindex = ifindex; - if (mnl_socket_sendto (nl, nlh, nlh->nlmsg_len) < 0) - { - ERROR ("netlink plugin: ir_read: mnl_socket_sendto failed."); + if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { + ERROR("netlink plugin: ir_read: mnl_socket_sendto failed."); continue; } - ret = mnl_socket_recvfrom (nl, buf, sizeof (buf)); - while (ret > 0) - { - ret = mnl_cb_run (buf, ret, seq, portid, qos_filter_cb, &ifindex); + ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); + while (ret > 0) { + ret = mnl_cb_run(buf, ret, seq, portid, qos_filter_cb, &ifindex); if (ret <= MNL_CB_STOP) break; - ret = mnl_socket_recvfrom (nl, buf, sizeof (buf)); + ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); } - if (ret < 0) - { - ERROR ("netlink plugin: ir_read:mnl_socket_recvfrom failed."); + if (ret < 0) { + ERROR("netlink plugin: ir_read:mnl_socket_recvfrom failed."); continue; } } /* for (type_index) */ - } /* for (if_index) */ + } /* for (if_index) */ return (0); } /* int ir_read */ -static int ir_shutdown (void) -{ - if (nl) - { - mnl_socket_close (nl); +static int ir_shutdown(void) { + if (nl) { + mnl_socket_close(nl); nl = NULL; } return (0); } /* int ir_shutdown */ -void module_register (void) -{ - plugin_register_config ("netlink", ir_config, config_keys, config_keys_num); - plugin_register_init ("netlink", ir_init); - plugin_register_read ("netlink", ir_read); - plugin_register_shutdown ("netlink", ir_shutdown); +void module_register(void) { + plugin_register_config("netlink", ir_config, config_keys, config_keys_num); + plugin_register_init("netlink", ir_init); + plugin_register_read("netlink", ir_read); + plugin_register_shutdown("netlink", ir_shutdown); } /* void module_register */ /* diff --git a/src/network.c b/src/network.c index d7eb32c3..8eab08b6 100644 --- a/src/network.c +++ b/src/network.c @@ -27,59 +27,59 @@ #include "collectd.h" -#include "plugin.h" #include "common.h" -#include "utils_fbhash.h" +#include "plugin.h" #include "utils_cache.h" #include "utils_complain.h" +#include "utils_fbhash.h" #include "network.h" #if HAVE_NETDB_H -# include +#include #endif #if HAVE_NETINET_IN_H -# include +#include #endif #if HAVE_ARPA_INET_H -# include +#include #endif #if HAVE_POLL_H -# include +#include #endif #if HAVE_NET_IF_H -# include +#include #endif #if HAVE_LIBGCRYPT -# if defined __APPLE__ +#if defined __APPLE__ /* default xcode compiler throws warnings even when deprecated functionality * is not used. -Werror breaks the build because of erroneous warnings. * http://stackoverflow.com/questions/10556299/compiler-warnings-with-libgcrypt-v1-5-0/12830209#12830209 */ -# pragma GCC diagnostic ignored "-Wdeprecated-declarations" -# endif +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif /* FreeBSD's copy of libgcrypt extends the existing GCRYPT_NO_DEPRECATED * to properly hide all deprecated functionality. * http://svnweb.freebsd.org/ports/head/security/libgcrypt/files/patch-src__gcrypt.h.in */ -# define GCRYPT_NO_DEPRECATED -# include -# if defined __APPLE__ +#define GCRYPT_NO_DEPRECATED +#include +#if defined __APPLE__ /* Re enable deprecation warnings */ -# pragma GCC diagnostic warning "-Wdeprecated-declarations" -# endif -# if GCRYPT_VERSION_NUMBER < 0x010600 +#pragma GCC diagnostic warning "-Wdeprecated-declarations" +#endif +#if GCRYPT_VERSION_NUMBER < 0x010600 GCRY_THREAD_OPTION_PTHREAD_IMPL; -# endif +#endif #endif #ifndef IPV6_ADD_MEMBERSHIP -# ifdef IPV6_JOIN_GROUP -# define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP -# else -# error "Neither IP_ADD_MEMBERSHIP nor IPV6_JOIN_GROUP is defined" -# endif +#ifdef IPV6_JOIN_GROUP +#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP +#else +#error "Neither IP_ADD_MEMBERSHIP nor IPV6_JOIN_GROUP is defined" +#endif #endif /* !IP_ADD_MEMBERSHIP */ /* @@ -95,56 +95,52 @@ GCRY_THREAD_OPTION_PTHREAD_IMPL; /* * Private data types */ -#define SECURITY_LEVEL_NONE 0 +#define SECURITY_LEVEL_NONE 0 #if HAVE_LIBGCRYPT -# define SECURITY_LEVEL_SIGN 1 -# define SECURITY_LEVEL_ENCRYPT 2 +#define SECURITY_LEVEL_SIGN 1 +#define SECURITY_LEVEL_ENCRYPT 2 #endif -struct sockent_client -{ - int fd; - struct sockaddr_storage *addr; - socklen_t addrlen; +struct sockent_client { + int fd; + struct sockaddr_storage *addr; + socklen_t addrlen; #if HAVE_LIBGCRYPT - int security_level; - char *username; - char *password; - gcry_cipher_hd_t cypher; - unsigned char password_hash[32]; + int security_level; + char *username; + char *password; + gcry_cipher_hd_t cypher; + unsigned char password_hash[32]; #endif - cdtime_t next_resolve_reconnect; - cdtime_t resolve_interval; + cdtime_t next_resolve_reconnect; + cdtime_t resolve_interval; }; -struct sockent_server -{ - int *fd; - size_t fd_num; +struct sockent_server { + int *fd; + size_t fd_num; #if HAVE_LIBGCRYPT - int security_level; - char *auth_file; - fbhash_t *userdb; - gcry_cipher_hd_t cypher; + int security_level; + char *auth_file; + fbhash_t *userdb; + gcry_cipher_hd_t cypher; #endif }; -typedef struct sockent -{ +typedef struct sockent { #define SOCKENT_TYPE_CLIENT 1 #define SOCKENT_TYPE_SERVER 2 - int type; + int type; - char *node; - char *service; - int interface; + char *node; + char *service; + int interface; - union - { - struct sockent_client client; - struct sockent_server server; - } data; + union { + struct sockent_client client; + struct sockent_server server; + } data; - struct sockent *next; + struct sockent *next; } sockent_t; /* 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 @@ -153,10 +149,9 @@ typedef struct sockent * ! Ver. ! ! Length ! * +-------+-----------------------+-------------------------------+ */ -struct part_header_s -{ - uint16_t type; - uint16_t length; +struct part_header_s { + uint16_t type; + uint16_t length; }; typedef struct part_header_s part_header_t; @@ -168,10 +163,9 @@ typedef struct part_header_s part_header_t; * : (Length - 4) Bytes : * +---------------------------------------------------------------+ */ -struct part_string_s -{ - part_header_t *head; - char *value; +struct part_string_s { + part_header_t *head; + char *value; }; typedef struct part_string_s part_string_t; @@ -183,10 +177,9 @@ typedef struct part_string_s part_string_t; * : (Length - 4 == 2 || 4 || 8) Bytes : * +---------------------------------------------------------------+ */ -struct part_number_s -{ - part_header_t *head; - uint64_t *value; +struct part_number_s { + part_header_t *head; + uint64_t *value; }; typedef struct part_number_s part_number_t; @@ -204,12 +197,11 @@ typedef struct part_number_s part_number_t; * ! ! * +---------------------------------------------------------------+ */ -struct part_values_s -{ - part_header_t *head; - uint16_t *num_values; - uint8_t *values_types; - value_t *values; +struct part_values_s { + part_header_t *head; + uint16_t *num_values; + uint8_t *values_types; + value_t *values; }; typedef struct part_values_s part_values_t; @@ -225,8 +217,7 @@ typedef struct part_values_s part_values_t; */ /* Minimum size */ #define PART_SIGNATURE_SHA256_SIZE 36 -struct part_signature_sha256_s -{ +struct part_signature_sha256_s { part_header_t head; unsigned char hash[32]; char *username; @@ -247,8 +238,7 @@ typedef struct part_signature_sha256_s part_signature_sha256_t; */ /* Minimum size */ #define PART_ENCRYPTION_AES256_SIZE 42 -struct part_encryption_aes256_s -{ +struct part_encryption_aes256_s { part_header_t head; uint16_t username_length; char *username; @@ -260,11 +250,10 @@ struct part_encryption_aes256_s }; typedef struct part_encryption_aes256_s part_encryption_aes256_t; -struct receive_list_entry_s -{ +struct receive_list_entry_s { char *data; - int data_len; - int fd; + int data_len; + int fd; struct receive_list_entry_s *next; }; typedef struct receive_list_entry_s receive_list_entry_t; @@ -282,29 +271,29 @@ static sockent_t *sending_sockets = NULL; static receive_list_entry_t *receive_list_head = NULL; static receive_list_entry_t *receive_list_tail = NULL; -static pthread_mutex_t receive_list_lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t receive_list_cond = PTHREAD_COND_INITIALIZER; -static uint64_t receive_list_length = 0; +static pthread_mutex_t receive_list_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t receive_list_cond = PTHREAD_COND_INITIALIZER; +static uint64_t receive_list_length = 0; -static sockent_t *listen_sockets = NULL; +static sockent_t *listen_sockets = NULL; static struct pollfd *listen_sockets_pollfd = NULL; -static size_t listen_sockets_num = 0; +static size_t listen_sockets_num = 0; /* The receive and dispatch threads will run as long as `listen_loop' is set to * zero. */ -static int listen_loop = 0; -static int receive_thread_running = 0; +static int listen_loop = 0; +static int receive_thread_running = 0; static pthread_t receive_thread_id; -static int dispatch_thread_running = 0; +static int dispatch_thread_running = 0; static pthread_t dispatch_thread_id; /* Buffer in which to-be-sent network packets are constructed. */ -static char *send_buffer; -static char *send_buffer_ptr; -static int send_buffer_fill; -static cdtime_t send_buffer_last_update; -static value_list_t send_buffer_vl = VALUE_LIST_INIT; -static pthread_mutex_t send_buffer_lock = PTHREAD_MUTEX_INITIALIZER; +static char *send_buffer; +static char *send_buffer_ptr; +static int send_buffer_fill; +static cdtime_t send_buffer_last_update; +static value_list_t send_buffer_vl = VALUE_LIST_INIT; +static pthread_mutex_t send_buffer_lock = PTHREAD_MUTEX_INITIALIZER; /* XXX: These counters are incremented from one place only. The spot in which * the values are incremented is either only reachable by one thread (the @@ -312,8 +301,8 @@ static pthread_mutex_t send_buffer_lock = PTHREAD_MUTEX_INITIALIZER; * example). Only if neither is true, the stats_lock is acquired. The counters * are always read without holding a lock in the hope that writing 8 bytes to * memory is an atomic operation. */ -static derive_t stats_octets_rx = 0; -static derive_t stats_octets_tx = 0; +static derive_t stats_octets_rx = 0; +static derive_t stats_octets_tx = 0; static derive_t stats_packets_rx = 0; static derive_t stats_packets_tx = 0; static derive_t stats_values_dispatched = 0; @@ -325,23 +314,22 @@ static pthread_mutex_t stats_lock = PTHREAD_MUTEX_INITIALIZER; /* * Private functions */ -static _Bool check_receive_okay (const value_list_t *vl) /* {{{ */ +static _Bool check_receive_okay(const value_list_t *vl) /* {{{ */ { uint64_t time_sent = 0; int status; - status = uc_meta_data_get_unsigned_int (vl, - "network:time_sent", &time_sent); + status = uc_meta_data_get_unsigned_int(vl, "network:time_sent", &time_sent); /* This is a value we already sent. Don't allow it to be received again in * order to avoid looping. */ - if ((status == 0) && (time_sent >= ((uint64_t) vl->time))) + if ((status == 0) && (time_sent >= ((uint64_t)vl->time))) return (0); return (1); } /* }}} _Bool check_receive_okay */ -static _Bool check_send_okay (const value_list_t *vl) /* {{{ */ +static _Bool check_send_okay(const value_list_t *vl) /* {{{ */ { _Bool received = 0; int status; @@ -352,13 +340,13 @@ static _Bool check_send_okay (const value_list_t *vl) /* {{{ */ if (vl->meta == NULL) return (1); - status = meta_data_get_boolean (vl->meta, "network:received", &received); + status = meta_data_get_boolean(vl->meta, "network:received", &received); if (status == -ENOENT) return (1); - else if (status != 0) - { - ERROR ("network plugin: check_send_okay: meta_data_get_boolean failed " - "with status %i.", status); + else if (status != 0) { + ERROR("network plugin: check_send_okay: meta_data_get_boolean failed " + "with status %i.", + status); return (1); } @@ -367,17 +355,17 @@ static _Bool check_send_okay (const value_list_t *vl) /* {{{ */ return (!received); } /* }}} _Bool check_send_okay */ -static _Bool check_notify_received (const notification_t *n) /* {{{ */ +static _Bool check_notify_received(const notification_t *n) /* {{{ */ { for (notification_meta_t *ptr = n->meta; ptr != NULL; ptr = ptr->next) - if ((strcmp ("network:received", ptr->name) == 0) - && (ptr->type == NM_TYPE_BOOLEAN)) - return ((_Bool) ptr->nm_value.nm_boolean); + if ((strcmp("network:received", ptr->name) == 0) && + (ptr->type == NM_TYPE_BOOLEAN)) + return ((_Bool)ptr->nm_value.nm_boolean); return (0); } /* }}} _Bool check_notify_received */ -static _Bool check_send_notify_okay (const notification_t *n) /* {{{ */ +static _Bool check_send_notify_okay(const notification_t *n) /* {{{ */ { static c_complain_t complain_forwarding = C_COMPLAIN_INIT_STATIC; _Bool received = 0; @@ -385,11 +373,11 @@ static _Bool check_send_notify_okay (const notification_t *n) /* {{{ */ if (n->meta == NULL) return (1); - received = check_notify_received (n); + received = check_notify_received(n); - if (network_config_forward && received) - { - c_complain_once (LOG_ERR, &complain_forwarding, + if (network_config_forward && received) { + c_complain_once( + LOG_ERR, &complain_forwarding, "network plugin: A notification has been received via the network " "and forwarding is enabled. Forwarding of notifications is currently " "not supported, because there is not loop-deteciton available. " @@ -402,200 +390,180 @@ static _Bool check_send_notify_okay (const notification_t *n) /* {{{ */ return (!received); } /* }}} _Bool check_send_notify_okay */ -static int network_dispatch_values (value_list_t *vl, /* {{{ */ - const char *username) -{ +static int network_dispatch_values(value_list_t *vl, /* {{{ */ + const char *username) { int status; - if ((vl->time == 0) - || (strlen (vl->host) == 0) - || (strlen (vl->plugin) == 0) - || (strlen (vl->type) == 0)) + if ((vl->time == 0) || (strlen(vl->host) == 0) || (strlen(vl->plugin) == 0) || + (strlen(vl->type) == 0)) return (-EINVAL); - if (!check_receive_okay (vl)) - { + if (!check_receive_okay(vl)) { #if COLLECT_DEBUG - char name[6*DATA_MAX_NAME_LEN]; - FORMAT_VL (name, sizeof (name), vl); - name[sizeof (name) - 1] = 0; - DEBUG ("network plugin: network_dispatch_values: " - "NOT dispatching %s.", name); + char name[6 * DATA_MAX_NAME_LEN]; + FORMAT_VL(name, sizeof(name), vl); + name[sizeof(name) - 1] = 0; + DEBUG("network plugin: network_dispatch_values: " + "NOT dispatching %s.", + name); #endif stats_values_not_dispatched++; return (0); } - assert (vl->meta == NULL); + assert(vl->meta == NULL); - vl->meta = meta_data_create (); - if (vl->meta == NULL) - { - ERROR ("network plugin: meta_data_create failed."); + vl->meta = meta_data_create(); + if (vl->meta == NULL) { + ERROR("network plugin: meta_data_create failed."); return (-ENOMEM); } - status = meta_data_add_boolean (vl->meta, "network:received", 1); - if (status != 0) - { - ERROR ("network plugin: meta_data_add_boolean failed."); - meta_data_destroy (vl->meta); + status = meta_data_add_boolean(vl->meta, "network:received", 1); + if (status != 0) { + ERROR("network plugin: meta_data_add_boolean failed."); + meta_data_destroy(vl->meta); vl->meta = NULL; return (status); } - if (username != NULL) - { - status = meta_data_add_string (vl->meta, "network:username", username); - if (status != 0) - { - ERROR ("network plugin: meta_data_add_string failed."); - meta_data_destroy (vl->meta); + if (username != NULL) { + status = meta_data_add_string(vl->meta, "network:username", username); + if (status != 0) { + ERROR("network plugin: meta_data_add_string failed."); + meta_data_destroy(vl->meta); vl->meta = NULL; return (status); } } - plugin_dispatch_values (vl); + plugin_dispatch_values(vl); stats_values_dispatched++; - meta_data_destroy (vl->meta); + meta_data_destroy(vl->meta); vl->meta = NULL; return (0); } /* }}} int network_dispatch_values */ -static int network_dispatch_notification (notification_t *n) /* {{{ */ +static int network_dispatch_notification(notification_t *n) /* {{{ */ { int status; - assert (n->meta == NULL); + assert(n->meta == NULL); - status = plugin_notification_meta_add_boolean (n, "network:received", 1); - if (status != 0) - { - ERROR ("network plugin: plugin_notification_meta_add_boolean failed."); - plugin_notification_meta_free (n->meta); + status = plugin_notification_meta_add_boolean(n, "network:received", 1); + if (status != 0) { + ERROR("network plugin: plugin_notification_meta_add_boolean failed."); + plugin_notification_meta_free(n->meta); n->meta = NULL; return (status); } - status = plugin_dispatch_notification (n); + status = plugin_dispatch_notification(n); - plugin_notification_meta_free (n->meta); + plugin_notification_meta_free(n->meta); n->meta = NULL; return (status); } /* }}} int network_dispatch_notification */ #if HAVE_LIBGCRYPT -static int network_init_gcrypt (void) /* {{{ */ +static int network_init_gcrypt(void) /* {{{ */ { gcry_error_t err; /* http://lists.gnupg.org/pipermail/gcrypt-devel/2003-August/000458.html * Because you can't know in a library whether another library has * already initialized the library */ - if (gcry_control (GCRYCTL_ANY_INITIALIZATION_P)) + if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P)) return (0); - /* http://www.gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html - * To ensure thread-safety, it's important to set GCRYCTL_SET_THREAD_CBS - * *before* initalizing Libgcrypt with gcry_check_version(), which itself must - * be called before any other gcry_* function. GCRYCTL_ANY_INITIALIZATION_P - * above doesn't count, as it doesn't implicitly initalize Libgcrypt. - * - * tl;dr: keep all these gry_* statements in this exact order please. */ -# if GCRYPT_VERSION_NUMBER < 0x010600 - err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); - if (err) - { - ERROR ("network plugin: gcry_control (GCRYCTL_SET_THREAD_CBS) failed: %s", gcry_strerror (err)); +/* http://www.gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html + * To ensure thread-safety, it's important to set GCRYCTL_SET_THREAD_CBS + * *before* initalizing Libgcrypt with gcry_check_version(), which itself must + * be called before any other gcry_* function. GCRYCTL_ANY_INITIALIZATION_P + * above doesn't count, as it doesn't implicitly initalize Libgcrypt. + * + * tl;dr: keep all these gry_* statements in this exact order please. */ +#if GCRYPT_VERSION_NUMBER < 0x010600 + err = gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); + if (err) { + ERROR("network plugin: gcry_control (GCRYCTL_SET_THREAD_CBS) failed: %s", + gcry_strerror(err)); return (-1); } -# endif +#endif - gcry_check_version (NULL); + gcry_check_version(NULL); - err = gcry_control (GCRYCTL_INIT_SECMEM, 32768); - if (err) - { - ERROR ("network plugin: gcry_control (GCRYCTL_INIT_SECMEM) failed: %s", gcry_strerror (err)); + err = gcry_control(GCRYCTL_INIT_SECMEM, 32768); + if (err) { + ERROR("network plugin: gcry_control (GCRYCTL_INIT_SECMEM) failed: %s", + gcry_strerror(err)); return (-1); } - gcry_control (GCRYCTL_INITIALIZATION_FINISHED); + gcry_control(GCRYCTL_INITIALIZATION_FINISHED); return (0); } /* }}} int network_init_gcrypt */ -static gcry_cipher_hd_t network_get_aes256_cypher (sockent_t *se, /* {{{ */ - const void *iv, size_t iv_size, const char *username) -{ +static gcry_cipher_hd_t network_get_aes256_cypher(sockent_t *se, /* {{{ */ + const void *iv, + size_t iv_size, + const char *username) { gcry_error_t err; gcry_cipher_hd_t *cyper_ptr; unsigned char password_hash[32]; - if (se->type == SOCKENT_TYPE_CLIENT) - { - cyper_ptr = &se->data.client.cypher; - memcpy (password_hash, se->data.client.password_hash, - sizeof (password_hash)); - } - else - { - char *secret; + if (se->type == SOCKENT_TYPE_CLIENT) { + cyper_ptr = &se->data.client.cypher; + memcpy(password_hash, se->data.client.password_hash, sizeof(password_hash)); + } else { + char *secret; - cyper_ptr = &se->data.server.cypher; + cyper_ptr = &se->data.server.cypher; - if (username == NULL) - return (NULL); + if (username == NULL) + return (NULL); - secret = fbh_get (se->data.server.userdb, username); - if (secret == NULL) - return (NULL); + secret = fbh_get(se->data.server.userdb, username); + if (secret == NULL) + return (NULL); - gcry_md_hash_buffer (GCRY_MD_SHA256, - password_hash, - secret, strlen (secret)); + gcry_md_hash_buffer(GCRY_MD_SHA256, password_hash, secret, strlen(secret)); - sfree (secret); + sfree(secret); } - if (*cyper_ptr == NULL) - { - err = gcry_cipher_open (cyper_ptr, - GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB, /* flags = */ 0); - if (err != 0) - { - ERROR ("network plugin: gcry_cipher_open returned: %s", - gcry_strerror (err)); + if (*cyper_ptr == NULL) { + err = gcry_cipher_open(cyper_ptr, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB, + /* flags = */ 0); + if (err != 0) { + ERROR("network plugin: gcry_cipher_open returned: %s", + gcry_strerror(err)); *cyper_ptr = NULL; return (NULL); } + } else { + gcry_cipher_reset(*cyper_ptr); } - else - { - gcry_cipher_reset (*cyper_ptr); - } - assert (*cyper_ptr != NULL); + assert(*cyper_ptr != NULL); - err = gcry_cipher_setkey (*cyper_ptr, - password_hash, sizeof (password_hash)); - if (err != 0) - { - ERROR ("network plugin: gcry_cipher_setkey returned: %s", - gcry_strerror (err)); - gcry_cipher_close (*cyper_ptr); + err = gcry_cipher_setkey(*cyper_ptr, password_hash, sizeof(password_hash)); + if (err != 0) { + ERROR("network plugin: gcry_cipher_setkey returned: %s", + gcry_strerror(err)); + gcry_cipher_close(*cyper_ptr); *cyper_ptr = NULL; return (NULL); } - err = gcry_cipher_setiv (*cyper_ptr, iv, iv_size); - if (err != 0) - { - ERROR ("network plugin: gcry_cipher_setkey returned: %s", - gcry_strerror (err)); - gcry_cipher_close (*cyper_ptr); + err = gcry_cipher_setiv(*cyper_ptr, iv, iv_size); + if (err != 0) { + ERROR("network plugin: gcry_cipher_setkey returned: %s", + gcry_strerror(err)); + gcry_cipher_close(*cyper_ptr); *cyper_ptr = NULL; return (NULL); } @@ -604,437 +572,416 @@ static gcry_cipher_hd_t network_get_aes256_cypher (sockent_t *se, /* {{{ */ } /* }}} int network_get_aes256_cypher */ #endif /* HAVE_LIBGCRYPT */ -static int write_part_values (char **ret_buffer, size_t *ret_buffer_len, - const data_set_t *ds, const value_list_t *vl) -{ - char *packet_ptr; - size_t packet_len; - int num_values; - - part_header_t pkg_ph; - uint16_t pkg_num_values; - uint8_t *pkg_values_types; - value_t *pkg_values; - - size_t offset; - - num_values = vl->values_len; - packet_len = sizeof (part_header_t) + sizeof (uint16_t) - + (num_values * sizeof (uint8_t)) - + (num_values * sizeof (value_t)); - - if (*ret_buffer_len < packet_len) - return (-1); - - pkg_values_types = malloc (num_values * sizeof (*pkg_values_types)); - if (pkg_values_types == NULL) - { - ERROR ("network plugin: write_part_values: malloc failed."); - return (-1); - } - - pkg_values = malloc (num_values * sizeof (*pkg_values)); - if (pkg_values == NULL) - { - free (pkg_values_types); - ERROR ("network plugin: write_part_values: malloc failed."); - return (-1); - } - - pkg_ph.type = htons (TYPE_VALUES); - pkg_ph.length = htons (packet_len); - - pkg_num_values = htons ((uint16_t) vl->values_len); - - for (int i = 0; i < num_values; i++) - { - pkg_values_types[i] = (uint8_t) ds->ds[i].type; - switch (ds->ds[i].type) - { - case DS_TYPE_COUNTER: - pkg_values[i].counter = htonll (vl->values[i].counter); - break; - - case DS_TYPE_GAUGE: - pkg_values[i].gauge = htond (vl->values[i].gauge); - break; - - case DS_TYPE_DERIVE: - pkg_values[i].derive = htonll (vl->values[i].derive); - break; - - case DS_TYPE_ABSOLUTE: - pkg_values[i].absolute = htonll (vl->values[i].absolute); - break; - - default: - free (pkg_values_types); - free (pkg_values); - ERROR ("network plugin: write_part_values: " - "Unknown data source type: %i", - ds->ds[i].type); - return (-1); - } /* switch (ds->ds[i].type) */ - } /* for (num_values) */ - - /* - * Use `memcpy' to write everything to the buffer, because the pointer - * may be unaligned and some architectures, such as SPARC, can't handle - * that. - */ - packet_ptr = *ret_buffer; - offset = 0; - memcpy (packet_ptr + offset, &pkg_ph, sizeof (pkg_ph)); - offset += sizeof (pkg_ph); - memcpy (packet_ptr + offset, &pkg_num_values, sizeof (pkg_num_values)); - offset += sizeof (pkg_num_values); - memcpy (packet_ptr + offset, pkg_values_types, num_values * sizeof (uint8_t)); - offset += num_values * sizeof (uint8_t); - memcpy (packet_ptr + offset, pkg_values, num_values * sizeof (value_t)); - offset += num_values * sizeof (value_t); - - assert (offset == packet_len); - - *ret_buffer = packet_ptr + packet_len; - *ret_buffer_len -= packet_len; - - free (pkg_values_types); - free (pkg_values); - - return (0); +static int write_part_values(char **ret_buffer, size_t *ret_buffer_len, + const data_set_t *ds, const value_list_t *vl) { + char *packet_ptr; + size_t packet_len; + int num_values; + + part_header_t pkg_ph; + uint16_t pkg_num_values; + uint8_t *pkg_values_types; + value_t *pkg_values; + + size_t offset; + + num_values = vl->values_len; + packet_len = sizeof(part_header_t) + sizeof(uint16_t) + + (num_values * sizeof(uint8_t)) + (num_values * sizeof(value_t)); + + if (*ret_buffer_len < packet_len) + return (-1); + + pkg_values_types = malloc(num_values * sizeof(*pkg_values_types)); + if (pkg_values_types == NULL) { + ERROR("network plugin: write_part_values: malloc failed."); + return (-1); + } + + pkg_values = malloc(num_values * sizeof(*pkg_values)); + if (pkg_values == NULL) { + free(pkg_values_types); + ERROR("network plugin: write_part_values: malloc failed."); + return (-1); + } + + pkg_ph.type = htons(TYPE_VALUES); + pkg_ph.length = htons(packet_len); + + pkg_num_values = htons((uint16_t)vl->values_len); + + for (int i = 0; i < num_values; i++) { + pkg_values_types[i] = (uint8_t)ds->ds[i].type; + switch (ds->ds[i].type) { + case DS_TYPE_COUNTER: + pkg_values[i].counter = htonll(vl->values[i].counter); + break; + + case DS_TYPE_GAUGE: + pkg_values[i].gauge = htond(vl->values[i].gauge); + break; + + case DS_TYPE_DERIVE: + pkg_values[i].derive = htonll(vl->values[i].derive); + break; + + case DS_TYPE_ABSOLUTE: + pkg_values[i].absolute = htonll(vl->values[i].absolute); + break; + + default: + free(pkg_values_types); + free(pkg_values); + ERROR("network plugin: write_part_values: " + "Unknown data source type: %i", + ds->ds[i].type); + return (-1); + } /* switch (ds->ds[i].type) */ + } /* for (num_values) */ + + /* + * Use `memcpy' to write everything to the buffer, because the pointer + * may be unaligned and some architectures, such as SPARC, can't handle + * that. + */ + packet_ptr = *ret_buffer; + offset = 0; + memcpy(packet_ptr + offset, &pkg_ph, sizeof(pkg_ph)); + offset += sizeof(pkg_ph); + memcpy(packet_ptr + offset, &pkg_num_values, sizeof(pkg_num_values)); + offset += sizeof(pkg_num_values); + memcpy(packet_ptr + offset, pkg_values_types, num_values * sizeof(uint8_t)); + offset += num_values * sizeof(uint8_t); + memcpy(packet_ptr + offset, pkg_values, num_values * sizeof(value_t)); + offset += num_values * sizeof(value_t); + + assert(offset == packet_len); + + *ret_buffer = packet_ptr + packet_len; + *ret_buffer_len -= packet_len; + + free(pkg_values_types); + free(pkg_values); + + return (0); } /* int write_part_values */ -static int write_part_number (char **ret_buffer, size_t *ret_buffer_len, - int type, uint64_t value) -{ - char *packet_ptr; - size_t packet_len; +static int write_part_number(char **ret_buffer, size_t *ret_buffer_len, + int type, uint64_t value) { + char *packet_ptr; + size_t packet_len; - part_header_t pkg_head; - uint64_t pkg_value; + part_header_t pkg_head; + uint64_t pkg_value; - size_t offset; + size_t offset; - packet_len = sizeof (pkg_head) + sizeof (pkg_value); + packet_len = sizeof(pkg_head) + sizeof(pkg_value); - if (*ret_buffer_len < packet_len) - return (-1); + if (*ret_buffer_len < packet_len) + return (-1); - pkg_head.type = htons (type); - pkg_head.length = htons (packet_len); - pkg_value = htonll (value); + pkg_head.type = htons(type); + pkg_head.length = htons(packet_len); + pkg_value = htonll(value); - packet_ptr = *ret_buffer; - offset = 0; - memcpy (packet_ptr + offset, &pkg_head, sizeof (pkg_head)); - offset += sizeof (pkg_head); - memcpy (packet_ptr + offset, &pkg_value, sizeof (pkg_value)); - offset += sizeof (pkg_value); + packet_ptr = *ret_buffer; + offset = 0; + memcpy(packet_ptr + offset, &pkg_head, sizeof(pkg_head)); + offset += sizeof(pkg_head); + memcpy(packet_ptr + offset, &pkg_value, sizeof(pkg_value)); + offset += sizeof(pkg_value); - assert (offset == packet_len); + assert(offset == packet_len); - *ret_buffer = packet_ptr + packet_len; - *ret_buffer_len -= packet_len; + *ret_buffer = packet_ptr + packet_len; + *ret_buffer_len -= packet_len; - return (0); + return (0); } /* int write_part_number */ -static int write_part_string (char **ret_buffer, size_t *ret_buffer_len, - int type, const char *str, size_t str_len) -{ - char *buffer; - size_t buffer_len; - - uint16_t pkg_type; - uint16_t pkg_length; +static int write_part_string(char **ret_buffer, size_t *ret_buffer_len, + int type, const char *str, size_t str_len) { + char *buffer; + size_t buffer_len; - size_t offset; + uint16_t pkg_type; + uint16_t pkg_length; - buffer_len = 2 * sizeof (uint16_t) + str_len + 1; - if (*ret_buffer_len < buffer_len) - return (-1); + size_t offset; - pkg_type = htons (type); - pkg_length = htons (buffer_len); + buffer_len = 2 * sizeof(uint16_t) + str_len + 1; + if (*ret_buffer_len < buffer_len) + return (-1); - buffer = *ret_buffer; - offset = 0; - memcpy (buffer + offset, (void *) &pkg_type, sizeof (pkg_type)); - offset += sizeof (pkg_type); - memcpy (buffer + offset, (void *) &pkg_length, sizeof (pkg_length)); - offset += sizeof (pkg_length); - memcpy (buffer + offset, str, str_len); - offset += str_len; - memset (buffer + offset, '\0', 1); - offset += 1; + pkg_type = htons(type); + pkg_length = htons(buffer_len); - assert (offset == buffer_len); + buffer = *ret_buffer; + offset = 0; + memcpy(buffer + offset, (void *)&pkg_type, sizeof(pkg_type)); + offset += sizeof(pkg_type); + memcpy(buffer + offset, (void *)&pkg_length, sizeof(pkg_length)); + offset += sizeof(pkg_length); + memcpy(buffer + offset, str, str_len); + offset += str_len; + memset(buffer + offset, '\0', 1); + offset += 1; + + assert(offset == buffer_len); - *ret_buffer = buffer + buffer_len; - *ret_buffer_len -= buffer_len; + *ret_buffer = buffer + buffer_len; + *ret_buffer_len -= buffer_len; - return (0); + return (0); } /* int write_part_string */ -static int parse_part_values (void **ret_buffer, size_t *ret_buffer_len, - value_t **ret_values, size_t *ret_num_values) -{ - char *buffer = *ret_buffer; - size_t buffer_len = *ret_buffer_len; - - uint16_t tmp16; - size_t exp_size; - - uint16_t pkg_length; - uint16_t pkg_type; - size_t pkg_numval; - - uint8_t *pkg_types; - value_t *pkg_values; - - if (buffer_len < 15) - { - NOTICE ("network plugin: packet is too short: " - "buffer_len = %zu", buffer_len); - return (-1); - } - - memcpy ((void *) &tmp16, buffer, sizeof (tmp16)); - buffer += sizeof (tmp16); - pkg_type = ntohs (tmp16); - - memcpy ((void *) &tmp16, buffer, sizeof (tmp16)); - buffer += sizeof (tmp16); - pkg_length = ntohs (tmp16); - - memcpy ((void *) &tmp16, buffer, sizeof (tmp16)); - buffer += sizeof (tmp16); - pkg_numval = (size_t) ntohs (tmp16); - - assert (pkg_type == TYPE_VALUES); - - exp_size = 3 * sizeof (uint16_t) - + pkg_numval * (sizeof (uint8_t) + sizeof (value_t)); - if (buffer_len < exp_size) - { - WARNING ("network plugin: parse_part_values: " - "Packet too short: " - "Chunk of size %zu expected, " - "but buffer has only %zu bytes left.", - exp_size, buffer_len); - return (-1); - } - assert (pkg_numval <= ((buffer_len - 6) / 9)); - - if (pkg_length != exp_size) - { - WARNING ("network plugin: parse_part_values: " - "Length and number of values " - "in the packet don't match."); - return (-1); - } - - pkg_types = calloc (pkg_numval, sizeof (*pkg_types)); - pkg_values = calloc (pkg_numval, sizeof (*pkg_values)); - if ((pkg_types == NULL) || (pkg_values == NULL)) - { - sfree (pkg_types); - sfree (pkg_values); - ERROR ("network plugin: parse_part_values: calloc failed."); - return (-1); - } - - memcpy (pkg_types, buffer, pkg_numval * sizeof (*pkg_types)); - buffer += pkg_numval * sizeof (*pkg_types); - memcpy (pkg_values, buffer, pkg_numval * sizeof (*pkg_values)); - buffer += pkg_numval * sizeof (*pkg_values); - - for (size_t i = 0; i < pkg_numval; i++) - { - switch (pkg_types[i]) - { - case DS_TYPE_COUNTER: - pkg_values[i].counter = (counter_t) ntohll (pkg_values[i].counter); - break; - - case DS_TYPE_GAUGE: - pkg_values[i].gauge = (gauge_t) ntohd (pkg_values[i].gauge); - break; - - case DS_TYPE_DERIVE: - pkg_values[i].derive = (derive_t) ntohll (pkg_values[i].derive); - break; - - case DS_TYPE_ABSOLUTE: - pkg_values[i].absolute = (absolute_t) ntohll (pkg_values[i].absolute); - break; - - default: - NOTICE ("network plugin: parse_part_values: " - "Don't know how to handle data source type %"PRIu8, - pkg_types[i]); - sfree (pkg_types); - sfree (pkg_values); - return (-1); - } /* switch (pkg_types[i]) */ - } - - *ret_buffer = buffer; - *ret_buffer_len = buffer_len - pkg_length; - *ret_num_values = pkg_numval; - *ret_values = pkg_values; - - sfree (pkg_types); - - return (0); +static int parse_part_values(void **ret_buffer, size_t *ret_buffer_len, + value_t **ret_values, size_t *ret_num_values) { + char *buffer = *ret_buffer; + size_t buffer_len = *ret_buffer_len; + + uint16_t tmp16; + size_t exp_size; + + uint16_t pkg_length; + uint16_t pkg_type; + size_t pkg_numval; + + uint8_t *pkg_types; + value_t *pkg_values; + + if (buffer_len < 15) { + NOTICE("network plugin: packet is too short: " + "buffer_len = %zu", + buffer_len); + return (-1); + } + + memcpy((void *)&tmp16, buffer, sizeof(tmp16)); + buffer += sizeof(tmp16); + pkg_type = ntohs(tmp16); + + memcpy((void *)&tmp16, buffer, sizeof(tmp16)); + buffer += sizeof(tmp16); + pkg_length = ntohs(tmp16); + + memcpy((void *)&tmp16, buffer, sizeof(tmp16)); + buffer += sizeof(tmp16); + pkg_numval = (size_t)ntohs(tmp16); + + assert(pkg_type == TYPE_VALUES); + + exp_size = + 3 * sizeof(uint16_t) + pkg_numval * (sizeof(uint8_t) + sizeof(value_t)); + if (buffer_len < exp_size) { + WARNING("network plugin: parse_part_values: " + "Packet too short: " + "Chunk of size %zu expected, " + "but buffer has only %zu bytes left.", + exp_size, buffer_len); + return (-1); + } + assert(pkg_numval <= ((buffer_len - 6) / 9)); + + if (pkg_length != exp_size) { + WARNING("network plugin: parse_part_values: " + "Length and number of values " + "in the packet don't match."); + return (-1); + } + + pkg_types = calloc(pkg_numval, sizeof(*pkg_types)); + pkg_values = calloc(pkg_numval, sizeof(*pkg_values)); + if ((pkg_types == NULL) || (pkg_values == NULL)) { + sfree(pkg_types); + sfree(pkg_values); + ERROR("network plugin: parse_part_values: calloc failed."); + return (-1); + } + + memcpy(pkg_types, buffer, pkg_numval * sizeof(*pkg_types)); + buffer += pkg_numval * sizeof(*pkg_types); + memcpy(pkg_values, buffer, pkg_numval * sizeof(*pkg_values)); + buffer += pkg_numval * sizeof(*pkg_values); + + for (size_t i = 0; i < pkg_numval; i++) { + switch (pkg_types[i]) { + case DS_TYPE_COUNTER: + pkg_values[i].counter = (counter_t)ntohll(pkg_values[i].counter); + break; + + case DS_TYPE_GAUGE: + pkg_values[i].gauge = (gauge_t)ntohd(pkg_values[i].gauge); + break; + + case DS_TYPE_DERIVE: + pkg_values[i].derive = (derive_t)ntohll(pkg_values[i].derive); + break; + + case DS_TYPE_ABSOLUTE: + pkg_values[i].absolute = (absolute_t)ntohll(pkg_values[i].absolute); + break; + + default: + NOTICE("network plugin: parse_part_values: " + "Don't know how to handle data source type %" PRIu8, + pkg_types[i]); + sfree(pkg_types); + sfree(pkg_values); + return (-1); + } /* switch (pkg_types[i]) */ + } + + *ret_buffer = buffer; + *ret_buffer_len = buffer_len - pkg_length; + *ret_num_values = pkg_numval; + *ret_values = pkg_values; + + sfree(pkg_types); + + return (0); } /* int parse_part_values */ -static int parse_part_number (void **ret_buffer, size_t *ret_buffer_len, - uint64_t *value) -{ - char *buffer = *ret_buffer; - size_t buffer_len = *ret_buffer_len; +static int parse_part_number(void **ret_buffer, size_t *ret_buffer_len, + uint64_t *value) { + char *buffer = *ret_buffer; + size_t buffer_len = *ret_buffer_len; - uint16_t tmp16; - uint64_t tmp64; - size_t exp_size = 2 * sizeof (uint16_t) + sizeof (uint64_t); + uint16_t tmp16; + uint64_t tmp64; + size_t exp_size = 2 * sizeof(uint16_t) + sizeof(uint64_t); - uint16_t pkg_length; + uint16_t pkg_length; - if (buffer_len < exp_size) - { - WARNING ("network plugin: parse_part_number: " - "Packet too short: " - "Chunk of size %zu expected, " - "but buffer has only %zu bytes left.", - exp_size, buffer_len); - return (-1); - } + if (buffer_len < exp_size) { + WARNING("network plugin: parse_part_number: " + "Packet too short: " + "Chunk of size %zu expected, " + "but buffer has only %zu bytes left.", + exp_size, buffer_len); + return (-1); + } - memcpy ((void *) &tmp16, buffer, sizeof (tmp16)); - buffer += sizeof (tmp16); - /* pkg_type = ntohs (tmp16); */ + memcpy((void *)&tmp16, buffer, sizeof(tmp16)); + buffer += sizeof(tmp16); + /* pkg_type = ntohs (tmp16); */ - memcpy ((void *) &tmp16, buffer, sizeof (tmp16)); - buffer += sizeof (tmp16); - pkg_length = ntohs (tmp16); + memcpy((void *)&tmp16, buffer, sizeof(tmp16)); + buffer += sizeof(tmp16); + pkg_length = ntohs(tmp16); - memcpy ((void *) &tmp64, buffer, sizeof (tmp64)); - buffer += sizeof (tmp64); - *value = ntohll (tmp64); + memcpy((void *)&tmp64, buffer, sizeof(tmp64)); + buffer += sizeof(tmp64); + *value = ntohll(tmp64); - *ret_buffer = buffer; - *ret_buffer_len = buffer_len - pkg_length; + *ret_buffer = buffer; + *ret_buffer_len = buffer_len - pkg_length; - return (0); + return (0); } /* int parse_part_number */ -static int parse_part_string (void **ret_buffer, size_t *ret_buffer_len, - char *output, size_t const output_len) -{ - char *buffer = *ret_buffer; - size_t buffer_len = *ret_buffer_len; - - uint16_t tmp16; - size_t const header_size = 2 * sizeof (uint16_t); - - uint16_t pkg_length; - size_t payload_size; - - if (output_len == 0) - return (EINVAL); - - if (buffer_len < header_size) - { - WARNING ("network plugin: parse_part_string: " - "Packet too short: " - "Chunk of at least size %zu expected, " - "but buffer has only %zu bytes left.", - header_size, buffer_len); - return (-1); - } - - memcpy ((void *) &tmp16, buffer, sizeof (tmp16)); - buffer += sizeof (tmp16); - /* pkg_type = ntohs (tmp16); */ - - memcpy ((void *) &tmp16, buffer, sizeof (tmp16)); - buffer += sizeof (tmp16); - pkg_length = ntohs (tmp16); - payload_size = ((size_t) pkg_length) - header_size; - - /* Check that packet fits in the input buffer */ - if (pkg_length > buffer_len) - { - WARNING ("network plugin: parse_part_string: " - "Packet too big: " - "Chunk of size %"PRIu16" received, " - "but buffer has only %zu bytes left.", - pkg_length, buffer_len); - return (-1); - } - - /* Check that pkg_length is in the valid range */ - if (pkg_length <= header_size) - { - WARNING ("network plugin: parse_part_string: " - "Packet too short: " - "Header claims this packet is only %hu " - "bytes long.", pkg_length); - return (-1); - } - - /* Check that the package data fits into the output buffer. - * The previous if-statement ensures that: - * `pkg_length > header_size' */ - if (output_len < payload_size) - { - WARNING ("network plugin: parse_part_string: " - "Buffer too small: " - "Output buffer holds %zu bytes, " - "which is too small to hold the received " - "%zu byte string.", - output_len, payload_size); - return (-1); - } - - /* All sanity checks successfull, let's copy the data over */ - memcpy ((void *) output, (void *) buffer, payload_size); - buffer += payload_size; - - /* For some very weird reason '\0' doesn't do the trick on SPARC in - * this statement. */ - if (output[payload_size - 1] != 0) - { - WARNING ("network plugin: parse_part_string: " - "Received string does not end " - "with a NULL-byte."); - return (-1); - } - - *ret_buffer = buffer; - *ret_buffer_len = buffer_len - pkg_length; - - return (0); +static int parse_part_string(void **ret_buffer, size_t *ret_buffer_len, + char *output, size_t const output_len) { + char *buffer = *ret_buffer; + size_t buffer_len = *ret_buffer_len; + + uint16_t tmp16; + size_t const header_size = 2 * sizeof(uint16_t); + + uint16_t pkg_length; + size_t payload_size; + + if (output_len == 0) + return (EINVAL); + + if (buffer_len < header_size) { + WARNING("network plugin: parse_part_string: " + "Packet too short: " + "Chunk of at least size %zu expected, " + "but buffer has only %zu bytes left.", + header_size, buffer_len); + return (-1); + } + + memcpy((void *)&tmp16, buffer, sizeof(tmp16)); + buffer += sizeof(tmp16); + /* pkg_type = ntohs (tmp16); */ + + memcpy((void *)&tmp16, buffer, sizeof(tmp16)); + buffer += sizeof(tmp16); + pkg_length = ntohs(tmp16); + payload_size = ((size_t)pkg_length) - header_size; + + /* Check that packet fits in the input buffer */ + if (pkg_length > buffer_len) { + WARNING("network plugin: parse_part_string: " + "Packet too big: " + "Chunk of size %" PRIu16 " received, " + "but buffer has only %zu bytes left.", + pkg_length, buffer_len); + return (-1); + } + + /* Check that pkg_length is in the valid range */ + if (pkg_length <= header_size) { + WARNING("network plugin: parse_part_string: " + "Packet too short: " + "Header claims this packet is only %hu " + "bytes long.", + pkg_length); + return (-1); + } + + /* Check that the package data fits into the output buffer. + * The previous if-statement ensures that: + * `pkg_length > header_size' */ + if (output_len < payload_size) { + WARNING("network plugin: parse_part_string: " + "Buffer too small: " + "Output buffer holds %zu bytes, " + "which is too small to hold the received " + "%zu byte string.", + output_len, payload_size); + return (-1); + } + + /* All sanity checks successfull, let's copy the data over */ + memcpy((void *)output, (void *)buffer, payload_size); + buffer += payload_size; + + /* For some very weird reason '\0' doesn't do the trick on SPARC in + * this statement. */ + if (output[payload_size - 1] != 0) { + WARNING("network plugin: parse_part_string: " + "Received string does not end " + "with a NULL-byte."); + return (-1); + } + + *ret_buffer = buffer; + *ret_buffer_len = buffer_len - pkg_length; + + return (0); } /* int parse_part_string */ /* Forward declaration: parse_part_sign_sha256 and parse_part_encr_aes256 call * parse_packet and vice versa. */ -#define PP_SIGNED 0x01 +#define PP_SIGNED 0x01 #define PP_ENCRYPTED 0x02 -static int parse_packet (sockent_t *se, - void *buffer, size_t buffer_size, int flags, - const char *username); +static int parse_packet(sockent_t *se, void *buffer, size_t buffer_size, + int flags, const char *username); -#define BUFFER_READ(p,s) do { \ - memcpy ((p), buffer + buffer_offset, (s)); \ - buffer_offset += (s); \ -} while (0) +#define BUFFER_READ(p, s) \ + do { \ + memcpy((p), buffer + buffer_offset, (s)); \ + buffer_offset += (s); \ + } while (0) #if HAVE_LIBGCRYPT -static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */ - void **ret_buffer, size_t *ret_buffer_len, int flags) -{ +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; @@ -1046,7 +993,7 @@ static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */ part_signature_sha256_t pss; uint16_t pss_head_length; - char hash[sizeof (pss.hash)]; + char hash[sizeof(pss.hash)]; gcry_md_hd_t hd; gcry_error_t err; @@ -1056,9 +1003,9 @@ static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */ buffer_len = *ret_buffer_len; buffer_offset = 0; - if (se->data.server.userdb == NULL) - { - c_complain (LOG_NOTICE, &complain_no_users, + if (se->data.server.userdb == NULL) { + 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); @@ -1069,95 +1016,87 @@ static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */ return (-ENOMEM); /* Read type and length header */ - BUFFER_READ (&pss.head.type, sizeof (pss.head.type)); - BUFFER_READ (&pss.head.length, sizeof (pss.head.length)); - pss_head_length = ntohs (pss.head.length); + BUFFER_READ(&pss.head.type, sizeof(pss.head.type)); + BUFFER_READ(&pss.head.length, sizeof(pss.head.length)); + pss_head_length = ntohs(pss.head.length); /* Check if the `pss_head_length' is within bounds. */ - if ((pss_head_length <= PART_SIGNATURE_SHA256_SIZE) - || (pss_head_length > buffer_len)) - { - ERROR ("network plugin: HMAC-SHA-256 with invalid length received."); + if ((pss_head_length <= PART_SIGNATURE_SHA256_SIZE) || + (pss_head_length > buffer_len)) { + ERROR("network plugin: HMAC-SHA-256 with invalid length received."); return (-1); } /* Copy the hash. */ - BUFFER_READ (pss.hash, sizeof (pss.hash)); + BUFFER_READ(pss.hash, sizeof(pss.hash)); /* Calculate username length (without null byte) and allocate memory */ username_len = pss_head_length - PART_SIGNATURE_SHA256_SIZE; - pss.username = malloc (username_len + 1); + pss.username = malloc(username_len + 1); if (pss.username == NULL) return (-ENOMEM); /* Read the username */ - BUFFER_READ (pss.username, username_len); + BUFFER_READ(pss.username, username_len); pss.username[username_len] = 0; - assert (buffer_offset == pss_head_length); + assert(buffer_offset == pss_head_length); /* Query the password */ - secret = fbh_get (se->data.server.userdb, pss.username); - if (secret == NULL) - { - ERROR ("network plugin: Unknown user: %s", pss.username); - sfree (pss.username); + secret = fbh_get(se->data.server.userdb, pss.username); + if (secret == NULL) { + ERROR("network plugin: Unknown user: %s", pss.username); + sfree(pss.username); return (-ENOENT); } /* Create a hash device and check the HMAC */ hd = NULL; - err = gcry_md_open (&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); - if (err != 0) - { - ERROR ("network plugin: Creating HMAC-SHA-256 object failed: %s", - gcry_strerror (err)); - sfree (secret); - sfree (pss.username); + err = gcry_md_open(&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); + if (err != 0) { + ERROR("network plugin: Creating HMAC-SHA-256 object failed: %s", + gcry_strerror(err)); + sfree(secret); + sfree(pss.username); return (-1); } - err = gcry_md_setkey (hd, secret, strlen (secret)); - if (err != 0) - { - ERROR ("network plugin: gcry_md_setkey failed: %s", gcry_strerror (err)); - gcry_md_close (hd); - sfree (secret); - sfree (pss.username); + err = gcry_md_setkey(hd, secret, strlen(secret)); + if (err != 0) { + ERROR("network plugin: gcry_md_setkey failed: %s", gcry_strerror(err)); + gcry_md_close(hd); + sfree(secret); + sfree(pss.username); return (-1); } - gcry_md_write (hd, - buffer + PART_SIGNATURE_SHA256_SIZE, - buffer_len - PART_SIGNATURE_SHA256_SIZE); - hash_ptr = gcry_md_read (hd, GCRY_MD_SHA256); - if (hash_ptr == NULL) - { - ERROR ("network plugin: gcry_md_read failed."); - gcry_md_close (hd); - sfree (secret); - sfree (pss.username); + gcry_md_write(hd, buffer + PART_SIGNATURE_SHA256_SIZE, + buffer_len - PART_SIGNATURE_SHA256_SIZE); + hash_ptr = gcry_md_read(hd, GCRY_MD_SHA256); + if (hash_ptr == NULL) { + ERROR("network plugin: gcry_md_read failed."); + gcry_md_close(hd); + sfree(secret); + sfree(pss.username); return (-1); } - memcpy (hash, hash_ptr, sizeof (hash)); + memcpy(hash, hash_ptr, sizeof(hash)); /* Clean up */ - gcry_md_close (hd); + gcry_md_close(hd); hd = NULL; - if (memcmp (pss.hash, hash, sizeof (pss.hash)) != 0) - { - WARNING ("network plugin: Verifying HMAC-SHA-256 signature failed: " - "Hash mismatch. Username: %s", pss.username); - } - else - { - parse_packet (se, buffer + buffer_offset, buffer_len - buffer_offset, - flags | PP_SIGNED, pss.username); + if (memcmp(pss.hash, hash, sizeof(pss.hash)) != 0) { + WARNING("network plugin: Verifying HMAC-SHA-256 signature failed: " + "Hash mismatch. Username: %s", + pss.username); + } else { + parse_packet(se, buffer + buffer_offset, buffer_len - buffer_offset, + flags | PP_SIGNED, pss.username); } - sfree (secret); - sfree (pss.username); + sfree(secret); + sfree(pss.username); *ret_buffer = buffer + buffer_len; *ret_buffer_len = 0; @@ -1166,10 +1105,10 @@ static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */ } /* }}} int parse_part_sign_sha256 */ /* #endif HAVE_LIBGCRYPT */ -#else /* if !HAVE_LIBGCRYPT */ -static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */ - void **ret_buffer, size_t *ret_buffer_size, int flags) -{ +#else /* if !HAVE_LIBGCRYPT */ +static int parse_part_sign_sha256(sockent_t *se, /* {{{ */ + void **ret_buffer, size_t *ret_buffer_size, + int flags) { static int warning_has_been_printed = 0; char *buffer; @@ -1186,24 +1125,22 @@ static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */ if (buffer_size <= PART_SIGNATURE_SHA256_SIZE) return (-ENOMEM); - BUFFER_READ (&pss.head.type, sizeof (pss.head.type)); - BUFFER_READ (&pss.head.length, sizeof (pss.head.length)); - part_len = ntohs (pss.head.length); + BUFFER_READ(&pss.head.type, sizeof(pss.head.type)); + BUFFER_READ(&pss.head.length, sizeof(pss.head.length)); + part_len = ntohs(pss.head.length); - if ((part_len <= PART_SIGNATURE_SHA256_SIZE) - || (part_len > buffer_size)) + if ((part_len <= PART_SIGNATURE_SHA256_SIZE) || (part_len > buffer_size)) return (-EINVAL); - if (warning_has_been_printed == 0) - { - WARNING ("network plugin: Received signed packet, but the network " - "plugin was not linked with libgcrypt, so I cannot " - "verify the signature. The packet will be accepted."); + if (warning_has_been_printed == 0) { + WARNING("network plugin: Received signed packet, but the network " + "plugin was not linked with libgcrypt, so I cannot " + "verify the signature. The packet will be accepted."); warning_has_been_printed = 1; } - parse_packet (se, buffer + part_len, buffer_size - part_len, flags, - /* username = */ NULL); + parse_packet(se, buffer + part_len, buffer_size - part_len, flags, + /* username = */ NULL); *ret_buffer = buffer + buffer_size; *ret_buffer_size = 0; @@ -1213,133 +1150,122 @@ static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */ #endif /* !HAVE_LIBGCRYPT */ #if HAVE_LIBGCRYPT -static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */ - void **ret_buffer, size_t *ret_buffer_len, - int flags) -{ - char *buffer = *ret_buffer; +static int parse_part_encr_aes256(sockent_t *se, /* {{{ */ + void **ret_buffer, size_t *ret_buffer_len, + int flags) { + char *buffer = *ret_buffer; size_t buffer_len = *ret_buffer_len; size_t payload_len; size_t part_size; size_t buffer_offset; uint16_t username_len; part_encryption_aes256_t pea; - unsigned char hash[sizeof (pea.hash)] = { 0 }; + unsigned char hash[sizeof(pea.hash)] = {0}; gcry_cipher_hd_t cypher; gcry_error_t err; /* Make sure at least the header if available. */ - if (buffer_len <= PART_ENCRYPTION_AES256_SIZE) - { - NOTICE ("network plugin: parse_part_encr_aes256: " - "Discarding short packet."); + if (buffer_len <= PART_ENCRYPTION_AES256_SIZE) { + NOTICE("network plugin: parse_part_encr_aes256: " + "Discarding short packet."); return (-1); } buffer_offset = 0; /* Copy the unencrypted information into `pea'. */ - BUFFER_READ (&pea.head.type, sizeof (pea.head.type)); - BUFFER_READ (&pea.head.length, sizeof (pea.head.length)); + BUFFER_READ(&pea.head.type, sizeof(pea.head.type)); + BUFFER_READ(&pea.head.length, sizeof(pea.head.length)); /* Check the `part size'. */ - part_size = ntohs (pea.head.length); - if ((part_size <= PART_ENCRYPTION_AES256_SIZE) - || (part_size > buffer_len)) - { - NOTICE ("network plugin: parse_part_encr_aes256: " - "Discarding part with invalid size."); + part_size = ntohs(pea.head.length); + if ((part_size <= PART_ENCRYPTION_AES256_SIZE) || (part_size > buffer_len)) { + NOTICE("network plugin: parse_part_encr_aes256: " + "Discarding part with invalid size."); return (-1); } /* Read the username */ - BUFFER_READ (&username_len, sizeof (username_len)); - username_len = ntohs (username_len); + BUFFER_READ(&username_len, sizeof(username_len)); + username_len = ntohs(username_len); - if ((username_len == 0) - || (username_len > (part_size - (PART_ENCRYPTION_AES256_SIZE + 1)))) - { - NOTICE ("network plugin: parse_part_encr_aes256: " - "Discarding part with invalid username length."); + if ((username_len == 0) || + (username_len > (part_size - (PART_ENCRYPTION_AES256_SIZE + 1)))) { + NOTICE("network plugin: parse_part_encr_aes256: " + "Discarding part with invalid username length."); return (-1); } - assert (username_len > 0); - pea.username = malloc (username_len + 1); + assert(username_len > 0); + pea.username = malloc(username_len + 1); if (pea.username == NULL) return (-ENOMEM); - BUFFER_READ (pea.username, username_len); + BUFFER_READ(pea.username, username_len); pea.username[username_len] = 0; /* Last but not least, the initialization vector */ - BUFFER_READ (pea.iv, sizeof (pea.iv)); + BUFFER_READ(pea.iv, sizeof(pea.iv)); /* Make sure we are at the right position */ - assert (buffer_offset == (username_len + - PART_ENCRYPTION_AES256_SIZE - sizeof (pea.hash))); + assert(buffer_offset == + (username_len + PART_ENCRYPTION_AES256_SIZE - sizeof(pea.hash))); - cypher = network_get_aes256_cypher (se, pea.iv, sizeof (pea.iv), - pea.username); - if (cypher == NULL) - { - ERROR ("network plugin: Failed to get cypher. Username: %s", pea.username); - sfree (pea.username); + cypher = network_get_aes256_cypher(se, pea.iv, sizeof(pea.iv), pea.username); + if (cypher == NULL) { + ERROR("network plugin: Failed to get cypher. Username: %s", pea.username); + sfree(pea.username); return (-1); } payload_len = part_size - (PART_ENCRYPTION_AES256_SIZE + username_len); - assert (payload_len > 0); + assert(payload_len > 0); /* Decrypt the packet in-place */ - err = gcry_cipher_decrypt (cypher, - buffer + buffer_offset, - part_size - buffer_offset, - /* in = */ NULL, /* in len = */ 0); - if (err != 0) - { - sfree (pea.username); - ERROR ("network plugin: gcry_cipher_decrypt returned: %s. Username: %s", - gcry_strerror (err), pea.username); + err = gcry_cipher_decrypt(cypher, buffer + buffer_offset, + part_size - buffer_offset, + /* in = */ NULL, /* in len = */ 0); + if (err != 0) { + sfree(pea.username); + ERROR("network plugin: gcry_cipher_decrypt returned: %s. Username: %s", + gcry_strerror(err), pea.username); return (-1); } /* Read the hash */ - BUFFER_READ (pea.hash, sizeof (pea.hash)); + BUFFER_READ(pea.hash, sizeof(pea.hash)); /* Make sure we're at the right position - again */ - assert (buffer_offset == (username_len + PART_ENCRYPTION_AES256_SIZE)); - assert (buffer_offset == (part_size - payload_len)); + assert(buffer_offset == (username_len + PART_ENCRYPTION_AES256_SIZE)); + assert(buffer_offset == (part_size - payload_len)); /* Check hash sum */ - gcry_md_hash_buffer (GCRY_MD_SHA1, hash, - buffer + buffer_offset, payload_len); - if (memcmp (hash, pea.hash, sizeof (hash)) != 0) - { - ERROR ("network plugin: Checksum mismatch. Username: %s", pea.username); - sfree (pea.username); + gcry_md_hash_buffer(GCRY_MD_SHA1, hash, buffer + buffer_offset, payload_len); + if (memcmp(hash, pea.hash, sizeof(hash)) != 0) { + ERROR("network plugin: Checksum mismatch. Username: %s", pea.username); + sfree(pea.username); return (-1); } - parse_packet (se, buffer + buffer_offset, payload_len, - flags | PP_ENCRYPTED, pea.username); + parse_packet(se, buffer + buffer_offset, payload_len, flags | PP_ENCRYPTED, + pea.username); /* XXX: Free pea.username?!? */ /* Update return values */ - *ret_buffer = buffer + part_size; + *ret_buffer = buffer + part_size; *ret_buffer_len = buffer_len - part_size; - sfree (pea.username); + sfree(pea.username); return (0); } /* }}} int parse_part_encr_aes256 */ /* #endif HAVE_LIBGCRYPT */ -#else /* if !HAVE_LIBGCRYPT */ -static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */ - void **ret_buffer, size_t *ret_buffer_size, int flags) -{ +#else /* if !HAVE_LIBGCRYPT */ +static int parse_part_encr_aes256(sockent_t *se, /* {{{ */ + void **ret_buffer, size_t *ret_buffer_size, + int flags) { static int warning_has_been_printed = 0; char *buffer; @@ -1354,29 +1280,26 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */ buffer_offset = 0; /* parse_packet assures this minimum size. */ - assert (buffer_size >= (sizeof (ph.type) + sizeof (ph.length))); + assert(buffer_size >= (sizeof(ph.type) + sizeof(ph.length))); - BUFFER_READ (&ph.type, sizeof (ph.type)); - BUFFER_READ (&ph.length, sizeof (ph.length)); - ph_length = ntohs (ph.length); + BUFFER_READ(&ph.type, sizeof(ph.type)); + BUFFER_READ(&ph.length, sizeof(ph.length)); + ph_length = ntohs(ph.length); - if ((ph_length <= PART_ENCRYPTION_AES256_SIZE) - || (ph_length > buffer_size)) - { - ERROR ("network plugin: AES-256 encrypted part " - "with invalid length received."); + if ((ph_length <= PART_ENCRYPTION_AES256_SIZE) || (ph_length > buffer_size)) { + ERROR("network plugin: AES-256 encrypted part " + "with invalid length received."); return (-1); } - if (warning_has_been_printed == 0) - { - WARNING ("network plugin: Received encrypted packet, but the network " - "plugin was not linked with libgcrypt, so I cannot " - "decrypt it. The part will be discarded."); + if (warning_has_been_printed == 0) { + WARNING("network plugin: Received encrypted packet, but the network " + "plugin was not linked with libgcrypt, so I cannot " + "decrypt it. The part will be discarded."); warning_has_been_printed = 1; } - *ret_buffer = (void *) (((char *) *ret_buffer) + ph_length); + *ret_buffer = (void *)(((char *)*ret_buffer) + ph_length); *ret_buffer_size -= ph_length; return (0); @@ -1385,306 +1308,241 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */ #undef BUFFER_READ -static int parse_packet (sockent_t *se, /* {{{ */ - void *buffer, size_t buffer_size, int flags, - const char *username) -{ - int status; +static int parse_packet(sockent_t *se, /* {{{ */ + void *buffer, size_t buffer_size, int flags, + const char *username) { + int status; - value_list_t vl = VALUE_LIST_INIT; - notification_t n = { 0 }; + value_list_t vl = VALUE_LIST_INIT; + notification_t n = {0}; #if HAVE_LIBGCRYPT - int packet_was_signed = (flags & PP_SIGNED); - int packet_was_encrypted = (flags & PP_ENCRYPTED); - int printed_ignore_warning = 0; + int packet_was_signed = (flags & PP_SIGNED); + int packet_was_encrypted = (flags & PP_ENCRYPTED); + int printed_ignore_warning = 0; #endif /* HAVE_LIBGCRYPT */ + memset(&vl, '\0', sizeof(vl)); + status = 0; + + while ((status == 0) && (0 < buffer_size) && + ((unsigned int)buffer_size > sizeof(part_header_t))) { + uint16_t pkg_length; + uint16_t pkg_type; + + memcpy((void *)&pkg_type, (void *)buffer, sizeof(pkg_type)); + memcpy((void *)&pkg_length, (void *)(((char *)buffer) + sizeof(pkg_type)), + sizeof(pkg_length)); + + pkg_length = ntohs(pkg_length); + pkg_type = ntohs(pkg_type); + + if (pkg_length > buffer_size) + break; + /* Ensure that this loop terminates eventually */ + if (pkg_length < (2 * sizeof(uint16_t))) + break; - memset (&vl, '\0', sizeof (vl)); - status = 0; - - while ((status == 0) && (0 < buffer_size) - && ((unsigned int) buffer_size > sizeof (part_header_t))) - { - uint16_t pkg_length; - uint16_t pkg_type; - - memcpy ((void *) &pkg_type, - (void *) buffer, - sizeof (pkg_type)); - memcpy ((void *) &pkg_length, - (void *) (((char *) buffer) + sizeof (pkg_type)), - sizeof (pkg_length)); - - pkg_length = ntohs (pkg_length); - pkg_type = ntohs (pkg_type); - - if (pkg_length > buffer_size) - break; - /* Ensure that this loop terminates eventually */ - if (pkg_length < (2 * sizeof (uint16_t))) - break; - - if (pkg_type == TYPE_ENCR_AES256) - { - status = parse_part_encr_aes256 (se, - &buffer, &buffer_size, flags); - if (status != 0) - { - ERROR ("network plugin: Decrypting AES256 " - "part failed " - "with status %i.", status); - break; - } - } + if (pkg_type == TYPE_ENCR_AES256) { + status = parse_part_encr_aes256(se, &buffer, &buffer_size, flags); + if (status != 0) { + ERROR("network plugin: Decrypting AES256 " + "part failed " + "with status %i.", + status); + break; + } + } #if HAVE_LIBGCRYPT - else if ((se->data.server.security_level == SECURITY_LEVEL_ENCRYPT) - && (packet_was_encrypted == 0)) - { - if (printed_ignore_warning == 0) - { - INFO ("network plugin: Unencrypted packet or " - "part has been ignored."); - printed_ignore_warning = 1; - } - buffer = ((char *) buffer) + pkg_length; - buffer_size -= (size_t) pkg_length; - continue; - } + else if ((se->data.server.security_level == SECURITY_LEVEL_ENCRYPT) && + (packet_was_encrypted == 0)) { + if (printed_ignore_warning == 0) { + INFO("network plugin: Unencrypted packet or " + "part has been ignored."); + printed_ignore_warning = 1; + } + buffer = ((char *)buffer) + pkg_length; + buffer_size -= (size_t)pkg_length; + continue; + } #endif /* HAVE_LIBGCRYPT */ - else if (pkg_type == TYPE_SIGN_SHA256) - { - status = parse_part_sign_sha256 (se, - &buffer, &buffer_size, flags); - if (status != 0) - { - ERROR ("network plugin: Verifying HMAC-SHA-256 " - "signature failed " - "with status %i.", status); - break; - } - } + else if (pkg_type == TYPE_SIGN_SHA256) { + status = parse_part_sign_sha256(se, &buffer, &buffer_size, flags); + if (status != 0) { + ERROR("network plugin: Verifying HMAC-SHA-256 " + "signature failed " + "with status %i.", + status); + break; + } + } #if HAVE_LIBGCRYPT - else if ((se->data.server.security_level == SECURITY_LEVEL_SIGN) - && (packet_was_encrypted == 0) - && (packet_was_signed == 0)) - { - if (printed_ignore_warning == 0) - { - INFO ("network plugin: Unsigned packet or " - "part has been ignored."); - printed_ignore_warning = 1; - } - buffer = ((char *) buffer) + pkg_length; - buffer_size -= (size_t) pkg_length; - continue; - } + else if ((se->data.server.security_level == SECURITY_LEVEL_SIGN) && + (packet_was_encrypted == 0) && (packet_was_signed == 0)) { + if (printed_ignore_warning == 0) { + INFO("network plugin: Unsigned packet or " + "part has been ignored."); + printed_ignore_warning = 1; + } + buffer = ((char *)buffer) + pkg_length; + buffer_size -= (size_t)pkg_length; + continue; + } #endif /* HAVE_LIBGCRYPT */ - else if (pkg_type == TYPE_VALUES) - { - status = parse_part_values (&buffer, &buffer_size, - &vl.values, &vl.values_len); - if (status != 0) - break; - - network_dispatch_values (&vl, username); - - sfree (vl.values); - } - else if (pkg_type == TYPE_TIME) - { - uint64_t tmp = 0; - status = parse_part_number (&buffer, &buffer_size, - &tmp); - if (status == 0) - { - 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) - { - uint64_t tmp = 0; - status = parse_part_number (&buffer, &buffer_size, - &tmp); - if (status == 0) - 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) - { - status = parse_part_string (&buffer, &buffer_size, - vl.host, sizeof (vl.host)); - if (status == 0) - sstrncpy (n.host, vl.host, sizeof (n.host)); - } - else if (pkg_type == TYPE_PLUGIN) - { - status = parse_part_string (&buffer, &buffer_size, - vl.plugin, sizeof (vl.plugin)); - if (status == 0) - sstrncpy (n.plugin, vl.plugin, - sizeof (n.plugin)); - } - else if (pkg_type == TYPE_PLUGIN_INSTANCE) - { - status = parse_part_string (&buffer, &buffer_size, - vl.plugin_instance, - sizeof (vl.plugin_instance)); - if (status == 0) - sstrncpy (n.plugin_instance, - vl.plugin_instance, - sizeof (n.plugin_instance)); - } - else if (pkg_type == TYPE_TYPE) - { - status = parse_part_string (&buffer, &buffer_size, - vl.type, sizeof (vl.type)); - if (status == 0) - sstrncpy (n.type, vl.type, sizeof (n.type)); - } - else if (pkg_type == TYPE_TYPE_INSTANCE) - { - status = parse_part_string (&buffer, &buffer_size, - vl.type_instance, - sizeof (vl.type_instance)); - if (status == 0) - sstrncpy (n.type_instance, vl.type_instance, - sizeof (n.type_instance)); - } - else if (pkg_type == TYPE_MESSAGE) - { - status = parse_part_string (&buffer, &buffer_size, - n.message, sizeof (n.message)); - - if (status != 0) - { - /* do nothing */ - } - else if ((n.severity != NOTIF_FAILURE) - && (n.severity != NOTIF_WARNING) - && (n.severity != NOTIF_OKAY)) - { - INFO ("network plugin: " - "Ignoring notification with " - "unknown severity %i.", - n.severity); - } - else if (n.time == 0) - { - INFO ("network plugin: " - "Ignoring notification with " - "time == 0."); - } - else if (strlen (n.message) == 0) - { - INFO ("network plugin: " - "Ignoring notification with " - "an empty message."); - } - else - { - network_dispatch_notification (&n); - } - } - else if (pkg_type == TYPE_SEVERITY) - { - uint64_t tmp = 0; - status = parse_part_number (&buffer, &buffer_size, - &tmp); - if (status == 0) - n.severity = (int) tmp; - } - else - { - DEBUG ("network plugin: parse_packet: Unknown part" - " type: 0x%04hx", pkg_type); - buffer = ((char *) buffer) + pkg_length; - buffer_size -= (size_t) pkg_length; - } - } /* while (buffer_size > sizeof (part_header_t)) */ - - if (status == 0 && buffer_size > 0) - WARNING ("network plugin: parse_packet: Received truncated " - "packet, try increasing `MaxPacketSize'"); - - return (status); + else if (pkg_type == TYPE_VALUES) { + status = + parse_part_values(&buffer, &buffer_size, &vl.values, &vl.values_len); + if (status != 0) + break; + + network_dispatch_values(&vl, username); + + sfree(vl.values); + } else if (pkg_type == TYPE_TIME) { + uint64_t tmp = 0; + status = parse_part_number(&buffer, &buffer_size, &tmp); + if (status == 0) { + 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) { + uint64_t tmp = 0; + status = parse_part_number(&buffer, &buffer_size, &tmp); + if (status == 0) + 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) { + status = + parse_part_string(&buffer, &buffer_size, vl.host, sizeof(vl.host)); + if (status == 0) + sstrncpy(n.host, vl.host, sizeof(n.host)); + } else if (pkg_type == TYPE_PLUGIN) { + status = parse_part_string(&buffer, &buffer_size, vl.plugin, + sizeof(vl.plugin)); + if (status == 0) + sstrncpy(n.plugin, vl.plugin, sizeof(n.plugin)); + } else if (pkg_type == TYPE_PLUGIN_INSTANCE) { + status = parse_part_string(&buffer, &buffer_size, vl.plugin_instance, + sizeof(vl.plugin_instance)); + if (status == 0) + sstrncpy(n.plugin_instance, vl.plugin_instance, + sizeof(n.plugin_instance)); + } else if (pkg_type == TYPE_TYPE) { + status = + parse_part_string(&buffer, &buffer_size, vl.type, sizeof(vl.type)); + if (status == 0) + sstrncpy(n.type, vl.type, sizeof(n.type)); + } else if (pkg_type == TYPE_TYPE_INSTANCE) { + status = parse_part_string(&buffer, &buffer_size, vl.type_instance, + sizeof(vl.type_instance)); + if (status == 0) + sstrncpy(n.type_instance, vl.type_instance, sizeof(n.type_instance)); + } else if (pkg_type == TYPE_MESSAGE) { + status = parse_part_string(&buffer, &buffer_size, n.message, + sizeof(n.message)); + + if (status != 0) { + /* do nothing */ + } else if ((n.severity != NOTIF_FAILURE) && + (n.severity != NOTIF_WARNING) && (n.severity != NOTIF_OKAY)) { + INFO("network plugin: " + "Ignoring notification with " + "unknown severity %i.", + n.severity); + } else if (n.time == 0) { + INFO("network plugin: " + "Ignoring notification with " + "time == 0."); + } else if (strlen(n.message) == 0) { + INFO("network plugin: " + "Ignoring notification with " + "an empty message."); + } else { + network_dispatch_notification(&n); + } + } else if (pkg_type == TYPE_SEVERITY) { + uint64_t tmp = 0; + status = parse_part_number(&buffer, &buffer_size, &tmp); + if (status == 0) + n.severity = (int)tmp; + } else { + DEBUG("network plugin: parse_packet: Unknown part" + " type: 0x%04hx", + pkg_type); + buffer = ((char *)buffer) + pkg_length; + buffer_size -= (size_t)pkg_length; + } + } /* while (buffer_size > sizeof (part_header_t)) */ + + if (status == 0 && buffer_size > 0) + WARNING("network plugin: parse_packet: Received truncated " + "packet, try increasing `MaxPacketSize'"); + + return (status); } /* }}} int parse_packet */ -static void free_sockent_client (struct sockent_client *sec) /* {{{ */ +static void free_sockent_client(struct sockent_client *sec) /* {{{ */ { - if (sec->fd >= 0) - { - close (sec->fd); + if (sec->fd >= 0) { + close(sec->fd); sec->fd = -1; } - sfree (sec->addr); + sfree(sec->addr); #if HAVE_LIBGCRYPT - sfree (sec->username); - sfree (sec->password); + sfree(sec->username); + sfree(sec->password); if (sec->cypher != NULL) - gcry_cipher_close (sec->cypher); + gcry_cipher_close(sec->cypher); #endif } /* }}} void free_sockent_client */ -static void free_sockent_server (struct sockent_server *ses) /* {{{ */ +static void free_sockent_server(struct sockent_server *ses) /* {{{ */ { - for (size_t i = 0; i < ses->fd_num; i++) - { - if (ses->fd[i] >= 0) - { - close (ses->fd[i]); + for (size_t i = 0; i < ses->fd_num; i++) { + if (ses->fd[i] >= 0) { + close(ses->fd[i]); ses->fd[i] = -1; } } - sfree (ses->fd); + sfree(ses->fd); #if HAVE_LIBGCRYPT - sfree (ses->auth_file); - fbh_destroy (ses->userdb); + sfree(ses->auth_file); + fbh_destroy(ses->userdb); if (ses->cypher != NULL) - gcry_cipher_close (ses->cypher); + gcry_cipher_close(ses->cypher); #endif } /* }}} void free_sockent_server */ -static void sockent_destroy (sockent_t *se) /* {{{ */ +static void sockent_destroy(sockent_t *se) /* {{{ */ { sockent_t *next; - DEBUG ("network plugin: sockent_destroy (se = %p);", (void *) se); + DEBUG("network plugin: sockent_destroy (se = %p);", (void *)se); - while (se != NULL) - { + while (se != NULL) { next = se->next; - sfree (se->node); - sfree (se->service); + sfree(se->node); + sfree(se->service); if (se->type == SOCKENT_TYPE_CLIENT) - free_sockent_client (&se->data.client); + free_sockent_client(&se->data.client); else - free_sockent_server (&se->data.server); + free_sockent_server(&se->data.server); - sfree (se); + sfree(se); se = next; } } /* }}} void sockent_destroy */ @@ -1698,702 +1556,620 @@ static void sockent_destroy (sockent_t *se) /* {{{ */ * The `struct addrinfo' is used to destinguish between unicast and multicast * sockets. */ -static int network_set_ttl (const sockent_t *se, const struct addrinfo *ai) -{ - DEBUG ("network plugin: network_set_ttl: network_config_ttl = %i;", - network_config_ttl); - - assert (se->type == SOCKENT_TYPE_CLIENT); - - if ((network_config_ttl < 1) || (network_config_ttl > 255)) - return (-1); - - if (ai->ai_family == AF_INET) - { - struct sockaddr_in *addr = (struct sockaddr_in *) ai->ai_addr; - int optname; - - if (IN_MULTICAST (ntohl (addr->sin_addr.s_addr))) - optname = IP_MULTICAST_TTL; - else - optname = IP_TTL; - - if (setsockopt (se->data.client.fd, IPPROTO_IP, optname, - &network_config_ttl, - sizeof (network_config_ttl)) != 0) - { - char errbuf[1024]; - ERROR ("network plugin: setsockopt (ipv4-ttl): %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - } - else if (ai->ai_family == AF_INET6) - { - /* Useful example: http://gsyc.escet.urjc.es/~eva/IPv6-web/examples/mcast.html */ - struct sockaddr_in6 *addr = (struct sockaddr_in6 *) ai->ai_addr; - int optname; - - if (IN6_IS_ADDR_MULTICAST (&addr->sin6_addr)) - optname = IPV6_MULTICAST_HOPS; - else - optname = IPV6_UNICAST_HOPS; - - if (setsockopt (se->data.client.fd, IPPROTO_IPV6, optname, - &network_config_ttl, - sizeof (network_config_ttl)) != 0) - { - char errbuf[1024]; - ERROR ("network plugin: setsockopt(ipv6-ttl): %s", - sstrerror (errno, errbuf, - sizeof (errbuf))); - return (-1); - } - } - - return (0); +static int network_set_ttl(const sockent_t *se, const struct addrinfo *ai) { + DEBUG("network plugin: network_set_ttl: network_config_ttl = %i;", + network_config_ttl); + + assert(se->type == SOCKENT_TYPE_CLIENT); + + if ((network_config_ttl < 1) || (network_config_ttl > 255)) + return (-1); + + if (ai->ai_family == AF_INET) { + struct sockaddr_in *addr = (struct sockaddr_in *)ai->ai_addr; + int optname; + + if (IN_MULTICAST(ntohl(addr->sin_addr.s_addr))) + optname = IP_MULTICAST_TTL; + else + optname = IP_TTL; + + if (setsockopt(se->data.client.fd, IPPROTO_IP, optname, &network_config_ttl, + sizeof(network_config_ttl)) != 0) { + char errbuf[1024]; + ERROR("network plugin: setsockopt (ipv4-ttl): %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + } else if (ai->ai_family == AF_INET6) { + /* Useful example: + * http://gsyc.escet.urjc.es/~eva/IPv6-web/examples/mcast.html */ + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)ai->ai_addr; + int optname; + + if (IN6_IS_ADDR_MULTICAST(&addr->sin6_addr)) + optname = IPV6_MULTICAST_HOPS; + else + optname = IPV6_UNICAST_HOPS; + + if (setsockopt(se->data.client.fd, IPPROTO_IPV6, optname, + &network_config_ttl, sizeof(network_config_ttl)) != 0) { + char errbuf[1024]; + ERROR("network plugin: setsockopt(ipv6-ttl): %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + } + + return (0); } /* int network_set_ttl */ -static int network_set_interface (const sockent_t *se, const struct addrinfo *ai) /* {{{ */ +static int network_set_interface(const sockent_t *se, + const struct addrinfo *ai) /* {{{ */ { - DEBUG ("network plugin: network_set_interface: interface index = %i;", - se->interface); + DEBUG("network plugin: network_set_interface: interface index = %i;", + se->interface); - assert (se->type == SOCKENT_TYPE_CLIENT); + assert(se->type == SOCKENT_TYPE_CLIENT); - if (ai->ai_family == AF_INET) - { - struct sockaddr_in *addr = (struct sockaddr_in *) ai->ai_addr; + if (ai->ai_family == AF_INET) { + struct sockaddr_in *addr = (struct sockaddr_in *)ai->ai_addr; - if (IN_MULTICAST (ntohl (addr->sin_addr.s_addr))) - { + if (IN_MULTICAST(ntohl(addr->sin_addr.s_addr))) { #if HAVE_STRUCT_IP_MREQN_IMR_IFINDEX - /* If possible, use the "ip_mreqn" structure which has - * an "interface index" member. Using the interface - * index is preferred here, because of its similarity - * to the way IPv6 handles this. Unfortunately, it - * appears not to be portable. */ - struct ip_mreqn mreq = { - .imr_multiaddr.s_addr = addr->sin_addr.s_addr, - .imr_address.s_addr = ntohl (INADDR_ANY), - .imr_ifindex = se->interface - }; + /* If possible, use the "ip_mreqn" structure which has + * an "interface index" member. Using the interface + * index is preferred here, because of its similarity + * to the way IPv6 handles this. Unfortunately, it + * appears not to be portable. */ + struct ip_mreqn mreq = {.imr_multiaddr.s_addr = addr->sin_addr.s_addr, + .imr_address.s_addr = ntohl(INADDR_ANY), + .imr_ifindex = se->interface}; #else - struct ip_mreq mreq = { - .imr_multiaddr.s_addr = addr->sin_addr.s_addr, - .imr_interface.s_addr = ntohl (INADDR_ANY) - }; + struct ip_mreq mreq = {.imr_multiaddr.s_addr = addr->sin_addr.s_addr, + .imr_interface.s_addr = ntohl(INADDR_ANY)}; #endif - if (setsockopt (se->data.client.fd, IPPROTO_IP, IP_MULTICAST_IF, - &mreq, sizeof (mreq)) != 0) - { - char errbuf[1024]; - ERROR ("network plugin: setsockopt (ipv4-multicast-if): %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - return (0); - } - } - else if (ai->ai_family == AF_INET6) - { - struct sockaddr_in6 *addr = (struct sockaddr_in6 *) ai->ai_addr; - - if (IN6_IS_ADDR_MULTICAST (&addr->sin6_addr)) - { - if (setsockopt (se->data.client.fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, - &se->interface, - sizeof (se->interface)) != 0) - { - char errbuf[1024]; - ERROR ("network plugin: setsockopt (ipv6-multicast-if): %s", - sstrerror (errno, errbuf, - sizeof (errbuf))); - return (-1); - } - - return (0); - } - } - - /* else: Not a multicast interface. */ - if (se->interface != 0) - { -#if defined(HAVE_IF_INDEXTONAME) && HAVE_IF_INDEXTONAME && defined(SO_BINDTODEVICE) - char interface_name[IFNAMSIZ]; - - if (if_indextoname (se->interface, interface_name) == NULL) - return (-1); - - DEBUG ("network plugin: Binding socket to interface %s", interface_name); - - if (setsockopt (se->data.client.fd, SOL_SOCKET, SO_BINDTODEVICE, - interface_name, - sizeof(interface_name)) == -1 ) - { - char errbuf[1024]; - ERROR ("network plugin: setsockopt (bind-if): %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } + if (setsockopt(se->data.client.fd, IPPROTO_IP, IP_MULTICAST_IF, &mreq, + sizeof(mreq)) != 0) { + char errbuf[1024]; + ERROR("network plugin: setsockopt (ipv4-multicast-if): %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + return (0); + } + } else if (ai->ai_family == AF_INET6) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)ai->ai_addr; + + if (IN6_IS_ADDR_MULTICAST(&addr->sin6_addr)) { + if (setsockopt(se->data.client.fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, + &se->interface, sizeof(se->interface)) != 0) { + char errbuf[1024]; + ERROR("network plugin: setsockopt (ipv6-multicast-if): %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + return (0); + } + } + + /* else: Not a multicast interface. */ + if (se->interface != 0) { +#if defined(HAVE_IF_INDEXTONAME) && HAVE_IF_INDEXTONAME && \ + defined(SO_BINDTODEVICE) + char interface_name[IFNAMSIZ]; + + if (if_indextoname(se->interface, interface_name) == NULL) + return (-1); + + DEBUG("network plugin: Binding socket to interface %s", interface_name); + + if (setsockopt(se->data.client.fd, SOL_SOCKET, SO_BINDTODEVICE, + interface_name, sizeof(interface_name)) == -1) { + char errbuf[1024]; + ERROR("network plugin: setsockopt (bind-if): %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } /* #endif HAVE_IF_INDEXTONAME && SO_BINDTODEVICE */ #else - WARNING ("network plugin: Cannot set the interface on a unicast " - "socket because " -# if !defined(SO_BINDTODEVICE) - "the \"SO_BINDTODEVICE\" socket option " -# else - "the \"if_indextoname\" function " -# endif - "is not available on your system."); + WARNING("network plugin: Cannot set the interface on a unicast " + "socket because " +#if !defined(SO_BINDTODEVICE) + "the \"SO_BINDTODEVICE\" socket option " +#else + "the \"if_indextoname\" function " #endif + "is not available on your system."); +#endif + } - } - - return (0); + return (0); } /* }}} network_set_interface */ -static int network_bind_socket (int fd, const struct addrinfo *ai, const int interface_idx) -{ +static int network_bind_socket(int fd, const struct addrinfo *ai, + const int interface_idx) { #if KERNEL_SOLARIS - char loop = 0; + char loop = 0; #else - int loop = 0; + int loop = 0; #endif - int yes = 1; - - /* allow multiple sockets to use the same PORT number */ - if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, - &yes, sizeof(yes)) == -1) { - char errbuf[1024]; - ERROR ("network plugin: setsockopt (reuseaddr): %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - DEBUG ("fd = %i; calling `bind'", fd); - - if (bind (fd, ai->ai_addr, ai->ai_addrlen) == -1) - { - char errbuf[1024]; - ERROR ("bind: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - if (ai->ai_family == AF_INET) - { - struct sockaddr_in *addr = (struct sockaddr_in *) ai->ai_addr; - if (IN_MULTICAST (ntohl (addr->sin_addr.s_addr))) - { + int yes = 1; + + /* allow multiple sockets to use the same PORT number */ + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) { + char errbuf[1024]; + ERROR("network plugin: setsockopt (reuseaddr): %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + DEBUG("fd = %i; calling `bind'", fd); + + if (bind(fd, ai->ai_addr, ai->ai_addrlen) == -1) { + char errbuf[1024]; + ERROR("bind: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + if (ai->ai_family == AF_INET) { + struct sockaddr_in *addr = (struct sockaddr_in *)ai->ai_addr; + if (IN_MULTICAST(ntohl(addr->sin_addr.s_addr))) { #if HAVE_STRUCT_IP_MREQN_IMR_IFINDEX - struct ip_mreqn mreq; + struct ip_mreqn mreq; #else - struct ip_mreq mreq; + struct ip_mreq mreq; #endif - DEBUG ("fd = %i; IPv4 multicast address found", fd); + DEBUG("fd = %i; IPv4 multicast address found", fd); - mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr; + mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr; #if HAVE_STRUCT_IP_MREQN_IMR_IFINDEX - /* Set the interface using the interface index if - * possible (available). Unfortunately, the struct - * ip_mreqn is not portable. */ - mreq.imr_address.s_addr = ntohl (INADDR_ANY); - mreq.imr_ifindex = interface_idx; + /* Set the interface using the interface index if + * possible (available). Unfortunately, the struct + * ip_mreqn is not portable. */ + mreq.imr_address.s_addr = ntohl(INADDR_ANY); + mreq.imr_ifindex = interface_idx; #else - mreq.imr_interface.s_addr = ntohl (INADDR_ANY); + mreq.imr_interface.s_addr = ntohl(INADDR_ANY); #endif - if (setsockopt (fd, IPPROTO_IP, IP_MULTICAST_LOOP, - &loop, sizeof (loop)) == -1) - { - char errbuf[1024]; - ERROR ("network plugin: setsockopt (multicast-loop): %s", - sstrerror (errno, errbuf, - sizeof (errbuf))); - return (-1); - } - - if (setsockopt (fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, - &mreq, sizeof (mreq)) == -1) - { - char errbuf[1024]; - ERROR ("network plugin: setsockopt (add-membership): %s", - sstrerror (errno, errbuf, - sizeof (errbuf))); - return (-1); - } - - return (0); - } - } - else if (ai->ai_family == AF_INET6) - { - /* Useful example: http://gsyc.escet.urjc.es/~eva/IPv6-web/examples/mcast.html */ - struct sockaddr_in6 *addr = (struct sockaddr_in6 *) ai->ai_addr; - if (IN6_IS_ADDR_MULTICAST (&addr->sin6_addr)) - { - struct ipv6_mreq mreq; - - DEBUG ("fd = %i; IPv6 multicast address found", fd); - - memcpy (&mreq.ipv6mr_multiaddr, - &addr->sin6_addr, - sizeof (addr->sin6_addr)); - - /* http://developer.apple.com/documentation/Darwin/Reference/ManPages/man4/ip6.4.html - * ipv6mr_interface may be set to zeroes to - * choose the default multicast interface or to - * the index of a particular multicast-capable - * interface if the host is multihomed. - * Membership is associ-associated with a - * single interface; programs running on - * multihomed hosts may need to join the same - * group on more than one interface.*/ - mreq.ipv6mr_interface = interface_idx; - - if (setsockopt (fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, - &loop, sizeof (loop)) == -1) - { - char errbuf[1024]; - ERROR ("network plugin: setsockopt (ipv6-multicast-loop): %s", - sstrerror (errno, errbuf, - sizeof (errbuf))); - return (-1); - } - - if (setsockopt (fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, - &mreq, sizeof (mreq)) == -1) - { - char errbuf[1024]; - ERROR ("network plugin: setsockopt (ipv6-add-membership): %s", - sstrerror (errno, errbuf, - sizeof (errbuf))); - return (-1); - } - - return (0); - } - } - -#if defined(HAVE_IF_INDEXTONAME) && HAVE_IF_INDEXTONAME && defined(SO_BINDTODEVICE) - /* if a specific interface was set, bind the socket to it. But to avoid - * possible problems with multicast routing, only do that for non-multicast - * addresses */ - if (interface_idx != 0) - { - char interface_name[IFNAMSIZ]; - - if (if_indextoname (interface_idx, interface_name) == NULL) - return (-1); - - DEBUG ("fd = %i; Binding socket to interface %s", fd, interface_name); - - if (setsockopt (fd, SOL_SOCKET, SO_BINDTODEVICE, - interface_name, - sizeof(interface_name)) == -1 ) - { - char errbuf[1024]; - ERROR ("network plugin: setsockopt (bind-if): %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - } + if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) == + -1) { + char errbuf[1024]; + ERROR("network plugin: setsockopt (multicast-loop): %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == + -1) { + char errbuf[1024]; + ERROR("network plugin: setsockopt (add-membership): %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + return (0); + } + } else if (ai->ai_family == AF_INET6) { + /* Useful example: + * http://gsyc.escet.urjc.es/~eva/IPv6-web/examples/mcast.html */ + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)ai->ai_addr; + if (IN6_IS_ADDR_MULTICAST(&addr->sin6_addr)) { + struct ipv6_mreq mreq; + + DEBUG("fd = %i; IPv6 multicast address found", fd); + + memcpy(&mreq.ipv6mr_multiaddr, &addr->sin6_addr, sizeof(addr->sin6_addr)); + + /* http://developer.apple.com/documentation/Darwin/Reference/ManPages/man4/ip6.4.html + * ipv6mr_interface may be set to zeroes to + * choose the default multicast interface or to + * the index of a particular multicast-capable + * interface if the host is multihomed. + * Membership is associ-associated with a + * single interface; programs running on + * multihomed hosts may need to join the same + * group on more than one interface.*/ + mreq.ipv6mr_interface = interface_idx; + + if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, + sizeof(loop)) == -1) { + char errbuf[1024]; + ERROR("network plugin: setsockopt (ipv6-multicast-loop): %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + if (setsockopt(fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, + sizeof(mreq)) == -1) { + char errbuf[1024]; + ERROR("network plugin: setsockopt (ipv6-add-membership): %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + return (0); + } + } + +#if defined(HAVE_IF_INDEXTONAME) && HAVE_IF_INDEXTONAME && \ + defined(SO_BINDTODEVICE) + /* if a specific interface was set, bind the socket to it. But to avoid + * possible problems with multicast routing, only do that for non-multicast + * addresses */ + if (interface_idx != 0) { + char interface_name[IFNAMSIZ]; + + if (if_indextoname(interface_idx, interface_name) == NULL) + return (-1); + + DEBUG("fd = %i; Binding socket to interface %s", fd, interface_name); + + if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, interface_name, + sizeof(interface_name)) == -1) { + char errbuf[1024]; + ERROR("network plugin: setsockopt (bind-if): %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + } #endif /* HAVE_IF_INDEXTONAME && SO_BINDTODEVICE */ - return (0); + return (0); } /* int network_bind_socket */ /* Initialize a sockent structure. `type' must be either `SOCKENT_TYPE_CLIENT' * or `SOCKENT_TYPE_SERVER' */ -static sockent_t *sockent_create (int type) /* {{{ */ +static sockent_t *sockent_create(int type) /* {{{ */ { - sockent_t *se; + sockent_t *se; - if ((type != SOCKENT_TYPE_CLIENT) && (type != SOCKENT_TYPE_SERVER)) - return (NULL); + if ((type != SOCKENT_TYPE_CLIENT) && (type != SOCKENT_TYPE_SERVER)) + return (NULL); - se = calloc (1, sizeof (*se)); - if (se == NULL) - return (NULL); + se = calloc(1, sizeof(*se)); + if (se == NULL) + return (NULL); - se->type = type; - se->node = NULL; - se->service = NULL; - se->interface = 0; - se->next = NULL; + se->type = type; + se->node = NULL; + se->service = NULL; + se->interface = 0; + se->next = NULL; - if (type == SOCKENT_TYPE_SERVER) - { - se->data.server.fd = NULL; - se->data.server.fd_num = 0; + if (type == SOCKENT_TYPE_SERVER) { + se->data.server.fd = NULL; + se->data.server.fd_num = 0; #if HAVE_LIBGCRYPT - se->data.server.security_level = SECURITY_LEVEL_NONE; - se->data.server.auth_file = NULL; - se->data.server.userdb = NULL; - se->data.server.cypher = NULL; + se->data.server.security_level = SECURITY_LEVEL_NONE; + se->data.server.auth_file = NULL; + se->data.server.userdb = NULL; + se->data.server.cypher = NULL; #endif - } - else - { - se->data.client.fd = -1; - se->data.client.addr = NULL; - se->data.client.resolve_interval = 0; - se->data.client.next_resolve_reconnect = 0; + } else { + se->data.client.fd = -1; + se->data.client.addr = NULL; + se->data.client.resolve_interval = 0; + se->data.client.next_resolve_reconnect = 0; #if HAVE_LIBGCRYPT - se->data.client.security_level = SECURITY_LEVEL_NONE; - se->data.client.username = NULL; - se->data.client.password = NULL; - se->data.client.cypher = NULL; + se->data.client.security_level = SECURITY_LEVEL_NONE; + se->data.client.username = NULL; + se->data.client.password = NULL; + se->data.client.cypher = NULL; #endif - } + } - return (se); + return (se); } /* }}} sockent_t *sockent_create */ -static int sockent_init_crypto (sockent_t *se) /* {{{ */ +static int sockent_init_crypto(sockent_t *se) /* {{{ */ { #if HAVE_LIBGCRYPT /* {{{ */ - if (se->type == SOCKENT_TYPE_CLIENT) - { - if (se->data.client.security_level > SECURITY_LEVEL_NONE) - { - if (network_init_gcrypt () < 0) - { - ERROR ("network plugin: Cannot configure client socket with " - "security: Failed to initialize crypto library."); - return (-1); - } - - if ((se->data.client.username == NULL) - || (se->data.client.password == NULL)) - { - ERROR ("network plugin: Client socket with " - "security requested, but no " - "credentials are configured."); - return (-1); - } - gcry_md_hash_buffer (GCRY_MD_SHA256, - se->data.client.password_hash, - se->data.client.password, - strlen (se->data.client.password)); - } - } - else /* (se->type == SOCKENT_TYPE_SERVER) */ - { - if ((se->data.server.security_level > SECURITY_LEVEL_NONE) - && (se->data.server.auth_file == NULL)) - { - ERROR ("network plugin: Server socket with security requested, " - "but no \"AuthFile\" is configured."); - return (-1); - } - if (se->data.server.auth_file != NULL) - { - if (network_init_gcrypt () < 0) - { - ERROR ("network plugin: Cannot configure server socket with security: " - "Failed to initialize crypto library."); - return (-1); - } - - se->data.server.userdb = fbh_create (se->data.server.auth_file); - if (se->data.server.userdb == NULL) - { - ERROR ("network plugin: Reading password file \"%s\" failed.", - se->data.server.auth_file); - return (-1); - } - } - } + if (se->type == SOCKENT_TYPE_CLIENT) { + if (se->data.client.security_level > SECURITY_LEVEL_NONE) { + if (network_init_gcrypt() < 0) { + ERROR("network plugin: Cannot configure client socket with " + "security: Failed to initialize crypto library."); + return (-1); + } + + if ((se->data.client.username == NULL) || + (se->data.client.password == NULL)) { + ERROR("network plugin: Client socket with " + "security requested, but no " + "credentials are configured."); + return (-1); + } + gcry_md_hash_buffer(GCRY_MD_SHA256, se->data.client.password_hash, + se->data.client.password, + strlen(se->data.client.password)); + } + } else /* (se->type == SOCKENT_TYPE_SERVER) */ + { + if ((se->data.server.security_level > SECURITY_LEVEL_NONE) && + (se->data.server.auth_file == NULL)) { + ERROR("network plugin: Server socket with security requested, " + "but no \"AuthFile\" is configured."); + return (-1); + } + if (se->data.server.auth_file != NULL) { + if (network_init_gcrypt() < 0) { + ERROR("network plugin: Cannot configure server socket with security: " + "Failed to initialize crypto library."); + return (-1); + } + + se->data.server.userdb = fbh_create(se->data.server.auth_file); + if (se->data.server.userdb == NULL) { + ERROR("network plugin: Reading password file \"%s\" failed.", + se->data.server.auth_file); + return (-1); + } + } + } #endif /* }}} HAVE_LIBGCRYPT */ - return (0); + return (0); } /* }}} int sockent_init_crypto */ -static int sockent_client_disconnect (sockent_t *se) /* {{{ */ +static int sockent_client_disconnect(sockent_t *se) /* {{{ */ { - struct sockent_client *client; + struct sockent_client *client; - if ((se == NULL) || (se->type != SOCKENT_TYPE_CLIENT)) - return (EINVAL); + if ((se == NULL) || (se->type != SOCKENT_TYPE_CLIENT)) + return (EINVAL); - client = &se->data.client; - if (client->fd >= 0) /* connected */ - { - close (client->fd); - client->fd = -1; - } + client = &se->data.client; + if (client->fd >= 0) /* connected */ + { + close(client->fd); + client->fd = -1; + } - sfree (client->addr); - client->addrlen = 0; + sfree(client->addr); + client->addrlen = 0; - return (0); + return (0); } /* }}} int sockent_client_disconnect */ -static int sockent_client_connect (sockent_t *se) /* {{{ */ +static int sockent_client_connect(sockent_t *se) /* {{{ */ { - static c_complain_t complaint = C_COMPLAIN_INIT_STATIC; - - struct sockent_client *client; - struct addrinfo *ai_list; - int status; - _Bool reconnect = 0; - cdtime_t now; - - if ((se == NULL) || (se->type != SOCKENT_TYPE_CLIENT)) - return (EINVAL); - - client = &se->data.client; - - now = cdtime (); - if (client->resolve_interval != 0 && client->next_resolve_reconnect < now) { - DEBUG("network plugin: Reconnecting socket, resolve_interval = %lf, next_resolve_reconnect = %lf", - CDTIME_T_TO_DOUBLE(client->resolve_interval), CDTIME_T_TO_DOUBLE(client->next_resolve_reconnect)); - reconnect = 1; - } - - if (client->fd >= 0 && !reconnect) /* already connected and not stale*/ - return (0); - - struct addrinfo ai_hints = { - .ai_family = AF_UNSPEC, - .ai_flags = AI_ADDRCONFIG, - .ai_protocol = IPPROTO_UDP, - .ai_socktype = SOCK_DGRAM - }; - - status = getaddrinfo (se->node, - (se->service != NULL) ? se->service : NET_DEFAULT_PORT, - &ai_hints, &ai_list); - if (status != 0) - { - c_complain (LOG_ERR, &complaint, - "network plugin: getaddrinfo (%s, %s) failed: %s", - (se->node == NULL) ? "(null)" : se->node, - (se->service == NULL) ? "(null)" : se->service, - gai_strerror (status)); - return (-1); - } - else - { - c_release (LOG_NOTICE, &complaint, - "network plugin: Successfully resolved \"%s\".", - se->node); - } - - for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) - { - if (client->fd >= 0) /* when we reconnect */ - sockent_client_disconnect(se); - - client->fd = socket (ai_ptr->ai_family, - ai_ptr->ai_socktype, - ai_ptr->ai_protocol); - if (client->fd < 0) - { - char errbuf[1024]; - ERROR ("network plugin: socket(2) failed: %s", - sstrerror (errno, errbuf, - sizeof (errbuf))); - continue; - } - - client->addr = calloc (1, sizeof (*client->addr)); - if (client->addr == NULL) - { - ERROR ("network plugin: calloc failed."); - close (client->fd); - client->fd = -1; - continue; - } - - assert (sizeof (*client->addr) >= ai_ptr->ai_addrlen); - memcpy (client->addr, ai_ptr->ai_addr, ai_ptr->ai_addrlen); - client->addrlen = ai_ptr->ai_addrlen; - - network_set_ttl (se, ai_ptr); - network_set_interface (se, ai_ptr); - - /* We don't open more than one write-socket per - * node/service pair.. */ - break; - } - - freeaddrinfo (ai_list); - if (client->fd < 0) - return (-1); - - if (client->resolve_interval > 0) - client->next_resolve_reconnect = now + client->resolve_interval; - return (0); + static c_complain_t complaint = C_COMPLAIN_INIT_STATIC; + + struct sockent_client *client; + struct addrinfo *ai_list; + int status; + _Bool reconnect = 0; + cdtime_t now; + + if ((se == NULL) || (se->type != SOCKENT_TYPE_CLIENT)) + return (EINVAL); + + client = &se->data.client; + + now = cdtime(); + if (client->resolve_interval != 0 && client->next_resolve_reconnect < now) { + DEBUG("network plugin: Reconnecting socket, resolve_interval = %lf, " + "next_resolve_reconnect = %lf", + CDTIME_T_TO_DOUBLE(client->resolve_interval), + CDTIME_T_TO_DOUBLE(client->next_resolve_reconnect)); + reconnect = 1; + } + + if (client->fd >= 0 && !reconnect) /* already connected and not stale*/ + return (0); + + struct addrinfo ai_hints = {.ai_family = AF_UNSPEC, + .ai_flags = AI_ADDRCONFIG, + .ai_protocol = IPPROTO_UDP, + .ai_socktype = SOCK_DGRAM}; + + status = getaddrinfo(se->node, + (se->service != NULL) ? se->service : NET_DEFAULT_PORT, + &ai_hints, &ai_list); + if (status != 0) { + c_complain( + LOG_ERR, &complaint, "network plugin: getaddrinfo (%s, %s) failed: %s", + (se->node == NULL) ? "(null)" : se->node, + (se->service == NULL) ? "(null)" : se->service, gai_strerror(status)); + return (-1); + } else { + c_release(LOG_NOTICE, &complaint, + "network plugin: Successfully resolved \"%s\".", se->node); + } + + for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; + ai_ptr = ai_ptr->ai_next) { + if (client->fd >= 0) /* when we reconnect */ + sockent_client_disconnect(se); + + client->fd = + socket(ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); + if (client->fd < 0) { + char errbuf[1024]; + ERROR("network plugin: socket(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + continue; + } + + client->addr = calloc(1, sizeof(*client->addr)); + if (client->addr == NULL) { + ERROR("network plugin: calloc failed."); + close(client->fd); + client->fd = -1; + continue; + } + + assert(sizeof(*client->addr) >= ai_ptr->ai_addrlen); + memcpy(client->addr, ai_ptr->ai_addr, ai_ptr->ai_addrlen); + client->addrlen = ai_ptr->ai_addrlen; + + network_set_ttl(se, ai_ptr); + network_set_interface(se, ai_ptr); + + /* We don't open more than one write-socket per + * node/service pair.. */ + break; + } + + freeaddrinfo(ai_list); + if (client->fd < 0) + return (-1); + + if (client->resolve_interval > 0) + client->next_resolve_reconnect = now + client->resolve_interval; + return (0); } /* }}} int sockent_client_connect */ /* Open the file descriptors for a initialized sockent structure. */ -static int sockent_server_listen (sockent_t *se) /* {{{ */ +static int sockent_server_listen(sockent_t *se) /* {{{ */ { - struct addrinfo *ai_list; - int status; - - const char *node; - const char *service; - - if (se == NULL) - return (-1); - - assert (se->data.server.fd == NULL); - assert (se->data.server.fd_num == 0); - - node = se->node; - service = se->service; - - if (service == NULL) - service = NET_DEFAULT_PORT; - - DEBUG ("network plugin: sockent_server_listen: node = %s; service = %s;", - node, service); - - struct addrinfo ai_hints = { - .ai_family = AF_UNSPEC, - .ai_flags = AI_ADDRCONFIG | AI_PASSIVE, - .ai_protocol = IPPROTO_UDP, - .ai_socktype = SOCK_DGRAM - }; - - status = getaddrinfo (node, service, &ai_hints, &ai_list); - if (status != 0) - { - ERROR ("network plugin: getaddrinfo (%s, %s) failed: %s", - (se->node == NULL) ? "(null)" : se->node, - (se->service == NULL) ? "(null)" : se->service, - gai_strerror (status)); - return (-1); - } - - for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) - { - int *tmp; - - tmp = realloc (se->data.server.fd, - sizeof (*tmp) * (se->data.server.fd_num + 1)); - if (tmp == NULL) - { - ERROR ("network plugin: realloc failed."); - continue; - } - se->data.server.fd = tmp; - tmp = se->data.server.fd + se->data.server.fd_num; - - *tmp = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, - ai_ptr->ai_protocol); - if (*tmp < 0) - { - char errbuf[1024]; - ERROR ("network plugin: socket(2) failed: %s", - sstrerror (errno, errbuf, - sizeof (errbuf))); - continue; - } - - status = network_bind_socket (*tmp, ai_ptr, se->interface); - if (status != 0) - { - close (*tmp); - *tmp = -1; - continue; - } - - se->data.server.fd_num++; - continue; - } /* for (ai_list) */ - - freeaddrinfo (ai_list); - - if (se->data.server.fd_num == 0) - return (-1); - return (0); + struct addrinfo *ai_list; + int status; + + const char *node; + const char *service; + + if (se == NULL) + return (-1); + + assert(se->data.server.fd == NULL); + assert(se->data.server.fd_num == 0); + + node = se->node; + service = se->service; + + if (service == NULL) + service = NET_DEFAULT_PORT; + + DEBUG("network plugin: sockent_server_listen: node = %s; service = %s;", node, + service); + + struct addrinfo ai_hints = {.ai_family = AF_UNSPEC, + .ai_flags = AI_ADDRCONFIG | AI_PASSIVE, + .ai_protocol = IPPROTO_UDP, + .ai_socktype = SOCK_DGRAM}; + + status = getaddrinfo(node, service, &ai_hints, &ai_list); + if (status != 0) { + ERROR("network plugin: getaddrinfo (%s, %s) failed: %s", + (se->node == NULL) ? "(null)" : se->node, + (se->service == NULL) ? "(null)" : se->service, gai_strerror(status)); + return (-1); + } + + for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; + ai_ptr = ai_ptr->ai_next) { + int *tmp; + + tmp = realloc(se->data.server.fd, + sizeof(*tmp) * (se->data.server.fd_num + 1)); + if (tmp == NULL) { + ERROR("network plugin: realloc failed."); + continue; + } + se->data.server.fd = tmp; + tmp = se->data.server.fd + se->data.server.fd_num; + + *tmp = socket(ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); + if (*tmp < 0) { + char errbuf[1024]; + ERROR("network plugin: socket(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + continue; + } + + status = network_bind_socket(*tmp, ai_ptr, se->interface); + if (status != 0) { + close(*tmp); + *tmp = -1; + continue; + } + + se->data.server.fd_num++; + continue; + } /* for (ai_list) */ + + freeaddrinfo(ai_list); + + if (se->data.server.fd_num == 0) + return (-1); + return (0); } /* }}} int sockent_server_listen */ /* Add a sockent to the global list of sockets */ -static int sockent_add (sockent_t *se) /* {{{ */ +static int sockent_add(sockent_t *se) /* {{{ */ { - sockent_t *last_ptr; - - if (se == NULL) - return (-1); - - if (se->type == SOCKENT_TYPE_SERVER) - { - struct pollfd *tmp; - - tmp = realloc (listen_sockets_pollfd, - sizeof (*tmp) * (listen_sockets_num - + se->data.server.fd_num)); - if (tmp == NULL) - { - ERROR ("network plugin: realloc failed."); - return (-1); - } - listen_sockets_pollfd = tmp; - tmp = listen_sockets_pollfd + listen_sockets_num; - - for (size_t i = 0; i < se->data.server.fd_num; i++) - { - memset (tmp + i, 0, sizeof (*tmp)); - tmp[i].fd = se->data.server.fd[i]; - tmp[i].events = POLLIN | POLLPRI; - tmp[i].revents = 0; - } - - listen_sockets_num += se->data.server.fd_num; - - if (listen_sockets == NULL) - { - listen_sockets = se; - return (0); - } - last_ptr = listen_sockets; - } - else /* if (se->type == SOCKENT_TYPE_CLIENT) */ - { - if (sending_sockets == NULL) - { - sending_sockets = se; - return (0); - } - last_ptr = sending_sockets; - } - - while (last_ptr->next != NULL) - last_ptr = last_ptr->next; - last_ptr->next = se; - - return (0); + sockent_t *last_ptr; + + if (se == NULL) + return (-1); + + if (se->type == SOCKENT_TYPE_SERVER) { + struct pollfd *tmp; + + tmp = realloc(listen_sockets_pollfd, + sizeof(*tmp) * (listen_sockets_num + se->data.server.fd_num)); + if (tmp == NULL) { + ERROR("network plugin: realloc failed."); + return (-1); + } + listen_sockets_pollfd = tmp; + tmp = listen_sockets_pollfd + listen_sockets_num; + + for (size_t i = 0; i < se->data.server.fd_num; i++) { + memset(tmp + i, 0, sizeof(*tmp)); + tmp[i].fd = se->data.server.fd[i]; + tmp[i].events = POLLIN | POLLPRI; + tmp[i].revents = 0; + } + + listen_sockets_num += se->data.server.fd_num; + + if (listen_sockets == NULL) { + listen_sockets = se; + return (0); + } + last_ptr = listen_sockets; + } else /* if (se->type == SOCKENT_TYPE_CLIENT) */ + { + if (sending_sockets == NULL) { + sending_sockets = se; + return (0); + } + last_ptr = sending_sockets; + } + + while (last_ptr->next != NULL) + last_ptr = last_ptr->next; + last_ptr->next = se; + + return (0); } /* }}} int sockent_add */ -static void *dispatch_thread (void __attribute__((unused)) *arg) /* {{{ */ +static void *dispatch_thread(void __attribute__((unused)) * arg) /* {{{ */ { - while (42) - { + while (42) { receive_list_entry_t *ent; sockent_t *se; /* Lock and wait for more data to come in */ - pthread_mutex_lock (&receive_list_lock); - while ((listen_loop == 0) - && (receive_list_head == NULL)) - pthread_cond_wait (&receive_list_cond, &receive_list_lock); + pthread_mutex_lock(&receive_list_lock); + while ((listen_loop == 0) && (receive_list_head == NULL)) + pthread_cond_wait(&receive_list_cond, &receive_list_lock); /* Remove the head entry and unlock */ ent = receive_list_head; if (ent != NULL) receive_list_head = ent->next; receive_list_length--; - pthread_mutex_unlock (&receive_list_lock); + pthread_mutex_unlock(&receive_list_lock); /* Check whether we are supposed to exit. We do NOT check `listen_loop' * because we dispatch all missing packets before shutting down. */ @@ -2402,8 +2178,7 @@ static void *dispatch_thread (void __attribute__((unused)) *arg) /* {{{ */ /* Look for the correct `sockent_t' */ se = listen_sockets; - while (se != NULL) - { + while (se != NULL) { size_t i; for (i = 0; i < se->data.server.fd_num; i++) @@ -2416,216 +2191,200 @@ static void *dispatch_thread (void __attribute__((unused)) *arg) /* {{{ */ se = se->next; } - if (se == NULL) - { - ERROR ("network plugin: Got packet from FD %i, but can't " - "find an appropriate socket entry.", - ent->fd); - sfree (ent->data); - sfree (ent); + if (se == NULL) { + ERROR("network plugin: Got packet from FD %i, but can't " + "find an appropriate socket entry.", + ent->fd); + sfree(ent->data); + sfree(ent); continue; } - parse_packet (se, ent->data, ent->data_len, /* flags = */ 0, - /* username = */ NULL); - sfree (ent->data); - sfree (ent); + parse_packet(se, ent->data, ent->data_len, /* flags = */ 0, + /* username = */ NULL); + sfree(ent->data); + sfree(ent); } /* while (42) */ return (NULL); } /* }}} void *dispatch_thread */ -static int network_receive (void) /* {{{ */ +static int network_receive(void) /* {{{ */ { - char buffer[network_config_packet_size]; - int buffer_len; - - int status = 0; - - receive_list_entry_t *private_list_head; - receive_list_entry_t *private_list_tail; - uint64_t private_list_length; - - assert (listen_sockets_num > 0); - - private_list_head = NULL; - private_list_tail = NULL; - private_list_length = 0; - - while (listen_loop == 0) - { - status = poll (listen_sockets_pollfd, listen_sockets_num, -1); - if (status <= 0) - { - char errbuf[1024]; - if (errno == EINTR) - continue; - ERROR ("network plugin: poll(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - break; - } - - for (size_t i = 0; (i < listen_sockets_num) && (status > 0); i++) - { - receive_list_entry_t *ent; - - if ((listen_sockets_pollfd[i].revents - & (POLLIN | POLLPRI)) == 0) - continue; - status--; - - buffer_len = recv (listen_sockets_pollfd[i].fd, - buffer, sizeof (buffer), - 0 /* no flags */); - if (buffer_len < 0) - { - char errbuf[1024]; - status = (errno != 0) ? errno : -1; - ERROR ("network plugin: recv(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - break; - } - - stats_octets_rx += ((uint64_t) buffer_len); - stats_packets_rx++; - - /* TODO: Possible performance enhancement: Do not free - * these entries in the dispatch thread but put them in - * another list, so we don't have to allocate more and - * more of these structures. */ - ent = calloc (1, sizeof (*ent)); - if (ent == NULL) - { - ERROR ("network plugin: calloc failed."); - status = ENOMEM; - break; - } - - ent->data = malloc (network_config_packet_size); - if (ent->data == NULL) - { - sfree (ent); - ERROR ("network plugin: malloc failed."); - status = ENOMEM; - break; - } - ent->fd = listen_sockets_pollfd[i].fd; - ent->next = NULL; - - memcpy (ent->data, buffer, buffer_len); - ent->data_len = buffer_len; - - if (private_list_head == NULL) - private_list_head = ent; - else - private_list_tail->next = ent; - private_list_tail = ent; - private_list_length++; - - /* Do not block here. Blocking here has led to - * insufficient performance in the past. */ - if (pthread_mutex_trylock (&receive_list_lock) == 0) - { - assert (((receive_list_head == NULL) && (receive_list_length == 0)) - || ((receive_list_head != NULL) && (receive_list_length != 0))); - - if (receive_list_head == NULL) - receive_list_head = private_list_head; - else - receive_list_tail->next = private_list_head; - receive_list_tail = private_list_tail; - receive_list_length += private_list_length; - - pthread_cond_signal (&receive_list_cond); - pthread_mutex_unlock (&receive_list_lock); - - private_list_head = NULL; - private_list_tail = NULL; - private_list_length = 0; - } - - status = 0; - } /* for (listen_sockets_pollfd) */ - - if (status != 0) - break; - } /* while (listen_loop == 0) */ - - /* Make sure everything is dispatched before exiting. */ - if (private_list_head != NULL) - { - pthread_mutex_lock (&receive_list_lock); - - if (receive_list_head == NULL) - receive_list_head = private_list_head; - else - receive_list_tail->next = private_list_head; - receive_list_tail = private_list_tail; - receive_list_length += private_list_length; - - pthread_cond_signal (&receive_list_cond); - pthread_mutex_unlock (&receive_list_lock); - } - - return (status); + char buffer[network_config_packet_size]; + int buffer_len; + + int status = 0; + + receive_list_entry_t *private_list_head; + receive_list_entry_t *private_list_tail; + uint64_t private_list_length; + + assert(listen_sockets_num > 0); + + private_list_head = NULL; + private_list_tail = NULL; + private_list_length = 0; + + while (listen_loop == 0) { + status = poll(listen_sockets_pollfd, listen_sockets_num, -1); + if (status <= 0) { + char errbuf[1024]; + if (errno == EINTR) + continue; + ERROR("network plugin: poll(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + break; + } + + for (size_t i = 0; (i < listen_sockets_num) && (status > 0); i++) { + receive_list_entry_t *ent; + + if ((listen_sockets_pollfd[i].revents & (POLLIN | POLLPRI)) == 0) + continue; + status--; + + buffer_len = recv(listen_sockets_pollfd[i].fd, buffer, sizeof(buffer), + 0 /* no flags */); + if (buffer_len < 0) { + char errbuf[1024]; + status = (errno != 0) ? errno : -1; + ERROR("network plugin: recv(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + break; + } + + stats_octets_rx += ((uint64_t)buffer_len); + stats_packets_rx++; + + /* TODO: Possible performance enhancement: Do not free + * these entries in the dispatch thread but put them in + * another list, so we don't have to allocate more and + * more of these structures. */ + ent = calloc(1, sizeof(*ent)); + if (ent == NULL) { + ERROR("network plugin: calloc failed."); + status = ENOMEM; + break; + } + + ent->data = malloc(network_config_packet_size); + if (ent->data == NULL) { + sfree(ent); + ERROR("network plugin: malloc failed."); + status = ENOMEM; + break; + } + ent->fd = listen_sockets_pollfd[i].fd; + ent->next = NULL; + + memcpy(ent->data, buffer, buffer_len); + ent->data_len = buffer_len; + + if (private_list_head == NULL) + private_list_head = ent; + else + private_list_tail->next = ent; + private_list_tail = ent; + private_list_length++; + + /* Do not block here. Blocking here has led to + * insufficient performance in the past. */ + if (pthread_mutex_trylock(&receive_list_lock) == 0) { + assert(((receive_list_head == NULL) && (receive_list_length == 0)) || + ((receive_list_head != NULL) && (receive_list_length != 0))); + + if (receive_list_head == NULL) + receive_list_head = private_list_head; + else + receive_list_tail->next = private_list_head; + receive_list_tail = private_list_tail; + receive_list_length += private_list_length; + + pthread_cond_signal(&receive_list_cond); + pthread_mutex_unlock(&receive_list_lock); + + private_list_head = NULL; + private_list_tail = NULL; + private_list_length = 0; + } + + status = 0; + } /* for (listen_sockets_pollfd) */ + + if (status != 0) + break; + } /* while (listen_loop == 0) */ + + /* Make sure everything is dispatched before exiting. */ + if (private_list_head != NULL) { + pthread_mutex_lock(&receive_list_lock); + + if (receive_list_head == NULL) + receive_list_head = private_list_head; + else + receive_list_tail->next = private_list_head; + receive_list_tail = private_list_tail; + receive_list_length += private_list_length; + + pthread_cond_signal(&receive_list_cond); + pthread_mutex_unlock(&receive_list_lock); + } + + return (status); } /* }}} int network_receive */ -static void *receive_thread (void __attribute__((unused)) *arg) -{ - return (network_receive () ? (void *) 1 : (void *) 0); +static void *receive_thread(void __attribute__((unused)) * arg) { + return (network_receive() ? (void *)1 : (void *)0); } /* void *receive_thread */ -static void network_init_buffer (void) -{ - memset (send_buffer, 0, network_config_packet_size); - send_buffer_ptr = send_buffer; - send_buffer_fill = 0; - send_buffer_last_update = 0; +static void network_init_buffer(void) { + memset(send_buffer, 0, network_config_packet_size); + send_buffer_ptr = send_buffer; + send_buffer_fill = 0; + send_buffer_last_update = 0; - memset (&send_buffer_vl, 0, sizeof (send_buffer_vl)); + memset(&send_buffer_vl, 0, sizeof(send_buffer_vl)); } /* int network_init_buffer */ -static void network_send_buffer_plain (sockent_t *se, /* {{{ */ - const char *buffer, size_t buffer_size) -{ - int status; - - while (42) - { - status = sockent_client_connect (se); - if (status != 0) - return; - - status = sendto (se->data.client.fd, buffer, buffer_size, - /* flags = */ 0, - (struct sockaddr *) se->data.client.addr, - se->data.client.addrlen); - if (status < 0) - { - char errbuf[1024]; - - if ((errno == EINTR) || (errno == EAGAIN)) - continue; - - ERROR ("network plugin: sendto failed: %s. Closing sending socket.", - sstrerror (errno, errbuf, sizeof (errbuf))); - sockent_client_disconnect (se); - return; - } - - break; - } /* while (42) */ +static void network_send_buffer_plain(sockent_t *se, /* {{{ */ + const char *buffer, size_t buffer_size) { + int status; + + while (42) { + status = sockent_client_connect(se); + if (status != 0) + return; + + status = sendto(se->data.client.fd, buffer, buffer_size, + /* flags = */ 0, (struct sockaddr *)se->data.client.addr, + se->data.client.addrlen); + if (status < 0) { + char errbuf[1024]; + + if ((errno == EINTR) || (errno == EAGAIN)) + continue; + + ERROR("network plugin: sendto failed: %s. Closing sending socket.", + sstrerror(errno, errbuf, sizeof(errbuf))); + sockent_client_disconnect(se); + return; + } + + break; + } /* while (42) */ } /* }}} void network_send_buffer_plain */ #if HAVE_LIBGCRYPT -#define BUFFER_ADD(p,s) do { \ - memcpy (buffer + buffer_offset, (p), (s)); \ - buffer_offset += (s); \ -} while (0) - -static void network_send_buffer_signed (sockent_t *se, /* {{{ */ - const char *in_buffer, size_t in_buffer_size) -{ +#define BUFFER_ADD(p, s) \ + do { \ + memcpy(buffer + buffer_offset, (p), (s)); \ + buffer_offset += (s); \ + } while (0) + +static void network_send_buffer_signed(sockent_t *se, /* {{{ */ + const char *in_buffer, + size_t in_buffer_size) { char buffer[BUFF_SIG_SIZE + in_buffer_size]; size_t buffer_offset; size_t username_len; @@ -2635,74 +2394,67 @@ static void network_send_buffer_signed (sockent_t *se, /* {{{ */ unsigned char *hash; hd = NULL; - err = gcry_md_open (&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); - if (err != 0) - { - ERROR ("network plugin: Creating HMAC object failed: %s", - gcry_strerror (err)); + err = gcry_md_open(&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); + if (err != 0) { + ERROR("network plugin: Creating HMAC object failed: %s", + gcry_strerror(err)); return; } - err = gcry_md_setkey (hd, se->data.client.password, - strlen (se->data.client.password)); - if (err != 0) - { - ERROR ("network plugin: gcry_md_setkey failed: %s", - gcry_strerror (err)); - gcry_md_close (hd); + err = gcry_md_setkey(hd, se->data.client.password, + strlen(se->data.client.password)); + if (err != 0) { + ERROR("network plugin: gcry_md_setkey failed: %s", gcry_strerror(err)); + gcry_md_close(hd); return; } - username_len = strlen (se->data.client.username); - if (username_len > (BUFF_SIG_SIZE - PART_SIGNATURE_SHA256_SIZE)) - { - ERROR ("network plugin: Username too long: %s", - se->data.client.username); + username_len = strlen(se->data.client.username); + if (username_len > (BUFF_SIG_SIZE - PART_SIGNATURE_SHA256_SIZE)) { + ERROR("network plugin: Username too long: %s", se->data.client.username); return; } - memcpy (buffer + PART_SIGNATURE_SHA256_SIZE, - se->data.client.username, username_len); - memcpy (buffer + PART_SIGNATURE_SHA256_SIZE + username_len, - in_buffer, in_buffer_size); + memcpy(buffer + PART_SIGNATURE_SHA256_SIZE, se->data.client.username, + username_len); + memcpy(buffer + PART_SIGNATURE_SHA256_SIZE + username_len, in_buffer, + in_buffer_size); /* Initialize the `ps' structure. */ part_signature_sha256_t ps = { - .head.type = htons (TYPE_SIGN_SHA256), - .head.length = htons (PART_SIGNATURE_SHA256_SIZE + username_len) - }; + .head.type = htons(TYPE_SIGN_SHA256), + .head.length = htons(PART_SIGNATURE_SHA256_SIZE + username_len)}; /* Calculate the hash value. */ - gcry_md_write (hd, buffer + PART_SIGNATURE_SHA256_SIZE, - username_len + in_buffer_size); - hash = gcry_md_read (hd, GCRY_MD_SHA256); - if (hash == NULL) - { - ERROR ("network plugin: gcry_md_read failed."); - gcry_md_close (hd); + gcry_md_write(hd, buffer + PART_SIGNATURE_SHA256_SIZE, + username_len + in_buffer_size); + hash = gcry_md_read(hd, GCRY_MD_SHA256); + if (hash == NULL) { + ERROR("network plugin: gcry_md_read failed."); + gcry_md_close(hd); return; } - memcpy (ps.hash, hash, sizeof (ps.hash)); + memcpy(ps.hash, hash, sizeof(ps.hash)); /* Add the header */ buffer_offset = 0; - BUFFER_ADD (&ps.head.type, sizeof (ps.head.type)); - BUFFER_ADD (&ps.head.length, sizeof (ps.head.length)); - BUFFER_ADD (ps.hash, sizeof (ps.hash)); + BUFFER_ADD(&ps.head.type, sizeof(ps.head.type)); + BUFFER_ADD(&ps.head.length, sizeof(ps.head.length)); + BUFFER_ADD(ps.hash, sizeof(ps.hash)); - assert (buffer_offset == PART_SIGNATURE_SHA256_SIZE); + assert(buffer_offset == PART_SIGNATURE_SHA256_SIZE); - gcry_md_close (hd); + gcry_md_close(hd); hd = NULL; buffer_offset = PART_SIGNATURE_SHA256_SIZE + username_len + in_buffer_size; - network_send_buffer_plain (se, buffer, buffer_offset); + network_send_buffer_plain(se, buffer, buffer_offset); } /* }}} void network_send_buffer_signed */ -static void network_send_buffer_encrypted (sockent_t *se, /* {{{ */ - const char *in_buffer, size_t in_buffer_size) -{ +static void network_send_buffer_encrypted(sockent_t *se, /* {{{ */ + const char *in_buffer, + size_t in_buffer_size) { char buffer[BUFF_SIG_SIZE + in_buffer_size]; size_t buffer_size; size_t buffer_offset; @@ -2712,291 +2464,267 @@ static void network_send_buffer_encrypted (sockent_t *se, /* {{{ */ gcry_cipher_hd_t cypher; /* Initialize the header fields */ - part_encryption_aes256_t pea = { - .head.type = htons (TYPE_ENCR_AES256), - .username = se->data.client.username - }; + part_encryption_aes256_t pea = {.head.type = htons(TYPE_ENCR_AES256), + .username = se->data.client.username}; - username_len = strlen (pea.username); - if ((PART_ENCRYPTION_AES256_SIZE + username_len) > BUFF_SIG_SIZE) - { - ERROR ("network plugin: Username too long: %s", pea.username); + username_len = strlen(pea.username); + if ((PART_ENCRYPTION_AES256_SIZE + username_len) > BUFF_SIG_SIZE) { + ERROR("network plugin: Username too long: %s", pea.username); return; } buffer_size = PART_ENCRYPTION_AES256_SIZE + username_len + in_buffer_size; - header_size = PART_ENCRYPTION_AES256_SIZE + username_len - - sizeof (pea.hash); + header_size = PART_ENCRYPTION_AES256_SIZE + username_len - sizeof(pea.hash); - assert (buffer_size <= sizeof (buffer)); - DEBUG ("network plugin: network_send_buffer_encrypted: " - "buffer_size = %zu;", buffer_size); + assert(buffer_size <= sizeof(buffer)); + DEBUG("network plugin: network_send_buffer_encrypted: " + "buffer_size = %zu;", + buffer_size); - pea.head.length = htons ((uint16_t) (PART_ENCRYPTION_AES256_SIZE - + username_len + in_buffer_size)); - pea.username_length = htons ((uint16_t) username_len); + pea.head.length = htons( + (uint16_t)(PART_ENCRYPTION_AES256_SIZE + username_len + in_buffer_size)); + pea.username_length = htons((uint16_t)username_len); /* Chose a random initialization vector. */ - gcry_randomize ((void *) &pea.iv, sizeof (pea.iv), GCRY_STRONG_RANDOM); + gcry_randomize((void *)&pea.iv, sizeof(pea.iv), GCRY_STRONG_RANDOM); /* Create hash of the payload */ - gcry_md_hash_buffer (GCRY_MD_SHA1, pea.hash, in_buffer, in_buffer_size); + gcry_md_hash_buffer(GCRY_MD_SHA1, pea.hash, in_buffer, in_buffer_size); /* Initialize the buffer */ buffer_offset = 0; - memset (buffer, 0, sizeof (buffer)); + memset(buffer, 0, sizeof(buffer)); + BUFFER_ADD(&pea.head.type, sizeof(pea.head.type)); + BUFFER_ADD(&pea.head.length, sizeof(pea.head.length)); + BUFFER_ADD(&pea.username_length, sizeof(pea.username_length)); + BUFFER_ADD(pea.username, username_len); + BUFFER_ADD(pea.iv, sizeof(pea.iv)); + assert(buffer_offset == header_size); + BUFFER_ADD(pea.hash, sizeof(pea.hash)); + BUFFER_ADD(in_buffer, in_buffer_size); - BUFFER_ADD (&pea.head.type, sizeof (pea.head.type)); - BUFFER_ADD (&pea.head.length, sizeof (pea.head.length)); - BUFFER_ADD (&pea.username_length, sizeof (pea.username_length)); - BUFFER_ADD (pea.username, username_len); - BUFFER_ADD (pea.iv, sizeof (pea.iv)); - assert (buffer_offset == header_size); - BUFFER_ADD (pea.hash, sizeof (pea.hash)); - BUFFER_ADD (in_buffer, in_buffer_size); + assert(buffer_offset == buffer_size); - assert (buffer_offset == buffer_size); - - cypher = network_get_aes256_cypher (se, pea.iv, sizeof (pea.iv), - se->data.client.password); + cypher = network_get_aes256_cypher(se, pea.iv, sizeof(pea.iv), + se->data.client.password); if (cypher == NULL) return; /* Encrypt the buffer in-place */ - err = gcry_cipher_encrypt (cypher, - buffer + header_size, - buffer_size - header_size, - /* in = */ NULL, /* in len = */ 0); - if (err != 0) - { - ERROR ("network plugin: gcry_cipher_encrypt returned: %s", - gcry_strerror (err)); + err = gcry_cipher_encrypt(cypher, buffer + header_size, + buffer_size - header_size, + /* in = */ NULL, /* in len = */ 0); + if (err != 0) { + ERROR("network plugin: gcry_cipher_encrypt returned: %s", + gcry_strerror(err)); return; } /* Send it out without further modifications */ - network_send_buffer_plain (se, buffer, buffer_size); + network_send_buffer_plain(se, buffer, buffer_size); } /* }}} void network_send_buffer_encrypted */ #undef BUFFER_ADD #endif /* HAVE_LIBGCRYPT */ -static void network_send_buffer (char *buffer, size_t buffer_len) /* {{{ */ +static void network_send_buffer(char *buffer, size_t buffer_len) /* {{{ */ { - DEBUG ("network plugin: network_send_buffer: buffer_len = %zu", buffer_len); + DEBUG("network plugin: network_send_buffer: buffer_len = %zu", buffer_len); - for (sockent_t *se = sending_sockets; se != NULL; se = se->next) - { + for (sockent_t *se = sending_sockets; se != NULL; se = se->next) { #if HAVE_LIBGCRYPT if (se->data.client.security_level == SECURITY_LEVEL_ENCRYPT) - network_send_buffer_encrypted (se, buffer, buffer_len); + network_send_buffer_encrypted(se, buffer, buffer_len); else if (se->data.client.security_level == SECURITY_LEVEL_SIGN) - network_send_buffer_signed (se, buffer, buffer_len); + network_send_buffer_signed(se, buffer, buffer_len); else /* if (se->data.client.security_level == SECURITY_LEVEL_NONE) */ -#endif /* HAVE_LIBGCRYPT */ - network_send_buffer_plain (se, buffer, buffer_len); +#endif /* HAVE_LIBGCRYPT */ + network_send_buffer_plain(se, buffer, buffer_len); } /* for (sending_sockets) */ } /* }}} void network_send_buffer */ -static int add_to_buffer (char *buffer, size_t buffer_size, /* {{{ */ - value_list_t *vl_def, - const data_set_t *ds, const value_list_t *vl) -{ - char *buffer_orig = buffer; - - if (strcmp (vl_def->host, vl->host) != 0) - { - if (write_part_string (&buffer, &buffer_size, TYPE_HOST, - vl->host, strlen (vl->host)) != 0) - return (-1); - sstrncpy (vl_def->host, vl->host, sizeof (vl_def->host)); - } - - if (vl_def->time != vl->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_HR, - (uint64_t) vl->interval)) - return (-1); - vl_def->interval = vl->interval; - } - - if (strcmp (vl_def->plugin, vl->plugin) != 0) - { - if (write_part_string (&buffer, &buffer_size, TYPE_PLUGIN, - vl->plugin, strlen (vl->plugin)) != 0) - return (-1); - sstrncpy (vl_def->plugin, vl->plugin, sizeof (vl_def->plugin)); - } - - if (strcmp (vl_def->plugin_instance, vl->plugin_instance) != 0) - { - if (write_part_string (&buffer, &buffer_size, TYPE_PLUGIN_INSTANCE, - vl->plugin_instance, - strlen (vl->plugin_instance)) != 0) - return (-1); - sstrncpy (vl_def->plugin_instance, vl->plugin_instance, sizeof (vl_def->plugin_instance)); - } - - if (strcmp (vl_def->type, vl->type) != 0) - { - if (write_part_string (&buffer, &buffer_size, TYPE_TYPE, - vl->type, strlen (vl->type)) != 0) - return (-1); - sstrncpy (vl_def->type, ds->type, sizeof (vl_def->type)); - } - - if (strcmp (vl_def->type_instance, vl->type_instance) != 0) - { - if (write_part_string (&buffer, &buffer_size, TYPE_TYPE_INSTANCE, - vl->type_instance, - strlen (vl->type_instance)) != 0) - return (-1); - sstrncpy (vl_def->type_instance, vl->type_instance, sizeof (vl_def->type_instance)); - } - - if (write_part_values (&buffer, &buffer_size, ds, vl) != 0) - return (-1); - - return (buffer - buffer_orig); +static int add_to_buffer(char *buffer, size_t buffer_size, /* {{{ */ + value_list_t *vl_def, const data_set_t *ds, + const value_list_t *vl) { + char *buffer_orig = buffer; + + if (strcmp(vl_def->host, vl->host) != 0) { + if (write_part_string(&buffer, &buffer_size, TYPE_HOST, vl->host, + strlen(vl->host)) != 0) + return (-1); + sstrncpy(vl_def->host, vl->host, sizeof(vl_def->host)); + } + + if (vl_def->time != vl->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_HR, + (uint64_t)vl->interval)) + return (-1); + vl_def->interval = vl->interval; + } + + if (strcmp(vl_def->plugin, vl->plugin) != 0) { + if (write_part_string(&buffer, &buffer_size, TYPE_PLUGIN, vl->plugin, + strlen(vl->plugin)) != 0) + return (-1); + sstrncpy(vl_def->plugin, vl->plugin, sizeof(vl_def->plugin)); + } + + if (strcmp(vl_def->plugin_instance, vl->plugin_instance) != 0) { + if (write_part_string(&buffer, &buffer_size, TYPE_PLUGIN_INSTANCE, + vl->plugin_instance, + strlen(vl->plugin_instance)) != 0) + return (-1); + sstrncpy(vl_def->plugin_instance, vl->plugin_instance, + sizeof(vl_def->plugin_instance)); + } + + if (strcmp(vl_def->type, vl->type) != 0) { + if (write_part_string(&buffer, &buffer_size, TYPE_TYPE, vl->type, + strlen(vl->type)) != 0) + return (-1); + sstrncpy(vl_def->type, ds->type, sizeof(vl_def->type)); + } + + if (strcmp(vl_def->type_instance, vl->type_instance) != 0) { + if (write_part_string(&buffer, &buffer_size, TYPE_TYPE_INSTANCE, + vl->type_instance, strlen(vl->type_instance)) != 0) + return (-1); + sstrncpy(vl_def->type_instance, vl->type_instance, + sizeof(vl_def->type_instance)); + } + + if (write_part_values(&buffer, &buffer_size, ds, vl) != 0) + return (-1); + + return (buffer - buffer_orig); } /* }}} int add_to_buffer */ -static void flush_buffer (void) -{ - DEBUG ("network plugin: flush_buffer: send_buffer_fill = %i", - send_buffer_fill); +static void flush_buffer(void) { + DEBUG("network plugin: flush_buffer: send_buffer_fill = %i", + send_buffer_fill); - network_send_buffer (send_buffer, (size_t) send_buffer_fill); + network_send_buffer(send_buffer, (size_t)send_buffer_fill); - stats_octets_tx += ((uint64_t) send_buffer_fill); - stats_packets_tx++; + stats_octets_tx += ((uint64_t)send_buffer_fill); + stats_packets_tx++; - network_init_buffer (); + network_init_buffer(); } -static int network_write (const data_set_t *ds, const value_list_t *vl, - user_data_t __attribute__((unused)) *user_data) -{ - int status; +static int network_write(const data_set_t *ds, const value_list_t *vl, + user_data_t __attribute__((unused)) * user_data) { + int status; - /* listen_loop is set to non-zero in the shutdown callback, which is - * guaranteed to be called *after* all the write threads have been shut - * down. */ - assert (listen_loop == 0); + /* listen_loop is set to non-zero in the shutdown callback, which is + * guaranteed to be called *after* all the write threads have been shut + * down. */ + assert(listen_loop == 0); - if (!check_send_okay (vl)) - { + if (!check_send_okay(vl)) { #if COLLECT_DEBUG - char name[6*DATA_MAX_NAME_LEN]; - FORMAT_VL (name, sizeof (name), vl); - name[sizeof (name) - 1] = 0; - DEBUG ("network plugin: network_write: " - "NOT sending %s.", name); + char name[6 * DATA_MAX_NAME_LEN]; + FORMAT_VL(name, sizeof(name), vl); + name[sizeof(name) - 1] = 0; + DEBUG("network plugin: network_write: " + "NOT sending %s.", + name); #endif - /* Counter is not protected by another lock and may be reached by - * multiple threads */ - pthread_mutex_lock (&stats_lock); - stats_values_not_sent++; - pthread_mutex_unlock (&stats_lock); - return (0); - } - - uc_meta_data_add_unsigned_int (vl, - "network:time_sent", (uint64_t) vl->time); - - pthread_mutex_lock (&send_buffer_lock); - - status = add_to_buffer (send_buffer_ptr, - network_config_packet_size - (send_buffer_fill + BUFF_SIG_SIZE), - &send_buffer_vl, - ds, vl); - if (status >= 0) - { - /* status == bytes added to the buffer */ - send_buffer_fill += status; - send_buffer_ptr += status; - send_buffer_last_update = cdtime(); - - stats_values_sent++; - } - else - { - flush_buffer (); - - status = add_to_buffer (send_buffer_ptr, - network_config_packet_size - (send_buffer_fill + BUFF_SIG_SIZE), - &send_buffer_vl, - ds, vl); - - if (status >= 0) - { - send_buffer_fill += status; - send_buffer_ptr += status; - - stats_values_sent++; - } - } - - if (status < 0) - { - ERROR ("network plugin: Unable to append to the " - "buffer for some weird reason"); - } - else if ((network_config_packet_size - send_buffer_fill) < 15) - { - flush_buffer (); - } - - pthread_mutex_unlock (&send_buffer_lock); - - return ((status < 0) ? -1 : 0); + /* Counter is not protected by another lock and may be reached by + * multiple threads */ + pthread_mutex_lock(&stats_lock); + stats_values_not_sent++; + pthread_mutex_unlock(&stats_lock); + return (0); + } + + uc_meta_data_add_unsigned_int(vl, "network:time_sent", (uint64_t)vl->time); + + pthread_mutex_lock(&send_buffer_lock); + + status = + add_to_buffer(send_buffer_ptr, network_config_packet_size - + (send_buffer_fill + BUFF_SIG_SIZE), + &send_buffer_vl, ds, vl); + if (status >= 0) { + /* status == bytes added to the buffer */ + send_buffer_fill += status; + send_buffer_ptr += status; + send_buffer_last_update = cdtime(); + + stats_values_sent++; + } else { + flush_buffer(); + + status = + add_to_buffer(send_buffer_ptr, network_config_packet_size - + (send_buffer_fill + BUFF_SIG_SIZE), + &send_buffer_vl, ds, vl); + + if (status >= 0) { + send_buffer_fill += status; + send_buffer_ptr += status; + + stats_values_sent++; + } + } + + if (status < 0) { + ERROR("network plugin: Unable to append to the " + "buffer for some weird reason"); + } else if ((network_config_packet_size - send_buffer_fill) < 15) { + flush_buffer(); + } + + pthread_mutex_unlock(&send_buffer_lock); + + return ((status < 0) ? -1 : 0); } /* int network_write */ -static int network_config_set_ttl (const oconfig_item_t *ci) /* {{{ */ +static int network_config_set_ttl(const oconfig_item_t *ci) /* {{{ */ { int tmp = 0; - if (cf_util_get_int (ci, &tmp) != 0) + if (cf_util_get_int(ci, &tmp) != 0) return (-1); else if ((tmp > 0) && (tmp <= 255)) network_config_ttl = tmp; else { - WARNING ("network plugin: The `TimeToLive' must be between 1 and 255."); + WARNING("network plugin: The `TimeToLive' must be between 1 and 255."); return (-1); } return (0); } /* }}} int network_config_set_ttl */ -static int network_config_set_interface (const oconfig_item_t *ci, /* {{{ */ - int *interface) -{ +static int network_config_set_interface(const oconfig_item_t *ci, /* {{{ */ + int *interface) { char if_name[256]; - if (cf_util_get_string_buffer (ci, if_name, sizeof (if_name)) != 0) + if (cf_util_get_string_buffer(ci, if_name, sizeof(if_name)) != 0) return (-1); - *interface = if_nametoindex (if_name); + *interface = if_nametoindex(if_name); return (0); } /* }}} int network_config_set_interface */ -static int network_config_set_buffer_size (const oconfig_item_t *ci) /* {{{ */ +static int network_config_set_buffer_size(const oconfig_item_t *ci) /* {{{ */ { int tmp = 0; - if (cf_util_get_int (ci, &tmp) != 0) + if (cf_util_get_int(ci, &tmp) != 0) return (-1); else if ((tmp >= 1024) && (tmp <= 65535)) network_config_packet_size = tmp; else { - WARNING ("network plugin: The `MaxPacketSize' must be between 1024 and 65535."); + WARNING( + "network plugin: The `MaxPacketSize' must be between 1024 and 65535."); return (-1); } @@ -3004,28 +2732,24 @@ static int network_config_set_buffer_size (const oconfig_item_t *ci) /* {{{ */ } /* }}} int network_config_set_buffer_size */ #if HAVE_LIBGCRYPT -static int network_config_set_security_level (oconfig_item_t *ci, /* {{{ */ - int *retval) -{ +static int network_config_set_security_level(oconfig_item_t *ci, /* {{{ */ + int *retval) { char *str; - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("network plugin: The `SecurityLevel' config option needs exactly " - "one string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("network plugin: The `SecurityLevel' config option needs exactly " + "one string argument."); return (-1); } str = ci->values[0].value.string; - if (strcasecmp ("Encrypt", str) == 0) + if (strcasecmp("Encrypt", str) == 0) *retval = SECURITY_LEVEL_ENCRYPT; - else if (strcasecmp ("Sign", str) == 0) + else if (strcasecmp("Sign", str) == 0) *retval = SECURITY_LEVEL_SIGN; - else if (strcasecmp ("None", str) == 0) + else if (strcasecmp("None", str) == 0) *retval = SECURITY_LEVEL_NONE; - else - { - WARNING ("network plugin: Unknown security level: %s.", str); + else { + WARNING("network plugin: Unknown security level: %s.", str); return (-1); } @@ -3033,485 +2757,437 @@ static int network_config_set_security_level (oconfig_item_t *ci, /* {{{ */ } /* }}} int network_config_set_security_level */ #endif /* HAVE_LIBGCRYPT */ -static int network_config_add_listen (const oconfig_item_t *ci) /* {{{ */ +static int network_config_add_listen(const oconfig_item_t *ci) /* {{{ */ { sockent_t *se; int status; - if ((ci->values_num < 1) || (ci->values_num > 2) - || (ci->values[0].type != OCONFIG_TYPE_STRING) - || ((ci->values_num > 1) && (ci->values[1].type != OCONFIG_TYPE_STRING))) - { - ERROR ("network plugin: The `%s' config option needs " - "one or two string arguments.", ci->key); + if ((ci->values_num < 1) || (ci->values_num > 2) || + (ci->values[0].type != OCONFIG_TYPE_STRING) || + ((ci->values_num > 1) && (ci->values[1].type != OCONFIG_TYPE_STRING))) { + ERROR("network plugin: The `%s' config option needs " + "one or two string arguments.", + ci->key); return (-1); } - se = sockent_create (SOCKENT_TYPE_SERVER); - if (se == NULL) - { - ERROR ("network plugin: sockent_create failed."); + se = sockent_create(SOCKENT_TYPE_SERVER); + if (se == NULL) { + ERROR("network plugin: sockent_create failed."); return (-1); } - se->node = strdup (ci->values[0].value.string); + se->node = strdup(ci->values[0].value.string); if (ci->values_num >= 2) - se->service = strdup (ci->values[1].value.string); + se->service = strdup(ci->values[1].value.string); - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; #if HAVE_LIBGCRYPT - if (strcasecmp ("AuthFile", child->key) == 0) - cf_util_get_string (child, &se->data.server.auth_file); - else if (strcasecmp ("SecurityLevel", child->key) == 0) - network_config_set_security_level (child, - &se->data.server.security_level); + if (strcasecmp("AuthFile", child->key) == 0) + cf_util_get_string(child, &se->data.server.auth_file); + else if (strcasecmp("SecurityLevel", child->key) == 0) + network_config_set_security_level(child, &se->data.server.security_level); else #endif /* HAVE_LIBGCRYPT */ - if (strcasecmp ("Interface", child->key) == 0) - network_config_set_interface (child, &se->interface); - else - { - WARNING ("network plugin: Option `%s' is not allowed here.", - child->key); + if (strcasecmp("Interface", child->key) == 0) + network_config_set_interface(child, &se->interface); + else { + WARNING("network plugin: Option `%s' is not allowed here.", child->key); } } #if HAVE_LIBGCRYPT - if ((se->data.server.security_level > SECURITY_LEVEL_NONE) - && (se->data.server.auth_file == NULL)) - { - ERROR ("network plugin: A security level higher than `none' was " - "requested, but no AuthFile option was given. Cowardly refusing to " - "open this socket!"); - sockent_destroy (se); + if ((se->data.server.security_level > SECURITY_LEVEL_NONE) && + (se->data.server.auth_file == NULL)) { + ERROR("network plugin: A security level higher than `none' was " + "requested, but no AuthFile option was given. Cowardly refusing to " + "open this socket!"); + sockent_destroy(se); return (-1); } #endif /* HAVE_LIBGCRYPT */ - status = sockent_init_crypto (se); - if (status != 0) - { - ERROR ("network plugin: network_config_add_listen: sockent_init_crypto() failed."); - sockent_destroy (se); + status = sockent_init_crypto(se); + if (status != 0) { + ERROR("network plugin: network_config_add_listen: sockent_init_crypto() " + "failed."); + sockent_destroy(se); return (-1); } - status = sockent_server_listen (se); - if (status != 0) - { - ERROR ("network plugin: network_config_add_listen: sockent_server_listen failed."); - sockent_destroy (se); + status = sockent_server_listen(se); + if (status != 0) { + ERROR("network plugin: network_config_add_listen: sockent_server_listen " + "failed."); + sockent_destroy(se); return (-1); } - status = sockent_add (se); - if (status != 0) - { - ERROR ("network plugin: network_config_add_listen: sockent_add failed."); - sockent_destroy (se); + status = sockent_add(se); + if (status != 0) { + ERROR("network plugin: network_config_add_listen: sockent_add failed."); + sockent_destroy(se); return (-1); } return (0); } /* }}} int network_config_add_listen */ -static int network_config_add_server (const oconfig_item_t *ci) /* {{{ */ +static int network_config_add_server(const oconfig_item_t *ci) /* {{{ */ { sockent_t *se; int status; - if ((ci->values_num < 1) || (ci->values_num > 2) - || (ci->values[0].type != OCONFIG_TYPE_STRING) - || ((ci->values_num > 1) && (ci->values[1].type != OCONFIG_TYPE_STRING))) - { - ERROR ("network plugin: The `%s' config option needs " - "one or two string arguments.", ci->key); + if ((ci->values_num < 1) || (ci->values_num > 2) || + (ci->values[0].type != OCONFIG_TYPE_STRING) || + ((ci->values_num > 1) && (ci->values[1].type != OCONFIG_TYPE_STRING))) { + ERROR("network plugin: The `%s' config option needs " + "one or two string arguments.", + ci->key); return (-1); } - se = sockent_create (SOCKENT_TYPE_CLIENT); - if (se == NULL) - { - ERROR ("network plugin: sockent_create failed."); + se = sockent_create(SOCKENT_TYPE_CLIENT); + if (se == NULL) { + ERROR("network plugin: sockent_create failed."); return (-1); } - se->node = strdup (ci->values[0].value.string); + se->node = strdup(ci->values[0].value.string); if (ci->values_num >= 2) - se->service = strdup (ci->values[1].value.string); + se->service = strdup(ci->values[1].value.string); - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; #if HAVE_LIBGCRYPT - if (strcasecmp ("Username", child->key) == 0) - cf_util_get_string (child, &se->data.client.username); - else if (strcasecmp ("Password", child->key) == 0) - cf_util_get_string (child, &se->data.client.password); - else if (strcasecmp ("SecurityLevel", child->key) == 0) - network_config_set_security_level (child, - &se->data.client.security_level); + if (strcasecmp("Username", child->key) == 0) + cf_util_get_string(child, &se->data.client.username); + else if (strcasecmp("Password", child->key) == 0) + cf_util_get_string(child, &se->data.client.password); + else if (strcasecmp("SecurityLevel", child->key) == 0) + network_config_set_security_level(child, &se->data.client.security_level); else #endif /* HAVE_LIBGCRYPT */ - if (strcasecmp ("Interface", child->key) == 0) - network_config_set_interface (child, &se->interface); - else if (strcasecmp ("ResolveInterval", child->key) == 0) + if (strcasecmp("Interface", child->key) == 0) + network_config_set_interface(child, &se->interface); + else if (strcasecmp("ResolveInterval", child->key) == 0) cf_util_get_cdtime(child, &se->data.client.resolve_interval); - else - { - WARNING ("network plugin: Option `%s' is not allowed here.", - child->key); + else { + WARNING("network plugin: Option `%s' is not allowed here.", child->key); } } #if HAVE_LIBGCRYPT - if ((se->data.client.security_level > SECURITY_LEVEL_NONE) - && ((se->data.client.username == NULL) - || (se->data.client.password == NULL))) - { - ERROR ("network plugin: A security level higher than `none' was " - "requested, but no Username or Password option was given. " - "Cowardly refusing to open this socket!"); - sockent_destroy (se); + if ((se->data.client.security_level > SECURITY_LEVEL_NONE) && + ((se->data.client.username == NULL) || + (se->data.client.password == NULL))) { + ERROR("network plugin: A security level higher than `none' was " + "requested, but no Username or Password option was given. " + "Cowardly refusing to open this socket!"); + sockent_destroy(se); return (-1); } #endif /* HAVE_LIBGCRYPT */ - status = sockent_init_crypto (se); - if (status != 0) - { - ERROR ("network plugin: network_config_add_server: sockent_init_crypto() failed."); - sockent_destroy (se); + status = sockent_init_crypto(se); + if (status != 0) { + ERROR("network plugin: network_config_add_server: sockent_init_crypto() " + "failed."); + sockent_destroy(se); return (-1); } /* No call to sockent_client_connect() here -- it is called from * network_send_buffer_plain(). */ - status = sockent_add (se); - if (status != 0) - { - ERROR ("network plugin: network_config_add_server: sockent_add failed."); - sockent_destroy (se); + status = sockent_add(se); + if (status != 0) { + ERROR("network plugin: network_config_add_server: sockent_add failed."); + sockent_destroy(se); return (-1); } return (0); } /* }}} int network_config_add_server */ -static int network_config (oconfig_item_t *ci) /* {{{ */ +static int network_config(oconfig_item_t *ci) /* {{{ */ { /* The options need to be applied first */ - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("TimeToLive", child->key) == 0) - network_config_set_ttl (child); + if (strcasecmp("TimeToLive", child->key) == 0) + network_config_set_ttl(child); } - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Listen", child->key) == 0) - network_config_add_listen (child); - else if (strcasecmp ("Server", child->key) == 0) - network_config_add_server (child); - else if (strcasecmp ("TimeToLive", child->key) == 0) { + if (strcasecmp("Listen", child->key) == 0) + network_config_add_listen(child); + else if (strcasecmp("Server", child->key) == 0) + network_config_add_server(child); + else if (strcasecmp("TimeToLive", child->key) == 0) { /* Handled earlier */ - } - else if (strcasecmp ("MaxPacketSize", child->key) == 0) - network_config_set_buffer_size (child); - else if (strcasecmp ("Forward", child->key) == 0) - cf_util_get_boolean (child, &network_config_forward); - else if (strcasecmp ("ReportStats", child->key) == 0) - cf_util_get_boolean (child, &network_config_stats); - else - { - WARNING ("network plugin: Option `%s' is not allowed here.", - child->key); + } else if (strcasecmp("MaxPacketSize", child->key) == 0) + network_config_set_buffer_size(child); + else if (strcasecmp("Forward", child->key) == 0) + cf_util_get_boolean(child, &network_config_forward); + else if (strcasecmp("ReportStats", child->key) == 0) + cf_util_get_boolean(child, &network_config_stats); + else { + WARNING("network plugin: Option `%s' is not allowed here.", child->key); } } return (0); } /* }}} int network_config */ -static int network_notification (const notification_t *n, - user_data_t __attribute__((unused)) *user_data) -{ - char buffer[network_config_packet_size]; - char *buffer_ptr = buffer; - size_t buffer_free = sizeof (buffer); - int status; +static int network_notification(const notification_t *n, + user_data_t __attribute__((unused)) * + user_data) { + char buffer[network_config_packet_size]; + char *buffer_ptr = buffer; + size_t buffer_free = sizeof(buffer); + int status; - if (!check_send_notify_okay (n)) + if (!check_send_notify_okay(n)) return (0); - memset (buffer, 0, sizeof (buffer)); + memset(buffer, 0, sizeof(buffer)); - status = write_part_number (&buffer_ptr, &buffer_free, TYPE_TIME_HR, - (uint64_t) n->time); + status = write_part_number(&buffer_ptr, &buffer_free, TYPE_TIME_HR, + (uint64_t)n->time); if (status != 0) return (-1); - status = write_part_number (&buffer_ptr, &buffer_free, TYPE_SEVERITY, - (uint64_t) n->severity); + status = write_part_number(&buffer_ptr, &buffer_free, TYPE_SEVERITY, + (uint64_t)n->severity); if (status != 0) return (-1); - if (strlen (n->host) > 0) - { - status = write_part_string (&buffer_ptr, &buffer_free, TYPE_HOST, - n->host, strlen (n->host)); + if (strlen(n->host) > 0) { + status = write_part_string(&buffer_ptr, &buffer_free, TYPE_HOST, n->host, + strlen(n->host)); if (status != 0) return (-1); } - if (strlen (n->plugin) > 0) - { - status = write_part_string (&buffer_ptr, &buffer_free, TYPE_PLUGIN, - n->plugin, strlen (n->plugin)); + if (strlen(n->plugin) > 0) { + status = write_part_string(&buffer_ptr, &buffer_free, TYPE_PLUGIN, + n->plugin, strlen(n->plugin)); if (status != 0) return (-1); } - if (strlen (n->plugin_instance) > 0) - { - status = write_part_string (&buffer_ptr, &buffer_free, - TYPE_PLUGIN_INSTANCE, - n->plugin_instance, strlen (n->plugin_instance)); + if (strlen(n->plugin_instance) > 0) { + status = write_part_string(&buffer_ptr, &buffer_free, TYPE_PLUGIN_INSTANCE, + n->plugin_instance, strlen(n->plugin_instance)); if (status != 0) return (-1); } - if (strlen (n->type) > 0) - { - status = write_part_string (&buffer_ptr, &buffer_free, TYPE_TYPE, - n->type, strlen (n->type)); + if (strlen(n->type) > 0) { + status = write_part_string(&buffer_ptr, &buffer_free, TYPE_TYPE, n->type, + strlen(n->type)); if (status != 0) return (-1); } - if (strlen (n->type_instance) > 0) - { - status = write_part_string (&buffer_ptr, &buffer_free, TYPE_TYPE_INSTANCE, - n->type_instance, strlen (n->type_instance)); + if (strlen(n->type_instance) > 0) { + status = write_part_string(&buffer_ptr, &buffer_free, TYPE_TYPE_INSTANCE, + n->type_instance, strlen(n->type_instance)); if (status != 0) return (-1); } - status = write_part_string (&buffer_ptr, &buffer_free, TYPE_MESSAGE, - n->message, strlen (n->message)); + status = write_part_string(&buffer_ptr, &buffer_free, TYPE_MESSAGE, + n->message, strlen(n->message)); if (status != 0) return (-1); - network_send_buffer (buffer, sizeof (buffer) - buffer_free); + network_send_buffer(buffer, sizeof(buffer) - buffer_free); return (0); } /* int network_notification */ -static int network_shutdown (void) -{ - listen_loop++; - - /* Kill the listening thread */ - if (receive_thread_running != 0) - { - INFO ("network plugin: Stopping receive thread."); - pthread_kill (receive_thread_id, SIGTERM); - pthread_join (receive_thread_id, NULL /* no return value */); - memset (&receive_thread_id, 0, sizeof (receive_thread_id)); - receive_thread_running = 0; - } - - /* Shutdown the dispatching thread */ - if (dispatch_thread_running != 0) - { - INFO ("network plugin: Stopping dispatch thread."); - pthread_mutex_lock (&receive_list_lock); - pthread_cond_broadcast (&receive_list_cond); - pthread_mutex_unlock (&receive_list_lock); - pthread_join (dispatch_thread_id, /* ret = */ NULL); - dispatch_thread_running = 0; - } - - sockent_destroy (listen_sockets); - - if (send_buffer_fill > 0) - flush_buffer (); - - sfree (send_buffer); - - for (sockent_t *se = sending_sockets; se != NULL; se = se->next) - sockent_client_disconnect (se); - sockent_destroy (sending_sockets); - - plugin_unregister_config ("network"); - plugin_unregister_init ("network"); - plugin_unregister_write ("network"); - plugin_unregister_shutdown ("network"); - - return (0); +static int network_shutdown(void) { + listen_loop++; + + /* Kill the listening thread */ + if (receive_thread_running != 0) { + INFO("network plugin: Stopping receive thread."); + pthread_kill(receive_thread_id, SIGTERM); + pthread_join(receive_thread_id, NULL /* no return value */); + memset(&receive_thread_id, 0, sizeof(receive_thread_id)); + receive_thread_running = 0; + } + + /* Shutdown the dispatching thread */ + if (dispatch_thread_running != 0) { + INFO("network plugin: Stopping dispatch thread."); + pthread_mutex_lock(&receive_list_lock); + pthread_cond_broadcast(&receive_list_cond); + pthread_mutex_unlock(&receive_list_lock); + pthread_join(dispatch_thread_id, /* ret = */ NULL); + dispatch_thread_running = 0; + } + + sockent_destroy(listen_sockets); + + if (send_buffer_fill > 0) + flush_buffer(); + + sfree(send_buffer); + + for (sockent_t *se = sending_sockets; se != NULL; se = se->next) + sockent_client_disconnect(se); + sockent_destroy(sending_sockets); + + plugin_unregister_config("network"); + plugin_unregister_init("network"); + plugin_unregister_write("network"); + plugin_unregister_shutdown("network"); + + return (0); } /* int network_shutdown */ -static int network_stats_read (void) /* {{{ */ -{ - derive_t copy_octets_rx; - derive_t copy_octets_tx; - derive_t copy_packets_rx; - derive_t copy_packets_tx; - derive_t copy_values_dispatched; - derive_t copy_values_not_dispatched; - derive_t copy_values_sent; - derive_t copy_values_not_sent; - derive_t copy_receive_list_length; - value_list_t vl = VALUE_LIST_INIT; - value_t values[2]; - - copy_octets_rx = stats_octets_rx; - copy_octets_tx = stats_octets_tx; - copy_packets_rx = stats_packets_rx; - copy_packets_tx = stats_packets_tx; - copy_values_dispatched = stats_values_dispatched; - copy_values_not_dispatched = stats_values_not_dispatched; - copy_values_sent = stats_values_sent; - copy_values_not_sent = stats_values_not_sent; - copy_receive_list_length = receive_list_length; - - /* Initialize `vl' */ - vl.values = values; - vl.values_len = 2; - vl.time = 0; - sstrncpy (vl.plugin, "network", sizeof (vl.plugin)); - - /* Octets received / sent */ - vl.values[0].derive = (derive_t) copy_octets_rx; - vl.values[1].derive = (derive_t) copy_octets_tx; - sstrncpy (vl.type, "if_octets", sizeof (vl.type)); - plugin_dispatch_values (&vl); - - /* Packets received / send */ - vl.values[0].derive = (derive_t) copy_packets_rx; - vl.values[1].derive = (derive_t) copy_packets_tx; - sstrncpy (vl.type, "if_packets", sizeof (vl.type)); - plugin_dispatch_values (&vl); - - /* Values (not) dispatched and (not) send */ - sstrncpy (vl.type, "total_values", sizeof (vl.type)); - vl.values_len = 1; - - vl.values[0].derive = (derive_t) copy_values_dispatched; - sstrncpy (vl.type_instance, "dispatch-accepted", - sizeof (vl.type_instance)); - plugin_dispatch_values (&vl); - - vl.values[0].derive = (derive_t) copy_values_not_dispatched; - sstrncpy (vl.type_instance, "dispatch-rejected", - sizeof (vl.type_instance)); - plugin_dispatch_values (&vl); - - vl.values[0].derive = (derive_t) copy_values_sent; - sstrncpy (vl.type_instance, "send-accepted", - sizeof (vl.type_instance)); - plugin_dispatch_values (&vl); - - vl.values[0].derive = (derive_t) copy_values_not_sent; - sstrncpy (vl.type_instance, "send-rejected", - sizeof (vl.type_instance)); - plugin_dispatch_values (&vl); - - /* Receive queue length */ - vl.values[0].gauge = (gauge_t) copy_receive_list_length; - sstrncpy (vl.type, "queue_length", sizeof (vl.type)); - vl.type_instance[0] = 0; - plugin_dispatch_values (&vl); - - return (0); +static int network_stats_read(void) /* {{{ */ +{ + derive_t copy_octets_rx; + derive_t copy_octets_tx; + derive_t copy_packets_rx; + derive_t copy_packets_tx; + derive_t copy_values_dispatched; + derive_t copy_values_not_dispatched; + derive_t copy_values_sent; + derive_t copy_values_not_sent; + derive_t copy_receive_list_length; + value_list_t vl = VALUE_LIST_INIT; + value_t values[2]; + + copy_octets_rx = stats_octets_rx; + copy_octets_tx = stats_octets_tx; + copy_packets_rx = stats_packets_rx; + copy_packets_tx = stats_packets_tx; + copy_values_dispatched = stats_values_dispatched; + copy_values_not_dispatched = stats_values_not_dispatched; + copy_values_sent = stats_values_sent; + copy_values_not_sent = stats_values_not_sent; + copy_receive_list_length = receive_list_length; + + /* Initialize `vl' */ + vl.values = values; + vl.values_len = 2; + vl.time = 0; + sstrncpy(vl.plugin, "network", sizeof(vl.plugin)); + + /* Octets received / sent */ + vl.values[0].derive = (derive_t)copy_octets_rx; + vl.values[1].derive = (derive_t)copy_octets_tx; + sstrncpy(vl.type, "if_octets", sizeof(vl.type)); + plugin_dispatch_values(&vl); + + /* Packets received / send */ + vl.values[0].derive = (derive_t)copy_packets_rx; + vl.values[1].derive = (derive_t)copy_packets_tx; + sstrncpy(vl.type, "if_packets", sizeof(vl.type)); + plugin_dispatch_values(&vl); + + /* Values (not) dispatched and (not) send */ + sstrncpy(vl.type, "total_values", sizeof(vl.type)); + vl.values_len = 1; + + vl.values[0].derive = (derive_t)copy_values_dispatched; + sstrncpy(vl.type_instance, "dispatch-accepted", sizeof(vl.type_instance)); + plugin_dispatch_values(&vl); + + vl.values[0].derive = (derive_t)copy_values_not_dispatched; + sstrncpy(vl.type_instance, "dispatch-rejected", sizeof(vl.type_instance)); + plugin_dispatch_values(&vl); + + vl.values[0].derive = (derive_t)copy_values_sent; + sstrncpy(vl.type_instance, "send-accepted", sizeof(vl.type_instance)); + plugin_dispatch_values(&vl); + + vl.values[0].derive = (derive_t)copy_values_not_sent; + sstrncpy(vl.type_instance, "send-rejected", sizeof(vl.type_instance)); + plugin_dispatch_values(&vl); + + /* Receive queue length */ + vl.values[0].gauge = (gauge_t)copy_receive_list_length; + sstrncpy(vl.type, "queue_length", sizeof(vl.type)); + vl.type_instance[0] = 0; + plugin_dispatch_values(&vl); + + return (0); } /* }}} int network_stats_read */ -static int network_init (void) -{ - static _Bool have_init = 0; - - /* Check if we were already initialized. If so, just return - there's - * nothing more to do (for now, that is). */ - if (have_init) - return (0); - have_init = 1; - - if (network_config_stats) - plugin_register_read ("network", network_stats_read); - - plugin_register_shutdown ("network", network_shutdown); - - send_buffer = malloc (network_config_packet_size); - if (send_buffer == NULL) - { - ERROR ("network plugin: malloc failed."); - return (-1); - } - network_init_buffer (); - - /* setup socket(s) and so on */ - if (sending_sockets != NULL) - { - plugin_register_write ("network", network_write, - /* user_data = */ NULL); - plugin_register_notification ("network", network_notification, - /* user_data = */ NULL); - } - - /* If no threads need to be started, return here. */ - if ((listen_sockets_num == 0) - || ((dispatch_thread_running != 0) - && (receive_thread_running != 0))) - return (0); - - if (dispatch_thread_running == 0) - { - int status; - status = plugin_thread_create (&dispatch_thread_id, - NULL /* no attributes */, - dispatch_thread, - NULL /* no argument */, "network disp"); - if (status != 0) - { - char errbuf[1024]; - ERROR ("network: pthread_create failed: %s", - sstrerror (errno, errbuf, - sizeof (errbuf))); - } - else - { - dispatch_thread_running = 1; - } - } - - if (receive_thread_running == 0) - { - int status; - status = plugin_thread_create (&receive_thread_id, - NULL /* no attributes */, - receive_thread, - NULL /* no argument */, "network recv"); - if (status != 0) - { - char errbuf[1024]; - ERROR ("network: pthread_create failed: %s", - sstrerror (errno, errbuf, - sizeof (errbuf))); - } - else - { - receive_thread_running = 1; - } - } - - return (0); +static int network_init(void) { + static _Bool have_init = 0; + + /* Check if we were already initialized. If so, just return - there's + * nothing more to do (for now, that is). */ + if (have_init) + return (0); + have_init = 1; + + if (network_config_stats) + plugin_register_read("network", network_stats_read); + + plugin_register_shutdown("network", network_shutdown); + + send_buffer = malloc(network_config_packet_size); + if (send_buffer == NULL) { + ERROR("network plugin: malloc failed."); + return (-1); + } + network_init_buffer(); + + /* setup socket(s) and so on */ + if (sending_sockets != NULL) { + plugin_register_write("network", network_write, + /* user_data = */ NULL); + plugin_register_notification("network", network_notification, + /* user_data = */ NULL); + } + + /* If no threads need to be started, return here. */ + if ((listen_sockets_num == 0) || + ((dispatch_thread_running != 0) && (receive_thread_running != 0))) + return (0); + + if (dispatch_thread_running == 0) { + int status; + status = plugin_thread_create(&dispatch_thread_id, NULL /* no attributes */, + dispatch_thread, NULL /* no argument */, + "network disp"); + if (status != 0) { + char errbuf[1024]; + ERROR("network: pthread_create failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + } else { + dispatch_thread_running = 1; + } + } + + if (receive_thread_running == 0) { + int status; + status = plugin_thread_create(&receive_thread_id, NULL /* no attributes */, + receive_thread, NULL /* no argument */, + "network recv"); + if (status != 0) { + char errbuf[1024]; + ERROR("network: pthread_create failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + } else { + receive_thread_running = 1; + } + } + + return (0); } /* int network_init */ /* @@ -3521,36 +3197,31 @@ 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 (cdtime_t timeout, - __attribute__((unused)) const char *identifier, - __attribute__((unused)) user_data_t *user_data) -{ - pthread_mutex_lock (&send_buffer_lock); - - if (send_buffer_fill > 0) - { - if (timeout > 0) - { - cdtime_t now = cdtime (); - if ((send_buffer_last_update + timeout) > now) - { - pthread_mutex_unlock (&send_buffer_lock); - return (0); - } - } - flush_buffer (); - } - pthread_mutex_unlock (&send_buffer_lock); - - return (0); +static int network_flush(cdtime_t timeout, + __attribute__((unused)) const char *identifier, + __attribute__((unused)) user_data_t *user_data) { + pthread_mutex_lock(&send_buffer_lock); + + if (send_buffer_fill > 0) { + if (timeout > 0) { + cdtime_t now = cdtime(); + if ((send_buffer_last_update + timeout) > now) { + pthread_mutex_unlock(&send_buffer_lock); + return (0); + } + } + flush_buffer(); + } + pthread_mutex_unlock(&send_buffer_lock); + + return (0); } /* int network_flush */ -void module_register (void) -{ - plugin_register_complex_config ("network", network_config); - plugin_register_init ("network", network_init); - plugin_register_flush ("network", network_flush, - /* user_data = */ NULL); +void module_register(void) { + plugin_register_complex_config("network", network_config); + plugin_register_init("network", network_init); + plugin_register_flush("network", network_flush, + /* user_data = */ NULL); } /* void module_register */ /* vim: set fdm=marker : */ diff --git a/src/network.h b/src/network.h index 54577220..14a34a92 100644 --- a/src/network.h +++ b/src/network.h @@ -57,24 +57,24 @@ #define NET_DEFAULT_V4_ADDR "239.192.74.66" #define NET_DEFAULT_V6_ADDR "ff18::efc0:4a42" -#define NET_DEFAULT_PORT "25826" +#define NET_DEFAULT_PORT "25826" -#define TYPE_HOST 0x0000 -#define TYPE_TIME 0x0001 -#define TYPE_TIME_HR 0x0008 -#define TYPE_PLUGIN 0x0002 +#define TYPE_HOST 0x0000 +#define TYPE_TIME 0x0001 +#define TYPE_TIME_HR 0x0008 +#define TYPE_PLUGIN 0x0002 #define TYPE_PLUGIN_INSTANCE 0x0003 -#define TYPE_TYPE 0x0004 -#define TYPE_TYPE_INSTANCE 0x0005 -#define TYPE_VALUES 0x0006 -#define TYPE_INTERVAL 0x0007 -#define TYPE_INTERVAL_HR 0x0009 +#define TYPE_TYPE 0x0004 +#define TYPE_TYPE_INSTANCE 0x0005 +#define TYPE_VALUES 0x0006 +#define TYPE_INTERVAL 0x0007 +#define TYPE_INTERVAL_HR 0x0009 /* Types to transmit notifications */ -#define TYPE_MESSAGE 0x0100 -#define TYPE_SEVERITY 0x0101 +#define TYPE_MESSAGE 0x0100 +#define TYPE_SEVERITY 0x0101 -#define TYPE_SIGN_SHA256 0x0200 -#define TYPE_ENCR_AES256 0x0210 +#define TYPE_SIGN_SHA256 0x0200 +#define TYPE_ENCR_AES256 0x0210 #endif /* NETWORK_H */ diff --git a/src/nfs.c b/src/nfs.c index d080cd6e..74c6cbc3 100644 --- a/src/nfs.c +++ b/src/nfs.c @@ -76,251 +76,210 @@ Number Procedures Procedures 21 commit */ -static const char *nfs2_procedures_names[] = -{ - "null", - "getattr", - "setattr", - "root", - "lookup", - "readlink", - "read", - "wrcache", - "write", - "create", - "remove", - "rename", - "link", - "symlink", - "mkdir", - "rmdir", - "readdir", - "fsstat" -}; -static size_t nfs2_procedures_names_num = STATIC_ARRAY_SIZE (nfs2_procedures_names); - -static const char *nfs3_procedures_names[] = -{ - "null", - "getattr", - "setattr", - "lookup", - "access", - "readlink", - "read", - "write", - "create", - "mkdir", - "symlink", - "mknod", - "remove", - "rmdir", - "rename", - "link", - "readdir", - "readdirplus", - "fsstat", - "fsinfo", - "pathconf", - "commit" -}; -static size_t nfs3_procedures_names_num = STATIC_ARRAY_SIZE (nfs3_procedures_names); +static const char *nfs2_procedures_names[] = { + "null", "getattr", "setattr", "root", "lookup", "readlink", + "read", "wrcache", "write", "create", "remove", "rename", + "link", "symlink", "mkdir", "rmdir", "readdir", "fsstat"}; +static size_t nfs2_procedures_names_num = + STATIC_ARRAY_SIZE(nfs2_procedures_names); + +static const char *nfs3_procedures_names[] = { + "null", "getattr", "setattr", "lookup", "access", "readlink", + "read", "write", "create", "mkdir", "symlink", "mknod", + "remove", "rmdir", "rename", "link", "readdir", "readdirplus", + "fsstat", "fsinfo", "pathconf", "commit"}; +static size_t nfs3_procedures_names_num = + STATIC_ARRAY_SIZE(nfs3_procedures_names); #if HAVE_LIBKSTAT -static const char *nfs4_procedures_names[] = -{ - "null", - "compound", - "reserved", - "access", - "close", - "commit", - "create", - "delegpurge", - "delegreturn", - "getattr", - "getfh", - "link", - "lock", - "lockt", - "locku", - "lookup", - "lookupp", - "nverify", - "open", - "openattr", - "open_confirm", - "open_downgrade", - "putfh", - "putpubfh", - "putrootfh", - "read", - "readdir", - "readlink", - "remove", - "rename", - "renew", - "restorefh", - "savefh", - "secinfo", - "setattr", - "setclientid", - "setclientid_confirm", - "verify", - "write" -}; -static size_t nfs4_procedures_names_num = STATIC_ARRAY_SIZE (nfs4_procedures_names); +static const char *nfs4_procedures_names[] = {"null", + "compound", + "reserved", + "access", + "close", + "commit", + "create", + "delegpurge", + "delegreturn", + "getattr", + "getfh", + "link", + "lock", + "lockt", + "locku", + "lookup", + "lookupp", + "nverify", + "open", + "openattr", + "open_confirm", + "open_downgrade", + "putfh", + "putpubfh", + "putrootfh", + "read", + "readdir", + "readlink", + "remove", + "rename", + "renew", + "restorefh", + "savefh", + "secinfo", + "setattr", + "setclientid", + "setclientid_confirm", + "verify", + "write"}; +static size_t nfs4_procedures_names_num = + STATIC_ARRAY_SIZE(nfs4_procedures_names); #endif #if KERNEL_LINUX -static const char *nfs4_server40_procedures_names[] = -{ - "null", - "compound", - "reserved", - "access", - "close", - "commit", - "create", - "delegpurge", - "delegreturn", - "getattr", - "getfh", - "link", - "lock", - "lockt", - "locku", - "lookup", - "lookupp", - "nverify", - "open", - "openattr", - "open_confirm", - "open_downgrade", - "putfh", - "putpubfh", - "putrootfh", - "read", - "readdir", - "readlink", - "remove", - "rename", - "renew", - "restorefh", - "savefh", - "secinfo", - "setattr", - "setclientid", - "setcltid_confirm", - "verify", - "write", - "release_lockowner" -}; - -static size_t nfs4_server40_procedures_names_num = STATIC_ARRAY_SIZE (nfs4_server40_procedures_names); - -static const char *nfs4_server41_procedures_names[] = -{ - "backchannel_ctl", - "bind_conn_to_session", - "exchange_id", - "create_session", - "destroy_session", - "free_stateid", - "get_dir_delegation", - "getdeviceinfo", - "getdevicelist", - "layoutcommit", - "layoutget", - "layoutreturn", - "secinfo_no_name", - "sequence", - "set_ssv", - "test_stateid", - "want_delegation", - "destroy_clientid", - "reclaim_complete", +static const char *nfs4_server40_procedures_names[] = {"null", + "compound", + "reserved", + "access", + "close", + "commit", + "create", + "delegpurge", + "delegreturn", + "getattr", + "getfh", + "link", + "lock", + "lockt", + "locku", + "lookup", + "lookupp", + "nverify", + "open", + "openattr", + "open_confirm", + "open_downgrade", + "putfh", + "putpubfh", + "putrootfh", + "read", + "readdir", + "readlink", + "remove", + "rename", + "renew", + "restorefh", + "savefh", + "secinfo", + "setattr", + "setclientid", + "setcltid_confirm", + "verify", + "write", + "release_lockowner"}; + +static size_t nfs4_server40_procedures_names_num = + STATIC_ARRAY_SIZE(nfs4_server40_procedures_names); + +static const char *nfs4_server41_procedures_names[] = { + "backchannel_ctl", + "bind_conn_to_session", + "exchange_id", + "create_session", + "destroy_session", + "free_stateid", + "get_dir_delegation", + "getdeviceinfo", + "getdevicelist", + "layoutcommit", + "layoutget", + "layoutreturn", + "secinfo_no_name", + "sequence", + "set_ssv", + "test_stateid", + "want_delegation", + "destroy_clientid", + "reclaim_complete", }; -static size_t nfs4_server41_procedures_names_num = STATIC_ARRAY_SIZE (nfs4_server41_procedures_names); +static size_t nfs4_server41_procedures_names_num = + STATIC_ARRAY_SIZE(nfs4_server41_procedures_names); -#define NFS4_SERVER40_NUM_PROC ( \ - STATIC_ARRAY_SIZE (nfs4_server40_procedures_names) ) +#define NFS4_SERVER40_NUM_PROC \ + (STATIC_ARRAY_SIZE(nfs4_server40_procedures_names)) -#define NFS4_SERVER41_NUM_PROC ( \ - STATIC_ARRAY_SIZE (nfs4_server40_procedures_names) + \ - STATIC_ARRAY_SIZE (nfs4_server41_procedures_names) ) +#define NFS4_SERVER41_NUM_PROC \ + (STATIC_ARRAY_SIZE(nfs4_server40_procedures_names) + \ + STATIC_ARRAY_SIZE(nfs4_server41_procedures_names)) #define NFS4_SERVER_MAX_PROC (NFS4_SERVER41_NUM_PROC) -static const char *nfs4_client40_procedures_names[] = -{ - "null", - "read", - "write", - "commit", - "open", - "open_confirm", - "open_noattr", - "open_downgrade", - "close", - "setattr", - "fsinfo", - "renew", - "setclientid", - "setclientid_confirm", - "lock", - "lockt", - "locku", - "access", - "getattr", - "lookup", - "lookupp", - "remove", - "rename", - "link", - "symlink", - "create", - "pathconf", - "statfs", - "readlink", - "readdir", - "server_caps", - "delegreturn", - "getacl", - "setacl", - "fs_locations", /* |35| 2.6.18 */ - "release_lockowner", /* |42| 2.6.36 */ - "secinfo", /* |46| 2.6.39 */ - "fsid_present" /* |54| 3.13 */ +static const char *nfs4_client40_procedures_names[] = { + "null", + "read", + "write", + "commit", + "open", + "open_confirm", + "open_noattr", + "open_downgrade", + "close", + "setattr", + "fsinfo", + "renew", + "setclientid", + "setclientid_confirm", + "lock", + "lockt", + "locku", + "access", + "getattr", + "lookup", + "lookupp", + "remove", + "rename", + "link", + "symlink", + "create", + "pathconf", + "statfs", + "readlink", + "readdir", + "server_caps", + "delegreturn", + "getacl", + "setacl", + "fs_locations", /* |35| 2.6.18 */ + "release_lockowner", /* |42| 2.6.36 */ + "secinfo", /* |46| 2.6.39 */ + "fsid_present" /* |54| 3.13 */ }; -static const char *nfs4_client41_procedures_names[] = -{ - "exchange_id", /* |40| 2.6.30 */ - "create_session", /* |40| 2.6.30 */ - "destroy_session", /* |40| 2.6.30 */ - "sequence", /* |40| 2.6.30 */ - "get_lease_time", /* |40| 2.6.30 */ - "reclaim_complete", /* |41| 2.6.33 */ - "layoutget", /* |44| 2.6.37 */ - "getdeviceinfo", /* |44| 2.6.37 */ - "layoutcommit", /* |46| 2.6.39 */ - "layoutreturn", /* |47| 3.0 */ - "secinfo_no_name", /* |51| 3.1 */ - "test_stateid", /* |51| 3.1 */ - "free_stateid", /* |51| 3.1 */ - "getdevicelist", /* |51| 3.1 */ - "bind_conn_to_session", /* |53| 3.5 */ - "destroy_clientid" /* |53| 3.5 */ +static const char *nfs4_client41_procedures_names[] = { + "exchange_id", /* |40| 2.6.30 */ + "create_session", /* |40| 2.6.30 */ + "destroy_session", /* |40| 2.6.30 */ + "sequence", /* |40| 2.6.30 */ + "get_lease_time", /* |40| 2.6.30 */ + "reclaim_complete", /* |41| 2.6.33 */ + "layoutget", /* |44| 2.6.37 */ + "getdeviceinfo", /* |44| 2.6.37 */ + "layoutcommit", /* |46| 2.6.39 */ + "layoutreturn", /* |47| 3.0 */ + "secinfo_no_name", /* |51| 3.1 */ + "test_stateid", /* |51| 3.1 */ + "free_stateid", /* |51| 3.1 */ + "getdevicelist", /* |51| 3.1 */ + "bind_conn_to_session", /* |53| 3.5 */ + "destroy_clientid" /* |53| 3.5 */ }; -#define NFS4_CLIENT40_NUM_PROC ( \ - STATIC_ARRAY_SIZE (nfs4_client40_procedures_names) ) +#define NFS4_CLIENT40_NUM_PROC \ + (STATIC_ARRAY_SIZE(nfs4_client40_procedures_names)) -#define NFS4_CLIENT41_NUM_PROC ( \ - STATIC_ARRAY_SIZE (nfs4_client40_procedures_names) + \ - STATIC_ARRAY_SIZE (nfs4_client41_procedures_names) ) +#define NFS4_CLIENT41_NUM_PROC \ + (STATIC_ARRAY_SIZE(nfs4_client40_procedures_names) + \ + STATIC_ARRAY_SIZE(nfs4_client41_procedures_names)) #define NFS4_CLIENT_MAX_PROC (NFS4_CLIENT41_NUM_PROC) @@ -337,340 +296,289 @@ static kstat_t *nfs4_ksp_server; #endif #if KERNEL_LINUX -static int nfs_init (void) -{ - return (0); -} +static int nfs_init(void) { return (0); } /* #endif KERNEL_LINUX */ #elif HAVE_LIBKSTAT -static int nfs_init (void) -{ - nfs2_ksp_client = NULL; - nfs2_ksp_server = NULL; - nfs3_ksp_client = NULL; - nfs3_ksp_server = NULL; - nfs4_ksp_client = NULL; - nfs4_ksp_server = NULL; - - if (kc == NULL) - return (-1); - - for (kstat_t *ksp_chain = kc->kc_chain; ksp_chain != NULL; - ksp_chain = ksp_chain->ks_next) - { - if (strncmp (ksp_chain->ks_module, "nfs", 3) != 0) - continue; - else if (strncmp (ksp_chain->ks_name, "rfsproccnt_v2", 13) == 0) - nfs2_ksp_server = ksp_chain; - else if (strncmp (ksp_chain->ks_name, "rfsproccnt_v3", 13) == 0) - nfs3_ksp_server = ksp_chain; - else if (strncmp (ksp_chain->ks_name, "rfsproccnt_v4", 13) == 0) - nfs4_ksp_server = ksp_chain; - else if (strncmp (ksp_chain->ks_name, "rfsreqcnt_v2", 12) == 0) - nfs2_ksp_client = ksp_chain; - else if (strncmp (ksp_chain->ks_name, "rfsreqcnt_v3", 12) == 0) - nfs3_ksp_client = ksp_chain; - else if (strncmp (ksp_chain->ks_name, "rfsreqcnt_v4", 12) == 0) - nfs4_ksp_client = ksp_chain; - } - - return (0); +static int nfs_init(void) { + nfs2_ksp_client = NULL; + nfs2_ksp_server = NULL; + nfs3_ksp_client = NULL; + nfs3_ksp_server = NULL; + nfs4_ksp_client = NULL; + nfs4_ksp_server = NULL; + + if (kc == NULL) + return (-1); + + for (kstat_t *ksp_chain = kc->kc_chain; ksp_chain != NULL; + ksp_chain = ksp_chain->ks_next) { + if (strncmp(ksp_chain->ks_module, "nfs", 3) != 0) + continue; + else if (strncmp(ksp_chain->ks_name, "rfsproccnt_v2", 13) == 0) + nfs2_ksp_server = ksp_chain; + else if (strncmp(ksp_chain->ks_name, "rfsproccnt_v3", 13) == 0) + nfs3_ksp_server = ksp_chain; + else if (strncmp(ksp_chain->ks_name, "rfsproccnt_v4", 13) == 0) + nfs4_ksp_server = ksp_chain; + else if (strncmp(ksp_chain->ks_name, "rfsreqcnt_v2", 12) == 0) + nfs2_ksp_client = ksp_chain; + else if (strncmp(ksp_chain->ks_name, "rfsreqcnt_v3", 12) == 0) + nfs3_ksp_client = ksp_chain; + else if (strncmp(ksp_chain->ks_name, "rfsreqcnt_v4", 12) == 0) + nfs4_ksp_client = ksp_chain; + } + + return (0); } /* int nfs_init */ #endif -static void nfs_procedures_submit (const char *plugin_instance, - const char **type_instances, - value_t *values, size_t values_num) -{ - value_list_t vl = VALUE_LIST_INIT; - - vl.values_len = 1; - sstrncpy (vl.plugin, "nfs", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, plugin_instance, - sizeof (vl.plugin_instance)); - sstrncpy (vl.type, "nfs_procedure", sizeof (vl.type)); - - for (size_t i = 0; i < values_num; i++) - { - vl.values = values + i; - sstrncpy (vl.type_instance, type_instances[i], - sizeof (vl.type_instance)); - plugin_dispatch_values (&vl); - } +static void nfs_procedures_submit(const char *plugin_instance, + const char **type_instances, value_t *values, + size_t values_num) { + value_list_t vl = VALUE_LIST_INIT; + + vl.values_len = 1; + sstrncpy(vl.plugin, "nfs", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "nfs_procedure", sizeof(vl.type)); + + for (size_t i = 0; i < values_num; i++) { + vl.values = values + i; + sstrncpy(vl.type_instance, type_instances[i], sizeof(vl.type_instance)); + plugin_dispatch_values(&vl); + } } /* void nfs_procedures_submit */ #if KERNEL_LINUX -static void nfs_submit_fields (int nfs_version, const char *instance, - char **fields, size_t fields_num, const char **proc_names) -{ - char plugin_instance[DATA_MAX_NAME_LEN]; - value_t values[fields_num]; +static void nfs_submit_fields(int nfs_version, const char *instance, + char **fields, size_t fields_num, + const char **proc_names) { + char plugin_instance[DATA_MAX_NAME_LEN]; + value_t values[fields_num]; - ssnprintf (plugin_instance, sizeof (plugin_instance), "v%i%s", - nfs_version, instance); + ssnprintf(plugin_instance, sizeof(plugin_instance), "v%i%s", nfs_version, + instance); - for (size_t i = 0; i < fields_num; i++) - (void) parse_value (fields[i], &values[i], DS_TYPE_DERIVE); + for (size_t i = 0; i < fields_num; i++) + (void)parse_value(fields[i], &values[i], DS_TYPE_DERIVE); - nfs_procedures_submit (plugin_instance, proc_names, values, - fields_num); + nfs_procedures_submit(plugin_instance, proc_names, values, fields_num); } -static int nfs_submit_fields_safe (int nfs_version, const char *instance, - char **fields, size_t fields_num, - const char **proc_names, size_t proc_names_num) -{ - if (fields_num != proc_names_num) - { - WARNING ("nfs plugin: Wrong number of fields for " - "NFSv%i %s statistics. Expected %zu, got %zu.", - nfs_version, instance, - proc_names_num, fields_num); - return (EINVAL); - } - - nfs_submit_fields (nfs_version, instance, fields, fields_num, - proc_names); - - return (0); +static int nfs_submit_fields_safe(int nfs_version, const char *instance, + char **fields, size_t fields_num, + const char **proc_names, + size_t proc_names_num) { + if (fields_num != proc_names_num) { + WARNING("nfs plugin: Wrong number of fields for " + "NFSv%i %s statistics. Expected %zu, got %zu.", + nfs_version, instance, proc_names_num, fields_num); + return (EINVAL); + } + + nfs_submit_fields(nfs_version, instance, fields, fields_num, proc_names); + + return (0); } -static int nfs_submit_nfs4_server (const char *instance, char **fields, - size_t fields_num) -{ - static int suppress_warning = 0; - - if (fields_num != NFS4_SERVER40_NUM_PROC && - fields_num != NFS4_SERVER41_NUM_PROC) - { - if (!suppress_warning) - { - WARNING ("nfs plugin: Unexpected number of fields for " - "NFSv4 %s statistics: %zu. ", - instance, fields_num); - } - - if (fields_num > NFS4_SERVER_MAX_PROC) - { - fields_num = NFS4_SERVER_MAX_PROC; - suppress_warning = 1; - } - else - { - return (EINVAL); - } - } - - nfs_submit_fields (4, instance, fields, - nfs4_server40_procedures_names_num, - nfs4_server40_procedures_names); - - if (fields_num >= NFS4_SERVER41_NUM_PROC) - { - fields += nfs4_server40_procedures_names_num; - - nfs_submit_fields (4, instance, fields, - nfs4_server41_procedures_names_num, - nfs4_server41_procedures_names); - } - - return (0); +static int nfs_submit_nfs4_server(const char *instance, char **fields, + size_t fields_num) { + static int suppress_warning = 0; + + if (fields_num != NFS4_SERVER40_NUM_PROC && + fields_num != NFS4_SERVER41_NUM_PROC) { + if (!suppress_warning) { + WARNING("nfs plugin: Unexpected number of fields for " + "NFSv4 %s statistics: %zu. ", + instance, fields_num); + } + + if (fields_num > NFS4_SERVER_MAX_PROC) { + fields_num = NFS4_SERVER_MAX_PROC; + suppress_warning = 1; + } else { + return (EINVAL); + } + } + + nfs_submit_fields(4, instance, fields, nfs4_server40_procedures_names_num, + nfs4_server40_procedures_names); + + if (fields_num >= NFS4_SERVER41_NUM_PROC) { + fields += nfs4_server40_procedures_names_num; + + nfs_submit_fields(4, instance, fields, nfs4_server41_procedures_names_num, + nfs4_server41_procedures_names); + } + + return (0); } -static int nfs_submit_nfs4_client (const char *instance, char **fields, - size_t fields_num) -{ - size_t proc40_names_num, proc41_names_num; - - static int suppress_warning = 0; - - switch (fields_num) - { - case 34: - case 35: - case 36: - case 37: - case 38: - /* 4.0-only configuration */ - proc40_names_num = fields_num; - break; - case 40: - case 41: - proc40_names_num = 35; - break; - case 42: - case 44: - proc40_names_num = 36; - break; - case 46: - case 47: - case 51: - case 53: - proc40_names_num = 37; - break; - case 54: - proc40_names_num = 38; - break; - default: - if (!suppress_warning) - { - WARNING ("nfs plugin: Unexpected number of " - "fields for NFSv4 %s " - "statistics: %zu. ", - instance, fields_num); - } - - if (fields_num > 34) - { - /* safe fallback to basic nfs40 procedures */ - fields_num = 34; - proc40_names_num = 34; - - suppress_warning = 1; - } - else - { - return (EINVAL); - } - } - - nfs_submit_fields (4, instance, fields, proc40_names_num, - nfs4_client40_procedures_names); - - if (fields_num > proc40_names_num) - { - proc41_names_num = fields_num - proc40_names_num; - fields += proc40_names_num; - - nfs_submit_fields (4, instance, fields,proc41_names_num, - nfs4_client41_procedures_names); - } - - return (0); +static int nfs_submit_nfs4_client(const char *instance, char **fields, + size_t fields_num) { + size_t proc40_names_num, proc41_names_num; + + static int suppress_warning = 0; + + switch (fields_num) { + case 34: + case 35: + case 36: + case 37: + case 38: + /* 4.0-only configuration */ + proc40_names_num = fields_num; + break; + case 40: + case 41: + proc40_names_num = 35; + break; + case 42: + case 44: + proc40_names_num = 36; + break; + case 46: + case 47: + case 51: + case 53: + proc40_names_num = 37; + break; + case 54: + proc40_names_num = 38; + break; + default: + if (!suppress_warning) { + WARNING("nfs plugin: Unexpected number of " + "fields for NFSv4 %s " + "statistics: %zu. ", + instance, fields_num); + } + + if (fields_num > 34) { + /* safe fallback to basic nfs40 procedures */ + fields_num = 34; + proc40_names_num = 34; + + suppress_warning = 1; + } else { + return (EINVAL); + } + } + + nfs_submit_fields(4, instance, fields, proc40_names_num, + nfs4_client40_procedures_names); + + if (fields_num > proc40_names_num) { + proc41_names_num = fields_num - proc40_names_num; + fields += proc40_names_num; + + nfs_submit_fields(4, instance, fields, proc41_names_num, + nfs4_client41_procedures_names); + } + + return (0); } -static void nfs_read_linux (FILE *fh, const char *inst) -{ - char buffer[1024]; - - char *fields[64]; - int fields_num = 0; - - if (fh == NULL) - return; - - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - fields_num = strsplit (buffer, - fields, STATIC_ARRAY_SIZE (fields)); - - if (fields_num < 3) - continue; - - if (strcmp (fields[0], "proc2") == 0) - { - nfs_submit_fields_safe (/* version = */ 2, inst, - fields + 2, (size_t) (fields_num - 2), - nfs2_procedures_names, - nfs2_procedures_names_num); - } - else if (strncmp (fields[0], "proc3", 5) == 0) - { - nfs_submit_fields_safe (/* version = */ 3, inst, - fields + 2, (size_t) (fields_num - 2), - nfs3_procedures_names, - nfs3_procedures_names_num); - } - else if (strcmp (fields[0], "proc4ops") == 0) - { - if (inst[0] == 's') - nfs_submit_nfs4_server (inst, fields + 2, - (size_t) (fields_num - 2)); - } - else if (strcmp (fields[0], "proc4") == 0) - { - if (inst[0] == 'c') - nfs_submit_nfs4_client (inst, fields + 2, - (size_t) (fields_num - 2)); - } - } /* while (fgets) */ +static void nfs_read_linux(FILE *fh, const char *inst) { + char buffer[1024]; + + char *fields[64]; + int fields_num = 0; + + if (fh == NULL) + return; + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + fields_num = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + + if (fields_num < 3) + continue; + + if (strcmp(fields[0], "proc2") == 0) { + nfs_submit_fields_safe(/* version = */ 2, inst, fields + 2, + (size_t)(fields_num - 2), nfs2_procedures_names, + nfs2_procedures_names_num); + } else if (strncmp(fields[0], "proc3", 5) == 0) { + nfs_submit_fields_safe(/* version = */ 3, inst, fields + 2, + (size_t)(fields_num - 2), nfs3_procedures_names, + nfs3_procedures_names_num); + } else if (strcmp(fields[0], "proc4ops") == 0) { + if (inst[0] == 's') + nfs_submit_nfs4_server(inst, fields + 2, (size_t)(fields_num - 2)); + } else if (strcmp(fields[0], "proc4") == 0) { + if (inst[0] == 'c') + nfs_submit_nfs4_client(inst, fields + 2, (size_t)(fields_num - 2)); + } + } /* while (fgets) */ } /* void nfs_read_linux */ #endif /* KERNEL_LINUX */ #if HAVE_LIBKSTAT -static int nfs_read_kstat (kstat_t *ksp, int nfs_version, const char *inst, - char const **proc_names, size_t proc_names_num) -{ - char plugin_instance[DATA_MAX_NAME_LEN]; - value_t values[proc_names_num]; - - if (ksp == NULL) - return (EINVAL); - - ssnprintf (plugin_instance, sizeof (plugin_instance), "v%i%s", - nfs_version, inst); - - kstat_read(kc, ksp, NULL); - for (size_t i = 0; i < proc_names_num; i++) - { - /* The name passed to kstat_data_lookup() doesn't have the - * "const" modifier, so we need to copy the name here. */ - char name[32]; - sstrncpy (name, proc_names[i], sizeof (name)); - - values[i].counter = (derive_t) get_kstat_value (ksp, name); - } - - nfs_procedures_submit (plugin_instance, proc_names, values, - proc_names_num); - return (0); +static int nfs_read_kstat(kstat_t *ksp, int nfs_version, const char *inst, + char const **proc_names, size_t proc_names_num) { + char plugin_instance[DATA_MAX_NAME_LEN]; + value_t values[proc_names_num]; + + if (ksp == NULL) + return (EINVAL); + + ssnprintf(plugin_instance, sizeof(plugin_instance), "v%i%s", nfs_version, + inst); + + kstat_read(kc, ksp, NULL); + for (size_t i = 0; i < proc_names_num; i++) { + /* The name passed to kstat_data_lookup() doesn't have the + * "const" modifier, so we need to copy the name here. */ + char name[32]; + sstrncpy(name, proc_names[i], sizeof(name)); + + values[i].counter = (derive_t)get_kstat_value(ksp, name); + } + + nfs_procedures_submit(plugin_instance, proc_names, values, proc_names_num); + return (0); } #endif #if KERNEL_LINUX -static int nfs_read (void) -{ - FILE *fh; - - if ((fh = fopen ("/proc/net/rpc/nfs", "r")) != NULL) - { - nfs_read_linux (fh, "client"); - fclose (fh); - } - - if ((fh = fopen ("/proc/net/rpc/nfsd", "r")) != NULL) - { - nfs_read_linux (fh, "server"); - fclose (fh); - } - - return (0); +static int nfs_read(void) { + FILE *fh; + + if ((fh = fopen("/proc/net/rpc/nfs", "r")) != NULL) { + nfs_read_linux(fh, "client"); + fclose(fh); + } + + if ((fh = fopen("/proc/net/rpc/nfsd", "r")) != NULL) { + nfs_read_linux(fh, "server"); + fclose(fh); + } + + return (0); } /* #endif KERNEL_LINUX */ #elif HAVE_LIBKSTAT -static int nfs_read (void) -{ - nfs_read_kstat (nfs2_ksp_client, /* version = */ 2, "client", - nfs2_procedures_names, nfs2_procedures_names_num); - nfs_read_kstat (nfs2_ksp_server, /* version = */ 2, "server", - nfs2_procedures_names, nfs2_procedures_names_num); - nfs_read_kstat (nfs3_ksp_client, /* version = */ 3, "client", - nfs3_procedures_names, nfs3_procedures_names_num); - nfs_read_kstat (nfs3_ksp_server, /* version = */ 3, "server", - nfs3_procedures_names, nfs3_procedures_names_num); - nfs_read_kstat (nfs4_ksp_client, /* version = */ 4, "client", - nfs4_procedures_names, nfs4_procedures_names_num); - nfs_read_kstat (nfs4_ksp_server, /* version = */ 4, "server", - nfs4_procedures_names, nfs4_procedures_names_num); - - return (0); +static int nfs_read(void) { + nfs_read_kstat(nfs2_ksp_client, /* version = */ 2, "client", + nfs2_procedures_names, nfs2_procedures_names_num); + nfs_read_kstat(nfs2_ksp_server, /* version = */ 2, "server", + nfs2_procedures_names, nfs2_procedures_names_num); + nfs_read_kstat(nfs3_ksp_client, /* version = */ 3, "client", + nfs3_procedures_names, nfs3_procedures_names_num); + nfs_read_kstat(nfs3_ksp_server, /* version = */ 3, "server", + nfs3_procedures_names, nfs3_procedures_names_num); + nfs_read_kstat(nfs4_ksp_client, /* version = */ 4, "client", + nfs4_procedures_names, nfs4_procedures_names_num); + nfs_read_kstat(nfs4_ksp_server, /* version = */ 4, "server", + nfs4_procedures_names, nfs4_procedures_names_num); + + return (0); } #endif /* HAVE_LIBKSTAT */ -void module_register (void) -{ - plugin_register_init ("nfs", nfs_init); - plugin_register_read ("nfs", nfs_read); +void module_register(void) { + plugin_register_init("nfs", nfs_init); + plugin_register_read("nfs", nfs_read); } /* void module_register */ diff --git a/src/nginx.c b/src/nginx.c index 08c24f9a..ffc545c4 100644 --- a/src/nginx.c +++ b/src/nginx.c @@ -33,202 +33,173 @@ #include -static char *url = NULL; -static char *user = NULL; -static char *pass = NULL; +static char *url = NULL; +static char *user = NULL; +static char *pass = NULL; static char *verify_peer = NULL; static char *verify_host = NULL; -static char *cacert = NULL; -static char *timeout = NULL; +static char *cacert = NULL; +static char *timeout = NULL; static CURL *curl = NULL; -static char nginx_buffer[16384]; +static char nginx_buffer[16384]; static size_t nginx_buffer_len = 0; -static char nginx_curl_error[CURL_ERROR_SIZE]; - -static const char *config_keys[] = -{ - "URL", - "User", - "Password", - "VerifyPeer", - "VerifyHost", - "CACert", - "Timeout" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); - -static size_t nginx_curl_callback (void *buf, size_t size, size_t nmemb, - void __attribute__((unused)) *stream) -{ +static char nginx_curl_error[CURL_ERROR_SIZE]; + +static const char *config_keys[] = { + "URL", "User", "Password", "VerifyPeer", "VerifyHost", "CACert", "Timeout"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); + +static size_t nginx_curl_callback(void *buf, size_t size, size_t nmemb, + void __attribute__((unused)) * stream) { size_t len = size * nmemb; /* Check if the data fits into the memory. If not, truncate it. */ - if ((nginx_buffer_len + len) >= sizeof (nginx_buffer)) - { - assert (sizeof (nginx_buffer) > nginx_buffer_len); - len = (sizeof (nginx_buffer) - 1) - nginx_buffer_len; + if ((nginx_buffer_len + len) >= sizeof(nginx_buffer)) { + assert(sizeof(nginx_buffer) > nginx_buffer_len); + len = (sizeof(nginx_buffer) - 1) - nginx_buffer_len; } if (len == 0) return (len); - memcpy (&nginx_buffer[nginx_buffer_len], buf, len); + memcpy(&nginx_buffer[nginx_buffer_len], buf, len); nginx_buffer_len += len; nginx_buffer[nginx_buffer_len] = 0; return (len); } -static int config_set (char **var, const char *value) -{ - if (*var != NULL) - { - free (*var); +static int config_set(char **var, const char *value) { + if (*var != NULL) { + free(*var); *var = NULL; } - if ((*var = strdup (value)) == NULL) + if ((*var = strdup(value)) == NULL) return (1); else return (0); } -static int config (const char *key, const char *value) -{ - if (strcasecmp (key, "url") == 0) - return (config_set (&url, value)); - else if (strcasecmp (key, "user") == 0) - return (config_set (&user, value)); - else if (strcasecmp (key, "password") == 0) - return (config_set (&pass, value)); - else if (strcasecmp (key, "verifypeer") == 0) - return (config_set (&verify_peer, value)); - else if (strcasecmp (key, "verifyhost") == 0) - return (config_set (&verify_host, value)); - else if (strcasecmp (key, "cacert") == 0) - return (config_set (&cacert, value)); - else if (strcasecmp (key, "timeout") == 0) - return (config_set (&timeout, value)); +static int config(const char *key, const char *value) { + if (strcasecmp(key, "url") == 0) + return (config_set(&url, value)); + else if (strcasecmp(key, "user") == 0) + return (config_set(&user, value)); + else if (strcasecmp(key, "password") == 0) + return (config_set(&pass, value)); + else if (strcasecmp(key, "verifypeer") == 0) + return (config_set(&verify_peer, value)); + else if (strcasecmp(key, "verifyhost") == 0) + return (config_set(&verify_host, value)); + else if (strcasecmp(key, "cacert") == 0) + return (config_set(&cacert, value)); + else if (strcasecmp(key, "timeout") == 0) + return (config_set(&timeout, value)); else return (-1); } /* int config */ -static int init (void) -{ +static int init(void) { if (curl != NULL) - curl_easy_cleanup (curl); + curl_easy_cleanup(curl); - if ((curl = curl_easy_init ()) == NULL) - { - ERROR ("nginx plugin: curl_easy_init failed."); + if ((curl = curl_easy_init()) == NULL) { + ERROR("nginx plugin: curl_easy_init failed."); return (-1); } - curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, nginx_curl_callback); - curl_easy_setopt (curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); - curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, nginx_curl_error); + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, nginx_curl_callback); + curl_easy_setopt(curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, nginx_curl_error); - if (user != NULL) - { + if (user != NULL) { #ifdef HAVE_CURLOPT_USERNAME - curl_easy_setopt (curl, CURLOPT_USERNAME, user); - curl_easy_setopt (curl, CURLOPT_PASSWORD, (pass == NULL) ? "" : pass); + curl_easy_setopt(curl, CURLOPT_USERNAME, user); + curl_easy_setopt(curl, CURLOPT_PASSWORD, (pass == NULL) ? "" : pass); #else static char credentials[1024]; - int status = ssnprintf (credentials, sizeof (credentials), - "%s:%s", user, pass == NULL ? "" : pass); - if ((status < 0) || ((size_t) status >= sizeof (credentials))) - { - ERROR ("nginx plugin: Credentials would have been truncated."); + int status = ssnprintf(credentials, sizeof(credentials), "%s:%s", user, + pass == NULL ? "" : pass); + if ((status < 0) || ((size_t)status >= sizeof(credentials))) { + ERROR("nginx plugin: Credentials would have been truncated."); return (-1); } - curl_easy_setopt (curl, CURLOPT_USERPWD, credentials); + curl_easy_setopt(curl, CURLOPT_USERPWD, credentials); #endif } - if (url != NULL) - { - curl_easy_setopt (curl, CURLOPT_URL, url); + if (url != NULL) { + curl_easy_setopt(curl, CURLOPT_URL, url); } - curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt (curl, CURLOPT_MAXREDIRS, 50L); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L); - if ((verify_peer == NULL) || IS_TRUE (verify_peer)) - { - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 1L); - } - else - { - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0L); + if ((verify_peer == NULL) || IS_TRUE(verify_peer)) { + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); + } else { + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); } - if ((verify_host == NULL) || IS_TRUE (verify_host)) - { - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 2L); - } - else - { - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0L); + if ((verify_host == NULL) || IS_TRUE(verify_host)) { + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L); + } else { + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); } - if (cacert != NULL) - { - curl_easy_setopt (curl, CURLOPT_CAINFO, cacert); + if (cacert != NULL) { + curl_easy_setopt(curl, CURLOPT_CAINFO, cacert); } #ifdef HAVE_CURLOPT_TIMEOUT_MS - if (timeout != NULL) - { - curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS, atol(timeout)); - } - else - { - curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval())); + if (timeout != NULL) { + curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, atol(timeout)); + } else { + curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, + (long)CDTIME_T_TO_MS(plugin_get_interval())); } #endif return (0); } /* void init */ -static void submit (const char *type, const char *inst, long long value) -{ +static void submit(const char *type, const char *inst, long long value) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; - if (strcmp (type, "nginx_connections") == 0) + if (strcmp(type, "nginx_connections") == 0) values[0].gauge = value; - else if (strcmp (type, "nginx_requests") == 0) + else if (strcmp(type, "nginx_requests") == 0) values[0].derive = value; - else if (strcmp (type, "connections") == 0) + else if (strcmp(type, "connections") == 0) values[0].derive = value; else return; vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - sstrncpy (vl.plugin, "nginx", sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof (vl.type)); + vl.values_len = STATIC_ARRAY_SIZE(values); + sstrncpy(vl.plugin, "nginx", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); if (inst != NULL) - sstrncpy (vl.type_instance, inst, sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, inst, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* void submit */ -static int nginx_read (void) -{ +static int nginx_read(void) { char *ptr; char *lines[16]; - int lines_num = 0; + int lines_num = 0; char *saveptr; char *fields[16]; - int fields_num; + int fields_num; if (curl == NULL) return (-1); @@ -236,16 +207,14 @@ static int nginx_read (void) return (-1); nginx_buffer_len = 0; - if (curl_easy_perform (curl) != CURLE_OK) - { - WARNING ("nginx plugin: curl_easy_perform failed: %s", nginx_curl_error); + if (curl_easy_perform(curl) != CURLE_OK) { + WARNING("nginx plugin: curl_easy_perform failed: %s", nginx_curl_error); return (-1); } ptr = nginx_buffer; saveptr = NULL; - while ((lines[lines_num] = strtok_r (ptr, "\n\r", &saveptr)) != NULL) - { + while ((lines[lines_num] = strtok_r(ptr, "\n\r", &saveptr)) != NULL) { ptr = NULL; lines_num++; @@ -259,40 +228,31 @@ static int nginx_read (void) * 101059015 100422216 347910649 * Reading: 6 Writing: 179 Waiting: 106 */ - for (int i = 0; i < lines_num; i++) - { - fields_num = strsplit (lines[i], fields, - (sizeof (fields) / sizeof (fields[0]))); - - if (fields_num == 3) - { - if ((strcmp (fields[0], "Active") == 0) - && (strcmp (fields[1], "connections:") == 0)) - { - submit ("nginx_connections", "active", atoll (fields[2])); - } - else if ((atoll (fields[0]) != 0) - && (atoll (fields[1]) != 0) - && (atoll (fields[2]) != 0)) - { - submit ("connections", "accepted", atoll (fields[0])); + for (int i = 0; i < lines_num; i++) { + fields_num = + strsplit(lines[i], fields, (sizeof(fields) / sizeof(fields[0]))); + + if (fields_num == 3) { + if ((strcmp(fields[0], "Active") == 0) && + (strcmp(fields[1], "connections:") == 0)) { + submit("nginx_connections", "active", atoll(fields[2])); + } else if ((atoll(fields[0]) != 0) && (atoll(fields[1]) != 0) && + (atoll(fields[2]) != 0)) { + submit("connections", "accepted", atoll(fields[0])); /* TODO: The legacy metric "handled", which is the sum of "accepted" and * "failed", is reported for backwards compatibility only. Remove in the * next major version. */ - submit ("connections", "handled", atoll (fields[1])); - submit ("connections", "failed", (atoll(fields[0]) - atoll (fields[1]))); - submit ("nginx_requests", NULL, atoll (fields[2])); + submit("connections", "handled", atoll(fields[1])); + submit("connections", "failed", (atoll(fields[0]) - atoll(fields[1]))); + submit("nginx_requests", NULL, atoll(fields[2])); } - } - else if (fields_num == 6) - { - if ((strcmp (fields[0], "Reading:") == 0) - && (strcmp (fields[2], "Writing:") == 0) - && (strcmp (fields[4], "Waiting:") == 0)) - { - submit ("nginx_connections", "reading", atoll (fields[1])); - submit ("nginx_connections", "writing", atoll (fields[3])); - submit ("nginx_connections", "waiting", atoll (fields[5])); + } else if (fields_num == 6) { + if ((strcmp(fields[0], "Reading:") == 0) && + (strcmp(fields[2], "Writing:") == 0) && + (strcmp(fields[4], "Waiting:") == 0)) { + submit("nginx_connections", "reading", atoll(fields[1])); + submit("nginx_connections", "writing", atoll(fields[3])); + submit("nginx_connections", "waiting", atoll(fields[5])); } } } @@ -302,11 +262,10 @@ static int nginx_read (void) return (0); } /* int nginx_read */ -void module_register (void) -{ - plugin_register_config ("nginx", config, config_keys, config_keys_num); - plugin_register_init ("nginx", init); - plugin_register_read ("nginx", nginx_read); +void module_register(void) { + plugin_register_config("nginx", config, config_keys, config_keys_num); + plugin_register_init("nginx", init); + plugin_register_read("nginx", nginx_read); } /* void module_register */ /* diff --git a/src/notify_desktop.c b/src/notify_desktop.c index 5cab1190..48404411 100644 --- a/src/notify_desktop.c +++ b/src/notify_desktop.c @@ -37,12 +37,12 @@ #include #ifndef NOTIFY_CHECK_VERSION -# define NOTIFY_CHECK_VERSION(x,y,z) 0 +#define NOTIFY_CHECK_VERSION(x, y, z) 0 #endif -#define log_info(...) INFO ("notify_desktop: " __VA_ARGS__) -#define log_warn(...) WARNING ("notify_desktop: " __VA_ARGS__) -#define log_err(...) ERROR ("notify_desktop: " __VA_ARGS__) +#define log_info(...) INFO("notify_desktop: " __VA_ARGS__) +#define log_warn(...) WARNING("notify_desktop: " __VA_ARGS__) +#define log_err(...) ERROR("notify_desktop: " __VA_ARGS__) #define DEFAULT_TIMEOUT 5000 @@ -50,126 +50,121 @@ static int okay_timeout = DEFAULT_TIMEOUT; static int warn_timeout = DEFAULT_TIMEOUT; static int fail_timeout = DEFAULT_TIMEOUT; -static int set_timeout (oconfig_item_t *ci, int *timeout) -{ - if ((0 != ci->children_num) || (1 != ci->values_num) - || (OCONFIG_TYPE_NUMBER != ci->values[0].type)) { - log_err ("%s expects a single number argument.", ci->key); - return 1; - } - - *timeout = (int)ci->values[0].value.number; - if (0 > *timeout) - *timeout = DEFAULT_TIMEOUT; - return 0; +static int set_timeout(oconfig_item_t *ci, int *timeout) { + if ((0 != ci->children_num) || (1 != ci->values_num) || + (OCONFIG_TYPE_NUMBER != ci->values[0].type)) { + log_err("%s expects a single number argument.", ci->key); + return 1; + } + + *timeout = (int)ci->values[0].value.number; + if (0 > *timeout) + *timeout = DEFAULT_TIMEOUT; + return 0; } /* set_timeout */ -static int c_notify_config (oconfig_item_t *ci) -{ - for (int i = 0; i < ci->children_num; ++i) { - oconfig_item_t *c = ci->children + i; - - if (0 == strcasecmp (c->key, "OkayTimeout")) - set_timeout (c, &okay_timeout); - else if (0 == strcasecmp (c->key, "WarningTimeout")) - set_timeout (c, &warn_timeout); - else if (0 == strcasecmp (c->key, "FailureTimeout")) - set_timeout (c, &fail_timeout); - } - return 0; +static int c_notify_config(oconfig_item_t *ci) { + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *c = ci->children + i; + + if (0 == strcasecmp(c->key, "OkayTimeout")) + set_timeout(c, &okay_timeout); + else if (0 == strcasecmp(c->key, "WarningTimeout")) + set_timeout(c, &warn_timeout); + else if (0 == strcasecmp(c->key, "FailureTimeout")) + set_timeout(c, &fail_timeout); + } + return 0; } /* c_notify_config */ -static int c_notify (const notification_t *n, - user_data_t __attribute__((unused)) *user_data) -{ - NotifyNotification *notification = NULL; - NotifyUrgency urgency = NOTIFY_URGENCY_LOW; - int timeout = okay_timeout; - - char summary[1024]; - - if (NOTIF_WARNING == n->severity) { - urgency = NOTIFY_URGENCY_NORMAL; - timeout = warn_timeout; - } - else if (NOTIF_FAILURE == n->severity) { - urgency = NOTIFY_URGENCY_CRITICAL; - timeout = fail_timeout; - } - - ssnprintf (summary, sizeof (summary), "collectd %s notification", - (NOTIF_FAILURE == n->severity) ? "FAILURE" - : (NOTIF_WARNING == n->severity) ? "WARNING" - : (NOTIF_OKAY == n->severity) ? "OKAY" : "UNKNOWN"); - - notification = notify_notification_new (summary, n->message, NULL -#if NOTIFY_CHECK_VERSION (0, 7, 0) - ); +static int c_notify(const notification_t *n, + user_data_t __attribute__((unused)) * user_data) { + NotifyNotification *notification = NULL; + NotifyUrgency urgency = NOTIFY_URGENCY_LOW; + int timeout = okay_timeout; + + char summary[1024]; + + if (NOTIF_WARNING == n->severity) { + urgency = NOTIFY_URGENCY_NORMAL; + timeout = warn_timeout; + } else if (NOTIF_FAILURE == n->severity) { + urgency = NOTIFY_URGENCY_CRITICAL; + timeout = fail_timeout; + } + + ssnprintf(summary, sizeof(summary), "collectd %s notification", + (NOTIF_FAILURE == n->severity) + ? "FAILURE" + : (NOTIF_WARNING == n->severity) + ? "WARNING" + : (NOTIF_OKAY == n->severity) ? "OKAY" : "UNKNOWN"); + + notification = notify_notification_new(summary, n->message, NULL +#if NOTIFY_CHECK_VERSION(0, 7, 0) + ); #else - , NULL); + , + NULL); #endif - if (NULL == notification) { - log_err ("Failed to create a new notification."); - return -1; - } + if (NULL == notification) { + log_err("Failed to create a new notification."); + return -1; + } - notify_notification_set_urgency (notification, urgency); - notify_notification_set_timeout (notification, timeout); + notify_notification_set_urgency(notification, urgency); + notify_notification_set_timeout(notification, timeout); - if (! notify_notification_show (notification, NULL)) - log_err ("Failed to display notification."); + if (!notify_notification_show(notification, NULL)) + log_err("Failed to display notification."); - g_object_unref (G_OBJECT (notification)); - return 0; + g_object_unref(G_OBJECT(notification)); + return 0; } /* c_notify */ -static int c_notify_shutdown (void) -{ - plugin_unregister_init ("notify_desktop"); - plugin_unregister_notification ("notify_desktop"); - plugin_unregister_shutdown ("notify_desktop"); +static int c_notify_shutdown(void) { + plugin_unregister_init("notify_desktop"); + plugin_unregister_notification("notify_desktop"); + plugin_unregister_shutdown("notify_desktop"); - if (notify_is_initted ()) - notify_uninit (); - return 0; + if (notify_is_initted()) + notify_uninit(); + return 0; } /* c_notify_shutdown */ -static int c_notify_init (void) -{ - char *name = NULL; - char *vendor = NULL; - char *version = NULL; - char *spec_version = NULL; - - if (! notify_init (PACKAGE_STRING)) { - log_err ("Failed to initialize libnotify."); - return -1; - } - - if (! notify_get_server_info (&name, &vendor, &version, &spec_version)) - log_warn ("Failed to get the notification server info. " - "Check if you have a notification daemon running."); - else { - log_info ("Found notification daemon: %s (%s) %s (spec version %s)", - name, vendor, version, spec_version); - free (name); - free (vendor); - free (version); - free (spec_version); - } - - plugin_register_notification ("notify_desktop", c_notify, - /* user_data = */ NULL); - plugin_register_shutdown ("notify_desktop", c_notify_shutdown); - return 0; +static int c_notify_init(void) { + char *name = NULL; + char *vendor = NULL; + char *version = NULL; + char *spec_version = NULL; + + if (!notify_init(PACKAGE_STRING)) { + log_err("Failed to initialize libnotify."); + return -1; + } + + if (!notify_get_server_info(&name, &vendor, &version, &spec_version)) + log_warn("Failed to get the notification server info. " + "Check if you have a notification daemon running."); + else { + log_info("Found notification daemon: %s (%s) %s (spec version %s)", name, + vendor, version, spec_version); + free(name); + free(vendor); + free(version); + free(spec_version); + } + + plugin_register_notification("notify_desktop", c_notify, + /* user_data = */ NULL); + plugin_register_shutdown("notify_desktop", c_notify_shutdown); + return 0; } /* c_notify_init */ -void module_register (void) -{ - plugin_register_complex_config ("notify_desktop", c_notify_config); - plugin_register_init ("notify_desktop", c_notify_init); - return; +void module_register(void) { + plugin_register_complex_config("notify_desktop", c_notify_config); + plugin_register_init("notify_desktop", c_notify_init); + return; } /* module_register */ /* vim: set sw=4 ts=4 tw=78 noexpandtab : */ - diff --git a/src/notify_email.c b/src/notify_email.c index dc20cbbe..f42e66c6 100644 --- a/src/notify_email.c +++ b/src/notify_email.c @@ -30,19 +30,12 @@ #include #include -#define MAXSTRING 256 - -static const char *config_keys[] = -{ - "SMTPServer", - "SMTPPort", - "SMTPUser", - "SMTPPassword", - "From", - "Recipient", - "Subject" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +#define MAXSTRING 256 + +static const char *config_keys[] = {"SMTPServer", "SMTPPort", "SMTPUser", + "SMTPPassword", "From", "Recipient", + "Subject"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static char **recipients; static int recipients_len = 0; @@ -59,16 +52,14 @@ static char *smtp_password = NULL; static char *email_from = NULL; static char *email_subject = NULL; -#define DEFAULT_SMTP_HOST "localhost" -#define DEFAULT_SMTP_FROM "root@localhost" -#define DEFAULT_SMTP_SUBJECT "Collectd notify: %s@%s" +#define DEFAULT_SMTP_HOST "localhost" +#define DEFAULT_SMTP_FROM "root@localhost" +#define DEFAULT_SMTP_SUBJECT "Collectd notify: %s@%s" /* Callback to get username and password */ -static int authinteract (auth_client_request_t request, char **result, - int fields, void __attribute__((unused)) *arg) -{ - for (int i = 0; i < fields; i++) - { +static int authinteract(auth_client_request_t request, char **result, + int fields, void __attribute__((unused)) * arg) { + for (int i = 0; i < fields; i++) { if (request[i].flags & AUTH_USER) result[i] = smtp_user; else if (request[i].flags & AUTH_PASS) @@ -80,153 +71,138 @@ static int authinteract (auth_client_request_t request, char **result, } /* int authinteract */ /* Callback to print the recipient status */ -static void print_recipient_status (smtp_recipient_t recipient, - const char *mailbox, void __attribute__((unused)) *arg) -{ +static void print_recipient_status(smtp_recipient_t recipient, + const char *mailbox, + void __attribute__((unused)) * arg) { const smtp_status_t *status; - status = smtp_recipient_status (recipient); + status = smtp_recipient_status(recipient); if (status->text[strlen(status->text) - 2] == '\r') status->text[strlen(status->text) - 2] = 0; - INFO ("notify_email: notify sent to %s: %d %s", mailbox, status->code, - status->text); + INFO("notify_email: notify sent to %s: %d %s", mailbox, status->code, + status->text); } /* void print_recipient_status */ /* Callback to monitor SMTP activity */ -static void monitor_cb (const char *buf, int buflen, int writing, - void __attribute__((unused)) *arg) -{ +static void monitor_cb(const char *buf, int buflen, int writing, + void __attribute__((unused)) * arg) { char log_str[MAXSTRING]; - sstrncpy (log_str, buf, sizeof (log_str)); + sstrncpy(log_str, buf, sizeof(log_str)); if (buflen > 2) log_str[buflen - 2] = 0; /* replace \n with \0 */ if (writing == SMTP_CB_HEADERS) { - DEBUG ("notify_email plugin: SMTP --- H: %s", log_str); + DEBUG("notify_email plugin: SMTP --- H: %s", log_str); return; } - DEBUG (writing - ? "notify_email plugin: SMTP >>> C: %s" - : "notify_email plugin: SMTP <<< S: %s", - log_str); + DEBUG(writing ? "notify_email plugin: SMTP >>> C: %s" + : "notify_email plugin: SMTP <<< S: %s", + log_str); } /* void monitor_cb */ -static int notify_email_init (void) -{ +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); + ssnprintf(server, sizeof(server), "%s:%i", + (smtp_host == NULL) ? DEFAULT_SMTP_HOST : smtp_host, smtp_port); - pthread_mutex_lock (&session_lock); + pthread_mutex_lock(&session_lock); auth_client_init(); - session = smtp_create_session (); + session = smtp_create_session(); if (session == NULL) { - pthread_mutex_unlock (&session_lock); - ERROR ("notify_email plugin: cannot create SMTP session"); + 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); - smtp_set_server (session, server); + smtp_set_monitorcb(session, monitor_cb, NULL, 1); + smtp_set_hostname(session, hostname_g); + smtp_set_server(session, server); if (smtp_user && smtp_password) { - authctx = auth_create_context (); - auth_set_mechanism_flags (authctx, AUTH_PLUGIN_PLAIN, 0); - auth_set_interact_cb (authctx, authinteract, NULL); + authctx = auth_create_context(); + auth_set_mechanism_flags(authctx, AUTH_PLUGIN_PLAIN, 0); + auth_set_interact_cb(authctx, authinteract, NULL); } - if ( !smtp_auth_set_context (session, authctx)) { - pthread_mutex_unlock (&session_lock); - ERROR ("notify_email plugin: cannot set SMTP auth context"); + 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); + pthread_mutex_unlock(&session_lock); return (0); } /* int notify_email_init */ -static int notify_email_shutdown (void) -{ - pthread_mutex_lock (&session_lock); +static int notify_email_shutdown(void) { + pthread_mutex_lock(&session_lock); if (session != NULL) - smtp_destroy_session (session); + smtp_destroy_session(session); session = NULL; if (authctx != NULL) - auth_destroy_context (authctx); + auth_destroy_context(authctx); authctx = NULL; auth_client_exit(); - pthread_mutex_unlock (&session_lock); + pthread_mutex_unlock(&session_lock); return (0); } /* int notify_email_shutdown */ -static int notify_email_config (const char *key, const char *value) -{ - if (strcasecmp (key, "Recipient") == 0) - { +static int notify_email_config(const char *key, const char *value) { + if (strcasecmp(key, "Recipient") == 0) { char **tmp; - tmp = realloc (recipients, (recipients_len + 1) * sizeof (char *)); + tmp = realloc(recipients, (recipients_len + 1) * sizeof(char *)); if (tmp == NULL) { - ERROR ("notify_email: realloc failed."); + ERROR("notify_email: realloc failed."); return (-1); } recipients = tmp; - recipients[recipients_len] = strdup (value); + recipients[recipients_len] = strdup(value); if (recipients[recipients_len] == NULL) { - ERROR ("notify_email: strdup failed."); + ERROR("notify_email: strdup failed."); return (-1); } recipients_len++; - } - else if (0 == strcasecmp (key, "SMTPServer")) { - sfree (smtp_host); - smtp_host = strdup (value); - } - else if (0 == strcasecmp (key, "SMTPPort")) { - int port_tmp = atoi (value); - if (port_tmp < 1 || port_tmp > 65535) - { - WARNING ("notify_email plugin: Invalid SMTP port: %i", port_tmp); + } else if (0 == strcasecmp(key, "SMTPServer")) { + sfree(smtp_host); + smtp_host = strdup(value); + } else if (0 == strcasecmp(key, "SMTPPort")) { + int port_tmp = atoi(value); + if (port_tmp < 1 || port_tmp > 65535) { + WARNING("notify_email plugin: Invalid SMTP port: %i", port_tmp); return (1); } smtp_port = port_tmp; - } - else if (0 == strcasecmp (key, "SMTPUser")) { - sfree (smtp_user); - smtp_user = strdup (value); - } - else if (0 == strcasecmp (key, "SMTPPassword")) { - sfree (smtp_password); - smtp_password = strdup (value); - } - else if (0 == strcasecmp (key, "From")) { - sfree (email_from); - email_from = strdup (value); - } - else if (0 == strcasecmp (key, "Subject")) { - sfree (email_subject); - email_subject = strdup (value); - } - else { + } else if (0 == strcasecmp(key, "SMTPUser")) { + sfree(smtp_user); + smtp_user = strdup(value); + } else if (0 == strcasecmp(key, "SMTPPassword")) { + sfree(smtp_password); + smtp_password = strdup(value); + } else if (0 == strcasecmp(key, "From")) { + sfree(email_from); + email_from = strdup(value); + } else if (0 == strcasecmp(key, "Subject")) { + sfree(email_subject); + email_subject = strdup(value); + } else { return -1; } return 0; } /* int notify_email_config (const char *, const char *) */ -static int notify_email_notification (const notification_t *n, - user_data_t __attribute__((unused)) *user_data) -{ +static int notify_email_notification(const notification_t *n, + user_data_t __attribute__((unused)) * + user_data) { struct tm timestamp_tm; char timestamp_str[64]; @@ -235,88 +211,84 @@ static int notify_email_notification (const notification_t *n, char subject[MAXSTRING]; char buf[4096] = ""; - int buf_len = sizeof (buf); + int buf_len = sizeof(buf); int i; - ssnprintf (severity, sizeof (severity), "%s", - (n->severity == NOTIF_FAILURE) ? "FAILURE" - : ((n->severity == NOTIF_WARNING) ? "WARNING" - : ((n->severity == NOTIF_OKAY) ? "OKAY" : "UNKNOWN"))); + ssnprintf(severity, sizeof(severity), "%s", + (n->severity == NOTIF_FAILURE) + ? "FAILURE" + : ((n->severity == NOTIF_WARNING) + ? "WARNING" + : ((n->severity == NOTIF_OKAY) ? "OKAY" : "UNKNOWN"))); - ssnprintf (subject, sizeof (subject), - (email_subject == NULL) ? DEFAULT_SMTP_SUBJECT : email_subject, - severity, n->host); + ssnprintf(subject, sizeof(subject), + (email_subject == NULL) ? DEFAULT_SMTP_SUBJECT : email_subject, + severity, n->host); - localtime_r (&CDTIME_T_TO_TIME_T (n->time), ×tamp_tm); - strftime (timestamp_str, sizeof (timestamp_str), "%Y-%m-%d %H:%M:%S", - ×tamp_tm); - timestamp_str[sizeof (timestamp_str) - 1] = '\0'; + localtime_r(&CDTIME_T_TO_TIME_T(n->time), ×tamp_tm); + strftime(timestamp_str, sizeof(timestamp_str), "%Y-%m-%d %H:%M:%S", + ×tamp_tm); + timestamp_str[sizeof(timestamp_str) - 1] = '\0'; /* Let's make RFC822 message text with \r\n EOLs */ - ssnprintf (buf, buf_len, - "MIME-Version: 1.0\r\n" - "Content-Type: text/plain; charset=\"US-ASCII\"\r\n" - "Content-Transfer-Encoding: 8bit\r\n" - "Subject: %s\r\n" - "\r\n" - "%s - %s@%s\r\n" - "\r\n" - "Message: %s", - subject, - timestamp_str, - severity, - n->host, - n->message); - - pthread_mutex_lock (&session_lock); + ssnprintf(buf, buf_len, "MIME-Version: 1.0\r\n" + "Content-Type: text/plain; charset=\"US-ASCII\"\r\n" + "Content-Transfer-Encoding: 8bit\r\n" + "Subject: %s\r\n" + "\r\n" + "%s - %s@%s\r\n" + "\r\n" + "Message: %s", + subject, timestamp_str, severity, 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); + 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"); + if (!(message = smtp_add_message(session))) { + pthread_mutex_unlock(&session_lock); + ERROR("notify_email plugin: cannot set SMTP message"); return (-1); } - smtp_set_reverse_path (message, email_from); - smtp_set_header (message, "To", NULL, NULL); - smtp_set_message_str (message, buf); + smtp_set_reverse_path(message, email_from); + smtp_set_header(message, "To", NULL, NULL); + smtp_set_message_str(message, buf); for (i = 0; i < recipients_len; i++) - smtp_add_recipient (message, recipients[i]); + smtp_add_recipient(message, recipients[i]); /* Initiate a connection to the SMTP server and transfer the message. */ - if (!smtp_start_session (session)) { - ERROR ("notify_email plugin: SMTP server problem: %s", - smtp_strerror (smtp_errno (), buf, sizeof buf)); - pthread_mutex_unlock (&session_lock); + if (!smtp_start_session(session)) { + ERROR("notify_email plugin: SMTP server problem: %s", + smtp_strerror(smtp_errno(), buf, sizeof buf)); + pthread_mutex_unlock(&session_lock); return (-1); } else { - #if COLLECT_DEBUG +#if COLLECT_DEBUG const smtp_status_t *status; /* Report on the success or otherwise of the mail transfer. */ - status = smtp_message_transfer_status (message); - DEBUG ("notify_email plugin: SMTP server report: %d %s", - status->code, (status->text != NULL) ? status->text : "\n"); - #endif - smtp_enumerate_recipients (message, print_recipient_status, NULL); + status = smtp_message_transfer_status(message); + DEBUG("notify_email plugin: SMTP server report: %d %s", status->code, + (status->text != NULL) ? status->text : "\n"); +#endif + smtp_enumerate_recipients(message, print_recipient_status, NULL); } - pthread_mutex_unlock (&session_lock); + pthread_mutex_unlock(&session_lock); return (0); } /* int notify_email_notification */ -void module_register (void) -{ - plugin_register_init ("notify_email", notify_email_init); - plugin_register_shutdown ("notify_email", notify_email_shutdown); - plugin_register_config ("notify_email", notify_email_config, - config_keys, config_keys_num); - plugin_register_notification ("notify_email", notify_email_notification, - /* user_data = */ NULL); +void module_register(void) { + plugin_register_init("notify_email", notify_email_init); + plugin_register_shutdown("notify_email", notify_email_shutdown); + plugin_register_config("notify_email", notify_email_config, config_keys, + config_keys_num); + plugin_register_notification("notify_email", notify_email_notification, + /* user_data = */ NULL); } /* void module_register (void) */ /* vim: set sw=2 sts=2 ts=8 et : */ diff --git a/src/notify_nagios.c b/src/notify_nagios.c index b08c411d..13516915 100644 --- a/src/notify_nagios.c +++ b/src/notify_nagios.c @@ -26,140 +26,132 @@ #include "collectd.h" -#include "plugin.h" #include "common.h" +#include "plugin.h" -#define NAGIOS_OK 0 -#define NAGIOS_WARNING 1 +#define NAGIOS_OK 0 +#define NAGIOS_WARNING 1 #define NAGIOS_CRITICAL 2 -#define NAGIOS_UNKNOWN 3 +#define NAGIOS_UNKNOWN 3 #ifndef NAGIOS_COMMAND_FILE -# define NAGIOS_COMMAND_FILE "/usr/local/nagios/var/rw/nagios.cmd" +#define NAGIOS_COMMAND_FILE "/usr/local/nagios/var/rw/nagios.cmd" #endif static char *nagios_command_file; -static int nagios_config (oconfig_item_t *ci) /* {{{ */ +static int nagios_config(oconfig_item_t *ci) /* {{{ */ { - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("CommandFile", child->key) == 0) - cf_util_get_string (child, &nagios_command_file); + if (strcasecmp("CommandFile", child->key) == 0) + cf_util_get_string(child, &nagios_command_file); else - WARNING ("notify_nagios plugin: Ignoring unknown config option \"%s\".", - child->key); + WARNING("notify_nagios plugin: Ignoring unknown config option \"%s\".", + child->key); } return 0; } /* }}} nagios_config */ -static int nagios_print (char const *buffer) /* {{{ */ +static int nagios_print(char const *buffer) /* {{{ */ { char const *file = NAGIOS_COMMAND_FILE; int fd; int status; - struct flock lock = { 0 }; + struct flock lock = {0}; if (nagios_command_file != NULL) file = nagios_command_file; - fd = open (file, O_WRONLY | O_APPEND); - if (fd < 0) - { + fd = open(file, O_WRONLY | O_APPEND); + if (fd < 0) { char errbuf[1024]; status = errno; - ERROR ("notify_nagios plugin: Opening \"%s\" failed: %s", - file, sstrerror (status, errbuf, sizeof (errbuf))); + ERROR("notify_nagios plugin: Opening \"%s\" failed: %s", file, + sstrerror(status, errbuf, sizeof(errbuf))); return status; } lock.l_type = F_WRLCK; lock.l_whence = SEEK_END; - status = fcntl (fd, F_GETLK, &lock); - if (status != 0) - { + status = fcntl(fd, F_GETLK, &lock); + if (status != 0) { char errbuf[1024]; status = errno; - ERROR ("notify_nagios plugin: Failed to acquire write lock on \"%s\": %s", - file, sstrerror (status, errbuf, sizeof (errbuf))); - close (fd); + ERROR("notify_nagios plugin: Failed to acquire write lock on \"%s\": %s", + file, sstrerror(status, errbuf, sizeof(errbuf))); + close(fd); return status; } - status = (int) lseek (fd, 0, SEEK_END); - if (status == -1) - { + status = (int)lseek(fd, 0, SEEK_END); + if (status == -1) { char errbuf[1024]; status = errno; - ERROR ("notify_nagios plugin: Seeking to end of \"%s\" failed: %s", - file, sstrerror (status, errbuf, sizeof (errbuf))); - close (fd); + ERROR("notify_nagios plugin: Seeking to end of \"%s\" failed: %s", file, + sstrerror(status, errbuf, sizeof(errbuf))); + close(fd); return status; } - status = (int) swrite (fd, buffer, strlen (buffer)); - if (status != 0) - { + status = (int)swrite(fd, buffer, strlen(buffer)); + if (status != 0) { char errbuf[1024]; status = errno; - ERROR ("notify_nagios plugin: Writing to \"%s\" failed: %s", - file, sstrerror (status, errbuf, sizeof (errbuf))); - close (fd); + ERROR("notify_nagios plugin: Writing to \"%s\" failed: %s", file, + sstrerror(status, errbuf, sizeof(errbuf))); + close(fd); return status; } - close (fd); + close(fd); return status; } /* }}} int nagios_print */ -static int nagios_notify (const notification_t *n, /* {{{ */ - __attribute__((unused)) user_data_t *user_data) -{ +static int nagios_notify(const notification_t *n, /* {{{ */ + __attribute__((unused)) user_data_t *user_data) { char svc_description[4 * DATA_MAX_NAME_LEN]; char buffer[4096]; int code; int status; - status = format_name (svc_description, (int) sizeof (svc_description), - /* host */ "", n->plugin, n->plugin_instance, n->type, n->type_instance); - if (status != 0) - { - ERROR ("notify_nagios plugin: Formatting service name failed."); + status = format_name(svc_description, (int)sizeof(svc_description), + /* host */ "", n->plugin, n->plugin_instance, n->type, + n->type_instance); + if (status != 0) { + ERROR("notify_nagios plugin: Formatting service name failed."); return status; } - switch (n->severity) - { - case NOTIF_OKAY: - code = NAGIOS_OK; - break; - case NOTIF_WARNING: - code = NAGIOS_WARNING; - break; - case NOTIF_FAILURE: - code = NAGIOS_CRITICAL; - break; - default: - code = NAGIOS_UNKNOWN; - break; + switch (n->severity) { + case NOTIF_OKAY: + code = NAGIOS_OK; + break; + case NOTIF_WARNING: + code = NAGIOS_WARNING; + break; + case NOTIF_FAILURE: + code = NAGIOS_CRITICAL; + break; + default: + code = NAGIOS_UNKNOWN; + break; } - ssnprintf (buffer, sizeof (buffer), - "[%.0f] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n", - CDTIME_T_TO_DOUBLE (n->time), n->host, &svc_description[1], code, - n->message); + ssnprintf(buffer, sizeof(buffer), + "[%.0f] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n", + CDTIME_T_TO_DOUBLE(n->time), n->host, &svc_description[1], code, + n->message); - return nagios_print (buffer); + return nagios_print(buffer); } /* }}} int nagios_notify */ -void module_register (void) -{ - plugin_register_complex_config ("notify_nagios", nagios_config); - plugin_register_notification ("notify_nagios", nagios_notify, NULL); +void module_register(void) { + plugin_register_complex_config("notify_nagios", nagios_config); + plugin_register_notification("notify_nagios", nagios_notify, NULL); } /* void module_register (void) */ /* vim: set sw=2 sts=2 ts=8 et : */ diff --git a/src/ntpd.c b/src/ntpd.c index 7f6f982a..1dc1857b 100644 --- a/src/ntpd.c +++ b/src/ntpd.c @@ -33,36 +33,31 @@ #include "plugin.h" #if HAVE_STDINT_H -# include +#include #endif #if HAVE_NETDB_H -# include +#include #endif #if HAVE_NETINET_IN_H -# include +#include #endif #if HAVE_ARPA_INET_H -# include /* inet_ntoa */ +#include /* inet_ntoa */ #endif #if HAVE_NETINET_TCP_H -# include +#include #endif #if HAVE_POLL_H -# include +#include #endif #ifndef STA_NANO -# define STA_NANO 0x2000 +#define STA_NANO 0x2000 #endif -static const char *config_keys[] = -{ - "Host", - "Port", - "ReverseLookups", - "IncludeUnitID" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"Host", "Port", "ReverseLookups", + "IncludeUnitID"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static _Bool do_reverse_lookups = 1; @@ -71,19 +66,19 @@ static _Bool do_reverse_lookups = 1; * simultaneous measurements from both to the same type instance. */ static _Bool include_unit_id = 0; -# define NTPD_DEFAULT_HOST "localhost" -# define NTPD_DEFAULT_PORT "123" -static int sock_descr = -1; +#define NTPD_DEFAULT_HOST "localhost" +#define NTPD_DEFAULT_PORT "123" +static int sock_descr = -1; static char *ntpd_host = NULL; -static char ntpd_port[16]; +static char ntpd_port[16]; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * The following definitions were copied from the NTPd distribution * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #define MAXFILENAME 128 -#define MAXSEQ 127 +#define MAXSEQ 127 #define MODE_PRIVATE 7 -#define NTP_OLDVERSION ((uint8_t) 1) /* oldest credible version */ +#define NTP_OLDVERSION ((uint8_t)1) /* oldest credible version */ #define IMPL_XNTPD 3 #define FP_FRAC 65536.0 @@ -92,16 +87,15 @@ static char ntpd_port[16]; /* This structure is missing the message authentication code, since collectd * doesn't use it. */ -struct req_pkt -{ - uint8_t rm_vn_mode; - uint8_t auth_seq; - uint8_t implementation; /* implementation number */ - uint8_t request; /* request number */ - uint16_t err_nitems; /* error code/number of data items */ - uint16_t mbz_itemsize; /* item size */ - char data[MAXFILENAME + 48]; /* data area [32 prev](176 byte max) */ - /* struct conf_peer must fit */ +struct req_pkt { + uint8_t rm_vn_mode; + uint8_t auth_seq; + uint8_t implementation; /* implementation number */ + uint8_t request; /* request number */ + uint16_t err_nitems; /* error code/number of data items */ + uint16_t mbz_itemsize; /* item size */ + char data[MAXFILENAME + 48]; /* data area [32 prev](176 byte max) */ + /* struct conf_peer must fit */ }; #define REQ_LEN_NOMAC (sizeof(struct req_pkt)) @@ -110,638 +104,582 @@ struct req_pkt * maximally sized one. Note that this implementation doesn't * authenticate responses. */ -#define RESP_HEADER_SIZE (8) -#define RESP_DATA_SIZE (500) - -struct resp_pkt -{ - uint8_t rm_vn_mode; /* response, more, version, mode */ - uint8_t auth_seq; /* key, sequence number */ - uint8_t implementation; /* implementation number */ - uint8_t request; /* request number */ - uint16_t err_nitems; /* error code/number of data items */ - uint16_t mbz_itemsize; /* item size */ - char data[RESP_DATA_SIZE]; /* data area */ +#define RESP_HEADER_SIZE (8) +#define RESP_DATA_SIZE (500) + +struct resp_pkt { + uint8_t rm_vn_mode; /* response, more, version, mode */ + uint8_t auth_seq; /* key, sequence number */ + uint8_t implementation; /* implementation number */ + uint8_t request; /* request number */ + uint16_t err_nitems; /* error code/number of data items */ + uint16_t mbz_itemsize; /* item size */ + char data[RESP_DATA_SIZE]; /* data area */ }; /* * Bit setting macros for multifield items. */ -#define RESP_BIT 0x80 -#define MORE_BIT 0x40 - -#define ISRESPONSE(rm_vn_mode) (((rm_vn_mode)&RESP_BIT)!=0) -#define ISMORE(rm_vn_mode) (((rm_vn_mode)&MORE_BIT)!=0) -#define INFO_VERSION(rm_vn_mode) ((uint8_t)(((rm_vn_mode)>>3)&0x7)) -#define INFO_MODE(rm_vn_mode) ((rm_vn_mode)&0x7) - -#define RM_VN_MODE(resp, more, version) \ - ((uint8_t)(((resp)?RESP_BIT:0)\ - |((more)?MORE_BIT:0)\ - |((version?version:(NTP_OLDVERSION+1))<<3)\ - |(MODE_PRIVATE))) - -#define INFO_IS_AUTH(auth_seq) (((auth_seq) & 0x80) != 0) -#define INFO_SEQ(auth_seq) ((auth_seq)&0x7f) -#define AUTH_SEQ(auth, seq) ((uint8_t)((((auth)!=0)?0x80:0)|((seq)&0x7f))) - -#define INFO_ERR(err_nitems) ((uint16_t)((ntohs(err_nitems)>>12)&0xf)) -#define INFO_NITEMS(err_nitems) ((uint16_t)(ntohs(err_nitems)&0xfff)) -#define ERR_NITEMS(err, nitems) (htons((uint16_t)((((uint16_t)(err)<<12)&0xf000)\ - |((uint16_t)(nitems)&0xfff)))) - -#define INFO_MBZ(mbz_itemsize) ((ntohs(mbz_itemsize)>>12)&0xf) -#define INFO_ITEMSIZE(mbz_itemsize) ((uint16_t)(ntohs(mbz_itemsize)&0xfff)) -#define MBZ_ITEMSIZE(itemsize) (htons((uint16_t)(itemsize))) +#define RESP_BIT 0x80 +#define MORE_BIT 0x40 + +#define ISRESPONSE(rm_vn_mode) (((rm_vn_mode)&RESP_BIT) != 0) +#define ISMORE(rm_vn_mode) (((rm_vn_mode)&MORE_BIT) != 0) +#define INFO_VERSION(rm_vn_mode) ((uint8_t)(((rm_vn_mode) >> 3) & 0x7)) +#define INFO_MODE(rm_vn_mode) ((rm_vn_mode)&0x7) + +#define RM_VN_MODE(resp, more, version) \ + ((uint8_t)(((resp) ? RESP_BIT : 0) | ((more) ? MORE_BIT : 0) | \ + ((version ? version : (NTP_OLDVERSION + 1)) << 3) | \ + (MODE_PRIVATE))) + +#define INFO_IS_AUTH(auth_seq) (((auth_seq)&0x80) != 0) +#define INFO_SEQ(auth_seq) ((auth_seq)&0x7f) +#define AUTH_SEQ(auth, seq) \ + ((uint8_t)((((auth) != 0) ? 0x80 : 0) | ((seq)&0x7f))) + +#define INFO_ERR(err_nitems) ((uint16_t)((ntohs(err_nitems) >> 12) & 0xf)) +#define INFO_NITEMS(err_nitems) ((uint16_t)(ntohs(err_nitems) & 0xfff)) +#define ERR_NITEMS(err, nitems) \ + (htons((uint16_t)((((uint16_t)(err) << 12) & 0xf000) | \ + ((uint16_t)(nitems)&0xfff)))) + +#define INFO_MBZ(mbz_itemsize) ((ntohs(mbz_itemsize) >> 12) & 0xf) +#define INFO_ITEMSIZE(mbz_itemsize) ((uint16_t)(ntohs(mbz_itemsize) & 0xfff)) +#define MBZ_ITEMSIZE(itemsize) (htons((uint16_t)(itemsize))) /* negate a long float type */ -#define M_NEG(v_i, v_f) \ - do { \ - if ((v_f) == 0) \ - (v_i) = -((uint32_t)(v_i)); \ - else { \ - (v_f) = -((uint32_t)(v_f)); \ - (v_i) = ~(v_i); \ - } \ - } while(0) +#define M_NEG(v_i, v_f) \ + do { \ + if ((v_f) == 0) \ + (v_i) = -((uint32_t)(v_i)); \ + else { \ + (v_f) = -((uint32_t)(v_f)); \ + (v_i) = ~(v_i); \ + } \ + } while (0) /* l_fp to double */ -#define M_LFPTOD(r_i, r_uf, d) \ - do { \ - register int32_t ri; \ - register uint32_t rf; \ - \ - ri = (r_i); \ - rf = (r_uf); \ - if (ri < 0) { \ - M_NEG(ri, rf); \ - (d) = -((double) ri + ((double) rf) / 4294967296.0); \ - } else { \ - (d) = (double) ri + ((double) rf) / 4294967296.0; \ - } \ - } while (0) +#define M_LFPTOD(r_i, r_uf, d) \ + do { \ + register int32_t ri; \ + register uint32_t rf; \ + \ + ri = (r_i); \ + rf = (r_uf); \ + if (ri < 0) { \ + M_NEG(ri, rf); \ + (d) = -((double)ri + ((double)rf) / 4294967296.0); \ + } else { \ + (d) = (double)ri + ((double)rf) / 4294967296.0; \ + } \ + } while (0) #define REQ_PEER_LIST_SUM 1 -struct info_peer_summary -{ - uint32_t dstadr; /* local address (zero for undetermined) */ - uint32_t srcadr; /* source address */ - uint16_t srcport; /* source port */ - uint8_t stratum; /* stratum of peer */ - int8_t hpoll; /* host polling interval */ - int8_t ppoll; /* peer polling interval */ - uint8_t reach; /* reachability register */ - uint8_t flags; /* flags, from above */ - uint8_t hmode; /* peer mode */ - int32_t delay; /* peer.estdelay; s_fp */ - int32_t offset_int; /* peer.estoffset; integral part */ - int32_t offset_frc; /* peer.estoffset; fractional part */ - uint32_t dispersion; /* peer.estdisp; u_fp */ - uint32_t v6_flag; /* is this v6 or not */ - uint32_t unused1; /* (unused) padding for dstadr6 */ - struct in6_addr dstadr6; /* local address (v6) */ - struct in6_addr srcadr6; /* source address (v6) */ +struct info_peer_summary { + uint32_t dstadr; /* local address (zero for undetermined) */ + uint32_t srcadr; /* source address */ + uint16_t srcport; /* source port */ + uint8_t stratum; /* stratum of peer */ + int8_t hpoll; /* host polling interval */ + int8_t ppoll; /* peer polling interval */ + uint8_t reach; /* reachability register */ + uint8_t flags; /* flags, from above */ + uint8_t hmode; /* peer mode */ + int32_t delay; /* peer.estdelay; s_fp */ + int32_t offset_int; /* peer.estoffset; integral part */ + int32_t offset_frc; /* peer.estoffset; fractional part */ + uint32_t dispersion; /* peer.estdisp; u_fp */ + uint32_t v6_flag; /* is this v6 or not */ + uint32_t unused1; /* (unused) padding for dstadr6 */ + struct in6_addr dstadr6; /* local address (v6) */ + struct in6_addr srcadr6; /* source address (v6) */ }; #define REQ_SYS_INFO 4 -struct info_sys -{ - uint32_t peer; /* system peer address (v4) */ - uint8_t peer_mode; /* mode we are syncing to peer in */ - uint8_t leap; /* system leap bits */ - uint8_t stratum; /* our stratum */ - int8_t precision; /* local clock precision */ - int32_t rootdelay; /* distance from sync source */ - uint32_t rootdispersion; /* dispersion from sync source */ - uint32_t refid; /* reference ID of sync source */ - uint64_t reftime; /* system reference time */ - uint32_t poll; /* system poll interval */ - uint8_t flags; /* system flags */ - uint8_t unused1; /* unused */ - uint8_t unused2; /* unused */ - uint8_t unused3; /* unused */ - int32_t bdelay; /* default broadcast offset */ - int32_t frequency; /* frequency residual (scaled ppm) */ - uint64_t authdelay; /* default authentication delay */ - uint32_t stability; /* clock stability (scaled ppm) */ - int32_t v6_flag; /* is this v6 or not */ - int32_t unused4; /* unused, padding for peer6 */ - struct in6_addr peer6; /* system peer address (v6) */ +struct info_sys { + uint32_t peer; /* system peer address (v4) */ + uint8_t peer_mode; /* mode we are syncing to peer in */ + uint8_t leap; /* system leap bits */ + uint8_t stratum; /* our stratum */ + int8_t precision; /* local clock precision */ + int32_t rootdelay; /* distance from sync source */ + uint32_t rootdispersion; /* dispersion from sync source */ + uint32_t refid; /* reference ID of sync source */ + uint64_t reftime; /* system reference time */ + uint32_t poll; /* system poll interval */ + uint8_t flags; /* system flags */ + uint8_t unused1; /* unused */ + uint8_t unused2; /* unused */ + uint8_t unused3; /* unused */ + int32_t bdelay; /* default broadcast offset */ + int32_t frequency; /* frequency residual (scaled ppm) */ + uint64_t authdelay; /* default authentication delay */ + uint32_t stability; /* clock stability (scaled ppm) */ + int32_t v6_flag; /* is this v6 or not */ + int32_t unused4; /* unused, padding for peer6 */ + struct in6_addr peer6; /* system peer address (v6) */ }; #define REQ_GET_KERNEL 38 -struct info_kernel -{ - int32_t offset; - int32_t freq; - int32_t maxerror; - int32_t esterror; - uint16_t status; - uint16_t shift; - int32_t constant; - int32_t precision; - int32_t tolerance; - /* pps stuff */ - int32_t ppsfreq; - int32_t jitter; - int32_t stabil; - int32_t jitcnt; - int32_t calcnt; - int32_t errcnt; - int32_t stbcnt; +struct info_kernel { + int32_t offset; + int32_t freq; + int32_t maxerror; + int32_t esterror; + uint16_t status; + uint16_t shift; + int32_t constant; + int32_t precision; + int32_t tolerance; + /* pps stuff */ + int32_t ppsfreq; + int32_t jitter; + int32_t stabil; + int32_t jitcnt; + int32_t calcnt; + int32_t errcnt; + int32_t stbcnt; }; /* List of reference clock names */ -static const char *refclock_names[] = -{ - "UNKNOWN", "LOCAL", "GPS_TRAK", "WWV_PST", /* 0- 3 */ - "SPECTRACOM", "TRUETIME", "IRIG_AUDIO", "CHU_AUDIO", /* 4- 7 */ - "GENERIC", "GPS_MX4200", "GPS_AS2201", "GPS_ARBITER", /* 8-11 */ - "IRIG_TPRO", "ATOM_LEITCH", "MSF_EES", "GPSTM_TRUE", /* 12-15 */ - "GPS_BANC", "GPS_DATUM", "ACTS_NIST", "WWV_HEATH", /* 16-19 */ - "GPS_NMEA", "GPS_VME", "PPS", "ACTS_PTB", /* 20-23 */ - "ACTS_USNO", "TRUETIME", "GPS_HP", "MSF_ARCRON", /* 24-27 */ - "SHM", "GPS_PALISADE", "GPS_ONCORE", "GPS_JUPITER", /* 28-31 */ - "CHRONOLOG", "DUMBCLOCK", "ULINK_M320", "PCF", /* 32-35 */ - "WWV_AUDIO", "GPS_FG", "HOPF_S", "HOPF_P", /* 36-39 */ - "JJY", "TT_IRIG", "GPS_ZYFER", "GPS_RIPENCC", /* 40-43 */ - "NEOCLK4X" /* 44 */ +static const char *refclock_names[] = { + "UNKNOWN", "LOCAL", "GPS_TRAK", "WWV_PST", /* 0- 3 */ + "SPECTRACOM", "TRUETIME", "IRIG_AUDIO", "CHU_AUDIO", /* 4- 7 */ + "GENERIC", "GPS_MX4200", "GPS_AS2201", "GPS_ARBITER", /* 8-11 */ + "IRIG_TPRO", "ATOM_LEITCH", "MSF_EES", "GPSTM_TRUE", /* 12-15 */ + "GPS_BANC", "GPS_DATUM", "ACTS_NIST", "WWV_HEATH", /* 16-19 */ + "GPS_NMEA", "GPS_VME", "PPS", "ACTS_PTB", /* 20-23 */ + "ACTS_USNO", "TRUETIME", "GPS_HP", "MSF_ARCRON", /* 24-27 */ + "SHM", "GPS_PALISADE", "GPS_ONCORE", "GPS_JUPITER", /* 28-31 */ + "CHRONOLOG", "DUMBCLOCK", "ULINK_M320", "PCF", /* 32-35 */ + "WWV_AUDIO", "GPS_FG", "HOPF_S", "HOPF_P", /* 36-39 */ + "JJY", "TT_IRIG", "GPS_ZYFER", "GPS_RIPENCC", /* 40-43 */ + "NEOCLK4X" /* 44 */ }; -static size_t refclock_names_num = STATIC_ARRAY_SIZE (refclock_names); +static size_t refclock_names_num = STATIC_ARRAY_SIZE(refclock_names); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * End of the copied stuff.. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -static int ntpd_config (const char *key, const char *value) -{ - if (strcasecmp (key, "Host") == 0) - { - if (ntpd_host != NULL) - free (ntpd_host); - if ((ntpd_host = strdup (value)) == NULL) - return (1); - } - else if (strcasecmp (key, "Port") == 0) - { - int port = (int) (atof (value)); - if ((port > 0) && (port <= 65535)) - ssnprintf (ntpd_port, sizeof (ntpd_port), - "%i", port); - else - sstrncpy (ntpd_port, value, sizeof (ntpd_port)); - } - else if (strcasecmp (key, "ReverseLookups") == 0) - { - if (IS_TRUE (value)) - do_reverse_lookups = 1; - else - do_reverse_lookups = 0; - } - else if (strcasecmp (key, "IncludeUnitID") == 0) - { - if (IS_TRUE (value)) - include_unit_id = 1; - else - include_unit_id = 0; - } - else - { - return (-1); - } - - return (0); +static int ntpd_config(const char *key, const char *value) { + if (strcasecmp(key, "Host") == 0) { + if (ntpd_host != NULL) + free(ntpd_host); + if ((ntpd_host = strdup(value)) == NULL) + return (1); + } else if (strcasecmp(key, "Port") == 0) { + int port = (int)(atof(value)); + if ((port > 0) && (port <= 65535)) + ssnprintf(ntpd_port, sizeof(ntpd_port), "%i", port); + else + sstrncpy(ntpd_port, value, sizeof(ntpd_port)); + } else if (strcasecmp(key, "ReverseLookups") == 0) { + if (IS_TRUE(value)) + do_reverse_lookups = 1; + else + do_reverse_lookups = 0; + } else if (strcasecmp(key, "IncludeUnitID") == 0) { + if (IS_TRUE(value)) + include_unit_id = 1; + else + include_unit_id = 0; + } else { + return (-1); + } + + return (0); } -static void ntpd_submit (const char *type, const char *type_inst, gauge_t value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void ntpd_submit(const char *type, const char *type_inst, + gauge_t value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "ntpd", sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance)); + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "ntpd", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, type_inst, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* Each time a peer is polled, ntpd shifts the reach register to the left and * sets the LSB based on whether the peer was reachable. If the LSB is zero, * the values are out of date. */ -static void ntpd_submit_reach (const char *type, const char *type_inst, - uint8_t reach, gauge_t value) -{ - if (!(reach & 1)) - value = NAN; +static void ntpd_submit_reach(const char *type, const char *type_inst, + uint8_t reach, gauge_t value) { + if (!(reach & 1)) + value = NAN; - ntpd_submit (type, type_inst, value); + ntpd_submit(type, type_inst, value); } -static int ntpd_connect (void) -{ - const char *host; - const char *port; - - struct addrinfo *ai_list; - int status; - - if (sock_descr >= 0) - return (sock_descr); - - DEBUG ("Opening a new socket"); - - host = ntpd_host; - if (host == NULL) - host = NTPD_DEFAULT_HOST; - - port = ntpd_port; - if (strlen (port) == 0) - port = NTPD_DEFAULT_PORT; - - struct addrinfo ai_hints = { - .ai_family = AF_UNSPEC, - .ai_flags = AI_ADDRCONFIG, - .ai_protocol = IPPROTO_UDP, - .ai_socktype = SOCK_DGRAM - }; - - if ((status = getaddrinfo (host, port, &ai_hints, &ai_list)) != 0) - { - char errbuf[1024]; - ERROR ("ntpd plugin: getaddrinfo (%s, %s): %s", - host, port, - (status == EAI_SYSTEM) - ? sstrerror (errno, errbuf, sizeof (errbuf)) - : gai_strerror (status)); - return (-1); - } - - for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) - { - /* create our socket descriptor */ - if ((sock_descr = socket (ai_ptr->ai_family, - ai_ptr->ai_socktype, - ai_ptr->ai_protocol)) < 0) - continue; - - /* connect to the ntpd */ - if (connect (sock_descr, ai_ptr->ai_addr, ai_ptr->ai_addrlen)) - { - close (sock_descr); - sock_descr = -1; - continue; - } - - break; - } - - freeaddrinfo (ai_list); - - if (sock_descr < 0) - { - ERROR ("ntpd plugin: Unable to connect to server."); - } - - return (sock_descr); +static int ntpd_connect(void) { + const char *host; + const char *port; + + struct addrinfo *ai_list; + int status; + + if (sock_descr >= 0) + return (sock_descr); + + DEBUG("Opening a new socket"); + + host = ntpd_host; + if (host == NULL) + host = NTPD_DEFAULT_HOST; + + port = ntpd_port; + if (strlen(port) == 0) + port = NTPD_DEFAULT_PORT; + + struct addrinfo ai_hints = {.ai_family = AF_UNSPEC, + .ai_flags = AI_ADDRCONFIG, + .ai_protocol = IPPROTO_UDP, + .ai_socktype = SOCK_DGRAM}; + + if ((status = getaddrinfo(host, port, &ai_hints, &ai_list)) != 0) { + char errbuf[1024]; + ERROR("ntpd plugin: getaddrinfo (%s, %s): %s", host, port, + (status == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf)) + : gai_strerror(status)); + return (-1); + } + + for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; + ai_ptr = ai_ptr->ai_next) { + /* create our socket descriptor */ + if ((sock_descr = socket(ai_ptr->ai_family, ai_ptr->ai_socktype, + ai_ptr->ai_protocol)) < 0) + continue; + + /* connect to the ntpd */ + if (connect(sock_descr, ai_ptr->ai_addr, ai_ptr->ai_addrlen)) { + close(sock_descr); + sock_descr = -1; + continue; + } + + break; + } + + freeaddrinfo(ai_list); + + if (sock_descr < 0) { + ERROR("ntpd plugin: Unable to connect to server."); + } + + return (sock_descr); } /* For a description of the arguments see `ntpd_do_query' below. */ -static int ntpd_receive_response (int *res_items, int *res_size, - char **res_data, int res_item_size) -{ - int sd; - struct pollfd poll_s; - struct resp_pkt res; - int status; - int done; - - char *items; - size_t items_num; - - struct timeval time_end; - struct timeval time_now; - int timeout; - - int pkt_item_num; /* items in this packet */ - int pkt_item_len; /* size of the items in this packet */ - int pkt_sequence; - char pkt_recvd[MAXSEQ+1] = { 0 }; /* sequence numbers that have been received */ - int pkt_recvd_num; /* number of packets that have been received */ - int pkt_lastseq; /* the last sequence number */ - ssize_t pkt_padding; /* Padding in this packet */ - - if ((sd = ntpd_connect ()) < 0) - return (-1); - - items = NULL; - items_num = 0; - - pkt_recvd_num = 0; - pkt_lastseq = -1; - - *res_items = 0; - *res_size = 0; - *res_data = NULL; - - if (gettimeofday (&time_end, NULL) < 0) - { - char errbuf[1024]; - ERROR ("ntpd plugin: gettimeofday failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - time_end.tv_sec++; /* wait for a most one second */ - - done = 0; - while (done == 0) - { - struct timeval time_left; - - if (gettimeofday (&time_now, NULL) < 0) - { - char errbuf[1024]; - ERROR ("ntpd plugin: gettimeofday failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - if (timeval_cmp (time_end, time_now, &time_left) <= 0) - timeout = 0; - else - timeout = 1000 * time_left.tv_sec - + ((time_left.tv_usec + 500) / 1000); - - /* timeout reached */ - if (timeout <= 0) - break; - - poll_s.fd = sd; - poll_s.events = POLLIN | POLLPRI; - poll_s.revents = 0; - - DEBUG ("Polling for %ims", timeout); - status = poll (&poll_s, 1, timeout); - - if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) - continue; - - if (status < 0) - { - char errbuf[1024]; - ERROR ("ntpd plugin: poll failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - if (status == 0) /* timeout */ - { - DEBUG ("timeout reached."); - break; - } - - memset (&res, '\0', sizeof (res)); - status = recv (sd, (void *) &res, sizeof (res), 0 /* no flags */); - - if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) - continue; - - if (status < 0) - { - char errbuf[1024]; - INFO ("recv(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - DEBUG ("Closing socket #%i", sd); - close (sd); - sock_descr = sd = -1; - return (-1); - } - - DEBUG ("recv'd %i bytes", status); - - /* - * Do some sanity checks first - */ - if (status < RESP_HEADER_SIZE) - { - WARNING ("ntpd plugin: Short (%i bytes) packet received", - (int) status); - continue; - } - if (INFO_MODE (res.rm_vn_mode) != MODE_PRIVATE) - { - NOTICE ("ntpd plugin: Packet received with mode %i", - INFO_MODE (res.rm_vn_mode)); - continue; - } - if (INFO_IS_AUTH (res.auth_seq)) - { - NOTICE ("ntpd plugin: Encrypted packet received"); - continue; - } - if (!ISRESPONSE (res.rm_vn_mode)) - { - NOTICE ("ntpd plugin: Received request packet, " - "wanted response"); - continue; - } - if (INFO_MBZ (res.mbz_itemsize)) - { - WARNING ("ntpd plugin: Received packet with nonzero " - "MBZ field!"); - continue; - } - if (res.implementation != IMPL_XNTPD) - { - WARNING ("ntpd plugin: Asked for request of type %i, " - "got %i", (int) IMPL_XNTPD, (int) res.implementation); - continue; - } - - /* Check for error code */ - if (INFO_ERR (res.err_nitems) != 0) - { - ERROR ("ntpd plugin: Received error code %i", - (int) INFO_ERR(res.err_nitems)); - return ((int) INFO_ERR (res.err_nitems)); - } - - /* extract number of items in this packet and the size of these items */ - pkt_item_num = INFO_NITEMS (res.err_nitems); - pkt_item_len = INFO_ITEMSIZE (res.mbz_itemsize); - DEBUG ("pkt_item_num = %i; pkt_item_len = %i;", - pkt_item_num, pkt_item_len); - - /* Check if the reported items fit in the packet */ - if ((pkt_item_num * pkt_item_len) > (status - RESP_HEADER_SIZE)) - { - ERROR ("ntpd plugin: %i items * %i bytes > " - "%i bytes - %i bytes header", - (int) pkt_item_num, (int) pkt_item_len, - (int) status, (int) RESP_HEADER_SIZE); - continue; - } - - if (pkt_item_len > res_item_size) - { - ERROR ("ntpd plugin: (pkt_item_len = %i) " - ">= (res_item_size = %i)", - pkt_item_len, res_item_size); - continue; - } - - /* If this is the first packet (time wise, not sequence wise), - * set `res_size'. If it's not the first packet check if the - * items have the same size. Discard invalid packets. */ - if (items_num == 0) /* first packet */ - { - DEBUG ("*res_size = %i", pkt_item_len); - *res_size = pkt_item_len; - } - else if (*res_size != pkt_item_len) - { - DEBUG ("Error: *res_size = %i; pkt_item_len = %i;", - *res_size, pkt_item_len); - ERROR ("Item sizes differ."); - continue; - } - - /* - * Because the items in the packet may be smaller than the - * items requested, the following holds true: - */ - assert ((*res_size == pkt_item_len) - && (pkt_item_len <= res_item_size)); - - /* Calculate the padding. No idea why there might be any padding.. */ - pkt_padding = 0; - if (pkt_item_len < res_item_size) - pkt_padding = res_item_size - pkt_item_len; - DEBUG ("res_item_size = %i; pkt_padding = %zi;", - res_item_size, pkt_padding); - - /* Extract the sequence number */ - pkt_sequence = INFO_SEQ (res.auth_seq); - if ((pkt_sequence < 0) || (pkt_sequence > MAXSEQ)) - { - ERROR ("ntpd plugin: Received packet with sequence %i", - pkt_sequence); - continue; - } - - /* Check if this sequence has been received before. If so, discard it. */ - if (pkt_recvd[pkt_sequence] != '\0') - { - NOTICE ("ntpd plugin: Sequence %i received twice", - pkt_sequence); - continue; - } - - /* If `pkt_lastseq != -1' another packet without `more bit' has - * been received. */ - if (!ISMORE (res.rm_vn_mode)) - { - if (pkt_lastseq != -1) - { - ERROR ("ntpd plugin: Two packets which both " - "claim to be the last one in the " - "sequence have been received."); - continue; - } - pkt_lastseq = pkt_sequence; - DEBUG ("Last sequence = %i;", pkt_lastseq); - } - - /* - * Enough with the checks. Copy the data now. - * We start by allocating some more memory. - */ - DEBUG ("realloc (%p, %zu)", (void *) *res_data, - (items_num + pkt_item_num) * res_item_size); - items = realloc (*res_data, - (items_num + pkt_item_num) * res_item_size); - if (items == NULL) - { - ERROR ("ntpd plugin: realloc failed."); - continue; - } - items_num += pkt_item_num; - *res_data = items; - - for (int i = 0; i < pkt_item_num; i++) - { - /* dst: There are already `*res_items' items with - * res_item_size bytes each in in `*res_data'. Set - * dst to the first byte after that. */ - void *dst = (void *) (*res_data + ((*res_items) * res_item_size)); - /* src: We use `pkt_item_len' to calculate the offset - * from the beginning of the packet, because the - * items in the packet may be smaller than the - * items that were requested. We skip `i' such - * items. */ - void *src = (void *) (((char *) res.data) + (i * pkt_item_len)); - - /* Set the padding to zeros */ - if (pkt_padding != 0) - memset (dst, '\0', res_item_size); - memcpy (dst, src, (size_t) pkt_item_len); - - /* Increment `*res_items' by one, so `dst' will end up - * one further in the next round. */ - (*res_items)++; - } /* for (pkt_item_num) */ - - pkt_recvd[pkt_sequence] = (char) 1; - pkt_recvd_num++; - - if ((pkt_recvd_num - 1) == pkt_lastseq) - done = 1; - } /* while (done == 0) */ - - return (0); +static int ntpd_receive_response(int *res_items, int *res_size, char **res_data, + int res_item_size) { + int sd; + struct pollfd poll_s; + struct resp_pkt res; + int status; + int done; + + char *items; + size_t items_num; + + struct timeval time_end; + struct timeval time_now; + int timeout; + + int pkt_item_num; /* items in this packet */ + int pkt_item_len; /* size of the items in this packet */ + int pkt_sequence; + char pkt_recvd[MAXSEQ + 1] = { + 0}; /* sequence numbers that have been received */ + int pkt_recvd_num; /* number of packets that have been received */ + int pkt_lastseq; /* the last sequence number */ + ssize_t pkt_padding; /* Padding in this packet */ + + if ((sd = ntpd_connect()) < 0) + return (-1); + + items = NULL; + items_num = 0; + + pkt_recvd_num = 0; + pkt_lastseq = -1; + + *res_items = 0; + *res_size = 0; + *res_data = NULL; + + if (gettimeofday(&time_end, NULL) < 0) { + char errbuf[1024]; + ERROR("ntpd plugin: gettimeofday failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + time_end.tv_sec++; /* wait for a most one second */ + + done = 0; + while (done == 0) { + struct timeval time_left; + + if (gettimeofday(&time_now, NULL) < 0) { + char errbuf[1024]; + ERROR("ntpd plugin: gettimeofday failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + if (timeval_cmp(time_end, time_now, &time_left) <= 0) + timeout = 0; + else + timeout = 1000 * time_left.tv_sec + ((time_left.tv_usec + 500) / 1000); + + /* timeout reached */ + if (timeout <= 0) + break; + + poll_s.fd = sd; + poll_s.events = POLLIN | POLLPRI; + poll_s.revents = 0; + + DEBUG("Polling for %ims", timeout); + status = poll(&poll_s, 1, timeout); + + if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) + continue; + + if (status < 0) { + char errbuf[1024]; + ERROR("ntpd plugin: poll failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + if (status == 0) /* timeout */ + { + DEBUG("timeout reached."); + break; + } + + memset(&res, '\0', sizeof(res)); + status = recv(sd, (void *)&res, sizeof(res), 0 /* no flags */); + + if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) + continue; + + if (status < 0) { + char errbuf[1024]; + INFO("recv(2) failed: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + DEBUG("Closing socket #%i", sd); + close(sd); + sock_descr = sd = -1; + return (-1); + } + + DEBUG("recv'd %i bytes", status); + + /* + * Do some sanity checks first + */ + if (status < RESP_HEADER_SIZE) { + WARNING("ntpd plugin: Short (%i bytes) packet received", (int)status); + continue; + } + if (INFO_MODE(res.rm_vn_mode) != MODE_PRIVATE) { + NOTICE("ntpd plugin: Packet received with mode %i", + INFO_MODE(res.rm_vn_mode)); + continue; + } + if (INFO_IS_AUTH(res.auth_seq)) { + NOTICE("ntpd plugin: Encrypted packet received"); + continue; + } + if (!ISRESPONSE(res.rm_vn_mode)) { + NOTICE("ntpd plugin: Received request packet, " + "wanted response"); + continue; + } + if (INFO_MBZ(res.mbz_itemsize)) { + WARNING("ntpd plugin: Received packet with nonzero " + "MBZ field!"); + continue; + } + if (res.implementation != IMPL_XNTPD) { + WARNING("ntpd plugin: Asked for request of type %i, " + "got %i", + (int)IMPL_XNTPD, (int)res.implementation); + continue; + } + + /* Check for error code */ + if (INFO_ERR(res.err_nitems) != 0) { + ERROR("ntpd plugin: Received error code %i", + (int)INFO_ERR(res.err_nitems)); + return ((int)INFO_ERR(res.err_nitems)); + } + + /* extract number of items in this packet and the size of these items */ + pkt_item_num = INFO_NITEMS(res.err_nitems); + pkt_item_len = INFO_ITEMSIZE(res.mbz_itemsize); + DEBUG("pkt_item_num = %i; pkt_item_len = %i;", pkt_item_num, pkt_item_len); + + /* Check if the reported items fit in the packet */ + if ((pkt_item_num * pkt_item_len) > (status - RESP_HEADER_SIZE)) { + ERROR("ntpd plugin: %i items * %i bytes > " + "%i bytes - %i bytes header", + (int)pkt_item_num, (int)pkt_item_len, (int)status, + (int)RESP_HEADER_SIZE); + continue; + } + + if (pkt_item_len > res_item_size) { + ERROR("ntpd plugin: (pkt_item_len = %i) " + ">= (res_item_size = %i)", + pkt_item_len, res_item_size); + continue; + } + + /* If this is the first packet (time wise, not sequence wise), + * set `res_size'. If it's not the first packet check if the + * items have the same size. Discard invalid packets. */ + if (items_num == 0) /* first packet */ + { + DEBUG("*res_size = %i", pkt_item_len); + *res_size = pkt_item_len; + } else if (*res_size != pkt_item_len) { + DEBUG("Error: *res_size = %i; pkt_item_len = %i;", *res_size, + pkt_item_len); + ERROR("Item sizes differ."); + continue; + } + + /* + * Because the items in the packet may be smaller than the + * items requested, the following holds true: + */ + assert((*res_size == pkt_item_len) && (pkt_item_len <= res_item_size)); + + /* Calculate the padding. No idea why there might be any padding.. */ + pkt_padding = 0; + if (pkt_item_len < res_item_size) + pkt_padding = res_item_size - pkt_item_len; + DEBUG("res_item_size = %i; pkt_padding = %zi;", res_item_size, pkt_padding); + + /* Extract the sequence number */ + pkt_sequence = INFO_SEQ(res.auth_seq); + if ((pkt_sequence < 0) || (pkt_sequence > MAXSEQ)) { + ERROR("ntpd plugin: Received packet with sequence %i", pkt_sequence); + continue; + } + + /* Check if this sequence has been received before. If so, discard it. */ + if (pkt_recvd[pkt_sequence] != '\0') { + NOTICE("ntpd plugin: Sequence %i received twice", pkt_sequence); + continue; + } + + /* If `pkt_lastseq != -1' another packet without `more bit' has + * been received. */ + if (!ISMORE(res.rm_vn_mode)) { + if (pkt_lastseq != -1) { + ERROR("ntpd plugin: Two packets which both " + "claim to be the last one in the " + "sequence have been received."); + continue; + } + pkt_lastseq = pkt_sequence; + DEBUG("Last sequence = %i;", pkt_lastseq); + } + + /* + * Enough with the checks. Copy the data now. + * We start by allocating some more memory. + */ + DEBUG("realloc (%p, %zu)", (void *)*res_data, + (items_num + pkt_item_num) * res_item_size); + items = realloc(*res_data, (items_num + pkt_item_num) * res_item_size); + if (items == NULL) { + ERROR("ntpd plugin: realloc failed."); + continue; + } + items_num += pkt_item_num; + *res_data = items; + + for (int i = 0; i < pkt_item_num; i++) { + /* dst: There are already `*res_items' items with + * res_item_size bytes each in in `*res_data'. Set + * dst to the first byte after that. */ + void *dst = (void *)(*res_data + ((*res_items) * res_item_size)); + /* src: We use `pkt_item_len' to calculate the offset + * from the beginning of the packet, because the + * items in the packet may be smaller than the + * items that were requested. We skip `i' such + * items. */ + void *src = (void *)(((char *)res.data) + (i * pkt_item_len)); + + /* Set the padding to zeros */ + if (pkt_padding != 0) + memset(dst, '\0', res_item_size); + memcpy(dst, src, (size_t)pkt_item_len); + + /* Increment `*res_items' by one, so `dst' will end up + * one further in the next round. */ + (*res_items)++; + } /* for (pkt_item_num) */ + + pkt_recvd[pkt_sequence] = (char)1; + pkt_recvd_num++; + + if ((pkt_recvd_num - 1) == pkt_lastseq) + done = 1; + } /* while (done == 0) */ + + return (0); } /* int ntpd_receive_response */ /* For a description of the arguments see `ntpd_do_query' below. */ -static int ntpd_send_request (int req_code, int req_items, int req_size, char *req_data) -{ - int sd; - struct req_pkt req = { 0 }; - size_t req_data_len; - int status; +static int ntpd_send_request(int req_code, int req_items, int req_size, + char *req_data) { + int sd; + struct req_pkt req = {0}; + size_t req_data_len; + int status; - assert (req_items >= 0); - assert (req_size >= 0); + assert(req_items >= 0); + assert(req_size >= 0); - if ((sd = ntpd_connect ()) < 0) - return (-1); + if ((sd = ntpd_connect()) < 0) + return (-1); - req.rm_vn_mode = RM_VN_MODE(0, 0, 0); - req.auth_seq = AUTH_SEQ (0, 0); - req.implementation = IMPL_XNTPD; - req.request = (unsigned char) req_code; + req.rm_vn_mode = RM_VN_MODE(0, 0, 0); + req.auth_seq = AUTH_SEQ(0, 0); + req.implementation = IMPL_XNTPD; + req.request = (unsigned char)req_code; - req_data_len = (size_t) (req_items * req_size); + req_data_len = (size_t)(req_items * req_size); - assert (((req_data != NULL) && (req_data_len > 0)) - || ((req_data == NULL) && (req_items == 0) && (req_size == 0))); + assert(((req_data != NULL) && (req_data_len > 0)) || + ((req_data == NULL) && (req_items == 0) && (req_size == 0))); - req.err_nitems = ERR_NITEMS (0, req_items); - req.mbz_itemsize = MBZ_ITEMSIZE (req_size); + req.err_nitems = ERR_NITEMS(0, req_items); + req.mbz_itemsize = MBZ_ITEMSIZE(req_size); - if (req_data != NULL) - memcpy ((void *) req.data, (const void *) req_data, req_data_len); + if (req_data != NULL) + memcpy((void *)req.data, (const void *)req_data, req_data_len); - DEBUG ("req_items = %i; req_size = %i; req_data = %p;", - req_items, req_size, (void *) req_data); + DEBUG("req_items = %i; req_size = %i; req_data = %p;", req_items, req_size, + (void *)req_data); - status = swrite (sd, (const char *) &req, REQ_LEN_NOMAC); - if (status < 0) - { - DEBUG ("`swrite' failed. Closing socket #%i", sd); - close (sd); - sock_descr = sd = -1; - return (status); - } + status = swrite(sd, (const char *)&req, REQ_LEN_NOMAC); + if (status < 0) { + DEBUG("`swrite' failed. Closing socket #%i", sd); + close(sd); + sock_descr = sd = -1; + return (status); + } - return (0); + return (0); } /* @@ -753,275 +691,248 @@ static int ntpd_send_request (int req_code, int req_items, int req_size, char *r * req_data: Data of the request packet * res_items: Pointer to where the number returned items will be stored. * res_size: Pointer to where the size of one returned item will be stored. - * res_data: This is where a pointer to the (allocated) data will be stored. + * res_data: This is where a pointer to the (allocated) data will be + * stored. * res_item_size: Size of one returned item. (used to calculate padding) * * returns: zero upon success, non-zero otherwise. */ -static int ntpd_do_query (int req_code, int req_items, int req_size, char *req_data, - int *res_items, int *res_size, char **res_data, int res_item_size) -{ - int status; - - status = ntpd_send_request (req_code, req_items, req_size, req_data); - if (status != 0) - return (status); - - status = ntpd_receive_response (res_items, res_size, res_data, - res_item_size); - return (status); +static int ntpd_do_query(int req_code, int req_items, int req_size, + char *req_data, int *res_items, int *res_size, + char **res_data, int res_item_size) { + int status; + + status = ntpd_send_request(req_code, req_items, req_size, req_data); + if (status != 0) + return (status); + + status = ntpd_receive_response(res_items, res_size, res_data, res_item_size); + return (status); } -static double ntpd_read_fp (int32_t val_int) -{ - double val_double; +static double ntpd_read_fp(int32_t val_int) { + double val_double; - val_int = ntohl (val_int); - val_double = ((double) val_int) / FP_FRAC; + val_int = ntohl(val_int); + val_double = ((double)val_int) / FP_FRAC; - return (val_double); + return (val_double); } -static uint32_t ntpd_get_refclock_id (struct info_peer_summary const *peer_info) -{ - uint32_t addr = ntohl (peer_info->srcadr); - uint32_t refclock_id = (addr >> 8) & 0x00FF; +static uint32_t +ntpd_get_refclock_id(struct info_peer_summary const *peer_info) { + uint32_t addr = ntohl(peer_info->srcadr); + uint32_t refclock_id = (addr >> 8) & 0x00FF; - return (refclock_id); + return (refclock_id); } -static int ntpd_get_name_from_address (char *buffer, size_t buffer_size, - struct info_peer_summary const *peer_info, _Bool do_reverse_lookup) -{ - struct sockaddr_storage sa = { 0 }; - socklen_t sa_len; - int flags = 0; - int status; - - if (peer_info->v6_flag) - { - struct sockaddr_in6 sa6 = { 0 }; - - assert (sizeof (sa) >= sizeof (sa6)); - - sa6.sin6_family = AF_INET6; - sa6.sin6_port = htons (123); - memcpy (&sa6.sin6_addr, &peer_info->srcadr6, - sizeof (struct in6_addr)); - sa_len = sizeof (sa6); - - memcpy (&sa, &sa6, sizeof (sa6)); - } - else - { - struct sockaddr_in sa4 = { 0 }; - - assert (sizeof (sa) >= sizeof (sa4)); - - sa4.sin_family = AF_INET; - sa4.sin_port = htons (123); - memcpy (&sa4.sin_addr, &peer_info->srcadr, - sizeof (struct in_addr)); - sa_len = sizeof (sa4); - - memcpy (&sa, &sa4, sizeof (sa4)); - } - - if (!do_reverse_lookup) - flags |= NI_NUMERICHOST; - - status = getnameinfo ((struct sockaddr const *) &sa, sa_len, - buffer, buffer_size, - NULL, 0, /* No port name */ - flags); - if (status != 0) - { - char errbuf[1024]; - ERROR ("ntpd plugin: getnameinfo failed: %s", - (status == EAI_SYSTEM) - ? sstrerror (errno, errbuf, sizeof (errbuf)) - : gai_strerror (status)); - return (-1); - } - - return (0); +static int ntpd_get_name_from_address(char *buffer, size_t buffer_size, + struct info_peer_summary const *peer_info, + _Bool do_reverse_lookup) { + struct sockaddr_storage sa = {0}; + socklen_t sa_len; + int flags = 0; + int status; + + if (peer_info->v6_flag) { + struct sockaddr_in6 sa6 = {0}; + + assert(sizeof(sa) >= sizeof(sa6)); + + sa6.sin6_family = AF_INET6; + sa6.sin6_port = htons(123); + memcpy(&sa6.sin6_addr, &peer_info->srcadr6, sizeof(struct in6_addr)); + sa_len = sizeof(sa6); + + memcpy(&sa, &sa6, sizeof(sa6)); + } else { + struct sockaddr_in sa4 = {0}; + + assert(sizeof(sa) >= sizeof(sa4)); + + sa4.sin_family = AF_INET; + sa4.sin_port = htons(123); + memcpy(&sa4.sin_addr, &peer_info->srcadr, sizeof(struct in_addr)); + sa_len = sizeof(sa4); + + memcpy(&sa, &sa4, sizeof(sa4)); + } + + if (!do_reverse_lookup) + flags |= NI_NUMERICHOST; + + status = getnameinfo((struct sockaddr const *)&sa, sa_len, buffer, + buffer_size, NULL, 0, /* No port name */ + flags); + if (status != 0) { + char errbuf[1024]; + ERROR("ntpd plugin: getnameinfo failed: %s", + (status == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf)) + : gai_strerror(status)); + return (-1); + } + + return (0); } /* ntpd_get_name_from_address */ -static int ntpd_get_name_refclock (char *buffer, size_t buffer_size, - struct info_peer_summary const *peer_info) -{ - uint32_t refclock_id = ntpd_get_refclock_id (peer_info); - uint32_t unit_id = ntohl (peer_info->srcadr) & 0x00FF; +static int ntpd_get_name_refclock(char *buffer, size_t buffer_size, + struct info_peer_summary const *peer_info) { + uint32_t refclock_id = ntpd_get_refclock_id(peer_info); + uint32_t unit_id = ntohl(peer_info->srcadr) & 0x00FF; - if (((size_t) refclock_id) >= refclock_names_num) - return (ntpd_get_name_from_address (buffer, buffer_size, - peer_info, - /* do_reverse_lookup = */ 0)); + if (((size_t)refclock_id) >= refclock_names_num) + return (ntpd_get_name_from_address(buffer, buffer_size, peer_info, + /* do_reverse_lookup = */ 0)); - if (include_unit_id) - ssnprintf (buffer, buffer_size, "%s-%"PRIu32, - refclock_names[refclock_id], unit_id); - else - sstrncpy (buffer, refclock_names[refclock_id], buffer_size); + if (include_unit_id) + ssnprintf(buffer, buffer_size, "%s-%" PRIu32, refclock_names[refclock_id], + unit_id); + else + sstrncpy(buffer, refclock_names[refclock_id], buffer_size); - return (0); + return (0); } /* int ntpd_get_name_refclock */ -static int ntpd_get_name (char *buffer, size_t buffer_size, - struct info_peer_summary const *peer_info) -{ - uint32_t addr = ntohl (peer_info->srcadr); - - if (!peer_info->v6_flag && ((addr & REFCLOCK_MASK) == REFCLOCK_ADDR)) - return (ntpd_get_name_refclock (buffer, buffer_size, - peer_info)); - else - return (ntpd_get_name_from_address (buffer, buffer_size, - peer_info, do_reverse_lookups)); +static int ntpd_get_name(char *buffer, size_t buffer_size, + struct info_peer_summary const *peer_info) { + uint32_t addr = ntohl(peer_info->srcadr); + + if (!peer_info->v6_flag && ((addr & REFCLOCK_MASK) == REFCLOCK_ADDR)) + return (ntpd_get_name_refclock(buffer, buffer_size, peer_info)); + else + return (ntpd_get_name_from_address(buffer, buffer_size, peer_info, + do_reverse_lookups)); } /* int ntpd_addr_to_name */ -static int ntpd_read (void) -{ - struct info_kernel *ik; - int ik_num; - int ik_size; - - struct info_peer_summary *ps; - int ps_num; - int ps_size; - - gauge_t offset_loop; - gauge_t freq_loop; - gauge_t offset_error; - - int status; - - /* On Linux, if the STA_NANO bit is set in ik->status, then ik->offset - * is is nanoseconds, otherwise it's microseconds. */ - double scale_loop = 1e-6; - double scale_error = 1e-6; - - ik = NULL; - ik_num = 0; - ik_size = 0; - - status = ntpd_do_query (REQ_GET_KERNEL, - 0, 0, NULL, /* request data */ - &ik_num, &ik_size, (char **) ((void *) &ik), /* response data */ - sizeof (struct info_kernel)); - if (status != 0) - { - ERROR ("ntpd plugin: ntpd_do_query (REQ_GET_KERNEL) failed with status %i", status); - return (status); - } - else if ((ik == NULL) || (ik_num == 0) || (ik_size == 0)) - { - ERROR ("ntpd plugin: ntpd_do_query returned unexpected data. " - "(ik = %p; ik_num = %i; ik_size = %i)", - (void *) ik, ik_num, ik_size); - return (-1); - } - - if (ntohs(ik->status) & STA_NANO) { - scale_loop = 1e-9; - scale_error = 1e-9; - } - - /* kerninfo -> estimated error */ - offset_loop = scale_loop * ((gauge_t) ntohl (ik->offset)); - freq_loop = ntpd_read_fp (ik->freq); - offset_error = scale_error * ((gauge_t) ntohl (ik->esterror)); - - DEBUG ("info_kernel:\n" - " pll offset = %.8g\n" - " pll frequency = %.8g\n" /* drift compensation */ - " est error = %.8g\n", - offset_loop, freq_loop, offset_error); - - ntpd_submit ("frequency_offset", "loop", freq_loop); - ntpd_submit ("time_offset", "loop", offset_loop); - ntpd_submit ("time_offset", "error", offset_error); - - free (ik); - ik = NULL; - - status = ntpd_do_query (REQ_PEER_LIST_SUM, - 0, 0, NULL, /* request data */ - &ps_num, &ps_size, (char **) ((void *) &ps), /* response data */ - sizeof (struct info_peer_summary)); - if (status != 0) - { - ERROR ("ntpd plugin: ntpd_do_query (REQ_PEER_LIST_SUM) failed with status %i", status); - return (status); - } - else if ((ps == NULL) || (ps_num == 0) || (ps_size == 0)) - { - ERROR ("ntpd plugin: ntpd_do_query returned unexpected data. " - "(ps = %p; ps_num = %i; ps_size = %i)", - (void *) ps, ps_num, ps_size); - return (-1); - } - - for (int i = 0; i < ps_num; i++) - { - struct info_peer_summary *ptr; - double offset; - - char peername[NI_MAXHOST]; - uint32_t refclock_id; - - ptr = ps + i; - - status = ntpd_get_name (peername, sizeof (peername), ptr); - if (status != 0) - { - ERROR ("ntpd plugin: Determining name of peer failed."); - continue; - } - - refclock_id = ntpd_get_refclock_id (ptr); - - /* Convert the `long floating point' offset value to double */ - M_LFPTOD (ntohl (ptr->offset_int), ntohl (ptr->offset_frc), offset); - - DEBUG ("peer %i:\n" - " peername = %s\n" - " srcadr = 0x%08x\n" - " reach = 0%03o\n" - " delay = %f\n" - " offset_int = %i\n" - " offset_frc = %i\n" - " offset = %f\n" - " dispersion = %f\n", - i, - peername, - ntohl (ptr->srcadr), - ptr->reach, - ntpd_read_fp (ptr->delay), - ntohl (ptr->offset_int), - ntohl (ptr->offset_frc), - offset, - ntpd_read_fp (ptr->dispersion)); - - if (refclock_id != 1) /* not the system clock (offset will always be zero.. */ - ntpd_submit_reach ("time_offset", peername, ptr->reach, - offset); - ntpd_submit_reach ("time_dispersion", peername, ptr->reach, - ntpd_read_fp (ptr->dispersion)); - if (refclock_id == 0) /* not a reference clock */ - ntpd_submit_reach ("delay", peername, ptr->reach, - ntpd_read_fp (ptr->delay)); - } - - free (ps); - ps = NULL; - - return (0); +static int ntpd_read(void) { + struct info_kernel *ik; + int ik_num; + int ik_size; + + struct info_peer_summary *ps; + int ps_num; + int ps_size; + + gauge_t offset_loop; + gauge_t freq_loop; + gauge_t offset_error; + + int status; + + /* On Linux, if the STA_NANO bit is set in ik->status, then ik->offset + * is is nanoseconds, otherwise it's microseconds. */ + double scale_loop = 1e-6; + double scale_error = 1e-6; + + ik = NULL; + ik_num = 0; + ik_size = 0; + + status = ntpd_do_query(REQ_GET_KERNEL, 0, 0, NULL, /* request data */ + &ik_num, &ik_size, + (char **)((void *)&ik), /* response data */ + sizeof(struct info_kernel)); + if (status != 0) { + ERROR("ntpd plugin: ntpd_do_query (REQ_GET_KERNEL) failed with status %i", + status); + return (status); + } else if ((ik == NULL) || (ik_num == 0) || (ik_size == 0)) { + ERROR("ntpd plugin: ntpd_do_query returned unexpected data. " + "(ik = %p; ik_num = %i; ik_size = %i)", + (void *)ik, ik_num, ik_size); + return (-1); + } + + if (ntohs(ik->status) & STA_NANO) { + scale_loop = 1e-9; + scale_error = 1e-9; + } + + /* kerninfo -> estimated error */ + offset_loop = scale_loop * ((gauge_t)ntohl(ik->offset)); + freq_loop = ntpd_read_fp(ik->freq); + offset_error = scale_error * ((gauge_t)ntohl(ik->esterror)); + + DEBUG("info_kernel:\n" + " pll offset = %.8g\n" + " pll frequency = %.8g\n" /* drift compensation */ + " est error = %.8g\n", + offset_loop, freq_loop, offset_error); + + ntpd_submit("frequency_offset", "loop", freq_loop); + ntpd_submit("time_offset", "loop", offset_loop); + ntpd_submit("time_offset", "error", offset_error); + + free(ik); + ik = NULL; + + status = ntpd_do_query(REQ_PEER_LIST_SUM, 0, 0, NULL, /* request data */ + &ps_num, &ps_size, + (char **)((void *)&ps), /* response data */ + sizeof(struct info_peer_summary)); + if (status != 0) { + ERROR( + "ntpd plugin: ntpd_do_query (REQ_PEER_LIST_SUM) failed with status %i", + status); + return (status); + } else if ((ps == NULL) || (ps_num == 0) || (ps_size == 0)) { + ERROR("ntpd plugin: ntpd_do_query returned unexpected data. " + "(ps = %p; ps_num = %i; ps_size = %i)", + (void *)ps, ps_num, ps_size); + return (-1); + } + + for (int i = 0; i < ps_num; i++) { + struct info_peer_summary *ptr; + double offset; + + char peername[NI_MAXHOST]; + uint32_t refclock_id; + + ptr = ps + i; + + status = ntpd_get_name(peername, sizeof(peername), ptr); + if (status != 0) { + ERROR("ntpd plugin: Determining name of peer failed."); + continue; + } + + refclock_id = ntpd_get_refclock_id(ptr); + + /* Convert the `long floating point' offset value to double */ + M_LFPTOD(ntohl(ptr->offset_int), ntohl(ptr->offset_frc), offset); + + DEBUG("peer %i:\n" + " peername = %s\n" + " srcadr = 0x%08x\n" + " reach = 0%03o\n" + " delay = %f\n" + " offset_int = %i\n" + " offset_frc = %i\n" + " offset = %f\n" + " dispersion = %f\n", + i, peername, ntohl(ptr->srcadr), ptr->reach, ntpd_read_fp(ptr->delay), + ntohl(ptr->offset_int), ntohl(ptr->offset_frc), offset, + ntpd_read_fp(ptr->dispersion)); + + if (refclock_id != + 1) /* not the system clock (offset will always be zero.. */ + ntpd_submit_reach("time_offset", peername, ptr->reach, offset); + ntpd_submit_reach("time_dispersion", peername, ptr->reach, + ntpd_read_fp(ptr->dispersion)); + if (refclock_id == 0) /* not a reference clock */ + ntpd_submit_reach("delay", peername, ptr->reach, + ntpd_read_fp(ptr->delay)); + } + + free(ps); + ps = NULL; + + return (0); } /* int ntpd_read */ -void module_register (void) -{ - plugin_register_config ("ntpd", ntpd_config, - config_keys, config_keys_num); - plugin_register_read ("ntpd", ntpd_read); +void module_register(void) { + plugin_register_config("ntpd", ntpd_config, config_keys, config_keys_num); + plugin_register_read("ntpd", ntpd_read); } /* void module_register */ diff --git a/src/numa.c b/src/numa.c index e1653832..049daeee 100644 --- a/src/numa.c +++ b/src/numa.c @@ -30,32 +30,31 @@ #include "plugin.h" #if !KERNEL_LINUX -# error "No applicable input method." +#error "No applicable input method." #endif #ifndef NUMA_ROOT_DIR -# define NUMA_ROOT_DIR "/sys/devices/system/node" +#define NUMA_ROOT_DIR "/sys/devices/system/node" #endif static int max_node = -1; -static void numa_dispatch_value (int node, /* {{{ */ - const char *type_instance, value_t v) -{ +static void numa_dispatch_value(int node, /* {{{ */ + const char *type_instance, value_t v) { value_list_t vl = VALUE_LIST_INIT; vl.values = &v; vl.values_len = 1; - sstrncpy (vl.plugin, "numa", sizeof (vl.plugin)); - ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), "node%i", node); - sstrncpy (vl.type, "vmpage_action", sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + sstrncpy(vl.plugin, "numa", sizeof(vl.plugin)); + ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "node%i", node); + sstrncpy(vl.type, "vmpage_action", sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* }}} void numa_dispatch_value */ -static int numa_read_node (int node) /* {{{ */ +static int numa_read_node(int node) /* {{{ */ { char path[PATH_MAX]; FILE *fh; @@ -63,60 +62,56 @@ static int numa_read_node (int node) /* {{{ */ int status; int success; - ssnprintf (path, sizeof (path), NUMA_ROOT_DIR "/node%i/numastat", node); + ssnprintf(path, sizeof(path), NUMA_ROOT_DIR "/node%i/numastat", node); - fh = fopen (path, "r"); - if (fh == NULL) - { + fh = fopen(path, "r"); + if (fh == NULL) { char errbuf[1024]; - ERROR ("numa plugin: Reading node %i failed: open(%s): %s", - node, path, sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("numa plugin: Reading node %i failed: open(%s): %s", node, path, + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } success = 0; - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { + while (fgets(buffer, sizeof(buffer), fh) != NULL) { char *fields[4]; value_t v; - status = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields)); - if (status != 2) - { - WARNING ("numa plugin: Ignoring line with unexpected " - "number of fields (node %i).", node); + status = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + if (status != 2) { + WARNING("numa plugin: Ignoring line with unexpected " + "number of fields (node %i).", + node); continue; } v.derive = 0; - status = parse_value (fields[1], &v, DS_TYPE_DERIVE); + status = parse_value(fields[1], &v, DS_TYPE_DERIVE); if (status != 0) continue; - numa_dispatch_value (node, fields[0], v); + numa_dispatch_value(node, fields[0], v); success++; } - fclose (fh); + fclose(fh); return (success ? 0 : -1); } /* }}} int numa_read_node */ -static int numa_read (void) /* {{{ */ +static int numa_read(void) /* {{{ */ { int i; int status; int success; - if (max_node < 0) - { - WARNING ("numa plugin: No NUMA nodes were detected."); + if (max_node < 0) { + WARNING("numa plugin: No NUMA nodes were detected."); return (-1); } success = 0; - for (i = 0; i <= max_node; i++) - { - status = numa_read_node (i); + for (i = 0; i <= max_node; i++) { + status = numa_read_node(i); if (status == 0) success++; } @@ -124,44 +119,38 @@ static int numa_read (void) /* {{{ */ return (success ? 0 : -1); } /* }}} int numa_read */ -static int numa_init (void) /* {{{ */ +static int numa_init(void) /* {{{ */ { /* Determine the number of nodes on this machine. */ - while (42) - { + while (42) { char path[PATH_MAX]; - struct stat statbuf = { 0 }; + struct stat statbuf = {0}; int status; - ssnprintf (path, sizeof (path), NUMA_ROOT_DIR "/node%i", max_node + 1); + ssnprintf(path, sizeof(path), NUMA_ROOT_DIR "/node%i", max_node + 1); - status = stat (path, &statbuf); - if (status == 0) - { + status = stat(path, &statbuf); + if (status == 0) { max_node++; continue; - } - else if (errno == ENOENT) - { + } else if (errno == ENOENT) { break; - } - else /* ((status != 0) && (errno != ENOENT)) */ + } else /* ((status != 0) && (errno != ENOENT)) */ { char errbuf[1024]; - ERROR ("numa plugin: stat(%s) failed: %s", path, - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("numa plugin: stat(%s) failed: %s", path, + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } } - DEBUG ("numa plugin: Found %i nodes.", max_node + 1); + DEBUG("numa plugin: Found %i nodes.", max_node + 1); return (0); } /* }}} int numa_init */ -void module_register (void) -{ - plugin_register_init ("numa", numa_init); - plugin_register_read ("numa", numa_read); +void module_register(void) { + plugin_register_init("numa", numa_init); + plugin_register_read("numa", numa_read); } /* void module_register */ /* vim: set sw=2 sts=2 et : */ diff --git a/src/nut.c b/src/nut.c index 29074c4e..d40e0951 100644 --- a/src/nut.c +++ b/src/nut.c @@ -36,17 +36,16 @@ typedef UPSCONN_t collectd_upsconn_t; #elif HAVE_UPSCONN typedef UPSCONN collectd_upsconn_t; #else -# error "Unable to determine the UPS connection type." +#error "Unable to determine the UPS connection type." #endif struct nut_ups_s; typedef struct nut_ups_s nut_ups_t; -struct nut_ups_s -{ +struct nut_ups_s { collectd_upsconn_t *conn; - char *upsname; - char *hostname; - int port; + char *upsname; + char *hostname; + int port; nut_ups_t *next; }; @@ -55,51 +54,41 @@ static nut_ups_t *upslist_head = NULL; static pthread_mutex_t read_lock = PTHREAD_MUTEX_INITIALIZER; static int read_busy = 0; -static const char *config_keys[] = -{ - "UPS" -}; +static const char *config_keys[] = {"UPS"}; static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); -static void free_nut_ups_t (nut_ups_t *ups) -{ - if (ups->conn != NULL) - { - upscli_disconnect (ups->conn); - sfree (ups->conn); +static void free_nut_ups_t(nut_ups_t *ups) { + if (ups->conn != NULL) { + upscli_disconnect(ups->conn); + sfree(ups->conn); } - sfree (ups->hostname); - sfree (ups->upsname); - sfree (ups); + sfree(ups->hostname); + sfree(ups->upsname); + sfree(ups); } /* void free_nut_ups_t */ -static int nut_add_ups (const char *name) -{ +static int nut_add_ups(const char *name) { nut_ups_t *ups; int status; - DEBUG ("nut plugin: nut_add_ups (name = %s);", name); + DEBUG("nut plugin: nut_add_ups (name = %s);", name); - ups = calloc (1, sizeof (*ups)); - if (ups == NULL) - { - ERROR ("nut plugin: nut_add_ups: calloc failed."); + ups = calloc(1, sizeof(*ups)); + if (ups == NULL) { + ERROR("nut plugin: nut_add_ups: calloc failed."); return (1); } - status = upscli_splitname (name, &ups->upsname, &ups->hostname, - &ups->port); - if (status != 0) - { - ERROR ("nut plugin: nut_add_ups: upscli_splitname (%s) failed.", name); - free_nut_ups_t (ups); + status = upscli_splitname(name, &ups->upsname, &ups->hostname, &ups->port); + if (status != 0) { + ERROR("nut plugin: nut_add_ups: upscli_splitname (%s) failed.", name); + free_nut_ups_t(ups); return (1); } if (upslist_head == NULL) upslist_head = ups; - else - { + else { nut_ups_t *last = upslist_head; while (last->next != NULL) last = last->next; @@ -109,36 +98,32 @@ static int nut_add_ups (const char *name) return (0); } /* int nut_add_ups */ -static int nut_config (const char *key, const char *value) -{ - if (strcasecmp (key, "UPS") == 0) - return (nut_add_ups (value)); +static int nut_config(const char *key, const char *value) { + if (strcasecmp(key, "UPS") == 0) + return (nut_add_ups(value)); else return (-1); } /* int nut_config */ -static void nut_submit (nut_ups_t *ups, const char *type, - const char *type_instance, gauge_t value) -{ +static void nut_submit(nut_ups_t *ups, const char *type, + const char *type_instance, gauge_t value) { value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; + vl.values = &(value_t){.gauge = value}; vl.values_len = 1; - sstrncpy (vl.host, - (strcasecmp (ups->hostname, "localhost") == 0) - ? hostname_g - : ups->hostname, - sizeof (vl.host)); - sstrncpy (vl.plugin, "nut", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, ups->upsname, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); + sstrncpy(vl.host, + (strcasecmp(ups->hostname, "localhost") == 0) ? hostname_g + : ups->hostname, + sizeof(vl.host)); + sstrncpy(vl.plugin, "nut", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, ups->upsname, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); } /* void nut_submit */ -static int nut_read_one (nut_ups_t *ups) -{ +static int nut_read_one(nut_ups_t *ups) { const char *query[3] = {"VAR", ups->upsname, NULL}; unsigned int query_num = 2; char **answer; @@ -146,147 +131,129 @@ static int nut_read_one (nut_ups_t *ups) int status; /* (Re-)Connect if we have no connection */ - if (ups->conn == NULL) - { - ups->conn = malloc (sizeof (*ups->conn)); - if (ups->conn == NULL) - { - ERROR ("nut plugin: malloc failed."); + if (ups->conn == NULL) { + ups->conn = malloc(sizeof(*ups->conn)); + if (ups->conn == NULL) { + ERROR("nut plugin: malloc failed."); return (-1); } - status = upscli_connect (ups->conn, ups->hostname, ups->port, - UPSCLI_CONN_TRYSSL); - if (status != 0) - { - ERROR ("nut plugin: nut_read_one: upscli_connect (%s, %i) failed: %s", - ups->hostname, ups->port, upscli_strerror (ups->conn)); - sfree (ups->conn); + status = + upscli_connect(ups->conn, ups->hostname, ups->port, UPSCLI_CONN_TRYSSL); + if (status != 0) { + ERROR("nut plugin: nut_read_one: upscli_connect (%s, %i) failed: %s", + ups->hostname, ups->port, upscli_strerror(ups->conn)); + sfree(ups->conn); return (-1); } - INFO ("nut plugin: Connection to (%s, %i) established.", - ups->hostname, ups->port); + INFO("nut plugin: Connection to (%s, %i) established.", ups->hostname, + ups->port); } /* if (ups->conn == NULL) */ /* nut plugin: nut_read_one: upscli_list_start (adpos) failed: Protocol * error */ - status = upscli_list_start (ups->conn, query_num, query); - if (status != 0) - { - ERROR ("nut plugin: nut_read_one: upscli_list_start (%s) failed: %s", - ups->upsname, upscli_strerror (ups->conn)); - upscli_disconnect (ups->conn); - sfree (ups->conn); + status = upscli_list_start(ups->conn, query_num, query); + if (status != 0) { + ERROR("nut plugin: nut_read_one: upscli_list_start (%s) failed: %s", + ups->upsname, upscli_strerror(ups->conn)); + upscli_disconnect(ups->conn); + sfree(ups->conn); return (-1); } - while ((status = upscli_list_next (ups->conn, query_num, query, - &answer_num, &answer)) == 1) - { - char *key; + while ((status = upscli_list_next(ups->conn, query_num, query, &answer_num, + &answer)) == 1) { + char *key; double value; if (answer_num < 4) continue; key = answer[2]; - value = atof (answer[3]); - - if (strncmp ("ambient.", key, 8) == 0) - { - if (strcmp ("ambient.humidity", key) == 0) - nut_submit (ups, "humidity", "ambient", value); - else if (strcmp ("ambient.temperature", key) == 0) - nut_submit (ups, "temperature", "ambient", value); - } - else if (strncmp ("battery.", key, 8) == 0) - { - if (strcmp ("battery.charge", key) == 0) - nut_submit (ups, "percent", "charge", value); - else if (strcmp ("battery.current", key) == 0) - nut_submit (ups, "current", "battery", value); - else if (strcmp ("battery.runtime", key) == 0) - nut_submit (ups, "timeleft", "battery", value); - else if (strcmp ("battery.temperature", key) == 0) - nut_submit (ups, "temperature", "battery", value); - else if (strcmp ("battery.voltage", key) == 0) - nut_submit (ups, "voltage", "battery", value); - } - else if (strncmp ("input.", key, 6) == 0) - { - if (strcmp ("input.frequency", key) == 0) - nut_submit (ups, "frequency", "input", value); - else if (strcmp ("input.voltage", key) == 0) - nut_submit (ups, "voltage", "input", value); - } - else if (strncmp ("output.", key, 7) == 0) - { - if (strcmp ("output.current", key) == 0) - nut_submit (ups, "current", "output", value); - else if (strcmp ("output.frequency", key) == 0) - nut_submit (ups, "frequency", "output", value); - else if (strcmp ("output.voltage", key) == 0) - nut_submit (ups, "voltage", "output", value); - } - else if (strncmp ("ups.", key, 4) == 0) - { - if (strcmp ("ups.load", key) == 0) - nut_submit (ups, "percent", "load", value); - else if (strcmp ("ups.power", key) == 0) - nut_submit (ups, "power", "ups", value); - else if (strcmp ("ups.temperature", key) == 0) - nut_submit (ups, "temperature", "ups", value); + value = atof(answer[3]); + + if (strncmp("ambient.", key, 8) == 0) { + if (strcmp("ambient.humidity", key) == 0) + nut_submit(ups, "humidity", "ambient", value); + else if (strcmp("ambient.temperature", key) == 0) + nut_submit(ups, "temperature", "ambient", value); + } else if (strncmp("battery.", key, 8) == 0) { + if (strcmp("battery.charge", key) == 0) + nut_submit(ups, "percent", "charge", value); + else if (strcmp("battery.current", key) == 0) + nut_submit(ups, "current", "battery", value); + else if (strcmp("battery.runtime", key) == 0) + nut_submit(ups, "timeleft", "battery", value); + else if (strcmp("battery.temperature", key) == 0) + nut_submit(ups, "temperature", "battery", value); + else if (strcmp("battery.voltage", key) == 0) + nut_submit(ups, "voltage", "battery", value); + } else if (strncmp("input.", key, 6) == 0) { + if (strcmp("input.frequency", key) == 0) + nut_submit(ups, "frequency", "input", value); + else if (strcmp("input.voltage", key) == 0) + nut_submit(ups, "voltage", "input", value); + } else if (strncmp("output.", key, 7) == 0) { + if (strcmp("output.current", key) == 0) + nut_submit(ups, "current", "output", value); + else if (strcmp("output.frequency", key) == 0) + nut_submit(ups, "frequency", "output", value); + else if (strcmp("output.voltage", key) == 0) + nut_submit(ups, "voltage", "output", value); + } else if (strncmp("ups.", key, 4) == 0) { + if (strcmp("ups.load", key) == 0) + nut_submit(ups, "percent", "load", value); + else if (strcmp("ups.power", key) == 0) + nut_submit(ups, "power", "ups", value); + else if (strcmp("ups.temperature", key) == 0) + nut_submit(ups, "temperature", "ups", value); } } /* while (upscli_list_next) */ return (0); } /* int nut_read_one */ -static int nut_read (void) -{ +static int nut_read(void) { int success = 0; - pthread_mutex_lock (&read_lock); + pthread_mutex_lock(&read_lock); success = read_busy; read_busy = 1; - pthread_mutex_unlock (&read_lock); + pthread_mutex_unlock(&read_lock); if (success != 0) return (0); for (nut_ups_t *ups = upslist_head; ups != NULL; ups = ups->next) - if (nut_read_one (ups) == 0) + if (nut_read_one(ups) == 0) success++; - pthread_mutex_lock (&read_lock); + pthread_mutex_lock(&read_lock); read_busy = 0; - pthread_mutex_unlock (&read_lock); + pthread_mutex_unlock(&read_lock); return ((success != 0) ? 0 : -1); } /* int nut_read */ -static int nut_shutdown (void) -{ +static int nut_shutdown(void) { nut_ups_t *this; nut_ups_t *next; this = upslist_head; - while (this != NULL) - { + while (this != NULL) { next = this->next; - free_nut_ups_t (this); + free_nut_ups_t(this); this = next; } return (0); } /* int nut_shutdown */ -void module_register (void) -{ - plugin_register_config ("nut", nut_config, config_keys, config_keys_num); - plugin_register_read ("nut", nut_read); - plugin_register_shutdown ("nut", nut_shutdown); +void module_register(void) { + plugin_register_config("nut", nut_config, config_keys, config_keys_num); + plugin_register_read("nut", nut_read); + plugin_register_shutdown("nut", nut_shutdown); } /* void module_register */ /* vim: set sw=2 ts=8 sts=2 tw=78 : */ diff --git a/src/olsrd.c b/src/olsrd.c index 3a36723d..d1caf461 100644 --- a/src/olsrd.c +++ b/src/olsrd.c @@ -29,97 +29,87 @@ #include "common.h" #include "plugin.h" -#include #include #include #include +#include #define OLSRD_DEFAULT_NODE "localhost" #define OLSRD_DEFAULT_SERVICE "2006" -static const char *config_keys[] = -{ - "Host", - "Port", - "CollectLinks", - "CollectRoutes", - "CollectTopology" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"Host", "Port", "CollectLinks", + "CollectRoutes", "CollectTopology"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static char *config_node = NULL; static char *config_service = NULL; -#define OLSRD_WANT_NOT 0 +#define OLSRD_WANT_NOT 0 #define OLSRD_WANT_SUMMARY 1 -#define OLSRD_WANT_DETAIL 2 -static int config_want_links = OLSRD_WANT_DETAIL; -static int config_want_routes = OLSRD_WANT_SUMMARY; +#define OLSRD_WANT_DETAIL 2 +static int config_want_links = OLSRD_WANT_DETAIL; +static int config_want_routes = OLSRD_WANT_SUMMARY; static int config_want_topology = OLSRD_WANT_SUMMARY; -static const char *olsrd_get_node (void) /* {{{ */ +static const char *olsrd_get_node(void) /* {{{ */ { if (config_node != NULL) return (config_node); return (OLSRD_DEFAULT_NODE); } /* }}} const char *olsrd_get_node */ -static const char *olsrd_get_service (void) /* {{{ */ +static const char *olsrd_get_service(void) /* {{{ */ { if (config_service != NULL) return (config_service); return (OLSRD_DEFAULT_SERVICE); } /* }}} const char *olsrd_get_service */ -static void olsrd_set_node (const char *node) /* {{{ */ +static void olsrd_set_node(const char *node) /* {{{ */ { char *tmp; if (node == NULL) return; - tmp = strdup (node); + tmp = strdup(node); if (tmp == NULL) return; config_node = tmp; } /* }}} void olsrd_set_node */ -static void olsrd_set_service (const char *service) /* {{{ */ +static void olsrd_set_service(const char *service) /* {{{ */ { char *tmp; if (service == NULL) return; - tmp = strdup (service); + tmp = strdup(service); if (tmp == NULL) return; config_service = tmp; } /* }}} void olsrd_set_service */ -static void olsrd_set_detail (int *varptr, const char *detail, /* {{{ */ - const char *key) -{ - if (strcasecmp ("No", detail) == 0) +static void olsrd_set_detail(int *varptr, const char *detail, /* {{{ */ + const char *key) { + if (strcasecmp("No", detail) == 0) *varptr = OLSRD_WANT_NOT; - else if (strcasecmp ("Summary", detail) == 0) + else if (strcasecmp("Summary", detail) == 0) *varptr = OLSRD_WANT_SUMMARY; - else if (strcasecmp ("Detail", detail) == 0) + else if (strcasecmp("Detail", detail) == 0) *varptr = OLSRD_WANT_DETAIL; - else - { - ERROR ("olsrd plugin: Invalid argument given to the `%s' configuration " - "option: `%s'. Expected: `No', `Summary', or `Detail'.", - key, detail); + else { + ERROR("olsrd plugin: Invalid argument given to the `%s' configuration " + "option: `%s'. Expected: `No', `Summary', or `Detail'.", + key, detail); } } /* }}} void olsrd_set_detail */ /* Strip trailing newline characters. Returns length of string. */ -static size_t strchomp (char *buffer) /* {{{ */ +static size_t strchomp(char *buffer) /* {{{ */ { size_t buffer_len; - buffer_len = strlen (buffer); - while ((buffer_len > 0) - && ((buffer[buffer_len - 1] == '\r') - || (buffer[buffer_len - 1] == '\n'))) - { + buffer_len = strlen(buffer); + while ((buffer_len > 0) && ((buffer[buffer_len - 1] == '\r') || + (buffer[buffer_len - 1] == '\n'))) { buffer_len--; buffer[buffer_len] = 0; } @@ -127,7 +117,7 @@ static size_t strchomp (char *buffer) /* {{{ */ return (buffer_len); } /* }}} size_t strchomp */ -static size_t strtabsplit (char *string, char **fields, size_t size) /* {{{ */ +static size_t strtabsplit(char *string, char **fields, size_t size) /* {{{ */ { size_t i; char *ptr; @@ -136,8 +126,7 @@ static size_t strtabsplit (char *string, char **fields, size_t size) /* {{{ */ i = 0; ptr = string; saveptr = NULL; - while ((fields[i] = strtok_r (ptr, " \t\r\n", &saveptr)) != NULL) - { + while ((fields[i] = strtok_r(ptr, " \t\r\n", &saveptr)) != NULL) { ptr = NULL; i++; @@ -148,100 +137,88 @@ static size_t strtabsplit (char *string, char **fields, size_t size) /* {{{ */ return (i); } /* }}} size_t strtabsplit */ -static FILE *olsrd_connect (void) /* {{{ */ +static FILE *olsrd_connect(void) /* {{{ */ { struct addrinfo *ai_list; - int ai_return; + int ai_return; FILE *fh; - struct addrinfo ai_hints = { - .ai_family = AF_UNSPEC, - .ai_flags = AI_ADDRCONFIG, - .ai_protocol = IPPROTO_TCP, - .ai_socktype = SOCK_STREAM - }; - - ai_return = getaddrinfo (olsrd_get_node (), olsrd_get_service (), - &ai_hints, &ai_list); - if (ai_return != 0) - { - ERROR ("olsrd plugin: getaddrinfo (%s, %s) failed: %s", - olsrd_get_node (), olsrd_get_service (), - gai_strerror (ai_return)); + struct addrinfo ai_hints = {.ai_family = AF_UNSPEC, + .ai_flags = AI_ADDRCONFIG, + .ai_protocol = IPPROTO_TCP, + .ai_socktype = SOCK_STREAM}; + + ai_return = + getaddrinfo(olsrd_get_node(), olsrd_get_service(), &ai_hints, &ai_list); + if (ai_return != 0) { + ERROR("olsrd plugin: getaddrinfo (%s, %s) failed: %s", olsrd_get_node(), + olsrd_get_service(), gai_strerror(ai_return)); return (NULL); } fh = NULL; - for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) - { + for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; + ai_ptr = ai_ptr->ai_next) { int fd; int status; char errbuf[1024]; - fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); - if (fd < 0) - { - ERROR ("olsrd plugin: socket failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + fd = socket(ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); + if (fd < 0) { + ERROR("olsrd plugin: socket failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); continue; } - status = connect (fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); - if (status != 0) - { - ERROR ("olsrd plugin: connect failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - close (fd); + status = connect(fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); + if (status != 0) { + ERROR("olsrd plugin: connect failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(fd); continue; } - fh = fdopen (fd, "r+"); - if (fh == NULL) - { - ERROR ("olsrd plugin: fdopen failed."); - close (fd); + fh = fdopen(fd, "r+"); + if (fh == NULL) { + ERROR("olsrd plugin: fdopen failed."); + close(fd); continue; } break; } /* for (ai_ptr) */ - freeaddrinfo (ai_list); + freeaddrinfo(ai_list); return (fh); } /* }}} FILE *olsrd_connect */ -__attribute__ ((nonnull(2))) -static void olsrd_submit (const char *plugin_instance, /* {{{ */ - const char *type, const char *type_instance, gauge_t value) -{ +__attribute__((nonnull(2))) static void +olsrd_submit(const char *plugin_instance, /* {{{ */ + const char *type, const char *type_instance, gauge_t value) { value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; + vl.values = &(value_t){.gauge = value}; vl.values_len = 1; - sstrncpy (vl.plugin, "olsrd", sizeof (vl.plugin)); + sstrncpy(vl.plugin, "olsrd", sizeof(vl.plugin)); if (plugin_instance != NULL) - sstrncpy (vl.plugin_instance, plugin_instance, - sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, - sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* }}} void olsrd_submit */ -static int olsrd_cb_ignore (int lineno, /* {{{ */ - size_t fields_num, char **fields) -{ +static int olsrd_cb_ignore(int lineno, /* {{{ */ + size_t fields_num, char **fields) { return (0); } /* }}} int olsrd_cb_ignore */ -static int olsrd_cb_links (int lineno, /* {{{ */ - size_t fields_num, char **fields) -{ +static int olsrd_cb_links(int lineno, /* {{{ */ + size_t fields_num, char **fields) { /* Fields: * 0 = Local IP * 1 = Remote IP @@ -251,9 +228,9 @@ static int olsrd_cb_links (int lineno, /* {{{ */ * 5 = Cost */ static uint32_t links_num; - static double lq_sum; - static uint32_t lq_num; - static double nlq_sum; + static double lq_sum; + static uint32_t lq_num; + static double nlq_sum; static uint32_t nlq_num; double lq; @@ -265,8 +242,7 @@ static int olsrd_cb_links (int lineno, /* {{{ */ return (0); /* Special handling of the first line. */ - if (lineno <= 0) - { + if (lineno <= 0) { links_num = 0; lq_sum = 0.0; lq_num = 0; @@ -277,25 +253,24 @@ static int olsrd_cb_links (int lineno, /* {{{ */ } /* Special handling of the last line. */ - if (fields_num == 0) - { - DEBUG ("olsrd plugin: Number of links: %"PRIu32, links_num); - olsrd_submit (/* p.-inst = */ "links", /* type = */ "links", - /* t.-inst = */ NULL, (gauge_t) links_num); + if (fields_num == 0) { + DEBUG("olsrd plugin: Number of links: %" PRIu32, links_num); + olsrd_submit(/* p.-inst = */ "links", /* type = */ "links", + /* t.-inst = */ NULL, (gauge_t)links_num); lq = NAN; if (lq_num > 0) - lq = lq_sum / ((double) lq_num); - DEBUG ("olsrd plugin: Average LQ: %g", lq); - olsrd_submit (/* p.-inst = */ "links", /* type = */ "signal_quality", - "average-lq", lq); + lq = lq_sum / ((double)lq_num); + DEBUG("olsrd plugin: Average LQ: %g", lq); + olsrd_submit(/* p.-inst = */ "links", /* type = */ "signal_quality", + "average-lq", lq); nlq = NAN; if (nlq_num > 0) - nlq = nlq_sum / ((double) nlq_num); - DEBUG ("olsrd plugin: Average NLQ: %g", nlq); - olsrd_submit (/* p.-inst = */ "links", /* type = */ "signal_quality", - "average-nlq", nlq); + nlq = nlq_sum / ((double)nlq_num); + DEBUG("olsrd plugin: Average NLQ: %g", nlq); + olsrd_submit(/* p.-inst = */ "links", /* type = */ "signal_quality", + "average-nlq", nlq); return (0); } @@ -307,68 +282,57 @@ static int olsrd_cb_links (int lineno, /* {{{ */ errno = 0; endptr = NULL; - lq = strtod (fields[3], &endptr); - if ((errno != 0) || (endptr == fields[3])) - { - ERROR ("olsrd plugin: Cannot parse link quality: %s", fields[3]); - } - else - { - if (!isnan (lq)) - { + lq = strtod(fields[3], &endptr); + if ((errno != 0) || (endptr == fields[3])) { + ERROR("olsrd plugin: Cannot parse link quality: %s", fields[3]); + } else { + if (!isnan(lq)) { lq_sum += lq; lq_num++; } - if (config_want_links == OLSRD_WANT_DETAIL) - { + if (config_want_links == OLSRD_WANT_DETAIL) { char type_instance[DATA_MAX_NAME_LEN]; - ssnprintf (type_instance, sizeof (type_instance), "%s-%s-lq", - fields[0], fields[1]); + ssnprintf(type_instance, sizeof(type_instance), "%s-%s-lq", fields[0], + fields[1]); - DEBUG ("olsrd plugin: links: type_instance = %s; lq = %g;", - type_instance, lq); - olsrd_submit (/* p.-inst = */ "links", /* type = */ "signal_quality", - type_instance, lq); + DEBUG("olsrd plugin: links: type_instance = %s; lq = %g;", type_instance, + lq); + olsrd_submit(/* p.-inst = */ "links", /* type = */ "signal_quality", + type_instance, lq); } } errno = 0; endptr = NULL; - nlq = strtod (fields[4], &endptr); - if ((errno != 0) || (endptr == fields[4])) - { - ERROR ("olsrd plugin: Cannot parse neighbor link quality: %s", fields[4]); - } - else - { - if (!isnan (nlq)) - { + nlq = strtod(fields[4], &endptr); + if ((errno != 0) || (endptr == fields[4])) { + ERROR("olsrd plugin: Cannot parse neighbor link quality: %s", fields[4]); + } else { + if (!isnan(nlq)) { nlq_sum += nlq; nlq_num++; } - if (config_want_links == OLSRD_WANT_DETAIL) - { + if (config_want_links == OLSRD_WANT_DETAIL) { char type_instance[DATA_MAX_NAME_LEN]; - ssnprintf (type_instance, sizeof (type_instance), "%s-%s-rx", - fields[0], fields[1]); + ssnprintf(type_instance, sizeof(type_instance), "%s-%s-rx", fields[0], + fields[1]); - DEBUG ("olsrd plugin: links: type_instance = %s; nlq = %g;", - type_instance, lq); - olsrd_submit (/* p.-inst = */ "links", /* type = */ "signal_quality", - type_instance, nlq); + DEBUG("olsrd plugin: links: type_instance = %s; nlq = %g;", type_instance, + lq); + olsrd_submit(/* p.-inst = */ "links", /* type = */ "signal_quality", + type_instance, nlq); } } return (0); } /* }}} int olsrd_cb_links */ -static int olsrd_cb_routes (int lineno, /* {{{ */ - size_t fields_num, char **fields) -{ +static int olsrd_cb_routes(int lineno, /* {{{ */ + size_t fields_num, char **fields) { /* Fields: * 0 = Destination * 1 = Gateway IP @@ -379,7 +343,7 @@ static int olsrd_cb_routes (int lineno, /* {{{ */ static uint32_t routes_num; static uint32_t metric_sum; static uint32_t metric_num; - static double etx_sum; + static double etx_sum; static uint32_t etx_num; uint32_t metric; @@ -390,8 +354,7 @@ static int olsrd_cb_routes (int lineno, /* {{{ */ return (0); /* Special handling of the first line */ - if (lineno <= 0) - { + if (lineno <= 0) { routes_num = 0; metric_num = 0; metric_sum = 0; @@ -402,27 +365,26 @@ static int olsrd_cb_routes (int lineno, /* {{{ */ } /* Special handling after the last line */ - if (fields_num == 0) - { + if (fields_num == 0) { double metric_avg; - DEBUG ("olsrd plugin: Number of routes: %"PRIu32, routes_num); - olsrd_submit (/* p.-inst = */ "routes", /* type = */ "routes", - /* t.-inst = */ NULL, (gauge_t) routes_num); + DEBUG("olsrd plugin: Number of routes: %" PRIu32, routes_num); + olsrd_submit(/* p.-inst = */ "routes", /* type = */ "routes", + /* t.-inst = */ NULL, (gauge_t)routes_num); metric_avg = NAN; if (metric_num > 0) - metric_avg = ((double) metric_sum) / ((double) metric_num); - DEBUG ("olsrd plugin: Average metric: %g", metric_avg); - olsrd_submit (/* p.-inst = */ "routes", /* type = */ "route_metric", - "average", metric_avg); + metric_avg = ((double)metric_sum) / ((double)metric_num); + DEBUG("olsrd plugin: Average metric: %g", metric_avg); + olsrd_submit(/* p.-inst = */ "routes", /* type = */ "route_metric", + "average", metric_avg); etx = NAN; if (etx_num > 0) - etx = etx_sum / ((double) etx_sum); - DEBUG ("olsrd plugin: Average ETX: %g", etx); - olsrd_submit (/* p.-inst = */ "routes", /* type = */ "route_etx", - "average", etx); + etx = etx_sum / ((double)etx_sum); + DEBUG("olsrd plugin: Average ETX: %g", etx); + olsrd_submit(/* p.-inst = */ "routes", /* type = */ "route_etx", "average", + etx); return (0); } @@ -434,55 +396,44 @@ static int olsrd_cb_routes (int lineno, /* {{{ */ errno = 0; endptr = NULL; - metric = (uint32_t) strtoul (fields[2], &endptr, 0); - if ((errno != 0) || (endptr == fields[2])) - { - ERROR ("olsrd plugin: Unable to parse metric: %s", fields[2]); - } - else - { + metric = (uint32_t)strtoul(fields[2], &endptr, 0); + if ((errno != 0) || (endptr == fields[2])) { + ERROR("olsrd plugin: Unable to parse metric: %s", fields[2]); + } else { metric_num++; metric_sum += metric; - if (config_want_routes == OLSRD_WANT_DETAIL) - { - DEBUG ("olsrd plugin: destination = %s; metric = %"PRIu32";", - fields[0], metric); - olsrd_submit (/* p.-inst = */ "routes", /* type = */ "route_metric", - /* t.-inst = */ fields[0], (gauge_t) metric); + if (config_want_routes == OLSRD_WANT_DETAIL) { + DEBUG("olsrd plugin: destination = %s; metric = %" PRIu32 ";", fields[0], + metric); + olsrd_submit(/* p.-inst = */ "routes", /* type = */ "route_metric", + /* t.-inst = */ fields[0], (gauge_t)metric); } } errno = 0; endptr = NULL; - etx = strtod (fields[3], &endptr); - if ((errno != 0) || (endptr == fields[3])) - { - ERROR ("olsrd plugin: Unable to parse ETX: %s", fields[3]); - } - else - { - if (!isnan (etx)) - { + etx = strtod(fields[3], &endptr); + if ((errno != 0) || (endptr == fields[3])) { + ERROR("olsrd plugin: Unable to parse ETX: %s", fields[3]); + } else { + if (!isnan(etx)) { etx_sum += etx; etx_num++; } - if (config_want_routes == OLSRD_WANT_DETAIL) - { - DEBUG ("olsrd plugin: destination = %s; etx = %g;", - fields[0], etx); - olsrd_submit (/* p.-inst = */ "routes", /* type = */ "route_etx", - /* t.-inst = */ fields[0], etx); + if (config_want_routes == OLSRD_WANT_DETAIL) { + DEBUG("olsrd plugin: destination = %s; etx = %g;", fields[0], etx); + olsrd_submit(/* p.-inst = */ "routes", /* type = */ "route_etx", + /* t.-inst = */ fields[0], etx); } } return (0); } /* }}} int olsrd_cb_routes */ -static int olsrd_cb_topology (int lineno, /* {{{ */ - size_t fields_num, char **fields) -{ +static int olsrd_cb_topology(int lineno, /* {{{ */ + size_t fields_num, char **fields) { /* Fields: * 0 = Dest. IP * 1 = Last hop IP @@ -490,7 +441,7 @@ static int olsrd_cb_topology (int lineno, /* {{{ */ * 3 = NLQ * 4 = Cost */ - static double lq_sum; + static double lq_sum; static uint32_t lq_num; static uint32_t links_num; @@ -502,8 +453,7 @@ static int olsrd_cb_topology (int lineno, /* {{{ */ return (0); /* Special handling of the first line */ - if (lineno <= 0) - { + if (lineno <= 0) { lq_sum = 0.0; lq_num = 0; links_num = 0; @@ -512,18 +462,17 @@ static int olsrd_cb_topology (int lineno, /* {{{ */ } /* Special handling after the last line */ - if (fields_num == 0) - { - DEBUG ("olsrd plugin: topology: Number of links: %"PRIu32, links_num); - olsrd_submit (/* p.-inst = */ "topology", /* type = */ "links", - /* t.-inst = */ NULL, (gauge_t) links_num); + if (fields_num == 0) { + DEBUG("olsrd plugin: topology: Number of links: %" PRIu32, links_num); + olsrd_submit(/* p.-inst = */ "topology", /* type = */ "links", + /* t.-inst = */ NULL, (gauge_t)links_num); lq = NAN; if (lq_num > 0) - lq = lq_sum / ((double) lq_sum); - DEBUG ("olsrd plugin: topology: Average link quality: %g", lq); - olsrd_submit (/* p.-inst = */ "topology", /* type = */ "signal_quality", - /* t.-inst = */ "average", lq); + lq = lq_sum / ((double)lq_sum); + DEBUG("olsrd plugin: topology: Average link quality: %g", lq); + olsrd_submit(/* p.-inst = */ "topology", /* type = */ "signal_quality", + /* t.-inst = */ "average", lq); return (0); } @@ -535,60 +484,51 @@ static int olsrd_cb_topology (int lineno, /* {{{ */ errno = 0; endptr = NULL; - lq = strtod (fields[2], &endptr); - if ((errno != 0) || (endptr == fields[2])) - { - ERROR ("olsrd plugin: Unable to parse LQ: %s", fields[2]); - } - else - { - if (!isnan (lq)) - { + lq = strtod(fields[2], &endptr); + if ((errno != 0) || (endptr == fields[2])) { + ERROR("olsrd plugin: Unable to parse LQ: %s", fields[2]); + } else { + if (!isnan(lq)) { lq_sum += lq; lq_num++; } - if (config_want_topology == OLSRD_WANT_DETAIL) - { - char type_instance[DATA_MAX_NAME_LEN] = { 0 }; + if (config_want_topology == OLSRD_WANT_DETAIL) { + char type_instance[DATA_MAX_NAME_LEN] = {0}; - ssnprintf (type_instance, sizeof (type_instance), "%s-%s-lq", - fields[0], fields[1]); - DEBUG ("olsrd plugin: type_instance = %s; lq = %g;", type_instance, lq); - olsrd_submit (/* p.-inst = */ "topology", /* type = */ "signal_quality", - type_instance, lq); + ssnprintf(type_instance, sizeof(type_instance), "%s-%s-lq", fields[0], + fields[1]); + DEBUG("olsrd plugin: type_instance = %s; lq = %g;", type_instance, lq); + olsrd_submit(/* p.-inst = */ "topology", /* type = */ "signal_quality", + type_instance, lq); } } - if (config_want_topology == OLSRD_WANT_DETAIL) - { + if (config_want_topology == OLSRD_WANT_DETAIL) { double nlq; errno = 0; endptr = NULL; - nlq = strtod (fields[3], &endptr); - if ((errno != 0) || (endptr == fields[3])) - { - ERROR ("olsrd plugin: Unable to parse NLQ: %s", fields[3]); - } - else - { - char type_instance[DATA_MAX_NAME_LEN] = { 0 }; - - ssnprintf (type_instance, sizeof (type_instance), "%s-%s-nlq", - fields[0], fields[1]); - DEBUG ("olsrd plugin: type_instance = %s; nlq = %g;", type_instance, nlq); - olsrd_submit (/* p.-inst = */ "topology", /* type = */ "signal_quality", - type_instance, nlq); + nlq = strtod(fields[3], &endptr); + if ((errno != 0) || (endptr == fields[3])) { + ERROR("olsrd plugin: Unable to parse NLQ: %s", fields[3]); + } else { + char type_instance[DATA_MAX_NAME_LEN] = {0}; + + ssnprintf(type_instance, sizeof(type_instance), "%s-%s-nlq", fields[0], + fields[1]); + DEBUG("olsrd plugin: type_instance = %s; nlq = %g;", type_instance, nlq); + olsrd_submit(/* p.-inst = */ "topology", /* type = */ "signal_quality", + type_instance, nlq); } } return (0); } /* }}} int olsrd_cb_topology */ -static int olsrd_read_table (FILE *fh, /* {{{ */ - int (*callback) (int lineno, size_t fields_num, char **fields)) -{ +static int olsrd_read_table(FILE *fh, /* {{{ */ + int (*callback)(int lineno, size_t fields_num, + char **fields)) { char buffer[1024]; size_t buffer_len; @@ -598,107 +538,98 @@ static int olsrd_read_table (FILE *fh, /* {{{ */ int lineno; lineno = 0; - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { + while (fgets(buffer, sizeof(buffer), fh) != NULL) { /* An empty line ends the table. */ - buffer_len = strchomp (buffer); - if (buffer_len == 0) - { - (*callback) (lineno, /* fields_num = */ 0, /* fields = */ NULL); + buffer_len = strchomp(buffer); + if (buffer_len == 0) { + (*callback)(lineno, /* fields_num = */ 0, /* fields = */ NULL); break; } - fields_num = strtabsplit (buffer, fields, STATIC_ARRAY_SIZE (fields)); + fields_num = strtabsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); - (*callback) (lineno, fields_num, fields); + (*callback)(lineno, fields_num, fields); lineno++; } /* while (fgets) */ return (0); } /* }}} int olsrd_read_table */ -static int olsrd_config (const char *key, const char *value) /* {{{ */ +static int olsrd_config(const char *key, const char *value) /* {{{ */ { - if (strcasecmp ("Host", key) == 0) - olsrd_set_node (value); - else if (strcasecmp ("Port", key) == 0) - olsrd_set_service (value); - else if (strcasecmp ("CollectLinks", key) == 0) - olsrd_set_detail (&config_want_links, value, key); - else if (strcasecmp ("CollectRoutes", key) == 0) - olsrd_set_detail (&config_want_routes, value, key); - else if (strcasecmp ("CollectTopology", key) == 0) - olsrd_set_detail (&config_want_topology, value, key); - else - { - ERROR ("olsrd plugin: Unknown configuration option given: %s", key); + if (strcasecmp("Host", key) == 0) + olsrd_set_node(value); + else if (strcasecmp("Port", key) == 0) + olsrd_set_service(value); + else if (strcasecmp("CollectLinks", key) == 0) + olsrd_set_detail(&config_want_links, value, key); + else if (strcasecmp("CollectRoutes", key) == 0) + olsrd_set_detail(&config_want_routes, value, key); + else if (strcasecmp("CollectTopology", key) == 0) + olsrd_set_detail(&config_want_topology, value, key); + else { + ERROR("olsrd plugin: Unknown configuration option given: %s", key); return (-1); } return (0); } /* }}} int olsrd_config */ -static int olsrd_read (void) /* {{{ */ +static int olsrd_read(void) /* {{{ */ { FILE *fh; char buffer[1024]; size_t buffer_len; - fh = olsrd_connect (); + fh = olsrd_connect(); if (fh == NULL) return (-1); - fputs ("\r\n", fh); - fflush (fh); + fputs("\r\n", fh); + fflush(fh); - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - buffer_len = strchomp (buffer); + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + buffer_len = strchomp(buffer); if (buffer_len == 0) continue; - if (strcmp ("Table: Links", buffer) == 0) - olsrd_read_table (fh, olsrd_cb_links); - else if (strcmp ("Table: Neighbors", buffer) == 0) - olsrd_read_table (fh, olsrd_cb_ignore); - else if (strcmp ("Table: Topology", buffer) == 0) - olsrd_read_table (fh, olsrd_cb_topology); - else if (strcmp ("Table: HNA", buffer) == 0) - olsrd_read_table (fh, olsrd_cb_ignore); - else if (strcmp ("Table: MID", buffer) == 0) - olsrd_read_table (fh, olsrd_cb_ignore); - else if (strcmp ("Table: Routes", buffer) == 0) - olsrd_read_table (fh, olsrd_cb_routes); - else if ((strcmp ("HTTP/1.0 200 OK", buffer) == 0) - || (strcmp ("Content-type: text/plain", buffer) == 0)) - { + if (strcmp("Table: Links", buffer) == 0) + olsrd_read_table(fh, olsrd_cb_links); + else if (strcmp("Table: Neighbors", buffer) == 0) + olsrd_read_table(fh, olsrd_cb_ignore); + else if (strcmp("Table: Topology", buffer) == 0) + olsrd_read_table(fh, olsrd_cb_topology); + else if (strcmp("Table: HNA", buffer) == 0) + olsrd_read_table(fh, olsrd_cb_ignore); + else if (strcmp("Table: MID", buffer) == 0) + olsrd_read_table(fh, olsrd_cb_ignore); + else if (strcmp("Table: Routes", buffer) == 0) + olsrd_read_table(fh, olsrd_cb_routes); + else if ((strcmp("HTTP/1.0 200 OK", buffer) == 0) || + (strcmp("Content-type: text/plain", buffer) == 0)) { /* ignore */ - } - else - { - DEBUG ("olsrd plugin: Unable to handle line: %s", buffer); + } else { + DEBUG("olsrd plugin: Unable to handle line: %s", buffer); } } /* while (fgets) */ - fclose (fh); + fclose(fh); return (0); } /* }}} int olsrd_read */ -static int olsrd_shutdown (void) /* {{{ */ +static int olsrd_shutdown(void) /* {{{ */ { - sfree (config_node); - sfree (config_service); + sfree(config_node); + sfree(config_service); return (0); } /* }}} int olsrd_shutdown */ -void module_register (void) -{ - plugin_register_config ("olsrd", olsrd_config, - config_keys, config_keys_num); - plugin_register_read ("olsrd", olsrd_read); - plugin_register_shutdown ("olsrd", olsrd_shutdown); +void module_register(void) { + plugin_register_config("olsrd", olsrd_config, config_keys, config_keys_num); + plugin_register_read("olsrd", olsrd_read); + plugin_register_shutdown("olsrd", olsrd_shutdown); } /* void module_register */ /* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/onewire.c b/src/onewire.c index c333fead..10fa5ca1 100644 --- a/src/onewire.c +++ b/src/onewire.c @@ -25,18 +25,16 @@ #include "plugin.h" #include "utils_ignorelist.h" +#include +#include #include #include -#include -#include #define OW_FAMILY_LENGTH 8 #define OW_FAMILY_MAX_FEATURES 2 -struct ow_family_features_s -{ +struct ow_family_features_s { char family[OW_FAMILY_LENGTH]; - struct - { + struct { char filename[DATA_MAX_NAME_LEN]; char type[DATA_MAX_NAME_LEN]; char type_instance[DATA_MAX_NAME_LEN]; @@ -51,306 +49,247 @@ static struct timeval tv_begin, tv_end, tv_diff; #endif /* COLLECT_DEBUG */ /* regexp to extract address (without family) and file from the owfs path */ -static const char *regexp_to_match = "[A-Fa-f0-9]{2}\\.([A-Fa-f0-9]{12})/([[:alnum:]]+)$"; +static const char *regexp_to_match = + "[A-Fa-f0-9]{2}\\.([A-Fa-f0-9]{12})/([[:alnum:]]+)$"; /* see http://owfs.sourceforge.net/ow_table.html for a list of families */ -static ow_family_features_t ow_family_features[] = -{ - { /* DS18S20 Precision Thermometer and DS1920 ibutton */ - /* family = */ "10.", - { - { - /* filename = */ "temperature", - /* type = */ "temperature", - /* type_instance = */ "" - } - }, - /* features_num = */ 1 - }, - { /* DS1822 Econo Thermometer */ - /* family = */ "22.", - { - { - /* filename = */ "temperature", - /* type = */ "temperature", - /* type_instance = */ "" - } - }, - /* features_num = */ 1 - }, - { /* DS18B20 Programmable Resolution Thermometer */ - /* family = */ "28.", - { - { - /* filename = */ "temperature", - /* type = */ "temperature", - /* type_instance = */ "" - } - }, - /* features_num = */ 1 - }, - { /* DS2436 Volts/Temp */ - /* family = */ "1B.", - { - { - /* filename = */ "temperature", - /* type = */ "temperature", - /* type_instance = */ "" - } - }, - /* features_num = */ 1 - }, - { /* DS2438 Volts/Temp */ - /* family = */ "26.", - { - { - /* filename = */ "temperature", - /* type = */ "temperature", - /* type_instance = */ "" - } - }, - /* features_num = */ 1 - } -}; -static int ow_family_features_num = STATIC_ARRAY_SIZE (ow_family_features); +static ow_family_features_t ow_family_features[] = { + {/* DS18S20 Precision Thermometer and DS1920 ibutton */ + /* family = */ "10.", + {{/* filename = */ "temperature", + /* type = */ "temperature", + /* type_instance = */ ""}}, + /* features_num = */ 1}, + {/* DS1822 Econo Thermometer */ + /* family = */ "22.", + {{/* filename = */ "temperature", + /* type = */ "temperature", + /* type_instance = */ ""}}, + /* features_num = */ 1}, + {/* DS18B20 Programmable Resolution Thermometer */ + /* family = */ "28.", + {{/* filename = */ "temperature", + /* type = */ "temperature", + /* type_instance = */ ""}}, + /* features_num = */ 1}, + {/* DS2436 Volts/Temp */ + /* family = */ "1B.", + {{/* filename = */ "temperature", + /* type = */ "temperature", + /* type_instance = */ ""}}, + /* features_num = */ 1}, + {/* DS2438 Volts/Temp */ + /* family = */ "26.", + {{/* filename = */ "temperature", + /* type = */ "temperature", + /* type_instance = */ ""}}, + /* features_num = */ 1}}; +static int ow_family_features_num = STATIC_ARRAY_SIZE(ow_family_features); static char *device_g = NULL; static cdtime_t ow_interval = 0; static _Bool direct_access = 0; -static const char *config_keys[] = -{ - "Device", - "IgnoreSelected", - "Sensor", - "Interval" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"Device", "IgnoreSelected", "Sensor", + "Interval"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static ignorelist_t *sensor_list; -static _Bool regex_direct_initialized = 0; +static _Bool regex_direct_initialized = 0; static regex_t regex_direct; /** * List of onewire owfs "files" to be directly read */ -typedef struct direct_access_element_s -{ - char *path; /**< The whole owfs path */ - char *address; /**< 1-wire address without family */ - char *file; /**< owfs file - e.g. temperature */ - struct direct_access_element_s *next; /**< Next in the list */ +typedef struct direct_access_element_s { + char *path; /**< The whole owfs path */ + char *address; /**< 1-wire address without family */ + char *file; /**< owfs file - e.g. temperature */ + struct direct_access_element_s *next; /**< Next in the list */ } direct_access_element_t; -static direct_access_element_t * direct_list = NULL; +static direct_access_element_t *direct_list = NULL; -/* =================================================================================== */ +/* =================================================================================== + */ #if COLLECT_DEBUG /* Return 1 if the difference is negative, otherwise 0. */ -static int timeval_subtract(struct timeval *result, struct timeval *t2, struct timeval *t1) -{ - long int diff = (t2->tv_usec + 1000000 * t2->tv_sec) - (t1->tv_usec + 1000000 * t1->tv_sec); - result->tv_sec = diff / 1000000; - result->tv_usec = diff % 1000000; - - return (diff<0); +static int timeval_subtract(struct timeval *result, struct timeval *t2, + struct timeval *t1) { + long int diff = (t2->tv_usec + 1000000 * t2->tv_sec) - + (t1->tv_usec + 1000000 * t1->tv_sec); + result->tv_sec = diff / 1000000; + result->tv_usec = diff % 1000000; + + return (diff < 0); } #endif /* COLLECT_DEBUG */ -/* =================================================================================== */ - -static void direct_list_element_free(direct_access_element_t *el) -{ - if (el != NULL) - { - DEBUG ("onewire plugin: direct_list_element_free - deleting <%s>", el->path); - sfree (el->path); - sfree (el->address); - sfree (el->file); - free (el); - } +/* =================================================================================== + */ + +static void direct_list_element_free(direct_access_element_t *el) { + if (el != NULL) { + DEBUG("onewire plugin: direct_list_element_free - deleting <%s>", el->path); + sfree(el->path); + sfree(el->address); + sfree(el->file); + free(el); + } } -static int direct_list_insert(const char * config) -{ - regmatch_t pmatch[3]; - size_t nmatch = 3; - direct_access_element_t *element; +static int direct_list_insert(const char *config) { + regmatch_t pmatch[3]; + size_t nmatch = 3; + direct_access_element_t *element; - DEBUG ("onewire plugin: direct_list_insert <%s>", config); + DEBUG("onewire plugin: direct_list_insert <%s>", config); - element = malloc (sizeof (*element)); - if (element == NULL) - { - ERROR ("onewire plugin: direct_list_insert - cannot allocate element"); - return 1; - } - element->path = NULL; - element->address = NULL; - element->file = NULL; - - element->path = strdup (config); - if (element->path == NULL) - { - ERROR ("onewire plugin: direct_list_insert - cannot allocate path"); - direct_list_element_free (element); - return 1; - } + element = malloc(sizeof(*element)); + if (element == NULL) { + ERROR("onewire plugin: direct_list_insert - cannot allocate element"); + return 1; + } + element->path = NULL; + element->address = NULL; + element->file = NULL; + + element->path = strdup(config); + if (element->path == NULL) { + ERROR("onewire plugin: direct_list_insert - cannot allocate path"); + direct_list_element_free(element); + return 1; + } - DEBUG ("onewire plugin: direct_list_insert - about to match %s", config); - - if (!regex_direct_initialized) - { - if (regcomp (®ex_direct, regexp_to_match, REG_EXTENDED)) - { - ERROR ("onewire plugin: Cannot compile regex"); - direct_list_element_free (element); - return (1); - } - regex_direct_initialized = 1; - DEBUG ("onewire plugin: Compiled regex!!"); - } + DEBUG("onewire plugin: direct_list_insert - about to match %s", config); - if (regexec (®ex_direct, config, nmatch, pmatch, 0)) - { - ERROR ("onewire plugin: direct_list_insert - no regex match"); - direct_list_element_free (element); - return 1; + if (!regex_direct_initialized) { + if (regcomp(®ex_direct, regexp_to_match, REG_EXTENDED)) { + ERROR("onewire plugin: Cannot compile regex"); + direct_list_element_free(element); + return (1); } + regex_direct_initialized = 1; + DEBUG("onewire plugin: Compiled regex!!"); + } - if (pmatch[1].rm_so<0) - { - ERROR ("onewire plugin: direct_list_insert - no address regex match"); - direct_list_element_free (element); - return 1; - } - element->address = strndup (config+pmatch[1].rm_so, - pmatch[1].rm_eo - pmatch[1].rm_so); - if (element->address == NULL) - { - ERROR ("onewire plugin: direct_list_insert - cannot allocate address"); - direct_list_element_free (element); - return 1; - } - DEBUG ("onewire plugin: direct_list_insert - found address <%s>", - element->address); - - if (pmatch[2].rm_so<0) - { - ERROR ("onewire plugin: direct_list_insert - no file regex match"); - direct_list_element_free (element); - return 1; - } - element->file = strndup (config+pmatch[2].rm_so, - pmatch[2].rm_eo - pmatch[2].rm_so); - if (element->file == NULL) - { - ERROR ("onewire plugin: direct_list_insert - cannot allocate file"); - direct_list_element_free (element); - return 1; - } - DEBUG ("onewire plugin: direct_list_insert - found file <%s>", element->file); + if (regexec(®ex_direct, config, nmatch, pmatch, 0)) { + ERROR("onewire plugin: direct_list_insert - no regex match"); + direct_list_element_free(element); + return 1; + } - element->next = direct_list; - direct_list = element; + if (pmatch[1].rm_so < 0) { + ERROR("onewire plugin: direct_list_insert - no address regex match"); + direct_list_element_free(element); + return 1; + } + element->address = + strndup(config + pmatch[1].rm_so, pmatch[1].rm_eo - pmatch[1].rm_so); + if (element->address == NULL) { + ERROR("onewire plugin: direct_list_insert - cannot allocate address"); + direct_list_element_free(element); + return 1; + } + DEBUG("onewire plugin: direct_list_insert - found address <%s>", + element->address); - return 0; + if (pmatch[2].rm_so < 0) { + ERROR("onewire plugin: direct_list_insert - no file regex match"); + direct_list_element_free(element); + return 1; + } + element->file = + strndup(config + pmatch[2].rm_so, pmatch[2].rm_eo - pmatch[2].rm_so); + if (element->file == NULL) { + ERROR("onewire plugin: direct_list_insert - cannot allocate file"); + direct_list_element_free(element); + return 1; + } + DEBUG("onewire plugin: direct_list_insert - found file <%s>", element->file); + + element->next = direct_list; + direct_list = element; + + return 0; } -static void direct_list_free(void) -{ - direct_access_element_t *traverse = direct_list; - direct_access_element_t *tmp = NULL;; - - while(traverse != NULL) - { - tmp = traverse; - traverse = traverse->next; - direct_list_element_free (tmp); - tmp = NULL; - } +static void direct_list_free(void) { + direct_access_element_t *traverse = direct_list; + direct_access_element_t *tmp = NULL; + ; + + while (traverse != NULL) { + tmp = traverse; + traverse = traverse->next; + direct_list_element_free(tmp); + tmp = NULL; + } } -/* =================================================================================== */ +/* =================================================================================== + */ -static int cow_load_config (const char *key, const char *value) -{ +static int cow_load_config(const char *key, const char *value) { if (sensor_list == NULL) - sensor_list = ignorelist_create (1); - - if (strcasecmp (key, "Sensor") == 0) - { - if (direct_list_insert (value)) - { - DEBUG ("onewire plugin: Cannot add %s to direct_list_insert.", value); - - if (ignorelist_add (sensor_list, value)) - { - ERROR ("onewire plugin: Cannot add value to ignorelist."); - return (1); - } - } - else - { - DEBUG ("onewire plugin: %s is a direct access", value); - direct_access = 1; + sensor_list = ignorelist_create(1); + + if (strcasecmp(key, "Sensor") == 0) { + if (direct_list_insert(value)) { + DEBUG("onewire plugin: Cannot add %s to direct_list_insert.", value); + + if (ignorelist_add(sensor_list, value)) { + ERROR("onewire plugin: Cannot add value to ignorelist."); + return (1); + } + } else { + DEBUG("onewire plugin: %s is a direct access", value); + direct_access = 1; } - } - else if (strcasecmp (key, "IgnoreSelected") == 0) - { - ignorelist_set_invert (sensor_list, 1); - if (IS_TRUE (value)) - ignorelist_set_invert (sensor_list, 0); - } - else if (strcasecmp (key, "Device") == 0) - { + } else if (strcasecmp(key, "IgnoreSelected") == 0) { + ignorelist_set_invert(sensor_list, 1); + if (IS_TRUE(value)) + ignorelist_set_invert(sensor_list, 0); + } else if (strcasecmp(key, "Device") == 0) { char *temp; - temp = strdup (value); - if (temp == NULL) - { - ERROR ("onewire plugin: strdup failed."); + temp = strdup(value); + if (temp == NULL) { + ERROR("onewire plugin: strdup failed."); return (1); } - sfree (device_g); + sfree(device_g); device_g = temp; - } - else if (strcasecmp ("Interval", key) == 0) - { + } else if (strcasecmp("Interval", key) == 0) { double tmp; - tmp = atof (value); + tmp = atof(value); if (tmp > 0.0) - ow_interval = DOUBLE_TO_CDTIME_T (tmp); + ow_interval = DOUBLE_TO_CDTIME_T(tmp); else - ERROR ("onewire plugin: Invalid `Interval' setting: %s", value); - } - else - { + ERROR("onewire plugin: Invalid `Interval' setting: %s", value); + } else { return (-1); } return (0); } -static int cow_read_values (const char *path, const char *name, - const ow_family_features_t *family_info) -{ +static int cow_read_values(const char *path, const char *name, + const ow_family_features_t *family_info) { value_list_t vl = VALUE_LIST_INIT; int success = 0; - if (sensor_list != NULL) - { - DEBUG ("onewire plugin: Checking ignorelist for `%s'", name); - if (ignorelist_match (sensor_list, name) != 0) + if (sensor_list != NULL) { + DEBUG("onewire plugin: Checking ignorelist for `%s'", name); + if (ignorelist_match(sensor_list, name) != 0) return 0; } - sstrncpy (vl.plugin, "onewire", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, name, sizeof (vl.plugin_instance)); + sstrncpy(vl.plugin, "onewire", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, name, sizeof(vl.plugin_instance)); - for (size_t i = 0; i < family_info->features_num; i++) - { + for (size_t i = 0; i < family_info->features_num; i++) { char *buffer; size_t buffer_size; int status; @@ -359,48 +298,47 @@ static int cow_read_values (const char *path, const char *name, char file[4096]; char *endptr; - snprintf (file, sizeof (file), "%s/%s", - path, family_info->features[i].filename); - file[sizeof (file) - 1] = 0; + snprintf(file, sizeof(file), "%s/%s", path, + family_info->features[i].filename); + file[sizeof(file) - 1] = 0; buffer = NULL; buffer_size = 0; - DEBUG ("Start reading onewire device %s", file); - status = OW_get (file, &buffer, &buffer_size); - if (status < 0) - { - ERROR ("onewire plugin: OW_get (%s/%s) failed. error = %s;", - path, family_info->features[i].filename, sstrerror(errno, errbuf, sizeof (errbuf))); + DEBUG("Start reading onewire device %s", file); + status = OW_get(file, &buffer, &buffer_size); + if (status < 0) { + ERROR("onewire plugin: OW_get (%s/%s) failed. error = %s;", path, + family_info->features[i].filename, + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } - DEBUG ("Read onewire device %s as %s", file, buffer); + DEBUG("Read onewire device %s as %s", file, buffer); endptr = NULL; - gauge_t g = strtod (buffer, &endptr); - if (endptr == NULL) - { - ERROR ("onewire plugin: Buffer is not a number: %s", buffer); + gauge_t g = strtod(buffer, &endptr); + if (endptr == NULL) { + ERROR("onewire plugin: Buffer is not a number: %s", buffer); continue; } - sstrncpy (vl.type, family_info->features[i].type, sizeof (vl.type)); - sstrncpy (vl.type_instance, family_info->features[i].type_instance, - sizeof (vl.type_instance)); + sstrncpy(vl.type, family_info->features[i].type, sizeof(vl.type)); + sstrncpy(vl.type_instance, family_info->features[i].type_instance, + sizeof(vl.type_instance)); - vl.values = &(value_t) { .gauge = g }; + vl.values = &(value_t){.gauge = g}; vl.values_len = 1; - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); success++; - free (buffer); + free(buffer); } /* for (i = 0; i < features_num; i++) */ return ((success > 0) ? 0 : -1); } /* int cow_read_values */ /* Forward declaration so the recursion below works */ -static int cow_read_bus (const char *path); +static int cow_read_bus(const char *path); /* * cow_read_ds2409 @@ -408,24 +346,22 @@ static int cow_read_bus (const char *path); * Handles: * - DS2409 - MicroLAN Coupler */ -static int cow_read_ds2409 (const char *path) -{ +static int cow_read_ds2409(const char *path) { char subpath[4096]; int status; - status = ssnprintf (subpath, sizeof (subpath), "%s/main", path); - if ((status > 0) && (status < (int) sizeof (subpath))) - cow_read_bus (subpath); + status = ssnprintf(subpath, sizeof(subpath), "%s/main", path); + if ((status > 0) && (status < (int)sizeof(subpath))) + cow_read_bus(subpath); - status = ssnprintf (subpath, sizeof (subpath), "%s/aux", path); - if ((status > 0) && (status < (int) sizeof (subpath))) - cow_read_bus (subpath); + status = ssnprintf(subpath, sizeof(subpath), "%s/aux", path); + if ((status > 0) && (status < (int)sizeof(subpath))) + cow_read_bus(subpath); return (0); } /* int cow_read_ds2409 */ -static int cow_read_bus (const char *path) -{ +static int cow_read_bus(const char *path) { char *buffer; size_t buffer_size; int status; @@ -436,186 +372,167 @@ static int cow_read_bus (const char *path) char *saveptr; char subpath[4096]; - status = OW_get (path, &buffer, &buffer_size); - if (status < 0) - { - ERROR ("onewire plugin: OW_get (%s) failed. error = %s;", - path, sstrerror(errno, errbuf, sizeof (errbuf))); + status = OW_get(path, &buffer, &buffer_size); + if (status < 0) { + ERROR("onewire plugin: OW_get (%s) failed. error = %s;", path, + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } - DEBUG ("onewire plugin: OW_get (%s) returned: %s", - path, buffer); + DEBUG("onewire plugin: OW_get (%s) returned: %s", path, buffer); dummy = buffer; saveptr = NULL; - while ((buffer_ptr = strtok_r (dummy, ",/", &saveptr)) != NULL) - { + while ((buffer_ptr = strtok_r(dummy, ",/", &saveptr)) != NULL) { int i; dummy = NULL; - if (strcmp ("/", path) == 0) - status = ssnprintf (subpath, sizeof (subpath), "/%s", buffer_ptr); + if (strcmp("/", path) == 0) + status = ssnprintf(subpath, sizeof(subpath), "/%s", buffer_ptr); else - status = ssnprintf (subpath, sizeof (subpath), "%s/%s", - path, buffer_ptr); - if ((status <= 0) || (status >= (int) sizeof (subpath))) + status = ssnprintf(subpath, sizeof(subpath), "%s/%s", path, buffer_ptr); + if ((status <= 0) || (status >= (int)sizeof(subpath))) continue; - for (i = 0; i < ow_family_features_num; i++) - { - if (strncmp (ow_family_features[i].family, buffer_ptr, - strlen (ow_family_features[i].family)) != 0) + for (i = 0; i < ow_family_features_num; i++) { + if (strncmp(ow_family_features[i].family, buffer_ptr, + strlen(ow_family_features[i].family)) != 0) continue; - cow_read_values (subpath, - buffer_ptr + strlen (ow_family_features[i].family), - ow_family_features + i); + cow_read_values(subpath, + buffer_ptr + strlen(ow_family_features[i].family), + ow_family_features + i); break; } if (i < ow_family_features_num) continue; /* DS2409 */ - if (strncmp ("1F.", buffer_ptr, strlen ("1F.")) == 0) - { - cow_read_ds2409 (subpath); + if (strncmp("1F.", buffer_ptr, strlen("1F.")) == 0) { + cow_read_ds2409(subpath); continue; } } /* while (strtok_r) */ - free (buffer); + free(buffer); return (0); } /* int cow_read_bus */ +/* =================================================================================== + */ -/* =================================================================================== */ - -static int cow_simple_read (void) -{ +static int cow_simple_read(void) { value_list_t vl = VALUE_LIST_INIT; - char *buffer; - size_t buffer_size; - int status; - char errbuf[1024]; - char *endptr; + char *buffer; + size_t buffer_size; + int status; + char errbuf[1024]; + char *endptr; direct_access_element_t *traverse; /* traverse list and check entries */ - for (traverse = direct_list; traverse != NULL; traverse = traverse->next) - { - sstrncpy (vl.plugin, "onewire", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, traverse->address, sizeof (vl.plugin_instance)); - - status = OW_get (traverse->path, &buffer, &buffer_size); - if (status < 0) - { - ERROR ("onewire plugin: OW_get (%s) failed. status = %s;", - traverse->path, - sstrerror(errno, errbuf, sizeof (errbuf))); - return (-1); - } - DEBUG ("onewire plugin: Read onewire device %s as %s", traverse->path, buffer); - - endptr = NULL; - gauge_t g = strtod (buffer, &endptr); - if (endptr == NULL) - { - ERROR ("onewire plugin: Buffer is not a number: %s", buffer); - continue; - } + for (traverse = direct_list; traverse != NULL; traverse = traverse->next) { + sstrncpy(vl.plugin, "onewire", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, traverse->address, sizeof(vl.plugin_instance)); + + status = OW_get(traverse->path, &buffer, &buffer_size); + if (status < 0) { + ERROR("onewire plugin: OW_get (%s) failed. status = %s;", traverse->path, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + DEBUG("onewire plugin: Read onewire device %s as %s", traverse->path, + buffer); + + endptr = NULL; + gauge_t g = strtod(buffer, &endptr); + if (endptr == NULL) { + ERROR("onewire plugin: Buffer is not a number: %s", buffer); + continue; + } - sstrncpy (vl.type, traverse->file, sizeof (vl.type)); - sstrncpy (vl.type_instance, "", sizeof ("")); + sstrncpy(vl.type, traverse->file, sizeof(vl.type)); + sstrncpy(vl.type_instance, "", sizeof("")); - vl.values = &(value_t) { .gauge = g }; - vl.values_len = 1; + vl.values = &(value_t){.gauge = g}; + vl.values_len = 1; - plugin_dispatch_values (&vl); - free (buffer); + plugin_dispatch_values(&vl); + free(buffer); } /* for (traverse) */ return 0; } /* int cow_simple_read */ -/* =================================================================================== */ +/* =================================================================================== + */ -static int cow_read (user_data_t *ud __attribute__((unused))) -{ - int result=0; +static int cow_read(user_data_t *ud __attribute__((unused))) { + int result = 0; #if COLLECT_DEBUG - gettimeofday (&tv_begin, NULL); + gettimeofday(&tv_begin, NULL); #endif /* COLLECT_DEBUG */ - if (direct_access) - { - DEBUG ("onewire plugin: Direct access read"); - result = cow_simple_read (); - } - else - { - DEBUG ("onewire plugin: Standard access read"); - result = cow_read_bus ("/"); - } + if (direct_access) { + DEBUG("onewire plugin: Direct access read"); + result = cow_simple_read(); + } else { + DEBUG("onewire plugin: Standard access read"); + result = cow_read_bus("/"); + } #if COLLECT_DEBUG - gettimeofday (&tv_end, NULL); - timeval_subtract (&tv_diff, &tv_end, &tv_begin); - DEBUG ("onewire plugin: Onewire read took us %ld.%06ld s", - tv_diff.tv_sec, - tv_diff.tv_usec); + gettimeofday(&tv_end, NULL); + timeval_subtract(&tv_diff, &tv_end, &tv_begin); + DEBUG("onewire plugin: Onewire read took us %ld.%06ld s", tv_diff.tv_sec, + tv_diff.tv_usec); #endif /* COLLECT_DEBUG */ - return result; + return result; } /* int cow_read */ -static int cow_shutdown (void) -{ - OW_finish (); - ignorelist_free (sensor_list); +static int cow_shutdown(void) { + OW_finish(); + ignorelist_free(sensor_list); - direct_list_free (); + direct_list_free(); - if (regex_direct_initialized) - { - regfree(®ex_direct); - } + if (regex_direct_initialized) { + regfree(®ex_direct); + } - return (0); + return (0); } /* int cow_shutdown */ -static int cow_init (void) -{ +static int cow_init(void) { int status; char errbuf[1024]; - if (device_g == NULL) - { - ERROR ("onewire plugin: cow_init: No device configured."); + if (device_g == NULL) { + ERROR("onewire plugin: cow_init: No device configured."); return (-1); } - DEBUG ("onewire plugin: about to init device <%s>.", device_g); - status = (int) OW_init (device_g); - if (status != 0) - { - ERROR ("onewire plugin: OW_init(%s) failed: %s.", device_g, sstrerror(errno, errbuf, sizeof (errbuf))); + DEBUG("onewire plugin: about to init device <%s>.", device_g); + status = (int)OW_init(device_g); + if (status != 0) { + ERROR("onewire plugin: OW_init(%s) failed: %s.", device_g, + sstrerror(errno, errbuf, sizeof(errbuf))); return (1); } - plugin_register_complex_read (/* group = */ NULL, "onewire", cow_read, - ow_interval, /* user data = */ NULL); - plugin_register_shutdown ("onewire", cow_shutdown); + plugin_register_complex_read(/* group = */ NULL, "onewire", cow_read, + ow_interval, /* user data = */ NULL); + plugin_register_shutdown("onewire", cow_shutdown); return (0); } /* int cow_init */ -void module_register (void) -{ - plugin_register_init ("onewire", cow_init); - plugin_register_config ("onewire", cow_load_config, - config_keys, config_keys_num); +void module_register(void) { + plugin_register_init("onewire", cow_init); + plugin_register_config("onewire", cow_load_config, config_keys, + config_keys_num); } /* vim: set sw=2 sts=2 ts=8 et fdm=marker cindent : */ diff --git a/src/openldap.c b/src/openldap.c index e100aeed..5269e5f2 100644 --- a/src/openldap.c +++ b/src/openldap.c @@ -41,500 +41,338 @@ struct cldap_s /* {{{ */ { - char *name; - - char *binddn; - char *password; - char *cacert; - char *host; - int state; - _Bool starttls; - int timeout; - char *url; - _Bool verifyhost; - int version; - - LDAP *ld; + char *name; + + char *binddn; + char *password; + char *cacert; + char *host; + int state; + _Bool starttls; + int timeout; + char *url; + _Bool verifyhost; + int version; + + LDAP *ld; }; typedef struct cldap_s cldap_t; /* }}} */ -static cldap_t **databases = NULL; -static size_t databases_num = 0; +static cldap_t **databases = NULL; +static size_t databases_num = 0; -static void cldap_free (cldap_t *st) /* {{{ */ +static void cldap_free(cldap_t *st) /* {{{ */ { - if (st == NULL) - return; - - sfree (st->binddn); - sfree (st->password); - sfree (st->cacert); - sfree (st->host); - sfree (st->name); - sfree (st->url); - if (st->ld) - ldap_memfree (st->ld); - sfree (st); + if (st == NULL) + return; + + sfree(st->binddn); + sfree(st->password); + sfree(st->cacert); + sfree(st->host); + sfree(st->name); + sfree(st->url); + if (st->ld) + ldap_memfree(st->ld); + sfree(st); } /* }}} void cldap_free */ /* initialize ldap for each host */ -static int cldap_init_host (cldap_t *st) /* {{{ */ +static int cldap_init_host(cldap_t *st) /* {{{ */ { - LDAP *ld; - int rc; - - if (st->state && st->ld) - { - DEBUG ("openldap plugin: Already connected to %s", st->url); - return (0); - } - - rc = ldap_initialize (&ld, st->url); - if (rc != LDAP_SUCCESS) - { - ERROR ("openldap plugin: ldap_initialize failed: %s", - ldap_err2string (rc)); - st->state = 0; - ldap_unbind_ext_s (ld, NULL, NULL); - return (-1); - } - - st->ld = ld; - - ldap_set_option (st->ld, LDAP_OPT_PROTOCOL_VERSION, &st->version); - - ldap_set_option (st->ld, LDAP_OPT_TIMEOUT, - &(const struct timeval){st->timeout, 0}); - - ldap_set_option (st->ld, LDAP_OPT_RESTART, LDAP_OPT_ON); - - if (st->cacert != NULL) - ldap_set_option (st->ld, LDAP_OPT_X_TLS_CACERTFILE, st->cacert); - - if (st->verifyhost == 0) - { - int never = LDAP_OPT_X_TLS_NEVER; - ldap_set_option (st->ld, LDAP_OPT_X_TLS_REQUIRE_CERT, &never); - } - - if (st->starttls != 0) - { - rc = ldap_start_tls_s (ld, NULL, NULL); - if (rc != LDAP_SUCCESS) - { - ERROR ("openldap plugin: Failed to start tls on %s: %s", - st->url, ldap_err2string (rc)); - st->state = 0; - ldap_unbind_ext_s (st->ld, NULL, NULL); - return (-1); - } - } - - struct berval cred; - if (st->password != NULL) - { - cred.bv_val = st->password; - cred.bv_len = strlen (st->password); - } - else - { - cred.bv_val = ""; - cred.bv_len = 0; - } - - rc = ldap_sasl_bind_s (st->ld, st->binddn, LDAP_SASL_SIMPLE, &cred, - NULL, NULL, NULL); - if (rc != LDAP_SUCCESS) - { - ERROR ("openldap plugin: Failed to bind to %s: %s", - st->url, ldap_err2string (rc)); - st->state = 0; - ldap_unbind_ext_s (st->ld, NULL, NULL); - return (-1); - } - else - { - DEBUG ("openldap plugin: Successfully connected to %s", - st->url); - st->state = 1; - return (0); - } + LDAP *ld; + int rc; + + if (st->state && st->ld) { + DEBUG("openldap plugin: Already connected to %s", st->url); + return (0); + } + + rc = ldap_initialize(&ld, st->url); + if (rc != LDAP_SUCCESS) { + ERROR("openldap plugin: ldap_initialize failed: %s", ldap_err2string(rc)); + st->state = 0; + ldap_unbind_ext_s(ld, NULL, NULL); + return (-1); + } + + st->ld = ld; + + ldap_set_option(st->ld, LDAP_OPT_PROTOCOL_VERSION, &st->version); + + ldap_set_option(st->ld, LDAP_OPT_TIMEOUT, + &(const struct timeval){st->timeout, 0}); + + ldap_set_option(st->ld, LDAP_OPT_RESTART, LDAP_OPT_ON); + + if (st->cacert != NULL) + ldap_set_option(st->ld, LDAP_OPT_X_TLS_CACERTFILE, st->cacert); + + if (st->verifyhost == 0) { + int never = LDAP_OPT_X_TLS_NEVER; + ldap_set_option(st->ld, LDAP_OPT_X_TLS_REQUIRE_CERT, &never); + } + + if (st->starttls != 0) { + rc = ldap_start_tls_s(ld, NULL, NULL); + if (rc != LDAP_SUCCESS) { + ERROR("openldap plugin: Failed to start tls on %s: %s", st->url, + ldap_err2string(rc)); + st->state = 0; + ldap_unbind_ext_s(st->ld, NULL, NULL); + return (-1); + } + } + + struct berval cred; + if (st->password != NULL) { + cred.bv_val = st->password; + cred.bv_len = strlen(st->password); + } else { + cred.bv_val = ""; + cred.bv_len = 0; + } + + rc = ldap_sasl_bind_s(st->ld, st->binddn, LDAP_SASL_SIMPLE, &cred, NULL, NULL, + NULL); + if (rc != LDAP_SUCCESS) { + ERROR("openldap plugin: Failed to bind to %s: %s", st->url, + ldap_err2string(rc)); + st->state = 0; + ldap_unbind_ext_s(st->ld, NULL, NULL); + return (-1); + } else { + DEBUG("openldap plugin: Successfully connected to %s", st->url); + st->state = 1; + return (0); + } } /* }}} static cldap_init_host */ -static void cldap_submit_value (const char *type, const char *type_instance, /* {{{ */ - value_t value, cldap_t *st) -{ - value_list_t vl = VALUE_LIST_INIT; +static void cldap_submit_value(const char *type, + const char *type_instance, /* {{{ */ + value_t value, cldap_t *st) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &value; - vl.values_len = 1; + vl.values = &value; + vl.values_len = 1; - if ((st->host != NULL) && (strcmp ("localhost", st->host) != 0)) - sstrncpy (vl.host, st->host, sizeof (vl.host)); + if ((st->host != NULL) && (strcmp("localhost", st->host) != 0)) + sstrncpy(vl.host, st->host, sizeof(vl.host)); - sstrncpy (vl.plugin, "openldap", sizeof (vl.plugin)); - if (st->name != NULL) - sstrncpy (vl.plugin_instance, st->name, - sizeof (vl.plugin_instance)); + sstrncpy(vl.plugin, "openldap", sizeof(vl.plugin)); + if (st->name != NULL) + sstrncpy(vl.plugin_instance, st->name, sizeof(vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, - sizeof (vl.type_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + if (type_instance != NULL) + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* }}} void cldap_submit_value */ -static void cldap_submit_derive (const char *type, const char *type_instance, /* {{{ */ - derive_t d, cldap_t *st) -{ - cldap_submit_value (type, type_instance, (value_t) { .derive = d }, st); +static void cldap_submit_derive(const char *type, + const char *type_instance, /* {{{ */ + derive_t d, cldap_t *st) { + cldap_submit_value(type, type_instance, (value_t){.derive = d}, st); } /* }}} void cldap_submit_derive */ -static void cldap_submit_gauge (const char *type, const char *type_instance, /* {{{ */ - gauge_t g, cldap_t *st) -{ - cldap_submit_value (type, type_instance, (value_t) { .gauge = g }, st); +static void cldap_submit_gauge(const char *type, + const char *type_instance, /* {{{ */ + gauge_t g, cldap_t *st) { + cldap_submit_value(type, type_instance, (value_t){.gauge = g}, st); } /* }}} void cldap_submit_gauge */ -static int cldap_read_host (user_data_t *ud) /* {{{ */ +static int cldap_read_host(user_data_t *ud) /* {{{ */ { - cldap_t *st; - LDAPMessage *result; - char *dn; - int rc; - int status; - - char *attrs[9] = { "monitorCounter", - "monitorOpCompleted", - "monitorOpInitiated", - "monitoredInfo", - "olmBDBEntryCache", - "olmBDBDNCache", - "olmBDBIDLCache", - "namingContexts", - NULL }; - - if ((ud == NULL) || (ud->data == NULL)) - { - ERROR ("openldap plugin: cldap_read_host: Invalid user data."); - return (-1); - } - - st = (cldap_t *) ud->data; - - status = cldap_init_host (st); - if (status != 0) - return (-1); - - rc = ldap_search_ext_s (st->ld, "cn=Monitor", LDAP_SCOPE_SUBTREE, - "(|(!(cn=* *))(cn=Database*))", attrs, 0, - NULL, NULL, NULL, 0, &result); - - if (rc != LDAP_SUCCESS) - { - ERROR ("openldap plugin: Failed to execute search: %s", - ldap_err2string (rc)); - ldap_msgfree (result); - st->state = 0; - ldap_unbind_ext_s (st->ld, NULL, NULL); - return (-1); - } - - for (LDAPMessage *e = ldap_first_entry (st->ld, result); e != NULL; - e = ldap_next_entry (st->ld, e)) - { - if ((dn = ldap_get_dn (st->ld, e)) != NULL) - { - unsigned long long counter = 0; - unsigned long long opc = 0; - unsigned long long opi = 0; - unsigned long long info = 0; - - struct berval counter_data; - struct berval opc_data; - struct berval opi_data; - struct berval info_data; - struct berval olmbdb_data; - struct berval nc_data; - - struct berval **counter_list; - struct berval **opc_list; - struct berval **opi_list; - struct berval **info_list; - struct berval **olmbdb_list; - struct berval **nc_list; - - if ((counter_list = ldap_get_values_len (st->ld, e, - "monitorCounter")) != NULL) - { - counter_data = *counter_list[0]; - counter = atoll (counter_data.bv_val); - } - - if ((opc_list = ldap_get_values_len (st->ld, e, - "monitorOpCompleted")) != NULL) - { - opc_data = *opc_list[0]; - opc = atoll (opc_data.bv_val); - } - - if ((opi_list = ldap_get_values_len (st->ld, e, - "monitorOpInitiated")) != NULL) - { - opi_data = *opi_list[0]; - opi = atoll (opi_data.bv_val); - } - - if ((info_list = ldap_get_values_len (st->ld, e, - "monitoredInfo")) != NULL) - { - info_data = *info_list[0]; - info = atoll (info_data.bv_val); - } - - if (strcmp (dn, "cn=Total,cn=Connections,cn=Monitor") - == 0) - { - cldap_submit_derive ("total_connections", NULL, - counter, st); - } - else if (strcmp (dn, - "cn=Current,cn=Connections,cn=Monitor") - == 0) - { - cldap_submit_gauge ("current_connections", NULL, - counter, st); - } - else if (strcmp (dn, - "cn=Operations,cn=Monitor") == 0) - { - cldap_submit_derive ("operations", - "completed", opc, st); - cldap_submit_derive ("operations", - "initiated", opi, st); - } - else if (strcmp (dn, - "cn=Bind,cn=Operations,cn=Monitor") - == 0) - { - cldap_submit_derive ("operations", - "bind-completed", opc, st); - cldap_submit_derive ("operations", - "bind-initiated", opi, st); - } - else if (strcmp (dn, - "cn=UnBind,cn=Operations,cn=Monitor") - == 0) - { - cldap_submit_derive ("operations", - "unbind-completed", opc, st); - cldap_submit_derive ("operations", - "unbind-initiated", opi, st); - } - else if (strcmp (dn, - "cn=Search,cn=Operations,cn=Monitor") - == 0) - { - cldap_submit_derive ("operations", - "search-completed", opc, st); - cldap_submit_derive ("operations", - "search-initiated", opi, st); - } - else if (strcmp (dn, - "cn=Compare,cn=Operations,cn=Monitor") - == 0) - { - cldap_submit_derive ("operations", - "compare-completed", opc, st); - cldap_submit_derive ("operations", - "compare-initiated", opi, st); - } - else if (strcmp (dn, - "cn=Modify,cn=Operations,cn=Monitor") - == 0) - { - cldap_submit_derive ("operations", - "modify-completed", opc, st); - cldap_submit_derive ("operations", - "modify-initiated", opi, st); - } - else if (strcmp (dn, - "cn=Modrdn,cn=Operations,cn=Monitor") - == 0) - { - cldap_submit_derive ("operations", - "modrdn-completed", opc, st); - cldap_submit_derive ("operations", - "modrdn-initiated", opi, st); - } - else if (strcmp (dn, - "cn=Add,cn=Operations,cn=Monitor") - == 0) - { - cldap_submit_derive ("operations", - "add-completed", opc, st); - cldap_submit_derive ("operations", - "add-initiated", opi, st); - } - else if (strcmp (dn, - "cn=Delete,cn=Operations,cn=Monitor") - == 0) - { - cldap_submit_derive ("operations", - "delete-completed", opc, st); - cldap_submit_derive ("operations", - "delete-initiated", opi, st); - } - else if (strcmp (dn, - "cn=Abandon,cn=Operations,cn=Monitor") - == 0) - { - cldap_submit_derive ("operations", - "abandon-completed", opc, st); - cldap_submit_derive ("operations", - "abandon-initiated", opi, st); - } - else if (strcmp (dn, - "cn=Extended,cn=Operations,cn=Monitor") - == 0) - { - cldap_submit_derive ("operations", - "extended-completed", opc, st); - cldap_submit_derive ("operations", - "extended-initiated", opi, st); - } - else if ((strncmp (dn, "cn=Database", 11) == 0) - && ((nc_list = ldap_get_values_len - (st->ld, e, "namingContexts")) != NULL)) - { - nc_data = *nc_list[0]; - char typeinst[DATA_MAX_NAME_LEN]; - - if ((olmbdb_list = ldap_get_values_len (st->ld, e, - "olmBDBEntryCache")) != NULL) - { - olmbdb_data = *olmbdb_list[0]; - ssnprintf (typeinst, sizeof (typeinst), - "bdbentrycache-%s", nc_data.bv_val); - cldap_submit_gauge ("cache_size", typeinst, - atoll (olmbdb_data.bv_val), st); - ldap_value_free_len (olmbdb_list); - } - - if ((olmbdb_list = ldap_get_values_len (st->ld, e, - "olmBDBDNCache")) != NULL) - { - olmbdb_data = *olmbdb_list[0]; - ssnprintf (typeinst, sizeof (typeinst), - "bdbdncache-%s", nc_data.bv_val); - cldap_submit_gauge ("cache_size", typeinst, - atoll (olmbdb_data.bv_val), st); - ldap_value_free_len (olmbdb_list); - } - - if ((olmbdb_list = ldap_get_values_len (st->ld, e, - "olmBDBIDLCache")) != NULL) - { - olmbdb_data = *olmbdb_list[0]; - ssnprintf (typeinst, sizeof (typeinst), - "bdbidlcache-%s", nc_data.bv_val); - cldap_submit_gauge ("cache_size", typeinst, - atoll (olmbdb_data.bv_val), st); - ldap_value_free_len (olmbdb_list); - } - - ldap_value_free_len (nc_list); - } - else if (strcmp (dn, - "cn=Bytes,cn=Statistics,cn=Monitor") - == 0) - { - cldap_submit_derive ("derive", "statistics-bytes", - counter, st); - } - else if (strcmp (dn, - "cn=PDU,cn=Statistics,cn=Monitor") - == 0) - { - cldap_submit_derive ("derive", "statistics-pdu", - counter, st); - } - else if (strcmp (dn, - "cn=Entries,cn=Statistics,cn=Monitor") - == 0) - { - cldap_submit_derive ("derive", "statistics-entries", - counter, st); - } - else if (strcmp (dn, - "cn=Referrals,cn=Statistics,cn=Monitor") - == 0) - { - cldap_submit_derive ("derive", "statistics-referrals", - counter, st); - } - else if (strcmp (dn, - "cn=Open,cn=Threads,cn=Monitor") - == 0) - { - cldap_submit_gauge ("threads", "threads-open", - info, st); - } - else if (strcmp (dn, - "cn=Starting,cn=Threads,cn=Monitor") - == 0) - { - cldap_submit_gauge ("threads", "threads-starting", - info, st); - } - else if (strcmp (dn, - "cn=Active,cn=Threads,cn=Monitor") - == 0) - { - cldap_submit_gauge ("threads", "threads-active", - info, st); - } - else if (strcmp (dn, - "cn=Pending,cn=Threads,cn=Monitor") - == 0) - { - cldap_submit_gauge ("threads", "threads-pending", - info, st); - } - else if (strcmp (dn, - "cn=Backload,cn=Threads,cn=Monitor") - == 0) - { - cldap_submit_gauge ("threads", "threads-backload", - info, st); - } - else if (strcmp (dn, - "cn=Read,cn=Waiters,cn=Monitor") - == 0) - { - cldap_submit_derive ("derive", "waiters-read", - counter, st); - } - else if (strcmp (dn, - "cn=Write,cn=Waiters,cn=Monitor") - == 0) - { - cldap_submit_derive ("derive", "waiters-write", - counter, st); - } - - ldap_value_free_len (counter_list); - ldap_value_free_len (opc_list); - ldap_value_free_len (opi_list); - ldap_value_free_len (info_list); - } - - ldap_memfree (dn); - } - - ldap_msgfree (result); - return (0); + cldap_t *st; + LDAPMessage *result; + char *dn; + int rc; + int status; + + char *attrs[9] = { + "monitorCounter", "monitorOpCompleted", "monitorOpInitiated", + "monitoredInfo", "olmBDBEntryCache", "olmBDBDNCache", + "olmBDBIDLCache", "namingContexts", NULL}; + + if ((ud == NULL) || (ud->data == NULL)) { + ERROR("openldap plugin: cldap_read_host: Invalid user data."); + return (-1); + } + + st = (cldap_t *)ud->data; + + status = cldap_init_host(st); + if (status != 0) + return (-1); + + rc = ldap_search_ext_s(st->ld, "cn=Monitor", LDAP_SCOPE_SUBTREE, + "(|(!(cn=* *))(cn=Database*))", attrs, 0, NULL, NULL, + NULL, 0, &result); + + if (rc != LDAP_SUCCESS) { + ERROR("openldap plugin: Failed to execute search: %s", ldap_err2string(rc)); + ldap_msgfree(result); + st->state = 0; + ldap_unbind_ext_s(st->ld, NULL, NULL); + return (-1); + } + + for (LDAPMessage *e = ldap_first_entry(st->ld, result); e != NULL; + e = ldap_next_entry(st->ld, e)) { + if ((dn = ldap_get_dn(st->ld, e)) != NULL) { + unsigned long long counter = 0; + unsigned long long opc = 0; + unsigned long long opi = 0; + unsigned long long info = 0; + + struct berval counter_data; + struct berval opc_data; + struct berval opi_data; + struct berval info_data; + struct berval olmbdb_data; + struct berval nc_data; + + struct berval **counter_list; + struct berval **opc_list; + struct berval **opi_list; + struct berval **info_list; + struct berval **olmbdb_list; + struct berval **nc_list; + + if ((counter_list = ldap_get_values_len(st->ld, e, "monitorCounter")) != + NULL) { + counter_data = *counter_list[0]; + counter = atoll(counter_data.bv_val); + } + + if ((opc_list = ldap_get_values_len(st->ld, e, "monitorOpCompleted")) != + NULL) { + opc_data = *opc_list[0]; + opc = atoll(opc_data.bv_val); + } + + if ((opi_list = ldap_get_values_len(st->ld, e, "monitorOpInitiated")) != + NULL) { + opi_data = *opi_list[0]; + opi = atoll(opi_data.bv_val); + } + + if ((info_list = ldap_get_values_len(st->ld, e, "monitoredInfo")) != + NULL) { + info_data = *info_list[0]; + info = atoll(info_data.bv_val); + } + + if (strcmp(dn, "cn=Total,cn=Connections,cn=Monitor") == 0) { + cldap_submit_derive("total_connections", NULL, counter, st); + } else if (strcmp(dn, "cn=Current,cn=Connections,cn=Monitor") == 0) { + cldap_submit_gauge("current_connections", NULL, counter, st); + } else if (strcmp(dn, "cn=Operations,cn=Monitor") == 0) { + cldap_submit_derive("operations", "completed", opc, st); + cldap_submit_derive("operations", "initiated", opi, st); + } else if (strcmp(dn, "cn=Bind,cn=Operations,cn=Monitor") == 0) { + cldap_submit_derive("operations", "bind-completed", opc, st); + cldap_submit_derive("operations", "bind-initiated", opi, st); + } else if (strcmp(dn, "cn=UnBind,cn=Operations,cn=Monitor") == 0) { + cldap_submit_derive("operations", "unbind-completed", opc, st); + cldap_submit_derive("operations", "unbind-initiated", opi, st); + } else if (strcmp(dn, "cn=Search,cn=Operations,cn=Monitor") == 0) { + cldap_submit_derive("operations", "search-completed", opc, st); + cldap_submit_derive("operations", "search-initiated", opi, st); + } else if (strcmp(dn, "cn=Compare,cn=Operations,cn=Monitor") == 0) { + cldap_submit_derive("operations", "compare-completed", opc, st); + cldap_submit_derive("operations", "compare-initiated", opi, st); + } else if (strcmp(dn, "cn=Modify,cn=Operations,cn=Monitor") == 0) { + cldap_submit_derive("operations", "modify-completed", opc, st); + cldap_submit_derive("operations", "modify-initiated", opi, st); + } else if (strcmp(dn, "cn=Modrdn,cn=Operations,cn=Monitor") == 0) { + cldap_submit_derive("operations", "modrdn-completed", opc, st); + cldap_submit_derive("operations", "modrdn-initiated", opi, st); + } else if (strcmp(dn, "cn=Add,cn=Operations,cn=Monitor") == 0) { + cldap_submit_derive("operations", "add-completed", opc, st); + cldap_submit_derive("operations", "add-initiated", opi, st); + } else if (strcmp(dn, "cn=Delete,cn=Operations,cn=Monitor") == 0) { + cldap_submit_derive("operations", "delete-completed", opc, st); + cldap_submit_derive("operations", "delete-initiated", opi, st); + } else if (strcmp(dn, "cn=Abandon,cn=Operations,cn=Monitor") == 0) { + cldap_submit_derive("operations", "abandon-completed", opc, st); + cldap_submit_derive("operations", "abandon-initiated", opi, st); + } else if (strcmp(dn, "cn=Extended,cn=Operations,cn=Monitor") == 0) { + cldap_submit_derive("operations", "extended-completed", opc, st); + cldap_submit_derive("operations", "extended-initiated", opi, st); + } else if ((strncmp(dn, "cn=Database", 11) == 0) && + ((nc_list = ldap_get_values_len(st->ld, e, + "namingContexts")) != NULL)) { + nc_data = *nc_list[0]; + char typeinst[DATA_MAX_NAME_LEN]; + + if ((olmbdb_list = + ldap_get_values_len(st->ld, e, "olmBDBEntryCache")) != NULL) { + olmbdb_data = *olmbdb_list[0]; + ssnprintf(typeinst, sizeof(typeinst), "bdbentrycache-%s", + nc_data.bv_val); + cldap_submit_gauge("cache_size", typeinst, atoll(olmbdb_data.bv_val), + st); + ldap_value_free_len(olmbdb_list); + } + + if ((olmbdb_list = ldap_get_values_len(st->ld, e, "olmBDBDNCache")) != + NULL) { + olmbdb_data = *olmbdb_list[0]; + ssnprintf(typeinst, sizeof(typeinst), "bdbdncache-%s", + nc_data.bv_val); + cldap_submit_gauge("cache_size", typeinst, atoll(olmbdb_data.bv_val), + st); + ldap_value_free_len(olmbdb_list); + } + + if ((olmbdb_list = ldap_get_values_len(st->ld, e, "olmBDBIDLCache")) != + NULL) { + olmbdb_data = *olmbdb_list[0]; + ssnprintf(typeinst, sizeof(typeinst), "bdbidlcache-%s", + nc_data.bv_val); + cldap_submit_gauge("cache_size", typeinst, atoll(olmbdb_data.bv_val), + st); + ldap_value_free_len(olmbdb_list); + } + + ldap_value_free_len(nc_list); + } else if (strcmp(dn, "cn=Bytes,cn=Statistics,cn=Monitor") == 0) { + cldap_submit_derive("derive", "statistics-bytes", counter, st); + } else if (strcmp(dn, "cn=PDU,cn=Statistics,cn=Monitor") == 0) { + cldap_submit_derive("derive", "statistics-pdu", counter, st); + } else if (strcmp(dn, "cn=Entries,cn=Statistics,cn=Monitor") == 0) { + cldap_submit_derive("derive", "statistics-entries", counter, st); + } else if (strcmp(dn, "cn=Referrals,cn=Statistics,cn=Monitor") == 0) { + cldap_submit_derive("derive", "statistics-referrals", counter, st); + } else if (strcmp(dn, "cn=Open,cn=Threads,cn=Monitor") == 0) { + cldap_submit_gauge("threads", "threads-open", info, st); + } else if (strcmp(dn, "cn=Starting,cn=Threads,cn=Monitor") == 0) { + cldap_submit_gauge("threads", "threads-starting", info, st); + } else if (strcmp(dn, "cn=Active,cn=Threads,cn=Monitor") == 0) { + cldap_submit_gauge("threads", "threads-active", info, st); + } else if (strcmp(dn, "cn=Pending,cn=Threads,cn=Monitor") == 0) { + cldap_submit_gauge("threads", "threads-pending", info, st); + } else if (strcmp(dn, "cn=Backload,cn=Threads,cn=Monitor") == 0) { + cldap_submit_gauge("threads", "threads-backload", info, st); + } else if (strcmp(dn, "cn=Read,cn=Waiters,cn=Monitor") == 0) { + cldap_submit_derive("derive", "waiters-read", counter, st); + } else if (strcmp(dn, "cn=Write,cn=Waiters,cn=Monitor") == 0) { + cldap_submit_derive("derive", "waiters-write", counter, st); + } + + ldap_value_free_len(counter_list); + ldap_value_free_len(opc_list); + ldap_value_free_len(opi_list); + ldap_value_free_len(info_list); + } + + ldap_memfree(dn); + } + + ldap_msgfree(result); + return (0); } /* }}} int cldap_read_host */ /* Configuration handling functions {{{ @@ -547,181 +385,165 @@ static int cldap_read_host (user_data_t *ud) /* {{{ */ * */ -static int cldap_config_add (oconfig_item_t *ci) /* {{{ */ +static int cldap_config_add(oconfig_item_t *ci) /* {{{ */ { - cldap_t *st; - int status; - - st = calloc (1, sizeof (*st)); - if (st == NULL) - { - ERROR ("openldap plugin: calloc failed."); - return (-1); - } - - status = cf_util_get_string (ci, &st->name); - if (status != 0) - { - sfree (st); - return (status); - } - - st->starttls = 0; - st->timeout = (long) CDTIME_T_TO_TIME_T(plugin_get_interval()); - st->verifyhost = 1; - st->version = LDAP_VERSION3; - - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("BindDN", child->key) == 0) - status = cf_util_get_string (child, &st->binddn); - else if (strcasecmp ("Password", child->key) == 0) - status = cf_util_get_string (child, &st->password); - else if (strcasecmp ("CACert", child->key) == 0) - status = cf_util_get_string (child, &st->cacert); - else if (strcasecmp ("StartTLS", child->key) == 0) - status = cf_util_get_boolean (child, &st->starttls); - else if (strcasecmp ("Timeout", child->key) == 0) - status = cf_util_get_int (child, &st->timeout); - else if (strcasecmp ("URL", child->key) == 0) - status = cf_util_get_string (child, &st->url); - else if (strcasecmp ("VerifyHost", child->key) == 0) - status = cf_util_get_boolean (child, &st->verifyhost); - else if (strcasecmp ("Version", child->key) == 0) - status = cf_util_get_int (child, &st->version); - else - { - WARNING ("openldap plugin: Option `%s' not allowed here.", - child->key); - status = -1; - } - - if (status != 0) - break; - } - - /* Check if struct is complete.. */ - if ((status == 0) && (st->url == NULL)) - { - ERROR ("openldap plugin: Instance `%s': " - "No URL has been configured.", - st->name); - status = -1; - } - - /* Check if URL is valid */ - if ((status == 0) && (st->url != NULL)) - { - LDAPURLDesc *ludpp; - - if (ldap_url_parse (st->url, &ludpp) != 0) - { - ERROR ("openldap plugin: Instance `%s': " - "Invalid URL: `%s'", - st->name, st->url); - status = -1; - } - - if ((status == 0) && (ludpp->lud_host != NULL)) - st->host = strdup (ludpp->lud_host); - - ldap_free_urldesc (ludpp); - } - - if (status == 0) - { - cldap_t **temp; - - temp = (cldap_t **) realloc (databases, - sizeof (*databases) * (databases_num + 1)); - - if (temp == NULL) - { - ERROR ("openldap plugin: realloc failed"); - status = -1; - } - else - { - char callback_name[3*DATA_MAX_NAME_LEN] = { 0 }; - - databases = temp; - databases[databases_num] = st; - databases_num++; - - ssnprintf (callback_name, sizeof (callback_name), - "openldap/%s/%s", - (st->host != NULL) ? st->host : hostname_g, - (st->name != NULL) ? st->name : "default"); - - status = plugin_register_complex_read (/* group = */ NULL, - /* name = */ callback_name, - /* callback = */ cldap_read_host, - /* interval = */ 0, - &(user_data_t) { - .data = st, - }); - } - } - - if (status != 0) - { - cldap_free (st); - return (-1); - } - - return (0); + cldap_t *st; + int status; + + st = calloc(1, sizeof(*st)); + if (st == NULL) { + ERROR("openldap plugin: calloc failed."); + return (-1); + } + + status = cf_util_get_string(ci, &st->name); + if (status != 0) { + sfree(st); + return (status); + } + + st->starttls = 0; + st->timeout = (long)CDTIME_T_TO_TIME_T(plugin_get_interval()); + st->verifyhost = 1; + st->version = LDAP_VERSION3; + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("BindDN", child->key) == 0) + status = cf_util_get_string(child, &st->binddn); + else if (strcasecmp("Password", child->key) == 0) + status = cf_util_get_string(child, &st->password); + else if (strcasecmp("CACert", child->key) == 0) + status = cf_util_get_string(child, &st->cacert); + else if (strcasecmp("StartTLS", child->key) == 0) + status = cf_util_get_boolean(child, &st->starttls); + else if (strcasecmp("Timeout", child->key) == 0) + status = cf_util_get_int(child, &st->timeout); + else if (strcasecmp("URL", child->key) == 0) + status = cf_util_get_string(child, &st->url); + else if (strcasecmp("VerifyHost", child->key) == 0) + status = cf_util_get_boolean(child, &st->verifyhost); + else if (strcasecmp("Version", child->key) == 0) + status = cf_util_get_int(child, &st->version); + else { + WARNING("openldap plugin: Option `%s' not allowed here.", child->key); + status = -1; + } + + if (status != 0) + break; + } + + /* Check if struct is complete.. */ + if ((status == 0) && (st->url == NULL)) { + ERROR("openldap plugin: Instance `%s': " + "No URL has been configured.", + st->name); + status = -1; + } + + /* Check if URL is valid */ + if ((status == 0) && (st->url != NULL)) { + LDAPURLDesc *ludpp; + + if (ldap_url_parse(st->url, &ludpp) != 0) { + ERROR("openldap plugin: Instance `%s': " + "Invalid URL: `%s'", + st->name, st->url); + status = -1; + } + + if ((status == 0) && (ludpp->lud_host != NULL)) + st->host = strdup(ludpp->lud_host); + + ldap_free_urldesc(ludpp); + } + + if (status == 0) { + cldap_t **temp; + + temp = (cldap_t **)realloc(databases, + sizeof(*databases) * (databases_num + 1)); + + if (temp == NULL) { + ERROR("openldap plugin: realloc failed"); + status = -1; + } else { + char callback_name[3 * DATA_MAX_NAME_LEN] = {0}; + + databases = temp; + databases[databases_num] = st; + databases_num++; + + ssnprintf(callback_name, sizeof(callback_name), "openldap/%s/%s", + (st->host != NULL) ? st->host : hostname_g, + (st->name != NULL) ? st->name : "default"); + + status = plugin_register_complex_read(/* group = */ NULL, + /* name = */ callback_name, + /* callback = */ cldap_read_host, + /* interval = */ 0, &(user_data_t){ + .data = st, + }); + } + } + + if (status != 0) { + cldap_free(st); + return (-1); + } + + return (0); } /* }}} int cldap_config_add */ -static int cldap_config (oconfig_item_t *ci) /* {{{ */ +static int cldap_config(oconfig_item_t *ci) /* {{{ */ { - int status = 0; - - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("Instance", child->key) == 0) - cldap_config_add (child); - else - WARNING ("openldap plugin: The configuration option " - "\"%s\" is not allowed here. Did you " - "forget to add an block " - "around the configuration?", - child->key); - } /* for (ci->children) */ - - return (status); + int status = 0; + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Instance", child->key) == 0) + cldap_config_add(child); + else + WARNING("openldap plugin: The configuration option " + "\"%s\" is not allowed here. Did you " + "forget to add an block " + "around the configuration?", + child->key); + } /* for (ci->children) */ + + return (status); } /* }}} int cldap_config */ /* }}} End of configuration handling functions */ -static int cldap_init (void) /* {{{ */ +static int cldap_init(void) /* {{{ */ { - /* Initialize LDAP library while still single-threaded as recommended in - * ldap_initialize(3) */ - int debug_level; - ldap_get_option (NULL, LDAP_OPT_DEBUG_LEVEL, &debug_level); - return (0); + /* Initialize LDAP library while still single-threaded as recommended in + * ldap_initialize(3) */ + int debug_level; + ldap_get_option(NULL, LDAP_OPT_DEBUG_LEVEL, &debug_level); + return (0); } /* }}} int cldap_init */ -static int cldap_shutdown (void) /* {{{ */ +static int cldap_shutdown(void) /* {{{ */ { - for (size_t i = 0; i < databases_num; i++) - if (databases[i]->ld != NULL) - ldap_unbind_ext_s (databases[i]->ld, NULL, NULL); - sfree (databases); - databases_num = 0; + for (size_t i = 0; i < databases_num; i++) + if (databases[i]->ld != NULL) + ldap_unbind_ext_s(databases[i]->ld, NULL, NULL); + sfree(databases); + databases_num = 0; - return (0); + return (0); } /* }}} int cldap_shutdown */ -void module_register (void) /* {{{ */ +void module_register(void) /* {{{ */ { - plugin_register_complex_config ("openldap", cldap_config); - plugin_register_init ("openldap", cldap_init); - plugin_register_shutdown ("openldap", cldap_shutdown); + plugin_register_complex_config("openldap", cldap_config); + plugin_register_init("openldap", cldap_init); + plugin_register_shutdown("openldap", cldap_shutdown); } /* }}} void module_register */ #if defined(__APPLE__) diff --git a/src/openvpn.c b/src/openvpn.c index 50670c53..90694b78 100644 --- a/src/openvpn.c +++ b/src/openvpn.c @@ -30,25 +30,29 @@ #include "common.h" #include "plugin.h" -#define V1STRING "Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since\n" -#define V2STRING "HEADER,CLIENT_LIST,Common Name,Real Address,Virtual Address,Bytes Received,Bytes Sent,Connected Since,Connected Since (time_t)\n" -#define V3STRING "HEADER CLIENT_LIST Common Name Real Address Virtual Address Bytes Received Bytes Sent Connected Since Connected Since (time_t)\n" -#define V4STRING "HEADER,CLIENT_LIST,Common Name,Real Address,Virtual Address,Bytes Received,Bytes Sent,Connected Since,Connected Since (time_t),Username\n" +#define V1STRING \ + "Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since\n" +#define V2STRING \ + "HEADER,CLIENT_LIST,Common Name,Real Address,Virtual Address,Bytes " \ + "Received,Bytes Sent,Connected Since,Connected Since (time_t)\n" +#define V3STRING \ + "HEADER CLIENT_LIST Common Name Real Address Virtual Address Bytes " \ + "Received Bytes Sent Connected Since Connected Since (time_t)\n" +#define V4STRING \ + "HEADER,CLIENT_LIST,Common Name,Real Address,Virtual Address,Bytes " \ + "Received,Bytes Sent,Connected Since,Connected Since (time_t),Username\n" #define VSSTRING "OpenVPN STATISTICS\n" - -struct vpn_status_s -{ - char *file; - enum - { - MULTI1 = 1, /* status-version 1 */ - MULTI2, /* status-version 2 */ - MULTI3, /* status-version 3 */ - MULTI4, /* status-version 4 */ - SINGLE = 10 /* currently no versions for single mode, maybe in the future */ - } version; - char *name; +struct vpn_status_s { + char *file; + enum { + MULTI1 = 1, /* status-version 1 */ + MULTI2, /* status-version 2 */ + MULTI3, /* status-version 3 */ + MULTI4, /* status-version 4 */ + SINGLE = 10 /* currently no versions for single mode, maybe in the future */ + } version; + char *name; }; typedef struct vpn_status_s vpn_status_t; @@ -57,758 +61,659 @@ static int vpn_num = 0; static _Bool new_naming_schema = 0; static _Bool collect_compression = 1; -static _Bool collect_user_count = 0; -static _Bool collect_individual_users = 1; - -static const char *config_keys[] = -{ - "StatusFile", - "Compression", /* old, deprecated name */ - "ImprovedNamingSchema", - "CollectCompression", - "CollectUserCount", - "CollectIndividualUsers" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static _Bool collect_user_count = 0; +static _Bool collect_individual_users = 1; +static const char *config_keys[] = { + "StatusFile", "Compression", /* old, deprecated name */ + "ImprovedNamingSchema", "CollectCompression", + "CollectUserCount", "CollectIndividualUsers"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); /* Helper function * copy-n-pasted from common.c - changed delim to "," */ -static int openvpn_strsplit (char *string, char **fields, size_t size) -{ - size_t i; - char *ptr; - char *saveptr; - - i = 0; - ptr = string; - saveptr = NULL; - while ((fields[i] = strtok_r (ptr, ",", &saveptr)) != NULL) - { - ptr = NULL; - i++; - - if (i >= size) - break; - } - - return (i); +static int openvpn_strsplit(char *string, char **fields, size_t size) { + size_t i; + char *ptr; + char *saveptr; + + i = 0; + ptr = string; + saveptr = NULL; + while ((fields[i] = strtok_r(ptr, ",", &saveptr)) != NULL) { + ptr = NULL; + i++; + + if (i >= size) + break; + } + + return (i); } /* int openvpn_strsplit */ /* dispatches number of users */ -static void numusers_submit (const char *pinst, const char *tinst, - gauge_t value) -{ - value_list_t vl = VALUE_LIST_INIT; - - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "openvpn", sizeof (vl.plugin)); - sstrncpy (vl.type, "users", sizeof (vl.type)); - if (pinst != NULL) - sstrncpy (vl.plugin_instance, pinst, sizeof (vl.plugin_instance)); - if (tinst != NULL) - sstrncpy (vl.type_instance, tinst, sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); +static void numusers_submit(const char *pinst, const char *tinst, + gauge_t value) { + value_list_t vl = VALUE_LIST_INIT; + + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "openvpn", sizeof(vl.plugin)); + sstrncpy(vl.type, "users", sizeof(vl.type)); + if (pinst != NULL) + sstrncpy(vl.plugin_instance, pinst, sizeof(vl.plugin_instance)); + if (tinst != NULL) + sstrncpy(vl.type_instance, tinst, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); } /* void numusers_submit */ /* dispatches stats about traffic (TCP or UDP) generated by the tunnel * per single endpoint */ -static void iostats_submit (const char *pinst, const char *tinst, - derive_t rx, derive_t tx) -{ - value_list_t vl = VALUE_LIST_INIT; - value_t values[] = { - { .derive = rx }, - { .derive = tx }, +static void iostats_submit(const char *pinst, const char *tinst, derive_t rx, + derive_t tx) { + value_list_t vl = VALUE_LIST_INIT; + value_t values[] = { + {.derive = rx}, {.derive = tx}, }; - /* NOTE ON THE NEW NAMING SCHEMA: - * using plugin_instance to identify each vpn config (and - * status) file; using type_instance to identify the endpoint - * host when in multimode, traffic or overhead when in single. - */ - - vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - sstrncpy (vl.plugin, "openvpn", sizeof (vl.plugin)); - if (pinst != NULL) - sstrncpy (vl.plugin_instance, pinst, - sizeof (vl.plugin_instance)); - sstrncpy (vl.type, "if_octets", sizeof (vl.type)); - if (tinst != NULL) - sstrncpy (vl.type_instance, tinst, sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); + /* NOTE ON THE NEW NAMING SCHEMA: + * using plugin_instance to identify each vpn config (and + * status) file; using type_instance to identify the endpoint + * host when in multimode, traffic or overhead when in single. + */ + + vl.values = values; + vl.values_len = STATIC_ARRAY_SIZE(values); + sstrncpy(vl.plugin, "openvpn", sizeof(vl.plugin)); + if (pinst != NULL) + sstrncpy(vl.plugin_instance, pinst, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "if_octets", sizeof(vl.type)); + if (tinst != NULL) + sstrncpy(vl.type_instance, tinst, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); } /* void traffic_submit */ /* dispatches stats about data compression shown when in single mode */ -static void compression_submit (const char *pinst, const char *tinst, - derive_t uncompressed, derive_t compressed) -{ - value_list_t vl = VALUE_LIST_INIT; - value_t values[] = { - { .derive = uncompressed }, - { .derive = compressed }, +static void compression_submit(const char *pinst, const char *tinst, + derive_t uncompressed, derive_t compressed) { + value_list_t vl = VALUE_LIST_INIT; + value_t values[] = { + {.derive = uncompressed}, {.derive = compressed}, }; - vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - sstrncpy (vl.plugin, "openvpn", sizeof (vl.plugin)); - if (pinst != NULL) - sstrncpy (vl.plugin_instance, pinst, - sizeof (vl.plugin_instance)); - sstrncpy (vl.type, "compression", sizeof (vl.type)); - if (tinst != NULL) - sstrncpy (vl.type_instance, tinst, sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); + vl.values = values; + vl.values_len = STATIC_ARRAY_SIZE(values); + sstrncpy(vl.plugin, "openvpn", sizeof(vl.plugin)); + if (pinst != NULL) + sstrncpy(vl.plugin_instance, pinst, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "compression", sizeof(vl.type)); + if (tinst != NULL) + sstrncpy(vl.type_instance, tinst, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); } /* void compression_submit */ -static int single_read (const char *name, FILE *fh) -{ - char buffer[1024]; - char *fields[4]; - const int max_fields = STATIC_ARRAY_SIZE (fields); - int fields_num, read = 0; - - derive_t link_rx, link_tx; - derive_t tun_rx, tun_tx; - derive_t pre_compress, post_compress; - derive_t pre_decompress, post_decompress; - derive_t overhead_rx, overhead_tx; - - link_rx = 0; - link_tx = 0; - tun_rx = 0; - tun_tx = 0; - pre_compress = 0; - post_compress = 0; - pre_decompress = 0; - post_decompress = 0; - - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - fields_num = openvpn_strsplit (buffer, fields, max_fields); - - /* status file is generated by openvpn/sig.c:print_status() - * http://svn.openvpn.net/projects/openvpn/trunk/openvpn/sig.c - * - * The line we're expecting has 2 fields. We ignore all lines - * with more or less fields. - */ - if (fields_num != 2) - { - continue; - } - - if (strcmp (fields[0], "TUN/TAP read bytes") == 0) - { - /* read from the system and sent over the tunnel */ - tun_tx = atoll (fields[1]); - } - else if (strcmp (fields[0], "TUN/TAP write bytes") == 0) - { - /* read from the tunnel and written in the system */ - tun_rx = atoll (fields[1]); - } - else if (strcmp (fields[0], "TCP/UDP read bytes") == 0) - { - link_rx = atoll (fields[1]); - } - else if (strcmp (fields[0], "TCP/UDP write bytes") == 0) - { - link_tx = atoll (fields[1]); - } - else if (strcmp (fields[0], "pre-compress bytes") == 0) - { - pre_compress = atoll (fields[1]); - } - else if (strcmp (fields[0], "post-compress bytes") == 0) - { - post_compress = atoll (fields[1]); - } - else if (strcmp (fields[0], "pre-decompress bytes") == 0) - { - pre_decompress = atoll (fields[1]); - } - else if (strcmp (fields[0], "post-decompress bytes") == 0) - { - post_decompress = atoll (fields[1]); - } - } - - iostats_submit (name, "traffic", link_rx, link_tx); - - /* we need to force this order to avoid negative values with these unsigned */ - overhead_rx = (((link_rx - pre_decompress) + post_decompress) - tun_rx); - overhead_tx = (((link_tx - post_compress) + pre_compress) - tun_tx); - - iostats_submit (name, "overhead", overhead_rx, overhead_tx); - - if (collect_compression) - { - compression_submit (name, "data_in", post_decompress, pre_decompress); - compression_submit (name, "data_out", pre_compress, post_compress); - } - - read = 1; - - return (read); +static int single_read(const char *name, FILE *fh) { + char buffer[1024]; + char *fields[4]; + const int max_fields = STATIC_ARRAY_SIZE(fields); + int fields_num, read = 0; + + derive_t link_rx, link_tx; + derive_t tun_rx, tun_tx; + derive_t pre_compress, post_compress; + derive_t pre_decompress, post_decompress; + derive_t overhead_rx, overhead_tx; + + link_rx = 0; + link_tx = 0; + tun_rx = 0; + tun_tx = 0; + pre_compress = 0; + post_compress = 0; + pre_decompress = 0; + post_decompress = 0; + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + fields_num = openvpn_strsplit(buffer, fields, max_fields); + + /* status file is generated by openvpn/sig.c:print_status() + * http://svn.openvpn.net/projects/openvpn/trunk/openvpn/sig.c + * + * The line we're expecting has 2 fields. We ignore all lines + * with more or less fields. + */ + if (fields_num != 2) { + continue; + } + + if (strcmp(fields[0], "TUN/TAP read bytes") == 0) { + /* read from the system and sent over the tunnel */ + tun_tx = atoll(fields[1]); + } else if (strcmp(fields[0], "TUN/TAP write bytes") == 0) { + /* read from the tunnel and written in the system */ + tun_rx = atoll(fields[1]); + } else if (strcmp(fields[0], "TCP/UDP read bytes") == 0) { + link_rx = atoll(fields[1]); + } else if (strcmp(fields[0], "TCP/UDP write bytes") == 0) { + link_tx = atoll(fields[1]); + } else if (strcmp(fields[0], "pre-compress bytes") == 0) { + pre_compress = atoll(fields[1]); + } else if (strcmp(fields[0], "post-compress bytes") == 0) { + post_compress = atoll(fields[1]); + } else if (strcmp(fields[0], "pre-decompress bytes") == 0) { + pre_decompress = atoll(fields[1]); + } else if (strcmp(fields[0], "post-decompress bytes") == 0) { + post_decompress = atoll(fields[1]); + } + } + + iostats_submit(name, "traffic", link_rx, link_tx); + + /* we need to force this order to avoid negative values with these unsigned */ + overhead_rx = (((link_rx - pre_decompress) + post_decompress) - tun_rx); + overhead_tx = (((link_tx - post_compress) + pre_compress) - tun_tx); + + iostats_submit(name, "overhead", overhead_rx, overhead_tx); + + if (collect_compression) { + compression_submit(name, "data_in", post_decompress, pre_decompress); + compression_submit(name, "data_out", pre_compress, post_compress); + } + + read = 1; + + return (read); } /* int single_read */ /* for reading status version 1 */ -static int multi1_read (const char *name, FILE *fh) -{ - char buffer[1024]; - char *fields[10]; - int fields_num, found_header = 0; - long long sum_users = 0; - - /* read the file until the "ROUTING TABLE" line is found (no more info after) */ - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - if (strcmp (buffer, "ROUTING TABLE\n") == 0) - break; - - if (strcmp (buffer, V1STRING) == 0) - { - found_header = 1; - continue; - } - - /* skip the first lines until the client list section is found */ - if (found_header == 0) - /* we can't start reading data until this string is found */ - continue; - - fields_num = openvpn_strsplit (buffer, - fields, STATIC_ARRAY_SIZE (fields)); - if (fields_num < 4) - continue; - - if (collect_user_count) - /* If so, sum all users, ignore the individuals*/ - { - sum_users += 1; - } - if (collect_individual_users) - { - if (new_naming_schema) - { - iostats_submit (name, /* vpn instance */ - fields[0], /* "Common Name" */ - atoll (fields[2]), /* "Bytes Received" */ - atoll (fields[3])); /* "Bytes Sent" */ - } - else - { - iostats_submit (fields[0], /* "Common Name" */ - NULL, /* unused when in multimode */ - atoll (fields[2]), /* "Bytes Received" */ - atoll (fields[3])); /* "Bytes Sent" */ - } - } - } - - if (ferror (fh)) - return (0); - - if (collect_user_count) - numusers_submit(name, name, sum_users); - - return (1); +static int multi1_read(const char *name, FILE *fh) { + char buffer[1024]; + char *fields[10]; + int fields_num, found_header = 0; + long long sum_users = 0; + + /* read the file until the "ROUTING TABLE" line is found (no more info after) + */ + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + if (strcmp(buffer, "ROUTING TABLE\n") == 0) + break; + + if (strcmp(buffer, V1STRING) == 0) { + found_header = 1; + continue; + } + + /* skip the first lines until the client list section is found */ + if (found_header == 0) + /* we can't start reading data until this string is found */ + continue; + + fields_num = openvpn_strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + if (fields_num < 4) + continue; + + if (collect_user_count) + /* If so, sum all users, ignore the individuals*/ + { + sum_users += 1; + } + if (collect_individual_users) { + if (new_naming_schema) { + iostats_submit(name, /* vpn instance */ + fields[0], /* "Common Name" */ + atoll(fields[2]), /* "Bytes Received" */ + atoll(fields[3])); /* "Bytes Sent" */ + } else { + iostats_submit(fields[0], /* "Common Name" */ + NULL, /* unused when in multimode */ + atoll(fields[2]), /* "Bytes Received" */ + atoll(fields[3])); /* "Bytes Sent" */ + } + } + } + + if (ferror(fh)) + return (0); + + if (collect_user_count) + numusers_submit(name, name, sum_users); + + return (1); } /* int multi1_read */ /* for reading status version 2 */ -static int multi2_read (const char *name, FILE *fh) -{ - char buffer[1024]; - char *fields[10]; - const int max_fields = STATIC_ARRAY_SIZE (fields); - int fields_num, read = 0; - long long sum_users = 0; - - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - fields_num = openvpn_strsplit (buffer, fields, max_fields); - - /* status file is generated by openvpn/multi.c:multi_print_status() - * http://svn.openvpn.net/projects/openvpn/trunk/openvpn/multi.c - * - * The line we're expecting has 8 fields. We ignore all lines - * with more or less fields. - */ - if (fields_num != 8) - continue; - - if (strcmp (fields[0], "CLIENT_LIST") != 0) - continue; - - if (collect_user_count) - /* If so, sum all users, ignore the individuals*/ - { - sum_users += 1; - } - if (collect_individual_users) - { - if (new_naming_schema) - { - /* plugin inst = file name, type inst = fields[1] */ - iostats_submit (name, /* vpn instance */ - fields[1], /* "Common Name" */ - atoll (fields[4]), /* "Bytes Received" */ - atoll (fields[5])); /* "Bytes Sent" */ - } - else - { - /* plugin inst = fields[1], type inst = "" */ - iostats_submit (fields[1], /* "Common Name" */ - NULL, /* unused when in multimode */ - atoll (fields[4]), /* "Bytes Received" */ - atoll (fields[5])); /* "Bytes Sent" */ - } - } - - read = 1; - } - - if (collect_user_count) - { - numusers_submit(name, name, sum_users); - read = 1; - } - - return (read); +static int multi2_read(const char *name, FILE *fh) { + char buffer[1024]; + char *fields[10]; + const int max_fields = STATIC_ARRAY_SIZE(fields); + int fields_num, read = 0; + long long sum_users = 0; + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + fields_num = openvpn_strsplit(buffer, fields, max_fields); + + /* status file is generated by openvpn/multi.c:multi_print_status() + * http://svn.openvpn.net/projects/openvpn/trunk/openvpn/multi.c + * + * The line we're expecting has 8 fields. We ignore all lines + * with more or less fields. + */ + if (fields_num != 8) + continue; + + if (strcmp(fields[0], "CLIENT_LIST") != 0) + continue; + + if (collect_user_count) + /* If so, sum all users, ignore the individuals*/ + { + sum_users += 1; + } + if (collect_individual_users) { + if (new_naming_schema) { + /* plugin inst = file name, type inst = fields[1] */ + iostats_submit(name, /* vpn instance */ + fields[1], /* "Common Name" */ + atoll(fields[4]), /* "Bytes Received" */ + atoll(fields[5])); /* "Bytes Sent" */ + } else { + /* plugin inst = fields[1], type inst = "" */ + iostats_submit(fields[1], /* "Common Name" */ + NULL, /* unused when in multimode */ + atoll(fields[4]), /* "Bytes Received" */ + atoll(fields[5])); /* "Bytes Sent" */ + } + } + + read = 1; + } + + if (collect_user_count) { + numusers_submit(name, name, sum_users); + read = 1; + } + + return (read); } /* int multi2_read */ /* for reading status version 3 */ -static int multi3_read (const char *name, FILE *fh) -{ - char buffer[1024]; - char *fields[15]; - const int max_fields = STATIC_ARRAY_SIZE (fields); - int fields_num, read = 0; - long long sum_users = 0; - - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - fields_num = strsplit (buffer, fields, max_fields); - - /* status file is generated by openvpn/multi.c:multi_print_status() - * http://svn.openvpn.net/projects/openvpn/trunk/openvpn/multi.c - * - * The line we're expecting has 12 fields. We ignore all lines - * with more or less fields. - */ - if (fields_num != 12) - { - continue; - } - else - { - if (strcmp (fields[0], "CLIENT_LIST") != 0) - continue; - - if (collect_user_count) - /* If so, sum all users, ignore the individuals*/ - { - sum_users += 1; - } - - if (collect_individual_users) - { - if (new_naming_schema) - { - iostats_submit (name, /* vpn instance */ - fields[1], /* "Common Name" */ - atoll (fields[4]), /* "Bytes Received" */ - atoll (fields[5])); /* "Bytes Sent" */ - } - else - { - iostats_submit (fields[1], /* "Common Name" */ - NULL, /* unused when in multimode */ - atoll (fields[4]), /* "Bytes Received" */ - atoll (fields[5])); /* "Bytes Sent" */ - } - } - - read = 1; - } - } - - if (collect_user_count) - { - numusers_submit(name, name, sum_users); - read = 1; - } - - return (read); +static int multi3_read(const char *name, FILE *fh) { + char buffer[1024]; + char *fields[15]; + const int max_fields = STATIC_ARRAY_SIZE(fields); + int fields_num, read = 0; + long long sum_users = 0; + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + fields_num = strsplit(buffer, fields, max_fields); + + /* status file is generated by openvpn/multi.c:multi_print_status() + * http://svn.openvpn.net/projects/openvpn/trunk/openvpn/multi.c + * + * The line we're expecting has 12 fields. We ignore all lines + * with more or less fields. + */ + if (fields_num != 12) { + continue; + } else { + if (strcmp(fields[0], "CLIENT_LIST") != 0) + continue; + + if (collect_user_count) + /* If so, sum all users, ignore the individuals*/ + { + sum_users += 1; + } + + if (collect_individual_users) { + if (new_naming_schema) { + iostats_submit(name, /* vpn instance */ + fields[1], /* "Common Name" */ + atoll(fields[4]), /* "Bytes Received" */ + atoll(fields[5])); /* "Bytes Sent" */ + } else { + iostats_submit(fields[1], /* "Common Name" */ + NULL, /* unused when in multimode */ + atoll(fields[4]), /* "Bytes Received" */ + atoll(fields[5])); /* "Bytes Sent" */ + } + } + + read = 1; + } + } + + if (collect_user_count) { + numusers_submit(name, name, sum_users); + read = 1; + } + + return (read); } /* int multi3_read */ /* for reading status version 4 */ -static int multi4_read (const char *name, FILE *fh) -{ - char buffer[1024]; - char *fields[11]; - const int max_fields = STATIC_ARRAY_SIZE (fields); - int fields_num, read = 0; - long long sum_users = 0; - - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - fields_num = openvpn_strsplit (buffer, fields, max_fields); - - /* status file is generated by openvpn/multi.c:multi_print_status() - * http://svn.openvpn.net/projects/openvpn/trunk/openvpn/multi.c - * - * The line we're expecting has 9 fields. We ignore all lines - * with more or less fields. - */ - if (fields_num != 9) - continue; - - - if (strcmp (fields[0], "CLIENT_LIST") != 0) - continue; - - - if (collect_user_count) - /* If so, sum all users, ignore the individuals*/ - { - sum_users += 1; - } - if (collect_individual_users) - { - if (new_naming_schema) - { - /* plugin inst = file name, type inst = fields[1] */ - iostats_submit (name, /* vpn instance */ - fields[1], /* "Common Name" */ - atoll (fields[4]), /* "Bytes Received" */ - atoll (fields[5])); /* "Bytes Sent" */ - } - else - { - /* plugin inst = fields[1], type inst = "" */ - iostats_submit (fields[1], /* "Common Name" */ - NULL, /* unused when in multimode */ - atoll (fields[4]), /* "Bytes Received" */ - atoll (fields[5])); /* "Bytes Sent" */ - } - } - - read = 1; - } - - if (collect_user_count) - { - numusers_submit(name, name, sum_users); - read = 1; - } - - return (read); +static int multi4_read(const char *name, FILE *fh) { + char buffer[1024]; + char *fields[11]; + const int max_fields = STATIC_ARRAY_SIZE(fields); + int fields_num, read = 0; + long long sum_users = 0; + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + fields_num = openvpn_strsplit(buffer, fields, max_fields); + + /* status file is generated by openvpn/multi.c:multi_print_status() + * http://svn.openvpn.net/projects/openvpn/trunk/openvpn/multi.c + * + * The line we're expecting has 9 fields. We ignore all lines + * with more or less fields. + */ + if (fields_num != 9) + continue; + + if (strcmp(fields[0], "CLIENT_LIST") != 0) + continue; + + if (collect_user_count) + /* If so, sum all users, ignore the individuals*/ + { + sum_users += 1; + } + if (collect_individual_users) { + if (new_naming_schema) { + /* plugin inst = file name, type inst = fields[1] */ + iostats_submit(name, /* vpn instance */ + fields[1], /* "Common Name" */ + atoll(fields[4]), /* "Bytes Received" */ + atoll(fields[5])); /* "Bytes Sent" */ + } else { + /* plugin inst = fields[1], type inst = "" */ + iostats_submit(fields[1], /* "Common Name" */ + NULL, /* unused when in multimode */ + atoll(fields[4]), /* "Bytes Received" */ + atoll(fields[5])); /* "Bytes Sent" */ + } + } + + read = 1; + } + + if (collect_user_count) { + numusers_submit(name, name, sum_users); + read = 1; + } + + return (read); } /* int multi4_read */ /* read callback */ -static int openvpn_read (void) -{ - FILE *fh; - int read; - - read = 0; - - if (vpn_num == 0) - return (0); - - /* call the right read function for every status entry in the list */ - for (int i = 0; i < vpn_num; i++) - { - int vpn_read = 0; - - fh = fopen (vpn_list[i]->file, "r"); - if (fh == NULL) - { - char errbuf[1024]; - WARNING ("openvpn plugin: fopen(%s) failed: %s", vpn_list[i]->file, - sstrerror (errno, errbuf, sizeof (errbuf))); - - continue; - } - - switch (vpn_list[i]->version) - { - case SINGLE: - vpn_read = single_read(vpn_list[i]->name, fh); - break; - - case MULTI1: - vpn_read = multi1_read(vpn_list[i]->name, fh); - break; - - case MULTI2: - vpn_read = multi2_read(vpn_list[i]->name, fh); - break; - - case MULTI3: - vpn_read = multi3_read(vpn_list[i]->name, fh); - break; - - case MULTI4: - vpn_read = multi4_read(vpn_list[i]->name, fh); - break; - } - - fclose (fh); - read += vpn_read; - } - - return (read ? 0 : -1); +static int openvpn_read(void) { + FILE *fh; + int read; + + read = 0; + + if (vpn_num == 0) + return (0); + + /* call the right read function for every status entry in the list */ + for (int i = 0; i < vpn_num; i++) { + int vpn_read = 0; + + fh = fopen(vpn_list[i]->file, "r"); + if (fh == NULL) { + char errbuf[1024]; + WARNING("openvpn plugin: fopen(%s) failed: %s", vpn_list[i]->file, + sstrerror(errno, errbuf, sizeof(errbuf))); + + continue; + } + + switch (vpn_list[i]->version) { + case SINGLE: + vpn_read = single_read(vpn_list[i]->name, fh); + break; + + case MULTI1: + vpn_read = multi1_read(vpn_list[i]->name, fh); + break; + + case MULTI2: + vpn_read = multi2_read(vpn_list[i]->name, fh); + break; + + case MULTI3: + vpn_read = multi3_read(vpn_list[i]->name, fh); + break; + + case MULTI4: + vpn_read = multi4_read(vpn_list[i]->name, fh); + break; + } + + fclose(fh); + read += vpn_read; + } + + return (read ? 0 : -1); } /* int openvpn_read */ -static int version_detect (const char *filename) -{ - FILE *fh; - char buffer[1024]; - int version = 0; - - /* Sanity checking. We're called from the config handling routine, so - * better play it save. */ - if ((filename == NULL) || (*filename == 0)) - return (0); - - fh = fopen (filename, "r"); - if (fh == NULL) - { - char errbuf[1024]; - WARNING ("openvpn plugin: Unable to read \"%s\": %s", filename, - sstrerror (errno, errbuf, sizeof (errbuf))); - return (0); - } - - /* now search for the specific multimode data format */ - while ((fgets (buffer, sizeof (buffer), fh)) != NULL) - { - /* we look at the first line searching for SINGLE mode configuration */ - if (strcmp (buffer, VSSTRING) == 0) - { - DEBUG ("openvpn plugin: found status file version SINGLE"); - version = SINGLE; - break; - } - /* searching for multi version 1 */ - else if (strcmp (buffer, V1STRING) == 0) - { - DEBUG ("openvpn plugin: found status file version MULTI1"); - version = MULTI1; - break; - } - /* searching for multi version 2 */ - else if (strcmp (buffer, V2STRING) == 0) - { - DEBUG ("openvpn plugin: found status file version MULTI2"); - version = MULTI2; - break; - } - /* searching for multi version 3 */ - else if (strcmp (buffer, V3STRING) == 0) - { - DEBUG ("openvpn plugin: found status file version MULTI3"); - version = MULTI3; - break; - } - /* searching for multi version 4 */ - else if (strcmp (buffer, V4STRING) == 0) - { - DEBUG ("openvpn plugin: found status file version MULTI4"); - version = MULTI4; - break; - } - } - - if (version == 0) - { - /* This is only reached during configuration, so complaining to - * the user is in order. */ - NOTICE ("openvpn plugin: %s: Unknown file format, please " - "report this as bug. Make sure to include " - "your status file, so the plugin can " - "be adapted.", filename); - } - - fclose (fh); - - return version; +static int version_detect(const char *filename) { + FILE *fh; + char buffer[1024]; + int version = 0; + + /* Sanity checking. We're called from the config handling routine, so + * better play it save. */ + if ((filename == NULL) || (*filename == 0)) + return (0); + + fh = fopen(filename, "r"); + if (fh == NULL) { + char errbuf[1024]; + WARNING("openvpn plugin: Unable to read \"%s\": %s", filename, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (0); + } + + /* now search for the specific multimode data format */ + while ((fgets(buffer, sizeof(buffer), fh)) != NULL) { + /* we look at the first line searching for SINGLE mode configuration */ + if (strcmp(buffer, VSSTRING) == 0) { + DEBUG("openvpn plugin: found status file version SINGLE"); + version = SINGLE; + break; + } + /* searching for multi version 1 */ + else if (strcmp(buffer, V1STRING) == 0) { + DEBUG("openvpn plugin: found status file version MULTI1"); + version = MULTI1; + break; + } + /* searching for multi version 2 */ + else if (strcmp(buffer, V2STRING) == 0) { + DEBUG("openvpn plugin: found status file version MULTI2"); + version = MULTI2; + break; + } + /* searching for multi version 3 */ + else if (strcmp(buffer, V3STRING) == 0) { + DEBUG("openvpn plugin: found status file version MULTI3"); + version = MULTI3; + break; + } + /* searching for multi version 4 */ + else if (strcmp(buffer, V4STRING) == 0) { + DEBUG("openvpn plugin: found status file version MULTI4"); + version = MULTI4; + break; + } + } + + if (version == 0) { + /* This is only reached during configuration, so complaining to + * the user is in order. */ + NOTICE("openvpn plugin: %s: Unknown file format, please " + "report this as bug. Make sure to include " + "your status file, so the plugin can " + "be adapted.", + filename); + } + + fclose(fh); + + return version; } /* int version_detect */ -static int openvpn_config (const char *key, const char *value) -{ - if (strcasecmp ("StatusFile", key) == 0) - { - char *status_file, *status_name, *filename; - int status_version; - vpn_status_t *temp; - - /* try to detect the status file format */ - status_version = version_detect (value); - - if (status_version == 0) - { - WARNING ("openvpn plugin: unable to detect status version, " - "discarding status file \"%s\".", value); - return (1); - } - - status_file = sstrdup (value); - if (status_file == NULL) - { - char errbuf[1024]; - WARNING ("openvpn plugin: sstrdup failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (1); - } - - /* it determines the file name as string starting at location filename + 1 */ - filename = strrchr (status_file, (int) '/'); - if (filename == NULL) - { - /* status_file is already the file name only */ - status_name = status_file; - } - else - { - /* doesn't waste memory, uses status_file starting at filename + 1 */ - status_name = filename + 1; - } - - /* scan the list looking for a clone */ - for (int i = 0; i < vpn_num; i++) - { - if (strcasecmp (vpn_list[i]->name, status_name) == 0) - { - WARNING ("openvpn plugin: status filename \"%s\" " - "already used, please choose a " - "different one.", status_name); - sfree (status_file); - return (1); - } - } - - /* create a new vpn element since file, version and name are ok */ - temp = malloc (sizeof (*temp)); - if (temp == NULL) - { - char errbuf[1024]; - ERROR ("openvpn plugin: malloc failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - sfree (status_file); - return (1); - } - temp->file = status_file; - temp->version = status_version; - temp->name = status_name; - - vpn_status_t **tmp_list = realloc (vpn_list, (vpn_num + 1) * sizeof (*vpn_list)); - if (tmp_list == NULL) - { - char errbuf[1024]; - ERROR ("openvpn plugin: realloc failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - - sfree (vpn_list); - sfree (temp->file); - sfree (temp); - return (1); - } - vpn_list = tmp_list; - - vpn_list[vpn_num] = temp; - vpn_num++; - - DEBUG ("openvpn plugin: status file \"%s\" added", temp->file); - - } /* if (strcasecmp ("StatusFile", key) == 0) */ - else if ((strcasecmp ("CollectCompression", key) == 0) - || (strcasecmp ("Compression", key) == 0)) /* old, deprecated name */ - { - if (IS_FALSE (value)) - collect_compression = 0; - else - collect_compression = 1; - } /* if (strcasecmp ("CollectCompression", key) == 0) */ - else if (strcasecmp ("ImprovedNamingSchema", key) == 0) - { - if (IS_TRUE (value)) - { - DEBUG ("openvpn plugin: using the new naming schema"); - new_naming_schema = 1; - } - else - { - new_naming_schema = 0; - } - } /* if (strcasecmp ("ImprovedNamingSchema", key) == 0) */ - else if (strcasecmp("CollectUserCount", key) == 0) - { - if (IS_TRUE(value)) - collect_user_count = 1; - else - collect_user_count = 0; - } /* if (strcasecmp("CollectUserCount", key) == 0) */ - else if (strcasecmp("CollectIndividualUsers", key) == 0) - { - if (IS_FALSE (value)) - collect_individual_users = 0; - else - collect_individual_users = 1; - } /* if (strcasecmp("CollectIndividualUsers", key) == 0) */ - else - { - return (-1); - } - - return (0); +static int openvpn_config(const char *key, const char *value) { + if (strcasecmp("StatusFile", key) == 0) { + char *status_file, *status_name, *filename; + int status_version; + vpn_status_t *temp; + + /* try to detect the status file format */ + status_version = version_detect(value); + + if (status_version == 0) { + WARNING("openvpn plugin: unable to detect status version, " + "discarding status file \"%s\".", + value); + return (1); + } + + status_file = sstrdup(value); + if (status_file == NULL) { + char errbuf[1024]; + WARNING("openvpn plugin: sstrdup failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (1); + } + + /* it determines the file name as string starting at location filename + 1 + */ + filename = strrchr(status_file, (int)'/'); + if (filename == NULL) { + /* status_file is already the file name only */ + status_name = status_file; + } else { + /* doesn't waste memory, uses status_file starting at filename + 1 */ + status_name = filename + 1; + } + + /* scan the list looking for a clone */ + for (int i = 0; i < vpn_num; i++) { + if (strcasecmp(vpn_list[i]->name, status_name) == 0) { + WARNING("openvpn plugin: status filename \"%s\" " + "already used, please choose a " + "different one.", + status_name); + sfree(status_file); + return (1); + } + } + + /* create a new vpn element since file, version and name are ok */ + temp = malloc(sizeof(*temp)); + if (temp == NULL) { + char errbuf[1024]; + ERROR("openvpn plugin: malloc failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + sfree(status_file); + return (1); + } + temp->file = status_file; + temp->version = status_version; + temp->name = status_name; + + vpn_status_t **tmp_list = + realloc(vpn_list, (vpn_num + 1) * sizeof(*vpn_list)); + if (tmp_list == NULL) { + char errbuf[1024]; + ERROR("openvpn plugin: realloc failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + + sfree(vpn_list); + sfree(temp->file); + sfree(temp); + return (1); + } + vpn_list = tmp_list; + + vpn_list[vpn_num] = temp; + vpn_num++; + + DEBUG("openvpn plugin: status file \"%s\" added", temp->file); + + } /* if (strcasecmp ("StatusFile", key) == 0) */ + else if ((strcasecmp("CollectCompression", key) == 0) || + (strcasecmp("Compression", key) == 0)) /* old, deprecated name */ + { + if (IS_FALSE(value)) + collect_compression = 0; + else + collect_compression = 1; + } /* if (strcasecmp ("CollectCompression", key) == 0) */ + else if (strcasecmp("ImprovedNamingSchema", key) == 0) { + if (IS_TRUE(value)) { + DEBUG("openvpn plugin: using the new naming schema"); + new_naming_schema = 1; + } else { + new_naming_schema = 0; + } + } /* if (strcasecmp ("ImprovedNamingSchema", key) == 0) */ + else if (strcasecmp("CollectUserCount", key) == 0) { + if (IS_TRUE(value)) + collect_user_count = 1; + else + collect_user_count = 0; + } /* if (strcasecmp("CollectUserCount", key) == 0) */ + else if (strcasecmp("CollectIndividualUsers", key) == 0) { + if (IS_FALSE(value)) + collect_individual_users = 0; + else + collect_individual_users = 1; + } /* if (strcasecmp("CollectIndividualUsers", key) == 0) */ + else { + return (-1); + } + + return (0); } /* int openvpn_config */ /* shutdown callback */ -static int openvpn_shutdown (void) -{ - for (int i = 0; i < vpn_num; i++) - { - sfree (vpn_list[i]->file); - sfree (vpn_list[i]); - } +static int openvpn_shutdown(void) { + for (int i = 0; i < vpn_num; i++) { + sfree(vpn_list[i]->file); + sfree(vpn_list[i]); + } - sfree (vpn_list); + sfree(vpn_list); - return (0); + return (0); } /* int openvpn_shutdown */ -static int openvpn_init (void) -{ - if (!collect_individual_users - && !collect_compression - && !collect_user_count) - { - WARNING ("OpenVPN plugin: Neither `CollectIndividualUsers', " - "`CollectCompression', nor `CollectUserCount' is true. There's no " - "data left to collect."); - return (-1); - } - - plugin_register_read ("openvpn", openvpn_read); - plugin_register_shutdown ("openvpn", openvpn_shutdown); - - return (0); +static int openvpn_init(void) { + if (!collect_individual_users && !collect_compression && + !collect_user_count) { + WARNING("OpenVPN plugin: Neither `CollectIndividualUsers', " + "`CollectCompression', nor `CollectUserCount' is true. There's no " + "data left to collect."); + return (-1); + } + + plugin_register_read("openvpn", openvpn_read); + plugin_register_shutdown("openvpn", openvpn_shutdown); + + return (0); } /* int openvpn_init */ -void module_register (void) -{ - plugin_register_config ("openvpn", openvpn_config, - config_keys, config_keys_num); - plugin_register_init ("openvpn", openvpn_init); +void module_register(void) { + plugin_register_config("openvpn", openvpn_config, config_keys, + config_keys_num); + plugin_register_init("openvpn", openvpn_init); } /* void module_register */ /* vim: set sw=2 ts=2 : */ diff --git a/src/oracle.c b/src/oracle.c index c0f2fa41..4eacc543 100644 --- a/src/oracle.c +++ b/src/oracle.c @@ -56,8 +56,7 @@ /* * Data types */ -struct o_database_s -{ +struct o_database_s { char *name; char *host; char *connect_id; @@ -66,7 +65,7 @@ struct o_database_s udb_query_preparation_area_t **q_prep_areas; udb_query_t **queries; - size_t queries_num; + size_t queries_num; OCISvcCtx *oci_service_context; }; @@ -75,21 +74,20 @@ typedef struct o_database_s o_database_t; /* * Global variables */ -static udb_query_t **queries = NULL; -static size_t queries_num = 0; -static o_database_t **databases = NULL; -static size_t databases_num = 0; +static udb_query_t **queries = NULL; +static size_t queries_num = 0; +static o_database_t **databases = NULL; +static size_t databases_num = 0; -OCIEnv *oci_env = NULL; +OCIEnv *oci_env = NULL; 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) -{ +static void o_report_error(const char *where, /* {{{ */ + const char *db_name, const char *query_name, + const char *what, OCIError *eh) { char buffer[2048]; sb4 error_code; int status; @@ -101,63 +99,55 @@ static void o_report_error (const char *where, /* {{{ */ /* An operation may cause / return multiple errors. Loop until we have * handled all errors available (with a fail-save limit of 16). */ - for (unsigned int record_number = 1; record_number <= 16; record_number++) - { - memset (buffer, 0, sizeof (buffer)); + for (unsigned int record_number = 1; record_number <= 16; record_number++) { + memset(buffer, 0, sizeof(buffer)); error_code = -1; - status = OCIErrorGet (eh, (ub4) record_number, - /* sqlstate = */ NULL, - &error_code, - (text *) &buffer[0], - (ub4) sizeof (buffer), - OCI_HTYPE_ERROR); - buffer[sizeof (buffer) - 1] = 0; + status = OCIErrorGet(eh, (ub4)record_number, + /* sqlstate = */ NULL, &error_code, (text *)&buffer[0], + (ub4)sizeof(buffer), OCI_HTYPE_ERROR); + buffer[sizeof(buffer) - 1] = 0; if (status == OCI_NO_DATA) return; - if (status == OCI_SUCCESS) - { + if (status == OCI_SUCCESS) { size_t buffer_length; - buffer_length = strlen (buffer); - while ((buffer_length > 0) && (buffer[buffer_length - 1] < 32)) - { + buffer_length = strlen(buffer); + while ((buffer_length > 0) && (buffer[buffer_length - 1] < 32)) { buffer_length--; buffer[buffer_length] = 0; } - ERROR ("oracle plugin: %s (db = %s, query = %s): %s failed: %s", - where, db_name, query_name, what, buffer); - } - else - { - ERROR ("oracle plugin: %s (db = %s, query = %s): %s failed. " - "Additionally, OCIErrorGet failed with status %i.", - where, db_name, query_name, what, status); + ERROR("oracle plugin: %s (db = %s, query = %s): %s failed: %s", where, + db_name, query_name, what, buffer); + } else { + ERROR("oracle plugin: %s (db = %s, query = %s): %s failed. " + "Additionally, OCIErrorGet failed with status %i.", + where, db_name, query_name, what, status); return; } } } /* }}} void o_report_error */ -static void o_database_free (o_database_t *db) /* {{{ */ +static void o_database_free(o_database_t *db) /* {{{ */ { if (db == NULL) return; - sfree (db->name); - sfree (db->connect_id); - sfree (db->username); - sfree (db->password); - sfree (db->queries); + sfree(db->name); + sfree(db->connect_id); + sfree(db->username); + sfree(db->password); + sfree(db->queries); if (db->q_prep_areas != NULL) for (size_t i = 0; i < db->queries_num; ++i) - udb_query_delete_preparation_area (db->q_prep_areas[i]); - free (db->q_prep_areas); + udb_query_delete_preparation_area(db->q_prep_areas[i]); + free(db->q_prep_areas); - sfree (db); + sfree(db); } /* }}} void o_database_free */ /* Configuration handling functions {{{ @@ -181,23 +171,20 @@ static void o_database_free (o_database_t *db) /* {{{ */ * */ -static int o_config_add_database (oconfig_item_t *ci) /* {{{ */ +static int o_config_add_database(oconfig_item_t *ci) /* {{{ */ { o_database_t *db; int status; - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("oracle plugin: The `Database' block " - "needs exactly one string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("oracle plugin: The `Database' block " + "needs exactly one string argument."); return (-1); } - db = calloc (1, sizeof (*db)); - if (db == NULL) - { - ERROR ("oracle plugin: calloc failed."); + db = calloc(1, sizeof(*db)); + if (db == NULL) { + ERROR("oracle plugin: calloc failed."); return (-1); } db->name = NULL; @@ -206,32 +193,29 @@ static int o_config_add_database (oconfig_item_t *ci) /* {{{ */ db->username = NULL; db->password = NULL; - status = cf_util_get_string (ci, &db->name); - if (status != 0) - { - sfree (db); + status = cf_util_get_string(ci, &db->name); + if (status != 0) { + sfree(db); return (status); } /* Fill the `o_database_t' structure.. */ - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("ConnectID", child->key) == 0) - status = cf_util_get_string (child, &db->connect_id); - else if (strcasecmp ("Host", child->key) == 0) - status = cf_util_get_string (child, &db->host); - else if (strcasecmp ("Username", child->key) == 0) - status = cf_util_get_string (child, &db->username); - else if (strcasecmp ("Password", child->key) == 0) - status = cf_util_get_string (child, &db->password); - else if (strcasecmp ("Query", child->key) == 0) - status = udb_query_pick_from_list (child, queries, queries_num, - &db->queries, &db->queries_num); - else - { - WARNING ("oracle plugin: Option `%s' not allowed here.", child->key); + if (strcasecmp("ConnectID", child->key) == 0) + status = cf_util_get_string(child, &db->connect_id); + else if (strcasecmp("Host", child->key) == 0) + status = cf_util_get_string(child, &db->host); + else if (strcasecmp("Username", child->key) == 0) + status = cf_util_get_string(child, &db->username); + else if (strcasecmp("Password", child->key) == 0) + status = cf_util_get_string(child, &db->password); + else if (strcasecmp("Query", child->key) == 0) + status = udb_query_pick_from_list(child, queries, queries_num, + &db->queries, &db->queries_num); + else { + WARNING("oracle plugin: Option `%s' not allowed here.", child->key); status = -1; } @@ -240,47 +224,38 @@ static int o_config_add_database (oconfig_item_t *ci) /* {{{ */ } /* Check that all necessary options have been given. */ - while (status == 0) - { - if (db->connect_id == NULL) - { - WARNING ("oracle plugin: `ConnectID' not given for query `%s'", db->name); + while (status == 0) { + if (db->connect_id == NULL) { + WARNING("oracle plugin: `ConnectID' not given for query `%s'", db->name); status = -1; } - if (db->username == NULL) - { - WARNING ("oracle plugin: `Username' not given for query `%s'", db->name); + if (db->username == NULL) { + WARNING("oracle plugin: `Username' not given for query `%s'", db->name); status = -1; } - if (db->password == NULL) - { - WARNING ("oracle plugin: `Password' not given for query `%s'", db->name); + if (db->password == NULL) { + WARNING("oracle plugin: `Password' not given for query `%s'", db->name); status = -1; } break; } /* while (status == 0) */ - while ((status == 0) && (db->queries_num > 0)) - { - db->q_prep_areas = (udb_query_preparation_area_t **) calloc ( - db->queries_num, sizeof (*db->q_prep_areas)); + while ((status == 0) && (db->queries_num > 0)) { + db->q_prep_areas = (udb_query_preparation_area_t **)calloc( + db->queries_num, sizeof(*db->q_prep_areas)); - if (db->q_prep_areas == NULL) - { - WARNING ("oracle plugin: calloc failed"); + if (db->q_prep_areas == NULL) { + WARNING("oracle plugin: calloc failed"); status = -1; break; } - for (int i = 0; i < db->queries_num; ++i) - { - db->q_prep_areas[i] - = udb_query_allocate_preparation_area (db->queries[i]); + for (int i = 0; i < db->queries_num; ++i) { + db->q_prep_areas[i] = udb_query_allocate_preparation_area(db->queries[i]); - if (db->q_prep_areas[i] == NULL) - { - WARNING ("oracle plugin: udb_query_allocate_preparation_area failed"); + if (db->q_prep_areas[i] == NULL) { + WARNING("oracle plugin: udb_query_allocate_preparation_area failed"); status = -1; break; } @@ -291,53 +266,47 @@ static int o_config_add_database (oconfig_item_t *ci) /* {{{ */ /* If all went well, add this query to the list of queries within the * database structure. */ - if (status == 0) - { + if (status == 0) { o_database_t **temp; - temp = realloc (databases, - sizeof (*databases) * (databases_num + 1)); - if (temp == NULL) - { - ERROR ("oracle plugin: realloc failed"); + temp = realloc(databases, sizeof(*databases) * (databases_num + 1)); + if (temp == NULL) { + ERROR("oracle plugin: realloc failed"); status = -1; - } - else - { + } else { databases = temp; databases[databases_num] = db; databases_num++; } } - if (status != 0) - { - o_database_free (db); + if (status != 0) { + o_database_free(db); return (-1); } return (0); } /* }}} int o_config_add_database */ -static int o_config (oconfig_item_t *ci) /* {{{ */ +static int o_config(oconfig_item_t *ci) /* {{{ */ { - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Query", child->key) == 0) - udb_query_create (&queries, &queries_num, child, - /* callback = */ NULL); - else if (strcasecmp ("Database", child->key) == 0) - o_config_add_database (child); - else - { - WARNING ("oracle plugin: Ignoring unknown config option `%s'.", child->key); + if (strcasecmp("Query", child->key) == 0) + udb_query_create(&queries, &queries_num, child, + /* callback = */ NULL); + else if (strcasecmp("Database", child->key) == 0) + o_config_add_database(child); + else { + WARNING("oracle plugin: Ignoring unknown config option `%s'.", + child->key); } - if (queries_num > 0) - { - DEBUG ("oracle plugin: o_config: queries_num = %zu; queries[0] = %p; udb_query_get_user_data (queries[0]) = %p;", - queries_num, (void *) queries[0], udb_query_get_user_data (queries[0])); + if (queries_num > 0) { + DEBUG("oracle plugin: o_config: queries_num = %zu; queries[0] = %p; " + "udb_query_get_user_data (queries[0]) = %p;", + queries_num, (void *)queries[0], + udb_query_get_user_data(queries[0])); } } /* for (ci->children) */ @@ -346,42 +315,41 @@ static int o_config (oconfig_item_t *ci) /* {{{ */ /* }}} End of configuration handling functions */ -static int o_init (void) /* {{{ */ +static int o_init(void) /* {{{ */ { int status; if (oci_env != NULL) return (0); - status = OCIEnvCreate (&oci_env, - /* mode = */ OCI_THREADED, - /* context = */ NULL, - /* malloc = */ NULL, - /* realloc = */ NULL, - /* free = */ NULL, - /* user_data_size = */ 0, - /* user_data_ptr = */ NULL); - if (status != 0) - { - ERROR ("oracle plugin: OCIEnvCreate failed with status %i.", status); + status = OCIEnvCreate(&oci_env, + /* mode = */ OCI_THREADED, + /* context = */ NULL, + /* malloc = */ NULL, + /* realloc = */ NULL, + /* free = */ NULL, + /* user_data_size = */ 0, + /* user_data_ptr = */ NULL); + if (status != 0) { + ERROR("oracle plugin: OCIEnvCreate failed with status %i.", status); return (-1); } - status = OCIHandleAlloc (oci_env, (void *) &oci_error, OCI_HTYPE_ERROR, - /* user_data_size = */ 0, /* user_data = */ NULL); - if (status != OCI_SUCCESS) - { - ERROR ("oracle plugin: OCIHandleAlloc (OCI_HTYPE_ERROR) failed " - "with status %i.", status); + status = OCIHandleAlloc(oci_env, (void *)&oci_error, OCI_HTYPE_ERROR, + /* user_data_size = */ 0, /* user_data = */ NULL); + if (status != OCI_SUCCESS) { + ERROR("oracle plugin: OCIHandleAlloc (OCI_HTYPE_ERROR) failed " + "with status %i.", + status); return (-1); } return (0); } /* }}} int o_init */ -static int o_read_database_query (o_database_t *db, /* {{{ */ - udb_query_t *q, udb_query_preparation_area_t *prep_area) -{ +static int o_read_database_query(o_database_t *db, /* {{{ */ + udb_query_t *q, + udb_query_preparation_area_t *prep_area) { char **column_names; char **column_values; size_t column_num; @@ -394,59 +362,55 @@ static int o_read_database_query (o_database_t *db, /* {{{ */ int status; - oci_statement = udb_query_get_user_data (q); + oci_statement = udb_query_get_user_data(q); /* Prepare the statement */ if (oci_statement == NULL) /* {{{ */ { const char *statement; - statement = udb_query_get_statement (q); - assert (statement != NULL); + statement = udb_query_get_statement(q); + assert(statement != NULL); - status = OCIHandleAlloc (oci_env, (void *) &oci_statement, - OCI_HTYPE_STMT, /* user_data_size = */ 0, /* user_data = */ NULL); - if (status != OCI_SUCCESS) - { - o_report_error ("o_read_database_query", db->name, - udb_query_get_name (q), "OCIHandleAlloc", oci_error); + status = OCIHandleAlloc(oci_env, (void *)&oci_statement, OCI_HTYPE_STMT, + /* user_data_size = */ 0, /* user_data = */ NULL); + if (status != OCI_SUCCESS) { + o_report_error("o_read_database_query", db->name, udb_query_get_name(q), + "OCIHandleAlloc", oci_error); oci_statement = NULL; return (-1); } - status = OCIStmtPrepare (oci_statement, oci_error, - (text *) statement, (ub4) strlen (statement), - /* language = */ OCI_NTV_SYNTAX, - /* mode = */ OCI_DEFAULT); - if (status != OCI_SUCCESS) - { - o_report_error ("o_read_database_query", db->name, - udb_query_get_name (q), "OCIStmtPrepare", oci_error); - OCIHandleFree (oci_statement, OCI_HTYPE_STMT); + status = OCIStmtPrepare(oci_statement, oci_error, (text *)statement, + (ub4)strlen(statement), + /* language = */ OCI_NTV_SYNTAX, + /* mode = */ OCI_DEFAULT); + if (status != OCI_SUCCESS) { + 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); } - udb_query_set_user_data (q, oci_statement); + udb_query_set_user_data(q, oci_statement); - DEBUG ("oracle plugin: o_read_database_query (%s, %s): " - "Successfully allocated statement handle.", - db->name, udb_query_get_name (q)); + DEBUG("oracle plugin: o_read_database_query (%s, %s): " + "Successfully allocated statement handle.", + db->name, udb_query_get_name(q)); } /* }}} */ - assert (oci_statement != NULL); + assert(oci_statement != NULL); /* Execute the statement */ - status = OCIStmtExecute (db->oci_service_context, /* {{{ */ - oci_statement, - oci_error, - /* iters = */ 0, - /* rowoff = */ 0, - /* snap_in = */ NULL, /* snap_out = */ NULL, - /* mode = */ OCI_DEFAULT); - if (status != OCI_SUCCESS) - { - o_report_error ("o_read_database_query", db->name, udb_query_get_name (q), - "OCIStmtExecute", oci_error); + status = OCIStmtExecute(db->oci_service_context, /* {{{ */ + oci_statement, oci_error, + /* iters = */ 0, + /* rowoff = */ 0, + /* snap_in = */ NULL, /* snap_out = */ NULL, + /* mode = */ OCI_DEFAULT); + if (status != OCI_SUCCESS) { + o_report_error("o_read_database_query", db->name, udb_query_get_name(q), + "OCIStmtExecute", oci_error); return (-1); } /* }}} */ @@ -454,72 +418,70 @@ static int o_read_database_query (o_database_t *db, /* {{{ */ do /* {{{ */ { ub4 param_counter = 0; - status = OCIAttrGet (oci_statement, OCI_HTYPE_STMT, /* {{{ */ - ¶m_counter, /* size pointer = */ NULL, - OCI_ATTR_PARAM_COUNT, oci_error); - if (status != OCI_SUCCESS) - { - o_report_error ("o_read_database_query", db->name, - udb_query_get_name (q), "OCIAttrGet", oci_error); + status = OCIAttrGet(oci_statement, OCI_HTYPE_STMT, /* {{{ */ + ¶m_counter, /* size pointer = */ NULL, + OCI_ATTR_PARAM_COUNT, oci_error); + if (status != OCI_SUCCESS) { + o_report_error("o_read_database_query", db->name, udb_query_get_name(q), + "OCIAttrGet", oci_error); return (-1); } /* }}} */ - column_num = (size_t) param_counter; + column_num = (size_t)param_counter; } while (0); /* }}} */ - /* Allocate the following buffers: - * - * +---------------+-----------------------------------+ - * ! Name ! Size ! - * +---------------+-----------------------------------+ - * ! column_names ! column_num x DATA_MAX_NAME_LEN ! - * ! column_values ! column_num x DATA_MAX_NAME_LEN ! - * ! oci_defines ! column_num x sizeof (OCIDefine *) ! - * +---------------+-----------------------------------+ - * - * {{{ */ +/* Allocate the following buffers: + * + * +---------------+-----------------------------------+ + * ! Name ! Size ! + * +---------------+-----------------------------------+ + * ! column_names ! column_num x DATA_MAX_NAME_LEN ! + * ! column_values ! column_num x DATA_MAX_NAME_LEN ! + * ! oci_defines ! column_num x sizeof (OCIDefine *) ! + * +---------------+-----------------------------------+ + * + * {{{ */ #define NUMBER_BUFFER_SIZE 64 -#define FREE_ALL \ - if (column_names != NULL) { \ - sfree (column_names[0]); \ - sfree (column_names); \ - } \ - if (column_values != NULL) { \ - sfree (column_values[0]); \ - sfree (column_values); \ - } \ - sfree (oci_defines) - -#define ALLOC_OR_FAIL(ptr, ptr_size) \ - do { \ - size_t alloc_size = (size_t) ((ptr_size)); \ - (ptr) = calloc (1, alloc_size); \ - if ((ptr) == NULL) { \ - FREE_ALL; \ - ERROR ("oracle plugin: o_read_database_query: calloc failed."); \ - return (-1); \ - } \ +#define FREE_ALL \ + if (column_names != NULL) { \ + sfree(column_names[0]); \ + sfree(column_names); \ + } \ + if (column_values != NULL) { \ + sfree(column_values[0]); \ + sfree(column_values); \ + } \ + sfree(oci_defines) + +#define ALLOC_OR_FAIL(ptr, ptr_size) \ + do { \ + size_t alloc_size = (size_t)((ptr_size)); \ + (ptr) = calloc(1, alloc_size); \ + if ((ptr) == NULL) { \ + FREE_ALL; \ + ERROR("oracle plugin: o_read_database_query: calloc failed."); \ + return (-1); \ + } \ } while (0) /* Initialize everything to NULL so the above works. */ - column_names = NULL; + column_names = NULL; column_values = NULL; - oci_defines = NULL; + oci_defines = NULL; - ALLOC_OR_FAIL (column_names, column_num * sizeof (char *)); - ALLOC_OR_FAIL (column_names[0], column_num * DATA_MAX_NAME_LEN - * sizeof (char)); + ALLOC_OR_FAIL(column_names, column_num * sizeof(char *)); + ALLOC_OR_FAIL(column_names[0], column_num * DATA_MAX_NAME_LEN * sizeof(char)); for (size_t i = 1; i < column_num; i++) column_names[i] = column_names[i - 1] + DATA_MAX_NAME_LEN; - ALLOC_OR_FAIL (column_values, column_num * sizeof (char *)); - ALLOC_OR_FAIL (column_values[0], column_num * DATA_MAX_NAME_LEN - * sizeof (char)); + ALLOC_OR_FAIL(column_values, column_num * sizeof(char *)); + ALLOC_OR_FAIL(column_values[0], + column_num * DATA_MAX_NAME_LEN * sizeof(char)); for (size_t i = 1; i < column_num; i++) column_values[i] = column_values[i - 1] + DATA_MAX_NAME_LEN; - ALLOC_OR_FAIL (oci_defines, column_num * sizeof (OCIDefine *)); + ALLOC_OR_FAIL(oci_defines, column_num * sizeof(OCIDefine *)); /* }}} End of buffer allocations. */ /* ``Define'' the returned data, i. e. bind the columns to the buffers @@ -532,68 +494,63 @@ static int o_read_database_query (o_database_t *db, /* {{{ */ oci_param = NULL; - status = OCIParamGet (oci_statement, OCI_HTYPE_STMT, oci_error, - (void *) &oci_param, (ub4) (i + 1)); - if (status != OCI_SUCCESS) - { + status = OCIParamGet(oci_statement, OCI_HTYPE_STMT, oci_error, + (void *)&oci_param, (ub4)(i + 1)); + 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", db->name, - udb_query_get_name (q), "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; } column_name = NULL; column_name_length = 0; - status = OCIAttrGet (oci_param, OCI_DTYPE_PARAM, - &column_name, &column_name_length, OCI_ATTR_NAME, oci_error); - if (status != OCI_SUCCESS) - { - OCIDescriptorFree (oci_param, OCI_DTYPE_PARAM); - o_report_error ("o_read_database_query", db->name, - udb_query_get_name (q), "OCIAttrGet (OCI_ATTR_NAME)", oci_error); + status = OCIAttrGet(oci_param, OCI_DTYPE_PARAM, &column_name, + &column_name_length, OCI_ATTR_NAME, oci_error); + if (status != OCI_SUCCESS) { + OCIDescriptorFree(oci_param, OCI_DTYPE_PARAM); + o_report_error("o_read_database_query", db->name, udb_query_get_name(q), + "OCIAttrGet (OCI_ATTR_NAME)", oci_error); continue; } - OCIDescriptorFree (oci_param, OCI_DTYPE_PARAM); + OCIDescriptorFree(oci_param, OCI_DTYPE_PARAM); oci_param = NULL; /* Copy the name to column_names. Warning: The ``string'' returned by OCI * may not be null terminated! */ - memset (column_names[i], 0, DATA_MAX_NAME_LEN); + memset(column_names[i], 0, DATA_MAX_NAME_LEN); if (column_name_length >= DATA_MAX_NAME_LEN) column_name_length = DATA_MAX_NAME_LEN - 1; - memcpy (column_names[i], column_name, column_name_length); + memcpy(column_names[i], column_name, column_name_length); column_names[i][column_name_length] = 0; - DEBUG ("oracle plugin: o_read_database_query: column_names[%zu] = %s; " - "column_name_length = %"PRIu32";", - i, column_names[i], (uint32_t) column_name_length); + DEBUG("oracle plugin: o_read_database_query: column_names[%zu] = %s; " + "column_name_length = %" PRIu32 ";", + i, column_names[i], (uint32_t)column_name_length); - status = OCIDefineByPos (oci_statement, - &oci_defines[i], oci_error, (ub4) (i + 1), - column_values[i], DATA_MAX_NAME_LEN, SQLT_STR, - NULL, NULL, NULL, OCI_DEFAULT); - if (status != OCI_SUCCESS) - { - o_report_error ("o_read_database_query", db->name, - udb_query_get_name (q), "OCIDefineByPos", oci_error); + status = OCIDefineByPos(oci_statement, &oci_defines[i], oci_error, + (ub4)(i + 1), column_values[i], DATA_MAX_NAME_LEN, + SQLT_STR, NULL, NULL, NULL, OCI_DEFAULT); + if (status != OCI_SUCCESS) { + 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++) */ /* }}} End of the ``define'' stuff. */ - status = udb_query_prepare_result (q, prep_area, - (db->host != NULL) ? db->host : hostname_g, + status = udb_query_prepare_result( + q, prep_area, (db->host != NULL) ? db->host : hostname_g, /* plugin = */ "oracle", db->name, column_names, column_num, /* interval = */ 0); - if (status != 0) - { - ERROR ("oracle plugin: o_read_database_query (%s, %s): " - "udb_query_prepare_result failed.", - db->name, udb_query_get_name (q)); + if (status != 0) { + ERROR("oracle plugin: o_read_database_query (%s, %s): " + "udb_query_prepare_result failed.", + db->name, udb_query_get_name(q)); FREE_ALL; return (-1); } @@ -601,31 +558,28 @@ static int o_read_database_query (o_database_t *db, /* {{{ */ /* Fetch and handle all the rows that matched the query. */ while (42) /* {{{ */ { - status = OCIStmtFetch2 (oci_statement, oci_error, - /* nrows = */ 1, /* orientation = */ OCI_FETCH_NEXT, - /* fetch offset = */ 0, /* mode = */ OCI_DEFAULT); - if (status == OCI_NO_DATA) - { + status = OCIStmtFetch2(oci_statement, oci_error, + /* nrows = */ 1, /* orientation = */ OCI_FETCH_NEXT, + /* fetch offset = */ 0, /* mode = */ OCI_DEFAULT); + if (status == OCI_NO_DATA) { status = OCI_SUCCESS; break; - } - else if ((status != OCI_SUCCESS) && (status != OCI_SUCCESS_WITH_INFO)) - { - o_report_error ("o_read_database_query", db->name, - udb_query_get_name (q), "OCIStmtFetch2", oci_error); + } else if ((status != OCI_SUCCESS) && (status != OCI_SUCCESS_WITH_INFO)) { + o_report_error("o_read_database_query", db->name, udb_query_get_name(q), + "OCIStmtFetch2", oci_error); break; } - status = udb_query_handle_result (q, prep_area, column_values); - if (status != 0) - { - WARNING ("oracle plugin: o_read_database_query (%s, %s): " - "udb_query_handle_result failed.", - db->name, udb_query_get_name (q)); + status = udb_query_handle_result(q, prep_area, column_values); + if (status != 0) { + WARNING("oracle plugin: o_read_database_query (%s, %s): " + "udb_query_handle_result failed.", + db->name, udb_query_get_name(q)); } } /* }}} while (42) */ - /* DEBUG ("oracle plugin: o_read_database_query: This statement succeeded: %s", q->statement); */ + /* DEBUG ("oracle plugin: o_read_database_query: This statement succeeded: + * %s", q->statement); */ FREE_ALL; return (0); @@ -633,137 +587,124 @@ static int o_read_database_query (o_database_t *db, /* {{{ */ #undef ALLOC_OR_FAIL } /* }}} int o_read_database_query */ -static int o_read_database (o_database_t *db) /* {{{ */ +static int o_read_database(o_database_t *db) /* {{{ */ { int status; - if (db->oci_service_context != NULL) - { + if (db->oci_service_context != NULL) { OCIServer *server_handle; ub4 connection_status; server_handle = NULL; - status = OCIAttrGet ((void *) db->oci_service_context, OCI_HTYPE_SVCCTX, - (void *) &server_handle, /* size pointer = */ NULL, - OCI_ATTR_SERVER, oci_error); - if (status != OCI_SUCCESS) - { - o_report_error ("o_read_database", db->name, NULL, "OCIAttrGet", - oci_error); + status = OCIAttrGet((void *)db->oci_service_context, OCI_HTYPE_SVCCTX, + (void *)&server_handle, /* size pointer = */ NULL, + OCI_ATTR_SERVER, oci_error); + if (status != OCI_SUCCESS) { + o_report_error("o_read_database", db->name, NULL, "OCIAttrGet", + oci_error); return (-1); } - if (server_handle == NULL) - { + if (server_handle == NULL) { connection_status = OCI_SERVER_NOT_CONNECTED; - } - else /* if (server_handle != NULL) */ + } else /* if (server_handle != NULL) */ { connection_status = 0; - status = OCIAttrGet ((void *) server_handle, OCI_HTYPE_SERVER, - (void *) &connection_status, /* size pointer = */ NULL, - OCI_ATTR_SERVER_STATUS, oci_error); - if (status != OCI_SUCCESS) - { - o_report_error ("o_read_database", db->name, NULL, "OCIAttrGet", - oci_error); + status = OCIAttrGet((void *)server_handle, OCI_HTYPE_SERVER, + (void *)&connection_status, /* size pointer = */ NULL, + OCI_ATTR_SERVER_STATUS, oci_error); + if (status != OCI_SUCCESS) { + o_report_error("o_read_database", db->name, NULL, "OCIAttrGet", + oci_error); return (-1); } } - if (connection_status != OCI_SERVER_NORMAL) - { - INFO ("oracle plugin: Connection to %s lost. Trying to reconnect.", - db->name); - OCIHandleFree (db->oci_service_context, OCI_HTYPE_SVCCTX); + if (connection_status != OCI_SERVER_NORMAL) { + INFO("oracle plugin: Connection to %s lost. Trying to reconnect.", + db->name); + OCIHandleFree(db->oci_service_context, OCI_HTYPE_SVCCTX); db->oci_service_context = NULL; } } /* if (db->oci_service_context != NULL) */ - if (db->oci_service_context == NULL) - { - status = OCILogon (oci_env, oci_error, - &db->oci_service_context, - (OraText *) db->username, (ub4) strlen (db->username), - (OraText *) db->password, (ub4) strlen (db->password), - (OraText *) db->connect_id, (ub4) strlen (db->connect_id)); - if ((status != OCI_SUCCESS) && (status != OCI_SUCCESS_WITH_INFO)) - { + if (db->oci_service_context == NULL) { + status = OCILogon(oci_env, oci_error, &db->oci_service_context, + (OraText *)db->username, (ub4)strlen(db->username), + (OraText *)db->password, (ub4)strlen(db->password), + (OraText *)db->connect_id, (ub4)strlen(db->connect_id)); + if ((status != OCI_SUCCESS) && (status != OCI_SUCCESS_WITH_INFO)) { char errfunc[256]; - ssnprintf (errfunc, sizeof (errfunc), "OCILogon(\"%s\")", db->connect_id); + 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); + 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; return (-1); - } - else if (status == OCI_SUCCESS_WITH_INFO) - { + } else if (status == OCI_SUCCESS_WITH_INFO) { /* TODO: Print NOTIFY message. */ } - assert (db->oci_service_context != NULL); + assert(db->oci_service_context != NULL); } - DEBUG ("oracle plugin: o_read_database: db->connect_id = %s; db->oci_service_context = %p;", - db->connect_id, db->oci_service_context); + DEBUG("oracle plugin: o_read_database: db->connect_id = %s; " + "db->oci_service_context = %p;", + db->connect_id, db->oci_service_context); for (size_t i = 0; i < db->queries_num; i++) - o_read_database_query (db, db->queries[i], db->q_prep_areas[i]); + o_read_database_query(db, db->queries[i], db->q_prep_areas[i]); return (0); } /* }}} int o_read_database */ -static int o_read (void) /* {{{ */ +static int o_read(void) /* {{{ */ { size_t i; for (i = 0; i < databases_num; i++) - o_read_database (databases[i]); + o_read_database(databases[i]); return (0); } /* }}} int o_read */ -static int o_shutdown (void) /* {{{ */ +static int o_shutdown(void) /* {{{ */ { size_t i; for (i = 0; i < databases_num; i++) - if (databases[i]->oci_service_context != NULL) - { - OCIHandleFree (databases[i]->oci_service_context, OCI_HTYPE_SVCCTX); + if (databases[i]->oci_service_context != NULL) { + OCIHandleFree(databases[i]->oci_service_context, OCI_HTYPE_SVCCTX); databases[i]->oci_service_context = NULL; } - for (i = 0; i < queries_num; i++) - { + for (i = 0; i < queries_num; i++) { OCIStmt *oci_statement; - oci_statement = udb_query_get_user_data (queries[i]); - if (oci_statement != NULL) - { - OCIHandleFree (oci_statement, OCI_HTYPE_STMT); - udb_query_set_user_data (queries[i], NULL); + oci_statement = udb_query_get_user_data(queries[i]); + if (oci_statement != NULL) { + OCIHandleFree(oci_statement, OCI_HTYPE_STMT); + udb_query_set_user_data(queries[i], NULL); } } - OCIHandleFree (oci_env, OCI_HTYPE_ENV); + OCIHandleFree(oci_env, OCI_HTYPE_ENV); oci_env = NULL; - udb_query_free (queries, queries_num); + udb_query_free(queries, queries_num); queries = NULL; queries_num = 0; return (0); } /* }}} int o_shutdown */ -void module_register (void) /* {{{ */ +void module_register(void) /* {{{ */ { - plugin_register_complex_config ("oracle", o_config); - plugin_register_init ("oracle", o_init); - plugin_register_read ("oracle", o_read); - plugin_register_shutdown ("oracle", o_shutdown); + plugin_register_complex_config("oracle", o_config); + plugin_register_init("oracle", o_init); + plugin_register_read("oracle", o_read); + plugin_register_shutdown("oracle", o_shutdown); } /* }}} void module_register */ /* diff --git a/src/perl.c b/src/perl.c index 4a11d6c1..59109133 100644 --- a/src/perl.c +++ b/src/perl.c @@ -39,142 +39,142 @@ #undef DONT_POISON_SPRINTF_YET #if HAVE_STDBOOL_H -# include +#include #endif #include #include #if defined(COLLECT_DEBUG) && COLLECT_DEBUG && defined(__GNUC__) && __GNUC__ -# undef sprintf -# pragma GCC poison sprintf +#undef sprintf +#pragma GCC poison sprintf #endif #include /* Some versions of Perl define their own version of DEBUG... :-/ */ #ifdef DEBUG -# undef DEBUG +#undef DEBUG #endif /* DEBUG */ /* ... while we want the definition found in plugin.h. */ -#include "plugin.h" #include "common.h" +#include "plugin.h" #include "filter_chain.h" #if !defined(USE_ITHREADS) -# error "Perl does not support ithreads!" +#error "Perl does not support ithreads!" #endif /* !defined(USE_ITHREADS) */ /* clear the Perl sub's stack frame * (this should only be used inside an XSUB) */ #define CLEAR_STACK_FRAME PL_stack_sp = PL_stack_base + *PL_markstack_ptr -#define PLUGIN_INIT 0 -#define PLUGIN_READ 1 -#define PLUGIN_WRITE 2 +#define PLUGIN_INIT 0 +#define PLUGIN_READ 1 +#define PLUGIN_WRITE 2 #define PLUGIN_SHUTDOWN 3 -#define PLUGIN_LOG 4 -#define PLUGIN_NOTIF 5 -#define PLUGIN_FLUSH 6 -#define PLUGIN_FLUSH_ALL 7 /* For collectd-5.6 only */ +#define PLUGIN_LOG 4 +#define PLUGIN_NOTIF 5 +#define PLUGIN_FLUSH 6 +#define PLUGIN_FLUSH_ALL 7 /* For collectd-5.6 only */ -#define PLUGIN_TYPES 8 +#define PLUGIN_TYPES 8 -#define PLUGIN_CONFIG 254 -#define PLUGIN_DATASET 255 +#define PLUGIN_CONFIG 254 +#define PLUGIN_DATASET 255 -#define FC_MATCH 0 +#define FC_MATCH 0 #define FC_TARGET 1 -#define FC_TYPES 2 +#define FC_TYPES 2 -#define FC_CB_CREATE 0 +#define FC_CB_CREATE 0 #define FC_CB_DESTROY 1 -#define FC_CB_EXEC 2 +#define FC_CB_EXEC 2 -#define FC_CB_TYPES 3 +#define FC_CB_TYPES 3 -#define log_debug(...) DEBUG ("perl: " __VA_ARGS__) -#define log_info(...) INFO ("perl: " __VA_ARGS__) -#define log_warn(...) WARNING ("perl: " __VA_ARGS__) -#define log_err(...) ERROR ("perl: " __VA_ARGS__) +#define log_debug(...) DEBUG("perl: " __VA_ARGS__) +#define log_info(...) INFO("perl: " __VA_ARGS__) +#define log_warn(...) WARNING("perl: " __VA_ARGS__) +#define log_err(...) ERROR("perl: " __VA_ARGS__) /* this is defined in DynaLoader.a */ -void boot_DynaLoader (PerlInterpreter *, CV *); - -static XS (Collectd_plugin_register_read); -static XS (Collectd_plugin_register_write); -static XS (Collectd_plugin_register_log); -static XS (Collectd_plugin_register_notification); -static XS (Collectd_plugin_register_flush); -static XS (Collectd_plugin_unregister_read); -static XS (Collectd_plugin_unregister_write); -static XS (Collectd_plugin_unregister_log); -static XS (Collectd_plugin_unregister_notification); -static XS (Collectd_plugin_unregister_flush); -static XS (Collectd_plugin_register_ds); -static XS (Collectd_plugin_unregister_ds); -static XS (Collectd_plugin_dispatch_values); -static XS (Collectd_plugin_get_interval); -static XS (Collectd__plugin_write); -static XS (Collectd__plugin_flush); -static XS (Collectd_plugin_dispatch_notification); -static XS (Collectd_plugin_log); -static XS (Collectd__fc_register); -static XS (Collectd_call_by_name); - -static int perl_read (user_data_t *ud); -static int perl_write (const data_set_t *ds, const value_list_t *vl, - user_data_t *user_data); -static void perl_log (int level, const char *msg, user_data_t *user_data); -static int perl_notify (const notification_t *notif, user_data_t *user_data); -static int perl_flush (cdtime_t timeout, const char *identifier, - user_data_t *user_data); +void boot_DynaLoader(PerlInterpreter *, CV *); + +static XS(Collectd_plugin_register_read); +static XS(Collectd_plugin_register_write); +static XS(Collectd_plugin_register_log); +static XS(Collectd_plugin_register_notification); +static XS(Collectd_plugin_register_flush); +static XS(Collectd_plugin_unregister_read); +static XS(Collectd_plugin_unregister_write); +static XS(Collectd_plugin_unregister_log); +static XS(Collectd_plugin_unregister_notification); +static XS(Collectd_plugin_unregister_flush); +static XS(Collectd_plugin_register_ds); +static XS(Collectd_plugin_unregister_ds); +static XS(Collectd_plugin_dispatch_values); +static XS(Collectd_plugin_get_interval); +static XS(Collectd__plugin_write); +static XS(Collectd__plugin_flush); +static XS(Collectd_plugin_dispatch_notification); +static XS(Collectd_plugin_log); +static XS(Collectd__fc_register); +static XS(Collectd_call_by_name); + +static int perl_read(user_data_t *ud); +static int perl_write(const data_set_t *ds, const value_list_t *vl, + user_data_t *user_data); +static void perl_log(int level, const char *msg, user_data_t *user_data); +static int perl_notify(const notification_t *notif, user_data_t *user_data); +static int perl_flush(cdtime_t timeout, const char *identifier, + user_data_t *user_data); /* * private data types */ typedef struct c_ithread_s { - /* the thread's Perl interpreter */ - PerlInterpreter *interp; - _Bool running; /* thread is inside Perl interpreter */ - _Bool shutdown; - pthread_t pthread; - - /* double linked list of threads */ - struct c_ithread_s *prev; - struct c_ithread_s *next; + /* the thread's Perl interpreter */ + PerlInterpreter *interp; + _Bool running; /* thread is inside Perl interpreter */ + _Bool shutdown; + pthread_t pthread; + + /* double linked list of threads */ + struct c_ithread_s *prev; + struct c_ithread_s *next; } c_ithread_t; typedef struct { - c_ithread_t *head; - c_ithread_t *tail; + c_ithread_t *head; + c_ithread_t *tail; #if COLLECT_DEBUG - /* some usage stats */ - int number_of_threads; + /* some usage stats */ + int number_of_threads; #endif /* COLLECT_DEBUG */ - pthread_mutex_t mutex; - pthread_mutexattr_t mutexattr; + pthread_mutex_t mutex; + pthread_mutexattr_t mutexattr; } c_ithread_list_t; /* name / user_data for Perl matches / targets */ typedef struct { - char *name; - SV *user_data; + char *name; + SV *user_data; } pfc_user_data_t; -#define PFC_USER_DATA_FREE(data) \ - do { \ - sfree ((data)->name); \ - if (NULL != (data)->user_data) \ - sv_free ((data)->user_data); \ - sfree (data); \ - } while (0) +#define PFC_USER_DATA_FREE(data) \ + do { \ + sfree((data)->name); \ + if (NULL != (data)->user_data) \ + sv_free((data)->user_data); \ + sfree(data); \ + } while (0) /* * Public variable @@ -194,89 +194,80 @@ static c_ithread_list_t *perl_threads = NULL; /* the key used to store each pthread's ithread */ static pthread_key_t perl_thr_key; -static int perl_argc = 0; +static int perl_argc = 0; static char **perl_argv = NULL; static char base_name[DATA_MAX_NAME_LEN] = ""; static struct { - char name[64]; - XS ((*f)); -} api[] = -{ - { "Collectd::plugin_register_read", Collectd_plugin_register_read }, - { "Collectd::plugin_register_write", Collectd_plugin_register_write }, - { "Collectd::plugin_register_log", Collectd_plugin_register_log }, - { "Collectd::plugin_register_notification", - Collectd_plugin_register_notification }, - { "Collectd::plugin_register_flush", Collectd_plugin_register_flush }, - { "Collectd::plugin_unregister_read", Collectd_plugin_unregister_read }, - { "Collectd::plugin_unregister_write", Collectd_plugin_unregister_write }, - { "Collectd::plugin_unregister_log", Collectd_plugin_unregister_log }, - { "Collectd::plugin_unregister_notification", - Collectd_plugin_unregister_notification }, - { "Collectd::plugin_unregister_flush", Collectd_plugin_unregister_flush }, - { "Collectd::plugin_register_data_set", Collectd_plugin_register_ds }, - { "Collectd::plugin_unregister_data_set", Collectd_plugin_unregister_ds }, - { "Collectd::plugin_dispatch_values", Collectd_plugin_dispatch_values }, - { "Collectd::plugin_get_interval", Collectd_plugin_get_interval }, - { "Collectd::_plugin_write", Collectd__plugin_write }, - { "Collectd::_plugin_flush", Collectd__plugin_flush }, - { "Collectd::plugin_dispatch_notification", - Collectd_plugin_dispatch_notification }, - { "Collectd::plugin_log", Collectd_plugin_log }, - { "Collectd::_fc_register", Collectd__fc_register }, - { "Collectd::call_by_name", Collectd_call_by_name }, - { "", NULL } -}; + char name[64]; + XS((*f)); +} api[] = { + {"Collectd::plugin_register_read", Collectd_plugin_register_read}, + {"Collectd::plugin_register_write", Collectd_plugin_register_write}, + {"Collectd::plugin_register_log", Collectd_plugin_register_log}, + {"Collectd::plugin_register_notification", + Collectd_plugin_register_notification}, + {"Collectd::plugin_register_flush", Collectd_plugin_register_flush}, + {"Collectd::plugin_unregister_read", Collectd_plugin_unregister_read}, + {"Collectd::plugin_unregister_write", Collectd_plugin_unregister_write}, + {"Collectd::plugin_unregister_log", Collectd_plugin_unregister_log}, + {"Collectd::plugin_unregister_notification", + Collectd_plugin_unregister_notification}, + {"Collectd::plugin_unregister_flush", Collectd_plugin_unregister_flush}, + {"Collectd::plugin_register_data_set", Collectd_plugin_register_ds}, + {"Collectd::plugin_unregister_data_set", Collectd_plugin_unregister_ds}, + {"Collectd::plugin_dispatch_values", Collectd_plugin_dispatch_values}, + {"Collectd::plugin_get_interval", Collectd_plugin_get_interval}, + {"Collectd::_plugin_write", Collectd__plugin_write}, + {"Collectd::_plugin_flush", Collectd__plugin_flush}, + {"Collectd::plugin_dispatch_notification", + Collectd_plugin_dispatch_notification}, + {"Collectd::plugin_log", Collectd_plugin_log}, + {"Collectd::_fc_register", Collectd__fc_register}, + {"Collectd::call_by_name", Collectd_call_by_name}, + {"", NULL}}; struct { - char name[64]; - int value; -} constants[] = -{ - { "Collectd::TYPE_INIT", PLUGIN_INIT }, - { "Collectd::TYPE_READ", PLUGIN_READ }, - { "Collectd::TYPE_WRITE", PLUGIN_WRITE }, - { "Collectd::TYPE_SHUTDOWN", PLUGIN_SHUTDOWN }, - { "Collectd::TYPE_LOG", PLUGIN_LOG }, - { "Collectd::TYPE_NOTIF", PLUGIN_NOTIF }, - { "Collectd::TYPE_FLUSH", PLUGIN_FLUSH }, - { "Collectd::TYPE_CONFIG", PLUGIN_CONFIG }, - { "Collectd::TYPE_DATASET", PLUGIN_DATASET }, - { "Collectd::DS_TYPE_COUNTER", DS_TYPE_COUNTER }, - { "Collectd::DS_TYPE_GAUGE", DS_TYPE_GAUGE }, - { "Collectd::DS_TYPE_DERIVE", DS_TYPE_DERIVE }, - { "Collectd::DS_TYPE_ABSOLUTE", DS_TYPE_ABSOLUTE }, - { "Collectd::LOG_ERR", LOG_ERR }, - { "Collectd::LOG_WARNING", LOG_WARNING }, - { "Collectd::LOG_NOTICE", LOG_NOTICE }, - { "Collectd::LOG_INFO", LOG_INFO }, - { "Collectd::LOG_DEBUG", LOG_DEBUG }, - { "Collectd::FC_MATCH", FC_MATCH }, - { "Collectd::FC_TARGET", FC_TARGET }, - { "Collectd::FC_CB_CREATE", FC_CB_CREATE }, - { "Collectd::FC_CB_DESTROY", FC_CB_DESTROY }, - { "Collectd::FC_CB_EXEC", FC_CB_EXEC }, - { "Collectd::FC_MATCH_NO_MATCH", FC_MATCH_NO_MATCH }, - { "Collectd::FC_MATCH_MATCHES", FC_MATCH_MATCHES }, - { "Collectd::FC_TARGET_CONTINUE", FC_TARGET_CONTINUE }, - { "Collectd::FC_TARGET_STOP", FC_TARGET_STOP }, - { "Collectd::FC_TARGET_RETURN", FC_TARGET_RETURN }, - { "Collectd::NOTIF_FAILURE", NOTIF_FAILURE }, - { "Collectd::NOTIF_WARNING", NOTIF_WARNING }, - { "Collectd::NOTIF_OKAY", NOTIF_OKAY }, - { "", 0 } -}; + char name[64]; + int value; +} constants[] = {{"Collectd::TYPE_INIT", PLUGIN_INIT}, + {"Collectd::TYPE_READ", PLUGIN_READ}, + {"Collectd::TYPE_WRITE", PLUGIN_WRITE}, + {"Collectd::TYPE_SHUTDOWN", PLUGIN_SHUTDOWN}, + {"Collectd::TYPE_LOG", PLUGIN_LOG}, + {"Collectd::TYPE_NOTIF", PLUGIN_NOTIF}, + {"Collectd::TYPE_FLUSH", PLUGIN_FLUSH}, + {"Collectd::TYPE_CONFIG", PLUGIN_CONFIG}, + {"Collectd::TYPE_DATASET", PLUGIN_DATASET}, + {"Collectd::DS_TYPE_COUNTER", DS_TYPE_COUNTER}, + {"Collectd::DS_TYPE_GAUGE", DS_TYPE_GAUGE}, + {"Collectd::DS_TYPE_DERIVE", DS_TYPE_DERIVE}, + {"Collectd::DS_TYPE_ABSOLUTE", DS_TYPE_ABSOLUTE}, + {"Collectd::LOG_ERR", LOG_ERR}, + {"Collectd::LOG_WARNING", LOG_WARNING}, + {"Collectd::LOG_NOTICE", LOG_NOTICE}, + {"Collectd::LOG_INFO", LOG_INFO}, + {"Collectd::LOG_DEBUG", LOG_DEBUG}, + {"Collectd::FC_MATCH", FC_MATCH}, + {"Collectd::FC_TARGET", FC_TARGET}, + {"Collectd::FC_CB_CREATE", FC_CB_CREATE}, + {"Collectd::FC_CB_DESTROY", FC_CB_DESTROY}, + {"Collectd::FC_CB_EXEC", FC_CB_EXEC}, + {"Collectd::FC_MATCH_NO_MATCH", FC_MATCH_NO_MATCH}, + {"Collectd::FC_MATCH_MATCHES", FC_MATCH_MATCHES}, + {"Collectd::FC_TARGET_CONTINUE", FC_TARGET_CONTINUE}, + {"Collectd::FC_TARGET_STOP", FC_TARGET_STOP}, + {"Collectd::FC_TARGET_RETURN", FC_TARGET_RETURN}, + {"Collectd::NOTIF_FAILURE", NOTIF_FAILURE}, + {"Collectd::NOTIF_WARNING", NOTIF_WARNING}, + {"Collectd::NOTIF_OKAY", NOTIF_OKAY}, + {"", 0}}; struct { - char name[64]; - char *var; -} g_strings[] = -{ - { "Collectd::hostname_g", hostname_g }, - { "", NULL } -}; + char name[64]; + char *var; +} g_strings[] = {{"Collectd::hostname_g", hostname_g}, {"", NULL}}; /* * Helper functions for data type conversion. @@ -294,91 +285,87 @@ struct { * ... * ] */ -static int hv2data_source (pTHX_ HV *hash, data_source_t *ds) -{ - SV **tmp = NULL; - - if ((NULL == hash) || (NULL == ds)) - return -1; - - if (NULL != (tmp = hv_fetch (hash, "name", 4, 0))) { - sstrncpy (ds->name, SvPV_nolen (*tmp), sizeof (ds->name)); - } - else { - log_err ("hv2data_source: No DS name given."); - return -1; - } - - if (NULL != (tmp = hv_fetch (hash, "type", 4, 0))) { - ds->type = SvIV (*tmp); - - if ((DS_TYPE_COUNTER != ds->type) - && (DS_TYPE_GAUGE != ds->type) - && (DS_TYPE_DERIVE != ds->type) - && (DS_TYPE_ABSOLUTE != ds->type)) { - log_err ("hv2data_source: Invalid DS type."); - return -1; - } - } - else { - ds->type = DS_TYPE_COUNTER; - } - - if (NULL != (tmp = hv_fetch (hash, "min", 3, 0))) - ds->min = SvNV (*tmp); - else - ds->min = NAN; - - if (NULL != (tmp = hv_fetch (hash, "max", 3, 0))) - ds->max = SvNV (*tmp); - else - ds->max = NAN; - return 0; +static int hv2data_source(pTHX_ HV *hash, data_source_t *ds) { + SV **tmp = NULL; + + if ((NULL == hash) || (NULL == ds)) + return -1; + + if (NULL != (tmp = hv_fetch(hash, "name", 4, 0))) { + sstrncpy(ds->name, SvPV_nolen(*tmp), sizeof(ds->name)); + } else { + log_err("hv2data_source: No DS name given."); + return -1; + } + + if (NULL != (tmp = hv_fetch(hash, "type", 4, 0))) { + ds->type = SvIV(*tmp); + + if ((DS_TYPE_COUNTER != ds->type) && (DS_TYPE_GAUGE != ds->type) && + (DS_TYPE_DERIVE != ds->type) && (DS_TYPE_ABSOLUTE != ds->type)) { + log_err("hv2data_source: Invalid DS type."); + return -1; + } + } else { + ds->type = DS_TYPE_COUNTER; + } + + if (NULL != (tmp = hv_fetch(hash, "min", 3, 0))) + ds->min = SvNV(*tmp); + else + ds->min = NAN; + + if (NULL != (tmp = hv_fetch(hash, "max", 3, 0))) + ds->max = SvNV(*tmp); + else + ds->max = NAN; + return 0; } /* static int hv2data_source (HV *, data_source_t *) */ /* av2value converts at most "len" elements from "array" to "value". Returns the * number of elements converted or zero on error. */ -static size_t av2value (pTHX_ char *name, AV *array, value_t *value, size_t array_len) -{ - const data_set_t *ds; - - if ((NULL == name) || (NULL == array) || (NULL == value) || (array_len == 0)) - return 0; - - ds = plugin_get_ds (name); - if (NULL == ds) { - log_err ("av2value: Unknown dataset \"%s\"", name); - return 0; - } - - if (array_len < ds->ds_num) { - log_warn ("av2value: array does not contain enough elements for type \"%s\": got %zu, want %zu", - name, array_len, ds->ds_num); - return 0; - } else if (array_len > ds->ds_num) { - log_warn ("av2value: array contains excess elements for type \"%s\": got %zu, want %zu", - name, array_len, ds->ds_num); - } - - for (size_t i = 0; i < ds->ds_num; ++i) { - SV **tmp = av_fetch (array, i, 0); - - if (NULL != tmp) { - if (DS_TYPE_COUNTER == ds->ds[i].type) - value[i].counter = SvIV (*tmp); - else if (DS_TYPE_GAUGE == ds->ds[i].type) - value[i].gauge = SvNV (*tmp); - else if (DS_TYPE_DERIVE == ds->ds[i].type) - value[i].derive = SvIV (*tmp); - else if (DS_TYPE_ABSOLUTE == ds->ds[i].type) - value[i].absolute = SvIV (*tmp); - } - else { - return 0; - } - } - - return ds->ds_num; +static size_t av2value(pTHX_ char *name, AV *array, value_t *value, + size_t array_len) { + const data_set_t *ds; + + if ((NULL == name) || (NULL == array) || (NULL == value) || (array_len == 0)) + return 0; + + ds = plugin_get_ds(name); + if (NULL == ds) { + log_err("av2value: Unknown dataset \"%s\"", name); + return 0; + } + + if (array_len < ds->ds_num) { + log_warn("av2value: array does not contain enough elements for type " + "\"%s\": got %zu, want %zu", + name, array_len, ds->ds_num); + return 0; + } else if (array_len > ds->ds_num) { + log_warn("av2value: array contains excess elements for type \"%s\": got " + "%zu, want %zu", + name, array_len, ds->ds_num); + } + + for (size_t i = 0; i < ds->ds_num; ++i) { + SV **tmp = av_fetch(array, i, 0); + + if (NULL != tmp) { + if (DS_TYPE_COUNTER == ds->ds[i].type) + value[i].counter = SvIV(*tmp); + else if (DS_TYPE_GAUGE == ds->ds[i].type) + value[i].gauge = SvNV(*tmp); + else if (DS_TYPE_DERIVE == ds->ds[i].type) + value[i].derive = SvIV(*tmp); + else if (DS_TYPE_ABSOLUTE == ds->ds[i].type) + value[i].absolute = SvIV(*tmp); + } else { + return 0; + } + } + + return ds->ds_num; } /* static size_t av2value (char *, AV *, value_t *, size_t) */ /* @@ -392,111 +379,107 @@ static size_t av2value (pTHX_ char *name, AV *array, value_t *value, size_t arra * type_instance => $tinstance, * } */ -static int hv2value_list (pTHX_ HV *hash, value_list_t *vl) -{ - SV **tmp; - - if ((NULL == hash) || (NULL == vl)) - return -1; - - if (NULL == (tmp = hv_fetch (hash, "type", 4, 0))) { - log_err ("hv2value_list: No type given."); - return -1; - } - - sstrncpy (vl->type, SvPV_nolen (*tmp), sizeof (vl->type)); - - if ((NULL == (tmp = hv_fetch (hash, "values", 6, 0))) - || (! (SvROK (*tmp) && (SVt_PVAV == SvTYPE (SvRV (*tmp)))))) { - log_err ("hv2value_list: No valid values given."); - return -1; - } - - { - AV *array = (AV *)SvRV (*tmp); - /* av_len returns the highest index, not the actual length. */ - size_t array_len = (size_t) (av_len (array) + 1); - if (array_len == 0) - return -1; - - vl->values = calloc (array_len, sizeof (*vl->values)); - vl->values_len = av2value (aTHX_ vl->type, (AV *)SvRV (*tmp), vl->values, array_len); - if (vl->values_len == 0) { - sfree (vl->values); - return -1; - } - } - - if (NULL != (tmp = hv_fetch (hash, "time", 4, 0))) - { - double t = SvNV (*tmp); - vl->time = DOUBLE_TO_CDTIME_T (t); - } - - if (NULL != (tmp = hv_fetch (hash, "interval", 8, 0))) - { - double t = SvNV (*tmp); - vl->interval = DOUBLE_TO_CDTIME_T (t); - } - - if (NULL != (tmp = hv_fetch (hash, "host", 4, 0))) - sstrncpy (vl->host, SvPV_nolen (*tmp), sizeof (vl->host)); - else - sstrncpy (vl->host, hostname_g, sizeof (vl->host)); - - if (NULL != (tmp = hv_fetch (hash, "plugin", 6, 0))) - sstrncpy (vl->plugin, SvPV_nolen (*tmp), sizeof (vl->plugin)); - - if (NULL != (tmp = hv_fetch (hash, "plugin_instance", 15, 0))) - sstrncpy (vl->plugin_instance, SvPV_nolen (*tmp), - sizeof (vl->plugin_instance)); - - if (NULL != (tmp = hv_fetch (hash, "type_instance", 13, 0))) - sstrncpy (vl->type_instance, SvPV_nolen (*tmp), - sizeof (vl->type_instance)); - return 0; +static int hv2value_list(pTHX_ HV *hash, value_list_t *vl) { + SV **tmp; + + if ((NULL == hash) || (NULL == vl)) + return -1; + + if (NULL == (tmp = hv_fetch(hash, "type", 4, 0))) { + log_err("hv2value_list: No type given."); + return -1; + } + + sstrncpy(vl->type, SvPV_nolen(*tmp), sizeof(vl->type)); + + if ((NULL == (tmp = hv_fetch(hash, "values", 6, 0))) || + (!(SvROK(*tmp) && (SVt_PVAV == SvTYPE(SvRV(*tmp)))))) { + log_err("hv2value_list: No valid values given."); + return -1; + } + + { + AV *array = (AV *)SvRV(*tmp); + /* av_len returns the highest index, not the actual length. */ + size_t array_len = (size_t)(av_len(array) + 1); + if (array_len == 0) + return -1; + + vl->values = calloc(array_len, sizeof(*vl->values)); + vl->values_len = + av2value(aTHX_ vl->type, (AV *)SvRV(*tmp), vl->values, array_len); + if (vl->values_len == 0) { + sfree(vl->values); + return -1; + } + } + + if (NULL != (tmp = hv_fetch(hash, "time", 4, 0))) { + double t = SvNV(*tmp); + vl->time = DOUBLE_TO_CDTIME_T(t); + } + + if (NULL != (tmp = hv_fetch(hash, "interval", 8, 0))) { + double t = SvNV(*tmp); + vl->interval = DOUBLE_TO_CDTIME_T(t); + } + + if (NULL != (tmp = hv_fetch(hash, "host", 4, 0))) + sstrncpy(vl->host, SvPV_nolen(*tmp), sizeof(vl->host)); + else + sstrncpy(vl->host, hostname_g, sizeof(vl->host)); + + if (NULL != (tmp = hv_fetch(hash, "plugin", 6, 0))) + sstrncpy(vl->plugin, SvPV_nolen(*tmp), sizeof(vl->plugin)); + + if (NULL != (tmp = hv_fetch(hash, "plugin_instance", 15, 0))) + sstrncpy(vl->plugin_instance, SvPV_nolen(*tmp), + sizeof(vl->plugin_instance)); + + if (NULL != (tmp = hv_fetch(hash, "type_instance", 13, 0))) + sstrncpy(vl->type_instance, SvPV_nolen(*tmp), sizeof(vl->type_instance)); + return 0; } /* static int hv2value_list (pTHX_ HV *, value_list_t *) */ -static int av2data_set (pTHX_ AV *array, char *name, data_set_t *ds) -{ - int len; +static int av2data_set(pTHX_ AV *array, char *name, data_set_t *ds) { + int len; - if ((NULL == array) || (NULL == name) || (NULL == ds)) - return -1; + if ((NULL == array) || (NULL == name) || (NULL == ds)) + return -1; - len = av_len (array); + len = av_len(array); - if (-1 == len) { - log_err ("av2data_set: Invalid data set."); - return -1; - } + if (-1 == len) { + log_err("av2data_set: Invalid data set."); + return -1; + } - ds->ds = smalloc ((len + 1) * sizeof (*ds->ds)); - ds->ds_num = len + 1; + ds->ds = smalloc((len + 1) * sizeof(*ds->ds)); + ds->ds_num = len + 1; - for (int i = 0; i <= len; ++i) { - SV **elem = av_fetch (array, i, 0); + for (int i = 0; i <= len; ++i) { + SV **elem = av_fetch(array, i, 0); - if (NULL == elem) { - log_err ("av2data_set: Failed to fetch data source %i.", i); - return -1; - } + if (NULL == elem) { + log_err("av2data_set: Failed to fetch data source %i.", i); + return -1; + } - if (! (SvROK (*elem) && (SVt_PVHV == SvTYPE (SvRV (*elem))))) { - log_err ("av2data_set: Invalid data source."); - return -1; - } + if (!(SvROK(*elem) && (SVt_PVHV == SvTYPE(SvRV(*elem))))) { + log_err("av2data_set: Invalid data source."); + return -1; + } - if (-1 == hv2data_source (aTHX_ (HV *)SvRV (*elem), &ds->ds[i])) - return -1; + if (-1 == hv2data_source(aTHX_(HV *) SvRV(*elem), &ds->ds[i])) + return -1; - log_debug ("av2data_set: " - "DS.name = \"%s\", DS.type = %i, DS.min = %f, DS.max = %f", - ds->ds[i].name, ds->ds[i].type, ds->ds[i].min, ds->ds[i].max); - } + log_debug("av2data_set: " + "DS.name = \"%s\", DS.type = %i, DS.min = %f, DS.max = %f", + ds->ds[i].name, ds->ds[i].type, ds->ds[i].min, ds->ds[i].max); + } - sstrncpy (ds->type, name, sizeof (ds->type)); - return 0; + sstrncpy(ds->type, name, sizeof(ds->type)); + return 0; } /* static int av2data_set (pTHX_ AV *, data_set_t *) */ /* @@ -513,722 +496,684 @@ static int av2data_set (pTHX_ AV *array, char *name, data_set_t *ds) * meta => [ { name => , value => }, ... ] * } */ -static int av2notification_meta (pTHX_ AV *array, notification_meta_t **meta) -{ - notification_meta_t **m = meta; - - int len = av_len (array); - - for (int i = 0; i <= len; ++i) { - SV **tmp = av_fetch (array, i, 0); - HV *hash; - - if (NULL == tmp) - return -1; - - if (! (SvROK (*tmp) && (SVt_PVHV == SvTYPE (SvRV (*tmp))))) { - log_warn ("av2notification_meta: Skipping invalid " - "meta information."); - continue; - } - - hash = (HV *)SvRV (*tmp); - - *m = smalloc (sizeof (**m)); - - if (NULL == (tmp = hv_fetch (hash, "name", 4, 0))) { - log_warn ("av2notification_meta: Skipping invalid " - "meta information."); - free (*m); - continue; - } - sstrncpy ((*m)->name, SvPV_nolen (*tmp), sizeof ((*m)->name)); - - if (NULL == (tmp = hv_fetch (hash, "value", 5, 0))) { - log_warn ("av2notification_meta: Skipping invalid " - "meta information."); - free (*m); - continue; - } - - if (SvNOK (*tmp)) { - (*m)->nm_value.nm_double = SvNVX (*tmp); - (*m)->type = NM_TYPE_DOUBLE; - } - else if (SvUOK (*tmp)) { - (*m)->nm_value.nm_unsigned_int = SvUVX (*tmp); - (*m)->type = NM_TYPE_UNSIGNED_INT; - } - else if (SvIOK (*tmp)) { - (*m)->nm_value.nm_signed_int = SvIVX (*tmp); - (*m)->type = NM_TYPE_SIGNED_INT; - } - else { - (*m)->nm_value.nm_string = sstrdup (SvPV_nolen (*tmp)); - (*m)->type = NM_TYPE_STRING; - } - - (*m)->next = NULL; - m = &((*m)->next); - } - return 0; +static int av2notification_meta(pTHX_ AV *array, notification_meta_t **meta) { + notification_meta_t **m = meta; + + int len = av_len(array); + + for (int i = 0; i <= len; ++i) { + SV **tmp = av_fetch(array, i, 0); + HV *hash; + + if (NULL == tmp) + return -1; + + if (!(SvROK(*tmp) && (SVt_PVHV == SvTYPE(SvRV(*tmp))))) { + log_warn("av2notification_meta: Skipping invalid " + "meta information."); + continue; + } + + hash = (HV *)SvRV(*tmp); + + *m = smalloc(sizeof(**m)); + + if (NULL == (tmp = hv_fetch(hash, "name", 4, 0))) { + log_warn("av2notification_meta: Skipping invalid " + "meta information."); + free(*m); + continue; + } + sstrncpy((*m)->name, SvPV_nolen(*tmp), sizeof((*m)->name)); + + if (NULL == (tmp = hv_fetch(hash, "value", 5, 0))) { + log_warn("av2notification_meta: Skipping invalid " + "meta information."); + free(*m); + continue; + } + + if (SvNOK(*tmp)) { + (*m)->nm_value.nm_double = SvNVX(*tmp); + (*m)->type = NM_TYPE_DOUBLE; + } else if (SvUOK(*tmp)) { + (*m)->nm_value.nm_unsigned_int = SvUVX(*tmp); + (*m)->type = NM_TYPE_UNSIGNED_INT; + } else if (SvIOK(*tmp)) { + (*m)->nm_value.nm_signed_int = SvIVX(*tmp); + (*m)->type = NM_TYPE_SIGNED_INT; + } else { + (*m)->nm_value.nm_string = sstrdup(SvPV_nolen(*tmp)); + (*m)->type = NM_TYPE_STRING; + } + + (*m)->next = NULL; + m = &((*m)->next); + } + return 0; } /* static int av2notification_meta (AV *, notification_meta_t *) */ -static int hv2notification (pTHX_ HV *hash, notification_t *n) -{ - SV **tmp = NULL; - - if ((NULL == hash) || (NULL == n)) - return -1; - - if (NULL != (tmp = hv_fetch (hash, "severity", 8, 0))) - n->severity = SvIV (*tmp); - else - n->severity = NOTIF_FAILURE; - - if (NULL != (tmp = hv_fetch (hash, "time", 4, 0))) - { - double t = SvNV (*tmp); - n->time = DOUBLE_TO_CDTIME_T (t); - } - else - n->time = cdtime (); - - if (NULL != (tmp = hv_fetch (hash, "message", 7, 0))) - sstrncpy (n->message, SvPV_nolen (*tmp), sizeof (n->message)); - - if (NULL != (tmp = hv_fetch (hash, "host", 4, 0))) - sstrncpy (n->host, SvPV_nolen (*tmp), sizeof (n->host)); - else - sstrncpy (n->host, hostname_g, sizeof (n->host)); - - if (NULL != (tmp = hv_fetch (hash, "plugin", 6, 0))) - sstrncpy (n->plugin, SvPV_nolen (*tmp), sizeof (n->plugin)); - - if (NULL != (tmp = hv_fetch (hash, "plugin_instance", 15, 0))) - sstrncpy (n->plugin_instance, SvPV_nolen (*tmp), - sizeof (n->plugin_instance)); - - if (NULL != (tmp = hv_fetch (hash, "type", 4, 0))) - sstrncpy (n->type, SvPV_nolen (*tmp), sizeof (n->type)); - - if (NULL != (tmp = hv_fetch (hash, "type_instance", 13, 0))) - sstrncpy (n->type_instance, SvPV_nolen (*tmp), - sizeof (n->type_instance)); - - n->meta = NULL; - while (NULL != (tmp = hv_fetch (hash, "meta", 4, 0))) { - if (! (SvROK (*tmp) && (SVt_PVAV == SvTYPE (SvRV (*tmp))))) { - log_warn ("hv2notification: Ignoring invalid meta information."); - break; - } - - if (0 != av2notification_meta (aTHX_ (AV *)SvRV (*tmp), &n->meta)) { - plugin_notification_meta_free (n->meta); - n->meta = NULL; - return -1; - } - break; - } - return 0; +static int hv2notification(pTHX_ HV *hash, notification_t *n) { + SV **tmp = NULL; + + if ((NULL == hash) || (NULL == n)) + return -1; + + if (NULL != (tmp = hv_fetch(hash, "severity", 8, 0))) + n->severity = SvIV(*tmp); + else + n->severity = NOTIF_FAILURE; + + if (NULL != (tmp = hv_fetch(hash, "time", 4, 0))) { + double t = SvNV(*tmp); + n->time = DOUBLE_TO_CDTIME_T(t); + } else + n->time = cdtime(); + + if (NULL != (tmp = hv_fetch(hash, "message", 7, 0))) + sstrncpy(n->message, SvPV_nolen(*tmp), sizeof(n->message)); + + if (NULL != (tmp = hv_fetch(hash, "host", 4, 0))) + sstrncpy(n->host, SvPV_nolen(*tmp), sizeof(n->host)); + else + sstrncpy(n->host, hostname_g, sizeof(n->host)); + + if (NULL != (tmp = hv_fetch(hash, "plugin", 6, 0))) + sstrncpy(n->plugin, SvPV_nolen(*tmp), sizeof(n->plugin)); + + if (NULL != (tmp = hv_fetch(hash, "plugin_instance", 15, 0))) + sstrncpy(n->plugin_instance, SvPV_nolen(*tmp), sizeof(n->plugin_instance)); + + if (NULL != (tmp = hv_fetch(hash, "type", 4, 0))) + sstrncpy(n->type, SvPV_nolen(*tmp), sizeof(n->type)); + + if (NULL != (tmp = hv_fetch(hash, "type_instance", 13, 0))) + sstrncpy(n->type_instance, SvPV_nolen(*tmp), sizeof(n->type_instance)); + + n->meta = NULL; + while (NULL != (tmp = hv_fetch(hash, "meta", 4, 0))) { + if (!(SvROK(*tmp) && (SVt_PVAV == SvTYPE(SvRV(*tmp))))) { + log_warn("hv2notification: Ignoring invalid meta information."); + break; + } + + if (0 != av2notification_meta(aTHX_(AV *) SvRV(*tmp), &n->meta)) { + plugin_notification_meta_free(n->meta); + n->meta = NULL; + return -1; + } + break; + } + return 0; } /* static int hv2notification (pTHX_ HV *, notification_t *) */ -static int data_set2av (pTHX_ data_set_t *ds, AV *array) -{ - if ((NULL == ds) || (NULL == array)) - return -1; +static int data_set2av(pTHX_ data_set_t *ds, AV *array) { + if ((NULL == ds) || (NULL == array)) + return -1; - av_extend (array, ds->ds_num); + av_extend(array, ds->ds_num); - for (size_t i = 0; i < ds->ds_num; ++i) { - HV *source = newHV (); + for (size_t i = 0; i < ds->ds_num; ++i) { + HV *source = newHV(); - if (NULL == hv_store (source, "name", 4, - newSVpv (ds->ds[i].name, 0), 0)) - return -1; + if (NULL == hv_store(source, "name", 4, newSVpv(ds->ds[i].name, 0), 0)) + return -1; - if (NULL == hv_store (source, "type", 4, newSViv (ds->ds[i].type), 0)) - return -1; + if (NULL == hv_store(source, "type", 4, newSViv(ds->ds[i].type), 0)) + return -1; - if (! isnan (ds->ds[i].min)) - if (NULL == hv_store (source, "min", 3, - newSVnv (ds->ds[i].min), 0)) - return -1; + if (!isnan(ds->ds[i].min)) + if (NULL == hv_store(source, "min", 3, newSVnv(ds->ds[i].min), 0)) + return -1; - if (! isnan (ds->ds[i].max)) - if (NULL == hv_store (source, "max", 3, - newSVnv (ds->ds[i].max), 0)) - return -1; + if (!isnan(ds->ds[i].max)) + if (NULL == hv_store(source, "max", 3, newSVnv(ds->ds[i].max), 0)) + return -1; - if (NULL == av_store (array, i, newRV_noinc ((SV *)source))) - return -1; - } - return 0; + if (NULL == av_store(array, i, newRV_noinc((SV *)source))) + return -1; + } + return 0; } /* static int data_set2av (data_set_t *, AV *) */ -static int value_list2hv (pTHX_ value_list_t *vl, data_set_t *ds, HV *hash) -{ - AV *values = NULL; - size_t i; - - if ((NULL == vl) || (NULL == ds) || (NULL == hash)) - return -1; - - values = newAV (); - /* av_extend takes the last *index* to which the array should be extended. */ - av_extend (values, vl->values_len - 1); - - assert (ds->ds_num == vl->values_len); - for (i = 0; i < vl->values_len; ++i) { - SV *val = NULL; - - if (DS_TYPE_COUNTER == ds->ds[i].type) - val = newSViv (vl->values[i].counter); - else if (DS_TYPE_GAUGE == ds->ds[i].type) - val = newSVnv (vl->values[i].gauge); - else if (DS_TYPE_DERIVE == ds->ds[i].type) - val = newSViv (vl->values[i].derive); - else if (DS_TYPE_ABSOLUTE == ds->ds[i].type) - val = newSViv (vl->values[i].absolute); - - if (NULL == av_store (values, i, val)) { - av_undef (values); - return -1; - } - } - - if (NULL == hv_store (hash, "values", 6, newRV_noinc ((SV *)values), 0)) - return -1; - - if (0 != vl->time) - { - double t = CDTIME_T_TO_DOUBLE (vl->time); - if (NULL == hv_store (hash, "time", 4, newSVnv (t), 0)) - return -1; - } - - { - double t = CDTIME_T_TO_DOUBLE (vl->interval); - if (NULL == hv_store (hash, "interval", 8, newSVnv (t), 0)) - return -1; - } - - if ('\0' != vl->host[0]) - if (NULL == hv_store (hash, "host", 4, newSVpv (vl->host, 0), 0)) - return -1; - - if ('\0' != vl->plugin[0]) - if (NULL == hv_store (hash, "plugin", 6, newSVpv (vl->plugin, 0), 0)) - return -1; - - if ('\0' != vl->plugin_instance[0]) - if (NULL == hv_store (hash, "plugin_instance", 15, - newSVpv (vl->plugin_instance, 0), 0)) - return -1; - - if ('\0' != vl->type[0]) - if (NULL == hv_store (hash, "type", 4, newSVpv (vl->type, 0), 0)) - return -1; - - if ('\0' != vl->type_instance[0]) - if (NULL == hv_store (hash, "type_instance", 13, - newSVpv (vl->type_instance, 0), 0)) - return -1; - return 0; +static int value_list2hv(pTHX_ value_list_t *vl, data_set_t *ds, HV *hash) { + AV *values = NULL; + size_t i; + + if ((NULL == vl) || (NULL == ds) || (NULL == hash)) + return -1; + + values = newAV(); + /* av_extend takes the last *index* to which the array should be extended. */ + av_extend(values, vl->values_len - 1); + + assert(ds->ds_num == vl->values_len); + for (i = 0; i < vl->values_len; ++i) { + SV *val = NULL; + + if (DS_TYPE_COUNTER == ds->ds[i].type) + val = newSViv(vl->values[i].counter); + else if (DS_TYPE_GAUGE == ds->ds[i].type) + val = newSVnv(vl->values[i].gauge); + else if (DS_TYPE_DERIVE == ds->ds[i].type) + val = newSViv(vl->values[i].derive); + else if (DS_TYPE_ABSOLUTE == ds->ds[i].type) + val = newSViv(vl->values[i].absolute); + + if (NULL == av_store(values, i, val)) { + av_undef(values); + return -1; + } + } + + if (NULL == hv_store(hash, "values", 6, newRV_noinc((SV *)values), 0)) + return -1; + + if (0 != vl->time) { + double t = CDTIME_T_TO_DOUBLE(vl->time); + if (NULL == hv_store(hash, "time", 4, newSVnv(t), 0)) + return -1; + } + + { + double t = CDTIME_T_TO_DOUBLE(vl->interval); + if (NULL == hv_store(hash, "interval", 8, newSVnv(t), 0)) + return -1; + } + + if ('\0' != vl->host[0]) + if (NULL == hv_store(hash, "host", 4, newSVpv(vl->host, 0), 0)) + return -1; + + if ('\0' != vl->plugin[0]) + if (NULL == hv_store(hash, "plugin", 6, newSVpv(vl->plugin, 0), 0)) + return -1; + + if ('\0' != vl->plugin_instance[0]) + if (NULL == hv_store(hash, "plugin_instance", 15, + newSVpv(vl->plugin_instance, 0), 0)) + return -1; + + if ('\0' != vl->type[0]) + if (NULL == hv_store(hash, "type", 4, newSVpv(vl->type, 0), 0)) + return -1; + + if ('\0' != vl->type_instance[0]) + if (NULL == + hv_store(hash, "type_instance", 13, newSVpv(vl->type_instance, 0), 0)) + return -1; + return 0; } /* static int value2av (value_list_t *, data_set_t *, HV *) */ -static int notification_meta2av (pTHX_ notification_meta_t *meta, AV *array) -{ - int meta_num = 0; - - while (meta) { - ++meta_num; - meta = meta->next; - } - - av_extend (array, meta_num); - - for (int i = 0; NULL != meta; meta = meta->next, ++i) { - HV *m = newHV (); - SV *value; - - if (NULL == hv_store (m, "name", 4, newSVpv (meta->name, 0), 0)) - return -1; - - if (NM_TYPE_STRING == meta->type) - value = newSVpv (meta->nm_value.nm_string, 0); - else if (NM_TYPE_SIGNED_INT == meta->type) - value = newSViv (meta->nm_value.nm_signed_int); - else if (NM_TYPE_UNSIGNED_INT == meta->type) - value = newSVuv (meta->nm_value.nm_unsigned_int); - else if (NM_TYPE_DOUBLE == meta->type) - value = newSVnv (meta->nm_value.nm_double); - else if (NM_TYPE_BOOLEAN == meta->type) - value = meta->nm_value.nm_boolean ? &PL_sv_yes : &PL_sv_no; - else - return -1; - - if (NULL == hv_store (m, "value", 5, value, 0)) { - sv_free (value); - return -1; - } - - if (NULL == av_store (array, i, newRV_noinc ((SV *)m))) { - hv_clear (m); - hv_undef (m); - return -1; - } - } - return 0; +static int notification_meta2av(pTHX_ notification_meta_t *meta, AV *array) { + int meta_num = 0; + + while (meta) { + ++meta_num; + meta = meta->next; + } + + av_extend(array, meta_num); + + for (int i = 0; NULL != meta; meta = meta->next, ++i) { + HV *m = newHV(); + SV *value; + + if (NULL == hv_store(m, "name", 4, newSVpv(meta->name, 0), 0)) + return -1; + + if (NM_TYPE_STRING == meta->type) + value = newSVpv(meta->nm_value.nm_string, 0); + else if (NM_TYPE_SIGNED_INT == meta->type) + value = newSViv(meta->nm_value.nm_signed_int); + else if (NM_TYPE_UNSIGNED_INT == meta->type) + value = newSVuv(meta->nm_value.nm_unsigned_int); + else if (NM_TYPE_DOUBLE == meta->type) + value = newSVnv(meta->nm_value.nm_double); + else if (NM_TYPE_BOOLEAN == meta->type) + value = meta->nm_value.nm_boolean ? &PL_sv_yes : &PL_sv_no; + else + return -1; + + if (NULL == hv_store(m, "value", 5, value, 0)) { + sv_free(value); + return -1; + } + + if (NULL == av_store(array, i, newRV_noinc((SV *)m))) { + hv_clear(m); + hv_undef(m); + return -1; + } + } + return 0; } /* static int notification_meta2av (notification_meta_t *, AV *) */ -static int notification2hv (pTHX_ notification_t *n, HV *hash) -{ - if (NULL == hv_store (hash, "severity", 8, newSViv (n->severity), 0)) - return -1; - - if (0 != n->time) - { - double t = CDTIME_T_TO_DOUBLE (n->time); - if (NULL == hv_store (hash, "time", 4, newSVnv (t), 0)) - return -1; - } - - if ('\0' != *n->message) - if (NULL == hv_store (hash, "message", 7, newSVpv (n->message, 0), 0)) - return -1; - - if ('\0' != *n->host) - if (NULL == hv_store (hash, "host", 4, newSVpv (n->host, 0), 0)) - return -1; - - if ('\0' != *n->plugin) - if (NULL == hv_store (hash, "plugin", 6, newSVpv (n->plugin, 0), 0)) - return -1; - - if ('\0' != *n->plugin_instance) - if (NULL == hv_store (hash, "plugin_instance", 15, - newSVpv (n->plugin_instance, 0), 0)) - return -1; - - if ('\0' != *n->type) - if (NULL == hv_store (hash, "type", 4, newSVpv (n->type, 0), 0)) - return -1; - - if ('\0' != *n->type_instance) - if (NULL == hv_store (hash, "type_instance", 13, - newSVpv (n->type_instance, 0), 0)) - return -1; - - if (NULL != n->meta) { - AV *meta = newAV (); - if ((0 != notification_meta2av (aTHX_ n->meta, meta)) - || (NULL == hv_store (hash, "meta", 4, - newRV_noinc ((SV *)meta), 0))) { - av_clear (meta); - av_undef (meta); - return -1; - } - } - return 0; +static int notification2hv(pTHX_ notification_t *n, HV *hash) { + if (NULL == hv_store(hash, "severity", 8, newSViv(n->severity), 0)) + return -1; + + if (0 != n->time) { + double t = CDTIME_T_TO_DOUBLE(n->time); + if (NULL == hv_store(hash, "time", 4, newSVnv(t), 0)) + return -1; + } + + if ('\0' != *n->message) + if (NULL == hv_store(hash, "message", 7, newSVpv(n->message, 0), 0)) + return -1; + + if ('\0' != *n->host) + if (NULL == hv_store(hash, "host", 4, newSVpv(n->host, 0), 0)) + return -1; + + if ('\0' != *n->plugin) + if (NULL == hv_store(hash, "plugin", 6, newSVpv(n->plugin, 0), 0)) + return -1; + + if ('\0' != *n->plugin_instance) + if (NULL == hv_store(hash, "plugin_instance", 15, + newSVpv(n->plugin_instance, 0), 0)) + return -1; + + if ('\0' != *n->type) + if (NULL == hv_store(hash, "type", 4, newSVpv(n->type, 0), 0)) + return -1; + + if ('\0' != *n->type_instance) + if (NULL == + hv_store(hash, "type_instance", 13, newSVpv(n->type_instance, 0), 0)) + return -1; + + if (NULL != n->meta) { + AV *meta = newAV(); + if ((0 != notification_meta2av(aTHX_ n->meta, meta)) || + (NULL == hv_store(hash, "meta", 4, newRV_noinc((SV *)meta), 0))) { + av_clear(meta); + av_undef(meta); + return -1; + } + } + return 0; } /* static int notification2hv (notification_t *, HV *) */ -static int oconfig_item2hv (pTHX_ oconfig_item_t *ci, HV *hash) -{ - AV *values; - AV *children; - - if (NULL == hv_store (hash, "key", 3, newSVpv (ci->key, 0), 0)) - return -1; - - values = newAV (); - if (0 < ci->values_num) - av_extend (values, ci->values_num); - - if (NULL == hv_store (hash, "values", 6, newRV_noinc ((SV *)values), 0)) { - av_clear (values); - av_undef (values); - return -1; - } - - for (int i = 0; i < ci->values_num; ++i) { - SV *value; - - switch (ci->values[i].type) { - case OCONFIG_TYPE_STRING: - value = newSVpv (ci->values[i].value.string, 0); - break; - case OCONFIG_TYPE_NUMBER: - value = newSVnv ((NV)ci->values[i].value.number); - break; - case OCONFIG_TYPE_BOOLEAN: - value = ci->values[i].value.boolean ? &PL_sv_yes : &PL_sv_no; - break; - default: - log_err ("oconfig_item2hv: Invalid value type %i.", - ci->values[i].type); - value = &PL_sv_undef; - } - - if (NULL == av_store (values, i, value)) { - sv_free (value); - return -1; - } - } - - /* ignoring 'parent' member which is uninteresting in this case */ - - children = newAV (); - if (0 < ci->children_num) - av_extend (children, ci->children_num); - - if (NULL == hv_store (hash, "children", 8, newRV_noinc ((SV *)children), 0)) { - av_clear (children); - av_undef (children); - return -1; - } - - for (int i = 0; i < ci->children_num; ++i) { - HV *child = newHV (); - - if (0 != oconfig_item2hv (aTHX_ ci->children + i, child)) { - hv_clear (child); - hv_undef (child); - return -1; - } - - if (NULL == av_store (children, i, newRV_noinc ((SV *)child))) { - hv_clear (child); - hv_undef (child); - return -1; - } - } - return 0; +static int oconfig_item2hv(pTHX_ oconfig_item_t *ci, HV *hash) { + AV *values; + AV *children; + + if (NULL == hv_store(hash, "key", 3, newSVpv(ci->key, 0), 0)) + return -1; + + values = newAV(); + if (0 < ci->values_num) + av_extend(values, ci->values_num); + + if (NULL == hv_store(hash, "values", 6, newRV_noinc((SV *)values), 0)) { + av_clear(values); + av_undef(values); + return -1; + } + + for (int i = 0; i < ci->values_num; ++i) { + SV *value; + + switch (ci->values[i].type) { + case OCONFIG_TYPE_STRING: + value = newSVpv(ci->values[i].value.string, 0); + break; + case OCONFIG_TYPE_NUMBER: + value = newSVnv((NV)ci->values[i].value.number); + break; + case OCONFIG_TYPE_BOOLEAN: + value = ci->values[i].value.boolean ? &PL_sv_yes : &PL_sv_no; + break; + default: + log_err("oconfig_item2hv: Invalid value type %i.", ci->values[i].type); + value = &PL_sv_undef; + } + + if (NULL == av_store(values, i, value)) { + sv_free(value); + return -1; + } + } + + /* ignoring 'parent' member which is uninteresting in this case */ + + children = newAV(); + if (0 < ci->children_num) + av_extend(children, ci->children_num); + + if (NULL == hv_store(hash, "children", 8, newRV_noinc((SV *)children), 0)) { + av_clear(children); + av_undef(children); + return -1; + } + + for (int i = 0; i < ci->children_num; ++i) { + HV *child = newHV(); + + if (0 != oconfig_item2hv(aTHX_ ci->children + i, child)) { + hv_clear(child); + hv_undef(child); + return -1; + } + + if (NULL == av_store(children, i, newRV_noinc((SV *)child))) { + hv_clear(child); + hv_undef(child); + return -1; + } + } + return 0; } /* static int oconfig_item2hv (pTHX_ oconfig_item_t *, HV *) */ /* * Internal functions. */ -static char *get_module_name (char *buf, size_t buf_len, const char *module) { - int status = 0; - if (base_name[0] == '\0') - status = ssnprintf (buf, buf_len, "%s", module); - else - status = ssnprintf (buf, buf_len, "%s::%s", base_name, module); - if ((status < 0) || ((unsigned int)status >= buf_len)) - return (NULL); - return (buf); +static char *get_module_name(char *buf, size_t buf_len, const char *module) { + int status = 0; + if (base_name[0] == '\0') + status = ssnprintf(buf, buf_len, "%s", module); + else + status = ssnprintf(buf, buf_len, "%s::%s", base_name, module); + if ((status < 0) || ((unsigned int)status >= buf_len)) + return (NULL); + return (buf); } /* char *get_module_name */ /* * Add a plugin's data set definition. */ -static int pplugin_register_data_set (pTHX_ char *name, AV *dataset) -{ - int ret = 0; +static int pplugin_register_data_set(pTHX_ char *name, AV *dataset) { + int ret = 0; - data_set_t ds; + data_set_t ds; - if ((NULL == name) || (NULL == dataset)) - return -1; + if ((NULL == name) || (NULL == dataset)) + return -1; - if (0 != av2data_set (aTHX_ dataset, name, &ds)) - return -1; + if (0 != av2data_set(aTHX_ dataset, name, &ds)) + return -1; - ret = plugin_register_data_set (&ds); + ret = plugin_register_data_set(&ds); - free (ds.ds); - return ret; + free(ds.ds); + return ret; } /* static int pplugin_register_data_set (char *, SV *) */ /* * Remove a plugin's data set definition. */ -static int pplugin_unregister_data_set (char *name) -{ - if (NULL == name) - return 0; - return plugin_unregister_data_set (name); +static int pplugin_unregister_data_set(char *name) { + if (NULL == name) + return 0; + return plugin_unregister_data_set(name); } /* static int pplugin_unregister_data_set (char *) */ /* * Submit the values to the write functions. */ -static int pplugin_dispatch_values (pTHX_ HV *values) -{ - value_list_t vl = VALUE_LIST_INIT; +static int pplugin_dispatch_values(pTHX_ HV *values) { + value_list_t vl = VALUE_LIST_INIT; - int ret = 0; + int ret = 0; - if (NULL == values) - return -1; + if (NULL == values) + return -1; - if (0 != hv2value_list (aTHX_ values, &vl)) - return -1; + if (0 != hv2value_list(aTHX_ values, &vl)) + return -1; - ret = plugin_dispatch_values (&vl); + ret = plugin_dispatch_values(&vl); - sfree (vl.values); - return ret; + sfree(vl.values); + return ret; } /* static int pplugin_dispatch_values (char *, HV *) */ /* * Submit the values to a single write function. */ -static int pplugin_write (pTHX_ const char *plugin, AV *data_set, HV *values) -{ - data_set_t ds; - value_list_t vl = VALUE_LIST_INIT; +static int pplugin_write(pTHX_ const char *plugin, AV *data_set, HV *values) { + data_set_t ds; + value_list_t vl = VALUE_LIST_INIT; - int ret; + int ret; - if (NULL == values) - return -1; + if (NULL == values) + return -1; - if (0 != hv2value_list (aTHX_ values, &vl)) - return -1; + if (0 != hv2value_list(aTHX_ values, &vl)) + return -1; - if ((NULL != data_set) - && (0 != av2data_set (aTHX_ data_set, vl.type, &ds))) - return -1; + if ((NULL != data_set) && (0 != av2data_set(aTHX_ data_set, vl.type, &ds))) + return -1; - ret = plugin_write (plugin, NULL == data_set ? NULL : &ds, &vl); - if (0 != ret) - log_warn ("Dispatching value to plugin \"%s\" failed with status %i.", - NULL == plugin ? "" : plugin, ret); + ret = plugin_write(plugin, NULL == data_set ? NULL : &ds, &vl); + if (0 != ret) + log_warn("Dispatching value to plugin \"%s\" failed with status %i.", + NULL == plugin ? "" : plugin, ret); - if (NULL != data_set) - sfree (ds.ds); - sfree (vl.values); - return ret; + if (NULL != data_set) + sfree(ds.ds); + sfree(vl.values); + return ret; } /* static int pplugin_write (const char *plugin, HV *, HV *) */ /* * Dispatch a notification. */ -static int pplugin_dispatch_notification (pTHX_ HV *notif) -{ - notification_t n = { 0 }; +static int pplugin_dispatch_notification(pTHX_ HV *notif) { + notification_t n = {0}; - int ret; + int ret; - if (NULL == notif) - return -1; + if (NULL == notif) + return -1; - if (0 != hv2notification (aTHX_ notif, &n)) - return -1; + if (0 != hv2notification(aTHX_ notif, &n)) + return -1; - ret = plugin_dispatch_notification (&n); - plugin_notification_meta_free (n.meta); - return ret; + ret = plugin_dispatch_notification(&n); + plugin_notification_meta_free(n.meta); + return ret; } /* static int pplugin_dispatch_notification (HV *) */ /* * Call perl sub with thread locking flags handled. */ -static int call_pv_locked (pTHX_ const char* sub_name) -{ - _Bool old_running; - int ret; +static int call_pv_locked(pTHX_ const char *sub_name) { + _Bool old_running; + int ret; - c_ithread_t *t = (c_ithread_t *)pthread_getspecific(perl_thr_key); - if (t == NULL) /* thread destroyed */ - return 0; + c_ithread_t *t = (c_ithread_t *)pthread_getspecific(perl_thr_key); + if (t == NULL) /* thread destroyed */ + return 0; - old_running = t->running; - t->running = 1; + old_running = t->running; + t->running = 1; - if (t->shutdown) { - t->running = old_running; - return 0; - } + if (t->shutdown) { + t->running = old_running; + return 0; + } - ret = call_pv (sub_name, G_SCALAR|G_EVAL); + ret = call_pv(sub_name, G_SCALAR | G_EVAL); - t->running = old_running; - return ret; + t->running = old_running; + return ret; } /* static int call_pv_locked (pTHX, *sub_name) */ /* * Call all working functions of the given type. */ -static int pplugin_call (pTHX_ int type, ...) -{ - int retvals = 0; - - va_list ap; - int ret = 0; - char *subname; - - dSP; - - if ((type < 0) || (type >= PLUGIN_TYPES)) - return -1; - - va_start (ap, type); - - ENTER; - SAVETMPS; - - PUSHMARK (SP); - - if (PLUGIN_READ == type) { - subname = va_arg(ap, char *); - } - else if (PLUGIN_WRITE == type) { - data_set_t *ds; - value_list_t *vl; - - AV *pds = newAV (); - HV *pvl = newHV (); - - subname = va_arg(ap, char *); - /* - * $_[0] = $plugin_type; - * - * $_[1] = - * [ - * { - * name => $ds_name, - * type => $ds_type, - * min => $ds_min, - * max => $ds_max - * }, - * ... - * ]; - * - * $_[2] = - * { - * values => [ $v1, ... ], - * time => $time, - * host => $hostname, - * plugin => $plugin, - * type => $type, - * plugin_instance => $instance, - * type_instance => $type_instance - * }; - */ - ds = va_arg (ap, data_set_t *); - vl = va_arg (ap, value_list_t *); - - if (-1 == data_set2av (aTHX_ ds, pds)) { - av_clear (pds); - av_undef (pds); - pds = (AV *)&PL_sv_undef; - ret = -1; - } - - if (-1 == value_list2hv (aTHX_ vl, ds, pvl)) { - hv_clear (pvl); - hv_undef (pvl); - pvl = (HV *)&PL_sv_undef; - ret = -1; - } - - XPUSHs (sv_2mortal (newSVpv (ds->type, 0))); - XPUSHs (sv_2mortal (newRV_noinc ((SV *)pds))); - XPUSHs (sv_2mortal (newRV_noinc ((SV *)pvl))); - } - else if (PLUGIN_LOG == type) { - subname = va_arg(ap, char *); - /* - * $_[0] = $level; - * - * $_[1] = $message; - */ - XPUSHs (sv_2mortal (newSViv (va_arg (ap, int)))); - XPUSHs (sv_2mortal (newSVpv (va_arg (ap, char *), 0))); - } - else if (PLUGIN_NOTIF == type) { - notification_t *n; - HV *notif = newHV (); - - subname = va_arg(ap, char *); - /* - * $_[0] = - * { - * severity => $severity, - * time => $time, - * message => $msg, - * host => $host, - * plugin => $plugin, - * type => $type, - * plugin_instance => $instance, - * type_instance => $type_instance - * }; - */ - n = va_arg (ap, notification_t *); - - if (-1 == notification2hv (aTHX_ n, notif)) { - hv_clear (notif); - hv_undef (notif); - notif = (HV *)&PL_sv_undef; - ret = -1; - } - - XPUSHs (sv_2mortal (newRV_noinc ((SV *)notif))); - } - else if (PLUGIN_FLUSH == type) { - cdtime_t timeout; - subname = va_arg(ap, char *); - /* - * $_[0] = $timeout; - * $_[1] = $identifier; - */ - timeout = va_arg (ap, cdtime_t); - - XPUSHs (sv_2mortal (newSVnv (CDTIME_T_TO_DOUBLE (timeout)))); - XPUSHs (sv_2mortal (newSVpv (va_arg (ap, char *), 0))); - } - else if (PLUGIN_FLUSH_ALL == type) { - cdtime_t timeout; - subname = "Collectd::plugin_call_all"; - /* - * $_[0] = $timeout; - * $_[1] = $identifier; - */ - timeout = va_arg (ap, cdtime_t); - - XPUSHs (sv_2mortal (newSViv ((IV)PLUGIN_FLUSH))); - XPUSHs (sv_2mortal (newSVnv (CDTIME_T_TO_DOUBLE (timeout)))); - XPUSHs (sv_2mortal (newSVpv (va_arg (ap, char *), 0))); - } - else if (PLUGIN_INIT == type) { - subname = "Collectd::plugin_call_all"; - XPUSHs (sv_2mortal (newSViv ((IV)type))); - } - else if (PLUGIN_SHUTDOWN == type) { - subname = "Collectd::plugin_call_all"; - XPUSHs (sv_2mortal (newSViv ((IV)type))); - } - else { /* Unknown type. Run 'plugin_call_all' and make compiler happy */ - subname = "Collectd::plugin_call_all"; - XPUSHs (sv_2mortal (newSViv ((IV)type))); - } - - PUTBACK; - - retvals = call_pv_locked (aTHX_ subname); - - SPAGAIN; - if (SvTRUE(ERRSV)) { - if (PLUGIN_LOG != type) - ERROR ("perl: %s error: %s", subname, SvPV_nolen(ERRSV)); - ret = -1; - } - else if (0 < retvals) { - SV *tmp = POPs; - if (! SvTRUE (tmp)) - ret = -1; - } - - PUTBACK; - FREETMPS; - LEAVE; - - va_end (ap); - return ret; +static int pplugin_call(pTHX_ int type, ...) { + int retvals = 0; + + va_list ap; + int ret = 0; + char *subname; + + dSP; + + if ((type < 0) || (type >= PLUGIN_TYPES)) + return -1; + + va_start(ap, type); + + ENTER; + SAVETMPS; + + PUSHMARK(SP); + + if (PLUGIN_READ == type) { + subname = va_arg(ap, char *); + } else if (PLUGIN_WRITE == type) { + data_set_t *ds; + value_list_t *vl; + + AV *pds = newAV(); + HV *pvl = newHV(); + + subname = va_arg(ap, char *); + /* + * $_[0] = $plugin_type; + * + * $_[1] = + * [ + * { + * name => $ds_name, + * type => $ds_type, + * min => $ds_min, + * max => $ds_max + * }, + * ... + * ]; + * + * $_[2] = + * { + * values => [ $v1, ... ], + * time => $time, + * host => $hostname, + * plugin => $plugin, + * type => $type, + * plugin_instance => $instance, + * type_instance => $type_instance + * }; + */ + ds = va_arg(ap, data_set_t *); + vl = va_arg(ap, value_list_t *); + + if (-1 == data_set2av(aTHX_ ds, pds)) { + av_clear(pds); + av_undef(pds); + pds = (AV *)&PL_sv_undef; + ret = -1; + } + + if (-1 == value_list2hv(aTHX_ vl, ds, pvl)) { + hv_clear(pvl); + hv_undef(pvl); + pvl = (HV *)&PL_sv_undef; + ret = -1; + } + + XPUSHs(sv_2mortal(newSVpv(ds->type, 0))); + XPUSHs(sv_2mortal(newRV_noinc((SV *)pds))); + XPUSHs(sv_2mortal(newRV_noinc((SV *)pvl))); + } else if (PLUGIN_LOG == type) { + subname = va_arg(ap, char *); + /* + * $_[0] = $level; + * + * $_[1] = $message; + */ + XPUSHs(sv_2mortal(newSViv(va_arg(ap, int)))); + XPUSHs(sv_2mortal(newSVpv(va_arg(ap, char *), 0))); + } else if (PLUGIN_NOTIF == type) { + notification_t *n; + HV *notif = newHV(); + + subname = va_arg(ap, char *); + /* + * $_[0] = + * { + * severity => $severity, + * time => $time, + * message => $msg, + * host => $host, + * plugin => $plugin, + * type => $type, + * plugin_instance => $instance, + * type_instance => $type_instance + * }; + */ + n = va_arg(ap, notification_t *); + + if (-1 == notification2hv(aTHX_ n, notif)) { + hv_clear(notif); + hv_undef(notif); + notif = (HV *)&PL_sv_undef; + ret = -1; + } + + XPUSHs(sv_2mortal(newRV_noinc((SV *)notif))); + } else if (PLUGIN_FLUSH == type) { + cdtime_t timeout; + subname = va_arg(ap, char *); + /* + * $_[0] = $timeout; + * $_[1] = $identifier; + */ + timeout = va_arg(ap, cdtime_t); + + XPUSHs(sv_2mortal(newSVnv(CDTIME_T_TO_DOUBLE(timeout)))); + XPUSHs(sv_2mortal(newSVpv(va_arg(ap, char *), 0))); + } else if (PLUGIN_FLUSH_ALL == type) { + cdtime_t timeout; + subname = "Collectd::plugin_call_all"; + /* + * $_[0] = $timeout; + * $_[1] = $identifier; + */ + timeout = va_arg(ap, cdtime_t); + + XPUSHs(sv_2mortal(newSViv((IV)PLUGIN_FLUSH))); + XPUSHs(sv_2mortal(newSVnv(CDTIME_T_TO_DOUBLE(timeout)))); + XPUSHs(sv_2mortal(newSVpv(va_arg(ap, char *), 0))); + } else if (PLUGIN_INIT == type) { + subname = "Collectd::plugin_call_all"; + XPUSHs(sv_2mortal(newSViv((IV)type))); + } else if (PLUGIN_SHUTDOWN == type) { + subname = "Collectd::plugin_call_all"; + XPUSHs(sv_2mortal(newSViv((IV)type))); + } else { /* Unknown type. Run 'plugin_call_all' and make compiler happy */ + subname = "Collectd::plugin_call_all"; + XPUSHs(sv_2mortal(newSViv((IV)type))); + } + + PUTBACK; + + retvals = call_pv_locked(aTHX_ subname); + + SPAGAIN; + if (SvTRUE(ERRSV)) { + if (PLUGIN_LOG != type) + ERROR("perl: %s error: %s", subname, SvPV_nolen(ERRSV)); + ret = -1; + } else if (0 < retvals) { + SV *tmp = POPs; + if (!SvTRUE(tmp)) + ret = -1; + } + + PUTBACK; + FREETMPS; + LEAVE; + + va_end(ap); + return ret; } /* static int pplugin_call (int, ...) */ /* @@ -1238,485 +1183,454 @@ static int pplugin_call (pTHX_ int type, ...) */ /* must be called with perl_threads->mutex locked */ -static void c_ithread_destroy (c_ithread_t *ithread) -{ - dTHXa (ithread->interp); +static void c_ithread_destroy(c_ithread_t *ithread) { + dTHXa(ithread->interp); - assert (NULL != perl_threads); + assert(NULL != perl_threads); - PERL_SET_CONTEXT (aTHX); - /* Mark as running to avoid deadlock: - c_ithread_destroy -> log_debug -> perl_log() - */ - ithread->running = 1; - log_debug ("Shutting down Perl interpreter %p...", aTHX); + PERL_SET_CONTEXT(aTHX); + /* Mark as running to avoid deadlock: + c_ithread_destroy -> log_debug -> perl_log() + */ + ithread->running = 1; + log_debug("Shutting down Perl interpreter %p...", aTHX); #if COLLECT_DEBUG - sv_report_used (); + sv_report_used(); - --perl_threads->number_of_threads; + --perl_threads->number_of_threads; #endif /* COLLECT_DEBUG */ - perl_destruct (aTHX); - perl_free (aTHX); + perl_destruct(aTHX); + perl_free(aTHX); - if (NULL == ithread->prev) - perl_threads->head = ithread->next; - else - ithread->prev->next = ithread->next; + if (NULL == ithread->prev) + perl_threads->head = ithread->next; + else + ithread->prev->next = ithread->next; - if (NULL == ithread->next) - perl_threads->tail = ithread->prev; - else - ithread->next->prev = ithread->prev; + if (NULL == ithread->next) + perl_threads->tail = ithread->prev; + else + ithread->next->prev = ithread->prev; - sfree (ithread); - return; + sfree(ithread); + return; } /* static void c_ithread_destroy (c_ithread_t *) */ -static void c_ithread_destructor (void *arg) -{ - c_ithread_t *ithread = (c_ithread_t *)arg; - c_ithread_t *t = NULL; +static void c_ithread_destructor(void *arg) { + c_ithread_t *ithread = (c_ithread_t *)arg; + c_ithread_t *t = NULL; - if (NULL == perl_threads) - return; + if (NULL == perl_threads) + return; - pthread_mutex_lock (&perl_threads->mutex); + pthread_mutex_lock(&perl_threads->mutex); - for (t = perl_threads->head; NULL != t; t = t->next) - if (t == ithread) - break; + for (t = perl_threads->head; NULL != t; t = t->next) + if (t == ithread) + break; - /* the ithread no longer exists */ - if (NULL == t) - { - pthread_mutex_unlock (&perl_threads->mutex); - return; - } + /* the ithread no longer exists */ + if (NULL == t) { + pthread_mutex_unlock(&perl_threads->mutex); + return; + } - c_ithread_destroy (ithread); + c_ithread_destroy(ithread); - pthread_mutex_unlock (&perl_threads->mutex); - return; + pthread_mutex_unlock(&perl_threads->mutex); + return; } /* static void c_ithread_destructor (void *) */ /* must be called with perl_threads->mutex locked */ -static c_ithread_t *c_ithread_create (PerlInterpreter *base) -{ - c_ithread_t *t = NULL; - dTHXa (NULL); +static c_ithread_t *c_ithread_create(PerlInterpreter *base) { + c_ithread_t *t = NULL; + dTHXa(NULL); - assert (NULL != perl_threads); + assert(NULL != perl_threads); - t = smalloc (sizeof (*t)); - memset (t, 0, sizeof (c_ithread_t)); + t = smalloc(sizeof(*t)); + memset(t, 0, sizeof(c_ithread_t)); - t->interp = (NULL == base) - ? NULL - : perl_clone (base, CLONEf_KEEP_PTR_TABLE); + t->interp = (NULL == base) ? NULL : perl_clone(base, CLONEf_KEEP_PTR_TABLE); - aTHX = t->interp; + aTHX = t->interp; - if ((NULL != base) && (NULL != PL_endav)) { - av_clear (PL_endav); - av_undef (PL_endav); - PL_endav = Nullav; - } + if ((NULL != base) && (NULL != PL_endav)) { + av_clear(PL_endav); + av_undef(PL_endav); + PL_endav = Nullav; + } #if COLLECT_DEBUG - ++perl_threads->number_of_threads; + ++perl_threads->number_of_threads; #endif /* COLLECT_DEBUG */ - t->next = NULL; + t->next = NULL; - if (NULL == perl_threads->tail) { - perl_threads->head = t; - t->prev = NULL; - } - else { - perl_threads->tail->next = t; - t->prev = perl_threads->tail; - } + if (NULL == perl_threads->tail) { + perl_threads->head = t; + t->prev = NULL; + } else { + perl_threads->tail->next = t; + t->prev = perl_threads->tail; + } - t->pthread = pthread_self(); - t->running = 0; - t->shutdown = 0; - perl_threads->tail = t; + t->pthread = pthread_self(); + t->running = 0; + t->shutdown = 0; + perl_threads->tail = t; - pthread_setspecific (perl_thr_key, (const void *)t); - return t; + pthread_setspecific(perl_thr_key, (const void *)t); + return t; } /* static c_ithread_t *c_ithread_create (PerlInterpreter *) */ /* * Filter chains implementation. */ -static int fc_call (pTHX_ int type, int cb_type, pfc_user_data_t *data, ...) -{ - int retvals = 0; - - va_list ap; - int ret = 0; - - notification_meta_t **meta = NULL; - AV *pmeta = NULL; - - dSP; - - if ((type < 0) || (type >= FC_TYPES)) - return -1; - - if ((cb_type < 0) || (cb_type >= FC_CB_TYPES)) - return -1; - - va_start (ap, data); - - ENTER; - SAVETMPS; - - PUSHMARK (SP); - - XPUSHs (sv_2mortal (newSViv ((IV)type))); - XPUSHs (sv_2mortal (newSVpv (data->name, 0))); - XPUSHs (sv_2mortal (newSViv ((IV)cb_type))); - - if (FC_CB_CREATE == cb_type) { - /* - * $_[0] = $ci; - * $_[1] = $user_data; - */ - oconfig_item_t *ci; - HV *config = newHV (); - - ci = va_arg (ap, oconfig_item_t *); - - if (0 != oconfig_item2hv (aTHX_ ci, config)) { - hv_clear (config); - hv_undef (config); - config = (HV *)&PL_sv_undef; - ret = -1; - } - - XPUSHs (sv_2mortal (newRV_noinc ((SV *)config))); - } - else if (FC_CB_DESTROY == cb_type) { - /* - * $_[1] = $user_data; - */ - - /* nothing to be done - the user data pointer - * is pushed onto the stack later */ - } - else if (FC_CB_EXEC == cb_type) { - /* - * $_[0] = $ds; - * $_[1] = $vl; - * $_[2] = $meta; - * $_[3] = $user_data; - */ - data_set_t *ds; - value_list_t *vl; - - AV *pds = newAV (); - HV *pvl = newHV (); - - ds = va_arg (ap, data_set_t *); - vl = va_arg (ap, value_list_t *); - meta = va_arg (ap, notification_meta_t **); - - if (0 != data_set2av (aTHX_ ds, pds)) { - av_clear (pds); - av_undef (pds); - pds = (AV *)&PL_sv_undef; - ret = -1; - } - - if (0 != value_list2hv (aTHX_ vl, ds, pvl)) { - hv_clear (pvl); - hv_undef (pvl); - pvl = (HV *)&PL_sv_undef; - ret = -1; - } - - if (NULL != meta) { - pmeta = newAV (); - - if (0 != notification_meta2av (aTHX_ *meta, pmeta)) { - av_clear (pmeta); - av_undef (pmeta); - pmeta = (AV *)&PL_sv_undef; - ret = -1; - } - } - else { - pmeta = (AV *)&PL_sv_undef; - } - - XPUSHs (sv_2mortal (newRV_noinc ((SV *)pds))); - XPUSHs (sv_2mortal (newRV_noinc ((SV *)pvl))); - XPUSHs (sv_2mortal (newRV_noinc ((SV *)pmeta))); - } - - XPUSHs (sv_2mortal (newRV_inc (data->user_data))); - - PUTBACK; - - retvals = call_pv_locked (aTHX_ "Collectd::fc_call"); - - if ((FC_CB_EXEC == cb_type) && (meta != NULL)) { - assert (pmeta != NULL); - - plugin_notification_meta_free (*meta); - av2notification_meta (aTHX_ pmeta, meta); - } - - SPAGAIN; - if (SvTRUE(ERRSV)) { - ERROR ("perl: Collectd::fc_call error: %s", SvPV_nolen(ERRSV)); - ret = -1; - } - else if (0 < retvals) { - SV *tmp = POPs; - - /* the exec callbacks return a status, while - * the others return a boolean value */ - if (FC_CB_EXEC == cb_type) - ret = SvIV (tmp); - else if (! SvTRUE (tmp)) - ret = -1; - } - - PUTBACK; - FREETMPS; - LEAVE; - - va_end (ap); - return ret; +static int fc_call(pTHX_ int type, int cb_type, pfc_user_data_t *data, ...) { + int retvals = 0; + + va_list ap; + int ret = 0; + + notification_meta_t **meta = NULL; + AV *pmeta = NULL; + + dSP; + + if ((type < 0) || (type >= FC_TYPES)) + return -1; + + if ((cb_type < 0) || (cb_type >= FC_CB_TYPES)) + return -1; + + va_start(ap, data); + + ENTER; + SAVETMPS; + + PUSHMARK(SP); + + XPUSHs(sv_2mortal(newSViv((IV)type))); + XPUSHs(sv_2mortal(newSVpv(data->name, 0))); + XPUSHs(sv_2mortal(newSViv((IV)cb_type))); + + if (FC_CB_CREATE == cb_type) { + /* + * $_[0] = $ci; + * $_[1] = $user_data; + */ + oconfig_item_t *ci; + HV *config = newHV(); + + ci = va_arg(ap, oconfig_item_t *); + + if (0 != oconfig_item2hv(aTHX_ ci, config)) { + hv_clear(config); + hv_undef(config); + config = (HV *)&PL_sv_undef; + ret = -1; + } + + XPUSHs(sv_2mortal(newRV_noinc((SV *)config))); + } else if (FC_CB_DESTROY == cb_type) { + /* + * $_[1] = $user_data; + */ + + /* nothing to be done - the user data pointer + * is pushed onto the stack later */ + } else if (FC_CB_EXEC == cb_type) { + /* + * $_[0] = $ds; + * $_[1] = $vl; + * $_[2] = $meta; + * $_[3] = $user_data; + */ + data_set_t *ds; + value_list_t *vl; + + AV *pds = newAV(); + HV *pvl = newHV(); + + ds = va_arg(ap, data_set_t *); + vl = va_arg(ap, value_list_t *); + meta = va_arg(ap, notification_meta_t **); + + if (0 != data_set2av(aTHX_ ds, pds)) { + av_clear(pds); + av_undef(pds); + pds = (AV *)&PL_sv_undef; + ret = -1; + } + + if (0 != value_list2hv(aTHX_ vl, ds, pvl)) { + hv_clear(pvl); + hv_undef(pvl); + pvl = (HV *)&PL_sv_undef; + ret = -1; + } + + if (NULL != meta) { + pmeta = newAV(); + + if (0 != notification_meta2av(aTHX_ * meta, pmeta)) { + av_clear(pmeta); + av_undef(pmeta); + pmeta = (AV *)&PL_sv_undef; + ret = -1; + } + } else { + pmeta = (AV *)&PL_sv_undef; + } + + XPUSHs(sv_2mortal(newRV_noinc((SV *)pds))); + XPUSHs(sv_2mortal(newRV_noinc((SV *)pvl))); + XPUSHs(sv_2mortal(newRV_noinc((SV *)pmeta))); + } + + XPUSHs(sv_2mortal(newRV_inc(data->user_data))); + + PUTBACK; + + retvals = call_pv_locked(aTHX_ "Collectd::fc_call"); + + if ((FC_CB_EXEC == cb_type) && (meta != NULL)) { + assert(pmeta != NULL); + + plugin_notification_meta_free(*meta); + av2notification_meta(aTHX_ pmeta, meta); + } + + SPAGAIN; + if (SvTRUE(ERRSV)) { + ERROR("perl: Collectd::fc_call error: %s", SvPV_nolen(ERRSV)); + ret = -1; + } else if (0 < retvals) { + SV *tmp = POPs; + + /* the exec callbacks return a status, while + * the others return a boolean value */ + if (FC_CB_EXEC == cb_type) + ret = SvIV(tmp); + else if (!SvTRUE(tmp)) + ret = -1; + } + + PUTBACK; + FREETMPS; + LEAVE; + + va_end(ap); + return ret; } /* static int fc_call (int, int, pfc_user_data_t *, ...) */ -static int fc_create (int type, const oconfig_item_t *ci, void **user_data) -{ - pfc_user_data_t *data; +static int fc_create(int type, const oconfig_item_t *ci, void **user_data) { + pfc_user_data_t *data; - int ret = 0; + int ret = 0; - dTHX; + dTHX; - if (NULL == perl_threads) - return 0; + if (NULL == perl_threads) + return 0; - if (NULL == aTHX) { - c_ithread_t *t = NULL; + if (NULL == aTHX) { + c_ithread_t *t = NULL; - pthread_mutex_lock (&perl_threads->mutex); - t = c_ithread_create (perl_threads->head->interp); - pthread_mutex_unlock (&perl_threads->mutex); + pthread_mutex_lock(&perl_threads->mutex); + t = c_ithread_create(perl_threads->head->interp); + pthread_mutex_unlock(&perl_threads->mutex); - aTHX = t->interp; - } + aTHX = t->interp; + } - log_debug ("fc_create: c_ithread: interp = %p (active threads: %i)", - aTHX, perl_threads->number_of_threads); + log_debug("fc_create: c_ithread: interp = %p (active threads: %i)", aTHX, + perl_threads->number_of_threads); - if ((1 != ci->values_num) - || (OCONFIG_TYPE_STRING != ci->values[0].type)) { - log_warn ("A \"%s\" block expects a single string argument.", - (FC_MATCH == type) ? "Match" : "Target"); - return -1; - } + if ((1 != ci->values_num) || (OCONFIG_TYPE_STRING != ci->values[0].type)) { + log_warn("A \"%s\" block expects a single string argument.", + (FC_MATCH == type) ? "Match" : "Target"); + return -1; + } - data = smalloc (sizeof (*data)); - data->name = sstrdup (ci->values[0].value.string); - data->user_data = newSV (0); + data = smalloc(sizeof(*data)); + data->name = sstrdup(ci->values[0].value.string); + data->user_data = newSV(0); - ret = fc_call (aTHX_ type, FC_CB_CREATE, data, ci); + ret = fc_call(aTHX_ type, FC_CB_CREATE, data, ci); - if (0 != ret) - PFC_USER_DATA_FREE (data); - else - *user_data = data; - return ret; + if (0 != ret) + PFC_USER_DATA_FREE(data); + else + *user_data = data; + return ret; } /* static int fc_create (int, const oconfig_item_t *, void **) */ -static int fc_destroy (int type, void **user_data) -{ - pfc_user_data_t *data = *(pfc_user_data_t **)user_data; +static int fc_destroy(int type, void **user_data) { + pfc_user_data_t *data = *(pfc_user_data_t **)user_data; - int ret = 0; + int ret = 0; - dTHX; + dTHX; - if ((NULL == perl_threads) || (NULL == data)) - return 0; + if ((NULL == perl_threads) || (NULL == data)) + return 0; - if (NULL == aTHX) { - c_ithread_t *t = NULL; + if (NULL == aTHX) { + c_ithread_t *t = NULL; - pthread_mutex_lock (&perl_threads->mutex); - t = c_ithread_create (perl_threads->head->interp); - pthread_mutex_unlock (&perl_threads->mutex); + pthread_mutex_lock(&perl_threads->mutex); + t = c_ithread_create(perl_threads->head->interp); + pthread_mutex_unlock(&perl_threads->mutex); - aTHX = t->interp; - } + aTHX = t->interp; + } - log_debug ("fc_destroy: c_ithread: interp = %p (active threads: %i)", - aTHX, perl_threads->number_of_threads); + log_debug("fc_destroy: c_ithread: interp = %p (active threads: %i)", aTHX, + perl_threads->number_of_threads); - ret = fc_call (aTHX_ type, FC_CB_DESTROY, data); + ret = fc_call(aTHX_ type, FC_CB_DESTROY, data); - PFC_USER_DATA_FREE (data); - *user_data = NULL; - return ret; + PFC_USER_DATA_FREE(data); + *user_data = NULL; + return ret; } /* static int fc_destroy (int, void **) */ -static int fc_exec (int type, const data_set_t *ds, const value_list_t *vl, - notification_meta_t **meta, void **user_data) -{ - pfc_user_data_t *data = *(pfc_user_data_t **)user_data; +static int fc_exec(int type, const data_set_t *ds, const value_list_t *vl, + notification_meta_t **meta, void **user_data) { + pfc_user_data_t *data = *(pfc_user_data_t **)user_data; - dTHX; + dTHX; - if (NULL == perl_threads) - return 0; + if (NULL == perl_threads) + return 0; - assert (NULL != data); + assert(NULL != data); - if (NULL == aTHX) { - c_ithread_t *t = NULL; + if (NULL == aTHX) { + c_ithread_t *t = NULL; - pthread_mutex_lock (&perl_threads->mutex); - t = c_ithread_create (perl_threads->head->interp); - pthread_mutex_unlock (&perl_threads->mutex); + pthread_mutex_lock(&perl_threads->mutex); + t = c_ithread_create(perl_threads->head->interp); + pthread_mutex_unlock(&perl_threads->mutex); - aTHX = t->interp; - } + aTHX = t->interp; + } - log_debug ("fc_exec: c_ithread: interp = %p (active threads: %i)", - aTHX, perl_threads->number_of_threads); + log_debug("fc_exec: c_ithread: interp = %p (active threads: %i)", aTHX, + perl_threads->number_of_threads); - return fc_call (aTHX_ type, FC_CB_EXEC, data, ds, vl, meta); + return fc_call(aTHX_ type, FC_CB_EXEC, data, ds, vl, meta); } /* static int fc_exec (int, const data_set_t *, const value_list_t *, - notification_meta_t **, void **) */ + notification_meta_t **, void **) */ -static int pmatch_create (const oconfig_item_t *ci, void **user_data) -{ - return fc_create (FC_MATCH, ci, user_data); +static int pmatch_create(const oconfig_item_t *ci, void **user_data) { + return fc_create(FC_MATCH, ci, user_data); } /* static int pmatch_create (const oconfig_item_t *, void **) */ -static int pmatch_destroy (void **user_data) -{ - return fc_destroy (FC_MATCH, user_data); +static int pmatch_destroy(void **user_data) { + return fc_destroy(FC_MATCH, user_data); } /* static int pmatch_destroy (void **) */ -static int pmatch_match (const data_set_t *ds, const value_list_t *vl, - notification_meta_t **meta, void **user_data) -{ - return fc_exec (FC_MATCH, ds, vl, meta, user_data); +static int pmatch_match(const data_set_t *ds, const value_list_t *vl, + notification_meta_t **meta, void **user_data) { + return fc_exec(FC_MATCH, ds, vl, meta, user_data); } /* static int pmatch_match (const data_set_t *, const value_list_t *, - notification_meta_t **, void **) */ + notification_meta_t **, void **) */ -static match_proc_t pmatch = { - pmatch_create, pmatch_destroy, pmatch_match -}; +static match_proc_t pmatch = {pmatch_create, pmatch_destroy, pmatch_match}; -static int ptarget_create (const oconfig_item_t *ci, void **user_data) -{ - return fc_create (FC_TARGET, ci, user_data); +static int ptarget_create(const oconfig_item_t *ci, void **user_data) { + return fc_create(FC_TARGET, ci, user_data); } /* static int ptarget_create (const oconfig_item_t *, void **) */ -static int ptarget_destroy (void **user_data) -{ - return fc_destroy (FC_TARGET, user_data); +static int ptarget_destroy(void **user_data) { + return fc_destroy(FC_TARGET, user_data); } /* static int ptarget_destroy (void **) */ -static int ptarget_invoke (const data_set_t *ds, value_list_t *vl, - notification_meta_t **meta, void **user_data) -{ - return fc_exec (FC_TARGET, ds, vl, meta, user_data); +static int ptarget_invoke(const data_set_t *ds, value_list_t *vl, + notification_meta_t **meta, void **user_data) { + return fc_exec(FC_TARGET, ds, vl, meta, user_data); } /* static int ptarget_invoke (const data_set_t *, value_list_t *, - notification_meta_t **, void **) */ + notification_meta_t **, void **) */ -static target_proc_t ptarget = { - ptarget_create, ptarget_destroy, ptarget_invoke -}; +static target_proc_t ptarget = {ptarget_create, ptarget_destroy, + ptarget_invoke}; /* * Exported Perl API. */ -static void _plugin_register_generic_userdata (pTHX, int type, const char *desc) -{ - int ret = 0; - user_data_t userdata; - char *pluginname; - - dXSARGS; - - if (2 != items) { - log_err ("Usage: Collectd::plugin_register_%s(pluginname, subname)", - desc); - XSRETURN_EMPTY; - } - - if (! SvOK (ST (0))) { - log_err ("Collectd::plugin_register_%s(pluginname, subname): " - "Invalid pluginname", desc); - XSRETURN_EMPTY; - } - if (! SvOK (ST (1))) { - log_err ("Collectd::plugin_register_%s(pluginname, subname): " - "Invalid subname", desc); - XSRETURN_EMPTY; - } - - /* Use pluginname as-is to allow flush a single perl plugin */ - pluginname = SvPV_nolen (ST (0)); - - log_debug ("Collectd::plugin_register_%s: " - "plugin = \"%s\", sub = \"%s\"", - desc, pluginname, SvPV_nolen (ST (1))); - - memset(&userdata, 0, sizeof(userdata)); - userdata.data = strdup(SvPV_nolen (ST (1))); - userdata.free_func = free; - - if (PLUGIN_READ == type) { - ret = plugin_register_complex_read( - "perl", /* group */ - pluginname, - perl_read, - plugin_get_interval(), /* Default interval */ - &userdata); - } - else if (PLUGIN_WRITE == type) { - ret = plugin_register_write(pluginname, perl_write, &userdata); - } - else if (PLUGIN_LOG == type) { - ret = plugin_register_log(pluginname, perl_log, &userdata); - } - else if (PLUGIN_NOTIF == type) { - ret = plugin_register_notification(pluginname, perl_notify, &userdata); - } - else if (PLUGIN_FLUSH == type) { - if (1 == register_legacy_flush) { /* For collectd-5.7 only, #1731 */ - register_legacy_flush = 0; - ret = plugin_register_flush("perl", perl_flush, /* user_data = */ NULL); - } - - if (0 == ret) - ret = plugin_register_flush(pluginname, perl_flush, &userdata); - } - else { - ret = -1; - } - - if (0 == ret) - XSRETURN_YES; - else { - free (userdata.data); - XSRETURN_EMPTY; - } +static void _plugin_register_generic_userdata(pTHX, int type, + const char *desc) { + int ret = 0; + user_data_t userdata; + char *pluginname; + + dXSARGS; + + if (2 != items) { + log_err("Usage: Collectd::plugin_register_%s(pluginname, subname)", desc); + XSRETURN_EMPTY; + } + + if (!SvOK(ST(0))) { + log_err("Collectd::plugin_register_%s(pluginname, subname): " + "Invalid pluginname", + desc); + XSRETURN_EMPTY; + } + if (!SvOK(ST(1))) { + log_err("Collectd::plugin_register_%s(pluginname, subname): " + "Invalid subname", + desc); + XSRETURN_EMPTY; + } + + /* Use pluginname as-is to allow flush a single perl plugin */ + pluginname = SvPV_nolen(ST(0)); + + log_debug("Collectd::plugin_register_%s: " + "plugin = \"%s\", sub = \"%s\"", + desc, pluginname, SvPV_nolen(ST(1))); + + memset(&userdata, 0, sizeof(userdata)); + userdata.data = strdup(SvPV_nolen(ST(1))); + userdata.free_func = free; + + if (PLUGIN_READ == type) { + ret = plugin_register_complex_read( + "perl", /* group */ + pluginname, perl_read, plugin_get_interval(), /* Default interval */ + &userdata); + } else if (PLUGIN_WRITE == type) { + ret = plugin_register_write(pluginname, perl_write, &userdata); + } else if (PLUGIN_LOG == type) { + ret = plugin_register_log(pluginname, perl_log, &userdata); + } else if (PLUGIN_NOTIF == type) { + ret = plugin_register_notification(pluginname, perl_notify, &userdata); + } else if (PLUGIN_FLUSH == type) { + if (1 == register_legacy_flush) { /* For collectd-5.7 only, #1731 */ + register_legacy_flush = 0; + ret = plugin_register_flush("perl", perl_flush, /* user_data = */ NULL); + } + + if (0 == ret) + ret = plugin_register_flush(pluginname, perl_flush, &userdata); + } else { + ret = -1; + } + + if (0 == ret) + XSRETURN_YES; + else { + free(userdata.data); + XSRETURN_EMPTY; + } } /* static void _plugin_register_generic_userdata ( ... ) */ /* @@ -1729,52 +1643,52 @@ static void _plugin_register_generic_userdata (pTHX, int type, const char *desc) * name of the plugin's subroutine that does the work */ -static XS (Collectd_plugin_register_read) { - return _plugin_register_generic_userdata(aTHX, PLUGIN_READ, "read"); +static XS(Collectd_plugin_register_read) { + return _plugin_register_generic_userdata(aTHX, PLUGIN_READ, "read"); } -static XS (Collectd_plugin_register_write) { - return _plugin_register_generic_userdata(aTHX, PLUGIN_WRITE, "write"); +static XS(Collectd_plugin_register_write) { + return _plugin_register_generic_userdata(aTHX, PLUGIN_WRITE, "write"); } -static XS (Collectd_plugin_register_log) { - return _plugin_register_generic_userdata(aTHX, PLUGIN_LOG, "log"); +static XS(Collectd_plugin_register_log) { + return _plugin_register_generic_userdata(aTHX, PLUGIN_LOG, "log"); } -static XS (Collectd_plugin_register_notification) { - return _plugin_register_generic_userdata(aTHX, PLUGIN_NOTIF, "notification"); +static XS(Collectd_plugin_register_notification) { + return _plugin_register_generic_userdata(aTHX, PLUGIN_NOTIF, "notification"); } -static XS (Collectd_plugin_register_flush) { - return _plugin_register_generic_userdata(aTHX, PLUGIN_FLUSH, "flush"); +static XS(Collectd_plugin_register_flush) { + return _plugin_register_generic_userdata(aTHX, PLUGIN_FLUSH, "flush"); } typedef int perl_unregister_function_t(const char *name); -static void _plugin_unregister_generic (pTHX, - perl_unregister_function_t *unreg, const char *desc) -{ - dXSARGS; +static void _plugin_unregister_generic(pTHX, perl_unregister_function_t *unreg, + const char *desc) { + dXSARGS; - if (1 != items) { - log_err ("Usage: Collectd::plugin_unregister_%s(pluginname)", desc); - XSRETURN_EMPTY; - } + if (1 != items) { + log_err("Usage: Collectd::plugin_unregister_%s(pluginname)", desc); + XSRETURN_EMPTY; + } - if (! SvOK (ST (0))) { - log_err ("Collectd::plugin_unregister_%s(pluginname): " - "Invalid pluginname", desc); - XSRETURN_EMPTY; - } + if (!SvOK(ST(0))) { + log_err("Collectd::plugin_unregister_%s(pluginname): " + "Invalid pluginname", + desc); + XSRETURN_EMPTY; + } - log_debug ("Collectd::plugin_unregister_%s: plugin = \"%s\"", - desc, SvPV_nolen (ST (0))); + log_debug("Collectd::plugin_unregister_%s: plugin = \"%s\"", desc, + SvPV_nolen(ST(0))); - unreg(SvPV_nolen (ST (0))); + unreg(SvPV_nolen(ST(0))); - XSRETURN_EMPTY; + XSRETURN_EMPTY; - return; + return; } /* static void _plugin_unregister_generic ( ... ) */ /* @@ -1787,29 +1701,25 @@ static void _plugin_unregister_generic (pTHX, * name of the perl plugin */ -static XS (Collectd_plugin_unregister_read) { - return _plugin_unregister_generic(aTHX, - plugin_unregister_read, "read"); +static XS(Collectd_plugin_unregister_read) { + return _plugin_unregister_generic(aTHX, plugin_unregister_read, "read"); } -static XS (Collectd_plugin_unregister_write) { - return _plugin_unregister_generic(aTHX, - plugin_unregister_write, "write"); +static XS(Collectd_plugin_unregister_write) { + return _plugin_unregister_generic(aTHX, plugin_unregister_write, "write"); } -static XS (Collectd_plugin_unregister_log) { - return _plugin_unregister_generic(aTHX, - plugin_unregister_log, "log"); +static XS(Collectd_plugin_unregister_log) { + return _plugin_unregister_generic(aTHX, plugin_unregister_log, "log"); } -static XS (Collectd_plugin_unregister_notification) { - return _plugin_unregister_generic(aTHX, - plugin_unregister_notification, "notification"); +static XS(Collectd_plugin_unregister_notification) { + return _plugin_unregister_generic(aTHX, plugin_unregister_notification, + "notification"); } -static XS (Collectd_plugin_unregister_flush) { - return _plugin_unregister_generic(aTHX, - plugin_unregister_flush, "flush"); +static XS(Collectd_plugin_unregister_flush) { + return _plugin_unregister_generic(aTHX, plugin_unregister_flush, "flush"); } /* @@ -1821,40 +1731,37 @@ static XS (Collectd_plugin_unregister_flush) { * dataset: * dataset to be registered */ -static XS (Collectd_plugin_register_ds) -{ - SV *data = NULL; - int ret = 0; - - dXSARGS; - - log_warn ("Using plugin_register() to register new data-sets is " - "deprecated - add new entries to a custom types.db instead."); - - if (2 != items) { - log_err ("Usage: Collectd::plugin_register_data_set(type, dataset)"); - XSRETURN_EMPTY; - } - - log_debug ("Collectd::plugin_register_data_set: " - "type = \"%s\", dataset = \"%s\"", - SvPV_nolen (ST (0)), SvPV_nolen (ST (1))); - - data = ST (1); - - if (SvROK (data) && (SVt_PVAV == SvTYPE (SvRV (data)))) { - ret = pplugin_register_data_set (aTHX_ SvPV_nolen (ST (0)), - (AV *)SvRV (data)); - } - else { - log_err ("Collectd::plugin_register_data_set: Invalid data."); - XSRETURN_EMPTY; - } - - if (0 == ret) - XSRETURN_YES; - else - XSRETURN_EMPTY; +static XS(Collectd_plugin_register_ds) { + SV *data = NULL; + int ret = 0; + + dXSARGS; + + log_warn("Using plugin_register() to register new data-sets is " + "deprecated - add new entries to a custom types.db instead."); + + if (2 != items) { + log_err("Usage: Collectd::plugin_register_data_set(type, dataset)"); + XSRETURN_EMPTY; + } + + log_debug("Collectd::plugin_register_data_set: " + "type = \"%s\", dataset = \"%s\"", + SvPV_nolen(ST(0)), SvPV_nolen(ST(1))); + + data = ST(1); + + if (SvROK(data) && (SVt_PVAV == SvTYPE(SvRV(data)))) { + ret = pplugin_register_data_set(aTHX_ SvPV_nolen(ST(0)), (AV *)SvRV(data)); + } else { + log_err("Collectd::plugin_register_data_set: Invalid data."); + XSRETURN_EMPTY; + } + + if (0 == ret) + XSRETURN_YES; + else + XSRETURN_EMPTY; } /* static XS (Collectd_plugin_register_ds) */ /* @@ -1863,22 +1770,21 @@ static XS (Collectd_plugin_register_ds) * type: * type of the dataset */ -static XS (Collectd_plugin_unregister_ds) -{ - dXSARGS; - - if (1 != items) { - log_err ("Usage: Collectd::plugin_unregister_data_set(type)"); - XSRETURN_EMPTY; - } - - log_debug ("Collectd::plugin_unregister_data_set: type = \"%s\"", - SvPV_nolen (ST (0))); - - if (0 == pplugin_unregister_data_set (SvPV_nolen (ST (0)))) - XSRETURN_YES; - else - XSRETURN_EMPTY; +static XS(Collectd_plugin_unregister_ds) { + dXSARGS; + + if (1 != items) { + log_err("Usage: Collectd::plugin_unregister_data_set(type)"); + XSRETURN_EMPTY; + } + + log_debug("Collectd::plugin_unregister_data_set: type = \"%s\"", + SvPV_nolen(ST(0))); + + if (0 == pplugin_unregister_data_set(SvPV_nolen(ST(0)))) + XSRETURN_YES; + else + XSRETURN_EMPTY; } /* static XS (Collectd_plugin_register_ds) */ /* @@ -1890,54 +1796,52 @@ static XS (Collectd_plugin_unregister_ds) * values: * value list to submit */ -static XS (Collectd_plugin_dispatch_values) -{ - SV *values = NULL; +static XS(Collectd_plugin_dispatch_values) { + SV *values = NULL; - int ret = 0; + int ret = 0; - dXSARGS; + dXSARGS; - if (1 != items) { - log_err ("Usage: Collectd::plugin_dispatch_values(values)"); - XSRETURN_EMPTY; - } + if (1 != items) { + log_err("Usage: Collectd::plugin_dispatch_values(values)"); + XSRETURN_EMPTY; + } - log_debug ("Collectd::plugin_dispatch_values: values=\"%s\"", - SvPV_nolen (ST (/* stack index = */ 0))); + log_debug("Collectd::plugin_dispatch_values: values=\"%s\"", + SvPV_nolen(ST(/* stack index = */ 0))); - values = ST (/* stack index = */ 0); + values = ST(/* stack index = */ 0); - if (NULL == values) - XSRETURN_EMPTY; + if (NULL == values) + XSRETURN_EMPTY; - /* Make sure the argument is a hash reference. */ - if (! (SvROK (values) && (SVt_PVHV == SvTYPE (SvRV (values))))) { - log_err ("Collectd::plugin_dispatch_values: Invalid values."); - XSRETURN_EMPTY; - } + /* Make sure the argument is a hash reference. */ + if (!(SvROK(values) && (SVt_PVHV == SvTYPE(SvRV(values))))) { + log_err("Collectd::plugin_dispatch_values: Invalid values."); + XSRETURN_EMPTY; + } - ret = pplugin_dispatch_values (aTHX_ (HV *)SvRV (values)); + ret = pplugin_dispatch_values(aTHX_(HV *) SvRV(values)); - if (0 == ret) - XSRETURN_YES; - else - XSRETURN_EMPTY; + if (0 == ret) + XSRETURN_YES; + else + XSRETURN_EMPTY; } /* static XS (Collectd_plugin_dispatch_values) */ /* * Collectd::plugin_get_interval (). */ -static XS (Collectd_plugin_get_interval) -{ - dXSARGS; +static XS(Collectd_plugin_get_interval) { + dXSARGS; - /* make sure we don't get any unused variable warnings for 'items'; - * don't abort, though */ - if (items) - log_err ("Usage: Collectd::plugin_get_interval()"); + /* make sure we don't get any unused variable warnings for 'items'; + * don't abort, though */ + if (items) + log_err("Usage: Collectd::plugin_get_interval()"); - XSRETURN_NV ((NV) CDTIME_T_TO_DOUBLE (plugin_get_interval ())); + XSRETURN_NV((NV)CDTIME_T_TO_DOUBLE(plugin_get_interval())); } /* static XS (Collectd_plugin_get_interval) */ /* Collectd::plugin_write (plugin, ds, vl). @@ -1951,52 +1855,51 @@ static XS (Collectd_plugin_get_interval) * vl: * value-list to be written */ -static XS (Collectd__plugin_write) -{ - char *plugin; - SV *ds, *vl; - AV *ds_array; - - int ret; - - dXSARGS; - - if (3 != items) { - log_err ("Usage: Collectd::plugin_write(plugin, ds, vl)"); - XSRETURN_EMPTY; - } - - log_debug ("Collectd::plugin_write: plugin=\"%s\", ds=\"%s\", vl=\"%s\"", - SvPV_nolen (ST (0)), SvOK (ST (1)) ? SvPV_nolen (ST (1)) : "", - SvPV_nolen (ST (2))); - - if (! SvOK (ST (0))) - plugin = NULL; - else - plugin = SvPV_nolen (ST (0)); - - ds = ST (1); - if (SvROK (ds) && (SVt_PVAV == SvTYPE (SvRV (ds)))) - ds_array = (AV *)SvRV (ds); - else if (! SvOK (ds)) - ds_array = NULL; - else { - log_err ("Collectd::plugin_write: Invalid data-set."); - XSRETURN_EMPTY; - } - - vl = ST (2); - if (! (SvROK (vl) && (SVt_PVHV == SvTYPE (SvRV (vl))))) { - log_err ("Collectd::plugin_write: Invalid value-list."); - XSRETURN_EMPTY; - } - - ret = pplugin_write (aTHX_ plugin, ds_array, (HV *)SvRV (vl)); - - if (0 == ret) - XSRETURN_YES; - else - XSRETURN_EMPTY; +static XS(Collectd__plugin_write) { + char *plugin; + SV *ds, *vl; + AV *ds_array; + + int ret; + + dXSARGS; + + if (3 != items) { + log_err("Usage: Collectd::plugin_write(plugin, ds, vl)"); + XSRETURN_EMPTY; + } + + log_debug("Collectd::plugin_write: plugin=\"%s\", ds=\"%s\", vl=\"%s\"", + SvPV_nolen(ST(0)), SvOK(ST(1)) ? SvPV_nolen(ST(1)) : "", + SvPV_nolen(ST(2))); + + if (!SvOK(ST(0))) + plugin = NULL; + else + plugin = SvPV_nolen(ST(0)); + + ds = ST(1); + if (SvROK(ds) && (SVt_PVAV == SvTYPE(SvRV(ds)))) + ds_array = (AV *)SvRV(ds); + else if (!SvOK(ds)) + ds_array = NULL; + else { + log_err("Collectd::plugin_write: Invalid data-set."); + XSRETURN_EMPTY; + } + + vl = ST(2); + if (!(SvROK(vl) && (SVt_PVHV == SvTYPE(SvRV(vl))))) { + log_err("Collectd::plugin_write: Invalid value-list."); + XSRETURN_EMPTY; + } + + ret = pplugin_write(aTHX_ plugin, ds_array, (HV *)SvRV(vl)); + + if (0 == ret) + XSRETURN_YES; + else + XSRETURN_EMPTY; } /* static XS (Collectd__plugin_write) */ /* @@ -2011,35 +1914,35 @@ static XS (Collectd__plugin_write) * identifier: * data-set identifier to flush */ -static XS (Collectd__plugin_flush) -{ - char *plugin = NULL; - int timeout = -1; - char *id = NULL; +static XS(Collectd__plugin_flush) { + char *plugin = NULL; + int timeout = -1; + char *id = NULL; - dXSARGS; + dXSARGS; - if (3 != items) { - log_err ("Usage: Collectd::_plugin_flush(plugin, timeout, id)"); - XSRETURN_EMPTY; - } + if (3 != items) { + log_err("Usage: Collectd::_plugin_flush(plugin, timeout, id)"); + XSRETURN_EMPTY; + } - if (SvOK (ST (0))) - plugin = SvPV_nolen (ST (0)); + if (SvOK(ST(0))) + plugin = SvPV_nolen(ST(0)); - if (SvOK (ST (1))) - timeout = (int)SvIV (ST (1)); + if (SvOK(ST(1))) + timeout = (int)SvIV(ST(1)); - if (SvOK (ST (2))) - id = SvPV_nolen (ST (2)); + if (SvOK(ST(2))) + id = SvPV_nolen(ST(2)); - log_debug ("Collectd::_plugin_flush: plugin = \"%s\", timeout = %i, " - "id = \"%s\"", plugin, timeout, id); + log_debug("Collectd::_plugin_flush: plugin = \"%s\", timeout = %i, " + "id = \"%s\"", + plugin, timeout, id); - if (0 == plugin_flush (plugin, timeout, id)) - XSRETURN_YES; - else - XSRETURN_EMPTY; + if (0 == plugin_flush(plugin, timeout, id)) + XSRETURN_YES; + else + XSRETURN_EMPTY; } /* static XS (Collectd__plugin_flush) */ /* @@ -2048,35 +1951,34 @@ static XS (Collectd__plugin_flush) * notif: * notification to dispatch */ -static XS (Collectd_plugin_dispatch_notification) -{ - SV *notif = NULL; +static XS(Collectd_plugin_dispatch_notification) { + SV *notif = NULL; - int ret = 0; + int ret = 0; - dXSARGS; + dXSARGS; - if (1 != items) { - log_err ("Usage: Collectd::plugin_dispatch_notification(notif)"); - XSRETURN_EMPTY; - } + if (1 != items) { + log_err("Usage: Collectd::plugin_dispatch_notification(notif)"); + XSRETURN_EMPTY; + } - log_debug ("Collectd::plugin_dispatch_notification: notif = \"%s\"", - SvPV_nolen (ST (0))); + log_debug("Collectd::plugin_dispatch_notification: notif = \"%s\"", + SvPV_nolen(ST(0))); - notif = ST (0); + notif = ST(0); - if (! (SvROK (notif) && (SVt_PVHV == SvTYPE (SvRV (notif))))) { - log_err ("Collectd::plugin_dispatch_notification: Invalid notif."); - XSRETURN_EMPTY; - } + if (!(SvROK(notif) && (SVt_PVHV == SvTYPE(SvRV(notif))))) { + log_err("Collectd::plugin_dispatch_notification: Invalid notif."); + XSRETURN_EMPTY; + } - ret = pplugin_dispatch_notification (aTHX_ (HV *)SvRV (notif)); + ret = pplugin_dispatch_notification(aTHX_(HV *) SvRV(notif)); - if (0 == ret) - XSRETURN_YES; - else - XSRETURN_EMPTY; + if (0 == ret) + XSRETURN_YES; + else + XSRETURN_EMPTY; } /* static XS (Collectd_plugin_dispatch_notification) */ /* @@ -2088,17 +1990,16 @@ static XS (Collectd_plugin_dispatch_notification) * message: * log message */ -static XS (Collectd_plugin_log) -{ - dXSARGS; +static XS(Collectd_plugin_log) { + dXSARGS; - if (2 != items) { - log_err ("Usage: Collectd::plugin_log(level, message)"); - XSRETURN_EMPTY; - } + if (2 != items) { + log_err("Usage: Collectd::plugin_log(level, message)"); + XSRETURN_EMPTY; + } - plugin_log (SvIV (ST (0)), "%s", SvPV_nolen (ST (1))); - XSRETURN_YES; + plugin_log(SvIV(ST(0)), "%s", SvPV_nolen(ST(1))); + XSRETURN_YES; } /* static XS (Collectd_plugin_log) */ /* @@ -2110,32 +2011,31 @@ static XS (Collectd_plugin_log) * name: * name of the match */ -static XS (Collectd__fc_register) -{ - int type; - char *name; +static XS(Collectd__fc_register) { + int type; + char *name; - int ret = 0; + int ret = 0; - dXSARGS; + dXSARGS; - if (2 != items) { - log_err ("Usage: Collectd::_fc_register(type, name)"); - XSRETURN_EMPTY; - } + if (2 != items) { + log_err("Usage: Collectd::_fc_register(type, name)"); + XSRETURN_EMPTY; + } - type = SvIV (ST (0)); - name = SvPV_nolen (ST (1)); + type = SvIV(ST(0)); + name = SvPV_nolen(ST(1)); - if (FC_MATCH == type) - ret = fc_register_match (name, pmatch); - else if (FC_TARGET == type) - ret = fc_register_target (name, ptarget); + if (FC_MATCH == type) + ret = fc_register_match(name, pmatch); + else if (FC_TARGET == type) + ret = fc_register_target(name, ptarget); - if (0 == ret) - XSRETURN_YES; - else - XSRETURN_EMPTY; + if (0 == ret) + XSRETURN_YES; + else + XSRETURN_EMPTY; } /* static XS (Collectd_fc_register) */ /* @@ -2143,277 +2043,268 @@ static XS (Collectd__fc_register) * * Call a Perl sub identified by its name passed through $Collectd::cb_name. */ -static XS (Collectd_call_by_name) -{ - SV *tmp = NULL; - char *name = NULL; - - if (NULL == (tmp = get_sv ("Collectd::cb_name", 0))) { - sv_setpv (get_sv ("@", 1), "cb_name has not been set"); - CLEAR_STACK_FRAME; - return; - } - - name = SvPV_nolen (tmp); - - if (NULL == get_cv (name, 0)) { - sv_setpvf (get_sv ("@", 1), "unknown callback \"%s\"", name); - CLEAR_STACK_FRAME; - return; - } - - /* simply pass on the subroutine call without touching the stack, - * thus leaving any arguments and return values in place */ - call_pv (name, 0); +static XS(Collectd_call_by_name) { + SV *tmp = NULL; + char *name = NULL; + + if (NULL == (tmp = get_sv("Collectd::cb_name", 0))) { + sv_setpv(get_sv("@", 1), "cb_name has not been set"); + CLEAR_STACK_FRAME; + return; + } + + name = SvPV_nolen(tmp); + + if (NULL == get_cv(name, 0)) { + sv_setpvf(get_sv("@", 1), "unknown callback \"%s\"", name); + CLEAR_STACK_FRAME; + return; + } + + /* simply pass on the subroutine call without touching the stack, + * thus leaving any arguments and return values in place */ + call_pv(name, 0); } /* static XS (Collectd_call_by_name) */ /* * Interface to collectd. */ -static int perl_init (void) -{ - int status; - dTHX; +static int perl_init(void) { + int status; + dTHX; - if (NULL == perl_threads) - return 0; + if (NULL == perl_threads) + return 0; - if (NULL == aTHX) { - c_ithread_t *t = NULL; + if (NULL == aTHX) { + c_ithread_t *t = NULL; - pthread_mutex_lock (&perl_threads->mutex); - t = c_ithread_create (perl_threads->head->interp); - pthread_mutex_unlock (&perl_threads->mutex); + pthread_mutex_lock(&perl_threads->mutex); + t = c_ithread_create(perl_threads->head->interp); + pthread_mutex_unlock(&perl_threads->mutex); - aTHX = t->interp; - } + aTHX = t->interp; + } - log_debug ("perl_init: c_ithread: interp = %p (active threads: %i)", - aTHX, perl_threads->number_of_threads); + log_debug("perl_init: c_ithread: interp = %p (active threads: %i)", aTHX, + perl_threads->number_of_threads); - /* Lock the base thread to avoid race conditions with c_ithread_create(). - * See https://github.com/collectd/collectd/issues/9 and - * https://github.com/collectd/collectd/issues/1706 for details. - */ - assert (aTHX == perl_threads->head->interp); - pthread_mutex_lock (&perl_threads->mutex); + /* Lock the base thread to avoid race conditions with c_ithread_create(). + * See https://github.com/collectd/collectd/issues/9 and + * https://github.com/collectd/collectd/issues/1706 for details. + */ + assert(aTHX == perl_threads->head->interp); + pthread_mutex_lock(&perl_threads->mutex); - status = pplugin_call (aTHX_ PLUGIN_INIT); + status = pplugin_call(aTHX_ PLUGIN_INIT); - pthread_mutex_unlock (&perl_threads->mutex); + pthread_mutex_unlock(&perl_threads->mutex); - return status; + return status; } /* static int perl_init (void) */ -static int perl_read (user_data_t *user_data) -{ - dTHX; +static int perl_read(user_data_t *user_data) { + dTHX; - if (NULL == perl_threads) - return 0; + if (NULL == perl_threads) + return 0; - if (NULL == aTHX) { - c_ithread_t *t = NULL; + if (NULL == aTHX) { + c_ithread_t *t = NULL; - pthread_mutex_lock (&perl_threads->mutex); - t = c_ithread_create (perl_threads->head->interp); - pthread_mutex_unlock (&perl_threads->mutex); + pthread_mutex_lock(&perl_threads->mutex); + t = c_ithread_create(perl_threads->head->interp); + pthread_mutex_unlock(&perl_threads->mutex); - aTHX = t->interp; - } + aTHX = t->interp; + } - /* Assert that we're not running as the base thread. Otherwise, we might - * run into concurrency issues with c_ithread_create(). See - * https://github.com/collectd/collectd/issues/9 for details. */ - assert (aTHX != perl_threads->head->interp); + /* Assert that we're not running as the base thread. Otherwise, we might + * run into concurrency issues with c_ithread_create(). See + * https://github.com/collectd/collectd/issues/9 for details. */ + assert(aTHX != perl_threads->head->interp); - log_debug ("perl_read: c_ithread: interp = %p (active threads: %i)", - aTHX, perl_threads->number_of_threads); + log_debug("perl_read: c_ithread: interp = %p (active threads: %i)", aTHX, + perl_threads->number_of_threads); - return pplugin_call (aTHX_ PLUGIN_READ, user_data->data); + return pplugin_call(aTHX_ PLUGIN_READ, user_data->data); } /* static int perl_read (user_data_t *user_data) */ -static int perl_write (const data_set_t *ds, const value_list_t *vl, - user_data_t *user_data) -{ - int status; - dTHX; +static int perl_write(const data_set_t *ds, const value_list_t *vl, + user_data_t *user_data) { + int status; + dTHX; - if (NULL == perl_threads) - return 0; + if (NULL == perl_threads) + return 0; - if (NULL == aTHX) { - c_ithread_t *t = NULL; + if (NULL == aTHX) { + c_ithread_t *t = NULL; - pthread_mutex_lock (&perl_threads->mutex); - t = c_ithread_create (perl_threads->head->interp); - pthread_mutex_unlock (&perl_threads->mutex); + pthread_mutex_lock(&perl_threads->mutex); + t = c_ithread_create(perl_threads->head->interp); + pthread_mutex_unlock(&perl_threads->mutex); - aTHX = t->interp; - } + aTHX = t->interp; + } - /* Lock the base thread if this is not called from one of the read threads - * to avoid race conditions with c_ithread_create(). See - * https://github.com/collectd/collectd/issues/9 for details. */ - if (aTHX == perl_threads->head->interp) - pthread_mutex_lock (&perl_threads->mutex); + /* Lock the base thread if this is not called from one of the read threads + * to avoid race conditions with c_ithread_create(). See + * https://github.com/collectd/collectd/issues/9 for details. */ + if (aTHX == perl_threads->head->interp) + pthread_mutex_lock(&perl_threads->mutex); - log_debug ("perl_write: c_ithread: interp = %p (active threads: %i)", - aTHX, perl_threads->number_of_threads); - status = pplugin_call (aTHX_ PLUGIN_WRITE, user_data->data, ds, vl); + log_debug("perl_write: c_ithread: interp = %p (active threads: %i)", aTHX, + perl_threads->number_of_threads); + status = pplugin_call(aTHX_ PLUGIN_WRITE, user_data->data, ds, vl); - if (aTHX == perl_threads->head->interp) - pthread_mutex_unlock (&perl_threads->mutex); + if (aTHX == perl_threads->head->interp) + pthread_mutex_unlock(&perl_threads->mutex); - return status; + return status; } /* static int perl_write (const data_set_t *, const value_list_t *) */ -static void perl_log (int level, const char *msg, - user_data_t *user_data) -{ - dTHX; +static void perl_log(int level, const char *msg, user_data_t *user_data) { + dTHX; - if (NULL == perl_threads) - return; + if (NULL == perl_threads) + return; - if (NULL == aTHX) { - c_ithread_t *t = NULL; + if (NULL == aTHX) { + c_ithread_t *t = NULL; - pthread_mutex_lock (&perl_threads->mutex); - t = c_ithread_create (perl_threads->head->interp); - pthread_mutex_unlock (&perl_threads->mutex); + pthread_mutex_lock(&perl_threads->mutex); + t = c_ithread_create(perl_threads->head->interp); + pthread_mutex_unlock(&perl_threads->mutex); - aTHX = t->interp; - } + aTHX = t->interp; + } - /* Lock the base thread if this is not called from one of the read threads - * to avoid race conditions with c_ithread_create(). See - * https://github.com/collectd/collectd/issues/9 for details. - */ + /* Lock the base thread if this is not called from one of the read threads + * to avoid race conditions with c_ithread_create(). See + * https://github.com/collectd/collectd/issues/9 for details. + */ - if (aTHX == perl_threads->head->interp) - pthread_mutex_lock (&perl_threads->mutex); + if (aTHX == perl_threads->head->interp) + pthread_mutex_lock(&perl_threads->mutex); - pplugin_call (aTHX_ PLUGIN_LOG, user_data->data, level, msg); + pplugin_call(aTHX_ PLUGIN_LOG, user_data->data, level, msg); - if (aTHX == perl_threads->head->interp) - pthread_mutex_unlock (&perl_threads->mutex); + if (aTHX == perl_threads->head->interp) + pthread_mutex_unlock(&perl_threads->mutex); - return; + return; } /* static void perl_log (int, const char *) */ -static int perl_notify (const notification_t *notif, user_data_t *user_data) -{ - dTHX; +static int perl_notify(const notification_t *notif, user_data_t *user_data) { + dTHX; - if (NULL == perl_threads) - return 0; + if (NULL == perl_threads) + return 0; - if (NULL == aTHX) { - c_ithread_t *t = NULL; + if (NULL == aTHX) { + c_ithread_t *t = NULL; - pthread_mutex_lock (&perl_threads->mutex); - t = c_ithread_create (perl_threads->head->interp); - pthread_mutex_unlock (&perl_threads->mutex); + pthread_mutex_lock(&perl_threads->mutex); + t = c_ithread_create(perl_threads->head->interp); + pthread_mutex_unlock(&perl_threads->mutex); - aTHX = t->interp; - } - return pplugin_call (aTHX_ PLUGIN_NOTIF, user_data->data, notif); + aTHX = t->interp; + } + return pplugin_call(aTHX_ PLUGIN_NOTIF, user_data->data, notif); } /* static int perl_notify (const notification_t *) */ -static int perl_flush (cdtime_t timeout, const char *identifier, - user_data_t *user_data) -{ - dTHX; +static int perl_flush(cdtime_t timeout, const char *identifier, + user_data_t *user_data) { + dTHX; - if (NULL == perl_threads) - return 0; + if (NULL == perl_threads) + return 0; - if (NULL == aTHX) { - c_ithread_t *t = NULL; + if (NULL == aTHX) { + c_ithread_t *t = NULL; - pthread_mutex_lock (&perl_threads->mutex); - t = c_ithread_create (perl_threads->head->interp); - pthread_mutex_unlock (&perl_threads->mutex); + pthread_mutex_lock(&perl_threads->mutex); + t = c_ithread_create(perl_threads->head->interp); + pthread_mutex_unlock(&perl_threads->mutex); - aTHX = t->interp; - } + aTHX = t->interp; + } - /* For collectd-5.6 only, #1731 */ - if (user_data == NULL || user_data->data == NULL) - return pplugin_call (aTHX_ PLUGIN_FLUSH_ALL, timeout, identifier); + /* For collectd-5.6 only, #1731 */ + if (user_data == NULL || user_data->data == NULL) + return pplugin_call(aTHX_ PLUGIN_FLUSH_ALL, timeout, identifier); - return pplugin_call (aTHX_ PLUGIN_FLUSH, user_data->data, timeout, identifier); + return pplugin_call(aTHX_ PLUGIN_FLUSH, user_data->data, timeout, identifier); } /* static int perl_flush (const int) */ -static int perl_shutdown (void) -{ - c_ithread_t *t; - int ret; +static int perl_shutdown(void) { + c_ithread_t *t; + int ret; - dTHX; + dTHX; - plugin_unregister_complex_config ("perl"); - plugin_unregister_read_group ("perl"); + plugin_unregister_complex_config("perl"); + plugin_unregister_read_group("perl"); - if (NULL == perl_threads) - return 0; + if (NULL == perl_threads) + return 0; - if (NULL == aTHX) { - pthread_mutex_lock (&perl_threads->mutex); - t = c_ithread_create (perl_threads->head->interp); - pthread_mutex_unlock (&perl_threads->mutex); + if (NULL == aTHX) { + pthread_mutex_lock(&perl_threads->mutex); + t = c_ithread_create(perl_threads->head->interp); + pthread_mutex_unlock(&perl_threads->mutex); - aTHX = t->interp; - } + aTHX = t->interp; + } - log_debug ("perl_shutdown: c_ithread: interp = %p (active threads: %i)", - aTHX, perl_threads->number_of_threads); + log_debug("perl_shutdown: c_ithread: interp = %p (active threads: %i)", aTHX, + perl_threads->number_of_threads); - plugin_unregister_init ("perl"); - plugin_unregister_flush ("perl"); /* For collectd-5.6 only, #1731 */ + plugin_unregister_init("perl"); + plugin_unregister_flush("perl"); /* For collectd-5.6 only, #1731 */ - ret = pplugin_call (aTHX_ PLUGIN_SHUTDOWN); + ret = pplugin_call(aTHX_ PLUGIN_SHUTDOWN); - pthread_mutex_lock (&perl_threads->mutex); - t = perl_threads->tail; + pthread_mutex_lock(&perl_threads->mutex); + t = perl_threads->tail; - while (NULL != t) { - struct timespec ts_wait; - c_ithread_t *thr = t; + while (NULL != t) { + struct timespec ts_wait; + c_ithread_t *thr = t; - /* the pointer has to be advanced before destroying - * the thread as this will free the memory */ - t = t->prev; + /* the pointer has to be advanced before destroying + * the thread as this will free the memory */ + t = t->prev; - thr->shutdown = 1; - if (thr->running) { - /* Give some time to thread to exit from Perl interpreter */ - WARNING ("perl shutdown: Thread is running inside Perl. Waiting."); - ts_wait.tv_sec = 0; - ts_wait.tv_nsec = 500000; - nanosleep (&ts_wait, NULL); - } - if (thr->running) { - pthread_kill (thr->pthread, SIGTERM); - ERROR ("perl shutdown: Thread hangs inside Perl. Thread killed."); - } - c_ithread_destroy (thr); - } + thr->shutdown = 1; + if (thr->running) { + /* Give some time to thread to exit from Perl interpreter */ + WARNING("perl shutdown: Thread is running inside Perl. Waiting."); + ts_wait.tv_sec = 0; + ts_wait.tv_nsec = 500000; + nanosleep(&ts_wait, NULL); + } + if (thr->running) { + pthread_kill(thr->pthread, SIGTERM); + ERROR("perl shutdown: Thread hangs inside Perl. Thread killed."); + } + c_ithread_destroy(thr); + } - pthread_mutex_unlock (&perl_threads->mutex); - pthread_mutex_destroy (&perl_threads->mutex); - pthread_mutexattr_destroy (&perl_threads->mutexattr); + pthread_mutex_unlock(&perl_threads->mutex); + pthread_mutex_destroy(&perl_threads->mutex); + pthread_mutexattr_destroy(&perl_threads->mutexattr); - sfree (perl_threads); + sfree(perl_threads); - pthread_key_delete (perl_thr_key); + pthread_key_delete(perl_thr_key); - PERL_SYS_TERM (); + PERL_SYS_TERM(); - plugin_unregister_shutdown ("perl"); - return ret; + plugin_unregister_shutdown("perl"); + return ret; } /* static void perl_shutdown (void) */ /* @@ -2423,424 +2314,402 @@ static int perl_shutdown (void) * the global variables from Perl. */ -static int g_pv_get (pTHX_ SV *var, MAGIC *mg) -{ - char *pv = mg->mg_ptr; - sv_setpv (var, pv); - return 0; +static int g_pv_get(pTHX_ SV *var, MAGIC *mg) { + char *pv = mg->mg_ptr; + sv_setpv(var, pv); + return 0; } /* static int g_pv_get (pTHX_ SV *, MAGIC *) */ -static int g_pv_set (pTHX_ SV *var, MAGIC *mg) -{ - char *pv = mg->mg_ptr; - sstrncpy (pv, SvPV_nolen (var), DATA_MAX_NAME_LEN); - return 0; +static int g_pv_set(pTHX_ SV *var, MAGIC *mg) { + char *pv = mg->mg_ptr; + sstrncpy(pv, SvPV_nolen(var), DATA_MAX_NAME_LEN); + return 0; } /* static int g_pv_set (pTHX_ SV *, MAGIC *) */ -static int g_interval_get (pTHX_ SV *var, MAGIC *mg) -{ - log_warn ("Accessing $interval_g is deprecated (and might not " - "give the desired results) - plugin_get_interval() should " - "be used instead."); - sv_setnv (var, CDTIME_T_TO_DOUBLE (interval_g)); - return 0; +static int g_interval_get(pTHX_ SV *var, MAGIC *mg) { + log_warn("Accessing $interval_g is deprecated (and might not " + "give the desired results) - plugin_get_interval() should " + "be used instead."); + sv_setnv(var, CDTIME_T_TO_DOUBLE(interval_g)); + return 0; } /* static int g_interval_get (pTHX_ SV *, MAGIC *) */ -static int g_interval_set (pTHX_ SV *var, MAGIC *mg) -{ - double nv = (double)SvNV (var); - log_warn ("Accessing $interval_g is deprecated (and might not " - "give the desired results) - plugin_get_interval() should " - "be used instead."); - interval_g = DOUBLE_TO_CDTIME_T (nv); - return 0; +static int g_interval_set(pTHX_ SV *var, MAGIC *mg) { + double nv = (double)SvNV(var); + log_warn("Accessing $interval_g is deprecated (and might not " + "give the desired results) - plugin_get_interval() should " + "be used instead."); + interval_g = DOUBLE_TO_CDTIME_T(nv); + return 0; } /* static int g_interval_set (pTHX_ SV *, MAGIC *) */ -static MGVTBL g_pv_vtbl = { - g_pv_get, g_pv_set, NULL, NULL, NULL, NULL, NULL +static MGVTBL g_pv_vtbl = {g_pv_get, g_pv_set, NULL, NULL, NULL, NULL, NULL #if HAVE_PERL_STRUCT_MGVTBL_SVT_LOCAL - , NULL + , + NULL #endif }; -static MGVTBL g_interval_vtbl = { - g_interval_get, g_interval_set, NULL, NULL, NULL, NULL, NULL +static MGVTBL g_interval_vtbl = {g_interval_get, g_interval_set, NULL, NULL, + NULL, NULL, NULL #if HAVE_PERL_STRUCT_MGVTBL_SVT_LOCAL - , NULL + , + NULL #endif }; /* bootstrap the Collectd module */ -static void xs_init (pTHX) -{ - HV *stash = NULL; - SV *tmp = NULL; - char *file = __FILE__; - - dXSUB_SYS; - - /* enable usage of Perl modules using shared libraries */ - newXS ("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); - - /* register API */ - for (int i = 0; NULL != api[i].f; ++i) - newXS (api[i].name, api[i].f, file); - - stash = gv_stashpv ("Collectd", 1); - - /* export "constants" */ - for (int i = 0; '\0' != constants[i].name[0]; ++i) - newCONSTSUB (stash, constants[i].name, newSViv (constants[i].value)); - - /* export global variables - * by adding "magic" to the SV's representing the globale variables - * perl is able to automagically call the get/set function when - * accessing any such variable (this is basically the same as using - * tie() in Perl) */ - /* global strings */ - for (int i = 0; '\0' != g_strings[i].name[0]; ++i) { - tmp = get_sv (g_strings[i].name, 1); - sv_magicext (tmp, NULL, PERL_MAGIC_ext, &g_pv_vtbl, - g_strings[i].var, 0); - } - - tmp = get_sv ("Collectd::interval_g", /* create = */ 1); - sv_magicext (tmp, NULL, /* how = */ PERL_MAGIC_ext, - /* vtbl = */ &g_interval_vtbl, - /* name = */ NULL, /* namelen = */ 0); - - return; +static void xs_init(pTHX) { + HV *stash = NULL; + SV *tmp = NULL; + char *file = __FILE__; + + dXSUB_SYS; + + /* enable usage of Perl modules using shared libraries */ + newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); + + /* register API */ + for (int i = 0; NULL != api[i].f; ++i) + newXS(api[i].name, api[i].f, file); + + stash = gv_stashpv("Collectd", 1); + + /* export "constants" */ + for (int i = 0; '\0' != constants[i].name[0]; ++i) + newCONSTSUB(stash, constants[i].name, newSViv(constants[i].value)); + + /* export global variables + * by adding "magic" to the SV's representing the globale variables + * perl is able to automagically call the get/set function when + * accessing any such variable (this is basically the same as using + * tie() in Perl) */ + /* global strings */ + for (int i = 0; '\0' != g_strings[i].name[0]; ++i) { + tmp = get_sv(g_strings[i].name, 1); + sv_magicext(tmp, NULL, PERL_MAGIC_ext, &g_pv_vtbl, g_strings[i].var, 0); + } + + tmp = get_sv("Collectd::interval_g", /* create = */ 1); + sv_magicext(tmp, NULL, /* how = */ PERL_MAGIC_ext, + /* vtbl = */ &g_interval_vtbl, + /* name = */ NULL, /* namelen = */ 0); + + return; } /* static void xs_init (pTHX) */ /* Initialize the global Perl interpreter. */ -static int init_pi (int argc, char **argv) -{ - dTHXa (NULL); +static int init_pi(int argc, char **argv) { + dTHXa(NULL); - if (NULL != perl_threads) - return 0; + if (NULL != perl_threads) + return 0; - log_info ("Initializing Perl interpreter..."); + log_info("Initializing Perl interpreter..."); #if COLLECT_DEBUG - { - for (int i = 0; i < argc; ++i) - log_debug ("argv[%i] = \"%s\"", i, argv[i]); - } + { + for (int i = 0; i < argc; ++i) + log_debug("argv[%i] = \"%s\"", i, argv[i]); + } #endif /* COLLECT_DEBUG */ - if (0 != pthread_key_create (&perl_thr_key, c_ithread_destructor)) { - log_err ("init_pi: pthread_key_create failed"); + if (0 != pthread_key_create(&perl_thr_key, c_ithread_destructor)) { + log_err("init_pi: pthread_key_create failed"); - /* this must not happen - cowardly giving up if it does */ - return -1; - } + /* this must not happen - cowardly giving up if it does */ + return -1; + } #ifdef __FreeBSD__ - /* On FreeBSD, PERL_SYS_INIT3 expands to some expression which - * triggers a "value computed is not used" warning by gcc. */ - (void) + /* On FreeBSD, PERL_SYS_INIT3 expands to some expression which + * triggers a "value computed is not used" warning by gcc. */ + (void) #endif - PERL_SYS_INIT3 (&argc, &argv, &environ); + PERL_SYS_INIT3(&argc, &argv, &environ); - perl_threads = smalloc (sizeof (*perl_threads)); - memset (perl_threads, 0, sizeof (c_ithread_list_t)); + perl_threads = smalloc(sizeof(*perl_threads)); + memset(perl_threads, 0, sizeof(c_ithread_list_t)); - pthread_mutexattr_init(&perl_threads->mutexattr); - pthread_mutexattr_settype(&perl_threads->mutexattr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init (&perl_threads->mutex, &perl_threads->mutexattr); - /* locking the mutex should not be necessary at this point - * but let's just do it for the sake of completeness */ - pthread_mutex_lock (&perl_threads->mutex); + pthread_mutexattr_init(&perl_threads->mutexattr); + pthread_mutexattr_settype(&perl_threads->mutexattr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&perl_threads->mutex, &perl_threads->mutexattr); + /* locking the mutex should not be necessary at this point + * but let's just do it for the sake of completeness */ + pthread_mutex_lock(&perl_threads->mutex); - perl_threads->head = c_ithread_create (NULL); - perl_threads->tail = perl_threads->head; + perl_threads->head = c_ithread_create(NULL); + perl_threads->tail = perl_threads->head; - if (NULL == (perl_threads->head->interp = perl_alloc ())) { - log_err ("init_pi: Not enough memory."); - exit (3); - } + if (NULL == (perl_threads->head->interp = perl_alloc())) { + log_err("init_pi: Not enough memory."); + exit(3); + } - aTHX = perl_threads->head->interp; - pthread_mutex_unlock (&perl_threads->mutex); + aTHX = perl_threads->head->interp; + pthread_mutex_unlock(&perl_threads->mutex); - perl_construct (aTHX); + perl_construct(aTHX); - PL_exit_flags |= PERL_EXIT_DESTRUCT_END; + PL_exit_flags |= PERL_EXIT_DESTRUCT_END; - if (0 != perl_parse (aTHX_ xs_init, argc, argv, NULL)) { - SV *err = get_sv ("@", 1); - log_err ("init_pi: Unable to bootstrap Collectd: %s", - SvPV_nolen (err)); + if (0 != perl_parse(aTHX_ xs_init, argc, argv, NULL)) { + SV *err = get_sv("@", 1); + log_err("init_pi: Unable to bootstrap Collectd: %s", SvPV_nolen(err)); - perl_destruct (perl_threads->head->interp); - perl_free (perl_threads->head->interp); - sfree (perl_threads); + perl_destruct(perl_threads->head->interp); + perl_free(perl_threads->head->interp); + sfree(perl_threads); - pthread_key_delete (perl_thr_key); - return -1; - } + pthread_key_delete(perl_thr_key); + return -1; + } - /* Set $0 to "collectd" because perl_parse() has to set it to "-e". */ - sv_setpv (get_sv ("0", 0), "collectd"); + /* Set $0 to "collectd" because perl_parse() has to set it to "-e". */ + sv_setpv(get_sv("0", 0), "collectd"); - perl_run (aTHX); + perl_run(aTHX); - plugin_register_init ("perl", perl_init); - plugin_register_shutdown ("perl", perl_shutdown); - return 0; + plugin_register_init("perl", perl_init); + plugin_register_shutdown("perl", perl_shutdown); + return 0; } /* static int init_pi (const char **, const int) */ /* * LoadPlugin "" */ -static int perl_config_loadplugin (pTHX_ oconfig_item_t *ci) -{ - char module_name[DATA_MAX_NAME_LEN]; +static int perl_config_loadplugin(pTHX_ oconfig_item_t *ci) { + char module_name[DATA_MAX_NAME_LEN]; - char *value = NULL; + char *value = NULL; - if ((0 != ci->children_num) || (1 != ci->values_num) - || (OCONFIG_TYPE_STRING != ci->values[0].type)) { - log_err ("LoadPlugin expects a single string argument."); - return 1; - } + if ((0 != ci->children_num) || (1 != ci->values_num) || + (OCONFIG_TYPE_STRING != ci->values[0].type)) { + log_err("LoadPlugin expects a single string argument."); + return 1; + } - value = ci->values[0].value.string; + value = ci->values[0].value.string; - if (NULL == get_module_name (module_name, sizeof (module_name), value)) { - log_err ("Invalid module name %s", value); - return (1); - } + if (NULL == get_module_name(module_name, sizeof(module_name), value)) { + log_err("Invalid module name %s", value); + return (1); + } - if (0 != init_pi (perl_argc, perl_argv)) - return -1; + if (0 != init_pi(perl_argc, perl_argv)) + return -1; - assert (NULL != perl_threads); - assert (NULL != perl_threads->head); + assert(NULL != perl_threads); + assert(NULL != perl_threads->head); - aTHX = perl_threads->head->interp; + aTHX = perl_threads->head->interp; - log_debug ("perl_config: Loading Perl plugin \"%s\"", value); - load_module (PERL_LOADMOD_NOIMPORT, - newSVpv (module_name, strlen (module_name)), Nullsv); - return 0; + log_debug("perl_config: Loading Perl plugin \"%s\"", value); + load_module(PERL_LOADMOD_NOIMPORT, newSVpv(module_name, strlen(module_name)), + Nullsv); + return 0; } /* static int perl_config_loadplugin (oconfig_item_it *) */ /* * BaseName "" */ -static int perl_config_basename (pTHX_ oconfig_item_t *ci) -{ - char *value = NULL; +static int perl_config_basename(pTHX_ oconfig_item_t *ci) { + char *value = NULL; - if ((0 != ci->children_num) || (1 != ci->values_num) - || (OCONFIG_TYPE_STRING != ci->values[0].type)) { - log_err ("BaseName expects a single string argument."); - return 1; - } + if ((0 != ci->children_num) || (1 != ci->values_num) || + (OCONFIG_TYPE_STRING != ci->values[0].type)) { + log_err("BaseName expects a single string argument."); + return 1; + } - value = ci->values[0].value.string; + value = ci->values[0].value.string; - log_debug ("perl_config: Setting plugin basename to \"%s\"", value); - sstrncpy (base_name, value, sizeof (base_name)); - return 0; + log_debug("perl_config: Setting plugin basename to \"%s\"", value); + sstrncpy(base_name, value, sizeof(base_name)); + return 0; } /* static int perl_config_basename (oconfig_item_it *) */ /* * EnableDebugger ""|"" */ -static int perl_config_enabledebugger (pTHX_ oconfig_item_t *ci) -{ - char *value = NULL; - - if ((0 != ci->children_num) || (1 != ci->values_num) - || (OCONFIG_TYPE_STRING != ci->values[0].type)) { - log_err ("EnableDebugger expects a single string argument."); - return 1; - } - - if (NULL != perl_threads) { - log_warn ("EnableDebugger has no effects if used after LoadPlugin."); - return 1; - } - - value = ci->values[0].value.string; - - perl_argv = realloc (perl_argv, - (++perl_argc + 1) * sizeof (char *)); - - if (NULL == perl_argv) { - log_err ("perl_config: Not enough memory."); - exit (3); - } - - if ('\0' == value[0]) { - perl_argv[perl_argc - 1] = "-d"; - } - else { - perl_argv[perl_argc - 1] = smalloc (strlen (value) + 4); - sstrncpy (perl_argv[perl_argc - 1], "-d:", 4); - sstrncpy (perl_argv[perl_argc - 1] + 3, value, strlen (value) + 1); - } - - perl_argv[perl_argc] = NULL; - return 0; +static int perl_config_enabledebugger(pTHX_ oconfig_item_t *ci) { + char *value = NULL; + + if ((0 != ci->children_num) || (1 != ci->values_num) || + (OCONFIG_TYPE_STRING != ci->values[0].type)) { + log_err("EnableDebugger expects a single string argument."); + return 1; + } + + if (NULL != perl_threads) { + log_warn("EnableDebugger has no effects if used after LoadPlugin."); + return 1; + } + + value = ci->values[0].value.string; + + perl_argv = realloc(perl_argv, (++perl_argc + 1) * sizeof(char *)); + + if (NULL == perl_argv) { + log_err("perl_config: Not enough memory."); + exit(3); + } + + if ('\0' == value[0]) { + perl_argv[perl_argc - 1] = "-d"; + } else { + perl_argv[perl_argc - 1] = smalloc(strlen(value) + 4); + sstrncpy(perl_argv[perl_argc - 1], "-d:", 4); + sstrncpy(perl_argv[perl_argc - 1] + 3, value, strlen(value) + 1); + } + + perl_argv[perl_argc] = NULL; + return 0; } /* static int perl_config_enabledebugger (oconfig_item_it *) */ /* * IncludeDir "" */ -static int perl_config_includedir (pTHX_ oconfig_item_t *ci) -{ - char *value = NULL; - - if ((0 != ci->children_num) || (1 != ci->values_num) - || (OCONFIG_TYPE_STRING != ci->values[0].type)) { - log_err ("IncludeDir expects a single string argument."); - return 1; - } - - value = ci->values[0].value.string; - - if (NULL == aTHX) { - perl_argv = realloc (perl_argv, - (++perl_argc + 1) * sizeof (char *)); - - if (NULL == perl_argv) { - log_err ("perl_config: Not enough memory."); - exit (3); - } - - perl_argv[perl_argc - 1] = smalloc (strlen (value) + 3); - sstrncpy(perl_argv[perl_argc - 1], "-I", 3); - sstrncpy(perl_argv[perl_argc - 1] + 2, value, strlen (value) + 1); - - perl_argv[perl_argc] = NULL; - } - else { - /* prepend the directory to @INC */ - av_unshift (GvAVn (PL_incgv), 1); - av_store (GvAVn (PL_incgv), 0, newSVpv (value, strlen (value))); - } - return 0; +static int perl_config_includedir(pTHX_ oconfig_item_t *ci) { + char *value = NULL; + + if ((0 != ci->children_num) || (1 != ci->values_num) || + (OCONFIG_TYPE_STRING != ci->values[0].type)) { + log_err("IncludeDir expects a single string argument."); + return 1; + } + + value = ci->values[0].value.string; + + if (NULL == aTHX) { + perl_argv = realloc(perl_argv, (++perl_argc + 1) * sizeof(char *)); + + if (NULL == perl_argv) { + log_err("perl_config: Not enough memory."); + exit(3); + } + + perl_argv[perl_argc - 1] = smalloc(strlen(value) + 3); + sstrncpy(perl_argv[perl_argc - 1], "-I", 3); + sstrncpy(perl_argv[perl_argc - 1] + 2, value, strlen(value) + 1); + + perl_argv[perl_argc] = NULL; + } else { + /* prepend the directory to @INC */ + av_unshift(GvAVn(PL_incgv), 1); + av_store(GvAVn(PL_incgv), 0, newSVpv(value, strlen(value))); + } + return 0; } /* static int perl_config_includedir (oconfig_item_it *) */ /* * block */ -static int perl_config_plugin (pTHX_ oconfig_item_t *ci) -{ - int retvals = 0; - int ret = 0; +static int perl_config_plugin(pTHX_ oconfig_item_t *ci) { + int retvals = 0; + int ret = 0; - char *plugin; - HV *config; + char *plugin; + HV *config; - dSP; + dSP; - if ((1 != ci->values_num) || (OCONFIG_TYPE_STRING != ci->values[0].type)) { - log_err ("LoadPlugin expects a single string argument."); - return 1; - } + if ((1 != ci->values_num) || (OCONFIG_TYPE_STRING != ci->values[0].type)) { + log_err("LoadPlugin expects a single string argument."); + return 1; + } - plugin = ci->values[0].value.string; - config = newHV (); + plugin = ci->values[0].value.string; + config = newHV(); - if (0 != oconfig_item2hv (aTHX_ ci, config)) { - hv_clear (config); - hv_undef (config); + if (0 != oconfig_item2hv(aTHX_ ci, config)) { + hv_clear(config); + hv_undef(config); - log_err ("Unable to convert configuration to a Perl hash value."); - config = (HV *)&PL_sv_undef; - } + log_err("Unable to convert configuration to a Perl hash value."); + config = (HV *)&PL_sv_undef; + } - ENTER; - SAVETMPS; + ENTER; + SAVETMPS; - PUSHMARK (SP); + PUSHMARK(SP); - XPUSHs (sv_2mortal (newSVpv (plugin, 0))); - XPUSHs (sv_2mortal (newRV_noinc ((SV *)config))); + XPUSHs(sv_2mortal(newSVpv(plugin, 0))); + XPUSHs(sv_2mortal(newRV_noinc((SV *)config))); - PUTBACK; + PUTBACK; - retvals = call_pv ("Collectd::_plugin_dispatch_config", G_SCALAR); + retvals = call_pv("Collectd::_plugin_dispatch_config", G_SCALAR); - SPAGAIN; - if (0 < retvals) { - SV *tmp = POPs; - if (! SvTRUE (tmp)) - ret = 1; - } - else - ret = 1; + SPAGAIN; + if (0 < retvals) { + SV *tmp = POPs; + if (!SvTRUE(tmp)) + ret = 1; + } else + ret = 1; - PUTBACK; - FREETMPS; - LEAVE; - return ret; + PUTBACK; + FREETMPS; + LEAVE; + return ret; } /* static int perl_config_plugin (oconfig_item_it *) */ -static int perl_config (oconfig_item_t *ci) -{ - int status = 0; - - dTHXa (NULL); - - for (int i = 0; i < ci->children_num; ++i) { - oconfig_item_t *c = ci->children + i; - int current_status = 0; - - if (NULL != perl_threads) - { - if ((aTHX = PERL_GET_CONTEXT) == NULL) - return -1; - } - - if (0 == strcasecmp (c->key, "LoadPlugin")) - current_status = perl_config_loadplugin (aTHX_ c); - else if (0 == strcasecmp (c->key, "BaseName")) - current_status = perl_config_basename (aTHX_ c); - else if (0 == strcasecmp (c->key, "EnableDebugger")) - current_status = perl_config_enabledebugger (aTHX_ c); - else if (0 == strcasecmp (c->key, "IncludeDir")) - current_status = perl_config_includedir (aTHX_ c); - else if (0 == strcasecmp (c->key, "Plugin")) - current_status = perl_config_plugin (aTHX_ c); - else if (0 == strcasecmp (c->key, "RegisterLegacyFlush")) - cf_util_get_boolean (c, ®ister_legacy_flush); - else - { - log_warn ("Ignoring unknown config key \"%s\".", c->key); - current_status = 0; - } - - /* fatal error - it's up to perl_config_* to clean up */ - if (0 > current_status) { - log_err ("Configuration failed with a fatal error - " - "plugin disabled!"); - return current_status; - } - - status += current_status; - } - return status; +static int perl_config(oconfig_item_t *ci) { + int status = 0; + + dTHXa(NULL); + + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *c = ci->children + i; + int current_status = 0; + + if (NULL != perl_threads) { + if ((aTHX = PERL_GET_CONTEXT) == NULL) + return -1; + } + + if (0 == strcasecmp(c->key, "LoadPlugin")) + current_status = perl_config_loadplugin(aTHX_ c); + else if (0 == strcasecmp(c->key, "BaseName")) + current_status = perl_config_basename(aTHX_ c); + else if (0 == strcasecmp(c->key, "EnableDebugger")) + current_status = perl_config_enabledebugger(aTHX_ c); + else if (0 == strcasecmp(c->key, "IncludeDir")) + current_status = perl_config_includedir(aTHX_ c); + else if (0 == strcasecmp(c->key, "Plugin")) + current_status = perl_config_plugin(aTHX_ c); + else if (0 == strcasecmp(c->key, "RegisterLegacyFlush")) + cf_util_get_boolean(c, ®ister_legacy_flush); + else { + log_warn("Ignoring unknown config key \"%s\".", c->key); + current_status = 0; + } + + /* fatal error - it's up to perl_config_* to clean up */ + if (0 > current_status) { + log_err("Configuration failed with a fatal error - " + "plugin disabled!"); + return current_status; + } + + status += current_status; + } + return status; } /* static int perl_config (oconfig_item_t *) */ -void module_register (void) -{ - perl_argc = 4; - perl_argv = smalloc ((perl_argc + 1) * sizeof (*perl_argv)); +void module_register(void) { + perl_argc = 4; + perl_argv = smalloc((perl_argc + 1) * sizeof(*perl_argv)); - /* default options for the Perl interpreter */ - perl_argv[0] = ""; - perl_argv[1] = "-MCollectd"; - perl_argv[2] = "-e"; - perl_argv[3] = "1"; - perl_argv[4] = NULL; + /* default options for the Perl interpreter */ + perl_argv[0] = ""; + perl_argv[1] = "-MCollectd"; + perl_argv[2] = "-e"; + perl_argv[3] = "1"; + perl_argv[4] = NULL; - plugin_register_complex_config ("perl", perl_config); - return; + plugin_register_complex_config("perl", perl_config); + return; } /* void module_register (void) */ /* vim: set sw=4 ts=4 tw=78 noexpandtab : */ - diff --git a/src/pf.c b/src/pf.c index ecaa869c..533dffed 100644 --- a/src/pf.c +++ b/src/pf.c @@ -21,116 +21,107 @@ #include "collectd.h" -#include "plugin.h" #include "common.h" +#include "plugin.h" #if HAVE_SYS_IOCTL_H -# include +#include #endif #if HAVE_NET_IF_H -# include +#include #endif #if HAVE_NETINET_IN_H -# include +#include #endif #include #ifndef FCNT_NAMES -# if FCNT_MAX != 3 -# error "Unexpected value for FCNT_MAX" -# endif -# define FCNT_NAMES {"search", "insert", "removals", NULL}; +#if FCNT_MAX != 3 +#error "Unexpected value for FCNT_MAX" +#endif +#define FCNT_NAMES {"search", "insert", "removals", NULL}; #endif #ifndef SCNT_NAMES -# if SCNT_MAX != 3 -# error "Unexpected value for SCNT_MAX" -# endif -# define SCNT_NAMES {"search", "insert", "removals", NULL}; +#if SCNT_MAX != 3 +#error "Unexpected value for SCNT_MAX" +#endif +#define SCNT_NAMES {"search", "insert", "removals", NULL}; #endif -static char const *pf_reasons[PFRES_MAX+1] = PFRES_NAMES; -static char const *pf_lcounters[LCNT_MAX+1] = LCNT_NAMES; -static char const *pf_fcounters[FCNT_MAX+1] = FCNT_NAMES; -static char const *pf_scounters[SCNT_MAX+1] = SCNT_NAMES; +static char const *pf_reasons[PFRES_MAX + 1] = PFRES_NAMES; +static char const *pf_lcounters[LCNT_MAX + 1] = LCNT_NAMES; +static char const *pf_fcounters[FCNT_MAX + 1] = FCNT_NAMES; +static char const *pf_scounters[SCNT_MAX + 1] = SCNT_NAMES; static char const *pf_device = "/dev/pf"; -static void pf_submit (char const *type, char const *type_instance, - uint64_t val, _Bool is_gauge) -{ - value_t values[1]; - value_list_t vl = VALUE_LIST_INIT; +static void pf_submit(char const *type, char const *type_instance, uint64_t val, + _Bool is_gauge) { + value_t values[1]; + value_list_t vl = VALUE_LIST_INIT; - if (is_gauge) - values[0].gauge = (gauge_t) val; - else - values[0].derive = (derive_t) val; + if (is_gauge) + values[0].gauge = (gauge_t)val; + else + values[0].derive = (derive_t)val; - vl.values = values; - vl.values_len = 1; - sstrncpy (vl.plugin, "pf", sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof(vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof(vl.type_instance)); + vl.values = values; + vl.values_len = 1; + sstrncpy(vl.plugin, "pf", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values(&vl); + plugin_dispatch_values(&vl); } /* void pf_submit */ -static int pf_read (void) -{ - struct pf_status state; - int fd; - int status; - - fd = open (pf_device, O_RDONLY); - if (fd < 0) - { - char errbuf[1024]; - ERROR("pf plugin: Unable to open %s: %s", - pf_device, - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - status = ioctl (fd, DIOCGETSTATUS, &state); - if (status != 0) - { - char errbuf[1024]; - ERROR("pf plugin: ioctl(DIOCGETSTATUS) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - close(fd); - return (-1); - } - - close (fd); - - if (!state.running) - { - WARNING ("pf plugin: PF is not running."); - return (-1); - } - - for (int i = 0; i < PFRES_MAX; i++) - pf_submit ("pf_counters", pf_reasons[i], state.counters[i], - /* is gauge = */ 0); - for (int i = 0; i < LCNT_MAX; i++) - pf_submit ("pf_limits", pf_lcounters[i], state.lcounters[i], - /* is gauge = */ 0); - for (int i = 0; i < FCNT_MAX; i++) - pf_submit ("pf_state", pf_fcounters[i], state.fcounters[i], - /* is gauge = */ 0); - for (int i = 0; i < SCNT_MAX; i++) - pf_submit ("pf_source", pf_scounters[i], state.scounters[i], - /* is gauge = */ 0); - - pf_submit ("pf_states", "current", (uint32_t) state.states, - /* is gauge = */ 1); - - return (0); +static int pf_read(void) { + struct pf_status state; + int fd; + int status; + + fd = open(pf_device, O_RDONLY); + if (fd < 0) { + char errbuf[1024]; + ERROR("pf plugin: Unable to open %s: %s", pf_device, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + status = ioctl(fd, DIOCGETSTATUS, &state); + if (status != 0) { + char errbuf[1024]; + ERROR("pf plugin: ioctl(DIOCGETSTATUS) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(fd); + return (-1); + } + + close(fd); + + if (!state.running) { + WARNING("pf plugin: PF is not running."); + return (-1); + } + + for (int i = 0; i < PFRES_MAX; i++) + pf_submit("pf_counters", pf_reasons[i], state.counters[i], + /* is gauge = */ 0); + for (int i = 0; i < LCNT_MAX; i++) + pf_submit("pf_limits", pf_lcounters[i], state.lcounters[i], + /* is gauge = */ 0); + for (int i = 0; i < FCNT_MAX; i++) + pf_submit("pf_state", pf_fcounters[i], state.fcounters[i], + /* is gauge = */ 0); + for (int i = 0; i < SCNT_MAX; i++) + pf_submit("pf_source", pf_scounters[i], state.scounters[i], + /* is gauge = */ 0); + + pf_submit("pf_states", "current", (uint32_t)state.states, + /* is gauge = */ 1); + + return (0); } /* int pf_read */ -void module_register (void) -{ - plugin_register_read ("pf", pf_read); -} +void module_register(void) { plugin_register_read("pf", pf_read); } diff --git a/src/pinba.c b/src/pinba.c index ba8069da..7fd23a02 100644 --- a/src/pinba.c +++ b/src/pinba.c @@ -35,49 +35,46 @@ /* AIX doesn't have MSG_DONTWAIT */ #ifndef MSG_DONTWAIT -# define MSG_DONTWAIT MSG_NONBLOCK +#define MSG_DONTWAIT MSG_NONBLOCK #endif /* * Defines */ #ifndef PINBA_UDP_BUFFER_SIZE -# define PINBA_UDP_BUFFER_SIZE 65536 +#define PINBA_UDP_BUFFER_SIZE 65536 #endif #ifndef PINBA_DEFAULT_NODE -# define PINBA_DEFAULT_NODE "::0" +#define PINBA_DEFAULT_NODE "::0" #endif #ifndef PINBA_DEFAULT_SERVICE -# define PINBA_DEFAULT_SERVICE "30002" +#define PINBA_DEFAULT_SERVICE "30002" #endif #ifndef PINBA_MAX_SOCKETS -# define PINBA_MAX_SOCKETS 16 +#define PINBA_MAX_SOCKETS 16 #endif /* * Private data structures */ /* {{{ */ -struct pinba_socket_s -{ +struct pinba_socket_s { struct pollfd fd[PINBA_MAX_SOCKETS]; nfds_t fd_num; }; typedef struct pinba_socket_s pinba_socket_t; /* Fixed point counter value. n is the decimal part multiplied by 10^9. */ -struct float_counter_s -{ +struct float_counter_s { uint64_t i; uint64_t n; /* nanos */ }; typedef struct float_counter_s float_counter_t; -struct pinba_statnode_s -{ +struct pinba_statnode_s { /* collector name, used as plugin instance */ char *name; @@ -117,85 +114,79 @@ static pthread_t collector_thread_id; /* * Functions */ -static void float_counter_add (float_counter_t *fc, float val) /* {{{ */ +static void float_counter_add(float_counter_t *fc, float val) /* {{{ */ { uint64_t tmp; if (val < 0.0) return; - tmp = (uint64_t) val; - val -= (double) tmp; + tmp = (uint64_t)val; + val -= (double)tmp; fc->i += tmp; - fc->n += (uint64_t) ((val * 1000000000.0) + .5); + fc->n += (uint64_t)((val * 1000000000.0) + .5); - if (fc->n >= 1000000000) - { + if (fc->n >= 1000000000) { fc->i += 1; fc->n -= 1000000000; - assert (fc->n < 1000000000); + assert(fc->n < 1000000000); } } /* }}} void float_counter_add */ -static derive_t float_counter_get (const float_counter_t *fc, /* {{{ */ - uint64_t factor) -{ +static derive_t float_counter_get(const float_counter_t *fc, /* {{{ */ + uint64_t factor) { derive_t ret; - ret = (derive_t) (fc->i * factor); - ret += (derive_t) (fc->n / (1000000000 / factor)); + ret = (derive_t)(fc->i * factor); + ret += (derive_t)(fc->n / (1000000000 / factor)); return (ret); } /* }}} derive_t float_counter_get */ -static void strset (char **str, const char *new) /* {{{ */ +static void strset(char **str, const char *new) /* {{{ */ { char *tmp; if (!str || !new) return; - tmp = strdup (new); + tmp = strdup(new); if (tmp == NULL) return; - sfree (*str); + sfree(*str); *str = tmp; } /* }}} void strset */ static void service_statnode_add(const char *name, /* {{{ */ - const char *host, - const char *server, - const char *script) -{ + const char *host, const char *server, + const char *script) { pinba_statnode_t *node; - node = realloc (stat_nodes, - sizeof (*stat_nodes) * (stat_nodes_num + 1)); - if (node == NULL) - { - ERROR ("pinba plugin: realloc failed"); + node = realloc(stat_nodes, sizeof(*stat_nodes) * (stat_nodes_num + 1)); + if (node == NULL) { + ERROR("pinba plugin: realloc failed"); return; } stat_nodes = node; node = stat_nodes + stat_nodes_num; - memset (node, 0, sizeof (*node)); + memset(node, 0, sizeof(*node)); /* reset strings */ - node->name = NULL; - node->host = NULL; + node->name = NULL; + node->host = NULL; node->server = NULL; node->script = NULL; node->mem_peak = NAN; /* fill query data */ - strset (&node->name, name); - strset (&node->host, host); - strset (&node->server, server); - strset (&node->script, script); + strset(&node->name, name); + strset(&node->host, host); + strset(&node->server, server); + strset(&node->script, script); /* increment counter */ stat_nodes_num++; @@ -204,9 +195,8 @@ static void service_statnode_add(const char *name, /* {{{ */ /* Copy the data from the global "stat_nodes" list into the buffer pointed to * by "res", doing the derivation in the process. Returns the next index or * zero if the end of the list has been reached. */ -static unsigned int service_statnode_collect (pinba_statnode_t *res, /* {{{ */ - unsigned int index) -{ +static unsigned int service_statnode_collect(pinba_statnode_t *res, /* {{{ */ + unsigned int index) { pinba_statnode_t *node; if (stat_nodes_num == 0) @@ -214,17 +204,16 @@ static unsigned int service_statnode_collect (pinba_statnode_t *res, /* {{{ */ /* begin collecting */ if (index == 0) - pthread_mutex_lock (&stat_nodes_lock); + pthread_mutex_lock(&stat_nodes_lock); /* end collecting */ - if (index >= stat_nodes_num) - { - pthread_mutex_unlock (&stat_nodes_lock); + if (index >= stat_nodes_num) { + pthread_mutex_unlock(&stat_nodes_lock); return 0; } node = stat_nodes + index; - memcpy (res, node, sizeof (*res)); + memcpy(res, node, sizeof(*res)); /* reset node */ node->mem_peak = NAN; @@ -232,39 +221,37 @@ static unsigned int service_statnode_collect (pinba_statnode_t *res, /* {{{ */ return (index + 1); } /* }}} unsigned int service_statnode_collect */ -static void service_statnode_process (pinba_statnode_t *node, /* {{{ */ - Pinba__Request* request) -{ +static void service_statnode_process(pinba_statnode_t *node, /* {{{ */ + Pinba__Request *request) { node->req_count++; - float_counter_add (&node->req_time, request->request_time); - float_counter_add (&node->ru_utime, request->ru_utime); - float_counter_add (&node->ru_stime, request->ru_stime); + float_counter_add(&node->req_time, request->request_time); + float_counter_add(&node->ru_utime, request->ru_utime); + float_counter_add(&node->ru_stime, request->ru_stime); node->doc_size += request->document_size; - if (isnan (node->mem_peak) - || (node->mem_peak < ((gauge_t) request->memory_peak))) - node->mem_peak = (gauge_t) request->memory_peak; + if (isnan(node->mem_peak) || + (node->mem_peak < ((gauge_t)request->memory_peak))) + node->mem_peak = (gauge_t)request->memory_peak; } /* }}} void service_statnode_process */ -static void service_process_request (Pinba__Request *request) /* {{{ */ +static void service_process_request(Pinba__Request *request) /* {{{ */ { - pthread_mutex_lock (&stat_nodes_lock); + pthread_mutex_lock(&stat_nodes_lock); - for (unsigned int i = 0; i < stat_nodes_num; i++) - { - if ((stat_nodes[i].host != NULL) - && (strcmp (request->hostname, stat_nodes[i].host) != 0)) + for (unsigned int i = 0; i < stat_nodes_num; i++) { + if ((stat_nodes[i].host != NULL) && + (strcmp(request->hostname, stat_nodes[i].host) != 0)) continue; - if ((stat_nodes[i].server != NULL) - && (strcmp (request->server_name, stat_nodes[i].server) != 0)) + if ((stat_nodes[i].server != NULL) && + (strcmp(request->server_name, stat_nodes[i].server) != 0)) continue; - if ((stat_nodes[i].script != NULL) - && (strcmp (request->script_name, stat_nodes[i].script) != 0)) + if ((stat_nodes[i].script != NULL) && + (strcmp(request->script_name, stat_nodes[i].script) != 0)) continue; service_statnode_process(&stat_nodes[i], request); @@ -273,66 +260,60 @@ static void service_process_request (Pinba__Request *request) /* {{{ */ pthread_mutex_unlock(&stat_nodes_lock); } /* }}} void service_process_request */ -static int pb_del_socket (pinba_socket_t *s, /* {{{ */ - nfds_t index) -{ +static int pb_del_socket(pinba_socket_t *s, /* {{{ */ + nfds_t index) { if (index >= s->fd_num) return (EINVAL); - close (s->fd[index].fd); + close(s->fd[index].fd); s->fd[index].fd = -1; /* When deleting the last element in the list, no memmove is necessary. */ - if (index < (s->fd_num - 1)) - { - memmove (&s->fd[index], &s->fd[index + 1], - sizeof (s->fd[0]) * (s->fd_num - (index + 1))); + if (index < (s->fd_num - 1)) { + memmove(&s->fd[index], &s->fd[index + 1], + sizeof(s->fd[0]) * (s->fd_num - (index + 1))); } s->fd_num--; return (0); } /* }}} int pb_del_socket */ -static int pb_add_socket (pinba_socket_t *s, /* {{{ */ - const struct addrinfo *ai) -{ +static int pb_add_socket(pinba_socket_t *s, /* {{{ */ + const struct addrinfo *ai) { int fd; int tmp; int status; - if (s->fd_num == PINBA_MAX_SOCKETS) - { - WARNING ("pinba plugin: Sorry, you have hit the built-in limit of " - "%i sockets. Please complain to the collectd developers so we can " - "raise the limit.", PINBA_MAX_SOCKETS); + if (s->fd_num == PINBA_MAX_SOCKETS) { + WARNING("pinba plugin: Sorry, you have hit the built-in limit of " + "%i sockets. Please complain to the collectd developers so we can " + "raise the limit.", + PINBA_MAX_SOCKETS); return (-1); } - fd = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (fd < 0) - { + fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (fd < 0) { char errbuf[1024]; - ERROR ("pinba plugin: socket(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("pinba plugin: socket(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); return (0); } tmp = 1; - status = setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof (tmp)); - if (status != 0) - { + status = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp)); + if (status != 0) { char errbuf[1024]; - WARNING ("pinba plugin: setsockopt(SO_REUSEADDR) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + WARNING("pinba plugin: setsockopt(SO_REUSEADDR) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); } - status = bind (fd, ai->ai_addr, ai->ai_addrlen); - if (status != 0) - { + status = bind(fd, ai->ai_addr, ai->ai_addrlen); + if (status != 0) { char errbuf[1024]; - ERROR ("pinba plugin: bind(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - close (fd); + ERROR("pinba plugin: bind(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(fd); return (0); } @@ -344,9 +325,8 @@ static int pb_add_socket (pinba_socket_t *s, /* {{{ */ return (0); } /* }}} int pb_add_socket */ -static pinba_socket_t *pinba_socket_open (const char *node, /* {{{ */ - const char *service) -{ +static pinba_socket_t *pinba_socket_open(const char *node, /* {{{ */ + const char *service) { pinba_socket_t *s; struct addrinfo *ai_list; int status; @@ -357,120 +337,106 @@ static pinba_socket_t *pinba_socket_open (const char *node, /* {{{ */ if (service == NULL) service = PINBA_DEFAULT_SERVICE; - struct addrinfo ai_hints = { - .ai_family = AF_UNSPEC, - .ai_flags = AI_PASSIVE, - .ai_socktype = SOCK_DGRAM - }; + struct addrinfo ai_hints = {.ai_family = AF_UNSPEC, + .ai_flags = AI_PASSIVE, + .ai_socktype = SOCK_DGRAM}; - status = getaddrinfo (node, service, - &ai_hints, &ai_list); - if (status != 0) - { - ERROR ("pinba plugin: getaddrinfo(3) failed: %s", - gai_strerror (status)); + status = getaddrinfo(node, service, &ai_hints, &ai_list); + if (status != 0) { + ERROR("pinba plugin: getaddrinfo(3) failed: %s", gai_strerror(status)); return (NULL); } - assert (ai_list != NULL); + assert(ai_list != NULL); - s = calloc (1, sizeof (*s)); - if (s == NULL) - { - freeaddrinfo (ai_list); - ERROR ("pinba plugin: calloc failed."); + s = calloc(1, sizeof(*s)); + if (s == NULL) { + freeaddrinfo(ai_list); + ERROR("pinba plugin: calloc failed."); return (NULL); } - for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) - { - status = pb_add_socket (s, ai_ptr); + for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; + ai_ptr = ai_ptr->ai_next) { + status = pb_add_socket(s, ai_ptr); if (status != 0) break; } /* for (ai_list) */ - freeaddrinfo (ai_list); + freeaddrinfo(ai_list); - if (s->fd_num < 1) - { - WARNING ("pinba plugin: Unable to open socket for address %s.", node); - sfree (s); + if (s->fd_num < 1) { + WARNING("pinba plugin: Unable to open socket for address %s.", node); + sfree(s); s = NULL; } return (s); } /* }}} pinba_socket_open */ -static void pinba_socket_free (pinba_socket_t *socket) /* {{{ */ +static void pinba_socket_free(pinba_socket_t *socket) /* {{{ */ { if (!socket) return; - for (nfds_t i = 0; i < socket->fd_num; i++) - { + for (nfds_t i = 0; i < socket->fd_num; i++) { if (socket->fd[i].fd < 0) continue; - close (socket->fd[i].fd); + close(socket->fd[i].fd); socket->fd[i].fd = -1; } sfree(socket); } /* }}} void pinba_socket_free */ -static int pinba_process_stats_packet (const uint8_t *buffer, /* {{{ */ - size_t buffer_size) -{ +static int pinba_process_stats_packet(const uint8_t *buffer, /* {{{ */ + size_t buffer_size) { Pinba__Request *request; - request = pinba__request__unpack (NULL, buffer_size, buffer); + request = pinba__request__unpack(NULL, buffer_size, buffer); if (!request) return (-1); service_process_request(request); - pinba__request__free_unpacked (request, NULL); + pinba__request__free_unpacked(request, NULL); return (0); } /* }}} int pinba_process_stats_packet */ -static int pinba_udp_read_callback_fn (int sock) /* {{{ */ +static int pinba_udp_read_callback_fn(int sock) /* {{{ */ { uint8_t buffer[PINBA_UDP_BUFFER_SIZE]; size_t buffer_size; int status; - while (42) - { - buffer_size = sizeof (buffer); - status = recvfrom (sock, buffer, buffer_size - 1, MSG_DONTWAIT, /* from = */ NULL, /* from len = */ 0); - if (status < 0) - { + while (42) { + buffer_size = sizeof(buffer); + status = recvfrom(sock, buffer, buffer_size - 1, MSG_DONTWAIT, + /* from = */ NULL, /* from len = */ 0); + if (status < 0) { char errbuf[1024]; if ((errno == EINTR) #ifdef EWOULDBLOCK || (errno == EWOULDBLOCK) #endif - || (errno == EAGAIN)) - { + || (errno == EAGAIN)) { continue; } WARNING("pinba plugin: recvfrom(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); - } - else if (status == 0) - { - DEBUG ("pinba plugin: recvfrom(2) returned unexpected status zero."); + } else if (status == 0) { + DEBUG("pinba plugin: recvfrom(2) returned unexpected status zero."); return (-1); - } - else /* if (status > 0) */ + } else /* if (status > 0) */ { - assert (((size_t) status) < buffer_size); - buffer_size = (size_t) status; + assert(((size_t)status) < buffer_size); + buffer_size = (size_t)status; buffer[buffer_size] = 0; - status = pinba_process_stats_packet (buffer, buffer_size); + status = pinba_process_stats_packet(buffer, buffer_size); if (status != 0) DEBUG("pinba plugin: Parsing packet failed."); return (status); @@ -478,104 +444,94 @@ static int pinba_udp_read_callback_fn (int sock) /* {{{ */ } /* while (42) */ /* not reached */ - assert (23 == 42); + assert(23 == 42); return (-1); } /* }}} void pinba_udp_read_callback_fn */ -static int receive_loop (void) /* {{{ */ +static int receive_loop(void) /* {{{ */ { pinba_socket_t *s; - s = pinba_socket_open (conf_node, conf_service); - if (s == NULL) - { - ERROR ("pinba plugin: Collector thread is exiting prematurely."); + s = pinba_socket_open(conf_node, conf_service); + if (s == NULL) { + ERROR("pinba plugin: Collector thread is exiting prematurely."); return (-1); } - while (!collector_thread_do_shutdown) - { + while (!collector_thread_do_shutdown) { int status; if (s->fd_num < 1) break; - status = poll (s->fd, s->fd_num, /* timeout = */ 1000); + status = poll(s->fd, s->fd_num, /* timeout = */ 1000); if (status == 0) /* timeout */ { continue; - } - else if (status < 0) - { + } else if (status < 0) { char errbuf[1024]; if ((errno == EINTR) || (errno == EAGAIN)) continue; - ERROR ("pinba plugin: poll(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - pinba_socket_free (s); + ERROR("pinba plugin: poll(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + pinba_socket_free(s); return (-1); } - for (nfds_t i = 0; i < s->fd_num; i++) - { - if (s->fd[i].revents & (POLLERR | POLLHUP | POLLNVAL)) - { - pb_del_socket (s, i); + for (nfds_t i = 0; i < s->fd_num; i++) { + if (s->fd[i].revents & (POLLERR | POLLHUP | POLLNVAL)) { + pb_del_socket(s, i); i--; - } - else if (s->fd[i].revents & (POLLIN | POLLPRI)) - { - pinba_udp_read_callback_fn (s->fd[i].fd); + } else if (s->fd[i].revents & (POLLIN | POLLPRI)) { + pinba_udp_read_callback_fn(s->fd[i].fd); } } /* for (s->fd) */ - } /* while (!collector_thread_do_shutdown) */ + } /* while (!collector_thread_do_shutdown) */ - pinba_socket_free (s); + pinba_socket_free(s); s = NULL; return (0); } /* }}} int receive_loop */ -static void *collector_thread (void *arg) /* {{{ */ +static void *collector_thread(void *arg) /* {{{ */ { - receive_loop (); + receive_loop(); - memset (&collector_thread_id, 0, sizeof (collector_thread_id)); + memset(&collector_thread_id, 0, sizeof(collector_thread_id)); collector_thread_running = 0; - pthread_exit (NULL); + pthread_exit(NULL); return (NULL); } /* }}} void *collector_thread */ /* * Plugin declaration section */ -static int pinba_config_view (const oconfig_item_t *ci) /* {{{ */ +static int pinba_config_view(const oconfig_item_t *ci) /* {{{ */ { - char *name = NULL; - char *host = NULL; + char *name = NULL; + char *host = NULL; char *server = NULL; char *script = NULL; int status; - status = cf_util_get_string (ci, &name); + status = cf_util_get_string(ci, &name); if (status != 0) return (status); - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Host", child->key) == 0) - status = cf_util_get_string (child, &host); - else if (strcasecmp ("Server", child->key) == 0) - status = cf_util_get_string (child, &server); - else if (strcasecmp ("Script", child->key) == 0) - status = cf_util_get_string (child, &script); - else - { - WARNING ("pinba plugin: Unknown config option: %s", child->key); + if (strcasecmp("Host", child->key) == 0) + status = cf_util_get_string(child, &host); + else if (strcasecmp("Server", child->key) == 0) + status = cf_util_get_string(child, &server); + else if (strcasecmp("Script", child->key) == 0) + status = cf_util_get_string(child, &script); + else { + WARNING("pinba plugin: Unknown config option: %s", child->key); status = -1; } @@ -584,34 +540,33 @@ static int pinba_config_view (const oconfig_item_t *ci) /* {{{ */ } if (status == 0) - service_statnode_add (name, host, server, script); + service_statnode_add(name, host, server, script); - sfree (name); - sfree (host); - sfree (server); - sfree (script); + sfree(name); + sfree(host); + sfree(server); + sfree(script); return (status); } /* }}} int pinba_config_view */ -static int plugin_config (oconfig_item_t *ci) /* {{{ */ +static int plugin_config(oconfig_item_t *ci) /* {{{ */ { /* The lock should not be necessary in the config callback, but let's be * sure.. */ - pthread_mutex_lock (&stat_nodes_lock); + pthread_mutex_lock(&stat_nodes_lock); - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Address", child->key) == 0) - cf_util_get_string (child, &conf_node); - else if (strcasecmp ("Port", child->key) == 0) - cf_util_get_service (child, &conf_service); - else if (strcasecmp ("View", child->key) == 0) - pinba_config_view (child); + if (strcasecmp("Address", child->key) == 0) + cf_util_get_string(child, &conf_node); + else if (strcasecmp("Port", child->key) == 0) + cf_util_get_service(child, &conf_service); + else if (strcasecmp("View", child->key) == 0) + pinba_config_view(child); else - WARNING ("pinba plugin: Unknown config option: %s", child->key); + WARNING("pinba plugin: Unknown config option: %s", child->key); } pthread_mutex_unlock(&stat_nodes_lock); @@ -619,31 +574,28 @@ static int plugin_config (oconfig_item_t *ci) /* {{{ */ return (0); } /* }}} int pinba_config */ -static int plugin_init (void) /* {{{ */ +static int plugin_init(void) /* {{{ */ { int status; - if (stat_nodes == NULL) - { + if (stat_nodes == NULL) { /* Collect the "total" data by default. */ - service_statnode_add ("total", - /* host = */ NULL, - /* server = */ NULL, - /* script = */ NULL); + service_statnode_add("total", + /* host = */ NULL, + /* server = */ NULL, + /* script = */ NULL); } if (collector_thread_running) return (0); - status = plugin_thread_create (&collector_thread_id, - /* attrs = */ NULL, - collector_thread, - /* args = */ NULL, "pinba collector"); - if (status != 0) - { + status = plugin_thread_create(&collector_thread_id, + /* attrs = */ NULL, collector_thread, + /* args = */ NULL, "pinba collector"); + if (status != 0) { char errbuf[1024]; - ERROR ("pinba plugin: pthread_create(3) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("pinba plugin: pthread_create(3) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } collector_thread_running = 1; @@ -651,21 +603,19 @@ static int plugin_init (void) /* {{{ */ return (0); } /* }}} */ -static int plugin_shutdown (void) /* {{{ */ +static int plugin_shutdown(void) /* {{{ */ { - if (collector_thread_running) - { + if (collector_thread_running) { int status; - DEBUG ("pinba plugin: Shutting down collector thread."); + DEBUG("pinba plugin: Shutting down collector thread."); collector_thread_do_shutdown = 1; - status = pthread_join (collector_thread_id, /* retval = */ NULL); - if (status != 0) - { + status = pthread_join(collector_thread_id, /* retval = */ NULL); + if (status != 0) { char errbuf[1024]; - ERROR ("pinba plugin: pthread_join(3) failed: %s", - sstrerror (status, errbuf, sizeof (errbuf))); + ERROR("pinba plugin: pthread_join(3) failed: %s", + sstrerror(status, errbuf, sizeof(errbuf))); } collector_thread_running = 0; @@ -675,63 +625,65 @@ static int plugin_shutdown (void) /* {{{ */ return (0); } /* }}} int plugin_shutdown */ -static int plugin_submit (const pinba_statnode_t *res) /* {{{ */ +static int plugin_submit(const pinba_statnode_t *res) /* {{{ */ { value_list_t vl = VALUE_LIST_INIT; vl.values_len = 1; - sstrncpy (vl.plugin, "pinba", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, res->name, sizeof (vl.plugin_instance)); - - vl.values = &(value_t) { .derive = res->req_count }; - sstrncpy (vl.type, "total_requests", sizeof (vl.type)); - plugin_dispatch_values (&vl); - - vl.values = &(value_t) { .derive = float_counter_get (&res->req_time, /* factor = */ 1000) }; - sstrncpy (vl.type, "total_time_in_ms", sizeof (vl.type)); - plugin_dispatch_values (&vl); - - vl.values = &(value_t) { .derive = res->doc_size }; - sstrncpy (vl.type, "total_bytes", sizeof (vl.type)); - plugin_dispatch_values (&vl); - - vl.values = &(value_t) { .derive = float_counter_get (&res->ru_utime, /* factor = */ 100) }; - sstrncpy (vl.type, "cpu", sizeof (vl.type)); - sstrncpy (vl.type_instance, "user", sizeof (vl.type_instance)); - plugin_dispatch_values (&vl); - - vl.values = &(value_t) { .derive = float_counter_get (&res->ru_stime, /* factor = */ 100) }; - sstrncpy (vl.type, "cpu", sizeof (vl.type)); - sstrncpy (vl.type_instance, "system", sizeof (vl.type_instance)); - plugin_dispatch_values (&vl); - - vl.values = &(value_t) { .gauge = res->mem_peak }; - sstrncpy (vl.type, "memory", sizeof (vl.type)); - sstrncpy (vl.type_instance, "peak", sizeof (vl.type_instance)); - plugin_dispatch_values (&vl); + sstrncpy(vl.plugin, "pinba", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, res->name, sizeof(vl.plugin_instance)); + + vl.values = &(value_t){.derive = res->req_count}; + sstrncpy(vl.type, "total_requests", sizeof(vl.type)); + plugin_dispatch_values(&vl); + + vl.values = &(value_t){ + .derive = float_counter_get(&res->req_time, /* factor = */ 1000)}; + sstrncpy(vl.type, "total_time_in_ms", sizeof(vl.type)); + plugin_dispatch_values(&vl); + + vl.values = &(value_t){.derive = res->doc_size}; + sstrncpy(vl.type, "total_bytes", sizeof(vl.type)); + plugin_dispatch_values(&vl); + + vl.values = &(value_t){ + .derive = float_counter_get(&res->ru_utime, /* factor = */ 100)}; + sstrncpy(vl.type, "cpu", sizeof(vl.type)); + sstrncpy(vl.type_instance, "user", sizeof(vl.type_instance)); + plugin_dispatch_values(&vl); + + vl.values = &(value_t){ + .derive = float_counter_get(&res->ru_stime, /* factor = */ 100)}; + sstrncpy(vl.type, "cpu", sizeof(vl.type)); + sstrncpy(vl.type_instance, "system", sizeof(vl.type_instance)); + plugin_dispatch_values(&vl); + + vl.values = &(value_t){.gauge = res->mem_peak}; + sstrncpy(vl.type, "memory", sizeof(vl.type)); + sstrncpy(vl.type_instance, "peak", sizeof(vl.type_instance)); + plugin_dispatch_values(&vl); return (0); } /* }}} int plugin_submit */ -static int plugin_read (void) /* {{{ */ +static int plugin_read(void) /* {{{ */ { - unsigned int i=0; + unsigned int i = 0; pinba_statnode_t data; - while ((i = service_statnode_collect (&data, i)) != 0) - { - plugin_submit (&data); + while ((i = service_statnode_collect(&data, i)) != 0) { + plugin_submit(&data); } return 0; } /* }}} int plugin_read */ -void module_register (void) /* {{{ */ +void module_register(void) /* {{{ */ { - plugin_register_complex_config ("pinba", plugin_config); - plugin_register_init ("pinba", plugin_init); - plugin_register_read ("pinba", plugin_read); - plugin_register_shutdown ("pinba", plugin_shutdown); + plugin_register_complex_config("pinba", plugin_config); + plugin_register_init("pinba", plugin_init); + plugin_register_read("pinba", plugin_read); + plugin_register_shutdown("pinba", plugin_shutdown); } /* }}} void module_register */ /* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/pinba.proto b/src/pinba.proto index 22e61c6a..09d095c5 100644 --- a/src/pinba.proto +++ b/src/pinba.proto @@ -4,21 +4,21 @@ package Pinba; option optimize_for = SPEED; message Request { - required string hostname = 1; - required string server_name = 2; - required string script_name = 3; - required uint32 request_count = 4; - required uint32 document_size = 5; - required uint32 memory_peak = 6; - required float request_time = 7; - required float ru_utime = 8; - required float ru_stime = 9; + required string hostname = 1; + required string server_name = 2; + required string script_name = 3; + required uint32 request_count = 4; + required uint32 document_size = 5; + required uint32 memory_peak = 6; + required float request_time = 7; + required float ru_utime = 8; + required float ru_stime = 9; - repeated uint32 timer_hit_count = 10; - repeated float timer_value = 11; - repeated uint32 timer_tag_count = 12; - repeated uint32 timer_tag_name = 13; - repeated uint32 timer_tag_value = 14; - repeated string dictionary = 15; - optional uint32 status = 16; + repeated uint32 timer_hit_count = 10; + repeated float timer_value = 11; + repeated uint32 timer_tag_count = 12; + repeated uint32 timer_tag_name = 13; + repeated uint32 timer_tag_value = 14; + repeated string dictionary = 15; + optional uint32 status = 16; } diff --git a/src/ping.c b/src/ping.c index 66a254d5..82de59f0 100644 --- a/src/ping.c +++ b/src/ping.c @@ -32,28 +32,27 @@ #include #if HAVE_NETDB_H -# include /* NI_MAXHOST */ +#include /* NI_MAXHOST */ #endif #ifdef HAVE_SYS_CAPABILITY_H -# include +#include #endif #include #ifndef NI_MAXHOST -# define NI_MAXHOST 1025 +#define NI_MAXHOST 1025 #endif #if defined(OPING_VERSION) && (OPING_VERSION >= 1003000) -# define HAVE_OPING_1_3 +#define HAVE_OPING_1_3 #endif /* * Private data types */ -struct hostlist_s -{ +struct hostlist_s { char *host; uint32_t pkg_sent; @@ -72,138 +71,120 @@ typedef struct hostlist_s hostlist_t; */ static hostlist_t *hostlist_head = NULL; -static char *ping_source = NULL; +static char *ping_source = NULL; #ifdef HAVE_OPING_1_3 -static char *ping_device = NULL; +static char *ping_device = NULL; #endif -static char *ping_data = NULL; -static int ping_ttl = PING_DEF_TTL; +static char *ping_data = NULL; +static int ping_ttl = PING_DEF_TTL; static double ping_interval = 1.0; static double ping_timeout = 0.9; -static int ping_max_missed = -1; +static int ping_max_missed = -1; -static int ping_thread_loop = 0; -static int ping_thread_error = 0; -static pthread_t ping_thread_id; +static int ping_thread_loop = 0; +static int ping_thread_error = 0; +static pthread_t ping_thread_id; static pthread_mutex_t ping_lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t ping_cond = PTHREAD_COND_INITIALIZER; +static pthread_cond_t ping_cond = PTHREAD_COND_INITIALIZER; -static const char *config_keys[] = -{ - "Host", - "SourceAddress", +static const char *config_keys[] = {"Host", "SourceAddress", #ifdef HAVE_OPING_1_3 - "Device", + "Device", #endif - "Size", - "TTL", - "Interval", - "Timeout", - "MaxMissed" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); + "Size", "TTL", "Interval", + "Timeout", "MaxMissed"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); /* * Private functions */ /* Assure that `ts->tv_nsec' is in the range 0 .. 999999999 */ -static void time_normalize (struct timespec *ts) /* {{{ */ +static void time_normalize(struct timespec *ts) /* {{{ */ { - while (ts->tv_nsec < 0) - { - if (ts->tv_sec == 0) - { + while (ts->tv_nsec < 0) { + if (ts->tv_sec == 0) { ts->tv_nsec = 0; return; } - ts->tv_sec -= 1; + ts->tv_sec -= 1; ts->tv_nsec += 1000000000; } - while (ts->tv_nsec >= 1000000000) - { - ts->tv_sec += 1; + while (ts->tv_nsec >= 1000000000) { + ts->tv_sec += 1; ts->tv_nsec -= 1000000000; } } /* }}} void time_normalize */ /* Add `ts_int' to `tv_begin' and store the result in `ts_dest'. If the result * is larger than `tv_end', copy `tv_end' to `ts_dest' instead. */ -static void time_calc (struct timespec *ts_dest, /* {{{ */ - const struct timespec *ts_int, - const struct timeval *tv_begin, - const struct timeval *tv_end) -{ +static void time_calc(struct timespec *ts_dest, /* {{{ */ + const struct timespec *ts_int, + const struct timeval *tv_begin, + const struct timeval *tv_end) { ts_dest->tv_sec = tv_begin->tv_sec + ts_int->tv_sec; ts_dest->tv_nsec = (tv_begin->tv_usec * 1000) + ts_int->tv_nsec; - time_normalize (ts_dest); + time_normalize(ts_dest); /* Assure that `(begin + interval) > end'. * This may seem overly complicated, but `tv_sec' is of type `time_t' * which may be `unsigned. *sigh* */ - if ((tv_end->tv_sec > ts_dest->tv_sec) - || ((tv_end->tv_sec == ts_dest->tv_sec) - && ((tv_end->tv_usec * 1000) > ts_dest->tv_nsec))) - { + if ((tv_end->tv_sec > ts_dest->tv_sec) || + ((tv_end->tv_sec == ts_dest->tv_sec) && + ((tv_end->tv_usec * 1000) > ts_dest->tv_nsec))) { ts_dest->tv_sec = tv_end->tv_sec; ts_dest->tv_nsec = 1000 * tv_end->tv_usec; } - time_normalize (ts_dest); + time_normalize(ts_dest); } /* }}} void time_calc */ -static int ping_dispatch_all (pingobj_t *pingobj) /* {{{ */ +static int ping_dispatch_all(pingobj_t *pingobj) /* {{{ */ { hostlist_t *hl; int status; - for (pingobj_iter_t *iter = ping_iterator_get (pingobj); - iter != NULL; - iter = ping_iterator_next (iter)) - { /* {{{ */ + for (pingobj_iter_t *iter = ping_iterator_get(pingobj); iter != NULL; + iter = ping_iterator_next(iter)) { /* {{{ */ char userhost[NI_MAXHOST]; double latency; size_t param_size; - param_size = sizeof (userhost); - status = ping_iterator_get_info (iter, + param_size = sizeof(userhost); + status = ping_iterator_get_info(iter, #ifdef PING_INFO_USERNAME - PING_INFO_USERNAME, + PING_INFO_USERNAME, #else - PING_INFO_HOSTNAME, + PING_INFO_HOSTNAME, #endif - userhost, ¶m_size); - if (status != 0) - { - WARNING ("ping plugin: ping_iterator_get_info failed: %s", - ping_get_error (pingobj)); + userhost, ¶m_size); + if (status != 0) { + WARNING("ping plugin: ping_iterator_get_info failed: %s", + ping_get_error(pingobj)); continue; } for (hl = hostlist_head; hl != NULL; hl = hl->next) - if (strcmp (userhost, hl->host) == 0) + if (strcmp(userhost, hl->host) == 0) break; - if (hl == NULL) - { - WARNING ("ping plugin: Cannot find host %s.", userhost); + if (hl == NULL) { + WARNING("ping plugin: Cannot find host %s.", userhost); continue; } - param_size = sizeof (latency); - status = ping_iterator_get_info (iter, PING_INFO_LATENCY, - (void *) &latency, ¶m_size); - if (status != 0) - { - WARNING ("ping plugin: ping_iterator_get_info failed: %s", - ping_get_error (pingobj)); + param_size = sizeof(latency); + status = ping_iterator_get_info(iter, PING_INFO_LATENCY, (void *)&latency, + ¶m_size); + if (status != 0) { + WARNING("ping plugin: ping_iterator_get_info failed: %s", + ping_get_error(pingobj)); continue; } hl->pkg_sent++; - if (latency >= 0.0) - { + if (latency >= 0.0) { hl->pkg_recv++; hl->latency_total += latency; hl->latency_squared += (latency * latency); @@ -214,42 +195,39 @@ static int ping_dispatch_all (pingobj_t *pingobj) /* {{{ */ hl->pkg_missed++; /* if the host did not answer our last N packages, trigger a resolv. */ - if ((ping_max_missed >= 0) - && (hl->pkg_missed >= ((uint32_t) ping_max_missed))) - { /* {{{ */ + if ((ping_max_missed >= 0) && + (hl->pkg_missed >= ((uint32_t)ping_max_missed))) { /* {{{ */ /* we reset the missed package counter here, since we only want to * trigger a resolv every N packages and not every package _AFTER_ N * missed packages */ hl->pkg_missed = 0; - WARNING ("ping plugin: host %s has not answered %d PING requests," - " triggering resolve", hl->host, ping_max_missed); + WARNING("ping plugin: host %s has not answered %d PING requests," + " triggering resolve", + hl->host, ping_max_missed); /* we trigger the resolv simply be removeing and adding the host to our * ping object */ - status = ping_host_remove (pingobj, hl->host); - if (status != 0) - { - WARNING ("ping plugin: ping_host_remove (%s) failed.", hl->host); - } - else - { - status = ping_host_add (pingobj, hl->host); + status = ping_host_remove(pingobj, hl->host); + if (status != 0) { + WARNING("ping plugin: ping_host_remove (%s) failed.", hl->host); + } else { + status = ping_host_add(pingobj, hl->host); if (status != 0) - ERROR ("ping plugin: ping_host_add (%s) failed.", hl->host); + ERROR("ping plugin: ping_host_add (%s) failed.", hl->host); } } /* }}} ping_max_missed */ - } /* }}} for (iter) */ + } /* }}} for (iter) */ return (0); } /* }}} int ping_dispatch_all */ -static void *ping_thread (void *arg) /* {{{ */ +static void *ping_thread(void *arg) /* {{{ */ { pingobj_t *pingobj = NULL; - struct timeval tv_begin; - struct timeval tv_end; + struct timeval tv_begin; + struct timeval tv_end; struct timespec ts_wait; struct timespec ts_int; @@ -257,54 +235,50 @@ static void *ping_thread (void *arg) /* {{{ */ c_complain_t complaint = C_COMPLAIN_INIT_STATIC; - pthread_mutex_lock (&ping_lock); + pthread_mutex_lock(&ping_lock); - pingobj = ping_construct (); - if (pingobj == NULL) - { - ERROR ("ping plugin: ping_construct failed."); + pingobj = ping_construct(); + if (pingobj == NULL) { + ERROR("ping plugin: ping_construct failed."); ping_thread_error = 1; - pthread_mutex_unlock (&ping_lock); - return ((void *) -1); + pthread_mutex_unlock(&ping_lock); + return ((void *)-1); } if (ping_source != NULL) - if (ping_setopt (pingobj, PING_OPT_SOURCE, (void *) ping_source) != 0) - ERROR ("ping plugin: Failed to set source address: %s", - ping_get_error (pingobj)); + if (ping_setopt(pingobj, PING_OPT_SOURCE, (void *)ping_source) != 0) + ERROR("ping plugin: Failed to set source address: %s", + ping_get_error(pingobj)); #ifdef HAVE_OPING_1_3 if (ping_device != NULL) - if (ping_setopt (pingobj, PING_OPT_DEVICE, (void *) ping_device) != 0) - ERROR ("ping plugin: Failed to set device: %s", - ping_get_error (pingobj)); + if (ping_setopt(pingobj, PING_OPT_DEVICE, (void *)ping_device) != 0) + ERROR("ping plugin: Failed to set device: %s", ping_get_error(pingobj)); #endif - ping_setopt (pingobj, PING_OPT_TIMEOUT, (void *) &ping_timeout); - ping_setopt (pingobj, PING_OPT_TTL, (void *) &ping_ttl); + ping_setopt(pingobj, PING_OPT_TIMEOUT, (void *)&ping_timeout); + ping_setopt(pingobj, PING_OPT_TTL, (void *)&ping_ttl); if (ping_data != NULL) - ping_setopt (pingobj, PING_OPT_DATA, (void *) ping_data); + ping_setopt(pingobj, PING_OPT_DATA, (void *)ping_data); /* Add all the hosts to the ping object. */ count = 0; - for (hostlist_t *hl = hostlist_head; hl != NULL; hl = hl->next) - { + for (hostlist_t *hl = hostlist_head; hl != NULL; hl = hl->next) { int tmp_status; - tmp_status = ping_host_add (pingobj, hl->host); + tmp_status = ping_host_add(pingobj, hl->host); if (tmp_status != 0) - WARNING ("ping plugin: ping_host_add (%s) failed: %s", - hl->host, ping_get_error (pingobj)); + WARNING("ping plugin: ping_host_add (%s) failed: %s", hl->host, + ping_get_error(pingobj)); else count++; } - if (count == 0) - { - ERROR ("ping plugin: No host could be added to ping object. Giving up."); + if (count == 0) { + ERROR("ping plugin: No host could be added to ping object. Giving up."); ping_thread_error = 1; - pthread_mutex_unlock (&ping_lock); - return ((void *) -1); + pthread_mutex_unlock(&ping_lock); + return ((void *)-1); } /* Set up `ts_int' */ @@ -312,205 +286,188 @@ static void *ping_thread (void *arg) /* {{{ */ double temp_sec; double temp_nsec; - temp_nsec = modf (ping_interval, &temp_sec); - ts_int.tv_sec = (time_t) temp_sec; - ts_int.tv_nsec = (long) (temp_nsec * 1000000000L); + temp_nsec = modf(ping_interval, &temp_sec); + ts_int.tv_sec = (time_t)temp_sec; + ts_int.tv_nsec = (long)(temp_nsec * 1000000000L); } - while (ping_thread_loop > 0) - { + while (ping_thread_loop > 0) { int status; _Bool send_successful = 0; - if (gettimeofday (&tv_begin, NULL) < 0) - { + if (gettimeofday(&tv_begin, NULL) < 0) { char errbuf[1024]; - ERROR ("ping plugin: gettimeofday failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("ping plugin: gettimeofday failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); ping_thread_error = 1; break; } - pthread_mutex_unlock (&ping_lock); + pthread_mutex_unlock(&ping_lock); - status = ping_send (pingobj); - if (status < 0) - { - c_complain (LOG_ERR, &complaint, "ping plugin: ping_send failed: %s", - ping_get_error (pingobj)); - } - else - { - c_release (LOG_NOTICE, &complaint, "ping plugin: ping_send succeeded."); + status = ping_send(pingobj); + if (status < 0) { + c_complain(LOG_ERR, &complaint, "ping plugin: ping_send failed: %s", + ping_get_error(pingobj)); + } else { + c_release(LOG_NOTICE, &complaint, "ping plugin: ping_send succeeded."); send_successful = 1; } - pthread_mutex_lock (&ping_lock); + pthread_mutex_lock(&ping_lock); if (ping_thread_loop <= 0) break; if (send_successful) - (void) ping_dispatch_all (pingobj); + (void)ping_dispatch_all(pingobj); - if (gettimeofday (&tv_end, NULL) < 0) - { + if (gettimeofday(&tv_end, NULL) < 0) { char errbuf[1024]; - ERROR ("ping plugin: gettimeofday failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("ping plugin: gettimeofday failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); ping_thread_error = 1; break; } /* Calculate the absolute time until which to wait and store it in * `ts_wait'. */ - time_calc (&ts_wait, &ts_int, &tv_begin, &tv_end); + time_calc(&ts_wait, &ts_int, &tv_begin, &tv_end); - pthread_cond_timedwait (&ping_cond, &ping_lock, &ts_wait); + pthread_cond_timedwait(&ping_cond, &ping_lock, &ts_wait); if (ping_thread_loop <= 0) break; } /* while (ping_thread_loop > 0) */ - pthread_mutex_unlock (&ping_lock); - ping_destroy (pingobj); + pthread_mutex_unlock(&ping_lock); + ping_destroy(pingobj); - return ((void *) 0); + return ((void *)0); } /* }}} void *ping_thread */ -static int start_thread (void) /* {{{ */ +static int start_thread(void) /* {{{ */ { int status; - pthread_mutex_lock (&ping_lock); + pthread_mutex_lock(&ping_lock); - if (ping_thread_loop != 0) - { - pthread_mutex_unlock (&ping_lock); + if (ping_thread_loop != 0) { + pthread_mutex_unlock(&ping_lock); return (0); } ping_thread_loop = 1; ping_thread_error = 0; - status = plugin_thread_create (&ping_thread_id, /* attr = */ NULL, - ping_thread, /* arg = */ (void *) 0, "ping"); - if (status != 0) - { + status = plugin_thread_create(&ping_thread_id, /* attr = */ NULL, ping_thread, + /* arg = */ (void *)0, "ping"); + if (status != 0) { ping_thread_loop = 0; - ERROR ("ping plugin: Starting thread failed."); - pthread_mutex_unlock (&ping_lock); + ERROR("ping plugin: Starting thread failed."); + pthread_mutex_unlock(&ping_lock); return (-1); } - pthread_mutex_unlock (&ping_lock); + pthread_mutex_unlock(&ping_lock); return (0); } /* }}} int start_thread */ -static int stop_thread (void) /* {{{ */ +static int stop_thread(void) /* {{{ */ { int status; - pthread_mutex_lock (&ping_lock); + pthread_mutex_lock(&ping_lock); - if (ping_thread_loop == 0) - { - pthread_mutex_unlock (&ping_lock); + if (ping_thread_loop == 0) { + pthread_mutex_unlock(&ping_lock); return (-1); } ping_thread_loop = 0; - pthread_cond_broadcast (&ping_cond); - pthread_mutex_unlock (&ping_lock); + pthread_cond_broadcast(&ping_cond); + pthread_mutex_unlock(&ping_lock); - status = pthread_join (ping_thread_id, /* return = */ NULL); - if (status != 0) - { - ERROR ("ping plugin: Stopping thread failed."); + status = pthread_join(ping_thread_id, /* return = */ NULL); + if (status != 0) { + ERROR("ping plugin: Stopping thread failed."); status = -1; } - pthread_mutex_lock (&ping_lock); - memset (&ping_thread_id, 0, sizeof (ping_thread_id)); + pthread_mutex_lock(&ping_lock); + memset(&ping_thread_id, 0, sizeof(ping_thread_id)); ping_thread_error = 0; - pthread_mutex_unlock (&ping_lock); + pthread_mutex_unlock(&ping_lock); return (status); } /* }}} int stop_thread */ -static int ping_init (void) /* {{{ */ +static int ping_init(void) /* {{{ */ { - if (hostlist_head == NULL) - { - NOTICE ("ping plugin: No hosts have been configured."); + if (hostlist_head == NULL) { + NOTICE("ping plugin: No hosts have been configured."); return (-1); } - if (ping_timeout > ping_interval) - { + if (ping_timeout > ping_interval) { ping_timeout = 0.9 * ping_interval; - WARNING ("ping plugin: Timeout is greater than interval. " - "Will use a timeout of %gs.", ping_timeout); + WARNING("ping plugin: Timeout is greater than interval. " + "Will use a timeout of %gs.", + ping_timeout); } #if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_NET_RAW) - if (check_capability (CAP_NET_RAW) != 0) - { - if (getuid () == 0) - WARNING ("ping plugin: Running collectd as root, but the CAP_NET_RAW " - "capability is missing. The plugin's read function will probably " - "fail. Is your init system dropping capabilities?"); + if (check_capability(CAP_NET_RAW) != 0) { + if (getuid() == 0) + WARNING("ping plugin: Running collectd as root, but the CAP_NET_RAW " + "capability is missing. The plugin's read function will probably " + "fail. Is your init system dropping capabilities?"); else - WARNING ("ping plugin: collectd doesn't have the CAP_NET_RAW capability. " - "If you don't want to run collectd as root, try running \"setcap " - "cap_net_raw=ep\" on the collectd binary."); + WARNING("ping plugin: collectd doesn't have the CAP_NET_RAW capability. " + "If you don't want to run collectd as root, try running \"setcap " + "cap_net_raw=ep\" on the collectd binary."); } #endif - return (start_thread ()); + return (start_thread()); } /* }}} int ping_init */ -static int config_set_string (const char *name, /* {{{ */ - char **var, const char *value) -{ +static int config_set_string(const char *name, /* {{{ */ + char **var, const char *value) { char *tmp; - tmp = strdup (value); - if (tmp == NULL) - { + tmp = strdup(value); + if (tmp == NULL) { char errbuf[1024]; - ERROR ("ping plugin: Setting `%s' to `%s' failed: strdup failed: %s", - name, value, sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("ping plugin: Setting `%s' to `%s' failed: strdup failed: %s", name, + value, sstrerror(errno, errbuf, sizeof(errbuf))); return (1); } if (*var != NULL) - free (*var); + free(*var); *var = tmp; return (0); } /* }}} int config_set_string */ -static int ping_config (const char *key, const char *value) /* {{{ */ +static int ping_config(const char *key, const char *value) /* {{{ */ { - if (strcasecmp (key, "Host") == 0) - { + if (strcasecmp(key, "Host") == 0) { hostlist_t *hl; char *host; - hl = malloc (sizeof (*hl)); - if (hl == NULL) - { + hl = malloc(sizeof(*hl)); + if (hl == NULL) { char errbuf[1024]; - ERROR ("ping plugin: malloc failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("ping plugin: malloc failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); return (1); } - host = strdup (value); - if (host == NULL) - { + host = strdup(value); + if (host == NULL) { char errbuf[1024]; - sfree (hl); - ERROR ("ping plugin: strdup failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + sfree(hl); + ERROR("ping plugin: strdup failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); return (1); } @@ -522,51 +479,41 @@ static int ping_config (const char *key, const char *value) /* {{{ */ hl->latency_squared = 0.0; hl->next = hostlist_head; hostlist_head = hl; - } - else if (strcasecmp (key, "SourceAddress") == 0) - { - int status = config_set_string (key, &ping_source, value); + } else if (strcasecmp(key, "SourceAddress") == 0) { + int status = config_set_string(key, &ping_source, value); if (status != 0) return (status); } #ifdef HAVE_OPING_1_3 - else if (strcasecmp (key, "Device") == 0) - { - int status = config_set_string (key, &ping_device, value); + else if (strcasecmp(key, "Device") == 0) { + int status = config_set_string(key, &ping_device, value); if (status != 0) return (status); } #endif - else if (strcasecmp (key, "TTL") == 0) - { - int ttl = atoi (value); + else if (strcasecmp(key, "TTL") == 0) { + int ttl = atoi(value); if ((ttl > 0) && (ttl <= 255)) ping_ttl = ttl; else - WARNING ("ping plugin: Ignoring invalid TTL %i.", ttl); - } - else if (strcasecmp (key, "Interval") == 0) - { + WARNING("ping plugin: Ignoring invalid TTL %i.", ttl); + } else if (strcasecmp(key, "Interval") == 0) { double tmp; - tmp = atof (value); + tmp = atof(value); if (tmp > 0.0) ping_interval = tmp; else - WARNING ("ping plugin: Ignoring invalid interval %g (%s)", - tmp, value); - } - else if (strcasecmp (key, "Size") == 0) { - size_t size = (size_t) atoi (value); + WARNING("ping plugin: Ignoring invalid interval %g (%s)", tmp, value); + } else if (strcasecmp(key, "Size") == 0) { + size_t size = (size_t)atoi(value); /* Max IP packet size - (IPv6 + ICMP) = 65535 - (40 + 8) = 65487 */ - if (size <= 65487) - { - sfree (ping_data); - ping_data = malloc (size + 1); - if (ping_data == NULL) - { - ERROR ("ping plugin: malloc failed."); + if (size <= 65487) { + sfree(ping_data); + ping_data = malloc(size + 1); + if (ping_data == NULL) { + ERROR("ping plugin: malloc failed."); return (1); } @@ -582,67 +529,57 @@ static int ping_config (const char *key, const char *value) /* {{{ */ /* This restricts data pattern to be only composed of easily * printable characters, and not NUL character. */ ping_data[i] = ('0' + i % 64); - } /* }}} for (i = 0; i < size; i++) */ + } /* }}} for (i = 0; i < size; i++) */ ping_data[size] = 0; } else - WARNING ("ping plugin: Ignoring invalid Size %zu.", size); - } - else if (strcasecmp (key, "Timeout") == 0) - { + WARNING("ping plugin: Ignoring invalid Size %zu.", size); + } else if (strcasecmp(key, "Timeout") == 0) { double tmp; - tmp = atof (value); + tmp = atof(value); if (tmp > 0.0) ping_timeout = tmp; else - WARNING ("ping plugin: Ignoring invalid timeout %g (%s)", - tmp, value); - } - else if (strcasecmp (key, "MaxMissed") == 0) - { - ping_max_missed = atoi (value); + WARNING("ping plugin: Ignoring invalid timeout %g (%s)", tmp, value); + } else if (strcasecmp(key, "MaxMissed") == 0) { + ping_max_missed = atoi(value); if (ping_max_missed < 0) - INFO ("ping plugin: MaxMissed < 0, disabled re-resolving of hosts"); - } - else - { + INFO("ping plugin: MaxMissed < 0, disabled re-resolving of hosts"); + } else { return (-1); } return (0); } /* }}} int ping_config */ -static void submit (const char *host, const char *type, /* {{{ */ - gauge_t value) -{ +static void submit(const char *host, const char *type, /* {{{ */ + gauge_t value) { value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; + vl.values = &(value_t){.gauge = value}; vl.values_len = 1; - sstrncpy (vl.plugin, "ping", sizeof (vl.plugin)); - sstrncpy (vl.type_instance, host, sizeof (vl.type_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); + sstrncpy(vl.plugin, "ping", sizeof(vl.plugin)); + sstrncpy(vl.type_instance, host, sizeof(vl.type_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* }}} void ping_submit */ -static int ping_read (void) /* {{{ */ +static int ping_read(void) /* {{{ */ { - if (ping_thread_error != 0) - { - ERROR ("ping plugin: The ping thread had a problem. Restarting it."); + if (ping_thread_error != 0) { + ERROR("ping plugin: The ping thread had a problem. Restarting it."); - stop_thread (); + stop_thread(); - for (hostlist_t *hl = hostlist_head; hl != NULL; hl = hl->next) - { + for (hostlist_t *hl = hostlist_head; hl != NULL; hl = hl->next) { hl->pkg_sent = 0; hl->pkg_recv = 0; hl->latency_total = 0.0; hl->latency_squared = 0.0; } - start_thread (); + start_thread(); return (-1); } /* if (ping_thread_error != 0) */ @@ -661,7 +598,7 @@ static int ping_read (void) /* {{{ */ /* Locking here works, because the structure of the linked list is only * changed during configure and shutdown. */ - pthread_mutex_lock (&ping_lock); + pthread_mutex_lock(&ping_lock); pkg_sent = hl->pkg_sent; pkg_recv = hl->pkg_recv; @@ -673,13 +610,11 @@ static int ping_read (void) /* {{{ */ hl->latency_total = 0.0; hl->latency_squared = 0.0; - pthread_mutex_unlock (&ping_lock); + pthread_mutex_unlock(&ping_lock); /* This e. g. happens when starting up. */ - if (pkg_sent == 0) - { - DEBUG ("ping plugin: No packages for host %s have been sent.", - hl->host); + if (pkg_sent == 0) { + DEBUG("ping plugin: No packages for host %s have been sent.", hl->host); continue; } @@ -687,7 +622,7 @@ static int ping_read (void) /* {{{ */ if (pkg_recv == 0) latency_average = NAN; else - latency_average = latency_total / ((double) pkg_recv); + latency_average = latency_total / ((double)pkg_recv); /* Calculate standard deviation. Beware even more of division by zero. */ if (pkg_recv == 0) @@ -695,57 +630,54 @@ static int ping_read (void) /* {{{ */ else if (pkg_recv == 1) latency_stddev = 0.0; else - latency_stddev = sqrt (((((double) pkg_recv) * latency_squared) - - (latency_total * latency_total)) - / ((double) (pkg_recv * (pkg_recv - 1)))); + latency_stddev = sqrt(((((double)pkg_recv) * latency_squared) - + (latency_total * latency_total)) / + ((double)(pkg_recv * (pkg_recv - 1)))); /* Calculate drop rate. */ - droprate = ((double) (pkg_sent - pkg_recv)) / ((double) pkg_sent); + droprate = ((double)(pkg_sent - pkg_recv)) / ((double)pkg_sent); - submit (hl->host, "ping", latency_average); - submit (hl->host, "ping_stddev", latency_stddev); - submit (hl->host, "ping_droprate", droprate); + submit(hl->host, "ping", latency_average); + submit(hl->host, "ping_stddev", latency_stddev); + submit(hl->host, "ping_droprate", droprate); } /* }}} for (hl = hostlist_head; hl != NULL; hl = hl->next) */ return (0); } /* }}} int ping_read */ -static int ping_shutdown (void) /* {{{ */ +static int ping_shutdown(void) /* {{{ */ { hostlist_t *hl; - INFO ("ping plugin: Shutting down thread."); - if (stop_thread () < 0) + INFO("ping plugin: Shutting down thread."); + if (stop_thread() < 0) return (-1); hl = hostlist_head; - while (hl != NULL) - { + while (hl != NULL) { hostlist_t *hl_next; hl_next = hl->next; - sfree (hl->host); - sfree (hl); + sfree(hl->host); + sfree(hl); hl = hl_next; } if (ping_data != NULL) { - free (ping_data); + free(ping_data); ping_data = NULL; } return (0); } /* }}} int ping_shutdown */ -void module_register (void) -{ - plugin_register_config ("ping", ping_config, - config_keys, config_keys_num); - plugin_register_init ("ping", ping_init); - plugin_register_read ("ping", ping_read); - plugin_register_shutdown ("ping", ping_shutdown); +void module_register(void) { + plugin_register_config("ping", ping_config, config_keys, config_keys_num); + plugin_register_init("ping", ping_init); + plugin_register_read("ping", ping_read); + plugin_register_shutdown("ping", ping_shutdown); } /* void module_register */ /* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/postgresql.c b/src/postgresql.c index 8b609492..2af89886 100644 --- a/src/postgresql.c +++ b/src/postgresql.c @@ -37,1302 +37,1233 @@ #include "plugin.h" #include "utils_cache.h" -#include "utils_db_query.h" #include "utils_complain.h" +#include "utils_db_query.h" -#include #include +#include -#define log_err(...) ERROR ("postgresql: " __VA_ARGS__) -#define log_warn(...) WARNING ("postgresql: " __VA_ARGS__) -#define log_info(...) INFO ("postgresql: " __VA_ARGS__) -#define log_debug(...) DEBUG ("postgresql: " __VA_ARGS__) +#define log_err(...) ERROR("postgresql: " __VA_ARGS__) +#define log_warn(...) WARNING("postgresql: " __VA_ARGS__) +#define log_info(...) INFO("postgresql: " __VA_ARGS__) +#define log_debug(...) DEBUG("postgresql: " __VA_ARGS__) #ifndef C_PSQL_DEFAULT_CONF -# define C_PSQL_DEFAULT_CONF PKGDATADIR "/postgresql_default.conf" +#define C_PSQL_DEFAULT_CONF PKGDATADIR "/postgresql_default.conf" #endif /* Appends the (parameter, value) pair to the string * pointed to by 'buf' suitable to be used as argument * for PQconnectdb(). If value equals NULL, the pair * is ignored. */ -#define C_PSQL_PAR_APPEND(buf, buf_len, parameter, value) \ - if ((0 < (buf_len)) && (NULL != (value)) && ('\0' != *(value))) { \ - int s = ssnprintf (buf, buf_len, " %s = '%s'", parameter, value); \ - if (0 < s) { \ - buf += s; \ - buf_len -= s; \ - } \ - } +#define C_PSQL_PAR_APPEND(buf, buf_len, parameter, value) \ + if ((0 < (buf_len)) && (NULL != (value)) && ('\0' != *(value))) { \ + int s = ssnprintf(buf, buf_len, " %s = '%s'", parameter, value); \ + if (0 < s) { \ + buf += s; \ + buf_len -= s; \ + } \ + } /* Returns the tuple (major, minor, patchlevel) * for the given version number. */ -#define C_PSQL_SERVER_VERSION3(server_version) \ - (server_version) / 10000, \ - (server_version) / 100 - (int)((server_version) / 10000) * 100, \ - (server_version) - (int)((server_version) / 100) * 100 +#define C_PSQL_SERVER_VERSION3(server_version) \ + (server_version) / 10000, \ + (server_version) / 100 - (int)((server_version) / 10000) * 100, \ + (server_version) - (int)((server_version) / 100) * 100 /* Returns true if the given host specifies a * UNIX domain socket. */ -#define C_PSQL_IS_UNIX_DOMAIN_SOCKET(host) \ - ((NULL == (host)) || ('\0' == *(host)) || ('/' == *(host))) +#define C_PSQL_IS_UNIX_DOMAIN_SOCKET(host) \ + ((NULL == (host)) || ('\0' == *(host)) || ('/' == *(host))) /* Returns the tuple (host, delimiter, port) for a * given (host, port) pair. Depending on the value of * 'host' a UNIX domain socket or a TCP socket is * assumed. */ -#define C_PSQL_SOCKET3(host, port) \ - ((NULL == (host)) || ('\0' == *(host))) ? DEFAULT_PGSOCKET_DIR : host, \ - C_PSQL_IS_UNIX_DOMAIN_SOCKET (host) ? "/.s.PGSQL." : ":", \ - port +#define C_PSQL_SOCKET3(host, port) \ + ((NULL == (host)) || ('\0' == *(host))) ? DEFAULT_PGSOCKET_DIR : host, \ + C_PSQL_IS_UNIX_DOMAIN_SOCKET(host) ? "/.s.PGSQL." : ":", port typedef enum { - C_PSQL_PARAM_HOST = 1, - C_PSQL_PARAM_DB, - C_PSQL_PARAM_USER, - C_PSQL_PARAM_INTERVAL, - C_PSQL_PARAM_INSTANCE, + C_PSQL_PARAM_HOST = 1, + C_PSQL_PARAM_DB, + C_PSQL_PARAM_USER, + C_PSQL_PARAM_INTERVAL, + C_PSQL_PARAM_INSTANCE, } c_psql_param_t; /* Parameter configuration. Stored as `user data' in the query objects. */ typedef struct { - c_psql_param_t *params; - int params_num; + c_psql_param_t *params; + int params_num; } c_psql_user_data_t; typedef struct { - char *name; - char *statement; - _Bool store_rates; + char *name; + char *statement; + _Bool store_rates; } c_psql_writer_t; typedef struct { - PGconn *conn; - c_complain_t conn_complaint; + PGconn *conn; + c_complain_t conn_complaint; - int proto_version; - int server_version; + int proto_version; + int server_version; - int max_params_num; + int max_params_num; - /* user configuration */ - udb_query_preparation_area_t **q_prep_areas; - udb_query_t **queries; - size_t queries_num; + /* user configuration */ + udb_query_preparation_area_t **q_prep_areas; + udb_query_t **queries; + size_t queries_num; - c_psql_writer_t **writers; - size_t writers_num; + c_psql_writer_t **writers; + size_t writers_num; - /* make sure we don't access the database object in parallel */ - pthread_mutex_t db_lock; + /* make sure we don't access the database object in parallel */ + pthread_mutex_t db_lock; - cdtime_t interval; + cdtime_t interval; - /* writer "caching" settings */ - cdtime_t commit_interval; - cdtime_t next_commit; - cdtime_t expire_delay; + /* writer "caching" settings */ + cdtime_t commit_interval; + cdtime_t next_commit; + cdtime_t expire_delay; - char *host; - char *port; - char *database; - char *user; - char *password; + char *host; + char *port; + char *database; + char *user; + char *password; - char *instance; + char *instance; - char *sslmode; + char *sslmode; - char *krbsrvname; + char *krbsrvname; - char *service; + char *service; - int ref_cnt; + int ref_cnt; } c_psql_database_t; static const char *const def_queries[] = { - "backends", - "transactions", - "queries", - "query_plans", - "table_states", - "disk_io", - "disk_usage" -}; -static int def_queries_num = STATIC_ARRAY_SIZE (def_queries); - -static c_psql_database_t **databases = NULL; -static size_t databases_num = 0; - -static udb_query_t **queries = NULL; -static size_t queries_num = 0; - -static c_psql_writer_t *writers = NULL; -static size_t writers_num = 0; - -static int c_psql_begin (c_psql_database_t *db) -{ - PGresult *r = PQexec (db->conn, "BEGIN"); - - int status = 1; - - if (r != NULL) { - if (PGRES_COMMAND_OK == PQresultStatus (r)) { - db->next_commit = cdtime() + db->commit_interval; - status = 0; - } - else - log_warn ("Failed to initiate ('BEGIN') transaction: %s", - PQerrorMessage (db->conn)); - PQclear (r); - } - return status; + "backends", "transactions", "queries", "query_plans", + "table_states", "disk_io", "disk_usage"}; +static int def_queries_num = STATIC_ARRAY_SIZE(def_queries); + +static c_psql_database_t **databases = NULL; +static size_t databases_num = 0; + +static udb_query_t **queries = NULL; +static size_t queries_num = 0; + +static c_psql_writer_t *writers = NULL; +static size_t writers_num = 0; + +static int c_psql_begin(c_psql_database_t *db) { + PGresult *r = PQexec(db->conn, "BEGIN"); + + int status = 1; + + if (r != NULL) { + if (PGRES_COMMAND_OK == PQresultStatus(r)) { + db->next_commit = cdtime() + db->commit_interval; + status = 0; + } else + log_warn("Failed to initiate ('BEGIN') transaction: %s", + PQerrorMessage(db->conn)); + PQclear(r); + } + return status; } /* c_psql_begin */ -static int c_psql_commit (c_psql_database_t *db) -{ - PGresult *r = PQexec (db->conn, "COMMIT"); - - int status = 1; - - if (r != NULL) { - if (PGRES_COMMAND_OK == PQresultStatus (r)) { - db->next_commit = 0; - log_debug ("Successfully committed transaction."); - status = 0; - } - else - log_warn ("Failed to commit transaction: %s", - PQerrorMessage (db->conn)); - PQclear (r); - } - return status; +static int c_psql_commit(c_psql_database_t *db) { + PGresult *r = PQexec(db->conn, "COMMIT"); + + int status = 1; + + if (r != NULL) { + if (PGRES_COMMAND_OK == PQresultStatus(r)) { + db->next_commit = 0; + log_debug("Successfully committed transaction."); + status = 0; + } else + log_warn("Failed to commit transaction: %s", PQerrorMessage(db->conn)); + PQclear(r); + } + return status; } /* c_psql_commit */ -static c_psql_database_t *c_psql_database_new (const char *name) -{ - c_psql_database_t **tmp; - c_psql_database_t *db; +static c_psql_database_t *c_psql_database_new(const char *name) { + c_psql_database_t **tmp; + c_psql_database_t *db; - db = malloc (sizeof(*db)); - if (NULL == db) { - log_err ("Out of memory."); - return NULL; - } + db = malloc(sizeof(*db)); + if (NULL == db) { + log_err("Out of memory."); + return NULL; + } - tmp = realloc (databases, - (databases_num + 1) * sizeof (*databases)); - if (NULL == tmp) { - log_err ("Out of memory."); - sfree (db); - return NULL; - } + tmp = realloc(databases, (databases_num + 1) * sizeof(*databases)); + if (NULL == tmp) { + log_err("Out of memory."); + sfree(db); + return NULL; + } - databases = tmp; - databases[databases_num] = db; - ++databases_num; + databases = tmp; + databases[databases_num] = db; + ++databases_num; - db->conn = NULL; + db->conn = NULL; - C_COMPLAIN_INIT (&db->conn_complaint); + C_COMPLAIN_INIT(&db->conn_complaint); - db->proto_version = 0; - db->server_version = 0; + db->proto_version = 0; + db->server_version = 0; - db->max_params_num = 0; + db->max_params_num = 0; - db->q_prep_areas = NULL; - db->queries = NULL; - db->queries_num = 0; + db->q_prep_areas = NULL; + db->queries = NULL; + db->queries_num = 0; - db->writers = NULL; - db->writers_num = 0; + db->writers = NULL; + db->writers_num = 0; - pthread_mutex_init (&db->db_lock, /* attrs = */ NULL); + pthread_mutex_init(&db->db_lock, /* attrs = */ NULL); - db->interval = 0; + db->interval = 0; - db->commit_interval = 0; - db->next_commit = 0; - db->expire_delay = 0; + db->commit_interval = 0; + db->next_commit = 0; + db->expire_delay = 0; - db->database = sstrdup (name); - db->host = NULL; - db->port = NULL; - db->user = NULL; - db->password = NULL; + db->database = sstrdup(name); + db->host = NULL; + db->port = NULL; + db->user = NULL; + db->password = NULL; - db->instance = sstrdup (name); + db->instance = sstrdup(name); - db->sslmode = NULL; + db->sslmode = NULL; - db->krbsrvname = NULL; + db->krbsrvname = NULL; - db->service = NULL; + db->service = NULL; - db->ref_cnt = 0; - return db; + db->ref_cnt = 0; + return db; } /* c_psql_database_new */ -static void c_psql_database_delete (void *data) -{ - c_psql_database_t *db = data; +static void c_psql_database_delete(void *data) { + c_psql_database_t *db = data; - --db->ref_cnt; - /* readers and writers may access this database */ - if (db->ref_cnt > 0) - return; + --db->ref_cnt; + /* readers and writers may access this database */ + if (db->ref_cnt > 0) + return; - /* wait for the lock to be released by the last writer */ - pthread_mutex_lock (&db->db_lock); + /* wait for the lock to be released by the last writer */ + pthread_mutex_lock(&db->db_lock); - if (db->next_commit > 0) - c_psql_commit (db); + if (db->next_commit > 0) + c_psql_commit(db); - PQfinish (db->conn); - db->conn = NULL; + PQfinish(db->conn); + db->conn = NULL; - if (db->q_prep_areas) - for (size_t i = 0; i < db->queries_num; ++i) - udb_query_delete_preparation_area (db->q_prep_areas[i]); - free (db->q_prep_areas); + if (db->q_prep_areas) + for (size_t i = 0; i < db->queries_num; ++i) + udb_query_delete_preparation_area(db->q_prep_areas[i]); + free(db->q_prep_areas); - sfree (db->queries); - db->queries_num = 0; + sfree(db->queries); + db->queries_num = 0; - sfree (db->writers); - db->writers_num = 0; + sfree(db->writers); + db->writers_num = 0; - pthread_mutex_unlock (&db->db_lock); + pthread_mutex_unlock(&db->db_lock); - pthread_mutex_destroy (&db->db_lock); + pthread_mutex_destroy(&db->db_lock); - sfree (db->database); - sfree (db->host); - sfree (db->port); - sfree (db->user); - sfree (db->password); + sfree(db->database); + sfree(db->host); + sfree(db->port); + sfree(db->user); + sfree(db->password); - sfree (db->instance); + sfree(db->instance); - sfree (db->sslmode); + sfree(db->sslmode); - sfree (db->krbsrvname); + sfree(db->krbsrvname); - sfree (db->service); + sfree(db->service); - /* don't care about freeing or reordering the 'databases' array - * this is done in 'shutdown'; also, don't free the database instance - * object just to make sure that in case anybody accesses it before - * shutdown won't segfault */ - return; + /* don't care about freeing or reordering the 'databases' array + * this is done in 'shutdown'; also, don't free the database instance + * object just to make sure that in case anybody accesses it before + * shutdown won't segfault */ + return; } /* c_psql_database_delete */ -static int c_psql_connect (c_psql_database_t *db) -{ - char conninfo[4096]; - char *buf = conninfo; - int buf_len = sizeof (conninfo); - int status; - - if ((! db) || (! db->database)) - return -1; - - status = ssnprintf (buf, buf_len, "dbname = '%s'", db->database); - if (0 < status) { - buf += status; - buf_len -= status; - } - - C_PSQL_PAR_APPEND (buf, buf_len, "host", db->host); - C_PSQL_PAR_APPEND (buf, buf_len, "port", db->port); - C_PSQL_PAR_APPEND (buf, buf_len, "user", db->user); - C_PSQL_PAR_APPEND (buf, buf_len, "password", db->password); - C_PSQL_PAR_APPEND (buf, buf_len, "sslmode", db->sslmode); - C_PSQL_PAR_APPEND (buf, buf_len, "krbsrvname", db->krbsrvname); - C_PSQL_PAR_APPEND (buf, buf_len, "service", db->service); - - db->conn = PQconnectdb (conninfo); - db->proto_version = PQprotocolVersion (db->conn); - return 0; +static int c_psql_connect(c_psql_database_t *db) { + char conninfo[4096]; + char *buf = conninfo; + int buf_len = sizeof(conninfo); + int status; + + if ((!db) || (!db->database)) + return -1; + + status = ssnprintf(buf, buf_len, "dbname = '%s'", db->database); + if (0 < status) { + buf += status; + buf_len -= status; + } + + C_PSQL_PAR_APPEND(buf, buf_len, "host", db->host); + C_PSQL_PAR_APPEND(buf, buf_len, "port", db->port); + C_PSQL_PAR_APPEND(buf, buf_len, "user", db->user); + C_PSQL_PAR_APPEND(buf, buf_len, "password", db->password); + C_PSQL_PAR_APPEND(buf, buf_len, "sslmode", db->sslmode); + C_PSQL_PAR_APPEND(buf, buf_len, "krbsrvname", db->krbsrvname); + C_PSQL_PAR_APPEND(buf, buf_len, "service", db->service); + + db->conn = PQconnectdb(conninfo); + db->proto_version = PQprotocolVersion(db->conn); + return 0; } /* c_psql_connect */ -static int c_psql_check_connection (c_psql_database_t *db) -{ - _Bool init = 0; - - if (! db->conn) { - init = 1; - - /* trigger c_release() */ - if (0 == db->conn_complaint.interval) - db->conn_complaint.interval = 1; - - c_psql_connect (db); - } - - if (CONNECTION_OK != PQstatus (db->conn)) { - PQreset (db->conn); - - /* trigger c_release() */ - if (0 == db->conn_complaint.interval) - db->conn_complaint.interval = 1; - - if (CONNECTION_OK != PQstatus (db->conn)) { - c_complain (LOG_ERR, &db->conn_complaint, - "Failed to connect to database %s (%s): %s", - db->database, db->instance, - PQerrorMessage (db->conn)); - return -1; - } - - db->proto_version = PQprotocolVersion (db->conn); - } - - db->server_version = PQserverVersion (db->conn); - - if (c_would_release (&db->conn_complaint)) { - char *server_host; - int server_version; - - server_host = PQhost (db->conn); - server_version = PQserverVersion (db->conn); - - c_do_release (LOG_INFO, &db->conn_complaint, - "Successfully %sconnected to database %s (user %s) " - "at server %s%s%s (server version: %d.%d.%d, " - "protocol version: %d, pid: %d)", init ? "" : "re", - PQdb (db->conn), PQuser (db->conn), - C_PSQL_SOCKET3 (server_host, PQport (db->conn)), - C_PSQL_SERVER_VERSION3 (server_version), - db->proto_version, PQbackendPID (db->conn)); - - if (3 > db->proto_version) - log_warn ("Protocol version %d does not support parameters.", - db->proto_version); - } - return 0; +static int c_psql_check_connection(c_psql_database_t *db) { + _Bool init = 0; + + if (!db->conn) { + init = 1; + + /* trigger c_release() */ + if (0 == db->conn_complaint.interval) + db->conn_complaint.interval = 1; + + c_psql_connect(db); + } + + if (CONNECTION_OK != PQstatus(db->conn)) { + PQreset(db->conn); + + /* trigger c_release() */ + if (0 == db->conn_complaint.interval) + db->conn_complaint.interval = 1; + + if (CONNECTION_OK != PQstatus(db->conn)) { + c_complain(LOG_ERR, &db->conn_complaint, + "Failed to connect to database %s (%s): %s", db->database, + db->instance, PQerrorMessage(db->conn)); + return -1; + } + + db->proto_version = PQprotocolVersion(db->conn); + } + + db->server_version = PQserverVersion(db->conn); + + if (c_would_release(&db->conn_complaint)) { + char *server_host; + int server_version; + + server_host = PQhost(db->conn); + server_version = PQserverVersion(db->conn); + + c_do_release(LOG_INFO, &db->conn_complaint, + "Successfully %sconnected to database %s (user %s) " + "at server %s%s%s (server version: %d.%d.%d, " + "protocol version: %d, pid: %d)", + init ? "" : "re", PQdb(db->conn), PQuser(db->conn), + C_PSQL_SOCKET3(server_host, PQport(db->conn)), + C_PSQL_SERVER_VERSION3(server_version), db->proto_version, + PQbackendPID(db->conn)); + + if (3 > db->proto_version) + log_warn("Protocol version %d does not support parameters.", + db->proto_version); + } + return 0; } /* c_psql_check_connection */ -static PGresult *c_psql_exec_query_noparams (c_psql_database_t *db, - udb_query_t *q) -{ - return PQexec (db->conn, udb_query_get_statement (q)); +static PGresult *c_psql_exec_query_noparams(c_psql_database_t *db, + udb_query_t *q) { + return PQexec(db->conn, udb_query_get_statement(q)); } /* c_psql_exec_query_noparams */ -static PGresult *c_psql_exec_query_params (c_psql_database_t *db, - udb_query_t *q, c_psql_user_data_t *data) -{ - const char *params[db->max_params_num]; - char interval[64]; - - if ((data == NULL) || (data->params_num == 0)) - return (c_psql_exec_query_noparams (db, q)); - - assert (db->max_params_num >= data->params_num); - - for (int i = 0; i < data->params_num; ++i) { - switch (data->params[i]) { - case C_PSQL_PARAM_HOST: - params[i] = C_PSQL_IS_UNIX_DOMAIN_SOCKET (db->host) - ? "localhost" : db->host; - break; - case C_PSQL_PARAM_DB: - params[i] = db->database; - break; - case C_PSQL_PARAM_USER: - params[i] = db->user; - break; - case C_PSQL_PARAM_INTERVAL: - ssnprintf (interval, sizeof (interval), "%.3f", - (db->interval > 0) - ? CDTIME_T_TO_DOUBLE (db->interval) - : plugin_get_interval ()); - params[i] = interval; - break; - case C_PSQL_PARAM_INSTANCE: - params[i] = db->instance; - break; - default: - assert (0); - } - } - - return PQexecParams (db->conn, udb_query_get_statement (q), - data->params_num, NULL, - (const char *const *) params, - NULL, NULL, /* return text data */ 0); +static PGresult *c_psql_exec_query_params(c_psql_database_t *db, udb_query_t *q, + c_psql_user_data_t *data) { + const char *params[db->max_params_num]; + char interval[64]; + + if ((data == NULL) || (data->params_num == 0)) + return (c_psql_exec_query_noparams(db, q)); + + assert(db->max_params_num >= data->params_num); + + for (int i = 0; i < data->params_num; ++i) { + switch (data->params[i]) { + case C_PSQL_PARAM_HOST: + params[i] = + C_PSQL_IS_UNIX_DOMAIN_SOCKET(db->host) ? "localhost" : db->host; + break; + case C_PSQL_PARAM_DB: + params[i] = db->database; + break; + case C_PSQL_PARAM_USER: + params[i] = db->user; + break; + case C_PSQL_PARAM_INTERVAL: + ssnprintf(interval, sizeof(interval), "%.3f", + (db->interval > 0) ? CDTIME_T_TO_DOUBLE(db->interval) + : plugin_get_interval()); + params[i] = interval; + break; + case C_PSQL_PARAM_INSTANCE: + params[i] = db->instance; + break; + default: + assert(0); + } + } + + return PQexecParams(db->conn, udb_query_get_statement(q), data->params_num, + NULL, (const char *const *)params, NULL, NULL, + /* return text data */ 0); } /* c_psql_exec_query_params */ /* db->db_lock must be locked when calling this function */ -static int c_psql_exec_query (c_psql_database_t *db, udb_query_t *q, - udb_query_preparation_area_t *prep_area) -{ - PGresult *res; - - c_psql_user_data_t *data; - - const char *host; - - char **column_names; - char **column_values; - int column_num; - - int rows_num; - int status; - - /* The user data may hold parameter information, but may be NULL. */ - data = udb_query_get_user_data (q); - - /* Versions up to `3' don't know how to handle parameters. */ - if (3 <= db->proto_version) - res = c_psql_exec_query_params (db, q, data); - else if ((NULL == data) || (0 == data->params_num)) - res = c_psql_exec_query_noparams (db, q); - else { - log_err ("Connection to database \"%s\" (%s) does not support " - "parameters (protocol version %d) - " - "cannot execute query \"%s\".", - db->database, db->instance, db->proto_version, - udb_query_get_name (q)); - return -1; - } - - /* give c_psql_write() a chance to acquire the lock if called recursively - * through dispatch_values(); this will happen if, both, queries and - * writers are configured for a single connection */ - pthread_mutex_unlock (&db->db_lock); - - column_names = NULL; - column_values = NULL; - - if (PGRES_TUPLES_OK != PQresultStatus (res)) { - pthread_mutex_lock (&db->db_lock); - - if ((CONNECTION_OK != PQstatus (db->conn)) - && (0 == c_psql_check_connection (db))) { - PQclear (res); - return c_psql_exec_query (db, q, prep_area); - } - - log_err ("Failed to execute SQL query: %s", - PQerrorMessage (db->conn)); - log_info ("SQL query was: %s", - udb_query_get_statement (q)); - PQclear (res); - return -1; - } - -#define BAIL_OUT(status) \ - sfree (column_names); \ - sfree (column_values); \ - PQclear (res); \ - pthread_mutex_lock (&db->db_lock); \ - return status - - rows_num = PQntuples (res); - if (1 > rows_num) { - BAIL_OUT (0); - } - - column_num = PQnfields (res); - column_names = (char **) calloc (column_num, sizeof (char *)); - if (NULL == column_names) { - log_err ("calloc failed."); - BAIL_OUT (-1); - } - - column_values = (char **) calloc (column_num, sizeof (char *)); - if (NULL == column_values) { - log_err ("calloc failed."); - BAIL_OUT (-1); - } - - for (int col = 0; col < column_num; ++col) { - /* Pointers returned by `PQfname' are freed by `PQclear' via - * `BAIL_OUT'. */ - column_names[col] = PQfname (res, col); - if (NULL == column_names[col]) { - log_err ("Failed to resolve name of column %i.", col); - BAIL_OUT (-1); - } - } - - if (C_PSQL_IS_UNIX_DOMAIN_SOCKET (db->host) - || (0 == strcmp (db->host, "127.0.0.1")) - || (0 == strcmp (db->host, "localhost"))) - host = hostname_g; - else - host = db->host; - - status = udb_query_prepare_result (q, prep_area, host, "postgresql", - db->instance, column_names, (size_t) column_num, db->interval); - if (0 != status) { - log_err ("udb_query_prepare_result failed with status %i.", - status); - BAIL_OUT (-1); - } - - for (int row = 0; row < rows_num; ++row) { - int col; - for (col = 0; col < column_num; ++col) { - /* Pointers returned by `PQgetvalue' are freed by `PQclear' via - * `BAIL_OUT'. */ - column_values[col] = PQgetvalue (res, row, col); - if (NULL == column_values[col]) { - log_err ("Failed to get value at (row = %i, col = %i).", - row, col); - break; - } - } - - /* check for an error */ - if (col < column_num) - continue; - - status = udb_query_handle_result (q, prep_area, column_values); - if (status != 0) { - log_err ("udb_query_handle_result failed with status %i.", - status); - } - } /* for (row = 0; row < rows_num; ++row) */ - - udb_query_finish_result (q, prep_area); - - BAIL_OUT (0); +static int c_psql_exec_query(c_psql_database_t *db, udb_query_t *q, + udb_query_preparation_area_t *prep_area) { + PGresult *res; + + c_psql_user_data_t *data; + + const char *host; + + char **column_names; + char **column_values; + int column_num; + + int rows_num; + int status; + + /* The user data may hold parameter information, but may be NULL. */ + data = udb_query_get_user_data(q); + + /* Versions up to `3' don't know how to handle parameters. */ + if (3 <= db->proto_version) + res = c_psql_exec_query_params(db, q, data); + else if ((NULL == data) || (0 == data->params_num)) + res = c_psql_exec_query_noparams(db, q); + else { + log_err("Connection to database \"%s\" (%s) does not support " + "parameters (protocol version %d) - " + "cannot execute query \"%s\".", + db->database, db->instance, db->proto_version, + udb_query_get_name(q)); + return -1; + } + + /* give c_psql_write() a chance to acquire the lock if called recursively + * through dispatch_values(); this will happen if, both, queries and + * writers are configured for a single connection */ + pthread_mutex_unlock(&db->db_lock); + + column_names = NULL; + column_values = NULL; + + if (PGRES_TUPLES_OK != PQresultStatus(res)) { + pthread_mutex_lock(&db->db_lock); + + if ((CONNECTION_OK != PQstatus(db->conn)) && + (0 == c_psql_check_connection(db))) { + PQclear(res); + return c_psql_exec_query(db, q, prep_area); + } + + log_err("Failed to execute SQL query: %s", PQerrorMessage(db->conn)); + log_info("SQL query was: %s", udb_query_get_statement(q)); + PQclear(res); + return -1; + } + +#define BAIL_OUT(status) \ + sfree(column_names); \ + sfree(column_values); \ + PQclear(res); \ + pthread_mutex_lock(&db->db_lock); \ + return status + + rows_num = PQntuples(res); + if (1 > rows_num) { + BAIL_OUT(0); + } + + column_num = PQnfields(res); + column_names = (char **)calloc(column_num, sizeof(char *)); + if (NULL == column_names) { + log_err("calloc failed."); + BAIL_OUT(-1); + } + + column_values = (char **)calloc(column_num, sizeof(char *)); + if (NULL == column_values) { + log_err("calloc failed."); + BAIL_OUT(-1); + } + + for (int col = 0; col < column_num; ++col) { + /* Pointers returned by `PQfname' are freed by `PQclear' via + * `BAIL_OUT'. */ + column_names[col] = PQfname(res, col); + if (NULL == column_names[col]) { + log_err("Failed to resolve name of column %i.", col); + BAIL_OUT(-1); + } + } + + if (C_PSQL_IS_UNIX_DOMAIN_SOCKET(db->host) || + (0 == strcmp(db->host, "127.0.0.1")) || + (0 == strcmp(db->host, "localhost"))) + host = hostname_g; + else + host = db->host; + + status = + udb_query_prepare_result(q, prep_area, host, "postgresql", db->instance, + column_names, (size_t)column_num, db->interval); + if (0 != status) { + log_err("udb_query_prepare_result failed with status %i.", status); + BAIL_OUT(-1); + } + + for (int row = 0; row < rows_num; ++row) { + int col; + for (col = 0; col < column_num; ++col) { + /* Pointers returned by `PQgetvalue' are freed by `PQclear' via + * `BAIL_OUT'. */ + column_values[col] = PQgetvalue(res, row, col); + if (NULL == column_values[col]) { + log_err("Failed to get value at (row = %i, col = %i).", row, col); + break; + } + } + + /* check for an error */ + if (col < column_num) + continue; + + status = udb_query_handle_result(q, prep_area, column_values); + if (status != 0) { + log_err("udb_query_handle_result failed with status %i.", status); + } + } /* for (row = 0; row < rows_num; ++row) */ + + udb_query_finish_result(q, prep_area); + + BAIL_OUT(0); #undef BAIL_OUT } /* c_psql_exec_query */ -static int c_psql_read (user_data_t *ud) -{ - c_psql_database_t *db; +static int c_psql_read(user_data_t *ud) { + c_psql_database_t *db; - int success = 0; + int success = 0; - if ((ud == NULL) || (ud->data == NULL)) { - log_err ("c_psql_read: Invalid user data."); - return -1; - } + if ((ud == NULL) || (ud->data == NULL)) { + log_err("c_psql_read: Invalid user data."); + return -1; + } - db = ud->data; + db = ud->data; - assert (NULL != db->database); - assert (NULL != db->instance); - assert (NULL != db->queries); + assert(NULL != db->database); + assert(NULL != db->instance); + assert(NULL != db->queries); - pthread_mutex_lock (&db->db_lock); + pthread_mutex_lock(&db->db_lock); - if (0 != c_psql_check_connection (db)) { - pthread_mutex_unlock (&db->db_lock); - return -1; - } + if (0 != c_psql_check_connection(db)) { + pthread_mutex_unlock(&db->db_lock); + return -1; + } - for (size_t i = 0; i < db->queries_num; ++i) - { - udb_query_preparation_area_t *prep_area; - udb_query_t *q; + for (size_t i = 0; i < db->queries_num; ++i) { + udb_query_preparation_area_t *prep_area; + udb_query_t *q; - prep_area = db->q_prep_areas[i]; - q = db->queries[i]; + prep_area = db->q_prep_areas[i]; + q = db->queries[i]; - if ((0 != db->server_version) - && (udb_query_check_version (q, db->server_version) <= 0)) - continue; + if ((0 != db->server_version) && + (udb_query_check_version(q, db->server_version) <= 0)) + continue; - if (0 == c_psql_exec_query (db, q, prep_area)) - success = 1; - } + if (0 == c_psql_exec_query(db, q, prep_area)) + success = 1; + } - pthread_mutex_unlock (&db->db_lock); + pthread_mutex_unlock(&db->db_lock); - if (! success) - return -1; - return 0; + if (!success) + return -1; + return 0; } /* c_psql_read */ -static char *values_name_to_sqlarray (const data_set_t *ds, - char *string, size_t string_len) -{ - char *str_ptr; - size_t str_len; - - str_ptr = string; - str_len = string_len; - - for (size_t i = 0; i < ds->ds_num; ++i) { - int status = ssnprintf (str_ptr, str_len, ",'%s'", ds->ds[i].name); - - if (status < 1) - return NULL; - else if ((size_t)status >= str_len) { - str_len = 0; - break; - } - else { - str_ptr += status; - str_len -= (size_t)status; - } - } - - if (str_len <= 2) { - log_err ("c_psql_write: Failed to stringify value names"); - return NULL; - } - - /* overwrite the first comma */ - string[0] = '{'; - str_ptr[0] = '}'; - str_ptr[1] = '\0'; - - return string; +static char *values_name_to_sqlarray(const data_set_t *ds, char *string, + size_t string_len) { + char *str_ptr; + size_t str_len; + + str_ptr = string; + str_len = string_len; + + for (size_t i = 0; i < ds->ds_num; ++i) { + int status = ssnprintf(str_ptr, str_len, ",'%s'", ds->ds[i].name); + + if (status < 1) + return NULL; + else if ((size_t)status >= str_len) { + str_len = 0; + break; + } else { + str_ptr += status; + str_len -= (size_t)status; + } + } + + if (str_len <= 2) { + log_err("c_psql_write: Failed to stringify value names"); + return NULL; + } + + /* overwrite the first comma */ + string[0] = '{'; + str_ptr[0] = '}'; + str_ptr[1] = '\0'; + + return string; } /* values_name_to_sqlarray */ -static char *values_type_to_sqlarray (const data_set_t *ds, - char *string, size_t string_len, _Bool store_rates) -{ - char *str_ptr; - size_t str_len; - - str_ptr = string; - str_len = string_len; - - for (size_t i = 0; i < ds->ds_num; ++i) { - int status; - - if (store_rates) - status = ssnprintf(str_ptr, str_len, ",'gauge'"); - else - status = ssnprintf(str_ptr, str_len, ",'%s'", - DS_TYPE_TO_STRING (ds->ds[i].type)); - - if (status < 1) { - str_len = 0; - break; - } - else if ((size_t)status >= str_len) { - str_len = 0; - break; - } - else { - str_ptr += status; - str_len -= (size_t)status; - } - } - - if (str_len <= 2) { - log_err ("c_psql_write: Failed to stringify value types"); - return NULL; - } - - /* overwrite the first comma */ - string[0] = '{'; - str_ptr[0] = '}'; - str_ptr[1] = '\0'; - - return string; +static char *values_type_to_sqlarray(const data_set_t *ds, char *string, + size_t string_len, _Bool store_rates) { + char *str_ptr; + size_t str_len; + + str_ptr = string; + str_len = string_len; + + for (size_t i = 0; i < ds->ds_num; ++i) { + int status; + + if (store_rates) + status = ssnprintf(str_ptr, str_len, ",'gauge'"); + else + status = ssnprintf(str_ptr, str_len, ",'%s'", + DS_TYPE_TO_STRING(ds->ds[i].type)); + + if (status < 1) { + str_len = 0; + break; + } else if ((size_t)status >= str_len) { + str_len = 0; + break; + } else { + str_ptr += status; + str_len -= (size_t)status; + } + } + + if (str_len <= 2) { + log_err("c_psql_write: Failed to stringify value types"); + return NULL; + } + + /* overwrite the first comma */ + string[0] = '{'; + str_ptr[0] = '}'; + str_ptr[1] = '\0'; + + return string; } /* values_type_to_sqlarray */ -static char *values_to_sqlarray (const data_set_t *ds, const value_list_t *vl, - char *string, size_t string_len, _Bool store_rates) -{ - char *str_ptr; - size_t str_len; - - gauge_t *rates = NULL; - - str_ptr = string; - str_len = string_len; - - for (size_t i = 0; i < vl->values_len; ++i) { - int status = 0; - - if ((ds->ds[i].type != DS_TYPE_GAUGE) - && (ds->ds[i].type != DS_TYPE_COUNTER) - && (ds->ds[i].type != DS_TYPE_DERIVE) - && (ds->ds[i].type != DS_TYPE_ABSOLUTE)) { - log_err ("c_psql_write: Unknown data source type: %i", - ds->ds[i].type); - sfree (rates); - return NULL; - } - - if (ds->ds[i].type == DS_TYPE_GAUGE) - status = ssnprintf (str_ptr, str_len, - ","GAUGE_FORMAT, vl->values[i].gauge); - else if (store_rates) { - if (rates == NULL) - rates = uc_get_rate (ds, vl); - - if (rates == NULL) { - log_err ("c_psql_write: Failed to determine rate"); - return NULL; - } - - status = ssnprintf (str_ptr, str_len, - ",%lf", rates[i]); - } - else if (ds->ds[i].type == DS_TYPE_COUNTER) - status = ssnprintf (str_ptr, str_len, - ",%llu", vl->values[i].counter); - else if (ds->ds[i].type == DS_TYPE_DERIVE) - status = ssnprintf (str_ptr, str_len, - ",%"PRIi64, vl->values[i].derive); - else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) - status = ssnprintf (str_ptr, str_len, - ",%"PRIu64, vl->values[i].absolute); - - if (status < 1) { - str_len = 0; - break; - } - else if ((size_t)status >= str_len) { - str_len = 0; - break; - } - else { - str_ptr += status; - str_len -= (size_t)status; - } - } - - sfree (rates); - - if (str_len <= 2) { - log_err ("c_psql_write: Failed to stringify value list"); - return NULL; - } - - /* overwrite the first comma */ - string[0] = '{'; - str_ptr[0] = '}'; - str_ptr[1] = '\0'; - - return string; +static char *values_to_sqlarray(const data_set_t *ds, const value_list_t *vl, + char *string, size_t string_len, + _Bool store_rates) { + char *str_ptr; + size_t str_len; + + gauge_t *rates = NULL; + + str_ptr = string; + str_len = string_len; + + for (size_t i = 0; i < vl->values_len; ++i) { + int status = 0; + + if ((ds->ds[i].type != DS_TYPE_GAUGE) && + (ds->ds[i].type != DS_TYPE_COUNTER) && + (ds->ds[i].type != DS_TYPE_DERIVE) && + (ds->ds[i].type != DS_TYPE_ABSOLUTE)) { + log_err("c_psql_write: Unknown data source type: %i", ds->ds[i].type); + sfree(rates); + return NULL; + } + + if (ds->ds[i].type == DS_TYPE_GAUGE) + status = + ssnprintf(str_ptr, str_len, "," GAUGE_FORMAT, vl->values[i].gauge); + else if (store_rates) { + if (rates == NULL) + rates = uc_get_rate(ds, vl); + + if (rates == NULL) { + log_err("c_psql_write: Failed to determine rate"); + return NULL; + } + + status = ssnprintf(str_ptr, str_len, ",%lf", rates[i]); + } else if (ds->ds[i].type == DS_TYPE_COUNTER) + status = ssnprintf(str_ptr, str_len, ",%llu", vl->values[i].counter); + else if (ds->ds[i].type == DS_TYPE_DERIVE) + status = ssnprintf(str_ptr, str_len, ",%" PRIi64, vl->values[i].derive); + else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) + status = ssnprintf(str_ptr, str_len, ",%" PRIu64, vl->values[i].absolute); + + if (status < 1) { + str_len = 0; + break; + } else if ((size_t)status >= str_len) { + str_len = 0; + break; + } else { + str_ptr += status; + str_len -= (size_t)status; + } + } + + sfree(rates); + + if (str_len <= 2) { + log_err("c_psql_write: Failed to stringify value list"); + return NULL; + } + + /* overwrite the first comma */ + string[0] = '{'; + str_ptr[0] = '}'; + str_ptr[1] = '\0'; + + return string; } /* values_to_sqlarray */ -static int c_psql_write (const data_set_t *ds, const value_list_t *vl, - user_data_t *ud) -{ - c_psql_database_t *db; +static int c_psql_write(const data_set_t *ds, const value_list_t *vl, + user_data_t *ud) { + c_psql_database_t *db; - char time_str[RFC3339NANO_SIZE]; - char values_name_str[1024]; - char values_type_str[1024]; - char values_str[1024]; + char time_str[RFC3339NANO_SIZE]; + char values_name_str[1024]; + char values_type_str[1024]; + char values_str[1024]; - const char *params[9]; + const char *params[9]; - int success = 0; + int success = 0; - if ((ud == NULL) || (ud->data == NULL)) { - log_err ("c_psql_write: Invalid user data."); - return -1; - } + if ((ud == NULL) || (ud->data == NULL)) { + log_err("c_psql_write: Invalid user data."); + return -1; + } - db = ud->data; - assert (db->database != NULL); - assert (db->writers != NULL); + db = ud->data; + assert(db->database != NULL); + assert(db->writers != NULL); - if (rfc3339nano_local (time_str, sizeof (time_str), vl->time) != 0) { - log_err ("c_psql_write: Failed to convert time to RFC 3339 format"); - return -1; - } + if (rfc3339nano_local(time_str, sizeof(time_str), vl->time) != 0) { + log_err("c_psql_write: Failed to convert time to RFC 3339 format"); + return -1; + } - if (values_name_to_sqlarray (ds, - values_name_str, sizeof (values_name_str)) == NULL) - return -1; + if (values_name_to_sqlarray(ds, values_name_str, sizeof(values_name_str)) == + NULL) + return -1; #define VALUE_OR_NULL(v) ((((v) == NULL) || (*(v) == '\0')) ? NULL : (v)) - params[0] = time_str; - params[1] = vl->host; - params[2] = vl->plugin; - params[3] = VALUE_OR_NULL(vl->plugin_instance); - params[4] = vl->type; - params[5] = VALUE_OR_NULL(vl->type_instance); - params[6] = values_name_str; + params[0] = time_str; + params[1] = vl->host; + params[2] = vl->plugin; + params[3] = VALUE_OR_NULL(vl->plugin_instance); + params[4] = vl->type; + params[5] = VALUE_OR_NULL(vl->type_instance); + params[6] = values_name_str; #undef VALUE_OR_NULL - if( db->expire_delay > 0 && vl->time < (cdtime() - vl->interval - db->expire_delay) ) { - log_info ("c_psql_write: Skipped expired value @ %s - %s/%s-%s/%s-%s/%s", - params[0], params[1], params[2], params[3], params[4], params[5], params[6] ); - return 0; + if (db->expire_delay > 0 && + vl->time < (cdtime() - vl->interval - db->expire_delay)) { + log_info("c_psql_write: Skipped expired value @ %s - %s/%s-%s/%s-%s/%s", + params[0], params[1], params[2], params[3], params[4], params[5], + params[6]); + return 0; + } + + pthread_mutex_lock(&db->db_lock); + + if (0 != c_psql_check_connection(db)) { + pthread_mutex_unlock(&db->db_lock); + return -1; + } + + if ((db->commit_interval > 0) && (db->next_commit == 0)) + c_psql_begin(db); + + for (size_t i = 0; i < db->writers_num; ++i) { + c_psql_writer_t *writer; + PGresult *res; + + writer = db->writers[i]; + + if (values_type_to_sqlarray(ds, values_type_str, sizeof(values_type_str), + writer->store_rates) == NULL) { + pthread_mutex_unlock(&db->db_lock); + return -1; + } + + if (values_to_sqlarray(ds, vl, values_str, sizeof(values_str), + writer->store_rates) == NULL) { + pthread_mutex_unlock(&db->db_lock); + return -1; + } + + params[7] = values_type_str; + params[8] = values_str; + + res = PQexecParams(db->conn, writer->statement, STATIC_ARRAY_SIZE(params), + NULL, (const char *const *)params, NULL, NULL, + /* return text data */ 0); + + if ((PGRES_COMMAND_OK != PQresultStatus(res)) && + (PGRES_TUPLES_OK != PQresultStatus(res))) { + PQclear(res); + + if ((CONNECTION_OK != PQstatus(db->conn)) && + (0 == c_psql_check_connection(db))) { + /* try again */ + res = PQexecParams( + db->conn, writer->statement, STATIC_ARRAY_SIZE(params), NULL, + (const char *const *)params, NULL, NULL, /* return text data */ 0); + + if ((PGRES_COMMAND_OK == PQresultStatus(res)) || + (PGRES_TUPLES_OK == PQresultStatus(res))) { + PQclear(res); + success = 1; + continue; } + } + + log_err("Failed to execute SQL query: %s", PQerrorMessage(db->conn)); + log_info("SQL query was: '%s', " + "params: %s, %s, %s, %s, %s, %s, %s, %s", + writer->statement, params[0], params[1], params[2], params[3], + params[4], params[5], params[6], params[7]); + + /* this will abort any current transaction -> restart */ + if (db->next_commit > 0) + c_psql_commit(db); + + pthread_mutex_unlock(&db->db_lock); + return -1; + } + + PQclear(res); + success = 1; + } + + if ((db->next_commit > 0) && (cdtime() > db->next_commit)) + c_psql_commit(db); + + pthread_mutex_unlock(&db->db_lock); - pthread_mutex_lock (&db->db_lock); - - if (0 != c_psql_check_connection (db)) { - pthread_mutex_unlock (&db->db_lock); - return -1; - } - - if ((db->commit_interval > 0) - && (db->next_commit == 0)) - c_psql_begin (db); - - for (size_t i = 0; i < db->writers_num; ++i) { - c_psql_writer_t *writer; - PGresult *res; - - writer = db->writers[i]; - - if (values_type_to_sqlarray (ds, - values_type_str, sizeof (values_type_str), - writer->store_rates) == NULL) { - pthread_mutex_unlock (&db->db_lock); - return -1; - } - - if (values_to_sqlarray (ds, vl, - values_str, sizeof (values_str), - writer->store_rates) == NULL) { - pthread_mutex_unlock (&db->db_lock); - return -1; - } - - params[7] = values_type_str; - params[8] = values_str; - - res = PQexecParams (db->conn, writer->statement, - STATIC_ARRAY_SIZE (params), NULL, - (const char *const *)params, - NULL, NULL, /* return text data */ 0); - - if ((PGRES_COMMAND_OK != PQresultStatus (res)) - && (PGRES_TUPLES_OK != PQresultStatus (res))) { - PQclear (res); - - if ((CONNECTION_OK != PQstatus (db->conn)) - && (0 == c_psql_check_connection (db))) { - /* try again */ - res = PQexecParams (db->conn, writer->statement, - STATIC_ARRAY_SIZE (params), NULL, - (const char *const *)params, - NULL, NULL, /* return text data */ 0); - - if ((PGRES_COMMAND_OK == PQresultStatus (res)) - || (PGRES_TUPLES_OK == PQresultStatus (res))) { - PQclear (res); - success = 1; - continue; - } - } - - log_err ("Failed to execute SQL query: %s", - PQerrorMessage (db->conn)); - log_info ("SQL query was: '%s', " - "params: %s, %s, %s, %s, %s, %s, %s, %s", - writer->statement, - params[0], params[1], params[2], params[3], - params[4], params[5], params[6], params[7]); - - /* this will abort any current transaction -> restart */ - if (db->next_commit > 0) - c_psql_commit (db); - - pthread_mutex_unlock (&db->db_lock); - return -1; - } - - PQclear (res); - success = 1; - } - - if ((db->next_commit > 0) - && (cdtime () > db->next_commit)) - c_psql_commit (db); - - pthread_mutex_unlock (&db->db_lock); - - if (! success) - return -1; - return 0; + if (!success) + return -1; + return 0; } /* c_psql_write */ /* We cannot flush single identifiers as all we do is to commit the currently * running transaction, thus making sure that all written data is actually * visible to everybody. */ -static int c_psql_flush (cdtime_t timeout, - __attribute__((unused)) const char *ident, - user_data_t *ud) -{ - c_psql_database_t **dbs = databases; - size_t dbs_num = databases_num; - - if ((ud != NULL) && (ud->data != NULL)) { - dbs = (void *)&ud->data; - dbs_num = 1; - } - - for (size_t i = 0; i < dbs_num; ++i) { - c_psql_database_t *db = dbs[i]; - - /* don't commit if the timeout is larger than the regular commit - * interval as in that case all requested data has already been - * committed */ - if ((db->next_commit > 0) && (db->commit_interval > timeout)) - c_psql_commit (db); - } - return 0; +static int c_psql_flush(cdtime_t timeout, + __attribute__((unused)) const char *ident, + user_data_t *ud) { + c_psql_database_t **dbs = databases; + size_t dbs_num = databases_num; + + if ((ud != NULL) && (ud->data != NULL)) { + dbs = (void *)&ud->data; + dbs_num = 1; + } + + for (size_t i = 0; i < dbs_num; ++i) { + c_psql_database_t *db = dbs[i]; + + /* don't commit if the timeout is larger than the regular commit + * interval as in that case all requested data has already been + * committed */ + if ((db->next_commit > 0) && (db->commit_interval > timeout)) + c_psql_commit(db); + } + return 0; } /* c_psql_flush */ -static int c_psql_shutdown (void) -{ - _Bool had_flush = 0; +static int c_psql_shutdown(void) { + _Bool had_flush = 0; - plugin_unregister_read_group ("postgresql"); + plugin_unregister_read_group("postgresql"); - for (size_t i = 0; i < databases_num; ++i) { - c_psql_database_t *db = databases[i]; + for (size_t i = 0; i < databases_num; ++i) { + c_psql_database_t *db = databases[i]; - if (db->writers_num > 0) { - char cb_name[DATA_MAX_NAME_LEN]; - ssnprintf (cb_name, sizeof (cb_name), "postgresql-%s", - db->database); + if (db->writers_num > 0) { + char cb_name[DATA_MAX_NAME_LEN]; + ssnprintf(cb_name, sizeof(cb_name), "postgresql-%s", db->database); - if (! had_flush) { - plugin_unregister_flush ("postgresql"); - had_flush = 1; - } + if (!had_flush) { + plugin_unregister_flush("postgresql"); + had_flush = 1; + } - plugin_unregister_flush (cb_name); - plugin_unregister_write (cb_name); - } + plugin_unregister_flush(cb_name); + plugin_unregister_write(cb_name); + } - sfree (db); - } + sfree(db); + } - udb_query_free (queries, queries_num); - queries = NULL; - queries_num = 0; + udb_query_free(queries, queries_num); + queries = NULL; + queries_num = 0; - sfree (writers); - writers = NULL; - writers_num = 0; + sfree(writers); + writers = NULL; + writers_num = 0; - sfree (databases); - databases = NULL; - databases_num = 0; + sfree(databases); + databases = NULL; + databases_num = 0; - return 0; + return 0; } /* c_psql_shutdown */ -static int config_query_param_add (udb_query_t *q, oconfig_item_t *ci) -{ - c_psql_user_data_t *data; - const char *param_str; - - c_psql_param_t *tmp; - - data = udb_query_get_user_data (q); - if (NULL == data) { - data = calloc (1, sizeof (*data)); - if (NULL == data) { - log_err ("Out of memory."); - return -1; - } - data->params = NULL; - data->params_num = 0; - - udb_query_set_user_data (q, data); - } - - tmp = realloc (data->params, (data->params_num + 1) * sizeof (*data->params)); - if (NULL == tmp) { - log_err ("Out of memory."); - return -1; - } - data->params = tmp; - - param_str = ci->values[0].value.string; - if (0 == strcasecmp (param_str, "hostname")) - data->params[data->params_num] = C_PSQL_PARAM_HOST; - else if (0 == strcasecmp (param_str, "database")) - data->params[data->params_num] = C_PSQL_PARAM_DB; - else if (0 == strcasecmp (param_str, "username")) - data->params[data->params_num] = C_PSQL_PARAM_USER; - else if (0 == strcasecmp (param_str, "interval")) - data->params[data->params_num] = C_PSQL_PARAM_INTERVAL; - else if (0 == strcasecmp (param_str, "instance")) - data->params[data->params_num] = C_PSQL_PARAM_INSTANCE; - else { - log_err ("Invalid parameter \"%s\".", param_str); - return 1; - } - - data->params_num++; - return (0); +static int config_query_param_add(udb_query_t *q, oconfig_item_t *ci) { + c_psql_user_data_t *data; + const char *param_str; + + c_psql_param_t *tmp; + + data = udb_query_get_user_data(q); + if (NULL == data) { + data = calloc(1, sizeof(*data)); + if (NULL == data) { + log_err("Out of memory."); + return -1; + } + data->params = NULL; + data->params_num = 0; + + udb_query_set_user_data(q, data); + } + + tmp = realloc(data->params, (data->params_num + 1) * sizeof(*data->params)); + if (NULL == tmp) { + log_err("Out of memory."); + return -1; + } + data->params = tmp; + + param_str = ci->values[0].value.string; + if (0 == strcasecmp(param_str, "hostname")) + data->params[data->params_num] = C_PSQL_PARAM_HOST; + else if (0 == strcasecmp(param_str, "database")) + data->params[data->params_num] = C_PSQL_PARAM_DB; + else if (0 == strcasecmp(param_str, "username")) + data->params[data->params_num] = C_PSQL_PARAM_USER; + else if (0 == strcasecmp(param_str, "interval")) + data->params[data->params_num] = C_PSQL_PARAM_INTERVAL; + else if (0 == strcasecmp(param_str, "instance")) + data->params[data->params_num] = C_PSQL_PARAM_INSTANCE; + else { + log_err("Invalid parameter \"%s\".", param_str); + return 1; + } + + data->params_num++; + return (0); } /* config_query_param_add */ -static int config_query_callback (udb_query_t *q, oconfig_item_t *ci) -{ - if (0 == strcasecmp ("Param", ci->key)) - return config_query_param_add (q, ci); +static int config_query_callback(udb_query_t *q, oconfig_item_t *ci) { + if (0 == strcasecmp("Param", ci->key)) + return config_query_param_add(q, ci); - log_err ("Option not allowed within a Query block: `%s'", ci->key); + log_err("Option not allowed within a Query block: `%s'", ci->key); - return (-1); + return (-1); } /* config_query_callback */ -static int config_add_writer (oconfig_item_t *ci, - c_psql_writer_t *src_writers, size_t src_writers_num, - c_psql_writer_t ***dst_writers, size_t *dst_writers_num) -{ - char *name; +static int config_add_writer(oconfig_item_t *ci, c_psql_writer_t *src_writers, + size_t src_writers_num, + c_psql_writer_t ***dst_writers, + size_t *dst_writers_num) { + char *name; - size_t i; + size_t i; - if ((ci == NULL) || (dst_writers == NULL) || (dst_writers_num == NULL)) - return -1; + if ((ci == NULL) || (dst_writers == NULL) || (dst_writers_num == NULL)) + return -1; - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) { - log_err ("`Writer' expects a single string argument."); - return 1; - } + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + log_err("`Writer' expects a single string argument."); + return 1; + } - name = ci->values[0].value.string; + name = ci->values[0].value.string; - for (i = 0; i < src_writers_num; ++i) { - c_psql_writer_t **tmp; + for (i = 0; i < src_writers_num; ++i) { + c_psql_writer_t **tmp; - if (strcasecmp (name, src_writers[i].name) != 0) - continue; + if (strcasecmp(name, src_writers[i].name) != 0) + continue; - tmp = realloc (*dst_writers, - sizeof (**dst_writers) * (*dst_writers_num + 1)); - if (tmp == NULL) { - log_err ("Out of memory."); - return -1; - } + tmp = realloc(*dst_writers, sizeof(**dst_writers) * (*dst_writers_num + 1)); + if (tmp == NULL) { + log_err("Out of memory."); + return -1; + } - tmp[*dst_writers_num] = src_writers + i; + tmp[*dst_writers_num] = src_writers + i; - *dst_writers = tmp; - ++(*dst_writers_num); - break; - } + *dst_writers = tmp; + ++(*dst_writers_num); + break; + } - if (i >= src_writers_num) { - log_err ("No such writer: `%s'", name); - return -1; - } + if (i >= src_writers_num) { + log_err("No such writer: `%s'", name); + return -1; + } - return 0; + return 0; } /* config_add_writer */ -static int c_psql_config_writer (oconfig_item_t *ci) -{ - c_psql_writer_t *writer; - c_psql_writer_t *tmp; - - int status = 0; - - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) { - log_err (" expects a single string argument."); - return 1; - } - - tmp = realloc (writers, - sizeof (*writers) * (writers_num + 1)); - if (tmp == NULL) { - log_err ("Out of memory."); - return -1; - } - - writers = tmp; - writer = writers + writers_num; - memset (writer, 0, sizeof (*writer)); - - writer->name = sstrdup (ci->values[0].value.string); - writer->statement = NULL; - writer->store_rates = 1; - - for (int i = 0; i < ci->children_num; ++i) { - oconfig_item_t *c = ci->children + i; - - if (strcasecmp ("Statement", c->key) == 0) - status = cf_util_get_string (c, &writer->statement); - else if (strcasecmp ("StoreRates", c->key) == 0) - status = cf_util_get_boolean (c, &writer->store_rates); - else - log_warn ("Ignoring unknown config key \"%s\".", c->key); - } - - if (status != 0) { - sfree (writer->statement); - sfree (writer->name); - return status; - } - - ++writers_num; - return 0; +static int c_psql_config_writer(oconfig_item_t *ci) { + c_psql_writer_t *writer; + c_psql_writer_t *tmp; + + int status = 0; + + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + log_err(" expects a single string argument."); + return 1; + } + + tmp = realloc(writers, sizeof(*writers) * (writers_num + 1)); + if (tmp == NULL) { + log_err("Out of memory."); + return -1; + } + + writers = tmp; + writer = writers + writers_num; + memset(writer, 0, sizeof(*writer)); + + writer->name = sstrdup(ci->values[0].value.string); + writer->statement = NULL; + writer->store_rates = 1; + + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *c = ci->children + i; + + if (strcasecmp("Statement", c->key) == 0) + status = cf_util_get_string(c, &writer->statement); + else if (strcasecmp("StoreRates", c->key) == 0) + status = cf_util_get_boolean(c, &writer->store_rates); + else + log_warn("Ignoring unknown config key \"%s\".", c->key); + } + + if (status != 0) { + sfree(writer->statement); + sfree(writer->name); + return status; + } + + ++writers_num; + return 0; } /* c_psql_config_writer */ -static int c_psql_config_database (oconfig_item_t *ci) -{ - c_psql_database_t *db; - - char cb_name[DATA_MAX_NAME_LEN]; - static _Bool have_flush = 0; - - if ((1 != ci->values_num) - || (OCONFIG_TYPE_STRING != ci->values[0].type)) { - log_err (" expects a single string argument."); - return 1; - } - - db = c_psql_database_new (ci->values[0].value.string); - if (db == NULL) - return -1; - - for (int i = 0; i < ci->children_num; ++i) { - oconfig_item_t *c = ci->children + i; - - if (0 == strcasecmp (c->key, "Host")) - cf_util_get_string (c, &db->host); - else if (0 == strcasecmp (c->key, "Port")) - cf_util_get_service (c, &db->port); - else if (0 == strcasecmp (c->key, "User")) - cf_util_get_string (c, &db->user); - else if (0 == strcasecmp (c->key, "Password")) - cf_util_get_string (c, &db->password); - else if (0 == strcasecmp (c->key, "Instance")) - cf_util_get_string (c, &db->instance); - else if (0 == strcasecmp (c->key, "SSLMode")) - cf_util_get_string (c, &db->sslmode); - else if (0 == strcasecmp (c->key, "KRBSrvName")) - cf_util_get_string (c, &db->krbsrvname); - else if (0 == strcasecmp (c->key, "Service")) - cf_util_get_string (c, &db->service); - else if (0 == strcasecmp (c->key, "Query")) - udb_query_pick_from_list (c, queries, queries_num, - &db->queries, &db->queries_num); - else if (0 == strcasecmp (c->key, "Writer")) - config_add_writer (c, writers, writers_num, - &db->writers, &db->writers_num); - else if (0 == strcasecmp (c->key, "Interval")) - cf_util_get_cdtime (c, &db->interval); - else if (strcasecmp ("CommitInterval", c->key) == 0) - cf_util_get_cdtime (c, &db->commit_interval); - else if (strcasecmp ("ExpireDelay", c->key) == 0) - cf_util_get_cdtime (c, &db->expire_delay); - else - log_warn ("Ignoring unknown config key \"%s\".", c->key); - } - - /* If no `Query' options were given, add the default queries.. */ - if ((db->queries_num == 0) && (db->writers_num == 0)){ - for (int i = 0; i < def_queries_num; i++) - udb_query_pick_from_list_by_name (def_queries[i], - queries, queries_num, - &db->queries, &db->queries_num); - } - - if (db->queries_num > 0) { - db->q_prep_areas = (udb_query_preparation_area_t **) calloc ( - db->queries_num, sizeof (*db->q_prep_areas)); - - if (db->q_prep_areas == NULL) { - log_err ("Out of memory."); - c_psql_database_delete (db); - return -1; - } - } - - for (int i = 0; (size_t)i < db->queries_num; ++i) { - c_psql_user_data_t *data; - data = udb_query_get_user_data (db->queries[i]); - if ((data != NULL) && (data->params_num > db->max_params_num)) - db->max_params_num = data->params_num; - - db->q_prep_areas[i] - = udb_query_allocate_preparation_area (db->queries[i]); - - if (db->q_prep_areas[i] == NULL) { - log_err ("Out of memory."); - c_psql_database_delete (db); - return -1; - } - } - - ssnprintf (cb_name, sizeof (cb_name), "postgresql-%s", db->instance); - - user_data_t ud = { - .data = db, - .free_func = c_psql_database_delete - }; - - if (db->queries_num > 0) { - ++db->ref_cnt; - plugin_register_complex_read ("postgresql", cb_name, c_psql_read, - /* interval = */ db->interval, &ud); - } - if (db->writers_num > 0) { - ++db->ref_cnt; - plugin_register_write (cb_name, c_psql_write, &ud); - - if (! have_flush) { - /* flush all */ - plugin_register_flush ("postgresql", - c_psql_flush, /* user data = */ NULL); - have_flush = 1; - } - - /* flush this connection only */ - ++db->ref_cnt; - plugin_register_flush (cb_name, c_psql_flush, &ud); - } - else if (db->commit_interval > 0) { - log_warn ("Database '%s': You do not have any writers assigned to " - "this database connection. Setting 'CommitInterval' does " - "not have any effect.", db->database); - } - return 0; +static int c_psql_config_database(oconfig_item_t *ci) { + c_psql_database_t *db; + + char cb_name[DATA_MAX_NAME_LEN]; + static _Bool have_flush = 0; + + if ((1 != ci->values_num) || (OCONFIG_TYPE_STRING != ci->values[0].type)) { + log_err(" expects a single string argument."); + return 1; + } + + db = c_psql_database_new(ci->values[0].value.string); + if (db == NULL) + return -1; + + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *c = ci->children + i; + + if (0 == strcasecmp(c->key, "Host")) + cf_util_get_string(c, &db->host); + else if (0 == strcasecmp(c->key, "Port")) + cf_util_get_service(c, &db->port); + else if (0 == strcasecmp(c->key, "User")) + cf_util_get_string(c, &db->user); + else if (0 == strcasecmp(c->key, "Password")) + cf_util_get_string(c, &db->password); + else if (0 == strcasecmp(c->key, "Instance")) + cf_util_get_string(c, &db->instance); + else if (0 == strcasecmp(c->key, "SSLMode")) + cf_util_get_string(c, &db->sslmode); + else if (0 == strcasecmp(c->key, "KRBSrvName")) + cf_util_get_string(c, &db->krbsrvname); + else if (0 == strcasecmp(c->key, "Service")) + cf_util_get_string(c, &db->service); + else if (0 == strcasecmp(c->key, "Query")) + udb_query_pick_from_list(c, queries, queries_num, &db->queries, + &db->queries_num); + else if (0 == strcasecmp(c->key, "Writer")) + config_add_writer(c, writers, writers_num, &db->writers, + &db->writers_num); + else if (0 == strcasecmp(c->key, "Interval")) + cf_util_get_cdtime(c, &db->interval); + else if (strcasecmp("CommitInterval", c->key) == 0) + cf_util_get_cdtime(c, &db->commit_interval); + else if (strcasecmp("ExpireDelay", c->key) == 0) + cf_util_get_cdtime(c, &db->expire_delay); + else + log_warn("Ignoring unknown config key \"%s\".", c->key); + } + + /* If no `Query' options were given, add the default queries.. */ + if ((db->queries_num == 0) && (db->writers_num == 0)) { + for (int i = 0; i < def_queries_num; i++) + udb_query_pick_from_list_by_name(def_queries[i], queries, queries_num, + &db->queries, &db->queries_num); + } + + if (db->queries_num > 0) { + db->q_prep_areas = (udb_query_preparation_area_t **)calloc( + db->queries_num, sizeof(*db->q_prep_areas)); + + if (db->q_prep_areas == NULL) { + log_err("Out of memory."); + c_psql_database_delete(db); + return -1; + } + } + + for (int i = 0; (size_t)i < db->queries_num; ++i) { + c_psql_user_data_t *data; + data = udb_query_get_user_data(db->queries[i]); + if ((data != NULL) && (data->params_num > db->max_params_num)) + db->max_params_num = data->params_num; + + db->q_prep_areas[i] = udb_query_allocate_preparation_area(db->queries[i]); + + if (db->q_prep_areas[i] == NULL) { + log_err("Out of memory."); + c_psql_database_delete(db); + return -1; + } + } + + ssnprintf(cb_name, sizeof(cb_name), "postgresql-%s", db->instance); + + user_data_t ud = {.data = db, .free_func = c_psql_database_delete}; + + if (db->queries_num > 0) { + ++db->ref_cnt; + plugin_register_complex_read("postgresql", cb_name, c_psql_read, + /* interval = */ db->interval, &ud); + } + if (db->writers_num > 0) { + ++db->ref_cnt; + plugin_register_write(cb_name, c_psql_write, &ud); + + if (!have_flush) { + /* flush all */ + plugin_register_flush("postgresql", c_psql_flush, /* user data = */ NULL); + have_flush = 1; + } + + /* flush this connection only */ + ++db->ref_cnt; + plugin_register_flush(cb_name, c_psql_flush, &ud); + } else if (db->commit_interval > 0) { + log_warn("Database '%s': You do not have any writers assigned to " + "this database connection. Setting 'CommitInterval' does " + "not have any effect.", + db->database); + } + return 0; } /* c_psql_config_database */ -static int c_psql_config (oconfig_item_t *ci) -{ - static int have_def_config = 0; - - if (0 == have_def_config) { - oconfig_item_t *c; - - have_def_config = 1; - - c = oconfig_parse_file (C_PSQL_DEFAULT_CONF); - if (NULL == c) - log_err ("Failed to read default config ("C_PSQL_DEFAULT_CONF")."); - else - c_psql_config (c); - - if (NULL == queries) - log_err ("Default config ("C_PSQL_DEFAULT_CONF") did not define " - "any queries - please check your installation."); - } - - for (int i = 0; i < ci->children_num; ++i) { - oconfig_item_t *c = ci->children + i; - - if (0 == strcasecmp (c->key, "Query")) - udb_query_create (&queries, &queries_num, c, - /* callback = */ config_query_callback); - else if (0 == strcasecmp (c->key, "Writer")) - c_psql_config_writer (c); - else if (0 == strcasecmp (c->key, "Database")) - c_psql_config_database (c); - else - log_warn ("Ignoring unknown config key \"%s\".", c->key); - } - return 0; +static int c_psql_config(oconfig_item_t *ci) { + static int have_def_config = 0; + + if (0 == have_def_config) { + oconfig_item_t *c; + + have_def_config = 1; + + c = oconfig_parse_file(C_PSQL_DEFAULT_CONF); + if (NULL == c) + log_err("Failed to read default config (" C_PSQL_DEFAULT_CONF ")."); + else + c_psql_config(c); + + if (NULL == queries) + log_err("Default config (" C_PSQL_DEFAULT_CONF ") did not define " + "any queries - please check your installation."); + } + + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *c = ci->children + i; + + if (0 == strcasecmp(c->key, "Query")) + udb_query_create(&queries, &queries_num, c, + /* callback = */ config_query_callback); + else if (0 == strcasecmp(c->key, "Writer")) + c_psql_config_writer(c); + else if (0 == strcasecmp(c->key, "Database")) + c_psql_config_database(c); + else + log_warn("Ignoring unknown config key \"%s\".", c->key); + } + return 0; } /* c_psql_config */ -void module_register (void) -{ - plugin_register_complex_config ("postgresql", c_psql_config); - plugin_register_shutdown ("postgresql", c_psql_shutdown); +void module_register(void) { + plugin_register_complex_config("postgresql", c_psql_config); + plugin_register_shutdown("postgresql", c_psql_shutdown); } /* module_register */ /* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/powerdns.c b/src/powerdns.c index b5d4a32f..f2149ef2 100644 --- a/src/powerdns.c +++ b/src/powerdns.c @@ -30,40 +30,46 @@ #include "plugin.h" #include "utils_llist.h" -#include -#include -#include +#include #include +#include #include -#include +#include #include #include +#include #ifndef UNIX_PATH_MAX -# define UNIX_PATH_MAX sizeof (((struct sockaddr_un *)0)->sun_path) +#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *)0)->sun_path) #endif -#define FUNC_ERROR(func) do { char errbuf[1024]; ERROR ("powerdns plugin: %s failed: %s", func, sstrerror (errno, errbuf, sizeof (errbuf))); } while (0) -#define SOCK_ERROR(func, sockpath) do { char errbuf[1024]; ERROR ("powerdns plugin: Socket `%s` %s failed: %s", sockpath, func, sstrerror (errno, errbuf, sizeof (errbuf))); } while (0) - -#define SERVER_SOCKET LOCALSTATEDIR"/run/pdns.controlsocket" +#define FUNC_ERROR(func) \ + do { \ + char errbuf[1024]; \ + ERROR("powerdns plugin: %s failed: %s", func, \ + sstrerror(errno, errbuf, sizeof(errbuf))); \ + } while (0) +#define SOCK_ERROR(func, sockpath) \ + do { \ + char errbuf[1024]; \ + ERROR("powerdns plugin: Socket `%s` %s failed: %s", sockpath, func, \ + sstrerror(errno, errbuf, sizeof(errbuf))); \ + } while (0) + +#define SERVER_SOCKET LOCALSTATEDIR "/run/pdns.controlsocket" #define SERVER_COMMAND "SHOW * \n" -#define RECURSOR_SOCKET LOCALSTATEDIR"/run/pdns_recursor.controlsocket" -#define RECURSOR_COMMAND "get noerror-answers nxdomain-answers " \ - "servfail-answers sys-msec user-msec qa-latency cache-entries cache-hits " \ +#define RECURSOR_SOCKET LOCALSTATEDIR "/run/pdns_recursor.controlsocket" +#define RECURSOR_COMMAND \ + "get noerror-answers nxdomain-answers " \ + "servfail-answers sys-msec user-msec qa-latency cache-entries cache-hits " \ "cache-misses questions \n" struct list_item_s; typedef struct list_item_s list_item_t; -struct list_item_s -{ - enum - { - SRV_AUTHORITATIVE, - SRV_RECURSOR - } server_type; - int (*func) (list_item_t *item); +struct list_item_s { + enum { SRV_AUTHORITATIVE, SRV_RECURSOR } server_type; + int (*func)(list_item_t *item); char *instance; char **fields; @@ -74,8 +80,7 @@ struct list_item_s int socktype; }; -struct statname_lookup_s -{ +struct statname_lookup_s { const char *name; const char *type; const char *type_instance; @@ -86,36 +91,49 @@ typedef struct statname_lookup_s statname_lookup_t; all-outqueries counts the number of outgoing UDP queries since starting answers-slow counts the number of queries answered after 1 second answers0-1 counts the number of queries answered within 1 millisecond -answers1-10 counts the number of queries answered within 10 milliseconds -answers10-100 counts the number of queries answered within 100 milliseconds +answers1-10 counts the number of queries answered within 10 +milliseconds +answers10-100 counts the number of queries answered within 100 +milliseconds answers100-1000 counts the number of queries answered within 1 second cache-bytes size of the cache in bytes (since 3.3.1) cache-entries shows the number of entries in the cache -cache-hits counts the number of cache hits since starting, this does not include hits that got answered from the packet-cache +cache-hits counts the number of cache hits since starting, this does +not include hits that got answered from the packet-cache cache-misses counts the number of cache misses since starting -case-mismatches counts the number of mismatches in character case since starting +case-mismatches counts the number of mismatches in character case since +starting chain-resends number of queries chained to existing outstanding query client-parse-errors counts number of client packets that could not be parsed concurrent-queries shows the number of MThreads currently running -dlg-only-drops number of records dropped because of delegation only setting -dont-outqueries number of outgoing queries dropped because of 'dont-query' setting (since 3.3) +dlg-only-drops number of records dropped because of delegation only +setting +dont-outqueries number of outgoing queries dropped because of 'dont-query' +setting (since 3.3) edns-ping-matches number of servers that sent a valid EDNS PING respons edns-ping-mismatches number of servers that sent an invalid EDNS PING response failed-host-entries number of servers that failed to resolve ipv6-outqueries number of outgoing queries over IPv6 -ipv6-questions counts all End-user initiated queries with the RD bit set, received over IPv6 UDP -malloc-bytes returns the number of bytes allocated by the process (broken, always returns 0) +ipv6-questions counts all End-user initiated queries with the RD bit set, +received over IPv6 UDP +malloc-bytes returns the number of bytes allocated by the process +(broken, always returns 0) max-mthread-stack maximum amount of thread stack ever used negcache-entries shows the number of entries in the Negative answer cache no-packet-error number of errorneous received packets noedns-outqueries number of queries sent out without EDNS -noerror-answers counts the number of times it answered NOERROR since starting +noerror-answers counts the number of times it answered NOERROR since +starting noping-outqueries number of queries sent out without ENDS PING -nsset-invalidations number of times an nsset was dropped because it no longer worked +nsset-invalidations number of times an nsset was dropped because it no longer +worked nsspeeds-entries shows the number of entries in the NS speeds map -nxdomain-answers counts the number of times it answered NXDOMAIN since starting -outgoing-timeouts counts the number of timeouts on outgoing UDP queries since starting -over-capacity-drops questions dropped because over maximum concurrent query limit (since 3.2) +nxdomain-answers counts the number of times it answered NXDOMAIN since +starting +outgoing-timeouts counts the number of timeouts on outgoing UDP queries +since starting +over-capacity-drops questions dropped because over maximum concurrent query +limit (since 3.2) packetcache-bytes size of the packet cache in bytes (since 3.3.1) packetcache-entries size of packet cache (since 3.2) packetcache-hits packet cache hits (since 3.2) @@ -123,174 +141,175 @@ packetcache-misses packet cache misses (since 3.2) policy-drops packets dropped because of (Lua) policy decision qa-latency shows the current latency average questions counts all end-user initiated queries with the RD bit set -resource-limits counts number of queries that could not be performed because of resource limits +resource-limits counts number of queries that could not be performed +because of resource limits security-status security status based on security polling -server-parse-errors counts number of server replied packets that could not be parsed -servfail-answers counts the number of times it answered SERVFAIL since starting -spoof-prevents number of times PowerDNS considered itself spoofed, and dropped the data +server-parse-errors counts number of server replied packets that could not be +parsed +servfail-answers counts the number of times it answered SERVFAIL since +starting +spoof-prevents number of times PowerDNS considered itself spoofed, and +dropped the data sys-msec number of CPU milliseconds spent in 'system' mode -tcp-client-overflow number of times an IP address was denied TCP access because it already had too many connections +tcp-client-overflow number of times an IP address was denied TCP access +because it already had too many connections tcp-clients counts the number of currently active TCP/IP clients tcp-outqueries counts the number of outgoing TCP queries since starting tcp-questions counts all incoming TCP queries (since starting) throttle-entries shows the number of entries in the throttle map -throttled-out counts the number of throttled outgoing UDP queries since starting +throttled-out counts the number of throttled outgoing UDP queries since +starting throttled-outqueries idem to throttled-out -unauthorized-tcp number of TCP questions denied because of allow-from restrictions -unauthorized-udp number of UDP questions denied because of allow-from restrictions -unexpected-packets number of answers from remote servers that were unexpected (might point to spoofing) -unreachables number of times nameservers were unreachable since starting +unauthorized-tcp number of TCP questions denied because of allow-from +restrictions +unauthorized-udp number of UDP questions denied because of allow-from +restrictions +unexpected-packets number of answers from remote servers that were unexpected +(might point to spoofing) +unreachables number of times nameservers were unreachable since +starting uptime number of seconds process has been running (since 3.1.5) user-msec number of CPU milliseconds spent in 'user' mode }}} */ -static const char* const default_server_fields[] = /* {{{ */ -{ - "latency", - "packetcache-hit", - "packetcache-miss", - "packetcache-size", - "query-cache-hit", - "query-cache-miss", - "recursing-answers", - "recursing-questions", - "tcp-answers", - "tcp-queries", - "udp-answers", - "udp-queries", +static const char *const default_server_fields[] = /* {{{ */ + { + "latency", "packetcache-hit", "packetcache-miss", + "packetcache-size", "query-cache-hit", "query-cache-miss", + "recursing-answers", "recursing-questions", "tcp-answers", + "tcp-queries", "udp-answers", "udp-queries", }; /* }}} */ -static int default_server_fields_num = STATIC_ARRAY_SIZE (default_server_fields); +static int default_server_fields_num = STATIC_ARRAY_SIZE(default_server_fields); static statname_lookup_t lookup_table[] = /* {{{ */ -{ - /********************* - * Server statistics * - *********************/ - /* Questions */ - {"recursing-questions", "dns_question", "recurse"}, - {"tcp-queries", "dns_question", "tcp"}, - {"udp-queries", "dns_question", "udp"}, - {"rd-queries", "dns_question", "rd"}, - - /* Answers */ - {"recursing-answers", "dns_answer", "recurse"}, - {"tcp-answers", "dns_answer", "tcp"}, - {"udp-answers", "dns_answer", "udp"}, - {"recursion-unanswered", "dns_answer", "recursion-unanswered"}, - {"udp-answers-bytes", "total_bytes", "udp-answers-bytes"}, - - /* Cache stuff */ - {"cache-bytes", "cache_size", "cache-bytes"}, - {"packetcache-bytes", "cache_size", "packet-bytes"}, - {"packetcache-entries", "cache_size", "packet-entries"}, - {"packetcache-hit", "cache_result", "packet-hit"}, - {"packetcache-hits", "cache_result", "packet-hit"}, - {"packetcache-miss", "cache_result", "packet-miss"}, - {"packetcache-misses", "cache_result", "packet-miss"}, - {"packetcache-size", "cache_size", "packet"}, - {"key-cache-size", "cache_size", "key"}, - {"meta-cache-size", "cache_size", "meta"}, - {"signature-cache-size", "cache_size", "signature"}, - {"query-cache-hit", "cache_result", "query-hit"}, - {"query-cache-miss", "cache_result", "query-miss"}, - - /* Latency */ - {"latency", "latency", NULL}, - - /* DNS updates */ - {"dnsupdate-answers", "dns_answer", "dnsupdate-answer"}, - {"dnsupdate-changes", "dns_question", "dnsupdate-changes"}, - {"dnsupdate-queries", "dns_question", "dnsupdate-queries"}, - {"dnsupdate-refused", "dns_answer", "dnsupdate-refused"}, - - /* Other stuff.. */ - {"corrupt-packets", "ipt_packets", "corrupt"}, - {"deferred-cache-inserts", "counter", "cache-deferred_insert"}, - {"deferred-cache-lookup", "counter", "cache-deferred_lookup"}, - {"dont-outqueries", "dns_question", "dont-outqueries"}, - {"qsize-a", "cache_size", "answers"}, - {"qsize-q", "cache_size", "questions"}, - {"servfail-packets", "ipt_packets", "servfail"}, - {"timedout-packets", "ipt_packets", "timeout"}, - {"udp4-answers", "dns_answer", "udp4"}, - {"udp4-queries", "dns_question", "queries-udp4"}, - {"udp6-answers", "dns_answer", "udp6"}, - {"udp6-queries", "dns_question", "queries-udp6"}, - {"security-status", "dns_question", "security-status"}, - {"udp-do-queries", "dns_question", "udp-do_queries"}, - {"signatures", "counter", "signatures"}, - - /*********************** - * Recursor statistics * - ***********************/ - /* Answers by return code */ - {"noerror-answers", "dns_rcode", "NOERROR"}, - {"nxdomain-answers", "dns_rcode", "NXDOMAIN"}, - {"servfail-answers", "dns_rcode", "SERVFAIL"}, - - /* CPU utilization */ - {"sys-msec", "cpu", "system"}, - {"user-msec", "cpu", "user"}, - - /* Question-to-answer latency */ - {"qa-latency", "latency", NULL}, - - /* Cache */ - {"cache-entries", "cache_size", NULL}, - {"cache-hits", "cache_result", "hit"}, - {"cache-misses", "cache_result", "miss"}, - - /* Total number of questions.. */ - {"questions", "dns_qtype", "total"}, - - /* All the other stuff.. */ - {"all-outqueries", "dns_question", "outgoing"}, - {"answers0-1", "dns_answer", "0_1"}, - {"answers1-10", "dns_answer", "1_10"}, - {"answers10-100", "dns_answer", "10_100"}, - {"answers100-1000", "dns_answer", "100_1000"}, - {"answers-slow", "dns_answer", "slow"}, - {"case-mismatches", "counter", "case_mismatches"}, - {"chain-resends", "dns_question", "chained"}, - {"client-parse-errors", "counter", "drops-client_parse_error"}, - {"concurrent-queries", "dns_question", "concurrent"}, - {"dlg-only-drops", "counter", "drops-delegation_only"}, - {"edns-ping-matches", "counter", "edns-ping_matches"}, - {"edns-ping-mismatches", "counter", "edns-ping_mismatches"}, - {"failed-host-entries", "counter", "entries-failed_host"}, - {"ipv6-outqueries", "dns_question", "outgoing-ipv6"}, - {"ipv6-questions", "dns_question", "incoming-ipv6"}, - {"malloc-bytes", "gauge", "malloc_bytes"}, - {"max-mthread-stack", "gauge", "max_mthread_stack"}, - {"no-packet-error", "gauge", "no_packet_error"}, - {"noedns-outqueries", "dns_question", "outgoing-noedns"}, - {"noping-outqueries", "dns_question", "outgoing-noping"}, - {"over-capacity-drops", "dns_question", "incoming-over_capacity"}, - {"negcache-entries", "cache_size", "negative"}, - {"nsspeeds-entries", "gauge", "entries-ns_speeds"}, - {"nsset-invalidations", "counter", "ns_set_invalidation"}, - {"outgoing-timeouts", "counter", "drops-timeout_outgoing"}, - {"policy-drops", "counter", "drops-policy"}, - {"resource-limits", "counter", "drops-resource_limit"}, - {"server-parse-errors", "counter", "drops-server_parse_error"}, - {"spoof-prevents", "counter", "drops-spoofed"}, - {"tcp-client-overflow", "counter", "denied-client_overflow_tcp"}, - {"tcp-clients", "gauge", "clients-tcp"}, - {"tcp-outqueries", "dns_question", "outgoing-tcp"}, - {"tcp-questions", "dns_question", "incoming-tcp"}, - {"throttled-out", "dns_question", "outgoing-throttled"}, - {"throttle-entries", "gauge", "entries-throttle"}, - {"throttled-outqueries", "dns_question", "outgoing-throttle"}, - {"unauthorized-tcp", "counter", "denied-unauthorized_tcp"}, - {"unauthorized-udp", "counter", "denied-unauthorized_udp"}, - {"unexpected-packets", "dns_answer", "unexpected"}, - {"uptime", "uptime", NULL} -}; /* }}} */ -static int lookup_table_length = STATIC_ARRAY_SIZE (lookup_table); + { + /********************* + * Server statistics * + *********************/ + /* Questions */ + {"recursing-questions", "dns_question", "recurse"}, + {"tcp-queries", "dns_question", "tcp"}, + {"udp-queries", "dns_question", "udp"}, + {"rd-queries", "dns_question", "rd"}, + + /* Answers */ + {"recursing-answers", "dns_answer", "recurse"}, + {"tcp-answers", "dns_answer", "tcp"}, + {"udp-answers", "dns_answer", "udp"}, + {"recursion-unanswered", "dns_answer", "recursion-unanswered"}, + {"udp-answers-bytes", "total_bytes", "udp-answers-bytes"}, + + /* Cache stuff */ + {"cache-bytes", "cache_size", "cache-bytes"}, + {"packetcache-bytes", "cache_size", "packet-bytes"}, + {"packetcache-entries", "cache_size", "packet-entries"}, + {"packetcache-hit", "cache_result", "packet-hit"}, + {"packetcache-hits", "cache_result", "packet-hit"}, + {"packetcache-miss", "cache_result", "packet-miss"}, + {"packetcache-misses", "cache_result", "packet-miss"}, + {"packetcache-size", "cache_size", "packet"}, + {"key-cache-size", "cache_size", "key"}, + {"meta-cache-size", "cache_size", "meta"}, + {"signature-cache-size", "cache_size", "signature"}, + {"query-cache-hit", "cache_result", "query-hit"}, + {"query-cache-miss", "cache_result", "query-miss"}, + + /* Latency */ + {"latency", "latency", NULL}, + + /* DNS updates */ + {"dnsupdate-answers", "dns_answer", "dnsupdate-answer"}, + {"dnsupdate-changes", "dns_question", "dnsupdate-changes"}, + {"dnsupdate-queries", "dns_question", "dnsupdate-queries"}, + {"dnsupdate-refused", "dns_answer", "dnsupdate-refused"}, + + /* Other stuff.. */ + {"corrupt-packets", "ipt_packets", "corrupt"}, + {"deferred-cache-inserts", "counter", "cache-deferred_insert"}, + {"deferred-cache-lookup", "counter", "cache-deferred_lookup"}, + {"dont-outqueries", "dns_question", "dont-outqueries"}, + {"qsize-a", "cache_size", "answers"}, + {"qsize-q", "cache_size", "questions"}, + {"servfail-packets", "ipt_packets", "servfail"}, + {"timedout-packets", "ipt_packets", "timeout"}, + {"udp4-answers", "dns_answer", "udp4"}, + {"udp4-queries", "dns_question", "queries-udp4"}, + {"udp6-answers", "dns_answer", "udp6"}, + {"udp6-queries", "dns_question", "queries-udp6"}, + {"security-status", "dns_question", "security-status"}, + {"udp-do-queries", "dns_question", "udp-do_queries"}, + {"signatures", "counter", "signatures"}, + + /*********************** + * Recursor statistics * + ***********************/ + /* Answers by return code */ + {"noerror-answers", "dns_rcode", "NOERROR"}, + {"nxdomain-answers", "dns_rcode", "NXDOMAIN"}, + {"servfail-answers", "dns_rcode", "SERVFAIL"}, + + /* CPU utilization */ + {"sys-msec", "cpu", "system"}, + {"user-msec", "cpu", "user"}, + + /* Question-to-answer latency */ + {"qa-latency", "latency", NULL}, + + /* Cache */ + {"cache-entries", "cache_size", NULL}, + {"cache-hits", "cache_result", "hit"}, + {"cache-misses", "cache_result", "miss"}, + + /* Total number of questions.. */ + {"questions", "dns_qtype", "total"}, + + /* All the other stuff.. */ + {"all-outqueries", "dns_question", "outgoing"}, + {"answers0-1", "dns_answer", "0_1"}, + {"answers1-10", "dns_answer", "1_10"}, + {"answers10-100", "dns_answer", "10_100"}, + {"answers100-1000", "dns_answer", "100_1000"}, + {"answers-slow", "dns_answer", "slow"}, + {"case-mismatches", "counter", "case_mismatches"}, + {"chain-resends", "dns_question", "chained"}, + {"client-parse-errors", "counter", "drops-client_parse_error"}, + {"concurrent-queries", "dns_question", "concurrent"}, + {"dlg-only-drops", "counter", "drops-delegation_only"}, + {"edns-ping-matches", "counter", "edns-ping_matches"}, + {"edns-ping-mismatches", "counter", "edns-ping_mismatches"}, + {"failed-host-entries", "counter", "entries-failed_host"}, + {"ipv6-outqueries", "dns_question", "outgoing-ipv6"}, + {"ipv6-questions", "dns_question", "incoming-ipv6"}, + {"malloc-bytes", "gauge", "malloc_bytes"}, + {"max-mthread-stack", "gauge", "max_mthread_stack"}, + {"no-packet-error", "gauge", "no_packet_error"}, + {"noedns-outqueries", "dns_question", "outgoing-noedns"}, + {"noping-outqueries", "dns_question", "outgoing-noping"}, + {"over-capacity-drops", "dns_question", "incoming-over_capacity"}, + {"negcache-entries", "cache_size", "negative"}, + {"nsspeeds-entries", "gauge", "entries-ns_speeds"}, + {"nsset-invalidations", "counter", "ns_set_invalidation"}, + {"outgoing-timeouts", "counter", "drops-timeout_outgoing"}, + {"policy-drops", "counter", "drops-policy"}, + {"resource-limits", "counter", "drops-resource_limit"}, + {"server-parse-errors", "counter", "drops-server_parse_error"}, + {"spoof-prevents", "counter", "drops-spoofed"}, + {"tcp-client-overflow", "counter", "denied-client_overflow_tcp"}, + {"tcp-clients", "gauge", "clients-tcp"}, + {"tcp-outqueries", "dns_question", "outgoing-tcp"}, + {"tcp-questions", "dns_question", "incoming-tcp"}, + {"throttled-out", "dns_question", "outgoing-throttled"}, + {"throttle-entries", "gauge", "entries-throttle"}, + {"throttled-outqueries", "dns_question", "outgoing-throttle"}, + {"unauthorized-tcp", "counter", "denied-unauthorized_tcp"}, + {"unauthorized-udp", "counter", "denied-unauthorized_udp"}, + {"unexpected-packets", "dns_answer", "unexpected"}, + {"uptime", "uptime", NULL}}; /* }}} */ +static int lookup_table_length = STATIC_ARRAY_SIZE(lookup_table); static llist_t *list = NULL; -#define PDNS_LOCAL_SOCKPATH LOCALSTATEDIR"/run/"PACKAGE_NAME"-powerdns" +#define PDNS_LOCAL_SOCKPATH LOCALSTATEDIR "/run/" PACKAGE_NAME "-powerdns" static char *local_sockpath = NULL; /* TODO: Do this before 4.4: @@ -300,9 +319,8 @@ static char *local_sockpath = NULL; */ /* */ -static void submit (const char *plugin_instance, /* {{{ */ - const char *pdns_type, const char *value_str) -{ +static void submit(const char *plugin_instance, /* {{{ */ + const char *pdns_type, const char *value_str) { value_list_t vl = VALUE_LIST_INIT; value_t value; @@ -313,13 +331,12 @@ static void submit (const char *plugin_instance, /* {{{ */ int i; for (i = 0; i < lookup_table_length; i++) - if (strcmp (lookup_table[i].name, pdns_type) == 0) + if (strcmp(lookup_table[i].name, pdns_type) == 0) break; - if (i >= lookup_table_length) - { - INFO ("powerdns plugin: submit: Not found in lookup table: %s = %s;", - pdns_type, value_str); + if (i >= lookup_table_length) { + INFO("powerdns plugin: submit: Not found in lookup table: %s = %s;", + pdns_type, value_str); return; } @@ -329,45 +346,41 @@ static void submit (const char *plugin_instance, /* {{{ */ type = lookup_table[i].type; type_instance = lookup_table[i].type_instance; - ds = plugin_get_ds (type); - if (ds == NULL) - { - ERROR ("powerdns plugin: The lookup table returned type `%s', " - "but I cannot find it via `plugin_get_ds'.", - type); + ds = plugin_get_ds(type); + if (ds == NULL) { + ERROR("powerdns plugin: The lookup table returned type `%s', " + "but I cannot find it via `plugin_get_ds'.", + type); return; } - if (ds->ds_num != 1) - { - ERROR ("powerdns plugin: type `%s' has %zu data sources, " - "but I can only handle one.", - type, ds->ds_num); + if (ds->ds_num != 1) { + ERROR("powerdns plugin: type `%s' has %zu data sources, " + "but I can only handle one.", + type, ds->ds_num); return; } - if (0 != parse_value (value_str, &value, ds->ds[0].type)) - { - ERROR ("powerdns plugin: Cannot convert `%s' " - "to a number.", value_str); + if (0 != parse_value(value_str, &value, ds->ds[0].type)) { + ERROR("powerdns plugin: Cannot convert `%s' " + "to a number.", + value_str); return; } vl.values = &value; vl.values_len = 1; - sstrncpy (vl.plugin, "powerdns", sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof (vl.type)); + sstrncpy(vl.plugin, "powerdns", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); - sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* }}} static void submit */ -static int powerdns_get_data_dgram (list_item_t *item, /* {{{ */ - char **ret_buffer, - size_t *ret_buffer_size) -{ +static int powerdns_get_data_dgram(list_item_t *item, /* {{{ */ + char **ret_buffer, size_t *ret_buffer_size) { int sd; int status; @@ -375,27 +388,25 @@ static int powerdns_get_data_dgram (list_item_t *item, /* {{{ */ char *buffer = NULL; size_t buffer_size = 0; - struct sockaddr_un sa_unix = { 0 }; + struct sockaddr_un sa_unix = {0}; cdtime_t cdt_timeout; - sd = socket (PF_UNIX, item->socktype, 0); - if (sd < 0) - { - FUNC_ERROR ("socket"); + sd = socket(PF_UNIX, item->socktype, 0); + if (sd < 0) { + FUNC_ERROR("socket"); return (-1); } sa_unix.sun_family = AF_UNIX; - sstrncpy (sa_unix.sun_path, - (local_sockpath != NULL) ? local_sockpath : PDNS_LOCAL_SOCKPATH, - sizeof (sa_unix.sun_path)); - - status = unlink (sa_unix.sun_path); - if ((status != 0) && (errno != ENOENT)) - { - SOCK_ERROR ("unlink", sa_unix.sun_path); - close (sd); + sstrncpy(sa_unix.sun_path, + (local_sockpath != NULL) ? local_sockpath : PDNS_LOCAL_SOCKPATH, + sizeof(sa_unix.sun_path)); + + status = unlink(sa_unix.sun_path); + if ((status != 0) && (errno != ENOENT)) { + SOCK_ERROR("unlink", sa_unix.sun_path); + close(sd); return (-1); } @@ -403,74 +414,67 @@ static int powerdns_get_data_dgram (list_item_t *item, /* {{{ */ { /* We need to bind to a specific path, because this is a datagram socket * and otherwise the daemon cannot answer. */ - status = bind (sd, (struct sockaddr *) &sa_unix, sizeof (sa_unix)); - if (status != 0) - { - SOCK_ERROR ("bind", sa_unix.sun_path); + status = bind(sd, (struct sockaddr *)&sa_unix, sizeof(sa_unix)); + if (status != 0) { + SOCK_ERROR("bind", sa_unix.sun_path); break; } /* Make the socket writeable by the daemon.. */ - status = chmod (sa_unix.sun_path, 0666); - if (status != 0) - { - SOCK_ERROR ("chmod", sa_unix.sun_path); + status = chmod(sa_unix.sun_path, 0666); + if (status != 0) { + SOCK_ERROR("chmod", sa_unix.sun_path); break; } - cdt_timeout = plugin_get_interval () * 3 / 4; - if (cdt_timeout < TIME_T_TO_CDTIME_T (2)) - cdt_timeout = TIME_T_TO_CDTIME_T (2); + cdt_timeout = plugin_get_interval() * 3 / 4; + if (cdt_timeout < TIME_T_TO_CDTIME_T(2)) + cdt_timeout = TIME_T_TO_CDTIME_T(2); - status = setsockopt (sd, SOL_SOCKET, SO_RCVTIMEO, - &CDTIME_T_TO_TIMEVAL(cdt_timeout), - sizeof(struct timeval)); - if (status != 0) - { - SOCK_ERROR ("setsockopt", sa_unix.sun_path); + status = + setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, + &CDTIME_T_TO_TIMEVAL(cdt_timeout), sizeof(struct timeval)); + if (status != 0) { + SOCK_ERROR("setsockopt", sa_unix.sun_path); break; } - status = connect (sd, (struct sockaddr *) &item->sockaddr, - sizeof (item->sockaddr)); - if (status != 0) - { - SOCK_ERROR ("connect", sa_unix.sun_path); + status = + connect(sd, (struct sockaddr *)&item->sockaddr, sizeof(item->sockaddr)); + if (status != 0) { + SOCK_ERROR("connect", sa_unix.sun_path); break; } - status = send (sd, item->command, strlen (item->command), 0); - if (status < 0) - { - SOCK_ERROR ("send", sa_unix.sun_path); + status = send(sd, item->command, strlen(item->command), 0); + if (status < 0) { + SOCK_ERROR("send", sa_unix.sun_path); break; } - status = recv (sd, temp, sizeof (temp), /* flags = */ 0); - if (status < 0) - { - SOCK_ERROR ("recv", sa_unix.sun_path); + status = recv(sd, temp, sizeof(temp), /* flags = */ 0); + if (status < 0) { + SOCK_ERROR("recv", sa_unix.sun_path); break; } buffer_size = status + 1; status = 0; } while (0); - close (sd); - unlink (sa_unix.sun_path); + close(sd); + unlink(sa_unix.sun_path); if (status != 0) return (-1); - assert (buffer_size > 0); - buffer = malloc (buffer_size); - if (buffer == NULL) - { - FUNC_ERROR ("malloc"); + assert(buffer_size > 0); + buffer = malloc(buffer_size); + if (buffer == NULL) { + FUNC_ERROR("malloc"); return (-1); } - memcpy (buffer, temp, buffer_size - 1); + memcpy(buffer, temp, buffer_size - 1); buffer[buffer_size - 1] = 0; *ret_buffer = buffer; @@ -479,10 +483,9 @@ static int powerdns_get_data_dgram (list_item_t *item, /* {{{ */ return (0); } /* }}} int powerdns_get_data_dgram */ -static int powerdns_get_data_stream (list_item_t *item, /* {{{ */ - char **ret_buffer, - size_t *ret_buffer_size) -{ +static int powerdns_get_data_stream(list_item_t *item, /* {{{ */ + char **ret_buffer, + size_t *ret_buffer_size) { int sd; int status; @@ -490,78 +493,67 @@ static int powerdns_get_data_stream (list_item_t *item, /* {{{ */ char *buffer = NULL; size_t buffer_size = 0; - sd = socket (PF_UNIX, item->socktype, 0); - if (sd < 0) - { - FUNC_ERROR ("socket"); + sd = socket(PF_UNIX, item->socktype, 0); + if (sd < 0) { + FUNC_ERROR("socket"); return (-1); } struct timeval timeout; - timeout.tv_sec=5; - timeout.tv_usec=0; - status = setsockopt (sd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof (timeout)); - if (status != 0) - { - FUNC_ERROR ("setsockopt"); - close (sd); + timeout.tv_sec = 5; + timeout.tv_usec = 0; + status = setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); + if (status != 0) { + FUNC_ERROR("setsockopt"); + close(sd); return (-1); } - status = connect (sd, (struct sockaddr *) &item->sockaddr, - sizeof (item->sockaddr)); - if (status != 0) - { - SOCK_ERROR ("connect", item->sockaddr.sun_path); - close (sd); + status = + connect(sd, (struct sockaddr *)&item->sockaddr, sizeof(item->sockaddr)); + if (status != 0) { + SOCK_ERROR("connect", item->sockaddr.sun_path); + close(sd); return (-1); } /* strlen + 1, because we need to send the terminating NULL byte, too. */ - status = send (sd, item->command, strlen (item->command) + 1, - /* flags = */ 0); - if (status < 0) - { - SOCK_ERROR ("send", item->sockaddr.sun_path); - close (sd); + status = send(sd, item->command, strlen(item->command) + 1, + /* flags = */ 0); + if (status < 0) { + SOCK_ERROR("send", item->sockaddr.sun_path); + close(sd); return (-1); } - while (42) - { + while (42) { char *buffer_new; - status = recv (sd, temp, sizeof (temp), /* flags = */ 0); - if (status < 0) - { - SOCK_ERROR ("recv", item->sockaddr.sun_path); + status = recv(sd, temp, sizeof(temp), /* flags = */ 0); + if (status < 0) { + SOCK_ERROR("recv", item->sockaddr.sun_path); break; - } - else if (status == 0) + } else if (status == 0) break; - buffer_new = realloc (buffer, buffer_size + status + 1); - if (buffer_new == NULL) - { - FUNC_ERROR ("realloc"); + buffer_new = realloc(buffer, buffer_size + status + 1); + if (buffer_new == NULL) { + FUNC_ERROR("realloc"); status = -1; break; } buffer = buffer_new; - memcpy (buffer + buffer_size, temp, status); + memcpy(buffer + buffer_size, temp, status); buffer_size += status; buffer[buffer_size] = 0; } /* while (42) */ - close (sd); + close(sd); - if (status < 0) - { - sfree (buffer); - } - else - { - assert (status == 0); + if (status < 0) { + sfree(buffer); + } else { + assert(status == 0); *ret_buffer = buffer; *ret_buffer_size = buffer_size; } @@ -569,21 +561,19 @@ static int powerdns_get_data_stream (list_item_t *item, /* {{{ */ return (status); } /* }}} int powerdns_get_data_stream */ -static int powerdns_get_data (list_item_t *item, char **ret_buffer, - size_t *ret_buffer_size) -{ +static int powerdns_get_data(list_item_t *item, char **ret_buffer, + size_t *ret_buffer_size) { if (item->socktype == SOCK_DGRAM) - return (powerdns_get_data_dgram (item, ret_buffer, ret_buffer_size)); + return (powerdns_get_data_dgram(item, ret_buffer, ret_buffer_size)); else if (item->socktype == SOCK_STREAM) - return (powerdns_get_data_stream (item, ret_buffer, ret_buffer_size)); - else - { - ERROR ("powerdns plugin: Unknown socket type: %i", (int) item->socktype); + return (powerdns_get_data_stream(item, ret_buffer, ret_buffer_size)); + else { + ERROR("powerdns plugin: Unknown socket type: %i", (int)item->socktype); return (-1); } } /* int powerdns_get_data */ -static int powerdns_read_server (list_item_t *item) /* {{{ */ +static int powerdns_read_server(list_item_t *item) /* {{{ */ { char *buffer = NULL; size_t buffer_size = 0; @@ -595,43 +585,39 @@ static int powerdns_read_server (list_item_t *item) /* {{{ */ char *key; char *value; - const char* const *fields; + const char *const *fields; int fields_num; if (item->command == NULL) - item->command = strdup (SERVER_COMMAND); - if (item->command == NULL) - { - ERROR ("powerdns plugin: strdup failed."); + item->command = strdup(SERVER_COMMAND); + if (item->command == NULL) { + ERROR("powerdns plugin: strdup failed."); return (-1); } - status = powerdns_get_data (item, &buffer, &buffer_size); + status = powerdns_get_data(item, &buffer, &buffer_size); if (status != 0) return (-1); - if (item->fields_num != 0) - { - fields = (const char* const *) item->fields; + if (item->fields_num != 0) { + fields = (const char *const *)item->fields; fields_num = item->fields_num; - } - else - { + } else { fields = default_server_fields; fields_num = default_server_fields_num; } - assert (fields != NULL); - assert (fields_num > 0); + assert(fields != NULL); + assert(fields_num > 0); - /* corrupt-packets=0,deferred-cache-inserts=0,deferred-cache-lookup=0,latency=0,packetcache-hit=0,packetcache-miss=0,packetcache-size=0,qsize-q=0,query-cache-hit=0,query-cache-miss=0,recursing-answers=0,recursing-questions=0,servfail-packets=0,tcp-answers=0,tcp-queries=0,timedout-packets=0,udp-answers=0,udp-queries=0,udp4-answers=0,udp4-queries=0,udp6-answers=0,udp6-queries=0, */ + /* corrupt-packets=0,deferred-cache-inserts=0,deferred-cache-lookup=0,latency=0,packetcache-hit=0,packetcache-miss=0,packetcache-size=0,qsize-q=0,query-cache-hit=0,query-cache-miss=0,recursing-answers=0,recursing-questions=0,servfail-packets=0,tcp-answers=0,tcp-queries=0,timedout-packets=0,udp-answers=0,udp-queries=0,udp4-answers=0,udp4-queries=0,udp6-answers=0,udp6-queries=0, + */ dummy = buffer; saveptr = NULL; - while ((key = strtok_r (dummy, ",", &saveptr)) != NULL) - { + while ((key = strtok_r(dummy, ",", &saveptr)) != NULL) { dummy = NULL; - value = strchr (key, '='); + value = strchr(key, '='); if (value == NULL) break; @@ -644,15 +630,15 @@ static int powerdns_read_server (list_item_t *item) /* {{{ */ /* Check if this item was requested. */ int i; for (i = 0; i < fields_num; i++) - if (strcasecmp (key, fields[i]) == 0) - break; + if (strcasecmp(key, fields[i]) == 0) + break; if (i >= fields_num) continue; - submit (item->instance, key, value); + submit(item->instance, key, value); } /* while (strtok_r) */ - sfree (buffer); + sfree(buffer); return (0); } /* }}} int powerdns_read_server */ @@ -664,7 +650,7 @@ static int powerdns_read_server (list_item_t *item) /* {{{ */ * string is stores in the `command' member of the `list_item_t' passed to the * function. This function is called by `powerdns_read_recursor'. */ -static int powerdns_update_recursor_command (list_item_t *li) /* {{{ */ +static int powerdns_update_recursor_command(list_item_t *li) /* {{{ */ { char buffer[4096]; int status; @@ -672,43 +658,37 @@ static int powerdns_update_recursor_command (list_item_t *li) /* {{{ */ if (li == NULL) return (0); - if (li->fields_num < 1) - { - sstrncpy (buffer, RECURSOR_COMMAND, sizeof (buffer)); - } - else - { - sstrncpy (buffer, "get ", sizeof (buffer)); - status = strjoin (&buffer[strlen("get ")], sizeof (buffer) - strlen ("get "), - li->fields, li->fields_num, - /* seperator = */ " "); - if (status < 0) - { - ERROR ("powerdns plugin: strjoin failed."); + if (li->fields_num < 1) { + sstrncpy(buffer, RECURSOR_COMMAND, sizeof(buffer)); + } else { + sstrncpy(buffer, "get ", sizeof(buffer)); + status = strjoin(&buffer[strlen("get ")], sizeof(buffer) - strlen("get "), + li->fields, li->fields_num, + /* seperator = */ " "); + if (status < 0) { + ERROR("powerdns plugin: strjoin failed."); return (-1); } - buffer[sizeof (buffer) - 1] = 0; - size_t len = strlen (buffer); - if (len < sizeof (buffer) - 2) - { + buffer[sizeof(buffer) - 1] = 0; + size_t len = strlen(buffer); + if (len < sizeof(buffer) - 2) { buffer[len++] = ' '; buffer[len++] = '\n'; buffer[len++] = '\0'; } } - buffer[sizeof (buffer) - 1] = 0; - li->command = strdup (buffer); - if (li->command == NULL) - { - ERROR ("powerdns plugin: strdup failed."); + buffer[sizeof(buffer) - 1] = 0; + li->command = strdup(buffer); + if (li->command == NULL) { + ERROR("powerdns plugin: strdup failed."); return (-1); } return (0); } /* }}} int powerdns_update_recursor_command */ -static int powerdns_read_recursor (list_item_t *item) /* {{{ */ +static int powerdns_read_recursor(list_item_t *item) /* {{{ */ { char *buffer = NULL; size_t buffer_size = 0; @@ -722,32 +702,28 @@ static int powerdns_read_recursor (list_item_t *item) /* {{{ */ char *value; char *value_saveptr; - if (item->command == NULL) - { - status = powerdns_update_recursor_command (item); - if (status != 0) - { - ERROR ("powerdns plugin: powerdns_update_recursor_command failed."); + if (item->command == NULL) { + status = powerdns_update_recursor_command(item); + if (status != 0) { + ERROR("powerdns plugin: powerdns_update_recursor_command failed."); return (-1); } - DEBUG ("powerdns plugin: powerdns_read_recursor: item->command = %s;", - item->command); + DEBUG("powerdns plugin: powerdns_read_recursor: item->command = %s;", + item->command); } - assert (item->command != NULL); + assert(item->command != NULL); - status = powerdns_get_data (item, &buffer, &buffer_size); - if (status != 0) - { - ERROR ("powerdns plugin: powerdns_get_data failed."); + status = powerdns_get_data(item, &buffer, &buffer_size); + if (status != 0) { + ERROR("powerdns plugin: powerdns_get_data failed."); return (-1); } - keys_list = strdup (item->command); - if (keys_list == NULL) - { - FUNC_ERROR ("strdup"); - sfree (buffer); + keys_list = strdup(item->command); + if (keys_list == NULL) { + FUNC_ERROR("strdup"); + sfree(buffer); return (-1); } @@ -755,137 +731,120 @@ static int powerdns_read_recursor (list_item_t *item) /* {{{ */ value_saveptr = NULL; /* Skip the `get' at the beginning */ - strtok_r (keys_list, " \t", &key_saveptr); + strtok_r(keys_list, " \t", &key_saveptr); dummy = buffer; - while ((value = strtok_r (dummy, " \t\n\r", &value_saveptr)) != NULL) - { + while ((value = strtok_r(dummy, " \t\n\r", &value_saveptr)) != NULL) { dummy = NULL; - key = strtok_r (NULL, " \t", &key_saveptr); + key = strtok_r(NULL, " \t", &key_saveptr); if (key == NULL) break; - submit (item->instance, key, value); + submit(item->instance, key, value); } /* while (strtok_r) */ - sfree (buffer); - sfree (keys_list); + sfree(buffer); + sfree(keys_list); return (0); } /* }}} int powerdns_read_recursor */ -static int powerdns_config_add_collect (list_item_t *li, /* {{{ */ - oconfig_item_t *ci) -{ +static int powerdns_config_add_collect(list_item_t *li, /* {{{ */ + oconfig_item_t *ci) { char **temp; - if (ci->values_num < 1) - { - WARNING ("powerdns plugin: The `Collect' option needs " - "at least one argument."); + if (ci->values_num < 1) { + WARNING("powerdns plugin: The `Collect' option needs " + "at least one argument."); return (-1); } for (int i = 0; i < ci->values_num; i++) - if (ci->values[i].type != OCONFIG_TYPE_STRING) - { - WARNING ("powerdns plugin: Only string arguments are allowed to " - "the `Collect' option."); + if (ci->values[i].type != OCONFIG_TYPE_STRING) { + WARNING("powerdns plugin: Only string arguments are allowed to " + "the `Collect' option."); return (-1); } - temp = realloc (li->fields, - sizeof (char *) * (li->fields_num + ci->values_num)); - if (temp == NULL) - { - WARNING ("powerdns plugin: realloc failed."); + temp = + realloc(li->fields, sizeof(char *) * (li->fields_num + ci->values_num)); + if (temp == NULL) { + WARNING("powerdns plugin: realloc failed."); return (-1); } li->fields = temp; - for (int i = 0; i < ci->values_num; i++) - { - li->fields[li->fields_num] = strdup (ci->values[i].value.string); - if (li->fields[li->fields_num] == NULL) - { - WARNING ("powerdns plugin: strdup failed."); + for (int i = 0; i < ci->values_num; i++) { + li->fields[li->fields_num] = strdup(ci->values[i].value.string); + if (li->fields[li->fields_num] == NULL) { + WARNING("powerdns plugin: strdup failed."); continue; } li->fields_num++; } /* Invalidate a previously computed command */ - sfree (li->command); + sfree(li->command); return (0); } /* }}} int powerdns_config_add_collect */ -static int powerdns_config_add_server (oconfig_item_t *ci) /* {{{ */ +static int powerdns_config_add_server(oconfig_item_t *ci) /* {{{ */ { char *socket_temp; list_item_t *item; int status; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("powerdns plugin: `%s' needs exactly one string argument.", - ci->key); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("powerdns plugin: `%s' needs exactly one string argument.", + ci->key); return (-1); } - item = calloc (1, sizeof (*item)); - if (item == NULL) - { - ERROR ("powerdns plugin: calloc failed."); + item = calloc(1, sizeof(*item)); + if (item == NULL) { + ERROR("powerdns plugin: calloc failed."); return (-1); } - item->instance = strdup (ci->values[0].value.string); - if (item->instance == NULL) - { - ERROR ("powerdns plugin: strdup failed."); - sfree (item); + item->instance = strdup(ci->values[0].value.string); + if (item->instance == NULL) { + ERROR("powerdns plugin: strdup failed."); + sfree(item); return (-1); } /* * Set default values for the members of list_item_t */ - if (strcasecmp ("Server", ci->key) == 0) - { + if (strcasecmp("Server", ci->key) == 0) { item->server_type = SRV_AUTHORITATIVE; item->func = powerdns_read_server; item->socktype = SOCK_STREAM; - socket_temp = strdup (SERVER_SOCKET); - } - else if (strcasecmp ("Recursor", ci->key) == 0) - { + socket_temp = strdup(SERVER_SOCKET); + } else if (strcasecmp("Recursor", ci->key) == 0) { item->server_type = SRV_RECURSOR; item->func = powerdns_read_recursor; item->socktype = SOCK_DGRAM; - socket_temp = strdup (RECURSOR_SOCKET); - } - else - { + socket_temp = strdup(RECURSOR_SOCKET); + } else { /* We must never get here.. */ - assert (0); + assert(0); return (-1); } status = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; - if (strcasecmp ("Collect", option->key) == 0) - status = powerdns_config_add_collect (item, option); - else if (strcasecmp ("Socket", option->key) == 0) - status = cf_util_get_string (option, &socket_temp); - else - { - ERROR ("powerdns plugin: Option `%s' not allowed here.", option->key); + if (strcasecmp("Collect", option->key) == 0) + status = powerdns_config_add_collect(item, option); + else if (strcasecmp("Socket", option->key) == 0) + status = cf_util_get_string(option, &socket_temp); + else { + ERROR("powerdns plugin: Option `%s' not allowed here.", option->key); status = -1; } @@ -893,129 +852,113 @@ static int powerdns_config_add_server (oconfig_item_t *ci) /* {{{ */ break; } - while (status == 0) - { + while (status == 0) { llentry_t *e; - if (socket_temp == NULL) - { - ERROR ("powerdns plugin: socket_temp == NULL."); + if (socket_temp == NULL) { + ERROR("powerdns plugin: socket_temp == NULL."); status = -1; break; } item->sockaddr.sun_family = AF_UNIX; - sstrncpy (item->sockaddr.sun_path, socket_temp, - sizeof (item->sockaddr.sun_path)); + sstrncpy(item->sockaddr.sun_path, socket_temp, + sizeof(item->sockaddr.sun_path)); - e = llentry_create (item->instance, item); - if (e == NULL) - { - ERROR ("powerdns plugin: llentry_create failed."); + e = llentry_create(item->instance, item); + if (e == NULL) { + ERROR("powerdns plugin: llentry_create failed."); status = -1; break; } - llist_append (list, e); + llist_append(list, e); break; } - if (status != 0) - { - sfree (socket_temp); - sfree (item); + if (status != 0) { + sfree(socket_temp); + sfree(item); return (-1); } - DEBUG ("powerdns plugin: Add server: instance = %s;", item->instance); + DEBUG("powerdns plugin: Add server: instance = %s;", item->instance); - sfree (socket_temp); + sfree(socket_temp); return (0); } /* }}} int powerdns_config_add_server */ -static int powerdns_config (oconfig_item_t *ci) /* {{{ */ +static int powerdns_config(oconfig_item_t *ci) /* {{{ */ { - DEBUG ("powerdns plugin: powerdns_config (ci = %p);", (void *) ci); + DEBUG("powerdns plugin: powerdns_config (ci = %p);", (void *)ci); - if (list == NULL) - { - list = llist_create (); + if (list == NULL) { + list = llist_create(); - if (list == NULL) - { - ERROR ("powerdns plugin: `llist_create' failed."); + if (list == NULL) { + ERROR("powerdns plugin: `llist_create' failed."); return (-1); } } - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; - if ((strcasecmp ("Server", option->key) == 0) - || (strcasecmp ("Recursor", option->key) == 0)) - powerdns_config_add_server (option); - else if (strcasecmp ("LocalSocket", option->key) == 0) - { - if ((option->values_num != 1) || (option->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("powerdns plugin: `%s' needs exactly one string argument.", option->key); - } - else - { - char *temp = strdup (option->values[0].value.string); + if ((strcasecmp("Server", option->key) == 0) || + (strcasecmp("Recursor", option->key) == 0)) + powerdns_config_add_server(option); + else if (strcasecmp("LocalSocket", option->key) == 0) { + if ((option->values_num != 1) || + (option->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("powerdns plugin: `%s' needs exactly one string argument.", + option->key); + } else { + char *temp = strdup(option->values[0].value.string); if (temp == NULL) return (1); - sfree (local_sockpath); + sfree(local_sockpath); local_sockpath = temp; } - } - else - { - ERROR ("powerdns plugin: Option `%s' not allowed here.", option->key); + } else { + ERROR("powerdns plugin: Option `%s' not allowed here.", option->key); } } /* for (i = 0; i < ci->children_num; i++) */ return (0); } /* }}} int powerdns_config */ -static int powerdns_read (void) -{ - for (llentry_t *e = llist_head (list); e != NULL; e = e->next) - { +static int powerdns_read(void) { + for (llentry_t *e = llist_head(list); e != NULL; e = e->next) { list_item_t *item = e->value; - item->func (item); + item->func(item); } return (0); } /* static int powerdns_read */ -static int powerdns_shutdown (void) -{ +static int powerdns_shutdown(void) { if (list == NULL) return (0); - for (llentry_t *e = llist_head (list); e != NULL; e = e->next) - { - list_item_t *item = (list_item_t *) e->value; + for (llentry_t *e = llist_head(list); e != NULL; e = e->next) { + list_item_t *item = (list_item_t *)e->value; e->value = NULL; - sfree (item->instance); - sfree (item->command); - sfree (item); + sfree(item->instance); + sfree(item->command); + sfree(item); } - llist_destroy (list); + llist_destroy(list); list = NULL; return (0); } /* static int powerdns_shutdown */ -void module_register (void) -{ - plugin_register_complex_config ("powerdns", powerdns_config); - plugin_register_read ("powerdns", powerdns_read); - plugin_register_shutdown ("powerdns", powerdns_shutdown ); +void module_register(void) { + plugin_register_complex_config("powerdns", powerdns_config); + plugin_register_read("powerdns", powerdns_read); + plugin_register_shutdown("powerdns", powerdns_shutdown); } /* void module_register */ /* vim: set sw=2 sts=2 ts=8 fdm=marker : */ diff --git a/src/processes.c b/src/processes.c index e1660c55..86f690f3 100644 --- a/src/processes.c +++ b/src/processes.c @@ -41,70 +41,72 @@ /* Include header files for the mach system, if they exist.. */ #if HAVE_THREAD_INFO -# if HAVE_MACH_MACH_INIT_H -# include -# endif -# if HAVE_MACH_HOST_PRIV_H -# include -# endif -# if HAVE_MACH_MACH_ERROR_H -# include -# endif -# if HAVE_MACH_MACH_HOST_H -# include -# endif -# if HAVE_MACH_MACH_PORT_H -# include -# endif -# if HAVE_MACH_MACH_TYPES_H -# include -# endif -# if HAVE_MACH_MESSAGE_H -# include -# endif -# if HAVE_MACH_PROCESSOR_SET_H -# include -# endif -# if HAVE_MACH_TASK_H -# include -# endif -# if HAVE_MACH_THREAD_ACT_H -# include -# endif -# if HAVE_MACH_VM_REGION_H -# include -# endif -# if HAVE_MACH_VM_MAP_H -# include -# endif -# if HAVE_MACH_VM_PROT_H -# include -# endif -# if HAVE_SYS_SYSCTL_H -# include -# endif +#if HAVE_MACH_MACH_INIT_H +#include +#endif +#if HAVE_MACH_HOST_PRIV_H +#include +#endif +#if HAVE_MACH_MACH_ERROR_H +#include +#endif +#if HAVE_MACH_MACH_HOST_H +#include +#endif +#if HAVE_MACH_MACH_PORT_H +#include +#endif +#if HAVE_MACH_MACH_TYPES_H +#include +#endif +#if HAVE_MACH_MESSAGE_H +#include +#endif +#if HAVE_MACH_PROCESSOR_SET_H +#include +#endif +#if HAVE_MACH_TASK_H +#include +#endif +#if HAVE_MACH_THREAD_ACT_H +#include +#endif +#if HAVE_MACH_VM_REGION_H +#include +#endif +#if HAVE_MACH_VM_MAP_H +#include +#endif +#if HAVE_MACH_VM_PROT_H +#include +#endif +#if HAVE_SYS_SYSCTL_H +#include +#endif /* #endif HAVE_THREAD_INFO */ #elif KERNEL_LINUX -# if HAVE_LINUX_CONFIG_H -# include -# endif -# ifndef CONFIG_HZ -# define CONFIG_HZ 100 -# endif +#if HAVE_LINUX_CONFIG_H +#include +#endif +#ifndef CONFIG_HZ +#define CONFIG_HZ 100 +#endif /* #endif KERNEL_LINUX */ -#elif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD) -# include -# include -# include -# include -# include -/* #endif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD) */ +#elif HAVE_LIBKVM_GETPROCS && \ + (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD) +#include +#include +#include +#include +#include +/* #endif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || + * HAVE_STRUCT_KINFO_PROC_OPENBSD) */ #elif HAVE_PROCINFO_H -# include -# include +#include +#include #define MAXPROCENTRY 32 #define MAXTHRDENTRY 16 @@ -117,112 +119,110 @@ * of the structures in uses an off_t, but that * isn't relevant to our usage of procfs. */ #if !defined(_LP64) && _FILE_OFFSET_BITS == 64 -# define SAVE_FOB_64 -# undef _FILE_OFFSET_BITS +#define SAVE_FOB_64 +#undef _FILE_OFFSET_BITS #endif -# include +#include #ifdef SAVE_FOB_64 -# define _FILE_OFFSET_BITS 64 -# undef SAVE_FOB_64 +#define _FILE_OFFSET_BITS 64 +#undef SAVE_FOB_64 #endif -# include -# include +#include +#include #ifndef MAXCOMLEN -# define MAXCOMLEN 16 +#define MAXCOMLEN 16 #endif /* #endif KERNEL_SOLARIS */ #else -# error "No applicable input method." +#error "No applicable input method." #endif #if HAVE_REGEX_H -# include +#include #endif #if HAVE_KSTAT_H -# include +#include #endif #ifndef CMDLINE_BUFFER_SIZE -# if defined(ARG_MAX) && (ARG_MAX < 4096) -# define CMDLINE_BUFFER_SIZE ARG_MAX -# else -# define CMDLINE_BUFFER_SIZE 4096 -# endif +#if defined(ARG_MAX) && (ARG_MAX < 4096) +#define CMDLINE_BUFFER_SIZE ARG_MAX +#else +#define CMDLINE_BUFFER_SIZE 4096 +#endif #endif -typedef struct procstat_entry_s -{ - unsigned long id; - unsigned long age; - - unsigned long num_proc; - unsigned long num_lwp; - unsigned long vmem_size; - unsigned long vmem_rss; - unsigned long vmem_data; - unsigned long vmem_code; - unsigned long stack_size; - - derive_t vmem_minflt_counter; - derive_t vmem_majflt_counter; - - derive_t cpu_user_counter; - derive_t cpu_system_counter; - - /* io data */ - derive_t io_rchar; - derive_t io_wchar; - derive_t io_syscr; - derive_t io_syscw; - _Bool has_io; - - derive_t cswitch_vol; - derive_t cswitch_invol; - _Bool has_cswitch; - - struct procstat_entry_s *next; +typedef struct procstat_entry_s { + unsigned long id; + unsigned long age; + + unsigned long num_proc; + unsigned long num_lwp; + unsigned long vmem_size; + unsigned long vmem_rss; + unsigned long vmem_data; + unsigned long vmem_code; + unsigned long stack_size; + + derive_t vmem_minflt_counter; + derive_t vmem_majflt_counter; + + derive_t cpu_user_counter; + derive_t cpu_system_counter; + + /* io data */ + derive_t io_rchar; + derive_t io_wchar; + derive_t io_syscr; + derive_t io_syscw; + _Bool has_io; + + derive_t cswitch_vol; + derive_t cswitch_invol; + _Bool has_cswitch; + + struct procstat_entry_s *next; } procstat_entry_t; #define PROCSTAT_NAME_LEN 256 -typedef struct procstat -{ - char name[PROCSTAT_NAME_LEN]; +typedef struct procstat { + char name[PROCSTAT_NAME_LEN]; #if HAVE_REGEX_H - regex_t *re; + regex_t *re; #endif - unsigned long num_proc; - unsigned long num_lwp; - unsigned long vmem_size; - unsigned long vmem_rss; - unsigned long vmem_data; - unsigned long vmem_code; - unsigned long stack_size; + unsigned long num_proc; + unsigned long num_lwp; + unsigned long vmem_size; + unsigned long vmem_rss; + unsigned long vmem_data; + unsigned long vmem_code; + unsigned long stack_size; - derive_t vmem_minflt_counter; - derive_t vmem_majflt_counter; + derive_t vmem_minflt_counter; + derive_t vmem_majflt_counter; - derive_t cpu_user_counter; - derive_t cpu_system_counter; + derive_t cpu_user_counter; + derive_t cpu_system_counter; - /* io data */ - derive_t io_rchar; - derive_t io_wchar; - derive_t io_syscr; - derive_t io_syscw; + /* io data */ + derive_t io_rchar; + derive_t io_wchar; + derive_t io_syscr; + derive_t io_syscw; - derive_t cswitch_vol; - derive_t cswitch_invol; + derive_t cswitch_vol; + derive_t cswitch_invol; - struct procstat *next; - struct procstat_entry_s *instances; + struct procstat *next; + struct procstat_entry_s *instances; } procstat_t; static procstat_t *list_head_g = NULL; @@ -235,1215 +235,1118 @@ static mach_port_t port_host_self; static mach_port_t port_task_self; static processor_set_name_array_t pset_list; -static mach_msg_type_number_t pset_list_len; +static mach_msg_type_number_t pset_list_len; /* #endif HAVE_THREAD_INFO */ #elif KERNEL_LINUX static long pagesize_g; -static void ps_fill_details (const procstat_t *ps, procstat_entry_t *entry); +static void ps_fill_details(const procstat_t *ps, procstat_entry_t *entry); /* #endif KERNEL_LINUX */ -#elif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD) +#elif HAVE_LIBKVM_GETPROCS && \ + (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD) static int pagesize; -/* #endif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD) */ +/* #endif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || + * HAVE_STRUCT_KINFO_PROC_OPENBSD) */ #elif HAVE_PROCINFO_H -static struct procentry64 procentry[MAXPROCENTRY]; -static struct thrdentry64 thrdentry[MAXTHRDENTRY]; +static struct procentry64 procentry[MAXPROCENTRY]; +static struct thrdentry64 thrdentry[MAXTHRDENTRY]; static int pagesize; #ifndef _AIXVERSION_610 -int getprocs64 (void *procsinfo, int sizproc, void *fdsinfo, int sizfd, pid_t *index, int count); -int getthrds64( pid_t, void *, int, tid64_t *, int ); +int getprocs64(void *procsinfo, int sizproc, void *fdsinfo, int sizfd, + pid_t *index, int count); +int getthrds64(pid_t, void *, int, tid64_t *, int); #endif -int getargs (void *processBuffer, int bufferLen, char *argsBuffer, int argsLen); +int getargs(void *processBuffer, int bufferLen, char *argsBuffer, int argsLen); #endif /* HAVE_PROCINFO_H */ /* put name of process from config to list_head_g tree * list_head_g is a list of 'procstat_t' structs with * processes names we want to watch */ -static void ps_list_register (const char *name, const char *regexp) -{ - procstat_t *new; - procstat_t *ptr; - int status; - - new = calloc (1, sizeof (*new)); - if (new == NULL) - { - ERROR ("processes plugin: ps_list_register: calloc failed."); - return; - } - sstrncpy (new->name, name, sizeof (new->name)); +static void ps_list_register(const char *name, const char *regexp) { + procstat_t *new; + procstat_t *ptr; + int status; + + new = calloc(1, sizeof(*new)); + if (new == NULL) { + ERROR("processes plugin: ps_list_register: calloc failed."); + return; + } + sstrncpy(new->name, name, sizeof(new->name)); #if HAVE_REGEX_H - if (regexp != NULL) - { - DEBUG ("ProcessMatch: adding \"%s\" as criteria to process %s.", regexp, name); - new->re = malloc (sizeof (*new->re)); - if (new->re == NULL) - { - ERROR ("processes plugin: ps_list_register: malloc failed."); - sfree (new); - return; - } - - status = regcomp (new->re, regexp, REG_EXTENDED | REG_NOSUB); - if (status != 0) - { - DEBUG ("ProcessMatch: compiling the regular expression \"%s\" failed.", regexp); - sfree (new->re); - sfree (new); - return; - } - } + if (regexp != NULL) { + DEBUG("ProcessMatch: adding \"%s\" as criteria to process %s.", regexp, + name); + new->re = malloc(sizeof(*new->re)); + if (new->re == NULL) { + ERROR("processes plugin: ps_list_register: malloc failed."); + sfree(new); + return; + } + + status = regcomp(new->re, regexp, REG_EXTENDED | REG_NOSUB); + if (status != 0) { + DEBUG("ProcessMatch: compiling the regular expression \"%s\" failed.", + regexp); + sfree(new->re); + sfree(new); + return; + } + } #else - if (regexp != NULL) - { - ERROR ("processes plugin: ps_list_register: " - "Regular expression \"%s\" found in config " - "file, but support for regular expressions " - "has been disabled at compile time.", - regexp); - sfree (new); - return; - } + if (regexp != NULL) { + ERROR("processes plugin: ps_list_register: " + "Regular expression \"%s\" found in config " + "file, but support for regular expressions " + "has been disabled at compile time.", + regexp); + sfree(new); + return; + } #endif - for (ptr = list_head_g; ptr != NULL; ptr = ptr->next) - { - if (strcmp (ptr->name, name) == 0) - { - WARNING ("processes plugin: You have configured more " - "than one `Process' or " - "`ProcessMatch' with the same name. " - "All but the first setting will be " - "ignored."); + for (ptr = list_head_g; ptr != NULL; ptr = ptr->next) { + if (strcmp(ptr->name, name) == 0) { + WARNING("processes plugin: You have configured more " + "than one `Process' or " + "`ProcessMatch' with the same name. " + "All but the first setting will be " + "ignored."); #if HAVE_REGEX_H - sfree (new->re); + sfree(new->re); #endif - sfree (new); - return; - } - - if (ptr->next == NULL) - break; - } - - if (ptr == NULL) - list_head_g = new; - else - ptr->next = new; + sfree(new); + return; + } + + if (ptr->next == NULL) + break; + } + + if (ptr == NULL) + list_head_g = new; + else + ptr->next = new; } /* void ps_list_register */ /* try to match name against entry, returns 1 if success */ -static int ps_list_match (const char *name, const char *cmdline, procstat_t *ps) -{ +static int ps_list_match(const char *name, const char *cmdline, + procstat_t *ps) { #if HAVE_REGEX_H - if (ps->re != NULL) - { - int status; - const char *str; - - str = cmdline; - if ((str == NULL) || (str[0] == 0)) - str = name; - - assert (str != NULL); - - status = regexec (ps->re, str, - /* nmatch = */ 0, - /* pmatch = */ NULL, - /* eflags = */ 0); - if (status == 0) - return (1); - } - else + if (ps->re != NULL) { + int status; + const char *str; + + str = cmdline; + if ((str == NULL) || (str[0] == 0)) + str = name; + + assert(str != NULL); + + status = regexec(ps->re, str, + /* nmatch = */ 0, + /* pmatch = */ NULL, + /* eflags = */ 0); + if (status == 0) + return (1); + } else #endif - if (strcmp (ps->name, name) == 0) - return (1); + if (strcmp(ps->name, name) == 0) + return (1); - return (0); + return (0); } /* int ps_list_match */ -static void ps_update_counter (derive_t *group_counter, - derive_t *curr_counter, derive_t new_counter) -{ - unsigned long curr_value; - - if (want_init) - { - *curr_counter = new_counter; - return; - } - - if (new_counter < *curr_counter) - curr_value = new_counter + (ULONG_MAX - *curr_counter); - else - curr_value = new_counter - *curr_counter; - - *curr_counter = new_counter; - *group_counter += curr_value; +static void ps_update_counter(derive_t *group_counter, derive_t *curr_counter, + derive_t new_counter) { + unsigned long curr_value; + + if (want_init) { + *curr_counter = new_counter; + return; + } + + if (new_counter < *curr_counter) + curr_value = new_counter + (ULONG_MAX - *curr_counter); + else + curr_value = new_counter - *curr_counter; + + *curr_counter = new_counter; + *group_counter += curr_value; } /* add process entry to 'instances' of process 'name' (or refresh it) */ -static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t *entry) -{ - procstat_entry_t *pse; +static void ps_list_add(const char *name, const char *cmdline, + procstat_entry_t *entry) { + procstat_entry_t *pse; - if (entry->id == 0) - return; + if (entry->id == 0) + return; - for (procstat_t *ps = list_head_g; ps != NULL; ps = ps->next) - { - if ((ps_list_match (name, cmdline, ps)) == 0) - continue; + for (procstat_t *ps = list_head_g; ps != NULL; ps = ps->next) { + if ((ps_list_match(name, cmdline, ps)) == 0) + continue; #if KERNEL_LINUX - ps_fill_details(ps, entry); + ps_fill_details(ps, entry); #endif - for (pse = ps->instances; pse != NULL; pse = pse->next) - if ((pse->id == entry->id) || (pse->next == NULL)) - break; - - if ((pse == NULL) || (pse->id != entry->id)) - { - procstat_entry_t *new; - - new = calloc (1, sizeof (*new)); - if (new == NULL) - return; - new->id = entry->id; - - if (pse == NULL) - ps->instances = new; - else - pse->next = new; - - pse = new; - } - - pse->age = 0; - pse->num_proc = entry->num_proc; - pse->num_lwp = entry->num_lwp; - pse->vmem_size = entry->vmem_size; - pse->vmem_rss = entry->vmem_rss; - pse->vmem_data = entry->vmem_data; - pse->vmem_code = entry->vmem_code; - pse->stack_size = entry->stack_size; - pse->io_rchar = entry->io_rchar; - pse->io_wchar = entry->io_wchar; - pse->io_syscr = entry->io_syscr; - pse->io_syscw = entry->io_syscw; - pse->cswitch_vol = entry->cswitch_vol; - pse->cswitch_invol = entry->cswitch_invol; - - ps->num_proc += pse->num_proc; - ps->num_lwp += pse->num_lwp; - ps->vmem_size += pse->vmem_size; - ps->vmem_rss += pse->vmem_rss; - ps->vmem_data += pse->vmem_data; - ps->vmem_code += pse->vmem_code; - ps->stack_size += pse->stack_size; - - ps->io_rchar += ((pse->io_rchar == -1)?0:pse->io_rchar); - ps->io_wchar += ((pse->io_wchar == -1)?0:pse->io_wchar); - ps->io_syscr += ((pse->io_syscr == -1)?0:pse->io_syscr); - ps->io_syscw += ((pse->io_syscw == -1)?0:pse->io_syscw); - - ps->cswitch_vol += ((pse->cswitch_vol == -1)?0:pse->cswitch_vol); - ps->cswitch_invol += ((pse->cswitch_invol == -1)?0:pse->cswitch_invol); - - ps_update_counter ( - &ps->vmem_minflt_counter, - &pse->vmem_minflt_counter, - entry->vmem_minflt_counter); - ps_update_counter ( - &ps->vmem_majflt_counter, - &pse->vmem_majflt_counter, - entry->vmem_majflt_counter); - - ps_update_counter ( - &ps->cpu_user_counter, - &pse->cpu_user_counter, - entry->cpu_user_counter); - ps_update_counter ( - &ps->cpu_system_counter, - &pse->cpu_system_counter, - entry->cpu_system_counter); - } + for (pse = ps->instances; pse != NULL; pse = pse->next) + if ((pse->id == entry->id) || (pse->next == NULL)) + break; + + if ((pse == NULL) || (pse->id != entry->id)) { + procstat_entry_t *new; + + new = calloc(1, sizeof(*new)); + if (new == NULL) + return; + new->id = entry->id; + + if (pse == NULL) + ps->instances = new; + else + pse->next = new; + + pse = new; + } + + pse->age = 0; + pse->num_proc = entry->num_proc; + pse->num_lwp = entry->num_lwp; + pse->vmem_size = entry->vmem_size; + pse->vmem_rss = entry->vmem_rss; + pse->vmem_data = entry->vmem_data; + pse->vmem_code = entry->vmem_code; + pse->stack_size = entry->stack_size; + pse->io_rchar = entry->io_rchar; + pse->io_wchar = entry->io_wchar; + pse->io_syscr = entry->io_syscr; + pse->io_syscw = entry->io_syscw; + pse->cswitch_vol = entry->cswitch_vol; + pse->cswitch_invol = entry->cswitch_invol; + + ps->num_proc += pse->num_proc; + ps->num_lwp += pse->num_lwp; + ps->vmem_size += pse->vmem_size; + ps->vmem_rss += pse->vmem_rss; + ps->vmem_data += pse->vmem_data; + ps->vmem_code += pse->vmem_code; + ps->stack_size += pse->stack_size; + + ps->io_rchar += ((pse->io_rchar == -1) ? 0 : pse->io_rchar); + ps->io_wchar += ((pse->io_wchar == -1) ? 0 : pse->io_wchar); + ps->io_syscr += ((pse->io_syscr == -1) ? 0 : pse->io_syscr); + ps->io_syscw += ((pse->io_syscw == -1) ? 0 : pse->io_syscw); + + ps->cswitch_vol += ((pse->cswitch_vol == -1) ? 0 : pse->cswitch_vol); + ps->cswitch_invol += ((pse->cswitch_invol == -1) ? 0 : pse->cswitch_invol); + + ps_update_counter(&ps->vmem_minflt_counter, &pse->vmem_minflt_counter, + entry->vmem_minflt_counter); + ps_update_counter(&ps->vmem_majflt_counter, &pse->vmem_majflt_counter, + entry->vmem_majflt_counter); + + ps_update_counter(&ps->cpu_user_counter, &pse->cpu_user_counter, + entry->cpu_user_counter); + ps_update_counter(&ps->cpu_system_counter, &pse->cpu_system_counter, + entry->cpu_system_counter); + } } /* remove old entries from instances of processes in list_head_g */ -static void ps_list_reset (void) -{ - procstat_entry_t *pse; - procstat_entry_t *pse_prev; - - for (procstat_t *ps = list_head_g; ps != NULL; ps = ps->next) - { - ps->num_proc = 0; - ps->num_lwp = 0; - ps->vmem_size = 0; - ps->vmem_rss = 0; - ps->vmem_data = 0; - ps->vmem_code = 0; - ps->stack_size = 0; - ps->io_rchar = -1; - ps->io_wchar = -1; - ps->io_syscr = -1; - ps->io_syscw = -1; - ps->cswitch_vol = -1; - ps->cswitch_invol = -1; - - pse_prev = NULL; - pse = ps->instances; - while (pse != NULL) - { - if (pse->age > 10) - { - DEBUG ("Removing this procstat entry cause it's too old: " - "id = %lu; name = %s;", - pse->id, ps->name); - - if (pse_prev == NULL) - { - ps->instances = pse->next; - free (pse); - pse = ps->instances; - } - else - { - pse_prev->next = pse->next; - free (pse); - pse = pse_prev->next; - } - } - else - { - pse->age++; - pse_prev = pse; - pse = pse->next; - } - } /* while (pse != NULL) */ - } /* for (ps = list_head_g; ps != NULL; ps = ps->next) */ +static void ps_list_reset(void) { + procstat_entry_t *pse; + procstat_entry_t *pse_prev; + + for (procstat_t *ps = list_head_g; ps != NULL; ps = ps->next) { + ps->num_proc = 0; + ps->num_lwp = 0; + ps->vmem_size = 0; + ps->vmem_rss = 0; + ps->vmem_data = 0; + ps->vmem_code = 0; + ps->stack_size = 0; + ps->io_rchar = -1; + ps->io_wchar = -1; + ps->io_syscr = -1; + ps->io_syscw = -1; + ps->cswitch_vol = -1; + ps->cswitch_invol = -1; + + pse_prev = NULL; + pse = ps->instances; + while (pse != NULL) { + if (pse->age > 10) { + DEBUG("Removing this procstat entry cause it's too old: " + "id = %lu; name = %s;", + pse->id, ps->name); + + if (pse_prev == NULL) { + ps->instances = pse->next; + free(pse); + pse = ps->instances; + } else { + pse_prev->next = pse->next; + free(pse); + pse = pse_prev->next; + } + } else { + pse->age++; + pse_prev = pse; + pse = pse->next; + } + } /* while (pse != NULL) */ + } /* for (ps = list_head_g; ps != NULL; ps = ps->next) */ } /* put all pre-defined 'Process' names from config to list_head_g tree */ -static int ps_config (oconfig_item_t *ci) -{ +static int ps_config(oconfig_item_t *ci) { #if KERNEL_LINUX - const size_t max_procname_len = 15; + const size_t max_procname_len = 15; #elif KERNEL_SOLARIS || KERNEL_FREEBSD - const size_t max_procname_len = MAXCOMLEN -1; + const size_t max_procname_len = MAXCOMLEN - 1; #endif - for (int i = 0; i < ci->children_num; ++i) { - oconfig_item_t *c = ci->children + i; - - if (strcasecmp (c->key, "Process") == 0) - { - if ((c->values_num != 1) - || (OCONFIG_TYPE_STRING != c->values[0].type)) { - ERROR ("processes plugin: `Process' expects exactly " - "one string argument (got %i).", - c->values_num); - continue; - } - - if (c->children_num != 0) { - WARNING ("processes plugin: the `Process' config option " - "does not expect any child elements -- ignoring " - "content (%i elements) of the block.", - c->children_num, c->values[0].value.string); - } + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *c = ci->children + i; + + if (strcasecmp(c->key, "Process") == 0) { + if ((c->values_num != 1) || (OCONFIG_TYPE_STRING != c->values[0].type)) { + ERROR("processes plugin: `Process' expects exactly " + "one string argument (got %i).", + c->values_num); + continue; + } + + if (c->children_num != 0) { + WARNING("processes plugin: the `Process' config option " + "does not expect any child elements -- ignoring " + "content (%i elements) of the block.", + c->children_num, c->values[0].value.string); + } #if KERNEL_LINUX || KERNEL_SOLARIS || KERNEL_FREEBSD - if (strlen (c->values[0].value.string) > max_procname_len) { - WARNING ("processes plugin: this platform has a %zu character limit " - "to process names. The `Process \"%s\"' option will " - "not work as expected.", - max_procname_len, c->values[0].value.string); - } + if (strlen(c->values[0].value.string) > max_procname_len) { + WARNING("processes plugin: this platform has a %zu character limit " + "to process names. The `Process \"%s\"' option will " + "not work as expected.", + max_procname_len, c->values[0].value.string); + } #endif - ps_list_register (c->values[0].value.string, NULL); - } - else if (strcasecmp (c->key, "ProcessMatch") == 0) - { - if ((c->values_num != 2) - || (OCONFIG_TYPE_STRING != c->values[0].type) - || (OCONFIG_TYPE_STRING != c->values[1].type)) - { - ERROR ("processes plugin: `ProcessMatch' needs exactly " - "two string arguments (got %i).", - c->values_num); - continue; - } - - if (c->children_num != 0) { - WARNING ("processes plugin: the `ProcessMatch' config option " - "does not expect any child elements -- ignoring " - "content (%i elements) of the " - "block.", c->children_num, c->values[0].value.string, - c->values[1].value.string); - } - - ps_list_register (c->values[0].value.string, - c->values[1].value.string); - } - else if (strcasecmp (c->key, "CollectContextSwitch") == 0) - { - cf_util_get_boolean (c, &report_ctx_switch); - } - else - { - ERROR ("processes plugin: The `%s' configuration option is not " - "understood and will be ignored.", c->key); - continue; - } - } - - return (0); + ps_list_register(c->values[0].value.string, NULL); + } else if (strcasecmp(c->key, "ProcessMatch") == 0) { + if ((c->values_num != 2) || (OCONFIG_TYPE_STRING != c->values[0].type) || + (OCONFIG_TYPE_STRING != c->values[1].type)) { + ERROR("processes plugin: `ProcessMatch' needs exactly " + "two string arguments (got %i).", + c->values_num); + continue; + } + + if (c->children_num != 0) { + WARNING("processes plugin: the `ProcessMatch' config option " + "does not expect any child elements -- ignoring " + "content (%i elements) of the " + "block.", + c->children_num, c->values[0].value.string, + c->values[1].value.string); + } + + ps_list_register(c->values[0].value.string, c->values[1].value.string); + } else if (strcasecmp(c->key, "CollectContextSwitch") == 0) { + cf_util_get_boolean(c, &report_ctx_switch); + } else { + ERROR("processes plugin: The `%s' configuration option is not " + "understood and will be ignored.", + c->key); + continue; + } + } + + return (0); } -static int ps_init (void) -{ +static int ps_init(void) { #if HAVE_THREAD_INFO - kern_return_t status; - - port_host_self = mach_host_self (); - port_task_self = mach_task_self (); - - if (pset_list != NULL) - { - vm_deallocate (port_task_self, - (vm_address_t) pset_list, - pset_list_len * sizeof (processor_set_t)); - pset_list = NULL; - pset_list_len = 0; - } - - if ((status = host_processor_sets (port_host_self, - &pset_list, - &pset_list_len)) != KERN_SUCCESS) - { - ERROR ("host_processor_sets failed: %s\n", - mach_error_string (status)); - pset_list = NULL; - pset_list_len = 0; - return (-1); - } + kern_return_t status; + + port_host_self = mach_host_self(); + port_task_self = mach_task_self(); + + if (pset_list != NULL) { + vm_deallocate(port_task_self, (vm_address_t)pset_list, + pset_list_len * sizeof(processor_set_t)); + pset_list = NULL; + pset_list_len = 0; + } + + if ((status = host_processor_sets(port_host_self, &pset_list, + &pset_list_len)) != KERN_SUCCESS) { + ERROR("host_processor_sets failed: %s\n", mach_error_string(status)); + pset_list = NULL; + pset_list_len = 0; + return (-1); + } /* #endif HAVE_THREAD_INFO */ #elif KERNEL_LINUX - pagesize_g = sysconf(_SC_PAGESIZE); - DEBUG ("pagesize_g = %li; CONFIG_HZ = %i;", - pagesize_g, CONFIG_HZ); + pagesize_g = sysconf(_SC_PAGESIZE); + DEBUG("pagesize_g = %li; CONFIG_HZ = %i;", pagesize_g, CONFIG_HZ); /* #endif KERNEL_LINUX */ -#elif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD) - pagesize = getpagesize(); -/* #endif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD) */ +#elif HAVE_LIBKVM_GETPROCS && \ + (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD) + pagesize = getpagesize(); +/* #endif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || + * HAVE_STRUCT_KINFO_PROC_OPENBSD) */ #elif HAVE_PROCINFO_H - pagesize = getpagesize(); + pagesize = getpagesize(); #endif /* HAVE_PROCINFO_H */ - return (0); + return (0); } /* int ps_init */ /* submit global state (e.g.: qty of zombies, running, etc..) */ -static void ps_submit_state (const char *state, double value) -{ - value_list_t vl = VALUE_LIST_INIT; - - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "processes", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, "", sizeof (vl.plugin_instance)); - sstrncpy (vl.type, "ps_state", sizeof (vl.type)); - sstrncpy (vl.type_instance, state, sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); +static void ps_submit_state(const char *state, double value) { + value_list_t vl = VALUE_LIST_INIT; + + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "processes", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, "", sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "ps_state", sizeof(vl.type)); + sstrncpy(vl.type_instance, state, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); } /* submit info about specific process (e.g.: memory taken, cpu usage, etc..) */ -static void ps_submit_proc_list (procstat_t *ps) -{ - value_list_t vl = VALUE_LIST_INIT; - value_t values[2]; - - vl.values = values; - sstrncpy (vl.plugin, "processes", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, ps->name, sizeof (vl.plugin_instance)); - - sstrncpy (vl.type, "ps_vm", sizeof (vl.type)); - vl.values[0].gauge = ps->vmem_size; - vl.values_len = 1; - plugin_dispatch_values (&vl); - - sstrncpy (vl.type, "ps_rss", sizeof (vl.type)); - vl.values[0].gauge = ps->vmem_rss; - vl.values_len = 1; - plugin_dispatch_values (&vl); - - sstrncpy (vl.type, "ps_data", sizeof (vl.type)); - vl.values[0].gauge = ps->vmem_data; - vl.values_len = 1; - plugin_dispatch_values (&vl); - - sstrncpy (vl.type, "ps_code", sizeof (vl.type)); - vl.values[0].gauge = ps->vmem_code; - vl.values_len = 1; - plugin_dispatch_values (&vl); - - sstrncpy (vl.type, "ps_stacksize", sizeof (vl.type)); - vl.values[0].gauge = ps->stack_size; - vl.values_len = 1; - plugin_dispatch_values (&vl); - - sstrncpy (vl.type, "ps_cputime", sizeof (vl.type)); - vl.values[0].derive = ps->cpu_user_counter; - vl.values[1].derive = ps->cpu_system_counter; - vl.values_len = 2; - plugin_dispatch_values (&vl); - - sstrncpy (vl.type, "ps_count", sizeof (vl.type)); - vl.values[0].gauge = ps->num_proc; - vl.values[1].gauge = ps->num_lwp; - vl.values_len = 2; - plugin_dispatch_values (&vl); - - sstrncpy (vl.type, "ps_pagefaults", sizeof (vl.type)); - vl.values[0].derive = ps->vmem_minflt_counter; - vl.values[1].derive = ps->vmem_majflt_counter; - vl.values_len = 2; - plugin_dispatch_values (&vl); - - if ( (ps->io_rchar != -1) && (ps->io_wchar != -1) ) - { - sstrncpy (vl.type, "ps_disk_octets", sizeof (vl.type)); - vl.values[0].derive = ps->io_rchar; - vl.values[1].derive = ps->io_wchar; - vl.values_len = 2; - plugin_dispatch_values (&vl); - } - - if ( (ps->io_syscr != -1) && (ps->io_syscw != -1) ) - { - sstrncpy (vl.type, "ps_disk_ops", sizeof (vl.type)); - vl.values[0].derive = ps->io_syscr; - vl.values[1].derive = ps->io_syscw; - vl.values_len = 2; - plugin_dispatch_values (&vl); - } - - if ( report_ctx_switch ) - { - sstrncpy (vl.type, "contextswitch", sizeof (vl.type)); - sstrncpy (vl.type_instance, "voluntary", sizeof (vl.type_instance)); - vl.values[0].derive = ps->cswitch_vol; - vl.values_len = 1; - plugin_dispatch_values (&vl); - - sstrncpy (vl.type, "contextswitch", sizeof (vl.type)); - sstrncpy (vl.type_instance, "involuntary", sizeof (vl.type_instance)); - vl.values[0].derive = ps->cswitch_invol; - vl.values_len = 1; - plugin_dispatch_values (&vl); - } - - DEBUG ("name = %s; num_proc = %lu; num_lwp = %lu; " - "vmem_size = %lu; vmem_rss = %lu; vmem_data = %lu; " - "vmem_code = %lu; " - "vmem_minflt_counter = %"PRIi64"; vmem_majflt_counter = %"PRIi64"; " - "cpu_user_counter = %"PRIi64"; cpu_system_counter = %"PRIi64"; " - "io_rchar = %"PRIi64"; io_wchar = %"PRIi64"; " - "io_syscr = %"PRIi64"; io_syscw = %"PRIi64"; " - "cswitch_vol = %"PRIi64"; cswitch_invol = %"PRIi64";", - ps->name, ps->num_proc, ps->num_lwp, - ps->vmem_size, ps->vmem_rss, - ps->vmem_data, ps->vmem_code, - ps->vmem_minflt_counter, ps->vmem_majflt_counter, - ps->cpu_user_counter, ps->cpu_system_counter, - ps->io_rchar, ps->io_wchar, ps->io_syscr, ps->io_syscw, - ps->cswitch_vol, ps->cswitch_invol); +static void ps_submit_proc_list(procstat_t *ps) { + value_list_t vl = VALUE_LIST_INIT; + value_t values[2]; + + vl.values = values; + sstrncpy(vl.plugin, "processes", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, ps->name, sizeof(vl.plugin_instance)); + + sstrncpy(vl.type, "ps_vm", sizeof(vl.type)); + vl.values[0].gauge = ps->vmem_size; + vl.values_len = 1; + plugin_dispatch_values(&vl); + + sstrncpy(vl.type, "ps_rss", sizeof(vl.type)); + vl.values[0].gauge = ps->vmem_rss; + vl.values_len = 1; + plugin_dispatch_values(&vl); + + sstrncpy(vl.type, "ps_data", sizeof(vl.type)); + vl.values[0].gauge = ps->vmem_data; + vl.values_len = 1; + plugin_dispatch_values(&vl); + + sstrncpy(vl.type, "ps_code", sizeof(vl.type)); + vl.values[0].gauge = ps->vmem_code; + vl.values_len = 1; + plugin_dispatch_values(&vl); + + sstrncpy(vl.type, "ps_stacksize", sizeof(vl.type)); + vl.values[0].gauge = ps->stack_size; + vl.values_len = 1; + plugin_dispatch_values(&vl); + + sstrncpy(vl.type, "ps_cputime", sizeof(vl.type)); + vl.values[0].derive = ps->cpu_user_counter; + vl.values[1].derive = ps->cpu_system_counter; + vl.values_len = 2; + plugin_dispatch_values(&vl); + + sstrncpy(vl.type, "ps_count", sizeof(vl.type)); + vl.values[0].gauge = ps->num_proc; + vl.values[1].gauge = ps->num_lwp; + vl.values_len = 2; + plugin_dispatch_values(&vl); + + sstrncpy(vl.type, "ps_pagefaults", sizeof(vl.type)); + vl.values[0].derive = ps->vmem_minflt_counter; + vl.values[1].derive = ps->vmem_majflt_counter; + vl.values_len = 2; + plugin_dispatch_values(&vl); + + if ((ps->io_rchar != -1) && (ps->io_wchar != -1)) { + sstrncpy(vl.type, "ps_disk_octets", sizeof(vl.type)); + vl.values[0].derive = ps->io_rchar; + vl.values[1].derive = ps->io_wchar; + vl.values_len = 2; + plugin_dispatch_values(&vl); + } + + if ((ps->io_syscr != -1) && (ps->io_syscw != -1)) { + sstrncpy(vl.type, "ps_disk_ops", sizeof(vl.type)); + vl.values[0].derive = ps->io_syscr; + vl.values[1].derive = ps->io_syscw; + vl.values_len = 2; + plugin_dispatch_values(&vl); + } + + if (report_ctx_switch) { + sstrncpy(vl.type, "contextswitch", sizeof(vl.type)); + sstrncpy(vl.type_instance, "voluntary", sizeof(vl.type_instance)); + vl.values[0].derive = ps->cswitch_vol; + vl.values_len = 1; + plugin_dispatch_values(&vl); + + sstrncpy(vl.type, "contextswitch", sizeof(vl.type)); + sstrncpy(vl.type_instance, "involuntary", sizeof(vl.type_instance)); + vl.values[0].derive = ps->cswitch_invol; + vl.values_len = 1; + plugin_dispatch_values(&vl); + } + + DEBUG("name = %s; num_proc = %lu; num_lwp = %lu; " + "vmem_size = %lu; vmem_rss = %lu; vmem_data = %lu; " + "vmem_code = %lu; " + "vmem_minflt_counter = %" PRIi64 "; vmem_majflt_counter = %" PRIi64 "; " + "cpu_user_counter = %" PRIi64 "; cpu_system_counter = %" PRIi64 "; " + "io_rchar = %" PRIi64 "; io_wchar = %" PRIi64 "; " + "io_syscr = %" PRIi64 "; io_syscw = %" PRIi64 "; " + "cswitch_vol = %" PRIi64 "; cswitch_invol = %" PRIi64 ";", + ps->name, ps->num_proc, ps->num_lwp, ps->vmem_size, ps->vmem_rss, + ps->vmem_data, ps->vmem_code, ps->vmem_minflt_counter, + ps->vmem_majflt_counter, ps->cpu_user_counter, ps->cpu_system_counter, + ps->io_rchar, ps->io_wchar, ps->io_syscr, ps->io_syscw, ps->cswitch_vol, + ps->cswitch_invol); } /* void ps_submit_proc_list */ #if KERNEL_LINUX || KERNEL_SOLARIS -static void ps_submit_fork_rate (derive_t value) -{ - value_list_t vl = VALUE_LIST_INIT; - - vl.values = &(value_t) { .derive = value }; - vl.values_len = 1; - sstrncpy(vl.plugin, "processes", sizeof (vl.plugin)); - sstrncpy(vl.plugin_instance, "", sizeof (vl.plugin_instance)); - sstrncpy(vl.type, "fork_rate", sizeof (vl.type)); - sstrncpy(vl.type_instance, "", sizeof (vl.type_instance)); - - plugin_dispatch_values(&vl); +static void ps_submit_fork_rate(derive_t value) { + value_list_t vl = VALUE_LIST_INIT; + + vl.values = &(value_t){.derive = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "processes", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, "", sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "fork_rate", sizeof(vl.type)); + sstrncpy(vl.type_instance, "", sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); } #endif /* KERNEL_LINUX || KERNEL_SOLARIS*/ /* ------- additional functions for KERNEL_LINUX/HAVE_THREAD_INFO ------- */ #if KERNEL_LINUX -static int ps_read_tasks_status (procstat_entry_t *ps) -{ - char dirname[64]; - DIR *dh; - char filename[64]; - FILE *fh; - struct dirent *ent; - derive_t cswitch_vol = 0; - derive_t cswitch_invol = 0; - char buffer[1024]; - char *fields[8]; - int numfields; - - ssnprintf (dirname, sizeof (dirname), "/proc/%li/task", ps->id); - - if ((dh = opendir (dirname)) == NULL) - { - DEBUG ("Failed to open directory `%s'", dirname); - return (-1); - } - - while ((ent = readdir (dh)) != NULL) - { - char *tpid; - - if (!isdigit ((int) ent->d_name[0])) - continue; - - tpid = ent->d_name; - - ssnprintf (filename, sizeof (filename), "/proc/%li/task/%s/status", ps->id, tpid); - if ((fh = fopen (filename, "r")) == NULL) - { - DEBUG ("Failed to open file `%s'", filename); - continue; - } - - while (fgets (buffer, sizeof(buffer), fh) != NULL) - { - derive_t tmp; - char *endptr; - - if (strncmp (buffer, "voluntary_ctxt_switches", 23) != 0 - && strncmp (buffer, "nonvoluntary_ctxt_switches", 26) != 0) - continue; - - numfields = strsplit (buffer, fields, - STATIC_ARRAY_SIZE (fields)); - - if (numfields < 2) - continue; - - errno = 0; - endptr = NULL; - tmp = (derive_t) strtoll (fields[1], &endptr, /* base = */ 10); - if ((errno == 0) && (endptr != fields[1])) - { - if (strncmp (buffer, "voluntary_ctxt_switches", 23) == 0) - { - cswitch_vol += tmp; - } - else if (strncmp (buffer, "nonvoluntary_ctxt_switches", 26) == 0) - { - cswitch_invol += tmp; - } - } - } /* while (fgets) */ - - if (fclose (fh)) - { - char errbuf[1024]; - WARNING ("processes: fclose: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - } - } - closedir (dh); - - ps->cswitch_vol = cswitch_vol; - ps->cswitch_invol = cswitch_invol; - - return (0); +static int ps_read_tasks_status(procstat_entry_t *ps) { + char dirname[64]; + DIR *dh; + char filename[64]; + FILE *fh; + struct dirent *ent; + derive_t cswitch_vol = 0; + derive_t cswitch_invol = 0; + char buffer[1024]; + char *fields[8]; + int numfields; + + ssnprintf(dirname, sizeof(dirname), "/proc/%li/task", ps->id); + + if ((dh = opendir(dirname)) == NULL) { + DEBUG("Failed to open directory `%s'", dirname); + return (-1); + } + + while ((ent = readdir(dh)) != NULL) { + char *tpid; + + if (!isdigit((int)ent->d_name[0])) + continue; + + tpid = ent->d_name; + + ssnprintf(filename, sizeof(filename), "/proc/%li/task/%s/status", ps->id, + tpid); + if ((fh = fopen(filename, "r")) == NULL) { + DEBUG("Failed to open file `%s'", filename); + continue; + } + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + derive_t tmp; + char *endptr; + + if (strncmp(buffer, "voluntary_ctxt_switches", 23) != 0 && + strncmp(buffer, "nonvoluntary_ctxt_switches", 26) != 0) + continue; + + numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + + if (numfields < 2) + continue; + + errno = 0; + endptr = NULL; + tmp = (derive_t)strtoll(fields[1], &endptr, /* base = */ 10); + if ((errno == 0) && (endptr != fields[1])) { + if (strncmp(buffer, "voluntary_ctxt_switches", 23) == 0) { + cswitch_vol += tmp; + } else if (strncmp(buffer, "nonvoluntary_ctxt_switches", 26) == 0) { + cswitch_invol += tmp; + } + } + } /* while (fgets) */ + + if (fclose(fh)) { + char errbuf[1024]; + WARNING("processes: fclose: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + } + } + closedir(dh); + + ps->cswitch_vol = cswitch_vol; + ps->cswitch_invol = cswitch_invol; + + return (0); } /* int *ps_read_tasks_status */ /* Read data from /proc/pid/status */ -static procstat_t *ps_read_status (long pid, procstat_t *ps) -{ - FILE *fh; - char buffer[1024]; - char filename[64]; - unsigned long lib = 0; - unsigned long exe = 0; - unsigned long data = 0; - unsigned long threads = 0; - char *fields[8]; - int numfields; - - ssnprintf (filename, sizeof (filename), "/proc/%li/status", pid); - if ((fh = fopen (filename, "r")) == NULL) - return (NULL); - - while (fgets (buffer, sizeof(buffer), fh) != NULL) - { - unsigned long tmp; - char *endptr; - - if (strncmp (buffer, "Vm", 2) != 0 - && strncmp (buffer, "Threads", 7) != 0) - continue; - - numfields = strsplit (buffer, fields, - STATIC_ARRAY_SIZE (fields)); - - if (numfields < 2) - continue; - - errno = 0; - endptr = NULL; - tmp = strtoul (fields[1], &endptr, /* base = */ 10); - if ((errno == 0) && (endptr != fields[1])) - { - if (strncmp (buffer, "VmData", 6) == 0) - { - data = tmp; - } - else if (strncmp (buffer, "VmLib", 5) == 0) - { - lib = tmp; - } - else if (strncmp(buffer, "VmExe", 5) == 0) - { - exe = tmp; - } - else if (strncmp(buffer, "Threads", 7) == 0) - { - threads = tmp; - } - } - } /* while (fgets) */ - - if (fclose (fh)) - { - char errbuf[1024]; - WARNING ("processes: fclose: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - } - - ps->vmem_data = data * 1024; - ps->vmem_code = (exe + lib) * 1024; - if (threads != 0) - ps->num_lwp = threads; - - return (ps); +static procstat_t *ps_read_status(long pid, procstat_t *ps) { + FILE *fh; + char buffer[1024]; + char filename[64]; + unsigned long lib = 0; + unsigned long exe = 0; + unsigned long data = 0; + unsigned long threads = 0; + char *fields[8]; + int numfields; + + ssnprintf(filename, sizeof(filename), "/proc/%li/status", pid); + if ((fh = fopen(filename, "r")) == NULL) + return (NULL); + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + unsigned long tmp; + char *endptr; + + if (strncmp(buffer, "Vm", 2) != 0 && strncmp(buffer, "Threads", 7) != 0) + continue; + + numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + + if (numfields < 2) + continue; + + errno = 0; + endptr = NULL; + tmp = strtoul(fields[1], &endptr, /* base = */ 10); + if ((errno == 0) && (endptr != fields[1])) { + if (strncmp(buffer, "VmData", 6) == 0) { + data = tmp; + } else if (strncmp(buffer, "VmLib", 5) == 0) { + lib = tmp; + } else if (strncmp(buffer, "VmExe", 5) == 0) { + exe = tmp; + } else if (strncmp(buffer, "Threads", 7) == 0) { + threads = tmp; + } + } + } /* while (fgets) */ + + if (fclose(fh)) { + char errbuf[1024]; + WARNING("processes: fclose: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + } + + ps->vmem_data = data * 1024; + ps->vmem_code = (exe + lib) * 1024; + if (threads != 0) + ps->num_lwp = threads; + + return (ps); } /* procstat_t *ps_read_vmem */ -static int ps_read_io (procstat_entry_t *ps) -{ - FILE *fh; - char buffer[1024]; - char filename[64]; - - char *fields[8]; - int numfields; - - ssnprintf (filename, sizeof (filename), "/proc/%li/io", ps->id); - if ((fh = fopen (filename, "r")) == NULL) - return (-1); - - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - derive_t *val = NULL; - long long tmp; - char *endptr; - - if (strncasecmp (buffer, "rchar:", 6) == 0) - val = &(ps->io_rchar); - else if (strncasecmp (buffer, "wchar:", 6) == 0) - val = &(ps->io_wchar); - else if (strncasecmp (buffer, "syscr:", 6) == 0) - val = &(ps->io_syscr); - else if (strncasecmp (buffer, "syscw:", 6) == 0) - val = &(ps->io_syscw); - else - continue; - - numfields = strsplit (buffer, fields, - STATIC_ARRAY_SIZE (fields)); - - if (numfields < 2) - continue; - - errno = 0; - endptr = NULL; - tmp = strtoll (fields[1], &endptr, /* base = */ 10); - if ((errno != 0) || (endptr == fields[1])) - *val = -1; - else - *val = (derive_t) tmp; - } /* while (fgets) */ - - if (fclose (fh)) - { - char errbuf[1024]; - WARNING ("processes: fclose: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - } - return (0); +static int ps_read_io(procstat_entry_t *ps) { + FILE *fh; + char buffer[1024]; + char filename[64]; + + char *fields[8]; + int numfields; + + ssnprintf(filename, sizeof(filename), "/proc/%li/io", ps->id); + if ((fh = fopen(filename, "r")) == NULL) + return (-1); + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + derive_t *val = NULL; + long long tmp; + char *endptr; + + if (strncasecmp(buffer, "rchar:", 6) == 0) + val = &(ps->io_rchar); + else if (strncasecmp(buffer, "wchar:", 6) == 0) + val = &(ps->io_wchar); + else if (strncasecmp(buffer, "syscr:", 6) == 0) + val = &(ps->io_syscr); + else if (strncasecmp(buffer, "syscw:", 6) == 0) + val = &(ps->io_syscw); + else + continue; + + numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + + if (numfields < 2) + continue; + + errno = 0; + endptr = NULL; + tmp = strtoll(fields[1], &endptr, /* base = */ 10); + if ((errno != 0) || (endptr == fields[1])) + *val = -1; + else + *val = (derive_t)tmp; + } /* while (fgets) */ + + if (fclose(fh)) { + char errbuf[1024]; + WARNING("processes: fclose: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + } + return (0); } /* int ps_read_io (...) */ -static void ps_fill_details (const procstat_t *ps, procstat_entry_t *entry) -{ - if ( entry->has_io == 0 && ps_read_io (entry) != 0 ) - { - /* no io data */ - entry->io_rchar = -1; - entry->io_wchar = -1; - entry->io_syscr = -1; - entry->io_syscw = -1; - - DEBUG("ps_read_process: not get io data for pid %li", entry->id); - } - entry->has_io = 1; - - if ( report_ctx_switch ) - { - if ( entry->has_cswitch == 0 && ps_read_tasks_status(entry) != 0 ) - { - entry->cswitch_vol = -1; - entry->cswitch_invol = -1; - - DEBUG("ps_read_tasks_status: not get context " - "switch data for pid %li", entry->id); - } - entry->has_cswitch = 1; - } +static void ps_fill_details(const procstat_t *ps, procstat_entry_t *entry) { + if (entry->has_io == 0 && ps_read_io(entry) != 0) { + /* no io data */ + entry->io_rchar = -1; + entry->io_wchar = -1; + entry->io_syscr = -1; + entry->io_syscw = -1; + + DEBUG("ps_read_process: not get io data for pid %li", entry->id); + } + entry->has_io = 1; + + if (report_ctx_switch) { + if (entry->has_cswitch == 0 && ps_read_tasks_status(entry) != 0) { + entry->cswitch_vol = -1; + entry->cswitch_invol = -1; + + DEBUG("ps_read_tasks_status: not get context " + "switch data for pid %li", + entry->id); + } + entry->has_cswitch = 1; + } } /* void ps_fill_details (...) */ -static int ps_read_process (long pid, procstat_t *ps, char *state) -{ - char filename[64]; - char buffer[1024]; - - char *fields[64]; - char fields_len; - - size_t buffer_len; - - char *buffer_ptr; - size_t name_start_pos; - size_t name_end_pos; - size_t name_len; - - derive_t cpu_user_counter; - derive_t cpu_system_counter; - long long unsigned vmem_size; - long long unsigned vmem_rss; - long long unsigned stack_size; - - ssize_t status; - - memset (ps, 0, sizeof (procstat_t)); - - ssnprintf (filename, sizeof (filename), "/proc/%li/stat", pid); - - status = read_file_contents (filename, buffer, sizeof(buffer) - 1); - if (status <= 0) - return (-1); - buffer_len = (size_t) status; - buffer[buffer_len] = 0; - - /* The name of the process is enclosed in parens. Since the name can - * contain parens itself, spaces, numbers and pretty much everything - * else, use these to determine the process name. We don't use - * strchr(3) and strrchr(3) to avoid pointer arithmetic which would - * otherwise be required to determine name_len. */ - name_start_pos = 0; - while (name_start_pos < buffer_len && buffer[name_start_pos] != '(') - name_start_pos++; - - name_end_pos = buffer_len; - while (name_end_pos > 0 && buffer[name_end_pos] != ')') - name_end_pos--; - - /* Either '(' or ')' is not found or they are in the wrong order. - * Anyway, something weird that shouldn't happen ever. */ - if (name_start_pos >= name_end_pos) - { - ERROR ("processes plugin: name_start_pos = %zu >= name_end_pos = %zu", - name_start_pos, name_end_pos); - return (-1); - } - - name_len = (name_end_pos - name_start_pos) - 1; - if (name_len >= sizeof (ps->name)) - name_len = sizeof (ps->name) - 1; - - sstrncpy (ps->name, &buffer[name_start_pos + 1], name_len + 1); - - if ((buffer_len - name_end_pos) < 2) - return (-1); - buffer_ptr = &buffer[name_end_pos + 2]; - - fields_len = strsplit (buffer_ptr, fields, STATIC_ARRAY_SIZE (fields)); - if (fields_len < 22) - { - DEBUG ("processes plugin: ps_read_process (pid = %li):" - " `%s' has only %i fields..", - pid, filename, fields_len); - return (-1); - } - - *state = fields[0][0]; - - if (*state == 'Z') - { - ps->num_lwp = 0; - ps->num_proc = 0; - } - else - { - ps->num_lwp = strtoul (fields[17], /* endptr = */ NULL, /* base = */ 10); - if ((ps_read_status(pid, ps)) == NULL) - { - /* No VMem data */ - ps->vmem_data = -1; - ps->vmem_code = -1; - DEBUG("ps_read_process: did not get vmem data for pid %li", pid); - } - if (ps->num_lwp == 0) - ps->num_lwp = 1; - ps->num_proc = 1; - } - - /* Leave the rest at zero if this is only a zombi */ - if (ps->num_proc == 0) - { - DEBUG ("processes plugin: This is only a zombie: pid = %li; " - "name = %s;", pid, ps->name); - return (0); - } - - cpu_user_counter = atoll (fields[11]); - cpu_system_counter = atoll (fields[12]); - vmem_size = atoll (fields[20]); - vmem_rss = atoll (fields[21]); - ps->vmem_minflt_counter = atol (fields[7]); - ps->vmem_majflt_counter = atol (fields[9]); - - { - unsigned long long stack_start = atoll (fields[25]); - unsigned long long stack_ptr = atoll (fields[26]); - - stack_size = (stack_start > stack_ptr) - ? stack_start - stack_ptr - : stack_ptr - stack_start; - } - - /* Convert jiffies to useconds */ - cpu_user_counter = cpu_user_counter * 1000000 / CONFIG_HZ; - cpu_system_counter = cpu_system_counter * 1000000 / CONFIG_HZ; - vmem_rss = vmem_rss * pagesize_g; - - ps->cpu_user_counter = cpu_user_counter; - ps->cpu_system_counter = cpu_system_counter; - ps->vmem_size = (unsigned long) vmem_size; - ps->vmem_rss = (unsigned long) vmem_rss; - ps->stack_size = (unsigned long) stack_size; - - /* success */ - return (0); +static int ps_read_process(long pid, procstat_t *ps, char *state) { + char filename[64]; + char buffer[1024]; + + char *fields[64]; + char fields_len; + + size_t buffer_len; + + char *buffer_ptr; + size_t name_start_pos; + size_t name_end_pos; + size_t name_len; + + derive_t cpu_user_counter; + derive_t cpu_system_counter; + long long unsigned vmem_size; + long long unsigned vmem_rss; + long long unsigned stack_size; + + ssize_t status; + + memset(ps, 0, sizeof(procstat_t)); + + ssnprintf(filename, sizeof(filename), "/proc/%li/stat", pid); + + status = read_file_contents(filename, buffer, sizeof(buffer) - 1); + if (status <= 0) + return (-1); + buffer_len = (size_t)status; + buffer[buffer_len] = 0; + + /* The name of the process is enclosed in parens. Since the name can + * contain parens itself, spaces, numbers and pretty much everything + * else, use these to determine the process name. We don't use + * strchr(3) and strrchr(3) to avoid pointer arithmetic which would + * otherwise be required to determine name_len. */ + name_start_pos = 0; + while (name_start_pos < buffer_len && buffer[name_start_pos] != '(') + name_start_pos++; + + name_end_pos = buffer_len; + while (name_end_pos > 0 && buffer[name_end_pos] != ')') + name_end_pos--; + + /* Either '(' or ')' is not found or they are in the wrong order. + * Anyway, something weird that shouldn't happen ever. */ + if (name_start_pos >= name_end_pos) { + ERROR("processes plugin: name_start_pos = %zu >= name_end_pos = %zu", + name_start_pos, name_end_pos); + return (-1); + } + + name_len = (name_end_pos - name_start_pos) - 1; + if (name_len >= sizeof(ps->name)) + name_len = sizeof(ps->name) - 1; + + sstrncpy(ps->name, &buffer[name_start_pos + 1], name_len + 1); + + if ((buffer_len - name_end_pos) < 2) + return (-1); + buffer_ptr = &buffer[name_end_pos + 2]; + + fields_len = strsplit(buffer_ptr, fields, STATIC_ARRAY_SIZE(fields)); + if (fields_len < 22) { + DEBUG("processes plugin: ps_read_process (pid = %li):" + " `%s' has only %i fields..", + pid, filename, fields_len); + return (-1); + } + + *state = fields[0][0]; + + if (*state == 'Z') { + ps->num_lwp = 0; + ps->num_proc = 0; + } else { + ps->num_lwp = strtoul(fields[17], /* endptr = */ NULL, /* base = */ 10); + if ((ps_read_status(pid, ps)) == NULL) { + /* No VMem data */ + ps->vmem_data = -1; + ps->vmem_code = -1; + DEBUG("ps_read_process: did not get vmem data for pid %li", pid); + } + if (ps->num_lwp == 0) + ps->num_lwp = 1; + ps->num_proc = 1; + } + + /* Leave the rest at zero if this is only a zombi */ + if (ps->num_proc == 0) { + DEBUG("processes plugin: This is only a zombie: pid = %li; " + "name = %s;", + pid, ps->name); + return (0); + } + + cpu_user_counter = atoll(fields[11]); + cpu_system_counter = atoll(fields[12]); + vmem_size = atoll(fields[20]); + vmem_rss = atoll(fields[21]); + ps->vmem_minflt_counter = atol(fields[7]); + ps->vmem_majflt_counter = atol(fields[9]); + + { + unsigned long long stack_start = atoll(fields[25]); + unsigned long long stack_ptr = atoll(fields[26]); + + stack_size = (stack_start > stack_ptr) ? stack_start - stack_ptr + : stack_ptr - stack_start; + } + + /* Convert jiffies to useconds */ + cpu_user_counter = cpu_user_counter * 1000000 / CONFIG_HZ; + cpu_system_counter = cpu_system_counter * 1000000 / CONFIG_HZ; + vmem_rss = vmem_rss * pagesize_g; + + ps->cpu_user_counter = cpu_user_counter; + ps->cpu_system_counter = cpu_system_counter; + ps->vmem_size = (unsigned long)vmem_size; + ps->vmem_rss = (unsigned long)vmem_rss; + ps->stack_size = (unsigned long)stack_size; + + /* success */ + return (0); } /* int ps_read_process (...) */ -static char *ps_get_cmdline (long pid, char *name, char *buf, size_t buf_len) -{ - char *buf_ptr; - size_t len; +static char *ps_get_cmdline(long pid, char *name, char *buf, size_t buf_len) { + char *buf_ptr; + size_t len; - char file[PATH_MAX]; - int fd; + char file[PATH_MAX]; + int fd; - size_t n; + size_t n; - if ((pid < 1) || (NULL == buf) || (buf_len < 2)) - return NULL; + if ((pid < 1) || (NULL == buf) || (buf_len < 2)) + return NULL; - ssnprintf (file, sizeof (file), "/proc/%li/cmdline", pid); + ssnprintf(file, sizeof(file), "/proc/%li/cmdline", pid); - errno = 0; - fd = open (file, O_RDONLY); - if (fd < 0) { - char errbuf[4096]; - /* ENOENT means the process exited while we were handling it. - * Don't complain about this, it only fills the logs. */ - if (errno != ENOENT) - WARNING ("processes plugin: Failed to open `%s': %s.", file, - sstrerror (errno, errbuf, sizeof (errbuf))); - return NULL; - } + errno = 0; + fd = open(file, O_RDONLY); + if (fd < 0) { + char errbuf[4096]; + /* ENOENT means the process exited while we were handling it. + * Don't complain about this, it only fills the logs. */ + if (errno != ENOENT) + WARNING("processes plugin: Failed to open `%s': %s.", file, + sstrerror(errno, errbuf, sizeof(errbuf))); + return NULL; + } - buf_ptr = buf; - len = buf_len; + buf_ptr = buf; + len = buf_len; - n = 0; + n = 0; - while (42) { - ssize_t status; + while (42) { + ssize_t status; - status = read (fd, (void *)buf_ptr, len); + status = read(fd, (void *)buf_ptr, len); - if (status < 0) { - char errbuf[1024]; + if (status < 0) { + char errbuf[1024]; - if ((EAGAIN == errno) || (EINTR == errno)) - continue; + if ((EAGAIN == errno) || (EINTR == errno)) + continue; - WARNING ("processes plugin: Failed to read from `%s': %s.", file, - sstrerror (errno, errbuf, sizeof (errbuf))); - close (fd); - return NULL; - } + WARNING("processes plugin: Failed to read from `%s': %s.", file, + sstrerror(errno, errbuf, sizeof(errbuf))); + close(fd); + return NULL; + } - n += status; + n += status; - if (status == 0) - break; + if (status == 0) + break; - buf_ptr += status; - len -= status; + buf_ptr += status; + len -= status; - if (len == 0) - break; - } + if (len == 0) + break; + } - close (fd); + close(fd); - if (0 == n) { - /* cmdline not available; e.g. kernel thread, zombie */ - if (NULL == name) - return NULL; + if (0 == n) { + /* cmdline not available; e.g. kernel thread, zombie */ + if (NULL == name) + return NULL; - ssnprintf (buf, buf_len, "[%s]", name); - return buf; - } + ssnprintf(buf, buf_len, "[%s]", name); + return buf; + } - assert (n <= buf_len); + assert(n <= buf_len); - if (n == buf_len) - --n; - buf[n] = '\0'; + if (n == buf_len) + --n; + buf[n] = '\0'; - --n; - /* remove trailing whitespace */ - while ((n > 0) && (isspace (buf[n]) || ('\0' == buf[n]))) { - buf[n] = '\0'; - --n; - } + --n; + /* remove trailing whitespace */ + while ((n > 0) && (isspace(buf[n]) || ('\0' == buf[n]))) { + buf[n] = '\0'; + --n; + } - /* arguments are separated by '\0' in /proc//cmdline */ - while (n > 0) { - if ('\0' == buf[n]) - buf[n] = ' '; - --n; - } - return buf; + /* arguments are separated by '\0' in /proc//cmdline */ + while (n > 0) { + if ('\0' == buf[n]) + buf[n] = ' '; + --n; + } + return buf; } /* char *ps_get_cmdline (...) */ -static int read_fork_rate (void) -{ - FILE *proc_stat; - char buffer[1024]; - value_t value; - _Bool value_valid = 0; - - proc_stat = fopen ("/proc/stat", "r"); - if (proc_stat == NULL) - { - char errbuf[1024]; - ERROR ("processes plugin: fopen (/proc/stat) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - while (fgets (buffer, sizeof (buffer), proc_stat) != NULL) - { - int status; - char *fields[3]; - int fields_num; - - fields_num = strsplit (buffer, fields, - STATIC_ARRAY_SIZE (fields)); - if (fields_num != 2) - continue; - - if (strcmp ("processes", fields[0]) != 0) - continue; - - status = parse_value (fields[1], &value, DS_TYPE_DERIVE); - if (status == 0) - value_valid = 1; - - break; - } - fclose(proc_stat); - - if (!value_valid) - return (-1); - - ps_submit_fork_rate (value.derive); - return (0); +static int read_fork_rate(void) { + FILE *proc_stat; + char buffer[1024]; + value_t value; + _Bool value_valid = 0; + + proc_stat = fopen("/proc/stat", "r"); + if (proc_stat == NULL) { + char errbuf[1024]; + ERROR("processes plugin: fopen (/proc/stat) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + while (fgets(buffer, sizeof(buffer), proc_stat) != NULL) { + int status; + char *fields[3]; + int fields_num; + + fields_num = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + if (fields_num != 2) + continue; + + if (strcmp("processes", fields[0]) != 0) + continue; + + status = parse_value(fields[1], &value, DS_TYPE_DERIVE); + if (status == 0) + value_valid = 1; + + break; + } + fclose(proc_stat); + + if (!value_valid) + return (-1); + + ps_submit_fork_rate(value.derive); + return (0); } #endif /*KERNEL_LINUX */ #if KERNEL_SOLARIS -static char *ps_get_cmdline (long pid, char *name __attribute__((unused)), /* {{{ */ - char *buffer, size_t buffer_size) -{ - char path[PATH_MAX]; - psinfo_t info; - ssize_t status; - - snprintf(path, sizeof (path), "/proc/%li/psinfo", pid); - - status = read_file_contents (path, (void *) &info, sizeof (info)); - if ((status < 0) || (((size_t) status) != sizeof (info))) - { - ERROR ("processes plugin: Unexpected return value " - "while reading \"%s\": " - "Returned %zd but expected %zu.", - path, status, buffer_size); - return (NULL); - } - - info.pr_psargs[sizeof (info.pr_psargs) - 1] = 0; - sstrncpy (buffer, info.pr_psargs, buffer_size); - - return (buffer); +static char *ps_get_cmdline(long pid, + char *name __attribute__((unused)), /* {{{ */ + char *buffer, size_t buffer_size) { + char path[PATH_MAX]; + psinfo_t info; + ssize_t status; + + snprintf(path, sizeof(path), "/proc/%li/psinfo", pid); + + status = read_file_contents(path, (void *)&info, sizeof(info)); + if ((status < 0) || (((size_t)status) != sizeof(info))) { + ERROR("processes plugin: Unexpected return value " + "while reading \"%s\": " + "Returned %zd but expected %zu.", + path, status, buffer_size); + return (NULL); + } + + info.pr_psargs[sizeof(info.pr_psargs) - 1] = 0; + sstrncpy(buffer, info.pr_psargs, buffer_size); + + return (buffer); } /* }}} int ps_get_cmdline */ /* - * Reads process information on the Solaris OS. The information comes mainly from + * Reads process information on the Solaris OS. The information comes mainly + * from * /proc/PID/status, /proc/PID/psinfo and /proc/PID/usage * The values for input and ouput chars are calculated "by hand" * Added a few "solaris" specific process states as well */ -static int ps_read_process(long pid, procstat_t *ps, char *state) -{ - char filename[64]; - char f_psinfo[64], f_usage[64]; - char *buffer; - - pstatus_t *myStatus; - psinfo_t *myInfo; - prusage_t *myUsage; - - snprintf(filename, sizeof (filename), "/proc/%li/status", pid); - snprintf(f_psinfo, sizeof (f_psinfo), "/proc/%li/psinfo", pid); - snprintf(f_usage, sizeof (f_usage), "/proc/%li/usage", pid); - - - buffer = calloc(1, sizeof (pstatus_t)); - read_file_contents(filename, buffer, sizeof (pstatus_t)); - myStatus = (pstatus_t *) buffer; - - buffer = calloc(1, sizeof (psinfo_t)); - read_file_contents(f_psinfo, buffer, sizeof (psinfo_t)); - myInfo = (psinfo_t *) buffer; - - buffer = calloc(1, sizeof (prusage_t)); - read_file_contents(f_usage, buffer, sizeof (prusage_t)); - myUsage = (prusage_t *) buffer; - - sstrncpy(ps->name, myInfo->pr_fname, sizeof (myInfo->pr_fname)); - ps->num_lwp = myStatus->pr_nlwp; - if (myInfo->pr_wstat != 0) { - ps->num_proc = 0; - ps->num_lwp = 0; - *state = (char) 'Z'; - - sfree(myStatus); - sfree(myInfo); - sfree(myUsage); - return (0); - } else { - ps->num_proc = 1; - ps->num_lwp = myInfo->pr_nlwp; - } - - /* - * Convert system time and user time from nanoseconds to microseconds - * for compatibility with the linux module - */ - ps->cpu_system_counter = myStatus -> pr_stime.tv_nsec / 1000; - ps->cpu_user_counter = myStatus -> pr_utime.tv_nsec / 1000; - - /* - * Convert rssize from KB to bytes to be consistent w/ the linux module - */ - ps->vmem_rss = myInfo->pr_rssize * 1024; - ps->vmem_size = myInfo->pr_size * 1024; - ps->vmem_minflt_counter = myUsage->pr_minf; - ps->vmem_majflt_counter = myUsage->pr_majf; - - /* - * TODO: Data and code segment calculations for Solaris - */ - - ps->vmem_data = -1; - ps->vmem_code = -1; - ps->stack_size = myStatus->pr_stksize; - - /* - * Calculating input/ouput chars - * Formula used is total chars / total blocks => chars/block - * then convert input/output blocks to chars - */ - ulong_t tot_chars = myUsage->pr_ioch; - ulong_t tot_blocks = myUsage->pr_inblk + myUsage->pr_oublk; - ulong_t chars_per_block = 1; - if (tot_blocks != 0) - chars_per_block = tot_chars / tot_blocks; - ps->io_rchar = myUsage->pr_inblk * chars_per_block; - ps->io_wchar = myUsage->pr_oublk * chars_per_block; - ps->io_syscr = myUsage->pr_sysc; - ps->io_syscw = myUsage->pr_sysc; - - /* - * TODO: context switch counters for Solaris +static int ps_read_process(long pid, procstat_t *ps, char *state) { + char filename[64]; + char f_psinfo[64], f_usage[64]; + char *buffer; + + pstatus_t *myStatus; + psinfo_t *myInfo; + prusage_t *myUsage; + + snprintf(filename, sizeof(filename), "/proc/%li/status", pid); + snprintf(f_psinfo, sizeof(f_psinfo), "/proc/%li/psinfo", pid); + snprintf(f_usage, sizeof(f_usage), "/proc/%li/usage", pid); + + buffer = calloc(1, sizeof(pstatus_t)); + read_file_contents(filename, buffer, sizeof(pstatus_t)); + myStatus = (pstatus_t *)buffer; + + buffer = calloc(1, sizeof(psinfo_t)); + read_file_contents(f_psinfo, buffer, sizeof(psinfo_t)); + myInfo = (psinfo_t *)buffer; + + buffer = calloc(1, sizeof(prusage_t)); + read_file_contents(f_usage, buffer, sizeof(prusage_t)); + myUsage = (prusage_t *)buffer; + + sstrncpy(ps->name, myInfo->pr_fname, sizeof(myInfo->pr_fname)); + ps->num_lwp = myStatus->pr_nlwp; + if (myInfo->pr_wstat != 0) { + ps->num_proc = 0; + ps->num_lwp = 0; + *state = (char)'Z'; + + sfree(myStatus); + sfree(myInfo); + sfree(myUsage); + return (0); + } else { + ps->num_proc = 1; + ps->num_lwp = myInfo->pr_nlwp; + } + + /* + * Convert system time and user time from nanoseconds to microseconds + * for compatibility with the linux module + */ + ps->cpu_system_counter = myStatus->pr_stime.tv_nsec / 1000; + ps->cpu_user_counter = myStatus->pr_utime.tv_nsec / 1000; + + /* + * Convert rssize from KB to bytes to be consistent w/ the linux module + */ + ps->vmem_rss = myInfo->pr_rssize * 1024; + ps->vmem_size = myInfo->pr_size * 1024; + ps->vmem_minflt_counter = myUsage->pr_minf; + ps->vmem_majflt_counter = myUsage->pr_majf; + + /* + * TODO: Data and code segment calculations for Solaris + */ + + ps->vmem_data = -1; + ps->vmem_code = -1; + ps->stack_size = myStatus->pr_stksize; + + /* + * Calculating input/ouput chars + * Formula used is total chars / total blocks => chars/block + * then convert input/output blocks to chars */ - ps->cswitch_vol = -1; - ps->cswitch_invol = -1; - - - /* - * TODO: Find way of setting BLOCKED and PAGING status - */ - - *state = (char) 'R'; - if (myStatus->pr_flags & PR_ASLEEP) - *state = (char) 'S'; - else if (myStatus->pr_flags & PR_STOPPED) - *state = (char) 'T'; - else if (myStatus->pr_flags & PR_DETACH) - *state = (char) 'E'; - else if (myStatus->pr_flags & PR_DAEMON) - *state = (char) 'A'; - else if (myStatus->pr_flags & PR_ISSYS) - *state = (char) 'Y'; - else if (myStatus->pr_flags & PR_ORPHAN) - *state = (char) 'O'; - - sfree(myStatus); - sfree(myInfo); - sfree(myUsage); - - return (0); + ulong_t tot_chars = myUsage->pr_ioch; + ulong_t tot_blocks = myUsage->pr_inblk + myUsage->pr_oublk; + ulong_t chars_per_block = 1; + if (tot_blocks != 0) + chars_per_block = tot_chars / tot_blocks; + ps->io_rchar = myUsage->pr_inblk * chars_per_block; + ps->io_wchar = myUsage->pr_oublk * chars_per_block; + ps->io_syscr = myUsage->pr_sysc; + ps->io_syscw = myUsage->pr_sysc; + + /* + * TODO: context switch counters for Solaris +*/ + ps->cswitch_vol = -1; + ps->cswitch_invol = -1; + + /* + * TODO: Find way of setting BLOCKED and PAGING status + */ + + *state = (char)'R'; + if (myStatus->pr_flags & PR_ASLEEP) + *state = (char)'S'; + else if (myStatus->pr_flags & PR_STOPPED) + *state = (char)'T'; + else if (myStatus->pr_flags & PR_DETACH) + *state = (char)'E'; + else if (myStatus->pr_flags & PR_DAEMON) + *state = (char)'A'; + else if (myStatus->pr_flags & PR_ISSYS) + *state = (char)'Y'; + else if (myStatus->pr_flags & PR_ORPHAN) + *state = (char)'O'; + + sfree(myStatus); + sfree(myInfo); + sfree(myUsage); + + return (0); } /* @@ -1451,967 +1354,948 @@ static int ps_read_process(long pid, procstat_t *ps, char *state) * are retrieved from kstat (module cpu, name sys, class misc, stat nthreads). * The result is the sum for all the threads created on each cpu */ -static int read_fork_rate (void) -{ - extern kstat_ctl_t *kc; - derive_t result = 0; - - if (kc == NULL) - return (-1); - - for (kstat_t *ksp_chain = kc->kc_chain; - ksp_chain != NULL; - ksp_chain = ksp_chain->ks_next) - { - if ((strcmp (ksp_chain->ks_module, "cpu") == 0) - && (strcmp (ksp_chain->ks_name, "sys") == 0) - && (strcmp (ksp_chain->ks_class, "misc") == 0)) - { - long long tmp; - - kstat_read (kc, ksp_chain, NULL); - - tmp = get_kstat_value(ksp_chain, "nthreads"); - if (tmp != -1LL) - result += tmp; - } - } - - ps_submit_fork_rate (result); - return (0); +static int read_fork_rate(void) { + extern kstat_ctl_t *kc; + derive_t result = 0; + + if (kc == NULL) + return (-1); + + for (kstat_t *ksp_chain = kc->kc_chain; ksp_chain != NULL; + ksp_chain = ksp_chain->ks_next) { + if ((strcmp(ksp_chain->ks_module, "cpu") == 0) && + (strcmp(ksp_chain->ks_name, "sys") == 0) && + (strcmp(ksp_chain->ks_class, "misc") == 0)) { + long long tmp; + + kstat_read(kc, ksp_chain, NULL); + + tmp = get_kstat_value(ksp_chain, "nthreads"); + if (tmp != -1LL) + result += tmp; + } + } + + ps_submit_fork_rate(result); + return (0); } #endif /* KERNEL_SOLARIS */ #if HAVE_THREAD_INFO -static int mach_get_task_name (task_t t, int *pid, char *name, size_t name_max_len) -{ - int mib[4]; +static int mach_get_task_name(task_t t, int *pid, char *name, + size_t name_max_len) { + int mib[4]; - struct kinfo_proc kp; - size_t kp_size; + struct kinfo_proc kp; + size_t kp_size; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; - if (pid_for_task (t, pid) != KERN_SUCCESS) - return (-1); - mib[3] = *pid; + if (pid_for_task(t, pid) != KERN_SUCCESS) + return (-1); + mib[3] = *pid; - kp_size = sizeof (kp); - if (sysctl (mib, 4, &kp, &kp_size, NULL, 0) != 0) - return (-1); + kp_size = sizeof(kp); + if (sysctl(mib, 4, &kp, &kp_size, NULL, 0) != 0) + return (-1); - if (name_max_len > (MAXCOMLEN + 1)) - name_max_len = MAXCOMLEN + 1; + if (name_max_len > (MAXCOMLEN + 1)) + name_max_len = MAXCOMLEN + 1; - strncpy (name, kp.kp_proc.p_comm, name_max_len - 1); - name[name_max_len - 1] = '\0'; + strncpy(name, kp.kp_proc.p_comm, name_max_len - 1); + name[name_max_len - 1] = '\0'; - DEBUG ("pid = %i; name = %s;", *pid, name); + DEBUG("pid = %i; name = %s;", *pid, name); - /* We don't do the special handling for `p_comm == "LaunchCFMApp"' as - * `top' does it, because it is a lot of work and only used when - * debugging. -octo */ + /* We don't do the special handling for `p_comm == "LaunchCFMApp"' as + * `top' does it, because it is a lot of work and only used when + * debugging. -octo */ - return (0); + return (0); } #endif /* HAVE_THREAD_INFO */ -/* ------- end of additional functions for KERNEL_LINUX/HAVE_THREAD_INFO ------- */ +/* ------- end of additional functions for KERNEL_LINUX/HAVE_THREAD_INFO ------- + */ /* do actual readings from kernel */ -static int ps_read (void) -{ +static int ps_read(void) { #if HAVE_THREAD_INFO - kern_return_t status; - - processor_set_t port_pset_priv; - - task_array_t task_list; - mach_msg_type_number_t task_list_len; - - int task_pid; - char task_name[MAXCOMLEN + 1]; - - thread_act_array_t thread_list; - mach_msg_type_number_t thread_list_len; - thread_basic_info_data_t thread_data; - mach_msg_type_number_t thread_data_len; - - int running = 0; - int sleeping = 0; - int zombies = 0; - int stopped = 0; - int blocked = 0; - - procstat_t *ps; - procstat_entry_t pse; - - ps_list_reset (); - - /* - * The Mach-concept is a little different from the traditional UNIX - * concept: All the work is done in threads. Threads are contained in - * `tasks'. Therefore, `task status' doesn't make much sense, since - * it's actually a `thread status'. - * Tasks are assigned to sets of processors, so that's where you go to - * get a list. - */ - for (mach_msg_type_number_t pset = 0; pset < pset_list_len; pset++) - { - if ((status = host_processor_set_priv (port_host_self, - pset_list[pset], - &port_pset_priv)) != KERN_SUCCESS) - { - ERROR ("host_processor_set_priv failed: %s\n", - mach_error_string (status)); - continue; - } - - if ((status = processor_set_tasks (port_pset_priv, - &task_list, - &task_list_len)) != KERN_SUCCESS) - { - ERROR ("processor_set_tasks failed: %s\n", - mach_error_string (status)); - mach_port_deallocate (port_task_self, port_pset_priv); - continue; - } - - for (mach_msg_type_number_t task = 0; task < task_list_len; task++) - { - ps = NULL; - if (mach_get_task_name (task_list[task], - &task_pid, - task_name, PROCSTAT_NAME_LEN) == 0) - { - /* search for at least one match */ - for (ps = list_head_g; ps != NULL; ps = ps->next) - /* FIXME: cmdline should be here instead of NULL */ - if (ps_list_match (task_name, NULL, ps) == 1) - break; - } - - /* Collect more detailed statistics for this process */ - if (ps != NULL) - { - task_basic_info_data_t task_basic_info; - mach_msg_type_number_t task_basic_info_len; - task_events_info_data_t task_events_info; - mach_msg_type_number_t task_events_info_len; - task_absolutetime_info_data_t task_absolutetime_info; - mach_msg_type_number_t task_absolutetime_info_len; - - memset (&pse, '\0', sizeof (pse)); - pse.id = task_pid; - - task_basic_info_len = TASK_BASIC_INFO_COUNT; - status = task_info (task_list[task], - TASK_BASIC_INFO, - (task_info_t) &task_basic_info, - &task_basic_info_len); - if (status != KERN_SUCCESS) - { - ERROR ("task_info failed: %s", - mach_error_string (status)); - continue; /* with next thread_list */ - } - - task_events_info_len = TASK_EVENTS_INFO_COUNT; - status = task_info (task_list[task], - TASK_EVENTS_INFO, - (task_info_t) &task_events_info, - &task_events_info_len); - if (status != KERN_SUCCESS) - { - ERROR ("task_info failed: %s", - mach_error_string (status)); - continue; /* with next thread_list */ - } - - task_absolutetime_info_len = TASK_ABSOLUTETIME_INFO_COUNT; - status = task_info (task_list[task], - TASK_ABSOLUTETIME_INFO, - (task_info_t) &task_absolutetime_info, - &task_absolutetime_info_len); - if (status != KERN_SUCCESS) - { - ERROR ("task_info failed: %s", - mach_error_string (status)); - continue; /* with next thread_list */ - } - - pse.num_proc++; - pse.vmem_size = task_basic_info.virtual_size; - pse.vmem_rss = task_basic_info.resident_size; - /* Does not seem to be easily exposed */ - pse.vmem_data = 0; - pse.vmem_code = 0; - - pse.vmem_minflt_counter = task_events_info.cow_faults; - pse.vmem_majflt_counter = task_events_info.faults; - - pse.cpu_user_counter = task_absolutetime_info.total_user; - pse.cpu_system_counter = task_absolutetime_info.total_system; - - /* context switch counters not implemented */ - pse.cswitch_vol = -1; - pse.cswitch_invol = -1; - } - - status = task_threads (task_list[task], &thread_list, - &thread_list_len); - if (status != KERN_SUCCESS) - { - /* Apple's `top' treats this case a zombie. It - * makes sense to some extend: A `zombie' - * thread is nonsense, since the task/process - * is dead. */ - zombies++; - DEBUG ("task_threads failed: %s", - mach_error_string (status)); - if (task_list[task] != port_task_self) - mach_port_deallocate (port_task_self, - task_list[task]); - continue; /* with next task_list */ - } - - for (mach_msg_type_number_t thread = 0; thread < thread_list_len; thread++) - { - thread_data_len = THREAD_BASIC_INFO_COUNT; - status = thread_info (thread_list[thread], - THREAD_BASIC_INFO, - (thread_info_t) &thread_data, - &thread_data_len); - if (status != KERN_SUCCESS) - { - ERROR ("thread_info failed: %s", - mach_error_string (status)); - if (task_list[task] != port_task_self) - mach_port_deallocate (port_task_self, - thread_list[thread]); - continue; /* with next thread_list */ - } - - if (ps != NULL) - pse.num_lwp++; - - switch (thread_data.run_state) - { - case TH_STATE_RUNNING: - running++; - break; - case TH_STATE_STOPPED: - /* What exactly is `halted'? */ - case TH_STATE_HALTED: - stopped++; - break; - case TH_STATE_WAITING: - sleeping++; - break; - case TH_STATE_UNINTERRUPTIBLE: - blocked++; - break; - /* There is no `zombie' case here, - * since there are no zombie-threads. - * There's only zombie tasks, which are - * handled above. */ - default: - WARNING ("Unknown thread status: %i", - thread_data.run_state); - break; - } /* switch (thread_data.run_state) */ - - if (task_list[task] != port_task_self) - { - status = mach_port_deallocate (port_task_self, - thread_list[thread]); - if (status != KERN_SUCCESS) - ERROR ("mach_port_deallocate failed: %s", - mach_error_string (status)); - } - } /* for (thread_list) */ - - if ((status = vm_deallocate (port_task_self, - (vm_address_t) thread_list, - thread_list_len * sizeof (thread_act_t))) - != KERN_SUCCESS) - { - ERROR ("vm_deallocate failed: %s", - mach_error_string (status)); - } - thread_list = NULL; - thread_list_len = 0; - - /* Only deallocate the task port, if it isn't our own. - * Don't know what would happen in that case, but this - * is what Apple's top does.. ;) */ - if (task_list[task] != port_task_self) - { - status = mach_port_deallocate (port_task_self, - task_list[task]); - if (status != KERN_SUCCESS) - ERROR ("mach_port_deallocate failed: %s", - mach_error_string (status)); - } - - if (ps != NULL) - /* FIXME: cmdline should be here instead of NULL */ - ps_list_add (task_name, NULL, &pse); - } /* for (task_list) */ - - if ((status = vm_deallocate (port_task_self, - (vm_address_t) task_list, - task_list_len * sizeof (task_t))) != KERN_SUCCESS) - { - ERROR ("vm_deallocate failed: %s", - mach_error_string (status)); - } - task_list = NULL; - task_list_len = 0; - - if ((status = mach_port_deallocate (port_task_self, port_pset_priv)) - != KERN_SUCCESS) - { - ERROR ("mach_port_deallocate failed: %s", - mach_error_string (status)); - } - } /* for (pset_list) */ - - ps_submit_state ("running", running); - ps_submit_state ("sleeping", sleeping); - ps_submit_state ("zombies", zombies); - ps_submit_state ("stopped", stopped); - ps_submit_state ("blocked", blocked); - - for (ps = list_head_g; ps != NULL; ps = ps->next) - ps_submit_proc_list (ps); + kern_return_t status; + + processor_set_t port_pset_priv; + + task_array_t task_list; + mach_msg_type_number_t task_list_len; + + int task_pid; + char task_name[MAXCOMLEN + 1]; + + thread_act_array_t thread_list; + mach_msg_type_number_t thread_list_len; + thread_basic_info_data_t thread_data; + mach_msg_type_number_t thread_data_len; + + int running = 0; + int sleeping = 0; + int zombies = 0; + int stopped = 0; + int blocked = 0; + + procstat_t *ps; + procstat_entry_t pse; + + ps_list_reset(); + + /* + * The Mach-concept is a little different from the traditional UNIX + * concept: All the work is done in threads. Threads are contained in + * `tasks'. Therefore, `task status' doesn't make much sense, since + * it's actually a `thread status'. + * Tasks are assigned to sets of processors, so that's where you go to + * get a list. + */ + for (mach_msg_type_number_t pset = 0; pset < pset_list_len; pset++) { + if ((status = host_processor_set_priv(port_host_self, pset_list[pset], + &port_pset_priv)) != KERN_SUCCESS) { + ERROR("host_processor_set_priv failed: %s\n", mach_error_string(status)); + continue; + } + + if ((status = processor_set_tasks(port_pset_priv, &task_list, + &task_list_len)) != KERN_SUCCESS) { + ERROR("processor_set_tasks failed: %s\n", mach_error_string(status)); + mach_port_deallocate(port_task_self, port_pset_priv); + continue; + } + + for (mach_msg_type_number_t task = 0; task < task_list_len; task++) { + ps = NULL; + if (mach_get_task_name(task_list[task], &task_pid, task_name, + PROCSTAT_NAME_LEN) == 0) { + /* search for at least one match */ + for (ps = list_head_g; ps != NULL; ps = ps->next) + /* FIXME: cmdline should be here instead of NULL */ + if (ps_list_match(task_name, NULL, ps) == 1) + break; + } + + /* Collect more detailed statistics for this process */ + if (ps != NULL) { + task_basic_info_data_t task_basic_info; + mach_msg_type_number_t task_basic_info_len; + task_events_info_data_t task_events_info; + mach_msg_type_number_t task_events_info_len; + task_absolutetime_info_data_t task_absolutetime_info; + mach_msg_type_number_t task_absolutetime_info_len; + + memset(&pse, '\0', sizeof(pse)); + pse.id = task_pid; + + task_basic_info_len = TASK_BASIC_INFO_COUNT; + status = task_info(task_list[task], TASK_BASIC_INFO, + (task_info_t)&task_basic_info, &task_basic_info_len); + if (status != KERN_SUCCESS) { + ERROR("task_info failed: %s", mach_error_string(status)); + continue; /* with next thread_list */ + } + + task_events_info_len = TASK_EVENTS_INFO_COUNT; + status = + task_info(task_list[task], TASK_EVENTS_INFO, + (task_info_t)&task_events_info, &task_events_info_len); + if (status != KERN_SUCCESS) { + ERROR("task_info failed: %s", mach_error_string(status)); + continue; /* with next thread_list */ + } + + task_absolutetime_info_len = TASK_ABSOLUTETIME_INFO_COUNT; + status = task_info(task_list[task], TASK_ABSOLUTETIME_INFO, + (task_info_t)&task_absolutetime_info, + &task_absolutetime_info_len); + if (status != KERN_SUCCESS) { + ERROR("task_info failed: %s", mach_error_string(status)); + continue; /* with next thread_list */ + } + + pse.num_proc++; + pse.vmem_size = task_basic_info.virtual_size; + pse.vmem_rss = task_basic_info.resident_size; + /* Does not seem to be easily exposed */ + pse.vmem_data = 0; + pse.vmem_code = 0; + + pse.vmem_minflt_counter = task_events_info.cow_faults; + pse.vmem_majflt_counter = task_events_info.faults; + + pse.cpu_user_counter = task_absolutetime_info.total_user; + pse.cpu_system_counter = task_absolutetime_info.total_system; + + /* context switch counters not implemented */ + pse.cswitch_vol = -1; + pse.cswitch_invol = -1; + } + + status = task_threads(task_list[task], &thread_list, &thread_list_len); + if (status != KERN_SUCCESS) { + /* Apple's `top' treats this case a zombie. It + * makes sense to some extend: A `zombie' + * thread is nonsense, since the task/process + * is dead. */ + zombies++; + DEBUG("task_threads failed: %s", mach_error_string(status)); + if (task_list[task] != port_task_self) + mach_port_deallocate(port_task_self, task_list[task]); + continue; /* with next task_list */ + } + + for (mach_msg_type_number_t thread = 0; thread < thread_list_len; + thread++) { + thread_data_len = THREAD_BASIC_INFO_COUNT; + status = thread_info(thread_list[thread], THREAD_BASIC_INFO, + (thread_info_t)&thread_data, &thread_data_len); + if (status != KERN_SUCCESS) { + ERROR("thread_info failed: %s", mach_error_string(status)); + if (task_list[task] != port_task_self) + mach_port_deallocate(port_task_self, thread_list[thread]); + continue; /* with next thread_list */ + } + + if (ps != NULL) + pse.num_lwp++; + + switch (thread_data.run_state) { + case TH_STATE_RUNNING: + running++; + break; + case TH_STATE_STOPPED: + /* What exactly is `halted'? */ + case TH_STATE_HALTED: + stopped++; + break; + case TH_STATE_WAITING: + sleeping++; + break; + case TH_STATE_UNINTERRUPTIBLE: + blocked++; + break; + /* There is no `zombie' case here, + * since there are no zombie-threads. + * There's only zombie tasks, which are + * handled above. */ + default: + WARNING("Unknown thread status: %i", thread_data.run_state); + break; + } /* switch (thread_data.run_state) */ + + if (task_list[task] != port_task_self) { + status = mach_port_deallocate(port_task_self, thread_list[thread]); + if (status != KERN_SUCCESS) + ERROR("mach_port_deallocate failed: %s", mach_error_string(status)); + } + } /* for (thread_list) */ + + if ((status = vm_deallocate(port_task_self, (vm_address_t)thread_list, + thread_list_len * sizeof(thread_act_t))) != + KERN_SUCCESS) { + ERROR("vm_deallocate failed: %s", mach_error_string(status)); + } + thread_list = NULL; + thread_list_len = 0; + + /* Only deallocate the task port, if it isn't our own. + * Don't know what would happen in that case, but this + * is what Apple's top does.. ;) */ + if (task_list[task] != port_task_self) { + status = mach_port_deallocate(port_task_self, task_list[task]); + if (status != KERN_SUCCESS) + ERROR("mach_port_deallocate failed: %s", mach_error_string(status)); + } + + if (ps != NULL) + /* FIXME: cmdline should be here instead of NULL */ + ps_list_add(task_name, NULL, &pse); + } /* for (task_list) */ + + if ((status = vm_deallocate(port_task_self, (vm_address_t)task_list, + task_list_len * sizeof(task_t))) != + KERN_SUCCESS) { + ERROR("vm_deallocate failed: %s", mach_error_string(status)); + } + task_list = NULL; + task_list_len = 0; + + if ((status = mach_port_deallocate(port_task_self, port_pset_priv)) != + KERN_SUCCESS) { + ERROR("mach_port_deallocate failed: %s", mach_error_string(status)); + } + } /* for (pset_list) */ + + ps_submit_state("running", running); + ps_submit_state("sleeping", sleeping); + ps_submit_state("zombies", zombies); + ps_submit_state("stopped", stopped); + ps_submit_state("blocked", blocked); + + for (ps = list_head_g; ps != NULL; ps = ps->next) + ps_submit_proc_list(ps); /* #endif HAVE_THREAD_INFO */ #elif KERNEL_LINUX - int running = 0; - int sleeping = 0; - int zombies = 0; - int stopped = 0; - int paging = 0; - int blocked = 0; - - struct dirent *ent; - DIR *proc; - long pid; - - char cmdline[CMDLINE_BUFFER_SIZE]; - - int status; - procstat_t ps; - procstat_entry_t pse; - char state; - - running = sleeping = zombies = stopped = paging = blocked = 0; - ps_list_reset (); - - if ((proc = opendir ("/proc")) == NULL) - { - char errbuf[1024]; - ERROR ("Cannot open `/proc': %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - while ((ent = readdir (proc)) != NULL) - { - if (!isdigit (ent->d_name[0])) - continue; - - if ((pid = atol (ent->d_name)) < 1) - continue; - - status = ps_read_process (pid, &ps, &state); - if (status != 0) - { - DEBUG ("ps_read_process failed: %i", status); - continue; - } - - memset (&pse, 0, sizeof (pse)); - pse.id = pid; - pse.age = 0; - - pse.num_proc = ps.num_proc; - pse.num_lwp = ps.num_lwp; - pse.vmem_size = ps.vmem_size; - pse.vmem_rss = ps.vmem_rss; - pse.vmem_data = ps.vmem_data; - pse.vmem_code = ps.vmem_code; - pse.stack_size = ps.stack_size; - - pse.vmem_minflt_counter = ps.vmem_minflt_counter; - pse.vmem_majflt_counter = ps.vmem_majflt_counter; - - pse.cpu_user_counter = ps.cpu_user_counter; - pse.cpu_system_counter = ps.cpu_system_counter; - - pse.io_rchar = ps.io_rchar; - pse.io_wchar = ps.io_wchar; - pse.io_syscr = ps.io_syscr; - pse.io_syscw = ps.io_syscw; - - pse.cswitch_vol = ps.cswitch_vol; - pse.cswitch_invol = ps.cswitch_invol; - - switch (state) - { - case 'R': running++; break; - case 'S': sleeping++; break; - case 'D': blocked++; break; - case 'Z': zombies++; break; - case 'T': stopped++; break; - case 'W': paging++; break; - } - - ps_list_add (ps.name, - ps_get_cmdline (pid, ps.name, cmdline, sizeof (cmdline)), - &pse); - } - - closedir (proc); - - ps_submit_state ("running", running); - ps_submit_state ("sleeping", sleeping); - ps_submit_state ("zombies", zombies); - ps_submit_state ("stopped", stopped); - ps_submit_state ("paging", paging); - ps_submit_state ("blocked", blocked); - - for (procstat_t *ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next) - ps_submit_proc_list (ps_ptr); - - read_fork_rate(); + int running = 0; + int sleeping = 0; + int zombies = 0; + int stopped = 0; + int paging = 0; + int blocked = 0; + + struct dirent *ent; + DIR *proc; + long pid; + + char cmdline[CMDLINE_BUFFER_SIZE]; + + int status; + procstat_t ps; + procstat_entry_t pse; + char state; + + running = sleeping = zombies = stopped = paging = blocked = 0; + ps_list_reset(); + + if ((proc = opendir("/proc")) == NULL) { + char errbuf[1024]; + ERROR("Cannot open `/proc': %s", sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + while ((ent = readdir(proc)) != NULL) { + if (!isdigit(ent->d_name[0])) + continue; + + if ((pid = atol(ent->d_name)) < 1) + continue; + + status = ps_read_process(pid, &ps, &state); + if (status != 0) { + DEBUG("ps_read_process failed: %i", status); + continue; + } + + memset(&pse, 0, sizeof(pse)); + pse.id = pid; + pse.age = 0; + + pse.num_proc = ps.num_proc; + pse.num_lwp = ps.num_lwp; + pse.vmem_size = ps.vmem_size; + pse.vmem_rss = ps.vmem_rss; + pse.vmem_data = ps.vmem_data; + pse.vmem_code = ps.vmem_code; + pse.stack_size = ps.stack_size; + + pse.vmem_minflt_counter = ps.vmem_minflt_counter; + pse.vmem_majflt_counter = ps.vmem_majflt_counter; + + pse.cpu_user_counter = ps.cpu_user_counter; + pse.cpu_system_counter = ps.cpu_system_counter; + + pse.io_rchar = ps.io_rchar; + pse.io_wchar = ps.io_wchar; + pse.io_syscr = ps.io_syscr; + pse.io_syscw = ps.io_syscw; + + pse.cswitch_vol = ps.cswitch_vol; + pse.cswitch_invol = ps.cswitch_invol; + + switch (state) { + case 'R': + running++; + break; + case 'S': + sleeping++; + break; + case 'D': + blocked++; + break; + case 'Z': + zombies++; + break; + case 'T': + stopped++; + break; + case 'W': + paging++; + break; + } + + ps_list_add(ps.name, ps_get_cmdline(pid, ps.name, cmdline, sizeof(cmdline)), + &pse); + } + + closedir(proc); + + ps_submit_state("running", running); + ps_submit_state("sleeping", sleeping); + ps_submit_state("zombies", zombies); + ps_submit_state("stopped", stopped); + ps_submit_state("paging", paging); + ps_submit_state("blocked", blocked); + + for (procstat_t *ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next) + ps_submit_proc_list(ps_ptr); + + read_fork_rate(); /* #endif KERNEL_LINUX */ #elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD - int running = 0; - int sleeping = 0; - int zombies = 0; - int stopped = 0; - int blocked = 0; - int idle = 0; - int wait = 0; - - kvm_t *kd; - char errbuf[_POSIX2_LINE_MAX]; - struct kinfo_proc *procs; /* array of processes */ - struct kinfo_proc *proc_ptr = NULL; - int count; /* returns number of processes */ - - procstat_entry_t pse; - - ps_list_reset (); - - /* Open the kvm interface, get a descriptor */ - kd = kvm_openfiles (NULL, "/dev/null", NULL, 0, errbuf); - if (kd == NULL) - { - ERROR ("processes plugin: Cannot open kvm interface: %s", - errbuf); - return (0); - } - - /* Get the list of processes. */ - procs = kvm_getprocs(kd, KERN_PROC_ALL, 0, &count); - if (procs == NULL) - { - ERROR ("processes plugin: Cannot get kvm processes list: %s", - kvm_geterr(kd)); - kvm_close (kd); - return (0); - } - - /* Iterate through the processes in kinfo_proc */ - for (int i = 0; i < count; i++) - { - /* Create only one process list entry per _process_, i.e. - * filter out threads (duplicate PID entries). */ - if ((proc_ptr == NULL) || (proc_ptr->ki_pid != procs[i].ki_pid)) - { - char cmdline[CMDLINE_BUFFER_SIZE] = ""; - _Bool have_cmdline = 0; - - proc_ptr = &(procs[i]); - /* Don't probe system processes and processes without arguments */ - if (((procs[i].ki_flag & P_SYSTEM) == 0) - && (procs[i].ki_args != NULL)) - { - char **argv; - int argc; - int status; - - /* retrieve the arguments */ - argv = kvm_getargv (kd, proc_ptr, /* nchr = */ 0); - argc = 0; - if ((argv != NULL) && (argv[0] != NULL)) - { - while (argv[argc] != NULL) - argc++; - - status = strjoin (cmdline, sizeof (cmdline), argv, argc, " "); - if (status < 0) - WARNING ("processes plugin: Command line did not fit into buffer."); - else - have_cmdline = 1; - } - } /* if (process has argument list) */ - - pse.id = procs[i].ki_pid; - pse.age = 0; - - pse.num_proc = 1; - pse.num_lwp = procs[i].ki_numthreads; - - pse.vmem_size = procs[i].ki_size; - pse.vmem_rss = procs[i].ki_rssize * pagesize; - pse.vmem_data = procs[i].ki_dsize * pagesize; - pse.vmem_code = procs[i].ki_tsize * pagesize; - pse.stack_size = procs[i].ki_ssize * pagesize; - pse.vmem_minflt_counter = procs[i].ki_rusage.ru_minflt; - pse.vmem_majflt_counter = procs[i].ki_rusage.ru_majflt; - - pse.cpu_user_counter = 0; - pse.cpu_system_counter = 0; - /* - * The u-area might be swapped out, and we can't get - * at it because we have a crashdump and no swap. - * If it's here fill in these fields, otherwise, just - * leave them 0. - */ - if (procs[i].ki_flag & P_INMEM) - { - pse.cpu_user_counter = procs[i].ki_rusage.ru_utime.tv_usec - + (1000000lu * procs[i].ki_rusage.ru_utime.tv_sec); - pse.cpu_system_counter = procs[i].ki_rusage.ru_stime.tv_usec - + (1000000lu * procs[i].ki_rusage.ru_stime.tv_sec); - } - - /* no I/O data */ - pse.io_rchar = -1; - pse.io_wchar = -1; - pse.io_syscr = -1; - pse.io_syscw = -1; - - /* context switch counters not implemented */ - pse.cswitch_vol = -1; - pse.cswitch_invol = -1; - - ps_list_add (procs[i].ki_comm, have_cmdline ? cmdline : NULL, &pse); - - switch (procs[i].ki_stat) - { - case SSTOP: stopped++; break; - case SSLEEP: sleeping++; break; - case SRUN: running++; break; - case SIDL: idle++; break; - case SWAIT: wait++; break; - case SLOCK: blocked++; break; - case SZOMB: zombies++; break; - } - } /* if ((proc_ptr == NULL) || (proc_ptr->ki_pid != procs[i].ki_pid)) */ - } - - kvm_close(kd); - - ps_submit_state ("running", running); - ps_submit_state ("sleeping", sleeping); - ps_submit_state ("zombies", zombies); - ps_submit_state ("stopped", stopped); - ps_submit_state ("blocked", blocked); - ps_submit_state ("idle", idle); - ps_submit_state ("wait", wait); - - for (procstat_t *ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next) - ps_submit_proc_list (ps_ptr); + int running = 0; + int sleeping = 0; + int zombies = 0; + int stopped = 0; + int blocked = 0; + int idle = 0; + int wait = 0; + + kvm_t *kd; + char errbuf[_POSIX2_LINE_MAX]; + struct kinfo_proc *procs; /* array of processes */ + struct kinfo_proc *proc_ptr = NULL; + int count; /* returns number of processes */ + + procstat_entry_t pse; + + ps_list_reset(); + + /* Open the kvm interface, get a descriptor */ + kd = kvm_openfiles(NULL, "/dev/null", NULL, 0, errbuf); + if (kd == NULL) { + ERROR("processes plugin: Cannot open kvm interface: %s", errbuf); + return (0); + } + + /* Get the list of processes. */ + procs = kvm_getprocs(kd, KERN_PROC_ALL, 0, &count); + if (procs == NULL) { + ERROR("processes plugin: Cannot get kvm processes list: %s", + kvm_geterr(kd)); + kvm_close(kd); + return (0); + } + + /* Iterate through the processes in kinfo_proc */ + for (int i = 0; i < count; i++) { + /* Create only one process list entry per _process_, i.e. + * filter out threads (duplicate PID entries). */ + if ((proc_ptr == NULL) || (proc_ptr->ki_pid != procs[i].ki_pid)) { + char cmdline[CMDLINE_BUFFER_SIZE] = ""; + _Bool have_cmdline = 0; + + proc_ptr = &(procs[i]); + /* Don't probe system processes and processes without arguments */ + if (((procs[i].ki_flag & P_SYSTEM) == 0) && (procs[i].ki_args != NULL)) { + char **argv; + int argc; + int status; + + /* retrieve the arguments */ + argv = kvm_getargv(kd, proc_ptr, /* nchr = */ 0); + argc = 0; + if ((argv != NULL) && (argv[0] != NULL)) { + while (argv[argc] != NULL) + argc++; + + status = strjoin(cmdline, sizeof(cmdline), argv, argc, " "); + if (status < 0) + WARNING("processes plugin: Command line did not fit into buffer."); + else + have_cmdline = 1; + } + } /* if (process has argument list) */ + + pse.id = procs[i].ki_pid; + pse.age = 0; + + pse.num_proc = 1; + pse.num_lwp = procs[i].ki_numthreads; + + pse.vmem_size = procs[i].ki_size; + pse.vmem_rss = procs[i].ki_rssize * pagesize; + pse.vmem_data = procs[i].ki_dsize * pagesize; + pse.vmem_code = procs[i].ki_tsize * pagesize; + pse.stack_size = procs[i].ki_ssize * pagesize; + pse.vmem_minflt_counter = procs[i].ki_rusage.ru_minflt; + pse.vmem_majflt_counter = procs[i].ki_rusage.ru_majflt; + + pse.cpu_user_counter = 0; + pse.cpu_system_counter = 0; + /* + * The u-area might be swapped out, and we can't get + * at it because we have a crashdump and no swap. + * If it's here fill in these fields, otherwise, just + * leave them 0. + */ + if (procs[i].ki_flag & P_INMEM) { + pse.cpu_user_counter = procs[i].ki_rusage.ru_utime.tv_usec + + (1000000lu * procs[i].ki_rusage.ru_utime.tv_sec); + pse.cpu_system_counter = + procs[i].ki_rusage.ru_stime.tv_usec + + (1000000lu * procs[i].ki_rusage.ru_stime.tv_sec); + } + + /* no I/O data */ + pse.io_rchar = -1; + pse.io_wchar = -1; + pse.io_syscr = -1; + pse.io_syscw = -1; + + /* context switch counters not implemented */ + pse.cswitch_vol = -1; + pse.cswitch_invol = -1; + + ps_list_add(procs[i].ki_comm, have_cmdline ? cmdline : NULL, &pse); + + switch (procs[i].ki_stat) { + case SSTOP: + stopped++; + break; + case SSLEEP: + sleeping++; + break; + case SRUN: + running++; + break; + case SIDL: + idle++; + break; + case SWAIT: + wait++; + break; + case SLOCK: + blocked++; + break; + case SZOMB: + zombies++; + break; + } + } /* if ((proc_ptr == NULL) || (proc_ptr->ki_pid != procs[i].ki_pid)) */ + } + + kvm_close(kd); + + ps_submit_state("running", running); + ps_submit_state("sleeping", sleeping); + ps_submit_state("zombies", zombies); + ps_submit_state("stopped", stopped); + ps_submit_state("blocked", blocked); + ps_submit_state("idle", idle); + ps_submit_state("wait", wait); + + for (procstat_t *ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next) + ps_submit_proc_list(ps_ptr); /* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */ #elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_OPENBSD - int running = 0; - int sleeping = 0; - int zombies = 0; - int stopped = 0; - int onproc = 0; - int idle = 0; - int dead = 0; - - kvm_t *kd; - char errbuf[1024]; - struct kinfo_proc *procs; /* array of processes */ - struct kinfo_proc *proc_ptr = NULL; - int count; /* returns number of processes */ - - procstat_entry_t pse; - - ps_list_reset (); - - /* Open the kvm interface, get a descriptor */ - kd = kvm_open (NULL, NULL, NULL, 0, errbuf); - if (kd == NULL) - { - ERROR ("processes plugin: Cannot open kvm interface: %s", - errbuf); - return (0); - } - - /* Get the list of processes. */ - procs = kvm_getprocs(kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &count); - if (procs == NULL) - { - ERROR ("processes plugin: Cannot get kvm processes list: %s", - kvm_geterr(kd)); - kvm_close (kd); - return (0); - } - - /* Iterate through the processes in kinfo_proc */ - for (int i = 0; i < count; i++) - { - /* Create only one process list entry per _process_, i.e. - * filter out threads (duplicate PID entries). */ - if ((proc_ptr == NULL) || (proc_ptr->p_pid != procs[i].p_pid)) - { - char cmdline[CMDLINE_BUFFER_SIZE] = ""; - _Bool have_cmdline = 0; - - proc_ptr = &(procs[i]); - /* Don't probe zombie processes */ - if (!P_ZOMBIE(proc_ptr)) - { - char **argv; - int argc; - int status; - - /* retrieve the arguments */ - argv = kvm_getargv (kd, proc_ptr, /* nchr = */ 0); - argc = 0; - if ((argv != NULL) && (argv[0] != NULL)) - { - while (argv[argc] != NULL) - argc++; - - status = strjoin (cmdline, sizeof (cmdline), argv, argc, " "); - if (status < 0) - WARNING ("processes plugin: Command line did not fit into buffer."); - else - have_cmdline = 1; - } - } /* if (process has argument list) */ - - memset (&pse, 0, sizeof (pse)); - pse.id = procs[i].p_pid; - pse.age = 0; - - pse.num_proc = 1; - pse.num_lwp = 1; /* XXX: accumulate p_tid values for a single p_pid ? */ - - pse.vmem_rss = procs[i].p_vm_rssize * pagesize; - pse.vmem_data = procs[i].p_vm_dsize * pagesize; - pse.vmem_code = procs[i].p_vm_tsize * pagesize; - pse.stack_size = procs[i].p_vm_ssize * pagesize; - pse.vmem_size = pse.stack_size + pse.vmem_code + pse.vmem_data; - pse.vmem_minflt_counter = procs[i].p_uru_minflt; - pse.vmem_majflt_counter = procs[i].p_uru_majflt; - - pse.cpu_user_counter = procs[i].p_uutime_usec + - (1000000lu * procs[i].p_uutime_sec); - pse.cpu_system_counter = procs[i].p_ustime_usec + - (1000000lu * procs[i].p_ustime_sec); - - /* no I/O data */ - pse.io_rchar = -1; - pse.io_wchar = -1; - pse.io_syscr = -1; - pse.io_syscw = -1; - - /* context switch counters not implemented */ - pse.cswitch_vol = -1; - pse.cswitch_invol = -1; - - ps_list_add (procs[i].p_comm, have_cmdline ? cmdline : NULL, &pse); - - switch (procs[i].p_stat) - { - case SSTOP: stopped++; break; - case SSLEEP: sleeping++; break; - case SRUN: running++; break; - case SIDL: idle++; break; - case SONPROC: onproc++; break; - case SDEAD: dead++; break; - case SZOMB: zombies++; break; - } - } /* if ((proc_ptr == NULL) || (proc_ptr->p_pid != procs[i].p_pid)) */ - } - - kvm_close(kd); - - ps_submit_state ("running", running); - ps_submit_state ("sleeping", sleeping); - ps_submit_state ("zombies", zombies); - ps_submit_state ("stopped", stopped); - ps_submit_state ("onproc", onproc); - ps_submit_state ("idle", idle); - ps_submit_state ("dead", dead); - - for (procstat_t *ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next) - ps_submit_proc_list (ps_ptr); + int running = 0; + int sleeping = 0; + int zombies = 0; + int stopped = 0; + int onproc = 0; + int idle = 0; + int dead = 0; + + kvm_t *kd; + char errbuf[1024]; + struct kinfo_proc *procs; /* array of processes */ + struct kinfo_proc *proc_ptr = NULL; + int count; /* returns number of processes */ + + procstat_entry_t pse; + + ps_list_reset(); + + /* Open the kvm interface, get a descriptor */ + kd = kvm_open(NULL, NULL, NULL, 0, errbuf); + if (kd == NULL) { + ERROR("processes plugin: Cannot open kvm interface: %s", errbuf); + return (0); + } + + /* Get the list of processes. */ + procs = kvm_getprocs(kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &count); + if (procs == NULL) { + ERROR("processes plugin: Cannot get kvm processes list: %s", + kvm_geterr(kd)); + kvm_close(kd); + return (0); + } + + /* Iterate through the processes in kinfo_proc */ + for (int i = 0; i < count; i++) { + /* Create only one process list entry per _process_, i.e. + * filter out threads (duplicate PID entries). */ + if ((proc_ptr == NULL) || (proc_ptr->p_pid != procs[i].p_pid)) { + char cmdline[CMDLINE_BUFFER_SIZE] = ""; + _Bool have_cmdline = 0; + + proc_ptr = &(procs[i]); + /* Don't probe zombie processes */ + if (!P_ZOMBIE(proc_ptr)) { + char **argv; + int argc; + int status; + + /* retrieve the arguments */ + argv = kvm_getargv(kd, proc_ptr, /* nchr = */ 0); + argc = 0; + if ((argv != NULL) && (argv[0] != NULL)) { + while (argv[argc] != NULL) + argc++; + + status = strjoin(cmdline, sizeof(cmdline), argv, argc, " "); + if (status < 0) + WARNING("processes plugin: Command line did not fit into buffer."); + else + have_cmdline = 1; + } + } /* if (process has argument list) */ + + memset(&pse, 0, sizeof(pse)); + pse.id = procs[i].p_pid; + pse.age = 0; + + pse.num_proc = 1; + pse.num_lwp = 1; /* XXX: accumulate p_tid values for a single p_pid ? */ + + pse.vmem_rss = procs[i].p_vm_rssize * pagesize; + pse.vmem_data = procs[i].p_vm_dsize * pagesize; + pse.vmem_code = procs[i].p_vm_tsize * pagesize; + pse.stack_size = procs[i].p_vm_ssize * pagesize; + pse.vmem_size = pse.stack_size + pse.vmem_code + pse.vmem_data; + pse.vmem_minflt_counter = procs[i].p_uru_minflt; + pse.vmem_majflt_counter = procs[i].p_uru_majflt; + + pse.cpu_user_counter = + procs[i].p_uutime_usec + (1000000lu * procs[i].p_uutime_sec); + pse.cpu_system_counter = + procs[i].p_ustime_usec + (1000000lu * procs[i].p_ustime_sec); + + /* no I/O data */ + pse.io_rchar = -1; + pse.io_wchar = -1; + pse.io_syscr = -1; + pse.io_syscw = -1; + + /* context switch counters not implemented */ + pse.cswitch_vol = -1; + pse.cswitch_invol = -1; + + ps_list_add(procs[i].p_comm, have_cmdline ? cmdline : NULL, &pse); + + switch (procs[i].p_stat) { + case SSTOP: + stopped++; + break; + case SSLEEP: + sleeping++; + break; + case SRUN: + running++; + break; + case SIDL: + idle++; + break; + case SONPROC: + onproc++; + break; + case SDEAD: + dead++; + break; + case SZOMB: + zombies++; + break; + } + } /* if ((proc_ptr == NULL) || (proc_ptr->p_pid != procs[i].p_pid)) */ + } + + kvm_close(kd); + + ps_submit_state("running", running); + ps_submit_state("sleeping", sleeping); + ps_submit_state("zombies", zombies); + ps_submit_state("stopped", stopped); + ps_submit_state("onproc", onproc); + ps_submit_state("idle", idle); + ps_submit_state("dead", dead); + + for (procstat_t *ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next) + ps_submit_proc_list(ps_ptr); /* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_OPENBSD */ #elif HAVE_PROCINFO_H - /* AIX */ - int running = 0; - int sleeping = 0; - int zombies = 0; - int stopped = 0; - int paging = 0; - int blocked = 0; - - pid_t pindex = 0; - int nprocs; - - procstat_entry_t pse; - - ps_list_reset (); - while ((nprocs = getprocs64 (procentry, sizeof(struct procentry64), - /* fdsinfo = */ NULL, sizeof(struct fdsinfo64), - &pindex, MAXPROCENTRY)) > 0) - { - for (int i = 0; i < nprocs; i++) - { - tid64_t thindex; - int nthreads; - char arglist[MAXARGLN+1]; - char *cargs; - char *cmdline; - - if (procentry[i].pi_state == SNONE) continue; - /* if (procentry[i].pi_state == SZOMB) FIXME */ - - cmdline = procentry[i].pi_comm; - cargs = procentry[i].pi_comm; - if ( procentry[i].pi_flags & SKPROC ) - { - if (procentry[i].pi_pid == 0) - cmdline = "swapper"; - cargs = cmdline; - } - else - { - if (getargs(&procentry[i], sizeof(struct procentry64), arglist, MAXARGLN) >= 0) - { - int n; - - n = -1; - while (++n < MAXARGLN) - { - if (arglist[n] == '\0') - { - if (arglist[n+1] == '\0') - break; - arglist[n] = ' '; - } - } - cargs = arglist; - } - } - - pse.id = procentry[i].pi_pid; - pse.age = 0; - pse.num_lwp = procentry[i].pi_thcount; - pse.num_proc = 1; - - thindex=0; - while ((nthreads = getthrds64(procentry[i].pi_pid, - thrdentry, sizeof(struct thrdentry64), - &thindex, MAXTHRDENTRY)) > 0) - { - int j; - - for (j=0; j< nthreads; j++) - { - switch (thrdentry[j].ti_state) - { - /* case TSNONE: break; */ - case TSIDL: blocked++; break; /* FIXME is really blocked */ - case TSRUN: running++; break; - case TSSLEEP: sleeping++; break; - case TSSWAP: paging++; break; - case TSSTOP: stopped++; break; - case TSZOMB: zombies++; break; - } - } - if (nthreads < MAXTHRDENTRY) - break; - } - - /* tv_usec is nanosec ??? */ - pse.cpu_user_counter = procentry[i].pi_ru.ru_utime.tv_sec * 1000000 + - procentry[i].pi_ru.ru_utime.tv_usec / 1000; - - pse.cpu_system = 0; - /* tv_usec is nanosec ??? */ - pse.cpu_system_counter = procentry[i].pi_ru.ru_stime.tv_sec * 1000000 + - procentry[i].pi_ru.ru_stime.tv_usec / 1000; - - pse.vmem_minflt_counter = procentry[i].pi_minflt; - pse.vmem_majflt_counter = procentry[i].pi_majflt; - - pse.vmem_size = procentry[i].pi_tsize + procentry[i].pi_dvm * pagesize; - pse.vmem_rss = (procentry[i].pi_drss + procentry[i].pi_trss) * pagesize; - /* Not supported */ - pse.vmem_data = 0; - pse.vmem_code = 0; - pse.stack_size = 0; - - pse.io_rchar = -1; - pse.io_wchar = -1; - pse.io_syscr = -1; - pse.io_syscw = -1; - - pse.cswitch_vol = -1; - pse.cswitch_invol = -1; - - ps_list_add (cmdline, cargs, &pse); - } /* for (i = 0 .. nprocs) */ - - if (nprocs < MAXPROCENTRY) - break; - } /* while (getprocs64() > 0) */ - ps_submit_state ("running", running); - ps_submit_state ("sleeping", sleeping); - ps_submit_state ("zombies", zombies); - ps_submit_state ("stopped", stopped); - ps_submit_state ("paging", paging); - ps_submit_state ("blocked", blocked); - - for (procstat_t *ps = list_head_g; ps != NULL; ps = ps->next) - ps_submit_proc_list (ps); + /* AIX */ + int running = 0; + int sleeping = 0; + int zombies = 0; + int stopped = 0; + int paging = 0; + int blocked = 0; + + pid_t pindex = 0; + int nprocs; + + procstat_entry_t pse; + + ps_list_reset(); + while ((nprocs = getprocs64(procentry, sizeof(struct procentry64), + /* fdsinfo = */ NULL, sizeof(struct fdsinfo64), + &pindex, MAXPROCENTRY)) > 0) { + for (int i = 0; i < nprocs; i++) { + tid64_t thindex; + int nthreads; + char arglist[MAXARGLN + 1]; + char *cargs; + char *cmdline; + + if (procentry[i].pi_state == SNONE) + continue; + /* if (procentry[i].pi_state == SZOMB) FIXME */ + + cmdline = procentry[i].pi_comm; + cargs = procentry[i].pi_comm; + if (procentry[i].pi_flags & SKPROC) { + if (procentry[i].pi_pid == 0) + cmdline = "swapper"; + cargs = cmdline; + } else { + if (getargs(&procentry[i], sizeof(struct procentry64), arglist, + MAXARGLN) >= 0) { + int n; + + n = -1; + while (++n < MAXARGLN) { + if (arglist[n] == '\0') { + if (arglist[n + 1] == '\0') + break; + arglist[n] = ' '; + } + } + cargs = arglist; + } + } + + pse.id = procentry[i].pi_pid; + pse.age = 0; + pse.num_lwp = procentry[i].pi_thcount; + pse.num_proc = 1; + + thindex = 0; + while ((nthreads = getthrds64(procentry[i].pi_pid, thrdentry, + sizeof(struct thrdentry64), &thindex, + MAXTHRDENTRY)) > 0) { + int j; + + for (j = 0; j < nthreads; j++) { + switch (thrdentry[j].ti_state) { + /* case TSNONE: break; */ + case TSIDL: + blocked++; + break; /* FIXME is really blocked */ + case TSRUN: + running++; + break; + case TSSLEEP: + sleeping++; + break; + case TSSWAP: + paging++; + break; + case TSSTOP: + stopped++; + break; + case TSZOMB: + zombies++; + break; + } + } + if (nthreads < MAXTHRDENTRY) + break; + } + + /* tv_usec is nanosec ??? */ + pse.cpu_user_counter = procentry[i].pi_ru.ru_utime.tv_sec * 1000000 + + procentry[i].pi_ru.ru_utime.tv_usec / 1000; + + pse.cpu_system = 0; + /* tv_usec is nanosec ??? */ + pse.cpu_system_counter = procentry[i].pi_ru.ru_stime.tv_sec * 1000000 + + procentry[i].pi_ru.ru_stime.tv_usec / 1000; + + pse.vmem_minflt_counter = procentry[i].pi_minflt; + pse.vmem_majflt_counter = procentry[i].pi_majflt; + + pse.vmem_size = procentry[i].pi_tsize + procentry[i].pi_dvm * pagesize; + pse.vmem_rss = (procentry[i].pi_drss + procentry[i].pi_trss) * pagesize; + /* Not supported */ + pse.vmem_data = 0; + pse.vmem_code = 0; + pse.stack_size = 0; + + pse.io_rchar = -1; + pse.io_wchar = -1; + pse.io_syscr = -1; + pse.io_syscw = -1; + + pse.cswitch_vol = -1; + pse.cswitch_invol = -1; + + ps_list_add(cmdline, cargs, &pse); + } /* for (i = 0 .. nprocs) */ + + if (nprocs < MAXPROCENTRY) + break; + } /* while (getprocs64() > 0) */ + ps_submit_state("running", running); + ps_submit_state("sleeping", sleeping); + ps_submit_state("zombies", zombies); + ps_submit_state("stopped", stopped); + ps_submit_state("paging", paging); + ps_submit_state("blocked", blocked); + + for (procstat_t *ps = list_head_g; ps != NULL; ps = ps->next) + ps_submit_proc_list(ps); /* #endif HAVE_PROCINFO_H */ #elif KERNEL_SOLARIS - /* - * The Solaris section adds a few more process states and removes some - * process states compared to linux. Most notably there is no "PAGING" - * and "BLOCKED" state for a process. The rest is similar to the linux - * code. - */ - int running = 0; - int sleeping = 0; - int zombies = 0; - int stopped = 0; - int detached = 0; - int daemon = 0; - int system = 0; - int orphan = 0; - - struct dirent *ent; - DIR *proc; - - int status; - char state; - - char cmdline[PRARGSZ]; - - ps_list_reset (); - - proc = opendir ("/proc"); - if (proc == NULL) - return (-1); - - while ((ent = readdir(proc)) != NULL) - { - long pid; - struct procstat ps; - procstat_entry_t pse; - char *endptr; - - if (!isdigit ((int) ent->d_name[0])) - continue; - - pid = strtol (ent->d_name, &endptr, 10); - if (*endptr != 0) /* value didn't completely parse as a number */ - continue; - - status = ps_read_process (pid, &ps, &state); - if (status != 0) - { - DEBUG("ps_read_process failed: %i", status); - continue; - } - - memset (&pse, 0, sizeof (pse)); - pse.id = pid; - pse.age = 0; - - pse.num_proc = ps.num_proc; - pse.num_lwp = ps.num_lwp; - pse.vmem_size = ps.vmem_size; - pse.vmem_rss = ps.vmem_rss; - pse.vmem_data = ps.vmem_data; - pse.vmem_code = ps.vmem_code; - pse.stack_size = ps.stack_size; - - pse.vmem_minflt_counter = ps.vmem_minflt_counter; - pse.vmem_majflt_counter = ps.vmem_majflt_counter; - - pse.cpu_user_counter = ps.cpu_user_counter; - pse.cpu_system_counter = ps.cpu_system_counter; - - pse.io_rchar = ps.io_rchar; - pse.io_wchar = ps.io_wchar; - pse.io_syscr = ps.io_syscr; - pse.io_syscw = ps.io_syscw; - - pse.cswitch_vol = -1; - pse.cswitch_invol = -1; - - switch (state) - { - case 'R': running++; break; - case 'S': sleeping++; break; - case 'E': detached++; break; - case 'Z': zombies++; break; - case 'T': stopped++; break; - case 'A': daemon++; break; - case 'Y': system++; break; - case 'O': orphan++; break; - } - - - ps_list_add (ps.name, - ps_get_cmdline (pid, ps.name, cmdline, sizeof (cmdline)), - &pse); - } /* while(readdir) */ - closedir (proc); - - ps_submit_state ("running", running); - ps_submit_state ("sleeping", sleeping); - ps_submit_state ("zombies", zombies); - ps_submit_state ("stopped", stopped); - ps_submit_state ("detached", detached); - ps_submit_state ("daemon", daemon); - ps_submit_state ("system", system); - ps_submit_state ("orphan", orphan); - - for (procstat_t *ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next) - ps_submit_proc_list (ps_ptr); - - read_fork_rate(); + /* + * The Solaris section adds a few more process states and removes some + * process states compared to linux. Most notably there is no "PAGING" + * and "BLOCKED" state for a process. The rest is similar to the linux + * code. + */ + int running = 0; + int sleeping = 0; + int zombies = 0; + int stopped = 0; + int detached = 0; + int daemon = 0; + int system = 0; + int orphan = 0; + + struct dirent *ent; + DIR *proc; + + int status; + char state; + + char cmdline[PRARGSZ]; + + ps_list_reset(); + + proc = opendir("/proc"); + if (proc == NULL) + return (-1); + + while ((ent = readdir(proc)) != NULL) { + long pid; + struct procstat ps; + procstat_entry_t pse; + char *endptr; + + if (!isdigit((int)ent->d_name[0])) + continue; + + pid = strtol(ent->d_name, &endptr, 10); + if (*endptr != 0) /* value didn't completely parse as a number */ + continue; + + status = ps_read_process(pid, &ps, &state); + if (status != 0) { + DEBUG("ps_read_process failed: %i", status); + continue; + } + + memset(&pse, 0, sizeof(pse)); + pse.id = pid; + pse.age = 0; + + pse.num_proc = ps.num_proc; + pse.num_lwp = ps.num_lwp; + pse.vmem_size = ps.vmem_size; + pse.vmem_rss = ps.vmem_rss; + pse.vmem_data = ps.vmem_data; + pse.vmem_code = ps.vmem_code; + pse.stack_size = ps.stack_size; + + pse.vmem_minflt_counter = ps.vmem_minflt_counter; + pse.vmem_majflt_counter = ps.vmem_majflt_counter; + + pse.cpu_user_counter = ps.cpu_user_counter; + pse.cpu_system_counter = ps.cpu_system_counter; + + pse.io_rchar = ps.io_rchar; + pse.io_wchar = ps.io_wchar; + pse.io_syscr = ps.io_syscr; + pse.io_syscw = ps.io_syscw; + + pse.cswitch_vol = -1; + pse.cswitch_invol = -1; + + switch (state) { + case 'R': + running++; + break; + case 'S': + sleeping++; + break; + case 'E': + detached++; + break; + case 'Z': + zombies++; + break; + case 'T': + stopped++; + break; + case 'A': + daemon++; + break; + case 'Y': + system++; + break; + case 'O': + orphan++; + break; + } + + ps_list_add(ps.name, ps_get_cmdline(pid, ps.name, cmdline, sizeof(cmdline)), + &pse); + } /* while(readdir) */ + closedir(proc); + + ps_submit_state("running", running); + ps_submit_state("sleeping", sleeping); + ps_submit_state("zombies", zombies); + ps_submit_state("stopped", stopped); + ps_submit_state("detached", detached); + ps_submit_state("daemon", daemon); + ps_submit_state("system", system); + ps_submit_state("orphan", orphan); + + for (procstat_t *ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next) + ps_submit_proc_list(ps_ptr); + + read_fork_rate(); #endif /* KERNEL_SOLARIS */ - want_init = 0; + want_init = 0; - return (0); + return (0); } /* int ps_read */ -void module_register (void) -{ - plugin_register_complex_config ("processes", ps_config); - plugin_register_init ("processes", ps_init); - plugin_register_read ("processes", ps_read); +void module_register(void) { + plugin_register_complex_config("processes", ps_config); + plugin_register_init("processes", ps_init); + plugin_register_read("processes", ps_read); } /* void module_register */ diff --git a/src/protocols.c b/src/protocols.c index f7fd256b..64735e60 100644 --- a/src/protocols.c +++ b/src/protocols.c @@ -31,7 +31,7 @@ #include "utils_ignorelist.h" #if !KERNEL_LINUX -# error "No applicable input method." +#error "No applicable input method." #endif #define SNMP_FILE "/proc/net/snmp" @@ -40,45 +40,39 @@ /* * Global variables */ -static const char *config_keys[] = -{ - "Value", - "IgnoreSelected", +static const char *config_keys[] = { + "Value", "IgnoreSelected", }; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static ignorelist_t *values_list = NULL; /* * Functions */ -static void submit (const char *protocol_name, - const char *str_key, const char *str_value) -{ +static void submit(const char *protocol_name, const char *str_key, + const char *str_value) { value_t value; value_list_t vl = VALUE_LIST_INIT; int status; - status = parse_value (str_value, &value, DS_TYPE_DERIVE); - if (status != 0) - { - ERROR ("protocols plugin: Parsing string as integer failed: %s", - str_value); + status = parse_value(str_value, &value, DS_TYPE_DERIVE); + if (status != 0) { + ERROR("protocols plugin: Parsing string as integer failed: %s", str_value); return; } vl.values = &value; vl.values_len = 1; - sstrncpy (vl.plugin, "protocols", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, protocol_name, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, "protocol_counter", sizeof (vl.type)); - sstrncpy (vl.type_instance, str_key, sizeof (vl.type_instance)); + sstrncpy(vl.plugin, "protocols", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, protocol_name, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "protocol_counter", sizeof(vl.type)); + sstrncpy(vl.type_instance, str_key, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* void submit */ -static int read_file (const char *path) -{ +static int read_file(const char *path) { FILE *fh; char key_buffer[4096]; char value_buffer[4096]; @@ -91,119 +85,102 @@ static int read_file (const char *path) int status; int i; - fh = fopen (path, "r"); - if (fh == NULL) - { - ERROR ("protocols plugin: fopen (%s) failed: %s.", - path, sstrerror (errno, key_buffer, sizeof (key_buffer))); + fh = fopen(path, "r"); + if (fh == NULL) { + ERROR("protocols plugin: fopen (%s) failed: %s.", path, + sstrerror(errno, key_buffer, sizeof(key_buffer))); return (-1); } status = -1; - while (42) - { - clearerr (fh); - key_ptr = fgets (key_buffer, sizeof (key_buffer), fh); - if (key_ptr == NULL) - { - if (feof (fh) != 0) - { + while (42) { + clearerr(fh); + key_ptr = fgets(key_buffer, sizeof(key_buffer), fh); + if (key_ptr == NULL) { + if (feof(fh) != 0) { status = 0; break; - } - else if (ferror (fh) != 0) - { - ERROR ("protocols plugin: Reading from %s failed.", path); + } else if (ferror(fh) != 0) { + ERROR("protocols plugin: Reading from %s failed.", path); break; - } - else - { - ERROR ("protocols plugin: fgets failed for an unknown reason."); + } else { + ERROR("protocols plugin: fgets failed for an unknown reason."); break; } } /* if (key_ptr == NULL) */ - value_ptr = fgets (value_buffer, sizeof (value_buffer), fh); - if (value_ptr == NULL) - { - ERROR ("protocols plugin: read_file (%s): Could not read values line.", - path); + value_ptr = fgets(value_buffer, sizeof(value_buffer), fh); + if (value_ptr == NULL) { + ERROR("protocols plugin: read_file (%s): Could not read values line.", + path); break; } - key_ptr = strchr (key_buffer, ':'); - if (key_ptr == NULL) - { - ERROR ("protocols plugin: Could not find protocol name in keys line."); + key_ptr = strchr(key_buffer, ':'); + if (key_ptr == NULL) { + ERROR("protocols plugin: Could not find protocol name in keys line."); break; } *key_ptr = 0; key_ptr++; - value_ptr = strchr (value_buffer, ':'); - if (value_ptr == NULL) - { - ERROR ("protocols plugin: Could not find protocol name " - "in values line."); + value_ptr = strchr(value_buffer, ':'); + if (value_ptr == NULL) { + ERROR("protocols plugin: Could not find protocol name " + "in values line."); break; } *value_ptr = 0; value_ptr++; - if (strcmp (key_buffer, value_buffer) != 0) - { - ERROR ("protocols plugin: Protocol names in keys and values lines " - "don't match: `%s' vs. `%s'.", - key_buffer, value_buffer); + if (strcmp(key_buffer, value_buffer) != 0) { + ERROR("protocols plugin: Protocol names in keys and values lines " + "don't match: `%s' vs. `%s'.", + key_buffer, value_buffer); break; } + key_fields_num = + strsplit(key_ptr, key_fields, STATIC_ARRAY_SIZE(key_fields)); + value_fields_num = + strsplit(value_ptr, value_fields, STATIC_ARRAY_SIZE(value_fields)); - key_fields_num = strsplit (key_ptr, - key_fields, STATIC_ARRAY_SIZE (key_fields)); - value_fields_num = strsplit (value_ptr, - value_fields, STATIC_ARRAY_SIZE (value_fields)); - - if (key_fields_num != value_fields_num) - { - ERROR ("protocols plugin: Number of fields in keys and values lines " - "don't match: %i vs %i.", - key_fields_num, value_fields_num); + if (key_fields_num != value_fields_num) { + ERROR("protocols plugin: Number of fields in keys and values lines " + "don't match: %i vs %i.", + key_fields_num, value_fields_num); break; } - for (i = 0; i < key_fields_num; i++) - { - if (values_list != NULL) - { + for (i = 0; i < key_fields_num; i++) { + if (values_list != NULL) { char match_name[2 * DATA_MAX_NAME_LEN]; - ssnprintf (match_name, sizeof (match_name), "%s:%s", - key_buffer, key_fields[i]); + ssnprintf(match_name, sizeof(match_name), "%s:%s", key_buffer, + key_fields[i]); - if (ignorelist_match (values_list, match_name)) + if (ignorelist_match(values_list, match_name)) continue; } /* if (values_list != NULL) */ - submit (key_buffer, key_fields[i], value_fields[i]); + submit(key_buffer, key_fields[i], value_fields[i]); } /* for (i = 0; i < key_fields_num; i++) */ - } /* while (42) */ + } /* while (42) */ - fclose (fh); + fclose(fh); return (status); } /* int read_file */ -static int protocols_read (void) -{ +static int protocols_read(void) { int status; int success = 0; - status = read_file (SNMP_FILE); + status = read_file(SNMP_FILE); if (status == 0) success++; - status = read_file (NETSTAT_FILE); + status = read_file(NETSTAT_FILE); if (status == 0) success++; @@ -213,35 +190,28 @@ static int protocols_read (void) return (0); } /* int protocols_read */ -static int protocols_config (const char *key, const char *value) -{ +static int protocols_config(const char *key, const char *value) { if (values_list == NULL) - values_list = ignorelist_create (/* invert = */ 1); + values_list = ignorelist_create(/* invert = */ 1); - if (strcasecmp (key, "Value") == 0) - { - ignorelist_add (values_list, value); - } - else if (strcasecmp (key, "IgnoreSelected") == 0) - { + if (strcasecmp(key, "Value") == 0) { + ignorelist_add(values_list, value); + } else if (strcasecmp(key, "IgnoreSelected") == 0) { int invert = 1; - if (IS_TRUE (value)) + if (IS_TRUE(value)) invert = 0; - ignorelist_set_invert (values_list, invert); - } - else - { + ignorelist_set_invert(values_list, invert); + } else { return (-1); } return (0); } /* int protocols_config */ -void module_register (void) -{ - plugin_register_config ("protocols", protocols_config, - config_keys, config_keys_num); - plugin_register_read ("protocols", protocols_read); +void module_register(void) { + plugin_register_config("protocols", protocols_config, config_keys, + config_keys_num); + plugin_register_read("protocols", protocols_read); } /* void module_register */ /* vim: set sw=2 sts=2 et : */ diff --git a/src/pyconfig.c b/src/pyconfig.c index 83748b4f..c6e89306 100644 --- a/src/pyconfig.c +++ b/src/pyconfig.c @@ -33,186 +33,191 @@ #include "cpython.h" -static char config_doc[] = "This represents a piece of collectd's config file.\n" - "It is passed to scripts with config callbacks (see \"register_config\")\n" - "and is of little use if created somewhere else.\n" - "\n" - "It has no methods beyond the bare minimum and only exists for its\n" - "data members"; - -static char parent_doc[] = "This represents the parent of this node. On the root node\n" - "of the config tree it will be None.\n"; - -static char key_doc[] = "This is the keyword of this item, ie the first word of any\n" - "given line in the config file. It will always be a string.\n"; - -static char values_doc[] = "This is a tuple (which might be empty) of all value, ie words\n" - "following the keyword in any given line in the config file.\n" - "\n" - "Every item in this tuple will be either a string or a float or a bool,\n" - "depending on the contents of the configuration file.\n"; - -static char children_doc[] = "This is a tuple of child nodes. For most nodes this will be\n" - "empty. If this node represents a block instead of a single line of the config\n" - "file it will contain all nodes in this block.\n"; - -static PyObject *Config_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - Config *self; - - self = (Config *) type->tp_alloc(type, 0); - if (self == NULL) - return NULL; - - self->parent = NULL; - self->key = NULL; - self->values = NULL; - self->children = NULL; - return (PyObject *) self; +static char config_doc[] = + "This represents a piece of collectd's config file.\n" + "It is passed to scripts with config callbacks (see \"register_config\")\n" + "and is of little use if created somewhere else.\n" + "\n" + "It has no methods beyond the bare minimum and only exists for its\n" + "data members"; + +static char parent_doc[] = + "This represents the parent of this node. On the root node\n" + "of the config tree it will be None.\n"; + +static char key_doc[] = + "This is the keyword of this item, ie the first word of any\n" + "given line in the config file. It will always be a string.\n"; + +static char values_doc[] = + "This is a tuple (which might be empty) of all value, ie words\n" + "following the keyword in any given line in the config file.\n" + "\n" + "Every item in this tuple will be either a string or a float or a bool,\n" + "depending on the contents of the configuration file.\n"; + +static char children_doc[] = + "This is a tuple of child nodes. For most nodes this will be\n" + "empty. If this node represents a block instead of a single line of the " + "config\n" + "file it will contain all nodes in this block.\n"; + +static PyObject *Config_new(PyTypeObject *type, PyObject *args, + PyObject *kwds) { + Config *self; + + self = (Config *)type->tp_alloc(type, 0); + if (self == NULL) + return NULL; + + self->parent = NULL; + self->key = NULL; + self->values = NULL; + self->children = NULL; + return (PyObject *)self; } static int Config_init(PyObject *s, PyObject *args, PyObject *kwds) { - PyObject *key = NULL, *parent = NULL, *values = NULL, *children = NULL, *tmp; - Config *self = (Config *) s; - static char *kwlist[] = {"key", "parent", "values", "children", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OOO", kwlist, - &key, &parent, &values, &children)) - return -1; - - if (!IS_BYTES_OR_UNICODE(key)) { - PyErr_SetString(PyExc_TypeError, "argument 1 must be str"); - Py_XDECREF(parent); - Py_XDECREF(values); - Py_XDECREF(children); - return -1; - } - if (values == NULL) { - values = PyTuple_New(0); - PyErr_Clear(); - } - if (children == NULL) { - children = PyTuple_New(0); - PyErr_Clear(); - } - tmp = self->key; - Py_INCREF(key); - self->key = key; - Py_XDECREF(tmp); - if (parent != NULL) { - tmp = self->parent; - Py_INCREF(parent); - self->parent = parent; - Py_XDECREF(tmp); - } - if (values != NULL) { - tmp = self->values; - Py_INCREF(values); - self->values = values; - Py_XDECREF(tmp); - } - if (children != NULL) { - tmp = self->children; - Py_INCREF(children); - self->children = children; - Py_XDECREF(tmp); - } - return 0; + PyObject *key = NULL, *parent = NULL, *values = NULL, *children = NULL, *tmp; + Config *self = (Config *)s; + static char *kwlist[] = {"key", "parent", "values", "children", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OOO", kwlist, &key, &parent, + &values, &children)) + return -1; + + if (!IS_BYTES_OR_UNICODE(key)) { + PyErr_SetString(PyExc_TypeError, "argument 1 must be str"); + Py_XDECREF(parent); + Py_XDECREF(values); + Py_XDECREF(children); + return -1; + } + if (values == NULL) { + values = PyTuple_New(0); + PyErr_Clear(); + } + if (children == NULL) { + children = PyTuple_New(0); + PyErr_Clear(); + } + tmp = self->key; + Py_INCREF(key); + self->key = key; + Py_XDECREF(tmp); + if (parent != NULL) { + tmp = self->parent; + Py_INCREF(parent); + self->parent = parent; + Py_XDECREF(tmp); + } + if (values != NULL) { + tmp = self->values; + Py_INCREF(values); + self->values = values; + Py_XDECREF(tmp); + } + if (children != NULL) { + tmp = self->children; + Py_INCREF(children); + self->children = children; + Py_XDECREF(tmp); + } + return 0; } static PyObject *Config_repr(PyObject *s) { - Config *self = (Config *) s; - PyObject *ret = NULL; - static PyObject *node_prefix = NULL, *root_prefix = NULL, *ending = NULL; - - /* This is ok because we have the GIL, so this is thread-save by default. */ - if (node_prefix == NULL) - node_prefix = cpy_string_to_unicode_or_bytes(""); - if (node_prefix == NULL || root_prefix == NULL || ending == NULL) - return NULL; - - ret = PyObject_Str(self->key); - CPY_SUBSTITUTE(PyObject_Repr, ret, ret); - if (self->parent == NULL || self->parent == Py_None) - CPY_STRCAT(&ret, root_prefix); - else - CPY_STRCAT(&ret, node_prefix); - CPY_STRCAT(&ret, ending); - - return ret; + Config *self = (Config *)s; + PyObject *ret = NULL; + static PyObject *node_prefix = NULL, *root_prefix = NULL, *ending = NULL; + + /* This is ok because we have the GIL, so this is thread-save by default. */ + if (node_prefix == NULL) + node_prefix = cpy_string_to_unicode_or_bytes(""); + if (node_prefix == NULL || root_prefix == NULL || ending == NULL) + return NULL; + + ret = PyObject_Str(self->key); + CPY_SUBSTITUTE(PyObject_Repr, ret, ret); + if (self->parent == NULL || self->parent == Py_None) + CPY_STRCAT(&ret, root_prefix); + else + CPY_STRCAT(&ret, node_prefix); + CPY_STRCAT(&ret, ending); + + return ret; } static int Config_traverse(PyObject *self, visitproc visit, void *arg) { - Config *c = (Config *) self; - Py_VISIT(c->parent); - Py_VISIT(c->key); - Py_VISIT(c->values); - Py_VISIT(c->children); - return 0;} + Config *c = (Config *)self; + Py_VISIT(c->parent); + Py_VISIT(c->key); + Py_VISIT(c->values); + Py_VISIT(c->children); + return 0; +} static int Config_clear(PyObject *self) { - Config *c = (Config *) self; - Py_CLEAR(c->parent); - Py_CLEAR(c->key); - Py_CLEAR(c->values); - Py_CLEAR(c->children); - return 0; + Config *c = (Config *)self; + Py_CLEAR(c->parent); + Py_CLEAR(c->key); + Py_CLEAR(c->values); + Py_CLEAR(c->children); + return 0; } static void Config_dealloc(PyObject *self) { - Config_clear(self); - self->ob_type->tp_free(self); + Config_clear(self); + self->ob_type->tp_free(self); } static PyMemberDef Config_members[] = { - {"parent", T_OBJECT, offsetof(Config, parent), 0, parent_doc}, - {"key", T_OBJECT_EX, offsetof(Config, key), 0, key_doc}, - {"values", T_OBJECT_EX, offsetof(Config, values), 0, values_doc}, - {"children", T_OBJECT_EX, offsetof(Config, children), 0, children_doc}, - {NULL} -}; + {"parent", T_OBJECT, offsetof(Config, parent), 0, parent_doc}, + {"key", T_OBJECT_EX, offsetof(Config, key), 0, key_doc}, + {"values", T_OBJECT_EX, offsetof(Config, values), 0, values_doc}, + {"children", T_OBJECT_EX, offsetof(Config, children), 0, children_doc}, + {NULL}}; PyTypeObject ConfigType = { - CPY_INIT_TYPE - "collectd.Config", /* tp_name */ - sizeof(Config), /* tp_basicsize */ - 0, /* Will be filled in later */ - Config_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - Config_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - config_doc, /* tp_doc */ - Config_traverse, /* tp_traverse */ - Config_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - Config_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - Config_init, /* tp_init */ - 0, /* tp_alloc */ - Config_new /* tp_new */ + CPY_INIT_TYPE "collectd.Config", /* tp_name */ + sizeof(Config), /* tp_basicsize */ + 0, /* Will be filled in later */ + Config_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + Config_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + config_doc, /* tp_doc */ + Config_traverse, /* tp_traverse */ + Config_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + Config_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + Config_init, /* tp_init */ + 0, /* tp_alloc */ + Config_new /* tp_new */ }; - diff --git a/src/python.c b/src/python.c index 0dae99d8..c6ee5544 100644 --- a/src/python.c +++ b/src/python.c @@ -36,188 +36,202 @@ #include "cpython.h" typedef struct cpy_callback_s { - char *name; - PyObject *callback; - PyObject *data; - struct cpy_callback_s *next; + char *name; + PyObject *callback; + PyObject *data; + struct cpy_callback_s *next; } cpy_callback_t; static char log_doc[] = "This function sends a string to all logging plugins."; -static char get_ds_doc[] = "get_dataset(name) -> definition\n" - "\n" - "Returns the definition of a dataset specified by name.\n" - "\n" - "'name' is a string specifying the dataset to query.\n" - "'definition' is a list of 4-tuples. Every tuple represents a \n" - " data source within the data set and its 4 values are the \n" - " name, type, min and max value.\n" - " 'name' is a string.\n" - " 'type' is a string that is equal to either DS_TYPE_COUNTER,\n" - " DS_TYPE_GAUGE, DS_TYPE_DERIVE or DS_TYPE_ABSOLUTE.\n" - " 'min' and 'max' are either a float or None."; +static char get_ds_doc[] = + "get_dataset(name) -> definition\n" + "\n" + "Returns the definition of a dataset specified by name.\n" + "\n" + "'name' is a string specifying the dataset to query.\n" + "'definition' is a list of 4-tuples. Every tuple represents a \n" + " data source within the data set and its 4 values are the \n" + " name, type, min and max value.\n" + " 'name' is a string.\n" + " 'type' is a string that is equal to either DS_TYPE_COUNTER,\n" + " DS_TYPE_GAUGE, DS_TYPE_DERIVE or DS_TYPE_ABSOLUTE.\n" + " 'min' and 'max' are either a float or None."; static char flush_doc[] = "flush([plugin][, timeout][, identifier]) -> None\n" - "\n" - "Flushes the cache of another plugin."; - -static char unregister_doc[] = "Unregisters a callback. This function needs exactly one parameter either\n" - "the function to unregister or the callback identifier to unregister."; - -static char reg_log_doc[] = "register_log(callback[, data][, name]) -> identifier\n" - "\n" - "Register a callback function for log messages.\n" - "\n" - "'callback' is a callable object that will be called every time something\n" - " is logged.\n" - "'data' is an optional object that will be passed back to the callback\n" - " function every time it is called.\n" - "'name' is an optional identifier for this callback. The default name\n" - " is 'python.'.\n" - " Every callback needs a unique identifier, so if you want to\n" - " register this callback multiple time from the same module you need\n" - " to specify a name here.\n" - "'identifier' is the full identifier assigned to this callback.\n" - "\n" - "The callback function will be called with two or three parameters:\n" - "severity: An integer that should be compared to the LOG_ constants.\n" - "message: The text to be logged.\n" - "data: The optional data parameter passed to the register function.\n" - " If the parameter was omitted it will be omitted here, too."; - -static char reg_init_doc[] = "register_init(callback[, data][, name]) -> identifier\n" - "\n" - "Register a callback function that will be executed once after the config.\n" - "file has been read, all plugins heve been loaded and the collectd has\n" - "forked into the background.\n" - "\n" - "'callback' is a callable object that will be executed.\n" - "'data' is an optional object that will be passed back to the callback\n" - " function when it is called.\n" - "'name' is an optional identifier for this callback. The default name\n" - " is 'python.'.\n" - " Every callback needs a unique identifier, so if you want to\n" - " register this callback multiple time from the same module you need\n" - " to specify a name here.\n" - "'identifier' is the full identifier assigned to this callback.\n" - "\n" - "The callback function will be called without parameters, except for\n" - "data if it was supplied."; - -static char reg_config_doc[] = "register_config(callback[, data][, name]) -> identifier\n" - "\n" - "Register a callback function for config file entries.\n" - "'callback' is a callable object that will be called for every config block.\n" - "'data' is an optional object that will be passed back to the callback\n" - " function every time it is called.\n" - "'name' is an optional identifier for this callback. The default name\n" - " is 'python.'.\n" - " Every callback needs a unique identifier, so if you want to\n" - " register this callback multiple time from the same module you need\n" - " to specify a name here.\n" - "'identifier' is the full identifier assigned to this callback.\n" - "\n" - "The callback function will be called with one or two parameters:\n" - "config: A Config object.\n" - "data: The optional data parameter passed to the register function.\n" - " If the parameter was omitted it will be omitted here, too."; - -static char reg_read_doc[] = "register_read(callback[, interval][, data][, name]) -> identifier\n" - "\n" - "Register a callback function for reading data. It will just be called\n" - "in a fixed interval to signal that it's time to dispatch new values.\n" - "'callback' is a callable object that will be called every time something\n" - " is logged.\n" - "'interval' is the number of seconds between between calls to the callback\n" - " function. Full float precision is supported here.\n" - "'data' is an optional object that will be passed back to the callback\n" - " function every time it is called.\n" - "'name' is an optional identifier for this callback. The default name\n" - " is 'python.'.\n" - " Every callback needs a unique identifier, so if you want to\n" - " register this callback multiple time from the same module you need\n" - " to specify a name here.\n" - "'identifier' is the full identifier assigned to this callback.\n" - "\n" - "The callback function will be called without parameters, except for\n" - "data if it was supplied."; - -static char reg_write_doc[] = "register_write(callback[, data][, name]) -> identifier\n" - "\n" - "Register a callback function to receive values dispatched by other plugins.\n" - "'callback' is a callable object that will be called every time a value\n" - " is dispatched.\n" - "'data' is an optional object that will be passed back to the callback\n" - " function every time it is called.\n" - "'name' is an optional identifier for this callback. The default name\n" - " is 'python.'.\n" - " Every callback needs a unique identifier, so if you want to\n" - " register this callback multiple time from the same module you need\n" - " to specify a name here.\n" - "'identifier' is the full identifier assigned to this callback.\n" - "\n" - "The callback function will be called with one or two parameters:\n" - "values: A Values object which is a copy of the dispatched values.\n" - "data: The optional data parameter passed to the register function.\n" - " If the parameter was omitted it will be omitted here, too."; - -static char reg_notification_doc[] = "register_notification(callback[, data][, name]) -> identifier\n" - "\n" - "Register a callback function for notifications.\n" - "'callback' is a callable object that will be called every time a notification\n" - " is dispatched.\n" - "'data' is an optional object that will be passed back to the callback\n" - " function every time it is called.\n" - "'name' is an optional identifier for this callback. The default name\n" - " is 'python.'.\n" - " Every callback needs a unique identifier, so if you want to\n" - " register this callback multiple time from the same module you need\n" - " to specify a name here.\n" - "'identifier' is the full identifier assigned to this callback.\n" - "\n" - "The callback function will be called with one or two parameters:\n" - "notification: A copy of the notification that was dispatched.\n" - "data: The optional data parameter passed to the register function.\n" - " If the parameter was omitted it will be omitted here, too."; - -static char reg_flush_doc[] = "register_flush(callback[, data][, name]) -> identifier\n" - "\n" - "Register a callback function for flush messages.\n" - "'callback' is a callable object that will be called every time a plugin\n" - " requests a flush for either this or all plugins.\n" - "'data' is an optional object that will be passed back to the callback\n" - " function every time it is called.\n" - "'name' is an optional identifier for this callback. The default name\n" - " is 'python.'.\n" - " Every callback needs a unique identifier, so if you want to\n" - " register this callback multiple time from the same module you need\n" - " to specify a name here.\n" - "'identifier' is the full identifier assigned to this callback.\n" - "\n" - "The callback function will be called with two or three parameters:\n" - "timeout: Indicates that only data older than 'timeout' seconds is to\n" - " be flushed.\n" - "id: Specifies which values are to be flushed. Might be None.\n" - "data: The optional data parameter passed to the register function.\n" - " If the parameter was omitted it will be omitted here, too."; - -static char reg_shutdown_doc[] = "register_shutdown(callback[, data][, name]) -> identifier\n" - "\n" - "Register a callback function for collectd shutdown.\n" - "'callback' is a callable object that will be called once collectd is\n" - " shutting down.\n" - "'data' is an optional object that will be passed back to the callback\n" - " function if it is called.\n" - "'name' is an optional identifier for this callback. The default name\n" - " is 'python.'.\n" - " Every callback needs a unique identifier, so if you want to\n" - " register this callback multiple time from the same module you need\n" - " to specify a name here.\n" - "'identifier' is the full identifier assigned to this callback.\n" - "\n" - "The callback function will be called with no parameters except for\n" - " data if it was supplied."; - + "\n" + "Flushes the cache of another plugin."; + +static char unregister_doc[] = + "Unregisters a callback. This function needs exactly one parameter either\n" + "the function to unregister or the callback identifier to unregister."; + +static char reg_log_doc[] = + "register_log(callback[, data][, name]) -> identifier\n" + "\n" + "Register a callback function for log messages.\n" + "\n" + "'callback' is a callable object that will be called every time something\n" + " is logged.\n" + "'data' is an optional object that will be passed back to the callback\n" + " function every time it is called.\n" + "'name' is an optional identifier for this callback. The default name\n" + " is 'python.'.\n" + " Every callback needs a unique identifier, so if you want to\n" + " register this callback multiple time from the same module you need\n" + " to specify a name here.\n" + "'identifier' is the full identifier assigned to this callback.\n" + "\n" + "The callback function will be called with two or three parameters:\n" + "severity: An integer that should be compared to the LOG_ constants.\n" + "message: The text to be logged.\n" + "data: The optional data parameter passed to the register function.\n" + " If the parameter was omitted it will be omitted here, too."; + +static char reg_init_doc[] = + "register_init(callback[, data][, name]) -> identifier\n" + "\n" + "Register a callback function that will be executed once after the " + "config.\n" + "file has been read, all plugins heve been loaded and the collectd has\n" + "forked into the background.\n" + "\n" + "'callback' is a callable object that will be executed.\n" + "'data' is an optional object that will be passed back to the callback\n" + " function when it is called.\n" + "'name' is an optional identifier for this callback. The default name\n" + " is 'python.'.\n" + " Every callback needs a unique identifier, so if you want to\n" + " register this callback multiple time from the same module you need\n" + " to specify a name here.\n" + "'identifier' is the full identifier assigned to this callback.\n" + "\n" + "The callback function will be called without parameters, except for\n" + "data if it was supplied."; + +static char reg_config_doc[] = + "register_config(callback[, data][, name]) -> identifier\n" + "\n" + "Register a callback function for config file entries.\n" + "'callback' is a callable object that will be called for every config " + "block.\n" + "'data' is an optional object that will be passed back to the callback\n" + " function every time it is called.\n" + "'name' is an optional identifier for this callback. The default name\n" + " is 'python.'.\n" + " Every callback needs a unique identifier, so if you want to\n" + " register this callback multiple time from the same module you need\n" + " to specify a name here.\n" + "'identifier' is the full identifier assigned to this callback.\n" + "\n" + "The callback function will be called with one or two parameters:\n" + "config: A Config object.\n" + "data: The optional data parameter passed to the register function.\n" + " If the parameter was omitted it will be omitted here, too."; + +static char reg_read_doc[] = + "register_read(callback[, interval][, data][, name]) -> identifier\n" + "\n" + "Register a callback function for reading data. It will just be called\n" + "in a fixed interval to signal that it's time to dispatch new values.\n" + "'callback' is a callable object that will be called every time something\n" + " is logged.\n" + "'interval' is the number of seconds between between calls to the " + "callback\n" + " function. Full float precision is supported here.\n" + "'data' is an optional object that will be passed back to the callback\n" + " function every time it is called.\n" + "'name' is an optional identifier for this callback. The default name\n" + " is 'python.'.\n" + " Every callback needs a unique identifier, so if you want to\n" + " register this callback multiple time from the same module you need\n" + " to specify a name here.\n" + "'identifier' is the full identifier assigned to this callback.\n" + "\n" + "The callback function will be called without parameters, except for\n" + "data if it was supplied."; + +static char reg_write_doc[] = + "register_write(callback[, data][, name]) -> identifier\n" + "\n" + "Register a callback function to receive values dispatched by other " + "plugins.\n" + "'callback' is a callable object that will be called every time a value\n" + " is dispatched.\n" + "'data' is an optional object that will be passed back to the callback\n" + " function every time it is called.\n" + "'name' is an optional identifier for this callback. The default name\n" + " is 'python.'.\n" + " Every callback needs a unique identifier, so if you want to\n" + " register this callback multiple time from the same module you need\n" + " to specify a name here.\n" + "'identifier' is the full identifier assigned to this callback.\n" + "\n" + "The callback function will be called with one or two parameters:\n" + "values: A Values object which is a copy of the dispatched values.\n" + "data: The optional data parameter passed to the register function.\n" + " If the parameter was omitted it will be omitted here, too."; + +static char reg_notification_doc[] = + "register_notification(callback[, data][, name]) -> identifier\n" + "\n" + "Register a callback function for notifications.\n" + "'callback' is a callable object that will be called every time a " + "notification\n" + " is dispatched.\n" + "'data' is an optional object that will be passed back to the callback\n" + " function every time it is called.\n" + "'name' is an optional identifier for this callback. The default name\n" + " is 'python.'.\n" + " Every callback needs a unique identifier, so if you want to\n" + " register this callback multiple time from the same module you need\n" + " to specify a name here.\n" + "'identifier' is the full identifier assigned to this callback.\n" + "\n" + "The callback function will be called with one or two parameters:\n" + "notification: A copy of the notification that was dispatched.\n" + "data: The optional data parameter passed to the register function.\n" + " If the parameter was omitted it will be omitted here, too."; + +static char reg_flush_doc[] = + "register_flush(callback[, data][, name]) -> identifier\n" + "\n" + "Register a callback function for flush messages.\n" + "'callback' is a callable object that will be called every time a plugin\n" + " requests a flush for either this or all plugins.\n" + "'data' is an optional object that will be passed back to the callback\n" + " function every time it is called.\n" + "'name' is an optional identifier for this callback. The default name\n" + " is 'python.'.\n" + " Every callback needs a unique identifier, so if you want to\n" + " register this callback multiple time from the same module you need\n" + " to specify a name here.\n" + "'identifier' is the full identifier assigned to this callback.\n" + "\n" + "The callback function will be called with two or three parameters:\n" + "timeout: Indicates that only data older than 'timeout' seconds is to\n" + " be flushed.\n" + "id: Specifies which values are to be flushed. Might be None.\n" + "data: The optional data parameter passed to the register function.\n" + " If the parameter was omitted it will be omitted here, too."; + +static char reg_shutdown_doc[] = + "register_shutdown(callback[, data][, name]) -> identifier\n" + "\n" + "Register a callback function for collectd shutdown.\n" + "'callback' is a callable object that will be called once collectd is\n" + " shutting down.\n" + "'data' is an optional object that will be passed back to the callback\n" + " function if it is called.\n" + "'name' is an optional identifier for this callback. The default name\n" + " is 'python.'.\n" + " Every callback needs a unique identifier, so if you want to\n" + " register this callback multiple time from the same module you need\n" + " to specify a name here.\n" + "'identifier' is the full identifier assigned to this callback.\n" + "\n" + "The callback function will be called with no parameters except for\n" + " data if it was supplied."; static pthread_t main_thread; static PyOS_sighandler_t python_sigint_handler; @@ -241,1069 +255,1153 @@ static int cpy_shutdown_triggered = 0; static int cpy_num_callbacks = 0; static void cpy_destroy_user_data(void *data) { - cpy_callback_t *c = data; - free(c->name); - CPY_LOCK_THREADS - Py_DECREF(c->callback); - Py_XDECREF(c->data); - free(c); - --cpy_num_callbacks; - if (!cpy_num_callbacks && cpy_shutdown_triggered) { - Py_Finalize(); - return; - } - CPY_RELEASE_THREADS + cpy_callback_t *c = data; + free(c->name); + CPY_LOCK_THREADS + Py_DECREF(c->callback); + Py_XDECREF(c->data); + free(c); + --cpy_num_callbacks; + if (!cpy_num_callbacks && cpy_shutdown_triggered) { + Py_Finalize(); + return; + } + CPY_RELEASE_THREADS } /* You must hold the GIL to call this function! - * But if you managed to extract the callback parameter then you probably already do. */ - -static void cpy_build_name(char *buf, size_t size, PyObject *callback, const char *name) { - const char *module = NULL; - PyObject *mod = NULL; - - if (name != NULL) { - snprintf(buf, size, "python.%s", name); - return; - } - - mod = PyObject_GetAttrString(callback, "__module__"); /* New reference. */ - if (mod != NULL) - module = cpy_unicode_or_bytes_to_string(&mod); - - if (module != NULL) { - snprintf(buf, size, "python.%s", module); - Py_XDECREF(mod); - PyErr_Clear(); - return; - } - Py_XDECREF(mod); - - snprintf(buf, size, "python.%p", callback); - PyErr_Clear(); + * But if you managed to extract the callback parameter then you probably + * already do. */ + +static void cpy_build_name(char *buf, size_t size, PyObject *callback, + const char *name) { + const char *module = NULL; + PyObject *mod = NULL; + + if (name != NULL) { + snprintf(buf, size, "python.%s", name); + return; + } + + mod = PyObject_GetAttrString(callback, "__module__"); /* New reference. */ + if (mod != NULL) + module = cpy_unicode_or_bytes_to_string(&mod); + + if (module != NULL) { + snprintf(buf, size, "python.%s", module); + Py_XDECREF(mod); + PyErr_Clear(); + return; + } + Py_XDECREF(mod); + + snprintf(buf, size, "python.%p", callback); + PyErr_Clear(); } void cpy_log_exception(const char *context) { - int l = 0; - const char *typename = NULL, *message = NULL; - PyObject *type, *value, *traceback, *tn, *m, *list; - - PyErr_Fetch(&type, &value, &traceback); - PyErr_NormalizeException(&type, &value, &traceback); - if (type == NULL) return; - tn = PyObject_GetAttrString(type, "__name__"); /* New reference. */ - m = PyObject_Str(value); /* New reference. */ - if (tn != NULL) - typename = cpy_unicode_or_bytes_to_string(&tn); - if (m != NULL) - message = cpy_unicode_or_bytes_to_string(&m); - if (typename == NULL) - typename = "NamelessException"; - if (message == NULL) - message = "N/A"; - Py_BEGIN_ALLOW_THREADS - ERROR("Unhandled python exception in %s: %s: %s", context, typename, message); - Py_END_ALLOW_THREADS - Py_XDECREF(tn); - Py_XDECREF(m); - if (!cpy_format_exception || !traceback) { - PyErr_Clear(); - Py_DECREF(type); - Py_XDECREF(value); - Py_XDECREF(traceback); - return; - } - list = PyObject_CallFunction(cpy_format_exception, "NNN", type, value, traceback); /* New reference. Steals references from "type", "value" and "traceback". */ - if (list) - l = PyObject_Length(list); - - for (int i = 0; i < l; ++i) { - PyObject *line; - char const *msg; - char *cpy; - - line = PyList_GET_ITEM(list, i); /* Borrowed reference. */ - Py_INCREF(line); - - msg = cpy_unicode_or_bytes_to_string(&line); - Py_DECREF(line); - if (msg == NULL) - continue; - - cpy = strdup(msg); - if (cpy == NULL) - continue; - - if (cpy[strlen(cpy) - 1] == '\n') - cpy[strlen(cpy) - 1] = 0; - - Py_BEGIN_ALLOW_THREADS - ERROR("%s", cpy); - Py_END_ALLOW_THREADS - - free(cpy); - } - - Py_XDECREF(list); - PyErr_Clear(); + int l = 0; + const char *typename = NULL, *message = NULL; + PyObject *type, *value, *traceback, *tn, *m, *list; + + PyErr_Fetch(&type, &value, &traceback); + PyErr_NormalizeException(&type, &value, &traceback); + if (type == NULL) + return; + tn = PyObject_GetAttrString(type, "__name__"); /* New reference. */ + m = PyObject_Str(value); /* New reference. */ + if (tn != NULL) + typename = cpy_unicode_or_bytes_to_string(&tn); + if (m != NULL) + message = cpy_unicode_or_bytes_to_string(&m); + if (typename == NULL) + typename = "NamelessException"; + if (message == NULL) + message = "N/A"; + Py_BEGIN_ALLOW_THREADS ERROR("Unhandled python exception in %s: %s: %s", + context, typename, message); + Py_END_ALLOW_THREADS Py_XDECREF(tn); + Py_XDECREF(m); + if (!cpy_format_exception || !traceback) { + PyErr_Clear(); + Py_DECREF(type); + Py_XDECREF(value); + Py_XDECREF(traceback); + return; + } + list = PyObject_CallFunction(cpy_format_exception, "NNN", type, value, + traceback); /* New reference. Steals references + from "type", "value" and + "traceback". */ + if (list) + l = PyObject_Length(list); + + for (int i = 0; i < l; ++i) { + PyObject *line; + char const *msg; + char *cpy; + + line = PyList_GET_ITEM(list, i); /* Borrowed reference. */ + Py_INCREF(line); + + msg = cpy_unicode_or_bytes_to_string(&line); + Py_DECREF(line); + if (msg == NULL) + continue; + + cpy = strdup(msg); + if (cpy == NULL) + continue; + + if (cpy[strlen(cpy) - 1] == '\n') + cpy[strlen(cpy) - 1] = 0; + + Py_BEGIN_ALLOW_THREADS ERROR("%s", cpy); + Py_END_ALLOW_THREADS + + free(cpy); + } + + Py_XDECREF(list); + PyErr_Clear(); } static int cpy_read_callback(user_data_t *data) { - cpy_callback_t *c = data->data; - PyObject *ret; - - CPY_LOCK_THREADS - ret = PyObject_CallFunctionObjArgs(c->callback, c->data, (void *) 0); /* New reference. */ - if (ret == NULL) { - cpy_log_exception("read callback"); - } else { - Py_DECREF(ret); - } - CPY_RELEASE_THREADS - if (ret == NULL) - return 1; - return 0; + cpy_callback_t *c = data->data; + PyObject *ret; + + CPY_LOCK_THREADS + ret = PyObject_CallFunctionObjArgs(c->callback, c->data, + (void *)0); /* New reference. */ + if (ret == NULL) { + cpy_log_exception("read callback"); + } else { + Py_DECREF(ret); + } + CPY_RELEASE_THREADS + if (ret == NULL) + return 1; + return 0; } -static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_list, user_data_t *data) { - cpy_callback_t *c = data->data; - PyObject *ret, *list, *temp, *dict = NULL; - Values *v; - - CPY_LOCK_THREADS - list = PyList_New(value_list->values_len); /* New reference. */ - if (list == NULL) { - cpy_log_exception("write callback"); - CPY_RETURN_FROM_THREADS 0; - } - for (size_t i = 0; i < value_list->values_len; ++i) { - if (ds->ds[i].type == DS_TYPE_COUNTER) { - PyList_SetItem(list, i, PyLong_FromUnsignedLongLong(value_list->values[i].counter)); - } else if (ds->ds[i].type == DS_TYPE_GAUGE) { - PyList_SetItem(list, i, PyFloat_FromDouble(value_list->values[i].gauge)); - } else if (ds->ds[i].type == DS_TYPE_DERIVE) { - PyList_SetItem(list, i, PyLong_FromLongLong(value_list->values[i].derive)); - } else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) { - PyList_SetItem(list, i, PyLong_FromUnsignedLongLong(value_list->values[i].absolute)); - } else { - Py_BEGIN_ALLOW_THREADS - ERROR("cpy_write_callback: Unknown value type %d.", ds->ds[i].type); - Py_END_ALLOW_THREADS - Py_DECREF(list); - CPY_RETURN_FROM_THREADS 0; - } - if (PyErr_Occurred() != NULL) { - cpy_log_exception("value building for write callback"); - Py_DECREF(list); - CPY_RETURN_FROM_THREADS 0; - } - } - dict = PyDict_New(); /* New reference. */ - if (value_list->meta) { - char **table; - meta_data_t *meta = value_list->meta; - - int num = meta_data_toc(meta, &table); - for (int i = 0; i < num; ++i) { - int type; - char *string; - int64_t si; - uint64_t ui; - double d; - _Bool b; - - type = meta_data_type(meta, table[i]); - if (type == MD_TYPE_STRING) { - if (meta_data_get_string(meta, table[i], &string)) - continue; - temp = cpy_string_to_unicode_or_bytes(string); /* New reference. */ - free(string); - PyDict_SetItemString(dict, table[i], temp); - Py_XDECREF(temp); - } else if (type == MD_TYPE_SIGNED_INT) { - if (meta_data_get_signed_int(meta, table[i], &si)) - continue; - temp = PyObject_CallFunctionObjArgs((void *) &SignedType, PyLong_FromLongLong(si), (void *) 0); /* New reference. */ - PyDict_SetItemString(dict, table[i], temp); - Py_XDECREF(temp); - } else if (type == MD_TYPE_UNSIGNED_INT) { - if (meta_data_get_unsigned_int(meta, table[i], &ui)) - continue; - temp = PyObject_CallFunctionObjArgs((void *) &UnsignedType, PyLong_FromUnsignedLongLong(ui), (void *) 0); /* New reference. */ - PyDict_SetItemString(dict, table[i], temp); - Py_XDECREF(temp); - } else if (type == MD_TYPE_DOUBLE) { - if (meta_data_get_double(meta, table[i], &d)) - continue; - temp = PyFloat_FromDouble(d); /* New reference. */ - PyDict_SetItemString(dict, table[i], temp); - Py_XDECREF(temp); - } else if (type == MD_TYPE_BOOLEAN) { - if (meta_data_get_boolean(meta, table[i], &b)) - continue; - if (b) - PyDict_SetItemString(dict, table[i], Py_True); - else - PyDict_SetItemString(dict, table[i], Py_False); - } - free(table[i]); - } - free(table); - } - v = (Values *) Values_New(); /* New reference. */ - sstrncpy(v->data.host, value_list->host, sizeof(v->data.host)); - sstrncpy(v->data.type, value_list->type, sizeof(v->data.type)); - 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 = 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); - v->meta = dict; /* Steals a reference. */ - ret = PyObject_CallFunctionObjArgs(c->callback, v, c->data, (void *) 0); /* New reference. */ - Py_XDECREF(v); - if (ret == NULL) { - cpy_log_exception("write callback"); - } else { - Py_DECREF(ret); - } - CPY_RELEASE_THREADS - return 0; +static int cpy_write_callback(const data_set_t *ds, + const value_list_t *value_list, + user_data_t *data) { + cpy_callback_t *c = data->data; + PyObject *ret, *list, *temp, *dict = NULL; + Values *v; + + CPY_LOCK_THREADS + list = PyList_New(value_list->values_len); /* New reference. */ + if (list == NULL) { + cpy_log_exception("write callback"); + CPY_RETURN_FROM_THREADS 0; + } + for (size_t i = 0; i < value_list->values_len; ++i) { + if (ds->ds[i].type == DS_TYPE_COUNTER) { + PyList_SetItem( + list, i, PyLong_FromUnsignedLongLong(value_list->values[i].counter)); + } else if (ds->ds[i].type == DS_TYPE_GAUGE) { + PyList_SetItem(list, i, PyFloat_FromDouble(value_list->values[i].gauge)); + } else if (ds->ds[i].type == DS_TYPE_DERIVE) { + PyList_SetItem(list, i, + PyLong_FromLongLong(value_list->values[i].derive)); + } else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) { + PyList_SetItem( + list, i, PyLong_FromUnsignedLongLong(value_list->values[i].absolute)); + } else { + Py_BEGIN_ALLOW_THREADS ERROR("cpy_write_callback: Unknown value type %d.", + ds->ds[i].type); + Py_END_ALLOW_THREADS Py_DECREF(list); + CPY_RETURN_FROM_THREADS 0; + } + if (PyErr_Occurred() != NULL) { + cpy_log_exception("value building for write callback"); + Py_DECREF(list); + CPY_RETURN_FROM_THREADS 0; + } + } + dict = PyDict_New(); /* New reference. */ + if (value_list->meta) { + char **table; + meta_data_t *meta = value_list->meta; + + int num = meta_data_toc(meta, &table); + for (int i = 0; i < num; ++i) { + int type; + char *string; + int64_t si; + uint64_t ui; + double d; + _Bool b; + + type = meta_data_type(meta, table[i]); + if (type == MD_TYPE_STRING) { + if (meta_data_get_string(meta, table[i], &string)) + continue; + temp = cpy_string_to_unicode_or_bytes(string); /* New reference. */ + free(string); + PyDict_SetItemString(dict, table[i], temp); + Py_XDECREF(temp); + } else if (type == MD_TYPE_SIGNED_INT) { + if (meta_data_get_signed_int(meta, table[i], &si)) + continue; + temp = PyObject_CallFunctionObjArgs((void *)&SignedType, + PyLong_FromLongLong(si), + (void *)0); /* New reference. */ + PyDict_SetItemString(dict, table[i], temp); + Py_XDECREF(temp); + } else if (type == MD_TYPE_UNSIGNED_INT) { + if (meta_data_get_unsigned_int(meta, table[i], &ui)) + continue; + temp = PyObject_CallFunctionObjArgs((void *)&UnsignedType, + PyLong_FromUnsignedLongLong(ui), + (void *)0); /* New reference. */ + PyDict_SetItemString(dict, table[i], temp); + Py_XDECREF(temp); + } else if (type == MD_TYPE_DOUBLE) { + if (meta_data_get_double(meta, table[i], &d)) + continue; + temp = PyFloat_FromDouble(d); /* New reference. */ + PyDict_SetItemString(dict, table[i], temp); + Py_XDECREF(temp); + } else if (type == MD_TYPE_BOOLEAN) { + if (meta_data_get_boolean(meta, table[i], &b)) + continue; + if (b) + PyDict_SetItemString(dict, table[i], Py_True); + else + PyDict_SetItemString(dict, table[i], Py_False); + } + free(table[i]); + } + free(table); + } + v = (Values *)Values_New(); /* New reference. */ + sstrncpy(v->data.host, value_list->host, sizeof(v->data.host)); + sstrncpy(v->data.type, value_list->type, sizeof(v->data.type)); + 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 = 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); + v->meta = dict; /* Steals a reference. */ + ret = PyObject_CallFunctionObjArgs(c->callback, v, c->data, + (void *)0); /* New reference. */ + Py_XDECREF(v); + if (ret == NULL) { + cpy_log_exception("write callback"); + } else { + Py_DECREF(ret); + } + CPY_RELEASE_THREADS + return 0; } -static int cpy_notification_callback(const notification_t *notification, user_data_t *data) { - cpy_callback_t *c = data->data; - PyObject *ret, *notify; - Notification *n; - - CPY_LOCK_THREADS - notify = Notification_New(); /* New reference. */ - n = (Notification *) notify; - sstrncpy(n->data.host, notification->host, sizeof(n->data.host)); - sstrncpy(n->data.type, notification->type, sizeof(n->data.type)); - 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 = 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. */ - Py_XDECREF(notify); - if (ret == NULL) { - cpy_log_exception("notification callback"); - } else { - Py_DECREF(ret); - } - CPY_RELEASE_THREADS - return 0; +static int cpy_notification_callback(const notification_t *notification, + user_data_t *data) { + cpy_callback_t *c = data->data; + PyObject *ret, *notify; + Notification *n; + + CPY_LOCK_THREADS + notify = Notification_New(); /* New reference. */ + n = (Notification *)notify; + sstrncpy(n->data.host, notification->host, sizeof(n->data.host)); + sstrncpy(n->data.type, notification->type, sizeof(n->data.type)); + 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 = 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. */ + Py_XDECREF(notify); + if (ret == NULL) { + cpy_log_exception("notification callback"); + } else { + Py_DECREF(ret); + } + CPY_RELEASE_THREADS + return 0; } -static void cpy_log_callback(int severity, const char *message, user_data_t *data) { - cpy_callback_t * c = data->data; - PyObject *ret, *text; - - CPY_LOCK_THREADS - text = cpy_string_to_unicode_or_bytes(message); /* New reference. */ - if (c->data == NULL) - ret = PyObject_CallFunction(c->callback, "iN", severity, text); /* New reference. Steals a reference from "text". */ - else - ret = PyObject_CallFunction(c->callback, "iNO", severity, text, c->data); /* New reference. Steals a reference from "text". */ - - if (ret == NULL) { - /* FIXME */ - /* Do we really want to trigger a log callback because a log callback failed? - * Probably not. */ - PyErr_Print(); - /* In case someone wanted to be clever, replaced stderr and failed at that. */ - PyErr_Clear(); - } else { - Py_DECREF(ret); - } - CPY_RELEASE_THREADS +static void cpy_log_callback(int severity, const char *message, + user_data_t *data) { + cpy_callback_t *c = data->data; + PyObject *ret, *text; + + CPY_LOCK_THREADS + text = cpy_string_to_unicode_or_bytes(message); /* New reference. */ + if (c->data == NULL) + ret = PyObject_CallFunction( + c->callback, "iN", severity, + text); /* New reference. Steals a reference from "text". */ + else + ret = PyObject_CallFunction( + c->callback, "iNO", severity, text, + c->data); /* New reference. Steals a reference from "text". */ + + if (ret == NULL) { + /* FIXME */ + /* Do we really want to trigger a log callback because a log callback + * failed? + * Probably not. */ + PyErr_Print(); + /* In case someone wanted to be clever, replaced stderr and failed at that. + */ + PyErr_Clear(); + } else { + Py_DECREF(ret); + } + CPY_RELEASE_THREADS } static void cpy_flush_callback(int timeout, const char *id, user_data_t *data) { - cpy_callback_t * c = data->data; - PyObject *ret, *text; - - CPY_LOCK_THREADS - if (id) { - text = cpy_string_to_unicode_or_bytes(id); - } else { - text = Py_None; - Py_INCREF(text); - } - if (c->data == NULL) - ret = PyObject_CallFunction(c->callback, "iN", timeout, text); /* New reference. */ - else - ret = PyObject_CallFunction(c->callback, "iNO", timeout, text, c->data); /* New reference. */ - - if (ret == NULL) { - cpy_log_exception("flush callback"); - } else { - Py_DECREF(ret); - } - CPY_RELEASE_THREADS + cpy_callback_t *c = data->data; + PyObject *ret, *text; + + CPY_LOCK_THREADS + if (id) { + text = cpy_string_to_unicode_or_bytes(id); + } else { + text = Py_None; + Py_INCREF(text); + } + if (c->data == NULL) + ret = PyObject_CallFunction(c->callback, "iN", timeout, + text); /* New reference. */ + else + ret = PyObject_CallFunction(c->callback, "iNO", timeout, text, + c->data); /* New reference. */ + + if (ret == NULL) { + cpy_log_exception("flush callback"); + } else { + Py_DECREF(ret); + } + CPY_RELEASE_THREADS } -static PyObject *cpy_register_generic(cpy_callback_t **list_head, PyObject *args, PyObject *kwds) { - char buf[512]; - cpy_callback_t *c; - char *name = NULL; - PyObject *callback = NULL, *data = NULL, *mod = NULL; - static char *kwlist[] = {"callback", "data", "name", NULL}; - - if (PyArg_ParseTupleAndKeywords(args, kwds, "O|Oet", kwlist, &callback, &data, NULL, &name) == 0) return NULL; - if (PyCallable_Check(callback) == 0) { - PyMem_Free(name); - PyErr_SetString(PyExc_TypeError, "callback needs a be a callable object."); - return NULL; - } - cpy_build_name(buf, sizeof(buf), callback, name); - - Py_INCREF(callback); - Py_XINCREF(data); - - c = calloc(1, sizeof(*c)); - if (c == NULL) - return NULL; - - c->name = strdup(buf); - c->callback = callback; - c->data = data; - c->next = *list_head; - ++cpy_num_callbacks; - *list_head = c; - Py_XDECREF(mod); - PyMem_Free(name); - return cpy_string_to_unicode_or_bytes(buf); +static PyObject *cpy_register_generic(cpy_callback_t **list_head, + PyObject *args, PyObject *kwds) { + char buf[512]; + cpy_callback_t *c; + char *name = NULL; + PyObject *callback = NULL, *data = NULL, *mod = NULL; + static char *kwlist[] = {"callback", "data", "name", NULL}; + + if (PyArg_ParseTupleAndKeywords(args, kwds, "O|Oet", kwlist, &callback, &data, + NULL, &name) == 0) + return NULL; + if (PyCallable_Check(callback) == 0) { + PyMem_Free(name); + PyErr_SetString(PyExc_TypeError, "callback needs a be a callable object."); + return NULL; + } + cpy_build_name(buf, sizeof(buf), callback, name); + + Py_INCREF(callback); + Py_XINCREF(data); + + c = calloc(1, sizeof(*c)); + if (c == NULL) + return NULL; + + c->name = strdup(buf); + c->callback = callback; + c->data = data; + c->next = *list_head; + ++cpy_num_callbacks; + *list_head = c; + Py_XDECREF(mod); + PyMem_Free(name); + return cpy_string_to_unicode_or_bytes(buf); } static PyObject *float_or_none(float number) { - if (isnan(number)) { - Py_RETURN_NONE; - } - return PyFloat_FromDouble(number); + if (isnan(number)) { + Py_RETURN_NONE; + } + return PyFloat_FromDouble(number); } static PyObject *cpy_get_dataset(PyObject *self, PyObject *args) { - char *name; - const data_set_t *ds; - PyObject *list, *tuple; - - if (PyArg_ParseTuple(args, "et", NULL, &name) == 0) return NULL; - ds = plugin_get_ds(name); - PyMem_Free(name); - if (ds == NULL) { - PyErr_Format(PyExc_TypeError, "Dataset %s not found", name); - return NULL; - } - list = PyList_New(ds->ds_num); /* New reference. */ - for (size_t i = 0; i < ds->ds_num; ++i) { - tuple = PyTuple_New(4); - PyTuple_SET_ITEM(tuple, 0, cpy_string_to_unicode_or_bytes(ds->ds[i].name)); - PyTuple_SET_ITEM(tuple, 1, cpy_string_to_unicode_or_bytes(DS_TYPE_TO_STRING(ds->ds[i].type))); - PyTuple_SET_ITEM(tuple, 2, float_or_none(ds->ds[i].min)); - PyTuple_SET_ITEM(tuple, 3, float_or_none(ds->ds[i].max)); - PyList_SET_ITEM(list, i, tuple); - } - return list; + char *name; + const data_set_t *ds; + PyObject *list, *tuple; + + if (PyArg_ParseTuple(args, "et", NULL, &name) == 0) + return NULL; + ds = plugin_get_ds(name); + PyMem_Free(name); + if (ds == NULL) { + PyErr_Format(PyExc_TypeError, "Dataset %s not found", name); + return NULL; + } + list = PyList_New(ds->ds_num); /* New reference. */ + for (size_t i = 0; i < ds->ds_num; ++i) { + tuple = PyTuple_New(4); + PyTuple_SET_ITEM(tuple, 0, cpy_string_to_unicode_or_bytes(ds->ds[i].name)); + PyTuple_SET_ITEM(tuple, 1, cpy_string_to_unicode_or_bytes( + DS_TYPE_TO_STRING(ds->ds[i].type))); + PyTuple_SET_ITEM(tuple, 2, float_or_none(ds->ds[i].min)); + PyTuple_SET_ITEM(tuple, 3, float_or_none(ds->ds[i].max)); + PyList_SET_ITEM(list, i, tuple); + } + return list; } static PyObject *cpy_flush(PyObject *self, PyObject *args, PyObject *kwds) { - int timeout = -1; - char *plugin = NULL, *identifier = NULL; - static char *kwlist[] = {"plugin", "timeout", "identifier", NULL}; - - if (PyArg_ParseTupleAndKeywords(args, kwds, "|etiet", kwlist, NULL, &plugin, &timeout, NULL, &identifier) == 0) return NULL; - Py_BEGIN_ALLOW_THREADS - plugin_flush(plugin, timeout, identifier); - Py_END_ALLOW_THREADS - PyMem_Free(plugin); - PyMem_Free(identifier); - Py_RETURN_NONE; + int timeout = -1; + char *plugin = NULL, *identifier = NULL; + static char *kwlist[] = {"plugin", "timeout", "identifier", NULL}; + + if (PyArg_ParseTupleAndKeywords(args, kwds, "|etiet", kwlist, NULL, &plugin, + &timeout, NULL, &identifier) == 0) + return NULL; + Py_BEGIN_ALLOW_THREADS plugin_flush(plugin, timeout, identifier); + Py_END_ALLOW_THREADS PyMem_Free(plugin); + PyMem_Free(identifier); + Py_RETURN_NONE; } -static PyObject *cpy_register_config(PyObject *self, PyObject *args, PyObject *kwds) { - return cpy_register_generic(&cpy_config_callbacks, args, kwds); +static PyObject *cpy_register_config(PyObject *self, PyObject *args, + PyObject *kwds) { + return cpy_register_generic(&cpy_config_callbacks, args, kwds); } -static PyObject *cpy_register_init(PyObject *self, PyObject *args, PyObject *kwds) { - return cpy_register_generic(&cpy_init_callbacks, args, kwds); +static PyObject *cpy_register_init(PyObject *self, PyObject *args, + PyObject *kwds) { + return cpy_register_generic(&cpy_init_callbacks, args, kwds); } typedef int reg_function_t(const char *name, void *callback, void *data); -static PyObject *cpy_register_generic_userdata(void *reg, void *handler, PyObject *args, PyObject *kwds) { - char buf[512]; - reg_function_t *register_function = (reg_function_t *) reg; - cpy_callback_t *c = NULL; - char *name = NULL; - PyObject *callback = NULL, *data = NULL; - static char *kwlist[] = {"callback", "data", "name", NULL}; - - if (PyArg_ParseTupleAndKeywords(args, kwds, "O|Oet", kwlist, &callback, &data, NULL, &name) == 0) return NULL; - if (PyCallable_Check(callback) == 0) { - PyMem_Free(name); - PyErr_SetString(PyExc_TypeError, "callback needs a be a callable object."); - return NULL; - } - cpy_build_name(buf, sizeof(buf), callback, name); - PyMem_Free(name); - - Py_INCREF(callback); - Py_XINCREF(data); - - c = calloc(1, sizeof(*c)); - if (c == NULL) - return NULL; - - c->name = strdup(buf); - c->callback = callback; - c->data = data; - c->next = NULL; - - register_function(buf, handler, &(user_data_t) { - .data = c, - .free_func = cpy_destroy_user_data, - }); - - ++cpy_num_callbacks; - return cpy_string_to_unicode_or_bytes(buf); +static PyObject *cpy_register_generic_userdata(void *reg, void *handler, + PyObject *args, PyObject *kwds) { + char buf[512]; + reg_function_t *register_function = (reg_function_t *)reg; + cpy_callback_t *c = NULL; + char *name = NULL; + PyObject *callback = NULL, *data = NULL; + static char *kwlist[] = {"callback", "data", "name", NULL}; + + if (PyArg_ParseTupleAndKeywords(args, kwds, "O|Oet", kwlist, &callback, &data, + NULL, &name) == 0) + return NULL; + if (PyCallable_Check(callback) == 0) { + PyMem_Free(name); + PyErr_SetString(PyExc_TypeError, "callback needs a be a callable object."); + return NULL; + } + cpy_build_name(buf, sizeof(buf), callback, name); + PyMem_Free(name); + + Py_INCREF(callback); + Py_XINCREF(data); + + c = calloc(1, sizeof(*c)); + if (c == NULL) + return NULL; + + c->name = strdup(buf); + c->callback = callback; + c->data = data; + c->next = NULL; + + register_function(buf, handler, + &(user_data_t){ + .data = c, .free_func = cpy_destroy_user_data, + }); + + ++cpy_num_callbacks; + return cpy_string_to_unicode_or_bytes(buf); } -static PyObject *cpy_register_read(PyObject *self, PyObject *args, PyObject *kwds) { - char buf[512]; - cpy_callback_t *c = NULL; - double interval = 0; - char *name = NULL; - PyObject *callback = NULL, *data = NULL; - static char *kwlist[] = {"callback", "interval", "data", "name", NULL}; - - if (PyArg_ParseTupleAndKeywords(args, kwds, "O|dOet", kwlist, &callback, &interval, &data, NULL, &name) == 0) return NULL; - if (PyCallable_Check(callback) == 0) { - PyMem_Free(name); - PyErr_SetString(PyExc_TypeError, "callback needs a be a callable object."); - return NULL; - } - cpy_build_name(buf, sizeof(buf), callback, name); - PyMem_Free(name); - - Py_INCREF(callback); - Py_XINCREF(data); - - c = calloc(1, sizeof(*c)); - if (c == NULL) - return NULL; - - c->name = strdup(buf); - c->callback = callback; - c->data = data; - c->next = NULL; - - plugin_register_complex_read(/* group = */ "python", buf, - cpy_read_callback, DOUBLE_TO_CDTIME_T (interval), - &(user_data_t) { - .data = c, - .free_func = cpy_destroy_user_data, - }); - ++cpy_num_callbacks; - return cpy_string_to_unicode_or_bytes(buf); +static PyObject *cpy_register_read(PyObject *self, PyObject *args, + PyObject *kwds) { + char buf[512]; + cpy_callback_t *c = NULL; + double interval = 0; + char *name = NULL; + PyObject *callback = NULL, *data = NULL; + static char *kwlist[] = {"callback", "interval", "data", "name", NULL}; + + if (PyArg_ParseTupleAndKeywords(args, kwds, "O|dOet", kwlist, &callback, + &interval, &data, NULL, &name) == 0) + return NULL; + if (PyCallable_Check(callback) == 0) { + PyMem_Free(name); + PyErr_SetString(PyExc_TypeError, "callback needs a be a callable object."); + return NULL; + } + cpy_build_name(buf, sizeof(buf), callback, name); + PyMem_Free(name); + + Py_INCREF(callback); + Py_XINCREF(data); + + c = calloc(1, sizeof(*c)); + if (c == NULL) + return NULL; + + c->name = strdup(buf); + c->callback = callback; + c->data = data; + c->next = NULL; + + plugin_register_complex_read( + /* group = */ "python", buf, cpy_read_callback, + DOUBLE_TO_CDTIME_T(interval), + &(user_data_t){ + .data = c, .free_func = cpy_destroy_user_data, + }); + ++cpy_num_callbacks; + return cpy_string_to_unicode_or_bytes(buf); } -static PyObject *cpy_register_log(PyObject *self, PyObject *args, PyObject *kwds) { - return cpy_register_generic_userdata((void *) plugin_register_log, - (void *) cpy_log_callback, args, kwds); +static PyObject *cpy_register_log(PyObject *self, PyObject *args, + PyObject *kwds) { + return cpy_register_generic_userdata((void *)plugin_register_log, + (void *)cpy_log_callback, args, kwds); } -static PyObject *cpy_register_write(PyObject *self, PyObject *args, PyObject *kwds) { - return cpy_register_generic_userdata((void *) plugin_register_write, - (void *) cpy_write_callback, args, kwds); +static PyObject *cpy_register_write(PyObject *self, PyObject *args, + PyObject *kwds) { + return cpy_register_generic_userdata((void *)plugin_register_write, + (void *)cpy_write_callback, args, kwds); } -static PyObject *cpy_register_notification(PyObject *self, PyObject *args, PyObject *kwds) { - return cpy_register_generic_userdata((void *) plugin_register_notification, - (void *) cpy_notification_callback, args, kwds); +static PyObject *cpy_register_notification(PyObject *self, PyObject *args, + PyObject *kwds) { + return cpy_register_generic_userdata((void *)plugin_register_notification, + (void *)cpy_notification_callback, args, + kwds); } -static PyObject *cpy_register_flush(PyObject *self, PyObject *args, PyObject *kwds) { - return cpy_register_generic_userdata((void *) plugin_register_flush, - (void *) cpy_flush_callback, args, kwds); +static PyObject *cpy_register_flush(PyObject *self, PyObject *args, + PyObject *kwds) { + return cpy_register_generic_userdata((void *)plugin_register_flush, + (void *)cpy_flush_callback, args, kwds); } -static PyObject *cpy_register_shutdown(PyObject *self, PyObject *args, PyObject *kwds) { - return cpy_register_generic(&cpy_shutdown_callbacks, args, kwds); +static PyObject *cpy_register_shutdown(PyObject *self, PyObject *args, + PyObject *kwds) { + return cpy_register_generic(&cpy_shutdown_callbacks, args, kwds); } static PyObject *cpy_error(PyObject *self, PyObject *args) { - char *text; - if (PyArg_ParseTuple(args, "et", NULL, &text) == 0) return NULL; - Py_BEGIN_ALLOW_THREADS - plugin_log(LOG_ERR, "%s", text); - Py_END_ALLOW_THREADS - PyMem_Free(text); - Py_RETURN_NONE; + char *text; + if (PyArg_ParseTuple(args, "et", NULL, &text) == 0) + return NULL; + Py_BEGIN_ALLOW_THREADS plugin_log(LOG_ERR, "%s", text); + Py_END_ALLOW_THREADS PyMem_Free(text); + Py_RETURN_NONE; } static PyObject *cpy_warning(PyObject *self, PyObject *args) { - char *text; - if (PyArg_ParseTuple(args, "et", NULL, &text) == 0) return NULL; - Py_BEGIN_ALLOW_THREADS - plugin_log(LOG_WARNING, "%s", text); - Py_END_ALLOW_THREADS - PyMem_Free(text); - Py_RETURN_NONE; + char *text; + if (PyArg_ParseTuple(args, "et", NULL, &text) == 0) + return NULL; + Py_BEGIN_ALLOW_THREADS plugin_log(LOG_WARNING, "%s", text); + Py_END_ALLOW_THREADS PyMem_Free(text); + Py_RETURN_NONE; } static PyObject *cpy_notice(PyObject *self, PyObject *args) { - char *text; - if (PyArg_ParseTuple(args, "et", NULL, &text) == 0) return NULL; - Py_BEGIN_ALLOW_THREADS - plugin_log(LOG_NOTICE, "%s", text); - Py_END_ALLOW_THREADS - PyMem_Free(text); - Py_RETURN_NONE; + char *text; + if (PyArg_ParseTuple(args, "et", NULL, &text) == 0) + return NULL; + Py_BEGIN_ALLOW_THREADS plugin_log(LOG_NOTICE, "%s", text); + Py_END_ALLOW_THREADS PyMem_Free(text); + Py_RETURN_NONE; } static PyObject *cpy_info(PyObject *self, PyObject *args) { - char *text; - if (PyArg_ParseTuple(args, "et", NULL, &text) == 0) return NULL; - Py_BEGIN_ALLOW_THREADS - plugin_log(LOG_INFO, "%s", text); - Py_END_ALLOW_THREADS - PyMem_Free(text); - Py_RETURN_NONE; + char *text; + if (PyArg_ParseTuple(args, "et", NULL, &text) == 0) + return NULL; + Py_BEGIN_ALLOW_THREADS plugin_log(LOG_INFO, "%s", text); + Py_END_ALLOW_THREADS PyMem_Free(text); + Py_RETURN_NONE; } static PyObject *cpy_debug(PyObject *self, PyObject *args) { #ifdef COLLECT_DEBUG - char *text; - if (PyArg_ParseTuple(args, "et", NULL, &text) == 0) return NULL; - Py_BEGIN_ALLOW_THREADS - plugin_log(LOG_DEBUG, "%s", text); - Py_END_ALLOW_THREADS - PyMem_Free(text); + char *text; + if (PyArg_ParseTuple(args, "et", NULL, &text) == 0) + return NULL; + Py_BEGIN_ALLOW_THREADS plugin_log(LOG_DEBUG, "%s", text); + Py_END_ALLOW_THREADS PyMem_Free(text); #endif - Py_RETURN_NONE; + Py_RETURN_NONE; } -static PyObject *cpy_unregister_generic(cpy_callback_t **list_head, PyObject *arg, const char *desc) { - char buf[512]; - const char *name; - cpy_callback_t *prev = NULL, *tmp; - - Py_INCREF(arg); - name = cpy_unicode_or_bytes_to_string(&arg); - if (name == NULL) { - PyErr_Clear(); - if (!PyCallable_Check(arg)) { - PyErr_SetString(PyExc_TypeError, "This function needs a string or a callable object as its only parameter."); - Py_DECREF(arg); - return NULL; - } - cpy_build_name(buf, sizeof(buf), arg, NULL); - name = buf; - } - for (tmp = *list_head; tmp; prev = tmp, tmp = tmp->next) - if (strcmp(name, tmp->name) == 0) - break; - - Py_DECREF(arg); - if (tmp == NULL) { - PyErr_Format(PyExc_RuntimeError, "Unable to unregister %s callback '%s'.", desc, name); - return NULL; - } - /* Yes, this is actually safe. To call this function the caller has to - * hold the GIL. Well, safe as long as there is only one GIL anyway ... */ - if (prev == NULL) - *list_head = tmp->next; - else - prev->next = tmp->next; - cpy_destroy_user_data(tmp); - Py_RETURN_NONE; +static PyObject *cpy_unregister_generic(cpy_callback_t **list_head, + PyObject *arg, const char *desc) { + char buf[512]; + const char *name; + cpy_callback_t *prev = NULL, *tmp; + + Py_INCREF(arg); + name = cpy_unicode_or_bytes_to_string(&arg); + if (name == NULL) { + PyErr_Clear(); + if (!PyCallable_Check(arg)) { + PyErr_SetString(PyExc_TypeError, "This function needs a string or a " + "callable object as its only " + "parameter."); + Py_DECREF(arg); + return NULL; + } + cpy_build_name(buf, sizeof(buf), arg, NULL); + name = buf; + } + for (tmp = *list_head; tmp; prev = tmp, tmp = tmp->next) + if (strcmp(name, tmp->name) == 0) + break; + + Py_DECREF(arg); + if (tmp == NULL) { + PyErr_Format(PyExc_RuntimeError, "Unable to unregister %s callback '%s'.", + desc, name); + return NULL; + } + /* Yes, this is actually safe. To call this function the caller has to + * hold the GIL. Well, safe as long as there is only one GIL anyway ... */ + if (prev == NULL) + *list_head = tmp->next; + else + prev->next = tmp->next; + cpy_destroy_user_data(tmp); + Py_RETURN_NONE; } static void cpy_unregister_list(cpy_callback_t **list_head) { - cpy_callback_t *cur, *next; - for (cur = *list_head; cur; cur = next) { - next = cur->next; - cpy_destroy_user_data(cur); - } - *list_head = NULL; + cpy_callback_t *cur, *next; + for (cur = *list_head; cur; cur = next) { + next = cur->next; + cpy_destroy_user_data(cur); + } + *list_head = NULL; } typedef int cpy_unregister_function_t(const char *name); -static PyObject *cpy_unregister_generic_userdata(cpy_unregister_function_t *unreg, PyObject *arg, const char *desc) { - char buf[512]; - const char *name; - - Py_INCREF(arg); - name = cpy_unicode_or_bytes_to_string(&arg); - if (name == NULL) { - PyErr_Clear(); - if (!PyCallable_Check(arg)) { - PyErr_SetString(PyExc_TypeError, "This function needs a string or a callable object as its only parameter."); - Py_DECREF(arg); - return NULL; - } - cpy_build_name(buf, sizeof(buf), arg, NULL); - name = buf; - } - if (unreg(name) == 0) { - Py_DECREF(arg); - Py_RETURN_NONE; - } - PyErr_Format(PyExc_RuntimeError, "Unable to unregister %s callback '%s'.", desc, name); - Py_DECREF(arg); - return NULL; +static PyObject * +cpy_unregister_generic_userdata(cpy_unregister_function_t *unreg, PyObject *arg, + const char *desc) { + char buf[512]; + const char *name; + + Py_INCREF(arg); + name = cpy_unicode_or_bytes_to_string(&arg); + if (name == NULL) { + PyErr_Clear(); + if (!PyCallable_Check(arg)) { + PyErr_SetString(PyExc_TypeError, "This function needs a string or a " + "callable object as its only " + "parameter."); + Py_DECREF(arg); + return NULL; + } + cpy_build_name(buf, sizeof(buf), arg, NULL); + name = buf; + } + if (unreg(name) == 0) { + Py_DECREF(arg); + Py_RETURN_NONE; + } + PyErr_Format(PyExc_RuntimeError, "Unable to unregister %s callback '%s'.", + desc, name); + Py_DECREF(arg); + return NULL; } static PyObject *cpy_unregister_log(PyObject *self, PyObject *arg) { - return cpy_unregister_generic_userdata(plugin_unregister_log, arg, "log"); + return cpy_unregister_generic_userdata(plugin_unregister_log, arg, "log"); } static PyObject *cpy_unregister_init(PyObject *self, PyObject *arg) { - return cpy_unregister_generic(&cpy_init_callbacks, arg, "init"); + return cpy_unregister_generic(&cpy_init_callbacks, arg, "init"); } static PyObject *cpy_unregister_config(PyObject *self, PyObject *arg) { - return cpy_unregister_generic(&cpy_config_callbacks, arg, "config"); + return cpy_unregister_generic(&cpy_config_callbacks, arg, "config"); } static PyObject *cpy_unregister_read(PyObject *self, PyObject *arg) { - return cpy_unregister_generic_userdata(plugin_unregister_read, arg, "read"); + return cpy_unregister_generic_userdata(plugin_unregister_read, arg, "read"); } static PyObject *cpy_unregister_write(PyObject *self, PyObject *arg) { - return cpy_unregister_generic_userdata(plugin_unregister_write, arg, "write"); + return cpy_unregister_generic_userdata(plugin_unregister_write, arg, "write"); } static PyObject *cpy_unregister_notification(PyObject *self, PyObject *arg) { - return cpy_unregister_generic_userdata(plugin_unregister_notification, arg, "notification"); + return cpy_unregister_generic_userdata(plugin_unregister_notification, arg, + "notification"); } static PyObject *cpy_unregister_flush(PyObject *self, PyObject *arg) { - return cpy_unregister_generic_userdata(plugin_unregister_flush, arg, "flush"); + return cpy_unregister_generic_userdata(plugin_unregister_flush, arg, "flush"); } static PyObject *cpy_unregister_shutdown(PyObject *self, PyObject *arg) { - return cpy_unregister_generic(&cpy_shutdown_callbacks, arg, "shutdown"); + return cpy_unregister_generic(&cpy_shutdown_callbacks, arg, "shutdown"); } static PyMethodDef cpy_methods[] = { - {"debug", cpy_debug, METH_VARARGS, log_doc}, - {"info", cpy_info, METH_VARARGS, log_doc}, - {"notice", cpy_notice, METH_VARARGS, log_doc}, - {"warning", cpy_warning, METH_VARARGS, log_doc}, - {"error", cpy_error, METH_VARARGS, log_doc}, - {"get_dataset", (PyCFunction) cpy_get_dataset, METH_VARARGS, get_ds_doc}, - {"flush", (PyCFunction) cpy_flush, METH_VARARGS | METH_KEYWORDS, flush_doc}, - {"register_log", (PyCFunction) cpy_register_log, METH_VARARGS | METH_KEYWORDS, reg_log_doc}, - {"register_init", (PyCFunction) cpy_register_init, METH_VARARGS | METH_KEYWORDS, reg_init_doc}, - {"register_config", (PyCFunction) cpy_register_config, METH_VARARGS | METH_KEYWORDS, reg_config_doc}, - {"register_read", (PyCFunction) cpy_register_read, METH_VARARGS | METH_KEYWORDS, reg_read_doc}, - {"register_write", (PyCFunction) cpy_register_write, METH_VARARGS | METH_KEYWORDS, reg_write_doc}, - {"register_notification", (PyCFunction) cpy_register_notification, METH_VARARGS | METH_KEYWORDS, reg_notification_doc}, - {"register_flush", (PyCFunction) cpy_register_flush, METH_VARARGS | METH_KEYWORDS, reg_flush_doc}, - {"register_shutdown", (PyCFunction) cpy_register_shutdown, METH_VARARGS | METH_KEYWORDS, reg_shutdown_doc}, - {"unregister_log", cpy_unregister_log, METH_O, unregister_doc}, - {"unregister_init", cpy_unregister_init, METH_O, unregister_doc}, - {"unregister_config", cpy_unregister_config, METH_O, unregister_doc}, - {"unregister_read", cpy_unregister_read, METH_O, unregister_doc}, - {"unregister_write", cpy_unregister_write, METH_O, unregister_doc}, - {"unregister_notification", cpy_unregister_notification, METH_O, unregister_doc}, - {"unregister_flush", cpy_unregister_flush, METH_O, unregister_doc}, - {"unregister_shutdown", cpy_unregister_shutdown, METH_O, unregister_doc}, - {0, 0, 0, 0} -}; + {"debug", cpy_debug, METH_VARARGS, log_doc}, + {"info", cpy_info, METH_VARARGS, log_doc}, + {"notice", cpy_notice, METH_VARARGS, log_doc}, + {"warning", cpy_warning, METH_VARARGS, log_doc}, + {"error", cpy_error, METH_VARARGS, log_doc}, + {"get_dataset", (PyCFunction)cpy_get_dataset, METH_VARARGS, get_ds_doc}, + {"flush", (PyCFunction)cpy_flush, METH_VARARGS | METH_KEYWORDS, flush_doc}, + {"register_log", (PyCFunction)cpy_register_log, + METH_VARARGS | METH_KEYWORDS, reg_log_doc}, + {"register_init", (PyCFunction)cpy_register_init, + METH_VARARGS | METH_KEYWORDS, reg_init_doc}, + {"register_config", (PyCFunction)cpy_register_config, + METH_VARARGS | METH_KEYWORDS, reg_config_doc}, + {"register_read", (PyCFunction)cpy_register_read, + METH_VARARGS | METH_KEYWORDS, reg_read_doc}, + {"register_write", (PyCFunction)cpy_register_write, + METH_VARARGS | METH_KEYWORDS, reg_write_doc}, + {"register_notification", (PyCFunction)cpy_register_notification, + METH_VARARGS | METH_KEYWORDS, reg_notification_doc}, + {"register_flush", (PyCFunction)cpy_register_flush, + METH_VARARGS | METH_KEYWORDS, reg_flush_doc}, + {"register_shutdown", (PyCFunction)cpy_register_shutdown, + METH_VARARGS | METH_KEYWORDS, reg_shutdown_doc}, + {"unregister_log", cpy_unregister_log, METH_O, unregister_doc}, + {"unregister_init", cpy_unregister_init, METH_O, unregister_doc}, + {"unregister_config", cpy_unregister_config, METH_O, unregister_doc}, + {"unregister_read", cpy_unregister_read, METH_O, unregister_doc}, + {"unregister_write", cpy_unregister_write, METH_O, unregister_doc}, + {"unregister_notification", cpy_unregister_notification, METH_O, + unregister_doc}, + {"unregister_flush", cpy_unregister_flush, METH_O, unregister_doc}, + {"unregister_shutdown", cpy_unregister_shutdown, METH_O, unregister_doc}, + {0, 0, 0, 0}}; static int cpy_shutdown(void) { - PyObject *ret; - - if (!state) { - printf("================================================================\n"); - printf("collectd shutdown while running an interactive session. This will\n"); - printf("probably leave your terminal in a mess.\n"); - printf("Run the command \"reset\" to get it back into a usable state.\n"); - printf("You can press Ctrl+D in the interactive session to\n"); - printf("close collectd and avoid this problem in the future.\n"); - printf("================================================================\n"); - } - - CPY_LOCK_THREADS - - for (cpy_callback_t *c = cpy_shutdown_callbacks; c; c = c->next) { - ret = PyObject_CallFunctionObjArgs(c->callback, c->data, (void *) 0); /* New reference. */ - if (ret == NULL) - cpy_log_exception("shutdown callback"); - else - Py_DECREF(ret); - } - PyErr_Print(); - - Py_BEGIN_ALLOW_THREADS - cpy_unregister_list(&cpy_config_callbacks); - cpy_unregister_list(&cpy_init_callbacks); - cpy_unregister_list(&cpy_shutdown_callbacks); - cpy_shutdown_triggered = 1; - Py_END_ALLOW_THREADS - - if (!cpy_num_callbacks) { - Py_Finalize(); - return 0; - } - - CPY_RELEASE_THREADS - return 0; + PyObject *ret; + + if (!state) { + printf( + "================================================================\n"); + printf( + "collectd shutdown while running an interactive session. This will\n"); + printf("probably leave your terminal in a mess.\n"); + printf("Run the command \"reset\" to get it back into a usable state.\n"); + printf("You can press Ctrl+D in the interactive session to\n"); + printf("close collectd and avoid this problem in the future.\n"); + printf( + "================================================================\n"); + } + + CPY_LOCK_THREADS + + for (cpy_callback_t *c = cpy_shutdown_callbacks; c; c = c->next) { + ret = PyObject_CallFunctionObjArgs(c->callback, c->data, + (void *)0); /* New reference. */ + if (ret == NULL) + cpy_log_exception("shutdown callback"); + else + Py_DECREF(ret); + } + PyErr_Print(); + + Py_BEGIN_ALLOW_THREADS cpy_unregister_list(&cpy_config_callbacks); + cpy_unregister_list(&cpy_init_callbacks); + cpy_unregister_list(&cpy_shutdown_callbacks); + cpy_shutdown_triggered = 1; + Py_END_ALLOW_THREADS + + if (!cpy_num_callbacks) { + Py_Finalize(); + return 0; + } + + CPY_RELEASE_THREADS + return 0; } static void *cpy_interactive(void *pipefd) { - PyOS_sighandler_t cur_sig; - - /* Signal handler in a plugin? Bad stuff, but the best way to - * handle it I guess. In an interactive session people will - * press Ctrl+C at some time, which will generate a SIGINT. - * This will cause collectd to shutdown, thus killing the - * interactive interpreter, and leaving the terminal in a - * mess. Chances are, this isn't what the user wanted to do. - * - * So this is the plan: - * 1. Restore Python's own signal handler - * 2. Tell Python we just forked so it will accept this thread - * as the main one. No version of Python will ever handle - * interrupts anywhere but in the main thread. - * 3. After the interactive loop is done, restore collectd's - * SIGINT handler. - * 4. Raise SIGINT for a clean shutdown. The signal is sent to - * the main thread to ensure it wakes up the main interval - * sleep so that collectd shuts down immediately not in 10 - * seconds. - * - * This will make sure that SIGINT won't kill collectd but - * still interrupt syscalls like sleep and pause. */ - - if (PyImport_ImportModule("readline") == NULL) { - /* This interactive session will suck. */ - cpy_log_exception("interactive session init"); - } - cur_sig = PyOS_setsig(SIGINT, python_sigint_handler); - PyOS_AfterFork(); - PyEval_InitThreads(); - close(*(int *) pipefd); - PyRun_InteractiveLoop(stdin, ""); - PyOS_setsig(SIGINT, cur_sig); - PyErr_Print(); - state = PyEval_SaveThread(); - NOTICE("python: Interactive interpreter exited, stopping collectd ..."); - pthread_kill(main_thread, SIGINT); - return NULL; + PyOS_sighandler_t cur_sig; + + /* Signal handler in a plugin? Bad stuff, but the best way to + * handle it I guess. In an interactive session people will + * press Ctrl+C at some time, which will generate a SIGINT. + * This will cause collectd to shutdown, thus killing the + * interactive interpreter, and leaving the terminal in a + * mess. Chances are, this isn't what the user wanted to do. + * + * So this is the plan: + * 1. Restore Python's own signal handler + * 2. Tell Python we just forked so it will accept this thread + * as the main one. No version of Python will ever handle + * interrupts anywhere but in the main thread. + * 3. After the interactive loop is done, restore collectd's + * SIGINT handler. + * 4. Raise SIGINT for a clean shutdown. The signal is sent to + * the main thread to ensure it wakes up the main interval + * sleep so that collectd shuts down immediately not in 10 + * seconds. + * + * This will make sure that SIGINT won't kill collectd but + * still interrupt syscalls like sleep and pause. */ + + if (PyImport_ImportModule("readline") == NULL) { + /* This interactive session will suck. */ + cpy_log_exception("interactive session init"); + } + cur_sig = PyOS_setsig(SIGINT, python_sigint_handler); + PyOS_AfterFork(); + PyEval_InitThreads(); + close(*(int *)pipefd); + PyRun_InteractiveLoop(stdin, ""); + PyOS_setsig(SIGINT, cur_sig); + PyErr_Print(); + state = PyEval_SaveThread(); + NOTICE("python: Interactive interpreter exited, stopping collectd ..."); + pthread_kill(main_thread, SIGINT); + return NULL; } static int cpy_init(void) { - PyObject *ret; - int pipefd[2]; - char buf; - static pthread_t thread; - - if (!Py_IsInitialized()) { - WARNING("python: Plugin loaded but not configured."); - plugin_unregister_shutdown("python"); - Py_Finalize(); - return 0; - } - main_thread = pthread_self(); - if (do_interactive) { - if (pipe(pipefd)) { - ERROR("python: Unable to create pipe."); - return 1; - } - if (plugin_thread_create(&thread, NULL, cpy_interactive, pipefd + 1, - "python interpreter")) { - ERROR("python: Error creating thread for interactive interpreter."); - } - if(read(pipefd[0], &buf, 1)) - ; - (void)close(pipefd[0]); - } else { - PyEval_InitThreads(); - state = PyEval_SaveThread(); - } - CPY_LOCK_THREADS - for (cpy_callback_t *c = cpy_init_callbacks; c; c = c->next) { - ret = PyObject_CallFunctionObjArgs(c->callback, c->data, (void *) 0); /* New reference. */ - if (ret == NULL) - cpy_log_exception("init callback"); - else - Py_DECREF(ret); - } - CPY_RELEASE_THREADS - - return 0; + PyObject *ret; + int pipefd[2]; + char buf; + static pthread_t thread; + + if (!Py_IsInitialized()) { + WARNING("python: Plugin loaded but not configured."); + plugin_unregister_shutdown("python"); + Py_Finalize(); + return 0; + } + main_thread = pthread_self(); + if (do_interactive) { + if (pipe(pipefd)) { + ERROR("python: Unable to create pipe."); + return 1; + } + if (plugin_thread_create(&thread, NULL, cpy_interactive, pipefd + 1, + "python interpreter")) { + ERROR("python: Error creating thread for interactive interpreter."); + } + if (read(pipefd[0], &buf, 1)) + ; + (void)close(pipefd[0]); + } else { + PyEval_InitThreads(); + state = PyEval_SaveThread(); + } + CPY_LOCK_THREADS + for (cpy_callback_t *c = cpy_init_callbacks; c; c = c->next) { + ret = PyObject_CallFunctionObjArgs(c->callback, c->data, + (void *)0); /* New reference. */ + if (ret == NULL) + cpy_log_exception("init callback"); + else + Py_DECREF(ret); + } + CPY_RELEASE_THREADS + + return 0; } static PyObject *cpy_oconfig_to_pyconfig(oconfig_item_t *ci, PyObject *parent) { - PyObject *item, *values, *children, *tmp; - - if (parent == NULL) - parent = Py_None; - - values = PyTuple_New(ci->values_num); /* New reference. */ - for (int i = 0; i < ci->values_num; ++i) { - if (ci->values[i].type == OCONFIG_TYPE_STRING) { - PyTuple_SET_ITEM(values, i, cpy_string_to_unicode_or_bytes(ci->values[i].value.string)); - } else if (ci->values[i].type == OCONFIG_TYPE_NUMBER) { - PyTuple_SET_ITEM(values, i, PyFloat_FromDouble(ci->values[i].value.number)); - } else if (ci->values[i].type == OCONFIG_TYPE_BOOLEAN) { - PyTuple_SET_ITEM(values, i, PyBool_FromLong(ci->values[i].value.boolean)); - } - } - - tmp = cpy_string_to_unicode_or_bytes(ci->key); - item = PyObject_CallFunction((void *) &ConfigType, "NONO", tmp, parent, values, Py_None); - if (item == NULL) - return NULL; - children = PyTuple_New(ci->children_num); /* New reference. */ - for (int i = 0; i < ci->children_num; ++i) { - PyTuple_SET_ITEM(children, i, cpy_oconfig_to_pyconfig(ci->children + i, item)); - } - tmp = ((Config *) item)->children; - ((Config *) item)->children = children; - Py_XDECREF(tmp); - return item; + PyObject *item, *values, *children, *tmp; + + if (parent == NULL) + parent = Py_None; + + values = PyTuple_New(ci->values_num); /* New reference. */ + for (int i = 0; i < ci->values_num; ++i) { + if (ci->values[i].type == OCONFIG_TYPE_STRING) { + PyTuple_SET_ITEM(values, i, cpy_string_to_unicode_or_bytes( + ci->values[i].value.string)); + } else if (ci->values[i].type == OCONFIG_TYPE_NUMBER) { + PyTuple_SET_ITEM(values, i, + PyFloat_FromDouble(ci->values[i].value.number)); + } else if (ci->values[i].type == OCONFIG_TYPE_BOOLEAN) { + PyTuple_SET_ITEM(values, i, PyBool_FromLong(ci->values[i].value.boolean)); + } + } + + tmp = cpy_string_to_unicode_or_bytes(ci->key); + item = PyObject_CallFunction((void *)&ConfigType, "NONO", tmp, parent, values, + Py_None); + if (item == NULL) + return NULL; + children = PyTuple_New(ci->children_num); /* New reference. */ + for (int i = 0; i < ci->children_num; ++i) { + PyTuple_SET_ITEM(children, i, + cpy_oconfig_to_pyconfig(ci->children + i, item)); + } + tmp = ((Config *)item)->children; + ((Config *)item)->children = children; + Py_XDECREF(tmp); + return item; } #ifdef IS_PY3K static struct PyModuleDef collectdmodule = { - PyModuleDef_HEAD_INIT, - "collectd", /* name of module */ - "The python interface to collectd", /* module documentation, may be NULL */ - -1, - cpy_methods -}; + PyModuleDef_HEAD_INIT, "collectd", /* name of module */ + "The python interface to collectd", /* module documentation, may be NULL */ + -1, cpy_methods}; PyMODINIT_FUNC PyInit_collectd(void) { - return PyModule_Create(&collectdmodule); + return PyModule_Create(&collectdmodule); } #endif static int cpy_init_python(void) { - PyOS_sighandler_t cur_sig; - PyObject *sys; - PyObject *module; + PyOS_sighandler_t cur_sig; + PyObject *sys; + PyObject *module; #ifdef IS_PY3K - wchar_t *argv = L""; - /* Add a builtin module, before Py_Initialize */ - PyImport_AppendInittab("collectd", PyInit_collectd); + wchar_t *argv = L""; + /* Add a builtin module, before Py_Initialize */ + PyImport_AppendInittab("collectd", PyInit_collectd); #else - char *argv = ""; + char *argv = ""; #endif - /* Chances are the current signal handler is already SIG_DFL, but let's make sure. */ - cur_sig = PyOS_setsig(SIGINT, SIG_DFL); - Py_Initialize(); - python_sigint_handler = PyOS_setsig(SIGINT, cur_sig); - - PyType_Ready(&ConfigType); - PyType_Ready(&PluginDataType); - ValuesType.tp_base = &PluginDataType; - PyType_Ready(&ValuesType); - NotificationType.tp_base = &PluginDataType; - PyType_Ready(&NotificationType); - SignedType.tp_base = &PyLong_Type; - PyType_Ready(&SignedType); - UnsignedType.tp_base = &PyLong_Type; - PyType_Ready(&UnsignedType); - sys = PyImport_ImportModule("sys"); /* New reference. */ - if (sys == NULL) { - cpy_log_exception("python initialization"); - return 1; - } - sys_path = PyObject_GetAttrString(sys, "path"); /* New reference. */ - Py_DECREF(sys); - if (sys_path == NULL) { - cpy_log_exception("python initialization"); - return 1; - } - PySys_SetArgv(1, &argv); - PyList_SetSlice(sys_path, 0, 1, NULL); + /* Chances are the current signal handler is already SIG_DFL, but let's make + * sure. */ + cur_sig = PyOS_setsig(SIGINT, SIG_DFL); + Py_Initialize(); + python_sigint_handler = PyOS_setsig(SIGINT, cur_sig); + + PyType_Ready(&ConfigType); + PyType_Ready(&PluginDataType); + ValuesType.tp_base = &PluginDataType; + PyType_Ready(&ValuesType); + NotificationType.tp_base = &PluginDataType; + PyType_Ready(&NotificationType); + SignedType.tp_base = &PyLong_Type; + PyType_Ready(&SignedType); + UnsignedType.tp_base = &PyLong_Type; + PyType_Ready(&UnsignedType); + sys = PyImport_ImportModule("sys"); /* New reference. */ + if (sys == NULL) { + cpy_log_exception("python initialization"); + return 1; + } + sys_path = PyObject_GetAttrString(sys, "path"); /* New reference. */ + Py_DECREF(sys); + if (sys_path == NULL) { + 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"); + module = PyImport_ImportModule("collectd"); #else - module = Py_InitModule("collectd", cpy_methods); /* Borrowed reference. */ + module = Py_InitModule("collectd", cpy_methods); /* Borrowed reference. */ #endif - PyModule_AddObject(module, "Config", (void *) &ConfigType); /* Steals a reference. */ - PyModule_AddObject(module, "Values", (void *) &ValuesType); /* Steals a reference. */ - PyModule_AddObject(module, "Notification", (void *) &NotificationType); /* Steals a reference. */ - PyModule_AddObject(module, "Signed", (void *) &SignedType); /* Steals a reference. */ - PyModule_AddObject(module, "Unsigned", (void *) &UnsignedType); /* Steals a reference. */ - PyModule_AddIntConstant(module, "LOG_DEBUG", LOG_DEBUG); - PyModule_AddIntConstant(module, "LOG_INFO", LOG_INFO); - PyModule_AddIntConstant(module, "LOG_NOTICE", LOG_NOTICE); - PyModule_AddIntConstant(module, "LOG_WARNING", LOG_WARNING); - PyModule_AddIntConstant(module, "LOG_ERROR", LOG_ERR); - PyModule_AddIntConstant(module, "NOTIF_FAILURE", NOTIF_FAILURE); - PyModule_AddIntConstant(module, "NOTIF_WARNING", NOTIF_WARNING); - PyModule_AddIntConstant(module, "NOTIF_OKAY", NOTIF_OKAY); - PyModule_AddStringConstant(module, "DS_TYPE_COUNTER", DS_TYPE_TO_STRING(DS_TYPE_COUNTER)); - PyModule_AddStringConstant(module, "DS_TYPE_GAUGE", DS_TYPE_TO_STRING(DS_TYPE_GAUGE)); - PyModule_AddStringConstant(module, "DS_TYPE_DERIVE", DS_TYPE_TO_STRING(DS_TYPE_DERIVE)); - PyModule_AddStringConstant(module, "DS_TYPE_ABSOLUTE", DS_TYPE_TO_STRING(DS_TYPE_ABSOLUTE)); - return 0; + PyModule_AddObject(module, "Config", + (void *)&ConfigType); /* Steals a reference. */ + PyModule_AddObject(module, "Values", + (void *)&ValuesType); /* Steals a reference. */ + PyModule_AddObject(module, "Notification", + (void *)&NotificationType); /* Steals a reference. */ + PyModule_AddObject(module, "Signed", + (void *)&SignedType); /* Steals a reference. */ + PyModule_AddObject(module, "Unsigned", + (void *)&UnsignedType); /* Steals a reference. */ + PyModule_AddIntConstant(module, "LOG_DEBUG", LOG_DEBUG); + PyModule_AddIntConstant(module, "LOG_INFO", LOG_INFO); + PyModule_AddIntConstant(module, "LOG_NOTICE", LOG_NOTICE); + PyModule_AddIntConstant(module, "LOG_WARNING", LOG_WARNING); + PyModule_AddIntConstant(module, "LOG_ERROR", LOG_ERR); + PyModule_AddIntConstant(module, "NOTIF_FAILURE", NOTIF_FAILURE); + PyModule_AddIntConstant(module, "NOTIF_WARNING", NOTIF_WARNING); + PyModule_AddIntConstant(module, "NOTIF_OKAY", NOTIF_OKAY); + PyModule_AddStringConstant(module, "DS_TYPE_COUNTER", + DS_TYPE_TO_STRING(DS_TYPE_COUNTER)); + PyModule_AddStringConstant(module, "DS_TYPE_GAUGE", + DS_TYPE_TO_STRING(DS_TYPE_GAUGE)); + PyModule_AddStringConstant(module, "DS_TYPE_DERIVE", + DS_TYPE_TO_STRING(DS_TYPE_DERIVE)); + PyModule_AddStringConstant(module, "DS_TYPE_ABSOLUTE", + DS_TYPE_TO_STRING(DS_TYPE_ABSOLUTE)); + return 0; } static int cpy_config(oconfig_item_t *ci) { - PyObject *tb; - int status = 0; - - /* Ok in theory we shouldn't do initialization at this point - * but we have to. In order to give python scripts a chance - * to register a config callback we need to be able to execute - * python code during the config callback so we have to start - * the interpreter here. */ - /* Do *not* use the python "thread" module at this point! */ - - if (!Py_IsInitialized() && cpy_init_python()) return 1; - - for (int i = 0; i < ci->children_num; ++i) { - oconfig_item_t *item = ci->children + i; - - if (strcasecmp(item->key, "Interactive") == 0) { - if (cf_util_get_boolean(item, &do_interactive) != 0) { - status = 1; - continue; - } - } else if (strcasecmp(item->key, "Encoding") == 0) { - char *encoding = NULL; - if (cf_util_get_string(item, &encoding) != 0) { - status = 1; - continue; - } + PyObject *tb; + int status = 0; + + /* Ok in theory we shouldn't do initialization at this point + * but we have to. In order to give python scripts a chance + * to register a config callback we need to be able to execute + * python code during the config callback so we have to start + * the interpreter here. */ + /* Do *not* use the python "thread" module at this point! */ + + if (!Py_IsInitialized() && cpy_init_python()) + return 1; + + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *item = ci->children + i; + + if (strcasecmp(item->key, "Interactive") == 0) { + if (cf_util_get_boolean(item, &do_interactive) != 0) { + status = 1; + continue; + } + } else if (strcasecmp(item->key, "Encoding") == 0) { + char *encoding = NULL; + if (cf_util_get_string(item, &encoding) != 0) { + status = 1; + continue; + } #ifdef IS_PY3K - ERROR("python: \"Encoding\" was used in the config file but Python3 was used, which does not support changing encodings"); - status = 1; - sfree(encoding); - continue; + ERROR("python: \"Encoding\" was used in the config file but Python3 was " + "used, which does not support changing encodings"); + status = 1; + sfree(encoding); + continue; #else - /* Why is this even necessary? And undocumented? */ - if (PyUnicode_SetDefaultEncoding(encoding)) { - cpy_log_exception("setting default encoding"); - status = 1; - } + /* Why is this even necessary? And undocumented? */ + if (PyUnicode_SetDefaultEncoding(encoding)) { + cpy_log_exception("setting default encoding"); + status = 1; + } #endif - sfree(encoding); - } else if (strcasecmp(item->key, "LogTraces") == 0) { - _Bool log_traces; - if (cf_util_get_boolean(item, &log_traces) != 0) { - status = 1; - continue; - } - if (!log_traces) { - Py_XDECREF(cpy_format_exception); - cpy_format_exception = NULL; - continue; - } - if (cpy_format_exception) - continue; - tb = PyImport_ImportModule("traceback"); /* New reference. */ - if (tb == NULL) { - cpy_log_exception("python initialization"); - status = 1; - continue; - } - cpy_format_exception = PyObject_GetAttrString(tb, "format_exception"); /* New reference. */ - Py_DECREF(tb); - if (cpy_format_exception == NULL) { - cpy_log_exception("python initialization"); - status = 1; - } - } else if (strcasecmp(item->key, "ModulePath") == 0) { - char *dir = NULL; - PyObject *dir_object; - - if (cf_util_get_string(item, &dir) != 0) { - status = 1; - continue; - } - dir_object = cpy_string_to_unicode_or_bytes(dir); /* New reference. */ - if (dir_object == NULL) { - ERROR("python plugin: Unable to convert \"%s\" to " - "a python object.", dir); - free(dir); - cpy_log_exception("python initialization"); - status = 1; - continue; - } - if (PyList_Insert(sys_path, 0, dir_object) != 0) { - ERROR("python plugin: Unable to prepend \"%s\" to " - "python module path.", dir); - cpy_log_exception("python initialization"); - status = 1; - } - Py_DECREF(dir_object); - free(dir); - } else if (strcasecmp(item->key, "Import") == 0) { - char *module_name = NULL; - PyObject *module; - - if (cf_util_get_string(item, &module_name) != 0) { - status = 1; - continue; - } - module = PyImport_ImportModule(module_name); /* New reference. */ - if (module == NULL) { - ERROR("python plugin: Error importing module \"%s\".", module_name); - cpy_log_exception("importing module"); - status = 1; - } - free(module_name); - Py_XDECREF(module); - } else if (strcasecmp(item->key, "Module") == 0) { - char *name = NULL; - cpy_callback_t *c; - PyObject *ret; - - if (cf_util_get_string(item, &name) != 0) { - status = 1; - continue; - } - for (c = cpy_config_callbacks; c; c = c->next) { - if (strcasecmp(c->name + 7, name) == 0) - break; - } - if (c == NULL) { - WARNING("python plugin: Found a configuration for the \"%s\" plugin, " - "but the plugin isn't loaded or didn't register " - "a configuration callback.", name); - free(name); - continue; - } - free(name); - if (c->data == NULL) - ret = PyObject_CallFunction(c->callback, "N", - cpy_oconfig_to_pyconfig(item, NULL)); /* New reference. */ - else - ret = PyObject_CallFunction(c->callback, "NO", - cpy_oconfig_to_pyconfig(item, NULL), c->data); /* New reference. */ - if (ret == NULL) { - cpy_log_exception("loading module"); - status = 1; - } else - Py_DECREF(ret); - } else { - ERROR("python plugin: Unknown config key \"%s\".", item->key); - status = 1; - } - } - return (status); + sfree(encoding); + } else if (strcasecmp(item->key, "LogTraces") == 0) { + _Bool log_traces; + if (cf_util_get_boolean(item, &log_traces) != 0) { + status = 1; + continue; + } + if (!log_traces) { + Py_XDECREF(cpy_format_exception); + cpy_format_exception = NULL; + continue; + } + if (cpy_format_exception) + continue; + tb = PyImport_ImportModule("traceback"); /* New reference. */ + if (tb == NULL) { + cpy_log_exception("python initialization"); + status = 1; + continue; + } + cpy_format_exception = + PyObject_GetAttrString(tb, "format_exception"); /* New reference. */ + Py_DECREF(tb); + if (cpy_format_exception == NULL) { + cpy_log_exception("python initialization"); + status = 1; + } + } else if (strcasecmp(item->key, "ModulePath") == 0) { + char *dir = NULL; + PyObject *dir_object; + + if (cf_util_get_string(item, &dir) != 0) { + status = 1; + continue; + } + dir_object = cpy_string_to_unicode_or_bytes(dir); /* New reference. */ + if (dir_object == NULL) { + ERROR("python plugin: Unable to convert \"%s\" to " + "a python object.", + dir); + free(dir); + cpy_log_exception("python initialization"); + status = 1; + continue; + } + if (PyList_Insert(sys_path, 0, dir_object) != 0) { + ERROR("python plugin: Unable to prepend \"%s\" to " + "python module path.", + dir); + cpy_log_exception("python initialization"); + status = 1; + } + Py_DECREF(dir_object); + free(dir); + } else if (strcasecmp(item->key, "Import") == 0) { + char *module_name = NULL; + PyObject *module; + + if (cf_util_get_string(item, &module_name) != 0) { + status = 1; + continue; + } + module = PyImport_ImportModule(module_name); /* New reference. */ + if (module == NULL) { + ERROR("python plugin: Error importing module \"%s\".", module_name); + cpy_log_exception("importing module"); + status = 1; + } + free(module_name); + Py_XDECREF(module); + } else if (strcasecmp(item->key, "Module") == 0) { + char *name = NULL; + cpy_callback_t *c; + PyObject *ret; + + if (cf_util_get_string(item, &name) != 0) { + status = 1; + continue; + } + for (c = cpy_config_callbacks; c; c = c->next) { + if (strcasecmp(c->name + 7, name) == 0) + break; + } + if (c == NULL) { + WARNING("python plugin: Found a configuration for the \"%s\" plugin, " + "but the plugin isn't loaded or didn't register " + "a configuration callback.", + name); + free(name); + continue; + } + free(name); + if (c->data == NULL) + ret = PyObject_CallFunction( + c->callback, "N", + cpy_oconfig_to_pyconfig(item, NULL)); /* New reference. */ + else + ret = PyObject_CallFunction(c->callback, "NO", + cpy_oconfig_to_pyconfig(item, NULL), + c->data); /* New reference. */ + if (ret == NULL) { + cpy_log_exception("loading module"); + status = 1; + } else + Py_DECREF(ret); + } else { + ERROR("python plugin: Unknown config key \"%s\".", item->key); + status = 1; + } + } + return (status); } void module_register(void) { - plugin_register_complex_config("python", cpy_config); - plugin_register_init("python", cpy_init); - plugin_register_shutdown("python", cpy_shutdown); + plugin_register_complex_config("python", cpy_config); + plugin_register_init("python", cpy_init); + plugin_register_shutdown("python", cpy_shutdown); } diff --git a/src/pyvalues.c b/src/pyvalues.c index a7cb7923..e1856b84 100644 --- a/src/pyvalues.c +++ b/src/pyvalues.c @@ -33,1079 +33,1175 @@ #include "cpython.h" -#define FreeAll() do {\ - PyMem_Free(type);\ - PyMem_Free(plugin_instance);\ - PyMem_Free(type_instance);\ - PyMem_Free(plugin);\ - PyMem_Free(host);\ -} while(0) +#define FreeAll() \ + do { \ + PyMem_Free(type); \ + PyMem_Free(plugin_instance); \ + PyMem_Free(type_instance); \ + PyMem_Free(plugin); \ + PyMem_Free(host); \ + } while (0) static PyObject *cpy_common_repr(PyObject *s) { - PyObject *ret, *tmp; - static PyObject *l_type = NULL, *l_type_instance = NULL, *l_plugin = NULL, *l_plugin_instance = NULL; - static PyObject *l_host = NULL, *l_time = NULL; - PluginData *self = (PluginData *) s; - - if (l_type == NULL) - l_type = cpy_string_to_unicode_or_bytes("(type="); - if (l_type_instance == NULL) - l_type_instance = cpy_string_to_unicode_or_bytes(",type_instance="); - if (l_plugin == NULL) - l_plugin = cpy_string_to_unicode_or_bytes(",plugin="); - if (l_plugin_instance == NULL) - l_plugin_instance = cpy_string_to_unicode_or_bytes(",plugin_instance="); - if (l_host == NULL) - l_host = cpy_string_to_unicode_or_bytes(",host="); - if (l_time == NULL) - l_time = cpy_string_to_unicode_or_bytes(",time="); - - if (!l_type || !l_type_instance || !l_plugin || !l_plugin_instance || !l_host || !l_time) - return NULL; - - ret = cpy_string_to_unicode_or_bytes(s->ob_type->tp_name); - - CPY_STRCAT(&ret, l_type); - tmp = cpy_string_to_unicode_or_bytes(self->type); - CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); - CPY_STRCAT_AND_DEL(&ret, tmp); - - if (self->type_instance[0] != 0) { - CPY_STRCAT(&ret, l_type_instance); - tmp = cpy_string_to_unicode_or_bytes(self->type_instance); - CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); - CPY_STRCAT_AND_DEL(&ret, tmp); - } - - if (self->plugin[0] != 0) { - CPY_STRCAT(&ret, l_plugin); - tmp = cpy_string_to_unicode_or_bytes(self->plugin); - CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); - CPY_STRCAT_AND_DEL(&ret, tmp); - } - - if (self->plugin_instance[0] != 0) { - CPY_STRCAT(&ret, l_plugin_instance); - tmp = cpy_string_to_unicode_or_bytes(self->plugin_instance); - CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); - CPY_STRCAT_AND_DEL(&ret, tmp); - } - - if (self->host[0] != 0) { - CPY_STRCAT(&ret, l_host); - tmp = cpy_string_to_unicode_or_bytes(self->host); - CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); - CPY_STRCAT_AND_DEL(&ret, tmp); - } - - if (self->time != 0) { - CPY_STRCAT(&ret, l_time); - tmp = PyFloat_FromDouble(self->time); - CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); - CPY_STRCAT_AND_DEL(&ret, tmp); - } - return ret; + PyObject *ret, *tmp; + static PyObject *l_type = NULL, *l_type_instance = NULL, *l_plugin = NULL, + *l_plugin_instance = NULL; + static PyObject *l_host = NULL, *l_time = NULL; + PluginData *self = (PluginData *)s; + + if (l_type == NULL) + l_type = cpy_string_to_unicode_or_bytes("(type="); + if (l_type_instance == NULL) + l_type_instance = cpy_string_to_unicode_or_bytes(",type_instance="); + if (l_plugin == NULL) + l_plugin = cpy_string_to_unicode_or_bytes(",plugin="); + if (l_plugin_instance == NULL) + l_plugin_instance = cpy_string_to_unicode_or_bytes(",plugin_instance="); + if (l_host == NULL) + l_host = cpy_string_to_unicode_or_bytes(",host="); + if (l_time == NULL) + l_time = cpy_string_to_unicode_or_bytes(",time="); + + if (!l_type || !l_type_instance || !l_plugin || !l_plugin_instance || + !l_host || !l_time) + return NULL; + + ret = cpy_string_to_unicode_or_bytes(s->ob_type->tp_name); + + CPY_STRCAT(&ret, l_type); + tmp = cpy_string_to_unicode_or_bytes(self->type); + CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); + CPY_STRCAT_AND_DEL(&ret, tmp); + + if (self->type_instance[0] != 0) { + CPY_STRCAT(&ret, l_type_instance); + tmp = cpy_string_to_unicode_or_bytes(self->type_instance); + CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); + CPY_STRCAT_AND_DEL(&ret, tmp); + } + + if (self->plugin[0] != 0) { + CPY_STRCAT(&ret, l_plugin); + tmp = cpy_string_to_unicode_or_bytes(self->plugin); + CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); + CPY_STRCAT_AND_DEL(&ret, tmp); + } + + if (self->plugin_instance[0] != 0) { + CPY_STRCAT(&ret, l_plugin_instance); + tmp = cpy_string_to_unicode_or_bytes(self->plugin_instance); + CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); + CPY_STRCAT_AND_DEL(&ret, tmp); + } + + if (self->host[0] != 0) { + CPY_STRCAT(&ret, l_host); + tmp = cpy_string_to_unicode_or_bytes(self->host); + CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); + CPY_STRCAT_AND_DEL(&ret, tmp); + } + + if (self->time != 0) { + CPY_STRCAT(&ret, l_time); + tmp = PyFloat_FromDouble(self->time); + CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); + CPY_STRCAT_AND_DEL(&ret, tmp); + } + return ret; } -static char time_doc[] = "This is the Unix timestamp of the time this value was read.\n" - "For dispatching values this can be set to 0 which means \"now\".\n" - "This means the time the value is actually dispatched, not the time\n" - "it was set to 0."; +static char time_doc[] = + "This is the Unix timestamp of the time this value was read.\n" + "For dispatching values this can be set to 0 which means \"now\".\n" + "This means the time the value is actually dispatched, not the time\n" + "it was set to 0."; -static char host_doc[] = "The hostname of the host this value was read from.\n" - "For dispatching this can be set to an empty string which means\n" - "the local hostname as defined in collectd.conf."; +static char host_doc[] = + "The hostname of the host this value was read from.\n" + "For dispatching this can be set to an empty string which means\n" + "the local hostname as defined in collectd.conf."; -static char type_doc[] = "The type of this value. This type has to be defined\n" - "in the types.db file. Attempting to set it to any other value\n" - "will raise a TypeError exception.\n" - "Assigning a type is mandatory, calling dispatch without doing\n" - "so will raise a RuntimeError exception."; +static char type_doc[] = + "The type of this value. This type has to be defined\n" + "in the types.db file. Attempting to set it to any other value\n" + "will raise a TypeError exception.\n" + "Assigning a type is mandatory, calling dispatch without doing\n" + "so will raise a RuntimeError exception."; static char type_instance_doc[] = ""; -static char plugin_doc[] = "The name of the plugin that read the data. Setting this\n" - "member to an empty string will insert \"python\" upon dispatching."; +static char plugin_doc[] = + "The name of the plugin that read the data. Setting this\n" + "member to an empty string will insert \"python\" upon dispatching."; static char plugin_instance_doc[] = ""; -static char PluginData_doc[] = "This is an internal class that is the base for Values\n" - "and Notification. It is pretty useless by itself and is therefore not\n" - "exported to the collectd module."; - -static PyObject *PluginData_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PluginData *self; - - self = (PluginData *) type->tp_alloc(type, 0); - if (self == NULL) - return NULL; - - self->time = 0; - self->host[0] = 0; - self->plugin[0] = 0; - self->plugin_instance[0] = 0; - self->type[0] = 0; - self->type_instance[0] = 0; - return (PyObject *) self; +static char PluginData_doc[] = + "This is an internal class that is the base for Values\n" + "and Notification. It is pretty useless by itself and is therefore not\n" + "exported to the collectd module."; + +static PyObject *PluginData_new(PyTypeObject *type, PyObject *args, + PyObject *kwds) { + PluginData *self; + + self = (PluginData *)type->tp_alloc(type, 0); + if (self == NULL) + return NULL; + + self->time = 0; + self->host[0] = 0; + self->plugin[0] = 0; + self->plugin_instance[0] = 0; + self->type[0] = 0; + self->type_instance[0] = 0; + return (PyObject *)self; } static int PluginData_init(PyObject *s, PyObject *args, PyObject *kwds) { - PluginData *self = (PluginData *) s; - double time = 0; - char *type = NULL, *plugin_instance = NULL, *type_instance = NULL, *plugin = NULL, *host = NULL; - static char *kwlist[] = {"type", "plugin_instance", "type_instance", - "plugin", "host", "time", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etetetetetd", kwlist, NULL, &type, - NULL, &plugin_instance, NULL, &type_instance, NULL, &plugin, NULL, &host, &time)) - return -1; - - if (type && plugin_get_ds(type) == NULL) { - PyErr_Format(PyExc_TypeError, "Dataset %s not found", type); - FreeAll(); - return -1; - } - - sstrncpy(self->host, host ? host : "", sizeof(self->host)); - sstrncpy(self->plugin, plugin ? plugin : "", sizeof(self->plugin)); - sstrncpy(self->plugin_instance, plugin_instance ? plugin_instance : "", sizeof(self->plugin_instance)); - sstrncpy(self->type, type ? type : "", sizeof(self->type)); - sstrncpy(self->type_instance, type_instance ? type_instance : "", sizeof(self->type_instance)); - self->time = time; - - FreeAll(); - - return 0; + PluginData *self = (PluginData *)s; + double time = 0; + char *type = NULL, *plugin_instance = NULL, *type_instance = NULL, + *plugin = NULL, *host = NULL; + static char *kwlist[] = { + "type", "plugin_instance", "type_instance", "plugin", "host", "time", + NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etetetetetd", kwlist, NULL, + &type, NULL, &plugin_instance, NULL, + &type_instance, NULL, &plugin, NULL, &host, + &time)) + return -1; + + if (type && plugin_get_ds(type) == NULL) { + PyErr_Format(PyExc_TypeError, "Dataset %s not found", type); + FreeAll(); + return -1; + } + + sstrncpy(self->host, host ? host : "", sizeof(self->host)); + sstrncpy(self->plugin, plugin ? plugin : "", sizeof(self->plugin)); + sstrncpy(self->plugin_instance, plugin_instance ? plugin_instance : "", + sizeof(self->plugin_instance)); + sstrncpy(self->type, type ? type : "", sizeof(self->type)); + sstrncpy(self->type_instance, type_instance ? type_instance : "", + sizeof(self->type_instance)); + self->time = time; + + FreeAll(); + + return 0; } static PyObject *PluginData_repr(PyObject *s) { - PyObject *ret; - static PyObject *l_closing = NULL; + PyObject *ret; + static PyObject *l_closing = NULL; - if (l_closing == NULL) - l_closing = cpy_string_to_unicode_or_bytes(")"); + if (l_closing == NULL) + l_closing = cpy_string_to_unicode_or_bytes(")"); - if (l_closing == NULL) - return NULL; + if (l_closing == NULL) + return NULL; - ret = cpy_common_repr(s); - CPY_STRCAT(&ret, l_closing); - return ret; + ret = cpy_common_repr(s); + CPY_STRCAT(&ret, l_closing); + return ret; } static PyMemberDef PluginData_members[] = { - {"time", T_DOUBLE, offsetof(PluginData, time), 0, time_doc}, - {NULL} -}; + {"time", T_DOUBLE, offsetof(PluginData, time), 0, time_doc}, {NULL}}; static PyObject *PluginData_getstring(PyObject *self, void *data) { - const char *value = ((char *) self) + (intptr_t) data; + const char *value = ((char *)self) + (intptr_t)data; - return cpy_string_to_unicode_or_bytes(value); + return cpy_string_to_unicode_or_bytes(value); } static int PluginData_setstring(PyObject *self, PyObject *value, void *data) { - char *old; - const char *new; - - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, "Cannot delete this attribute"); - return -1; - } - Py_INCREF(value); - new = cpy_unicode_or_bytes_to_string(&value); - if (new == NULL) { - Py_DECREF(value); - return -1; - } - old = ((char *) self) + (intptr_t) data; - sstrncpy(old, new, DATA_MAX_NAME_LEN); - Py_DECREF(value); - return 0; + char *old; + const char *new; + + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, "Cannot delete this attribute"); + return -1; + } + Py_INCREF(value); + new = cpy_unicode_or_bytes_to_string(&value); + if (new == NULL) { + Py_DECREF(value); + return -1; + } + old = ((char *)self) + (intptr_t)data; + sstrncpy(old, new, DATA_MAX_NAME_LEN); + Py_DECREF(value); + return 0; } static int PluginData_settype(PyObject *self, PyObject *value, void *data) { - char *old; - const char *new; - - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, "Cannot delete this attribute"); - return -1; - } - Py_INCREF(value); - new = cpy_unicode_or_bytes_to_string(&value); - if (new == NULL) { - Py_DECREF(value); - return -1; - } - - if (plugin_get_ds(new) == NULL) { - PyErr_Format(PyExc_TypeError, "Dataset %s not found", new); - Py_DECREF(value); - return -1; - } - - old = ((char *) self) + (intptr_t) data; - sstrncpy(old, new, DATA_MAX_NAME_LEN); - Py_DECREF(value); - return 0; + char *old; + const char *new; + + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, "Cannot delete this attribute"); + return -1; + } + Py_INCREF(value); + new = cpy_unicode_or_bytes_to_string(&value); + if (new == NULL) { + Py_DECREF(value); + return -1; + } + + if (plugin_get_ds(new) == NULL) { + PyErr_Format(PyExc_TypeError, "Dataset %s not found", new); + Py_DECREF(value); + return -1; + } + + old = ((char *)self) + (intptr_t)data; + sstrncpy(old, new, DATA_MAX_NAME_LEN); + Py_DECREF(value); + return 0; } static PyGetSetDef PluginData_getseters[] = { - {"host", PluginData_getstring, PluginData_setstring, host_doc, (void *) offsetof(PluginData, host)}, - {"plugin", PluginData_getstring, PluginData_setstring, plugin_doc, (void *) offsetof(PluginData, plugin)}, - {"plugin_instance", PluginData_getstring, PluginData_setstring, plugin_instance_doc, (void *) offsetof(PluginData, plugin_instance)}, - {"type_instance", PluginData_getstring, PluginData_setstring, type_instance_doc, (void *) offsetof(PluginData, type_instance)}, - {"type", PluginData_getstring, PluginData_settype, type_doc, (void *) offsetof(PluginData, type)}, - {NULL} -}; + {"host", PluginData_getstring, PluginData_setstring, host_doc, + (void *)offsetof(PluginData, host)}, + {"plugin", PluginData_getstring, PluginData_setstring, plugin_doc, + (void *)offsetof(PluginData, plugin)}, + {"plugin_instance", PluginData_getstring, PluginData_setstring, + plugin_instance_doc, (void *)offsetof(PluginData, plugin_instance)}, + {"type_instance", PluginData_getstring, PluginData_setstring, + type_instance_doc, (void *)offsetof(PluginData, type_instance)}, + {"type", PluginData_getstring, PluginData_settype, type_doc, + (void *)offsetof(PluginData, type)}, + {NULL}}; PyTypeObject PluginDataType = { - CPY_INIT_TYPE - "collectd.PluginData", /* tp_name */ - sizeof(PluginData), /* tp_basicsize */ - 0, /* Will be filled in later */ - 0, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - PluginData_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE /*| Py_TPFLAGS_HAVE_GC*/, /*tp_flags*/ - PluginData_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - PluginData_members, /* tp_members */ - PluginData_getseters, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - PluginData_init, /* tp_init */ - 0, /* tp_alloc */ - PluginData_new /* tp_new */ + CPY_INIT_TYPE "collectd.PluginData", /* tp_name */ + sizeof(PluginData), /* tp_basicsize */ + 0, /* Will be filled in later */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + PluginData_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | + Py_TPFLAGS_BASETYPE /*| Py_TPFLAGS_HAVE_GC*/, /*tp_flags*/ + PluginData_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + PluginData_members, /* tp_members */ + PluginData_getseters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + PluginData_init, /* tp_init */ + 0, /* tp_alloc */ + PluginData_new /* tp_new */ }; -static char interval_doc[] = "The interval is the timespan in seconds between two submits for\n" - "the same data source. This value has to be a positive integer, so you can't\n" - "submit more than one value per second. If this member is set to a\n" - "non-positive value, the default value as specified in the config file will\n" - "be used (default: 10).\n" - "\n" - "If you submit values more often than the specified interval, the average\n" - "will be used. If you submit less values, your graphs will have gaps."; - -static char values_doc[] = "These are the actual values that get dispatched to collectd.\n" - "It has to be a sequence (a tuple or list) of numbers.\n" - "The size of the sequence and the type of its content depend on the type\n" - "member in the types.db file. For more information on this read the\n" - "types.db man page.\n" - "\n" - "If the sequence does not have the correct size upon dispatch a RuntimeError\n" - "exception will be raised. If the content of the sequence is not a number,\n" - "a TypeError exception will be raised."; - -static char meta_doc[] = "These are the meta data for this Value object.\n" - "It has to be a dictionary of numbers, strings or bools. All keys must be\n" - "strings. int and long objects will be dispatched as signed integers unless\n" - "they are between 2**63 and 2**64-1, which will result in an unsigned integer.\n" - "You can force one of these storage classes by using the classes\n" - "collectd.Signed and collectd.Unsigned. A meta object received by a write\n" - "callback will always contain Signed or Unsigned objects."; - -static char dispatch_doc[] = "dispatch([type][, values][, plugin_instance][, type_instance]" - "[, plugin][, host][, time][, interval]) -> None. Dispatch a value list.\n" - "\n" - "Dispatch this instance to the collectd process. The object has members\n" - "for each of the possible arguments for this method. For a detailed explanation\n" - "of these parameters see the member of the same same.\n" - "\n" - "If you do not submit a parameter the value saved in its member will be submitted.\n" - "If you do provide a parameter it will be used instead, without altering the member."; - -static char write_doc[] = "write([destination][, type][, values][, plugin_instance][, type_instance]" - "[, plugin][, host][, time][, interval]) -> None. Dispatch a value list.\n" - "\n" - "Write this instance to a single plugin or all plugins if 'destination' is omitted.\n" - "This will bypass the main collectd process and all filtering and caching.\n" - "Other than that it works similar to 'dispatch'. In most cases 'dispatch' should be\n" - "used instead of 'write'.\n"; - -static char Values_doc[] = "A Values object used for dispatching values to collectd and receiving values from write callbacks."; - -static PyObject *Values_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - Values *self; - - self = (Values *) PluginData_new(type, args, kwds); - if (self == NULL) - return NULL; - - self->values = PyList_New(0); - self->meta = PyDict_New(); - self->interval = 0; - return (PyObject *) self; +static char interval_doc[] = + "The interval is the timespan in seconds between two submits for\n" + "the same data source. This value has to be a positive integer, so you " + "can't\n" + "submit more than one value per second. If this member is set to a\n" + "non-positive value, the default value as specified in the config file " + "will\n" + "be used (default: 10).\n" + "\n" + "If you submit values more often than the specified interval, the average\n" + "will be used. If you submit less values, your graphs will have gaps."; + +static char values_doc[] = + "These are the actual values that get dispatched to collectd.\n" + "It has to be a sequence (a tuple or list) of numbers.\n" + "The size of the sequence and the type of its content depend on the type\n" + "member in the types.db file. For more information on this read the\n" + "types.db man page.\n" + "\n" + "If the sequence does not have the correct size upon dispatch a " + "RuntimeError\n" + "exception will be raised. If the content of the sequence is not a " + "number,\n" + "a TypeError exception will be raised."; + +static char meta_doc[] = + "These are the meta data for this Value object.\n" + "It has to be a dictionary of numbers, strings or bools. All keys must be\n" + "strings. int and long objects will be dispatched as signed integers " + "unless\n" + "they are between 2**63 and 2**64-1, which will result in an unsigned " + "integer.\n" + "You can force one of these storage classes by using the classes\n" + "collectd.Signed and collectd.Unsigned. A meta object received by a write\n" + "callback will always contain Signed or Unsigned objects."; + +static char dispatch_doc[] = + "dispatch([type][, values][, plugin_instance][, type_instance]" + "[, plugin][, host][, time][, interval]) -> None. Dispatch a value list.\n" + "\n" + "Dispatch this instance to the collectd process. The object has members\n" + "for each of the possible arguments for this method. For a detailed " + "explanation\n" + "of these parameters see the member of the same same.\n" + "\n" + "If you do not submit a parameter the value saved in its member will be " + "submitted.\n" + "If you do provide a parameter it will be used instead, without altering " + "the member."; + +static char write_doc[] = + "write([destination][, type][, values][, plugin_instance][, type_instance]" + "[, plugin][, host][, time][, interval]) -> None. Dispatch a value list.\n" + "\n" + "Write this instance to a single plugin or all plugins if 'destination' is " + "omitted.\n" + "This will bypass the main collectd process and all filtering and " + "caching.\n" + "Other than that it works similar to 'dispatch'. In most cases 'dispatch' " + "should be\n" + "used instead of 'write'.\n"; + +static char Values_doc[] = "A Values object used for dispatching values to " + "collectd and receiving values from write " + "callbacks."; + +static PyObject *Values_new(PyTypeObject *type, PyObject *args, + PyObject *kwds) { + Values *self; + + self = (Values *)PluginData_new(type, args, kwds); + if (self == NULL) + return NULL; + + self->values = PyList_New(0); + self->meta = PyDict_New(); + self->interval = 0; + return (PyObject *)self; } static int Values_init(PyObject *s, PyObject *args, PyObject *kwds) { - Values *self = (Values *) s; - double interval = 0, time = 0; - PyObject *values = NULL, *meta = NULL, *tmp; - char *type = NULL, *plugin_instance = NULL, *type_instance = NULL, *plugin = NULL, *host = NULL; - static char *kwlist[] = {"type", "values", "plugin_instance", "type_instance", - "plugin", "host", "time", "interval", "meta", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetddO", kwlist, - NULL, &type, &values, NULL, &plugin_instance, NULL, &type_instance, - NULL, &plugin, NULL, &host, &time, &interval, &meta)) - return -1; - - if (type && plugin_get_ds(type) == NULL) { - PyErr_Format(PyExc_TypeError, "Dataset %s not found", type); - FreeAll(); - return -1; - } - - sstrncpy(self->data.host, host ? host : "", sizeof(self->data.host)); - sstrncpy(self->data.plugin, plugin ? plugin : "", sizeof(self->data.plugin)); - sstrncpy(self->data.plugin_instance, plugin_instance ? plugin_instance : "", sizeof(self->data.plugin_instance)); - sstrncpy(self->data.type, type ? type : "", sizeof(self->data.type)); - sstrncpy(self->data.type_instance, type_instance ? type_instance : "", sizeof(self->data.type_instance)); - self->data.time = time; - - FreeAll(); - - if (values == NULL) { - values = PyList_New(0); - PyErr_Clear(); - } else { - Py_INCREF(values); - } - - if (meta == NULL) { - meta = PyDict_New(); - PyErr_Clear(); - } else { - Py_INCREF(meta); - } - - tmp = self->values; - self->values = values; - Py_XDECREF(tmp); - - tmp = self->meta; - self->meta = meta; - Py_XDECREF(tmp); - - self->interval = interval; - return 0; + Values *self = (Values *)s; + double interval = 0, time = 0; + PyObject *values = NULL, *meta = NULL, *tmp; + char *type = NULL, *plugin_instance = NULL, *type_instance = NULL, + *plugin = NULL, *host = NULL; + static char *kwlist[] = { + "type", "values", "plugin_instance", "type_instance", "plugin", + "host", "time", "interval", "meta", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetddO", kwlist, NULL, + &type, &values, NULL, &plugin_instance, NULL, + &type_instance, NULL, &plugin, NULL, &host, + &time, &interval, &meta)) + return -1; + + if (type && plugin_get_ds(type) == NULL) { + PyErr_Format(PyExc_TypeError, "Dataset %s not found", type); + FreeAll(); + return -1; + } + + sstrncpy(self->data.host, host ? host : "", sizeof(self->data.host)); + sstrncpy(self->data.plugin, plugin ? plugin : "", sizeof(self->data.plugin)); + sstrncpy(self->data.plugin_instance, plugin_instance ? plugin_instance : "", + sizeof(self->data.plugin_instance)); + sstrncpy(self->data.type, type ? type : "", sizeof(self->data.type)); + sstrncpy(self->data.type_instance, type_instance ? type_instance : "", + sizeof(self->data.type_instance)); + self->data.time = time; + + FreeAll(); + + if (values == NULL) { + values = PyList_New(0); + PyErr_Clear(); + } else { + Py_INCREF(values); + } + + if (meta == NULL) { + meta = PyDict_New(); + PyErr_Clear(); + } else { + Py_INCREF(meta); + } + + tmp = self->values; + self->values = values; + Py_XDECREF(tmp); + + tmp = self->meta; + self->meta = meta; + Py_XDECREF(tmp); + + self->interval = interval; + return 0; } static meta_data_t *cpy_build_meta(PyObject *meta) { - int s; - meta_data_t *m = NULL; - PyObject *l; - - if ((meta == NULL) || (meta == Py_None)) - return NULL; - - l = PyDict_Items(meta); /* New reference. */ - if (!l) { - cpy_log_exception("building meta data"); - return NULL; - } - s = PyList_Size(l); - if (s <= 0) { - Py_XDECREF(l); - return NULL; - } - - m = meta_data_create(); - for (int i = 0; i < s; ++i) { - const char *string, *keystring; - PyObject *key, *value, *item, *tmp; - - item = PyList_GET_ITEM(l, i); - key = PyTuple_GET_ITEM(item, 0); - Py_INCREF(key); - keystring = cpy_unicode_or_bytes_to_string(&key); - if (!keystring) { - PyErr_Clear(); - Py_XDECREF(key); - continue; - } - value = PyTuple_GET_ITEM(item, 1); - Py_INCREF(value); - if (value == Py_True) { - meta_data_add_boolean(m, keystring, 1); - } else if (value == Py_False) { - meta_data_add_boolean(m, keystring, 0); - } else if (PyFloat_Check(value)) { - meta_data_add_double(m, keystring, PyFloat_AsDouble(value)); - } else if (PyObject_TypeCheck(value, &SignedType)) { - long long int lli; - lli = PyLong_AsLongLong(value); - if (!PyErr_Occurred() && (lli == (int64_t) lli)) - meta_data_add_signed_int(m, keystring, lli); - } else if (PyObject_TypeCheck(value, &UnsignedType)) { - long long unsigned llu; - llu = PyLong_AsUnsignedLongLong(value); - if (!PyErr_Occurred() && (llu == (uint64_t) llu)) - meta_data_add_unsigned_int(m, keystring, llu); - } else if (PyNumber_Check(value)) { - long long int lli; - long long unsigned llu; - tmp = PyNumber_Long(value); - lli = PyLong_AsLongLong(tmp); - if (!PyErr_Occurred() && (lli == (int64_t) lli)) { - meta_data_add_signed_int(m, keystring, lli); - } else { - PyErr_Clear(); - llu = PyLong_AsUnsignedLongLong(tmp); - if (!PyErr_Occurred() && (llu == (uint64_t) llu)) - meta_data_add_unsigned_int(m, keystring, llu); - } - Py_XDECREF(tmp); - } else { - string = cpy_unicode_or_bytes_to_string(&value); - if (string) { - meta_data_add_string(m, keystring, string); - } else { - PyErr_Clear(); - tmp = PyObject_Str(value); - string = cpy_unicode_or_bytes_to_string(&tmp); - if (string) - meta_data_add_string(m, keystring, string); - Py_XDECREF(tmp); - } - } - if (PyErr_Occurred()) - cpy_log_exception("building meta data"); - Py_XDECREF(value); - Py_DECREF(key); - } - Py_XDECREF(l); - return m; + int s; + meta_data_t *m = NULL; + PyObject *l; + + if ((meta == NULL) || (meta == Py_None)) + return NULL; + + l = PyDict_Items(meta); /* New reference. */ + if (!l) { + cpy_log_exception("building meta data"); + return NULL; + } + s = PyList_Size(l); + if (s <= 0) { + Py_XDECREF(l); + return NULL; + } + + m = meta_data_create(); + for (int i = 0; i < s; ++i) { + const char *string, *keystring; + PyObject *key, *value, *item, *tmp; + + item = PyList_GET_ITEM(l, i); + key = PyTuple_GET_ITEM(item, 0); + Py_INCREF(key); + keystring = cpy_unicode_or_bytes_to_string(&key); + if (!keystring) { + PyErr_Clear(); + Py_XDECREF(key); + continue; + } + value = PyTuple_GET_ITEM(item, 1); + Py_INCREF(value); + if (value == Py_True) { + meta_data_add_boolean(m, keystring, 1); + } else if (value == Py_False) { + meta_data_add_boolean(m, keystring, 0); + } else if (PyFloat_Check(value)) { + meta_data_add_double(m, keystring, PyFloat_AsDouble(value)); + } else if (PyObject_TypeCheck(value, &SignedType)) { + long long int lli; + lli = PyLong_AsLongLong(value); + if (!PyErr_Occurred() && (lli == (int64_t)lli)) + meta_data_add_signed_int(m, keystring, lli); + } else if (PyObject_TypeCheck(value, &UnsignedType)) { + long long unsigned llu; + llu = PyLong_AsUnsignedLongLong(value); + if (!PyErr_Occurred() && (llu == (uint64_t)llu)) + meta_data_add_unsigned_int(m, keystring, llu); + } else if (PyNumber_Check(value)) { + long long int lli; + long long unsigned llu; + tmp = PyNumber_Long(value); + lli = PyLong_AsLongLong(tmp); + if (!PyErr_Occurred() && (lli == (int64_t)lli)) { + meta_data_add_signed_int(m, keystring, lli); + } else { + PyErr_Clear(); + llu = PyLong_AsUnsignedLongLong(tmp); + if (!PyErr_Occurred() && (llu == (uint64_t)llu)) + meta_data_add_unsigned_int(m, keystring, llu); + } + Py_XDECREF(tmp); + } else { + string = cpy_unicode_or_bytes_to_string(&value); + if (string) { + meta_data_add_string(m, keystring, string); + } else { + PyErr_Clear(); + tmp = PyObject_Str(value); + string = cpy_unicode_or_bytes_to_string(&tmp); + if (string) + meta_data_add_string(m, keystring, string); + Py_XDECREF(tmp); + } + } + if (PyErr_Occurred()) + cpy_log_exception("building meta data"); + Py_XDECREF(value); + Py_DECREF(key); + } + Py_XDECREF(l); + return m; } static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) { - int ret; - const data_set_t *ds; - size_t size; - value_t *value; - value_list_t value_list = VALUE_LIST_INIT; - PyObject *values = self->values, *meta = self->meta; - double time = self->data.time, interval = self->interval; - char *host = NULL, *plugin = NULL, *plugin_instance = NULL, *type = NULL, *type_instance = NULL; - - static char *kwlist[] = {"type", "values", "plugin_instance", "type_instance", - "plugin", "host", "time", "interval", "meta", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetddO", kwlist, - NULL, &type, &values, NULL, &plugin_instance, NULL, &type_instance, - NULL, &plugin, NULL, &host, &time, &interval, &meta)) - return NULL; - - sstrncpy(value_list.host, host ? host : self->data.host, sizeof(value_list.host)); - sstrncpy(value_list.plugin, plugin ? plugin : self->data.plugin, sizeof(value_list.plugin)); - sstrncpy(value_list.plugin_instance, plugin_instance ? plugin_instance : self->data.plugin_instance, sizeof(value_list.plugin_instance)); - sstrncpy(value_list.type, type ? type : self->data.type, sizeof(value_list.type)); - sstrncpy(value_list.type_instance, type_instance ? type_instance : self->data.type_instance, sizeof(value_list.type_instance)); - FreeAll(); - if (value_list.type[0] == 0) { - PyErr_SetString(PyExc_RuntimeError, "type not set"); - FreeAll(); - return NULL; - } - ds = plugin_get_ds(value_list.type); - if (ds == NULL) { - PyErr_Format(PyExc_TypeError, "Dataset %s not found", value_list.type); - return NULL; - } - if (values == NULL || (PyTuple_Check(values) == 0 && PyList_Check(values) == 0)) { - PyErr_Format(PyExc_TypeError, "values must be list or tuple"); - return NULL; - } - if (meta != NULL && meta != Py_None && !PyDict_Check(meta)) { - PyErr_Format(PyExc_TypeError, "meta must be a dict"); - return NULL; - } - size = (size_t) PySequence_Length(values); - if (size != ds->ds_num) { - PyErr_Format(PyExc_RuntimeError, "type %s needs %zu values, got %zu", value_list.type, ds->ds_num, size); - return NULL; - } - value = calloc(size, sizeof(*value)); - for (size_t i = 0; i < size; ++i) { - PyObject *item, *num; - item = PySequence_Fast_GET_ITEM(values, (int) i); /* Borrowed reference. */ - switch (ds->ds[i].type) { - case DS_TYPE_COUNTER: - num = PyNumber_Long(item); /* New reference. */ - if (num != NULL) { - value[i].counter = PyLong_AsUnsignedLongLong(num); - Py_XDECREF(num); - } - break; - case DS_TYPE_GAUGE: - num = PyNumber_Float(item); /* New reference. */ - if (num != NULL) { - value[i].gauge = PyFloat_AsDouble(num); - Py_XDECREF(num); - } - break; - case DS_TYPE_DERIVE: - /* This might overflow without raising an exception. - * Not much we can do about it */ - num = PyNumber_Long(item); /* New reference. */ - if (num != NULL) { - value[i].derive = PyLong_AsLongLong(num); - Py_XDECREF(num); - } - break; - case DS_TYPE_ABSOLUTE: - /* This might overflow without raising an exception. - * Not much we can do about it */ - num = PyNumber_Long(item); /* New reference. */ - if (num != NULL) { - value[i].absolute = PyLong_AsUnsignedLongLong(num); - Py_XDECREF(num); - } - break; - default: - free(value); - PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds[i].type, value_list.type); - return NULL; - } - if (PyErr_Occurred() != NULL) { - free(value); - return NULL; - } - } - value_list.values = value; - value_list.meta = cpy_build_meta(meta); - value_list.values_len = size; - value_list.time = DOUBLE_TO_CDTIME_T(time); - value_list.interval = DOUBLE_TO_CDTIME_T(interval); - if (value_list.host[0] == 0) - sstrncpy(value_list.host, hostname_g, sizeof(value_list.host)); - if (value_list.plugin[0] == 0) - sstrncpy(value_list.plugin, "python", sizeof(value_list.plugin)); - Py_BEGIN_ALLOW_THREADS; - ret = plugin_dispatch_values(&value_list); - Py_END_ALLOW_THREADS; - meta_data_destroy(value_list.meta); - free(value); - if (ret != 0) { - PyErr_SetString(PyExc_RuntimeError, "error dispatching values, read the logs"); - return NULL; - } - Py_RETURN_NONE; + int ret; + const data_set_t *ds; + size_t size; + value_t *value; + value_list_t value_list = VALUE_LIST_INIT; + PyObject *values = self->values, *meta = self->meta; + double time = self->data.time, interval = self->interval; + char *host = NULL, *plugin = NULL, *plugin_instance = NULL, *type = NULL, + *type_instance = NULL; + + static char *kwlist[] = { + "type", "values", "plugin_instance", "type_instance", "plugin", + "host", "time", "interval", "meta", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetddO", kwlist, NULL, + &type, &values, NULL, &plugin_instance, NULL, + &type_instance, NULL, &plugin, NULL, &host, + &time, &interval, &meta)) + return NULL; + + sstrncpy(value_list.host, host ? host : self->data.host, + sizeof(value_list.host)); + sstrncpy(value_list.plugin, plugin ? plugin : self->data.plugin, + sizeof(value_list.plugin)); + sstrncpy(value_list.plugin_instance, + plugin_instance ? plugin_instance : self->data.plugin_instance, + sizeof(value_list.plugin_instance)); + sstrncpy(value_list.type, type ? type : self->data.type, + sizeof(value_list.type)); + sstrncpy(value_list.type_instance, + type_instance ? type_instance : self->data.type_instance, + sizeof(value_list.type_instance)); + FreeAll(); + if (value_list.type[0] == 0) { + PyErr_SetString(PyExc_RuntimeError, "type not set"); + FreeAll(); + return NULL; + } + ds = plugin_get_ds(value_list.type); + if (ds == NULL) { + PyErr_Format(PyExc_TypeError, "Dataset %s not found", value_list.type); + return NULL; + } + if (values == NULL || + (PyTuple_Check(values) == 0 && PyList_Check(values) == 0)) { + PyErr_Format(PyExc_TypeError, "values must be list or tuple"); + return NULL; + } + if (meta != NULL && meta != Py_None && !PyDict_Check(meta)) { + PyErr_Format(PyExc_TypeError, "meta must be a dict"); + return NULL; + } + size = (size_t)PySequence_Length(values); + if (size != ds->ds_num) { + PyErr_Format(PyExc_RuntimeError, "type %s needs %zu values, got %zu", + value_list.type, ds->ds_num, size); + return NULL; + } + value = calloc(size, sizeof(*value)); + for (size_t i = 0; i < size; ++i) { + PyObject *item, *num; + item = PySequence_Fast_GET_ITEM(values, (int)i); /* Borrowed reference. */ + switch (ds->ds[i].type) { + case DS_TYPE_COUNTER: + num = PyNumber_Long(item); /* New reference. */ + if (num != NULL) { + value[i].counter = PyLong_AsUnsignedLongLong(num); + Py_XDECREF(num); + } + break; + case DS_TYPE_GAUGE: + num = PyNumber_Float(item); /* New reference. */ + if (num != NULL) { + value[i].gauge = PyFloat_AsDouble(num); + Py_XDECREF(num); + } + break; + case DS_TYPE_DERIVE: + /* This might overflow without raising an exception. + * Not much we can do about it */ + num = PyNumber_Long(item); /* New reference. */ + if (num != NULL) { + value[i].derive = PyLong_AsLongLong(num); + Py_XDECREF(num); + } + break; + case DS_TYPE_ABSOLUTE: + /* This might overflow without raising an exception. + * Not much we can do about it */ + num = PyNumber_Long(item); /* New reference. */ + if (num != NULL) { + value[i].absolute = PyLong_AsUnsignedLongLong(num); + Py_XDECREF(num); + } + break; + default: + free(value); + PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", + ds->ds[i].type, value_list.type); + return NULL; + } + if (PyErr_Occurred() != NULL) { + free(value); + return NULL; + } + } + value_list.values = value; + value_list.meta = cpy_build_meta(meta); + value_list.values_len = size; + value_list.time = DOUBLE_TO_CDTIME_T(time); + value_list.interval = DOUBLE_TO_CDTIME_T(interval); + if (value_list.host[0] == 0) + sstrncpy(value_list.host, hostname_g, sizeof(value_list.host)); + if (value_list.plugin[0] == 0) + sstrncpy(value_list.plugin, "python", sizeof(value_list.plugin)); + Py_BEGIN_ALLOW_THREADS; + ret = plugin_dispatch_values(&value_list); + Py_END_ALLOW_THREADS; + meta_data_destroy(value_list.meta); + free(value); + if (ret != 0) { + PyErr_SetString(PyExc_RuntimeError, + "error dispatching values, read the logs"); + return NULL; + } + Py_RETURN_NONE; } static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) { - int ret; - const data_set_t *ds; - size_t size; - value_t *value; - value_list_t value_list = VALUE_LIST_INIT; - PyObject *values = self->values, *meta = self->meta; - double time = self->data.time, interval = self->interval; - char *host = NULL, *plugin = NULL, *plugin_instance = NULL, *type = NULL, *type_instance = NULL, *dest = NULL; - - static char *kwlist[] = {"destination", "type", "values", "plugin_instance", "type_instance", - "plugin", "host", "time", "interval", "meta", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|etOetetetetdiO", kwlist, NULL, &dest, - NULL, &type, &values, NULL, &plugin_instance, NULL, &type_instance, - NULL, &plugin, NULL, &host, &time, &interval, &meta)) - return NULL; - - sstrncpy(value_list.host, host ? host : self->data.host, sizeof(value_list.host)); - sstrncpy(value_list.plugin, plugin ? plugin : self->data.plugin, sizeof(value_list.plugin)); - sstrncpy(value_list.plugin_instance, plugin_instance ? plugin_instance : self->data.plugin_instance, sizeof(value_list.plugin_instance)); - sstrncpy(value_list.type, type ? type : self->data.type, sizeof(value_list.type)); - sstrncpy(value_list.type_instance, type_instance ? type_instance : self->data.type_instance, sizeof(value_list.type_instance)); - FreeAll(); - if (value_list.type[0] == 0) { - PyErr_SetString(PyExc_RuntimeError, "type not set"); - return NULL; - } - ds = plugin_get_ds(value_list.type); - if (ds == NULL) { - PyErr_Format(PyExc_TypeError, "Dataset %s not found", value_list.type); - return NULL; - } - if (values == NULL || (PyTuple_Check(values) == 0 && PyList_Check(values) == 0)) { - PyErr_Format(PyExc_TypeError, "values must be list or tuple"); - return NULL; - } - size = (size_t) PySequence_Length(values); - if (size != ds->ds_num) { - PyErr_Format(PyExc_RuntimeError, "type %s needs %zu values, got %zu", value_list.type, ds->ds_num, size); - return NULL; - } - value = calloc(size, sizeof(*value)); - for (size_t i = 0; i < size; ++i) { - PyObject *item, *num; - item = PySequence_Fast_GET_ITEM(values, i); /* Borrowed reference. */ - switch (ds->ds[i].type) { - case DS_TYPE_COUNTER: - num = PyNumber_Long(item); /* New reference. */ - if (num != NULL) { - value[i].counter = PyLong_AsUnsignedLongLong(num); - Py_XDECREF(num); - } - break; - case DS_TYPE_GAUGE: - num = PyNumber_Float(item); /* New reference. */ - if (num != NULL) { - value[i].gauge = PyFloat_AsDouble(num); - Py_XDECREF(num); - } - break; - case DS_TYPE_DERIVE: - /* This might overflow without raising an exception. - * Not much we can do about it */ - num = PyNumber_Long(item); /* New reference. */ - if (num != NULL) { - value[i].derive = PyLong_AsLongLong(num); - Py_XDECREF(num); - } - break; - case DS_TYPE_ABSOLUTE: - /* This might overflow without raising an exception. - * Not much we can do about it */ - num = PyNumber_Long(item); /* New reference. */ - if (num != NULL) { - value[i].absolute = PyLong_AsUnsignedLongLong(num); - Py_XDECREF(num); - } - break; - default: - free(value); - PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds[i].type, value_list.type); - return NULL; - } - if (PyErr_Occurred() != NULL) { - free(value); - return NULL; - } - } - value_list.values = value; - value_list.values_len = size; - value_list.time = DOUBLE_TO_CDTIME_T(time); - value_list.interval = DOUBLE_TO_CDTIME_T(interval); - value_list.meta = cpy_build_meta(meta); - if (value_list.host[0] == 0) - sstrncpy(value_list.host, hostname_g, sizeof(value_list.host)); - if (value_list.plugin[0] == 0) - sstrncpy(value_list.plugin, "python", sizeof(value_list.plugin)); - Py_BEGIN_ALLOW_THREADS; - ret = plugin_write(dest, NULL, &value_list); - Py_END_ALLOW_THREADS; - meta_data_destroy(value_list.meta); - free(value); - if (ret != 0) { - PyErr_SetString(PyExc_RuntimeError, "error dispatching values, read the logs"); - return NULL; - } - Py_RETURN_NONE; + int ret; + const data_set_t *ds; + size_t size; + value_t *value; + value_list_t value_list = VALUE_LIST_INIT; + PyObject *values = self->values, *meta = self->meta; + double time = self->data.time, interval = self->interval; + char *host = NULL, *plugin = NULL, *plugin_instance = NULL, *type = NULL, + *type_instance = NULL, *dest = NULL; + + static char *kwlist[] = { + "destination", "type", "values", "plugin_instance", + "type_instance", "plugin", "host", "time", + "interval", "meta", NULL}; + if (!PyArg_ParseTupleAndKeywords( + args, kwds, "et|etOetetetetdiO", kwlist, NULL, &dest, NULL, &type, + &values, NULL, &plugin_instance, NULL, &type_instance, NULL, &plugin, + NULL, &host, &time, &interval, &meta)) + return NULL; + + sstrncpy(value_list.host, host ? host : self->data.host, + sizeof(value_list.host)); + sstrncpy(value_list.plugin, plugin ? plugin : self->data.plugin, + sizeof(value_list.plugin)); + sstrncpy(value_list.plugin_instance, + plugin_instance ? plugin_instance : self->data.plugin_instance, + sizeof(value_list.plugin_instance)); + sstrncpy(value_list.type, type ? type : self->data.type, + sizeof(value_list.type)); + sstrncpy(value_list.type_instance, + type_instance ? type_instance : self->data.type_instance, + sizeof(value_list.type_instance)); + FreeAll(); + if (value_list.type[0] == 0) { + PyErr_SetString(PyExc_RuntimeError, "type not set"); + return NULL; + } + ds = plugin_get_ds(value_list.type); + if (ds == NULL) { + PyErr_Format(PyExc_TypeError, "Dataset %s not found", value_list.type); + return NULL; + } + if (values == NULL || + (PyTuple_Check(values) == 0 && PyList_Check(values) == 0)) { + PyErr_Format(PyExc_TypeError, "values must be list or tuple"); + return NULL; + } + size = (size_t)PySequence_Length(values); + if (size != ds->ds_num) { + PyErr_Format(PyExc_RuntimeError, "type %s needs %zu values, got %zu", + value_list.type, ds->ds_num, size); + return NULL; + } + value = calloc(size, sizeof(*value)); + for (size_t i = 0; i < size; ++i) { + PyObject *item, *num; + item = PySequence_Fast_GET_ITEM(values, i); /* Borrowed reference. */ + switch (ds->ds[i].type) { + case DS_TYPE_COUNTER: + num = PyNumber_Long(item); /* New reference. */ + if (num != NULL) { + value[i].counter = PyLong_AsUnsignedLongLong(num); + Py_XDECREF(num); + } + break; + case DS_TYPE_GAUGE: + num = PyNumber_Float(item); /* New reference. */ + if (num != NULL) { + value[i].gauge = PyFloat_AsDouble(num); + Py_XDECREF(num); + } + break; + case DS_TYPE_DERIVE: + /* This might overflow without raising an exception. + * Not much we can do about it */ + num = PyNumber_Long(item); /* New reference. */ + if (num != NULL) { + value[i].derive = PyLong_AsLongLong(num); + Py_XDECREF(num); + } + break; + case DS_TYPE_ABSOLUTE: + /* This might overflow without raising an exception. + * Not much we can do about it */ + num = PyNumber_Long(item); /* New reference. */ + if (num != NULL) { + value[i].absolute = PyLong_AsUnsignedLongLong(num); + Py_XDECREF(num); + } + break; + default: + free(value); + PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", + ds->ds[i].type, value_list.type); + return NULL; + } + if (PyErr_Occurred() != NULL) { + free(value); + return NULL; + } + } + value_list.values = value; + value_list.values_len = size; + value_list.time = DOUBLE_TO_CDTIME_T(time); + value_list.interval = DOUBLE_TO_CDTIME_T(interval); + value_list.meta = cpy_build_meta(meta); + if (value_list.host[0] == 0) + sstrncpy(value_list.host, hostname_g, sizeof(value_list.host)); + if (value_list.plugin[0] == 0) + sstrncpy(value_list.plugin, "python", sizeof(value_list.plugin)); + Py_BEGIN_ALLOW_THREADS; + ret = plugin_write(dest, NULL, &value_list); + Py_END_ALLOW_THREADS; + meta_data_destroy(value_list.meta); + free(value); + if (ret != 0) { + PyErr_SetString(PyExc_RuntimeError, + "error dispatching values, read the logs"); + return NULL; + } + Py_RETURN_NONE; } static PyObject *Values_repr(PyObject *s) { - PyObject *ret, *tmp; - static PyObject *l_interval = NULL, *l_values = NULL, *l_meta = NULL, *l_closing = NULL; - Values *self = (Values *) s; - - if (l_interval == NULL) - l_interval = cpy_string_to_unicode_or_bytes(",interval="); - if (l_values == NULL) - l_values = cpy_string_to_unicode_or_bytes(",values="); - if (l_meta == NULL) - l_meta = cpy_string_to_unicode_or_bytes(",meta="); - if (l_closing == NULL) - l_closing = cpy_string_to_unicode_or_bytes(")"); - - if (l_interval == NULL || l_values == NULL || l_meta == NULL || l_closing == NULL) - return NULL; - - ret = cpy_common_repr(s); - if (self->interval != 0) { - CPY_STRCAT(&ret, l_interval); - tmp = PyFloat_FromDouble(self->interval); - CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); - CPY_STRCAT_AND_DEL(&ret, tmp); - } - if (self->values && (!PyList_Check(self->values) || PySequence_Length(self->values) > 0)) { - CPY_STRCAT(&ret, l_values); - tmp = PyObject_Repr(self->values); - CPY_STRCAT_AND_DEL(&ret, tmp); - } - if (self->meta && (!PyDict_Check(self->meta) || PyDict_Size(self->meta) > 0)) { - CPY_STRCAT(&ret, l_meta); - tmp = PyObject_Repr(self->meta); - CPY_STRCAT_AND_DEL(&ret, tmp); - } - CPY_STRCAT(&ret, l_closing); - return ret; + PyObject *ret, *tmp; + static PyObject *l_interval = NULL, *l_values = NULL, *l_meta = NULL, + *l_closing = NULL; + Values *self = (Values *)s; + + if (l_interval == NULL) + l_interval = cpy_string_to_unicode_or_bytes(",interval="); + if (l_values == NULL) + l_values = cpy_string_to_unicode_or_bytes(",values="); + if (l_meta == NULL) + l_meta = cpy_string_to_unicode_or_bytes(",meta="); + if (l_closing == NULL) + l_closing = cpy_string_to_unicode_or_bytes(")"); + + if (l_interval == NULL || l_values == NULL || l_meta == NULL || + l_closing == NULL) + return NULL; + + ret = cpy_common_repr(s); + if (self->interval != 0) { + CPY_STRCAT(&ret, l_interval); + tmp = PyFloat_FromDouble(self->interval); + CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); + CPY_STRCAT_AND_DEL(&ret, tmp); + } + if (self->values && + (!PyList_Check(self->values) || PySequence_Length(self->values) > 0)) { + CPY_STRCAT(&ret, l_values); + tmp = PyObject_Repr(self->values); + CPY_STRCAT_AND_DEL(&ret, tmp); + } + if (self->meta && + (!PyDict_Check(self->meta) || PyDict_Size(self->meta) > 0)) { + CPY_STRCAT(&ret, l_meta); + tmp = PyObject_Repr(self->meta); + CPY_STRCAT_AND_DEL(&ret, tmp); + } + CPY_STRCAT(&ret, l_closing); + return ret; } static int Values_traverse(PyObject *self, visitproc visit, void *arg) { - Values *v = (Values *) self; - Py_VISIT(v->values); - Py_VISIT(v->meta); - return 0; + Values *v = (Values *)self; + Py_VISIT(v->values); + Py_VISIT(v->meta); + return 0; } static int Values_clear(PyObject *self) { - Values *v = (Values *) self; - Py_CLEAR(v->values); - Py_CLEAR(v->meta); - return 0; + Values *v = (Values *)self; + Py_CLEAR(v->values); + Py_CLEAR(v->meta); + return 0; } static void Values_dealloc(PyObject *self) { - Values_clear(self); - self->ob_type->tp_free(self); + Values_clear(self); + self->ob_type->tp_free(self); } static PyMemberDef Values_members[] = { - {"interval", T_DOUBLE, offsetof(Values, interval), 0, interval_doc}, - {"values", T_OBJECT_EX, offsetof(Values, values), 0, values_doc}, - {"meta", T_OBJECT_EX, offsetof(Values, meta), 0, meta_doc}, - {NULL} -}; + {"interval", T_DOUBLE, offsetof(Values, interval), 0, interval_doc}, + {"values", T_OBJECT_EX, offsetof(Values, values), 0, values_doc}, + {"meta", T_OBJECT_EX, offsetof(Values, meta), 0, meta_doc}, + {NULL}}; static PyMethodDef Values_methods[] = { - {"dispatch", (PyCFunction) Values_dispatch, METH_VARARGS | METH_KEYWORDS, dispatch_doc}, - {"write", (PyCFunction) Values_write, METH_VARARGS | METH_KEYWORDS, write_doc}, - {NULL} -}; + {"dispatch", (PyCFunction)Values_dispatch, METH_VARARGS | METH_KEYWORDS, + dispatch_doc}, + {"write", (PyCFunction)Values_write, METH_VARARGS | METH_KEYWORDS, + write_doc}, + {NULL}}; PyTypeObject ValuesType = { - CPY_INIT_TYPE - "collectd.Values", /* tp_name */ - sizeof(Values), /* tp_basicsize */ - 0, /* Will be filled in later */ - Values_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - Values_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - Values_doc, /* tp_doc */ - Values_traverse, /* tp_traverse */ - Values_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - Values_methods, /* tp_methods */ - Values_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - Values_init, /* tp_init */ - 0, /* tp_alloc */ - Values_new /* tp_new */ + CPY_INIT_TYPE "collectd.Values", /* tp_name */ + sizeof(Values), /* tp_basicsize */ + 0, /* Will be filled in later */ + Values_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + Values_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + Values_doc, /* tp_doc */ + Values_traverse, /* tp_traverse */ + Values_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + Values_methods, /* tp_methods */ + Values_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + Values_init, /* tp_init */ + 0, /* tp_alloc */ + Values_new /* tp_new */ }; -static char severity_doc[] = "The severity of this notification. Assign or compare to\n" - "NOTIF_FAILURE, NOTIF_WARNING or NOTIF_OKAY."; +static char severity_doc[] = + "The severity of this notification. Assign or compare to\n" + "NOTIF_FAILURE, NOTIF_WARNING or NOTIF_OKAY."; -static char message_doc[] = "Some kind of description what's going on and why this Notification was generated."; +static char message_doc[] = "Some kind of description what's going on and why " + "this Notification was generated."; -static char Notification_doc[] = "The Notification class is a wrapper around the collectd notification.\n" - "It can be used to notify other plugins about bad stuff happening. It works\n" - "similar to Values but has a severity and a message instead of interval\n" - "and time.\n" - "Notifications can be dispatched at any time and can be received with register_notification."; +static char Notification_doc[] = + "The Notification class is a wrapper around the collectd notification.\n" + "It can be used to notify other plugins about bad stuff happening. It " + "works\n" + "similar to Values but has a severity and a message instead of interval\n" + "and time.\n" + "Notifications can be dispatched at any time and can be received with " + "register_notification."; static int Notification_init(PyObject *s, PyObject *args, PyObject *kwds) { - Notification *self = (Notification *) s; - int severity = 0; - double time = 0; - char *message = NULL; - char *type = NULL, *plugin_instance = NULL, *type_instance = NULL, *plugin = NULL, *host = NULL; - static char *kwlist[] = {"type", "message", "plugin_instance", "type_instance", - "plugin", "host", "time", "severity", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etetetetetetdi", kwlist, - NULL, &type, NULL, &message, NULL, &plugin_instance, NULL, &type_instance, - NULL, &plugin, NULL, &host, &time, &severity)) - return -1; - - if (type && plugin_get_ds(type) == NULL) { - PyErr_Format(PyExc_TypeError, "Dataset %s not found", type); - FreeAll(); - PyMem_Free(message); - return -1; - } - - sstrncpy(self->data.host, host ? host : "", sizeof(self->data.host)); - sstrncpy(self->data.plugin, plugin ? plugin : "", sizeof(self->data.plugin)); - sstrncpy(self->data.plugin_instance, plugin_instance ? plugin_instance : "", sizeof(self->data.plugin_instance)); - sstrncpy(self->data.type, type ? type : "", sizeof(self->data.type)); - sstrncpy(self->data.type_instance, type_instance ? type_instance : "", sizeof(self->data.type_instance)); - sstrncpy(self->message, message ? message : "", sizeof(self->message)); - self->data.time = time; - self->severity = severity; - - FreeAll(); - PyMem_Free(message); - return 0; + Notification *self = (Notification *)s; + int severity = 0; + double time = 0; + char *message = NULL; + char *type = NULL, *plugin_instance = NULL, *type_instance = NULL, + *plugin = NULL, *host = NULL; + static char *kwlist[] = {"type", "message", "plugin_instance", + "type_instance", "plugin", "host", + "time", "severity", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etetetetetetdi", kwlist, NULL, + &type, NULL, &message, NULL, + &plugin_instance, NULL, &type_instance, NULL, + &plugin, NULL, &host, &time, &severity)) + return -1; + + if (type && plugin_get_ds(type) == NULL) { + PyErr_Format(PyExc_TypeError, "Dataset %s not found", type); + FreeAll(); + PyMem_Free(message); + return -1; + } + + sstrncpy(self->data.host, host ? host : "", sizeof(self->data.host)); + sstrncpy(self->data.plugin, plugin ? plugin : "", sizeof(self->data.plugin)); + sstrncpy(self->data.plugin_instance, plugin_instance ? plugin_instance : "", + sizeof(self->data.plugin_instance)); + sstrncpy(self->data.type, type ? type : "", sizeof(self->data.type)); + sstrncpy(self->data.type_instance, type_instance ? type_instance : "", + sizeof(self->data.type_instance)); + sstrncpy(self->message, message ? message : "", sizeof(self->message)); + self->data.time = time; + self->severity = severity; + + FreeAll(); + PyMem_Free(message); + return 0; } -static PyObject *Notification_dispatch(Notification *self, PyObject *args, PyObject *kwds) { - int ret; - const data_set_t *ds; - notification_t notification; - double t = self->data.time; - int severity = self->severity; - char *host = NULL, *plugin = NULL, *plugin_instance = NULL, *type = NULL, *type_instance = NULL; - char *message = NULL; - - static char *kwlist[] = {"type", "message", "plugin_instance", "type_instance", - "plugin", "host", "time", "severity", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etetetetetetdi", kwlist, - NULL, &type, NULL, &message, NULL, &plugin_instance, NULL, &type_instance, - NULL, &plugin, NULL, &host, &t, &severity)) - return NULL; - - notification.time = DOUBLE_TO_CDTIME_T(t); - notification.severity = severity; - sstrncpy(notification.message, message ? message : self->message, sizeof(notification.message)); - sstrncpy(notification.host, host ? host : self->data.host, sizeof(notification.host)); - sstrncpy(notification.plugin, plugin ? plugin : self->data.plugin, sizeof(notification.plugin)); - sstrncpy(notification.plugin_instance, plugin_instance ? plugin_instance : self->data.plugin_instance, sizeof(notification.plugin_instance)); - sstrncpy(notification.type, type ? type : self->data.type, sizeof(notification.type)); - sstrncpy(notification.type_instance, type_instance ? type_instance : self->data.type_instance, sizeof(notification.type_instance)); - notification.meta = NULL; - FreeAll(); - PyMem_Free(message); - - if (notification.type[0] == 0) { - PyErr_SetString(PyExc_RuntimeError, "type not set"); - return NULL; - } - ds = plugin_get_ds(notification.type); - if (ds == NULL) { - PyErr_Format(PyExc_TypeError, "Dataset %s not found", notification.type); - return NULL; - } - - if (notification.time == 0) - notification.time = cdtime(); - if (notification.host[0] == 0) - sstrncpy(notification.host, hostname_g, sizeof(notification.host)); - if (notification.plugin[0] == 0) - sstrncpy(notification.plugin, "python", sizeof(notification.plugin)); - Py_BEGIN_ALLOW_THREADS; - ret = plugin_dispatch_notification(¬ification); - Py_END_ALLOW_THREADS; - if (ret != 0) { - PyErr_SetString(PyExc_RuntimeError, "error dispatching notification, read the logs"); - return NULL; - } - Py_RETURN_NONE; +static PyObject *Notification_dispatch(Notification *self, PyObject *args, + PyObject *kwds) { + int ret; + const data_set_t *ds; + notification_t notification; + double t = self->data.time; + int severity = self->severity; + char *host = NULL, *plugin = NULL, *plugin_instance = NULL, *type = NULL, + *type_instance = NULL; + char *message = NULL; + + static char *kwlist[] = {"type", "message", "plugin_instance", + "type_instance", "plugin", "host", + "time", "severity", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etetetetetetdi", kwlist, NULL, + &type, NULL, &message, NULL, + &plugin_instance, NULL, &type_instance, NULL, + &plugin, NULL, &host, &t, &severity)) + return NULL; + + notification.time = DOUBLE_TO_CDTIME_T(t); + notification.severity = severity; + sstrncpy(notification.message, message ? message : self->message, + sizeof(notification.message)); + sstrncpy(notification.host, host ? host : self->data.host, + sizeof(notification.host)); + sstrncpy(notification.plugin, plugin ? plugin : self->data.plugin, + sizeof(notification.plugin)); + sstrncpy(notification.plugin_instance, + plugin_instance ? plugin_instance : self->data.plugin_instance, + sizeof(notification.plugin_instance)); + sstrncpy(notification.type, type ? type : self->data.type, + sizeof(notification.type)); + sstrncpy(notification.type_instance, + type_instance ? type_instance : self->data.type_instance, + sizeof(notification.type_instance)); + notification.meta = NULL; + FreeAll(); + PyMem_Free(message); + + if (notification.type[0] == 0) { + PyErr_SetString(PyExc_RuntimeError, "type not set"); + return NULL; + } + ds = plugin_get_ds(notification.type); + if (ds == NULL) { + PyErr_Format(PyExc_TypeError, "Dataset %s not found", notification.type); + return NULL; + } + + if (notification.time == 0) + notification.time = cdtime(); + if (notification.host[0] == 0) + sstrncpy(notification.host, hostname_g, sizeof(notification.host)); + if (notification.plugin[0] == 0) + sstrncpy(notification.plugin, "python", sizeof(notification.plugin)); + Py_BEGIN_ALLOW_THREADS; + ret = plugin_dispatch_notification(¬ification); + Py_END_ALLOW_THREADS; + if (ret != 0) { + PyErr_SetString(PyExc_RuntimeError, + "error dispatching notification, read the logs"); + return NULL; + } + Py_RETURN_NONE; } -static PyObject *Notification_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - Notification *self; +static PyObject *Notification_new(PyTypeObject *type, PyObject *args, + PyObject *kwds) { + Notification *self; - self = (Notification *) PluginData_new(type, args, kwds); - if (self == NULL) - return NULL; + self = (Notification *)PluginData_new(type, args, kwds); + if (self == NULL) + return NULL; - self->message[0] = 0; - self->severity = 0; - return (PyObject *) self; + self->message[0] = 0; + self->severity = 0; + return (PyObject *)self; } static int Notification_setstring(PyObject *self, PyObject *value, void *data) { - char *old; - const char *new; - - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, "Cannot delete this attribute"); - return -1; - } - Py_INCREF(value); - new = cpy_unicode_or_bytes_to_string(&value); - if (new == NULL) { - Py_DECREF(value); - return -1; - } - old = ((char *) self) + (intptr_t) data; - sstrncpy(old, new, NOTIF_MAX_MSG_LEN); - Py_DECREF(value); - return 0; + char *old; + const char *new; + + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, "Cannot delete this attribute"); + return -1; + } + Py_INCREF(value); + new = cpy_unicode_or_bytes_to_string(&value); + if (new == NULL) { + Py_DECREF(value); + return -1; + } + old = ((char *)self) + (intptr_t)data; + sstrncpy(old, new, NOTIF_MAX_MSG_LEN); + Py_DECREF(value); + return 0; } static PyObject *Notification_repr(PyObject *s) { - PyObject *ret, *tmp; - static PyObject *l_severity = NULL, *l_message = NULL, *l_closing = NULL; - Notification *self = (Notification *) s; - - if (l_severity == NULL) - l_severity = cpy_string_to_unicode_or_bytes(",severity="); - if (l_message == NULL) - l_message = cpy_string_to_unicode_or_bytes(",message="); - if (l_closing == NULL) - l_closing = cpy_string_to_unicode_or_bytes(")"); - - if (l_severity == NULL || l_message == NULL || l_closing == NULL) - return NULL; - - ret = cpy_common_repr(s); - if (self->severity != 0) { - CPY_STRCAT(&ret, l_severity); - tmp = PyInt_FromLong(self->severity); - CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); - CPY_STRCAT_AND_DEL(&ret, tmp); - } - if (self->message[0] != 0) { - CPY_STRCAT(&ret, l_message); - tmp = cpy_string_to_unicode_or_bytes(self->message); - CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); - CPY_STRCAT_AND_DEL(&ret, tmp); - } - CPY_STRCAT(&ret, l_closing); - return ret; + PyObject *ret, *tmp; + static PyObject *l_severity = NULL, *l_message = NULL, *l_closing = NULL; + Notification *self = (Notification *)s; + + if (l_severity == NULL) + l_severity = cpy_string_to_unicode_or_bytes(",severity="); + if (l_message == NULL) + l_message = cpy_string_to_unicode_or_bytes(",message="); + if (l_closing == NULL) + l_closing = cpy_string_to_unicode_or_bytes(")"); + + if (l_severity == NULL || l_message == NULL || l_closing == NULL) + return NULL; + + ret = cpy_common_repr(s); + if (self->severity != 0) { + CPY_STRCAT(&ret, l_severity); + tmp = PyInt_FromLong(self->severity); + CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); + CPY_STRCAT_AND_DEL(&ret, tmp); + } + if (self->message[0] != 0) { + CPY_STRCAT(&ret, l_message); + tmp = cpy_string_to_unicode_or_bytes(self->message); + CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); + CPY_STRCAT_AND_DEL(&ret, tmp); + } + CPY_STRCAT(&ret, l_closing); + return ret; } static PyMethodDef Notification_methods[] = { - {"dispatch", (PyCFunction) Notification_dispatch, METH_VARARGS | METH_KEYWORDS, dispatch_doc}, - {NULL} -}; + {"dispatch", (PyCFunction)Notification_dispatch, + METH_VARARGS | METH_KEYWORDS, dispatch_doc}, + {NULL}}; static PyMemberDef Notification_members[] = { - {"severity", T_INT, offsetof(Notification, severity), 0, severity_doc}, - {NULL} -}; + {"severity", T_INT, offsetof(Notification, severity), 0, severity_doc}, + {NULL}}; static PyGetSetDef Notification_getseters[] = { - {"message", PluginData_getstring, Notification_setstring, message_doc, (void *) offsetof(Notification, message)}, - {NULL} -}; + {"message", PluginData_getstring, Notification_setstring, message_doc, + (void *)offsetof(Notification, message)}, + {NULL}}; PyTypeObject NotificationType = { - CPY_INIT_TYPE - "collectd.Notification", /* tp_name */ - sizeof(Notification), /* tp_basicsize */ - 0, /* Will be filled in later */ - 0, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - Notification_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - Notification_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - Notification_methods, /* tp_methods */ - Notification_members, /* tp_members */ - Notification_getseters, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - Notification_init, /* tp_init */ - 0, /* tp_alloc */ - Notification_new /* tp_new */ + CPY_INIT_TYPE "collectd.Notification", /* tp_name */ + sizeof(Notification), /* tp_basicsize */ + 0, /* Will be filled in later */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + Notification_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + Notification_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + Notification_methods, /* tp_methods */ + Notification_members, /* tp_members */ + Notification_getseters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + Notification_init, /* tp_init */ + 0, /* tp_alloc */ + Notification_new /* tp_new */ }; -static char Signed_doc[] = "This is a long by another name. Use it in meta data dicts\n" - "to choose the way it is stored in the meta data."; +static char Signed_doc[] = + "This is a long by another name. Use it in meta data dicts\n" + "to choose the way it is stored in the meta data."; PyTypeObject SignedType = { - CPY_INIT_TYPE - "collectd.Signed", /* tp_name */ - sizeof(Signed), /* tp_basicsize */ - 0, /* Will be filled in later */ - 0, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - Signed_doc /* tp_doc */ + CPY_INIT_TYPE "collectd.Signed", /* tp_name */ + sizeof(Signed), /* tp_basicsize */ + 0, /* Will be filled in later */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + Signed_doc /* tp_doc */ }; -static char Unsigned_doc[] = "This is a long by another name. Use it in meta data dicts\n" - "to choose the way it is stored in the meta data."; +static char Unsigned_doc[] = + "This is a long by another name. Use it in meta data dicts\n" + "to choose the way it is stored in the meta data."; PyTypeObject UnsignedType = { - CPY_INIT_TYPE - "collectd.Unsigned", /* tp_name */ - sizeof(Unsigned), /* tp_basicsize */ - 0, /* Will be filled in later */ - 0, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - Unsigned_doc /* tp_doc */ + CPY_INIT_TYPE "collectd.Unsigned", /* tp_name */ + sizeof(Unsigned), /* tp_basicsize */ + 0, /* Will be filled in later */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + Unsigned_doc /* tp_doc */ }; diff --git a/src/redis.c b/src/redis.c index c3c8efa5..7875c7ea 100644 --- a/src/redis.c +++ b/src/redis.c @@ -25,16 +25,16 @@ #include "common.h" #include "plugin.h" -#include #include +#include #ifndef HOST_NAME_MAX -# define HOST_NAME_MAX _POSIX_HOST_NAME_MAX +#define HOST_NAME_MAX _POSIX_HOST_NAME_MAX #endif -#define REDIS_DEF_HOST "localhost" +#define REDIS_DEF_HOST "localhost" #define REDIS_DEF_PASSWD "" -#define REDIS_DEF_PORT 6379 +#define REDIS_DEF_PORT 6379 #define REDIS_DEF_TIMEOUT 2000 #define MAX_REDIS_NODE_NAME 64 #define MAX_REDIS_PASSWD_LENGTH 512 @@ -55,18 +55,16 @@ struct redis_query_s; typedef struct redis_query_s redis_query_t; -struct redis_query_s -{ - char query[MAX_REDIS_QUERY]; - char type[DATA_MAX_NAME_LEN]; - char instance[DATA_MAX_NAME_LEN]; - redis_query_t *next; +struct redis_query_s { + char query[MAX_REDIS_QUERY]; + char type[DATA_MAX_NAME_LEN]; + char instance[DATA_MAX_NAME_LEN]; + redis_query_t *next; }; struct redis_node_s; typedef struct redis_node_s redis_node_t; -struct redis_node_s -{ +struct redis_node_s { char name[MAX_REDIS_NODE_NAME]; char host[HOST_NAME_MAX]; char passwd[MAX_REDIS_PASSWD_LENGTH]; @@ -79,39 +77,35 @@ struct redis_node_s static redis_node_t *nodes_head = NULL; -static int redis_node_add (const redis_node_t *rn) /* {{{ */ +static int redis_node_add(const redis_node_t *rn) /* {{{ */ { redis_node_t *rn_copy; redis_node_t *rn_ptr; /* Check for duplicates first */ for (rn_ptr = nodes_head; rn_ptr != NULL; rn_ptr = rn_ptr->next) - if (strcmp (rn->name, rn_ptr->name) == 0) + if (strcmp(rn->name, rn_ptr->name) == 0) break; - if (rn_ptr != NULL) - { - ERROR ("redis plugin: A node with the name `%s' already exists.", - rn->name); + if (rn_ptr != NULL) { + ERROR("redis plugin: A node with the name `%s' already exists.", rn->name); return (-1); } - rn_copy = malloc (sizeof (*rn_copy)); - if (rn_copy == NULL) - { - ERROR ("redis plugin: malloc failed adding redis_node to the tree."); + rn_copy = malloc(sizeof(*rn_copy)); + if (rn_copy == NULL) { + ERROR("redis plugin: malloc failed adding redis_node to the tree."); return (-1); } - memcpy (rn_copy, rn, sizeof (*rn_copy)); + memcpy(rn_copy, rn, sizeof(*rn_copy)); rn_copy->next = NULL; - DEBUG ("redis plugin: Adding node \"%s\".", rn->name); + DEBUG("redis plugin: Adding node \"%s\".", rn->name); if (nodes_head == NULL) nodes_head = rn_copy; - else - { + else { rn_ptr = nodes_head; while (rn_ptr->next != NULL) rn_ptr = rn_ptr->next; @@ -121,99 +115,92 @@ static int redis_node_add (const redis_node_t *rn) /* {{{ */ return (0); } /* }}} */ -static redis_query_t *redis_config_query (oconfig_item_t *ci) /* {{{ */ +static redis_query_t *redis_config_query(oconfig_item_t *ci) /* {{{ */ { - redis_query_t *rq; - int status; + redis_query_t *rq; + int status; + + rq = calloc(1, sizeof(*rq)); + if (rq == NULL) { + ERROR("redis plugin: calloc failed adding redis_query."); + return NULL; + } + status = cf_util_get_string_buffer(ci, rq->query, sizeof(rq->query)); + if (status != 0) + goto err; + + /* + * Default to a gauge type. + */ + (void)strncpy(rq->type, "gauge", sizeof(rq->type)); + (void)sstrncpy(rq->instance, rq->query, sizeof(rq->instance)); + replace_special(rq->instance, sizeof(rq->instance)); - rq = calloc(1, sizeof(*rq)); - if (rq == NULL) { - ERROR("redis plugin: calloc failed adding redis_query."); - return NULL; + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *option = ci->children + i; + + if (strcasecmp("Type", option->key) == 0) { + status = cf_util_get_string_buffer(option, rq->type, sizeof(rq->type)); + } else if (strcasecmp("Instance", option->key) == 0) { + status = + cf_util_get_string_buffer(option, rq->instance, sizeof(rq->instance)); + } else { + WARNING("redis plugin: unknown configuration option: %s", option->key); + status = -1; } - status = cf_util_get_string_buffer(ci, rq->query, sizeof(rq->query)); if (status != 0) - goto err; - - /* - * Default to a gauge type. - */ - (void)strncpy(rq->type, "gauge", sizeof(rq->type)); - (void)sstrncpy(rq->instance, rq->query, sizeof(rq->instance)); - replace_special(rq->instance, sizeof(rq->instance)); - - for (int i = 0; i < ci->children_num; i++) { - oconfig_item_t *option = ci->children + i; - - if (strcasecmp("Type", option->key) == 0) { - status = cf_util_get_string_buffer(option, rq->type, sizeof(rq->type)); - } else if (strcasecmp("Instance", option->key) == 0) { - status = cf_util_get_string_buffer(option, rq->instance, sizeof(rq->instance)); - } else { - WARNING("redis plugin: unknown configuration option: %s", option->key); - status = -1; - } - if (status != 0) - goto err; - } - return rq; - err: - free(rq); - return NULL; + goto err; + } + return rq; +err: + free(rq); + return NULL; } /* }}} */ -static int redis_config_node (oconfig_item_t *ci) /* {{{ */ +static int redis_config_node(oconfig_item_t *ci) /* {{{ */ { redis_query_t *rq; int status; int timeout; - redis_node_t rn = { - .port = REDIS_DEF_PORT, - .timeout.tv_usec = REDIS_DEF_TIMEOUT - }; + redis_node_t rn = {.port = REDIS_DEF_PORT, + .timeout.tv_usec = REDIS_DEF_TIMEOUT}; - sstrncpy (rn.host, REDIS_DEF_HOST, sizeof (rn.host)); + sstrncpy(rn.host, REDIS_DEF_HOST, sizeof(rn.host)); - status = cf_util_get_string_buffer (ci, rn.name, sizeof (rn.name)); + status = cf_util_get_string_buffer(ci, rn.name, sizeof(rn.name)); if (status != 0) return (status); - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; - if (strcasecmp ("Host", option->key) == 0) - status = cf_util_get_string_buffer (option, rn.host, sizeof (rn.host)); - else if (strcasecmp ("Port", option->key) == 0) - { - status = cf_util_get_port_number (option); - if (status > 0) - { + if (strcasecmp("Host", option->key) == 0) + status = cf_util_get_string_buffer(option, rn.host, sizeof(rn.host)); + else if (strcasecmp("Port", option->key) == 0) { + status = cf_util_get_port_number(option); + if (status > 0) { rn.port = status; status = 0; } - } - else if (strcasecmp ("Query", option->key) == 0) - { + } else if (strcasecmp("Query", option->key) == 0) { rq = redis_config_query(option); if (rq == NULL) { - status =1; + status = 1; } else { - rq->next = rn.queries; - rn.queries = rq; + rq->next = rn.queries; + rn.queries = rq; } - } - else if (strcasecmp ("Timeout", option->key) == 0) - { - status = cf_util_get_int (option, &timeout); - if (status == 0) rn.timeout.tv_usec = timeout; - } - else if (strcasecmp ("Password", option->key) == 0) - status = cf_util_get_string_buffer (option, rn.passwd, sizeof (rn.passwd)); + } else if (strcasecmp("Timeout", option->key) == 0) { + status = cf_util_get_int(option, &timeout); + if (status == 0) + rn.timeout.tv_usec = timeout; + } else if (strcasecmp("Password", option->key) == 0) + status = cf_util_get_string_buffer(option, rn.passwd, sizeof(rn.passwd)); else - WARNING ("redis plugin: Option `%s' not allowed inside a `Node' " - "block. I'll ignore this option.", option->key); + WARNING("redis plugin: Option `%s' not allowed inside a `Node' " + "block. I'll ignore this option.", + option->key); if (status != 0) break; @@ -222,232 +209,244 @@ static int redis_config_node (oconfig_item_t *ci) /* {{{ */ if (status != 0) return (status); - return (redis_node_add (&rn)); + return (redis_node_add(&rn)); } /* }}} int redis_config_node */ -static int redis_config (oconfig_item_t *ci) /* {{{ */ +static int redis_config(oconfig_item_t *ci) /* {{{ */ { - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; - if (strcasecmp ("Node", option->key) == 0) - redis_config_node (option); + if (strcasecmp("Node", option->key) == 0) + redis_config_node(option); else - WARNING ("redis plugin: Option `%s' not allowed in redis" - " configuration. It will be ignored.", option->key); + WARNING("redis plugin: Option `%s' not allowed in redis" + " configuration. It will be ignored.", + option->key); } - if (nodes_head == NULL) - { - ERROR ("redis plugin: No valid node configuration could be found."); + if (nodes_head == NULL) { + ERROR("redis plugin: No valid node configuration could be found."); return (ENOENT); } return (0); } /* }}} */ - __attribute__ ((nonnull(2))) -static void redis_submit (char *plugin_instance, - const char *type, const char *type_instance, - value_t value) /* {{{ */ +__attribute__((nonnull(2))) static void +redis_submit(char *plugin_instance, const char *type, const char *type_instance, + value_t value) /* {{{ */ { value_list_t vl = VALUE_LIST_INIT; vl.values = &value; vl.values_len = 1; - sstrncpy (vl.plugin, "redis", sizeof (vl.plugin)); + sstrncpy(vl.plugin, "redis", sizeof(vl.plugin)); if (plugin_instance != NULL) - sstrncpy (vl.plugin_instance, plugin_instance, - sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, - sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* }}} */ -static int redis_init (void) /* {{{ */ +static int redis_init(void) /* {{{ */ { - redis_node_t rn = { - .name = "default", - .host = REDIS_DEF_HOST, - .port = REDIS_DEF_PORT, - .timeout.tv_sec = 0, - .timeout.tv_usec = REDIS_DEF_TIMEOUT, - .next = NULL -}; + redis_node_t rn = {.name = "default", + .host = REDIS_DEF_HOST, + .port = REDIS_DEF_PORT, + .timeout.tv_sec = 0, + .timeout.tv_usec = REDIS_DEF_TIMEOUT, + .next = NULL}; if (nodes_head == NULL) - redis_node_add (&rn); + redis_node_add(&rn); return (0); } /* }}} int redis_init */ -static int redis_handle_info (char *node, char const *info_line, char const *type, char const *type_instance, char const *field_name, int ds_type) /* {{{ */ +static int redis_handle_info(char *node, char const *info_line, + char const *type, char const *type_instance, + char const *field_name, int ds_type) /* {{{ */ { - char *str = strstr (info_line, field_name); + char *str = strstr(info_line, field_name); static char buf[MAX_REDIS_VAL_SIZE]; value_t val; - if (str) - { + if (str) { int i; - str += strlen (field_name) + 1; /* also skip the ':' */ - for(i=0;(*str && (isdigit((unsigned char)*str) || *str == '.'));i++,str++) + str += strlen(field_name) + 1; /* also skip the ':' */ + for (i = 0; (*str && (isdigit((unsigned char)*str) || *str == '.')); + i++, str++) buf[i] = *str; - buf[i] ='\0'; + buf[i] = '\0'; - if(parse_value (buf, &val, ds_type) == -1) - { - WARNING ("redis plugin: Unable to parse field `%s'.", field_name); + if (parse_value(buf, &val, ds_type) == -1) { + WARNING("redis plugin: Unable to parse field `%s'.", field_name); return (-1); } - redis_submit (node, type, type_instance, val); + redis_submit(node, type, type_instance, val); return (0); } return (-1); } /* }}} int redis_handle_info */ -static int redis_handle_query (redisContext *rh, redis_node_t *rn, redis_query_t *rq) /* {{{ */ +static int redis_handle_query(redisContext *rh, redis_node_t *rn, + redis_query_t *rq) /* {{{ */ { - redisReply *rr; - const data_set_t *ds; - value_t val; + redisReply *rr; + const data_set_t *ds; + value_t val; - ds = plugin_get_ds (rq->type); - if (!ds) { - ERROR ("redis plugin: DataSet `%s' not defined.", rq->type); - return (-1); - } + ds = plugin_get_ds(rq->type); + if (!ds) { + ERROR("redis plugin: DataSet `%s' not defined.", rq->type); + return (-1); + } - if (ds->ds_num != 1) { - ERROR ("redis plugin: DS `%s' has too many types.", rq->type); - return (-1); - } + if (ds->ds_num != 1) { + ERROR("redis plugin: DS `%s' has too many types.", rq->type); + return (-1); + } - if ((rr = redisCommand(rh, rq->query)) == NULL) { - WARNING("redis plugin: unable to carry out query `%s'.", rq->query); - return (-1); - } + if ((rr = redisCommand(rh, rq->query)) == NULL) { + WARNING("redis plugin: unable to carry out query `%s'.", rq->query); + return (-1); + } - switch (rr->type) { - case REDIS_REPLY_INTEGER: - switch (ds->ds[0].type) { - case DS_TYPE_COUNTER: - val.counter = (counter_t)rr->integer; - break; - case DS_TYPE_GAUGE: - val.gauge = (gauge_t)rr->integer; - break; - case DS_TYPE_DERIVE: - val.gauge = (derive_t)rr->integer; - break; - case DS_TYPE_ABSOLUTE: - val.gauge = (absolute_t)rr->integer; - break; - } - break; - case REDIS_REPLY_STRING: - if (parse_value (rr->str, &val, ds->ds[0].type) == -1) { - WARNING("redis plugin: Unable to parse field `%s'.", rq->type); - freeReplyObject (rr); - return (-1); - } - break; - default: - WARNING("redis plugin: Cannot coerce redis type."); - freeReplyObject(rr); - return (-1); + switch (rr->type) { + case REDIS_REPLY_INTEGER: + switch (ds->ds[0].type) { + case DS_TYPE_COUNTER: + val.counter = (counter_t)rr->integer; + break; + case DS_TYPE_GAUGE: + val.gauge = (gauge_t)rr->integer; + break; + case DS_TYPE_DERIVE: + val.gauge = (derive_t)rr->integer; + break; + case DS_TYPE_ABSOLUTE: + val.gauge = (absolute_t)rr->integer; + break; + } + break; + case REDIS_REPLY_STRING: + if (parse_value(rr->str, &val, ds->ds[0].type) == -1) { + WARNING("redis plugin: Unable to parse field `%s'.", rq->type); + freeReplyObject(rr); + return (-1); } + break; + default: + WARNING("redis plugin: Cannot coerce redis type."); + freeReplyObject(rr); + return (-1); + } - redis_submit(rn->name, rq->type, (strlen(rq->instance) >0)?rq->instance:NULL, val); - freeReplyObject (rr); - return 0; + redis_submit(rn->name, rq->type, + (strlen(rq->instance) > 0) ? rq->instance : NULL, val); + freeReplyObject(rr); + return 0; } /* }}} int redis_handle_query */ -static int redis_read (void) /* {{{ */ +static int redis_read(void) /* {{{ */ { - for (redis_node_t *rn = nodes_head; rn != NULL; rn = rn->next) - { + for (redis_node_t *rn = nodes_head; rn != NULL; rn = rn->next) { redisContext *rh; - redisReply *rr; + redisReply *rr; - DEBUG ("redis plugin: querying info from node `%s' (%s:%d).", rn->name, rn->host, rn->port); + DEBUG("redis plugin: querying info from node `%s' (%s:%d).", rn->name, + rn->host, rn->port); - rh = redisConnectWithTimeout ((char *)rn->host, rn->port, rn->timeout); - if (rh == NULL) - { - ERROR ("redis plugin: unable to connect to node `%s' (%s:%d).", rn->name, rn->host, rn->port); + rh = redisConnectWithTimeout((char *)rn->host, rn->port, rn->timeout); + if (rh == NULL) { + ERROR("redis plugin: unable to connect to node `%s' (%s:%d).", rn->name, + rn->host, rn->port); continue; } - if (strlen (rn->passwd) > 0) - { - DEBUG ("redis plugin: authenticating node `%s' passwd(%s).", rn->name, rn->passwd); + if (strlen(rn->passwd) > 0) { + DEBUG("redis plugin: authenticating node `%s' passwd(%s).", rn->name, + rn->passwd); - if ((rr = redisCommand (rh, "AUTH %s", rn->passwd)) == NULL) - { - WARNING ("redis plugin: unable to authenticate on node `%s'.", rn->name); + if ((rr = redisCommand(rh, "AUTH %s", rn->passwd)) == NULL) { + WARNING("redis plugin: unable to authenticate on node `%s'.", rn->name); goto redis_fail; } - if (rr->type != REDIS_REPLY_STATUS) - { - WARNING ("redis plugin: invalid authentication on node `%s'.", rn->name); + if (rr->type != REDIS_REPLY_STATUS) { + WARNING("redis plugin: invalid authentication on node `%s'.", rn->name); goto redis_fail; } - freeReplyObject (rr); + freeReplyObject(rr); } - if ((rr = redisCommand(rh, "INFO")) == NULL) - { - WARNING ("redis plugin: unable to get info from node `%s'.", rn->name); + if ((rr = redisCommand(rh, "INFO")) == NULL) { + WARNING("redis plugin: unable to get info from node `%s'.", rn->name); goto redis_fail; } - redis_handle_info (rn->name, rr->str, "uptime", NULL, "uptime_in_seconds", DS_TYPE_GAUGE); - redis_handle_info (rn->name, rr->str, "current_connections", "clients", "connected_clients", DS_TYPE_GAUGE); - redis_handle_info (rn->name, rr->str, "blocked_clients", NULL, "blocked_clients", DS_TYPE_GAUGE); - redis_handle_info (rn->name, rr->str, "memory", NULL, "used_memory", DS_TYPE_GAUGE); - redis_handle_info (rn->name, rr->str, "memory_lua", NULL, "used_memory_lua", DS_TYPE_GAUGE); + redis_handle_info(rn->name, rr->str, "uptime", NULL, "uptime_in_seconds", + DS_TYPE_GAUGE); + redis_handle_info(rn->name, rr->str, "current_connections", "clients", + "connected_clients", DS_TYPE_GAUGE); + redis_handle_info(rn->name, rr->str, "blocked_clients", NULL, + "blocked_clients", DS_TYPE_GAUGE); + redis_handle_info(rn->name, rr->str, "memory", NULL, "used_memory", + DS_TYPE_GAUGE); + redis_handle_info(rn->name, rr->str, "memory_lua", NULL, "used_memory_lua", + DS_TYPE_GAUGE); /* changes_since_last_save: Deprecated in redis version 2.6 and above */ - redis_handle_info (rn->name, rr->str, "volatile_changes", NULL, "changes_since_last_save", DS_TYPE_GAUGE); - redis_handle_info (rn->name, rr->str, "total_connections", NULL, "total_connections_received", DS_TYPE_DERIVE); - redis_handle_info (rn->name, rr->str, "total_operations", NULL, "total_commands_processed", DS_TYPE_DERIVE); - redis_handle_info (rn->name, rr->str, "operations_per_second", NULL, "instantaneous_ops_per_sec", DS_TYPE_GAUGE); - redis_handle_info (rn->name, rr->str, "expired_keys", NULL, "expired_keys", DS_TYPE_DERIVE); - redis_handle_info (rn->name, rr->str, "evicted_keys", NULL, "evicted_keys", DS_TYPE_DERIVE); - redis_handle_info (rn->name, rr->str, "pubsub", "channels", "pubsub_channels", DS_TYPE_GAUGE); - redis_handle_info (rn->name, rr->str, "pubsub", "patterns", "pubsub_patterns", DS_TYPE_GAUGE); - redis_handle_info (rn->name, rr->str, "current_connections", "slaves", "connected_slaves", DS_TYPE_GAUGE); - redis_handle_info (rn->name, rr->str, "cache_result", "hits", "keyspace_hits", DS_TYPE_DERIVE); - redis_handle_info (rn->name, rr->str, "cache_result", "misses", "keyspace_misses", DS_TYPE_DERIVE); - redis_handle_info (rn->name, rr->str, "total_bytes", "input", "total_net_input_bytes", DS_TYPE_DERIVE); - redis_handle_info (rn->name, rr->str, "total_bytes", "output", "total_net_output_bytes", DS_TYPE_DERIVE); + redis_handle_info(rn->name, rr->str, "volatile_changes", NULL, + "changes_since_last_save", DS_TYPE_GAUGE); + redis_handle_info(rn->name, rr->str, "total_connections", NULL, + "total_connections_received", DS_TYPE_DERIVE); + redis_handle_info(rn->name, rr->str, "total_operations", NULL, + "total_commands_processed", DS_TYPE_DERIVE); + redis_handle_info(rn->name, rr->str, "operations_per_second", NULL, + "instantaneous_ops_per_sec", DS_TYPE_GAUGE); + redis_handle_info(rn->name, rr->str, "expired_keys", NULL, "expired_keys", + DS_TYPE_DERIVE); + redis_handle_info(rn->name, rr->str, "evicted_keys", NULL, "evicted_keys", + DS_TYPE_DERIVE); + redis_handle_info(rn->name, rr->str, "pubsub", "channels", + "pubsub_channels", DS_TYPE_GAUGE); + redis_handle_info(rn->name, rr->str, "pubsub", "patterns", + "pubsub_patterns", DS_TYPE_GAUGE); + redis_handle_info(rn->name, rr->str, "current_connections", "slaves", + "connected_slaves", DS_TYPE_GAUGE); + redis_handle_info(rn->name, rr->str, "cache_result", "hits", + "keyspace_hits", DS_TYPE_DERIVE); + redis_handle_info(rn->name, rr->str, "cache_result", "misses", + "keyspace_misses", DS_TYPE_DERIVE); + redis_handle_info(rn->name, rr->str, "total_bytes", "input", + "total_net_input_bytes", DS_TYPE_DERIVE); + redis_handle_info(rn->name, rr->str, "total_bytes", "output", + "total_net_output_bytes", DS_TYPE_DERIVE); for (redis_query_t *rq = rn->queries; rq != NULL; rq = rq->next) - redis_handle_query(rh, rn, rq); + redis_handle_query(rh, rn, rq); -redis_fail: + redis_fail: if (rr != NULL) - freeReplyObject (rr); - redisFree (rh); + freeReplyObject(rr); + redisFree(rh); } return 0; } /* }}} */ -void module_register (void) /* {{{ */ +void module_register(void) /* {{{ */ { - plugin_register_complex_config ("redis", redis_config); - plugin_register_init ("redis", redis_init); - plugin_register_read ("redis", redis_read); + plugin_register_complex_config("redis", redis_config); + plugin_register_init("redis", redis_init); + plugin_register_read("redis", redis_read); /* TODO: plugin_register_write: one redis list per value id with * X elements */ } diff --git a/src/routeros.c b/src/routeros.c index 5e8a2943..07493c75 100644 --- a/src/routeros.c +++ b/src/routeros.c @@ -31,8 +31,7 @@ #include -struct cr_data_s -{ +struct cr_data_s { ros_connection_t *connection; char *node; @@ -49,150 +48,143 @@ struct cr_data_s }; typedef struct cr_data_s cr_data_t; -static void cr_submit_io (cr_data_t *rd, const char *type, /* {{{ */ - const char *type_instance, derive_t rx, derive_t tx) -{ - value_list_t vl = VALUE_LIST_INIT; - value_t values[] = { - { .derive = rx }, - { .derive = tx }, - }; - - vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - sstrncpy (vl.host, rd->node, sizeof (vl.host)); - sstrncpy (vl.plugin, "routeros", sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); +static void cr_submit_io(cr_data_t *rd, const char *type, /* {{{ */ + const char *type_instance, derive_t rx, derive_t tx) { + value_list_t vl = VALUE_LIST_INIT; + value_t values[] = { + {.derive = rx}, {.derive = tx}, + }; + + vl.values = values; + vl.values_len = STATIC_ARRAY_SIZE(values); + sstrncpy(vl.host, rd->node, sizeof(vl.host)); + sstrncpy(vl.plugin, "routeros", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); } /* }}} void cr_submit_io */ -static void submit_interface (cr_data_t *rd, /* {{{ */ - const ros_interface_t *i) -{ +static void submit_interface(cr_data_t *rd, /* {{{ */ + const ros_interface_t *i) { if (i == NULL) return; - if (!i->running) - { - submit_interface (rd, i->next); + if (!i->running) { + submit_interface(rd, i->next); return; } - cr_submit_io (rd, "if_packets", i->name, - (derive_t) i->rx_packets, (derive_t) i->tx_packets); - cr_submit_io (rd, "if_octets", i->name, - (derive_t) i->rx_bytes, (derive_t) i->tx_bytes); - cr_submit_io (rd, "if_errors", i->name, - (derive_t) i->rx_errors, (derive_t) i->tx_errors); - cr_submit_io (rd, "if_dropped", i->name, - (derive_t) i->rx_drops, (derive_t) i->tx_drops); + cr_submit_io(rd, "if_packets", i->name, (derive_t)i->rx_packets, + (derive_t)i->tx_packets); + cr_submit_io(rd, "if_octets", i->name, (derive_t)i->rx_bytes, + (derive_t)i->tx_bytes); + cr_submit_io(rd, "if_errors", i->name, (derive_t)i->rx_errors, + (derive_t)i->tx_errors); + cr_submit_io(rd, "if_dropped", i->name, (derive_t)i->rx_drops, + (derive_t)i->tx_drops); - submit_interface (rd, i->next); + submit_interface(rd, i->next); } /* }}} void submit_interface */ -static int handle_interface (__attribute__((unused)) ros_connection_t *c, /* {{{ */ - const ros_interface_t *i, void *user_data) -{ +static int handle_interface(__attribute__((unused)) + ros_connection_t *c, /* {{{ */ + const ros_interface_t *i, + void *user_data) { if ((i == NULL) || (user_data == NULL)) return (EINVAL); - submit_interface (user_data, i); + submit_interface(user_data, i); return (0); } /* }}} int handle_interface */ -static void cr_submit_gauge (cr_data_t *rd, const char *type, /* {{{ */ - const char *type_instance, gauge_t value) -{ - value_t values[1]; - value_list_t vl = VALUE_LIST_INIT; +static void cr_submit_gauge(cr_data_t *rd, const char *type, /* {{{ */ + const char *type_instance, gauge_t value) { + value_t values[1]; + value_list_t vl = VALUE_LIST_INIT; - values[0].gauge = value; + values[0].gauge = value; - vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - sstrncpy (vl.host, rd->node, sizeof (vl.host)); - sstrncpy (vl.plugin, "routeros", sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + vl.values = values; + vl.values_len = STATIC_ARRAY_SIZE(values); + sstrncpy(vl.host, rd->node, sizeof(vl.host)); + sstrncpy(vl.plugin, "routeros", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* }}} void cr_submit_gauge */ #if ROS_VERSION >= ROS_VERSION_ENCODE(1, 1, 0) -static void cr_submit_counter (cr_data_t *rd, const char *type, /* {{{ */ - const char *type_instance, derive_t value) -{ - value_t values[1]; - value_list_t vl = VALUE_LIST_INIT; +static void cr_submit_counter(cr_data_t *rd, const char *type, /* {{{ */ + const char *type_instance, derive_t value) { + value_t values[1]; + value_list_t vl = VALUE_LIST_INIT; - values[0].derive = value; + values[0].derive = value; - vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - sstrncpy (vl.host, rd->node, sizeof (vl.host)); - sstrncpy (vl.plugin, "routeros", sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + vl.values = values; + vl.values_len = STATIC_ARRAY_SIZE(values); + sstrncpy(vl.host, rd->node, sizeof(vl.host)); + sstrncpy(vl.plugin, "routeros", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* }}} void cr_submit_gauge */ #endif -static void submit_regtable (cr_data_t *rd, /* {{{ */ - const ros_registration_table_t *r) -{ +static void submit_regtable(cr_data_t *rd, /* {{{ */ + const ros_registration_table_t *r) { char type_instance[DATA_MAX_NAME_LEN]; if (r == NULL) return; /*** RX ***/ - ssnprintf (type_instance, sizeof (type_instance), "%s-%s-rx", - r->interface, r->radio_name); - cr_submit_gauge (rd, "bitrate", type_instance, - (gauge_t) (1000000.0 * r->rx_rate)); - cr_submit_gauge (rd, "signal_power", type_instance, - (gauge_t) r->rx_signal_strength); - cr_submit_gauge (rd, "signal_quality", type_instance, - (gauge_t) r->rx_ccq); + ssnprintf(type_instance, sizeof(type_instance), "%s-%s-rx", r->interface, + r->radio_name); + cr_submit_gauge(rd, "bitrate", type_instance, + (gauge_t)(1000000.0 * r->rx_rate)); + cr_submit_gauge(rd, "signal_power", type_instance, + (gauge_t)r->rx_signal_strength); + cr_submit_gauge(rd, "signal_quality", type_instance, (gauge_t)r->rx_ccq); /*** TX ***/ - ssnprintf (type_instance, sizeof (type_instance), "%s-%s-tx", - r->interface, r->radio_name); - cr_submit_gauge (rd, "bitrate", type_instance, - (gauge_t) (1000000.0 * r->tx_rate)); - cr_submit_gauge (rd, "signal_power", type_instance, - (gauge_t) r->tx_signal_strength); - cr_submit_gauge (rd, "signal_quality", type_instance, - (gauge_t) r->tx_ccq); + ssnprintf(type_instance, sizeof(type_instance), "%s-%s-tx", r->interface, + r->radio_name); + cr_submit_gauge(rd, "bitrate", type_instance, + (gauge_t)(1000000.0 * r->tx_rate)); + cr_submit_gauge(rd, "signal_power", type_instance, + (gauge_t)r->tx_signal_strength); + cr_submit_gauge(rd, "signal_quality", type_instance, (gauge_t)r->tx_ccq); /*** RX / TX ***/ - ssnprintf (type_instance, sizeof (type_instance), "%s-%s", - r->interface, r->radio_name); - cr_submit_io (rd, "if_octets", type_instance, - (derive_t) r->rx_bytes, (derive_t) r->tx_bytes); - cr_submit_gauge (rd, "snr", type_instance, (gauge_t) r->signal_to_noise); + ssnprintf(type_instance, sizeof(type_instance), "%s-%s", r->interface, + r->radio_name); + cr_submit_io(rd, "if_octets", type_instance, (derive_t)r->rx_bytes, + (derive_t)r->tx_bytes); + cr_submit_gauge(rd, "snr", type_instance, (gauge_t)r->signal_to_noise); - submit_regtable (rd, r->next); + submit_regtable(rd, r->next); } /* }}} void submit_regtable */ -static int handle_regtable (__attribute__((unused)) ros_connection_t *c, /* {{{ */ - const ros_registration_table_t *r, void *user_data) -{ +static int handle_regtable(__attribute__((unused)) + ros_connection_t *c, /* {{{ */ + const ros_registration_table_t *r, + void *user_data) { if ((r == NULL) || (user_data == NULL)) return (EINVAL); - submit_regtable (user_data, r); + submit_regtable(user_data, r); return (0); } /* }}} int handle_regtable */ #if ROS_VERSION >= ROS_VERSION_ENCODE(1, 1, 0) -static int handle_system_resource (__attribute__((unused)) ros_connection_t *c, /* {{{ */ - const ros_system_resource_t *r, - __attribute__((unused)) void *user_data) -{ +static int handle_system_resource(__attribute__((unused)) + ros_connection_t *c, /* {{{ */ + const ros_system_resource_t *r, + __attribute__((unused)) void *user_data) { cr_data_t *rd; if ((r == NULL) || (user_data == NULL)) @@ -200,33 +192,31 @@ static int handle_system_resource (__attribute__((unused)) ros_connection_t *c, rd = user_data; if (rd->collect_cpu_load) - cr_submit_gauge (rd, "gauge", "cpu_load", (gauge_t) r->cpu_load); + cr_submit_gauge(rd, "gauge", "cpu_load", (gauge_t)r->cpu_load); - if (rd->collect_memory) - { - cr_submit_gauge (rd, "memory", "used", - (gauge_t) (r->total_memory - r->free_memory)); - cr_submit_gauge (rd, "memory", "free", (gauge_t) r->free_memory); + if (rd->collect_memory) { + cr_submit_gauge(rd, "memory", "used", + (gauge_t)(r->total_memory - r->free_memory)); + cr_submit_gauge(rd, "memory", "free", (gauge_t)r->free_memory); } - if (rd->collect_df) - { - cr_submit_gauge (rd, "df_complex", "used", - (gauge_t) (r->total_memory - r->free_memory)); - cr_submit_gauge (rd, "df_complex", "free", (gauge_t) r->free_memory); + if (rd->collect_df) { + cr_submit_gauge(rd, "df_complex", "used", + (gauge_t)(r->total_memory - r->free_memory)); + cr_submit_gauge(rd, "df_complex", "free", (gauge_t)r->free_memory); } - if (rd->collect_disk) - { - cr_submit_counter (rd, "counter", "secors_written", (derive_t) r->write_sect_total); - cr_submit_gauge (rd, "gauge", "bad_blocks", (gauge_t) r->bad_blocks); + if (rd->collect_disk) { + cr_submit_counter(rd, "counter", "secors_written", + (derive_t)r->write_sect_total); + cr_submit_gauge(rd, "gauge", "bad_blocks", (gauge_t)r->bad_blocks); } return (0); } /* }}} int handle_system_resource */ #endif -static int cr_read (user_data_t *user_data) /* {{{ */ +static int cr_read(user_data_t *user_data) /* {{{ */ { int status; cr_data_t *rd; @@ -238,64 +228,54 @@ static int cr_read (user_data_t *user_data) /* {{{ */ if (rd == NULL) return (EINVAL); - if (rd->connection == NULL) - { - rd->connection = ros_connect (rd->node, rd->service, - rd->username, rd->password); - if (rd->connection == NULL) - { + if (rd->connection == NULL) { + rd->connection = + ros_connect(rd->node, rd->service, rd->username, rd->password); + if (rd->connection == NULL) { char errbuf[128]; - ERROR ("routeros plugin: ros_connect failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("routeros plugin: ros_connect failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } } - assert (rd->connection != NULL); + assert(rd->connection != NULL); - if (rd->collect_interface) - { - status = ros_interface (rd->connection, handle_interface, - /* user data = */ rd); - if (status != 0) - { + if (rd->collect_interface) { + status = ros_interface(rd->connection, handle_interface, + /* user data = */ rd); + if (status != 0) { char errbuf[128]; - ERROR ("routeros plugin: ros_interface failed: %s", - sstrerror (status, errbuf, sizeof (errbuf))); - ros_disconnect (rd->connection); + ERROR("routeros plugin: ros_interface failed: %s", + sstrerror(status, errbuf, sizeof(errbuf))); + ros_disconnect(rd->connection); rd->connection = NULL; return (-1); } } - if (rd->collect_regtable) - { - status = ros_registration_table (rd->connection, handle_regtable, - /* user data = */ rd); - if (status != 0) - { + if (rd->collect_regtable) { + status = ros_registration_table(rd->connection, handle_regtable, + /* user data = */ rd); + if (status != 0) { char errbuf[128]; - ERROR ("routeros plugin: ros_registration_table failed: %s", - sstrerror (status, errbuf, sizeof (errbuf))); - ros_disconnect (rd->connection); + ERROR("routeros plugin: ros_registration_table failed: %s", + sstrerror(status, errbuf, sizeof(errbuf))); + ros_disconnect(rd->connection); rd->connection = NULL; return (-1); } } #if ROS_VERSION >= ROS_VERSION_ENCODE(1, 1, 0) - if (rd->collect_cpu_load - || rd->collect_memory - || rd->collect_df - || rd->collect_disk) - { - status = ros_system_resource (rd->connection, handle_system_resource, - /* user data = */ rd); - if (status != 0) - { + if (rd->collect_cpu_load || rd->collect_memory || rd->collect_df || + rd->collect_disk) { + status = ros_system_resource(rd->connection, handle_system_resource, + /* user data = */ rd); + if (status != 0) { char errbuf[128]; - ERROR ("routeros plugin: ros_system_resource failed: %s", - sstrerror (status, errbuf, sizeof (errbuf))); - ros_disconnect (rd->connection); + ERROR("routeros plugin: ros_system_resource failed: %s", + sstrerror(status, errbuf, sizeof(errbuf))); + ros_disconnect(rd->connection); rd->connection = NULL; return (-1); } @@ -305,29 +285,29 @@ static int cr_read (user_data_t *user_data) /* {{{ */ return (0); } /* }}} int cr_read */ -static void cr_free_data (cr_data_t *ptr) /* {{{ */ +static void cr_free_data(cr_data_t *ptr) /* {{{ */ { if (ptr == NULL) return; - ros_disconnect (ptr->connection); + ros_disconnect(ptr->connection); ptr->connection = NULL; - sfree (ptr->node); - sfree (ptr->service); - sfree (ptr->username); - sfree (ptr->password); + sfree(ptr->node); + sfree(ptr->service); + sfree(ptr->username); + sfree(ptr->password); - sfree (ptr); + sfree(ptr); } /* }}} void cr_free_data */ -static int cr_config_router (oconfig_item_t *ci) /* {{{ */ +static int cr_config_router(oconfig_item_t *ci) /* {{{ */ { cr_data_t *router_data; char read_name[128]; int status; - router_data = calloc (1, sizeof (*router_data)); + router_data = calloc(1, sizeof(*router_data)); if (router_data == NULL) return (-1); router_data->connection = NULL; @@ -337,110 +317,97 @@ static int cr_config_router (oconfig_item_t *ci) /* {{{ */ router_data->password = NULL; status = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Host", child->key) == 0) - status = cf_util_get_string (child, &router_data->node); - else if (strcasecmp ("Port", child->key) == 0) - status = cf_util_get_service (child, &router_data->service); - else if (strcasecmp ("User", child->key) == 0) - status = cf_util_get_string (child, &router_data->username); - else if (strcasecmp ("Password", child->key) == 0) - status = cf_util_get_string (child, &router_data->password); - else if (strcasecmp ("CollectInterface", child->key) == 0) - cf_util_get_boolean (child, &router_data->collect_interface); - else if (strcasecmp ("CollectRegistrationTable", child->key) == 0) - cf_util_get_boolean (child, &router_data->collect_regtable); + if (strcasecmp("Host", child->key) == 0) + status = cf_util_get_string(child, &router_data->node); + else if (strcasecmp("Port", child->key) == 0) + status = cf_util_get_service(child, &router_data->service); + else if (strcasecmp("User", child->key) == 0) + status = cf_util_get_string(child, &router_data->username); + else if (strcasecmp("Password", child->key) == 0) + status = cf_util_get_string(child, &router_data->password); + else if (strcasecmp("CollectInterface", child->key) == 0) + cf_util_get_boolean(child, &router_data->collect_interface); + else if (strcasecmp("CollectRegistrationTable", child->key) == 0) + cf_util_get_boolean(child, &router_data->collect_regtable); #if ROS_VERSION >= ROS_VERSION_ENCODE(1, 1, 0) - else if (strcasecmp ("CollectCPULoad", child->key) == 0) - cf_util_get_boolean (child, &router_data->collect_cpu_load); - else if (strcasecmp ("CollectMemory", child->key) == 0) - cf_util_get_boolean (child, &router_data->collect_memory); - else if (strcasecmp ("CollectDF", child->key) == 0) - cf_util_get_boolean (child, &router_data->collect_df); - else if (strcasecmp ("CollectDisk", child->key) == 0) - cf_util_get_boolean (child, &router_data->collect_disk); + else if (strcasecmp("CollectCPULoad", child->key) == 0) + cf_util_get_boolean(child, &router_data->collect_cpu_load); + else if (strcasecmp("CollectMemory", child->key) == 0) + cf_util_get_boolean(child, &router_data->collect_memory); + else if (strcasecmp("CollectDF", child->key) == 0) + cf_util_get_boolean(child, &router_data->collect_df); + else if (strcasecmp("CollectDisk", child->key) == 0) + cf_util_get_boolean(child, &router_data->collect_disk); #endif - else - { - WARNING ("routeros plugin: Unknown config option `%s'.", child->key); + else { + WARNING("routeros plugin: Unknown config option `%s'.", child->key); } if (status != 0) break; } - if (status == 0) - { - if (router_data->node == NULL) - { - ERROR ("routeros plugin: No `Host' option within a `Router' block. " - "Where should I connect to?"); + if (status == 0) { + if (router_data->node == NULL) { + ERROR("routeros plugin: No `Host' option within a `Router' block. " + "Where should I connect to?"); status = -1; } - if (router_data->password == NULL) - { - ERROR ("routeros plugin: No `Password' option within a `Router' block. " - "How should I authenticate?"); + if (router_data->password == NULL) { + ERROR("routeros plugin: No `Password' option within a `Router' block. " + "How should I authenticate?"); status = -1; } - if (!router_data->collect_interface - && !router_data->collect_regtable) - { - ERROR ("routeros plugin: No `Collect*' option within a `Router' block. " - "What statistics should I collect?"); + if (!router_data->collect_interface && !router_data->collect_regtable) { + ERROR("routeros plugin: No `Collect*' option within a `Router' block. " + "What statistics should I collect?"); status = -1; } } - if ((status == 0) && (router_data->username == NULL)) - { - router_data->username = sstrdup ("admin"); - if (router_data->username == NULL) - { - ERROR ("routeros plugin: sstrdup failed."); + if ((status == 0) && (router_data->username == NULL)) { + router_data->username = sstrdup("admin"); + if (router_data->username == NULL) { + ERROR("routeros plugin: sstrdup failed."); status = -1; } } - ssnprintf (read_name, sizeof (read_name), "routeros/%s", router_data->node); + ssnprintf(read_name, sizeof(read_name), "routeros/%s", router_data->node); if (status == 0) - status = plugin_register_complex_read (/* group = */ NULL, read_name, - cr_read, /* interval = */ 0, &(user_data_t) { - .data = router_data, - .free_func = (void *) cr_free_data, + status = plugin_register_complex_read( + /* group = */ NULL, read_name, cr_read, /* interval = */ 0, + &(user_data_t){ + .data = router_data, .free_func = (void *)cr_free_data, }); if (status != 0) - cr_free_data (router_data); + cr_free_data(router_data); return (status); } /* }}} int cr_config_router */ -static int cr_config (oconfig_item_t *ci) -{ - for (int i = 0; i < ci->children_num; i++) - { +static int cr_config(oconfig_item_t *ci) { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Router", child->key) == 0) - cr_config_router (child); - else - { - WARNING ("routeros plugin: Unknown config option `%s'.", child->key); + if (strcasecmp("Router", child->key) == 0) + cr_config_router(child); + else { + WARNING("routeros plugin: Unknown config option `%s'.", child->key); } } return (0); } /* }}} int cr_config */ -void module_register (void) -{ - plugin_register_complex_config ("routeros", cr_config); +void module_register(void) { + plugin_register_complex_config("routeros", cr_config); } /* void module_register */ /* vim: set sw=2 noet fdm=marker : */ diff --git a/src/rrdcached.c b/src/rrdcached.c index 6d45ac9f..6eb67d4f 100644 --- a/src/rrdcached.c +++ b/src/rrdcached.c @@ -26,8 +26,8 @@ #include "collectd.h" -#include "plugin.h" #include "common.h" +#include "plugin.h" #include "utils_rrdcreate.h" #undef HAVE_CONFIG_H @@ -41,73 +41,64 @@ static char *datadir = NULL; static char *daemon_address = NULL; static _Bool config_create_files = 1; static _Bool config_collect_stats = 1; -static rrdcreate_config_t rrdcreate_config = -{ - /* stepsize = */ 0, - /* heartbeat = */ 0, - /* rrarows = */ 1200, - /* xff = */ 0.1, +static rrdcreate_config_t rrdcreate_config = { + /* stepsize = */ 0, + /* heartbeat = */ 0, + /* rrarows = */ 1200, + /* xff = */ 0.1, - /* timespans = */ NULL, - /* timespans_num = */ 0, + /* timespans = */ NULL, + /* timespans_num = */ 0, - /* consolidation_functions = */ NULL, - /* consolidation_functions_num = */ 0, + /* consolidation_functions = */ NULL, + /* consolidation_functions_num = */ 0, - /* async = */ 0 -}; + /* async = */ 0}; /* * Prototypes. */ -static int rc_write (const data_set_t *ds, const value_list_t *vl, - user_data_t __attribute__((unused)) *user_data); -static int rc_flush (__attribute__((unused)) cdtime_t timeout, - const char *identifier, __attribute__((unused)) user_data_t *ud); - -static int value_list_to_string (char *buffer, int buffer_len, - const data_set_t *ds, const value_list_t *vl) -{ +static int rc_write(const data_set_t *ds, const value_list_t *vl, + user_data_t __attribute__((unused)) * user_data); +static int rc_flush(__attribute__((unused)) cdtime_t timeout, + const char *identifier, + __attribute__((unused)) user_data_t *ud); + +static int value_list_to_string(char *buffer, int buffer_len, + const data_set_t *ds, const value_list_t *vl) { int offset; int status; time_t t; - assert (0 == strcmp (ds->type, vl->type)); + assert(0 == strcmp(ds->type, vl->type)); - memset (buffer, '\0', buffer_len); + memset(buffer, '\0', buffer_len); - t = CDTIME_T_TO_TIME_T (vl->time); - status = ssnprintf (buffer, buffer_len, "%lu", (unsigned long) t); + t = CDTIME_T_TO_TIME_T(vl->time); + status = ssnprintf(buffer, buffer_len, "%lu", (unsigned long)t); if ((status < 1) || (status >= buffer_len)) return (-1); offset = status; - for (size_t i = 0; i < ds->ds_num; i++) - { - if ((ds->ds[i].type != DS_TYPE_COUNTER) - && (ds->ds[i].type != DS_TYPE_GAUGE) - && (ds->ds[i].type != DS_TYPE_DERIVE) - && (ds->ds[i].type != DS_TYPE_ABSOLUTE)) + for (size_t i = 0; i < ds->ds_num; i++) { + if ((ds->ds[i].type != DS_TYPE_COUNTER) && + (ds->ds[i].type != DS_TYPE_GAUGE) && + (ds->ds[i].type != DS_TYPE_DERIVE) && + (ds->ds[i].type != DS_TYPE_ABSOLUTE)) return (-1); - if (ds->ds[i].type == DS_TYPE_COUNTER) - { - status = ssnprintf (buffer + offset, buffer_len - offset, - ":%llu", vl->values[i].counter); - } - else if (ds->ds[i].type == DS_TYPE_GAUGE) - { - status = ssnprintf (buffer + offset, buffer_len - offset, - ":%f", vl->values[i].gauge); - } - else if (ds->ds[i].type == DS_TYPE_DERIVE) { - status = ssnprintf (buffer + offset, buffer_len - offset, - ":%"PRIi64, vl->values[i].derive); - } - else /* if (ds->ds[i].type == DS_TYPE_ABSOLUTE) */ { - status = ssnprintf (buffer + offset, buffer_len - offset, - ":%"PRIu64, vl->values[i].absolute); - + if (ds->ds[i].type == DS_TYPE_COUNTER) { + status = ssnprintf(buffer + offset, buffer_len - offset, ":%llu", + vl->values[i].counter); + } else if (ds->ds[i].type == DS_TYPE_GAUGE) { + status = ssnprintf(buffer + offset, buffer_len - offset, ":%f", + vl->values[i].gauge); + } else if (ds->ds[i].type == DS_TYPE_DERIVE) { + status = ssnprintf(buffer + offset, buffer_len - offset, ":%" PRIi64, + vl->values[i].derive); + } else /* if (ds->ds[i].type == DS_TYPE_ABSOLUTE) */ { + status = ssnprintf(buffer + offset, buffer_len - offset, ":%" PRIu64, + vl->values[i].absolute); } if ((status < 1) || (status >= (buffer_len - offset))) @@ -119,21 +110,19 @@ static int value_list_to_string (char *buffer, int buffer_len, return (0); } /* int value_list_to_string */ -static int value_list_to_filename (char *buffer, size_t buffer_size, - value_list_t const *vl) -{ +static int value_list_to_filename(char *buffer, size_t buffer_size, + value_list_t const *vl) { char const suffix[] = ".rrd"; int status; size_t len; - if (datadir != NULL) - { - size_t datadir_len = strlen (datadir) + 1; + if (datadir != NULL) { + size_t datadir_len = strlen(datadir) + 1; if (datadir_len >= buffer_size) return (ENOMEM); - sstrncpy (buffer, datadir, buffer_size); + sstrncpy(buffer, datadir, buffer_size); buffer[datadir_len - 1] = '/'; buffer[datadir_len] = 0; @@ -141,28 +130,27 @@ static int value_list_to_filename (char *buffer, size_t buffer_size, buffer_size -= datadir_len; } - status = FORMAT_VL (buffer, buffer_size, vl); + status = FORMAT_VL(buffer, buffer_size, vl); if (status != 0) return (status); - len = strlen (buffer); - assert (len < buffer_size); + len = strlen(buffer); + assert(len < buffer_size); buffer += len; buffer_size -= len; - if (buffer_size <= sizeof (suffix)) + if (buffer_size <= sizeof(suffix)) return (ENOMEM); - memcpy (buffer, suffix, sizeof (suffix)); + memcpy(buffer, suffix, sizeof(suffix)); return (0); } /* int value_list_to_filename */ -static int rc_config_get_int_positive (oconfig_item_t const *ci, int *ret) -{ +static int rc_config_get_int_positive(oconfig_item_t const *ci, int *ret) { int status; int tmp = 0; - status = cf_util_get_int (ci, &tmp); + status = cf_util_get_int(ci, &tmp); if (status != 0) return (status); if (tmp < 0) @@ -172,39 +160,37 @@ static int rc_config_get_int_positive (oconfig_item_t const *ci, int *ret) return (0); } /* int rc_config_get_int_positive */ -static int rc_config_get_xff (oconfig_item_t const *ci, double *ret) -{ +static int rc_config_get_xff(oconfig_item_t const *ci, double *ret) { double value; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) - { - ERROR ("rrdcached plugin: The \"%s\" needs exactly one numeric argument " - "in the range [0.0, 1.0)", ci->key); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) { + ERROR("rrdcached plugin: The \"%s\" needs exactly one numeric argument " + "in the range [0.0, 1.0)", + ci->key); return (EINVAL); } value = ci->values[0].value.number; - if ((value >= 0.0) && (value < 1.0)) - { + if ((value >= 0.0) && (value < 1.0)) { *ret = value; return (0); } - ERROR ("rrdcached plugin: The \"%s\" needs exactly one numeric argument " - "in the range [0.0, 1.0)", ci->key); + ERROR("rrdcached plugin: The \"%s\" needs exactly one numeric argument " + "in the range [0.0, 1.0)", + ci->key); return (EINVAL); } /* int rc_config_get_xff */ -static int rc_config_add_timespan (int timespan) -{ +static int rc_config_add_timespan(int timespan) { int *tmp; if (timespan <= 0) return (EINVAL); - tmp = realloc (rrdcreate_config.timespans, - sizeof (*rrdcreate_config.timespans) - * (rrdcreate_config.timespans_num + 1)); + tmp = realloc(rrdcreate_config.timespans, + sizeof(*rrdcreate_config.timespans) * + (rrdcreate_config.timespans_num + 1)); if (tmp == NULL) return (ENOMEM); rrdcreate_config.timespans = tmp; @@ -215,106 +201,93 @@ static int rc_config_add_timespan (int timespan) return (0); } /* int rc_config_add_timespan */ -static int rc_config (oconfig_item_t *ci) -{ - for (int i = 0; i < ci->children_num; i++) - { +static int rc_config(oconfig_item_t *ci) { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t const *child = ci->children + i; const char *key = child->key; int status = 0; - if (strcasecmp ("DataDir", key) == 0) - { - status = cf_util_get_string (child, &datadir); - if (status == 0) - { - int len = strlen (datadir); + if (strcasecmp("DataDir", key) == 0) { + status = cf_util_get_string(child, &datadir); + if (status == 0) { + int len = strlen(datadir); - while ((len > 0) && (datadir[len - 1] == '/')) - { + while ((len > 0) && (datadir[len - 1] == '/')) { len--; datadir[len] = 0; } if (len <= 0) - sfree (datadir); + sfree(datadir); } - } - else if (strcasecmp ("DaemonAddress", key) == 0) - status = cf_util_get_string (child, &daemon_address); - else if (strcasecmp ("CreateFiles", key) == 0) - status = cf_util_get_boolean (child, &config_create_files); - else if (strcasecmp ("CreateFilesAsync", key) == 0) - status = cf_util_get_boolean (child, &rrdcreate_config.async); - else if (strcasecmp ("CollectStatistics", key) == 0) - status = cf_util_get_boolean (child, &config_collect_stats); - else if (strcasecmp ("StepSize", key) == 0) - { + } else if (strcasecmp("DaemonAddress", key) == 0) + status = cf_util_get_string(child, &daemon_address); + else if (strcasecmp("CreateFiles", key) == 0) + status = cf_util_get_boolean(child, &config_create_files); + else if (strcasecmp("CreateFilesAsync", key) == 0) + status = cf_util_get_boolean(child, &rrdcreate_config.async); + else if (strcasecmp("CollectStatistics", key) == 0) + status = cf_util_get_boolean(child, &config_collect_stats); + else if (strcasecmp("StepSize", key) == 0) { int tmp = -1; - status = rc_config_get_int_positive (child, &tmp); + status = rc_config_get_int_positive(child, &tmp); if (status == 0) - rrdcreate_config.stepsize = (unsigned long) tmp; - } - else if (strcasecmp ("HeartBeat", key) == 0) - status = rc_config_get_int_positive (child, &rrdcreate_config.heartbeat); - else if (strcasecmp ("RRARows", key) == 0) - status = rc_config_get_int_positive (child, &rrdcreate_config.rrarows); - else if (strcasecmp ("RRATimespan", key) == 0) - { + rrdcreate_config.stepsize = (unsigned long)tmp; + } else if (strcasecmp("HeartBeat", key) == 0) + status = rc_config_get_int_positive(child, &rrdcreate_config.heartbeat); + else if (strcasecmp("RRARows", key) == 0) + status = rc_config_get_int_positive(child, &rrdcreate_config.rrarows); + else if (strcasecmp("RRATimespan", key) == 0) { int tmp = -1; - status = rc_config_get_int_positive (child, &tmp); + status = rc_config_get_int_positive(child, &tmp); if (status == 0) - status = rc_config_add_timespan (tmp); - } - else if (strcasecmp ("XFF", key) == 0) - status = rc_config_get_xff (child, &rrdcreate_config.xff); - else - { - WARNING ("rrdcached plugin: Ignoring invalid option %s.", key); + status = rc_config_add_timespan(tmp); + } else if (strcasecmp("XFF", key) == 0) + status = rc_config_get_xff(child, &rrdcreate_config.xff); + else { + WARNING("rrdcached plugin: Ignoring invalid option %s.", key); continue; } if (status != 0) - WARNING ("rrdcached plugin: Handling the \"%s\" option failed.", key); + WARNING("rrdcached plugin: Handling the \"%s\" option failed.", key); } - if (daemon_address != NULL) - { - plugin_register_write ("rrdcached", rc_write, /* user_data = */ NULL); - plugin_register_flush ("rrdcached", rc_flush, /* user_data = */ NULL); + if (daemon_address != NULL) { + plugin_register_write("rrdcached", rc_write, /* user_data = */ NULL); + plugin_register_flush("rrdcached", rc_flush, /* user_data = */ NULL); } return (0); } /* int rc_config */ -static int try_reconnect (void) -{ +static int try_reconnect(void) { int status; - rrdc_disconnect (); + rrdc_disconnect(); - rrd_clear_error (); - status = rrdc_connect (daemon_address); - if (status != 0) - { - ERROR ("rrdcached plugin: Failed to reconnect to RRDCacheD " - "at %s: %s (status=%d)", daemon_address, rrd_get_error (), status); + rrd_clear_error(); + status = rrdc_connect(daemon_address); + if (status != 0) { + ERROR("rrdcached plugin: Failed to reconnect to RRDCacheD " + "at %s: %s (status=%d)", + daemon_address, rrd_get_error(), status); return (-1); } - INFO ("rrdcached plugin: Successfully reconnected to RRDCacheD " - "at %s", daemon_address); + INFO("rrdcached plugin: Successfully reconnected to RRDCacheD " + "at %s", + daemon_address); return (0); } /* int try_reconnect */ -static int rc_read (void) -{ +static int rc_read(void) { int status; rrdc_stats_t *head; _Bool retried = 0; value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = NAN }; + vl.values = &(value_t){.gauge = NAN}; vl.values_len = 1; if (daemon_address == NULL) @@ -323,222 +296,184 @@ static int rc_read (void) if (!config_collect_stats) return (-1); - if ((strncmp ("unix:", daemon_address, strlen ("unix:")) != 0) - && (daemon_address[0] != '/')) - sstrncpy (vl.host, daemon_address, sizeof (vl.host)); - sstrncpy (vl.plugin, "rrdcached", sizeof (vl.plugin)); - - rrd_clear_error (); - status = rrdc_connect (daemon_address); - if (status != 0) - { - ERROR ("rrdcached plugin: Failed to connect to RRDCacheD " - "at %s: %s (status=%d)", daemon_address, rrd_get_error (), status); + if ((strncmp("unix:", daemon_address, strlen("unix:")) != 0) && + (daemon_address[0] != '/')) + sstrncpy(vl.host, daemon_address, sizeof(vl.host)); + sstrncpy(vl.plugin, "rrdcached", sizeof(vl.plugin)); + + rrd_clear_error(); + status = rrdc_connect(daemon_address); + if (status != 0) { + ERROR("rrdcached plugin: Failed to connect to RRDCacheD " + "at %s: %s (status=%d)", + daemon_address, rrd_get_error(), status); return (-1); } - while (42) - { + while (42) { /* The RRD client lib does not provide any means for checking a * connection, hence we'll have to retry upon failed operations. */ head = NULL; - rrd_clear_error (); - status = rrdc_stats_get (&head); + rrd_clear_error(); + status = rrdc_stats_get(&head); if (status == 0) break; - if (!retried) - { + if (!retried) { retried = 1; - if (try_reconnect () == 0) + if (try_reconnect() == 0) continue; /* else: report the error and fail */ } - ERROR ("rrdcached plugin: rrdc_stats_get failed: %s (status=%i).", - rrd_get_error (), status); + ERROR("rrdcached plugin: rrdc_stats_get failed: %s (status=%i).", + rrd_get_error(), status); return (-1); } - for (rrdc_stats_t *ptr = head; ptr != NULL; ptr = ptr->next) - { + for (rrdc_stats_t *ptr = head; ptr != NULL; ptr = ptr->next) { if (ptr->type == RRDC_STATS_TYPE_GAUGE) - vl.values[0].gauge = (gauge_t) ptr->value.gauge; + vl.values[0].gauge = (gauge_t)ptr->value.gauge; else if (ptr->type == RRDC_STATS_TYPE_COUNTER) - vl.values[0].counter = (counter_t) ptr->value.counter; + vl.values[0].counter = (counter_t)ptr->value.counter; else continue; - if (strcasecmp ("QueueLength", ptr->name) == 0) - { - sstrncpy (vl.type, "queue_length", sizeof (vl.type)); - sstrncpy (vl.type_instance, "", sizeof (vl.type_instance)); - } - else if (strcasecmp ("UpdatesWritten", ptr->name) == 0) - { - sstrncpy (vl.type, "operations", sizeof (vl.type)); - sstrncpy (vl.type_instance, "write-updates", sizeof (vl.type_instance)); - } - else if (strcasecmp ("DataSetsWritten", ptr->name) == 0) - { - sstrncpy (vl.type, "operations", sizeof (vl.type)); - sstrncpy (vl.type_instance, "write-data_sets", - sizeof (vl.type_instance)); - } - else if (strcasecmp ("TreeNodesNumber", ptr->name) == 0) - { - sstrncpy (vl.type, "gauge", sizeof (vl.type)); - sstrncpy (vl.type_instance, "tree_nodes", sizeof (vl.type_instance)); - } - else if (strcasecmp ("TreeDepth", ptr->name) == 0) - { - sstrncpy (vl.type, "gauge", sizeof (vl.type)); - sstrncpy (vl.type_instance, "tree_depth", sizeof (vl.type_instance)); - } - else if (strcasecmp ("FlushesReceived", ptr->name) == 0) - { - sstrncpy (vl.type, "operations", sizeof (vl.type)); - sstrncpy (vl.type_instance, "receive-flush", sizeof (vl.type_instance)); - } - else if (strcasecmp ("JournalBytes", ptr->name) == 0) - { - sstrncpy (vl.type, "counter", sizeof (vl.type)); - sstrncpy (vl.type_instance, "journal-bytes", sizeof (vl.type_instance)); - } - else if (strcasecmp ("JournalRotate", ptr->name) == 0) - { - sstrncpy (vl.type, "counter", sizeof (vl.type)); - sstrncpy (vl.type_instance, "journal-rotates", sizeof (vl.type_instance)); - } - else if (strcasecmp ("UpdatesReceived", ptr->name) == 0) - { - sstrncpy (vl.type, "operations", sizeof (vl.type)); - sstrncpy (vl.type_instance, "receive-update", sizeof (vl.type_instance)); - } - else - { - DEBUG ("rrdcached plugin: rc_read: Unknown statistic `%s'.", ptr->name); + if (strcasecmp("QueueLength", ptr->name) == 0) { + sstrncpy(vl.type, "queue_length", sizeof(vl.type)); + sstrncpy(vl.type_instance, "", sizeof(vl.type_instance)); + } else if (strcasecmp("UpdatesWritten", ptr->name) == 0) { + sstrncpy(vl.type, "operations", sizeof(vl.type)); + sstrncpy(vl.type_instance, "write-updates", sizeof(vl.type_instance)); + } else if (strcasecmp("DataSetsWritten", ptr->name) == 0) { + sstrncpy(vl.type, "operations", sizeof(vl.type)); + sstrncpy(vl.type_instance, "write-data_sets", sizeof(vl.type_instance)); + } else if (strcasecmp("TreeNodesNumber", ptr->name) == 0) { + sstrncpy(vl.type, "gauge", sizeof(vl.type)); + sstrncpy(vl.type_instance, "tree_nodes", sizeof(vl.type_instance)); + } else if (strcasecmp("TreeDepth", ptr->name) == 0) { + sstrncpy(vl.type, "gauge", sizeof(vl.type)); + sstrncpy(vl.type_instance, "tree_depth", sizeof(vl.type_instance)); + } else if (strcasecmp("FlushesReceived", ptr->name) == 0) { + sstrncpy(vl.type, "operations", sizeof(vl.type)); + sstrncpy(vl.type_instance, "receive-flush", sizeof(vl.type_instance)); + } else if (strcasecmp("JournalBytes", ptr->name) == 0) { + sstrncpy(vl.type, "counter", sizeof(vl.type)); + sstrncpy(vl.type_instance, "journal-bytes", sizeof(vl.type_instance)); + } else if (strcasecmp("JournalRotate", ptr->name) == 0) { + sstrncpy(vl.type, "counter", sizeof(vl.type)); + sstrncpy(vl.type_instance, "journal-rotates", sizeof(vl.type_instance)); + } else if (strcasecmp("UpdatesReceived", ptr->name) == 0) { + sstrncpy(vl.type, "operations", sizeof(vl.type)); + sstrncpy(vl.type_instance, "receive-update", sizeof(vl.type_instance)); + } else { + DEBUG("rrdcached plugin: rc_read: Unknown statistic `%s'.", ptr->name); continue; } - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* for (ptr = head; ptr != NULL; ptr = ptr->next) */ - rrdc_stats_free (head); + rrdc_stats_free(head); return (0); } /* int rc_read */ -static int rc_init (void) -{ +static int rc_init(void) { if (config_collect_stats) - plugin_register_read ("rrdcached", rc_read); + plugin_register_read("rrdcached", rc_read); return (0); } /* int rc_init */ -static int rc_write (const data_set_t *ds, const value_list_t *vl, - user_data_t __attribute__((unused)) *user_data) -{ +static int rc_write(const data_set_t *ds, const value_list_t *vl, + user_data_t __attribute__((unused)) * user_data) { char filename[PATH_MAX]; char values[512]; char *values_array[2]; int status; _Bool retried = 0; - if (daemon_address == NULL) - { - ERROR ("rrdcached plugin: daemon_address == NULL."); - plugin_unregister_write ("rrdcached"); + if (daemon_address == NULL) { + ERROR("rrdcached plugin: daemon_address == NULL."); + plugin_unregister_write("rrdcached"); return (-1); } - if (strcmp (ds->type, vl->type) != 0) - { - ERROR ("rrdcached plugin: DS type does not match value list type"); + if (strcmp(ds->type, vl->type) != 0) { + ERROR("rrdcached plugin: DS type does not match value list type"); return (-1); } - if (value_list_to_filename (filename, sizeof (filename), vl) != 0) - { - ERROR ("rrdcached plugin: value_list_to_filename failed."); + if (value_list_to_filename(filename, sizeof(filename), vl) != 0) { + ERROR("rrdcached plugin: value_list_to_filename failed."); return (-1); } - if (value_list_to_string (values, sizeof (values), ds, vl) != 0) - { - ERROR ("rrdcached plugin: value_list_to_string failed."); + if (value_list_to_string(values, sizeof(values), ds, vl) != 0) { + ERROR("rrdcached plugin: value_list_to_string failed."); return (-1); } values_array[0] = values; values_array[1] = NULL; - if (config_create_files) - { + if (config_create_files) { struct stat statbuf; - status = stat (filename, &statbuf); - if (status != 0) - { - if (errno != ENOENT) - { + status = stat(filename, &statbuf); + if (status != 0) { + if (errno != ENOENT) { char errbuf[1024]; - ERROR ("rrdcached plugin: stat (%s) failed: %s", - filename, sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("rrdcached plugin: stat (%s) failed: %s", filename, + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } - status = cu_rrd_create_file (filename, ds, vl, &rrdcreate_config); - if (status != 0) - { - ERROR ("rrdcached plugin: cu_rrd_create_file (%s) failed.", - filename); + status = cu_rrd_create_file(filename, ds, vl, &rrdcreate_config); + if (status != 0) { + ERROR("rrdcached plugin: cu_rrd_create_file (%s) failed.", filename); return (-1); - } - else if (rrdcreate_config.async) + } else if (rrdcreate_config.async) return (0); } } - rrd_clear_error (); - status = rrdc_connect (daemon_address); - if (status != 0) - { - ERROR ("rrdcached plugin: Failed to connect to RRDCacheD " - "at %s: %s (status=%d)", daemon_address, rrd_get_error (), status); + rrd_clear_error(); + status = rrdc_connect(daemon_address); + if (status != 0) { + ERROR("rrdcached plugin: Failed to connect to RRDCacheD " + "at %s: %s (status=%d)", + daemon_address, rrd_get_error(), status); return (-1); } - while (42) - { + while (42) { /* The RRD client lib does not provide any means for checking a * connection, hence we'll have to retry upon failed operations. */ - rrd_clear_error (); - status = rrdc_update (filename, /* values_num = */ 1, (void *) values_array); + rrd_clear_error(); + status = rrdc_update(filename, /* values_num = */ 1, (void *)values_array); if (status == 0) break; - if (!retried) - { + if (!retried) { retried = 1; - if (try_reconnect () == 0) + if (try_reconnect() == 0) continue; /* else: report the error and fail */ } - ERROR ("rrdcached plugin: rrdc_update (%s, [%s], 1) failed: %s (status=%i)", - filename, values_array[0], rrd_get_error (), status); + ERROR("rrdcached plugin: rrdc_update (%s, [%s], 1) failed: %s (status=%i)", + filename, values_array[0], rrd_get_error(), status); return (-1); } return (0); } /* int rc_write */ -static int rc_flush (__attribute__((unused)) cdtime_t timeout, /* {{{ */ - const char *identifier, - __attribute__((unused)) user_data_t *ud) -{ +static int rc_flush(__attribute__((unused)) cdtime_t timeout, /* {{{ */ + const char *identifier, + __attribute__((unused)) user_data_t *ud) { char filename[PATH_MAX + 1]; int status; _Bool retried = 0; @@ -547,56 +482,52 @@ static int rc_flush (__attribute__((unused)) cdtime_t timeout, /* {{{ */ return (EINVAL); if (datadir != NULL) - ssnprintf (filename, sizeof (filename), "%s/%s.rrd", datadir, identifier); + ssnprintf(filename, sizeof(filename), "%s/%s.rrd", datadir, identifier); else - ssnprintf (filename, sizeof (filename), "%s.rrd", identifier); - - rrd_clear_error (); - status = rrdc_connect (daemon_address); - if (status != 0) - { - ERROR ("rrdcached plugin: Failed to connect to RRDCacheD " - "at %s: %s (status=%d)", daemon_address, rrd_get_error (), status); + ssnprintf(filename, sizeof(filename), "%s.rrd", identifier); + + rrd_clear_error(); + status = rrdc_connect(daemon_address); + if (status != 0) { + ERROR("rrdcached plugin: Failed to connect to RRDCacheD " + "at %s: %s (status=%d)", + daemon_address, rrd_get_error(), status); return (-1); } - while (42) - { + while (42) { /* The RRD client lib does not provide any means for checking a * connection, hence we'll have to retry upon failed operations. */ - rrd_clear_error (); - status = rrdc_flush (filename); + rrd_clear_error(); + status = rrdc_flush(filename); if (status == 0) break; - if (!retried) - { + if (!retried) { retried = 1; - if (try_reconnect () == 0) + if (try_reconnect() == 0) continue; /* else: report the error and fail */ } - ERROR ("rrdcached plugin: rrdc_flush (%s) failed: %s (status=%i).", - filename, rrd_get_error (), status); + ERROR("rrdcached plugin: rrdc_flush (%s) failed: %s (status=%i).", filename, + rrd_get_error(), status); return (-1); } - DEBUG ("rrdcached plugin: rrdc_flush (%s): Success.", filename); + DEBUG("rrdcached plugin: rrdc_flush (%s): Success.", filename); return (0); } /* }}} int rc_flush */ -static int rc_shutdown (void) -{ - rrdc_disconnect (); +static int rc_shutdown(void) { + rrdc_disconnect(); return (0); } /* int rc_shutdown */ -void module_register (void) -{ - plugin_register_complex_config ("rrdcached", rc_config); - plugin_register_init ("rrdcached", rc_init); - plugin_register_shutdown ("rrdcached", rc_shutdown); +void module_register(void) { + plugin_register_complex_config("rrdcached", rc_config); + plugin_register_init("rrdcached", rc_init); + plugin_register_shutdown("rrdcached", rc_shutdown); } /* void module_register */ /* diff --git a/src/rrdtool.c b/src/rrdtool.c index 3d5ad9b9..e29d637d 100644 --- a/src/rrdtool.c +++ b/src/rrdtool.c @@ -25,8 +25,8 @@ #include "collectd.h" -#include "plugin.h" #include "common.h" +#include "plugin.h" #include "utils_avltree.h" #include "utils_random.h" #include "utils_rrdcreate.h" @@ -36,93 +36,70 @@ /* * Private types */ -struct rrd_cache_s -{ - int values_num; - char **values; - cdtime_t first_value; - cdtime_t last_value; - int64_t random_variation; - enum - { - FLAG_NONE = 0x00, - FLAG_QUEUED = 0x01, - FLAG_FLUSHQ = 0x02 - } flags; +struct rrd_cache_s { + int values_num; + char **values; + cdtime_t first_value; + cdtime_t last_value; + int64_t random_variation; + enum { FLAG_NONE = 0x00, FLAG_QUEUED = 0x01, FLAG_FLUSHQ = 0x02 } flags; }; typedef struct rrd_cache_s rrd_cache_t; -enum rrd_queue_dir_e -{ - QUEUE_INSERT_FRONT, - QUEUE_INSERT_BACK -}; +enum rrd_queue_dir_e { QUEUE_INSERT_FRONT, QUEUE_INSERT_BACK }; typedef enum rrd_queue_dir_e rrd_queue_dir_t; -struct rrd_queue_s -{ - char *filename; - struct rrd_queue_s *next; +struct rrd_queue_s { + char *filename; + struct rrd_queue_s *next; }; typedef struct rrd_queue_s rrd_queue_t; /* * Private variables */ -static const char *config_keys[] = -{ - "CacheTimeout", - "CacheFlush", - "CreateFilesAsync", - "DataDir", - "StepSize", - "HeartBeat", - "RRARows", - "RRATimespan", - "XFF", - "WritesPerSecond", - "RandomTimeout" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = { + "CacheTimeout", "CacheFlush", "CreateFilesAsync", "DataDir", + "StepSize", "HeartBeat", "RRARows", "RRATimespan", + "XFF", "WritesPerSecond", "RandomTimeout"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); /* If datadir is zero, the daemon's basedir is used. If stepsize or heartbeat * is zero a default, depending on the `interval' member of the value list is * being used. */ -static char *datadir = NULL; +static char *datadir = NULL; static double write_rate = 0.0; -static rrdcreate_config_t rrdcreate_config = -{ - /* stepsize = */ 0, - /* heartbeat = */ 0, - /* rrarows = */ 1200, - /* xff = */ 0.1, +static rrdcreate_config_t rrdcreate_config = { + /* stepsize = */ 0, + /* heartbeat = */ 0, + /* rrarows = */ 1200, + /* xff = */ 0.1, - /* timespans = */ NULL, - /* timespans_num = */ 0, + /* timespans = */ NULL, + /* timespans_num = */ 0, - /* consolidation_functions = */ NULL, - /* consolidation_functions_num = */ 0, + /* consolidation_functions = */ NULL, + /* consolidation_functions_num = */ 0, - /* async = */ 0 -}; + /* async = */ 0}; /* XXX: If you need to lock both, cache_lock and queue_lock, at the same time, * ALWAYS lock `cache_lock' first! */ -static cdtime_t cache_timeout = 0; -static cdtime_t cache_flush_timeout = 0; -static cdtime_t random_timeout = TIME_T_TO_CDTIME_T_STATIC (1); -static cdtime_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_STATIC(1); +static cdtime_t cache_flush_last; static c_avl_tree_t *cache = NULL; static pthread_mutex_t cache_lock = PTHREAD_MUTEX_INITIALIZER; -static rrd_queue_t *queue_head = NULL; -static rrd_queue_t *queue_tail = NULL; -static rrd_queue_t *flushq_head = NULL; -static rrd_queue_t *flushq_tail = NULL; -static pthread_t queue_thread; -static int queue_thread_running = 1; +static rrd_queue_t *queue_head = NULL; +static rrd_queue_t *queue_tail = NULL; +static rrd_queue_t *flushq_head = NULL; +static rrd_queue_t *flushq_tail = NULL; +static pthread_t queue_thread; +static int queue_thread_running = 1; static pthread_mutex_t queue_lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t queue_cond = PTHREAD_COND_INITIALIZER; +static pthread_cond_t queue_cond = PTHREAD_COND_INITIALIZER; #if !HAVE_THREADSAFE_LIBRRD static pthread_mutex_t librrd_lock = PTHREAD_MUTEX_INITIALIZER; @@ -131,364 +108,336 @@ static pthread_mutex_t librrd_lock = PTHREAD_MUTEX_INITIALIZER; static int do_shutdown = 0; #if HAVE_THREADSAFE_LIBRRD -static int srrd_update (char *filename, char *template, - int argc, const char **argv) -{ - int status; +static int srrd_update(char *filename, char *template, int argc, + const char **argv) { + int status; - optind = 0; /* bug in librrd? */ - rrd_clear_error (); + optind = 0; /* bug in librrd? */ + rrd_clear_error(); - status = rrd_update_r (filename, template, argc, (void *) argv); + status = rrd_update_r(filename, template, argc, (void *)argv); - if (status != 0) - { - WARNING ("rrdtool plugin: rrd_update_r (%s) failed: %s", - filename, rrd_get_error ()); - } + if (status != 0) { + WARNING("rrdtool plugin: rrd_update_r (%s) failed: %s", filename, + rrd_get_error()); + } - return (status); + return (status); } /* int srrd_update */ /* #endif HAVE_THREADSAFE_LIBRRD */ -#else /* !HAVE_THREADSAFE_LIBRRD */ -static int srrd_update (char *filename, char *template, - int argc, const char **argv) -{ - int status; +#else /* !HAVE_THREADSAFE_LIBRRD */ +static int srrd_update(char *filename, char *template, int argc, + const char **argv) { + int status; - int new_argc; - char **new_argv; + int new_argc; + char **new_argv; - assert (template == NULL); + assert(template == NULL); - new_argc = 2 + argc; - new_argv = malloc ((new_argc + 1) * sizeof (*new_argv)); - if (new_argv == NULL) - { - ERROR ("rrdtool plugin: malloc failed."); - return (-1); - } + new_argc = 2 + argc; + new_argv = malloc((new_argc + 1) * sizeof(*new_argv)); + if (new_argv == NULL) { + ERROR("rrdtool plugin: malloc failed."); + return (-1); + } - new_argv[0] = "update"; - new_argv[1] = filename; + new_argv[0] = "update"; + new_argv[1] = filename; - memcpy (new_argv + 2, argv, argc * sizeof (char *)); - new_argv[new_argc] = NULL; + memcpy(new_argv + 2, argv, argc * sizeof(char *)); + new_argv[new_argc] = NULL; - pthread_mutex_lock (&librrd_lock); - optind = 0; /* bug in librrd? */ - rrd_clear_error (); + pthread_mutex_lock(&librrd_lock); + optind = 0; /* bug in librrd? */ + rrd_clear_error(); - status = rrd_update (new_argc, new_argv); - pthread_mutex_unlock (&librrd_lock); + status = rrd_update(new_argc, new_argv); + pthread_mutex_unlock(&librrd_lock); - if (status != 0) - { - WARNING ("rrdtool plugin: rrd_update_r failed: %s: %s", - filename, rrd_get_error ()); - } + if (status != 0) { + WARNING("rrdtool plugin: rrd_update_r failed: %s: %s", filename, + rrd_get_error()); + } - sfree (new_argv); + sfree(new_argv); - return (status); + return (status); } /* int srrd_update */ #endif /* !HAVE_THREADSAFE_LIBRRD */ -static int value_list_to_string_multiple (char *buffer, int buffer_len, - const data_set_t *ds, const value_list_t *vl) -{ - int offset; - int status; - time_t tt; - - memset (buffer, '\0', buffer_len); - - 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; - - for (size_t i = 0; i < ds->ds_num; i++) - { - if ((ds->ds[i].type != DS_TYPE_COUNTER) - && (ds->ds[i].type != DS_TYPE_GAUGE) - && (ds->ds[i].type != DS_TYPE_DERIVE) - && (ds->ds[i].type != DS_TYPE_ABSOLUTE)) - return (-1); - - if (ds->ds[i].type == DS_TYPE_COUNTER) - status = ssnprintf (buffer + offset, buffer_len - offset, - ":%llu", vl->values[i].counter); - else if (ds->ds[i].type == DS_TYPE_GAUGE) - status = ssnprintf (buffer + offset, buffer_len - offset, - ":"GAUGE_FORMAT, vl->values[i].gauge); - else if (ds->ds[i].type == DS_TYPE_DERIVE) - status = ssnprintf (buffer + offset, buffer_len - offset, - ":%"PRIi64, vl->values[i].derive); - else /*if (ds->ds[i].type == DS_TYPE_ABSOLUTE) */ - status = ssnprintf (buffer + offset, buffer_len - offset, - ":%"PRIu64, vl->values[i].absolute); - - if ((status < 1) || (status >= (buffer_len - offset))) - return (-1); - - offset += status; - } /* for ds->ds_num */ - - return (0); +static int value_list_to_string_multiple(char *buffer, int buffer_len, + const data_set_t *ds, + const value_list_t *vl) { + int offset; + int status; + time_t tt; + + memset(buffer, '\0', buffer_len); + + 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; + + for (size_t i = 0; i < ds->ds_num; i++) { + if ((ds->ds[i].type != DS_TYPE_COUNTER) && + (ds->ds[i].type != DS_TYPE_GAUGE) && + (ds->ds[i].type != DS_TYPE_DERIVE) && + (ds->ds[i].type != DS_TYPE_ABSOLUTE)) + return (-1); + + if (ds->ds[i].type == DS_TYPE_COUNTER) + status = ssnprintf(buffer + offset, buffer_len - offset, ":%llu", + vl->values[i].counter); + else if (ds->ds[i].type == DS_TYPE_GAUGE) + status = ssnprintf(buffer + offset, buffer_len - offset, ":" GAUGE_FORMAT, + vl->values[i].gauge); + else if (ds->ds[i].type == DS_TYPE_DERIVE) + status = ssnprintf(buffer + offset, buffer_len - offset, ":%" PRIi64, + vl->values[i].derive); + else /*if (ds->ds[i].type == DS_TYPE_ABSOLUTE) */ + status = ssnprintf(buffer + offset, buffer_len - offset, ":%" PRIu64, + vl->values[i].absolute); + + if ((status < 1) || (status >= (buffer_len - offset))) + return (-1); + + offset += status; + } /* for ds->ds_num */ + + return (0); } /* int value_list_to_string_multiple */ -static int value_list_to_string (char *buffer, int buffer_len, - const data_set_t *ds, const value_list_t *vl) -{ - int status; - time_t tt; - - if (ds->ds_num != 1) - return (value_list_to_string_multiple (buffer, buffer_len, - ds, vl)); - - tt = CDTIME_T_TO_TIME_T (vl->time); - switch (ds->ds[0].type) - { - case DS_TYPE_DERIVE: - status = ssnprintf (buffer, buffer_len, "%u:%"PRIi64, - (unsigned) tt, vl->values[0].derive); - break; - case DS_TYPE_GAUGE: - status = ssnprintf (buffer, buffer_len, "%u:"GAUGE_FORMAT, - (unsigned) tt, vl->values[0].gauge); - break; - case DS_TYPE_COUNTER: - status = ssnprintf (buffer, buffer_len, "%u:%llu", - (unsigned) tt, vl->values[0].counter); - break; - case DS_TYPE_ABSOLUTE: - status = ssnprintf (buffer, buffer_len, "%u:%"PRIu64, - (unsigned) tt, vl->values[0].absolute); - break; - default: - return (EINVAL); - } - - if ((status < 1) || (status >= buffer_len)) - return (ENOMEM); - - return (0); +static int value_list_to_string(char *buffer, int buffer_len, + const data_set_t *ds, const value_list_t *vl) { + int status; + time_t tt; + + if (ds->ds_num != 1) + return (value_list_to_string_multiple(buffer, buffer_len, ds, vl)); + + tt = CDTIME_T_TO_TIME_T(vl->time); + switch (ds->ds[0].type) { + case DS_TYPE_DERIVE: + status = ssnprintf(buffer, buffer_len, "%u:%" PRIi64, (unsigned)tt, + vl->values[0].derive); + break; + case DS_TYPE_GAUGE: + status = ssnprintf(buffer, buffer_len, "%u:" GAUGE_FORMAT, (unsigned)tt, + vl->values[0].gauge); + break; + case DS_TYPE_COUNTER: + status = ssnprintf(buffer, buffer_len, "%u:%llu", (unsigned)tt, + vl->values[0].counter); + break; + case DS_TYPE_ABSOLUTE: + status = ssnprintf(buffer, buffer_len, "%u:%" PRIu64, (unsigned)tt, + vl->values[0].absolute); + break; + default: + return (EINVAL); + } + + if ((status < 1) || (status >= buffer_len)) + return (ENOMEM); + + return (0); } /* int value_list_to_string */ -static int value_list_to_filename (char *buffer, size_t buffer_size, - value_list_t const *vl) -{ - char const suffix[] = ".rrd"; - int status; - size_t len; +static int value_list_to_filename(char *buffer, size_t buffer_size, + value_list_t const *vl) { + char const suffix[] = ".rrd"; + int status; + size_t len; - if (datadir != NULL) - { - size_t datadir_len = strlen (datadir) + 1; + if (datadir != NULL) { + size_t datadir_len = strlen(datadir) + 1; - if (datadir_len >= buffer_size) - return (ENOMEM); + if (datadir_len >= buffer_size) + return (ENOMEM); - sstrncpy (buffer, datadir, buffer_size); - buffer[datadir_len - 1] = '/'; - buffer[datadir_len] = 0; + sstrncpy(buffer, datadir, buffer_size); + buffer[datadir_len - 1] = '/'; + buffer[datadir_len] = 0; - buffer += datadir_len; - buffer_size -= datadir_len; - } + buffer += datadir_len; + buffer_size -= datadir_len; + } - status = FORMAT_VL (buffer, buffer_size, vl); - if (status != 0) - return (status); + status = FORMAT_VL(buffer, buffer_size, vl); + if (status != 0) + return (status); - len = strlen (buffer); - assert (len < buffer_size); - buffer += len; - buffer_size -= len; + len = strlen(buffer); + assert(len < buffer_size); + buffer += len; + buffer_size -= len; - if (buffer_size <= sizeof (suffix)) - return (ENOMEM); + if (buffer_size <= sizeof(suffix)) + return (ENOMEM); - memcpy (buffer, suffix, sizeof (suffix)); - return (0); + memcpy(buffer, suffix, sizeof(suffix)); + return (0); } /* int value_list_to_filename */ -static void *rrd_queue_thread (void __attribute__((unused)) *data) -{ - struct timeval tv_next_update; - struct timeval tv_now; - - gettimeofday (&tv_next_update, /* timezone = */ NULL); - - while (42) - { - rrd_queue_t *queue_entry; - rrd_cache_t *cache_entry; - char **values; - int values_num; - int status; - - values = NULL; - values_num = 0; - - pthread_mutex_lock (&queue_lock); - /* Wait for values to arrive */ - while (42) - { - struct timespec ts_wait; - - while ((flushq_head == NULL) && (queue_head == NULL) - && (do_shutdown == 0)) - pthread_cond_wait (&queue_cond, &queue_lock); - - if ((flushq_head == NULL) && (queue_head == NULL)) - break; - - /* Don't delay if there's something to flush */ - if (flushq_head != NULL) - break; - - /* Don't delay if we're shutting down */ - if (do_shutdown != 0) - break; - - /* Don't delay if no delay was configured. */ - if (write_rate <= 0.0) - break; - - gettimeofday (&tv_now, /* timezone = */ NULL); - status = timeval_cmp (tv_next_update, tv_now, NULL); - /* We're good to go */ - if (status <= 0) - break; - - /* We're supposed to wait a bit with this update, so we'll - * wait for the next addition to the queue or to the end of - * the wait period - whichever comes first. */ - ts_wait.tv_sec = tv_next_update.tv_sec; - ts_wait.tv_nsec = 1000 * tv_next_update.tv_usec; - - status = pthread_cond_timedwait (&queue_cond, &queue_lock, - &ts_wait); - if (status == ETIMEDOUT) - break; - } /* while (42) */ - - /* XXX: If you need to lock both, cache_lock and queue_lock, at - * the same time, ALWAYS lock `cache_lock' first! */ - - /* We're in the shutdown phase */ - if ((flushq_head == NULL) && (queue_head == NULL)) - { - pthread_mutex_unlock (&queue_lock); - break; - } - - if (flushq_head != NULL) - { - /* Dequeue the first flush entry */ - queue_entry = flushq_head; - if (flushq_head == flushq_tail) - flushq_head = flushq_tail = NULL; - else - flushq_head = flushq_head->next; - } - else /* if (queue_head != NULL) */ - { - /* Dequeue the first regular entry */ - queue_entry = queue_head; - if (queue_head == queue_tail) - queue_head = queue_tail = NULL; - else - queue_head = queue_head->next; - } - - /* Unlock the queue again */ - pthread_mutex_unlock (&queue_lock); - - /* We now need the cache lock so the entry isn't updated while - * we make a copy of its values */ - pthread_mutex_lock (&cache_lock); - - status = c_avl_get (cache, queue_entry->filename, - (void *) &cache_entry); - - if (status == 0) - { - values = cache_entry->values; - values_num = cache_entry->values_num; - - cache_entry->values = NULL; - cache_entry->values_num = 0; - cache_entry->flags = FLAG_NONE; - } - - pthread_mutex_unlock (&cache_lock); - - if (status != 0) - { - sfree (queue_entry->filename); - sfree (queue_entry); - continue; - } - - /* Update `tv_next_update' */ - if (write_rate > 0.0) - { - gettimeofday (&tv_now, /* timezone = */ NULL); - tv_next_update.tv_sec = tv_now.tv_sec; - tv_next_update.tv_usec = tv_now.tv_usec - + ((suseconds_t) (1000000 * write_rate)); - while (tv_next_update.tv_usec > 1000000) - { - tv_next_update.tv_sec++; - tv_next_update.tv_usec -= 1000000; - } - } - - /* Write the values to the RRD-file */ - srrd_update (queue_entry->filename, NULL, - values_num, (const char **)values); - DEBUG ("rrdtool plugin: queue thread: Wrote %i value%s to %s", - values_num, (values_num == 1) ? "" : "s", - queue_entry->filename); - - for (int i = 0; i < values_num; i++) - { - sfree (values[i]); - } - sfree (values); - sfree (queue_entry->filename); - sfree (queue_entry); - } /* while (42) */ - - pthread_exit ((void *) 0); - return ((void *) 0); +static void *rrd_queue_thread(void __attribute__((unused)) * data) { + struct timeval tv_next_update; + struct timeval tv_now; + + gettimeofday(&tv_next_update, /* timezone = */ NULL); + + while (42) { + rrd_queue_t *queue_entry; + rrd_cache_t *cache_entry; + char **values; + int values_num; + int status; + + values = NULL; + values_num = 0; + + pthread_mutex_lock(&queue_lock); + /* Wait for values to arrive */ + while (42) { + struct timespec ts_wait; + + while ((flushq_head == NULL) && (queue_head == NULL) && + (do_shutdown == 0)) + pthread_cond_wait(&queue_cond, &queue_lock); + + if ((flushq_head == NULL) && (queue_head == NULL)) + break; + + /* Don't delay if there's something to flush */ + if (flushq_head != NULL) + break; + + /* Don't delay if we're shutting down */ + if (do_shutdown != 0) + break; + + /* Don't delay if no delay was configured. */ + if (write_rate <= 0.0) + break; + + gettimeofday(&tv_now, /* timezone = */ NULL); + status = timeval_cmp(tv_next_update, tv_now, NULL); + /* We're good to go */ + if (status <= 0) + break; + + /* We're supposed to wait a bit with this update, so we'll + * wait for the next addition to the queue or to the end of + * the wait period - whichever comes first. */ + ts_wait.tv_sec = tv_next_update.tv_sec; + ts_wait.tv_nsec = 1000 * tv_next_update.tv_usec; + + status = pthread_cond_timedwait(&queue_cond, &queue_lock, &ts_wait); + if (status == ETIMEDOUT) + break; + } /* while (42) */ + + /* XXX: If you need to lock both, cache_lock and queue_lock, at + * the same time, ALWAYS lock `cache_lock' first! */ + + /* We're in the shutdown phase */ + if ((flushq_head == NULL) && (queue_head == NULL)) { + pthread_mutex_unlock(&queue_lock); + break; + } + + if (flushq_head != NULL) { + /* Dequeue the first flush entry */ + queue_entry = flushq_head; + if (flushq_head == flushq_tail) + flushq_head = flushq_tail = NULL; + else + flushq_head = flushq_head->next; + } else /* if (queue_head != NULL) */ + { + /* Dequeue the first regular entry */ + queue_entry = queue_head; + if (queue_head == queue_tail) + queue_head = queue_tail = NULL; + else + queue_head = queue_head->next; + } + + /* Unlock the queue again */ + pthread_mutex_unlock(&queue_lock); + + /* We now need the cache lock so the entry isn't updated while + * we make a copy of its values */ + pthread_mutex_lock(&cache_lock); + + status = c_avl_get(cache, queue_entry->filename, (void *)&cache_entry); + + if (status == 0) { + values = cache_entry->values; + values_num = cache_entry->values_num; + + cache_entry->values = NULL; + cache_entry->values_num = 0; + cache_entry->flags = FLAG_NONE; + } + + pthread_mutex_unlock(&cache_lock); + + if (status != 0) { + sfree(queue_entry->filename); + sfree(queue_entry); + continue; + } + + /* Update `tv_next_update' */ + if (write_rate > 0.0) { + gettimeofday(&tv_now, /* timezone = */ NULL); + tv_next_update.tv_sec = tv_now.tv_sec; + tv_next_update.tv_usec = + tv_now.tv_usec + ((suseconds_t)(1000000 * write_rate)); + while (tv_next_update.tv_usec > 1000000) { + tv_next_update.tv_sec++; + tv_next_update.tv_usec -= 1000000; + } + } + + /* Write the values to the RRD-file */ + srrd_update(queue_entry->filename, NULL, values_num, (const char **)values); + DEBUG("rrdtool plugin: queue thread: Wrote %i value%s to %s", values_num, + (values_num == 1) ? "" : "s", queue_entry->filename); + + for (int i = 0; i < values_num; i++) { + sfree(values[i]); + } + sfree(values); + sfree(queue_entry->filename); + sfree(queue_entry); + } /* while (42) */ + + pthread_exit((void *)0); + return ((void *)0); } /* void *rrd_queue_thread */ -static int rrd_queue_enqueue (const char *filename, - rrd_queue_t **head, rrd_queue_t **tail) -{ +static int rrd_queue_enqueue(const char *filename, rrd_queue_t **head, + rrd_queue_t **tail) { rrd_queue_t *queue_entry; - queue_entry = malloc (sizeof (*queue_entry)); + queue_entry = malloc(sizeof(*queue_entry)); if (queue_entry == NULL) return (-1); - queue_entry->filename = strdup (filename); - if (queue_entry->filename == NULL) - { - free (queue_entry); + queue_entry->filename = strdup(filename); + if (queue_entry->filename == NULL) { + free(queue_entry); return (-1); } queue_entry->next = NULL; - pthread_mutex_lock (&queue_lock); + pthread_mutex_lock(&queue_lock); if (*tail == NULL) *head = queue_entry; @@ -496,35 +445,32 @@ static int rrd_queue_enqueue (const char *filename, (*tail)->next = queue_entry; *tail = queue_entry; - pthread_cond_signal (&queue_cond); - pthread_mutex_unlock (&queue_lock); + pthread_cond_signal(&queue_cond); + pthread_mutex_unlock(&queue_lock); return (0); } /* int rrd_queue_enqueue */ -static int rrd_queue_dequeue (const char *filename, - rrd_queue_t **head, rrd_queue_t **tail) -{ +static int rrd_queue_dequeue(const char *filename, rrd_queue_t **head, + rrd_queue_t **tail) { rrd_queue_t *this; rrd_queue_t *prev; - pthread_mutex_lock (&queue_lock); + pthread_mutex_lock(&queue_lock); prev = NULL; this = *head; - while (this != NULL) - { - if (strcmp (this->filename, filename) == 0) + while (this != NULL) { + if (strcmp(this->filename, filename) == 0) break; prev = this; this = this->next; } - if (this == NULL) - { - pthread_mutex_unlock (&queue_lock); + if (this == NULL) { + pthread_mutex_unlock(&queue_lock); return (-1); } @@ -536,144 +482,122 @@ static int rrd_queue_dequeue (const char *filename, if (this->next == NULL) *tail = prev; - pthread_mutex_unlock (&queue_lock); + pthread_mutex_unlock(&queue_lock); - sfree (this->filename); - sfree (this); + sfree(this->filename); + sfree(this); return (0); } /* int rrd_queue_dequeue */ /* XXX: You must hold "cache_lock" when calling this function! */ -static void rrd_cache_flush (cdtime_t timeout) -{ - rrd_cache_t *rc; - cdtime_t now; - - char **keys = NULL; - int keys_num = 0; - - char *key; - c_avl_iterator_t *iter; - - DEBUG ("rrdtool plugin: Flushing cache, timeout = %.3f", - CDTIME_T_TO_DOUBLE (timeout)); - - now = cdtime (); - timeout = TIME_T_TO_CDTIME_T (timeout); - - /* Build a list of entries to be flushed */ - iter = c_avl_get_iterator (cache); - while (c_avl_iterator_next (iter, (void *) &key, (void *) &rc) == 0) - { - if (rc->flags != FLAG_NONE) - continue; - /* timeout == 0 => flush everything */ - else if ((timeout != 0) - && ((now - rc->first_value) < timeout)) - continue; - else if (rc->values_num > 0) - { - int status; - - status = rrd_queue_enqueue (key, &queue_head, &queue_tail); - if (status == 0) - rc->flags = FLAG_QUEUED; - } - else /* ancient and no values -> waste of memory */ - { - char **tmp = realloc (keys, - (keys_num + 1) * sizeof (char *)); - if (tmp == NULL) - { - char errbuf[1024]; - ERROR ("rrdtool plugin: " - "realloc failed: %s", - sstrerror (errno, errbuf, - sizeof (errbuf))); - c_avl_iterator_destroy (iter); - sfree (keys); - return; - } - keys = tmp; - keys[keys_num] = key; - keys_num++; - } - } /* while (c_avl_iterator_next) */ - c_avl_iterator_destroy (iter); - - for (int i = 0; i < keys_num; i++) - { - if (c_avl_remove (cache, keys[i], (void *) &key, (void *) &rc) != 0) - { - DEBUG ("rrdtool plugin: c_avl_remove (%s) failed.", keys[i]); - continue; - } - - assert (rc->values == NULL); - assert (rc->values_num == 0); - - sfree (rc); - sfree (key); - keys[i] = NULL; - } /* for (i = 0..keys_num) */ - - sfree (keys); - - cache_flush_last = now; +static void rrd_cache_flush(cdtime_t timeout) { + rrd_cache_t *rc; + cdtime_t now; + + char **keys = NULL; + int keys_num = 0; + + char *key; + c_avl_iterator_t *iter; + + DEBUG("rrdtool plugin: Flushing cache, timeout = %.3f", + CDTIME_T_TO_DOUBLE(timeout)); + + now = cdtime(); + timeout = TIME_T_TO_CDTIME_T(timeout); + + /* Build a list of entries to be flushed */ + iter = c_avl_get_iterator(cache); + while (c_avl_iterator_next(iter, (void *)&key, (void *)&rc) == 0) { + if (rc->flags != FLAG_NONE) + continue; + /* timeout == 0 => flush everything */ + else if ((timeout != 0) && ((now - rc->first_value) < timeout)) + continue; + else if (rc->values_num > 0) { + int status; + + status = rrd_queue_enqueue(key, &queue_head, &queue_tail); + if (status == 0) + rc->flags = FLAG_QUEUED; + } else /* ancient and no values -> waste of memory */ + { + char **tmp = realloc(keys, (keys_num + 1) * sizeof(char *)); + if (tmp == NULL) { + char errbuf[1024]; + ERROR("rrdtool plugin: " + "realloc failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + c_avl_iterator_destroy(iter); + sfree(keys); + return; + } + keys = tmp; + keys[keys_num] = key; + keys_num++; + } + } /* while (c_avl_iterator_next) */ + c_avl_iterator_destroy(iter); + + for (int i = 0; i < keys_num; i++) { + if (c_avl_remove(cache, keys[i], (void *)&key, (void *)&rc) != 0) { + DEBUG("rrdtool plugin: c_avl_remove (%s) failed.", keys[i]); + continue; + } + + assert(rc->values == NULL); + assert(rc->values_num == 0); + + sfree(rc); + sfree(key); + keys[i] = NULL; + } /* for (i = 0..keys_num) */ + + sfree(keys); + + cache_flush_last = now; } /* void rrd_cache_flush */ -static int rrd_cache_flush_identifier (cdtime_t timeout, - const char *identifier) -{ +static int rrd_cache_flush_identifier(cdtime_t timeout, + const char *identifier) { rrd_cache_t *rc; cdtime_t now; int status; char key[2048]; - if (identifier == NULL) - { - rrd_cache_flush (timeout); + if (identifier == NULL) { + rrd_cache_flush(timeout); return (0); } - now = cdtime (); + now = cdtime(); if (datadir == NULL) - snprintf (key, sizeof (key), "%s.rrd", - identifier); + snprintf(key, sizeof(key), "%s.rrd", identifier); else - snprintf (key, sizeof (key), "%s/%s.rrd", - datadir, identifier); - key[sizeof (key) - 1] = 0; - - status = c_avl_get (cache, key, (void *) &rc); - if (status != 0) - { - INFO ("rrdtool plugin: rrd_cache_flush_identifier: " - "c_avl_get (%s) failed. Does that file really exist?", - key); + snprintf(key, sizeof(key), "%s/%s.rrd", datadir, identifier); + key[sizeof(key) - 1] = 0; + + status = c_avl_get(cache, key, (void *)&rc); + if (status != 0) { + INFO("rrdtool plugin: rrd_cache_flush_identifier: " + "c_avl_get (%s) failed. Does that file really exist?", + key); return (status); } - if (rc->flags == FLAG_FLUSHQ) - { + if (rc->flags == FLAG_FLUSHQ) { status = 0; - } - else if (rc->flags == FLAG_QUEUED) - { - rrd_queue_dequeue (key, &queue_head, &queue_tail); - status = rrd_queue_enqueue (key, &flushq_head, &flushq_tail); + } else if (rc->flags == FLAG_QUEUED) { + rrd_queue_dequeue(key, &queue_head, &queue_tail); + status = rrd_queue_enqueue(key, &flushq_head, &flushq_tail); if (status == 0) rc->flags = FLAG_FLUSHQ; - } - else if ((now - rc->first_value) < timeout) - { + } else if ((now - rc->first_value) < timeout) { status = 0; - } - else if (rc->values_num > 0) - { - status = rrd_queue_enqueue (key, &flushq_head, &flushq_tail); + } else if (rc->values_num > 0) { + status = rrd_queue_enqueue(key, &flushq_head, &flushq_tail); if (status == 0) rc->flags = FLAG_FLUSHQ; } @@ -681,8 +605,7 @@ static int rrd_cache_flush_identifier (cdtime_t timeout, return (status); } /* int rrd_cache_flush_identifier */ -static int64_t rrd_get_random_variation (void) -{ +static int64_t rrd_get_random_variation(void) { long min; long max; @@ -690,172 +613,158 @@ static int64_t rrd_get_random_variation (void) 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; + if (random_timeout > cache_timeout) { + INFO("rrdtool plugin: Adjusting \"RandomTimeout\" to %.3f seconds.", + CDTIME_T_TO_DOUBLE(cache_timeout)); + random_timeout = cache_timeout; } - max = (long) (random_timeout / 2); - min = max - ((long) random_timeout); + max = (long)(random_timeout / 2); + min = max - ((long)random_timeout); - return ((int64_t) cdrand_range (min, max)); + return ((int64_t)cdrand_range(min, max)); } /* int64_t rrd_get_random_variation */ -static int rrd_cache_insert (const char *filename, - const char *value, cdtime_t value_time) -{ - rrd_cache_t *rc = NULL; - int new_rc = 0; - char **values_new; - - pthread_mutex_lock (&cache_lock); - - /* This shouldn't happen, but it did happen at least once, so we'll be - * careful. */ - if (cache == NULL) - { - pthread_mutex_unlock (&cache_lock); - WARNING ("rrdtool plugin: cache == NULL."); - return (-1); - } - - c_avl_get (cache, filename, (void *) &rc); - - if (rc == NULL) - { - rc = malloc (sizeof (*rc)); - if (rc == NULL) - { - pthread_mutex_unlock (&cache_lock); - return (-1); - } - rc->values_num = 0; - rc->values = NULL; - rc->first_value = 0; - rc->last_value = 0; - rc->random_variation = rrd_get_random_variation (); - rc->flags = FLAG_NONE; - new_rc = 1; - } - - assert (value_time > 0); /* plugin_dispatch() ensures this. */ - if (rc->last_value >= value_time) - { - pthread_mutex_unlock (&cache_lock); - DEBUG ("rrdtool plugin: (rc->last_value = %"PRIu64") " - ">= (value_time = %"PRIu64")", - rc->last_value, value_time); - return (-1); - } - - values_new = realloc ((void *) rc->values, - (rc->values_num + 1) * sizeof (char *)); - if (values_new == NULL) - { - char errbuf[1024]; - void *cache_key = NULL; - - sstrerror (errno, errbuf, sizeof (errbuf)); - - c_avl_remove (cache, filename, &cache_key, NULL); - pthread_mutex_unlock (&cache_lock); - - ERROR ("rrdtool plugin: realloc failed: %s", errbuf); - - sfree (cache_key); - sfree (rc->values); - sfree (rc); - return (-1); - } - rc->values = values_new; - - rc->values[rc->values_num] = strdup (value); - if (rc->values[rc->values_num] != NULL) - rc->values_num++; - - if (rc->values_num == 1) - rc->first_value = value_time; - rc->last_value = value_time; - - /* Insert if this is the first value */ - if (new_rc == 1) - { - void *cache_key = strdup (filename); - - if (cache_key == NULL) - { - char errbuf[1024]; - sstrerror (errno, errbuf, sizeof (errbuf)); - - pthread_mutex_unlock (&cache_lock); - - ERROR ("rrdtool plugin: strdup failed: %s", errbuf); - - sfree (rc->values[0]); - sfree (rc->values); - sfree (rc); - return (-1); - } - - c_avl_insert (cache, cache_key, rc); - } - - DEBUG ("rrdtool plugin: rrd_cache_insert: file = %s; " - "values_num = %i; age = %.3f;", - filename, rc->values_num, - CDTIME_T_TO_DOUBLE (rc->last_value - rc->first_value)); - - 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! */ - if (rc->flags == FLAG_NONE) - { - int status; - - status = rrd_queue_enqueue (filename, &queue_head, &queue_tail); - if (status == 0) - rc->flags = FLAG_QUEUED; - - rc->random_variation = rrd_get_random_variation (); - } - else - { - DEBUG ("rrdtool plugin: `%s' is already queued.", filename); - } - } - - if ((cache_timeout > 0) && - ((cdtime () - cache_flush_last) > cache_flush_timeout)) - rrd_cache_flush (cache_flush_timeout); - - pthread_mutex_unlock (&cache_lock); - - return (0); +static int rrd_cache_insert(const char *filename, const char *value, + cdtime_t value_time) { + rrd_cache_t *rc = NULL; + int new_rc = 0; + char **values_new; + + pthread_mutex_lock(&cache_lock); + + /* This shouldn't happen, but it did happen at least once, so we'll be + * careful. */ + if (cache == NULL) { + pthread_mutex_unlock(&cache_lock); + WARNING("rrdtool plugin: cache == NULL."); + return (-1); + } + + c_avl_get(cache, filename, (void *)&rc); + + if (rc == NULL) { + rc = malloc(sizeof(*rc)); + if (rc == NULL) { + pthread_mutex_unlock(&cache_lock); + return (-1); + } + rc->values_num = 0; + rc->values = NULL; + rc->first_value = 0; + rc->last_value = 0; + rc->random_variation = rrd_get_random_variation(); + rc->flags = FLAG_NONE; + new_rc = 1; + } + + assert(value_time > 0); /* plugin_dispatch() ensures this. */ + if (rc->last_value >= value_time) { + pthread_mutex_unlock(&cache_lock); + DEBUG("rrdtool plugin: (rc->last_value = %" PRIu64 ") " + ">= (value_time = %" PRIu64 ")", + rc->last_value, value_time); + return (-1); + } + + values_new = + realloc((void *)rc->values, (rc->values_num + 1) * sizeof(char *)); + if (values_new == NULL) { + char errbuf[1024]; + void *cache_key = NULL; + + sstrerror(errno, errbuf, sizeof(errbuf)); + + c_avl_remove(cache, filename, &cache_key, NULL); + pthread_mutex_unlock(&cache_lock); + + ERROR("rrdtool plugin: realloc failed: %s", errbuf); + + sfree(cache_key); + sfree(rc->values); + sfree(rc); + return (-1); + } + rc->values = values_new; + + rc->values[rc->values_num] = strdup(value); + if (rc->values[rc->values_num] != NULL) + rc->values_num++; + + if (rc->values_num == 1) + rc->first_value = value_time; + rc->last_value = value_time; + + /* Insert if this is the first value */ + if (new_rc == 1) { + void *cache_key = strdup(filename); + + if (cache_key == NULL) { + char errbuf[1024]; + sstrerror(errno, errbuf, sizeof(errbuf)); + + pthread_mutex_unlock(&cache_lock); + + ERROR("rrdtool plugin: strdup failed: %s", errbuf); + + sfree(rc->values[0]); + sfree(rc->values); + sfree(rc); + return (-1); + } + + c_avl_insert(cache, cache_key, rc); + } + + DEBUG("rrdtool plugin: rrd_cache_insert: file = %s; " + "values_num = %i; age = %.3f;", + filename, rc->values_num, + CDTIME_T_TO_DOUBLE(rc->last_value - rc->first_value)); + + 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! */ + if (rc->flags == FLAG_NONE) { + int status; + + status = rrd_queue_enqueue(filename, &queue_head, &queue_tail); + if (status == 0) + rc->flags = FLAG_QUEUED; + + rc->random_variation = rrd_get_random_variation(); + } else { + DEBUG("rrdtool plugin: `%s' is already queued.", filename); + } + } + + if ((cache_timeout > 0) && + ((cdtime() - cache_flush_last) > cache_flush_timeout)) + rrd_cache_flush(cache_flush_timeout); + + pthread_mutex_unlock(&cache_lock); + + return (0); } /* int rrd_cache_insert */ -static int rrd_cache_destroy (void) /* {{{ */ +static int rrd_cache_destroy(void) /* {{{ */ { void *key = NULL; void *value = NULL; int non_empty = 0; - pthread_mutex_lock (&cache_lock); + pthread_mutex_lock(&cache_lock); - if (cache == NULL) - { - pthread_mutex_unlock (&cache_lock); + if (cache == NULL) { + pthread_mutex_unlock(&cache_lock); return (0); } - while (c_avl_pick (cache, &key, &value) == 0) - { + while (c_avl_pick(cache, &key, &value) == 0) { rrd_cache_t *rc; - sfree (key); + sfree(key); key = NULL; rc = value; @@ -865,395 +774,325 @@ static int rrd_cache_destroy (void) /* {{{ */ non_empty++; for (int i = 0; i < rc->values_num; i++) - sfree (rc->values[i]); - sfree (rc->values); - sfree (rc); + sfree(rc->values[i]); + sfree(rc->values); + sfree(rc); } - c_avl_destroy (cache); + c_avl_destroy(cache); cache = NULL; - if (non_empty > 0) - { - INFO ("rrdtool plugin: %i cache %s had values when destroying the cache.", - non_empty, (non_empty == 1) ? "entry" : "entries"); - } - else - { - DEBUG ("rrdtool plugin: No values have been lost " - "when destroying the cache."); + if (non_empty > 0) { + INFO("rrdtool plugin: %i cache %s had values when destroying the cache.", + non_empty, (non_empty == 1) ? "entry" : "entries"); + } else { + DEBUG("rrdtool plugin: No values have been lost " + "when destroying the cache."); } - pthread_mutex_unlock (&cache_lock); + pthread_mutex_unlock(&cache_lock); return (0); } /* }}} int rrd_cache_destroy */ -static int rrd_compare_numeric (const void *a_ptr, const void *b_ptr) -{ - int a = *((int *) a_ptr); - int b = *((int *) b_ptr); - - if (a < b) - return (-1); - else if (a > b) - return (1); - else - return (0); +static int rrd_compare_numeric(const void *a_ptr, const void *b_ptr) { + int a = *((int *)a_ptr); + int b = *((int *)b_ptr); + + if (a < b) + return (-1); + else if (a > b) + return (1); + else + return (0); } /* int rrd_compare_numeric */ -static int rrd_write (const data_set_t *ds, const value_list_t *vl, - user_data_t __attribute__((unused)) *user_data) -{ - struct stat statbuf; - char filename[512]; - char values[512]; - int status; - - if (do_shutdown) - return (0); - - if (0 != strcmp (ds->type, vl->type)) { - ERROR ("rrdtool plugin: DS type does not match value list type"); - return -1; - } - - if (value_list_to_filename (filename, sizeof (filename), vl) != 0) - return (-1); - - if (value_list_to_string (values, sizeof (values), ds, vl) != 0) - return (-1); - - if (stat (filename, &statbuf) == -1) - { - if (errno == ENOENT) - { - status = cu_rrd_create_file (filename, - ds, vl, &rrdcreate_config); - if (status != 0) - return (-1); - else if (rrdcreate_config.async) - return (0); - } - else - { - char errbuf[1024]; - ERROR ("stat(%s) failed: %s", filename, - sstrerror (errno, errbuf, - sizeof (errbuf))); - return (-1); - } - } - else if (!S_ISREG (statbuf.st_mode)) - { - ERROR ("stat(%s): Not a regular file!", - filename); - return (-1); - } - - status = rrd_cache_insert (filename, values, vl->time); - - return (status); +static int rrd_write(const data_set_t *ds, const value_list_t *vl, + user_data_t __attribute__((unused)) * user_data) { + struct stat statbuf; + char filename[512]; + char values[512]; + int status; + + if (do_shutdown) + return (0); + + if (0 != strcmp(ds->type, vl->type)) { + ERROR("rrdtool plugin: DS type does not match value list type"); + return -1; + } + + if (value_list_to_filename(filename, sizeof(filename), vl) != 0) + return (-1); + + if (value_list_to_string(values, sizeof(values), ds, vl) != 0) + return (-1); + + if (stat(filename, &statbuf) == -1) { + if (errno == ENOENT) { + status = cu_rrd_create_file(filename, ds, vl, &rrdcreate_config); + if (status != 0) + return (-1); + else if (rrdcreate_config.async) + return (0); + } else { + char errbuf[1024]; + ERROR("stat(%s) failed: %s", filename, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + } else if (!S_ISREG(statbuf.st_mode)) { + ERROR("stat(%s): Not a regular file!", filename); + return (-1); + } + + status = rrd_cache_insert(filename, values, vl->time); + + return (status); } /* int rrd_write */ -static int rrd_flush (cdtime_t timeout, const char *identifier, - __attribute__((unused)) user_data_t *user_data) -{ - pthread_mutex_lock (&cache_lock); +static int rrd_flush(cdtime_t timeout, const char *identifier, + __attribute__((unused)) user_data_t *user_data) { + pthread_mutex_lock(&cache_lock); - if (cache == NULL) { - pthread_mutex_unlock (&cache_lock); - return (0); - } + if (cache == NULL) { + pthread_mutex_unlock(&cache_lock); + return (0); + } - rrd_cache_flush_identifier (timeout, identifier); + rrd_cache_flush_identifier(timeout, identifier); - pthread_mutex_unlock (&cache_lock); - return (0); + pthread_mutex_unlock(&cache_lock); + return (0); } /* int rrd_flush */ -static int rrd_config (const char *key, const char *value) -{ - if (strcasecmp ("CacheTimeout", key) == 0) - { - double tmp = atof (value); - if (tmp < 0) - { - fprintf (stderr, "rrdtool: `CacheTimeout' must " - "be greater than 0.\n"); - ERROR ("rrdtool: `CacheTimeout' must " - "be greater than 0.\n"); - return (1); - } - cache_timeout = DOUBLE_TO_CDTIME_T (tmp); - } - else if (strcasecmp ("CacheFlush", key) == 0) - { - int tmp = atoi (value); - if (tmp < 0) - { - fprintf (stderr, "rrdtool: `CacheFlush' must " - "be greater than 0.\n"); - ERROR ("rrdtool: `CacheFlush' must " - "be greater than 0.\n"); - return (1); - } - cache_flush_timeout = tmp; - } - else if (strcasecmp ("DataDir", key) == 0) - { - char *tmp; - size_t len; - - tmp = strdup (value); - if (tmp == NULL) - { - ERROR ("rrdtool plugin: strdup failed."); - return (1); - } - - len = strlen (tmp); - while ((len > 0) && (tmp[len - 1] == '/')) - { - len--; - tmp[len] = 0; - } - - if (len == 0) - { - ERROR ("rrdtool plugin: Invalid \"DataDir\" option."); - sfree (tmp); - return (1); - } - - if (datadir != NULL) - { - sfree (datadir); - } - - datadir = tmp; - } - else if (strcasecmp ("StepSize", key) == 0) - { - unsigned long temp = strtoul (value, NULL, 0); - if (temp > 0) - rrdcreate_config.stepsize = temp; - } - else if (strcasecmp ("HeartBeat", key) == 0) - { - int temp = atoi (value); - if (temp > 0) - rrdcreate_config.heartbeat = temp; - } - else if (strcasecmp ("CreateFilesAsync", key) == 0) - { - if (IS_TRUE (value)) - rrdcreate_config.async = 1; - else - rrdcreate_config.async = 0; - } - else if (strcasecmp ("RRARows", key) == 0) - { - int tmp = atoi (value); - if (tmp <= 0) - { - fprintf (stderr, "rrdtool: `RRARows' must " - "be greater than 0.\n"); - ERROR ("rrdtool: `RRARows' must " - "be greater than 0.\n"); - return (1); - } - rrdcreate_config.rrarows = tmp; - } - else if (strcasecmp ("RRATimespan", key) == 0) - { - char *saveptr = NULL; - char *dummy; - char *ptr; - char *value_copy; - int *tmp_alloc; - - value_copy = strdup (value); - if (value_copy == NULL) - return (1); - - dummy = value_copy; - while ((ptr = strtok_r (dummy, ", \t", &saveptr)) != NULL) - { - dummy = NULL; - - tmp_alloc = realloc (rrdcreate_config.timespans, - sizeof (int) * (rrdcreate_config.timespans_num + 1)); - if (tmp_alloc == NULL) - { - fprintf (stderr, "rrdtool: realloc failed.\n"); - ERROR ("rrdtool: realloc failed.\n"); - free (value_copy); - return (1); - } - rrdcreate_config.timespans = tmp_alloc; - rrdcreate_config.timespans[rrdcreate_config.timespans_num] = atoi (ptr); - if (rrdcreate_config.timespans[rrdcreate_config.timespans_num] != 0) - rrdcreate_config.timespans_num++; - } /* while (strtok_r) */ - - qsort (/* base = */ rrdcreate_config.timespans, - /* nmemb = */ rrdcreate_config.timespans_num, - /* size = */ sizeof (rrdcreate_config.timespans[0]), - /* compar = */ rrd_compare_numeric); - - free (value_copy); - } - else if (strcasecmp ("XFF", key) == 0) - { - double tmp = atof (value); - if ((tmp < 0.0) || (tmp >= 1.0)) - { - fprintf (stderr, "rrdtool: `XFF' must " - "be in the range 0 to 1 (exclusive)."); - ERROR ("rrdtool: `XFF' must " - "be in the range 0 to 1 (exclusive)."); - return (1); - } - rrdcreate_config.xff = tmp; - } - else if (strcasecmp ("WritesPerSecond", key) == 0) - { - double wps = atof (value); - - if (wps < 0.0) - { - fprintf (stderr, "rrdtool: `WritesPerSecond' must be " - "greater than or equal to zero."); - return (1); - } - else if (wps == 0.0) - { - write_rate = 0.0; - } - else - { - write_rate = 1.0 / wps; - } - } - else if (strcasecmp ("RandomTimeout", key) == 0) - { - double tmp; - - tmp = atof (value); - if (tmp < 0.0) - { - fprintf (stderr, "rrdtool: `RandomTimeout' must " - "be greater than or equal to zero.\n"); - ERROR ("rrdtool: `RandomTimeout' must " - "be greater then or equal to zero."); - } - else - { - random_timeout = DOUBLE_TO_CDTIME_T (tmp); - } - } - else - { - return (-1); - } - return (0); +static int rrd_config(const char *key, const char *value) { + if (strcasecmp("CacheTimeout", key) == 0) { + double tmp = atof(value); + if (tmp < 0) { + fprintf(stderr, "rrdtool: `CacheTimeout' must " + "be greater than 0.\n"); + ERROR("rrdtool: `CacheTimeout' must " + "be greater than 0.\n"); + return (1); + } + cache_timeout = DOUBLE_TO_CDTIME_T(tmp); + } else if (strcasecmp("CacheFlush", key) == 0) { + int tmp = atoi(value); + if (tmp < 0) { + fprintf(stderr, "rrdtool: `CacheFlush' must " + "be greater than 0.\n"); + ERROR("rrdtool: `CacheFlush' must " + "be greater than 0.\n"); + return (1); + } + cache_flush_timeout = tmp; + } else if (strcasecmp("DataDir", key) == 0) { + char *tmp; + size_t len; + + tmp = strdup(value); + if (tmp == NULL) { + ERROR("rrdtool plugin: strdup failed."); + return (1); + } + + len = strlen(tmp); + while ((len > 0) && (tmp[len - 1] == '/')) { + len--; + tmp[len] = 0; + } + + if (len == 0) { + ERROR("rrdtool plugin: Invalid \"DataDir\" option."); + sfree(tmp); + return (1); + } + + if (datadir != NULL) { + sfree(datadir); + } + + datadir = tmp; + } else if (strcasecmp("StepSize", key) == 0) { + unsigned long temp = strtoul(value, NULL, 0); + if (temp > 0) + rrdcreate_config.stepsize = temp; + } else if (strcasecmp("HeartBeat", key) == 0) { + int temp = atoi(value); + if (temp > 0) + rrdcreate_config.heartbeat = temp; + } else if (strcasecmp("CreateFilesAsync", key) == 0) { + if (IS_TRUE(value)) + rrdcreate_config.async = 1; + else + rrdcreate_config.async = 0; + } else if (strcasecmp("RRARows", key) == 0) { + int tmp = atoi(value); + if (tmp <= 0) { + fprintf(stderr, "rrdtool: `RRARows' must " + "be greater than 0.\n"); + ERROR("rrdtool: `RRARows' must " + "be greater than 0.\n"); + return (1); + } + rrdcreate_config.rrarows = tmp; + } else if (strcasecmp("RRATimespan", key) == 0) { + char *saveptr = NULL; + char *dummy; + char *ptr; + char *value_copy; + int *tmp_alloc; + + value_copy = strdup(value); + if (value_copy == NULL) + return (1); + + dummy = value_copy; + while ((ptr = strtok_r(dummy, ", \t", &saveptr)) != NULL) { + dummy = NULL; + + tmp_alloc = realloc(rrdcreate_config.timespans, + sizeof(int) * (rrdcreate_config.timespans_num + 1)); + if (tmp_alloc == NULL) { + fprintf(stderr, "rrdtool: realloc failed.\n"); + ERROR("rrdtool: realloc failed.\n"); + free(value_copy); + return (1); + } + rrdcreate_config.timespans = tmp_alloc; + rrdcreate_config.timespans[rrdcreate_config.timespans_num] = atoi(ptr); + if (rrdcreate_config.timespans[rrdcreate_config.timespans_num] != 0) + rrdcreate_config.timespans_num++; + } /* while (strtok_r) */ + + qsort(/* base = */ rrdcreate_config.timespans, + /* nmemb = */ rrdcreate_config.timespans_num, + /* size = */ sizeof(rrdcreate_config.timespans[0]), + /* compar = */ rrd_compare_numeric); + + free(value_copy); + } else if (strcasecmp("XFF", key) == 0) { + double tmp = atof(value); + if ((tmp < 0.0) || (tmp >= 1.0)) { + fprintf(stderr, "rrdtool: `XFF' must " + "be in the range 0 to 1 (exclusive)."); + ERROR("rrdtool: `XFF' must " + "be in the range 0 to 1 (exclusive)."); + return (1); + } + rrdcreate_config.xff = tmp; + } else if (strcasecmp("WritesPerSecond", key) == 0) { + double wps = atof(value); + + if (wps < 0.0) { + fprintf(stderr, "rrdtool: `WritesPerSecond' must be " + "greater than or equal to zero."); + return (1); + } else if (wps == 0.0) { + write_rate = 0.0; + } else { + write_rate = 1.0 / wps; + } + } else if (strcasecmp("RandomTimeout", key) == 0) { + double tmp; + + tmp = atof(value); + if (tmp < 0.0) { + fprintf(stderr, "rrdtool: `RandomTimeout' must " + "be greater than or equal to zero.\n"); + ERROR("rrdtool: `RandomTimeout' must " + "be greater then or equal to zero."); + } else { + random_timeout = DOUBLE_TO_CDTIME_T(tmp); + } + } else { + return (-1); + } + return (0); } /* int rrd_config */ -static int rrd_shutdown (void) -{ - pthread_mutex_lock (&cache_lock); - rrd_cache_flush (0); - pthread_mutex_unlock (&cache_lock); - - pthread_mutex_lock (&queue_lock); - do_shutdown = 1; - pthread_cond_signal (&queue_cond); - pthread_mutex_unlock (&queue_lock); - - if ((queue_thread_running != 0) - && ((queue_head != NULL) || (flushq_head != NULL))) - { - INFO ("rrdtool plugin: Shutting down the queue thread. " - "This may take a while."); - } - else if (queue_thread_running != 0) - { - INFO ("rrdtool plugin: Shutting down the queue thread."); - } - - /* Wait for all the values to be written to disk before returning. */ - if (queue_thread_running != 0) - { - pthread_join (queue_thread, NULL); - memset (&queue_thread, 0, sizeof (queue_thread)); - queue_thread_running = 0; - DEBUG ("rrdtool plugin: queue_thread exited."); - } - - rrd_cache_destroy (); - - return (0); +static int rrd_shutdown(void) { + pthread_mutex_lock(&cache_lock); + rrd_cache_flush(0); + pthread_mutex_unlock(&cache_lock); + + pthread_mutex_lock(&queue_lock); + do_shutdown = 1; + pthread_cond_signal(&queue_cond); + pthread_mutex_unlock(&queue_lock); + + if ((queue_thread_running != 0) && + ((queue_head != NULL) || (flushq_head != NULL))) { + INFO("rrdtool plugin: Shutting down the queue thread. " + "This may take a while."); + } else if (queue_thread_running != 0) { + INFO("rrdtool plugin: Shutting down the queue thread."); + } + + /* Wait for all the values to be written to disk before returning. */ + if (queue_thread_running != 0) { + pthread_join(queue_thread, NULL); + memset(&queue_thread, 0, sizeof(queue_thread)); + queue_thread_running = 0; + DEBUG("rrdtool plugin: queue_thread exited."); + } + + rrd_cache_destroy(); + + return (0); } /* int rrd_shutdown */ -static int rrd_init (void) -{ - static int init_once = 0; - int status; - - if (init_once != 0) - return (0); - init_once = 1; - - if (rrdcreate_config.heartbeat <= 0) - rrdcreate_config.heartbeat = 2 * rrdcreate_config.stepsize; - - /* Set the cache up */ - pthread_mutex_lock (&cache_lock); - - cache = c_avl_create ((int (*) (const void *, const void *)) strcmp); - if (cache == NULL) - { - pthread_mutex_unlock (&cache_lock); - ERROR ("rrdtool plugin: c_avl_create failed."); - return (-1); - } - - cache_flush_last = cdtime (); - if (cache_timeout == 0) - { - cache_flush_timeout = 0; - } - else if (cache_flush_timeout < cache_timeout) - cache_flush_timeout = 10 * cache_timeout; - - pthread_mutex_unlock (&cache_lock); - - status = plugin_thread_create (&queue_thread, /* attr = */ NULL, - rrd_queue_thread, /* args = */ NULL, "rrdtool queue"); - if (status != 0) - { - ERROR ("rrdtool plugin: Cannot create queue-thread."); - return (-1); - } - queue_thread_running = 1; - - DEBUG ("rrdtool plugin: rrd_init: datadir = %s; stepsize = %lu;" - " heartbeat = %i; rrarows = %i; xff = %lf;", - (datadir == NULL) ? "(null)" : datadir, - rrdcreate_config.stepsize, - rrdcreate_config.heartbeat, - rrdcreate_config.rrarows, - rrdcreate_config.xff); - - return (0); +static int rrd_init(void) { + static int init_once = 0; + int status; + + if (init_once != 0) + return (0); + init_once = 1; + + if (rrdcreate_config.heartbeat <= 0) + rrdcreate_config.heartbeat = 2 * rrdcreate_config.stepsize; + + /* Set the cache up */ + pthread_mutex_lock(&cache_lock); + + cache = c_avl_create((int (*)(const void *, const void *))strcmp); + if (cache == NULL) { + pthread_mutex_unlock(&cache_lock); + ERROR("rrdtool plugin: c_avl_create failed."); + return (-1); + } + + cache_flush_last = cdtime(); + if (cache_timeout == 0) { + cache_flush_timeout = 0; + } else if (cache_flush_timeout < cache_timeout) + cache_flush_timeout = 10 * cache_timeout; + + pthread_mutex_unlock(&cache_lock); + + status = + plugin_thread_create(&queue_thread, /* attr = */ NULL, rrd_queue_thread, + /* args = */ NULL, "rrdtool queue"); + if (status != 0) { + ERROR("rrdtool plugin: Cannot create queue-thread."); + return (-1); + } + queue_thread_running = 1; + + DEBUG("rrdtool plugin: rrd_init: datadir = %s; stepsize = %lu;" + " heartbeat = %i; rrarows = %i; xff = %lf;", + (datadir == NULL) ? "(null)" : datadir, rrdcreate_config.stepsize, + rrdcreate_config.heartbeat, rrdcreate_config.rrarows, + rrdcreate_config.xff); + + return (0); } /* int rrd_init */ -void module_register (void) -{ - plugin_register_config ("rrdtool", rrd_config, - config_keys, config_keys_num); - plugin_register_init ("rrdtool", rrd_init); - plugin_register_write ("rrdtool", rrd_write, /* user_data = */ NULL); - plugin_register_flush ("rrdtool", rrd_flush, /* user_data = */ NULL); - plugin_register_shutdown ("rrdtool", rrd_shutdown); +void module_register(void) { + plugin_register_config("rrdtool", rrd_config, config_keys, config_keys_num); + plugin_register_init("rrdtool", rrd_init); + plugin_register_write("rrdtool", rrd_write, /* user_data = */ NULL); + plugin_register_flush("rrdtool", rrd_flush, /* user_data = */ NULL); + plugin_register_shutdown("rrdtool", rrd_shutdown); } diff --git a/src/sensors.c b/src/sensors.c index 438cd746..8f1824d0 100644 --- a/src/sensors.c +++ b/src/sensors.c @@ -40,11 +40,11 @@ #include "utils_ignorelist.h" #if defined(HAVE_SENSORS_SENSORS_H) -# include +#include #endif #if !defined(SENSORS_API_VERSION) -# define SENSORS_API_VERSION 0x000 +#define SENSORS_API_VERSION 0x000 #endif /* @@ -54,119 +54,107 @@ * interface. */ #if SENSORS_API_VERSION < 0x400 -static char *sensor_type_name_map[] = -{ -# define SENSOR_TYPE_VOLTAGE 0 - "voltage", -# define SENSOR_TYPE_FANSPEED 1 - "fanspeed", -# define SENSOR_TYPE_TEMPERATURE 2 - "temperature", -# define SENSOR_TYPE_POWER 3 - "power", -# define SENSOR_TYPE_UNKNOWN 4 - NULL -}; - -struct sensors_labeltypes_s -{ - char *label; - int type; +static char *sensor_type_name_map[] = { +#define SENSOR_TYPE_VOLTAGE 0 + "voltage", +#define SENSOR_TYPE_FANSPEED 1 + "fanspeed", +#define SENSOR_TYPE_TEMPERATURE 2 + "temperature", +#define SENSOR_TYPE_POWER 3 + "power", +#define SENSOR_TYPE_UNKNOWN 4 + NULL}; + +struct sensors_labeltypes_s { + char *label; + int type; }; typedef struct sensors_labeltypes_s sensors_labeltypes_t; /* finite list of known labels extracted from lm_sensors */ -static sensors_labeltypes_t known_features[] = -{ - { "fan1", SENSOR_TYPE_FANSPEED }, - { "fan2", SENSOR_TYPE_FANSPEED }, - { "fan3", SENSOR_TYPE_FANSPEED }, - { "fan4", SENSOR_TYPE_FANSPEED }, - { "fan5", SENSOR_TYPE_FANSPEED }, - { "fan6", SENSOR_TYPE_FANSPEED }, - { "fan7", SENSOR_TYPE_FANSPEED }, - { "AIN2", SENSOR_TYPE_VOLTAGE }, - { "AIN1", SENSOR_TYPE_VOLTAGE }, - { "in10", SENSOR_TYPE_VOLTAGE }, - { "in9", SENSOR_TYPE_VOLTAGE }, - { "in8", SENSOR_TYPE_VOLTAGE }, - { "in7", SENSOR_TYPE_VOLTAGE }, - { "in6", SENSOR_TYPE_VOLTAGE }, - { "in5", SENSOR_TYPE_VOLTAGE }, - { "in4", SENSOR_TYPE_VOLTAGE }, - { "in3", SENSOR_TYPE_VOLTAGE }, - { "in2", SENSOR_TYPE_VOLTAGE }, - { "in0", SENSOR_TYPE_VOLTAGE }, - { "CPU_Temp", SENSOR_TYPE_TEMPERATURE }, - { "remote_temp", SENSOR_TYPE_TEMPERATURE }, - { "temp1", SENSOR_TYPE_TEMPERATURE }, - { "temp2", SENSOR_TYPE_TEMPERATURE }, - { "temp3", SENSOR_TYPE_TEMPERATURE }, - { "temp4", SENSOR_TYPE_TEMPERATURE }, - { "temp5", SENSOR_TYPE_TEMPERATURE }, - { "temp6", SENSOR_TYPE_TEMPERATURE }, - { "temp7", SENSOR_TYPE_TEMPERATURE }, - { "temp", SENSOR_TYPE_TEMPERATURE }, - { "Vccp2", SENSOR_TYPE_VOLTAGE }, - { "Vccp1", SENSOR_TYPE_VOLTAGE }, - { "vdd", SENSOR_TYPE_VOLTAGE }, - { "vid5", SENSOR_TYPE_VOLTAGE }, - { "vid4", SENSOR_TYPE_VOLTAGE }, - { "vid3", SENSOR_TYPE_VOLTAGE }, - { "vid2", SENSOR_TYPE_VOLTAGE }, - { "vid1", SENSOR_TYPE_VOLTAGE }, - { "vid", SENSOR_TYPE_VOLTAGE }, - { "vin4", SENSOR_TYPE_VOLTAGE }, - { "vin3", SENSOR_TYPE_VOLTAGE }, - { "vin2", SENSOR_TYPE_VOLTAGE }, - { "vin1", SENSOR_TYPE_VOLTAGE }, - { "voltbatt", SENSOR_TYPE_VOLTAGE }, - { "volt12", SENSOR_TYPE_VOLTAGE }, - { "volt5", SENSOR_TYPE_VOLTAGE }, - { "vrm", SENSOR_TYPE_VOLTAGE }, - { "5.0V", SENSOR_TYPE_VOLTAGE }, - { "5V", SENSOR_TYPE_VOLTAGE }, - { "3.3V", SENSOR_TYPE_VOLTAGE }, - { "2.5V", SENSOR_TYPE_VOLTAGE }, - { "2.0V", SENSOR_TYPE_VOLTAGE }, - { "12V", SENSOR_TYPE_VOLTAGE }, - { "power1", SENSOR_TYPE_POWER } -}; -static int known_features_num = STATIC_ARRAY_SIZE (known_features); +static sensors_labeltypes_t known_features[] = { + {"fan1", SENSOR_TYPE_FANSPEED}, + {"fan2", SENSOR_TYPE_FANSPEED}, + {"fan3", SENSOR_TYPE_FANSPEED}, + {"fan4", SENSOR_TYPE_FANSPEED}, + {"fan5", SENSOR_TYPE_FANSPEED}, + {"fan6", SENSOR_TYPE_FANSPEED}, + {"fan7", SENSOR_TYPE_FANSPEED}, + {"AIN2", SENSOR_TYPE_VOLTAGE}, + {"AIN1", SENSOR_TYPE_VOLTAGE}, + {"in10", SENSOR_TYPE_VOLTAGE}, + {"in9", SENSOR_TYPE_VOLTAGE}, + {"in8", SENSOR_TYPE_VOLTAGE}, + {"in7", SENSOR_TYPE_VOLTAGE}, + {"in6", SENSOR_TYPE_VOLTAGE}, + {"in5", SENSOR_TYPE_VOLTAGE}, + {"in4", SENSOR_TYPE_VOLTAGE}, + {"in3", SENSOR_TYPE_VOLTAGE}, + {"in2", SENSOR_TYPE_VOLTAGE}, + {"in0", SENSOR_TYPE_VOLTAGE}, + {"CPU_Temp", SENSOR_TYPE_TEMPERATURE}, + {"remote_temp", SENSOR_TYPE_TEMPERATURE}, + {"temp1", SENSOR_TYPE_TEMPERATURE}, + {"temp2", SENSOR_TYPE_TEMPERATURE}, + {"temp3", SENSOR_TYPE_TEMPERATURE}, + {"temp4", SENSOR_TYPE_TEMPERATURE}, + {"temp5", SENSOR_TYPE_TEMPERATURE}, + {"temp6", SENSOR_TYPE_TEMPERATURE}, + {"temp7", SENSOR_TYPE_TEMPERATURE}, + {"temp", SENSOR_TYPE_TEMPERATURE}, + {"Vccp2", SENSOR_TYPE_VOLTAGE}, + {"Vccp1", SENSOR_TYPE_VOLTAGE}, + {"vdd", SENSOR_TYPE_VOLTAGE}, + {"vid5", SENSOR_TYPE_VOLTAGE}, + {"vid4", SENSOR_TYPE_VOLTAGE}, + {"vid3", SENSOR_TYPE_VOLTAGE}, + {"vid2", SENSOR_TYPE_VOLTAGE}, + {"vid1", SENSOR_TYPE_VOLTAGE}, + {"vid", SENSOR_TYPE_VOLTAGE}, + {"vin4", SENSOR_TYPE_VOLTAGE}, + {"vin3", SENSOR_TYPE_VOLTAGE}, + {"vin2", SENSOR_TYPE_VOLTAGE}, + {"vin1", SENSOR_TYPE_VOLTAGE}, + {"voltbatt", SENSOR_TYPE_VOLTAGE}, + {"volt12", SENSOR_TYPE_VOLTAGE}, + {"volt5", SENSOR_TYPE_VOLTAGE}, + {"vrm", SENSOR_TYPE_VOLTAGE}, + {"5.0V", SENSOR_TYPE_VOLTAGE}, + {"5V", SENSOR_TYPE_VOLTAGE}, + {"3.3V", SENSOR_TYPE_VOLTAGE}, + {"2.5V", SENSOR_TYPE_VOLTAGE}, + {"2.0V", SENSOR_TYPE_VOLTAGE}, + {"12V", SENSOR_TYPE_VOLTAGE}, + {"power1", SENSOR_TYPE_POWER}}; +static int known_features_num = STATIC_ARRAY_SIZE(known_features); /* end new naming */ #endif /* SENSORS_API_VERSION < 0x400 */ -static const char *config_keys[] = -{ - "Sensor", - "IgnoreSelected", - "SensorConfigFile", - "UseLabels" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"Sensor", "IgnoreSelected", + "SensorConfigFile", "UseLabels"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); #if SENSORS_API_VERSION < 0x400 -typedef struct featurelist -{ - const sensors_chip_name *chip; - const sensors_feature_data *data; - int type; - struct featurelist *next; +typedef struct featurelist { + const sensors_chip_name *chip; + const sensors_feature_data *data; + int type; + struct featurelist *next; } featurelist_t; -# ifndef SENSORS_CONF_PATH -# define SENSORS_CONF_PATH "/etc/sensors.conf" -# endif +#ifndef SENSORS_CONF_PATH +#define SENSORS_CONF_PATH "/etc/sensors.conf" +#endif static char *conffile = SENSORS_CONF_PATH; /* #endif SENSORS_API_VERSION < 0x400 */ #elif (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500) -typedef struct featurelist -{ - const sensors_chip_name *chip; - const sensors_feature *feature; - const sensors_subfeature *subfeature; - struct featurelist *next; +typedef struct featurelist { + const sensors_chip_name *chip; + const sensors_feature *feature; + const sensors_subfeature *subfeature; + struct featurelist *next; } featurelist_t; static char *conffile = NULL; @@ -174,7 +162,7 @@ static _Bool use_labels = 0; /* #endif (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500) */ #else /* if SENSORS_API_VERSION >= 0x500 */ -# error "This version of libsensors is not supported yet. Please report this " \ +#error "This version of libsensors is not supported yet. Please report this " \ "as bug." #endif @@ -183,425 +171,361 @@ static ignorelist_t *sensor_list; #if SENSORS_API_VERSION < 0x400 /* full chip name logic borrowed from lm_sensors */ -static int sensors_snprintf_chip_name (char *buf, size_t buf_size, - const sensors_chip_name *chip) -{ - int status = -1; - - if (chip->bus == SENSORS_CHIP_NAME_BUS_ISA) - { - status = ssnprintf (buf, buf_size, - "%s-isa-%04x", - chip->prefix, - chip->addr); - } - else if (chip->bus == SENSORS_CHIP_NAME_BUS_DUMMY) - { - status = snprintf (buf, buf_size, "%s-%s-%04x", - chip->prefix, - chip->busname, - chip->addr); - } - else - { - status = snprintf (buf, buf_size, "%s-i2c-%d-%02x", - chip->prefix, - chip->bus, - chip->addr); - } - - return (status); +static int sensors_snprintf_chip_name(char *buf, size_t buf_size, + const sensors_chip_name *chip) { + int status = -1; + + if (chip->bus == SENSORS_CHIP_NAME_BUS_ISA) { + status = ssnprintf(buf, buf_size, "%s-isa-%04x", chip->prefix, chip->addr); + } else if (chip->bus == SENSORS_CHIP_NAME_BUS_DUMMY) { + status = snprintf(buf, buf_size, "%s-%s-%04x", chip->prefix, chip->busname, + chip->addr); + } else { + status = snprintf(buf, buf_size, "%s-i2c-%d-%02x", chip->prefix, chip->bus, + chip->addr); + } + + return (status); } /* int sensors_snprintf_chip_name */ -static int sensors_feature_name_to_type (const char *name) -{ - /* Yes, this is slow, but it's only ever done during initialization, so - * it's a one time cost.. */ - for (int i = 0; i < known_features_num; i++) - if (strcasecmp (known_features[i].label, name) == 0) - return (known_features[i].type); +static int sensors_feature_name_to_type(const char *name) { + /* Yes, this is slow, but it's only ever done during initialization, so + * it's a one time cost.. */ + for (int i = 0; i < known_features_num; i++) + if (strcasecmp(known_features[i].label, name) == 0) + return (known_features[i].type); - return (SENSOR_TYPE_UNKNOWN); + return (SENSOR_TYPE_UNKNOWN); } /* int sensors_feature_name_to_type */ #endif -static int sensors_config (const char *key, const char *value) -{ - if (sensor_list == NULL) - sensor_list = ignorelist_create (1); - - /* TODO: This setting exists for compatibility with old versions of - * lm-sensors. Remove support for those ancient versions in the next - * major release. */ - if (strcasecmp (key, "SensorConfigFile") == 0) - { - char *tmp = strdup (value); - if (tmp != NULL) - { - sfree (conffile); - conffile = tmp; - } - } - else if (strcasecmp (key, "Sensor") == 0) - { - if (ignorelist_add (sensor_list, value)) - { - ERROR ("sensors plugin: " - "Cannot add value to ignorelist."); - return (1); - } - } - else if (strcasecmp (key, "IgnoreSelected") == 0) - { - ignorelist_set_invert (sensor_list, 1); - if (IS_TRUE (value)) - ignorelist_set_invert (sensor_list, 0); - } +static int sensors_config(const char *key, const char *value) { + if (sensor_list == NULL) + sensor_list = ignorelist_create(1); + + /* TODO: This setting exists for compatibility with old versions of + * lm-sensors. Remove support for those ancient versions in the next + * major release. */ + if (strcasecmp(key, "SensorConfigFile") == 0) { + char *tmp = strdup(value); + if (tmp != NULL) { + sfree(conffile); + conffile = tmp; + } + } else if (strcasecmp(key, "Sensor") == 0) { + if (ignorelist_add(sensor_list, value)) { + ERROR("sensors plugin: " + "Cannot add value to ignorelist."); + return (1); + } + } else if (strcasecmp(key, "IgnoreSelected") == 0) { + ignorelist_set_invert(sensor_list, 1); + if (IS_TRUE(value)) + ignorelist_set_invert(sensor_list, 0); + } #if (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500) - else if (strcasecmp (key, "UseLabels") == 0) - { - use_labels = IS_TRUE (value) ? 1 : 0; - } + else if (strcasecmp(key, "UseLabels") == 0) { + use_labels = IS_TRUE(value) ? 1 : 0; + } #endif - else - { - return (-1); - } + else { + return (-1); + } - return (0); + return (0); } -static void sensors_free_features (void) -{ - featurelist_t *nextft; +static void sensors_free_features(void) { + featurelist_t *nextft; - if (first_feature == NULL) - return; + if (first_feature == NULL) + return; - sensors_cleanup (); + sensors_cleanup(); - for (featurelist_t *thisft = first_feature; thisft != NULL; thisft = nextft) - { - nextft = thisft->next; - sfree (thisft); - } - first_feature = NULL; + for (featurelist_t *thisft = first_feature; thisft != NULL; thisft = nextft) { + nextft = thisft->next; + sfree(thisft); + } + first_feature = NULL; } -static int sensors_load_conf (void) -{ - static int call_once = 0; +static int sensors_load_conf(void) { + static int call_once = 0; - FILE *fh = NULL; - featurelist_t *last_feature = NULL; + FILE *fh = NULL; + featurelist_t *last_feature = NULL; - const sensors_chip_name *chip; - int chip_num; + const sensors_chip_name *chip; + int chip_num; - int status; + int status; - if (call_once) - return 0; + if (call_once) + return 0; - call_once = 1; + call_once = 1; - if (conffile != NULL) - { - fh = fopen (conffile, "r"); - if (fh == NULL) - { - char errbuf[1024]; - ERROR ("sensors plugin: fopen(%s) failed: %s", conffile, - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - } + if (conffile != NULL) { + fh = fopen(conffile, "r"); + if (fh == NULL) { + char errbuf[1024]; + ERROR("sensors plugin: fopen(%s) failed: %s", conffile, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + } - status = sensors_init (fh); - if (fh) - fclose (fh); + status = sensors_init(fh); + if (fh) + fclose(fh); - if (status != 0) - { - ERROR ("sensors plugin: Cannot initialize sensors. " - "Data will not be collected."); - return (-1); - } + if (status != 0) { + ERROR("sensors plugin: Cannot initialize sensors. " + "Data will not be collected."); + return (-1); + } #if SENSORS_API_VERSION < 0x400 - chip_num = 0; - while ((chip = sensors_get_detected_chips (&chip_num)) != NULL) - { - int feature_num0 = 0; - int feature_num1 = 0; - - while (42) - { - const sensors_feature_data *feature; - int feature_type; - featurelist_t *fl; - - feature = sensors_get_all_features (*chip, - &feature_num0, &feature_num1); - - /* Check if all features have been read. */ - if (feature == NULL) - break; - - /* "master features" only */ - if (feature->mapping != SENSORS_NO_MAPPING) - { - DEBUG ("sensors plugin: sensors_load_conf: " - "Ignoring subfeature `%s', " - "because (feature->mapping " - "!= SENSORS_NO_MAPPING).", - feature->name); - continue; - } - - /* skip ignored in sensors.conf */ - if (sensors_get_ignored (*chip, feature->number) == 0) - { - DEBUG ("sensors plugin: sensors_load_conf: " - "Ignoring subfeature `%s', " - "because " - "`sensors_get_ignored' told " - "me so.", - feature->name); - continue; - } - - feature_type = sensors_feature_name_to_type ( - feature->name); - if (feature_type == SENSOR_TYPE_UNKNOWN) - { - DEBUG ("sensors plugin: sensors_load_conf: " - "Ignoring subfeature `%s', " - "because its type is " - "unknown.", - feature->name); - continue; - } - - fl = calloc (1, sizeof (*fl)); - if (fl == NULL) - { - ERROR ("sensors plugin: calloc failed."); - continue; - } - - fl->chip = chip; - fl->data = feature; - fl->type = feature_type; - - if (first_feature == NULL) - first_feature = fl; - else - last_feature->next = fl; - last_feature = fl; - } /* while sensors_get_all_features */ - } /* while sensors_get_detected_chips */ + chip_num = 0; + while ((chip = sensors_get_detected_chips(&chip_num)) != NULL) { + int feature_num0 = 0; + int feature_num1 = 0; + + while (42) { + const sensors_feature_data *feature; + int feature_type; + featurelist_t *fl; + + feature = sensors_get_all_features(*chip, &feature_num0, &feature_num1); + + /* Check if all features have been read. */ + if (feature == NULL) + break; + + /* "master features" only */ + if (feature->mapping != SENSORS_NO_MAPPING) { + DEBUG("sensors plugin: sensors_load_conf: " + "Ignoring subfeature `%s', " + "because (feature->mapping " + "!= SENSORS_NO_MAPPING).", + feature->name); + continue; + } + + /* skip ignored in sensors.conf */ + if (sensors_get_ignored(*chip, feature->number) == 0) { + DEBUG("sensors plugin: sensors_load_conf: " + "Ignoring subfeature `%s', " + "because " + "`sensors_get_ignored' told " + "me so.", + feature->name); + continue; + } + + feature_type = sensors_feature_name_to_type(feature->name); + if (feature_type == SENSOR_TYPE_UNKNOWN) { + DEBUG("sensors plugin: sensors_load_conf: " + "Ignoring subfeature `%s', " + "because its type is " + "unknown.", + feature->name); + continue; + } + + fl = calloc(1, sizeof(*fl)); + if (fl == NULL) { + ERROR("sensors plugin: calloc failed."); + continue; + } + + fl->chip = chip; + fl->data = feature; + fl->type = feature_type; + + if (first_feature == NULL) + first_feature = fl; + else + last_feature->next = fl; + last_feature = fl; + } /* while sensors_get_all_features */ + } /* while sensors_get_detected_chips */ /* #endif SENSORS_API_VERSION < 0x400 */ #elif (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500) - chip_num = 0; - while ((chip = sensors_get_detected_chips (NULL, &chip_num)) != NULL) - { - const sensors_feature *feature; - int feature_num = 0; - - while ((feature = sensors_get_features (chip, &feature_num)) != NULL) - { - const sensors_subfeature *subfeature; - int subfeature_num = 0; - - /* Only handle voltage, fanspeeds and temperatures */ - if ((feature->type != SENSORS_FEATURE_IN) - && (feature->type != SENSORS_FEATURE_FAN) - && (feature->type != SENSORS_FEATURE_TEMP) - && (feature->type != SENSORS_FEATURE_POWER)) - { - DEBUG ("sensors plugin: sensors_load_conf: " - "Ignoring feature `%s', " - "because its type is not " - "supported.", feature->name); - continue; - } - - while ((subfeature = sensors_get_all_subfeatures (chip, - feature, &subfeature_num)) != NULL) - { - featurelist_t *fl; - - if ((subfeature->type != SENSORS_SUBFEATURE_IN_INPUT) - && (subfeature->type != SENSORS_SUBFEATURE_FAN_INPUT) - && (subfeature->type != SENSORS_SUBFEATURE_TEMP_INPUT) - && (subfeature->type != SENSORS_SUBFEATURE_POWER_INPUT)) - continue; - - fl = calloc (1, sizeof (*fl)); - if (fl == NULL) - { - ERROR ("sensors plugin: calloc failed."); - continue; - } - - fl->chip = chip; - fl->feature = feature; - fl->subfeature = subfeature; - - if (first_feature == NULL) - first_feature = fl; - else - last_feature->next = fl; - last_feature = fl; - } /* while (subfeature) */ - } /* while (feature) */ - } /* while (chip) */ + chip_num = 0; + while ((chip = sensors_get_detected_chips(NULL, &chip_num)) != NULL) { + const sensors_feature *feature; + int feature_num = 0; + + while ((feature = sensors_get_features(chip, &feature_num)) != NULL) { + const sensors_subfeature *subfeature; + int subfeature_num = 0; + + /* Only handle voltage, fanspeeds and temperatures */ + if ((feature->type != SENSORS_FEATURE_IN) && + (feature->type != SENSORS_FEATURE_FAN) && + (feature->type != SENSORS_FEATURE_TEMP) && + (feature->type != SENSORS_FEATURE_POWER)) { + DEBUG("sensors plugin: sensors_load_conf: " + "Ignoring feature `%s', " + "because its type is not " + "supported.", + feature->name); + continue; + } + + while ((subfeature = sensors_get_all_subfeatures( + chip, feature, &subfeature_num)) != NULL) { + featurelist_t *fl; + + if ((subfeature->type != SENSORS_SUBFEATURE_IN_INPUT) && + (subfeature->type != SENSORS_SUBFEATURE_FAN_INPUT) && + (subfeature->type != SENSORS_SUBFEATURE_TEMP_INPUT) && + (subfeature->type != SENSORS_SUBFEATURE_POWER_INPUT)) + continue; + + fl = calloc(1, sizeof(*fl)); + if (fl == NULL) { + ERROR("sensors plugin: calloc failed."); + continue; + } + + fl->chip = chip; + fl->feature = feature; + fl->subfeature = subfeature; + + if (first_feature == NULL) + first_feature = fl; + else + last_feature->next = fl; + last_feature = fl; + } /* while (subfeature) */ + } /* while (feature) */ + } /* while (chip) */ #endif /* (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500) */ - if (first_feature == NULL) - { - sensors_cleanup (); - INFO ("sensors plugin: lm_sensors reports no " - "features. Data will not be collected."); - return (-1); - } + if (first_feature == NULL) { + sensors_cleanup(); + INFO("sensors plugin: lm_sensors reports no " + "features. Data will not be collected."); + return (-1); + } - return (0); + return (0); } /* int sensors_load_conf */ -static int sensors_shutdown (void) -{ - sensors_free_features (); - ignorelist_free (sensor_list); +static int sensors_shutdown(void) { + sensors_free_features(); + ignorelist_free(sensor_list); - return (0); + return (0); } /* int sensors_shutdown */ -static void sensors_submit (const char *plugin_instance, - const char *type, const char *type_instance, - double value) -{ - char match_key[1024]; - int status; - - value_list_t vl = VALUE_LIST_INIT; - - status = ssnprintf (match_key, sizeof (match_key), "%s/%s-%s", - plugin_instance, type, type_instance); - if (status < 1) - return; - - if (sensor_list != NULL) - { - DEBUG ("sensors plugin: Checking ignorelist for `%s'", match_key); - if (ignorelist_match (sensor_list, match_key)) - return; - } - - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - - sstrncpy (vl.plugin, "sensors", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, plugin_instance, - sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); +static void sensors_submit(const char *plugin_instance, const char *type, + const char *type_instance, double value) { + char match_key[1024]; + int status; + + value_list_t vl = VALUE_LIST_INIT; + + status = ssnprintf(match_key, sizeof(match_key), "%s/%s-%s", plugin_instance, + type, type_instance); + if (status < 1) + return; + + if (sensor_list != NULL) { + DEBUG("sensors plugin: Checking ignorelist for `%s'", match_key); + if (ignorelist_match(sensor_list, match_key)) + return; + } + + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + + sstrncpy(vl.plugin, "sensors", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); } /* void sensors_submit */ -static int sensors_read (void) -{ - if (sensors_load_conf () != 0) - return (-1); +static int sensors_read(void) { + if (sensors_load_conf() != 0) + return (-1); #if SENSORS_API_VERSION < 0x400 - for (featurelist_t *fl = first_feature; fl != NULL; fl = fl->next) - { - double value; - int status; - char plugin_instance[DATA_MAX_NAME_LEN]; - char type_instance[DATA_MAX_NAME_LEN]; - - status = sensors_get_feature (*fl->chip, - fl->data->number, &value); - if (status < 0) - continue; - - status = sensors_snprintf_chip_name (plugin_instance, - sizeof (plugin_instance), fl->chip); - if (status < 0) - continue; - - sstrncpy (type_instance, fl->data->name, - sizeof (type_instance)); - - sensors_submit (plugin_instance, - sensor_type_name_map[fl->type], - type_instance, - value); - } /* for fl = first_feature .. NULL */ + for (featurelist_t *fl = first_feature; fl != NULL; fl = fl->next) { + double value; + int status; + char plugin_instance[DATA_MAX_NAME_LEN]; + char type_instance[DATA_MAX_NAME_LEN]; + + status = sensors_get_feature(*fl->chip, fl->data->number, &value); + if (status < 0) + continue; + + status = sensors_snprintf_chip_name(plugin_instance, + sizeof(plugin_instance), fl->chip); + if (status < 0) + continue; + + sstrncpy(type_instance, fl->data->name, sizeof(type_instance)); + + sensors_submit(plugin_instance, sensor_type_name_map[fl->type], + type_instance, value); + } /* for fl = first_feature .. NULL */ /* #endif SENSORS_API_VERSION < 0x400 */ #elif (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500) - for (featurelist_t *fl = first_feature; fl != NULL; fl = fl->next) - { - double value; - int status; - char plugin_instance[DATA_MAX_NAME_LEN]; - char type_instance[DATA_MAX_NAME_LEN]; - char *sensor_label; - const char *type; - - status = sensors_get_value (fl->chip, - fl->subfeature->number, &value); - if (status < 0) - continue; - - status = sensors_snprintf_chip_name (plugin_instance, - sizeof (plugin_instance), fl->chip); - if (status < 0) - continue; - - if (use_labels) - { - sensor_label = sensors_get_label (fl->chip, fl->feature); - sstrncpy (type_instance, sensor_label, sizeof (type_instance)); - free (sensor_label); - } - else - { - sstrncpy (type_instance, fl->feature->name, - sizeof (type_instance)); - } - - if (fl->feature->type == SENSORS_FEATURE_IN) - type = "voltage"; - else if (fl->feature->type - == SENSORS_FEATURE_FAN) - type = "fanspeed"; - else if (fl->feature->type - == SENSORS_FEATURE_TEMP) - type = "temperature"; - else if (fl->feature->type - == SENSORS_FEATURE_POWER) - type = "power"; - else - continue; - - sensors_submit (plugin_instance, type, type_instance, value); - } /* for fl = first_feature .. NULL */ + for (featurelist_t *fl = first_feature; fl != NULL; fl = fl->next) { + double value; + int status; + char plugin_instance[DATA_MAX_NAME_LEN]; + char type_instance[DATA_MAX_NAME_LEN]; + char *sensor_label; + const char *type; + + status = sensors_get_value(fl->chip, fl->subfeature->number, &value); + if (status < 0) + continue; + + status = sensors_snprintf_chip_name(plugin_instance, + sizeof(plugin_instance), fl->chip); + if (status < 0) + continue; + + if (use_labels) { + sensor_label = sensors_get_label(fl->chip, fl->feature); + sstrncpy(type_instance, sensor_label, sizeof(type_instance)); + free(sensor_label); + } else { + sstrncpy(type_instance, fl->feature->name, sizeof(type_instance)); + } + + if (fl->feature->type == SENSORS_FEATURE_IN) + type = "voltage"; + else if (fl->feature->type == SENSORS_FEATURE_FAN) + type = "fanspeed"; + else if (fl->feature->type == SENSORS_FEATURE_TEMP) + type = "temperature"; + else if (fl->feature->type == SENSORS_FEATURE_POWER) + type = "power"; + else + continue; + + sensors_submit(plugin_instance, type, type_instance, value); + } /* for fl = first_feature .. NULL */ #endif /* (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500) */ - return (0); + return (0); } /* int sensors_read */ -void module_register (void) -{ - plugin_register_config ("sensors", sensors_config, - config_keys, config_keys_num); - plugin_register_read ("sensors", sensors_read); - plugin_register_shutdown ("sensors", sensors_shutdown); +void module_register(void) { + plugin_register_config("sensors", sensors_config, config_keys, + config_keys_num); + plugin_register_read("sensors", sensors_read); + plugin_register_shutdown("sensors", sensors_shutdown); } /* void module_register */ diff --git a/src/serial.c b/src/serial.c index dc868fc2..5057fd3a 100644 --- a/src/serial.c +++ b/src/serial.c @@ -27,95 +27,82 @@ #include "plugin.h" #if !KERNEL_LINUX -# error "No applicable input method." +#error "No applicable input method." #endif -static void serial_submit (const char *type_instance, - derive_t rx, derive_t tx) -{ - value_list_t vl = VALUE_LIST_INIT; - value_t values[] = { - { .derive = rx }, - { .derive = tx }, - }; - - vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - sstrncpy (vl.plugin, "serial", sizeof (vl.plugin)); - sstrncpy (vl.type, "serial_octets", sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, - sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); +static void serial_submit(const char *type_instance, derive_t rx, derive_t tx) { + value_list_t vl = VALUE_LIST_INIT; + value_t values[] = { + {.derive = rx}, {.derive = tx}, + }; + + vl.values = values; + vl.values_len = STATIC_ARRAY_SIZE(values); + sstrncpy(vl.plugin, "serial", sizeof(vl.plugin)); + sstrncpy(vl.type, "serial_octets", sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); } -static int serial_read (void) -{ - FILE *fh; - char buffer[1024]; - - /* there are a variety of names for the serial device */ - if ((fh = fopen ("/proc/tty/driver/serial", "r")) == NULL && - (fh = fopen ("/proc/tty/driver/ttyS", "r")) == NULL) - { - char errbuf[1024]; - WARNING ("serial: fopen: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - derive_t rx = 0; - derive_t tx = 0; - _Bool have_rx = 0, have_tx = 0; - size_t len; - - char *fields[16]; - int numfields; - - numfields = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields)); - if (numfields < 6) - continue; - - /* - * 0: uart:16550A port:000003F8 irq:4 tx:0 rx:0 - * 1: uart:16550A port:000002F8 irq:3 tx:0 rx:0 - */ - len = strlen (fields[0]); - if (len < 2) - continue; - if (fields[0][len - 1] != ':') - continue; - fields[0][len - 1] = 0; - - for (int i = 1; i < numfields; i++) - { - len = strlen (fields[i]); - if (len < 4) - continue; - - if (strncmp (fields[i], "tx:", 3) == 0) - { - if (strtoderive (fields[i] + 3, &tx) == 0) - have_tx = 1; - } - else if (strncmp (fields[i], "rx:", 3) == 0) - { - if (strtoderive (fields[i] + 3, &rx) == 0) - have_rx = 1; - } - } - - if (have_rx && have_tx) - serial_submit (fields[0], rx, tx); - } - - fclose (fh); - return (0); +static int serial_read(void) { + FILE *fh; + char buffer[1024]; + + /* there are a variety of names for the serial device */ + if ((fh = fopen("/proc/tty/driver/serial", "r")) == NULL && + (fh = fopen("/proc/tty/driver/ttyS", "r")) == NULL) { + char errbuf[1024]; + WARNING("serial: fopen: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + derive_t rx = 0; + derive_t tx = 0; + _Bool have_rx = 0, have_tx = 0; + size_t len; + + char *fields[16]; + int numfields; + + numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + if (numfields < 6) + continue; + + /* + * 0: uart:16550A port:000003F8 irq:4 tx:0 rx:0 + * 1: uart:16550A port:000002F8 irq:3 tx:0 rx:0 + */ + len = strlen(fields[0]); + if (len < 2) + continue; + if (fields[0][len - 1] != ':') + continue; + fields[0][len - 1] = 0; + + for (int i = 1; i < numfields; i++) { + len = strlen(fields[i]); + if (len < 4) + continue; + + if (strncmp(fields[i], "tx:", 3) == 0) { + if (strtoderive(fields[i] + 3, &tx) == 0) + have_tx = 1; + } else if (strncmp(fields[i], "rx:", 3) == 0) { + if (strtoderive(fields[i] + 3, &rx) == 0) + have_rx = 1; + } + } + + if (have_rx && have_tx) + serial_submit(fields[0], rx, tx); + } + + fclose(fh); + return (0); } /* int serial_read */ -void module_register (void) -{ - plugin_register_read ("serial", serial_read); +void module_register(void) { + plugin_register_read("serial", serial_read); } /* void module_register */ diff --git a/src/sigrok.c b/src/sigrok.c index 6a8003c0..44920ada 100644 --- a/src/sigrok.c +++ b/src/sigrok.c @@ -44,353 +44,336 @@ static int loglevel = SR_LOG_WARN; static struct sr_context *sr_ctx; struct config_device { - char *name; - char *driver; - char *conn; - char *serialcomm; - struct sr_dev_inst *sdi; - cdtime_t min_dispatch_interval; - cdtime_t last_dispatch; + char *name; + char *driver; + char *conn; + char *serialcomm; + struct sr_dev_inst *sdi; + cdtime_t min_dispatch_interval; + cdtime_t last_dispatch; }; +static int sigrok_log_callback(void *cb_data __attribute__((unused)), + int msg_loglevel, const char *format, + va_list args) { + char s[512]; -static int sigrok_log_callback(void*cb_data __attribute__((unused)), - int msg_loglevel, const char *format, va_list args) -{ - char s[512]; + if (msg_loglevel <= loglevel) { + vsnprintf(s, 512, format, args); + plugin_log(LOG_INFO, "sigrok plugin: %s", s); + } - if (msg_loglevel <= loglevel) { - vsnprintf(s, 512, format, args); - plugin_log(LOG_INFO, "sigrok plugin: %s", s); - } - - return 0; + return 0; } -static int sigrok_config_device(oconfig_item_t *ci) -{ - struct config_device *cfdev; - - if (!(cfdev = calloc(1, sizeof(*cfdev)))) { - ERROR("sigrok plugin: calloc failed."); - return -1; - } - if (cf_util_get_string(ci, &cfdev->name)) { - free(cfdev); - WARNING("sigrok plugin: Invalid device name."); - return -1; - } - cfdev->min_dispatch_interval = DEFAULT_MIN_DISPATCH_INTERVAL; - - for (int i = 0; i < ci->children_num; i++) { - oconfig_item_t *item = ci->children + i; - if (!strcasecmp(item->key, "driver")) - cf_util_get_string(item, &cfdev->driver); - else if (!strcasecmp(item->key, "conn")) - cf_util_get_string(item, &cfdev->conn); - else if (!strcasecmp(item->key, "serialcomm")) - cf_util_get_string(item, &cfdev->serialcomm); - else if (!strcasecmp(item->key, "minimuminterval")) - cf_util_get_cdtime(item, &cfdev->min_dispatch_interval); - else - WARNING("sigrok plugin: Invalid keyword \"%s\".", - item->key); - } - - config_devices = g_slist_append(config_devices, cfdev); - - return 0; +static int sigrok_config_device(oconfig_item_t *ci) { + struct config_device *cfdev; + + if (!(cfdev = calloc(1, sizeof(*cfdev)))) { + ERROR("sigrok plugin: calloc failed."); + return -1; + } + if (cf_util_get_string(ci, &cfdev->name)) { + free(cfdev); + WARNING("sigrok plugin: Invalid device name."); + return -1; + } + cfdev->min_dispatch_interval = DEFAULT_MIN_DISPATCH_INTERVAL; + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *item = ci->children + i; + if (!strcasecmp(item->key, "driver")) + cf_util_get_string(item, &cfdev->driver); + else if (!strcasecmp(item->key, "conn")) + cf_util_get_string(item, &cfdev->conn); + else if (!strcasecmp(item->key, "serialcomm")) + cf_util_get_string(item, &cfdev->serialcomm); + else if (!strcasecmp(item->key, "minimuminterval")) + cf_util_get_cdtime(item, &cfdev->min_dispatch_interval); + else + WARNING("sigrok plugin: Invalid keyword \"%s\".", item->key); + } + + config_devices = g_slist_append(config_devices, cfdev); + + return 0; } -static int sigrok_config(oconfig_item_t *ci) -{ - for (int i = 0; i < ci->children_num; i++) { - oconfig_item_t *item = ci->children + i; - if (strcasecmp("LogLevel", item->key) == 0) { - int status; - int tmp = -1; - - status = cf_util_get_int (item, &tmp); - if (status != 0) - continue; - else if ((tmp < 0) || (tmp > 5)) { - ERROR ("sigrok plugin: The \"LogLevel\" " - "configuration option expects " - "an integer between 0 and 5 " - "(inclusive); you provided %i.", - tmp); - continue; - } - loglevel = tmp; - } else if (!strcasecmp(item->key, "Device")) - sigrok_config_device(item); - else - WARNING("sigrok plugin: Invalid keyword \"%s\".", - item->key); - } - - return 0; +static int sigrok_config(oconfig_item_t *ci) { + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *item = ci->children + i; + if (strcasecmp("LogLevel", item->key) == 0) { + int status; + int tmp = -1; + + status = cf_util_get_int(item, &tmp); + if (status != 0) + continue; + else if ((tmp < 0) || (tmp > 5)) { + ERROR("sigrok plugin: The \"LogLevel\" " + "configuration option expects " + "an integer between 0 and 5 " + "(inclusive); you provided %i.", + tmp); + continue; + } + loglevel = tmp; + } else if (!strcasecmp(item->key, "Device")) + sigrok_config_device(item); + else + WARNING("sigrok plugin: Invalid keyword \"%s\".", item->key); + } + + return 0; } -static const char *sigrok_value_type(const struct sr_datafeed_analog *analog) -{ - const char *s; - - if (analog->mq == SR_MQ_VOLTAGE) - s = "voltage"; - else if (analog->mq == SR_MQ_CURRENT) - s = "current"; - else if (analog->mq == SR_MQ_FREQUENCY) - s = "frequency"; - else if (analog->mq == SR_MQ_POWER) - s = "power"; - else if (analog->mq == SR_MQ_TEMPERATURE) - s = "temperature"; - else if (analog->mq == SR_MQ_RELATIVE_HUMIDITY) - s = "humidity"; - else if (analog->mq == SR_MQ_SOUND_PRESSURE_LEVEL) - s = "spl"; - else - s = "gauge"; - - return s; +static const char *sigrok_value_type(const struct sr_datafeed_analog *analog) { + const char *s; + + if (analog->mq == SR_MQ_VOLTAGE) + s = "voltage"; + else if (analog->mq == SR_MQ_CURRENT) + s = "current"; + else if (analog->mq == SR_MQ_FREQUENCY) + s = "frequency"; + else if (analog->mq == SR_MQ_POWER) + s = "power"; + else if (analog->mq == SR_MQ_TEMPERATURE) + s = "temperature"; + else if (analog->mq == SR_MQ_RELATIVE_HUMIDITY) + s = "humidity"; + else if (analog->mq == SR_MQ_SOUND_PRESSURE_LEVEL) + s = "spl"; + else + s = "gauge"; + + return s; } static void sigrok_feed_callback(const struct sr_dev_inst *sdi, - const struct sr_datafeed_packet *packet, void *cb_data) -{ - const struct sr_datafeed_analog *analog; - struct config_device *cfdev; - value_list_t vl = VALUE_LIST_INIT; - - /* Find this device's configuration. */ - cfdev = NULL; - for (GSList *l = config_devices; l; l = l->next) { - cfdev = l->data; - if (cfdev->sdi == sdi) { - /* Found it. */ - break; - } - cfdev = NULL; - } - - if (!cfdev) { - ERROR("sigrok plugin: Received data from driver \"%s\" but " - "can't find a configuration / device matching " - "it.", sdi->driver->name); - return; - } - - if (packet->type == SR_DF_END) { - /* TODO: try to restart acquisition after a delay? */ - WARNING("sigrok plugin: acquisition for \"%s\" ended.", - cfdev->name); - return; - } - - if (packet->type != SR_DF_ANALOG) - return; - - if ((cfdev->min_dispatch_interval != 0) - && ((cdtime() - cfdev->last_dispatch) - < cfdev->min_dispatch_interval)) - return; - - /* Ignore all but the first sample on the first probe. */ - analog = packet->payload; - vl.values = &(value_t) { .gauge = analog->data[0] }; - vl.values_len = 1; - sstrncpy(vl.plugin, "sigrok", sizeof(vl.plugin)); - sstrncpy(vl.plugin_instance, cfdev->name, sizeof(vl.plugin_instance)); - sstrncpy(vl.type, sigrok_value_type(analog), sizeof(vl.type)); - - plugin_dispatch_values(&vl); - cfdev->last_dispatch = cdtime(); + const struct sr_datafeed_packet *packet, + void *cb_data) { + const struct sr_datafeed_analog *analog; + struct config_device *cfdev; + value_list_t vl = VALUE_LIST_INIT; + + /* Find this device's configuration. */ + cfdev = NULL; + for (GSList *l = config_devices; l; l = l->next) { + cfdev = l->data; + if (cfdev->sdi == sdi) { + /* Found it. */ + break; + } + cfdev = NULL; + } + + if (!cfdev) { + ERROR("sigrok plugin: Received data from driver \"%s\" but " + "can't find a configuration / device matching " + "it.", + sdi->driver->name); + return; + } + + if (packet->type == SR_DF_END) { + /* TODO: try to restart acquisition after a delay? */ + WARNING("sigrok plugin: acquisition for \"%s\" ended.", cfdev->name); + return; + } + + if (packet->type != SR_DF_ANALOG) + return; + + if ((cfdev->min_dispatch_interval != 0) && + ((cdtime() - cfdev->last_dispatch) < cfdev->min_dispatch_interval)) + return; + + /* Ignore all but the first sample on the first probe. */ + analog = packet->payload; + vl.values = &(value_t){.gauge = analog->data[0]}; + vl.values_len = 1; + sstrncpy(vl.plugin, "sigrok", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, cfdev->name, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, sigrok_value_type(analog), sizeof(vl.type)); + + plugin_dispatch_values(&vl); + cfdev->last_dispatch = cdtime(); } -static void sigrok_free_drvopts(struct sr_config *src) -{ - g_variant_unref(src->data); - g_free(src); +static void sigrok_free_drvopts(struct sr_config *src) { + g_variant_unref(src->data); + g_free(src); } static int sigrok_init_driver(struct config_device *cfdev, - struct sr_dev_driver *drv) -{ - struct sr_config *src; - GSList *devlist, *drvopts; - char hwident[512]; - - if (sr_driver_init(sr_ctx, drv) != SR_OK) - /* Error was logged by libsigrok. */ - return -1; - - drvopts = NULL; - if (cfdev->conn) { - if (!(src = malloc(sizeof(*src)))) - return -1; - src->key = SR_CONF_CONN; - src->data = g_variant_new_string(cfdev->conn); - drvopts = g_slist_append(drvopts, src); - } - if (cfdev->serialcomm) { - if (!(src = malloc(sizeof(*src)))) - return -1; - src->key = SR_CONF_SERIALCOMM; - src->data = g_variant_new_string(cfdev->serialcomm); - drvopts = g_slist_append(drvopts, src); - } - devlist = sr_driver_scan(drv, drvopts); - g_slist_free_full(drvopts, (GDestroyNotify)sigrok_free_drvopts); - if (!devlist) { - /* Not an error, but the user should know about it. */ - WARNING("sigrok plugin: No device found for \"%s\".", - cfdev->name); - return 0; - } - - if (g_slist_length(devlist) > 1) { - INFO("sigrok plugin: %d sigrok devices for device entry " - "\"%s\": must be 1.", - g_slist_length(devlist), cfdev->name); - return -1; - } - cfdev->sdi = devlist->data; - g_slist_free(devlist); - ssnprintf(hwident, sizeof(hwident), "%s %s %s", - cfdev->sdi->vendor ? cfdev->sdi->vendor : "", - cfdev->sdi->model ? cfdev->sdi->model : "", - cfdev->sdi->version ? cfdev->sdi->version : ""); - INFO("sigrok plugin: Device \"%s\" is a %s", cfdev->name, hwident); - - if (sr_dev_open(cfdev->sdi) != SR_OK) - return -1; - - if (sr_session_dev_add(cfdev->sdi) != SR_OK) - return -1; - - return 1; + struct sr_dev_driver *drv) { + struct sr_config *src; + GSList *devlist, *drvopts; + char hwident[512]; + + if (sr_driver_init(sr_ctx, drv) != SR_OK) + /* Error was logged by libsigrok. */ + return -1; + + drvopts = NULL; + if (cfdev->conn) { + if (!(src = malloc(sizeof(*src)))) + return -1; + src->key = SR_CONF_CONN; + src->data = g_variant_new_string(cfdev->conn); + drvopts = g_slist_append(drvopts, src); + } + if (cfdev->serialcomm) { + if (!(src = malloc(sizeof(*src)))) + return -1; + src->key = SR_CONF_SERIALCOMM; + src->data = g_variant_new_string(cfdev->serialcomm); + drvopts = g_slist_append(drvopts, src); + } + devlist = sr_driver_scan(drv, drvopts); + g_slist_free_full(drvopts, (GDestroyNotify)sigrok_free_drvopts); + if (!devlist) { + /* Not an error, but the user should know about it. */ + WARNING("sigrok plugin: No device found for \"%s\".", cfdev->name); + return 0; + } + + if (g_slist_length(devlist) > 1) { + INFO("sigrok plugin: %d sigrok devices for device entry " + "\"%s\": must be 1.", + g_slist_length(devlist), cfdev->name); + return -1; + } + cfdev->sdi = devlist->data; + g_slist_free(devlist); + ssnprintf(hwident, sizeof(hwident), "%s %s %s", + cfdev->sdi->vendor ? cfdev->sdi->vendor : "", + cfdev->sdi->model ? cfdev->sdi->model : "", + cfdev->sdi->version ? cfdev->sdi->version : ""); + INFO("sigrok plugin: Device \"%s\" is a %s", cfdev->name, hwident); + + if (sr_dev_open(cfdev->sdi) != SR_OK) + return -1; + + if (sr_session_dev_add(cfdev->sdi) != SR_OK) + return -1; + + return 1; } -static void *sigrok_read_thread(void *arg __attribute__((unused))) -{ - struct sr_dev_driver *drv, **drvlist; - GSList *l; - struct config_device *cfdev; - int ret, i; - - sr_log_callback_set(sigrok_log_callback, NULL); - sr_log_loglevel_set(loglevel); - - if ((ret = sr_init(&sr_ctx)) != SR_OK) { - ERROR("sigrok plugin: Failed to initialize libsigrok: %s.", - sr_strerror(ret)); - return NULL; - } - - if (!sr_session_new()) - return NULL; - - num_devices = 0; - drvlist = sr_driver_list(); - for (l = config_devices; l; l = l->next) { - cfdev = l->data; - drv = NULL; - for (i = 0; drvlist[i]; i++) { - if (!strcmp(drvlist[i]->name, cfdev->driver)) { - drv = drvlist[i]; - break; - } - } - if (!drv) { - ERROR("sigrok plugin: Unknown driver \"%s\".", - cfdev->driver); - return NULL; - } - - if ((ret = sigrok_init_driver(cfdev, drv)) < 0) - /* Error was already logged. */ - return NULL; - - num_devices += ret; - } - - if (num_devices > 0) { - /* Do this only when we're sure there's hardware to talk to. */ - if (sr_session_datafeed_callback_add(sigrok_feed_callback, NULL) - != SR_OK) - return NULL; - - /* Start acquisition on all devices. */ - if (sr_session_start() != SR_OK) - return NULL; - - /* Main loop, runs forever. */ - sr_session_run(); - - sr_session_stop(); - sr_session_dev_remove_all(); - } - - sr_session_destroy(); - - sr_exit(sr_ctx); - - pthread_exit(NULL); - sr_thread_running = FALSE; - - return NULL; +static void *sigrok_read_thread(void *arg __attribute__((unused))) { + struct sr_dev_driver *drv, **drvlist; + GSList *l; + struct config_device *cfdev; + int ret, i; + + sr_log_callback_set(sigrok_log_callback, NULL); + sr_log_loglevel_set(loglevel); + + if ((ret = sr_init(&sr_ctx)) != SR_OK) { + ERROR("sigrok plugin: Failed to initialize libsigrok: %s.", + sr_strerror(ret)); + return NULL; + } + + if (!sr_session_new()) + return NULL; + + num_devices = 0; + drvlist = sr_driver_list(); + for (l = config_devices; l; l = l->next) { + cfdev = l->data; + drv = NULL; + for (i = 0; drvlist[i]; i++) { + if (!strcmp(drvlist[i]->name, cfdev->driver)) { + drv = drvlist[i]; + break; + } + } + if (!drv) { + ERROR("sigrok plugin: Unknown driver \"%s\".", cfdev->driver); + return NULL; + } + + if ((ret = sigrok_init_driver(cfdev, drv)) < 0) + /* Error was already logged. */ + return NULL; + + num_devices += ret; + } + + if (num_devices > 0) { + /* Do this only when we're sure there's hardware to talk to. */ + if (sr_session_datafeed_callback_add(sigrok_feed_callback, NULL) != SR_OK) + return NULL; + + /* Start acquisition on all devices. */ + if (sr_session_start() != SR_OK) + return NULL; + + /* Main loop, runs forever. */ + sr_session_run(); + + sr_session_stop(); + sr_session_dev_remove_all(); + } + + sr_session_destroy(); + + sr_exit(sr_ctx); + + pthread_exit(NULL); + sr_thread_running = FALSE; + + return NULL; } -static int sigrok_init(void) -{ - int status; - - if (sr_thread_running) { - ERROR("sigrok plugin: Thread already running."); - return -1; - } - - status = plugin_thread_create(&sr_thread, NULL, sigrok_read_thread, - NULL, "sigrok read"); - if (status != 0) - { - char errbuf[1024]; - ERROR("sigrok plugin: Failed to create thread: %s.", - sstrerror (errno, errbuf, sizeof (errbuf))); - return -1; - } - sr_thread_running = TRUE; - - return 0; +static int sigrok_init(void) { + int status; + + if (sr_thread_running) { + ERROR("sigrok plugin: Thread already running."); + return -1; + } + + status = plugin_thread_create(&sr_thread, NULL, sigrok_read_thread, NULL, + "sigrok read"); + if (status != 0) { + char errbuf[1024]; + ERROR("sigrok plugin: Failed to create thread: %s.", + sstrerror(errno, errbuf, sizeof(errbuf))); + return -1; + } + sr_thread_running = TRUE; + + return 0; } -static int sigrok_shutdown(void) -{ - struct config_device *cfdev; - GSList *l; - - if (sr_thread_running) { - pthread_cancel(sr_thread); - pthread_join(sr_thread, NULL); - } - - for (l = config_devices; l; l = l->next) { - cfdev = l->data; - free(cfdev->name); - free(cfdev->driver); - free(cfdev->conn); - free(cfdev->serialcomm); - free(cfdev); - } - g_slist_free(config_devices); - - return 0; +static int sigrok_shutdown(void) { + struct config_device *cfdev; + GSList *l; + + if (sr_thread_running) { + pthread_cancel(sr_thread); + pthread_join(sr_thread, NULL); + } + + for (l = config_devices; l; l = l->next) { + cfdev = l->data; + free(cfdev->name); + free(cfdev->driver); + free(cfdev->conn); + free(cfdev->serialcomm); + free(cfdev); + } + g_slist_free(config_devices); + + return 0; } -void module_register(void) -{ - plugin_register_complex_config("sigrok", sigrok_config); - plugin_register_init("sigrok", sigrok_init); - plugin_register_shutdown("sigrok", sigrok_shutdown); +void module_register(void) { + plugin_register_complex_config("sigrok", sigrok_config); + plugin_register_init("sigrok", sigrok_init); + plugin_register_shutdown("sigrok", sigrok_shutdown); } diff --git a/src/smart.c b/src/smart.c index 285eb860..373839e1 100644 --- a/src/smart.c +++ b/src/smart.c @@ -33,74 +33,58 @@ #include #include -static const char *config_keys[] = -{ - "Disk", - "IgnoreSelected", - "IgnoreSleepMode", - "UseSerial" -}; +static const char *config_keys[] = {"Disk", "IgnoreSelected", "IgnoreSleepMode", + "UseSerial"}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static ignorelist_t *ignorelist = NULL; static int ignore_sleep_mode = 0; static int use_serial = 0; -static int smart_config (const char *key, const char *value) -{ +static int smart_config(const char *key, const char *value) { if (ignorelist == NULL) - ignorelist = ignorelist_create (/* invert = */ 1); + ignorelist = ignorelist_create(/* invert = */ 1); if (ignorelist == NULL) return (1); - if (strcasecmp ("Disk", key) == 0) - { - ignorelist_add (ignorelist, value); - } - else if (strcasecmp ("IgnoreSelected", key) == 0) - { + if (strcasecmp("Disk", key) == 0) { + ignorelist_add(ignorelist, value); + } else if (strcasecmp("IgnoreSelected", key) == 0) { int invert = 1; - if (IS_TRUE (value)) + if (IS_TRUE(value)) invert = 0; - ignorelist_set_invert (ignorelist, invert); - } - else if (strcasecmp ("IgnoreSleepMode", key) == 0) - { - if (IS_TRUE (value)) + ignorelist_set_invert(ignorelist, invert); + } else if (strcasecmp("IgnoreSleepMode", key) == 0) { + if (IS_TRUE(value)) ignore_sleep_mode = 1; - } - else if (strcasecmp ("UseSerial", key) == 0) - { - if (IS_TRUE (value)) + } else if (strcasecmp("UseSerial", key) == 0) { + if (IS_TRUE(value)) use_serial = 1; - } - else - { + } else { return (-1); } return (0); } /* int smart_config */ -static void smart_submit (const char *dev, const char *type, - const char *type_inst, double value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void smart_submit(const char *dev, const char *type, + const char *type_inst, double value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "smart", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance)); + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "smart", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, dev, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, type_inst, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static void smart_handle_disk_attribute(SkDisk *d, const SkSmartAttributeParsedData *a, - void* userdata) -{ +static void smart_handle_disk_attribute(SkDisk *d, + const SkSmartAttributeParsedData *a, + void *userdata) { const char *dev = userdata; if (!a->current_value_valid || !a->worst_value_valid) @@ -108,43 +92,35 @@ static void smart_handle_disk_attribute(SkDisk *d, const SkSmartAttributeParsedD value_list_t vl = VALUE_LIST_INIT; value_t values[] = { - { .gauge = a->current_value }, - { .gauge = a->worst_value }, - { .gauge = a->threshold_valid ? a->threshold : 0 }, - { .gauge = a->pretty_value }, + {.gauge = a->current_value}, + {.gauge = a->worst_value}, + {.gauge = a->threshold_valid ? a->threshold : 0}, + {.gauge = a->pretty_value}, }; vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - sstrncpy (vl.plugin, "smart", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, "smart_attribute", sizeof (vl.type)); - sstrncpy (vl.type_instance, a->name, sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); - - if (a->threshold_valid && a->current_value <= a->threshold) - { - notification_t notif = { NOTIF_WARNING, - cdtime (), - "", - "", - "smart", "", - "smart_attribute", - "", - NULL }; - sstrncpy (notif.host, hostname_g, sizeof (notif.host)); - sstrncpy (notif.plugin_instance, dev, sizeof (notif.plugin_instance)); - sstrncpy (notif.type_instance, a->name, sizeof (notif.type_instance)); - ssnprintf (notif.message, sizeof (notif.message), - "attribute %s is below allowed threshold (%d < %d)", - a->name, a->current_value, a->threshold); - plugin_dispatch_notification (¬if); + vl.values_len = STATIC_ARRAY_SIZE(values); + sstrncpy(vl.plugin, "smart", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, dev, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "smart_attribute", sizeof(vl.type)); + sstrncpy(vl.type_instance, a->name, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); + + if (a->threshold_valid && a->current_value <= a->threshold) { + notification_t notif = {NOTIF_WARNING, cdtime(), "", "", "smart", "", + "smart_attribute", "", NULL}; + sstrncpy(notif.host, hostname_g, sizeof(notif.host)); + sstrncpy(notif.plugin_instance, dev, sizeof(notif.plugin_instance)); + sstrncpy(notif.type_instance, a->name, sizeof(notif.type_instance)); + ssnprintf(notif.message, sizeof(notif.message), + "attribute %s is below allowed threshold (%d < %d)", a->name, + a->current_value, a->threshold); + plugin_dispatch_notification(¬if); } } -static void smart_handle_disk (const char *dev, const char *serial) -{ +static void smart_handle_disk(const char *dev, const char *serial) { SkDisk *d = NULL; SkBool awake = FALSE; SkBool available = FALSE; @@ -152,105 +128,82 @@ static void smart_handle_disk (const char *dev, const char *serial) const SkSmartParsedData *spd; uint64_t poweron, powercycles, badsectors, temperature; - if (use_serial && serial) - { + if (use_serial && serial) { shortname = serial; - } - else - { + } else { shortname = strrchr(dev, '/'); - if (!shortname) return; + if (!shortname) + return; shortname++; } - if (ignorelist_match (ignorelist, shortname) != 0) { - DEBUG ("smart plugin: ignoring %s.", dev); + if (ignorelist_match(ignorelist, shortname) != 0) { + DEBUG("smart plugin: ignoring %s.", dev); return; } - DEBUG ("smart plugin: checking SMART status of %s.", - dev); + DEBUG("smart plugin: checking SMART status of %s.", dev); - if (sk_disk_open (dev, &d) < 0) - { - ERROR ("smart plugin: unable to open %s.", dev); + if (sk_disk_open(dev, &d) < 0) { + ERROR("smart plugin: unable to open %s.", dev); return; } - if (sk_disk_identify_is_available (d, &available) < 0 || !available) - { - DEBUG ("smart plugin: disk %s cannot be identified.", dev); + if (sk_disk_identify_is_available(d, &available) < 0 || !available) { + DEBUG("smart plugin: disk %s cannot be identified.", dev); goto end; } - if (sk_disk_smart_is_available (d, &available) < 0 || !available) - { - DEBUG ("smart plugin: disk %s has no SMART support.", dev); + if (sk_disk_smart_is_available(d, &available) < 0 || !available) { + DEBUG("smart plugin: disk %s has no SMART support.", dev); goto end; } - if (!ignore_sleep_mode) - { - if (sk_disk_check_sleep_mode (d, &awake) < 0 || !awake) - { - DEBUG ("smart plugin: disk %s is sleeping.", dev); + if (!ignore_sleep_mode) { + if (sk_disk_check_sleep_mode(d, &awake) < 0 || !awake) { + DEBUG("smart plugin: disk %s is sleeping.", dev); goto end; } } - if (sk_disk_smart_read_data (d) < 0) - { - ERROR ("smart plugin: unable to get SMART data for disk %s.", dev); + if (sk_disk_smart_read_data(d) < 0) { + ERROR("smart plugin: unable to get SMART data for disk %s.", dev); goto end; } - if (sk_disk_smart_parse (d, &spd) < 0) - { - ERROR ("smart plugin: unable to parse SMART data for disk %s.", dev); + if (sk_disk_smart_parse(d, &spd) < 0) { + ERROR("smart plugin: unable to parse SMART data for disk %s.", dev); goto end; } /* Get some specific values */ - if (sk_disk_smart_get_power_on (d, &poweron) < 0) - { - WARNING ("smart plugin: unable to get milliseconds since power on for %s.", - dev); - } - else - smart_submit (shortname, "smart_poweron", "", poweron / 1000.); - - if (sk_disk_smart_get_power_cycle (d, &powercycles) < 0) - { - WARNING ("smart plugin: unable to get number of power cycles for %s.", - dev); - } - else - smart_submit (shortname, "smart_powercycles", "", powercycles); - - if (sk_disk_smart_get_bad (d, &badsectors) < 0) - { - WARNING ("smart plugin: unable to get number of bad sectors for %s.", - dev); - } - else - smart_submit (shortname, "smart_badsectors", "", badsectors); - - if (sk_disk_smart_get_temperature (d, &temperature) < 0) - { - WARNING ("smart plugin: unable to get temperature for %s.", - dev); - } - else - smart_submit (shortname, "smart_temperature", "", temperature / 1000. - 273.15); + if (sk_disk_smart_get_power_on(d, &poweron) < 0) { + WARNING("smart plugin: unable to get milliseconds since power on for %s.", + dev); + } else + smart_submit(shortname, "smart_poweron", "", poweron / 1000.); + + if (sk_disk_smart_get_power_cycle(d, &powercycles) < 0) { + WARNING("smart plugin: unable to get number of power cycles for %s.", dev); + } else + smart_submit(shortname, "smart_powercycles", "", powercycles); + + if (sk_disk_smart_get_bad(d, &badsectors) < 0) { + WARNING("smart plugin: unable to get number of bad sectors for %s.", dev); + } else + smart_submit(shortname, "smart_badsectors", "", badsectors); + + if (sk_disk_smart_get_temperature(d, &temperature) < 0) { + WARNING("smart plugin: unable to get temperature for %s.", dev); + } else + smart_submit(shortname, "smart_temperature", "", + temperature / 1000. - 273.15); /* Grab all attributes */ if (sk_disk_smart_parse_attributes(d, smart_handle_disk_attribute, - (char *)shortname) < 0) - { - ERROR ("smart plugin: unable to handle SMART attributes for %s.", - dev); + (char *)shortname) < 0) { + ERROR("smart plugin: unable to handle SMART attributes for %s.", dev); } end: sk_disk_free(d); } -static int smart_read (void) -{ +static int smart_read(void) { struct udev *handle_udev; struct udev_enumerate *enumerate; struct udev_list_entry *devices, *dev_list_entry; @@ -258,38 +211,34 @@ static int smart_read (void) /* Use udev to get a list of disks */ handle_udev = udev_new(); - if (!handle_udev) - { - ERROR ("smart plugin: unable to initialize udev."); + if (!handle_udev) { + ERROR("smart plugin: unable to initialize udev."); return (-1); } - enumerate = udev_enumerate_new (handle_udev); - udev_enumerate_add_match_subsystem (enumerate, "block"); - udev_enumerate_add_match_property (enumerate, "DEVTYPE", "disk"); - udev_enumerate_scan_devices (enumerate); - devices = udev_enumerate_get_list_entry (enumerate); - udev_list_entry_foreach (dev_list_entry, devices) - { + enumerate = udev_enumerate_new(handle_udev); + udev_enumerate_add_match_subsystem(enumerate, "block"); + udev_enumerate_add_match_property(enumerate, "DEVTYPE", "disk"); + udev_enumerate_scan_devices(enumerate); + devices = udev_enumerate_get_list_entry(enumerate); + udev_list_entry_foreach(dev_list_entry, devices) { const char *path, *devpath, *serial; - path = udev_list_entry_get_name (dev_list_entry); - dev = udev_device_new_from_syspath (handle_udev, path); - devpath = udev_device_get_devnode (dev); - serial = udev_device_get_property_value (dev, "ID_SERIAL"); + path = udev_list_entry_get_name(dev_list_entry); + dev = udev_device_new_from_syspath(handle_udev, path); + devpath = udev_device_get_devnode(dev); + serial = udev_device_get_property_value(dev, "ID_SERIAL"); /* Query status with libatasmart */ - smart_handle_disk (devpath, serial); - udev_device_unref (dev); + smart_handle_disk(devpath, serial); + udev_device_unref(dev); } - udev_enumerate_unref (enumerate); - udev_unref (handle_udev); + udev_enumerate_unref(enumerate); + udev_unref(handle_udev); return (0); } /* int smart_read */ -void module_register (void) -{ - plugin_register_config ("smart", smart_config, - config_keys, config_keys_num); - plugin_register_read ("smart", smart_read); +void module_register(void) { + plugin_register_config("smart", smart_config, config_keys, config_keys_num); + plugin_register_read("smart", smart_read); } /* void module_register */ diff --git a/src/snmp.c b/src/snmp.c index d80ee922..3bfec47d 100644 --- a/src/snmp.c +++ b/src/snmp.c @@ -38,22 +38,19 @@ /* * Private data structes */ -struct oid_s -{ +struct oid_s { oid oid[MAX_OID_LEN]; size_t oid_len; }; typedef struct oid_s oid_t; -union instance_u -{ - char string[DATA_MAX_NAME_LEN]; +union instance_u { + char string[DATA_MAX_NAME_LEN]; oid_t oid; }; typedef union instance_u instance_t; -struct data_definition_s -{ +struct data_definition_s { char *name; /* used to reference this from the `Collect' option */ char *type; /* used to find the data_set */ _Bool is_table; @@ -70,8 +67,7 @@ struct data_definition_s }; typedef struct data_definition_s data_definition_t; -struct host_definition_s -{ +struct host_definition_s { char *name; char *address; int version; @@ -100,16 +96,14 @@ typedef struct host_definition_s host_definition_t; /* These two types are used to cache values in `csnmp_read_table' to handle * gaps in tables. */ -struct csnmp_list_instances_s -{ +struct csnmp_list_instances_s { oid_t suffix; char instance[DATA_MAX_NAME_LEN]; struct csnmp_list_instances_s *next; }; typedef struct csnmp_list_instances_s csnmp_list_instances_t; -struct csnmp_table_values_s -{ +struct csnmp_table_values_s { oid_t suffix; value_t value; struct csnmp_table_values_s *next; @@ -124,68 +118,61 @@ static data_definition_t *data_head = NULL; /* * Prototypes */ -static int csnmp_read_host (user_data_t *ud); +static int csnmp_read_host(user_data_t *ud); /* * Private functions */ -static void csnmp_oid_init (oid_t *dst, oid const *src, size_t n) -{ - assert (n <= STATIC_ARRAY_SIZE (dst->oid)); - memcpy (dst->oid, src, sizeof (*src) * n); +static void csnmp_oid_init(oid_t *dst, oid const *src, size_t n) { + assert(n <= STATIC_ARRAY_SIZE(dst->oid)); + memcpy(dst->oid, src, sizeof(*src) * n); dst->oid_len = n; } -static int csnmp_oid_compare (oid_t const *left, oid_t const *right) -{ - return (snmp_oid_compare (left->oid, left->oid_len, - right->oid, right->oid_len)); +static int csnmp_oid_compare(oid_t const *left, oid_t const *right) { + return ( + snmp_oid_compare(left->oid, left->oid_len, right->oid, right->oid_len)); } -static int csnmp_oid_suffix (oid_t *dst, oid_t const *src, - oid_t const *root) -{ +static int csnmp_oid_suffix(oid_t *dst, oid_t const *src, oid_t const *root) { /* Make sure "src" is in "root"s subtree. */ if (src->oid_len <= root->oid_len) return (EINVAL); - if (snmp_oid_ncompare (root->oid, root->oid_len, - src->oid, src->oid_len, - /* n = */ root->oid_len) != 0) + if (snmp_oid_ncompare(root->oid, root->oid_len, src->oid, src->oid_len, + /* n = */ root->oid_len) != 0) return (EINVAL); - memset (dst, 0, sizeof (*dst)); + memset(dst, 0, sizeof(*dst)); dst->oid_len = src->oid_len - root->oid_len; - memcpy (dst->oid, &src->oid[root->oid_len], - dst->oid_len * sizeof (dst->oid[0])); + memcpy(dst->oid, &src->oid[root->oid_len], + dst->oid_len * sizeof(dst->oid[0])); return (0); } -static int csnmp_oid_to_string (char *buffer, size_t buffer_size, - oid_t const *o) -{ +static int csnmp_oid_to_string(char *buffer, size_t buffer_size, + oid_t const *o) { char oid_str[MAX_OID_LEN][16]; char *oid_str_ptr[MAX_OID_LEN]; - for (size_t i = 0; i < o->oid_len; i++) - { - ssnprintf (oid_str[i], sizeof (oid_str[i]), "%lu", (unsigned long) o->oid[i]); + for (size_t i = 0; i < o->oid_len; i++) { + ssnprintf(oid_str[i], sizeof(oid_str[i]), "%lu", (unsigned long)o->oid[i]); oid_str_ptr[i] = oid_str[i]; } - return (strjoin (buffer, buffer_size, - oid_str_ptr, o->oid_len, /* separator = */ ".")); + return (strjoin(buffer, buffer_size, oid_str_ptr, o->oid_len, + /* separator = */ ".")); } -static void csnmp_host_close_session (host_definition_t *host) /* {{{ */ +static void csnmp_host_close_session(host_definition_t *host) /* {{{ */ { if (host->sess_handle == NULL) return; - snmp_sess_close (host->sess_handle); + snmp_sess_close(host->sess_handle); host->sess_handle = NULL; } /* }}} void csnmp_host_close_session */ -static void csnmp_host_definition_destroy (void *arg) /* {{{ */ +static void csnmp_host_definition_destroy(void *arg) /* {{{ */ { host_definition_t *hd; @@ -194,24 +181,22 @@ static void csnmp_host_definition_destroy (void *arg) /* {{{ */ if (hd == NULL) return; - if (hd->name != NULL) - { - DEBUG ("snmp plugin: Destroying host definition for host `%s'.", - hd->name); + if (hd->name != NULL) { + DEBUG("snmp plugin: Destroying host definition for host `%s'.", hd->name); } - csnmp_host_close_session (hd); + csnmp_host_close_session(hd); - sfree (hd->name); - sfree (hd->address); - sfree (hd->community); - sfree (hd->username); - sfree (hd->auth_passphrase); - sfree (hd->priv_passphrase); - sfree (hd->context); - sfree (hd->data_list); + sfree(hd->name); + sfree(hd->address); + sfree(hd->community); + sfree(hd->username); + sfree(hd->auth_passphrase); + sfree(hd->priv_passphrase); + sfree(hd->context); + sfree(hd->data_list); - sfree (hd); + sfree(hd); } /* }}} void csnmp_host_definition_destroy */ /* Many functions to handle the configuration. {{{ */ @@ -233,17 +218,16 @@ static void csnmp_host_definition_destroy (void *arg) /* {{{ */ * +-> csnmp_config_add_host_priv_protocol * +-> csnmp_config_add_host_security_level */ -static void call_snmp_init_once (void) -{ +static void call_snmp_init_once(void) { static int have_init = 0; if (have_init == 0) - init_snmp (PACKAGE_NAME); + init_snmp(PACKAGE_NAME); have_init = 1; } /* void call_snmp_init_once */ -static int csnmp_config_add_data_instance (data_definition_t *dd, oconfig_item_t *ci) -{ +static int csnmp_config_add_data_instance(data_definition_t *dd, + oconfig_item_t *ci) { char buffer[DATA_MAX_NAME_LEN]; int status; @@ -251,37 +235,30 @@ static int csnmp_config_add_data_instance (data_definition_t *dd, oconfig_item_t if (status != 0) return status; - if (dd->is_table) - { + if (dd->is_table) { /* Instance is an OID */ dd->instance.oid.oid_len = MAX_OID_LEN; - if (!read_objid (buffer, - dd->instance.oid.oid, &dd->instance.oid.oid_len)) - { - ERROR ("snmp plugin: read_objid (%s) failed.", buffer); + if (!read_objid(buffer, dd->instance.oid.oid, &dd->instance.oid.oid_len)) { + ERROR("snmp plugin: read_objid (%s) failed.", buffer); return (-1); } - } - else - { + } else { /* Instance is a simple string */ - sstrncpy (dd->instance.string, buffer, - sizeof (dd->instance.string)); + sstrncpy(dd->instance.string, buffer, sizeof(dd->instance.string)); } return (0); } /* int csnmp_config_add_data_instance */ -static int csnmp_config_add_data_instance_prefix (data_definition_t *dd, - oconfig_item_t *ci) -{ +static int csnmp_config_add_data_instance_prefix(data_definition_t *dd, + oconfig_item_t *ci) { int status; - if (!dd->is_table) - { - WARNING ("snmp plugin: data %s: InstancePrefix is ignored when `Table' " - "is set to `false'.", dd->name); + if (!dd->is_table) { + WARNING("snmp plugin: data %s: InstancePrefix is ignored when `Table' " + "is set to `false'.", + dd->name); return (-1); } @@ -289,38 +266,34 @@ static int csnmp_config_add_data_instance_prefix (data_definition_t *dd, return status; } /* int csnmp_config_add_data_instance_prefix */ -static int csnmp_config_add_data_values (data_definition_t *dd, oconfig_item_t *ci) -{ - if (ci->values_num < 1) - { - WARNING ("snmp plugin: `Values' needs at least one argument."); +static int csnmp_config_add_data_values(data_definition_t *dd, + oconfig_item_t *ci) { + if (ci->values_num < 1) { + WARNING("snmp plugin: `Values' needs at least one argument."); return (-1); } for (int i = 0; i < ci->values_num; i++) - if (ci->values[i].type != OCONFIG_TYPE_STRING) - { - WARNING ("snmp plugin: `Values' needs only string argument."); + if (ci->values[i].type != OCONFIG_TYPE_STRING) { + WARNING("snmp plugin: `Values' needs only string argument."); return (-1); } - sfree (dd->values); + sfree(dd->values); dd->values_len = 0; - dd->values = malloc (sizeof (*dd->values) * ci->values_num); + dd->values = malloc(sizeof(*dd->values) * ci->values_num); if (dd->values == NULL) return (-1); - dd->values_len = (size_t) ci->values_num; + dd->values_len = (size_t)ci->values_num; - for (int i = 0; i < ci->values_num; i++) - { + for (int i = 0; i < ci->values_num; i++) { dd->values[i].oid_len = MAX_OID_LEN; - if (NULL == snmp_parse_oid (ci->values[i].value.string, - dd->values[i].oid, &dd->values[i].oid_len)) - { - ERROR ("snmp plugin: snmp_parse_oid (%s) failed.", - ci->values[i].value.string); - free (dd->values); + if (NULL == snmp_parse_oid(ci->values[i].value.string, dd->values[i].oid, + &dd->values[i].oid_len)) { + ERROR("snmp plugin: snmp_parse_oid (%s) failed.", + ci->values[i].value.string); + free(dd->values); dd->values = NULL; dd->values_len = 0; return (-1); @@ -330,16 +303,14 @@ static int csnmp_config_add_data_values (data_definition_t *dd, oconfig_item_t * return (0); } /* int csnmp_config_add_data_instance */ -static int csnmp_config_add_data_blacklist(data_definition_t *dd, oconfig_item_t *ci) -{ +static int csnmp_config_add_data_blacklist(data_definition_t *dd, + oconfig_item_t *ci) { if (ci->values_num < 1) return (0); - for (int i = 0; i < ci->values_num; i++) - { - if (ci->values[i].type != OCONFIG_TYPE_STRING) - { - WARNING ("snmp plugin: `Ignore' needs only string argument."); + for (int i = 0; i < ci->values_num; i++) { + if (ci->values[i].type != OCONFIG_TYPE_STRING) { + WARNING("snmp plugin: `Ignore' needs only string argument."); return (-1); } } @@ -347,10 +318,9 @@ static int csnmp_config_add_data_blacklist(data_definition_t *dd, oconfig_item_t dd->ignores_len = 0; dd->ignores = NULL; - for (int i = 0; i < ci->values_num; ++i) - { - if (strarray_add(&(dd->ignores), &(dd->ignores_len), ci->values[i].value.string) != 0) - { + for (int i = 0; i < ci->values_num; ++i) { + if (strarray_add(&(dd->ignores), &(dd->ignores_len), + ci->values[i].value.string) != 0) { ERROR("snmp plugin: Can't allocate memory"); strarray_free(dd->ignores, dd->ignores_len); return (ENOMEM); @@ -359,11 +329,10 @@ static int csnmp_config_add_data_blacklist(data_definition_t *dd, oconfig_item_t return 0; } /* int csnmp_config_add_data_blacklist */ -static int csnmp_config_add_data_blacklist_match_inverted(data_definition_t *dd, oconfig_item_t *ci) -{ - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) - { - WARNING ("snmp plugin: `InvertMatch' needs exactly one boolean argument."); +static int csnmp_config_add_data_blacklist_match_inverted(data_definition_t *dd, + oconfig_item_t *ci) { + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) { + WARNING("snmp plugin: `InvertMatch' needs exactly one boolean argument."); return (-1); } @@ -372,50 +341,46 @@ static int csnmp_config_add_data_blacklist_match_inverted(data_definition_t *dd, return (0); } /* int csnmp_config_add_data_blacklist_match_inverted */ -static int csnmp_config_add_data (oconfig_item_t *ci) -{ +static int csnmp_config_add_data(oconfig_item_t *ci) { data_definition_t *dd; int status = 0; - dd = calloc (1, sizeof (*dd)); + dd = calloc(1, sizeof(*dd)); if (dd == NULL) return (-1); status = cf_util_get_string(ci, &dd->name); - if (status != 0) - { - free (dd); + if (status != 0) { + free(dd); return (-1); } dd->scale = 1.0; dd->shift = 0.0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; - if (strcasecmp ("Type", option->key) == 0) + if (strcasecmp("Type", option->key) == 0) status = cf_util_get_string(option, &dd->type); - else if (strcasecmp ("Table", option->key) == 0) + else if (strcasecmp("Table", option->key) == 0) status = cf_util_get_boolean(option, &dd->is_table); - else if (strcasecmp ("Instance", option->key) == 0) - status = csnmp_config_add_data_instance (dd, option); - else if (strcasecmp ("InstancePrefix", option->key) == 0) - status = csnmp_config_add_data_instance_prefix (dd, option); - else if (strcasecmp ("Values", option->key) == 0) - status = csnmp_config_add_data_values (dd, option); - else if (strcasecmp ("Shift", option->key) == 0) + else if (strcasecmp("Instance", option->key) == 0) + status = csnmp_config_add_data_instance(dd, option); + else if (strcasecmp("InstancePrefix", option->key) == 0) + status = csnmp_config_add_data_instance_prefix(dd, option); + else if (strcasecmp("Values", option->key) == 0) + status = csnmp_config_add_data_values(dd, option); + else if (strcasecmp("Shift", option->key) == 0) status = cf_util_get_double(option, &dd->shift); - else if (strcasecmp ("Scale", option->key) == 0) + else if (strcasecmp("Scale", option->key) == 0) status = cf_util_get_double(option, &dd->scale); - else if (strcasecmp ("Ignore", option->key) == 0) + else if (strcasecmp("Ignore", option->key) == 0) status = csnmp_config_add_data_blacklist(dd, option); - else if (strcasecmp ("InvertMatch", option->key) == 0) + else if (strcasecmp("InvertMatch", option->key) == 0) status = csnmp_config_add_data_blacklist_match_inverted(dd, option); - else - { - WARNING ("snmp plugin: Option `%s' not allowed here.", option->key); + else { + WARNING("snmp plugin: Option `%s' not allowed here.", option->key); status = -1; } @@ -423,17 +388,14 @@ static int csnmp_config_add_data (oconfig_item_t *ci) break; } /* for (ci->children) */ - while (status == 0) - { - if (dd->type == NULL) - { - WARNING ("snmp plugin: `Type' not given for data `%s'", dd->name); + while (status == 0) { + if (dd->type == NULL) { + WARNING("snmp plugin: `Type' not given for data `%s'", dd->name); status = -1; break; } - if (dd->values == NULL) - { - WARNING ("snmp plugin: No `Value' given for data `%s'", dd->name); + if (dd->values == NULL) { + WARNING("snmp plugin: No `Value' given for data `%s'", dd->name); status = -1; break; } @@ -441,23 +403,23 @@ static int csnmp_config_add_data (oconfig_item_t *ci) break; } /* while (status == 0) */ - if (status != 0) - { - sfree (dd->name); - sfree (dd->instance_prefix); - sfree (dd->values); - sfree (dd->ignores); - sfree (dd); + if (status != 0) { + sfree(dd->name); + sfree(dd->instance_prefix); + sfree(dd->values); + sfree(dd->ignores); + sfree(dd); return (-1); } - DEBUG ("snmp plugin: dd = { name = %s, type = %s, is_table = %s, values_len = %zu }", - dd->name, dd->type, (dd->is_table != 0) ? "true" : "false", dd->values_len); + DEBUG("snmp plugin: dd = { name = %s, type = %s, is_table = %s, values_len = " + "%zu }", + dd->name, dd->type, (dd->is_table != 0) ? "true" : "false", + dd->values_len); if (data_head == NULL) data_head = dd; - else - { + else { data_definition_t *last; last = data_head; while (last->next != NULL) @@ -468,21 +430,19 @@ static int csnmp_config_add_data (oconfig_item_t *ci) return (0); } /* int csnmp_config_add_data */ -static int csnmp_config_add_host_version (host_definition_t *hd, oconfig_item_t *ci) -{ +static int csnmp_config_add_host_version(host_definition_t *hd, + oconfig_item_t *ci) { int version; - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) - { - WARNING ("snmp plugin: The `Version' config option needs exactly one number argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) { + WARNING("snmp plugin: The `Version' config option needs exactly one number " + "argument."); return (-1); } - version = (int) ci->values[0].value.number; - if ((version < 1) || (version > 3)) - { - WARNING ("snmp plugin: `Version' must either be `1', `2', or `3'."); + version = (int)ci->values[0].value.number; + if ((version < 1) || (version > 3)) { + WARNING("snmp plugin: `Version' must either be `1', `2', or `3'."); return (-1); } @@ -491,48 +451,43 @@ static int csnmp_config_add_host_version (host_definition_t *hd, oconfig_item_t return (0); } /* int csnmp_config_add_host_address */ -static int csnmp_config_add_host_collect (host_definition_t *host, - oconfig_item_t *ci) -{ +static int csnmp_config_add_host_collect(host_definition_t *host, + oconfig_item_t *ci) { data_definition_t *data; data_definition_t **data_list; int data_list_len; - if (ci->values_num < 1) - { - WARNING ("snmp plugin: `Collect' needs at least one argument."); + if (ci->values_num < 1) { + WARNING("snmp plugin: `Collect' needs at least one argument."); return (-1); } for (int i = 0; i < ci->values_num; i++) - if (ci->values[i].type != OCONFIG_TYPE_STRING) - { - WARNING ("snmp plugin: All arguments to `Collect' must be strings."); + if (ci->values[i].type != OCONFIG_TYPE_STRING) { + WARNING("snmp plugin: All arguments to `Collect' must be strings."); return (-1); } data_list_len = host->data_list_len + ci->values_num; - data_list = realloc (host->data_list, - sizeof (data_definition_t *) * data_list_len); + data_list = + realloc(host->data_list, sizeof(data_definition_t *) * data_list_len); if (data_list == NULL) return (-1); host->data_list = data_list; - for (int i = 0; i < ci->values_num; i++) - { + for (int i = 0; i < ci->values_num; i++) { for (data = data_head; data != NULL; data = data->next) - if (strcasecmp (ci->values[i].value.string, data->name) == 0) + if (strcasecmp(ci->values[i].value.string, data->name) == 0) break; - if (data == NULL) - { - WARNING ("snmp plugin: No such data configured: `%s'", - ci->values[i].value.string); + if (data == NULL) { + WARNING("snmp plugin: No such data configured: `%s'", + ci->values[i].value.string); continue; } - DEBUG ("snmp plugin: Collect: host = %s, data[%i] = %s;", - host->name, host->data_list_len, data->name); + DEBUG("snmp plugin: Collect: host = %s, data[%i] = %s;", host->name, + host->data_list_len, data->name); host->data_list[host->data_list_len] = data; host->data_list_len++; @@ -541,8 +496,8 @@ static int csnmp_config_add_host_collect (host_definition_t *host, return (0); } /* int csnmp_config_add_host_collect */ -static int csnmp_config_add_host_auth_protocol (host_definition_t *hd, oconfig_item_t *ci) -{ +static int csnmp_config_add_host_auth_protocol(host_definition_t *hd, + oconfig_item_t *ci) { char buffer[4]; int status; @@ -552,26 +507,24 @@ static int csnmp_config_add_host_auth_protocol (host_definition_t *hd, oconfig_i if (strcasecmp("MD5", buffer) == 0) { hd->auth_protocol = usmHMACMD5AuthProtocol; - hd->auth_protocol_len = sizeof(usmHMACMD5AuthProtocol)/sizeof(oid); - } - else if (strcasecmp("SHA", buffer) == 0) { + hd->auth_protocol_len = sizeof(usmHMACMD5AuthProtocol) / sizeof(oid); + } else if (strcasecmp("SHA", buffer) == 0) { hd->auth_protocol = usmHMACSHA1AuthProtocol; - hd->auth_protocol_len = sizeof(usmHMACSHA1AuthProtocol)/sizeof(oid); - } - else - { - WARNING ("snmp plugin: The `AuthProtocol' config option must be `MD5' or `SHA'."); + hd->auth_protocol_len = sizeof(usmHMACSHA1AuthProtocol) / sizeof(oid); + } else { + WARNING("snmp plugin: The `AuthProtocol' config option must be `MD5' or " + "`SHA'."); return (-1); } - DEBUG ("snmp plugin: host = %s; host->auth_protocol = %s;", - hd->name, hd->auth_protocol == usmHMACMD5AuthProtocol ? "MD5" : "SHA"); + DEBUG("snmp plugin: host = %s; host->auth_protocol = %s;", hd->name, + hd->auth_protocol == usmHMACMD5AuthProtocol ? "MD5" : "SHA"); return (0); } /* int csnmp_config_add_host_auth_protocol */ -static int csnmp_config_add_host_priv_protocol (host_definition_t *hd, oconfig_item_t *ci) -{ +static int csnmp_config_add_host_priv_protocol(host_definition_t *hd, + oconfig_item_t *ci) { char buffer[4]; int status; @@ -579,29 +532,26 @@ static int csnmp_config_add_host_priv_protocol (host_definition_t *hd, oconfig_i if (status != 0) return status; - if (strcasecmp("AES", buffer) == 0) - { + if (strcasecmp("AES", buffer) == 0) { hd->priv_protocol = usmAESPrivProtocol; - hd->priv_protocol_len = sizeof(usmAESPrivProtocol)/sizeof(oid); - } - else if (strcasecmp("DES", buffer) == 0) { + hd->priv_protocol_len = sizeof(usmAESPrivProtocol) / sizeof(oid); + } else if (strcasecmp("DES", buffer) == 0) { hd->priv_protocol = usmDESPrivProtocol; - hd->priv_protocol_len = sizeof(usmDESPrivProtocol)/sizeof(oid); - } - else - { - WARNING ("snmp plugin: The `PrivProtocol' config option must be `AES' or `DES'."); + hd->priv_protocol_len = sizeof(usmDESPrivProtocol) / sizeof(oid); + } else { + WARNING("snmp plugin: The `PrivProtocol' config option must be `AES' or " + "`DES'."); return (-1); } - DEBUG ("snmp plugin: host = %s; host->priv_protocol = %s;", - hd->name, hd->priv_protocol == usmAESPrivProtocol ? "AES" : "DES"); + DEBUG("snmp plugin: host = %s; host->priv_protocol = %s;", hd->name, + hd->priv_protocol == usmAESPrivProtocol ? "AES" : "DES"); return (0); } /* int csnmp_config_add_host_priv_protocol */ -static int csnmp_config_add_host_security_level (host_definition_t *hd, oconfig_item_t *ci) -{ +static int csnmp_config_add_host_security_level(host_definition_t *hd, + oconfig_item_t *ci) { char buffer[16]; int status; @@ -615,74 +565,72 @@ static int csnmp_config_add_host_security_level (host_definition_t *hd, oconfig_ hd->security_level = SNMP_SEC_LEVEL_AUTHNOPRIV; else if (strcasecmp("authPriv", buffer) == 0) hd->security_level = SNMP_SEC_LEVEL_AUTHPRIV; - else - { - WARNING ("snmp plugin: The `SecurityLevel' config option must be `noAuthNoPriv', `authNoPriv', or `authPriv'."); + else { + WARNING("snmp plugin: The `SecurityLevel' config option must be " + "`noAuthNoPriv', `authNoPriv', or `authPriv'."); return (-1); } - DEBUG ("snmp plugin: host = %s; host->security_level = %d;", - hd->name, hd->security_level); + DEBUG("snmp plugin: host = %s; host->security_level = %d;", hd->name, + hd->security_level); return (0); } /* int csnmp_config_add_host_security_level */ -static int csnmp_config_add_host (oconfig_item_t *ci) -{ +static int csnmp_config_add_host(oconfig_item_t *ci) { host_definition_t *hd; int status = 0; /* Registration stuff. */ char cb_name[DATA_MAX_NAME_LEN]; - hd = calloc (1, sizeof (*hd)); + hd = calloc(1, sizeof(*hd)); if (hd == NULL) return (-1); hd->version = 2; - C_COMPLAIN_INIT (&hd->complaint); + C_COMPLAIN_INIT(&hd->complaint); status = cf_util_get_string(ci, &hd->name); - if (status != 0) - { - sfree (hd); + if (status != 0) { + sfree(hd); return status; } hd->sess_handle = NULL; hd->interval = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; status = 0; - if (strcasecmp ("Address", option->key) == 0) + if (strcasecmp("Address", option->key) == 0) status = cf_util_get_string(option, &hd->address); - else if (strcasecmp ("Community", option->key) == 0) + else if (strcasecmp("Community", option->key) == 0) status = cf_util_get_string(option, &hd->community); - else if (strcasecmp ("Version", option->key) == 0) - status = csnmp_config_add_host_version (hd, option); - else if (strcasecmp ("Collect", option->key) == 0) - csnmp_config_add_host_collect (hd, option); - else if (strcasecmp ("Interval", option->key) == 0) - cf_util_get_cdtime (option, &hd->interval); - else if (strcasecmp ("Username", option->key) == 0) + else if (strcasecmp("Version", option->key) == 0) + status = csnmp_config_add_host_version(hd, option); + else if (strcasecmp("Collect", option->key) == 0) + csnmp_config_add_host_collect(hd, option); + else if (strcasecmp("Interval", option->key) == 0) + cf_util_get_cdtime(option, &hd->interval); + else if (strcasecmp("Username", option->key) == 0) status = cf_util_get_string(option, &hd->username); - else if (strcasecmp ("AuthProtocol", option->key) == 0) - status = csnmp_config_add_host_auth_protocol (hd, option); - else if (strcasecmp ("PrivacyProtocol", option->key) == 0) - status = csnmp_config_add_host_priv_protocol (hd, option); - else if (strcasecmp ("AuthPassphrase", option->key) == 0) + else if (strcasecmp("AuthProtocol", option->key) == 0) + status = csnmp_config_add_host_auth_protocol(hd, option); + else if (strcasecmp("PrivacyProtocol", option->key) == 0) + status = csnmp_config_add_host_priv_protocol(hd, option); + else if (strcasecmp("AuthPassphrase", option->key) == 0) status = cf_util_get_string(option, &hd->auth_passphrase); - else if (strcasecmp ("PrivacyPassphrase", option->key) == 0) + else if (strcasecmp("PrivacyPassphrase", option->key) == 0) status = cf_util_get_string(option, &hd->priv_passphrase); - else if (strcasecmp ("SecurityLevel", option->key) == 0) - status = csnmp_config_add_host_security_level (hd, option); - else if (strcasecmp ("Context", option->key) == 0) + else if (strcasecmp("SecurityLevel", option->key) == 0) + status = csnmp_config_add_host_security_level(hd, option); + else if (strcasecmp("Context", option->key) == 0) status = cf_util_get_string(option, &hd->context); - else - { - WARNING ("snmp plugin: csnmp_config_add_host: Option `%s' not allowed here.", option->key); + else { + WARNING( + "snmp plugin: csnmp_config_add_host: Option `%s' not allowed here.", + option->key); status = -1; } @@ -690,109 +638,99 @@ static int csnmp_config_add_host (oconfig_item_t *ci) break; } /* for (ci->children) */ - while (status == 0) - { - if (hd->address == NULL) - { - WARNING ("snmp plugin: `Address' not given for host `%s'", hd->name); + while (status == 0) { + if (hd->address == NULL) { + WARNING("snmp plugin: `Address' not given for host `%s'", hd->name); status = -1; break; } - if (hd->community == NULL && hd->version < 3) - { - WARNING ("snmp plugin: `Community' not given for host `%s'", hd->name); + if (hd->community == NULL && hd->version < 3) { + WARNING("snmp plugin: `Community' not given for host `%s'", hd->name); status = -1; break; } - if (hd->version == 3) - { - if (hd->username == NULL) - { - WARNING ("snmp plugin: `Username' not given for host `%s'", hd->name); + if (hd->version == 3) { + if (hd->username == NULL) { + WARNING("snmp plugin: `Username' not given for host `%s'", hd->name); status = -1; break; } - if (hd->security_level == 0) - { - WARNING ("snmp plugin: `SecurityLevel' not given for host `%s'", hd->name); + if (hd->security_level == 0) { + WARNING("snmp plugin: `SecurityLevel' not given for host `%s'", + hd->name); status = -1; break; } - if (hd->security_level == SNMP_SEC_LEVEL_AUTHNOPRIV || hd->security_level == SNMP_SEC_LEVEL_AUTHPRIV) - { - if (hd->auth_protocol == NULL) - { - WARNING ("snmp plugin: `AuthProtocol' not given for host `%s'", hd->name); - status = -1; - break; - } - if (hd->auth_passphrase == NULL) - { - WARNING ("snmp plugin: `AuthPassphrase' not given for host `%s'", hd->name); - status = -1; - break; - } + if (hd->security_level == SNMP_SEC_LEVEL_AUTHNOPRIV || + hd->security_level == SNMP_SEC_LEVEL_AUTHPRIV) { + if (hd->auth_protocol == NULL) { + WARNING("snmp plugin: `AuthProtocol' not given for host `%s'", + hd->name); + status = -1; + break; + } + if (hd->auth_passphrase == NULL) { + WARNING("snmp plugin: `AuthPassphrase' not given for host `%s'", + hd->name); + status = -1; + break; + } } - if (hd->security_level == SNMP_SEC_LEVEL_AUTHPRIV) - { - if (hd->priv_protocol == NULL) - { - WARNING ("snmp plugin: `PrivacyProtocol' not given for host `%s'", hd->name); - status = -1; - break; - } - if (hd->priv_passphrase == NULL) - { - WARNING ("snmp plugin: `PrivacyPassphrase' not given for host `%s'", hd->name); - status = -1; - break; - } + if (hd->security_level == SNMP_SEC_LEVEL_AUTHPRIV) { + if (hd->priv_protocol == NULL) { + WARNING("snmp plugin: `PrivacyProtocol' not given for host `%s'", + hd->name); + status = -1; + break; + } + if (hd->priv_passphrase == NULL) { + WARNING("snmp plugin: `PrivacyPassphrase' not given for host `%s'", + hd->name); + status = -1; + break; + } } } break; } /* while (status == 0) */ - if (status != 0) - { - csnmp_host_definition_destroy (hd); + if (status != 0) { + csnmp_host_definition_destroy(hd); return (-1); } - DEBUG ("snmp plugin: hd = { name = %s, address = %s, community = %s, version = %i }", - hd->name, hd->address, hd->community, hd->version); + DEBUG("snmp plugin: hd = { name = %s, address = %s, community = %s, version " + "= %i }", + hd->name, hd->address, hd->community, hd->version); - ssnprintf (cb_name, sizeof (cb_name), "snmp-%s", hd->name); + ssnprintf(cb_name, sizeof(cb_name), "snmp-%s", hd->name); - status = plugin_register_complex_read (/* group = */ NULL, cb_name, - csnmp_read_host, hd->interval, &(user_data_t) { - .data = hd, - .free_func = csnmp_host_definition_destroy, + status = plugin_register_complex_read( + /* group = */ NULL, cb_name, csnmp_read_host, hd->interval, + &(user_data_t){ + .data = hd, .free_func = csnmp_host_definition_destroy, }); - if (status != 0) - { - ERROR ("snmp plugin: Registering complex read function failed."); - csnmp_host_definition_destroy (hd); + if (status != 0) { + ERROR("snmp plugin: Registering complex read function failed."); + csnmp_host_definition_destroy(hd); return (-1); } return (0); } /* int csnmp_config_add_host */ -static int csnmp_config (oconfig_item_t *ci) -{ - call_snmp_init_once (); +static int csnmp_config(oconfig_item_t *ci) { + call_snmp_init_once(); - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Data", child->key) == 0) - csnmp_config_add_data (child); - else if (strcasecmp ("Host", child->key) == 0) - csnmp_config_add_host (child); - else - { - WARNING ("snmp plugin: Ignoring unknown config option `%s'.", child->key); + if (strcasecmp("Data", child->key) == 0) + csnmp_config_add_data(child); + else if (strcasecmp("Host", child->key) == 0) + csnmp_config_add_host(child); + else { + WARNING("snmp plugin: Ignoring unknown config option `%s'.", child->key); } } /* for (ci->children) */ @@ -801,99 +739,93 @@ static int csnmp_config (oconfig_item_t *ci) /* }}} End of the config stuff. Now the interesting part begins */ -static void csnmp_host_open_session (host_definition_t *host) -{ +static void csnmp_host_open_session(host_definition_t *host) { struct snmp_session sess; int error; if (host->sess_handle != NULL) - csnmp_host_close_session (host); + csnmp_host_close_session(host); - snmp_sess_init (&sess); + snmp_sess_init(&sess); sess.peername = host->address; - switch (host->version) - { - case 1: - sess.version = SNMP_VERSION_1; - break; - case 3: - sess.version = SNMP_VERSION_3; - break; - default: - sess.version = SNMP_VERSION_2c; - break; + switch (host->version) { + case 1: + sess.version = SNMP_VERSION_1; + break; + case 3: + sess.version = SNMP_VERSION_3; + break; + default: + sess.version = SNMP_VERSION_2c; + break; } - if (host->version == 3) - { + if (host->version == 3) { sess.securityName = host->username; - sess.securityNameLen = strlen (host->username); + sess.securityNameLen = strlen(host->username); sess.securityLevel = host->security_level; - if (sess.securityLevel == SNMP_SEC_LEVEL_AUTHNOPRIV || sess.securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) - { + if (sess.securityLevel == SNMP_SEC_LEVEL_AUTHNOPRIV || + sess.securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) { sess.securityAuthProto = host->auth_protocol; sess.securityAuthProtoLen = host->auth_protocol_len; sess.securityAuthKeyLen = USM_AUTH_KU_LEN; - error = generate_Ku (sess.securityAuthProto, - sess.securityAuthProtoLen, - (u_char *) host->auth_passphrase, - strlen(host->auth_passphrase), - sess.securityAuthKey, - &sess.securityAuthKeyLen); + error = generate_Ku(sess.securityAuthProto, sess.securityAuthProtoLen, + (u_char *)host->auth_passphrase, + strlen(host->auth_passphrase), sess.securityAuthKey, + &sess.securityAuthKeyLen); if (error != SNMPERR_SUCCESS) { - ERROR ("snmp plugin: host %s: Error generating Ku from auth_passphrase. (Error %d)", host->name, error); + ERROR("snmp plugin: host %s: Error generating Ku from auth_passphrase. " + "(Error %d)", + host->name, error); } } - if (sess.securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) - { + if (sess.securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) { sess.securityPrivProto = host->priv_protocol; sess.securityPrivProtoLen = host->priv_protocol_len; sess.securityPrivKeyLen = USM_PRIV_KU_LEN; - error = generate_Ku (sess.securityAuthProto, - sess.securityAuthProtoLen, - (u_char *) host->priv_passphrase, - strlen(host->priv_passphrase), - sess.securityPrivKey, - &sess.securityPrivKeyLen); + error = generate_Ku(sess.securityAuthProto, sess.securityAuthProtoLen, + (u_char *)host->priv_passphrase, + strlen(host->priv_passphrase), sess.securityPrivKey, + &sess.securityPrivKeyLen); if (error != SNMPERR_SUCCESS) { - ERROR ("snmp plugin: host %s: Error generating Ku from priv_passphrase. (Error %d)", host->name, error); + ERROR("snmp plugin: host %s: Error generating Ku from priv_passphrase. " + "(Error %d)", + host->name, error); } } - if (host->context != NULL) - { + if (host->context != NULL) { sess.contextName = host->context; - sess.contextNameLen = strlen (host->context); + sess.contextNameLen = strlen(host->context); } - } - else /* SNMPv1/2 "authenticates" with community string */ + } else /* SNMPv1/2 "authenticates" with community string */ { - sess.community = (u_char *) host->community; - sess.community_len = strlen (host->community); + sess.community = (u_char *)host->community; + sess.community_len = strlen(host->community); } /* snmp_sess_open will copy the `struct snmp_session *'. */ - host->sess_handle = snmp_sess_open (&sess); + host->sess_handle = snmp_sess_open(&sess); - if (host->sess_handle == NULL) - { + if (host->sess_handle == NULL) { char *errstr = NULL; - snmp_error (&sess, NULL, NULL, &errstr); + snmp_error(&sess, NULL, NULL, &errstr); - ERROR ("snmp plugin: host %s: snmp_sess_open failed: %s", - host->name, (errstr == NULL) ? "Unknown problem" : errstr); - sfree (errstr); + ERROR("snmp plugin: host %s: snmp_sess_open failed: %s", host->name, + (errstr == NULL) ? "Unknown problem" : errstr); + sfree(errstr); } } /* void csnmp_host_open_session */ -/* TODO: Check if negative values wrap around. Problem: negative temperatures. */ -static value_t csnmp_value_list_to_value (struct variable_list *vl, int type, - double scale, double shift, - const char *host_name, const char *data_name) -{ +/* TODO: Check if negative values wrap around. Problem: negative temperatures. + */ +static value_t csnmp_value_list_to_value(struct variable_list *vl, int type, + double scale, double shift, + const char *host_name, + const char *data_name) { value_t ret; uint64_t tmp_unsigned = 0; int64_t tmp_signed = 0; @@ -901,66 +833,55 @@ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type, /* Set to true when the original SNMP type appears to have been signed. */ _Bool prefer_signed = 0; - if ((vl->type == ASN_INTEGER) - || (vl->type == ASN_UINTEGER) - || (vl->type == ASN_COUNTER) + if ((vl->type == ASN_INTEGER) || (vl->type == ASN_UINTEGER) || + (vl->type == ASN_COUNTER) #ifdef ASN_TIMETICKS || (vl->type == ASN_TIMETICKS) #endif - || (vl->type == ASN_GAUGE)) - { - tmp_unsigned = (uint32_t) *vl->val.integer; - tmp_signed = (int32_t) *vl->val.integer; + || (vl->type == ASN_GAUGE)) { + tmp_unsigned = (uint32_t)*vl->val.integer; + tmp_signed = (int32_t)*vl->val.integer; if (vl->type == ASN_INTEGER) prefer_signed = 1; - DEBUG ("snmp plugin: Parsed int32 value is %"PRIu64".", tmp_unsigned); - } - else if (vl->type == ASN_COUNTER64) - { - tmp_unsigned = (uint32_t) vl->val.counter64->high; + DEBUG("snmp plugin: Parsed int32 value is %" PRIu64 ".", tmp_unsigned); + } else if (vl->type == ASN_COUNTER64) { + tmp_unsigned = (uint32_t)vl->val.counter64->high; tmp_unsigned = tmp_unsigned << 32; - tmp_unsigned += (uint32_t) vl->val.counter64->low; - tmp_signed = (int64_t) tmp_unsigned; - DEBUG ("snmp plugin: Parsed int64 value is %"PRIu64".", tmp_unsigned); - } - else if (vl->type == ASN_OCTET_STR) - { + tmp_unsigned += (uint32_t)vl->val.counter64->low; + tmp_signed = (int64_t)tmp_unsigned; + DEBUG("snmp plugin: Parsed int64 value is %" PRIu64 ".", tmp_unsigned); + } else if (vl->type == ASN_OCTET_STR) { /* We'll handle this later.. */ - } - else - { - char oid_buffer[1024] = { 0 }; + } else { + char oid_buffer[1024] = {0}; - snprint_objid (oid_buffer, sizeof (oid_buffer) - 1, - vl->name, vl->name_length); + snprint_objid(oid_buffer, sizeof(oid_buffer) - 1, vl->name, + vl->name_length); #ifdef ASN_NULL if (vl->type == ASN_NULL) - INFO ("snmp plugin: OID \"%s\" is undefined (type ASN_NULL)", - oid_buffer); + INFO("snmp plugin: OID \"%s\" is undefined (type ASN_NULL)", oid_buffer); else #endif - WARNING ("snmp plugin: I don't know the ASN type #%i " - "(OID: \"%s\", data block \"%s\", host block \"%s\")", - (int) vl->type, oid_buffer, - (data_name != NULL) ? data_name : "UNKNOWN", - (host_name != NULL) ? host_name : "UNKNOWN"); + WARNING("snmp plugin: I don't know the ASN type #%i " + "(OID: \"%s\", data block \"%s\", host block \"%s\")", + (int)vl->type, oid_buffer, + (data_name != NULL) ? data_name : "UNKNOWN", + (host_name != NULL) ? host_name : "UNKNOWN"); defined = 0; } - if (vl->type == ASN_OCTET_STR) - { + if (vl->type == ASN_OCTET_STR) { int status = -1; - if (vl->val.string != NULL) - { + if (vl->val.string != NULL) { char string[64]; size_t string_length; - string_length = sizeof (string) - 1; + string_length = sizeof(string) - 1; if (vl->val_len < string_length) string_length = vl->val_len; @@ -968,67 +889,58 @@ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type, * terminated. That is why we're using `memcpy' here and not `strcpy'. * `string_length' is set to `vl->val_len' which holds the length of the * string. -octo */ - memcpy (string, vl->val.string, string_length); + memcpy(string, vl->val.string, string_length); string[string_length] = 0; - status = parse_value (string, &ret, type); - if (status != 0) - { - ERROR ("snmp plugin: host %s: csnmp_value_list_to_value: Parsing string as %s failed: %s", - (host_name != NULL) ? host_name : "UNKNOWN", - DS_TYPE_TO_STRING (type), string); + status = parse_value(string, &ret, type); + if (status != 0) { + ERROR("snmp plugin: host %s: csnmp_value_list_to_value: Parsing string " + "as %s failed: %s", + (host_name != NULL) ? host_name : "UNKNOWN", + DS_TYPE_TO_STRING(type), string); } } - if (status != 0) - { - switch (type) - { - case DS_TYPE_COUNTER: - case DS_TYPE_DERIVE: - case DS_TYPE_ABSOLUTE: - memset (&ret, 0, sizeof (ret)); - break; + if (status != 0) { + switch (type) { + case DS_TYPE_COUNTER: + case DS_TYPE_DERIVE: + case DS_TYPE_ABSOLUTE: + memset(&ret, 0, sizeof(ret)); + break; - case DS_TYPE_GAUGE: - ret.gauge = NAN; - break; + case DS_TYPE_GAUGE: + ret.gauge = NAN; + break; - default: - ERROR ("snmp plugin: csnmp_value_list_to_value: Unknown " - "data source type: %i.", type); - ret.gauge = NAN; + default: + ERROR("snmp plugin: csnmp_value_list_to_value: Unknown " + "data source type: %i.", + type); + ret.gauge = NAN; } } } /* if (vl->type == ASN_OCTET_STR) */ - else if (type == DS_TYPE_COUNTER) - { + else if (type == DS_TYPE_COUNTER) { ret.counter = tmp_unsigned; - } - else if (type == DS_TYPE_GAUGE) - { + } else if (type == DS_TYPE_GAUGE) { if (!defined) ret.gauge = NAN; else if (prefer_signed) ret.gauge = (scale * tmp_signed) + shift; else ret.gauge = (scale * tmp_unsigned) + shift; - } - else if (type == DS_TYPE_DERIVE) - { + } else if (type == DS_TYPE_DERIVE) { if (prefer_signed) - ret.derive = (derive_t) tmp_signed; + ret.derive = (derive_t)tmp_signed; else - ret.derive = (derive_t) tmp_unsigned; - } - else if (type == DS_TYPE_ABSOLUTE) - { - ret.absolute = (absolute_t) tmp_unsigned; - } - else - { - ERROR ("snmp plugin: csnmp_value_list_to_value: Unknown data source " - "type: %i.", type); + ret.derive = (derive_t)tmp_unsigned; + } else if (type == DS_TYPE_ABSOLUTE) { + ret.absolute = (absolute_t)tmp_unsigned; + } else { + ERROR("snmp plugin: csnmp_value_list_to_value: Unknown data source " + "type: %i.", + type); ret.gauge = NAN; } @@ -1039,9 +951,9 @@ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type, * representation and writes it to dst. Returns zero on success and ENOMEM if * dst is not large enough to hold the string. dst is guaranteed to be * nul-terminated. */ -static int csnmp_strvbcopy_hexstring (char *dst, /* {{{ */ - const struct variable_list *vb, size_t dst_size) -{ +static int csnmp_strvbcopy_hexstring(char *dst, /* {{{ */ + const struct variable_list *vb, + size_t dst_size) { char *buffer_ptr; size_t buffer_free; @@ -1050,23 +962,21 @@ static int csnmp_strvbcopy_hexstring (char *dst, /* {{{ */ buffer_ptr = dst; buffer_free = dst_size; - for (size_t i = 0; i < vb->val_len; i++) - { + for (size_t i = 0; i < vb->val_len; i++) { int status; - status = snprintf (buffer_ptr, buffer_free, - (i == 0) ? "%02x" : ":%02x", (unsigned int) vb->val.bitstring[i]); - assert (status >= 0); + status = snprintf(buffer_ptr, buffer_free, (i == 0) ? "%02x" : ":%02x", + (unsigned int)vb->val.bitstring[i]); + assert(status >= 0); - if (((size_t) status) >= buffer_free) /* truncated */ + if (((size_t)status) >= buffer_free) /* truncated */ { dst[dst_size - 1] = 0; return ENOMEM; - } - else /* if (status < buffer_free) */ + } else /* if (status < buffer_free) */ { - buffer_ptr += (size_t) status; - buffer_free -= (size_t) status; + buffer_ptr += (size_t)status; + buffer_free -= (size_t)status; } } @@ -1078,26 +988,21 @@ static int csnmp_strvbcopy_hexstring (char *dst, /* {{{ */ * representation of the string. Returns zero on success, EINVAL if vb does not * contain a string and ENOMEM if dst is not large enough to contain the * string. */ -static int csnmp_strvbcopy (char *dst, /* {{{ */ - const struct variable_list *vb, size_t dst_size) -{ +static int csnmp_strvbcopy(char *dst, /* {{{ */ + const struct variable_list *vb, size_t dst_size) { char *src; size_t num_chars; if (vb->type == ASN_OCTET_STR) - src = (char *) vb->val.string; + src = (char *)vb->val.string; else if (vb->type == ASN_BIT_STR) - src = (char *) vb->val.bitstring; - else if (vb->type == ASN_IPADDRESS) - { - return ssnprintf (dst, dst_size, "%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8"", - (uint8_t) vb->val.string[0], - (uint8_t) vb->val.string[1], - (uint8_t) vb->val.string[2], - (uint8_t) vb->val.string[3]); - } - else - { + src = (char *)vb->val.bitstring; + else if (vb->type == ASN_IPADDRESS) { + return ssnprintf(dst, dst_size, + "%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 "", + (uint8_t)vb->val.string[0], (uint8_t)vb->val.string[1], + (uint8_t)vb->val.string[2], (uint8_t)vb->val.string[3]); + } else { dst[0] = 0; return (EINVAL); } @@ -1106,11 +1011,10 @@ static int csnmp_strvbcopy (char *dst, /* {{{ */ if (num_chars > vb->val_len) num_chars = vb->val_len; - for (size_t i = 0; i < num_chars; i++) - { + for (size_t i = 0; i < num_chars; i++) { /* Check for control characters. */ if ((unsigned char)src[i] < 32) - return (csnmp_strvbcopy_hexstring (dst, vb, dst_size)); + return (csnmp_strvbcopy_hexstring(dst, vb, dst_size)); dst[i] = src[i]; } dst[num_chars] = 0; @@ -1122,11 +1026,11 @@ static int csnmp_strvbcopy (char *dst, /* {{{ */ return 0; } /* }}} int csnmp_strvbcopy */ -static int csnmp_instance_list_add (csnmp_list_instances_t **head, - csnmp_list_instances_t **tail, - const struct snmp_pdu *res, - const host_definition_t *hd, const data_definition_t *dd) -{ +static int csnmp_instance_list_add(csnmp_list_instances_t **head, + csnmp_list_instances_t **tail, + const struct snmp_pdu *res, + const host_definition_t *hd, + const data_definition_t *dd) { csnmp_list_instances_t *il; struct variable_list *vb; oid_t vb_name; @@ -1134,74 +1038,62 @@ static int csnmp_instance_list_add (csnmp_list_instances_t **head, uint32_t is_matched; /* Set vb on the last variable */ - for (vb = res->variables; - (vb != NULL) && (vb->next_variable != NULL); - vb = vb->next_variable) + for (vb = res->variables; (vb != NULL) && (vb->next_variable != NULL); + vb = vb->next_variable) /* do nothing */; if (vb == NULL) return (-1); - csnmp_oid_init (&vb_name, vb->name, vb->name_length); + csnmp_oid_init(&vb_name, vb->name, vb->name_length); - il = calloc (1, sizeof (*il)); - if (il == NULL) - { - ERROR ("snmp plugin: calloc failed."); + il = calloc(1, sizeof(*il)); + if (il == NULL) { + ERROR("snmp plugin: calloc failed."); return (-1); } il->next = NULL; - status = csnmp_oid_suffix (&il->suffix, &vb_name, &dd->instance.oid); - if (status != 0) - { - sfree (il); + status = csnmp_oid_suffix(&il->suffix, &vb_name, &dd->instance.oid); + if (status != 0) { + sfree(il); return (status); } /* Get instance name */ - if ((vb->type == ASN_OCTET_STR) || (vb->type == ASN_BIT_STR) || (vb->type == ASN_IPADDRESS)) - { + if ((vb->type == ASN_OCTET_STR) || (vb->type == ASN_BIT_STR) || + (vb->type == ASN_IPADDRESS)) { char *ptr; - csnmp_strvbcopy (il->instance, vb, sizeof (il->instance)); + csnmp_strvbcopy(il->instance, vb, sizeof(il->instance)); is_matched = 0; - for (uint32_t i = 0; i < dd->ignores_len; i++) - { + for (uint32_t i = 0; i < dd->ignores_len; i++) { status = fnmatch(dd->ignores[i], il->instance, 0); - if (status == 0) - { - if (dd->invert_match == 0) - { + if (status == 0) { + if (dd->invert_match == 0) { sfree(il); return 0; - } - else - { + } else { is_matched = 1; - break; - } + break; + } } } - if (dd->invert_match != 0 && is_matched == 0) - { + if (dd->invert_match != 0 && is_matched == 0) { sfree(il); return 0; } - for (ptr = il->instance; *ptr != '\0'; ptr++) - { + for (ptr = il->instance; *ptr != '\0'; ptr++) { if ((*ptr > 0) && (*ptr < 32)) *ptr = ' '; else if (*ptr == '/') *ptr = '_'; } - DEBUG ("snmp plugin: il->instance = `%s';", il->instance); - } - else - { - value_t val = csnmp_value_list_to_value (vb, DS_TYPE_COUNTER, + DEBUG("snmp plugin: il->instance = `%s';", il->instance); + } else { + value_t val = csnmp_value_list_to_value( + vb, DS_TYPE_COUNTER, /* scale = */ 1.0, /* shift = */ 0.0, hd->name, dd->name); - ssnprintf (il->instance, sizeof (il->instance), - "%llu", val.counter); + ssnprintf(il->instance, sizeof(il->instance), "%llu", val.counter); } /* TODO: Debugging output */ @@ -1215,10 +1107,10 @@ static int csnmp_instance_list_add (csnmp_list_instances_t **head, return (0); } /* int csnmp_instance_list_add */ -static int csnmp_dispatch_table (host_definition_t *host, data_definition_t *data, - csnmp_list_instances_t *instance_list, - csnmp_table_values_t **value_table) -{ +static int csnmp_dispatch_table(host_definition_t *host, + data_definition_t *data, + csnmp_list_instances_t *instance_list, + csnmp_table_values_t **value_table) { const data_set_t *ds; value_list_t vl = VALUE_LIST_INIT; @@ -1229,80 +1121,72 @@ static int csnmp_dispatch_table (host_definition_t *host, data_definition_t *dat _Bool have_more; oid_t current_suffix; - ds = plugin_get_ds (data->type); - if (!ds) - { - ERROR ("snmp plugin: DataSet `%s' not defined.", data->type); + ds = plugin_get_ds(data->type); + if (!ds) { + ERROR("snmp plugin: DataSet `%s' not defined.", data->type); return (-1); } - assert (ds->ds_num == data->values_len); - assert (data->values_len > 0); + assert(ds->ds_num == data->values_len); + assert(data->values_len > 0); instance_list_ptr = instance_list; - value_table_ptr = calloc (data->values_len, sizeof (*value_table_ptr)); + value_table_ptr = calloc(data->values_len, sizeof(*value_table_ptr)); if (value_table_ptr == NULL) return (-1); for (i = 0; i < data->values_len; i++) value_table_ptr[i] = value_table[i]; vl.values_len = data->values_len; - vl.values = malloc (sizeof (*vl.values) * vl.values_len); - if (vl.values == NULL) - { - ERROR ("snmp plugin: malloc failed."); - sfree (value_table_ptr); + vl.values = malloc(sizeof(*vl.values) * vl.values_len); + if (vl.values == NULL) { + ERROR("snmp plugin: malloc failed."); + sfree(value_table_ptr); return (-1); } - sstrncpy (vl.host, host->name, sizeof (vl.host)); - sstrncpy (vl.plugin, "snmp", sizeof (vl.plugin)); + sstrncpy(vl.host, host->name, sizeof(vl.host)); + sstrncpy(vl.plugin, "snmp", sizeof(vl.plugin)); vl.interval = host->interval; have_more = 1; - while (have_more) - { + while (have_more) { _Bool suffix_skipped = 0; /* Determine next suffix to handle. */ - if (instance_list != NULL) - { - if (instance_list_ptr == NULL) - { + if (instance_list != NULL) { + if (instance_list_ptr == NULL) { have_more = 0; continue; } - memcpy (¤t_suffix, &instance_list_ptr->suffix, sizeof (current_suffix)); - } - else /* no instance configured */ + memcpy(¤t_suffix, &instance_list_ptr->suffix, + sizeof(current_suffix)); + } else /* no instance configured */ { csnmp_table_values_t *ptr = value_table_ptr[0]; - if (ptr == NULL) - { + if (ptr == NULL) { have_more = 0; continue; } - memcpy (¤t_suffix, &ptr->suffix, sizeof (current_suffix)); + memcpy(¤t_suffix, &ptr->suffix, sizeof(current_suffix)); } /* Update all the value_table_ptr to point at the entry with the same * trailing partial OID */ - for (i = 0; i < data->values_len; i++) - { - while ((value_table_ptr[i] != NULL) - && (csnmp_oid_compare (&value_table_ptr[i]->suffix, ¤t_suffix) < 0)) + for (i = 0; i < data->values_len; i++) { + while ( + (value_table_ptr[i] != NULL) && + (csnmp_oid_compare(&value_table_ptr[i]->suffix, ¤t_suffix) < 0)) value_table_ptr[i] = value_table_ptr[i]->next; - if (value_table_ptr[i] == NULL) - { + if (value_table_ptr[i] == NULL) { have_more = 0; break; - } - else if (csnmp_oid_compare (&value_table_ptr[i]->suffix, ¤t_suffix) > 0) - { + } else if (csnmp_oid_compare(&value_table_ptr[i]->suffix, + ¤t_suffix) > 0) { /* This suffix is missing in the subtree. Indicate this with the * "suffix_skipped" flag and try the next instance / suffix. */ suffix_skipped = 1; @@ -1314,8 +1198,7 @@ static int csnmp_dispatch_table (host_definition_t *host, data_definition_t *dat break; /* Matching the values failed. Start from the beginning again. */ - if (suffix_skipped) - { + if (suffix_skipped) { if (instance_list != NULL) instance_list_ptr = instance_list_ptr->next; else @@ -1324,36 +1207,35 @@ static int csnmp_dispatch_table (host_definition_t *host, data_definition_t *dat continue; } - /* if we reach this line, all value_table_ptr[i] are non-NULL and are set - * to the same subid. instance_list_ptr is either NULL or points to the - * same subid, too. */ +/* if we reach this line, all value_table_ptr[i] are non-NULL and are set + * to the same subid. instance_list_ptr is either NULL or points to the + * same subid, too. */ #if COLLECT_DEBUG - for (i = 1; i < data->values_len; i++) - { - assert (value_table_ptr[i] != NULL); - assert (csnmp_oid_compare (&value_table_ptr[i-1]->suffix, - &value_table_ptr[i]->suffix) == 0); + for (i = 1; i < data->values_len; i++) { + assert(value_table_ptr[i] != NULL); + assert(csnmp_oid_compare(&value_table_ptr[i - 1]->suffix, + &value_table_ptr[i]->suffix) == 0); } - assert ((instance_list_ptr == NULL) - || (csnmp_oid_compare (&instance_list_ptr->suffix, - &value_table_ptr[0]->suffix) == 0)); + assert((instance_list_ptr == NULL) || + (csnmp_oid_compare(&instance_list_ptr->suffix, + &value_table_ptr[0]->suffix) == 0)); #endif - sstrncpy (vl.type, data->type, sizeof (vl.type)); + sstrncpy(vl.type, data->type, sizeof(vl.type)); { char temp[DATA_MAX_NAME_LEN]; if (instance_list_ptr == NULL) - csnmp_oid_to_string (temp, sizeof (temp), ¤t_suffix); + csnmp_oid_to_string(temp, sizeof(temp), ¤t_suffix); else - sstrncpy (temp, instance_list_ptr->instance, sizeof (temp)); + sstrncpy(temp, instance_list_ptr->instance, sizeof(temp)); if (data->instance_prefix == NULL) - sstrncpy (vl.type_instance, temp, sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, temp, sizeof(vl.type_instance)); else - ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%s%s", - data->instance_prefix, temp); + ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s%s", + data->instance_prefix, temp); } for (i = 0; i < data->values_len; i++) @@ -1364,7 +1246,7 @@ static int csnmp_dispatch_table (host_definition_t *host, data_definition_t *dat * switch if you're using IF-MIB::ifDescr as Instance. */ if (vl.type_instance[0] != '\0') - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); if (instance_list != NULL) instance_list_ptr = instance_list_ptr->next; @@ -1372,14 +1254,13 @@ static int csnmp_dispatch_table (host_definition_t *host, data_definition_t *dat value_table_ptr[0] = value_table_ptr[0]->next; } /* while (have_more) */ - sfree (vl.values); - sfree (value_table_ptr); + sfree(vl.values); + sfree(value_table_ptr); return (0); } /* int csnmp_dispatch_table */ -static int csnmp_read_table (host_definition_t *host, data_definition_t *data) -{ +static int csnmp_read_table(host_definition_t *host, data_definition_t *data) { struct snmp_pdu *req; struct snmp_pdu *res = NULL; struct variable_list *vb; @@ -1398,41 +1279,40 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data) size_t i; /* `value_list_head' and `value_list_tail' implement a linked list for each - * value. `instance_list_head' and `instance_list_tail' implement a linked list of + * value. `instance_list_head' and `instance_list_tail' implement a linked + * list of * instance names. This is used to jump gaps in the table. */ csnmp_list_instances_t *instance_list_head; csnmp_list_instances_t *instance_list_tail; csnmp_table_values_t **value_list_head; csnmp_table_values_t **value_list_tail; - DEBUG ("snmp plugin: csnmp_read_table (host = %s, data = %s)", - host->name, data->name); + DEBUG("snmp plugin: csnmp_read_table (host = %s, data = %s)", host->name, + data->name); - if (host->sess_handle == NULL) - { - DEBUG ("snmp plugin: csnmp_read_table: host->sess_handle == NULL"); + if (host->sess_handle == NULL) { + DEBUG("snmp plugin: csnmp_read_table: host->sess_handle == NULL"); return (-1); } - ds = plugin_get_ds (data->type); - if (!ds) - { - ERROR ("snmp plugin: DataSet `%s' not defined.", data->type); + ds = plugin_get_ds(data->type); + if (!ds) { + ERROR("snmp plugin: DataSet `%s' not defined.", data->type); return (-1); } - if (ds->ds_num != data->values_len) - { - ERROR ("snmp plugin: DataSet `%s' requires %zu values, but config talks about %zu", - data->type, ds->ds_num, data->values_len); + if (ds->ds_num != data->values_len) { + ERROR("snmp plugin: DataSet `%s' requires %zu values, but config talks " + "about %zu", + data->type, ds->ds_num, data->values_len); return (-1); } - assert (data->values_len > 0); + assert(data->values_len > 0); /* We need a copy of all the OIDs, because GETNEXT will destroy them. */ - memcpy (oid_list, data->values, data->values_len * sizeof (oid_t)); + memcpy(oid_list, data->values, data->values_len * sizeof(oid_t)); if (data->instance.oid.oid_len > 0) - memcpy (oid_list + data->values_len, &data->instance.oid, sizeof (oid_t)); + memcpy(oid_list + data->values_len, &data->instance.oid, sizeof(oid_t)); else /* no InstanceFrom option specified. */ oid_list_len--; @@ -1442,13 +1322,12 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data) /* We're going to construct n linked lists, one for each "value". * value_list_head will contain pointers to the heads of these linked lists, * value_list_tail will contain pointers to the tail of the lists. */ - value_list_head = calloc (data->values_len, sizeof (*value_list_head)); - value_list_tail = calloc (data->values_len, sizeof (*value_list_tail)); - if ((value_list_head == NULL) || (value_list_tail == NULL)) - { - ERROR ("snmp plugin: csnmp_read_table: calloc failed."); - sfree (value_list_head); - sfree (value_list_tail); + value_list_head = calloc(data->values_len, sizeof(*value_list_head)); + value_list_tail = calloc(data->values_len, sizeof(*value_list_tail)); + if ((value_list_head == NULL) || (value_list_tail == NULL)) { + ERROR("snmp plugin: csnmp_read_table: calloc failed."); + sfree(value_list_head); + sfree(value_list_tail); return (-1); } @@ -1456,151 +1335,139 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data) instance_list_tail = NULL; status = 0; - while (status == 0) - { + while (status == 0) { int oid_list_todo_num; - req = snmp_pdu_create (SNMP_MSG_GETNEXT); - if (req == NULL) - { - ERROR ("snmp plugin: snmp_pdu_create failed."); + req = snmp_pdu_create(SNMP_MSG_GETNEXT); + if (req == NULL) { + ERROR("snmp plugin: snmp_pdu_create failed."); status = -1; break; } oid_list_todo_num = 0; - for (i = 0; i < oid_list_len; i++) - { + for (i = 0; i < oid_list_len; i++) { /* Do not rerequest already finished OIDs */ if (!oid_list_todo[i]) continue; oid_list_todo_num++; - snmp_add_null_var (req, oid_list[i].oid, oid_list[i].oid_len); + snmp_add_null_var(req, oid_list[i].oid, oid_list[i].oid_len); } - if (oid_list_todo_num == 0) - { + if (oid_list_todo_num == 0) { /* The request is still empty - so we are finished */ - DEBUG ("snmp plugin: all variables have left their subtree"); + DEBUG("snmp plugin: all variables have left their subtree"); status = 0; break; } res = NULL; - status = snmp_sess_synch_response (host->sess_handle, req, &res); - if ((status != STAT_SUCCESS) || (res == NULL)) - { + status = snmp_sess_synch_response(host->sess_handle, req, &res); + if ((status != STAT_SUCCESS) || (res == NULL)) { char *errstr = NULL; - snmp_sess_error (host->sess_handle, NULL, NULL, &errstr); + snmp_sess_error(host->sess_handle, NULL, NULL, &errstr); - c_complain (LOG_ERR, &host->complaint, - "snmp plugin: host %s: snmp_sess_synch_response failed: %s", - host->name, (errstr == NULL) ? "Unknown problem" : errstr); + c_complain(LOG_ERR, &host->complaint, + "snmp plugin: host %s: snmp_sess_synch_response failed: %s", + host->name, (errstr == NULL) ? "Unknown problem" : errstr); if (res != NULL) - snmp_free_pdu (res); + snmp_free_pdu(res); res = NULL; /* snmp_synch_response already freed our PDU */ req = NULL; - sfree (errstr); - csnmp_host_close_session (host); + sfree(errstr); + csnmp_host_close_session(host); status = -1; break; } status = 0; - assert (res != NULL); - c_release (LOG_INFO, &host->complaint, - "snmp plugin: host %s: snmp_sess_synch_response successful.", - host->name); + assert(res != NULL); + c_release(LOG_INFO, &host->complaint, + "snmp plugin: host %s: snmp_sess_synch_response successful.", + host->name); vb = res->variables; - if (vb == NULL) - { + if (vb == NULL) { status = -1; break; } - for (vb = res->variables, i = 0; (vb != NULL); vb = vb->next_variable, i++) - { + for (vb = res->variables, i = 0; (vb != NULL); + vb = vb->next_variable, i++) { /* Calculate value index from todo list */ while ((i < oid_list_len) && !oid_list_todo[i]) i++; /* An instance is configured and the res variable we process is the * instance value (last index) */ - if ((data->instance.oid.oid_len > 0) && (i == data->values_len)) - { - if ((vb->type == SNMP_ENDOFMIBVIEW) - || (snmp_oid_ncompare (data->instance.oid.oid, - data->instance.oid.oid_len, - vb->name, vb->name_length, - data->instance.oid.oid_len) != 0)) - { - DEBUG ("snmp plugin: host = %s; data = %s; Instance left its subtree.", - host->name, data->name); + if ((data->instance.oid.oid_len > 0) && (i == data->values_len)) { + if ((vb->type == SNMP_ENDOFMIBVIEW) || + (snmp_oid_ncompare( + data->instance.oid.oid, data->instance.oid.oid_len, vb->name, + vb->name_length, data->instance.oid.oid_len) != 0)) { + DEBUG("snmp plugin: host = %s; data = %s; Instance left its subtree.", + host->name, data->name); oid_list_todo[i] = 0; continue; } /* Allocate a new `csnmp_list_instances_t', insert the instance name and * add it to the list */ - if (csnmp_instance_list_add (&instance_list_head, &instance_list_tail, - res, host, data) != 0) - { - ERROR ("snmp plugin: host %s: csnmp_instance_list_add failed.", - host->name); + if (csnmp_instance_list_add(&instance_list_head, &instance_list_tail, + res, host, data) != 0) { + ERROR("snmp plugin: host %s: csnmp_instance_list_add failed.", + host->name); status = -1; break; } - } - else /* The variable we are processing is a normal value */ + } else /* The variable we are processing is a normal value */ { csnmp_table_values_t *vt; oid_t vb_name; oid_t suffix; int ret; - csnmp_oid_init (&vb_name, vb->name, vb->name_length); + csnmp_oid_init(&vb_name, vb->name, vb->name_length); /* Calculate the current suffix. This is later used to check that the * suffix is increasing. This also checks if we left the subtree */ - ret = csnmp_oid_suffix (&suffix, &vb_name, data->values + i); - if (ret != 0) - { - DEBUG ("snmp plugin: host = %s; data = %s; i = %zu; " - "Value probably left its subtree.", - host->name, data->name, i); + ret = csnmp_oid_suffix(&suffix, &vb_name, data->values + i); + if (ret != 0) { + DEBUG("snmp plugin: host = %s; data = %s; i = %zu; " + "Value probably left its subtree.", + host->name, data->name, i); oid_list_todo[i] = 0; continue; } - /* Make sure the OIDs returned by the agent are increasing. Otherwise our + /* Make sure the OIDs returned by the agent are increasing. Otherwise + * our * table matching algorithm will get confused. */ - if ((value_list_tail[i] != NULL) - && (csnmp_oid_compare (&suffix, &value_list_tail[i]->suffix) <= 0)) - { - DEBUG ("snmp plugin: host = %s; data = %s; i = %zu; " - "Suffix is not increasing.", - host->name, data->name, i); + if ((value_list_tail[i] != NULL) && + (csnmp_oid_compare(&suffix, &value_list_tail[i]->suffix) <= 0)) { + DEBUG("snmp plugin: host = %s; data = %s; i = %zu; " + "Suffix is not increasing.", + host->name, data->name, i); oid_list_todo[i] = 0; continue; } - vt = calloc (1, sizeof (*vt)); - if (vt == NULL) - { - ERROR ("snmp plugin: calloc failed."); + vt = calloc(1, sizeof(*vt)); + if (vt == NULL) { + ERROR("snmp plugin: calloc failed."); status = -1; break; } - vt->value = csnmp_value_list_to_value (vb, ds->ds[i].type, - data->scale, data->shift, host->name, data->name); - memcpy (&vt->suffix, &suffix, sizeof (vt->suffix)); + vt->value = + csnmp_value_list_to_value(vb, ds->ds[i].type, data->scale, + data->shift, host->name, data->name); + memcpy(&vt->suffix, &suffix, sizeof(vt->suffix)); vt->next = NULL; if (value_list_tail[i] == NULL) @@ -1611,53 +1478,49 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data) } /* Copy OID to oid_list[i] */ - memcpy (oid_list[i].oid, vb->name, sizeof (oid) * vb->name_length); + memcpy(oid_list[i].oid, vb->name, sizeof(oid) * vb->name_length); oid_list[i].oid_len = vb->name_length; } /* for (vb = res->variables ...) */ if (res != NULL) - snmp_free_pdu (res); + snmp_free_pdu(res); res = NULL; } /* while (status == 0) */ if (res != NULL) - snmp_free_pdu (res); + snmp_free_pdu(res); res = NULL; if (req != NULL) - snmp_free_pdu (req); + snmp_free_pdu(req); req = NULL; if (status == 0) - csnmp_dispatch_table (host, data, instance_list_head, value_list_head); + csnmp_dispatch_table(host, data, instance_list_head, value_list_head); /* Free all allocated variables here */ - while (instance_list_head != NULL) - { + while (instance_list_head != NULL) { csnmp_list_instances_t *next = instance_list_head->next; - sfree (instance_list_head); + sfree(instance_list_head); instance_list_head = next; } - for (i = 0; i < data->values_len; i++) - { - while (value_list_head[i] != NULL) - { + for (i = 0; i < data->values_len; i++) { + while (value_list_head[i] != NULL) { csnmp_table_values_t *next = value_list_head[i]->next; - sfree (value_list_head[i]); + sfree(value_list_head[i]); value_list_head[i] = next; } } - sfree (value_list_head); - sfree (value_list_tail); + sfree(value_list_head); + sfree(value_list_tail); return (0); } /* int csnmp_read_table */ -static int csnmp_read_value (host_definition_t *host, data_definition_t *data) -{ +static int csnmp_read_value(host_definition_t *host, data_definition_t *data) { struct snmp_pdu *req; struct snmp_pdu *res = NULL; struct variable_list *vb; @@ -1668,107 +1531,99 @@ static int csnmp_read_value (host_definition_t *host, data_definition_t *data) int status; size_t i; - DEBUG ("snmp plugin: csnmp_read_value (host = %s, data = %s)", - host->name, data->name); + DEBUG("snmp plugin: csnmp_read_value (host = %s, data = %s)", host->name, + data->name); - if (host->sess_handle == NULL) - { - DEBUG ("snmp plugin: csnmp_read_value: host->sess_handle == NULL"); + if (host->sess_handle == NULL) { + DEBUG("snmp plugin: csnmp_read_value: host->sess_handle == NULL"); return (-1); } - ds = plugin_get_ds (data->type); - if (!ds) - { - ERROR ("snmp plugin: DataSet `%s' not defined.", data->type); + ds = plugin_get_ds(data->type); + if (!ds) { + ERROR("snmp plugin: DataSet `%s' not defined.", data->type); return (-1); } - if (ds->ds_num != data->values_len) - { - ERROR ("snmp plugin: DataSet `%s' requires %zu values, but config talks about %zu", - data->type, ds->ds_num, data->values_len); + if (ds->ds_num != data->values_len) { + ERROR("snmp plugin: DataSet `%s' requires %zu values, but config talks " + "about %zu", + data->type, ds->ds_num, data->values_len); return (-1); } vl.values_len = ds->ds_num; - vl.values = malloc (sizeof (*vl.values) * vl.values_len); + vl.values = malloc(sizeof(*vl.values) * vl.values_len); if (vl.values == NULL) return (-1); - for (i = 0; i < vl.values_len; i++) - { + for (i = 0; i < vl.values_len; i++) { if (ds->ds[i].type == DS_TYPE_COUNTER) vl.values[i].counter = 0; else vl.values[i].gauge = NAN; } - sstrncpy (vl.host, host->name, sizeof (vl.host)); - sstrncpy (vl.plugin, "snmp", sizeof (vl.plugin)); - sstrncpy (vl.type, data->type, sizeof (vl.type)); - sstrncpy (vl.type_instance, data->instance.string, sizeof (vl.type_instance)); + sstrncpy(vl.host, host->name, sizeof(vl.host)); + sstrncpy(vl.plugin, "snmp", sizeof(vl.plugin)); + sstrncpy(vl.type, data->type, sizeof(vl.type)); + sstrncpy(vl.type_instance, data->instance.string, sizeof(vl.type_instance)); vl.interval = host->interval; - req = snmp_pdu_create (SNMP_MSG_GET); - if (req == NULL) - { - ERROR ("snmp plugin: snmp_pdu_create failed."); - sfree (vl.values); + req = snmp_pdu_create(SNMP_MSG_GET); + if (req == NULL) { + ERROR("snmp plugin: snmp_pdu_create failed."); + sfree(vl.values); return (-1); } for (i = 0; i < data->values_len; i++) - snmp_add_null_var (req, data->values[i].oid, data->values[i].oid_len); + snmp_add_null_var(req, data->values[i].oid, data->values[i].oid_len); - status = snmp_sess_synch_response (host->sess_handle, req, &res); + status = snmp_sess_synch_response(host->sess_handle, req, &res); - if ((status != STAT_SUCCESS) || (res == NULL)) - { + if ((status != STAT_SUCCESS) || (res == NULL)) { char *errstr = NULL; - snmp_sess_error (host->sess_handle, NULL, NULL, &errstr); - ERROR ("snmp plugin: host %s: snmp_sess_synch_response failed: %s", - host->name, (errstr == NULL) ? "Unknown problem" : errstr); + snmp_sess_error(host->sess_handle, NULL, NULL, &errstr); + ERROR("snmp plugin: host %s: snmp_sess_synch_response failed: %s", + host->name, (errstr == NULL) ? "Unknown problem" : errstr); if (res != NULL) - snmp_free_pdu (res); + snmp_free_pdu(res); - sfree (errstr); - sfree (vl.values); - csnmp_host_close_session (host); + sfree(errstr); + sfree(vl.values); + csnmp_host_close_session(host); return (-1); } - - for (vb = res->variables; vb != NULL; vb = vb->next_variable) - { + for (vb = res->variables; vb != NULL; vb = vb->next_variable) { #if COLLECT_DEBUG char buffer[1024]; - snprint_variable (buffer, sizeof (buffer), - vb->name, vb->name_length, vb); - DEBUG ("snmp plugin: Got this variable: %s", buffer); + snprint_variable(buffer, sizeof(buffer), vb->name, vb->name_length, vb); + DEBUG("snmp plugin: Got this variable: %s", buffer); #endif /* COLLECT_DEBUG */ for (i = 0; i < data->values_len; i++) - if (snmp_oid_compare (data->values[i].oid, data->values[i].oid_len, - vb->name, vb->name_length) == 0) - vl.values[i] = csnmp_value_list_to_value (vb, ds->ds[i].type, - data->scale, data->shift, host->name, data->name); + if (snmp_oid_compare(data->values[i].oid, data->values[i].oid_len, + vb->name, vb->name_length) == 0) + vl.values[i] = + csnmp_value_list_to_value(vb, ds->ds[i].type, data->scale, + data->shift, host->name, data->name); } /* for (res->variables) */ - snmp_free_pdu (res); + snmp_free_pdu(res); - DEBUG ("snmp plugin: -> plugin_dispatch_values (&vl);"); - plugin_dispatch_values (&vl); - sfree (vl.values); + DEBUG("snmp plugin: -> plugin_dispatch_values (&vl);"); + plugin_dispatch_values(&vl); + sfree(vl.values); return (0); } /* int csnmp_read_value */ -static int csnmp_read_host (user_data_t *ud) -{ +static int csnmp_read_host(user_data_t *ud) { host_definition_t *host; int status; int success; @@ -1777,23 +1632,22 @@ static int csnmp_read_host (user_data_t *ud) host = ud->data; if (host->interval == 0) - host->interval = plugin_get_interval (); + host->interval = plugin_get_interval(); if (host->sess_handle == NULL) - csnmp_host_open_session (host); + csnmp_host_open_session(host); if (host->sess_handle == NULL) return (-1); success = 0; - for (i = 0; i < host->data_list_len; i++) - { + for (i = 0; i < host->data_list_len; i++) { data_definition_t *data = host->data_list[i]; if (data->is_table) - status = csnmp_read_table (host, data); + status = csnmp_read_table(host, data); else - status = csnmp_read_value (host, data); + status = csnmp_read_value(host, data); if (status == 0) success++; @@ -1805,33 +1659,30 @@ static int csnmp_read_host (user_data_t *ud) return (0); } /* int csnmp_read_host */ -static int csnmp_init (void) -{ - call_snmp_init_once (); +static int csnmp_init(void) { + call_snmp_init_once(); return (0); } /* int csnmp_init */ -static int csnmp_shutdown (void) -{ +static int csnmp_shutdown(void) { data_definition_t *data_this; data_definition_t *data_next; /* When we get here, the read threads have been stopped and all the * `host_definition_t' will be freed. */ - DEBUG ("snmp plugin: Destroying all data definitions."); + DEBUG("snmp plugin: Destroying all data definitions."); data_this = data_head; data_head = NULL; - while (data_this != NULL) - { + while (data_this != NULL) { data_next = data_this->next; - sfree (data_this->name); - sfree (data_this->type); - sfree (data_this->values); - sfree (data_this->ignores); - sfree (data_this); + sfree(data_this->name); + sfree(data_this->type); + sfree(data_this->values); + sfree(data_this->ignores); + sfree(data_this); data_this = data_next; } @@ -1839,11 +1690,10 @@ static int csnmp_shutdown (void) return (0); } /* int csnmp_shutdown */ -void module_register (void) -{ - plugin_register_complex_config ("snmp", csnmp_config); - plugin_register_init ("snmp", csnmp_init); - plugin_register_shutdown ("snmp", csnmp_shutdown); +void module_register(void) { + plugin_register_complex_config("snmp", csnmp_config); + plugin_register_init("snmp", csnmp_init); + plugin_register_shutdown("snmp", csnmp_shutdown); } /* void module_register */ /* diff --git a/src/statsd.c b/src/statsd.c index 491fe423..47e01d80 100644 --- a/src/statsd.c +++ b/src/statsd.c @@ -26,39 +26,32 @@ #include "collectd.h" -#include "plugin.h" #include "common.h" +#include "plugin.h" #include "utils_avltree.h" #include "utils_latency.h" -#include #include #include +#include /* AIX doesn't have MSG_DONTWAIT */ #ifndef MSG_DONTWAIT -# define MSG_DONTWAIT MSG_NONBLOCK +#define MSG_DONTWAIT MSG_NONBLOCK #endif #ifndef STATSD_DEFAULT_NODE -# define STATSD_DEFAULT_NODE NULL +#define STATSD_DEFAULT_NODE NULL #endif #ifndef STATSD_DEFAULT_SERVICE -# define STATSD_DEFAULT_SERVICE "8125" +#define STATSD_DEFAULT_SERVICE "8125" #endif -enum metric_type_e -{ - STATSD_COUNTER, - STATSD_TIMER, - STATSD_GAUGE, - STATSD_SET -}; +enum metric_type_e { STATSD_COUNTER, STATSD_TIMER, STATSD_GAUGE, STATSD_SET }; typedef enum metric_type_e metric_type_t; -struct statsd_metric_s -{ +struct statsd_metric_s { metric_type_t type; double value; derive_t counter; @@ -68,67 +61,72 @@ struct statsd_metric_s }; typedef struct statsd_metric_s statsd_metric_t; -static c_avl_tree_t *metrics_tree = NULL; +static c_avl_tree_t *metrics_tree = NULL; static pthread_mutex_t metrics_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_t network_thread; -static _Bool network_thread_running = 0; -static _Bool network_thread_shutdown = 0; +static _Bool network_thread_running = 0; +static _Bool network_thread_shutdown = 0; static char *conf_node = NULL; static char *conf_service = NULL; static _Bool conf_delete_counters = 0; -static _Bool conf_delete_timers = 0; -static _Bool conf_delete_gauges = 0; -static _Bool conf_delete_sets = 0; +static _Bool conf_delete_timers = 0; +static _Bool conf_delete_gauges = 0; +static _Bool conf_delete_sets = 0; static double *conf_timer_percentile = NULL; -static size_t conf_timer_percentile_num = 0; +static size_t conf_timer_percentile_num = 0; -static _Bool conf_counter_sum = 0; -static _Bool conf_timer_lower = 0; -static _Bool conf_timer_upper = 0; -static _Bool conf_timer_sum = 0; -static _Bool conf_timer_count = 0; +static _Bool conf_counter_sum = 0; +static _Bool conf_timer_lower = 0; +static _Bool conf_timer_upper = 0; +static _Bool conf_timer_sum = 0; +static _Bool conf_timer_count = 0; /* Must hold metrics_lock when calling this function. */ -static statsd_metric_t *statsd_metric_lookup_unsafe (char const *name, /* {{{ */ - metric_type_t type) -{ +static statsd_metric_t *statsd_metric_lookup_unsafe(char const *name, /* {{{ */ + metric_type_t type) { char key[DATA_MAX_NAME_LEN + 2]; char *key_copy; statsd_metric_t *metric; int status; - switch (type) - { - case STATSD_COUNTER: key[0] = 'c'; break; - case STATSD_TIMER: key[0] = 't'; break; - case STATSD_GAUGE: key[0] = 'g'; break; - case STATSD_SET: key[0] = 's'; break; - default: return (NULL); + switch (type) { + case STATSD_COUNTER: + key[0] = 'c'; + break; + case STATSD_TIMER: + key[0] = 't'; + break; + case STATSD_GAUGE: + key[0] = 'g'; + break; + case STATSD_SET: + key[0] = 's'; + break; + default: + return (NULL); } key[1] = ':'; - sstrncpy (&key[2], name, sizeof (key) - 2); + sstrncpy(&key[2], name, sizeof(key) - 2); - status = c_avl_get (metrics_tree, key, (void *) &metric); + status = c_avl_get(metrics_tree, key, (void *)&metric); if (status == 0) return (metric); - key_copy = strdup (key); - if (key_copy == NULL) - { - ERROR ("statsd plugin: strdup failed."); + key_copy = strdup(key); + if (key_copy == NULL) { + ERROR("statsd plugin: strdup failed."); return (NULL); } - metric = calloc (1, sizeof (*metric)); - if (metric == NULL) - { - ERROR ("statsd plugin: calloc failed."); - sfree (key_copy); + metric = calloc(1, sizeof(*metric)); + if (metric == NULL) { + ERROR("statsd plugin: calloc failed."); + sfree(key_copy); return (NULL); } @@ -136,106 +134,96 @@ static statsd_metric_t *statsd_metric_lookup_unsafe (char const *name, /* {{{ */ metric->latency = NULL; metric->set = NULL; - status = c_avl_insert (metrics_tree, key_copy, metric); - if (status != 0) - { - ERROR ("statsd plugin: c_avl_insert failed."); - sfree (key_copy); - sfree (metric); + status = c_avl_insert(metrics_tree, key_copy, metric); + if (status != 0) { + ERROR("statsd plugin: c_avl_insert failed."); + sfree(key_copy); + sfree(metric); return (NULL); } return (metric); } /* }}} statsd_metric_lookup_unsafe */ -static int statsd_metric_set (char const *name, double value, /* {{{ */ - metric_type_t type) -{ +static int statsd_metric_set(char const *name, double value, /* {{{ */ + metric_type_t type) { statsd_metric_t *metric; - pthread_mutex_lock (&metrics_lock); + pthread_mutex_lock(&metrics_lock); - metric = statsd_metric_lookup_unsafe (name, type); - if (metric == NULL) - { - pthread_mutex_unlock (&metrics_lock); + metric = statsd_metric_lookup_unsafe(name, type); + if (metric == NULL) { + pthread_mutex_unlock(&metrics_lock); return (-1); } metric->value = value; metric->updates_num++; - pthread_mutex_unlock (&metrics_lock); + pthread_mutex_unlock(&metrics_lock); return (0); } /* }}} int statsd_metric_set */ -static int statsd_metric_add (char const *name, double delta, /* {{{ */ - metric_type_t type) -{ +static int statsd_metric_add(char const *name, double delta, /* {{{ */ + metric_type_t type) { statsd_metric_t *metric; - pthread_mutex_lock (&metrics_lock); + pthread_mutex_lock(&metrics_lock); - metric = statsd_metric_lookup_unsafe (name, type); - if (metric == NULL) - { - pthread_mutex_unlock (&metrics_lock); + metric = statsd_metric_lookup_unsafe(name, type); + if (metric == NULL) { + pthread_mutex_unlock(&metrics_lock); return (-1); } metric->value += delta; metric->updates_num++; - pthread_mutex_unlock (&metrics_lock); + pthread_mutex_unlock(&metrics_lock); return (0); } /* }}} int statsd_metric_add */ -static void statsd_metric_free (statsd_metric_t *metric) /* {{{ */ +static void statsd_metric_free(statsd_metric_t *metric) /* {{{ */ { if (metric == NULL) return; - if (metric->latency != NULL) - { - latency_counter_destroy (metric->latency); + if (metric->latency != NULL) { + latency_counter_destroy(metric->latency); metric->latency = NULL; } - if (metric->set != NULL) - { + if (metric->set != NULL) { void *key; void *value; - while (c_avl_pick (metric->set, &key, &value) == 0) - { - sfree (key); - assert (value == NULL); + while (c_avl_pick(metric->set, &key, &value) == 0) { + sfree(key); + assert(value == NULL); } - c_avl_destroy (metric->set); + c_avl_destroy(metric->set); metric->set = NULL; } - sfree (metric); + sfree(metric); } /* }}} void statsd_metric_free */ -static int statsd_parse_value (char const *str, value_t *ret_value) /* {{{ */ +static int statsd_parse_value(char const *str, value_t *ret_value) /* {{{ */ { char *endptr = NULL; - ret_value->gauge = (gauge_t) strtod (str, &endptr); + ret_value->gauge = (gauge_t)strtod(str, &endptr); if ((str == endptr) || ((endptr != NULL) && (*endptr != 0))) return (-1); return (0); } /* }}} int statsd_parse_value */ -static int statsd_handle_counter (char const *name, /* {{{ */ - char const *value_str, - char const *extra) -{ +static int statsd_handle_counter(char const *name, /* {{{ */ + char const *value_str, char const *extra) { value_t value; value_t scale; int status; @@ -244,48 +232,44 @@ static int statsd_handle_counter (char const *name, /* {{{ */ return (-1); scale.gauge = 1.0; - if (extra != NULL) - { - status = statsd_parse_value (extra + 1, &scale); + if (extra != NULL) { + status = statsd_parse_value(extra + 1, &scale); if (status != 0) return (status); - if (!isfinite (scale.gauge) || (scale.gauge <= 0.0) || (scale.gauge > 1.0)) + if (!isfinite(scale.gauge) || (scale.gauge <= 0.0) || (scale.gauge > 1.0)) return (-1); } value.gauge = 1.0; - status = statsd_parse_value (value_str, &value); + status = statsd_parse_value(value_str, &value); if (status != 0) return (status); /* Changes to the counter are added to (statsd_metric_t*)->value. ->counter is * only updated in statsd_metric_submit_unsafe(). */ - return (statsd_metric_add (name, (double) (value.gauge / scale.gauge), - STATSD_COUNTER)); + return (statsd_metric_add(name, (double)(value.gauge / scale.gauge), + STATSD_COUNTER)); } /* }}} int statsd_handle_counter */ -static int statsd_handle_gauge (char const *name, /* {{{ */ - char const *value_str) -{ +static int statsd_handle_gauge(char const *name, /* {{{ */ + char const *value_str) { value_t value; int status; value.gauge = 0; - status = statsd_parse_value (value_str, &value); + status = statsd_parse_value(value_str, &value); if (status != 0) return (status); if ((value_str[0] == '+') || (value_str[0] == '-')) - return (statsd_metric_add (name, (double) value.gauge, STATSD_GAUGE)); + return (statsd_metric_add(name, (double)value.gauge, STATSD_GAUGE)); else - return (statsd_metric_set (name, (double) value.gauge, STATSD_GAUGE)); + return (statsd_metric_set(name, (double)value.gauge, STATSD_GAUGE)); } /* }}} int statsd_handle_gauge */ -static int statsd_handle_timer (char const *name, /* {{{ */ - char const *value_str, - char const *extra) -{ +static int statsd_handle_timer(char const *name, /* {{{ */ + char const *value_str, char const *extra) { statsd_metric_t *metric; value_t value_ms; value_t scale; @@ -296,207 +280,192 @@ static int statsd_handle_timer (char const *name, /* {{{ */ return (-1); scale.gauge = 1.0; - if (extra != NULL) - { - status = statsd_parse_value (extra + 1, &scale); + if (extra != NULL) { + status = statsd_parse_value(extra + 1, &scale); if (status != 0) return (status); - if (!isfinite (scale.gauge) || (scale.gauge <= 0.0) || (scale.gauge > 1.0)) + if (!isfinite(scale.gauge) || (scale.gauge <= 0.0) || (scale.gauge > 1.0)) return (-1); } value_ms.derive = 0; - status = statsd_parse_value (value_str, &value_ms); + status = statsd_parse_value(value_str, &value_ms); if (status != 0) return (status); - value = MS_TO_CDTIME_T (value_ms.gauge / scale.gauge); + value = MS_TO_CDTIME_T(value_ms.gauge / scale.gauge); - pthread_mutex_lock (&metrics_lock); + pthread_mutex_lock(&metrics_lock); - metric = statsd_metric_lookup_unsafe (name, STATSD_TIMER); - if (metric == NULL) - { - pthread_mutex_unlock (&metrics_lock); + metric = statsd_metric_lookup_unsafe(name, STATSD_TIMER); + if (metric == NULL) { + pthread_mutex_unlock(&metrics_lock); return (-1); } if (metric->latency == NULL) - metric->latency = latency_counter_create (); - if (metric->latency == NULL) - { - pthread_mutex_unlock (&metrics_lock); + metric->latency = latency_counter_create(); + if (metric->latency == NULL) { + pthread_mutex_unlock(&metrics_lock); return (-1); } - latency_counter_add (metric->latency, value); + latency_counter_add(metric->latency, value); metric->updates_num++; - pthread_mutex_unlock (&metrics_lock); + pthread_mutex_unlock(&metrics_lock); return (0); } /* }}} int statsd_handle_timer */ -static int statsd_handle_set (char const *name, /* {{{ */ - char const *set_key_orig) -{ +static int statsd_handle_set(char const *name, /* {{{ */ + char const *set_key_orig) { statsd_metric_t *metric = NULL; char *set_key; int status; - pthread_mutex_lock (&metrics_lock); + pthread_mutex_lock(&metrics_lock); - metric = statsd_metric_lookup_unsafe (name, STATSD_SET); - if (metric == NULL) - { - pthread_mutex_unlock (&metrics_lock); + metric = statsd_metric_lookup_unsafe(name, STATSD_SET); + if (metric == NULL) { + pthread_mutex_unlock(&metrics_lock); return (-1); } /* Make sure metric->set exists. */ if (metric->set == NULL) - metric->set = c_avl_create ((int (*) (const void *, const void *)) strcmp); + metric->set = c_avl_create((int (*)(const void *, const void *))strcmp); - if (metric->set == NULL) - { - pthread_mutex_unlock (&metrics_lock); - ERROR ("statsd plugin: c_avl_create failed."); + if (metric->set == NULL) { + pthread_mutex_unlock(&metrics_lock); + ERROR("statsd plugin: c_avl_create failed."); return (-1); } - set_key = strdup (set_key_orig); - if (set_key == NULL) - { - pthread_mutex_unlock (&metrics_lock); - ERROR ("statsd plugin: strdup failed."); + set_key = strdup(set_key_orig); + if (set_key == NULL) { + pthread_mutex_unlock(&metrics_lock); + ERROR("statsd plugin: strdup failed."); return (-1); } - status = c_avl_insert (metric->set, set_key, /* value = */ NULL); - if (status < 0) - { - pthread_mutex_unlock (&metrics_lock); + status = c_avl_insert(metric->set, set_key, /* value = */ NULL); + if (status < 0) { + pthread_mutex_unlock(&metrics_lock); if (status < 0) - ERROR ("statsd plugin: c_avl_insert (\"%s\") failed with status %i.", - set_key, status); - sfree (set_key); + ERROR("statsd plugin: c_avl_insert (\"%s\") failed with status %i.", + set_key, status); + sfree(set_key); return (-1); - } - else if (status > 0) /* key already exists */ + } else if (status > 0) /* key already exists */ { - sfree (set_key); + sfree(set_key); } metric->updates_num++; - pthread_mutex_unlock (&metrics_lock); + pthread_mutex_unlock(&metrics_lock); return (0); } /* }}} int statsd_handle_set */ -static int statsd_parse_line (char *buffer) /* {{{ */ +static int statsd_parse_line(char *buffer) /* {{{ */ { char *name = buffer; char *value; char *type; char *extra; - type = strchr (name, '|'); + type = strchr(name, '|'); if (type == NULL) return (-1); *type = 0; type++; - value = strrchr (name, ':'); + value = strrchr(name, ':'); if (value == NULL) return (-1); *value = 0; value++; - extra = strchr (type, '|'); - if (extra != NULL) - { + extra = strchr(type, '|'); + if (extra != NULL) { *extra = 0; extra++; } - if (strcmp ("c", type) == 0) - return (statsd_handle_counter (name, value, extra)); - else if (strcmp ("ms", type) == 0) - return (statsd_handle_timer (name, value, extra)); + if (strcmp("c", type) == 0) + return (statsd_handle_counter(name, value, extra)); + else if (strcmp("ms", type) == 0) + return (statsd_handle_timer(name, value, extra)); /* extra is only valid for counters and timers */ if (extra != NULL) return (-1); - if (strcmp ("g", type) == 0) - return (statsd_handle_gauge (name, value)); - else if (strcmp ("s", type) == 0) - return (statsd_handle_set (name, value)); + if (strcmp("g", type) == 0) + return (statsd_handle_gauge(name, value)); + else if (strcmp("s", type) == 0) + return (statsd_handle_set(name, value)); else return (-1); } /* }}} void statsd_parse_line */ -static void statsd_parse_buffer (char *buffer) /* {{{ */ +static void statsd_parse_buffer(char *buffer) /* {{{ */ { - while (buffer != NULL) - { + while (buffer != NULL) { char orig[64]; char *next; int status; - next = strchr (buffer, '\n'); - if (next != NULL) - { + next = strchr(buffer, '\n'); + if (next != NULL) { *next = 0; next++; } - if (*buffer == 0) - { + if (*buffer == 0) { buffer = next; continue; } - sstrncpy (orig, buffer, sizeof (orig)); + sstrncpy(orig, buffer, sizeof(orig)); - status = statsd_parse_line (buffer); + status = statsd_parse_line(buffer); if (status != 0) - ERROR ("statsd plugin: Unable to parse line: \"%s\"", orig); + ERROR("statsd plugin: Unable to parse line: \"%s\"", orig); buffer = next; } } /* }}} void statsd_parse_buffer */ -static void statsd_network_read (int fd) /* {{{ */ +static void statsd_network_read(int fd) /* {{{ */ { char buffer[4096]; size_t buffer_size; ssize_t status; - status = recv (fd, buffer, sizeof (buffer), /* flags = */ MSG_DONTWAIT); - if (status < 0) - { + status = recv(fd, buffer, sizeof(buffer), /* flags = */ MSG_DONTWAIT); + if (status < 0) { char errbuf[1024]; if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) return; - ERROR ("statsd plugin: recv(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("statsd plugin: recv(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); return; } - buffer_size = (size_t) status; - if (buffer_size >= sizeof (buffer)) - buffer_size = sizeof (buffer) - 1; + buffer_size = (size_t)status; + if (buffer_size >= sizeof(buffer)) + buffer_size = sizeof(buffer) - 1; buffer[buffer_size] = 0; - statsd_parse_buffer (buffer); + statsd_parse_buffer(buffer); } /* }}} void statsd_network_read */ -static int statsd_network_init (struct pollfd **ret_fds, /* {{{ */ - size_t *ret_fds_num) -{ +static int statsd_network_init(struct pollfd **ret_fds, /* {{{ */ + size_t *ret_fds_num) { struct pollfd *fds = NULL; size_t fds_num = 0; @@ -504,77 +473,71 @@ static int statsd_network_init (struct pollfd **ret_fds, /* {{{ */ int status; char const *node = (conf_node != NULL) ? conf_node : STATSD_DEFAULT_NODE; - char const *service = (conf_service != NULL) - ? conf_service : STATSD_DEFAULT_SERVICE; + char const *service = + (conf_service != NULL) ? conf_service : STATSD_DEFAULT_SERVICE; - struct addrinfo ai_hints = { - .ai_family = AF_UNSPEC, - .ai_flags = AI_PASSIVE | AI_ADDRCONFIG, - .ai_socktype = SOCK_DGRAM - }; + struct addrinfo ai_hints = {.ai_family = AF_UNSPEC, + .ai_flags = AI_PASSIVE | AI_ADDRCONFIG, + .ai_socktype = SOCK_DGRAM}; - status = getaddrinfo (node, service, &ai_hints, &ai_list); - if (status != 0) - { - ERROR ("statsd plugin: getaddrinfo (\"%s\", \"%s\") failed: %s", - node, service, gai_strerror (status)); + status = getaddrinfo(node, service, &ai_hints, &ai_list); + if (status != 0) { + ERROR("statsd plugin: getaddrinfo (\"%s\", \"%s\") failed: %s", node, + service, gai_strerror(status)); return (status); } - for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) - { + for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; + ai_ptr = ai_ptr->ai_next) { int fd; struct pollfd *tmp; char dbg_node[NI_MAXHOST]; char dbg_service[NI_MAXSERV]; - fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); - if (fd < 0) - { + fd = socket(ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); + if (fd < 0) { char errbuf[1024]; - ERROR ("statsd plugin: socket(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("statsd plugin: socket(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); continue; } - getnameinfo (ai_ptr->ai_addr, ai_ptr->ai_addrlen, - dbg_node, sizeof (dbg_node), dbg_service, sizeof (dbg_service), - NI_DGRAM | NI_NUMERICHOST | NI_NUMERICSERV); - DEBUG ("statsd plugin: Trying to bind to [%s]:%s ...", dbg_node, dbg_service); + getnameinfo(ai_ptr->ai_addr, ai_ptr->ai_addrlen, dbg_node, sizeof(dbg_node), + dbg_service, sizeof(dbg_service), + NI_DGRAM | NI_NUMERICHOST | NI_NUMERICSERV); + DEBUG("statsd plugin: Trying to bind to [%s]:%s ...", dbg_node, + dbg_service); - status = bind (fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); - if (status != 0) - { + status = bind(fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); + if (status != 0) { char errbuf[1024]; - ERROR ("statsd plugin: bind(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - close (fd); + ERROR("statsd plugin: bind(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(fd); continue; } - tmp = realloc (fds, sizeof (*fds) * (fds_num + 1)); - if (tmp == NULL) - { - ERROR ("statsd plugin: realloc failed."); - close (fd); + tmp = realloc(fds, sizeof(*fds) * (fds_num + 1)); + if (tmp == NULL) { + ERROR("statsd plugin: realloc failed."); + close(fd); continue; } fds = tmp; tmp = fds + fds_num; fds_num++; - memset (tmp, 0, sizeof (*tmp)); + memset(tmp, 0, sizeof(*tmp)); tmp->fd = fd; tmp->events = POLLIN | POLLPRI; } - freeaddrinfo (ai_list); + freeaddrinfo(ai_list); - if (fds_num == 0) - { - ERROR ("statsd plugin: Unable to create listening socket for [%s]:%s.", - (node != NULL) ? node : "::", service); + if (fds_num == 0) { + ERROR("statsd plugin: Unable to create listening socket for [%s]:%s.", + (node != NULL) ? node : "::", service); return (ENOENT); } @@ -583,74 +546,69 @@ static int statsd_network_init (struct pollfd **ret_fds, /* {{{ */ return (0); } /* }}} int statsd_network_init */ -static void *statsd_network_thread (void *args) /* {{{ */ +static void *statsd_network_thread(void *args) /* {{{ */ { struct pollfd *fds = NULL; size_t fds_num = 0; int status; - status = statsd_network_init (&fds, &fds_num); - if (status != 0) - { - ERROR ("statsd plugin: Unable to open listening sockets."); - pthread_exit ((void *) 0); + status = statsd_network_init(&fds, &fds_num); + if (status != 0) { + ERROR("statsd plugin: Unable to open listening sockets."); + pthread_exit((void *)0); } - while (!network_thread_shutdown) - { - status = poll (fds, (nfds_t) fds_num, /* timeout = */ -1); - if (status < 0) - { + while (!network_thread_shutdown) { + status = poll(fds, (nfds_t)fds_num, /* timeout = */ -1); + if (status < 0) { char errbuf[1024]; if ((errno == EINTR) || (errno == EAGAIN)) continue; - ERROR ("statsd plugin: poll(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("statsd plugin: poll(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); break; } - for (size_t i = 0; i < fds_num; i++) - { + for (size_t i = 0; i < fds_num; i++) { if ((fds[i].revents & (POLLIN | POLLPRI)) == 0) continue; - statsd_network_read (fds[i].fd); + statsd_network_read(fds[i].fd); fds[i].revents = 0; } } /* while (!network_thread_shutdown) */ /* Clean up */ for (size_t i = 0; i < fds_num; i++) - close (fds[i].fd); - sfree (fds); + close(fds[i].fd); + sfree(fds); - return ((void *) 0); + return ((void *)0); } /* }}} void *statsd_network_thread */ -static int statsd_config_timer_percentile (oconfig_item_t *ci) /* {{{ */ +static int statsd_config_timer_percentile(oconfig_item_t *ci) /* {{{ */ { double percent = NAN; double *tmp; int status; - status = cf_util_get_double (ci, &percent); + status = cf_util_get_double(ci, &percent); if (status != 0) return (status); - if ((percent <= 0.0) || (percent >= 100)) - { - ERROR ("statsd plugin: The value for \"%s\" must be between 0 and 100, " - "exclusively.", ci->key); + if ((percent <= 0.0) || (percent >= 100)) { + ERROR("statsd plugin: The value for \"%s\" must be between 0 and 100, " + "exclusively.", + ci->key); return (ERANGE); } - tmp = realloc (conf_timer_percentile, - sizeof (*conf_timer_percentile) * (conf_timer_percentile_num + 1)); - if (tmp == NULL) - { - ERROR ("statsd plugin: realloc failed."); + tmp = realloc(conf_timer_percentile, sizeof(*conf_timer_percentile) * + (conf_timer_percentile_num + 1)); + if (tmp == NULL) { + ERROR("statsd plugin: realloc failed."); return (ENOMEM); } conf_timer_percentile = tmp; @@ -660,76 +618,72 @@ static int statsd_config_timer_percentile (oconfig_item_t *ci) /* {{{ */ return (0); } /* }}} int statsd_config_timer_percentile */ -static int statsd_config (oconfig_item_t *ci) /* {{{ */ +static int statsd_config(oconfig_item_t *ci) /* {{{ */ { - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Host", child->key) == 0) - cf_util_get_string (child, &conf_node); - else if (strcasecmp ("Port", child->key) == 0) - cf_util_get_service (child, &conf_service); - else if (strcasecmp ("DeleteCounters", child->key) == 0) - cf_util_get_boolean (child, &conf_delete_counters); - else if (strcasecmp ("DeleteTimers", child->key) == 0) - cf_util_get_boolean (child, &conf_delete_timers); - else if (strcasecmp ("DeleteGauges", child->key) == 0) - cf_util_get_boolean (child, &conf_delete_gauges); - else if (strcasecmp ("DeleteSets", child->key) == 0) - cf_util_get_boolean (child, &conf_delete_sets); - else if (strcasecmp ("CounterSum", child->key) == 0) - cf_util_get_boolean (child, &conf_counter_sum); - else if (strcasecmp ("TimerLower", child->key) == 0) - cf_util_get_boolean (child, &conf_timer_lower); - else if (strcasecmp ("TimerUpper", child->key) == 0) - cf_util_get_boolean (child, &conf_timer_upper); - else if (strcasecmp ("TimerSum", child->key) == 0) - cf_util_get_boolean (child, &conf_timer_sum); - else if (strcasecmp ("TimerCount", child->key) == 0) - cf_util_get_boolean (child, &conf_timer_count); - else if (strcasecmp ("TimerPercentile", child->key) == 0) - statsd_config_timer_percentile (child); + if (strcasecmp("Host", child->key) == 0) + cf_util_get_string(child, &conf_node); + else if (strcasecmp("Port", child->key) == 0) + cf_util_get_service(child, &conf_service); + else if (strcasecmp("DeleteCounters", child->key) == 0) + cf_util_get_boolean(child, &conf_delete_counters); + else if (strcasecmp("DeleteTimers", child->key) == 0) + cf_util_get_boolean(child, &conf_delete_timers); + else if (strcasecmp("DeleteGauges", child->key) == 0) + cf_util_get_boolean(child, &conf_delete_gauges); + else if (strcasecmp("DeleteSets", child->key) == 0) + cf_util_get_boolean(child, &conf_delete_sets); + else if (strcasecmp("CounterSum", child->key) == 0) + cf_util_get_boolean(child, &conf_counter_sum); + else if (strcasecmp("TimerLower", child->key) == 0) + cf_util_get_boolean(child, &conf_timer_lower); + else if (strcasecmp("TimerUpper", child->key) == 0) + cf_util_get_boolean(child, &conf_timer_upper); + else if (strcasecmp("TimerSum", child->key) == 0) + cf_util_get_boolean(child, &conf_timer_sum); + else if (strcasecmp("TimerCount", child->key) == 0) + cf_util_get_boolean(child, &conf_timer_count); + else if (strcasecmp("TimerPercentile", child->key) == 0) + statsd_config_timer_percentile(child); else - ERROR ("statsd plugin: The \"%s\" config option is not valid.", - child->key); + ERROR("statsd plugin: The \"%s\" config option is not valid.", + child->key); } return (0); } /* }}} int statsd_config */ -static int statsd_init (void) /* {{{ */ +static int statsd_init(void) /* {{{ */ { - pthread_mutex_lock (&metrics_lock); + pthread_mutex_lock(&metrics_lock); if (metrics_tree == NULL) - metrics_tree = c_avl_create ((int (*) (const void *, const void *)) strcmp); + metrics_tree = c_avl_create((int (*)(const void *, const void *))strcmp); - if (!network_thread_running) - { + if (!network_thread_running) { int status; - status = pthread_create (&network_thread, - /* attr = */ NULL, - statsd_network_thread, - /* args = */ NULL); - if (status != 0) - { + status = pthread_create(&network_thread, + /* attr = */ NULL, statsd_network_thread, + /* args = */ NULL); + if (status != 0) { char errbuf[1024]; - pthread_mutex_unlock (&metrics_lock); - ERROR ("statsd plugin: pthread_create failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + pthread_mutex_unlock(&metrics_lock); + ERROR("statsd plugin: pthread_create failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); return (status); } } network_thread_running = 1; - pthread_mutex_unlock (&metrics_lock); + pthread_mutex_unlock(&metrics_lock); return (0); } /* }}} int statsd_init */ /* Must hold metrics_lock when calling this function. */ -static int statsd_metric_clear_set_unsafe (statsd_metric_t *metric) /* {{{ */ +static int statsd_metric_clear_set_unsafe(statsd_metric_t *metric) /* {{{ */ { void *key; void *value; @@ -740,137 +694,131 @@ static int statsd_metric_clear_set_unsafe (statsd_metric_t *metric) /* {{{ */ if (metric->set == NULL) return (0); - while (c_avl_pick (metric->set, &key, &value) == 0) - { - sfree (key); - sfree (value); + while (c_avl_pick(metric->set, &key, &value) == 0) { + sfree(key); + sfree(value); } return (0); } /* }}} int statsd_metric_clear_set_unsafe */ /* Must hold metrics_lock when calling this function. */ -static int statsd_metric_submit_unsafe (char const *name, statsd_metric_t *metric) /* {{{ */ +static int statsd_metric_submit_unsafe(char const *name, + statsd_metric_t *metric) /* {{{ */ { value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = NAN }; + vl.values = &(value_t){.gauge = NAN}; vl.values_len = 1; - sstrncpy (vl.plugin, "statsd", sizeof (vl.plugin)); + sstrncpy(vl.plugin, "statsd", sizeof(vl.plugin)); if (metric->type == STATSD_GAUGE) - sstrncpy (vl.type, "gauge", sizeof (vl.type)); + sstrncpy(vl.type, "gauge", sizeof(vl.type)); else if (metric->type == STATSD_TIMER) - sstrncpy (vl.type, "latency", sizeof (vl.type)); + sstrncpy(vl.type, "latency", sizeof(vl.type)); else if (metric->type == STATSD_SET) - sstrncpy (vl.type, "objects", sizeof (vl.type)); + sstrncpy(vl.type, "objects", sizeof(vl.type)); else /* if (metric->type == STATSD_COUNTER) */ - sstrncpy (vl.type, "derive", sizeof (vl.type)); + sstrncpy(vl.type, "derive", sizeof(vl.type)); - sstrncpy (vl.type_instance, name, sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, name, sizeof(vl.type_instance)); if (metric->type == STATSD_GAUGE) - vl.values[0].gauge = (gauge_t) metric->value; - else if (metric->type == STATSD_TIMER) - { + vl.values[0].gauge = (gauge_t)metric->value; + else if (metric->type == STATSD_TIMER) { _Bool have_events = (metric->updates_num > 0); /* Make sure all timer metrics share the *same* timestamp. */ - vl.time = cdtime (); + vl.time = cdtime(); - ssnprintf (vl.type_instance, sizeof (vl.type_instance), - "%s-average", name); - vl.values[0].gauge = have_events - ? CDTIME_T_TO_DOUBLE (latency_counter_get_average (metric->latency)) - : NAN; - plugin_dispatch_values (&vl); + ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s-average", name); + vl.values[0].gauge = + have_events + ? CDTIME_T_TO_DOUBLE(latency_counter_get_average(metric->latency)) + : NAN; + plugin_dispatch_values(&vl); if (conf_timer_lower) { - ssnprintf (vl.type_instance, sizeof (vl.type_instance), - "%s-lower", name); - vl.values[0].gauge = have_events - ? CDTIME_T_TO_DOUBLE (latency_counter_get_min (metric->latency)) - : NAN; - plugin_dispatch_values (&vl); + ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s-lower", name); + vl.values[0].gauge = + have_events + ? CDTIME_T_TO_DOUBLE(latency_counter_get_min(metric->latency)) + : NAN; + plugin_dispatch_values(&vl); } if (conf_timer_upper) { - ssnprintf (vl.type_instance, sizeof (vl.type_instance), - "%s-upper", name); - vl.values[0].gauge = have_events - ? CDTIME_T_TO_DOUBLE (latency_counter_get_max (metric->latency)) - : NAN; - plugin_dispatch_values (&vl); + ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s-upper", name); + vl.values[0].gauge = + have_events + ? CDTIME_T_TO_DOUBLE(latency_counter_get_max(metric->latency)) + : NAN; + plugin_dispatch_values(&vl); } if (conf_timer_sum) { - ssnprintf (vl.type_instance, sizeof (vl.type_instance), - "%s-sum", name); - vl.values[0].gauge = have_events - ? CDTIME_T_TO_DOUBLE (latency_counter_get_sum (metric->latency)) - : NAN; - plugin_dispatch_values (&vl); + ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s-sum", name); + vl.values[0].gauge = + have_events + ? CDTIME_T_TO_DOUBLE(latency_counter_get_sum(metric->latency)) + : NAN; + plugin_dispatch_values(&vl); } - for (size_t i = 0; i < conf_timer_percentile_num; i++) - { - ssnprintf (vl.type_instance, sizeof (vl.type_instance), - "%s-percentile-%.0f", name, conf_timer_percentile[i]); - vl.values[0].gauge = have_events - ? CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (metric->latency, conf_timer_percentile[i])) - : NAN; - plugin_dispatch_values (&vl); + for (size_t i = 0; i < conf_timer_percentile_num; i++) { + ssnprintf(vl.type_instance, sizeof(vl.type_instance), + "%s-percentile-%.0f", name, conf_timer_percentile[i]); + vl.values[0].gauge = + have_events ? CDTIME_T_TO_DOUBLE(latency_counter_get_percentile( + metric->latency, conf_timer_percentile[i])) + : NAN; + plugin_dispatch_values(&vl); } /* Keep this at the end, since vl.type is set to "gauge" here. The * vl.type's above are implicitly set to "latency". */ if (conf_timer_count) { - sstrncpy (vl.type, "gauge", sizeof (vl.type)); - ssnprintf (vl.type_instance, sizeof (vl.type_instance), - "%s-count", name); - vl.values[0].gauge = latency_counter_get_num (metric->latency); - plugin_dispatch_values (&vl); + sstrncpy(vl.type, "gauge", sizeof(vl.type)); + ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s-count", name); + vl.values[0].gauge = latency_counter_get_num(metric->latency); + plugin_dispatch_values(&vl); } - latency_counter_reset (metric->latency); + latency_counter_reset(metric->latency); return (0); - } - else if (metric->type == STATSD_SET) - { + } else if (metric->type == STATSD_SET) { if (metric->set == NULL) vl.values[0].gauge = 0.0; else - vl.values[0].gauge = (gauge_t) c_avl_size (metric->set); - } - else { /* STATSD_COUNTER */ - gauge_t delta = nearbyint (metric->value); + vl.values[0].gauge = (gauge_t)c_avl_size(metric->set); + } else { /* STATSD_COUNTER */ + gauge_t delta = nearbyint(metric->value); /* Etsy's statsd writes counters as two metrics: a rate and the change since * the last write. Since collectd does not reset its DERIVE metrics to zero, * this makes little sense, but we're dispatching a "count" metric here * anyway - if requested by the user - for compatibility reasons. */ - if (conf_counter_sum) - { - sstrncpy (vl.type, "count", sizeof (vl.type)); + if (conf_counter_sum) { + sstrncpy(vl.type, "count", sizeof(vl.type)); vl.values[0].gauge = delta; - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); /* restore vl.type */ - sstrncpy (vl.type, "derive", sizeof (vl.type)); + sstrncpy(vl.type, "derive", sizeof(vl.type)); } /* Rather than resetting value to zero, subtract delta so we correctly keep * track of residuals. */ - metric->value -= delta; - metric->counter += (derive_t) delta; + metric->value -= delta; + metric->counter += (derive_t)delta; vl.values[0].derive = metric->counter; } - return (plugin_dispatch_values (&vl)); + return (plugin_dispatch_values(&vl)); } /* }}} int statsd_metric_submit_unsafe */ -static int statsd_read (void) /* {{{ */ +static int statsd_read(void) /* {{{ */ { c_avl_iterator_t *iter; char *name; @@ -879,100 +827,92 @@ static int statsd_read (void) /* {{{ */ char **to_be_deleted = NULL; size_t to_be_deleted_num = 0; - pthread_mutex_lock (&metrics_lock); + pthread_mutex_lock(&metrics_lock); - if (metrics_tree == NULL) - { - pthread_mutex_unlock (&metrics_lock); + if (metrics_tree == NULL) { + pthread_mutex_unlock(&metrics_lock); return (0); } - iter = c_avl_get_iterator (metrics_tree); - while (c_avl_iterator_next (iter, (void *) &name, (void *) &metric) == 0) - { - if ((metric->updates_num == 0) - && ((conf_delete_counters && (metric->type == STATSD_COUNTER)) - || (conf_delete_timers && (metric->type == STATSD_TIMER)) - || (conf_delete_gauges && (metric->type == STATSD_GAUGE)) - || (conf_delete_sets && (metric->type == STATSD_SET)))) - { - DEBUG ("statsd plugin: Deleting metric \"%s\".", name); - strarray_add (&to_be_deleted, &to_be_deleted_num, name); + iter = c_avl_get_iterator(metrics_tree); + while (c_avl_iterator_next(iter, (void *)&name, (void *)&metric) == 0) { + if ((metric->updates_num == 0) && + ((conf_delete_counters && (metric->type == STATSD_COUNTER)) || + (conf_delete_timers && (metric->type == STATSD_TIMER)) || + (conf_delete_gauges && (metric->type == STATSD_GAUGE)) || + (conf_delete_sets && (metric->type == STATSD_SET)))) { + DEBUG("statsd plugin: Deleting metric \"%s\".", name); + strarray_add(&to_be_deleted, &to_be_deleted_num, name); continue; } /* Names have a prefix, e.g. "c:", which determines the (statsd) type. * Remove this here. */ - statsd_metric_submit_unsafe (name + 2, metric); + statsd_metric_submit_unsafe(name + 2, metric); /* Reset the metric. */ metric->updates_num = 0; if (metric->type == STATSD_SET) - statsd_metric_clear_set_unsafe (metric); + statsd_metric_clear_set_unsafe(metric); } - c_avl_iterator_destroy (iter); + c_avl_iterator_destroy(iter); - for (size_t i = 0; i < to_be_deleted_num; i++) - { + for (size_t i = 0; i < to_be_deleted_num; i++) { int status; - status = c_avl_remove (metrics_tree, to_be_deleted[i], - (void *) &name, (void *) &metric); - if (status != 0) - { - ERROR ("stats plugin: c_avl_remove (\"%s\") failed with status %i.", - to_be_deleted[i], status); + status = c_avl_remove(metrics_tree, to_be_deleted[i], (void *)&name, + (void *)&metric); + if (status != 0) { + ERROR("stats plugin: c_avl_remove (\"%s\") failed with status %i.", + to_be_deleted[i], status); continue; } - sfree (name); - statsd_metric_free (metric); + sfree(name); + statsd_metric_free(metric); } - pthread_mutex_unlock (&metrics_lock); + pthread_mutex_unlock(&metrics_lock); - strarray_free (to_be_deleted, to_be_deleted_num); + strarray_free(to_be_deleted, to_be_deleted_num); return (0); } /* }}} int statsd_read */ -static int statsd_shutdown (void) /* {{{ */ +static int statsd_shutdown(void) /* {{{ */ { void *key; void *value; - if (network_thread_running) - { + if (network_thread_running) { network_thread_shutdown = 1; - pthread_kill (network_thread, SIGTERM); - pthread_join (network_thread, /* retval = */ NULL); + pthread_kill(network_thread, SIGTERM); + pthread_join(network_thread, /* retval = */ NULL); } network_thread_running = 0; - pthread_mutex_lock (&metrics_lock); + pthread_mutex_lock(&metrics_lock); - while (c_avl_pick (metrics_tree, &key, &value) == 0) - { - sfree (key); - statsd_metric_free (value); + while (c_avl_pick(metrics_tree, &key, &value) == 0) { + sfree(key); + statsd_metric_free(value); } - c_avl_destroy (metrics_tree); + c_avl_destroy(metrics_tree); metrics_tree = NULL; - sfree (conf_node); - sfree (conf_service); + sfree(conf_node); + sfree(conf_service); - pthread_mutex_unlock (&metrics_lock); + pthread_mutex_unlock(&metrics_lock); return (0); } /* }}} int statsd_shutdown */ -void module_register (void) -{ - plugin_register_complex_config ("statsd", statsd_config); - plugin_register_init ("statsd", statsd_init); - plugin_register_read ("statsd", statsd_read); - plugin_register_shutdown ("statsd", statsd_shutdown); +void module_register(void) { + plugin_register_complex_config("statsd", statsd_config); + plugin_register_init("statsd", statsd_init); + plugin_register_read("statsd", statsd_read); + plugin_register_shutdown("statsd", statsd_shutdown); } /* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/swap.c b/src/swap.c index 403b148b..cbe1ab11 100644 --- a/src/swap.c +++ b/src/swap.c @@ -25,13 +25,14 @@ **/ #if HAVE_CONFIG_H -# include "config.h" -# undef HAVE_CONFIG_H +#include "config.h" +#undef HAVE_CONFIG_H #endif -/* avoid swap.h error "Cannot use swapctl in the large files compilation environment" */ +/* avoid swap.h error "Cannot use swapctl in the large files compilation + * environment" */ #if HAVE_SYS_SWAP_H && !defined(_LP64) && _FILE_OFFSET_BITS == 64 -# undef _FILE_OFFSET_BITS -# undef _LARGEFILE64_SOURCE +#undef _FILE_OFFSET_BITS +#undef _LARGEFILE64_SOURCE #endif #include "collectd.h" @@ -40,45 +41,45 @@ #include "plugin.h" #if HAVE_SYS_SWAP_H -# include +#include #endif #if HAVE_VM_ANON_H -# include +#include #endif #if HAVE_SYS_PARAM_H -# include +#include #endif #if HAVE_SYS_SYSCTL_H -# include +#include #endif #if HAVE_SYS_DKSTAT_H -# include +#include #endif #if HAVE_KVM_H -# include +#include #endif #if HAVE_STATGRAB_H -# include +#include #endif #if HAVE_PERFSTAT -# include -# include +#include +#include #endif -#undef MAX -#define MAX(x,y) ((x) > (y) ? (x) : (y)) +#undef MAX +#define MAX(x, y) ((x) > (y) ? (x) : (y)) #if KERNEL_LINUX -# define SWAP_HAVE_REPORT_BY_DEVICE 1 +#define SWAP_HAVE_REPORT_BY_DEVICE 1 static derive_t pagesize; static _Bool report_bytes = 0; static _Bool report_by_device = 0; /* #endif KERNEL_LINUX */ #elif HAVE_SWAPCTL && HAVE_SWAPCTL_TWO_ARGS -# define SWAP_HAVE_REPORT_BY_DEVICE 1 +#define SWAP_HAVE_REPORT_BY_DEVICE 1 static derive_t pagesize; static _Bool report_by_device = 0; /* #endif HAVE_SWAPCTL && HAVE_SWAPCTL_TWO_ARGS */ @@ -105,337 +106,311 @@ static int pagesize; /*# endif HAVE_PERFSTAT */ #else -# error "No applicable input method." +#error "No applicable input method." #endif /* HAVE_LIBSTATGRAB */ static _Bool values_absolute = 1; static _Bool values_percentage = 0; -static int swap_config (oconfig_item_t *ci) /* {{{ */ +static int swap_config(oconfig_item_t *ci) /* {{{ */ { - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - if (strcasecmp ("ReportBytes", child->key) == 0) + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + if (strcasecmp("ReportBytes", child->key) == 0) #if KERNEL_LINUX - cf_util_get_boolean (child, &report_bytes); + cf_util_get_boolean(child, &report_bytes); #else - WARNING ("swap plugin: The \"ReportBytes\" option " - "is only valid under Linux. " - "The option is going to be ignored."); + WARNING("swap plugin: The \"ReportBytes\" option " + "is only valid under Linux. " + "The option is going to be ignored."); #endif - else if (strcasecmp ("ReportByDevice", child->key) == 0) + else if (strcasecmp("ReportByDevice", child->key) == 0) #if SWAP_HAVE_REPORT_BY_DEVICE - cf_util_get_boolean (child, &report_by_device); + cf_util_get_boolean(child, &report_by_device); #else - WARNING ("swap plugin: The \"ReportByDevice\" option " - "is not supported on this platform. " - "The option is going to be ignored."); + WARNING("swap plugin: The \"ReportByDevice\" option " + "is not supported on this platform. " + "The option is going to be ignored."); #endif /* SWAP_HAVE_REPORT_BY_DEVICE */ - else if (strcasecmp ("ValuesAbsolute", child->key) == 0) - cf_util_get_boolean (child, &values_absolute); - else if (strcasecmp ("ValuesPercentage", child->key) == 0) - cf_util_get_boolean (child, &values_percentage); - else - WARNING ("swap plugin: Unknown config option: \"%s\"", - child->key); - } - - return (0); + else if (strcasecmp("ValuesAbsolute", child->key) == 0) + cf_util_get_boolean(child, &values_absolute); + else if (strcasecmp("ValuesPercentage", child->key) == 0) + cf_util_get_boolean(child, &values_percentage); + else + WARNING("swap plugin: Unknown config option: \"%s\"", child->key); + } + + return (0); } /* }}} int swap_config */ -static int swap_init (void) /* {{{ */ +static int swap_init(void) /* {{{ */ { #if KERNEL_LINUX - pagesize = (derive_t) sysconf (_SC_PAGESIZE); + pagesize = (derive_t)sysconf(_SC_PAGESIZE); /* #endif KERNEL_LINUX */ #elif HAVE_SWAPCTL && HAVE_SWAPCTL_TWO_ARGS - /* getpagesize(3C) tells me this does not fail.. */ - pagesize = (derive_t) getpagesize (); + /* getpagesize(3C) tells me this does not fail.. */ + pagesize = (derive_t)getpagesize(); /* #endif HAVE_SWAPCTL */ #elif defined(VM_SWAPUSAGE) - /* No init stuff */ +/* No init stuff */ /* #endif defined(VM_SWAPUSAGE) */ #elif HAVE_LIBKVM_GETSWAPINFO - char errbuf[_POSIX2_LINE_MAX]; + char errbuf[_POSIX2_LINE_MAX]; - if (kvm_obj != NULL) - { - kvm_close (kvm_obj); - kvm_obj = NULL; - } + if (kvm_obj != NULL) { + kvm_close(kvm_obj); + kvm_obj = NULL; + } - kvm_pagesize = getpagesize (); + kvm_pagesize = getpagesize(); - kvm_obj = kvm_openfiles (NULL, "/dev/null", NULL, O_RDONLY, errbuf); + kvm_obj = kvm_openfiles(NULL, "/dev/null", NULL, O_RDONLY, errbuf); - if (kvm_obj == NULL) - { - ERROR ("swap plugin: kvm_openfiles failed, %s", errbuf); - return (-1); - } + if (kvm_obj == NULL) { + ERROR("swap plugin: kvm_openfiles failed, %s", errbuf); + return (-1); + } /* #endif HAVE_LIBKVM_GETSWAPINFO */ #elif HAVE_LIBSTATGRAB - /* No init stuff */ +/* No init stuff */ /* #endif HAVE_LIBSTATGRAB */ #elif HAVE_PERFSTAT - pagesize = getpagesize(); + pagesize = getpagesize(); #endif /* HAVE_PERFSTAT */ - return (0); + return (0); } /* }}} int swap_init */ -static void swap_submit_usage (char const *plugin_instance, /* {{{ */ - gauge_t used, gauge_t free, - char const *other_name, gauge_t other_value) -{ - value_list_t vl = VALUE_LIST_INIT; - - vl.values = &(value_t) { .gauge = NAN }; - vl.values_len = 1; - sstrncpy (vl.plugin, "swap", sizeof (vl.plugin)); - if (plugin_instance != NULL) - sstrncpy (vl.plugin_instance, plugin_instance, - sizeof (vl.plugin_instance)); - sstrncpy (vl.type, "swap", sizeof (vl.type)); - - if (values_absolute) - plugin_dispatch_multivalue (&vl, 0, DS_TYPE_GAUGE, - "used", used, "free", free, - other_name, other_value, NULL); - if (values_percentage) - plugin_dispatch_multivalue (&vl, 1, DS_TYPE_GAUGE, - "used", used, "free", free, - other_name, other_value, NULL); +static void swap_submit_usage(char const *plugin_instance, /* {{{ */ + gauge_t used, gauge_t free, + char const *other_name, gauge_t other_value) { + value_list_t vl = VALUE_LIST_INIT; + + vl.values = &(value_t){.gauge = NAN}; + vl.values_len = 1; + sstrncpy(vl.plugin, "swap", sizeof(vl.plugin)); + if (plugin_instance != NULL) + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "swap", sizeof(vl.type)); + + if (values_absolute) + plugin_dispatch_multivalue(&vl, 0, DS_TYPE_GAUGE, "used", used, "free", + free, other_name, other_value, NULL); + if (values_percentage) + plugin_dispatch_multivalue(&vl, 1, DS_TYPE_GAUGE, "used", used, "free", + free, other_name, other_value, NULL); } /* }}} void swap_submit_usage */ #if KERNEL_LINUX || HAVE_PERFSTAT -__attribute__((nonnull(1))) -static void swap_submit_derive (char const *type_instance, /* {{{ */ - derive_t value) -{ - value_list_t vl = VALUE_LIST_INIT; - - vl.values = &(value_t) { .derive = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "swap", sizeof (vl.plugin)); - sstrncpy (vl.type, "swap_io", sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); +__attribute__((nonnull(1))) static void +swap_submit_derive(char const *type_instance, /* {{{ */ + derive_t value) { + value_list_t vl = VALUE_LIST_INIT; + + vl.values = &(value_t){.derive = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "swap", sizeof(vl.plugin)); + sstrncpy(vl.type, "swap_io", sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); } /* }}} void swap_submit_derive */ #endif #if KERNEL_LINUX -static int swap_read_separate (void) /* {{{ */ +static int swap_read_separate(void) /* {{{ */ { - FILE *fh; - char buffer[1024]; - - fh = fopen ("/proc/swaps", "r"); - if (fh == NULL) - { - char errbuf[1024]; - WARNING ("swap plugin: fopen (/proc/swaps) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - char *fields[8]; - int numfields; - char *endptr; - - char path[PATH_MAX]; - gauge_t total; - gauge_t used; - - numfields = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields)); - if (numfields != 5) - continue; - - sstrncpy (path, fields[0], sizeof (path)); - escape_slashes (path, sizeof (path)); - - errno = 0; - endptr = NULL; - total = strtod (fields[2], &endptr); - if ((endptr == fields[2]) || (errno != 0)) - continue; - - errno = 0; - endptr = NULL; - used = strtod (fields[3], &endptr); - if ((endptr == fields[3]) || (errno != 0)) - continue; - - if (total < used) - continue; - - swap_submit_usage (path, used * 1024.0, (total - used) * 1024.0, - NULL, NAN); - } - - fclose (fh); - - return (0); + FILE *fh; + char buffer[1024]; + + fh = fopen("/proc/swaps", "r"); + if (fh == NULL) { + char errbuf[1024]; + WARNING("swap plugin: fopen (/proc/swaps) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + char *fields[8]; + int numfields; + char *endptr; + + char path[PATH_MAX]; + gauge_t total; + gauge_t used; + + numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + if (numfields != 5) + continue; + + sstrncpy(path, fields[0], sizeof(path)); + escape_slashes(path, sizeof(path)); + + errno = 0; + endptr = NULL; + total = strtod(fields[2], &endptr); + if ((endptr == fields[2]) || (errno != 0)) + continue; + + errno = 0; + endptr = NULL; + used = strtod(fields[3], &endptr); + if ((endptr == fields[3]) || (errno != 0)) + continue; + + if (total < used) + continue; + + swap_submit_usage(path, used * 1024.0, (total - used) * 1024.0, NULL, NAN); + } + + fclose(fh); + + return (0); } /* }}} int swap_read_separate */ -static int swap_read_combined (void) /* {{{ */ +static int swap_read_combined(void) /* {{{ */ { - FILE *fh; - char buffer[1024]; - - gauge_t swap_used = NAN; - gauge_t swap_cached = NAN; - gauge_t swap_free = NAN; - gauge_t swap_total = NAN; - - fh = fopen ("/proc/meminfo", "r"); - if (fh == NULL) - { - char errbuf[1024]; - WARNING ("swap plugin: fopen (/proc/meminfo) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - char *fields[8]; - int numfields; - - numfields = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields)); - if (numfields < 2) - continue; - - if (strcasecmp (fields[0], "SwapTotal:") == 0) - strtogauge (fields[1], &swap_total); - else if (strcasecmp (fields[0], "SwapFree:") == 0) - strtogauge (fields[1], &swap_free); - else if (strcasecmp (fields[0], "SwapCached:") == 0) - strtogauge (fields[1], &swap_cached); - } - - fclose (fh); - - if (isnan (swap_total) || isnan (swap_free)) - return (ENOENT); - - /* Some systems, OpenVZ for example, don't provide SwapCached. */ - if (isnan (swap_cached)) - swap_used = swap_total - swap_free; - else - swap_used = swap_total - (swap_free + swap_cached); - assert (!isnan (swap_used)); - - if (swap_used < 0.0) - return (EINVAL); - - swap_submit_usage (NULL, swap_used * 1024.0, swap_free * 1024.0, - isnan (swap_cached) ? NULL : "cached", - isnan (swap_cached) ? NAN : swap_cached * 1024.0); - return (0); + FILE *fh; + char buffer[1024]; + + gauge_t swap_used = NAN; + gauge_t swap_cached = NAN; + gauge_t swap_free = NAN; + gauge_t swap_total = NAN; + + fh = fopen("/proc/meminfo", "r"); + if (fh == NULL) { + char errbuf[1024]; + WARNING("swap plugin: fopen (/proc/meminfo) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + char *fields[8]; + int numfields; + + numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + if (numfields < 2) + continue; + + if (strcasecmp(fields[0], "SwapTotal:") == 0) + strtogauge(fields[1], &swap_total); + else if (strcasecmp(fields[0], "SwapFree:") == 0) + strtogauge(fields[1], &swap_free); + else if (strcasecmp(fields[0], "SwapCached:") == 0) + strtogauge(fields[1], &swap_cached); + } + + fclose(fh); + + if (isnan(swap_total) || isnan(swap_free)) + return (ENOENT); + + /* Some systems, OpenVZ for example, don't provide SwapCached. */ + if (isnan(swap_cached)) + swap_used = swap_total - swap_free; + else + swap_used = swap_total - (swap_free + swap_cached); + assert(!isnan(swap_used)); + + if (swap_used < 0.0) + return (EINVAL); + + swap_submit_usage(NULL, swap_used * 1024.0, swap_free * 1024.0, + isnan(swap_cached) ? NULL : "cached", + isnan(swap_cached) ? NAN : swap_cached * 1024.0); + return (0); } /* }}} int swap_read_combined */ -static int swap_read_io (void) /* {{{ */ +static int swap_read_io(void) /* {{{ */ { - FILE *fh; - char buffer[1024]; - - _Bool old_kernel = 0; - - uint8_t have_data = 0; - derive_t swap_in = 0; - derive_t swap_out = 0; - - fh = fopen ("/proc/vmstat", "r"); - if (fh == NULL) - { - /* /proc/vmstat does not exist in kernels <2.6 */ - fh = fopen ("/proc/stat", "r"); - if (fh == NULL) - { - char errbuf[1024]; - WARNING ("swap: fopen: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - else - old_kernel = 1; - } - - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - char *fields[8]; - int numfields; - - numfields = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields)); - - if (!old_kernel) - { - if (numfields != 2) - continue; - - if (strcasecmp ("pswpin", fields[0]) == 0) - { - strtoderive (fields[1], &swap_in); - have_data |= 0x01; - } - else if (strcasecmp ("pswpout", fields[0]) == 0) - { - strtoderive (fields[1], &swap_out); - have_data |= 0x02; - } - } - else /* if (old_kernel) */ - { - if (numfields != 3) - continue; - - if (strcasecmp ("page", fields[0]) == 0) - { - strtoderive (fields[1], &swap_in); - strtoderive (fields[2], &swap_out); - } - } - } /* while (fgets) */ - - fclose (fh); - - if (have_data != 0x03) - return (ENOENT); - - if (report_bytes) - { - swap_in = swap_in * pagesize; - swap_out = swap_out * pagesize; - } - - swap_submit_derive ("in", swap_in); - swap_submit_derive ("out", swap_out); - - return (0); + FILE *fh; + char buffer[1024]; + + _Bool old_kernel = 0; + + uint8_t have_data = 0; + derive_t swap_in = 0; + derive_t swap_out = 0; + + fh = fopen("/proc/vmstat", "r"); + if (fh == NULL) { + /* /proc/vmstat does not exist in kernels <2.6 */ + fh = fopen("/proc/stat", "r"); + if (fh == NULL) { + char errbuf[1024]; + WARNING("swap: fopen: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } else + old_kernel = 1; + } + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + char *fields[8]; + int numfields; + + numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + + if (!old_kernel) { + if (numfields != 2) + continue; + + if (strcasecmp("pswpin", fields[0]) == 0) { + strtoderive(fields[1], &swap_in); + have_data |= 0x01; + } else if (strcasecmp("pswpout", fields[0]) == 0) { + strtoderive(fields[1], &swap_out); + have_data |= 0x02; + } + } else /* if (old_kernel) */ + { + if (numfields != 3) + continue; + + if (strcasecmp("page", fields[0]) == 0) { + strtoderive(fields[1], &swap_in); + strtoderive(fields[2], &swap_out); + } + } + } /* while (fgets) */ + + fclose(fh); + + if (have_data != 0x03) + return (ENOENT); + + if (report_bytes) { + swap_in = swap_in * pagesize; + swap_out = swap_out * pagesize; + } + + swap_submit_derive("in", swap_in); + swap_submit_derive("out", swap_out); + + return (0); } /* }}} int swap_read_io */ -static int swap_read (void) /* {{{ */ +static int swap_read(void) /* {{{ */ { - if (report_by_device) - swap_read_separate (); - else - swap_read_combined (); + if (report_by_device) + swap_read_separate(); + else + swap_read_combined(); - swap_read_io (); + swap_read_io(); - return (0); + return (0); } /* }}} int swap_read */ -/* #endif KERNEL_LINUX */ + /* #endif KERNEL_LINUX */ /* * Under Solaris, two mechanisms can be used to read swap statistics, swapctl @@ -448,344 +423,320 @@ static int swap_read (void) /* {{{ */ */ #elif 0 && HAVE_LIBKSTAT /* kstat-based read function */ -static int swap_read_kstat (void) /* {{{ */ +static int swap_read_kstat(void) /* {{{ */ { - gauge_t swap_alloc; - gauge_t swap_resv; - gauge_t swap_avail; - - struct anoninfo ai; - - if (swapctl (SC_AINFO, &ai) == -1) - { - char errbuf[1024]; - ERROR ("swap plugin: swapctl failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - /* - * Calculations from: - * http://cvs.opensolaris.org/source/xref/on/usr/src/cmd/swap/swap.c - * Also see: - * http://www.itworld.com/Comp/2377/UIR980701perf/ (outdated?) - * /usr/include/vm/anon.h - * - * In short, swap -s shows: allocated + reserved = used, available - * - * However, Solaris does not allow to allocated/reserved more than the - * available swap (physical memory + disk swap), so the pedant may - * prefer: allocated + unallocated = reserved, available - * - * We map the above to: used + resv = n/a, free - * - * Does your brain hurt yet? - Christophe Kalt - * - * Oh, and in case you wonder, - * swap_alloc = pagesize * ( ai.ani_max - ai.ani_free ); - * can suffer from a 32bit overflow. - */ - swap_alloc = (gauge_t) ((ai.ani_max - ai.ani_free) * pagesize); - swap_resv = (gauge_t) ((ai.ani_resv + ai.ani_free - ai.ani_max) * pagesize); - swap_avail = (gauge_t) ((ai.ani_max - ai.ani_resv) * pagesize); - - swap_submit_usage (NULL, swap_alloc, swap_avail, "reserved", swap_resv); - return (0); + gauge_t swap_alloc; + gauge_t swap_resv; + gauge_t swap_avail; + + struct anoninfo ai; + + if (swapctl(SC_AINFO, &ai) == -1) { + char errbuf[1024]; + ERROR("swap plugin: swapctl failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + /* + * Calculations from: + * http://cvs.opensolaris.org/source/xref/on/usr/src/cmd/swap/swap.c + * Also see: + * http://www.itworld.com/Comp/2377/UIR980701perf/ (outdated?) + * /usr/include/vm/anon.h + * + * In short, swap -s shows: allocated + reserved = used, available + * + * However, Solaris does not allow to allocated/reserved more than the + * available swap (physical memory + disk swap), so the pedant may + * prefer: allocated + unallocated = reserved, available + * + * We map the above to: used + resv = n/a, free + * + * Does your brain hurt yet? - Christophe Kalt + * + * Oh, and in case you wonder, + * swap_alloc = pagesize * ( ai.ani_max - ai.ani_free ); + * can suffer from a 32bit overflow. + */ + swap_alloc = (gauge_t)((ai.ani_max - ai.ani_free) * pagesize); + swap_resv = (gauge_t)((ai.ani_resv + ai.ani_free - ai.ani_max) * pagesize); + swap_avail = (gauge_t)((ai.ani_max - ai.ani_resv) * pagesize); + + swap_submit_usage(NULL, swap_alloc, swap_avail, "reserved", swap_resv); + return (0); } /* }}} int swap_read_kstat */ -/* #endif 0 && HAVE_LIBKSTAT */ + /* #endif 0 && HAVE_LIBKSTAT */ #elif HAVE_SWAPCTL && HAVE_SWAPCTL_TWO_ARGS /* swapctl-based read function */ -static int swap_read (void) /* {{{ */ +static int swap_read(void) /* {{{ */ { - swaptbl_t *s; - char *s_paths; - int swap_num; - int status; - - gauge_t avail = 0; - gauge_t total = 0; - - swap_num = swapctl (SC_GETNSWP, NULL); - if (swap_num < 0) - { - ERROR ("swap plugin: swapctl (SC_GETNSWP) failed with status %i.", - swap_num); - return (-1); - } - else if (swap_num == 0) - return (0); - - /* Allocate and initialize the swaptbl_t structure */ - s = malloc (swap_num * sizeof (swapent_t) + sizeof (struct swaptable)); - if (s == NULL) - { - ERROR ("swap plugin: malloc failed."); - return (-1); - } - - /* Memory to store the path names. We only use these paths when the - * separate option has been configured, but it's easier to just - * allocate enough memory in any case. */ - s_paths = calloc (swap_num, PATH_MAX); - if (s_paths == NULL) - { - ERROR ("swap plugin: calloc failed."); - sfree (s); - return (-1); - } - for (int i = 0; i < swap_num; i++) - s->swt_ent[i].ste_path = s_paths + (i * PATH_MAX); - s->swt_n = swap_num; - - status = swapctl (SC_LIST, s); - if (status < 0) - { - char errbuf[1024]; - ERROR ("swap plugin: swapctl (SC_LIST) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - sfree (s_paths); - sfree (s); - return (-1); - } - else if (swap_num < status) - { - /* more elements returned than requested */ - ERROR ("swap plugin: I allocated memory for %i structure%s, " - "but swapctl(2) claims to have returned %i. " - "I'm confused and will give up.", - swap_num, (swap_num == 1) ? "" : "s", - status); - sfree (s_paths); - sfree (s); - return (-1); - } - else if (swap_num > status) - /* less elements returned than requested */ - swap_num = status; - - for (int i = 0; i < swap_num; i++) - { - char path[PATH_MAX]; - gauge_t this_total; - gauge_t this_avail; - - if ((s->swt_ent[i].ste_flags & ST_INDEL) != 0) - continue; - - this_total = (gauge_t) (s->swt_ent[i].ste_pages * pagesize); - this_avail = (gauge_t) (s->swt_ent[i].ste_free * pagesize); - - /* Shortcut for the "combined" setting (default) */ - if (!report_by_device) - { - avail += this_avail; - total += this_total; - continue; - } - - sstrncpy (path, s->swt_ent[i].ste_path, sizeof (path)); - escape_slashes (path, sizeof (path)); - - swap_submit_usage (path, this_total - this_avail, this_avail, - NULL, NAN); - } /* for (swap_num) */ - - if (total < avail) - { - ERROR ("swap plugin: Total swap space (%g) is less than free swap space (%g).", - total, avail); - sfree (s_paths); - sfree (s); - return (-1); - } - - /* If the "separate" option was specified (report_by_device == 1), all - * values have already been dispatched from within the loop. */ - if (!report_by_device) - swap_submit_usage (NULL, total - avail, avail, NULL, NAN); - - sfree (s_paths); - sfree (s); - return (0); + swaptbl_t *s; + char *s_paths; + int swap_num; + int status; + + gauge_t avail = 0; + gauge_t total = 0; + + swap_num = swapctl(SC_GETNSWP, NULL); + if (swap_num < 0) { + ERROR("swap plugin: swapctl (SC_GETNSWP) failed with status %i.", swap_num); + return (-1); + } else if (swap_num == 0) + return (0); + + /* Allocate and initialize the swaptbl_t structure */ + s = malloc(swap_num * sizeof(swapent_t) + sizeof(struct swaptable)); + if (s == NULL) { + ERROR("swap plugin: malloc failed."); + return (-1); + } + + /* Memory to store the path names. We only use these paths when the + * separate option has been configured, but it's easier to just + * allocate enough memory in any case. */ + s_paths = calloc(swap_num, PATH_MAX); + if (s_paths == NULL) { + ERROR("swap plugin: calloc failed."); + sfree(s); + return (-1); + } + for (int i = 0; i < swap_num; i++) + s->swt_ent[i].ste_path = s_paths + (i * PATH_MAX); + s->swt_n = swap_num; + + status = swapctl(SC_LIST, s); + if (status < 0) { + char errbuf[1024]; + ERROR("swap plugin: swapctl (SC_LIST) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + sfree(s_paths); + sfree(s); + return (-1); + } else if (swap_num < status) { + /* more elements returned than requested */ + ERROR("swap plugin: I allocated memory for %i structure%s, " + "but swapctl(2) claims to have returned %i. " + "I'm confused and will give up.", + swap_num, (swap_num == 1) ? "" : "s", status); + sfree(s_paths); + sfree(s); + return (-1); + } else if (swap_num > status) + /* less elements returned than requested */ + swap_num = status; + + for (int i = 0; i < swap_num; i++) { + char path[PATH_MAX]; + gauge_t this_total; + gauge_t this_avail; + + if ((s->swt_ent[i].ste_flags & ST_INDEL) != 0) + continue; + + this_total = (gauge_t)(s->swt_ent[i].ste_pages * pagesize); + this_avail = (gauge_t)(s->swt_ent[i].ste_free * pagesize); + + /* Shortcut for the "combined" setting (default) */ + if (!report_by_device) { + avail += this_avail; + total += this_total; + continue; + } + + sstrncpy(path, s->swt_ent[i].ste_path, sizeof(path)); + escape_slashes(path, sizeof(path)); + + swap_submit_usage(path, this_total - this_avail, this_avail, NULL, NAN); + } /* for (swap_num) */ + + if (total < avail) { + ERROR( + "swap plugin: Total swap space (%g) is less than free swap space (%g).", + total, avail); + sfree(s_paths); + sfree(s); + return (-1); + } + + /* If the "separate" option was specified (report_by_device == 1), all + * values have already been dispatched from within the loop. */ + if (!report_by_device) + swap_submit_usage(NULL, total - avail, avail, NULL, NAN); + + sfree(s_paths); + sfree(s); + return (0); } /* }}} int swap_read */ -/* #endif HAVE_SWAPCTL && HAVE_SWAPCTL_TWO_ARGS */ + /* #endif HAVE_SWAPCTL && HAVE_SWAPCTL_TWO_ARGS */ #elif HAVE_SWAPCTL && HAVE_SWAPCTL_THREE_ARGS -static int swap_read (void) /* {{{ */ +static int swap_read(void) /* {{{ */ { - struct swapent *swap_entries; - int swap_num; - int status; - - gauge_t used = 0; - gauge_t total = 0; - - swap_num = swapctl (SWAP_NSWAP, NULL, 0); - if (swap_num < 0) - { - ERROR ("swap plugin: swapctl (SWAP_NSWAP) failed with status %i.", - swap_num); - return (-1); - } - else if (swap_num == 0) - return (0); - - swap_entries = calloc (swap_num, sizeof (*swap_entries)); - if (swap_entries == NULL) - { - ERROR ("swap plugin: calloc failed."); - return (-1); - } - - status = swapctl (SWAP_STATS, swap_entries, swap_num); - if (status != swap_num) - { - ERROR ("swap plugin: swapctl (SWAP_STATS) failed with status %i.", - status); - sfree (swap_entries); - return (-1); - } + struct swapent *swap_entries; + int swap_num; + int status; + + gauge_t used = 0; + gauge_t total = 0; + + swap_num = swapctl(SWAP_NSWAP, NULL, 0); + if (swap_num < 0) { + ERROR("swap plugin: swapctl (SWAP_NSWAP) failed with status %i.", swap_num); + return (-1); + } else if (swap_num == 0) + return (0); + + swap_entries = calloc(swap_num, sizeof(*swap_entries)); + if (swap_entries == NULL) { + ERROR("swap plugin: calloc failed."); + return (-1); + } + + status = swapctl(SWAP_STATS, swap_entries, swap_num); + if (status != swap_num) { + ERROR("swap plugin: swapctl (SWAP_STATS) failed with status %i.", status); + sfree(swap_entries); + return (-1); + } #if defined(DEV_BSIZE) && (DEV_BSIZE > 0) -# define C_SWAP_BLOCK_SIZE ((gauge_t) DEV_BSIZE) +#define C_SWAP_BLOCK_SIZE ((gauge_t)DEV_BSIZE) #else -# define C_SWAP_BLOCK_SIZE 512.0 +#define C_SWAP_BLOCK_SIZE 512.0 #endif - /* TODO: Report per-device stats. The path name is available from - * swap_entries[i].se_path */ - for (int i = 0; i < swap_num; i++) - { - if ((swap_entries[i].se_flags & SWF_ENABLE) == 0) - continue; - - used += ((gauge_t) swap_entries[i].se_inuse) * C_SWAP_BLOCK_SIZE; - total += ((gauge_t) swap_entries[i].se_nblks) * C_SWAP_BLOCK_SIZE; - } - - if (total < used) - { - ERROR ("swap plugin: Total swap space (%g) is less than used swap space (%g).", - total, used); - sfree (swap_entries); - return (-1); - } - - swap_submit_usage (NULL, used, total - used, NULL, NAN); - - sfree (swap_entries); - return (0); + /* TODO: Report per-device stats. The path name is available from + * swap_entries[i].se_path */ + for (int i = 0; i < swap_num; i++) { + if ((swap_entries[i].se_flags & SWF_ENABLE) == 0) + continue; + + used += ((gauge_t)swap_entries[i].se_inuse) * C_SWAP_BLOCK_SIZE; + total += ((gauge_t)swap_entries[i].se_nblks) * C_SWAP_BLOCK_SIZE; + } + + if (total < used) { + ERROR( + "swap plugin: Total swap space (%g) is less than used swap space (%g).", + total, used); + sfree(swap_entries); + return (-1); + } + + swap_submit_usage(NULL, used, total - used, NULL, NAN); + + sfree(swap_entries); + return (0); } /* }}} int swap_read */ -/* #endif HAVE_SWAPCTL && HAVE_SWAPCTL_THREE_ARGS */ + /* #endif HAVE_SWAPCTL && HAVE_SWAPCTL_THREE_ARGS */ #elif defined(VM_SWAPUSAGE) -static int swap_read (void) /* {{{ */ +static int swap_read(void) /* {{{ */ { - int mib[3]; - size_t mib_len; - struct xsw_usage sw_usage; - size_t sw_usage_len; + int mib[3]; + size_t mib_len; + struct xsw_usage sw_usage; + size_t sw_usage_len; - mib_len = 2; - mib[0] = CTL_VM; - mib[1] = VM_SWAPUSAGE; + mib_len = 2; + mib[0] = CTL_VM; + mib[1] = VM_SWAPUSAGE; - sw_usage_len = sizeof (struct xsw_usage); + sw_usage_len = sizeof(struct xsw_usage); - if (sysctl (mib, mib_len, &sw_usage, &sw_usage_len, NULL, 0) != 0) - return (-1); + if (sysctl(mib, mib_len, &sw_usage, &sw_usage_len, NULL, 0) != 0) + return (-1); - /* The returned values are bytes. */ - swap_submit_usage (NULL, - (gauge_t) sw_usage.xsu_used, (gauge_t) sw_usage.xsu_avail, - NULL, NAN); + /* The returned values are bytes. */ + swap_submit_usage(NULL, (gauge_t)sw_usage.xsu_used, + (gauge_t)sw_usage.xsu_avail, NULL, NAN); - return (0); + return (0); } /* }}} int swap_read */ -/* #endif VM_SWAPUSAGE */ + /* #endif VM_SWAPUSAGE */ #elif HAVE_LIBKVM_GETSWAPINFO -static int swap_read (void) /* {{{ */ +static int swap_read(void) /* {{{ */ { - struct kvm_swap data_s; - int status; + struct kvm_swap data_s; + int status; - gauge_t used; - gauge_t total; + gauge_t used; + gauge_t total; - if (kvm_obj == NULL) - return (-1); + if (kvm_obj == NULL) + return (-1); - /* only one structure => only get the grand total, no details */ - status = kvm_getswapinfo (kvm_obj, &data_s, 1, 0); - if (status == -1) - return (-1); + /* only one structure => only get the grand total, no details */ + status = kvm_getswapinfo(kvm_obj, &data_s, 1, 0); + if (status == -1) + return (-1); - total = (gauge_t) data_s.ksw_total; - used = (gauge_t) data_s.ksw_used; + total = (gauge_t)data_s.ksw_total; + used = (gauge_t)data_s.ksw_used; - total *= (gauge_t) kvm_pagesize; - used *= (gauge_t) kvm_pagesize; + total *= (gauge_t)kvm_pagesize; + used *= (gauge_t)kvm_pagesize; - swap_submit_usage (NULL, used, total - used, NULL, NAN); + swap_submit_usage(NULL, used, total - used, NULL, NAN); - return (0); + return (0); } /* }}} int swap_read */ -/* #endif HAVE_LIBKVM_GETSWAPINFO */ + /* #endif HAVE_LIBKVM_GETSWAPINFO */ #elif HAVE_LIBSTATGRAB -static int swap_read (void) /* {{{ */ +static int swap_read(void) /* {{{ */ { - sg_swap_stats *swap; + sg_swap_stats *swap; - swap = sg_get_swap_stats (); - if (swap == NULL) - return (-1); + swap = sg_get_swap_stats(); + if (swap == NULL) + return (-1); - swap_submit_usage (NULL, (gauge_t) swap->used, (gauge_t) swap->free, - NULL, NAN); + swap_submit_usage(NULL, (gauge_t)swap->used, (gauge_t)swap->free, NULL, NAN); - return (0); + return (0); } /* }}} int swap_read */ -/* #endif HAVE_LIBSTATGRAB */ + /* #endif HAVE_LIBSTATGRAB */ #elif HAVE_PERFSTAT -static int swap_read (void) /* {{{ */ +static int swap_read(void) /* {{{ */ { - perfstat_memory_total_t pmemory = { 0 }; - int status; - - gauge_t total; - gauge_t free; - gauge_t reserved; - - status = perfstat_memory_total (NULL, &pmemory, sizeof(perfstat_memory_total_t), 1); - if (status < 0) - { - char errbuf[1024]; - WARNING ("swap plugin: perfstat_memory_total failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - total = (gauge_t) (pmemory.pgsp_total * pagesize); - free = (gauge_t) (pmemory.pgsp_free * pagesize); - reserved = (gauge_t) (pmemory.pgsp_rsvd * pagesize); - - swap_submit_usage (NULL, total - free, free, "reserved", reserved); - swap_submit_derive ("in", (derive_t) pmemory.pgspins * pagesize); - swap_submit_derive ("out", (derive_t) pmemory.pgspouts * pagesize); - - return (0); + perfstat_memory_total_t pmemory = {0}; + int status; + + gauge_t total; + gauge_t free; + gauge_t reserved; + + status = + perfstat_memory_total(NULL, &pmemory, sizeof(perfstat_memory_total_t), 1); + if (status < 0) { + char errbuf[1024]; + WARNING("swap plugin: perfstat_memory_total failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + total = (gauge_t)(pmemory.pgsp_total * pagesize); + free = (gauge_t)(pmemory.pgsp_free * pagesize); + reserved = (gauge_t)(pmemory.pgsp_rsvd * pagesize); + + swap_submit_usage(NULL, total - free, free, "reserved", reserved); + swap_submit_derive("in", (derive_t)pmemory.pgspins * pagesize); + swap_submit_derive("out", (derive_t)pmemory.pgspouts * pagesize); + + return (0); } /* }}} int swap_read */ #endif /* HAVE_PERFSTAT */ -void module_register (void) -{ - plugin_register_complex_config ("swap", swap_config); - plugin_register_init ("swap", swap_init); - plugin_register_read ("swap", swap_read); +void module_register(void) { + plugin_register_complex_config("swap", swap_config); + plugin_register_init("swap", swap_init); + plugin_register_read("swap", swap_read); } /* void module_register */ /* vim: set fdm=marker : */ diff --git a/src/syslog.c b/src/syslog.c index 73e5e1f3..6d326ff1 100644 --- a/src/syslog.c +++ b/src/syslog.c @@ -30,7 +30,7 @@ #include "plugin.h" #if HAVE_SYSLOG_H -# include +#include #endif #if COLLECT_DEBUG @@ -40,122 +40,111 @@ static int log_level = LOG_INFO; #endif /* COLLECT_DEBUG */ static int notif_severity = 0; -static const char *config_keys[] = -{ - "LogLevel", - "NotifyLevel", +static const char *config_keys[] = { + "LogLevel", "NotifyLevel", }; static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); -static int sl_config (const char *key, const char *value) -{ - if (strcasecmp (key, "LogLevel") == 0) - { - log_level = parse_log_severity (value); - if (log_level < 0) - { - log_level = LOG_INFO; - ERROR ("syslog: invalid loglevel [%s] defaulting to 'info'", value); - return (1); - } - } - else if (strcasecmp (key, "NotifyLevel") == 0) - { - notif_severity = parse_notif_severity (value); - if (notif_severity < 0) - return (1); - } - - return (0); +static int sl_config(const char *key, const char *value) { + if (strcasecmp(key, "LogLevel") == 0) { + log_level = parse_log_severity(value); + if (log_level < 0) { + log_level = LOG_INFO; + ERROR("syslog: invalid loglevel [%s] defaulting to 'info'", value); + return (1); + } + } else if (strcasecmp(key, "NotifyLevel") == 0) { + notif_severity = parse_notif_severity(value); + if (notif_severity < 0) + return (1); + } + + return (0); } /* int sl_config */ -static void sl_log (int severity, const char *msg, - user_data_t __attribute__((unused)) *user_data) -{ - if (severity > log_level) - return; +static void sl_log(int severity, const char *msg, + user_data_t __attribute__((unused)) * user_data) { + if (severity > log_level) + return; - syslog (severity, "%s", msg); + syslog(severity, "%s", msg); } /* void sl_log */ -static int sl_shutdown (void) -{ - closelog (); +static int sl_shutdown(void) { + closelog(); - return (0); + return (0); } -static int sl_notification (const notification_t *n, - user_data_t __attribute__((unused)) *user_data) -{ - char buf[1024] = ""; - size_t offset = 0; - int log_severity; - const char *severity_string; - int status; - - if (n->severity > notif_severity) - return (0); - - switch (n->severity) - { - case NOTIF_FAILURE: - severity_string = "FAILURE"; - log_severity = LOG_ERR; - break; - case NOTIF_WARNING: - severity_string = "WARNING"; - log_severity = LOG_WARNING; - break; - case NOTIF_OKAY: - severity_string = "OKAY"; - log_severity = LOG_NOTICE; - break; - default: - severity_string = "UNKNOWN"; - log_severity = LOG_ERR; - } - -#define BUFFER_ADD(...) do { \ - status = ssnprintf (&buf[offset], sizeof (buf) - offset, \ - __VA_ARGS__); \ - if (status < 1) \ - return (-1); \ - else if (((size_t) status) >= (sizeof (buf) - offset)) \ - return (-ENOMEM); \ - else \ - offset += ((size_t) status); \ -} while (0) - -#define BUFFER_ADD_FIELD(field) do { \ - if (n->field[0]) \ - BUFFER_ADD (", " #field " = %s", n->field); \ -} while (0) - - BUFFER_ADD ("Notification: severity = %s", severity_string); - BUFFER_ADD_FIELD (host); - BUFFER_ADD_FIELD (plugin); - BUFFER_ADD_FIELD (plugin_instance); - BUFFER_ADD_FIELD (type); - BUFFER_ADD_FIELD (type_instance); - BUFFER_ADD_FIELD (message); +static int sl_notification(const notification_t *n, + user_data_t __attribute__((unused)) * user_data) { + char buf[1024] = ""; + size_t offset = 0; + int log_severity; + const char *severity_string; + int status; + + if (n->severity > notif_severity) + return (0); + + switch (n->severity) { + case NOTIF_FAILURE: + severity_string = "FAILURE"; + log_severity = LOG_ERR; + break; + case NOTIF_WARNING: + severity_string = "WARNING"; + log_severity = LOG_WARNING; + break; + case NOTIF_OKAY: + severity_string = "OKAY"; + log_severity = LOG_NOTICE; + break; + default: + severity_string = "UNKNOWN"; + log_severity = LOG_ERR; + } + +#define BUFFER_ADD(...) \ + do { \ + status = ssnprintf(&buf[offset], sizeof(buf) - offset, __VA_ARGS__); \ + if (status < 1) \ + return (-1); \ + else if (((size_t)status) >= (sizeof(buf) - offset)) \ + return (-ENOMEM); \ + else \ + offset += ((size_t)status); \ + } while (0) + +#define BUFFER_ADD_FIELD(field) \ + do { \ + if (n->field[0]) \ + BUFFER_ADD(", " #field " = %s", n->field); \ + } while (0) + + BUFFER_ADD("Notification: severity = %s", severity_string); + BUFFER_ADD_FIELD(host); + BUFFER_ADD_FIELD(plugin); + BUFFER_ADD_FIELD(plugin_instance); + BUFFER_ADD_FIELD(type); + BUFFER_ADD_FIELD(type_instance); + BUFFER_ADD_FIELD(message); #undef BUFFER_ADD_FIELD #undef BUFFER_ADD - buf[sizeof (buf) - 1] = '\0'; + buf[sizeof(buf) - 1] = '\0'; - sl_log (log_severity, buf, NULL); + sl_log(log_severity, buf, NULL); - return (0); + return (0); } /* int sl_notification */ -void module_register (void) -{ - openlog ("collectd", LOG_CONS | LOG_PID, LOG_DAEMON); +void module_register(void) { + openlog("collectd", LOG_CONS | LOG_PID, LOG_DAEMON); - plugin_register_config ("syslog", sl_config, config_keys, config_keys_num); - plugin_register_log ("syslog", sl_log, /* user_data = */ NULL); - plugin_register_notification ("syslog", sl_notification, NULL); - plugin_register_shutdown ("syslog", sl_shutdown); + plugin_register_config("syslog", sl_config, config_keys, config_keys_num); + plugin_register_log("syslog", sl_log, /* user_data = */ NULL); + plugin_register_notification("syslog", sl_notification, NULL); + plugin_register_shutdown("syslog", sl_shutdown); } /* void module_register(void) */ diff --git a/src/table.c b/src/table.c index 7181795e..3e8feada 100644 --- a/src/table.c +++ b/src/table.c @@ -34,87 +34,83 @@ #include "plugin.h" -#define log_err(...) ERROR ("table plugin: " __VA_ARGS__) -#define log_warn(...) WARNING ("table plugin: " __VA_ARGS__) +#define log_err(...) ERROR("table plugin: " __VA_ARGS__) +#define log_warn(...) WARNING("table plugin: " __VA_ARGS__) /* * private data types */ typedef struct { - char *type; - char *instance_prefix; - size_t *instances; - size_t instances_num; - size_t *values; - size_t values_num; - - const data_set_t *ds; + char *type; + char *instance_prefix; + size_t *instances; + size_t instances_num; + size_t *values; + size_t values_num; + + const data_set_t *ds; } tbl_result_t; typedef struct { - char *file; - char *sep; - char *instance; + char *file; + char *sep; + char *instance; - tbl_result_t *results; - size_t results_num; + tbl_result_t *results; + size_t results_num; - size_t max_colnum; + size_t max_colnum; } tbl_t; -static void tbl_result_setup (tbl_result_t *res) -{ - res->type = NULL; +static void tbl_result_setup(tbl_result_t *res) { + res->type = NULL; - res->instance_prefix = NULL; - res->instances = NULL; - res->instances_num = 0; + res->instance_prefix = NULL; + res->instances = NULL; + res->instances_num = 0; - res->values = NULL; - res->values_num = 0; + res->values = NULL; + res->values_num = 0; - res->ds = NULL; + res->ds = NULL; } /* tbl_result_setup */ -static void tbl_result_clear (tbl_result_t *res) -{ - sfree (res->type); +static void tbl_result_clear(tbl_result_t *res) { + sfree(res->type); - sfree (res->instance_prefix); - sfree (res->instances); - res->instances_num = 0; + sfree(res->instance_prefix); + sfree(res->instances); + res->instances_num = 0; - sfree (res->values); - res->values_num = 0; + sfree(res->values); + res->values_num = 0; - res->ds = NULL; + res->ds = NULL; } /* tbl_result_clear */ -static void tbl_setup (tbl_t *tbl, char *file) -{ - tbl->file = sstrdup (file); - tbl->sep = NULL; - tbl->instance = NULL; +static void tbl_setup(tbl_t *tbl, char *file) { + tbl->file = sstrdup(file); + tbl->sep = NULL; + tbl->instance = NULL; - tbl->results = NULL; - tbl->results_num = 0; + tbl->results = NULL; + tbl->results_num = 0; - tbl->max_colnum = 0; + tbl->max_colnum = 0; } /* tbl_setup */ -static void tbl_clear (tbl_t *tbl) -{ - sfree (tbl->file); - sfree (tbl->sep); - sfree (tbl->instance); +static void tbl_clear(tbl_t *tbl) { + sfree(tbl->file); + sfree(tbl->sep); + sfree(tbl->instance); - for (size_t i = 0; i < tbl->results_num; ++i) - tbl_result_clear (tbl->results + i); - sfree (tbl->results); - tbl->results_num = 0; + for (size_t i = 0; i < tbl->results_num; ++i) + tbl_result_clear(tbl->results + i); + sfree(tbl->results); + tbl->results_num = 0; - tbl->max_colnum = 0; + tbl->max_colnum = 0; } /* tbl_clear */ static tbl_t *tables; @@ -124,426 +120,405 @@ static size_t tables_num; * configuration handling */ -static int tbl_config_set_s (char *name, char **var, oconfig_item_t *ci) -{ - if ((1 != ci->values_num) - || (OCONFIG_TYPE_STRING != ci->values[0].type)) { - log_err ("\"%s\" expects a single string argument.", name); - return 1; - } - - sfree (*var); - *var = sstrdup (ci->values[0].value.string); - return 0; +static int tbl_config_set_s(char *name, char **var, oconfig_item_t *ci) { + if ((1 != ci->values_num) || (OCONFIG_TYPE_STRING != ci->values[0].type)) { + log_err("\"%s\" expects a single string argument.", name); + return 1; + } + + sfree(*var); + *var = sstrdup(ci->values[0].value.string); + return 0; } /* tbl_config_set_separator */ -static int tbl_config_append_array_i (char *name, size_t **var, size_t *len, - oconfig_item_t *ci) -{ - size_t *tmp; - size_t num; - - if (1 > ci->values_num) { - log_err ("\"%s\" expects at least one argument.", name); - return 1; - } - - num = (size_t) ci->values_num; - for (size_t i = 0; i < num; ++i) { - if (OCONFIG_TYPE_NUMBER != ci->values[i].type) { - log_err ("\"%s\" expects numerical arguments only.", name); - return 1; - } - } - - tmp = realloc (*var, ((*len) + num) * sizeof (**var)); - if (NULL == tmp) { - char errbuf[1024]; - log_err ("realloc failed: %s.", - sstrerror (errno, errbuf, sizeof (errbuf))); - return -1; - } - *var = tmp; - - for (size_t i = 0; i < num; ++i) { - (*var)[*len] = (size_t) ci->values[i].value.number; - (*len)++; - } - - return 0; +static int tbl_config_append_array_i(char *name, size_t **var, size_t *len, + oconfig_item_t *ci) { + size_t *tmp; + size_t num; + + if (1 > ci->values_num) { + log_err("\"%s\" expects at least one argument.", name); + return 1; + } + + num = (size_t)ci->values_num; + for (size_t i = 0; i < num; ++i) { + if (OCONFIG_TYPE_NUMBER != ci->values[i].type) { + log_err("\"%s\" expects numerical arguments only.", name); + return 1; + } + } + + tmp = realloc(*var, ((*len) + num) * sizeof(**var)); + if (NULL == tmp) { + char errbuf[1024]; + log_err("realloc failed: %s.", sstrerror(errno, errbuf, sizeof(errbuf))); + return -1; + } + *var = tmp; + + for (size_t i = 0; i < num; ++i) { + (*var)[*len] = (size_t)ci->values[i].value.number; + (*len)++; + } + + return 0; } /* tbl_config_append_array_s */ -static int tbl_config_result (tbl_t *tbl, oconfig_item_t *ci) -{ - tbl_result_t *res; - - int status = 0; - - if (0 != ci->values_num) { - log_err (" does not expect any arguments."); - return 1; - } - - res = realloc (tbl->results, - (tbl->results_num + 1) * sizeof (*tbl->results)); - if (res == NULL) { - char errbuf[1024]; - log_err ("realloc failed: %s.", - sstrerror (errno, errbuf, sizeof (errbuf))); - return -1; - } - - tbl->results = res; - ++tbl->results_num; - - res = tbl->results + tbl->results_num - 1; - tbl_result_setup (res); - - for (int i = 0; i < ci->children_num; ++i) { - oconfig_item_t *c = ci->children + i; - - if (0 == strcasecmp (c->key, "Type")) - tbl_config_set_s (c->key, &res->type, c); - else if (0 == strcasecmp (c->key, "InstancePrefix")) - tbl_config_set_s (c->key, &res->instance_prefix, c); - else if (0 == strcasecmp (c->key, "InstancesFrom")) - tbl_config_append_array_i (c->key, - &res->instances, &res->instances_num, c); - else if (0 == strcasecmp (c->key, "ValuesFrom")) - tbl_config_append_array_i (c->key, - &res->values, &res->values_num, c); - else - log_warn ("Ignoring unknown config key \"%s\" " - " in .", c->key); - } - - if (NULL == res->type) { - log_err ("No \"Type\" option specified for " - "in table \"%s\".", tbl->file); - status = 1; - } - - if (NULL == res->values) { - log_err ("No \"ValuesFrom\" option specified for " - "in table \"%s\".", tbl->file); - status = 1; - } - - if (0 != status) { - tbl_result_clear (res); - --tbl->results_num; - return status; - } - return 0; +static int tbl_config_result(tbl_t *tbl, oconfig_item_t *ci) { + tbl_result_t *res; + + int status = 0; + + if (0 != ci->values_num) { + log_err(" does not expect any arguments."); + return 1; + } + + res = realloc(tbl->results, (tbl->results_num + 1) * sizeof(*tbl->results)); + if (res == NULL) { + char errbuf[1024]; + log_err("realloc failed: %s.", sstrerror(errno, errbuf, sizeof(errbuf))); + return -1; + } + + tbl->results = res; + ++tbl->results_num; + + res = tbl->results + tbl->results_num - 1; + tbl_result_setup(res); + + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *c = ci->children + i; + + if (0 == strcasecmp(c->key, "Type")) + tbl_config_set_s(c->key, &res->type, c); + else if (0 == strcasecmp(c->key, "InstancePrefix")) + tbl_config_set_s(c->key, &res->instance_prefix, c); + else if (0 == strcasecmp(c->key, "InstancesFrom")) + tbl_config_append_array_i(c->key, &res->instances, &res->instances_num, + c); + else if (0 == strcasecmp(c->key, "ValuesFrom")) + tbl_config_append_array_i(c->key, &res->values, &res->values_num, c); + else + log_warn("Ignoring unknown config key \"%s\" " + " in .", + c->key); + } + + if (NULL == res->type) { + log_err("No \"Type\" option specified for " + "in table \"%s\".", + tbl->file); + status = 1; + } + + if (NULL == res->values) { + log_err("No \"ValuesFrom\" option specified for " + "in table \"%s\".", + tbl->file); + status = 1; + } + + if (0 != status) { + tbl_result_clear(res); + --tbl->results_num; + return status; + } + return 0; } /* tbl_config_result */ -static int tbl_config_table (oconfig_item_t *ci) -{ - tbl_t *tbl; - - int status = 0; - - if ((1 != ci->values_num) - || (OCONFIG_TYPE_STRING != ci->values[0].type)) { - log_err ("
expects a single string argument."); - return 1; - } - - tbl = realloc (tables, (tables_num + 1) * sizeof (*tables)); - if (NULL == tbl) { - char errbuf[1024]; - log_err ("realloc failed: %s.", - sstrerror (errno, errbuf, sizeof (errbuf))); - return -1; - } - - tables = tbl; - ++tables_num; - - tbl = tables + tables_num - 1; - tbl_setup (tbl, ci->values[0].value.string); - - for (size_t i = 0; i < ((size_t) ci->children_num); ++i) { - oconfig_item_t *c = ci->children + i; - - if (0 == strcasecmp (c->key, "Separator")) - tbl_config_set_s (c->key, &tbl->sep, c); - else if (0 == strcasecmp (c->key, "Instance")) - tbl_config_set_s (c->key, &tbl->instance, c); - else if (0 == strcasecmp (c->key, "Result")) - tbl_config_result (tbl, c); - else - log_warn ("Ignoring unknown config key \"%s\" " - "in
.", c->key, tbl->file); - } - - if (NULL == tbl->sep) { - log_err ("Table \"%s\" does not specify any separator.", tbl->file); - status = 1; - } else { - strunescape (tbl->sep, strlen (tbl->sep) + 1); - } - - if (NULL == tbl->instance) { - tbl->instance = sstrdup (tbl->file); - replace_special (tbl->instance, strlen (tbl->instance)); - } - - if (NULL == tbl->results) { - log_err ("Table \"%s\" does not specify any (valid) results.", - tbl->file); - status = 1; - } - - if (0 != status) { - tbl_clear (tbl); - --tables_num; - return status; - } - - for (size_t i = 0; i < tbl->results_num; ++i) { - tbl_result_t *res = tbl->results + i; - - for (size_t j = 0; j < res->instances_num; ++j) - if (res->instances[j] > tbl->max_colnum) - tbl->max_colnum = res->instances[j]; - - for (size_t j = 0; j < res->values_num; ++j) - if (res->values[j] > tbl->max_colnum) - tbl->max_colnum = res->values[j]; - } - return 0; +static int tbl_config_table(oconfig_item_t *ci) { + tbl_t *tbl; + + int status = 0; + + if ((1 != ci->values_num) || (OCONFIG_TYPE_STRING != ci->values[0].type)) { + log_err("
expects a single string argument."); + return 1; + } + + tbl = realloc(tables, (tables_num + 1) * sizeof(*tables)); + if (NULL == tbl) { + char errbuf[1024]; + log_err("realloc failed: %s.", sstrerror(errno, errbuf, sizeof(errbuf))); + return -1; + } + + tables = tbl; + ++tables_num; + + tbl = tables + tables_num - 1; + tbl_setup(tbl, ci->values[0].value.string); + + for (size_t i = 0; i < ((size_t)ci->children_num); ++i) { + oconfig_item_t *c = ci->children + i; + + if (0 == strcasecmp(c->key, "Separator")) + tbl_config_set_s(c->key, &tbl->sep, c); + else if (0 == strcasecmp(c->key, "Instance")) + tbl_config_set_s(c->key, &tbl->instance, c); + else if (0 == strcasecmp(c->key, "Result")) + tbl_config_result(tbl, c); + else + log_warn("Ignoring unknown config key \"%s\" " + "in
.", + c->key, tbl->file); + } + + if (NULL == tbl->sep) { + log_err("Table \"%s\" does not specify any separator.", tbl->file); + status = 1; + } else { + strunescape(tbl->sep, strlen(tbl->sep) + 1); + } + + if (NULL == tbl->instance) { + tbl->instance = sstrdup(tbl->file); + replace_special(tbl->instance, strlen(tbl->instance)); + } + + if (NULL == tbl->results) { + log_err("Table \"%s\" does not specify any (valid) results.", tbl->file); + status = 1; + } + + if (0 != status) { + tbl_clear(tbl); + --tables_num; + return status; + } + + for (size_t i = 0; i < tbl->results_num; ++i) { + tbl_result_t *res = tbl->results + i; + + for (size_t j = 0; j < res->instances_num; ++j) + if (res->instances[j] > tbl->max_colnum) + tbl->max_colnum = res->instances[j]; + + for (size_t j = 0; j < res->values_num; ++j) + if (res->values[j] > tbl->max_colnum) + tbl->max_colnum = res->values[j]; + } + return 0; } /* tbl_config_table */ -static int tbl_config (oconfig_item_t *ci) -{ - for (int i = 0; i < ci->children_num; ++i) { - oconfig_item_t *c = ci->children + i; - - if (0 == strcasecmp (c->key, "Table")) - tbl_config_table (c); - else - log_warn ("Ignoring unknown config key \"%s\".", c->key); - } - return 0; +static int tbl_config(oconfig_item_t *ci) { + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *c = ci->children + i; + + if (0 == strcasecmp(c->key, "Table")) + tbl_config_table(c); + else + log_warn("Ignoring unknown config key \"%s\".", c->key); + } + return 0; } /* tbl_config */ /* * result handling */ -static int tbl_prepare (tbl_t *tbl) -{ - for (size_t i = 0; i < tbl->results_num; ++i) { - tbl_result_t *res = tbl->results + i; - - res->ds = plugin_get_ds (res->type); - if (NULL == res->ds) { - log_err ("Unknown type \"%s\". See types.db(5) for details.", - res->type); - return -1; - } - - if (res->values_num != res->ds->ds_num) { - log_err ("Invalid type \"%s\". Expected %zu data source%s, " - "got %zu.", res->type, res->values_num, - (1 == res->values_num) ? "" : "s", - res->ds->ds_num); - return -1; - } - } - return 0; +static int tbl_prepare(tbl_t *tbl) { + for (size_t i = 0; i < tbl->results_num; ++i) { + tbl_result_t *res = tbl->results + i; + + res->ds = plugin_get_ds(res->type); + if (NULL == res->ds) { + log_err("Unknown type \"%s\". See types.db(5) for details.", res->type); + return -1; + } + + if (res->values_num != res->ds->ds_num) { + log_err("Invalid type \"%s\". Expected %zu data source%s, " + "got %zu.", + res->type, res->values_num, (1 == res->values_num) ? "" : "s", + res->ds->ds_num); + return -1; + } + } + return 0; } /* tbl_prepare */ -static int tbl_finish (tbl_t *tbl) -{ - for (size_t i = 0; i < tbl->results_num; ++i) - tbl->results[i].ds = NULL; - return 0; +static int tbl_finish(tbl_t *tbl) { + for (size_t i = 0; i < tbl->results_num; ++i) + tbl->results[i].ds = NULL; + return 0; } /* tbl_finish */ -static int tbl_result_dispatch (tbl_t *tbl, tbl_result_t *res, - char **fields, size_t fields_num) -{ - value_list_t vl = VALUE_LIST_INIT; - value_t values[res->values_num]; - - assert (NULL != res->ds); - assert (res->values_num == res->ds->ds_num); - - for (size_t i = 0; i < res->values_num; ++i) { - char *value; - - assert (res->values[i] < fields_num); - value = fields[res->values[i]]; - - if (0 != parse_value (value, &values[i], res->ds->ds[i].type)) - return -1; - } - - vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - - sstrncpy (vl.plugin, "table", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, tbl->instance, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, res->type, sizeof (vl.type)); - - if (0 == res->instances_num) { - if (NULL != res->instance_prefix) - sstrncpy (vl.type_instance, res->instance_prefix, - sizeof (vl.type_instance)); - } - else { - char *instances[res->instances_num]; - char instances_str[DATA_MAX_NAME_LEN]; - - for (size_t i = 0; i < res->instances_num; ++i) { - assert (res->instances[i] < fields_num); - instances[i] = fields[res->instances[i]]; - } - - strjoin (instances_str, sizeof (instances_str), - instances, STATIC_ARRAY_SIZE (instances), "-"); - instances_str[sizeof (instances_str) - 1] = '\0'; - - vl.type_instance[sizeof (vl.type_instance) - 1] = '\0'; - if (NULL == res->instance_prefix) - strncpy (vl.type_instance, instances_str, - sizeof (vl.type_instance)); - else - snprintf (vl.type_instance, sizeof (vl.type_instance), - "%s-%s", res->instance_prefix, instances_str); - - if ('\0' != vl.type_instance[sizeof (vl.type_instance) - 1]) { - vl.type_instance[sizeof (vl.type_instance) - 1] = '\0'; - log_warn ("Truncated type instance: %s.", vl.type_instance); - } - } - - plugin_dispatch_values (&vl); - return 0; +static int tbl_result_dispatch(tbl_t *tbl, tbl_result_t *res, char **fields, + size_t fields_num) { + value_list_t vl = VALUE_LIST_INIT; + value_t values[res->values_num]; + + assert(NULL != res->ds); + assert(res->values_num == res->ds->ds_num); + + for (size_t i = 0; i < res->values_num; ++i) { + char *value; + + assert(res->values[i] < fields_num); + value = fields[res->values[i]]; + + if (0 != parse_value(value, &values[i], res->ds->ds[i].type)) + return -1; + } + + vl.values = values; + vl.values_len = STATIC_ARRAY_SIZE(values); + + sstrncpy(vl.plugin, "table", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, tbl->instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, res->type, sizeof(vl.type)); + + if (0 == res->instances_num) { + if (NULL != res->instance_prefix) + sstrncpy(vl.type_instance, res->instance_prefix, + sizeof(vl.type_instance)); + } else { + char *instances[res->instances_num]; + char instances_str[DATA_MAX_NAME_LEN]; + + for (size_t i = 0; i < res->instances_num; ++i) { + assert(res->instances[i] < fields_num); + instances[i] = fields[res->instances[i]]; + } + + strjoin(instances_str, sizeof(instances_str), instances, + STATIC_ARRAY_SIZE(instances), "-"); + instances_str[sizeof(instances_str) - 1] = '\0'; + + vl.type_instance[sizeof(vl.type_instance) - 1] = '\0'; + if (NULL == res->instance_prefix) + strncpy(vl.type_instance, instances_str, sizeof(vl.type_instance)); + else + snprintf(vl.type_instance, sizeof(vl.type_instance), "%s-%s", + res->instance_prefix, instances_str); + + if ('\0' != vl.type_instance[sizeof(vl.type_instance) - 1]) { + vl.type_instance[sizeof(vl.type_instance) - 1] = '\0'; + log_warn("Truncated type instance: %s.", vl.type_instance); + } + } + + plugin_dispatch_values(&vl); + return 0; } /* tbl_result_dispatch */ -static int tbl_parse_line (tbl_t *tbl, char *line, size_t len) -{ - char *fields[tbl->max_colnum + 1]; - char *ptr, *saveptr; - - size_t i = 0; - - ptr = line; - saveptr = NULL; - while (NULL != (fields[i] = strtok_r (ptr, tbl->sep, &saveptr))) { - ptr = NULL; - ++i; - - if (i > tbl->max_colnum) - break; - } - - if (i <= tbl->max_colnum) { - log_warn ("Not enough columns in line " - "(expected at least %zu, got %zu).", - tbl->max_colnum + 1, i); - return -1; - } - - for (i = 0; i < tbl->results_num; ++i) - if (0 != tbl_result_dispatch (tbl, tbl->results + i, - fields, STATIC_ARRAY_SIZE (fields))) { - log_err ("Failed to dispatch result."); - continue; - } - return 0; +static int tbl_parse_line(tbl_t *tbl, char *line, size_t len) { + char *fields[tbl->max_colnum + 1]; + char *ptr, *saveptr; + + size_t i = 0; + + ptr = line; + saveptr = NULL; + while (NULL != (fields[i] = strtok_r(ptr, tbl->sep, &saveptr))) { + ptr = NULL; + ++i; + + if (i > tbl->max_colnum) + break; + } + + if (i <= tbl->max_colnum) { + log_warn("Not enough columns in line " + "(expected at least %zu, got %zu).", + tbl->max_colnum + 1, i); + return -1; + } + + for (i = 0; i < tbl->results_num; ++i) + if (0 != tbl_result_dispatch(tbl, tbl->results + i, fields, + STATIC_ARRAY_SIZE(fields))) { + log_err("Failed to dispatch result."); + continue; + } + return 0; } /* tbl_parse_line */ -static int tbl_read_table (tbl_t *tbl) -{ - FILE *fh; - char buf[4096]; - - fh = fopen (tbl->file, "r"); - if (NULL == fh) { - char errbuf[1024]; - log_err ("Failed to open file \"%s\": %s.", tbl->file, - sstrerror (errno, errbuf, sizeof (errbuf))); - return -1; - } - - buf[sizeof (buf) - 1] = '\0'; - while (NULL != fgets (buf, sizeof (buf), fh)) { - if ('\0' != buf[sizeof (buf) - 1]) { - buf[sizeof (buf) - 1] = '\0'; - log_warn ("Table %s: Truncated line: %s", tbl->file, buf); - } - - if (0 != tbl_parse_line (tbl, buf, sizeof (buf))) { - log_warn ("Table %s: Failed to parse line: %s", tbl->file, buf); - continue; - } - } - - if (0 != ferror (fh)) { - char errbuf[1024]; - log_err ("Failed to read from file \"%s\": %s.", tbl->file, - sstrerror (errno, errbuf, sizeof (errbuf))); - fclose (fh); - return -1; - } - - fclose (fh); - return 0; +static int tbl_read_table(tbl_t *tbl) { + FILE *fh; + char buf[4096]; + + fh = fopen(tbl->file, "r"); + if (NULL == fh) { + char errbuf[1024]; + log_err("Failed to open file \"%s\": %s.", tbl->file, + sstrerror(errno, errbuf, sizeof(errbuf))); + return -1; + } + + buf[sizeof(buf) - 1] = '\0'; + while (NULL != fgets(buf, sizeof(buf), fh)) { + if ('\0' != buf[sizeof(buf) - 1]) { + buf[sizeof(buf) - 1] = '\0'; + log_warn("Table %s: Truncated line: %s", tbl->file, buf); + } + + if (0 != tbl_parse_line(tbl, buf, sizeof(buf))) { + log_warn("Table %s: Failed to parse line: %s", tbl->file, buf); + continue; + } + } + + if (0 != ferror(fh)) { + char errbuf[1024]; + log_err("Failed to read from file \"%s\": %s.", tbl->file, + sstrerror(errno, errbuf, sizeof(errbuf))); + fclose(fh); + return -1; + } + + fclose(fh); + return 0; } /* tbl_read_table */ /* * collectd callbacks */ -static int tbl_read (void) -{ - int status = -1; +static int tbl_read(void) { + int status = -1; - if (0 == tables_num) - return 0; + if (0 == tables_num) + return 0; - for (size_t i = 0; i < tables_num; ++i) { - tbl_t *tbl = tables + i; + for (size_t i = 0; i < tables_num; ++i) { + tbl_t *tbl = tables + i; - if (0 != tbl_prepare (tbl)) { - log_err ("Failed to prepare and parse table \"%s\".", tbl->file); - continue; - } + if (0 != tbl_prepare(tbl)) { + log_err("Failed to prepare and parse table \"%s\".", tbl->file); + continue; + } - if (0 == tbl_read_table (tbl)) - status = 0; + if (0 == tbl_read_table(tbl)) + status = 0; - tbl_finish (tbl); - } - return status; + tbl_finish(tbl); + } + return status; } /* tbl_read */ -static int tbl_shutdown (void) -{ - for (size_t i = 0; i < tables_num; ++i) - tbl_clear (&tables[i]); - sfree (tables); - return 0; +static int tbl_shutdown(void) { + for (size_t i = 0; i < tables_num; ++i) + tbl_clear(&tables[i]); + sfree(tables); + return 0; } /* tbl_shutdown */ -static int tbl_init (void) -{ - if (0 == tables_num) - return 0; +static int tbl_init(void) { + if (0 == tables_num) + return 0; - plugin_register_read ("table", tbl_read); - plugin_register_shutdown ("table", tbl_shutdown); - return 0; + plugin_register_read("table", tbl_read); + plugin_register_shutdown("table", tbl_shutdown); + return 0; } /* tbl_init */ -void module_register (void) -{ - plugin_register_complex_config ("table", tbl_config); - plugin_register_init ("table", tbl_init); +void module_register(void) { + plugin_register_complex_config("table", tbl_config); + plugin_register_init("table", tbl_init); } /* module_register */ /* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/tail.c b/src/tail.c index ff76b725..bb4eb30b 100644 --- a/src/tail.c +++ b/src/tail.c @@ -28,8 +28,8 @@ #include "common.h" #include "plugin.h" -#include "utils_tail_match.h" #include "utils_latency_config.h" +#include "utils_tail_match.h" /* * @@ -47,8 +47,7 @@ * */ -struct ctail_config_match_s -{ +struct ctail_config_match_s { char *regex; char *excluderegex; int flags; @@ -63,120 +62,103 @@ static cu_tail_match_t **tail_match_list = NULL; static size_t tail_match_list_num = 0; static cdtime_t tail_match_list_intervals[255]; -static int ctail_config_add_match_dstype (ctail_config_match_t *cm, - oconfig_item_t *ci) -{ - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("tail plugin: `DSType' needs exactly one string argument."); +static int ctail_config_add_match_dstype(ctail_config_match_t *cm, + oconfig_item_t *ci) { + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("tail plugin: `DSType' needs exactly one string argument."); return (-1); } char const *ds_type = ci->values[0].value.string; - if (strncasecmp ("Gauge", ds_type, strlen ("Gauge")) == 0) - { + if (strncasecmp("Gauge", ds_type, strlen("Gauge")) == 0) { cm->flags = UTILS_MATCH_DS_TYPE_GAUGE; - if (strcasecmp ("GaugeAverage", ds_type) == 0) + if (strcasecmp("GaugeAverage", ds_type) == 0) cm->flags |= UTILS_MATCH_CF_GAUGE_AVERAGE; - else if (strcasecmp ("GaugeMin", ds_type) == 0) + else if (strcasecmp("GaugeMin", ds_type) == 0) cm->flags |= UTILS_MATCH_CF_GAUGE_MIN; - else if (strcasecmp ("GaugeMax", ds_type) == 0) + else if (strcasecmp("GaugeMax", ds_type) == 0) cm->flags |= UTILS_MATCH_CF_GAUGE_MAX; - else if (strcasecmp ("GaugeLast", ds_type) == 0) + else if (strcasecmp("GaugeLast", ds_type) == 0) cm->flags |= UTILS_MATCH_CF_GAUGE_LAST; - else if (strcasecmp ("GaugeInc", ds_type) == 0) + else if (strcasecmp("GaugeInc", ds_type) == 0) cm->flags |= UTILS_MATCH_CF_GAUGE_INC; - else if (strcasecmp ("GaugeAdd", ds_type) == 0) + else if (strcasecmp("GaugeAdd", ds_type) == 0) cm->flags |= UTILS_MATCH_CF_GAUGE_ADD; - else if (strcasecmp ("GaugePersist", ci->values[0].value.string) == 0) + else if (strcasecmp("GaugePersist", ci->values[0].value.string) == 0) cm->flags |= UTILS_MATCH_CF_GAUGE_PERSIST; else cm->flags = 0; - } - else if (strcasecmp ("Distribution", ds_type) == 0) - { + } else if (strcasecmp("Distribution", ds_type) == 0) { cm->flags = UTILS_MATCH_DS_TYPE_GAUGE | UTILS_MATCH_CF_GAUGE_DIST; - int status = latency_config (&cm->latency, ci, "tail"); + int status = latency_config(&cm->latency, ci, "tail"); if (status != 0) return (status); - } - else if (strncasecmp ("Counter", ds_type, strlen ("Counter")) == 0) - { + } else if (strncasecmp("Counter", ds_type, strlen("Counter")) == 0) { cm->flags = UTILS_MATCH_DS_TYPE_COUNTER; - if (strcasecmp ("CounterSet", ds_type) == 0) + if (strcasecmp("CounterSet", ds_type) == 0) cm->flags |= UTILS_MATCH_CF_COUNTER_SET; - else if (strcasecmp ("CounterAdd", ds_type) == 0) + else if (strcasecmp("CounterAdd", ds_type) == 0) cm->flags |= UTILS_MATCH_CF_COUNTER_ADD; - else if (strcasecmp ("CounterInc", ds_type) == 0) + else if (strcasecmp("CounterInc", ds_type) == 0) cm->flags |= UTILS_MATCH_CF_COUNTER_INC; else cm->flags = 0; - } - else if (strncasecmp ("Derive", ds_type, strlen ("Derive")) == 0) - { + } else if (strncasecmp("Derive", ds_type, strlen("Derive")) == 0) { cm->flags = UTILS_MATCH_DS_TYPE_DERIVE; - if (strcasecmp ("DeriveSet", ds_type) == 0) + if (strcasecmp("DeriveSet", ds_type) == 0) cm->flags |= UTILS_MATCH_CF_DERIVE_SET; - else if (strcasecmp ("DeriveAdd", ds_type) == 0) + else if (strcasecmp("DeriveAdd", ds_type) == 0) cm->flags |= UTILS_MATCH_CF_DERIVE_ADD; - else if (strcasecmp ("DeriveInc", ds_type) == 0) + else if (strcasecmp("DeriveInc", ds_type) == 0) cm->flags |= UTILS_MATCH_CF_DERIVE_INC; else cm->flags = 0; - } - else if (strncasecmp ("Absolute", ds_type, strlen ("Absolute")) == 0) - { + } else if (strncasecmp("Absolute", ds_type, strlen("Absolute")) == 0) { cm->flags = UTILS_MATCH_DS_TYPE_ABSOLUTE; - if (strcasecmp ("AbsoluteSet", ds_type) == 0) + if (strcasecmp("AbsoluteSet", ds_type) == 0) cm->flags |= UTILS_MATCH_CF_ABSOLUTE_SET; else cm->flags = 0; - } - else - { + } else { cm->flags = 0; } - if (cm->flags == 0) - { - WARNING ("tail plugin: `%s' is not a valid argument to `DSType'.", - ci->values[0].value.string); + if (cm->flags == 0) { + WARNING("tail plugin: `%s' is not a valid argument to `DSType'.", + ci->values[0].value.string); return (-1); } return (0); } /* int ctail_config_add_match_dstype */ -static int ctail_config_add_match (cu_tail_match_t *tm, - const char *plugin_instance, oconfig_item_t *ci, cdtime_t interval) -{ - ctail_config_match_t cm = { 0 }; +static int ctail_config_add_match(cu_tail_match_t *tm, + const char *plugin_instance, + oconfig_item_t *ci, cdtime_t interval) { + ctail_config_match_t cm = {0}; int status; - if (ci->values_num != 0) - { - WARNING ("tail plugin: Ignoring arguments for the `Match' block."); + if (ci->values_num != 0) { + WARNING("tail plugin: Ignoring arguments for the `Match' block."); } status = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; - if (strcasecmp ("Regex", option->key) == 0) - status = cf_util_get_string (option, &cm.regex); - else if (strcasecmp ("ExcludeRegex", option->key) == 0) - status = cf_util_get_string (option, &cm.excluderegex); - else if (strcasecmp ("DSType", option->key) == 0) - status = ctail_config_add_match_dstype (&cm, option); - else if (strcasecmp ("Type", option->key) == 0) - status = cf_util_get_string (option, &cm.type); - else if (strcasecmp ("Instance", option->key) == 0) - status = cf_util_get_string (option, &cm.type_instance); - else - { - WARNING ("tail plugin: Option `%s' not allowed here.", option->key); + if (strcasecmp("Regex", option->key) == 0) + status = cf_util_get_string(option, &cm.regex); + else if (strcasecmp("ExcludeRegex", option->key) == 0) + status = cf_util_get_string(option, &cm.excluderegex); + else if (strcasecmp("DSType", option->key) == 0) + status = ctail_config_add_match_dstype(&cm, option); + else if (strcasecmp("Type", option->key) == 0) + status = cf_util_get_string(option, &cm.type); + else if (strcasecmp("Instance", option->key) == 0) + status = cf_util_get_string(option, &cm.type_instance); + else { + WARNING("tail plugin: Option `%s' not allowed here.", option->key); status = -1; } @@ -184,25 +166,21 @@ static int ctail_config_add_match (cu_tail_match_t *tm, break; } /* for (i = 0; i < ci->children_num; i++) */ - while (status == 0) - { - if (cm.regex == NULL) - { - WARNING ("tail plugin: `Regex' missing in `Match' block."); + while (status == 0) { + if (cm.regex == NULL) { + WARNING("tail plugin: `Regex' missing in `Match' block."); status = -1; break; } - if (cm.type == NULL) - { - WARNING ("tail plugin: `Type' missing in `Match' block."); + if (cm.type == NULL) { + WARNING("tail plugin: `Type' missing in `Match' block."); status = -1; break; } - if (cm.flags == 0) - { - WARNING ("tail plugin: `DSType' missing in `Match' block."); + if (cm.flags == 0) { + WARNING("tail plugin: `DSType' missing in `Match' block."); status = -1; break; } @@ -210,66 +188,58 @@ static int ctail_config_add_match (cu_tail_match_t *tm, break; } /* while (status == 0) */ - if (status == 0) - { + if (status == 0) { // TODO(octo): there's nothing "simple" about the latency stuff … - status = tail_match_add_match_simple (tm, cm.regex, cm.excluderegex, - cm.flags, "tail", plugin_instance, cm.type, cm.type_instance, - cm.latency, interval); + status = tail_match_add_match_simple( + tm, cm.regex, cm.excluderegex, cm.flags, "tail", plugin_instance, + cm.type, cm.type_instance, cm.latency, interval); if (status != 0) - ERROR ("tail plugin: tail_match_add_match_simple failed."); + ERROR("tail plugin: tail_match_add_match_simple failed."); } - sfree (cm.regex); - sfree (cm.excluderegex); - sfree (cm.type); - sfree (cm.type_instance); + sfree(cm.regex); + sfree(cm.excluderegex); + sfree(cm.type); + sfree(cm.type_instance); latency_config_free(cm.latency); return (status); } /* int ctail_config_add_match */ -static int ctail_config_add_file (oconfig_item_t *ci) -{ +static int ctail_config_add_file(oconfig_item_t *ci) { cu_tail_match_t *tm; cdtime_t interval = 0; char *plugin_instance = NULL; int num_matches = 0; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("tail plugin: `File' needs exactly one string argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("tail plugin: `File' needs exactly one string argument."); return (-1); } - tm = tail_match_create (ci->values[0].value.string); - if (tm == NULL) - { - ERROR ("tail plugin: tail_match_create (%s) failed.", - ci->values[0].value.string); + tm = tail_match_create(ci->values[0].value.string); + if (tm == NULL) { + ERROR("tail plugin: tail_match_create (%s) failed.", + ci->values[0].value.string); return (-1); } - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; int status = 0; - if (strcasecmp ("Instance", option->key) == 0) - status = cf_util_get_string (option, &plugin_instance); - else if (strcasecmp ("Interval", option->key) == 0) - cf_util_get_cdtime (option, &interval); - else if (strcasecmp ("Match", option->key) == 0) - { - status = ctail_config_add_match (tm, plugin_instance, option, interval); + if (strcasecmp("Instance", option->key) == 0) + status = cf_util_get_string(option, &plugin_instance); + else if (strcasecmp("Interval", option->key) == 0) + cf_util_get_cdtime(option, &interval); + else if (strcasecmp("Match", option->key) == 0) { + status = ctail_config_add_match(tm, plugin_instance, option, interval); if (status == 0) num_matches++; /* Be mild with failed matches.. */ status = 0; - } - else - { + } else { status = -1; } @@ -277,25 +247,21 @@ static int ctail_config_add_file (oconfig_item_t *ci) break; } /* for (i = 0; i < ci->children_num; i++) */ - sfree (plugin_instance); + sfree(plugin_instance); - if (num_matches == 0) - { - ERROR ("tail plugin: No (valid) matches found for file `%s'.", - ci->values[0].value.string); - tail_match_destroy (tm); + if (num_matches == 0) { + ERROR("tail plugin: No (valid) matches found for file `%s'.", + ci->values[0].value.string); + tail_match_destroy(tm); return (-1); - } - else - { + } else { cu_tail_match_t **temp; - temp = realloc (tail_match_list, - sizeof (cu_tail_match_t *) * (tail_match_list_num + 1)); - if (temp == NULL) - { - ERROR ("tail plugin: realloc failed."); - tail_match_destroy (tm); + temp = realloc(tail_match_list, + sizeof(cu_tail_match_t *) * (tail_match_list_num + 1)); + if (temp == NULL) { + ERROR("tail plugin: realloc failed."); + tail_match_destroy(tm); return (-1); } @@ -308,78 +274,68 @@ static int ctail_config_add_file (oconfig_item_t *ci) return (0); } /* int ctail_config_add_file */ -static int ctail_config (oconfig_item_t *ci) -{ - for (int i = 0; i < ci->children_num; i++) - { +static int ctail_config(oconfig_item_t *ci) { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; - if (strcasecmp ("File", option->key) == 0) - ctail_config_add_file (option); - else - { - WARNING ("tail plugin: Option `%s' not allowed here.", option->key); + if (strcasecmp("File", option->key) == 0) + ctail_config_add_file(option); + else { + WARNING("tail plugin: Option `%s' not allowed here.", option->key); } } /* for (i = 0; i < ci->children_num; i++) */ return (0); } /* int ctail_config */ -static int ctail_read (user_data_t *ud) -{ +static int ctail_read(user_data_t *ud) { int status; - status = tail_match_read ((cu_tail_match_t *)ud->data); - if (status != 0) - { - ERROR ("tail plugin: tail_match_read failed."); + status = tail_match_read((cu_tail_match_t *)ud->data); + if (status != 0) { + ERROR("tail plugin: tail_match_read failed."); return (-1); } return (0); } /* int ctail_read */ -static int ctail_init (void) -{ +static int ctail_init(void) { char str[255]; - if (tail_match_list_num == 0) - { - WARNING ("tail plugin: File list is empty. Returning an error."); + if (tail_match_list_num == 0) { + WARNING("tail plugin: File list is empty. Returning an error."); return (-1); } - for (size_t i = 0; i < tail_match_list_num; i++) - { + for (size_t i = 0; i < tail_match_list_num; i++) { ssnprintf(str, sizeof(str), "tail-%zu", i); - plugin_register_complex_read (NULL, str, ctail_read, tail_match_list_intervals[i], - &(user_data_t) { - .data = tail_match_list[i], - }); + plugin_register_complex_read(NULL, str, ctail_read, + tail_match_list_intervals[i], + &(user_data_t){ + .data = tail_match_list[i], + }); } return (0); } /* int ctail_init */ -static int ctail_shutdown (void) -{ - for (size_t i = 0; i < tail_match_list_num; i++) - { - tail_match_destroy (tail_match_list[i]); +static int ctail_shutdown(void) { + for (size_t i = 0; i < tail_match_list_num; i++) { + tail_match_destroy(tail_match_list[i]); tail_match_list[i] = NULL; } - sfree (tail_match_list); + sfree(tail_match_list); tail_match_list_num = 0; return (0); } /* int ctail_shutdown */ -void module_register (void) -{ - plugin_register_complex_config ("tail", ctail_config); - plugin_register_init ("tail", ctail_init); - plugin_register_shutdown ("tail", ctail_shutdown); +void module_register(void) { + plugin_register_complex_config("tail", ctail_config); + plugin_register_init("tail", ctail_init); + plugin_register_shutdown("tail", ctail_shutdown); } /* void module_register */ /* vim: set sw=2 sts=2 ts=8 : */ diff --git a/src/tail_csv.c b/src/tail_csv.c index 02473879..b1a3292d 100644 --- a/src/tail_csv.c +++ b/src/tail_csv.c @@ -23,539 +23,533 @@ #include "collectd.h" -#include "plugin.h" /* plugin_register_*, plugin_dispatch_values */ #include "common.h" /* auxiliary functions */ +#include "plugin.h" /* plugin_register_*, plugin_dispatch_values */ #include "utils_tail.h" -#include -#include #include #include #include +#include +#include struct metric_definition_s { - char *name; - char *type; - char *instance; - int data_source_type; - ssize_t value_from; - struct metric_definition_s *next; + char *name; + char *type; + char *instance; + int data_source_type; + ssize_t value_from; + struct metric_definition_s *next; }; typedef struct metric_definition_s metric_definition_t; struct instance_definition_s { - char *instance; - char *path; - cu_tail_t *tail; - metric_definition_t **metric_list; - size_t metric_list_len; - cdtime_t interval; - ssize_t time_from; - struct instance_definition_s *next; + char *instance; + char *path; + cu_tail_t *tail; + metric_definition_t **metric_list; + size_t metric_list_len; + cdtime_t interval; + ssize_t time_from; + struct instance_definition_s *next; }; typedef struct instance_definition_s instance_definition_t; /* Private */ static metric_definition_t *metric_head = NULL; -static int tcsv_submit (instance_definition_t *id, - metric_definition_t *md, - value_t v, cdtime_t t) -{ - /* Registration variables */ - value_list_t vl = VALUE_LIST_INIT; +static int tcsv_submit(instance_definition_t *id, metric_definition_t *md, + value_t v, cdtime_t t) { + /* Registration variables */ + value_list_t vl = VALUE_LIST_INIT; - /* Register */ - vl.values_len = 1; - vl.values = &v; + /* Register */ + vl.values_len = 1; + vl.values = &v; - sstrncpy(vl.plugin, "tail_csv", sizeof(vl.plugin)); - if (id->instance != NULL) - sstrncpy(vl.plugin_instance, id->instance, sizeof(vl.plugin_instance)); - sstrncpy(vl.type, md->type, sizeof(vl.type)); - if (md->instance != NULL) - sstrncpy(vl.type_instance, md->instance, sizeof(vl.type_instance)); + sstrncpy(vl.plugin, "tail_csv", sizeof(vl.plugin)); + if (id->instance != NULL) + sstrncpy(vl.plugin_instance, id->instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, md->type, sizeof(vl.type)); + if (md->instance != NULL) + sstrncpy(vl.type_instance, md->instance, sizeof(vl.type_instance)); - vl.time = t; - vl.interval = id->interval; + vl.time = t; + vl.interval = id->interval; - return (plugin_dispatch_values(&vl)); + return (plugin_dispatch_values(&vl)); } -static cdtime_t parse_time (char const *tbuf) -{ - double t; - char *endptr = NULL; +static cdtime_t parse_time(char const *tbuf) { + double t; + char *endptr = NULL; - errno = 0; - t = strtod (tbuf, &endptr); - if ((errno != 0) || (endptr == NULL) || (endptr[0] != 0)) - return (cdtime ()); + errno = 0; + t = strtod(tbuf, &endptr); + if ((errno != 0) || (endptr == NULL) || (endptr[0] != 0)) + return (cdtime()); - return (DOUBLE_TO_CDTIME_T (t)); + return (DOUBLE_TO_CDTIME_T(t)); } -static int tcsv_read_metric (instance_definition_t *id, - metric_definition_t *md, - char **fields, size_t fields_num) -{ - value_t v; - cdtime_t t = 0; - int status; +static int tcsv_read_metric(instance_definition_t *id, metric_definition_t *md, + char **fields, size_t fields_num) { + value_t v; + cdtime_t t = 0; + int status; - if (md->data_source_type == -1) - return (EINVAL); + if (md->data_source_type == -1) + return (EINVAL); - assert (md->value_from >= 0); - if (((size_t) md->value_from) >= fields_num) - return (EINVAL); + assert(md->value_from >= 0); + if (((size_t)md->value_from) >= fields_num) + return (EINVAL); - status = parse_value (fields[md->value_from], &v, md->data_source_type); - if (status != 0) - return (status); + status = parse_value(fields[md->value_from], &v, md->data_source_type); + if (status != 0) + return (status); - if (id->time_from >= 0) { - if (((size_t) id->time_from) >= fields_num) - return (EINVAL); - t = parse_time (fields[id->time_from]); - } + if (id->time_from >= 0) { + if (((size_t)id->time_from) >= fields_num) + return (EINVAL); + t = parse_time(fields[id->time_from]); + } - return (tcsv_submit (id, md, v, t)); + return (tcsv_submit(id, md, v, t)); } -static _Bool tcsv_check_index (ssize_t index, size_t fields_num, char const *name) -{ - if (index < 0) - return 1; - else if (((size_t) index) < fields_num) - return 1; - - ERROR ("tail_csv plugin: Metric \"%s\": Request for index %zd when " - "only %zu fields are available.", - name, index, fields_num); - return (0); +static _Bool tcsv_check_index(ssize_t index, size_t fields_num, + char const *name) { + if (index < 0) + return 1; + else if (((size_t)index) < fields_num) + return 1; + + ERROR("tail_csv plugin: Metric \"%s\": Request for index %zd when " + "only %zu fields are available.", + name, index, fields_num); + return (0); } -static int tcsv_read_buffer (instance_definition_t *id, - char *buffer, size_t buffer_size) -{ - char **metrics; - size_t metrics_num; - - char *ptr; - size_t i; - - /* Remove newlines at the end of line. */ - while (buffer_size > 0) { - if ((buffer[buffer_size - 1] == '\n') - || (buffer[buffer_size - 1] == '\r')) { - buffer[buffer_size - 1] = 0; - buffer_size--; - } else { - break; - } +static int tcsv_read_buffer(instance_definition_t *id, char *buffer, + size_t buffer_size) { + char **metrics; + size_t metrics_num; + + char *ptr; + size_t i; + + /* Remove newlines at the end of line. */ + while (buffer_size > 0) { + if ((buffer[buffer_size - 1] == '\n') || + (buffer[buffer_size - 1] == '\r')) { + buffer[buffer_size - 1] = 0; + buffer_size--; + } else { + break; } + } - /* Ignore empty lines. */ - if ((buffer_size == 0) || (buffer[0] == '#')) - return (0); - - /* Count the number of fields. */ - metrics_num = 1; - for (i = 0; i < buffer_size; i++) { - if (buffer[i] == ',') - metrics_num++; - } - - if (metrics_num == 1) { - ERROR("tail_csv plugin: last line of `%s' does not contain " - "enough values.", id->path); - return (-1); - } + /* Ignore empty lines. */ + if ((buffer_size == 0) || (buffer[0] == '#')) + return (0); - /* Create a list of all values */ - metrics = calloc (metrics_num, sizeof (*metrics)); - if (metrics == NULL) { - ERROR ("tail_csv plugin: calloc failed."); - return (ENOMEM); - } + /* Count the number of fields. */ + metrics_num = 1; + for (i = 0; i < buffer_size; i++) { + if (buffer[i] == ',') + metrics_num++; + } + + if (metrics_num == 1) { + ERROR("tail_csv plugin: last line of `%s' does not contain " + "enough values.", + id->path); + return (-1); + } + + /* Create a list of all values */ + metrics = calloc(metrics_num, sizeof(*metrics)); + if (metrics == NULL) { + ERROR("tail_csv plugin: calloc failed."); + return (ENOMEM); + } + + ptr = buffer; + metrics[0] = ptr; + i = 1; + for (ptr = buffer; *ptr != 0; ptr++) { + if (*ptr != ',') + continue; + + *ptr = 0; + metrics[i] = ptr + 1; + i++; + } + assert(i == metrics_num); + + /* Register values */ + for (i = 0; i < id->metric_list_len; ++i) { + metric_definition_t *md = id->metric_list[i]; + + if (!tcsv_check_index(md->value_from, metrics_num, md->name) || + !tcsv_check_index(id->time_from, metrics_num, md->name)) + continue; + + tcsv_read_metric(id, md, metrics, metrics_num); + } + + /* Free up resources */ + sfree(metrics); + return (0); +} - ptr = buffer; - metrics[0] = ptr; - i = 1; - for (ptr = buffer; *ptr != 0; ptr++) { - if (*ptr != ',') - continue; +static int tcsv_read(user_data_t *ud) { + instance_definition_t *id; + id = ud->data; - *ptr = 0; - metrics[i] = ptr + 1; - i++; + if (id->tail == NULL) { + id->tail = cu_tail_create(id->path); + if (id->tail == NULL) { + ERROR("tail_csv plugin: cu_tail_create (\"%s\") failed.", id->path); + return (-1); } - assert (i == metrics_num); + } - /* Register values */ - for (i = 0; i < id->metric_list_len; ++i){ - metric_definition_t *md = id->metric_list[i]; - - if (!tcsv_check_index (md->value_from, metrics_num, md->name) - || !tcsv_check_index (id->time_from, metrics_num, md->name)) - continue; + while (42) { + char buffer[1024]; + size_t buffer_len; + int status; - tcsv_read_metric (id, md, metrics, metrics_num); + status = cu_tail_readline(id->tail, buffer, (int)sizeof(buffer)); + if (status != 0) { + ERROR("tail_csv plugin: File \"%s\": cu_tail_readline failed " + "with status %i.", + id->path, status); + return (-1); } - /* Free up resources */ - sfree (metrics); - return (0); -} - -static int tcsv_read (user_data_t *ud) { - instance_definition_t *id; - id = ud->data; - - if (id->tail == NULL) - { - id->tail = cu_tail_create (id->path); - if (id->tail == NULL) - { - ERROR ("tail_csv plugin: cu_tail_create (\"%s\") failed.", - id->path); - return (-1); - } - } + buffer_len = strlen(buffer); + if (buffer_len == 0) + break; - while (42) - { - char buffer[1024]; - size_t buffer_len; - int status; - - status = cu_tail_readline (id->tail, buffer, (int) sizeof (buffer)); - if (status != 0) - { - ERROR ("tail_csv plugin: File \"%s\": cu_tail_readline failed " - "with status %i.", id->path, status); - return (-1); - } - - buffer_len = strlen (buffer); - if (buffer_len == 0) - break; - - tcsv_read_buffer (id, buffer, buffer_len); - } + tcsv_read_buffer(id, buffer, buffer_len); + } - return (0); + return (0); } -static void tcsv_metric_definition_destroy(void *arg){ - metric_definition_t *md; - metric_definition_t *next; +static void tcsv_metric_definition_destroy(void *arg) { + metric_definition_t *md; + metric_definition_t *next; - md = arg; - if (md == NULL) - return; + md = arg; + if (md == NULL) + return; - next = md->next; - md->next = NULL; + next = md->next; + md->next = NULL; - sfree(md->name); - sfree(md->type); - sfree(md->instance); - sfree(md); + sfree(md->name); + sfree(md->type); + sfree(md->instance); + sfree(md); - tcsv_metric_definition_destroy (next); + tcsv_metric_definition_destroy(next); } static int tcsv_config_get_index(oconfig_item_t *ci, ssize_t *ret_index) { - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)){ - WARNING("tail_csv plugin: The \"%s\" config option needs exactly one " - "integer argument.", ci->key); - return (-1); - } - - if (ci->values[0].value.number < 0) { - WARNING("tail_csv plugin: The \"%s\" config option must be positive " - "(or zero).", ci->key); - return (-1); - } - - *ret_index = (ssize_t) ci->values[0].value.number; - return (0); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) { + WARNING("tail_csv plugin: The \"%s\" config option needs exactly one " + "integer argument.", + ci->key); + return (-1); + } + + if (ci->values[0].value.number < 0) { + WARNING("tail_csv plugin: The \"%s\" config option must be positive " + "(or zero).", + ci->key); + return (-1); + } + + *ret_index = (ssize_t)ci->values[0].value.number; + return (0); } /* Parse metric */ -static int tcsv_config_add_metric(oconfig_item_t *ci){ - metric_definition_t *md; - int status; - - md = calloc(1, sizeof(*md)); - if (md == NULL) - return (-1); - md->name = NULL; - md->type = NULL; - md->instance = NULL; - md->data_source_type = -1; - md->value_from = -1; - md->next = NULL; - - status = cf_util_get_string (ci, &md->name); - if (status != 0) { - sfree (md); - return (-1); - } - - for (int i = 0; i < ci->children_num; ++i){ - oconfig_item_t *option = ci->children + i; - - if (strcasecmp("Type", option->key) == 0) - status = cf_util_get_string(option, &md->type); - else if (strcasecmp("Instance", option->key) == 0) - status = cf_util_get_string(option, &md->instance); - else if (strcasecmp("ValueFrom", option->key) == 0) - status = tcsv_config_get_index (option, &md->value_from); - else { - WARNING("tail_csv plugin: Option `%s' not allowed here.", option->key); - status = -1; - } - - if (status != 0) - break; - } - - if (status != 0){ - tcsv_metric_definition_destroy(md); - return (-1); - } - - /* Verify all necessary options have been set. */ - if (md->type == NULL) { - WARNING("tail_csv plugin: Option `Type' must be set."); - status = -1; - } else if (md->value_from < 0) { - WARNING("tail_csv plugin: Option `ValueFrom' must be set."); - status = -1; - } - if (status != 0) { - tcsv_metric_definition_destroy(md); - return (status); - } - - if (metric_head == NULL) - metric_head = md; +static int tcsv_config_add_metric(oconfig_item_t *ci) { + metric_definition_t *md; + int status; + + md = calloc(1, sizeof(*md)); + if (md == NULL) + return (-1); + md->name = NULL; + md->type = NULL; + md->instance = NULL; + md->data_source_type = -1; + md->value_from = -1; + md->next = NULL; + + status = cf_util_get_string(ci, &md->name); + if (status != 0) { + sfree(md); + return (-1); + } + + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *option = ci->children + i; + + if (strcasecmp("Type", option->key) == 0) + status = cf_util_get_string(option, &md->type); + else if (strcasecmp("Instance", option->key) == 0) + status = cf_util_get_string(option, &md->instance); + else if (strcasecmp("ValueFrom", option->key) == 0) + status = tcsv_config_get_index(option, &md->value_from); else { - metric_definition_t *last; - last = metric_head; - while (last->next != NULL) - last = last->next; - last->next = md; + WARNING("tail_csv plugin: Option `%s' not allowed here.", option->key); + status = -1; } - return (0); + if (status != 0) + break; + } + + if (status != 0) { + tcsv_metric_definition_destroy(md); + return (-1); + } + + /* Verify all necessary options have been set. */ + if (md->type == NULL) { + WARNING("tail_csv plugin: Option `Type' must be set."); + status = -1; + } else if (md->value_from < 0) { + WARNING("tail_csv plugin: Option `ValueFrom' must be set."); + status = -1; + } + if (status != 0) { + tcsv_metric_definition_destroy(md); + return (status); + } + + if (metric_head == NULL) + metric_head = md; + else { + metric_definition_t *last; + last = metric_head; + while (last->next != NULL) + last = last->next; + last->next = md; + } + + return (0); } -static void tcsv_instance_definition_destroy(void *arg){ - instance_definition_t *id; +static void tcsv_instance_definition_destroy(void *arg) { + instance_definition_t *id; - id = arg; - if (id == NULL) - return; + id = arg; + if (id == NULL) + return; - if (id->tail != NULL) - cu_tail_destroy (id->tail); - id->tail = NULL; + if (id->tail != NULL) + cu_tail_destroy(id->tail); + id->tail = NULL; - sfree(id->instance); - sfree(id->path); - sfree(id->metric_list); - sfree(id); + sfree(id->instance); + sfree(id->path); + sfree(id->metric_list); + sfree(id); } -static int tcsv_config_add_instance_collect(instance_definition_t *id, oconfig_item_t *ci) { - metric_definition_t *metric; - metric_definition_t **metric_list; - size_t metric_list_size; - - if (ci->values_num < 1) { - WARNING("tail_csv plugin: The `Collect' config option needs at least one argument."); - return (-1); +static int tcsv_config_add_instance_collect(instance_definition_t *id, + oconfig_item_t *ci) { + metric_definition_t *metric; + metric_definition_t **metric_list; + size_t metric_list_size; + + if (ci->values_num < 1) { + WARNING("tail_csv plugin: The `Collect' config option needs at least one " + "argument."); + return (-1); + } + + metric_list_size = id->metric_list_len + (size_t)ci->values_num; + metric_list = + realloc(id->metric_list, sizeof(*id->metric_list) * metric_list_size); + if (metric_list == NULL) + return (-1); + id->metric_list = metric_list; + + for (int i = 0; i < ci->values_num; i++) { + char *metric_name; + + if (ci->values[i].type != OCONFIG_TYPE_STRING) { + WARNING("tail_csv plugin: All arguments to `Collect' must be strings."); + continue; } + metric_name = ci->values[i].value.string; - metric_list_size = id->metric_list_len + (size_t) ci->values_num; - metric_list = realloc (id->metric_list, sizeof (*id->metric_list) * metric_list_size); - if (metric_list == NULL) - return (-1); - id->metric_list = metric_list; - - for (int i = 0; i < ci->values_num; i++) { - char *metric_name; - - if (ci->values[i].type != OCONFIG_TYPE_STRING) { - WARNING("tail_csv plugin: All arguments to `Collect' must be strings."); - continue; - } - metric_name = ci->values[i].value.string; - - for (metric = metric_head; metric != NULL; metric = metric->next) - if (strcasecmp(metric_name, metric->name) == 0) - break; - - if (metric == NULL) { - WARNING ("tail_csv plugin: `Collect' argument not found `%s'.", metric_name); - continue; - } + for (metric = metric_head; metric != NULL; metric = metric->next) + if (strcasecmp(metric_name, metric->name) == 0) + break; - id->metric_list[id->metric_list_len] = metric; - id->metric_list_len++; + if (metric == NULL) { + WARNING("tail_csv plugin: `Collect' argument not found `%s'.", + metric_name); + continue; } - return (0); + id->metric_list[id->metric_list_len] = metric; + id->metric_list_len++; + } + + return (0); } /* block */ -static int tcsv_config_add_file(oconfig_item_t *ci) -{ - instance_definition_t* id; - int status = 0; - - /* Registration variables */ - char cb_name[DATA_MAX_NAME_LEN]; - - id = calloc(1, sizeof(*id)); - if (id == NULL) - return (-1); - id->instance = NULL; - id->path = NULL; - id->metric_list = NULL; - id->time_from = -1; - id->next = NULL; - - status = cf_util_get_string (ci, &id->path); - if (status != 0) { - sfree (id); - return (status); - } - - /* Use default interval. */ - id->interval = plugin_get_interval(); - - for (int i = 0; i < ci->children_num; ++i){ - oconfig_item_t *option = ci->children + i; - status = 0; - - if (strcasecmp("Instance", option->key) == 0) - status = cf_util_get_string(option, &id->instance); - else if (strcasecmp("Collect", option->key) == 0) - status = tcsv_config_add_instance_collect(id, option); - else if (strcasecmp("Interval", option->key) == 0) - cf_util_get_cdtime(option, &id->interval); - else if (strcasecmp("TimeFrom", option->key) == 0) - status = tcsv_config_get_index (option, &id->time_from); - else { - WARNING("tail_csv plugin: Option `%s' not allowed here.", option->key); - status = -1; - } - - if (status != 0) - break; - } - - if (status != 0){ - tcsv_instance_definition_destroy(id); - return (-1); - } - - /* Verify all necessary options have been set. */ - if (id->path == NULL){ - WARNING("tail_csv plugin: Option `Path' must be set."); - status = -1; - } else if (id->metric_list == NULL){ - WARNING("tail_csv plugin: Option `Collect' must be set."); - status = -1; - } - - if (status != 0){ - tcsv_instance_definition_destroy(id); - return (-1); - } - - ssnprintf (cb_name, sizeof (cb_name), "tail_csv/%s", id->path); - - status = plugin_register_complex_read(NULL, cb_name, tcsv_read, id->interval, - &(user_data_t) { - .data = id, - .free_func = tcsv_instance_definition_destroy, - }); - if (status != 0){ - ERROR("tail_csv plugin: Registering complex read function failed."); - tcsv_instance_definition_destroy(id); - return (-1); +static int tcsv_config_add_file(oconfig_item_t *ci) { + instance_definition_t *id; + int status = 0; + + /* Registration variables */ + char cb_name[DATA_MAX_NAME_LEN]; + + id = calloc(1, sizeof(*id)); + if (id == NULL) + return (-1); + id->instance = NULL; + id->path = NULL; + id->metric_list = NULL; + id->time_from = -1; + id->next = NULL; + + status = cf_util_get_string(ci, &id->path); + if (status != 0) { + sfree(id); + return (status); + } + + /* Use default interval. */ + id->interval = plugin_get_interval(); + + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *option = ci->children + i; + status = 0; + + if (strcasecmp("Instance", option->key) == 0) + status = cf_util_get_string(option, &id->instance); + else if (strcasecmp("Collect", option->key) == 0) + status = tcsv_config_add_instance_collect(id, option); + else if (strcasecmp("Interval", option->key) == 0) + cf_util_get_cdtime(option, &id->interval); + else if (strcasecmp("TimeFrom", option->key) == 0) + status = tcsv_config_get_index(option, &id->time_from); + else { + WARNING("tail_csv plugin: Option `%s' not allowed here.", option->key); + status = -1; } - return (0); + if (status != 0) + break; + } + + if (status != 0) { + tcsv_instance_definition_destroy(id); + return (-1); + } + + /* Verify all necessary options have been set. */ + if (id->path == NULL) { + WARNING("tail_csv plugin: Option `Path' must be set."); + status = -1; + } else if (id->metric_list == NULL) { + WARNING("tail_csv plugin: Option `Collect' must be set."); + status = -1; + } + + if (status != 0) { + tcsv_instance_definition_destroy(id); + return (-1); + } + + ssnprintf(cb_name, sizeof(cb_name), "tail_csv/%s", id->path); + + status = plugin_register_complex_read( + NULL, cb_name, tcsv_read, id->interval, + &(user_data_t){ + .data = id, .free_func = tcsv_instance_definition_destroy, + }); + if (status != 0) { + ERROR("tail_csv plugin: Registering complex read function failed."); + tcsv_instance_definition_destroy(id); + return (-1); + } + + return (0); } /* Parse blocks */ -static int tcsv_config(oconfig_item_t *ci){ - for (int i = 0; i < ci->children_num; ++i){ - oconfig_item_t *child = ci->children + i; - if (strcasecmp("Metric", child->key) == 0) - tcsv_config_add_metric(child); - else if (strcasecmp("File", child->key) == 0) - tcsv_config_add_file(child); - else - WARNING("tail_csv plugin: Ignore unknown config option `%s'.", child->key); - } - - return (0); +static int tcsv_config(oconfig_item_t *ci) { + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *child = ci->children + i; + if (strcasecmp("Metric", child->key) == 0) + tcsv_config_add_metric(child); + else if (strcasecmp("File", child->key) == 0) + tcsv_config_add_file(child); + else + WARNING("tail_csv plugin: Ignore unknown config option `%s'.", + child->key); + } + + return (0); } /* int tcsv_config */ static int tcsv_init(void) { /* {{{ */ - static _Bool have_init = 0; - metric_definition_t *md; - - if (have_init) - return (0); - - for (md = metric_head; md != NULL; md = md->next) { - data_set_t const *ds; - - /* Retrieve the data source type from the types db. */ - ds = plugin_get_ds(md->type); - if (ds == NULL) - { - ERROR ("tail_csv plugin: Failed to look up type \"%s\" for " - "metric \"%s\". It may not be defined in the types.db " - "file. Please read the types.db(5) manual page for more " - "details.", - md->type, md->name); - continue; - } - else if (ds->ds_num != 1) - { - ERROR ("tail_csv plugin: The type \"%s\" has %zu data sources. " - "Only types with a single data source are supported.", - ds->type, ds->ds_num); - continue; - } - - md->data_source_type = ds->ds->type; - } + static _Bool have_init = 0; + metric_definition_t *md; + if (have_init) return (0); + + for (md = metric_head; md != NULL; md = md->next) { + data_set_t const *ds; + + /* Retrieve the data source type from the types db. */ + ds = plugin_get_ds(md->type); + if (ds == NULL) { + ERROR("tail_csv plugin: Failed to look up type \"%s\" for " + "metric \"%s\". It may not be defined in the types.db " + "file. Please read the types.db(5) manual page for more " + "details.", + md->type, md->name); + continue; + } else if (ds->ds_num != 1) { + ERROR("tail_csv plugin: The type \"%s\" has %zu data sources. " + "Only types with a single data source are supported.", + ds->type, ds->ds_num); + continue; + } + + md->data_source_type = ds->ds->type; + } + + return (0); } /* }}} int tcsv_init */ -static int tcsv_shutdown (void) { - tcsv_metric_definition_destroy (metric_head); - metric_head = NULL; +static int tcsv_shutdown(void) { + tcsv_metric_definition_destroy(metric_head); + metric_head = NULL; - return (0); + return (0); } -void module_register(void){ - plugin_register_complex_config("tail_csv", tcsv_config); - plugin_register_init("tail_csv", tcsv_init); - plugin_register_shutdown("tail_csv", tcsv_shutdown); +void module_register(void) { + plugin_register_complex_config("tail_csv", tcsv_config); + plugin_register_init("tail_csv", tcsv_init); + plugin_register_shutdown("tail_csv", tcsv_shutdown); } /* vim: set sw=4 sts=4 et : */ diff --git a/src/tape.c b/src/tape.c index c7d56c73..3f4bb55b 100644 --- a/src/tape.c +++ b/src/tape.c @@ -26,7 +26,7 @@ #include "plugin.h" #if !HAVE_LIBKSTAT -# error "No applicable input method." +#error "No applicable input method." #endif #define MAX_NUMTAPE 256 @@ -34,99 +34,88 @@ extern kstat_ctl_t *kc; static kstat_t *ksp[MAX_NUMTAPE]; static int numtape = 0; -static int tape_init (void) -{ - kstat_t *ksp_chain; +static int tape_init(void) { + kstat_t *ksp_chain; - numtape = 0; + numtape = 0; - if (kc == NULL) - return (-1); + if (kc == NULL) + return (-1); - for (numtape = 0, ksp_chain = kc->kc_chain; - (numtape < MAX_NUMTAPE) && (ksp_chain != NULL); - ksp_chain = ksp_chain->ks_next) - { - if (strncmp (ksp_chain->ks_class, "tape", 4) ) - continue; - if (ksp_chain->ks_type != KSTAT_TYPE_IO) - continue; - ksp[numtape++] = ksp_chain; - } + for (numtape = 0, ksp_chain = kc->kc_chain; + (numtape < MAX_NUMTAPE) && (ksp_chain != NULL); + ksp_chain = ksp_chain->ks_next) { + if (strncmp(ksp_chain->ks_class, "tape", 4)) + continue; + if (ksp_chain->ks_type != KSTAT_TYPE_IO) + continue; + ksp[numtape++] = ksp_chain; + } - return (0); + return (0); } /* int tape_init */ -static void tape_submit (const char *plugin_instance, - const char *type, - derive_t read, derive_t write) -{ - value_list_t vl = VALUE_LIST_INIT; - value_t values[] = { - { .derive = read }, - { .derive = write }, - }; - - vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - sstrncpy (vl.plugin, "tape", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, plugin_instance, - sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - - plugin_dispatch_values (&vl); +static void tape_submit(const char *plugin_instance, const char *type, + derive_t read, derive_t write) { + value_list_t vl = VALUE_LIST_INIT; + value_t values[] = { + {.derive = read}, {.derive = write}, + }; + + vl.values = values; + vl.values_len = STATIC_ARRAY_SIZE(values); + sstrncpy(vl.plugin, "tape", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + + plugin_dispatch_values(&vl); } /* void tape_submit */ -static int tape_read (void) -{ +static int tape_read(void) { #if HAVE_KSTAT_IO_T_WRITES && HAVE_KSTAT_IO_T_NWRITES && HAVE_KSTAT_IO_T_WTIME -# define KIO_ROCTETS reads -# define KIO_WOCTETS writes -# define KIO_ROPS nreads -# define KIO_WOPS nwrites -# define KIO_RTIME rtime -# define KIO_WTIME wtime -#elif HAVE_KSTAT_IO_T_NWRITTEN && HAVE_KSTAT_IO_T_WRITES && HAVE_KSTAT_IO_T_WTIME -# define KIO_ROCTETS nread -# define KIO_WOCTETS nwritten -# define KIO_ROPS reads -# define KIO_WOPS writes -# define KIO_RTIME rtime -# define KIO_WTIME wtime +#define KIO_ROCTETS reads +#define KIO_WOCTETS writes +#define KIO_ROPS nreads +#define KIO_WOPS nwrites +#define KIO_RTIME rtime +#define KIO_WTIME wtime +#elif HAVE_KSTAT_IO_T_NWRITTEN && HAVE_KSTAT_IO_T_WRITES && \ + HAVE_KSTAT_IO_T_WTIME +#define KIO_ROCTETS nread +#define KIO_WOCTETS nwritten +#define KIO_ROPS reads +#define KIO_WOPS writes +#define KIO_RTIME rtime +#define KIO_WTIME wtime #else -# error "kstat_io_t does not have the required members" +#error "kstat_io_t does not have the required members" #endif - static kstat_io_t kio; - - if (kc == NULL) - return (-1); - - if (numtape <= 0) - return (-1); - - for (int i = 0; i < numtape; i++) - { - if (kstat_read (kc, ksp[i], &kio) == -1) - continue; - - if (strncmp (ksp[i]->ks_class, "tape", 4) == 0) - { - tape_submit (ksp[i]->ks_name, "tape_octets", - kio.KIO_ROCTETS, kio.KIO_WOCTETS); - tape_submit (ksp[i]->ks_name, "tape_ops", - kio.KIO_ROPS, kio.KIO_WOPS); - /* FIXME: Convert this to microseconds if necessary */ - tape_submit (ksp[i]->ks_name, "tape_time", - kio.KIO_RTIME, kio.KIO_WTIME); - } - } - - return (0); + static kstat_io_t kio; + + if (kc == NULL) + return (-1); + + if (numtape <= 0) + return (-1); + + for (int i = 0; i < numtape; i++) { + if (kstat_read(kc, ksp[i], &kio) == -1) + continue; + + if (strncmp(ksp[i]->ks_class, "tape", 4) == 0) { + tape_submit(ksp[i]->ks_name, "tape_octets", kio.KIO_ROCTETS, + kio.KIO_WOCTETS); + tape_submit(ksp[i]->ks_name, "tape_ops", kio.KIO_ROPS, kio.KIO_WOPS); + /* FIXME: Convert this to microseconds if necessary */ + tape_submit(ksp[i]->ks_name, "tape_time", kio.KIO_RTIME, kio.KIO_WTIME); + } + } + + return (0); } -void module_register (void) -{ - plugin_register_init ("tape", tape_init); - plugin_register_read ("tape", tape_read); +void module_register(void) { + plugin_register_init("tape", tape_init); + plugin_register_read("tape", tape_read); } diff --git a/src/target_notification.c b/src/target_notification.c index 21c071ed..dc93b98b 100644 --- a/src/target_notification.c +++ b/src/target_notification.c @@ -31,80 +31,73 @@ #include "utils_cache.h" #include "utils_subst.h" -struct tn_data_s -{ +struct tn_data_s { int severity; char *message; }; typedef struct tn_data_s tn_data_t; -static int tn_config_add_severity (tn_data_t *data, /* {{{ */ - const oconfig_item_t *ci) -{ - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - ERROR ("Target `notification': The `%s' option requires exactly one string " - "argument.", ci->key); +static int tn_config_add_severity(tn_data_t *data, /* {{{ */ + const oconfig_item_t *ci) { + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + ERROR("Target `notification': The `%s' option requires exactly one string " + "argument.", + ci->key); return (-1); } - if ((strcasecmp ("FAILURE", ci->values[0].value.string) == 0) - || (strcasecmp ("CRITICAL", ci->values[0].value.string) == 0)) + if ((strcasecmp("FAILURE", ci->values[0].value.string) == 0) || + (strcasecmp("CRITICAL", ci->values[0].value.string) == 0)) data->severity = NOTIF_FAILURE; - else if ((strcasecmp ("WARNING", ci->values[0].value.string) == 0) - || (strcasecmp ("WARN", ci->values[0].value.string) == 0)) + else if ((strcasecmp("WARNING", ci->values[0].value.string) == 0) || + (strcasecmp("WARN", ci->values[0].value.string) == 0)) data->severity = NOTIF_WARNING; - else if (strcasecmp ("OKAY", ci->values[0].value.string) == 0) + else if (strcasecmp("OKAY", ci->values[0].value.string) == 0) data->severity = NOTIF_OKAY; - else - { - WARNING ("Target `notification': Unknown severity `%s'. " - "Will use `FAILURE' instead.", - ci->values[0].value.string); + else { + WARNING("Target `notification': Unknown severity `%s'. " + "Will use `FAILURE' instead.", + ci->values[0].value.string); data->severity = NOTIF_FAILURE; } return (0); } /* }}} int tn_config_add_severity */ -static int tn_config_add_string (char **dest, /* {{{ */ - const oconfig_item_t *ci) -{ +static int tn_config_add_string(char **dest, /* {{{ */ + const oconfig_item_t *ci) { char *temp; if (dest == NULL) return (-EINVAL); - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - ERROR ("Target `notification': The `%s' option requires exactly one string " - "argument.", ci->key); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + ERROR("Target `notification': The `%s' option requires exactly one string " + "argument.", + ci->key); return (-1); } - if (ci->values[0].value.string[0] == 0) - { - ERROR ("Target `notification': The `%s' option does not accept empty strings.", + if (ci->values[0].value.string[0] == 0) { + ERROR( + "Target `notification': The `%s' option does not accept empty strings.", ci->key); return (-1); } - temp = sstrdup (ci->values[0].value.string); - if (temp == NULL) - { - ERROR ("tn_config_add_string: sstrdup failed."); + temp = sstrdup(ci->values[0].value.string); + if (temp == NULL) { + ERROR("tn_config_add_string: sstrdup failed."); return (-1); } - free (*dest); + free(*dest); *dest = temp; return (0); } /* }}} int tn_config_add_string */ -static int tn_destroy (void **user_data) /* {{{ */ +static int tn_destroy(void **user_data) /* {{{ */ { tn_data_t *data; @@ -115,21 +108,20 @@ static int tn_destroy (void **user_data) /* {{{ */ if (data == NULL) return (0); - sfree (data->message); - sfree (data); + sfree(data->message); + sfree(data); return (0); } /* }}} int tn_destroy */ -static int tn_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ +static int tn_create(const oconfig_item_t *ci, void **user_data) /* {{{ */ { tn_data_t *data; int status; - data = calloc (1, sizeof (*data)); - if (data == NULL) - { - ERROR ("tn_create: calloc failed."); + data = calloc(1, sizeof(*data)); + if (data == NULL) { + ERROR("tn_create: calloc failed."); return (-ENOMEM); } @@ -137,18 +129,18 @@ static int tn_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ data->severity = 0; status = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Message", child->key) == 0) - status = tn_config_add_string (&data->message, child); - else if (strcasecmp ("Severity", child->key) == 0) - status = tn_config_add_severity (data, child); - else - { - ERROR ("Target `notification': The `%s' configuration option is not understood " - "and will be ignored.", child->key); + if (strcasecmp("Message", child->key) == 0) + status = tn_config_add_string(&data->message, child); + else if (strcasecmp("Severity", child->key) == 0) + status = tn_config_add_severity(data, child); + else { + ERROR("Target `notification': The `%s' configuration option is not " + "understood " + "and will be ignored.", + child->key); status = 0; } @@ -157,30 +149,25 @@ static int tn_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ } /* Additional sanity-checking */ - while (status == 0) - { - if ((data->severity != NOTIF_FAILURE) - && (data->severity != NOTIF_WARNING) - && (data->severity != NOTIF_OKAY)) - { - DEBUG ("Target `notification': Setting " - "the default severity `WARNING'."); + while (status == 0) { + if ((data->severity != NOTIF_FAILURE) && + (data->severity != NOTIF_WARNING) && (data->severity != NOTIF_OKAY)) { + DEBUG("Target `notification': Setting " + "the default severity `WARNING'."); data->severity = NOTIF_WARNING; } - if (data->message == NULL) - { - ERROR ("Target `notification': No `Message' option has been specified. " - "Without it, the `Notification' target is useless."); + if (data->message == NULL) { + ERROR("Target `notification': No `Message' option has been specified. " + "Without it, the `Notification' target is useless."); status = -1; } break; } - if (status != 0) - { - tn_destroy ((void *) &data); + if (status != 0) { + tn_destroy((void *)&data); return (status); } @@ -188,11 +175,11 @@ static int tn_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ return (0); } /* }}} int tn_create */ -static int tn_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */ - notification_meta_t __attribute__((unused)) **meta, void **user_data) -{ +static int tn_invoke(const data_set_t *ds, value_list_t *vl, /* {{{ */ + notification_meta_t __attribute__((unused)) * *meta, + void **user_data) { tn_data_t *data; - notification_t n = { 0 }; + notification_t n = {0}; char temp[NOTIF_MAX_MSG_LEN]; gauge_t *rates; @@ -202,49 +189,43 @@ static int tn_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */ return (-EINVAL); data = *user_data; - if (data == NULL) - { - ERROR ("Target `notification': Invoke: `data' is NULL."); + if (data == NULL) { + ERROR("Target `notification': Invoke: `data' is NULL."); return (-EINVAL); } /* Initialize the structure. */ n.severity = data->severity; - n.time = cdtime (); - sstrncpy (n.message, data->message, sizeof (n.message)); - sstrncpy (n.host, vl->host, sizeof (n.host)); - sstrncpy (n.plugin, vl->plugin, sizeof (n.plugin)); - sstrncpy (n.plugin_instance, vl->plugin_instance, - sizeof (n.plugin_instance)); - sstrncpy (n.type, vl->type, sizeof (n.type)); - sstrncpy (n.type_instance, vl->type_instance, - sizeof (n.type_instance)); + n.time = cdtime(); + sstrncpy(n.message, data->message, sizeof(n.message)); + sstrncpy(n.host, vl->host, sizeof(n.host)); + sstrncpy(n.plugin, vl->plugin, sizeof(n.plugin)); + sstrncpy(n.plugin_instance, vl->plugin_instance, sizeof(n.plugin_instance)); + sstrncpy(n.type, vl->type, sizeof(n.type)); + sstrncpy(n.type_instance, vl->type_instance, sizeof(n.type_instance)); n.meta = NULL; -#define REPLACE_FIELD(t,v) \ - if (subst_string (temp, sizeof (temp), n.message, t, v) != NULL) \ - sstrncpy (n.message, temp, sizeof (n.message)); - REPLACE_FIELD ("%{host}", n.host); - REPLACE_FIELD ("%{plugin}", n.plugin); - REPLACE_FIELD ("%{plugin_instance}", n.plugin_instance); - REPLACE_FIELD ("%{type}", n.type); - REPLACE_FIELD ("%{type_instance}", n.type_instance); +#define REPLACE_FIELD(t, v) \ + if (subst_string(temp, sizeof(temp), n.message, t, v) != NULL) \ + sstrncpy(n.message, temp, sizeof(n.message)); + REPLACE_FIELD("%{host}", n.host); + REPLACE_FIELD("%{plugin}", n.plugin); + REPLACE_FIELD("%{plugin_instance}", n.plugin_instance); + REPLACE_FIELD("%{type}", n.type); + REPLACE_FIELD("%{type_instance}", n.type_instance); rates_failed = 0; rates = NULL; - for (size_t i = 0; i < ds->ds_num; i++) - { + for (size_t i = 0; i < ds->ds_num; i++) { char template[DATA_MAX_NAME_LEN]; char value_str[DATA_MAX_NAME_LEN]; - ssnprintf (template, sizeof (template), "%%{ds:%s}", ds->ds[i].name); + ssnprintf(template, sizeof(template), "%%{ds:%s}", ds->ds[i].name); - if (ds->ds[i].type != DS_TYPE_GAUGE) - { - if ((rates == NULL) && (rates_failed == 0)) - { - rates = uc_get_rate (ds, vl); + if (ds->ds[i].type != DS_TYPE_GAUGE) { + if ((rates == NULL) && (rates_failed == 0)) { + rates = uc_get_rate(ds, vl); if (rates == NULL) rates_failed = 1; } @@ -252,35 +233,32 @@ static int tn_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */ /* If this is a gauge value, use the current value. */ if (ds->ds[i].type == DS_TYPE_GAUGE) - ssnprintf (value_str, sizeof (value_str), - GAUGE_FORMAT, (double) vl->values[i].gauge); + ssnprintf(value_str, sizeof(value_str), GAUGE_FORMAT, + (double)vl->values[i].gauge); /* If it's a counter, try to use the current rate. This may fail, if the * value has been renamed. */ else if (rates != NULL) - ssnprintf (value_str, sizeof (value_str), - GAUGE_FORMAT, (double) rates[i]); + ssnprintf(value_str, sizeof(value_str), GAUGE_FORMAT, (double)rates[i]); /* Since we don't know any better, use the string `unknown'. */ else - sstrncpy (value_str, "unknown", sizeof (value_str)); + sstrncpy(value_str, "unknown", sizeof(value_str)); - REPLACE_FIELD (template, value_str); + REPLACE_FIELD(template, value_str); } - sfree (rates); + sfree(rates); - plugin_dispatch_notification (&n); + plugin_dispatch_notification(&n); return (FC_TARGET_CONTINUE); } /* }}} int tn_invoke */ -void module_register (void) -{ - target_proc_t tproc = { 0 }; +void module_register(void) { + target_proc_t tproc = {0}; - tproc.create = tn_create; - tproc.destroy = tn_destroy; - tproc.invoke = tn_invoke; - fc_register_target ("notification", tproc); + tproc.create = tn_create; + tproc.destroy = tn_destroy; + tproc.invoke = tn_invoke; + fc_register_target("notification", tproc); } /* module_register */ /* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ - diff --git a/src/target_replace.c b/src/target_replace.c index dba3a8cf..b43a025b 100644 --- a/src/target_replace.c +++ b/src/target_replace.c @@ -34,8 +34,7 @@ struct tr_action_s; typedef struct tr_action_s tr_action_t; -struct tr_action_s -{ +struct tr_action_s { regex_t re; char *replacement; _Bool may_be_empty; @@ -45,8 +44,7 @@ struct tr_action_s struct tr_meta_data_action_s; typedef struct tr_meta_data_action_s tr_meta_data_action_t; -struct tr_meta_data_action_s -{ +struct tr_meta_data_action_s { char *key; regex_t re; char *replacement; @@ -54,8 +52,7 @@ struct tr_meta_data_action_s tr_meta_data_action_t *next; }; -struct tr_data_s -{ +struct tr_data_s { tr_action_t *host; tr_action_t *plugin; tr_action_t *plugin_instance; @@ -65,7 +62,7 @@ struct tr_data_s }; typedef struct tr_data_s tr_data_t; -static char *tr_strdup (const char *orig) /* {{{ */ +static char *tr_strdup(const char *orig) /* {{{ */ { size_t sz; char *dest; @@ -73,100 +70,94 @@ static char *tr_strdup (const char *orig) /* {{{ */ if (orig == NULL) return (NULL); - sz = strlen (orig) + 1; - dest = malloc (sz); + sz = strlen(orig) + 1; + dest = malloc(sz); if (dest == NULL) return (NULL); - memcpy (dest, orig, sz); + memcpy(dest, orig, sz); return (dest); } /* }}} char *tr_strdup */ -static void tr_action_destroy (tr_action_t *act) /* {{{ */ +static void tr_action_destroy(tr_action_t *act) /* {{{ */ { if (act == NULL) return; - regfree (&act->re); - sfree (act->replacement); + regfree(&act->re); + sfree(act->replacement); if (act->next != NULL) - tr_action_destroy (act->next); + tr_action_destroy(act->next); - sfree (act); + sfree(act); } /* }}} void tr_action_destroy */ -static void tr_meta_data_action_destroy (tr_meta_data_action_t *act) /* {{{ */ +static void tr_meta_data_action_destroy(tr_meta_data_action_t *act) /* {{{ */ { if (act == NULL) return; - sfree (act->key); - regfree (&act->re); - sfree (act->replacement); + sfree(act->key); + regfree(&act->re); + sfree(act->replacement); if (act->next != NULL) - tr_meta_data_action_destroy (act->next); + tr_meta_data_action_destroy(act->next); - sfree (act); + sfree(act); } /* }}} void tr_meta_data_action_destroy */ -static int tr_config_add_action (tr_action_t **dest, /* {{{ */ - const oconfig_item_t *ci, _Bool may_be_empty) -{ +static int tr_config_add_action(tr_action_t **dest, /* {{{ */ + const oconfig_item_t *ci, _Bool may_be_empty) { tr_action_t *act; int status; if (dest == NULL) return (-EINVAL); - if ((ci->values_num != 2) - || (ci->values[0].type != OCONFIG_TYPE_STRING) - || (ci->values[1].type != OCONFIG_TYPE_STRING)) - { - ERROR ("Target `replace': The `%s' option requires exactly two string " - "arguments.", ci->key); + if ((ci->values_num != 2) || (ci->values[0].type != OCONFIG_TYPE_STRING) || + (ci->values[1].type != OCONFIG_TYPE_STRING)) { + ERROR("Target `replace': The `%s' option requires exactly two string " + "arguments.", + ci->key); return (-1); } - act = calloc (1, sizeof (*act)); - if (act == NULL) - { - ERROR ("tr_config_add_action: calloc failed."); + act = calloc(1, sizeof(*act)); + if (act == NULL) { + ERROR("tr_config_add_action: calloc failed."); return (-ENOMEM); } act->replacement = NULL; act->may_be_empty = may_be_empty; - status = regcomp (&act->re, ci->values[0].value.string, REG_EXTENDED); - if (status != 0) - { + status = regcomp(&act->re, ci->values[0].value.string, REG_EXTENDED); + if (status != 0) { char errbuf[1024] = ""; /* regerror assures null termination. */ - regerror (status, &act->re, errbuf, sizeof (errbuf)); - ERROR ("Target `replace': Compiling the regular expression `%s' " - "failed: %s.", - ci->values[0].value.string, errbuf); - sfree (act); + regerror(status, &act->re, errbuf, sizeof(errbuf)); + ERROR("Target `replace': Compiling the regular expression `%s' " + "failed: %s.", + ci->values[0].value.string, errbuf); + sfree(act); return (-EINVAL); } - act->replacement = tr_strdup (ci->values[1].value.string); - if (act->replacement == NULL) - { - ERROR ("tr_config_add_action: tr_strdup failed."); - tr_action_destroy (act); + act->replacement = tr_strdup(ci->values[1].value.string); + if (act->replacement == NULL) { + ERROR("tr_config_add_action: tr_strdup failed."); + tr_action_destroy(act); return (-ENOMEM); } /* Insert action at end of list. */ if (*dest == NULL) *dest = act; - else - { + else { tr_action_t *prev; prev = *dest; @@ -179,85 +170,76 @@ static int tr_config_add_action (tr_action_t **dest, /* {{{ */ return (0); } /* }}} int tr_config_add_action */ -static int tr_config_add_meta_action (tr_meta_data_action_t **dest, /* {{{ */ - const oconfig_item_t *ci, _Bool should_delete) -{ +static int tr_config_add_meta_action(tr_meta_data_action_t **dest, /* {{{ */ + const oconfig_item_t *ci, + _Bool should_delete) { tr_meta_data_action_t *act; int status; if (dest == NULL) return (-EINVAL); - if (should_delete) - { - if ((ci->values_num != 2) - || (ci->values[0].type != OCONFIG_TYPE_STRING) - || (ci->values[1].type != OCONFIG_TYPE_STRING)) - { - ERROR ("Target `replace': The `%s' option requires exactly two string " - "arguments.", ci->key); + if (should_delete) { + if ((ci->values_num != 2) || (ci->values[0].type != OCONFIG_TYPE_STRING) || + (ci->values[1].type != OCONFIG_TYPE_STRING)) { + ERROR("Target `replace': The `%s' option requires exactly two string " + "arguments.", + ci->key); return (-1); } - } - else - { - if ((ci->values_num != 3) - || (ci->values[0].type != OCONFIG_TYPE_STRING) - || (ci->values[1].type != OCONFIG_TYPE_STRING) - || (ci->values[2].type != OCONFIG_TYPE_STRING)) - { - ERROR ("Target `replace': The `%s' option requires exactly three string " - "arguments.", ci->key); + } else { + if ((ci->values_num != 3) || (ci->values[0].type != OCONFIG_TYPE_STRING) || + (ci->values[1].type != OCONFIG_TYPE_STRING) || + (ci->values[2].type != OCONFIG_TYPE_STRING)) { + ERROR("Target `replace': The `%s' option requires exactly three string " + "arguments.", + ci->key); return (-1); } } - if (strlen (ci->values[0].value.string) == 0) - { - ERROR ("Target `replace': The `%s' option does not accept empty string as " - "first argument.", ci->key); + if (strlen(ci->values[0].value.string) == 0) { + ERROR("Target `replace': The `%s' option does not accept empty string as " + "first argument.", + ci->key); return (-1); } - act = calloc (1, sizeof (*act)); - if (act == NULL) - { - ERROR ("tr_config_add_meta_action: calloc failed."); + act = calloc(1, sizeof(*act)); + if (act == NULL) { + ERROR("tr_config_add_meta_action: calloc failed."); return (-ENOMEM); } act->key = NULL; act->replacement = NULL; - status = regcomp (&act->re, ci->values[1].value.string, REG_EXTENDED); - if (status != 0) - { + status = regcomp(&act->re, ci->values[1].value.string, REG_EXTENDED); + if (status != 0) { char errbuf[1024] = ""; /* regerror assures null termination. */ - regerror (status, &act->re, errbuf, sizeof (errbuf)); - ERROR ("Target `replace': Compiling the regular expression `%s' " - "failed: %s.", - ci->values[1].value.string, errbuf); - sfree (act->key); - sfree (act); + regerror(status, &act->re, errbuf, sizeof(errbuf)); + ERROR("Target `replace': Compiling the regular expression `%s' " + "failed: %s.", + ci->values[1].value.string, errbuf); + sfree(act->key); + sfree(act); return (-EINVAL); } - act->key = tr_strdup (ci->values[0].value.string); - if (act->key == NULL) - { - ERROR ("tr_config_add_meta_action: tr_strdup failed."); - tr_meta_data_action_destroy (act); + act->key = tr_strdup(ci->values[0].value.string); + if (act->key == NULL) { + ERROR("tr_config_add_meta_action: tr_strdup failed."); + tr_meta_data_action_destroy(act); return (-ENOMEM); } if (!should_delete) { - act->replacement = tr_strdup (ci->values[2].value.string); - if (act->replacement == NULL) - { - ERROR ("tr_config_add_meta_action: tr_strdup failed."); - tr_meta_data_action_destroy (act); + act->replacement = tr_strdup(ci->values[2].value.string); + if (act->replacement == NULL) { + ERROR("tr_config_add_meta_action: tr_strdup failed."); + tr_meta_data_action_destroy(act); return (-ENOMEM); } } @@ -265,8 +247,7 @@ static int tr_config_add_meta_action (tr_meta_data_action_t **dest, /* {{{ */ /* Insert action at end of list. */ if (*dest == NULL) *dest = act; - else - { + else { tr_meta_data_action_t *prev; prev = *dest; @@ -279,82 +260,76 @@ static int tr_config_add_meta_action (tr_meta_data_action_t **dest, /* {{{ */ return (0); } /* }}} int tr_config_add_meta_action */ -static int tr_action_invoke (tr_action_t *act_head, /* {{{ */ - char *buffer_in, size_t buffer_in_size, _Bool may_be_empty) -{ +static int tr_action_invoke(tr_action_t *act_head, /* {{{ */ + char *buffer_in, size_t buffer_in_size, + _Bool may_be_empty) { int status; char buffer[DATA_MAX_NAME_LEN]; - regmatch_t matches[8] = { [0] = { 0 } }; + regmatch_t matches[8] = {[0] = {0}}; if (act_head == NULL) return (-EINVAL); - sstrncpy (buffer, buffer_in, sizeof (buffer)); + sstrncpy(buffer, buffer_in, sizeof(buffer)); - DEBUG ("target_replace plugin: tr_action_invoke: <- buffer = %s;", buffer); + DEBUG("target_replace plugin: tr_action_invoke: <- buffer = %s;", buffer); - for (tr_action_t *act = act_head; act != NULL; act = act->next) - { + for (tr_action_t *act = act_head; act != NULL; act = act->next) { char temp[DATA_MAX_NAME_LEN]; char *subst_status; - status = regexec (&act->re, buffer, - STATIC_ARRAY_SIZE (matches), matches, - /* flags = */ 0); + status = regexec(&act->re, buffer, STATIC_ARRAY_SIZE(matches), matches, + /* flags = */ 0); if (status == REG_NOMATCH) continue; - else if (status != 0) - { + else if (status != 0) { char errbuf[1024] = ""; - regerror (status, &act->re, errbuf, sizeof (errbuf)); - ERROR ("Target `replace': Executing a regular expression failed: %s.", - errbuf); + regerror(status, &act->re, errbuf, sizeof(errbuf)); + ERROR("Target `replace': Executing a regular expression failed: %s.", + errbuf); continue; } - subst_status = subst (temp, sizeof (temp), buffer, - (size_t) matches[0].rm_so, (size_t) matches[0].rm_eo, act->replacement); - if (subst_status == NULL) - { - ERROR ("Target `replace': subst (buffer = %s, start = %zu, end = %zu, " - "replacement = %s) failed.", - buffer, (size_t) matches[0].rm_so, (size_t) matches[0].rm_eo, - act->replacement); + subst_status = subst(temp, sizeof(temp), buffer, (size_t)matches[0].rm_so, + (size_t)matches[0].rm_eo, act->replacement); + if (subst_status == NULL) { + ERROR("Target `replace': subst (buffer = %s, start = %zu, end = %zu, " + "replacement = %s) failed.", + buffer, (size_t)matches[0].rm_so, (size_t)matches[0].rm_eo, + act->replacement); continue; } - sstrncpy (buffer, temp, sizeof (buffer)); + sstrncpy(buffer, temp, sizeof(buffer)); - DEBUG ("target_replace plugin: tr_action_invoke: -- buffer = %s;", buffer); + DEBUG("target_replace plugin: tr_action_invoke: -- buffer = %s;", buffer); } /* for (act = act_head; act != NULL; act = act->next) */ - if ((may_be_empty == 0) && (buffer[0] == 0)) - { - WARNING ("Target `replace': Replacement resulted in an empty string, " - "which is not allowed for this buffer (`host' or `plugin')."); + if ((may_be_empty == 0) && (buffer[0] == 0)) { + WARNING("Target `replace': Replacement resulted in an empty string, " + "which is not allowed for this buffer (`host' or `plugin')."); return (0); } - DEBUG ("target_replace plugin: tr_action_invoke: -> buffer = %s;", buffer); - sstrncpy (buffer_in, buffer, buffer_in_size); + DEBUG("target_replace plugin: tr_action_invoke: -> buffer = %s;", buffer); + sstrncpy(buffer_in, buffer, buffer_in_size); return (0); } /* }}} int tr_action_invoke */ -static int tr_meta_data_action_invoke ( /* {{{ */ - tr_meta_data_action_t *act_head, meta_data_t **dest) -{ +static int tr_meta_data_action_invoke(/* {{{ */ + tr_meta_data_action_t *act_head, + meta_data_t **dest) { int status; - regmatch_t matches[8] = { [0] = { 0 } }; + regmatch_t matches[8] = {[0] = {0}}; if (act_head == NULL) return (-EINVAL); - if ((*dest) == NULL) /* nothing to do */ + if ((*dest) == NULL) /* nothing to do */ return (0); - for (tr_meta_data_action_t *act = act_head; act != NULL; act = act->next) - { + for (tr_meta_data_action_t *act = act_head; act != NULL; act = act->next) { char temp[DATA_MAX_NAME_LEN]; char *subst_status; int value_type; @@ -362,99 +337,91 @@ static int tr_meta_data_action_invoke ( /* {{{ */ char *value; meta_data_t *result; - value_type = meta_data_type (*dest, act->key); - if (value_type == 0) /* not found */ + value_type = meta_data_type(*dest, act->key); + if (value_type == 0) /* not found */ continue; - if (value_type != MD_TYPE_STRING) - { - WARNING ("Target `replace': Attempting replace on metadata key `%s', " - "which isn't a string.", - act->key); + if (value_type != MD_TYPE_STRING) { + WARNING("Target `replace': Attempting replace on metadata key `%s', " + "which isn't a string.", + act->key); continue; } - meta_data_status = meta_data_get_string (*dest, act->key, &value); - if (meta_data_status != 0) - { - ERROR ("Target `replace': Unable to retrieve metadata value for `%s'.", - act->key); + meta_data_status = meta_data_get_string(*dest, act->key, &value); + if (meta_data_status != 0) { + ERROR("Target `replace': Unable to retrieve metadata value for `%s'.", + act->key); return (meta_data_status); } - DEBUG ("target_replace plugin: tr_meta_data_action_invoke: `%s' " - "old value = `%s'", act->key, value); + DEBUG("target_replace plugin: tr_meta_data_action_invoke: `%s' " + "old value = `%s'", + act->key, value); - status = regexec (&act->re, value, - STATIC_ARRAY_SIZE (matches), matches, - /* flags = */ 0); - if (status == REG_NOMATCH) - { - sfree (value); + status = regexec(&act->re, value, STATIC_ARRAY_SIZE(matches), matches, + /* flags = */ 0); + if (status == REG_NOMATCH) { + sfree(value); continue; - } - else if (status != 0) - { + } else if (status != 0) { char errbuf[1024] = ""; - regerror (status, &act->re, errbuf, sizeof (errbuf)); - ERROR ("Target `replace': Executing a regular expression failed: %s.", - errbuf); - sfree (value); + regerror(status, &act->re, errbuf, sizeof(errbuf)); + ERROR("Target `replace': Executing a regular expression failed: %s.", + errbuf); + sfree(value); continue; } - if (act->replacement == NULL) - { + if (act->replacement == NULL) { /* no replacement; delete the key */ - DEBUG ("target_replace plugin: tr_meta_data_action_invoke: " - "deleting `%s'", act->key); - meta_data_delete (*dest, act->key); - sfree (value); + DEBUG("target_replace plugin: tr_meta_data_action_invoke: " + "deleting `%s'", + act->key); + meta_data_delete(*dest, act->key); + sfree(value); continue; } - subst_status = subst (temp, sizeof (temp), value, - (size_t) matches[0].rm_so, (size_t) matches[0].rm_eo, act->replacement); - if (subst_status == NULL) - { - ERROR ("Target `replace': subst (value = %s, start = %zu, end = %zu, " - "replacement = %s) failed.", - value, (size_t) matches[0].rm_so, (size_t) matches[0].rm_eo, - act->replacement); - sfree (value); + subst_status = subst(temp, sizeof(temp), value, (size_t)matches[0].rm_so, + (size_t)matches[0].rm_eo, act->replacement); + if (subst_status == NULL) { + ERROR("Target `replace': subst (value = %s, start = %zu, end = %zu, " + "replacement = %s) failed.", + value, (size_t)matches[0].rm_so, (size_t)matches[0].rm_eo, + act->replacement); + sfree(value); continue; } - DEBUG ("target_replace plugin: tr_meta_data_action_invoke: `%s' " - "value `%s' -> `%s'", act->key, value, temp); + DEBUG("target_replace plugin: tr_meta_data_action_invoke: `%s' " + "value `%s' -> `%s'", + act->key, value, temp); - if ((result = meta_data_create()) == NULL) - { - ERROR ("Target `replace': failed to create metadata for `%s'.", - act->key); - sfree (value); + if ((result = meta_data_create()) == NULL) { + ERROR("Target `replace': failed to create metadata for `%s'.", act->key); + sfree(value); return (-ENOMEM); } - meta_data_status = meta_data_add_string (result, act->key, temp); - if (meta_data_status != 0) - { - ERROR ("Target `replace': Unable to set metadata value for `%s'.", - act->key); - meta_data_destroy (result); - sfree (value); + meta_data_status = meta_data_add_string(result, act->key, temp); + if (meta_data_status != 0) { + ERROR("Target `replace': Unable to set metadata value for `%s'.", + act->key); + meta_data_destroy(result); + sfree(value); return (meta_data_status); } - meta_data_clone_merge (dest, result); - meta_data_destroy (result); - sfree (value); + meta_data_clone_merge(dest, result); + meta_data_destroy(result); + sfree(value); } /* for (act = act_head; act != NULL; act = act->next) */ return (0); } /* }}} int tr_meta_data_action_invoke */ -static int tr_destroy (void **user_data) /* {{{ */ +static int tr_destroy(void **user_data) /* {{{ */ { tr_data_t *data; @@ -465,26 +432,25 @@ static int tr_destroy (void **user_data) /* {{{ */ if (data == NULL) return (0); - tr_action_destroy (data->host); - tr_action_destroy (data->plugin); - tr_action_destroy (data->plugin_instance); + tr_action_destroy(data->host); + tr_action_destroy(data->plugin); + tr_action_destroy(data->plugin_instance); /* tr_action_destroy (data->type); */ - tr_action_destroy (data->type_instance); - tr_meta_data_action_destroy (data->meta); - sfree (data); + tr_action_destroy(data->type_instance); + tr_meta_data_action_destroy(data->meta); + sfree(data); return (0); } /* }}} int tr_destroy */ -static int tr_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ +static int tr_create(const oconfig_item_t *ci, void **user_data) /* {{{ */ { tr_data_t *data; int status; - data = calloc (1, sizeof (*data)); - if (data == NULL) - { - ERROR ("tr_create: calloc failed."); + data = calloc(1, sizeof(*data)); + if (data == NULL) { + ERROR("tr_create: calloc failed."); return (-ENOMEM); } @@ -496,38 +462,37 @@ static int tr_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ data->meta = NULL; status = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if ((strcasecmp ("Host", child->key) == 0) - || (strcasecmp ("Hostname", child->key) == 0)) - status = tr_config_add_action (&data->host, child, - /* may be empty = */ 0); - else if (strcasecmp ("Plugin", child->key) == 0) - status = tr_config_add_action (&data->plugin, child, - /* may be empty = */ 0); - else if (strcasecmp ("PluginInstance", child->key) == 0) - status = tr_config_add_action (&data->plugin_instance, child, - /* may be empty = */ 1); + if ((strcasecmp("Host", child->key) == 0) || + (strcasecmp("Hostname", child->key) == 0)) + status = tr_config_add_action(&data->host, child, + /* may be empty = */ 0); + else if (strcasecmp("Plugin", child->key) == 0) + status = tr_config_add_action(&data->plugin, child, + /* may be empty = */ 0); + else if (strcasecmp("PluginInstance", child->key) == 0) + status = tr_config_add_action(&data->plugin_instance, child, + /* may be empty = */ 1); #if 0 else if (strcasecmp ("Type", child->key) == 0) status = tr_config_add_action (&data->type, child, /* may be empty = */ 0); #endif - else if (strcasecmp ("TypeInstance", child->key) == 0) - status = tr_config_add_action (&data->type_instance, child, - /* may be empty = */ 1); - else if (strcasecmp ("MetaData", child->key) == 0) - status = tr_config_add_meta_action (&data->meta, child, - /* should delete = */ 0); - else if (strcasecmp ("DeleteMetaData", child->key) == 0) - status = tr_config_add_meta_action (&data->meta, child, - /* should delete = */ 1); - else - { - ERROR ("Target `replace': The `%s' configuration option is not understood " - "and will be ignored.", child->key); + else if (strcasecmp("TypeInstance", child->key) == 0) + status = tr_config_add_action(&data->type_instance, child, + /* may be empty = */ 1); + else if (strcasecmp("MetaData", child->key) == 0) + status = tr_config_add_meta_action(&data->meta, child, + /* should delete = */ 0); + else if (strcasecmp("DeleteMetaData", child->key) == 0) + status = tr_config_add_meta_action(&data->meta, child, + /* should delete = */ 1); + else { + ERROR("Target `replace': The `%s' configuration option is not understood " + "and will be ignored.", + child->key); status = 0; } @@ -536,26 +501,21 @@ static int tr_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ } /* Additional sanity-checking */ - while (status == 0) - { - if ((data->host == NULL) - && (data->plugin == NULL) - && (data->plugin_instance == NULL) + while (status == 0) { + if ((data->host == NULL) && (data->plugin == NULL) && + (data->plugin_instance == NULL) /* && (data->type == NULL) */ - && (data->type_instance == NULL) - && (data->meta == NULL)) - { - ERROR ("Target `replace': You need to set at least one of `Host', " - "`Plugin', `PluginInstance' or `TypeInstance'."); + && (data->type_instance == NULL) && (data->meta == NULL)) { + ERROR("Target `replace': You need to set at least one of `Host', " + "`Plugin', `PluginInstance' or `TypeInstance'."); status = -1; } break; } - if (status != 0) - { - tr_destroy ((void *) &data); + if (status != 0) { + tr_destroy((void *)&data); return (status); } @@ -563,47 +523,43 @@ static int tr_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ return (0); } /* }}} int tr_create */ -static int tr_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */ - notification_meta_t __attribute__((unused)) **meta, void **user_data) -{ +static int tr_invoke(const data_set_t *ds, value_list_t *vl, /* {{{ */ + notification_meta_t __attribute__((unused)) * *meta, + void **user_data) { tr_data_t *data; if ((ds == NULL) || (vl == NULL) || (user_data == NULL)) return (-EINVAL); data = *user_data; - if (data == NULL) - { - ERROR ("Target `replace': Invoke: `data' is NULL."); + if (data == NULL) { + ERROR("Target `replace': Invoke: `data' is NULL."); return (-EINVAL); } - if (data->meta != NULL) - { - tr_meta_data_action_invoke (data->meta, &(vl->meta)); + if (data->meta != NULL) { + tr_meta_data_action_invoke(data->meta, &(vl->meta)); } -#define HANDLE_FIELD(f,e) \ - if (data->f != NULL) \ - tr_action_invoke (data->f, vl->f, sizeof (vl->f), e) - HANDLE_FIELD (host, 0); - HANDLE_FIELD (plugin, 0); - HANDLE_FIELD (plugin_instance, 1); +#define HANDLE_FIELD(f, e) \ + if (data->f != NULL) \ + tr_action_invoke(data->f, vl->f, sizeof(vl->f), e) + HANDLE_FIELD(host, 0); + HANDLE_FIELD(plugin, 0); + HANDLE_FIELD(plugin_instance, 1); /* HANDLE_FIELD (type, 0); */ - HANDLE_FIELD (type_instance, 1); + HANDLE_FIELD(type_instance, 1); return (FC_TARGET_CONTINUE); } /* }}} int tr_invoke */ -void module_register (void) -{ - target_proc_t tproc = { 0 }; +void module_register(void) { + target_proc_t tproc = {0}; - tproc.create = tr_create; - tproc.destroy = tr_destroy; - tproc.invoke = tr_invoke; - fc_register_target ("replace", tproc); + tproc.create = tr_create; + tproc.destroy = tr_destroy; + tproc.invoke = tr_invoke; + fc_register_target("replace", tproc); } /* module_register */ /* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ - diff --git a/src/target_scale.c b/src/target_scale.c index 22af4e31..347d6272 100644 --- a/src/target_scale.c +++ b/src/target_scale.c @@ -31,469 +31,431 @@ #include "utils_cache.h" -struct ts_data_s -{ - double factor; - double offset; +struct ts_data_s { + double factor; + double offset; - char **data_sources; - size_t data_sources_num; + char **data_sources; + size_t data_sources_num; }; typedef struct ts_data_s ts_data_t; -static int ts_invoke_counter (const data_set_t *ds, value_list_t *vl, /* {{{ */ - ts_data_t *data, int dsrc_index) -{ - uint64_t curr_counter; - int status; - int failure; - - /* Required meta data */ - uint64_t prev_counter; - char key_prev_counter[128]; - uint64_t int_counter; - char key_int_counter[128]; - double int_fraction; - char key_int_fraction[128]; - - curr_counter = (uint64_t) vl->values[dsrc_index].counter; - - ssnprintf (key_prev_counter, sizeof (key_prev_counter), - "target_scale[%p,%i]:prev_counter", - (void *) data, dsrc_index); - ssnprintf (key_int_counter, sizeof (key_int_counter), - "target_scale[%p,%i]:int_counter", - (void *) data, dsrc_index); - ssnprintf (key_int_fraction, sizeof (key_int_fraction), - "target_scale[%p,%i]:int_fraction", - (void *) data, dsrc_index); - - prev_counter = curr_counter; - int_counter = 0; - int_fraction = 0.0; - - /* Query the meta data */ - failure = 0; - - status = uc_meta_data_get_unsigned_int (vl, key_prev_counter, - &prev_counter); - if (status != 0) - failure++; - - status = uc_meta_data_get_unsigned_int (vl, key_int_counter, &int_counter); - if (status != 0) - failure++; - - status = uc_meta_data_get_double (vl, key_int_fraction, &int_fraction); - if (status != 0) - failure++; - - if (failure == 0) - { - uint64_t diff; - double rate; - - diff = (uint64_t) counter_diff (prev_counter, curr_counter); - rate = ((double) diff) / CDTIME_T_TO_DOUBLE (vl->interval); - - /* Modify the rate. */ - if (!isnan (data->factor)) - rate *= data->factor; - if (!isnan (data->offset)) - rate += data->offset; - - /* Calculate the internal counter. */ - int_fraction += (rate * CDTIME_T_TO_DOUBLE (vl->interval)); - diff = (uint64_t) int_fraction; - int_fraction -= ((double) diff); - int_counter += diff; - - assert (int_fraction >= 0.0); - assert (int_fraction < 1.0); - - DEBUG ("Target `scale': ts_invoke_counter: %"PRIu64" -> %g -> %"PRIu64 - "(+%g)", - curr_counter, rate, int_counter, int_fraction); - } - else /* (failure != 0) */ - { - int_counter = 0; - int_fraction = 0.0; - } - - vl->values[dsrc_index].counter = (counter_t) int_counter; - - /* Update to the new counter value */ - uc_meta_data_add_unsigned_int (vl, key_prev_counter, curr_counter); - uc_meta_data_add_unsigned_int (vl, key_int_counter, int_counter); - uc_meta_data_add_double (vl, key_int_fraction, int_fraction); - - - return (0); +static int ts_invoke_counter(const data_set_t *ds, value_list_t *vl, /* {{{ */ + ts_data_t *data, int dsrc_index) { + uint64_t curr_counter; + int status; + int failure; + + /* Required meta data */ + uint64_t prev_counter; + char key_prev_counter[128]; + uint64_t int_counter; + char key_int_counter[128]; + double int_fraction; + char key_int_fraction[128]; + + curr_counter = (uint64_t)vl->values[dsrc_index].counter; + + ssnprintf(key_prev_counter, sizeof(key_prev_counter), + "target_scale[%p,%i]:prev_counter", (void *)data, dsrc_index); + ssnprintf(key_int_counter, sizeof(key_int_counter), + "target_scale[%p,%i]:int_counter", (void *)data, dsrc_index); + ssnprintf(key_int_fraction, sizeof(key_int_fraction), + "target_scale[%p,%i]:int_fraction", (void *)data, dsrc_index); + + prev_counter = curr_counter; + int_counter = 0; + int_fraction = 0.0; + + /* Query the meta data */ + failure = 0; + + status = uc_meta_data_get_unsigned_int(vl, key_prev_counter, &prev_counter); + if (status != 0) + failure++; + + status = uc_meta_data_get_unsigned_int(vl, key_int_counter, &int_counter); + if (status != 0) + failure++; + + status = uc_meta_data_get_double(vl, key_int_fraction, &int_fraction); + if (status != 0) + failure++; + + if (failure == 0) { + uint64_t diff; + double rate; + + diff = (uint64_t)counter_diff(prev_counter, curr_counter); + rate = ((double)diff) / CDTIME_T_TO_DOUBLE(vl->interval); + + /* Modify the rate. */ + if (!isnan(data->factor)) + rate *= data->factor; + if (!isnan(data->offset)) + rate += data->offset; + + /* Calculate the internal counter. */ + int_fraction += (rate * CDTIME_T_TO_DOUBLE(vl->interval)); + diff = (uint64_t)int_fraction; + int_fraction -= ((double)diff); + int_counter += diff; + + assert(int_fraction >= 0.0); + assert(int_fraction < 1.0); + + DEBUG("Target `scale': ts_invoke_counter: %" PRIu64 " -> %g -> %" PRIu64 + "(+%g)", + curr_counter, rate, int_counter, int_fraction); + } else /* (failure != 0) */ + { + int_counter = 0; + int_fraction = 0.0; + } + + vl->values[dsrc_index].counter = (counter_t)int_counter; + + /* Update to the new counter value */ + uc_meta_data_add_unsigned_int(vl, key_prev_counter, curr_counter); + uc_meta_data_add_unsigned_int(vl, key_int_counter, int_counter); + uc_meta_data_add_double(vl, key_int_fraction, int_fraction); + + return (0); } /* }}} int ts_invoke_counter */ -static int ts_invoke_gauge (const data_set_t *ds, value_list_t *vl, /* {{{ */ - ts_data_t *data, int dsrc_index) -{ - if (!isnan (data->factor)) - vl->values[dsrc_index].gauge *= data->factor; - if (!isnan (data->offset)) - vl->values[dsrc_index].gauge += data->offset; +static int ts_invoke_gauge(const data_set_t *ds, value_list_t *vl, /* {{{ */ + ts_data_t *data, int dsrc_index) { + if (!isnan(data->factor)) + vl->values[dsrc_index].gauge *= data->factor; + if (!isnan(data->offset)) + vl->values[dsrc_index].gauge += data->offset; - return (0); + return (0); } /* }}} int ts_invoke_gauge */ -static int ts_invoke_derive (const data_set_t *ds, value_list_t *vl, /* {{{ */ - ts_data_t *data, int dsrc_index) -{ - int64_t curr_derive; - int status; - int failure; - - /* Required meta data */ - int64_t prev_derive; - char key_prev_derive[128]; - int64_t int_derive; - char key_int_derive[128]; - double int_fraction; - char key_int_fraction[128]; - - curr_derive = (int64_t) vl->values[dsrc_index].derive; - - ssnprintf (key_prev_derive, sizeof (key_prev_derive), - "target_scale[%p,%i]:prev_derive", - (void *) data, dsrc_index); - ssnprintf (key_int_derive, sizeof (key_int_derive), - "target_scale[%p,%i]:int_derive", - (void *) data, dsrc_index); - ssnprintf (key_int_fraction, sizeof (key_int_fraction), - "target_scale[%p,%i]:int_fraction", - (void *) data, dsrc_index); - - prev_derive = curr_derive; - int_derive = 0; - int_fraction = 0.0; - - /* Query the meta data */ - failure = 0; - - status = uc_meta_data_get_signed_int (vl, key_prev_derive, - &prev_derive); - if (status != 0) - failure++; - - status = uc_meta_data_get_signed_int (vl, key_int_derive, &int_derive); - if (status != 0) - failure++; - - status = uc_meta_data_get_double (vl, key_int_fraction, &int_fraction); - if (status != 0) - failure++; - - if (failure == 0) - { - int64_t difference; - double rate; - - /* Calcualte the rate */ - difference = curr_derive - prev_derive; - rate = ((double) difference) / CDTIME_T_TO_DOUBLE (vl->interval); - - /* Modify the rate. */ - if (!isnan (data->factor)) - rate *= data->factor; - if (!isnan (data->offset)) - rate += data->offset; - - /* Calculate the internal derive. */ - int_fraction += (rate * CDTIME_T_TO_DOUBLE (vl->interval)); - if (int_fraction < 0.0) /* handle negative integer rounding correctly */ - difference = ((int64_t) int_fraction) - 1; - else - difference = (int64_t) int_fraction; - int_fraction -= ((double) difference); - int_derive += difference; - - assert (int_fraction >= 0.0); - assert (int_fraction < 1.0); - - DEBUG ("Target `scale': ts_invoke_derive: %"PRIu64" -> %g -> %"PRIu64 - "(+%g)", - curr_derive, rate, int_derive, int_fraction); - } - else /* (failure != 0) */ - { - int_derive = 0; - int_fraction = 0.0; - } - - vl->values[dsrc_index].derive = (derive_t) int_derive; - - /* Update to the new derive value */ - uc_meta_data_add_signed_int (vl, key_prev_derive, curr_derive); - uc_meta_data_add_signed_int (vl, key_int_derive, int_derive); - uc_meta_data_add_double (vl, key_int_fraction, int_fraction); - - return (0); +static int ts_invoke_derive(const data_set_t *ds, value_list_t *vl, /* {{{ */ + ts_data_t *data, int dsrc_index) { + int64_t curr_derive; + int status; + int failure; + + /* Required meta data */ + int64_t prev_derive; + char key_prev_derive[128]; + int64_t int_derive; + char key_int_derive[128]; + double int_fraction; + char key_int_fraction[128]; + + curr_derive = (int64_t)vl->values[dsrc_index].derive; + + ssnprintf(key_prev_derive, sizeof(key_prev_derive), + "target_scale[%p,%i]:prev_derive", (void *)data, dsrc_index); + ssnprintf(key_int_derive, sizeof(key_int_derive), + "target_scale[%p,%i]:int_derive", (void *)data, dsrc_index); + ssnprintf(key_int_fraction, sizeof(key_int_fraction), + "target_scale[%p,%i]:int_fraction", (void *)data, dsrc_index); + + prev_derive = curr_derive; + int_derive = 0; + int_fraction = 0.0; + + /* Query the meta data */ + failure = 0; + + status = uc_meta_data_get_signed_int(vl, key_prev_derive, &prev_derive); + if (status != 0) + failure++; + + status = uc_meta_data_get_signed_int(vl, key_int_derive, &int_derive); + if (status != 0) + failure++; + + status = uc_meta_data_get_double(vl, key_int_fraction, &int_fraction); + if (status != 0) + failure++; + + if (failure == 0) { + int64_t difference; + double rate; + + /* Calcualte the rate */ + difference = curr_derive - prev_derive; + rate = ((double)difference) / CDTIME_T_TO_DOUBLE(vl->interval); + + /* Modify the rate. */ + if (!isnan(data->factor)) + rate *= data->factor; + if (!isnan(data->offset)) + rate += data->offset; + + /* Calculate the internal derive. */ + int_fraction += (rate * CDTIME_T_TO_DOUBLE(vl->interval)); + if (int_fraction < 0.0) /* handle negative integer rounding correctly */ + difference = ((int64_t)int_fraction) - 1; + else + difference = (int64_t)int_fraction; + int_fraction -= ((double)difference); + int_derive += difference; + + assert(int_fraction >= 0.0); + assert(int_fraction < 1.0); + + DEBUG("Target `scale': ts_invoke_derive: %" PRIu64 " -> %g -> %" PRIu64 + "(+%g)", + curr_derive, rate, int_derive, int_fraction); + } else /* (failure != 0) */ + { + int_derive = 0; + int_fraction = 0.0; + } + + vl->values[dsrc_index].derive = (derive_t)int_derive; + + /* Update to the new derive value */ + uc_meta_data_add_signed_int(vl, key_prev_derive, curr_derive); + uc_meta_data_add_signed_int(vl, key_int_derive, int_derive); + uc_meta_data_add_double(vl, key_int_fraction, int_fraction); + + return (0); } /* }}} int ts_invoke_derive */ -static int ts_invoke_absolute (const data_set_t *ds, value_list_t *vl, /* {{{ */ - ts_data_t *data, int dsrc_index) -{ - uint64_t curr_absolute; - double rate; - int status; +static int ts_invoke_absolute(const data_set_t *ds, value_list_t *vl, /* {{{ */ + ts_data_t *data, int dsrc_index) { + uint64_t curr_absolute; + double rate; + int status; - /* Required meta data */ - double int_fraction; - char key_int_fraction[128]; + /* Required meta data */ + double int_fraction; + char key_int_fraction[128]; - curr_absolute = (uint64_t) vl->values[dsrc_index].absolute; + curr_absolute = (uint64_t)vl->values[dsrc_index].absolute; - ssnprintf (key_int_fraction, sizeof (key_int_fraction), - "target_scale[%p,%i]:int_fraction", - (void *) data, dsrc_index); + ssnprintf(key_int_fraction, sizeof(key_int_fraction), + "target_scale[%p,%i]:int_fraction", (void *)data, dsrc_index); - int_fraction = 0.0; + int_fraction = 0.0; - /* Query the meta data */ - status = uc_meta_data_get_double (vl, key_int_fraction, &int_fraction); - if (status != 0) - int_fraction = 0.0; + /* Query the meta data */ + status = uc_meta_data_get_double(vl, key_int_fraction, &int_fraction); + if (status != 0) + int_fraction = 0.0; - rate = ((double) curr_absolute) / CDTIME_T_TO_DOUBLE (vl->interval); + rate = ((double)curr_absolute) / CDTIME_T_TO_DOUBLE(vl->interval); - /* Modify the rate. */ - if (!isnan (data->factor)) - rate *= data->factor; - if (!isnan (data->offset)) - rate += data->offset; + /* Modify the rate. */ + if (!isnan(data->factor)) + rate *= data->factor; + if (!isnan(data->offset)) + rate += data->offset; - /* Calculate the new absolute. */ - int_fraction += (rate * CDTIME_T_TO_DOUBLE (vl->interval)); - curr_absolute = (uint64_t) int_fraction; - int_fraction -= ((double) curr_absolute); + /* Calculate the new absolute. */ + int_fraction += (rate * CDTIME_T_TO_DOUBLE(vl->interval)); + curr_absolute = (uint64_t)int_fraction; + int_fraction -= ((double)curr_absolute); - vl->values[dsrc_index].absolute = (absolute_t) curr_absolute; + vl->values[dsrc_index].absolute = (absolute_t)curr_absolute; - /* Update to the new absolute value */ - uc_meta_data_add_double (vl, key_int_fraction, int_fraction); + /* Update to the new absolute value */ + uc_meta_data_add_double(vl, key_int_fraction, int_fraction); - return (0); + return (0); } /* }}} int ts_invoke_absolute */ -static int ts_config_set_double (double *ret, oconfig_item_t *ci) /* {{{ */ +static int ts_config_set_double(double *ret, oconfig_item_t *ci) /* {{{ */ { - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) - { - WARNING ("scale target: The `%s' config option needs " - "exactly one numeric argument.", ci->key); - return (-1); - } - - *ret = ci->values[0].value.number; - DEBUG ("ts_config_set_double: *ret = %g", *ret); - - return (0); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) { + WARNING("scale target: The `%s' config option needs " + "exactly one numeric argument.", + ci->key); + return (-1); + } + + *ret = ci->values[0].value.number; + DEBUG("ts_config_set_double: *ret = %g", *ret); + + return (0); } /* }}} int ts_config_set_double */ static int ts_config_add_data_source(ts_data_t *data, /* {{{ */ - oconfig_item_t *ci) -{ - size_t new_data_sources_num; - char **temp; - - /* Check number of arbuments. */ - if (ci->values_num < 1) - { - ERROR ("`value' match: `%s' needs at least one argument.", - ci->key); - return (-1); - } - - /* Check type of arguments */ - for (int i = 0; i < ci->values_num; i++) - { - if (ci->values[i].type == OCONFIG_TYPE_STRING) - continue; - - ERROR ("`value' match: `%s' accepts only string arguments " - "(argument %i is a %s).", - ci->key, i + 1, - (ci->values[i].type == OCONFIG_TYPE_BOOLEAN) - ? "truth value" : "number"); - return (-1); - } - - /* Allocate space for the char pointers */ - new_data_sources_num = data->data_sources_num + ((size_t) ci->values_num); - temp = realloc (data->data_sources, - new_data_sources_num * sizeof (char *)); - if (temp == NULL) - { - ERROR ("`value' match: realloc failed."); - return (-1); - } - data->data_sources = temp; - - /* Copy the strings, allocating memory as needed. */ - for (int i = 0; i < ci->values_num; i++) - { - size_t j; - - /* If we get here, there better be memory for us to write to. */ - assert (data->data_sources_num < new_data_sources_num); - - j = data->data_sources_num; - data->data_sources[j] = sstrdup (ci->values[i].value.string); - if (data->data_sources[j] == NULL) - { - ERROR ("`value' match: sstrdup failed."); - continue; - } - data->data_sources_num++; - } - - return (0); + oconfig_item_t *ci) { + size_t new_data_sources_num; + char **temp; + + /* Check number of arbuments. */ + if (ci->values_num < 1) { + ERROR("`value' match: `%s' needs at least one argument.", ci->key); + return (-1); + } + + /* Check type of arguments */ + for (int i = 0; i < ci->values_num; i++) { + if (ci->values[i].type == OCONFIG_TYPE_STRING) + continue; + + ERROR("`value' match: `%s' accepts only string arguments " + "(argument %i is a %s).", + ci->key, i + 1, + (ci->values[i].type == OCONFIG_TYPE_BOOLEAN) ? "truth value" + : "number"); + return (-1); + } + + /* Allocate space for the char pointers */ + new_data_sources_num = data->data_sources_num + ((size_t)ci->values_num); + temp = realloc(data->data_sources, new_data_sources_num * sizeof(char *)); + if (temp == NULL) { + ERROR("`value' match: realloc failed."); + return (-1); + } + data->data_sources = temp; + + /* Copy the strings, allocating memory as needed. */ + for (int i = 0; i < ci->values_num; i++) { + size_t j; + + /* If we get here, there better be memory for us to write to. */ + assert(data->data_sources_num < new_data_sources_num); + + j = data->data_sources_num; + data->data_sources[j] = sstrdup(ci->values[i].value.string); + if (data->data_sources[j] == NULL) { + ERROR("`value' match: sstrdup failed."); + continue; + } + data->data_sources_num++; + } + + return (0); } /* }}} int ts_config_add_data_source */ -static int ts_destroy (void **user_data) /* {{{ */ +static int ts_destroy(void **user_data) /* {{{ */ { - ts_data_t *data; + ts_data_t *data; - if (user_data == NULL) - return (-EINVAL); + if (user_data == NULL) + return (-EINVAL); - data = (ts_data_t *) *user_data; + data = (ts_data_t *)*user_data; - if ((data != NULL) && (data->data_sources != NULL)) - { - for (size_t i = 0; i < data->data_sources_num; i++) - sfree (data->data_sources[i]); - sfree (data->data_sources); - } + if ((data != NULL) && (data->data_sources != NULL)) { + for (size_t i = 0; i < data->data_sources_num; i++) + sfree(data->data_sources[i]); + sfree(data->data_sources); + } - sfree (data); - *user_data = NULL; + sfree(data); + *user_data = NULL; - return (0); + return (0); } /* }}} int ts_destroy */ -static int ts_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ +static int ts_create(const oconfig_item_t *ci, void **user_data) /* {{{ */ { - ts_data_t *data; - int status; - - data = calloc (1, sizeof (*data)); - if (data == NULL) - { - ERROR ("ts_create: calloc failed."); - return (-ENOMEM); - } - - data->factor = NAN; - data->offset = NAN; - - status = 0; - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("Factor", child->key) == 0) - status = ts_config_set_double (&data->factor, child); - else if (strcasecmp ("Offset", child->key) == 0) - status = ts_config_set_double (&data->offset, child); - else if (strcasecmp ("DataSource", child->key) == 0) - status = ts_config_add_data_source(data, child); - else - { - ERROR ("Target `scale': The `%s' configuration option is not understood " - "and will be ignored.", child->key); - status = 0; - } - - if (status != 0) - break; - } - - /* Additional sanity-checking */ - while (status == 0) - { - if (isnan (data->factor) && isnan (data->offset)) - { - ERROR ("Target `scale': You need to at least set either the `Factor' " - "or `Offset' option!"); - status = -1; - } - - break; - } - - if (status != 0) - { - ts_destroy ((void *) &data); - return (status); - } - - *user_data = data; - return (0); + ts_data_t *data; + int status; + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + ERROR("ts_create: calloc failed."); + return (-ENOMEM); + } + + data->factor = NAN; + data->offset = NAN; + + status = 0; + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Factor", child->key) == 0) + status = ts_config_set_double(&data->factor, child); + else if (strcasecmp("Offset", child->key) == 0) + status = ts_config_set_double(&data->offset, child); + else if (strcasecmp("DataSource", child->key) == 0) + status = ts_config_add_data_source(data, child); + else { + ERROR("Target `scale': The `%s' configuration option is not understood " + "and will be ignored.", + child->key); + status = 0; + } + + if (status != 0) + break; + } + + /* Additional sanity-checking */ + while (status == 0) { + if (isnan(data->factor) && isnan(data->offset)) { + ERROR("Target `scale': You need to at least set either the `Factor' " + "or `Offset' option!"); + status = -1; + } + + break; + } + + if (status != 0) { + ts_destroy((void *)&data); + return (status); + } + + *user_data = data; + return (0); } /* }}} int ts_create */ -static int ts_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */ - notification_meta_t __attribute__((unused)) **meta, void **user_data) -{ - ts_data_t *data; - - if ((ds == NULL) || (vl == NULL) || (user_data == NULL)) - return (-EINVAL); - - data = *user_data; - if (data == NULL) - { - ERROR ("Target `scale': Invoke: `data' is NULL."); - return (-EINVAL); - } - - for (size_t i = 0; i < ds->ds_num; i++) - { - /* If we've got a list of data sources, is it in the list? */ - if (data->data_sources) { - size_t j; - for (j = 0; j < data->data_sources_num; j++) - if (strcasecmp(ds->ds[i].name, data->data_sources[j]) == 0) - break; - - /* No match, ignore */ - if (j >= data->data_sources_num) - continue; - } - - if (ds->ds[i].type == DS_TYPE_COUNTER) - ts_invoke_counter (ds, vl, data, i); - else if (ds->ds[i].type == DS_TYPE_GAUGE) - ts_invoke_gauge (ds, vl, data, i); - else if (ds->ds[i].type == DS_TYPE_DERIVE) - ts_invoke_derive (ds, vl, data, i); - else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) - ts_invoke_absolute (ds, vl, data, i); - else - ERROR ("Target `scale': Ignoring unknown data source type %i", - ds->ds[i].type); - } - - return (FC_TARGET_CONTINUE); +static int ts_invoke(const data_set_t *ds, value_list_t *vl, /* {{{ */ + notification_meta_t __attribute__((unused)) * *meta, + void **user_data) { + ts_data_t *data; + + if ((ds == NULL) || (vl == NULL) || (user_data == NULL)) + return (-EINVAL); + + data = *user_data; + if (data == NULL) { + ERROR("Target `scale': Invoke: `data' is NULL."); + return (-EINVAL); + } + + for (size_t i = 0; i < ds->ds_num; i++) { + /* If we've got a list of data sources, is it in the list? */ + if (data->data_sources) { + size_t j; + for (j = 0; j < data->data_sources_num; j++) + if (strcasecmp(ds->ds[i].name, data->data_sources[j]) == 0) + break; + + /* No match, ignore */ + if (j >= data->data_sources_num) + continue; + } + + if (ds->ds[i].type == DS_TYPE_COUNTER) + ts_invoke_counter(ds, vl, data, i); + else if (ds->ds[i].type == DS_TYPE_GAUGE) + ts_invoke_gauge(ds, vl, data, i); + else if (ds->ds[i].type == DS_TYPE_DERIVE) + ts_invoke_derive(ds, vl, data, i); + else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) + ts_invoke_absolute(ds, vl, data, i); + else + ERROR("Target `scale': Ignoring unknown data source type %i", + ds->ds[i].type); + } + + return (FC_TARGET_CONTINUE); } /* }}} int ts_invoke */ -void module_register (void) -{ - target_proc_t tproc = { 0 }; +void module_register(void) { + target_proc_t tproc = {0}; - tproc.create = ts_create; - tproc.destroy = ts_destroy; - tproc.invoke = ts_invoke; - fc_register_target ("scale", tproc); + tproc.create = ts_create; + tproc.destroy = ts_destroy; + tproc.invoke = ts_invoke; + fc_register_target("scale", tproc); } /* module_register */ /* vim: set sw=2 ts=2 tw=78 fdm=marker : */ - diff --git a/src/target_set.c b/src/target_set.c index 6b44bcc4..5bf40fa3 100644 --- a/src/target_set.c +++ b/src/target_set.c @@ -31,28 +31,26 @@ #include "meta_data.h" #include "utils_subst.h" -struct ts_key_list_s -{ +struct ts_key_list_s { char *key; struct ts_key_list_s *next; }; typedef struct ts_key_list_s ts_key_list_t; -static void ts_key_list_free (ts_key_list_t *l) /* {{{ */ +static void ts_key_list_free(ts_key_list_t *l) /* {{{ */ { if (l == NULL) return; - sfree (l->key); + sfree(l->key); if (l->next != NULL) - ts_key_list_free (l->next); + ts_key_list_free(l->next); - sfree (l); + sfree(l); } /* }}} void ts_name_list_free */ -struct ts_data_s -{ +struct ts_data_s { char *host; char *plugin; char *plugin_instance; @@ -63,14 +61,15 @@ struct ts_data_s }; typedef struct ts_data_s ts_data_t; -static int ts_util_get_key_and_string_wo_strdup (const oconfig_item_t *ci, char **ret_key, char **ret_string) /* {{{ */ +static int ts_util_get_key_and_string_wo_strdup(const oconfig_item_t *ci, + char **ret_key, + char **ret_string) /* {{{ */ { - if ((ci->values_num != 2) - || (ci->values[0].type != OCONFIG_TYPE_STRING) - || (ci->values[1].type != OCONFIG_TYPE_STRING)) - { - ERROR ("ts_util_get_key_and_string_wo_strdup: The %s option requires " - "exactly two string arguments.", ci->key); + if ((ci->values_num != 2) || (ci->values[0].type != OCONFIG_TYPE_STRING) || + (ci->values[1].type != OCONFIG_TYPE_STRING)) { + ERROR("ts_util_get_key_and_string_wo_strdup: The %s option requires " + "exactly two string arguments.", + ci->key); return (-1); } @@ -80,21 +79,19 @@ static int ts_util_get_key_and_string_wo_strdup (const oconfig_item_t *ci, char return (0); } /* }}} int ts_util_get_key_and_string_wo_strdup */ -static int ts_config_add_string (char **dest, /* {{{ */ - const oconfig_item_t *ci, int may_be_empty) -{ +static int ts_config_add_string(char **dest, /* {{{ */ + const oconfig_item_t *ci, int may_be_empty) { char *tmp = NULL; int status; - status = cf_util_get_string (ci, &tmp); + status = cf_util_get_string(ci, &tmp); if (status != 0) return (status); - if (!may_be_empty && (strlen (tmp) == 0)) - { - ERROR ("Target `set': The `%s' option does not accept empty strings.", - ci->key); - sfree (tmp); + if (!may_be_empty && (strlen(tmp) == 0)) { + ERROR("Target `set': The `%s' option does not accept empty strings.", + ci->key); + sfree(tmp); return (-1); } @@ -102,67 +99,61 @@ static int ts_config_add_string (char **dest, /* {{{ */ return (0); } /* }}} int ts_config_add_string */ -static int ts_config_add_meta (meta_data_t **dest, /* {{{ */ - const oconfig_item_t *ci, int may_be_empty) -{ +static int ts_config_add_meta(meta_data_t **dest, /* {{{ */ + const oconfig_item_t *ci, int may_be_empty) { char *key = NULL; char *string = NULL; int status; - status = ts_util_get_key_and_string_wo_strdup (ci, &key, &string); + status = ts_util_get_key_and_string_wo_strdup(ci, &key, &string); if (status != 0) return (status); - if (strlen (key) == 0) - { - ERROR ("Target `set': The `%s' option does not accept empty string as " - "first argument.", ci->key); + if (strlen(key) == 0) { + ERROR("Target `set': The `%s' option does not accept empty string as " + "first argument.", + ci->key); return (-1); } - if (!may_be_empty && (strlen (string) == 0)) - { - ERROR ("Target `set': The `%s' option does not accept empty string as " - "second argument.", ci->key); + if (!may_be_empty && (strlen(string) == 0)) { + ERROR("Target `set': The `%s' option does not accept empty string as " + "second argument.", + ci->key); return (-1); } - if ((*dest) == NULL) - { + if ((*dest) == NULL) { /* Create a new meta_data_t */ - if ((*dest = meta_data_create()) == NULL) - { - ERROR ("Target `set': failed to create a meta data for `%s'.", ci->key); + if ((*dest = meta_data_create()) == NULL) { + ERROR("Target `set': failed to create a meta data for `%s'.", ci->key); return (-ENOMEM); } } - return (meta_data_add_string (*dest, key, string)); + return (meta_data_add_string(*dest, key, string)); } /* }}} int ts_config_add_meta */ -static int ts_config_add_meta_delete (ts_key_list_t **dest, /* {{{ */ - const oconfig_item_t *ci) -{ +static int ts_config_add_meta_delete(ts_key_list_t **dest, /* {{{ */ + const oconfig_item_t *ci) { ts_key_list_t *entry = NULL; - entry = calloc (1, sizeof (*entry)); - if (entry == NULL) - { - ERROR ("ts_config_add_meta_delete: calloc failed."); + entry = calloc(1, sizeof(*entry)); + if (entry == NULL) { + ERROR("ts_config_add_meta_delete: calloc failed."); return (-ENOMEM); } - if (cf_util_get_string (ci, &entry->key) != 0) - { - ts_key_list_free (entry); - return (-1); /* An error has already been reported. */ + if (cf_util_get_string(ci, &entry->key) != 0) { + ts_key_list_free(entry); + return (-1); /* An error has already been reported. */ } - if (strlen (entry->key) == 0) - { - ERROR ("Target `set': The `%s' option does not accept empty string as " - "first argument.", ci->key); - ts_key_list_free (entry); + if (strlen(entry->key) == 0) { + ERROR("Target `set': The `%s' option does not accept empty string as " + "first argument.", + ci->key); + ts_key_list_free(entry); return (-1); } @@ -172,49 +163,46 @@ static int ts_config_add_meta_delete (ts_key_list_t **dest, /* {{{ */ return (0); } /* }}} int ts_config_add_meta_delete */ -static void ts_subst (char *dest, size_t size, const char *string, /* {{{ */ - const value_list_t *vl) -{ +static void ts_subst(char *dest, size_t size, const char *string, /* {{{ */ + const value_list_t *vl) { char temp[DATA_MAX_NAME_LEN]; /* Initialize the field with the template. */ - sstrncpy (dest, string, size); + sstrncpy(dest, string, size); - if (strchr (dest, '%') == NULL) + if (strchr(dest, '%') == NULL) return; -#define REPLACE_FIELD(t, v) \ - if (subst_string (temp, sizeof (temp), dest, t, v) != NULL) \ - sstrncpy (dest, temp, size); - REPLACE_FIELD ("%{host}", vl->host); - REPLACE_FIELD ("%{plugin}", vl->plugin); - REPLACE_FIELD ("%{plugin_instance}", vl->plugin_instance); - REPLACE_FIELD ("%{type}", vl->type); - REPLACE_FIELD ("%{type_instance}", vl->type_instance); - - if (vl->meta != NULL) - { +#define REPLACE_FIELD(t, v) \ + if (subst_string(temp, sizeof(temp), dest, t, v) != NULL) \ + sstrncpy(dest, temp, size); + REPLACE_FIELD("%{host}", vl->host); + REPLACE_FIELD("%{plugin}", vl->plugin); + REPLACE_FIELD("%{plugin_instance}", vl->plugin_instance); + REPLACE_FIELD("%{type}", vl->type); + REPLACE_FIELD("%{type_instance}", vl->type_instance); + + if (vl->meta != NULL) { char **meta_toc; - int meta_entries = meta_data_toc (vl->meta, &meta_toc); - for (int i = 0; i < meta_entries; i++) - { + int meta_entries = meta_data_toc(vl->meta, &meta_toc); + for (int i = 0; i < meta_entries; i++) { char meta_name[DATA_MAX_NAME_LEN]; char *value_str; const char *key = meta_toc[i]; - ssnprintf (meta_name, sizeof (meta_name), "%%{meta:%s}", key); - if (meta_data_as_string (vl->meta, key, &value_str) != 0) + ssnprintf(meta_name, sizeof(meta_name), "%%{meta:%s}", key); + if (meta_data_as_string(vl->meta, key, &value_str) != 0) continue; - REPLACE_FIELD (meta_name, value_str); - sfree (value_str); + REPLACE_FIELD(meta_name, value_str); + sfree(value_str); } - strarray_free (meta_toc, (size_t) meta_entries); + strarray_free(meta_toc, (size_t)meta_entries); } } /* }}} int ts_subst */ -static int ts_destroy (void **user_data) /* {{{ */ +static int ts_destroy(void **user_data) /* {{{ */ { ts_data_t *data; @@ -225,27 +213,26 @@ static int ts_destroy (void **user_data) /* {{{ */ if (data == NULL) return (0); - free (data->host); - free (data->plugin); - free (data->plugin_instance); + free(data->host); + free(data->plugin); + free(data->plugin_instance); /* free (data->type); */ - free (data->type_instance); + free(data->type_instance); meta_data_destroy(data->meta); - ts_key_list_free (data->meta_delete); - free (data); + ts_key_list_free(data->meta_delete); + free(data); return (0); } /* }}} int ts_destroy */ -static int ts_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ +static int ts_create(const oconfig_item_t *ci, void **user_data) /* {{{ */ { ts_data_t *data; int status; - data = calloc (1, sizeof (*data)); - if (data == NULL) - { - ERROR ("ts_create: calloc failed."); + data = calloc(1, sizeof(*data)); + if (data == NULL) { + ERROR("ts_create: calloc failed."); return (-ENOMEM); } @@ -258,37 +245,36 @@ static int ts_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ data->meta_delete = NULL; status = 0; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if ((strcasecmp ("Host", child->key) == 0) - || (strcasecmp ("Hostname", child->key) == 0)) - status = ts_config_add_string (&data->host, child, - /* may be empty = */ 0); - else if (strcasecmp ("Plugin", child->key) == 0) - status = ts_config_add_string (&data->plugin, child, - /* may be empty = */ 0); - else if (strcasecmp ("PluginInstance", child->key) == 0) - status = ts_config_add_string (&data->plugin_instance, child, - /* may be empty = */ 1); + if ((strcasecmp("Host", child->key) == 0) || + (strcasecmp("Hostname", child->key) == 0)) + status = ts_config_add_string(&data->host, child, + /* may be empty = */ 0); + else if (strcasecmp("Plugin", child->key) == 0) + status = ts_config_add_string(&data->plugin, child, + /* may be empty = */ 0); + else if (strcasecmp("PluginInstance", child->key) == 0) + status = ts_config_add_string(&data->plugin_instance, child, + /* may be empty = */ 1); #if 0 else if (strcasecmp ("Type", child->key) == 0) status = ts_config_add_string (&data->type, child, /* may be empty = */ 0); #endif - else if (strcasecmp ("TypeInstance", child->key) == 0) - status = ts_config_add_string (&data->type_instance, child, - /* may be empty = */ 1); - else if (strcasecmp ("MetaData", child->key) == 0) - status = ts_config_add_meta (&data->meta, child, - /* may be empty = */ 1); - else if (strcasecmp ("DeleteMetaData", child->key) == 0) - status = ts_config_add_meta_delete (&data->meta_delete, child); - else - { - ERROR ("Target `set': The `%s' configuration option is not understood " - "and will be ignored.", child->key); + else if (strcasecmp("TypeInstance", child->key) == 0) + status = ts_config_add_string(&data->type_instance, child, + /* may be empty = */ 1); + else if (strcasecmp("MetaData", child->key) == 0) + status = ts_config_add_meta(&data->meta, child, + /* may be empty = */ 1); + else if (strcasecmp("DeleteMetaData", child->key) == 0) + status = ts_config_add_meta_delete(&data->meta_delete, child); + else { + ERROR("Target `set': The `%s' configuration option is not understood " + "and will be ignored.", + child->key); status = 0; } @@ -297,32 +283,25 @@ static int ts_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ } /* Additional sanity-checking */ - while (status == 0) - { - if ((data->host == NULL) - && (data->plugin == NULL) - && (data->plugin_instance == NULL) + while (status == 0) { + if ((data->host == NULL) && (data->plugin == NULL) && + (data->plugin_instance == NULL) /* && (data->type == NULL) */ - && (data->type_instance == NULL) - && (data->meta == NULL) - && (data->meta_delete == NULL)) - { - ERROR ("Target `set': You need to set at least one of `Host', " - "`Plugin', `PluginInstance', `TypeInstance', " - "`MetaData', or `DeleteMetaData'."); + && (data->type_instance == NULL) && (data->meta == NULL) && + (data->meta_delete == NULL)) { + ERROR("Target `set': You need to set at least one of `Host', " + "`Plugin', `PluginInstance', `TypeInstance', " + "`MetaData', or `DeleteMetaData'."); status = -1; } - if (data->meta != NULL) - { + if (data->meta != NULL) { /* If data->meta_delete is NULL, this loop is a no-op. */ - for (ts_key_list_t *l=data->meta_delete; l != NULL; l = l->next) - { - if (meta_data_type (data->meta, l->key) != 0) - { + for (ts_key_list_t *l = data->meta_delete; l != NULL; l = l->next) { + if (meta_data_type(data->meta, l->key) != 0) { /* MetaData and DeleteMetaData for the same key. */ - ERROR ("Target `set': Can only have one of `MetaData' or " - "`DeleteMetaData' for any given key."); + ERROR("Target `set': Can only have one of `MetaData' or " + "`DeleteMetaData' for any given key."); status = -1; } } @@ -331,9 +310,8 @@ static int ts_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ break; } - if (status != 0) - { - ts_destroy ((void *) &data); + if (status != 0) { + ts_destroy((void *)&data); return (status); } @@ -341,9 +319,9 @@ static int ts_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ return (0); } /* }}} int ts_create */ -static int ts_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */ - notification_meta_t __attribute__((unused)) **meta, void **user_data) -{ +static int ts_invoke(const data_set_t *ds, value_list_t *vl, /* {{{ */ + notification_meta_t __attribute__((unused)) * *meta, + void **user_data) { ts_data_t *data; value_list_t orig; meta_data_t *new_meta = NULL; @@ -352,99 +330,90 @@ static int ts_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */ return (-EINVAL); data = *user_data; - if (data == NULL) - { - ERROR ("Target `set': Invoke: `data' is NULL."); + if (data == NULL) { + ERROR("Target `set': Invoke: `data' is NULL."); return (-EINVAL); } orig = *vl; - if (data->meta != NULL) - { - char temp[DATA_MAX_NAME_LEN*2]; + if (data->meta != NULL) { + char temp[DATA_MAX_NAME_LEN * 2]; int meta_entries; char **meta_toc; - if ((new_meta = meta_data_create()) == NULL) - { - ERROR ("Target `set': failed to create replacement metadata."); + if ((new_meta = meta_data_create()) == NULL) { + ERROR("Target `set': failed to create replacement metadata."); return (-ENOMEM); } - meta_entries = meta_data_toc (data->meta, &meta_toc); - for (int i = 0; i < meta_entries; i++) - { + meta_entries = meta_data_toc(data->meta, &meta_toc); + for (int i = 0; i < meta_entries; i++) { const char *key = meta_toc[i]; char *string; int status; - status = meta_data_get_string (data->meta, key, &string); - if (status) - { - ERROR ("Target `set': Unable to get replacement metadata value `%s'.", - key); - strarray_free (meta_toc, (size_t) meta_entries); + status = meta_data_get_string(data->meta, key, &string); + if (status) { + ERROR("Target `set': Unable to get replacement metadata value `%s'.", + key); + strarray_free(meta_toc, (size_t)meta_entries); return (status); } - ts_subst (temp, sizeof (temp), string, &orig); + ts_subst(temp, sizeof(temp), string, &orig); - DEBUG ("target_set: ts_invoke: setting metadata value for key `%s': " - "`%s'.", key, temp); + DEBUG("target_set: ts_invoke: setting metadata value for key `%s': " + "`%s'.", + key, temp); - sfree (string); + sfree(string); - status = meta_data_add_string (new_meta, key, temp); - if (status) - { - ERROR ("Target `set': Unable to set metadata value `%s'.", key); - strarray_free (meta_toc, (size_t) meta_entries); + status = meta_data_add_string(new_meta, key, temp); + if (status) { + ERROR("Target `set': Unable to set metadata value `%s'.", key); + strarray_free(meta_toc, (size_t)meta_entries); return (status); } } - strarray_free (meta_toc, (size_t) meta_entries); + strarray_free(meta_toc, (size_t)meta_entries); } -#define SUBST_FIELD(f) \ - if (data->f != NULL) { \ - ts_subst (vl->f, sizeof (vl->f), data->f, &orig); \ - DEBUG ("target_set: ts_invoke: setting "#f": `%s'.", vl->f); \ +#define SUBST_FIELD(f) \ + if (data->f != NULL) { \ + ts_subst(vl->f, sizeof(vl->f), data->f, &orig); \ + DEBUG("target_set: ts_invoke: setting " #f ": `%s'.", vl->f); \ } - SUBST_FIELD (host); - SUBST_FIELD (plugin); - SUBST_FIELD (plugin_instance); + SUBST_FIELD(host); + SUBST_FIELD(plugin); + SUBST_FIELD(plugin_instance); /* SUBST_FIELD (type); */ - SUBST_FIELD (type_instance); + SUBST_FIELD(type_instance); /* Need to merge the metadata in now, because of the shallow copy. */ - if (new_meta != NULL) - { + if (new_meta != NULL) { meta_data_clone_merge(&(vl->meta), new_meta); meta_data_destroy(new_meta); } /* If data->meta_delete is NULL, this loop is a no-op. */ - for (ts_key_list_t *l=data->meta_delete; l != NULL; l = l->next) - { - DEBUG ("target_set: ts_invoke: deleting metadata value for key `%s'.", - l->key); + for (ts_key_list_t *l = data->meta_delete; l != NULL; l = l->next) { + DEBUG("target_set: ts_invoke: deleting metadata value for key `%s'.", + l->key); meta_data_delete(vl->meta, l->key); } return (FC_TARGET_CONTINUE); } /* }}} int ts_invoke */ -void module_register (void) -{ - target_proc_t tproc = { 0 }; +void module_register(void) { + target_proc_t tproc = {0}; - tproc.create = ts_create; - tproc.destroy = ts_destroy; - tproc.invoke = ts_invoke; - fc_register_target ("set", tproc); + tproc.create = ts_create; + tproc.destroy = ts_destroy; + tproc.invoke = ts_invoke; + fc_register_target("set", tproc); } /* module_register */ /* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ - diff --git a/src/target_v5upgrade.c b/src/target_v5upgrade.c index 3f2c9583..54e37e16 100644 --- a/src/target_v5upgrade.c +++ b/src/target_v5upgrade.c @@ -26,20 +26,20 @@ #include "collectd.h" -#include "plugin.h" #include "common.h" #include "filter_chain.h" +#include "plugin.h" -static void v5_swap_instances (value_list_t *vl) /* {{{ */ +static void v5_swap_instances(value_list_t *vl) /* {{{ */ { char tmp[DATA_MAX_NAME_LEN]; - assert (sizeof (tmp) == sizeof (vl->plugin_instance)); - assert (sizeof (tmp) == sizeof (vl->type_instance)); + assert(sizeof(tmp) == sizeof(vl->plugin_instance)); + assert(sizeof(tmp) == sizeof(vl->type_instance)); - memcpy (tmp, vl->plugin_instance, sizeof (tmp)); - memcpy (vl->plugin_instance, vl->type_instance, sizeof (tmp)); - memcpy (vl->type_instance, tmp, sizeof (tmp)); + memcpy(tmp, vl->plugin_instance, sizeof(tmp)); + memcpy(vl->plugin_instance, vl->type_instance, sizeof(tmp)); + memcpy(vl->type_instance, tmp, sizeof(tmp)); } /* }}} void v5_swap_instances */ /* @@ -50,38 +50,37 @@ static void v5_swap_instances (value_list_t *vl) /* {{{ */ * to "df_complex". This can be selected in versions 4.9 and 4.10 by setting * the "ReportReserved" option of the "df" plugin. */ -static int v5_df (const data_set_t *ds, value_list_t *vl) /* {{{ */ +static int v5_df(const data_set_t *ds, value_list_t *vl) /* {{{ */ { value_list_t new_vl; /* Can't upgrade if both instances have been set. */ - if ((vl->plugin_instance[0] != 0) - && (vl->type_instance[0] != 0)) + if ((vl->plugin_instance[0] != 0) && (vl->type_instance[0] != 0)) return (FC_TARGET_CONTINUE); /* Copy everything: Time, interval, host, ... */ - memcpy (&new_vl, vl, sizeof (new_vl)); + memcpy(&new_vl, vl, sizeof(new_vl)); /* Reset data we can't simply copy */ - new_vl.values = &(value_t) { .gauge = NAN }; + new_vl.values = &(value_t){.gauge = NAN}; new_vl.values_len = 1; new_vl.meta = NULL; /* Move the mount point name to the plugin instance */ if (new_vl.plugin_instance[0] == 0) - v5_swap_instances (&new_vl); + v5_swap_instances(&new_vl); /* Change the type to "df_complex" */ - sstrncpy (new_vl.type, "df_complex", sizeof (new_vl.type)); + sstrncpy(new_vl.type, "df_complex", sizeof(new_vl.type)); /* Dispatch two new value lists instead of this one */ new_vl.values[0].gauge = vl->values[0].gauge; - sstrncpy (new_vl.type_instance, "used", sizeof (new_vl.type_instance)); - plugin_dispatch_values (&new_vl); + sstrncpy(new_vl.type_instance, "used", sizeof(new_vl.type_instance)); + plugin_dispatch_values(&new_vl); new_vl.values[0].gauge = vl->values[1].gauge; - sstrncpy (new_vl.type_instance, "free", sizeof (new_vl.type_instance)); - plugin_dispatch_values (&new_vl); + sstrncpy(new_vl.type_instance, "free", sizeof(new_vl.type_instance)); + plugin_dispatch_values(&new_vl); /* Abort processing */ return (FC_TARGET_STOP); @@ -94,12 +93,12 @@ static int v5_df (const data_set_t *ds, value_list_t *vl) /* {{{ */ * instance empty. If this is the case, put the interface name into the plugin * instance and clear the type instance. */ -static int v5_interface (const data_set_t *ds, value_list_t *vl) /* {{{ */ +static int v5_interface(const data_set_t *ds, value_list_t *vl) /* {{{ */ { if ((vl->plugin_instance[0] != 0) || (vl->type_instance[0] == 0)) return (FC_TARGET_CONTINUE); - v5_swap_instances (vl); + v5_swap_instances(vl); return (FC_TARGET_CONTINUE); } /* }}} int v5_interface */ @@ -109,7 +108,7 @@ static int v5_interface (const data_set_t *ds, value_list_t *vl) /* {{{ */ * 4.* uses the "mysql_qcache" type which mixes different types of * information. In 5.* this has been broken up. */ -static int v5_mysql_qcache (const data_set_t *ds, value_list_t *vl) /* {{{ */ +static int v5_mysql_qcache(const data_set_t *ds, value_list_t *vl) /* {{{ */ { value_list_t new_vl; @@ -117,44 +116,41 @@ static int v5_mysql_qcache (const data_set_t *ds, value_list_t *vl) /* {{{ */ return (FC_TARGET_STOP); /* Copy everything: Time, interval, host, ... */ - memcpy (&new_vl, vl, sizeof (new_vl)); + memcpy(&new_vl, vl, sizeof(new_vl)); /* Reset data we can't simply copy */ - new_vl.values = &(value_t) { .gauge = NAN }; + new_vl.values = &(value_t){.gauge = NAN}; new_vl.values_len = 1; new_vl.meta = NULL; /* Change the type to "cache_result" */ - sstrncpy (new_vl.type, "cache_result", sizeof (new_vl.type)); + sstrncpy(new_vl.type, "cache_result", sizeof(new_vl.type)); /* Dispatch new value lists instead of this one */ - new_vl.values[0].derive = (derive_t) vl->values[0].counter; - sstrncpy (new_vl.type_instance, "qcache-hits", - sizeof (new_vl.type_instance)); - plugin_dispatch_values (&new_vl); - - new_vl.values[0].derive = (derive_t) vl->values[1].counter; - sstrncpy (new_vl.type_instance, "qcache-inserts", - sizeof (new_vl.type_instance)); - plugin_dispatch_values (&new_vl); - - new_vl.values[0].derive = (derive_t) vl->values[2].counter; - sstrncpy (new_vl.type_instance, "qcache-not_cached", - sizeof (new_vl.type_instance)); - plugin_dispatch_values (&new_vl); - - new_vl.values[0].derive = (derive_t) vl->values[3].counter; - sstrncpy (new_vl.type_instance, "qcache-prunes", - sizeof (new_vl.type_instance)); - plugin_dispatch_values (&new_vl); + new_vl.values[0].derive = (derive_t)vl->values[0].counter; + sstrncpy(new_vl.type_instance, "qcache-hits", sizeof(new_vl.type_instance)); + plugin_dispatch_values(&new_vl); + + new_vl.values[0].derive = (derive_t)vl->values[1].counter; + sstrncpy(new_vl.type_instance, "qcache-inserts", + sizeof(new_vl.type_instance)); + plugin_dispatch_values(&new_vl); + + new_vl.values[0].derive = (derive_t)vl->values[2].counter; + sstrncpy(new_vl.type_instance, "qcache-not_cached", + sizeof(new_vl.type_instance)); + plugin_dispatch_values(&new_vl); + + new_vl.values[0].derive = (derive_t)vl->values[3].counter; + sstrncpy(new_vl.type_instance, "qcache-prunes", sizeof(new_vl.type_instance)); + plugin_dispatch_values(&new_vl); /* The last data source is a gauge value, so we have to use a different type * here. */ new_vl.values[0].gauge = vl->values[4].gauge; - sstrncpy (new_vl.type, "cache_size", sizeof (new_vl.type)); - sstrncpy (new_vl.type_instance, "qcache", - sizeof (new_vl.type_instance)); - plugin_dispatch_values (&new_vl); + sstrncpy(new_vl.type, "cache_size", sizeof(new_vl.type)); + sstrncpy(new_vl.type_instance, "qcache", sizeof(new_vl.type_instance)); + plugin_dispatch_values(&new_vl); /* Abort processing */ return (FC_TARGET_STOP); @@ -166,7 +162,7 @@ static int v5_mysql_qcache (const data_set_t *ds, value_list_t *vl) /* {{{ */ * 4.* uses the "mysql_threads" type which mixes different types of * information. In 5.* this has been broken up. */ -static int v5_mysql_threads (const data_set_t *ds, value_list_t *vl) /* {{{ */ +static int v5_mysql_threads(const data_set_t *ds, value_list_t *vl) /* {{{ */ { value_list_t new_vl; @@ -174,39 +170,35 @@ static int v5_mysql_threads (const data_set_t *ds, value_list_t *vl) /* {{{ */ return (FC_TARGET_STOP); /* Copy everything: Time, interval, host, ... */ - memcpy (&new_vl, vl, sizeof (new_vl)); + memcpy(&new_vl, vl, sizeof(new_vl)); /* Reset data we can't simply copy */ - new_vl.values = &(value_t) { .gauge = NAN }; + new_vl.values = &(value_t){.gauge = NAN}; new_vl.values_len = 1; new_vl.meta = NULL; /* Change the type to "threads" */ - sstrncpy (new_vl.type, "threads", sizeof (new_vl.type)); + sstrncpy(new_vl.type, "threads", sizeof(new_vl.type)); /* Dispatch new value lists instead of this one */ new_vl.values[0].gauge = vl->values[0].gauge; - sstrncpy (new_vl.type_instance, "running", - sizeof (new_vl.type_instance)); - plugin_dispatch_values (&new_vl); + sstrncpy(new_vl.type_instance, "running", sizeof(new_vl.type_instance)); + plugin_dispatch_values(&new_vl); new_vl.values[0].gauge = vl->values[1].gauge; - sstrncpy (new_vl.type_instance, "connected", - sizeof (new_vl.type_instance)); - plugin_dispatch_values (&new_vl); + sstrncpy(new_vl.type_instance, "connected", sizeof(new_vl.type_instance)); + plugin_dispatch_values(&new_vl); new_vl.values[0].gauge = vl->values[2].gauge; - sstrncpy (new_vl.type_instance, "cached", - sizeof (new_vl.type_instance)); - plugin_dispatch_values (&new_vl); + sstrncpy(new_vl.type_instance, "cached", sizeof(new_vl.type_instance)); + plugin_dispatch_values(&new_vl); /* The last data source is a counter value, so we have to use a different * type here. */ - new_vl.values[0].derive = (derive_t) vl->values[3].counter; - sstrncpy (new_vl.type, "total_threads", sizeof (new_vl.type)); - sstrncpy (new_vl.type_instance, "created", - sizeof (new_vl.type_instance)); - plugin_dispatch_values (&new_vl); + new_vl.values[0].derive = (derive_t)vl->values[3].counter; + sstrncpy(new_vl.type, "total_threads", sizeof(new_vl.type)); + sstrncpy(new_vl.type_instance, "created", sizeof(new_vl.type_instance)); + plugin_dispatch_values(&new_vl); /* Abort processing */ return (FC_TARGET_STOP); @@ -218,7 +210,7 @@ static int v5_mysql_threads (const data_set_t *ds, value_list_t *vl) /* {{{ */ * 4.* uses the flawed "arc_counts" type. In 5.* this has been replaced by the * more generic "cache_result" type. */ -static int v5_zfs_arc_counts (const data_set_t *ds, value_list_t *vl) /* {{{ */ +static int v5_zfs_arc_counts(const data_set_t *ds, value_list_t *vl) /* {{{ */ { value_list_t new_vl; _Bool is_hits; @@ -226,48 +218,44 @@ static int v5_zfs_arc_counts (const data_set_t *ds, value_list_t *vl) /* {{{ */ if (vl->values_len != 4) return (FC_TARGET_STOP); - if (strcmp ("hits", vl->type_instance) == 0) + if (strcmp("hits", vl->type_instance) == 0) is_hits = 1; - else if (strcmp ("misses", vl->type_instance) == 0) + else if (strcmp("misses", vl->type_instance) == 0) is_hits = 0; else return (FC_TARGET_STOP); /* Copy everything: Time, interval, host, ... */ - memcpy (&new_vl, vl, sizeof (new_vl)); + memcpy(&new_vl, vl, sizeof(new_vl)); /* Reset data we can't simply copy */ - new_vl.values = &(value_t) { .gauge = NAN }; + new_vl.values = &(value_t){.gauge = NAN}; new_vl.values_len = 1; new_vl.meta = NULL; /* Change the type to "cache_result" */ - sstrncpy (new_vl.type, "cache_result", sizeof (new_vl.type)); + sstrncpy(new_vl.type, "cache_result", sizeof(new_vl.type)); /* Dispatch new value lists instead of this one */ - new_vl.values[0].derive = (derive_t) vl->values[0].counter; - ssnprintf (new_vl.type_instance, sizeof (new_vl.type_instance), - "demand_data-%s", - is_hits ? "hit" : "miss"); - plugin_dispatch_values (&new_vl); - - new_vl.values[0].derive = (derive_t) vl->values[1].counter; - ssnprintf (new_vl.type_instance, sizeof (new_vl.type_instance), - "demand_metadata-%s", - is_hits ? "hit" : "miss"); - plugin_dispatch_values (&new_vl); - - new_vl.values[0].derive = (derive_t) vl->values[2].counter; - ssnprintf (new_vl.type_instance, sizeof (new_vl.type_instance), - "prefetch_data-%s", - is_hits ? "hit" : "miss"); - plugin_dispatch_values (&new_vl); - - new_vl.values[0].derive = (derive_t) vl->values[3].counter; - ssnprintf (new_vl.type_instance, sizeof (new_vl.type_instance), - "prefetch_metadata-%s", - is_hits ? "hit" : "miss"); - plugin_dispatch_values (&new_vl); + new_vl.values[0].derive = (derive_t)vl->values[0].counter; + ssnprintf(new_vl.type_instance, sizeof(new_vl.type_instance), + "demand_data-%s", is_hits ? "hit" : "miss"); + plugin_dispatch_values(&new_vl); + + new_vl.values[0].derive = (derive_t)vl->values[1].counter; + ssnprintf(new_vl.type_instance, sizeof(new_vl.type_instance), + "demand_metadata-%s", is_hits ? "hit" : "miss"); + plugin_dispatch_values(&new_vl); + + new_vl.values[0].derive = (derive_t)vl->values[2].counter; + ssnprintf(new_vl.type_instance, sizeof(new_vl.type_instance), + "prefetch_data-%s", is_hits ? "hit" : "miss"); + plugin_dispatch_values(&new_vl); + + new_vl.values[0].derive = (derive_t)vl->values[3].counter; + ssnprintf(new_vl.type_instance, sizeof(new_vl.type_instance), + "prefetch_metadata-%s", is_hits ? "hit" : "miss"); + plugin_dispatch_values(&new_vl); /* Abort processing */ return (FC_TARGET_STOP); @@ -278,7 +266,7 @@ static int v5_zfs_arc_counts (const data_set_t *ds, value_list_t *vl) /* {{{ */ * * "arc_l2_bytes" -> "io_octets-L2". */ -static int v5_zfs_arc_l2_bytes (const data_set_t *ds, value_list_t *vl) /* {{{ */ +static int v5_zfs_arc_l2_bytes(const data_set_t *ds, value_list_t *vl) /* {{{ */ { value_list_t new_vl; @@ -286,25 +274,25 @@ static int v5_zfs_arc_l2_bytes (const data_set_t *ds, value_list_t *vl) /* {{{ * return (FC_TARGET_STOP); /* Copy everything: Time, interval, host, ... */ - memcpy (&new_vl, vl, sizeof (new_vl)); + memcpy(&new_vl, vl, sizeof(new_vl)); /* Reset data we can't simply copy */ new_vl.meta = NULL; /* Change the type/-instance to "io_octets-L2" */ - sstrncpy (new_vl.type, "io_octets", sizeof (new_vl.type)); - sstrncpy (new_vl.type_instance, "L2", sizeof (new_vl.type_instance)); + sstrncpy(new_vl.type, "io_octets", sizeof(new_vl.type)); + sstrncpy(new_vl.type_instance, "L2", sizeof(new_vl.type_instance)); /* Copy the actual values. */ value_t values[] = { - { .derive = (derive_t) vl->values[0].counter }, - { .derive = (derive_t) vl->values[1].counter }, + {.derive = (derive_t)vl->values[0].counter}, + {.derive = (derive_t)vl->values[1].counter}, }; new_vl.values = values; - new_vl.values_len = STATIC_ARRAY_SIZE (values); + new_vl.values_len = STATIC_ARRAY_SIZE(values); /* Dispatch new value lists instead of this one */ - plugin_dispatch_values (&new_vl); + plugin_dispatch_values(&new_vl); /* Abort processing */ return (FC_TARGET_STOP); @@ -316,7 +304,7 @@ static int v5_zfs_arc_l2_bytes (const data_set_t *ds, value_list_t *vl) /* {{{ * * 4.* uses a separate type for this. 5.* uses the generic "cache_size" type * instead. */ -static int v5_zfs_arc_l2_size (const data_set_t *ds, value_list_t *vl) /* {{{ */ +static int v5_zfs_arc_l2_size(const data_set_t *ds, value_list_t *vl) /* {{{ */ { value_list_t new_vl; @@ -324,23 +312,23 @@ static int v5_zfs_arc_l2_size (const data_set_t *ds, value_list_t *vl) /* {{{ */ return (FC_TARGET_STOP); /* Copy everything: Time, interval, host, ... */ - memcpy (&new_vl, vl, sizeof (new_vl)); + memcpy(&new_vl, vl, sizeof(new_vl)); /* Reset data we can't simply copy */ - new_vl.values = &(value_t) { .gauge = NAN }; + new_vl.values = &(value_t){.gauge = NAN}; new_vl.values_len = 1; new_vl.meta = NULL; - new_vl.values[0].gauge = (gauge_t) vl->values[0].gauge; + new_vl.values[0].gauge = (gauge_t)vl->values[0].gauge; /* Change the type to "cache_size" */ - sstrncpy (new_vl.type, "cache_size", sizeof (new_vl.type)); + sstrncpy(new_vl.type, "cache_size", sizeof(new_vl.type)); /* Adapt the type instance */ - sstrncpy (new_vl.type_instance, "L2", sizeof (new_vl.type_instance)); + sstrncpy(new_vl.type_instance, "L2", sizeof(new_vl.type_instance)); /* Dispatch new value lists instead of this one */ - plugin_dispatch_values (&new_vl); + plugin_dispatch_values(&new_vl); /* Abort processing */ return (FC_TARGET_STOP); @@ -352,7 +340,7 @@ static int v5_zfs_arc_l2_size (const data_set_t *ds, value_list_t *vl) /* {{{ */ * "arc_ratio-L1" -> "cache_ratio-arc" * "arc_ratio-L2" -> "cache_ratio-L2" */ -static int v5_zfs_arc_ratio (const data_set_t *ds, value_list_t *vl) /* {{{ */ +static int v5_zfs_arc_ratio(const data_set_t *ds, value_list_t *vl) /* {{{ */ { value_list_t new_vl; @@ -360,24 +348,24 @@ static int v5_zfs_arc_ratio (const data_set_t *ds, value_list_t *vl) /* {{{ */ return (FC_TARGET_STOP); /* Copy everything: Time, interval, host, ... */ - memcpy (&new_vl, vl, sizeof (new_vl)); + memcpy(&new_vl, vl, sizeof(new_vl)); /* Reset data we can't simply copy */ - new_vl.values = &(value_t) { .gauge = NAN }; + new_vl.values = &(value_t){.gauge = NAN}; new_vl.values_len = 1; new_vl.meta = NULL; - new_vl.values[0].gauge = (gauge_t) vl->values[0].gauge; + new_vl.values[0].gauge = (gauge_t)vl->values[0].gauge; /* Change the type to "cache_ratio" */ - sstrncpy (new_vl.type, "cache_ratio", sizeof (new_vl.type)); + sstrncpy(new_vl.type, "cache_ratio", sizeof(new_vl.type)); /* Adapt the type instance */ - if (strcmp ("L1", vl->type_instance) == 0) - sstrncpy (new_vl.type_instance, "arc", sizeof (new_vl.type_instance)); + if (strcmp("L1", vl->type_instance) == 0) + sstrncpy(new_vl.type_instance, "arc", sizeof(new_vl.type_instance)); /* Dispatch new value lists instead of this one */ - plugin_dispatch_values (&new_vl); + plugin_dispatch_values(&new_vl); /* Abort processing */ return (FC_TARGET_STOP); @@ -389,7 +377,7 @@ static int v5_zfs_arc_ratio (const data_set_t *ds, value_list_t *vl) /* {{{ */ * 4.* uses the "arc_size" type with four data sources. In 5.* this has been * replaces with the "cache_size" type and static data has been removed. */ -static int v5_zfs_arc_size (const data_set_t *ds, value_list_t *vl) /* {{{ */ +static int v5_zfs_arc_size(const data_set_t *ds, value_list_t *vl) /* {{{ */ { value_list_t new_vl; @@ -397,74 +385,71 @@ static int v5_zfs_arc_size (const data_set_t *ds, value_list_t *vl) /* {{{ */ return (FC_TARGET_STOP); /* Copy everything: Time, interval, host, ... */ - memcpy (&new_vl, vl, sizeof (new_vl)); + memcpy(&new_vl, vl, sizeof(new_vl)); /* Reset data we can't simply copy */ - new_vl.values = &(value_t) { .gauge = NAN }; + new_vl.values = &(value_t){.gauge = NAN}; new_vl.values_len = 1; new_vl.meta = NULL; /* Change the type to "cache_size" */ - sstrncpy (new_vl.type, "cache_size", sizeof (new_vl.type)); + sstrncpy(new_vl.type, "cache_size", sizeof(new_vl.type)); /* Dispatch new value lists instead of this one */ - new_vl.values[0].derive = (derive_t) vl->values[0].counter; - sstrncpy (new_vl.type_instance, "arc", sizeof (new_vl.type_instance)); - plugin_dispatch_values (&new_vl); + new_vl.values[0].derive = (derive_t)vl->values[0].counter; + sstrncpy(new_vl.type_instance, "arc", sizeof(new_vl.type_instance)); + plugin_dispatch_values(&new_vl); /* Abort processing */ return (FC_TARGET_STOP); } /* }}} int v5_zfs_arc_size */ -static int v5_destroy (void **user_data) /* {{{ */ +static int v5_destroy(void **user_data) /* {{{ */ { return (0); } /* }}} int v5_destroy */ -static int v5_create (const oconfig_item_t *ci, void **user_data) /* {{{ */ +static int v5_create(const oconfig_item_t *ci, void **user_data) /* {{{ */ { *user_data = NULL; return (0); } /* }}} int v5_create */ -static int v5_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */ - notification_meta_t __attribute__((unused)) **meta, - void __attribute__((unused)) **user_data) -{ +static int v5_invoke(const data_set_t *ds, value_list_t *vl, /* {{{ */ + notification_meta_t __attribute__((unused)) * *meta, + void __attribute__((unused)) * *user_data) { if ((ds == NULL) || (vl == NULL) || (user_data == NULL)) return (-EINVAL); - if (strcmp ("df", vl->type) == 0) - return (v5_df (ds, vl)); - else if (strcmp ("interface", vl->plugin) == 0) - return (v5_interface (ds, vl)); - else if (strcmp ("mysql_qcache", vl->type) == 0) - return (v5_mysql_qcache (ds, vl)); - else if (strcmp ("mysql_threads", vl->type) == 0) - return (v5_mysql_threads (ds, vl)); - else if (strcmp ("arc_counts", vl->type) == 0) - return (v5_zfs_arc_counts (ds, vl)); - else if (strcmp ("arc_l2_bytes", vl->type) == 0) - return (v5_zfs_arc_l2_bytes (ds, vl)); - else if (strcmp ("arc_l2_size", vl->type) == 0) - return (v5_zfs_arc_l2_size (ds, vl)); - else if (strcmp ("arc_ratio", vl->type) == 0) - return (v5_zfs_arc_ratio (ds, vl)); - else if (strcmp ("arc_size", vl->type) == 0) - return (v5_zfs_arc_size (ds, vl)); + if (strcmp("df", vl->type) == 0) + return (v5_df(ds, vl)); + else if (strcmp("interface", vl->plugin) == 0) + return (v5_interface(ds, vl)); + else if (strcmp("mysql_qcache", vl->type) == 0) + return (v5_mysql_qcache(ds, vl)); + else if (strcmp("mysql_threads", vl->type) == 0) + return (v5_mysql_threads(ds, vl)); + else if (strcmp("arc_counts", vl->type) == 0) + return (v5_zfs_arc_counts(ds, vl)); + else if (strcmp("arc_l2_bytes", vl->type) == 0) + return (v5_zfs_arc_l2_bytes(ds, vl)); + else if (strcmp("arc_l2_size", vl->type) == 0) + return (v5_zfs_arc_l2_size(ds, vl)); + else if (strcmp("arc_ratio", vl->type) == 0) + return (v5_zfs_arc_ratio(ds, vl)); + else if (strcmp("arc_size", vl->type) == 0) + return (v5_zfs_arc_size(ds, vl)); return (FC_TARGET_CONTINUE); } /* }}} int v5_invoke */ -void module_register (void) -{ - target_proc_t tproc = { 0 }; +void module_register(void) { + target_proc_t tproc = {0}; - tproc.create = v5_create; - tproc.destroy = v5_destroy; - tproc.invoke = v5_invoke; - fc_register_target ("v5upgrade", tproc); + tproc.create = v5_create; + tproc.destroy = v5_destroy; + tproc.invoke = v5_invoke; + fc_register_target("v5upgrade", tproc); } /* module_register */ /* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ - diff --git a/src/tcpconns.c b/src/tcpconns.c index 8c93405e..f949d34e 100644 --- a/src/tcpconns.c +++ b/src/tcpconns.c @@ -67,69 +67,69 @@ #endif #if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_LIBKVM_NLIST && !KERNEL_AIX -# error "No applicable input method." +#error "No applicable input method." #endif #if KERNEL_LINUX -# include -# include +#include +#include #if HAVE_LINUX_INET_DIAG_H -# include +#include #endif -# include +#include /* #endif KERNEL_LINUX */ #elif HAVE_SYSCTLBYNAME -# include -# include +#include +#include /* Some includes needed for compiling on FreeBSD */ #include #if HAVE_SYS_TYPES_H -# include +#include #endif #if HAVE_NET_IF_H -# include +#include #endif -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* #endif HAVE_SYSCTLBYNAME */ /* This is for OpenBSD and NetBSD. */ #elif HAVE_LIBKVM_NLIST -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# if !defined(HAVE_BSD_NLIST_H) || !HAVE_BSD_NLIST_H -# include -# else /* HAVE_BSD_NLIST_H */ -# include -# endif -# include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(HAVE_BSD_NLIST_H) || !HAVE_BSD_NLIST_H +#include +#else /* HAVE_BSD_NLIST_H */ +#include +#endif +#include /* #endif HAVE_LIBKVM_NLIST */ #elif KERNEL_AIX -# include -# include +#include +#include #endif /* KERNEL_AIX */ #if KERNEL_LINUX @@ -140,92 +140,59 @@ struct nlreq { }; #endif -static const char *tcp_state[] = -{ - "", /* 0 */ - "ESTABLISHED", - "SYN_SENT", - "SYN_RECV", - "FIN_WAIT1", - "FIN_WAIT2", - "TIME_WAIT", - "CLOSED", - "CLOSE_WAIT", - "LAST_ACK", - "LISTEN", /* 10 */ - "CLOSING" -}; - -# define TCP_STATE_LISTEN 10 -# define TCP_STATE_MIN 1 -# define TCP_STATE_MAX 11 +static const char *tcp_state[] = {"", /* 0 */ + "ESTABLISHED", + "SYN_SENT", + "SYN_RECV", + "FIN_WAIT1", + "FIN_WAIT2", + "TIME_WAIT", + "CLOSED", + "CLOSE_WAIT", + "LAST_ACK", + "LISTEN", /* 10 */ + "CLOSING"}; + +#define TCP_STATE_LISTEN 10 +#define TCP_STATE_MIN 1 +#define TCP_STATE_MAX 11 /* #endif KERNEL_LINUX */ #elif HAVE_SYSCTLBYNAME -static const char *tcp_state[] = -{ - "CLOSED", - "LISTEN", - "SYN_SENT", - "SYN_RECV", - "ESTABLISHED", - "CLOSE_WAIT", - "FIN_WAIT1", - "CLOSING", - "LAST_ACK", - "FIN_WAIT2", - "TIME_WAIT" -}; - -# define TCP_STATE_LISTEN 1 -# define TCP_STATE_MIN 0 -# define TCP_STATE_MAX 10 +static const char *tcp_state[] = {"CLOSED", "LISTEN", "SYN_SENT", + "SYN_RECV", "ESTABLISHED", "CLOSE_WAIT", + "FIN_WAIT1", "CLOSING", "LAST_ACK", + "FIN_WAIT2", "TIME_WAIT"}; + +#define TCP_STATE_LISTEN 1 +#define TCP_STATE_MIN 0 +#define TCP_STATE_MAX 10 /* #endif HAVE_SYSCTLBYNAME */ #elif HAVE_LIBKVM_NLIST -static const char *tcp_state[] = -{ - "CLOSED", - "LISTEN", - "SYN_SENT", - "SYN_RECV", - "ESTABLISHED", - "CLOSE_WAIT", - "FIN_WAIT1", - "CLOSING", - "LAST_ACK", - "FIN_WAIT2", - "TIME_WAIT" -}; +static const char *tcp_state[] = {"CLOSED", "LISTEN", "SYN_SENT", + "SYN_RECV", "ESTABLISHED", "CLOSE_WAIT", + "FIN_WAIT1", "CLOSING", "LAST_ACK", + "FIN_WAIT2", "TIME_WAIT"}; static kvm_t *kvmd; -static u_long inpcbtable_off = 0; +static u_long inpcbtable_off = 0; struct inpcbtable *inpcbtable_ptr = NULL; -# define TCP_STATE_LISTEN 1 -# define TCP_STATE_MIN 1 -# define TCP_STATE_MAX 10 +#define TCP_STATE_LISTEN 1 +#define TCP_STATE_MIN 1 +#define TCP_STATE_MAX 10 /* #endif HAVE_LIBKVM_NLIST */ #elif KERNEL_AIX -static const char *tcp_state[] = -{ - "CLOSED", - "LISTEN", - "SYN_SENT", - "SYN_RECV", - "ESTABLISHED", - "CLOSE_WAIT", - "FIN_WAIT1", - "CLOSING", - "LAST_ACK", - "FIN_WAIT2", - "TIME_WAIT" -}; +static const char *tcp_state[] = {"CLOSED", "LISTEN", "SYN_SENT", + "SYN_RECV", "ESTABLISHED", "CLOSE_WAIT", + "FIN_WAIT1", "CLOSING", "LAST_ACK", + "FIN_WAIT2", "TIME_WAIT"}; -# define TCP_STATE_LISTEN 1 -# define TCP_STATE_MIN 0 -# define TCP_STATE_MAX 10 +#define TCP_STATE_LISTEN 1 +#define TCP_STATE_MIN 0 +#define TCP_STATE_MAX 10 struct netinfo_conn { uint32_t unknow1[2]; @@ -245,16 +212,15 @@ struct netinfo_header { unsigned int size; }; -# define NETINFO_TCP 3 -extern int netinfo (int proto, void *data, int *size, int n); +#define NETINFO_TCP 3 +extern int netinfo(int proto, void *data, int *size, int n); #endif /* KERNEL_AIX */ -#define PORT_COLLECT_LOCAL 0x01 +#define PORT_COLLECT_LOCAL 0x01 #define PORT_COLLECT_REMOTE 0x02 -#define PORT_IS_LISTENING 0x04 +#define PORT_IS_LISTENING 0x04 -typedef struct port_entry_s -{ +typedef struct port_entry_s { uint16_t port; uint16_t flags; uint32_t count_local[TCP_STATE_MAX + 1]; @@ -262,14 +228,9 @@ typedef struct port_entry_s struct port_entry_s *next; } port_entry_t; -static const char *config_keys[] = -{ - "ListeningPorts", - "LocalPort", - "RemotePort", - "AllPortsSummary" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"ListeningPorts", "LocalPort", "RemotePort", + "AllPortsSummary"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static int port_collect_listening = 0; static int port_collect_total = 0; @@ -284,104 +245,87 @@ static uint32_t count_total[TCP_STATE_MAX + 1]; static uint32_t sequence_number = 0; #endif -static enum -{ - SRC_DUNNO, - SRC_NETLINK, - SRC_PROC -} linux_source = SRC_DUNNO; +static enum { SRC_DUNNO, SRC_NETLINK, SRC_PROC } linux_source = SRC_DUNNO; #endif -static void conn_prepare_vl (value_list_t *vl, value_t *values) -{ +static void conn_prepare_vl(value_list_t *vl, value_t *values) { vl->values = values; vl->values_len = 1; - sstrncpy (vl->plugin, "tcpconns", sizeof (vl->plugin)); - sstrncpy (vl->type, "tcp_connections", sizeof (vl->type)); + sstrncpy(vl->plugin, "tcpconns", sizeof(vl->plugin)); + sstrncpy(vl->type, "tcp_connections", sizeof(vl->type)); } -static void conn_submit_port_entry (port_entry_t *pe) -{ +static void conn_submit_port_entry(port_entry_t *pe) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; - conn_prepare_vl (&vl, values); + conn_prepare_vl(&vl, values); - if (((port_collect_listening != 0) && (pe->flags & PORT_IS_LISTENING)) - || (pe->flags & PORT_COLLECT_LOCAL)) - { - ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), - "%"PRIu16"-local", pe->port); + if (((port_collect_listening != 0) && (pe->flags & PORT_IS_LISTENING)) || + (pe->flags & PORT_COLLECT_LOCAL)) { + ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), + "%" PRIu16 "-local", pe->port); - for (int i = 1; i <= TCP_STATE_MAX; i++) - { + for (int i = 1; i <= TCP_STATE_MAX; i++) { vl.values[0].gauge = pe->count_local[i]; - sstrncpy (vl.type_instance, tcp_state[i], sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, tcp_state[i], sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } } - if (pe->flags & PORT_COLLECT_REMOTE) - { - ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), - "%"PRIu16"-remote", pe->port); + if (pe->flags & PORT_COLLECT_REMOTE) { + ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), + "%" PRIu16 "-remote", pe->port); - for (int i = 1; i <= TCP_STATE_MAX; i++) - { + for (int i = 1; i <= TCP_STATE_MAX; i++) { vl.values[0].gauge = pe->count_remote[i]; - sstrncpy (vl.type_instance, tcp_state[i], sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, tcp_state[i], sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } } } /* void conn_submit */ -static void conn_submit_port_total (void) -{ +static void conn_submit_port_total(void) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; - conn_prepare_vl (&vl, values); + conn_prepare_vl(&vl, values); - sstrncpy (vl.plugin_instance, "all", sizeof (vl.plugin_instance)); + sstrncpy(vl.plugin_instance, "all", sizeof(vl.plugin_instance)); - for (int i = 1; i <= TCP_STATE_MAX; i++) - { + for (int i = 1; i <= TCP_STATE_MAX; i++) { vl.values[0].gauge = count_total[i]; - sstrncpy (vl.type_instance, tcp_state[i], sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, tcp_state[i], sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } } -static void conn_submit_all (void) -{ +static void conn_submit_all(void) { if (port_collect_total) - conn_submit_port_total (); + conn_submit_port_total(); for (port_entry_t *pe = port_list_head; pe != NULL; pe = pe->next) - conn_submit_port_entry (pe); + conn_submit_port_entry(pe); } /* void conn_submit_all */ -static port_entry_t *conn_get_port_entry (uint16_t port, int create) -{ +static port_entry_t *conn_get_port_entry(uint16_t port, int create) { port_entry_t *ret; ret = port_list_head; - while (ret != NULL) - { + while (ret != NULL) { if (ret->port == port) break; ret = ret->next; } - if ((ret == NULL) && (create != 0)) - { - ret = calloc (1, sizeof (*ret)); + if ((ret == NULL) && (create != 0)) { + ret = calloc(1, sizeof(*ret)); if (ret == NULL) return (NULL); @@ -395,39 +339,36 @@ static port_entry_t *conn_get_port_entry (uint16_t port, int create) /* Removes ports that were added automatically due to the `ListeningPorts' * setting but which are no longer listening. */ -static void conn_reset_port_entry (void) -{ +static void conn_reset_port_entry(void) { port_entry_t *prev = NULL; port_entry_t *pe = port_list_head; - memset (&count_total, '\0', sizeof(count_total)); + memset(&count_total, '\0', sizeof(count_total)); - while (pe != NULL) - { + while (pe != NULL) { /* If this entry was created while reading the files (ant not when handling * the configuration) remove it now. */ - if ((pe->flags & (PORT_COLLECT_LOCAL - | PORT_COLLECT_REMOTE - | PORT_IS_LISTENING)) == 0) - { + if ((pe->flags & + (PORT_COLLECT_LOCAL | PORT_COLLECT_REMOTE | PORT_IS_LISTENING)) == 0) { port_entry_t *next = pe->next; - DEBUG ("tcpconns plugin: Removing temporary entry " - "for listening port %"PRIu16, pe->port); + DEBUG("tcpconns plugin: Removing temporary entry " + "for listening port %" PRIu16, + pe->port); if (prev == NULL) port_list_head = next; else prev->next = next; - sfree (pe); + sfree(pe); pe = next; continue; } - memset (pe->count_local, '\0', sizeof (pe->count_local)); - memset (pe->count_remote, '\0', sizeof (pe->count_remote)); + memset(pe->count_local, '\0', sizeof(pe->count_local)); + memset(pe->count_remote, '\0', sizeof(pe->count_remote)); pe->flags &= ~PORT_IS_LISTENING; prev = pe; @@ -435,39 +376,38 @@ static void conn_reset_port_entry (void) } } /* void conn_reset_port_entry */ -static int conn_handle_ports (uint16_t port_local, uint16_t port_remote, uint8_t state) -{ +static int conn_handle_ports(uint16_t port_local, uint16_t port_remote, + uint8_t state) { port_entry_t *pe = NULL; if ((state > TCP_STATE_MAX) #if TCP_STATE_MIN > 0 || (state < TCP_STATE_MIN) #endif - ) - { - NOTICE ("tcpconns plugin: Ignoring connection with " - "unknown state 0x%02"PRIx8".", state); + ) { + NOTICE("tcpconns plugin: Ignoring connection with " + "unknown state 0x%02" PRIx8 ".", + state); return (-1); } count_total[state]++; /* Listening sockets */ - if ((state == TCP_STATE_LISTEN) && (port_collect_listening != 0)) - { - pe = conn_get_port_entry (port_local, 1 /* create */); + if ((state == TCP_STATE_LISTEN) && (port_collect_listening != 0)) { + pe = conn_get_port_entry(port_local, 1 /* create */); if (pe != NULL) pe->flags |= PORT_IS_LISTENING; } - DEBUG ("tcpconns plugin: Connection %"PRIu16" <-> %"PRIu16" (%s)", - port_local, port_remote, tcp_state[state]); + DEBUG("tcpconns plugin: Connection %" PRIu16 " <-> %" PRIu16 " (%s)", + port_local, port_remote, tcp_state[state]); - pe = conn_get_port_entry (port_local, 0 /* no create */); + pe = conn_get_port_entry(port_local, 0 /* no create */); if (pe != NULL) pe->count_local[state]++; - pe = conn_get_port_entry (port_remote, 0 /* no create */); + pe = conn_get_port_entry(port_remote, 0 /* no create */); if (pe != NULL) pe->count_remote[state]++; @@ -477,8 +417,7 @@ static int conn_handle_ports (uint16_t port_local, uint16_t port_remote, uint8_t #if KERNEL_LINUX /* Returns zero on success, less than zero on socket error and greater than * zero on other errors. */ -static int conn_read_netlink (void) -{ +static int conn_read_netlink(void) { #if HAVE_STRUCT_LINUX_INET_DIAG_REQ int fd; struct inet_diag_msg *r; @@ -487,124 +426,104 @@ static int conn_read_netlink (void) /* If this fails, it's likely a permission problem. We'll fall back to * reading this information from files below. */ fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_INET_DIAG); - if (fd < 0) - { - ERROR ("tcpconns plugin: conn_read_netlink: socket(AF_NETLINK, SOCK_RAW, " - "NETLINK_INET_DIAG) failed: %s", - sstrerror (errno, buf, sizeof (buf))); + if (fd < 0) { + ERROR("tcpconns plugin: conn_read_netlink: socket(AF_NETLINK, SOCK_RAW, " + "NETLINK_INET_DIAG) failed: %s", + sstrerror(errno, buf, sizeof(buf))); return (-1); } - struct sockaddr_nl nladdr = { - .nl_family = AF_NETLINK - }; + struct sockaddr_nl nladdr = {.nl_family = AF_NETLINK}; struct nlreq req = { - .nlh.nlmsg_len = sizeof(req), - .nlh.nlmsg_type = TCPDIAG_GETSOCK, - /* NLM_F_ROOT: return the complete table instead of a single entry. - * NLM_F_MATCH: return all entries matching criteria (not implemented) - * NLM_F_REQUEST: must be set on all request messages */ - .nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST, - .nlh.nlmsg_pid = 0, - /* The sequence_number is used to track our messages. Since netlink is not - * reliable, we don't want to end up with a corrupt or incomplete old - * message in case the system is/was out of memory. */ - .nlh.nlmsg_seq = ++sequence_number, - .r.idiag_family = AF_INET, - .r.idiag_states = 0xfff, - .r.idiag_ext = 0 - }; - - struct iovec iov = { - .iov_base = &req, - .iov_len = sizeof(req) - }; - - struct msghdr msg = { - .msg_name = (void*)&nladdr, - .msg_namelen = sizeof(nladdr), - .msg_iov = &iov, - .msg_iovlen = 1 - }; - - if (sendmsg (fd, &msg, 0) < 0) - { - ERROR ("tcpconns plugin: conn_read_netlink: sendmsg(2) failed: %s", - sstrerror (errno, buf, sizeof (buf))); - close (fd); + .nlh.nlmsg_len = sizeof(req), + .nlh.nlmsg_type = TCPDIAG_GETSOCK, + /* NLM_F_ROOT: return the complete table instead of a single entry. + * NLM_F_MATCH: return all entries matching criteria (not implemented) + * NLM_F_REQUEST: must be set on all request messages */ + .nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST, + .nlh.nlmsg_pid = 0, + /* The sequence_number is used to track our messages. Since netlink is not + * reliable, we don't want to end up with a corrupt or incomplete old + * message in case the system is/was out of memory. */ + .nlh.nlmsg_seq = ++sequence_number, + .r.idiag_family = AF_INET, + .r.idiag_states = 0xfff, + .r.idiag_ext = 0}; + + struct iovec iov = {.iov_base = &req, .iov_len = sizeof(req)}; + + struct msghdr msg = {.msg_name = (void *)&nladdr, + .msg_namelen = sizeof(nladdr), + .msg_iov = &iov, + .msg_iovlen = 1}; + + if (sendmsg(fd, &msg, 0) < 0) { + ERROR("tcpconns plugin: conn_read_netlink: sendmsg(2) failed: %s", + sstrerror(errno, buf, sizeof(buf))); + close(fd); return (-1); } iov.iov_base = buf; iov.iov_len = sizeof(buf); - while (1) - { + while (1) { int status; struct nlmsghdr *h; memset(&msg, 0, sizeof(msg)); - msg.msg_name = (void*)&nladdr; + msg.msg_name = (void *)&nladdr; msg.msg_namelen = sizeof(nladdr); msg.msg_iov = &iov; msg.msg_iovlen = 1; - status = recvmsg(fd, (void *) &msg, /* flags = */ 0); - if (status < 0) - { + status = recvmsg(fd, (void *)&msg, /* flags = */ 0); + if (status < 0) { if ((errno == EINTR) || (errno == EAGAIN)) continue; - ERROR ("tcpconns plugin: conn_read_netlink: recvmsg(2) failed: %s", - sstrerror (errno, buf, sizeof (buf))); - close (fd); + ERROR("tcpconns plugin: conn_read_netlink: recvmsg(2) failed: %s", + sstrerror(errno, buf, sizeof(buf))); + close(fd); return (-1); - } - else if (status == 0) - { - close (fd); - DEBUG ("tcpconns plugin: conn_read_netlink: Unexpected zero-sized " - "reply from netlink socket."); + } else if (status == 0) { + close(fd); + DEBUG("tcpconns plugin: conn_read_netlink: Unexpected zero-sized " + "reply from netlink socket."); return (0); } - h = (struct nlmsghdr*)buf; - while (NLMSG_OK(h, status)) - { - if (h->nlmsg_seq != sequence_number) - { - h = NLMSG_NEXT(h, status); - continue; + h = (struct nlmsghdr *)buf; + while (NLMSG_OK(h, status)) { + if (h->nlmsg_seq != sequence_number) { + h = NLMSG_NEXT(h, status); + continue; } - if (h->nlmsg_type == NLMSG_DONE) - { - close (fd); - return (0); - } - else if (h->nlmsg_type == NLMSG_ERROR) - { - struct nlmsgerr *msg_error; + if (h->nlmsg_type == NLMSG_DONE) { + close(fd); + return (0); + } else if (h->nlmsg_type == NLMSG_ERROR) { + struct nlmsgerr *msg_error; - msg_error = NLMSG_DATA(h); - WARNING ("tcpconns plugin: conn_read_netlink: Received error %i.", - msg_error->error); + msg_error = NLMSG_DATA(h); + WARNING("tcpconns plugin: conn_read_netlink: Received error %i.", + msg_error->error); - close (fd); - return (1); + close(fd); + return (1); } r = NLMSG_DATA(h); /* This code does not (need to) distinguish between IPv4 and IPv6. */ - conn_handle_ports (ntohs(r->id.idiag_sport), - ntohs(r->id.idiag_dport), - r->idiag_state); + conn_handle_ports(ntohs(r->id.idiag_sport), ntohs(r->id.idiag_dport), + r->idiag_state); h = NLMSG_NEXT(h, status); } /* while (NLMSG_OK) */ - } /* while (1) */ + } /* while (1) */ /* Not reached because the while() loop above handles the exit condition. */ return (0); @@ -613,10 +532,9 @@ static int conn_read_netlink (void) #endif /* HAVE_STRUCT_LINUX_INET_DIAG_REQ */ } /* int conn_read_netlink */ -static int conn_handle_line (char *buffer) -{ +static int conn_handle_line(char *buffer) { char *fields[32]; - int fields_len; + int fields_len; char *endptr; @@ -627,22 +545,21 @@ static int conn_handle_line (char *buffer) uint8_t state; - int buffer_len = strlen (buffer); + int buffer_len = strlen(buffer); while ((buffer_len > 0) && (buffer[buffer_len - 1] < 32)) buffer[--buffer_len] = '\0'; if (buffer_len <= 0) return (-1); - fields_len = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields)); - if (fields_len < 12) - { - DEBUG ("tcpconns plugin: Got %i fields, expected at least 12.", fields_len); + fields_len = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + if (fields_len < 12) { + DEBUG("tcpconns plugin: Got %i fields, expected at least 12.", fields_len); return (-1); } - port_local_str = strchr (fields[1], ':'); - port_remote_str = strchr (fields[2], ':'); + port_local_str = strchr(fields[1], ':'); + port_remote_str = strchr(fields[2], ':'); if ((port_local_str == NULL) || (port_remote_str == NULL)) return (-1); @@ -652,38 +569,36 @@ static int conn_handle_line (char *buffer) return (-1); endptr = NULL; - port_local = (uint16_t) strtol (port_local_str, &endptr, 16); + port_local = (uint16_t)strtol(port_local_str, &endptr, 16); if ((endptr == NULL) || (*endptr != '\0')) return (-1); endptr = NULL; - port_remote = (uint16_t) strtol (port_remote_str, &endptr, 16); + port_remote = (uint16_t)strtol(port_remote_str, &endptr, 16); if ((endptr == NULL) || (*endptr != '\0')) return (-1); endptr = NULL; - state = (uint8_t) strtol (fields[3], &endptr, 16); + state = (uint8_t)strtol(fields[3], &endptr, 16); if ((endptr == NULL) || (*endptr != '\0')) return (-1); - return (conn_handle_ports (port_local, port_remote, state)); + return (conn_handle_ports(port_local, port_remote, state)); } /* int conn_handle_line */ -static int conn_read_file (const char *file) -{ +static int conn_read_file(const char *file) { FILE *fh; char buffer[1024]; - fh = fopen (file, "r"); + fh = fopen(file, "r"); if (fh == NULL) return (-1); - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - conn_handle_line (buffer); + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + conn_handle_line(buffer); } /* while (fgets) */ - fclose (fh); + fclose(fh); return (0); } /* int conn_read_file */ @@ -695,48 +610,38 @@ static int conn_read_file (const char *file) #elif HAVE_LIBKVM_NLIST #endif /* HAVE_LIBKVM_NLIST */ -static int conn_config (const char *key, const char *value) -{ - if (strcasecmp (key, "ListeningPorts") == 0) - { - if (IS_TRUE (value)) +static int conn_config(const char *key, const char *value) { + if (strcasecmp(key, "ListeningPorts") == 0) { + if (IS_TRUE(value)) port_collect_listening = 1; else port_collect_listening = 0; - } - else if ((strcasecmp (key, "LocalPort") == 0) - || (strcasecmp (key, "RemotePort") == 0)) - { - port_entry_t *pe; - int port = atoi (value); - - if ((port < 1) || (port > 65535)) - { - ERROR ("tcpconns plugin: Invalid port: %i", port); - return (1); - } + } else if ((strcasecmp(key, "LocalPort") == 0) || + (strcasecmp(key, "RemotePort") == 0)) { + port_entry_t *pe; + int port = atoi(value); + + if ((port < 1) || (port > 65535)) { + ERROR("tcpconns plugin: Invalid port: %i", port); + return (1); + } - pe = conn_get_port_entry ((uint16_t) port, 1 /* create */); - if (pe == NULL) - { - ERROR ("tcpconns plugin: conn_get_port_entry failed."); - return (1); - } + pe = conn_get_port_entry((uint16_t)port, 1 /* create */); + if (pe == NULL) { + ERROR("tcpconns plugin: conn_get_port_entry failed."); + return (1); + } - if (strcasecmp (key, "LocalPort") == 0) - pe->flags |= PORT_COLLECT_LOCAL; - else - pe->flags |= PORT_COLLECT_REMOTE; - } - else if (strcasecmp (key, "AllPortsSummary") == 0) - { - if (IS_TRUE (value)) + if (strcasecmp(key, "LocalPort") == 0) + pe->flags |= PORT_COLLECT_LOCAL; + else + pe->flags |= PORT_COLLECT_REMOTE; + } else if (strcasecmp(key, "AllPortsSummary") == 0) { + if (IS_TRUE(value)) port_collect_total = 1; else port_collect_total = 0; - } - else - { + } else { return (-1); } @@ -744,53 +649,44 @@ static int conn_config (const char *key, const char *value) } /* int conn_config */ #if KERNEL_LINUX -static int conn_init (void) -{ +static int conn_init(void) { if (port_collect_total == 0 && port_list_head == NULL) port_collect_listening = 1; return (0); } /* int conn_init */ -static int conn_read (void) -{ +static int conn_read(void) { int status; - conn_reset_port_entry (); + conn_reset_port_entry(); - if (linux_source == SRC_NETLINK) - { - status = conn_read_netlink (); - } - else if (linux_source == SRC_PROC) - { + if (linux_source == SRC_NETLINK) { + status = conn_read_netlink(); + } else if (linux_source == SRC_PROC) { int errors_num = 0; - if (conn_read_file ("/proc/net/tcp") != 0) + if (conn_read_file("/proc/net/tcp") != 0) errors_num++; - if (conn_read_file ("/proc/net/tcp6") != 0) + if (conn_read_file("/proc/net/tcp6") != 0) errors_num++; if (errors_num < 2) status = 0; else status = ENOENT; - } - else /* if (linux_source == SRC_DUNNO) */ + } else /* if (linux_source == SRC_DUNNO) */ { /* Try to use netlink for getting this data, it is _much_ faster on systems * with a large amount of connections. */ - status = conn_read_netlink (); - if (status == 0) - { - INFO ("tcpconns plugin: Reading from netlink succeeded. " - "Will use the netlink method from now on."); + status = conn_read_netlink(); + if (status == 0) { + INFO("tcpconns plugin: Reading from netlink succeeded. " + "Will use the netlink method from now on."); linux_source = SRC_NETLINK; - } - else - { - INFO ("tcpconns plugin: Reading from netlink failed. " - "Will read from /proc from now on."); + } else { + INFO("tcpconns plugin: Reading from netlink failed. " + "Will read from /proc from now on."); linux_source = SRC_PROC; /* return success here to avoid the "plugin failed" message. */ @@ -799,7 +695,7 @@ static int conn_read (void) } if (status == 0) - conn_submit_all (); + conn_submit_all(); else return (status); @@ -808,55 +704,50 @@ static int conn_read (void) /* #endif KERNEL_LINUX */ #elif HAVE_SYSCTLBYNAME -static int conn_read (void) -{ +static int conn_read(void) { int status; char *buffer; - size_t buffer_len;; + size_t buffer_len; + ; struct xinpgen *in_orig; struct xinpgen *in_ptr; - conn_reset_port_entry (); + conn_reset_port_entry(); buffer_len = 0; - status = sysctlbyname ("net.inet.tcp.pcblist", NULL, &buffer_len, 0, 0); - if (status < 0) - { - ERROR ("tcpconns plugin: sysctlbyname failed."); + status = sysctlbyname("net.inet.tcp.pcblist", NULL, &buffer_len, 0, 0); + if (status < 0) { + ERROR("tcpconns plugin: sysctlbyname failed."); return (-1); } - buffer = malloc (buffer_len); - if (buffer == NULL) - { - ERROR ("tcpconns plugin: malloc failed."); + buffer = malloc(buffer_len); + if (buffer == NULL) { + ERROR("tcpconns plugin: malloc failed."); return (-1); } - status = sysctlbyname ("net.inet.tcp.pcblist", buffer, &buffer_len, 0, 0); - if (status < 0) - { - ERROR ("tcpconns plugin: sysctlbyname failed."); - sfree (buffer); + status = sysctlbyname("net.inet.tcp.pcblist", buffer, &buffer_len, 0, 0); + if (status < 0) { + ERROR("tcpconns plugin: sysctlbyname failed."); + sfree(buffer); return (-1); } - if (buffer_len <= sizeof (struct xinpgen)) - { - ERROR ("tcpconns plugin: (buffer_len <= sizeof (struct xinpgen))"); - sfree (buffer); + if (buffer_len <= sizeof(struct xinpgen)) { + ERROR("tcpconns plugin: (buffer_len <= sizeof (struct xinpgen))"); + sfree(buffer); return (-1); } - in_orig = (struct xinpgen *) buffer; - for (in_ptr = (struct xinpgen *) (((char *) in_orig) + in_orig->xig_len); - in_ptr->xig_len > sizeof (struct xinpgen); - in_ptr = (struct xinpgen *) (((char *) in_ptr) + in_ptr->xig_len)) - { - struct tcpcb *tp = &((struct xtcpcb *) in_ptr)->xt_tp; - struct inpcb *inp = &((struct xtcpcb *) in_ptr)->xt_inp; - struct xsocket *so = &((struct xtcpcb *) in_ptr)->xt_socket; + in_orig = (struct xinpgen *)buffer; + for (in_ptr = (struct xinpgen *)(((char *)in_orig) + in_orig->xig_len); + in_ptr->xig_len > sizeof(struct xinpgen); + in_ptr = (struct xinpgen *)(((char *)in_ptr) + in_ptr->xig_len)) { + struct tcpcb *tp = &((struct xtcpcb *)in_ptr)->xt_tp; + struct inpcb *inp = &((struct xtcpcb *)in_ptr)->xt_inp; + struct xsocket *so = &((struct xtcpcb *)in_ptr)->xt_socket; /* Ignore non-TCP sockets */ if (so->xso_protocol != IPPROTO_TCP) @@ -866,81 +757,72 @@ static int conn_read (void) if (inp->inp_gencnt > in_orig->xig_gen) continue; - if (((inp->inp_vflag & INP_IPV4) == 0) - && ((inp->inp_vflag & INP_IPV6) == 0)) + if (((inp->inp_vflag & INP_IPV4) == 0) && + ((inp->inp_vflag & INP_IPV6) == 0)) continue; - conn_handle_ports (ntohs (inp->inp_lport), ntohs (inp->inp_fport), - tp->t_state); + conn_handle_ports(ntohs(inp->inp_lport), ntohs(inp->inp_fport), + tp->t_state); } /* for (in_ptr) */ in_orig = NULL; in_ptr = NULL; - sfree (buffer); + sfree(buffer); - conn_submit_all (); + conn_submit_all(); return (0); } /* int conn_read */ -/* #endif HAVE_SYSCTLBYNAME */ + /* #endif HAVE_SYSCTLBYNAME */ #elif HAVE_LIBKVM_NLIST -static int kread (u_long addr, void *buf, int size) -{ +static int kread(u_long addr, void *buf, int size) { int status; - status = kvm_read (kvmd, addr, buf, size); - if (status != size) - { - ERROR ("tcpconns plugin: kvm_read failed (got %i, expected %i): %s\n", - status, size, kvm_geterr (kvmd)); + status = kvm_read(kvmd, addr, buf, size); + if (status != size) { + ERROR("tcpconns plugin: kvm_read failed (got %i, expected %i): %s\n", + status, size, kvm_geterr(kvmd)); return (-1); } return (0); } /* int kread */ -static int conn_init (void) -{ +static int conn_init(void) { char buf[_POSIX2_LINE_MAX]; - struct nlist nl[] = - { + struct nlist nl[] = { #define N_TCBTABLE 0 - { "_tcbtable" }, - { "" } - }; + {"_tcbtable"}, {""}}; int status; - kvmd = kvm_openfiles (NULL, NULL, NULL, O_RDONLY, buf); - if (kvmd == NULL) - { - ERROR ("tcpconns plugin: kvm_openfiles failed: %s", buf); + kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, buf); + if (kvmd == NULL) { + ERROR("tcpconns plugin: kvm_openfiles failed: %s", buf); return (-1); } - status = kvm_nlist (kvmd, nl); - if (status < 0) - { - ERROR ("tcpconns plugin: kvm_nlist failed with status %i.", status); + status = kvm_nlist(kvmd, nl); + if (status < 0) { + ERROR("tcpconns plugin: kvm_nlist failed with status %i.", status); return (-1); } - if (nl[N_TCBTABLE].n_type == 0) - { - ERROR ("tcpconns plugin: Error looking up kernel's namelist: " - "N_TCBTABLE is invalid."); + if (nl[N_TCBTABLE].n_type == 0) { + ERROR("tcpconns plugin: Error looking up kernel's namelist: " + "N_TCBTABLE is invalid."); return (-1); } - inpcbtable_off = (u_long) nl[N_TCBTABLE].n_value; - inpcbtable_ptr = (struct inpcbtable *) nl[N_TCBTABLE].n_value; + inpcbtable_off = (u_long)nl[N_TCBTABLE].n_value; + inpcbtable_ptr = (struct inpcbtable *)nl[N_TCBTABLE].n_value; return (0); } /* int conn_init */ -static int conn_read (void) -{ +static int conn_read(void) { struct inpcbtable table; -#if !defined(__OpenBSD__) && (defined(__NetBSD_Version__) && __NetBSD_Version__ <= 699002700) +#if !defined(__OpenBSD__) && \ + (defined(__NetBSD_Version__) && __NetBSD_Version__ <= 699002700) struct inpcb *head; #endif struct inpcb *next; @@ -948,60 +830,63 @@ static int conn_read (void) struct tcpcb tcpcb; int status; - conn_reset_port_entry (); + conn_reset_port_entry(); /* Read the pcbtable from the kernel */ - status = kread (inpcbtable_off, &table, sizeof (table)); + status = kread(inpcbtable_off, &table, sizeof(table)); if (status != 0) return (-1); -#if defined(__OpenBSD__) || (defined(__NetBSD_Version__) && __NetBSD_Version__ > 699002700) +#if defined(__OpenBSD__) || \ + (defined(__NetBSD_Version__) && __NetBSD_Version__ > 699002700) /* inpt_queue is a TAILQ on OpenBSD */ /* Get the first pcb */ - next = (struct inpcb *)TAILQ_FIRST (&table.inpt_queue); + next = (struct inpcb *)TAILQ_FIRST(&table.inpt_queue); while (next) #else /* Get the `head' pcb */ - head = (struct inpcb *) &(inpcbtable_ptr->inpt_queue); + head = (struct inpcb *)&(inpcbtable_ptr->inpt_queue); /* Get the first pcb */ - next = (struct inpcb *)CIRCLEQ_FIRST (&table.inpt_queue); + next = (struct inpcb *)CIRCLEQ_FIRST(&table.inpt_queue); while (next != head) #endif { /* Read the pcb pointed to by `next' into `inpcb' */ - status = kread ((u_long) next, &inpcb, sizeof (inpcb)); + status = kread((u_long)next, &inpcb, sizeof(inpcb)); if (status != 0) return (-1); - /* Advance `next' */ -#if defined(__OpenBSD__) || (defined(__NetBSD_Version__) && __NetBSD_Version__ > 699002700) +/* Advance `next' */ +#if defined(__OpenBSD__) || \ + (defined(__NetBSD_Version__) && __NetBSD_Version__ > 699002700) /* inpt_queue is a TAILQ on OpenBSD */ - next = (struct inpcb *)TAILQ_NEXT (&inpcb, inp_queue); + next = (struct inpcb *)TAILQ_NEXT(&inpcb, inp_queue); #else - next = (struct inpcb *)CIRCLEQ_NEXT (&inpcb, inp_queue); + next = (struct inpcb *)CIRCLEQ_NEXT(&inpcb, inp_queue); #endif - /* Ignore sockets, that are not connected. */ +/* Ignore sockets, that are not connected. */ #ifdef __NetBSD__ if (inpcb.inp_af == AF_INET6) continue; /* XXX see netbsd/src/usr.bin/netstat/inet6.c */ #else - if (!(inpcb.inp_flags & INP_IPV6) - && (inet_lnaof(inpcb.inp_laddr) == INADDR_ANY)) + if (!(inpcb.inp_flags & INP_IPV6) && + (inet_lnaof(inpcb.inp_laddr) == INADDR_ANY)) continue; - if ((inpcb.inp_flags & INP_IPV6) - && IN6_IS_ADDR_UNSPECIFIED (&inpcb.inp_laddr6)) + if ((inpcb.inp_flags & INP_IPV6) && + IN6_IS_ADDR_UNSPECIFIED(&inpcb.inp_laddr6)) continue; #endif - status = kread ((u_long) inpcb.inp_ppcb, &tcpcb, sizeof (tcpcb)); + status = kread((u_long)inpcb.inp_ppcb, &tcpcb, sizeof(tcpcb)); if (status != 0) return (-1); - conn_handle_ports (ntohs(inpcb.inp_lport), ntohs(inpcb.inp_fport), tcpcb.t_state); + conn_handle_ports(ntohs(inpcb.inp_lport), ntohs(inpcb.inp_fport), + tcpcb.t_state); } /* while (next != head) */ - conn_submit_all (); + conn_submit_all(); return (0); } @@ -1009,42 +894,37 @@ static int conn_read (void) #elif KERNEL_AIX -static int conn_read (void) -{ +static int conn_read(void) { int size; int nconn; void *data; struct netinfo_header *header; struct netinfo_conn *conn; - conn_reset_port_entry (); + conn_reset_port_entry(); size = netinfo(NETINFO_TCP, 0, 0, 0); - if (size < 0) - { - ERROR ("tcpconns plugin: netinfo failed return: %i", size); + if (size < 0) { + ERROR("tcpconns plugin: netinfo failed return: %i", size); return (-1); } if (size == 0) return (0); - if ((size - sizeof (struct netinfo_header)) % sizeof (struct netinfo_conn)) - { - ERROR ("tcpconns plugin: invalid buffer size"); + if ((size - sizeof(struct netinfo_header)) % sizeof(struct netinfo_conn)) { + ERROR("tcpconns plugin: invalid buffer size"); return (-1); } data = malloc(size); - if (data == NULL) - { - ERROR ("tcpconns plugin: malloc failed"); + if (data == NULL) { + ERROR("tcpconns plugin: malloc failed"); return (-1); } - if (netinfo(NETINFO_TCP, data, &size, 0) < 0) - { - ERROR ("tcpconns plugin: netinfo failed"); + if (netinfo(NETINFO_TCP, data, &size, 0) < 0) { + ERROR("tcpconns plugin: netinfo failed"); free(data); return (-1); } @@ -1053,33 +933,30 @@ static int conn_read (void) nconn = header->size; conn = (struct netinfo_conn *)(data + sizeof(struct netinfo_header)); - for (int i = 0; i < nconn; conn++, i++) - { - conn_handle_ports (conn->srcport, conn->dstport, conn->tcp_state); + for (int i = 0; i < nconn; conn++, i++) { + conn_handle_ports(conn->srcport, conn->dstport, conn->tcp_state); } free(data); - conn_submit_all (); + conn_submit_all(); return (0); } #endif /* KERNEL_AIX */ -void module_register (void) -{ - plugin_register_config ("tcpconns", conn_config, - config_keys, config_keys_num); +void module_register(void) { + plugin_register_config("tcpconns", conn_config, config_keys, config_keys_num); #if KERNEL_LINUX - plugin_register_init ("tcpconns", conn_init); + plugin_register_init("tcpconns", conn_init); #elif HAVE_SYSCTLBYNAME - /* no initialization */ + /* no initialization */ #elif HAVE_LIBKVM_NLIST - plugin_register_init ("tcpconns", conn_init); + plugin_register_init("tcpconns", conn_init); #elif KERNEL_AIX - /* no initialization */ +/* no initialization */ #endif - plugin_register_read ("tcpconns", conn_read); + plugin_register_read("tcpconns", conn_read); } /* void module_register */ /* diff --git a/src/teamspeak2.c b/src/teamspeak2.c index 1bd969bd..960d6464 100644 --- a/src/teamspeak2.c +++ b/src/teamspeak2.c @@ -26,26 +26,25 @@ #include "common.h" #include "plugin.h" -#include #include -#include #include +#include +#include /* * Defines */ /* Default host and port */ -#define DEFAULT_HOST "127.0.0.1" -#define DEFAULT_PORT "51234" +#define DEFAULT_HOST "127.0.0.1" +#define DEFAULT_PORT "51234" /* * Variables */ /* Server linked list structure */ -typedef struct vserver_list_s -{ - int port; - struct vserver_list_s *next; +typedef struct vserver_list_s { + int port; + struct vserver_list_s *next; } vserver_list_t; static vserver_list_t *server_list = NULL; @@ -57,784 +56,677 @@ static FILE *global_read_fh = NULL; static FILE *global_write_fh = NULL; /* Config data */ -static const char *config_keys[] = -{ - "Host", - "Port", - "Server" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"Host", "Port", "Server"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); /* * Functions */ -static int tss2_add_vserver (int vserver_port) -{ - /* - * Adds a new vserver to the linked list - */ - vserver_list_t *entry; - - /* Check port range */ - if ((vserver_port <= 0) || (vserver_port > 65535)) - { - ERROR ("teamspeak2 plugin: VServer port is invalid: %i", - vserver_port); - return (-1); - } - - /* Allocate memory */ - entry = calloc (1, sizeof (*entry)); - if (entry == NULL) - { - ERROR ("teamspeak2 plugin: calloc failed."); - return (-1); - } - - /* Save data */ - entry->port = vserver_port; - - /* Insert to list */ - if(server_list == NULL) { - /* Add the server as the first element */ - server_list = entry; - } - else { - vserver_list_t *prev; - - /* Add the server to the end of the list */ - prev = server_list; - while (prev->next != NULL) - prev = prev->next; - prev->next = entry; - } - - INFO ("teamspeak2 plugin: Registered new vserver: %i", vserver_port); - - return (0); +static int tss2_add_vserver(int vserver_port) { + /* + * Adds a new vserver to the linked list + */ + vserver_list_t *entry; + + /* Check port range */ + if ((vserver_port <= 0) || (vserver_port > 65535)) { + ERROR("teamspeak2 plugin: VServer port is invalid: %i", vserver_port); + return (-1); + } + + /* Allocate memory */ + entry = calloc(1, sizeof(*entry)); + if (entry == NULL) { + ERROR("teamspeak2 plugin: calloc failed."); + return (-1); + } + + /* Save data */ + entry->port = vserver_port; + + /* Insert to list */ + if (server_list == NULL) { + /* Add the server as the first element */ + server_list = entry; + } else { + vserver_list_t *prev; + + /* Add the server to the end of the list */ + prev = server_list; + while (prev->next != NULL) + prev = prev->next; + prev->next = entry; + } + + INFO("teamspeak2 plugin: Registered new vserver: %i", vserver_port); + + return (0); } /* int tss2_add_vserver */ -static void tss2_submit_gauge (const char *plugin_instance, - const char *type, const char *type_instance, - gauge_t value) -{ - /* - * Submits a gauge value to the collectd daemon - */ - value_list_t vl = VALUE_LIST_INIT; +static void tss2_submit_gauge(const char *plugin_instance, const char *type, + const char *type_instance, gauge_t value) { + /* + * Submits a gauge value to the collectd daemon + */ + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "teamspeak2", sizeof (vl.plugin)); + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "teamspeak2", sizeof(vl.plugin)); - if (plugin_instance != NULL) - sstrncpy (vl.plugin_instance, plugin_instance, - sizeof (vl.plugin_instance)); + if (plugin_instance != NULL) + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); + sstrncpy(vl.type, type, sizeof(vl.type)); - if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, - sizeof (vl.type_instance)); + if (type_instance != NULL) + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* void tss2_submit_gauge */ -static void tss2_submit_io (const char *plugin_instance, const char *type, - derive_t rx, derive_t tx) -{ - /* - * Submits the io rx/tx tuple to the collectd daemon - */ - value_list_t vl = VALUE_LIST_INIT; - value_t values[] = { - { .derive = rx }, - { .derive = tx }, - }; - - vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - sstrncpy (vl.plugin, "teamspeak2", sizeof (vl.plugin)); - - if (plugin_instance != NULL) - sstrncpy (vl.plugin_instance, plugin_instance, - sizeof (vl.plugin_instance)); - - sstrncpy (vl.type, type, sizeof (vl.type)); - - plugin_dispatch_values (&vl); +static void tss2_submit_io(const char *plugin_instance, const char *type, + derive_t rx, derive_t tx) { + /* + * Submits the io rx/tx tuple to the collectd daemon + */ + value_list_t vl = VALUE_LIST_INIT; + value_t values[] = { + {.derive = rx}, {.derive = tx}, + }; + + vl.values = values; + vl.values_len = STATIC_ARRAY_SIZE(values); + sstrncpy(vl.plugin, "teamspeak2", sizeof(vl.plugin)); + + if (plugin_instance != NULL) + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + + sstrncpy(vl.type, type, sizeof(vl.type)); + + plugin_dispatch_values(&vl); } /* void tss2_submit_gauge */ -static void tss2_close_socket (void) -{ - /* - * Closes all sockets - */ - if (global_write_fh != NULL) - { - fputs ("quit\r\n", global_write_fh); - } - - if (global_read_fh != NULL) - { - fclose (global_read_fh); - global_read_fh = NULL; - } - - if (global_write_fh != NULL) - { - fclose (global_write_fh); - global_write_fh = NULL; - } +static void tss2_close_socket(void) { + /* + * Closes all sockets + */ + if (global_write_fh != NULL) { + fputs("quit\r\n", global_write_fh); + } + + if (global_read_fh != NULL) { + fclose(global_read_fh); + global_read_fh = NULL; + } + + if (global_write_fh != NULL) { + fclose(global_write_fh); + global_write_fh = NULL; + } } /* void tss2_close_socket */ -static int tss2_get_socket (FILE **ret_read_fh, FILE **ret_write_fh) -{ - /* - * Returns connected file objects or establishes the connection - * if it's not already present - */ - struct addrinfo *ai_head; - int sd = -1; - int status; - - /* Check if we already got opened connections */ - if ((global_read_fh != NULL) && (global_write_fh != NULL)) - { - /* If so, use them */ - if (ret_read_fh != NULL) - *ret_read_fh = global_read_fh; - if (ret_write_fh != NULL) - *ret_write_fh = global_write_fh; - return (0); - } - - /* Get all addrs for this hostname */ - struct addrinfo ai_hints = { - .ai_family = AF_UNSPEC, - .ai_flags = AI_ADDRCONFIG, - .ai_socktype = SOCK_STREAM - }; - - status = getaddrinfo ((config_host != NULL) ? config_host : DEFAULT_HOST, - (config_port != NULL) ? config_port : DEFAULT_PORT, - &ai_hints, - &ai_head); - if (status != 0) - { - ERROR ("teamspeak2 plugin: getaddrinfo failed: %s", - gai_strerror (status)); - return (-1); - } - - /* Try all given hosts until we can connect to one */ - for (struct addrinfo *ai_ptr = ai_head; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) - { - /* Create socket */ - sd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, - ai_ptr->ai_protocol); - if (sd < 0) - { - char errbuf[1024]; - WARNING ("teamspeak2 plugin: socket failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - continue; - } - - /* Try to connect */ - status = connect (sd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); - if (status != 0) - { - char errbuf[1024]; - WARNING ("teamspeak2 plugin: connect failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - close (sd); - sd = -1; - continue; - } - - /* - * Success, we can break. Don't need more than one connection - */ - break; - } /* for (ai_ptr) */ - - freeaddrinfo (ai_head); - - /* Check if we really got connected */ - if (sd < 0) - return (-1); - - /* Create file objects from sockets */ - global_read_fh = fdopen (sd, "r"); - if (global_read_fh == NULL) - { - char errbuf[1024]; - ERROR ("teamspeak2 plugin: fdopen failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - close (sd); - return (-1); - } - - global_write_fh = fdopen (sd, "w"); - if (global_write_fh == NULL) - { - char errbuf[1024]; - ERROR ("teamspeak2 plugin: fdopen failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - tss2_close_socket (); - return (-1); - } - - { /* Check that the server correctly identifies itself. */ - char buffer[4096]; - char *buffer_ptr; - - buffer_ptr = fgets (buffer, sizeof (buffer), global_read_fh); - if (buffer_ptr == NULL) - { - WARNING ("teamspeak2 plugin: Unexpected EOF received " - "from remote host %s:%s.", - config_host ? config_host : DEFAULT_HOST, - config_port ? config_port : DEFAULT_PORT); - } - buffer[sizeof (buffer) - 1] = 0; - - if (memcmp ("[TS]\r\n", buffer, 6) != 0) - { - ERROR ("teamspeak2 plugin: Unexpected response when connecting " - "to server. Expected ``[TS]'', got ``%s''.", - buffer); - tss2_close_socket (); - return (-1); - } - DEBUG ("teamspeak2 plugin: Server send correct banner, connected!"); - } - - /* Copy the new filehandles to the given pointers */ - if (ret_read_fh != NULL) - *ret_read_fh = global_read_fh; - if (ret_write_fh != NULL) - *ret_write_fh = global_write_fh; - return (0); +static int tss2_get_socket(FILE **ret_read_fh, FILE **ret_write_fh) { + /* + * Returns connected file objects or establishes the connection + * if it's not already present + */ + struct addrinfo *ai_head; + int sd = -1; + int status; + + /* Check if we already got opened connections */ + if ((global_read_fh != NULL) && (global_write_fh != NULL)) { + /* If so, use them */ + if (ret_read_fh != NULL) + *ret_read_fh = global_read_fh; + if (ret_write_fh != NULL) + *ret_write_fh = global_write_fh; + return (0); + } + + /* Get all addrs for this hostname */ + struct addrinfo ai_hints = {.ai_family = AF_UNSPEC, + .ai_flags = AI_ADDRCONFIG, + .ai_socktype = SOCK_STREAM}; + + status = getaddrinfo((config_host != NULL) ? config_host : DEFAULT_HOST, + (config_port != NULL) ? config_port : DEFAULT_PORT, + &ai_hints, &ai_head); + if (status != 0) { + ERROR("teamspeak2 plugin: getaddrinfo failed: %s", gai_strerror(status)); + return (-1); + } + + /* Try all given hosts until we can connect to one */ + for (struct addrinfo *ai_ptr = ai_head; ai_ptr != NULL; + ai_ptr = ai_ptr->ai_next) { + /* Create socket */ + sd = socket(ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); + if (sd < 0) { + char errbuf[1024]; + WARNING("teamspeak2 plugin: socket failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + continue; + } + + /* Try to connect */ + status = connect(sd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); + if (status != 0) { + char errbuf[1024]; + WARNING("teamspeak2 plugin: connect failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(sd); + sd = -1; + continue; + } + + /* + * Success, we can break. Don't need more than one connection + */ + break; + } /* for (ai_ptr) */ + + freeaddrinfo(ai_head); + + /* Check if we really got connected */ + if (sd < 0) + return (-1); + + /* Create file objects from sockets */ + global_read_fh = fdopen(sd, "r"); + if (global_read_fh == NULL) { + char errbuf[1024]; + ERROR("teamspeak2 plugin: fdopen failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(sd); + return (-1); + } + + global_write_fh = fdopen(sd, "w"); + if (global_write_fh == NULL) { + char errbuf[1024]; + ERROR("teamspeak2 plugin: fdopen failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + tss2_close_socket(); + return (-1); + } + + { /* Check that the server correctly identifies itself. */ + char buffer[4096]; + char *buffer_ptr; + + buffer_ptr = fgets(buffer, sizeof(buffer), global_read_fh); + if (buffer_ptr == NULL) { + WARNING("teamspeak2 plugin: Unexpected EOF received " + "from remote host %s:%s.", + config_host ? config_host : DEFAULT_HOST, + config_port ? config_port : DEFAULT_PORT); + } + buffer[sizeof(buffer) - 1] = 0; + + if (memcmp("[TS]\r\n", buffer, 6) != 0) { + ERROR("teamspeak2 plugin: Unexpected response when connecting " + "to server. Expected ``[TS]'', got ``%s''.", + buffer); + tss2_close_socket(); + return (-1); + } + DEBUG("teamspeak2 plugin: Server send correct banner, connected!"); + } + + /* Copy the new filehandles to the given pointers */ + if (ret_read_fh != NULL) + *ret_read_fh = global_read_fh; + if (ret_write_fh != NULL) + *ret_write_fh = global_write_fh; + return (0); } /* int tss2_get_socket */ -static int tss2_send_request (FILE *fh, const char *request) -{ - /* - * This function puts a request to the server socket - */ - int status; - - status = fputs (request, fh); - if (status < 0) - { - ERROR ("teamspeak2 plugin: fputs failed."); - tss2_close_socket (); - return (-1); - } - fflush (fh); - - return (0); +static int tss2_send_request(FILE *fh, const char *request) { + /* + * This function puts a request to the server socket + */ + int status; + + status = fputs(request, fh); + if (status < 0) { + ERROR("teamspeak2 plugin: fputs failed."); + tss2_close_socket(); + return (-1); + } + fflush(fh); + + return (0); } /* int tss2_send_request */ -static int tss2_receive_line (FILE *fh, char *buffer, int buffer_size) -{ - /* - * Receive a single line from the given file object - */ - char *temp; - - /* - * fgets is blocking but much easier then doing anything else - * TODO: Non-blocking Version would be safer - */ - temp = fgets (buffer, buffer_size, fh); - if (temp == NULL) - { - char errbuf[1024]; - ERROR ("teamspeak2 plugin: fgets failed: %s", - sstrerror (errno, errbuf, sizeof(errbuf))); - tss2_close_socket (); - return (-1); - } - - buffer[buffer_size - 1] = 0; - return (0); +static int tss2_receive_line(FILE *fh, char *buffer, int buffer_size) { + /* + * Receive a single line from the given file object + */ + char *temp; + + /* + * fgets is blocking but much easier then doing anything else + * TODO: Non-blocking Version would be safer + */ + temp = fgets(buffer, buffer_size, fh); + if (temp == NULL) { + char errbuf[1024]; + ERROR("teamspeak2 plugin: fgets failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + tss2_close_socket(); + return (-1); + } + + buffer[buffer_size - 1] = 0; + return (0); } /* int tss2_receive_line */ -static int tss2_select_vserver (FILE *read_fh, FILE *write_fh, vserver_list_t *vserver) -{ - /* - * Tell the server to select the given vserver - */ - char command[128]; - char response[128]; - int status; - - /* Send request */ - ssnprintf (command, sizeof (command), "sel %i\r\n", vserver->port); - - status = tss2_send_request (write_fh, command); - if (status != 0) - { - ERROR ("teamspeak2 plugin: tss2_send_request (%s) failed.", command); - return (-1); - } - - /* Get answer */ - status = tss2_receive_line (read_fh, response, sizeof (response)); - if (status != 0) - { - ERROR ("teamspeak2 plugin: tss2_receive_line failed."); - return (-1); - } - response[sizeof (response) - 1] = 0; - - /* Check answer */ - if ((strncasecmp ("OK", response, 2) == 0) - && ((response[2] == 0) - || (response[2] == '\n') - || (response[2] == '\r'))) - return (0); - - ERROR ("teamspeak2 plugin: Command ``%s'' failed. " - "Response received from server was: ``%s''.", - command, response); - return (-1); +static int tss2_select_vserver(FILE *read_fh, FILE *write_fh, + vserver_list_t *vserver) { + /* + * Tell the server to select the given vserver + */ + char command[128]; + char response[128]; + int status; + + /* Send request */ + ssnprintf(command, sizeof(command), "sel %i\r\n", vserver->port); + + status = tss2_send_request(write_fh, command); + if (status != 0) { + ERROR("teamspeak2 plugin: tss2_send_request (%s) failed.", command); + return (-1); + } + + /* Get answer */ + status = tss2_receive_line(read_fh, response, sizeof(response)); + if (status != 0) { + ERROR("teamspeak2 plugin: tss2_receive_line failed."); + return (-1); + } + response[sizeof(response) - 1] = 0; + + /* Check answer */ + if ((strncasecmp("OK", response, 2) == 0) && + ((response[2] == 0) || (response[2] == '\n') || (response[2] == '\r'))) + return (0); + + ERROR("teamspeak2 plugin: Command ``%s'' failed. " + "Response received from server was: ``%s''.", + command, response); + return (-1); } /* int tss2_select_vserver */ -static int tss2_vserver_gapl (FILE *read_fh, FILE *write_fh, - gauge_t *ret_value) -{ - /* - * Reads the vserver's average packet loss and submits it to collectd. - * Be sure to run the tss2_read_vserver function before calling this so - * the vserver is selected correctly. - */ - gauge_t packet_loss = NAN; - int status; - - status = tss2_send_request (write_fh, "gapl\r\n"); - if (status != 0) - { - ERROR("teamspeak2 plugin: tss2_send_request (gapl) failed."); - return (-1); - } - - while (42) - { - char buffer[4096]; - char *value; - char *endptr = NULL; - - status = tss2_receive_line (read_fh, buffer, sizeof (buffer)); - if (status != 0) - { - /* Set to NULL just to make sure no one uses these FHs anymore. */ - read_fh = NULL; - write_fh = NULL; - ERROR ("teamspeak2 plugin: tss2_receive_line failed."); - return (-1); - } - buffer[sizeof (buffer) - 1] = 0; - - if (strncmp ("average_packet_loss=", buffer, - strlen ("average_packet_loss=")) == 0) - { - /* Got average packet loss, now interpret it */ - value = &buffer[20]; - /* Replace , with . */ - while (*value != 0) - { - if (*value == ',') - { - *value = '.'; - break; - } - value++; - } - - value = &buffer[20]; - - packet_loss = strtod (value, &endptr); - if (value == endptr) - { - /* Failed */ - WARNING ("teamspeak2 plugin: Could not read average package " - "loss from string: %s", buffer); - continue; - } - } - else if (strncasecmp ("OK", buffer, 2) == 0) - { - break; - } - else if (strncasecmp ("ERROR", buffer, 5) == 0) - { - ERROR ("teamspeak2 plugin: Server returned an error: %s", buffer); - return (-1); - } - else - { - WARNING ("teamspeak2 plugin: Server returned unexpected string: %s", - buffer); - } - } - - *ret_value = packet_loss; - return (0); +static int tss2_vserver_gapl(FILE *read_fh, FILE *write_fh, + gauge_t *ret_value) { + /* + * Reads the vserver's average packet loss and submits it to collectd. + * Be sure to run the tss2_read_vserver function before calling this so + * the vserver is selected correctly. + */ + gauge_t packet_loss = NAN; + int status; + + status = tss2_send_request(write_fh, "gapl\r\n"); + if (status != 0) { + ERROR("teamspeak2 plugin: tss2_send_request (gapl) failed."); + return (-1); + } + + while (42) { + char buffer[4096]; + char *value; + char *endptr = NULL; + + status = tss2_receive_line(read_fh, buffer, sizeof(buffer)); + if (status != 0) { + /* Set to NULL just to make sure no one uses these FHs anymore. */ + read_fh = NULL; + write_fh = NULL; + ERROR("teamspeak2 plugin: tss2_receive_line failed."); + return (-1); + } + buffer[sizeof(buffer) - 1] = 0; + + if (strncmp("average_packet_loss=", buffer, + strlen("average_packet_loss=")) == 0) { + /* Got average packet loss, now interpret it */ + value = &buffer[20]; + /* Replace , with . */ + while (*value != 0) { + if (*value == ',') { + *value = '.'; + break; + } + value++; + } + + value = &buffer[20]; + + packet_loss = strtod(value, &endptr); + if (value == endptr) { + /* Failed */ + WARNING("teamspeak2 plugin: Could not read average package " + "loss from string: %s", + buffer); + continue; + } + } else if (strncasecmp("OK", buffer, 2) == 0) { + break; + } else if (strncasecmp("ERROR", buffer, 5) == 0) { + ERROR("teamspeak2 plugin: Server returned an error: %s", buffer); + return (-1); + } else { + WARNING("teamspeak2 plugin: Server returned unexpected string: %s", + buffer); + } + } + + *ret_value = packet_loss; + return (0); } /* int tss2_vserver_gapl */ -static int tss2_read_vserver (vserver_list_t *vserver) -{ - /* - * Poll information for the given vserver and submit it to collect. - * If vserver is NULL the global server information will be queried. - */ - int status; - - gauge_t users = NAN; - gauge_t channels = NAN; - gauge_t servers = NAN; - derive_t rx_octets = 0; - derive_t tx_octets = 0; - derive_t rx_packets = 0; - derive_t tx_packets = 0; - gauge_t packet_loss = NAN; - int valid = 0; - - char plugin_instance[DATA_MAX_NAME_LEN] = { 0 }; - - FILE *read_fh; - FILE *write_fh; - - /* Get the send/receive sockets */ - status = tss2_get_socket (&read_fh, &write_fh); - if (status != 0) - { - ERROR ("teamspeak2 plugin: tss2_get_socket failed."); - return (-1); - } - - if (vserver == NULL) - { - /* Request global information */ - status = tss2_send_request (write_fh, "gi\r\n"); - } - else - { - /* Request server information */ - ssnprintf (plugin_instance, sizeof (plugin_instance), "vserver%i", - vserver->port); - - /* Select the server */ - status = tss2_select_vserver (read_fh, write_fh, vserver); - if (status != 0) - return (status); - - status = tss2_send_request (write_fh, "si\r\n"); - } - - if (status != 0) - { - ERROR ("teamspeak2 plugin: tss2_send_request failed."); - return (-1); - } - - /* Loop until break */ - while (42) - { - char buffer[4096]; - char *key; - char *value; - char *endptr = NULL; - - /* Read one line of the server's answer */ - status = tss2_receive_line (read_fh, buffer, sizeof (buffer)); - if (status != 0) - { - /* Set to NULL just to make sure no one uses these FHs anymore. */ - read_fh = NULL; - write_fh = NULL; - ERROR ("teamspeak2 plugin: tss2_receive_line failed."); - break; - } - - if (strncasecmp ("ERROR", buffer, 5) == 0) - { - ERROR ("teamspeak2 plugin: Server returned an error: %s", - buffer); - break; - } - else if (strncasecmp ("OK", buffer, 2) == 0) - { - break; - } - - /* Split line into key and value */ - key = strchr (buffer, '_'); - if (key == NULL) - { - DEBUG ("teamspeak2 plugin: Cannot parse line: %s", buffer); - continue; - } - key++; - - /* Evaluate assignment */ - value = strchr (key, '='); - if (value == NULL) - { - DEBUG ("teamspeak2 plugin: Cannot parse line: %s", buffer); - continue; - } - *value = 0; - value++; - - /* Check for known key and save the given value */ - /* global info: users_online, - * server info: currentusers. */ - if ((strcmp ("currentusers", key) == 0) - || (strcmp ("users_online", key) == 0)) - { - users = strtod (value, &endptr); - if (value != endptr) - valid |= 0x01; - } - /* global info: channels, - * server info: currentchannels. */ - else if ((strcmp ("currentchannels", key) == 0) - || (strcmp ("channels", key) == 0)) - { - channels = strtod (value, &endptr); - if (value != endptr) - valid |= 0x40; - } - /* global only */ - else if (strcmp ("servers", key) == 0) - { - servers = strtod (value, &endptr); - if (value != endptr) - valid |= 0x80; - } - else if (strcmp ("bytesreceived", key) == 0) - { - rx_octets = strtoll (value, &endptr, 0); - if (value != endptr) - valid |= 0x02; - } - else if (strcmp ("bytessend", key) == 0) - { - tx_octets = strtoll (value, &endptr, 0); - if (value != endptr) - valid |= 0x04; - } - else if (strcmp ("packetsreceived", key) == 0) - { - rx_packets = strtoll (value, &endptr, 0); - if (value != endptr) - valid |= 0x08; - } - else if (strcmp ("packetssend", key) == 0) - { - tx_packets = strtoll (value, &endptr, 0); - if (value != endptr) - valid |= 0x10; - } - else if ((strncmp ("allow_codec_", key, strlen ("allow_codec_")) == 0) - || (strncmp ("bwinlast", key, strlen ("bwinlast")) == 0) - || (strncmp ("bwoutlast", key, strlen ("bwoutlast")) == 0) - || (strncmp ("webpost_", key, strlen ("webpost_")) == 0) - || (strcmp ("adminemail", key) == 0) - || (strcmp ("clan_server", key) == 0) - || (strcmp ("countrynumber", key) == 0) - || (strcmp ("id", key) == 0) - || (strcmp ("ispname", key) == 0) - || (strcmp ("linkurl", key) == 0) - || (strcmp ("maxusers", key) == 0) - || (strcmp ("name", key) == 0) - || (strcmp ("password", key) == 0) - || (strcmp ("platform", key) == 0) - || (strcmp ("server_platform", key) == 0) - || (strcmp ("server_uptime", key) == 0) - || (strcmp ("server_version", key) == 0) - || (strcmp ("udpport", key) == 0) - || (strcmp ("uptime", key) == 0) - || (strcmp ("users_maximal", key) == 0) - || (strcmp ("welcomemessage", key) == 0)) - /* ignore */; - else - { - INFO ("teamspeak2 plugin: Unknown key-value-pair: " - "key = %s; value = %s;", key, value); - } - } /* while (42) */ - - /* Collect vserver packet loss rates only if the loop above did not exit - * with an error. */ - if ((status == 0) && (vserver != NULL)) - { - status = tss2_vserver_gapl (read_fh, write_fh, &packet_loss); - if (status == 0) - { - valid |= 0x20; - } - else - { - WARNING ("teamspeak2 plugin: Reading package loss " - "for vserver %i failed.", vserver->port); - } - } - - if ((valid & 0x01) == 0x01) - tss2_submit_gauge (plugin_instance, "users", NULL, users); - - if ((valid & 0x06) == 0x06) - tss2_submit_io (plugin_instance, "io_octets", rx_octets, tx_octets); - - if ((valid & 0x18) == 0x18) - tss2_submit_io (plugin_instance, "io_packets", rx_packets, tx_packets); - - if ((valid & 0x20) == 0x20) - tss2_submit_gauge (plugin_instance, "percent", "packet_loss", packet_loss); - - if ((valid & 0x40) == 0x40) - tss2_submit_gauge (plugin_instance, "gauge", "channels", channels); - - if ((valid & 0x80) == 0x80) - tss2_submit_gauge (plugin_instance, "gauge", "servers", servers); - - if (valid == 0) - return (-1); - return (0); +static int tss2_read_vserver(vserver_list_t *vserver) { + /* + * Poll information for the given vserver and submit it to collect. + * If vserver is NULL the global server information will be queried. + */ + int status; + + gauge_t users = NAN; + gauge_t channels = NAN; + gauge_t servers = NAN; + derive_t rx_octets = 0; + derive_t tx_octets = 0; + derive_t rx_packets = 0; + derive_t tx_packets = 0; + gauge_t packet_loss = NAN; + int valid = 0; + + char plugin_instance[DATA_MAX_NAME_LEN] = {0}; + + FILE *read_fh; + FILE *write_fh; + + /* Get the send/receive sockets */ + status = tss2_get_socket(&read_fh, &write_fh); + if (status != 0) { + ERROR("teamspeak2 plugin: tss2_get_socket failed."); + return (-1); + } + + if (vserver == NULL) { + /* Request global information */ + status = tss2_send_request(write_fh, "gi\r\n"); + } else { + /* Request server information */ + ssnprintf(plugin_instance, sizeof(plugin_instance), "vserver%i", + vserver->port); + + /* Select the server */ + status = tss2_select_vserver(read_fh, write_fh, vserver); + if (status != 0) + return (status); + + status = tss2_send_request(write_fh, "si\r\n"); + } + + if (status != 0) { + ERROR("teamspeak2 plugin: tss2_send_request failed."); + return (-1); + } + + /* Loop until break */ + while (42) { + char buffer[4096]; + char *key; + char *value; + char *endptr = NULL; + + /* Read one line of the server's answer */ + status = tss2_receive_line(read_fh, buffer, sizeof(buffer)); + if (status != 0) { + /* Set to NULL just to make sure no one uses these FHs anymore. */ + read_fh = NULL; + write_fh = NULL; + ERROR("teamspeak2 plugin: tss2_receive_line failed."); + break; + } + + if (strncasecmp("ERROR", buffer, 5) == 0) { + ERROR("teamspeak2 plugin: Server returned an error: %s", buffer); + break; + } else if (strncasecmp("OK", buffer, 2) == 0) { + break; + } + + /* Split line into key and value */ + key = strchr(buffer, '_'); + if (key == NULL) { + DEBUG("teamspeak2 plugin: Cannot parse line: %s", buffer); + continue; + } + key++; + + /* Evaluate assignment */ + value = strchr(key, '='); + if (value == NULL) { + DEBUG("teamspeak2 plugin: Cannot parse line: %s", buffer); + continue; + } + *value = 0; + value++; + + /* Check for known key and save the given value */ + /* global info: users_online, + * server info: currentusers. */ + if ((strcmp("currentusers", key) == 0) || + (strcmp("users_online", key) == 0)) { + users = strtod(value, &endptr); + if (value != endptr) + valid |= 0x01; + } + /* global info: channels, + * server info: currentchannels. */ + else if ((strcmp("currentchannels", key) == 0) || + (strcmp("channels", key) == 0)) { + channels = strtod(value, &endptr); + if (value != endptr) + valid |= 0x40; + } + /* global only */ + else if (strcmp("servers", key) == 0) { + servers = strtod(value, &endptr); + if (value != endptr) + valid |= 0x80; + } else if (strcmp("bytesreceived", key) == 0) { + rx_octets = strtoll(value, &endptr, 0); + if (value != endptr) + valid |= 0x02; + } else if (strcmp("bytessend", key) == 0) { + tx_octets = strtoll(value, &endptr, 0); + if (value != endptr) + valid |= 0x04; + } else if (strcmp("packetsreceived", key) == 0) { + rx_packets = strtoll(value, &endptr, 0); + if (value != endptr) + valid |= 0x08; + } else if (strcmp("packetssend", key) == 0) { + tx_packets = strtoll(value, &endptr, 0); + if (value != endptr) + valid |= 0x10; + } else if ((strncmp("allow_codec_", key, strlen("allow_codec_")) == 0) || + (strncmp("bwinlast", key, strlen("bwinlast")) == 0) || + (strncmp("bwoutlast", key, strlen("bwoutlast")) == 0) || + (strncmp("webpost_", key, strlen("webpost_")) == 0) || + (strcmp("adminemail", key) == 0) || + (strcmp("clan_server", key) == 0) || + (strcmp("countrynumber", key) == 0) || + (strcmp("id", key) == 0) || (strcmp("ispname", key) == 0) || + (strcmp("linkurl", key) == 0) || + (strcmp("maxusers", key) == 0) || (strcmp("name", key) == 0) || + (strcmp("password", key) == 0) || + (strcmp("platform", key) == 0) || + (strcmp("server_platform", key) == 0) || + (strcmp("server_uptime", key) == 0) || + (strcmp("server_version", key) == 0) || + (strcmp("udpport", key) == 0) || (strcmp("uptime", key) == 0) || + (strcmp("users_maximal", key) == 0) || + (strcmp("welcomemessage", key) == 0)) + /* ignore */; + else { + INFO("teamspeak2 plugin: Unknown key-value-pair: " + "key = %s; value = %s;", + key, value); + } + } /* while (42) */ + + /* Collect vserver packet loss rates only if the loop above did not exit + * with an error. */ + if ((status == 0) && (vserver != NULL)) { + status = tss2_vserver_gapl(read_fh, write_fh, &packet_loss); + if (status == 0) { + valid |= 0x20; + } else { + WARNING("teamspeak2 plugin: Reading package loss " + "for vserver %i failed.", + vserver->port); + } + } + + if ((valid & 0x01) == 0x01) + tss2_submit_gauge(plugin_instance, "users", NULL, users); + + if ((valid & 0x06) == 0x06) + tss2_submit_io(plugin_instance, "io_octets", rx_octets, tx_octets); + + if ((valid & 0x18) == 0x18) + tss2_submit_io(plugin_instance, "io_packets", rx_packets, tx_packets); + + if ((valid & 0x20) == 0x20) + tss2_submit_gauge(plugin_instance, "percent", "packet_loss", packet_loss); + + if ((valid & 0x40) == 0x40) + tss2_submit_gauge(plugin_instance, "gauge", "channels", channels); + + if ((valid & 0x80) == 0x80) + tss2_submit_gauge(plugin_instance, "gauge", "servers", servers); + + if (valid == 0) + return (-1); + return (0); } /* int tss2_read_vserver */ -static int tss2_config (const char *key, const char *value) -{ - /* - * Interpret configuration values - */ - if (strcasecmp ("Host", key) == 0) - { - char *temp; - - temp = strdup (value); - if (temp == NULL) - { - ERROR("teamspeak2 plugin: strdup failed."); - return (1); - } - sfree (config_host); - config_host = temp; - } - else if (strcasecmp ("Port", key) == 0) - { - char *temp; - - temp = strdup (value); - if (temp == NULL) - { - ERROR("teamspeak2 plugin: strdup failed."); - return (1); - } - sfree (config_port); - config_port = temp; - } - else if (strcasecmp ("Server", key) == 0) - { - /* Server variable found */ - int status; - - status = tss2_add_vserver (atoi (value)); - if (status != 0) - return (1); - } - else - { - /* Unknown variable found */ - return (-1); - } - - return 0; +static int tss2_config(const char *key, const char *value) { + /* + * Interpret configuration values + */ + if (strcasecmp("Host", key) == 0) { + char *temp; + + temp = strdup(value); + if (temp == NULL) { + ERROR("teamspeak2 plugin: strdup failed."); + return (1); + } + sfree(config_host); + config_host = temp; + } else if (strcasecmp("Port", key) == 0) { + char *temp; + + temp = strdup(value); + if (temp == NULL) { + ERROR("teamspeak2 plugin: strdup failed."); + return (1); + } + sfree(config_port); + config_port = temp; + } else if (strcasecmp("Server", key) == 0) { + /* Server variable found */ + int status; + + status = tss2_add_vserver(atoi(value)); + if (status != 0) + return (1); + } else { + /* Unknown variable found */ + return (-1); + } + + return 0; } /* int tss2_config */ -static int tss2_read (void) -{ - /* - * Poll function which collects global and vserver information - * and submits it to collectd - */ - int success = 0; - int status; - - /* Handle global server variables */ - status = tss2_read_vserver (NULL); - if (status == 0) - { - success++; - } - else - { - WARNING ("teamspeak2 plugin: Reading global server variables failed."); - } - - /* Handle vservers */ - for (vserver_list_t *vserver = server_list; vserver != NULL; vserver = vserver->next) - { - status = tss2_read_vserver (vserver); - if (status == 0) - { - success++; - } - else - { - WARNING ("teamspeak2 plugin: Reading statistics " - "for vserver %i failed.", vserver->port); - continue; - } - } - - if (success == 0) - return (-1); - return (0); +static int tss2_read(void) { + /* + * Poll function which collects global and vserver information + * and submits it to collectd + */ + int success = 0; + int status; + + /* Handle global server variables */ + status = tss2_read_vserver(NULL); + if (status == 0) { + success++; + } else { + WARNING("teamspeak2 plugin: Reading global server variables failed."); + } + + /* Handle vservers */ + for (vserver_list_t *vserver = server_list; vserver != NULL; + vserver = vserver->next) { + status = tss2_read_vserver(vserver); + if (status == 0) { + success++; + } else { + WARNING("teamspeak2 plugin: Reading statistics " + "for vserver %i failed.", + vserver->port); + continue; + } + } + + if (success == 0) + return (-1); + return (0); } /* int tss2_read */ -static int tss2_shutdown(void) -{ - /* - * Shutdown handler - */ - vserver_list_t *entry; +static int tss2_shutdown(void) { + /* + * Shutdown handler + */ + vserver_list_t *entry; - tss2_close_socket (); + tss2_close_socket(); - entry = server_list; - server_list = NULL; - while (entry != NULL) - { - vserver_list_t *next; + entry = server_list; + server_list = NULL; + while (entry != NULL) { + vserver_list_t *next; - next = entry->next; - sfree (entry); - entry = next; - } + next = entry->next; + sfree(entry); + entry = next; + } - /* Get rid of the configuration */ - sfree (config_host); - sfree (config_port); + /* Get rid of the configuration */ + sfree(config_host); + sfree(config_port); - return (0); + return (0); } /* int tss2_shutdown */ -void module_register(void) -{ - /* - * Mandatory module_register function - */ - plugin_register_config ("teamspeak2", tss2_config, - config_keys, config_keys_num); - plugin_register_read ("teamspeak2", tss2_read); - plugin_register_shutdown ("teamspeak2", tss2_shutdown); +void module_register(void) { + /* + * Mandatory module_register function + */ + plugin_register_config("teamspeak2", tss2_config, config_keys, + config_keys_num); + plugin_register_read("teamspeak2", tss2_read); + plugin_register_shutdown("teamspeak2", tss2_shutdown); } /* void module_register */ /* vim: set sw=4 ts=4 : */ diff --git a/src/ted.c b/src/ted.c index 001eddf4..cccb3dbb 100644 --- a/src/ted.c +++ b/src/ted.c @@ -40,312 +40,265 @@ #include "plugin.h" #if HAVE_TERMIOS_H && HAVE_SYS_IOCTL_H && HAVE_MATH_H -# include -# include -# include +#include +#include +#include #else -# error "No applicable input method." +#error "No applicable input method." #endif #define EXPECTED_PACKAGE_LENGTH 278 -#define ESCAPE 0x10 -#define PKT_BEGIN 0x04 -#define PKT_END 0x03 +#define ESCAPE 0x10 +#define PKT_BEGIN 0x04 +#define PKT_END 0x03 #define DEFAULT_DEVICE "/dev/ttyUSB0" static char *conf_device = NULL; -static int conf_retries = 0; +static int conf_retries = 0; static int fd = -1; -static const char *config_keys[] = -{ - "Device", - "Retries" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"Device", "Retries"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); -static int ted_read_value(double *ret_power, double *ret_voltage) -{ - unsigned char receive_buffer[300]; - unsigned char package_buffer[300]; - unsigned char pkt_request[1] = {0xAA}; - int package_buffer_pos; +static int ted_read_value(double *ret_power, double *ret_voltage) { + unsigned char receive_buffer[300]; + unsigned char package_buffer[300]; + unsigned char pkt_request[1] = {0xAA}; + int package_buffer_pos; - fd_set input; + fd_set input; - /* Initialize timeout structure, set to 2 seconds */ - struct timeval timeout = { - .tv_sec = 2 - }; + /* Initialize timeout structure, set to 2 seconds */ + struct timeval timeout = {.tv_sec = 2}; - int end_flag; - int escape_flag; + int end_flag; + int escape_flag; - int status; + int status; - assert (fd >= 0); + assert(fd >= 0); - /* Initialize the input set*/ - FD_ZERO (&input); - FD_SET (fd, &input); + /* Initialize the input set*/ + FD_ZERO(&input); + FD_SET(fd, &input); - /* clear out anything in the buffer */ - tcflush (fd, TCIFLUSH); + /* clear out anything in the buffer */ + tcflush(fd, TCIFLUSH); - status = write (fd, pkt_request, sizeof(pkt_request)); - if (status <= 0) - { - ERROR ("ted plugin: swrite failed."); - return (-1); - } - - /* Loop until we find the end of the package */ - end_flag = 0; - package_buffer_pos = 0; - while (end_flag == 0) - { - ssize_t receive_buffer_length; - - /* check for timeout or input error*/ - status = select (fd + 1, &input, NULL, NULL, &timeout); - if (status == 0) /* Timeout */ - { - WARNING ("ted plugin: Timeout while waiting for file descriptor " - "to become ready."); - return (-1); - } - else if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) - { - /* Some signal or something. Start over.. */ - continue; - } - else if (status < 0) - { - char errbuf[1024]; - ERROR ("ted plugin: select failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } + status = write(fd, pkt_request, sizeof(pkt_request)); + if (status <= 0) { + ERROR("ted plugin: swrite failed."); + return (-1); + } - receive_buffer_length = read (fd, receive_buffer, sizeof (receive_buffer)); - if (receive_buffer_length < 0) - { - char errbuf[1024]; - if ((errno == EAGAIN) || (errno == EINTR)) - continue; - ERROR ("ted plugin: read(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - else if (receive_buffer_length == 0) - { - /* Should we close the FD in this case? */ - WARNING ("ted plugin: Received EOF from file descriptor."); - return (-1); - } - else if (((size_t) receive_buffer_length) > sizeof (receive_buffer)) - { - ERROR ("ted plugin: read(2) returned invalid value %zi.", - receive_buffer_length); - return (-1); - } + /* Loop until we find the end of the package */ + end_flag = 0; + package_buffer_pos = 0; + while (end_flag == 0) { + ssize_t receive_buffer_length; - /* - * packet filter loop - * - * Handle escape sequences in `receive_buffer' and put the - * result in `package_buffer'. - */ - /* We need to see the begin sequence first. When we receive `ESCAPE - * PKT_BEGIN', we set `package_buffer_pos' to zero to signal that - * the beginning of the package has been found. */ + /* check for timeout or input error*/ + status = select(fd + 1, &input, NULL, NULL, &timeout); + if (status == 0) /* Timeout */ + { + WARNING("ted plugin: Timeout while waiting for file descriptor " + "to become ready."); + return (-1); + } else if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) { + /* Some signal or something. Start over.. */ + continue; + } else if (status < 0) { + char errbuf[1024]; + ERROR("ted plugin: select failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } - escape_flag = 0; - for (ssize_t i = 0; i < receive_buffer_length; i++) - { - /* Check if previous byte was the escape byte. */ - if (escape_flag == 1) - { - escape_flag = 0; - /* escape escape = single escape */ - if ((receive_buffer[i] == ESCAPE) - && (package_buffer_pos >= 0)) - { - package_buffer[package_buffer_pos] = ESCAPE; - package_buffer_pos++; - } - else if (receive_buffer[i] == PKT_BEGIN) - { - package_buffer_pos = 0; - } - else if (receive_buffer[i] == PKT_END) - { - end_flag = 1; - break; - } - else - { - DEBUG ("ted plugin: Unknown escaped byte: %#x", - (unsigned int) receive_buffer[i]); - } - } - else if (receive_buffer[i] == ESCAPE) - { - escape_flag = 1; - } - /* if we are in a package add byte to buffer - * otherwise throw away */ - else if (package_buffer_pos >= 0) - { - package_buffer[package_buffer_pos] = receive_buffer[i]; - package_buffer_pos++; - } - } /* for (i = 0; i < receive_buffer_length; i++) */ - } /* while (end_flag == 0) */ - - /* Check for errors inside the loop. */ - if ((end_flag == 0) || (package_buffer_pos != EXPECTED_PACKAGE_LENGTH)) - return (-1); + receive_buffer_length = read(fd, receive_buffer, sizeof(receive_buffer)); + if (receive_buffer_length < 0) { + char errbuf[1024]; + if ((errno == EAGAIN) || (errno == EINTR)) + continue; + ERROR("ted plugin: read(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } else if (receive_buffer_length == 0) { + /* Should we close the FD in this case? */ + WARNING("ted plugin: Received EOF from file descriptor."); + return (-1); + } else if (((size_t)receive_buffer_length) > sizeof(receive_buffer)) { + ERROR("ted plugin: read(2) returned invalid value %zi.", + receive_buffer_length); + return (-1); + } /* - * Power is at positions 247 and 248 (LSB first) in [10kW]. - * Voltage is at positions 251 and 252 (LSB first) in [.1V]. + * packet filter loop * - * Power is in 10 Watt steps - * Voltage is in volts + * Handle escape sequences in `receive_buffer' and put the + * result in `package_buffer'. */ - *ret_power = 10.0 * (double) ((((int) package_buffer[248]) * 256) - + ((int) package_buffer[247])); - *ret_voltage = 0.1 * (double) ((((int) package_buffer[252]) * 256) - + ((int) package_buffer[251])); - - /* success */ - return (0); + /* We need to see the begin sequence first. When we receive `ESCAPE + * PKT_BEGIN', we set `package_buffer_pos' to zero to signal that + * the beginning of the package has been found. */ + + escape_flag = 0; + for (ssize_t i = 0; i < receive_buffer_length; i++) { + /* Check if previous byte was the escape byte. */ + if (escape_flag == 1) { + escape_flag = 0; + /* escape escape = single escape */ + if ((receive_buffer[i] == ESCAPE) && (package_buffer_pos >= 0)) { + package_buffer[package_buffer_pos] = ESCAPE; + package_buffer_pos++; + } else if (receive_buffer[i] == PKT_BEGIN) { + package_buffer_pos = 0; + } else if (receive_buffer[i] == PKT_END) { + end_flag = 1; + break; + } else { + DEBUG("ted plugin: Unknown escaped byte: %#x", + (unsigned int)receive_buffer[i]); + } + } else if (receive_buffer[i] == ESCAPE) { + escape_flag = 1; + } + /* if we are in a package add byte to buffer + * otherwise throw away */ + else if (package_buffer_pos >= 0) { + package_buffer[package_buffer_pos] = receive_buffer[i]; + package_buffer_pos++; + } + } /* for (i = 0; i < receive_buffer_length; i++) */ + } /* while (end_flag == 0) */ + + /* Check for errors inside the loop. */ + if ((end_flag == 0) || (package_buffer_pos != EXPECTED_PACKAGE_LENGTH)) + return (-1); + + /* + * Power is at positions 247 and 248 (LSB first) in [10kW]. + * Voltage is at positions 251 and 252 (LSB first) in [.1V]. + * + * Power is in 10 Watt steps + * Voltage is in volts + */ + *ret_power = 10.0 * (double)((((int)package_buffer[248]) * 256) + + ((int)package_buffer[247])); + *ret_voltage = 0.1 * (double)((((int)package_buffer[252]) * 256) + + ((int)package_buffer[251])); + + /* success */ + return (0); } /* int ted_read_value */ -static int ted_open_device (void) -{ - const char *dev; - struct termios options; - - if (fd >= 0) - return (0); - - dev = DEFAULT_DEVICE; - if (conf_device != NULL) - dev = conf_device; +static int ted_open_device(void) { + const char *dev; + struct termios options; - fd = open (dev, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); - if (fd < 0) - { - ERROR ("ted plugin: Unable to open device %s.", dev); - return (-1); - } - - /* Get the current options for the port... */ - tcgetattr(fd, &options); - options.c_cflag = B19200 | CS8 | CSTOPB | CREAD | CLOCAL; - options.c_iflag = IGNBRK | IGNPAR; - options.c_oflag = 0; - options.c_lflag = 0; - options.c_cc[VTIME] = 20; - options.c_cc[VMIN] = 250; - - /* Set the new options for the port... */ - tcflush(fd, TCIFLUSH); - tcsetattr(fd, TCSANOW, &options); - - INFO ("ted plugin: Successfully opened %s.", dev); + if (fd >= 0) return (0); + + dev = DEFAULT_DEVICE; + if (conf_device != NULL) + dev = conf_device; + + fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); + if (fd < 0) { + ERROR("ted plugin: Unable to open device %s.", dev); + return (-1); + } + + /* Get the current options for the port... */ + tcgetattr(fd, &options); + options.c_cflag = B19200 | CS8 | CSTOPB | CREAD | CLOCAL; + options.c_iflag = IGNBRK | IGNPAR; + options.c_oflag = 0; + options.c_lflag = 0; + options.c_cc[VTIME] = 20; + options.c_cc[VMIN] = 250; + + /* Set the new options for the port... */ + tcflush(fd, TCIFLUSH); + tcsetattr(fd, TCSANOW, &options); + + INFO("ted plugin: Successfully opened %s.", dev); + return (0); } /* int ted_open_device */ -static void ted_submit (const char *type, double value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void ted_submit(const char *type, double value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "ted", sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof (vl.type)); + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "ted", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static int ted_config (const char *key, const char *value) -{ - if (strcasecmp ("Device", key) == 0) - { - sfree (conf_device); - conf_device = sstrdup (value); - } - else if (strcasecmp ("Retries", key) == 0) - { - int tmp; - - tmp = atoi (value); - if (tmp < 0) - { - WARNING ("ted plugin: Invalid retry count: %i", tmp); - return (1); - } - conf_retries = tmp; - } - else - { - ERROR ("ted plugin: Unknown config option: %s", key); - return (-1); +static int ted_config(const char *key, const char *value) { + if (strcasecmp("Device", key) == 0) { + sfree(conf_device); + conf_device = sstrdup(value); + } else if (strcasecmp("Retries", key) == 0) { + int tmp; + + tmp = atoi(value); + if (tmp < 0) { + WARNING("ted plugin: Invalid retry count: %i", tmp); + return (1); } + conf_retries = tmp; + } else { + ERROR("ted plugin: Unknown config option: %s", key); + return (-1); + } - return (0); + return (0); } /* int ted_config */ -static int ted_read (void) -{ - double power; - double voltage; - int status; +static int ted_read(void) { + double power; + double voltage; + int status; - status = ted_open_device (); - if (status != 0) - return (-1); + status = ted_open_device(); + if (status != 0) + return (-1); - power = NAN; - voltage = NAN; - for (int i = 0; i <= conf_retries; i++) - { - status = ted_read_value (&power, &voltage); - if (status == 0) - break; - } + power = NAN; + voltage = NAN; + for (int i = 0; i <= conf_retries; i++) { + status = ted_read_value(&power, &voltage); + if (status == 0) + break; + } - if (status != 0) - return (-1); + if (status != 0) + return (-1); - ted_submit ("power", power); - ted_submit ("voltage", voltage); + ted_submit("power", power); + ted_submit("voltage", voltage); - return (0); + return (0); } /* int ted_read */ -static int ted_shutdown (void) -{ - if (fd >= 0) - { - close (fd); - fd = -1; - } +static int ted_shutdown(void) { + if (fd >= 0) { + close(fd); + fd = -1; + } - return (0); + return (0); } /* int ted_shutdown */ -void module_register (void) -{ - plugin_register_config ("ted", ted_config, - config_keys, config_keys_num); - plugin_register_read ("ted", ted_read); - plugin_register_shutdown ("ted", ted_shutdown); +void module_register(void) { + plugin_register_config("ted", ted_config, config_keys, config_keys_num); + plugin_register_read("ted", ted_read); + plugin_register_shutdown("ted", ted_shutdown); } /* void module_register */ /* vim: set sw=4 et : */ diff --git a/src/testing.h b/src/testing.h index 1bc966c8..42f45ce6 100644 --- a/src/testing.h +++ b/src/testing.h @@ -33,89 +33,102 @@ static int fail_count__ = 0; static int check_count__ = 0; #ifndef DBL_PRECISION -# define DBL_PRECISION 1e-12 +#define DBL_PRECISION 1e-12 #endif -#define DEF_TEST(func) static int test_##func (void) - -#define RUN_TEST(func) do { \ - int status; \ - printf ("Testing %s ...\n", #func); \ - status = test_ ## func (); \ - printf ("%s.\n", (status == 0) ? "Success" : "FAILURE"); \ - if (status != 0) { fail_count__++; } \ -} while (0) - -#define END_TEST exit ((fail_count__ == 0) ? 0 : 1); - -#define LOG(result, text) \ - printf ("%s %i - %s\n", result ? "ok" : "not ok", ++check_count__, text) - -#define OK1(cond, text) do { \ - _Bool result = (cond); \ - LOG (result, text); \ - if (!result) { return -1; } \ -} while (0) +#define DEF_TEST(func) static int test_##func(void) + +#define RUN_TEST(func) \ + do { \ + int status; \ + printf("Testing %s ...\n", #func); \ + status = test_##func(); \ + printf("%s.\n", (status == 0) ? "Success" : "FAILURE"); \ + if (status != 0) { \ + fail_count__++; \ + } \ + } while (0) + +#define END_TEST exit((fail_count__ == 0) ? 0 : 1); + +#define LOG(result, text) \ + printf("%s %i - %s\n", result ? "ok" : "not ok", ++check_count__, text) + +#define OK1(cond, text) \ + do { \ + _Bool result = (cond); \ + LOG(result, text); \ + if (!result) { \ + return -1; \ + } \ + } while (0) #define OK(cond) OK1(cond, #cond) -#define EXPECT_EQ_STR(expect, actual) do { \ - /* Evaluate 'actual' only once. */ \ - const char *got__ = actual; \ - if (strcmp (expect, got__) != 0) { \ - printf ("not ok %i - %s = \"%s\", want \"%s\"\n", \ - ++check_count__, #actual, got__, expect); \ - return (-1); \ - } \ - printf ("ok %i - %s = \"%s\"\n", ++check_count__, #actual, got__); \ -} while (0) - -#define EXPECT_EQ_INT(expect, actual) do { \ - int want__ = (int) expect; \ - int got__ = (int) actual; \ - if (got__ != want__) { \ - printf ("not ok %i - %s = %d, want %d\n", \ - ++check_count__, #actual, got__, want__); \ - return (-1); \ - } \ - printf ("ok %i - %s = %d\n", ++check_count__, #actual, got__); \ -} while (0) - -#define EXPECT_EQ_UINT64(expect, actual) do { \ - uint64_t want__ = (uint64_t) expect; \ - uint64_t got__ = (uint64_t) actual; \ - if (got__ != want__) { \ - printf ("not ok %i - %s = %"PRIu64", want %"PRIu64"\n", \ - ++check_count__, #actual, got__, want__); \ - return (-1); \ - } \ - printf ("ok %i - %s = %"PRIu64"\n", ++check_count__, #actual, got__); \ -} while (0) - -#define EXPECT_EQ_DOUBLE(expect, actual) do { \ - double want__ = (double) expect; \ - double got__ = (double) actual; \ - if (isnan (want__) && !isnan (got__)) { \ - printf ("not ok %i - %s = %.15g, want %.15g\n", \ - ++check_count__, #actual, got__, want__); \ - return (-1); \ - } else if (!isnan (want__) && (((want__-got__) < -DBL_PRECISION) || ((want__-got__) > DBL_PRECISION))) { \ - printf ("not ok %i - %s = %.15g, want %.15g\n", \ - ++check_count__, #actual, got__, want__); \ - return (-1); \ - } \ - printf ("ok %i - %s = %.15g\n", ++check_count__, #actual, got__); \ -} while (0) - -#define CHECK_NOT_NULL(expr) do { \ - void *ptr_; \ - ptr_ = (expr); \ - OK1(ptr_ != NULL, #expr); \ -} while (0) - -#define CHECK_ZERO(expr) do { \ - long status_; \ - status_ = (long) (expr); \ - OK1(status_ == 0L, #expr); \ -} while (0) +#define EXPECT_EQ_STR(expect, actual) \ + do { \ + /* Evaluate 'actual' only once. */ \ + const char *got__ = actual; \ + if (strcmp(expect, got__) != 0) { \ + printf("not ok %i - %s = \"%s\", want \"%s\"\n", ++check_count__, \ + #actual, got__, expect); \ + return (-1); \ + } \ + printf("ok %i - %s = \"%s\"\n", ++check_count__, #actual, got__); \ + } while (0) + +#define EXPECT_EQ_INT(expect, actual) \ + do { \ + int want__ = (int)expect; \ + int got__ = (int)actual; \ + if (got__ != want__) { \ + printf("not ok %i - %s = %d, want %d\n", ++check_count__, #actual, \ + got__, want__); \ + return (-1); \ + } \ + printf("ok %i - %s = %d\n", ++check_count__, #actual, got__); \ + } while (0) + +#define EXPECT_EQ_UINT64(expect, actual) \ + do { \ + uint64_t want__ = (uint64_t)expect; \ + uint64_t got__ = (uint64_t)actual; \ + if (got__ != want__) { \ + printf("not ok %i - %s = %" PRIu64 ", want %" PRIu64 "\n", \ + ++check_count__, #actual, got__, want__); \ + return (-1); \ + } \ + printf("ok %i - %s = %" PRIu64 "\n", ++check_count__, #actual, got__); \ + } while (0) + +#define EXPECT_EQ_DOUBLE(expect, actual) \ + do { \ + double want__ = (double)expect; \ + double got__ = (double)actual; \ + if (isnan(want__) && !isnan(got__)) { \ + printf("not ok %i - %s = %.15g, want %.15g\n", ++check_count__, #actual, \ + got__, want__); \ + return (-1); \ + } else if (!isnan(want__) && (((want__ - got__) < -DBL_PRECISION) || \ + ((want__ - got__) > DBL_PRECISION))) { \ + printf("not ok %i - %s = %.15g, want %.15g\n", ++check_count__, #actual, \ + got__, want__); \ + return (-1); \ + } \ + printf("ok %i - %s = %.15g\n", ++check_count__, #actual, got__); \ + } while (0) + +#define CHECK_NOT_NULL(expr) \ + do { \ + void *ptr_; \ + ptr_ = (expr); \ + OK1(ptr_ != NULL, #expr); \ + } while (0) + +#define CHECK_ZERO(expr) \ + do { \ + long status_; \ + status_ = (long)(expr); \ + OK1(status_ == 0L, #expr); \ + } while (0) #endif /* TESTING_H */ diff --git a/src/thermal.c b/src/thermal.c index 09d9157e..fbae6cc1 100644 --- a/src/thermal.c +++ b/src/thermal.c @@ -26,14 +26,11 @@ #include "utils_ignorelist.h" #if !KERNEL_LINUX -# error "This module is for Linux only." +#error "This module is for Linux only." #endif -static const char *config_keys[] = { - "Device", - "IgnoreSelected", - "ForceUseProcfs" -}; +static const char *config_keys[] = {"Device", "IgnoreSelected", + "ForceUseProcfs"}; static const char *const dirname_sysfs = "/sys/class/thermal"; static const char *const dirname_procfs = "/proc/acpi/thermal_zone"; @@ -41,190 +38,166 @@ static const char *const dirname_procfs = "/proc/acpi/thermal_zone"; static _Bool force_procfs = 0; static ignorelist_t *device_list; -enum dev_type { - TEMP = 0, - COOLING_DEV -}; +enum dev_type { TEMP = 0, COOLING_DEV }; -static void thermal_submit (const char *plugin_instance, enum dev_type dt, - value_t value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void thermal_submit(const char *plugin_instance, enum dev_type dt, + value_t value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &value; - vl.values_len = 1; + vl.values = &value; + vl.values_len = 1; - sstrncpy (vl.plugin, "thermal", sizeof(vl.plugin)); - if (plugin_instance != NULL) - sstrncpy (vl.plugin_instance, plugin_instance, - sizeof (vl.plugin_instance)); - sstrncpy (vl.type, - (dt == TEMP) ? "temperature" : "gauge", - sizeof (vl.type)); + sstrncpy(vl.plugin, "thermal", sizeof(vl.plugin)); + if (plugin_instance != NULL) + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, (dt == TEMP) ? "temperature" : "gauge", sizeof(vl.type)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static int thermal_sysfs_device_read (const char __attribute__((unused)) *dir, - const char *name, void __attribute__((unused)) *user_data) -{ - char filename[PATH_MAX]; - _Bool success = 0; - value_t value; - - if (device_list && ignorelist_match (device_list, name)) - return -1; - - ssnprintf (filename, sizeof (filename), "%s/%s/temp", dirname_sysfs, name); - if (parse_value_file (filename, &value, DS_TYPE_GAUGE) == 0) - { - value.gauge /= 1000.0; - thermal_submit(name, TEMP, value); - success = 1; - } - - ssnprintf (filename, sizeof (filename), "%s/%s/cur_state", dirname_sysfs, name); - if (parse_value_file (filename, &value, DS_TYPE_GAUGE) == 0) - { - thermal_submit(name, COOLING_DEV, value); - success = 1; - } - - return (success ? 0 : -1); +static int thermal_sysfs_device_read(const char __attribute__((unused)) * dir, + const char *name, + void __attribute__((unused)) * user_data) { + char filename[PATH_MAX]; + _Bool success = 0; + value_t value; + + if (device_list && ignorelist_match(device_list, name)) + return -1; + + ssnprintf(filename, sizeof(filename), "%s/%s/temp", dirname_sysfs, name); + if (parse_value_file(filename, &value, DS_TYPE_GAUGE) == 0) { + value.gauge /= 1000.0; + thermal_submit(name, TEMP, value); + success = 1; + } + + ssnprintf(filename, sizeof(filename), "%s/%s/cur_state", dirname_sysfs, name); + if (parse_value_file(filename, &value, DS_TYPE_GAUGE) == 0) { + thermal_submit(name, COOLING_DEV, value); + success = 1; + } + + return (success ? 0 : -1); } -static int thermal_procfs_device_read (const char __attribute__((unused)) *dir, - const char *name, void __attribute__((unused)) *user_data) -{ - const char str_temp[] = "temperature:"; - char filename[256]; - char data[1024]; - int len; - - if (device_list && ignorelist_match (device_list, name)) - return -1; - - /** - * rechot ~ # cat /proc/acpi/thermal_zone/THRM/temperature - * temperature: 55 C - */ - - len = ssnprintf (filename, sizeof (filename), - "%s/%s/temperature", dirname_procfs, name); - if ((len < 0) || ((size_t) len >= sizeof (filename))) - return -1; - - len = (ssize_t) read_file_contents (filename, data, sizeof(data)); - if ((len > 0) && ((size_t) len > sizeof(str_temp)) - && (data[--len] == '\n') - && (! strncmp(data, str_temp, sizeof(str_temp)-1))) { - char *endptr = NULL; - double temp; - double factor, add; - - if (data[--len] == 'C') { - add = 0; - factor = 1.0; - } else if (data[len] == 'F') { - add = -32; - factor = 5.0/9.0; - } else if (data[len] == 'K') { - add = -273.15; - factor = 1.0; - } else - return -1; - - while (len > 0 && data[--len] == ' ') - ; - data[len + 1] = 0; - - while (len > 0 && data[--len] != ' ') - ; - ++len; - - errno = 0; - temp = (strtod (data + len, &endptr) + add) * factor; - - if (endptr != data + len && errno == 0) { - thermal_submit(name, TEMP, (value_t) { .gauge = temp }); - return 0; - } - } - - return -1; +static int thermal_procfs_device_read(const char __attribute__((unused)) * dir, + const char *name, + void __attribute__((unused)) * + user_data) { + const char str_temp[] = "temperature:"; + char filename[256]; + char data[1024]; + int len; + + if (device_list && ignorelist_match(device_list, name)) + return -1; + + /** + * rechot ~ # cat /proc/acpi/thermal_zone/THRM/temperature + * temperature: 55 C + */ + + len = ssnprintf(filename, sizeof(filename), "%s/%s/temperature", + dirname_procfs, name); + if ((len < 0) || ((size_t)len >= sizeof(filename))) + return -1; + + len = (ssize_t)read_file_contents(filename, data, sizeof(data)); + if ((len > 0) && ((size_t)len > sizeof(str_temp)) && (data[--len] == '\n') && + (!strncmp(data, str_temp, sizeof(str_temp) - 1))) { + char *endptr = NULL; + double temp; + double factor, add; + + if (data[--len] == 'C') { + add = 0; + factor = 1.0; + } else if (data[len] == 'F') { + add = -32; + factor = 5.0 / 9.0; + } else if (data[len] == 'K') { + add = -273.15; + factor = 1.0; + } else + return -1; + + while (len > 0 && data[--len] == ' ') + ; + data[len + 1] = 0; + + while (len > 0 && data[--len] != ' ') + ; + ++len; + + errno = 0; + temp = (strtod(data + len, &endptr) + add) * factor; + + if (endptr != data + len && errno == 0) { + thermal_submit(name, TEMP, (value_t){.gauge = temp}); + return 0; + } + } + + return -1; } -static int thermal_config (const char *key, const char *value) -{ - if (device_list == NULL) - device_list = ignorelist_create (1); - - if (strcasecmp (key, "Device") == 0) - { - if (ignorelist_add (device_list, value)) - { - ERROR ("thermal plugin: " - "Cannot add value to ignorelist."); - return 1; - } - } - else if (strcasecmp (key, "IgnoreSelected") == 0) - { - ignorelist_set_invert (device_list, 1); - if (IS_TRUE (value)) - ignorelist_set_invert (device_list, 0); - } - else if (strcasecmp (key, "ForceUseProcfs") == 0) - { - force_procfs = 0; - if (IS_TRUE (value)) - force_procfs = 1; - } - else - { - return -1; - } - - return 0; +static int thermal_config(const char *key, const char *value) { + if (device_list == NULL) + device_list = ignorelist_create(1); + + if (strcasecmp(key, "Device") == 0) { + if (ignorelist_add(device_list, value)) { + ERROR("thermal plugin: " + "Cannot add value to ignorelist."); + return 1; + } + } else if (strcasecmp(key, "IgnoreSelected") == 0) { + ignorelist_set_invert(device_list, 1); + if (IS_TRUE(value)) + ignorelist_set_invert(device_list, 0); + } else if (strcasecmp(key, "ForceUseProcfs") == 0) { + force_procfs = 0; + if (IS_TRUE(value)) + force_procfs = 1; + } else { + return -1; + } + + return 0; } -static int thermal_sysfs_read (void) -{ - return walk_directory (dirname_sysfs, thermal_sysfs_device_read, - /* user_data = */ NULL, /* include hidden */ 0); +static int thermal_sysfs_read(void) { + return walk_directory(dirname_sysfs, thermal_sysfs_device_read, + /* user_data = */ NULL, /* include hidden */ 0); } -static int thermal_procfs_read (void) -{ - return walk_directory (dirname_procfs, thermal_procfs_device_read, - /* user_data = */ NULL, /* include hidden */ 0); +static int thermal_procfs_read(void) { + return walk_directory(dirname_procfs, thermal_procfs_device_read, + /* user_data = */ NULL, /* include hidden */ 0); } -static int thermal_init (void) -{ - int ret = -1; +static int thermal_init(void) { + int ret = -1; - if (!force_procfs && access (dirname_sysfs, R_OK | X_OK) == 0) { - ret = plugin_register_read ("thermal", thermal_sysfs_read); - } else if (access (dirname_procfs, R_OK | X_OK) == 0) { - ret = plugin_register_read ("thermal", thermal_procfs_read); - } + if (!force_procfs && access(dirname_sysfs, R_OK | X_OK) == 0) { + ret = plugin_register_read("thermal", thermal_sysfs_read); + } else if (access(dirname_procfs, R_OK | X_OK) == 0) { + ret = plugin_register_read("thermal", thermal_procfs_read); + } - return ret; + return ret; } -static int thermal_shutdown (void) -{ - ignorelist_free (device_list); +static int thermal_shutdown(void) { + ignorelist_free(device_list); - return 0; + return 0; } -void module_register (void) -{ - plugin_register_config ("thermal", thermal_config, - config_keys, STATIC_ARRAY_SIZE(config_keys)); - plugin_register_init ("thermal", thermal_init); - plugin_register_shutdown ("thermal", thermal_shutdown); +void module_register(void) { + plugin_register_config("thermal", thermal_config, config_keys, + STATIC_ARRAY_SIZE(config_keys)); + plugin_register_init("thermal", thermal_init); + plugin_register_shutdown("thermal", thermal_shutdown); } - diff --git a/src/threshold.c b/src/threshold.c index 1d9bcf95..743db28d 100644 --- a/src/threshold.c +++ b/src/threshold.c @@ -45,66 +45,59 @@ * structure is copied and may be destroyed after this call. Returns zero on * success, non-zero otherwise. */ -static int ut_threshold_add (const threshold_t *th) -{ /* {{{ */ +static int ut_threshold_add(const threshold_t *th) { /* {{{ */ char name[6 * DATA_MAX_NAME_LEN]; char *name_copy; threshold_t *th_copy; threshold_t *th_ptr; int status = 0; - if (format_name (name, sizeof (name), th->host, - th->plugin, th->plugin_instance, - th->type, th->type_instance) != 0) - { - ERROR ("ut_threshold_add: format_name failed."); + if (format_name(name, sizeof(name), th->host, th->plugin, th->plugin_instance, + th->type, th->type_instance) != 0) { + ERROR("ut_threshold_add: format_name failed."); return (-1); } - name_copy = strdup (name); - if (name_copy == NULL) - { - ERROR ("ut_threshold_add: strdup failed."); + name_copy = strdup(name); + if (name_copy == NULL) { + ERROR("ut_threshold_add: strdup failed."); return (-1); } - th_copy = malloc (sizeof (*th_copy)); - if (th_copy == NULL) - { - sfree (name_copy); - ERROR ("ut_threshold_add: malloc failed."); + th_copy = malloc(sizeof(*th_copy)); + if (th_copy == NULL) { + sfree(name_copy); + ERROR("ut_threshold_add: malloc failed."); return (-1); } - memcpy (th_copy, th, sizeof (threshold_t)); + memcpy(th_copy, th, sizeof(threshold_t)); - DEBUG ("ut_threshold_add: Adding entry `%s'", name); + DEBUG("ut_threshold_add: Adding entry `%s'", name); - pthread_mutex_lock (&threshold_lock); + pthread_mutex_lock(&threshold_lock); - th_ptr = threshold_get (th->host, th->plugin, th->plugin_instance, - th->type, th->type_instance); + th_ptr = threshold_get(th->host, th->plugin, th->plugin_instance, th->type, + th->type_instance); while ((th_ptr != NULL) && (th_ptr->next != NULL)) th_ptr = th_ptr->next; if (th_ptr == NULL) /* no such threshold yet */ { - status = c_avl_insert (threshold_tree, name_copy, th_copy); - } - else /* th_ptr points to the last threshold in the list */ + status = c_avl_insert(threshold_tree, name_copy, th_copy); + } else /* th_ptr points to the last threshold in the list */ { th_ptr->next = th_copy; /* name_copy isn't needed */ - sfree (name_copy); + sfree(name_copy); } - pthread_mutex_unlock (&threshold_lock); + pthread_mutex_unlock(&threshold_lock); - if (status != 0) - { - ERROR ("ut_threshold_add: c_avl_insert (%s) failed.", name); - sfree (name_copy); - sfree (th_copy); + if (status != 0) { + ERROR("ut_threshold_add: c_avl_insert (%s) failed.", name); + sfree(name_copy); + sfree(th_copy); } return (status); @@ -116,49 +109,41 @@ static int ut_threshold_add (const threshold_t *th) * The following approximately two hundred functions are used to handle the * configuration and fill the threshold list. * {{{ */ -static int ut_config_type_datasource (threshold_t *th, oconfig_item_t *ci) -{ - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("threshold values: The `DataSource' option needs exactly one " - "string argument."); +static int ut_config_type_datasource(threshold_t *th, oconfig_item_t *ci) { + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("threshold values: The `DataSource' option needs exactly one " + "string argument."); return (-1); } - sstrncpy (th->data_source, ci->values[0].value.string, - sizeof (th->data_source)); + sstrncpy(th->data_source, ci->values[0].value.string, + sizeof(th->data_source)); return (0); } /* int ut_config_type_datasource */ -static int ut_config_type_instance (threshold_t *th, oconfig_item_t *ci) -{ - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("threshold values: The `Instance' option needs exactly one " - "string argument."); +static int ut_config_type_instance(threshold_t *th, oconfig_item_t *ci) { + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("threshold values: The `Instance' option needs exactly one " + "string argument."); return (-1); } - sstrncpy (th->type_instance, ci->values[0].value.string, - sizeof (th->type_instance)); + sstrncpy(th->type_instance, ci->values[0].value.string, + sizeof(th->type_instance)); return (0); } /* int ut_config_type_instance */ -static int ut_config_type_max (threshold_t *th, oconfig_item_t *ci) -{ - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) - { - WARNING ("threshold values: The `%s' option needs exactly one " - "number argument.", ci->key); +static int ut_config_type_max(threshold_t *th, oconfig_item_t *ci) { + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) { + WARNING("threshold values: The `%s' option needs exactly one " + "number argument.", + ci->key); return (-1); } - if (strcasecmp (ci->key, "WarningMax") == 0) + if (strcasecmp(ci->key, "WarningMax") == 0) th->warning_max = ci->values[0].value.number; else th->failure_max = ci->values[0].value.number; @@ -166,17 +151,15 @@ static int ut_config_type_max (threshold_t *th, oconfig_item_t *ci) return (0); } /* int ut_config_type_max */ -static int ut_config_type_min (threshold_t *th, oconfig_item_t *ci) -{ - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) - { - WARNING ("threshold values: The `%s' option needs exactly one " - "number argument.", ci->key); +static int ut_config_type_min(threshold_t *th, oconfig_item_t *ci) { + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) { + WARNING("threshold values: The `%s' option needs exactly one " + "number argument.", + ci->key); return (-1); } - if (strcasecmp (ci->key, "WarningMin") == 0) + if (strcasecmp(ci->key, "WarningMin") == 0) th->warning_min = ci->values[0].value.number; else th->failure_min = ci->values[0].value.number; @@ -184,13 +167,11 @@ static int ut_config_type_min (threshold_t *th, oconfig_item_t *ci) return (0); } /* int ut_config_type_min */ -static int ut_config_type_hits (threshold_t *th, oconfig_item_t *ci) -{ - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) - { - WARNING ("threshold values: The `%s' option needs exactly one " - "number argument.", ci->key); +static int ut_config_type_hits(threshold_t *th, oconfig_item_t *ci) { + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) { + WARNING("threshold values: The `%s' option needs exactly one " + "number argument.", + ci->key); return (-1); } @@ -199,13 +180,11 @@ static int ut_config_type_hits (threshold_t *th, oconfig_item_t *ci) return (0); } /* int ut_config_type_hits */ -static int ut_config_type_hysteresis (threshold_t *th, oconfig_item_t *ci) -{ - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) - { - WARNING ("threshold values: The `%s' option needs exactly one " - "number argument.", ci->key); +static int ut_config_type_hysteresis(threshold_t *th, oconfig_item_t *ci) { + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) { + WARNING("threshold values: The `%s' option needs exactly one " + "number argument.", + ci->key); return (-1); } @@ -214,27 +193,23 @@ static int ut_config_type_hysteresis (threshold_t *th, oconfig_item_t *ci) return (0); } /* int ut_config_type_hysteresis */ -static int ut_config_type (const threshold_t *th_orig, oconfig_item_t *ci) -{ +static int ut_config_type(const threshold_t *th_orig, oconfig_item_t *ci) { threshold_t th; int status = 0; - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("threshold values: The `Type' block needs exactly one string " - "argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("threshold values: The `Type' block needs exactly one string " + "argument."); return (-1); } - if (ci->children_num < 1) - { - WARNING ("threshold values: The `Type' block needs at least one option."); + if (ci->children_num < 1) { + WARNING("threshold values: The `Type' block needs at least one option."); return (-1); } - memcpy (&th, th_orig, sizeof (th)); - sstrncpy (th.type, ci->values[0].value.string, sizeof (th.type)); + memcpy(&th, th_orig, sizeof(th)); + sstrncpy(th.type, ci->values[0].value.string, sizeof(th.type)); th.warning_min = NAN; th.warning_max = NAN; @@ -244,38 +219,37 @@ static int ut_config_type (const threshold_t *th_orig, oconfig_item_t *ci) th.hysteresis = 0; th.flags = UT_FLAG_INTERESTING; /* interesting by default */ - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; - if (strcasecmp ("Instance", option->key) == 0) - status = ut_config_type_instance (&th, option); - else if (strcasecmp ("DataSource", option->key) == 0) - status = ut_config_type_datasource (&th, option); - else if ((strcasecmp ("WarningMax", option->key) == 0) - || (strcasecmp ("FailureMax", option->key) == 0)) - status = ut_config_type_max (&th, option); - else if ((strcasecmp ("WarningMin", option->key) == 0) - || (strcasecmp ("FailureMin", option->key) == 0)) - status = ut_config_type_min (&th, option); - else if (strcasecmp ("Interesting", option->key) == 0) - status = cf_util_get_flag (option, &th.flags, UT_FLAG_INTERESTING); - else if (strcasecmp ("Invert", option->key) == 0) - status = cf_util_get_flag (option, &th.flags, UT_FLAG_INVERT); - else if (strcasecmp ("Persist", option->key) == 0) - status = cf_util_get_flag (option, &th.flags, UT_FLAG_PERSIST); - else if (strcasecmp ("PersistOK", option->key) == 0) - status = cf_util_get_flag (option, &th.flags, UT_FLAG_PERSIST_OK); - else if (strcasecmp ("Percentage", option->key) == 0) - status = cf_util_get_flag (option, &th.flags, UT_FLAG_PERCENTAGE); - else if (strcasecmp ("Hits", option->key) == 0) - status = ut_config_type_hits (&th, option); - else if (strcasecmp ("Hysteresis", option->key) == 0) - status = ut_config_type_hysteresis (&th, option); - else - { - WARNING ("threshold values: Option `%s' not allowed inside a `Type' " - "block.", option->key); + if (strcasecmp("Instance", option->key) == 0) + status = ut_config_type_instance(&th, option); + else if (strcasecmp("DataSource", option->key) == 0) + status = ut_config_type_datasource(&th, option); + else if ((strcasecmp("WarningMax", option->key) == 0) || + (strcasecmp("FailureMax", option->key) == 0)) + status = ut_config_type_max(&th, option); + else if ((strcasecmp("WarningMin", option->key) == 0) || + (strcasecmp("FailureMin", option->key) == 0)) + status = ut_config_type_min(&th, option); + else if (strcasecmp("Interesting", option->key) == 0) + status = cf_util_get_flag(option, &th.flags, UT_FLAG_INTERESTING); + else if (strcasecmp("Invert", option->key) == 0) + status = cf_util_get_flag(option, &th.flags, UT_FLAG_INVERT); + else if (strcasecmp("Persist", option->key) == 0) + status = cf_util_get_flag(option, &th.flags, UT_FLAG_PERSIST); + else if (strcasecmp("PersistOK", option->key) == 0) + status = cf_util_get_flag(option, &th.flags, UT_FLAG_PERSIST_OK); + else if (strcasecmp("Percentage", option->key) == 0) + status = cf_util_get_flag(option, &th.flags, UT_FLAG_PERCENTAGE); + else if (strcasecmp("Hits", option->key) == 0) + status = ut_config_type_hits(&th, option); + else if (strcasecmp("Hysteresis", option->key) == 0) + status = ut_config_type_hysteresis(&th, option); + else { + WARNING("threshold values: Option `%s' not allowed inside a `Type' " + "block.", + option->key); status = -1; } @@ -283,65 +257,56 @@ static int ut_config_type (const threshold_t *th_orig, oconfig_item_t *ci) break; } - if (status == 0) - { - status = ut_threshold_add (&th); + if (status == 0) { + status = ut_threshold_add(&th); } return (status); } /* int ut_config_type */ -static int ut_config_plugin_instance (threshold_t *th, oconfig_item_t *ci) -{ - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("threshold values: The `Instance' option needs exactly one " - "string argument."); +static int ut_config_plugin_instance(threshold_t *th, oconfig_item_t *ci) { + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("threshold values: The `Instance' option needs exactly one " + "string argument."); return (-1); } - sstrncpy (th->plugin_instance, ci->values[0].value.string, - sizeof (th->plugin_instance)); + sstrncpy(th->plugin_instance, ci->values[0].value.string, + sizeof(th->plugin_instance)); return (0); } /* int ut_config_plugin_instance */ -static int ut_config_plugin (const threshold_t *th_orig, oconfig_item_t *ci) -{ +static int ut_config_plugin(const threshold_t *th_orig, oconfig_item_t *ci) { threshold_t th; int status = 0; - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("threshold values: The `Plugin' block needs exactly one string " - "argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("threshold values: The `Plugin' block needs exactly one string " + "argument."); return (-1); } - if (ci->children_num < 1) - { - WARNING ("threshold values: The `Plugin' block needs at least one nested " - "block."); + if (ci->children_num < 1) { + WARNING("threshold values: The `Plugin' block needs at least one nested " + "block."); return (-1); } - memcpy (&th, th_orig, sizeof (th)); - sstrncpy (th.plugin, ci->values[0].value.string, sizeof (th.plugin)); + memcpy(&th, th_orig, sizeof(th)); + sstrncpy(th.plugin, ci->values[0].value.string, sizeof(th.plugin)); - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; - if (strcasecmp ("Type", option->key) == 0) - status = ut_config_type (&th, option); - else if (strcasecmp ("Instance", option->key) == 0) - status = ut_config_plugin_instance (&th, option); - else - { - WARNING ("threshold values: Option `%s' not allowed inside a `Plugin' " - "block.", option->key); + if (strcasecmp("Type", option->key) == 0) + status = ut_config_type(&th, option); + else if (strcasecmp("Instance", option->key) == 0) + status = ut_config_plugin_instance(&th, option); + else { + WARNING("threshold values: Option `%s' not allowed inside a `Plugin' " + "block.", + option->key); status = -1; } @@ -352,41 +317,36 @@ static int ut_config_plugin (const threshold_t *th_orig, oconfig_item_t *ci) return (status); } /* int ut_config_plugin */ -static int ut_config_host (const threshold_t *th_orig, oconfig_item_t *ci) -{ +static int ut_config_host(const threshold_t *th_orig, oconfig_item_t *ci) { threshold_t th; int status = 0; - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("threshold values: The `Host' block needs exactly one string " - "argument."); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("threshold values: The `Host' block needs exactly one string " + "argument."); return (-1); } - if (ci->children_num < 1) - { - WARNING ("threshold values: The `Host' block needs at least one nested " - "block."); + if (ci->children_num < 1) { + WARNING("threshold values: The `Host' block needs at least one nested " + "block."); return (-1); } - memcpy (&th, th_orig, sizeof (th)); - sstrncpy (th.host, ci->values[0].value.string, sizeof (th.host)); + memcpy(&th, th_orig, sizeof(th)); + sstrncpy(th.host, ci->values[0].value.string, sizeof(th.host)); - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; - if (strcasecmp ("Type", option->key) == 0) - status = ut_config_type (&th, option); - else if (strcasecmp ("Plugin", option->key) == 0) - status = ut_config_plugin (&th, option); - else - { - WARNING ("threshold values: Option `%s' not allowed inside a `Host' " - "block.", option->key); + if (strcasecmp("Type", option->key) == 0) + status = ut_config_type(&th, option); + else if (strcasecmp("Plugin", option->key) == 0) + status = ut_config_plugin(&th, option); + else { + WARNING("threshold values: Option `%s' not allowed inside a `Host' " + "block.", + option->key); status = -1; } @@ -396,9 +356,9 @@ static int ut_config_host (const threshold_t *th_orig, oconfig_item_t *ci) return (status); } /* int ut_config_host */ -/* - * End of the functions used to configure threshold values. - */ + /* + * End of the functions used to configure threshold values. + */ /* }}} */ /* @@ -408,13 +368,9 @@ static int ut_config_host (const threshold_t *th_orig, oconfig_item_t *ci) * if appropriate. * Does not fail. */ -static int ut_report_state (const data_set_t *ds, - const value_list_t *vl, - const threshold_t *th, - const gauge_t *values, - int ds_index, - int state) -{ /* {{{ */ +static int ut_report_state(const data_set_t *ds, const value_list_t *vl, + const threshold_t *th, const gauge_t *values, + int ds_index, int state) { /* {{{ */ int state_old; notification_t n; @@ -424,41 +380,40 @@ static int ut_report_state (const data_set_t *ds, int status; /* Check if hits matched */ - if ( (th->hits != 0) ) - { - int hits = uc_get_hits(ds,vl); + if ((th->hits != 0)) { + int hits = uc_get_hits(ds, vl); /* STATE_OKAY resets hits unless PERSIST_OK flag is set. Hits resets if * threshold is hit. */ - if ( ( (state == STATE_OKAY) && ((th->flags & UT_FLAG_PERSIST_OK) == 0) ) || (hits > th->hits) ) - { - DEBUG("ut_report_state: reset uc_get_hits = 0"); - uc_set_hits(ds,vl,0); /* reset hit counter and notify */ + if (((state == STATE_OKAY) && ((th->flags & UT_FLAG_PERSIST_OK) == 0)) || + (hits > th->hits)) { + DEBUG("ut_report_state: reset uc_get_hits = 0"); + uc_set_hits(ds, vl, 0); /* reset hit counter and notify */ } else { - DEBUG("ut_report_state: th->hits = %d, uc_get_hits = %d",th->hits,uc_get_hits(ds,vl)); - (void) uc_inc_hits(ds,vl,1); /* increase hit counter */ + DEBUG("ut_report_state: th->hits = %d, uc_get_hits = %d", th->hits, + uc_get_hits(ds, vl)); + (void)uc_inc_hits(ds, vl, 1); /* increase hit counter */ return (0); } } /* end check hits */ - state_old = uc_get_state (ds, vl); + state_old = uc_get_state(ds, vl); /* If the state didn't change, report if `persistent' is specified. If the * state is `okay', then only report if `persist_ok` flag is set. */ - if (state == state_old) - { + if (state == state_old) { if ((th->flags & UT_FLAG_PERSIST) == 0) return (0); - else if ( (state == STATE_OKAY) && ((th->flags & UT_FLAG_PERSIST_OK) == 0) ) + else if ((state == STATE_OKAY) && ((th->flags & UT_FLAG_PERSIST_OK) == 0)) return (0); } if (state != state_old) - uc_set_state (ds, vl, state); + uc_set_state(ds, vl, state); - NOTIFICATION_INIT_VL (&n, vl); + NOTIFICATION_INIT_VL(&n, vl); buf = n.message; - bufsize = sizeof (n.message); + bufsize = sizeof(n.message); if (state == STATE_OKAY) n.severity = NOTIF_OKAY; @@ -469,89 +424,73 @@ static int ut_report_state (const data_set_t *ds, n.time = vl->time; - status = ssnprintf (buf, bufsize, "Host %s, plugin %s", - vl->host, vl->plugin); + status = ssnprintf(buf, bufsize, "Host %s, plugin %s", vl->host, vl->plugin); buf += status; bufsize -= status; - if (vl->plugin_instance[0] != '\0') - { - status = ssnprintf (buf, bufsize, " (instance %s)", - vl->plugin_instance); + if (vl->plugin_instance[0] != '\0') { + status = ssnprintf(buf, bufsize, " (instance %s)", vl->plugin_instance); buf += status; bufsize -= status; } - status = ssnprintf (buf, bufsize, " type %s", vl->type); + status = ssnprintf(buf, bufsize, " type %s", vl->type); buf += status; bufsize -= status; - if (vl->type_instance[0] != '\0') - { - status = ssnprintf (buf, bufsize, " (instance %s)", - vl->type_instance); + if (vl->type_instance[0] != '\0') { + status = ssnprintf(buf, bufsize, " (instance %s)", vl->type_instance); buf += status; bufsize -= status; } - plugin_notification_meta_add_string (&n, "DataSource", - ds->ds[ds_index].name); - plugin_notification_meta_add_double (&n, "CurrentValue", values[ds_index]); - plugin_notification_meta_add_double (&n, "WarningMin", th->warning_min); - plugin_notification_meta_add_double (&n, "WarningMax", th->warning_max); - plugin_notification_meta_add_double (&n, "FailureMin", th->failure_min); - plugin_notification_meta_add_double (&n, "FailureMax", th->failure_max); + plugin_notification_meta_add_string(&n, "DataSource", ds->ds[ds_index].name); + plugin_notification_meta_add_double(&n, "CurrentValue", values[ds_index]); + plugin_notification_meta_add_double(&n, "WarningMin", th->warning_min); + plugin_notification_meta_add_double(&n, "WarningMax", th->warning_max); + plugin_notification_meta_add_double(&n, "FailureMin", th->failure_min); + plugin_notification_meta_add_double(&n, "FailureMax", th->failure_max); /* Send an okay notification */ - if (state == STATE_OKAY) - { + if (state == STATE_OKAY) { if (state_old == STATE_MISSING) - ssnprintf (buf, bufsize, ": Value is no longer missing."); + ssnprintf(buf, bufsize, ": Value is no longer missing."); else - ssnprintf (buf, bufsize, - ": All data sources are within range again. " - "Current value of \"%s\" is %f.", - ds->ds[ds_index].name, values[ds_index]); - } - else - { + ssnprintf(buf, bufsize, ": All data sources are within range again. " + "Current value of \"%s\" is %f.", + ds->ds[ds_index].name, values[ds_index]); + } else { double min; double max; min = (state == STATE_ERROR) ? th->failure_min : th->warning_min; max = (state == STATE_ERROR) ? th->failure_max : th->warning_max; - if (th->flags & UT_FLAG_INVERT) - { - if (!isnan (min) && !isnan (max)) - { - ssnprintf (buf, bufsize, ": Data source \"%s\" is currently " - "%f. That is within the %s region of %f%s and %f%s.", - ds->ds[ds_index].name, values[ds_index], - (state == STATE_ERROR) ? "failure" : "warning", - min, ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "", - max, ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : ""); + if (th->flags & UT_FLAG_INVERT) { + if (!isnan(min) && !isnan(max)) { + ssnprintf(buf, bufsize, + ": Data source \"%s\" is currently " + "%f. That is within the %s region of %f%s and %f%s.", + ds->ds[ds_index].name, values[ds_index], + (state == STATE_ERROR) ? "failure" : "warning", min, + ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "", max, + ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : ""); + } else { + ssnprintf(buf, bufsize, ": Data source \"%s\" is currently " + "%f. That is %s the %s threshold of %f%s.", + ds->ds[ds_index].name, values[ds_index], + isnan(min) ? "below" : "above", + (state == STATE_ERROR) ? "failure" : "warning", + isnan(min) ? max : min, + ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : ""); } - else - { - ssnprintf (buf, bufsize, ": Data source \"%s\" is currently " - "%f. That is %s the %s threshold of %f%s.", - ds->ds[ds_index].name, values[ds_index], - isnan (min) ? "below" : "above", - (state == STATE_ERROR) ? "failure" : "warning", - isnan (min) ? max : min, - ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : ""); - } - } - else if (th->flags & UT_FLAG_PERCENTAGE) - { + } else if (th->flags & UT_FLAG_PERCENTAGE) { gauge_t value; gauge_t sum; sum = 0.0; - for (size_t i = 0; i < vl->values_len; i++) - { - if (isnan (values[i])) + for (size_t i = 0; i < vl->values_len; i++) { + if (isnan(values[i])) continue; sum += values[i]; @@ -562,27 +501,27 @@ static int ut_report_state (const data_set_t *ds, else value = 100.0 * values[ds_index] / sum; - ssnprintf (buf, bufsize, ": Data source \"%s\" is currently " - "%g (%.2f%%). That is %s the %s threshold of %.2f%%.", - ds->ds[ds_index].name, values[ds_index], value, - (value < min) ? "below" : "above", - (state == STATE_ERROR) ? "failure" : "warning", - (value < min) ? min : max); - } - else /* is not inverted */ + ssnprintf(buf, bufsize, + ": Data source \"%s\" is currently " + "%g (%.2f%%). That is %s the %s threshold of %.2f%%.", + ds->ds[ds_index].name, values[ds_index], value, + (value < min) ? "below" : "above", + (state == STATE_ERROR) ? "failure" : "warning", + (value < min) ? min : max); + } else /* is not inverted */ { - ssnprintf (buf, bufsize, ": Data source \"%s\" is currently " - "%f. That is %s the %s threshold of %f.", - ds->ds[ds_index].name, values[ds_index], - (values[ds_index] < min) ? "below" : "above", - (state == STATE_ERROR) ? "failure" : "warning", - (values[ds_index] < min) ? min : max); + ssnprintf(buf, bufsize, ": Data source \"%s\" is currently " + "%f. That is %s the %s threshold of %f.", + ds->ds[ds_index].name, values[ds_index], + (values[ds_index] < min) ? "below" : "above", + (state == STATE_ERROR) ? "failure" : "warning", + (values[ds_index] < min) ? min : max); } } - plugin_dispatch_notification (&n); + plugin_dispatch_notification(&n); - plugin_notification_meta_free (n.meta); + plugin_notification_meta_free(n.meta); return (0); } /* }}} int ut_report_state */ @@ -596,37 +535,30 @@ static int ut_report_state (const data_set_t *ds, * appropriate. * Does not fail. */ -static int ut_check_one_data_source (const data_set_t *ds, - const value_list_t __attribute__((unused)) *vl, - const threshold_t *th, - const gauge_t *values, - int ds_index) -{ /* {{{ */ +static int ut_check_one_data_source( + const data_set_t *ds, const value_list_t __attribute__((unused)) * vl, + const threshold_t *th, const gauge_t *values, int ds_index) { /* {{{ */ const char *ds_name; int is_warning = 0; int is_failure = 0; int prev_state = STATE_OKAY; /* check if this threshold applies to this data source */ - if (ds != NULL) - { + if (ds != NULL) { ds_name = ds->ds[ds_index].name; - if ((th->data_source[0] != 0) - && (strcmp (ds_name, th->data_source) != 0)) + if ((th->data_source[0] != 0) && (strcmp(ds_name, th->data_source) != 0)) return (STATE_OKAY); } - if ((th->flags & UT_FLAG_INVERT) != 0) - { + if ((th->flags & UT_FLAG_INVERT) != 0) { is_warning--; is_failure--; } /* XXX: This is an experimental code, not optimized, not fast, not reliable, * and probably, do not work as you expect. Enjoy! :D */ - if (th->hysteresis > 0) - { - prev_state = uc_get_state(ds,vl); + if (th->hysteresis > 0) { + prev_state = uc_get_state(ds, vl); /* The purpose of hysteresis is elliminating flapping state when the value * oscilates around the thresholds. In other words, what is important is * the previous state; if the new value would trigger a transition, make @@ -637,35 +569,37 @@ static int ut_check_one_data_source (const data_set_t *ds, * There is no hysteresis for the OKAY state. * */ gauge_t hysteresis_for_warning = 0, hysteresis_for_failure = 0; - switch (prev_state) - { - case STATE_ERROR: - hysteresis_for_failure = th->hysteresis; - break; - case STATE_WARNING: - hysteresis_for_warning = th->hysteresis; - break; - case STATE_OKAY: - /* do nothing -- the hysteresis only applies to the non-normal states */ - break; + switch (prev_state) { + case STATE_ERROR: + hysteresis_for_failure = th->hysteresis; + break; + case STATE_WARNING: + hysteresis_for_warning = th->hysteresis; + break; + case STATE_OKAY: + /* do nothing -- the hysteresis only applies to the non-normal states */ + break; } - if ((!isnan (th->failure_min) && (th->failure_min + hysteresis_for_failure > values[ds_index])) - || (!isnan (th->failure_max) && (th->failure_max - hysteresis_for_failure < values[ds_index]))) + if ((!isnan(th->failure_min) && + (th->failure_min + hysteresis_for_failure > values[ds_index])) || + (!isnan(th->failure_max) && + (th->failure_max - hysteresis_for_failure < values[ds_index]))) is_failure++; - if ((!isnan (th->warning_min) && (th->warning_min + hysteresis_for_warning > values[ds_index])) - || (!isnan (th->warning_max) && (th->warning_max - hysteresis_for_warning < values[ds_index]))) + if ((!isnan(th->warning_min) && + (th->warning_min + hysteresis_for_warning > values[ds_index])) || + (!isnan(th->warning_max) && + (th->warning_max - hysteresis_for_warning < values[ds_index]))) is_warning++; - } - else { /* no hysteresis */ - if ((!isnan (th->failure_min) && (th->failure_min > values[ds_index])) - || (!isnan (th->failure_max) && (th->failure_max < values[ds_index]))) + } else { /* no hysteresis */ + if ((!isnan(th->failure_min) && (th->failure_min > values[ds_index])) || + (!isnan(th->failure_max) && (th->failure_max < values[ds_index]))) is_failure++; - if ((!isnan (th->warning_min) && (th->warning_min > values[ds_index])) - || (!isnan (th->warning_max) && (th->warning_max < values[ds_index]))) + if ((!isnan(th->warning_min) && (th->warning_min > values[ds_index])) || + (!isnan(th->warning_max) && (th->warning_max < values[ds_index]))) is_warning++; } @@ -686,59 +620,52 @@ static int ut_check_one_data_source (const data_set_t *ds, * which is `okay' if nothing has failed. * Returns less than zero if the data set doesn't have any data sources. */ -static int ut_check_one_threshold (const data_set_t *ds, - const value_list_t *vl, - const threshold_t *th, - const gauge_t *values, - int *ret_ds_index) -{ /* {{{ */ +static int ut_check_one_threshold(const data_set_t *ds, const value_list_t *vl, + const threshold_t *th, const gauge_t *values, + int *ret_ds_index) { /* {{{ */ int ret = -1; int ds_index = -1; gauge_t values_copy[ds->ds_num]; - memcpy (values_copy, values, sizeof (values_copy)); + memcpy(values_copy, values, sizeof(values_copy)); - if ((th->flags & UT_FLAG_PERCENTAGE) != 0) - { + if ((th->flags & UT_FLAG_PERCENTAGE) != 0) { int num = 0; - gauge_t sum=0.0; + gauge_t sum = 0.0; - if (ds->ds_num == 1) - { - WARNING ("ut_check_one_threshold: The %s type has only one data " + if (ds->ds_num == 1) { + WARNING( + "ut_check_one_threshold: The %s type has only one data " "source, but you have configured to check this as a percentage. " "That doesn't make much sense, because the percentage will always " - "be 100%%!", ds->type); + "be 100%%!", + ds->type); } /* Prepare `sum' and `num'. */ for (size_t i = 0; i < ds->ds_num; i++) - if (!isnan (values[i])) - { + if (!isnan(values[i])) { num++; - sum += values[i]; + sum += values[i]; } - if ((num == 0) /* All data sources are undefined. */ + if ((num == 0) /* All data sources are undefined. */ || (sum == 0.0)) /* Sum is zero, cannot calculate percentage. */ { for (size_t i = 0; i < ds->ds_num; i++) values_copy[i] = NAN; - } - else /* We can actually calculate the percentage. */ + } else /* We can actually calculate the percentage. */ { for (size_t i = 0; i < ds->ds_num; i++) values_copy[i] = 100.0 * values[i] / sum; } } /* if (UT_FLAG_PERCENTAGE) */ - for (size_t i = 0; i < ds->ds_num; i++) - { + for (size_t i = 0; i < ds->ds_num; i++) { int status; - status = ut_check_one_data_source (ds, vl, th, values_copy, i); - if (ret < status) - { + status = ut_check_one_data_source(ds, vl, th, values_copy, i); + if (ret < status) { ret = status; ds_index = i; } @@ -759,9 +686,9 @@ static int ut_check_one_threshold (const data_set_t *ds, * Returns zero on success and if no threshold has been configured. Returns * less than zero on failure. */ -static int ut_check_threshold (const data_set_t *ds, const value_list_t *vl, - __attribute__((unused)) user_data_t *ud) -{ /* {{{ */ +static int ut_check_threshold(const data_set_t *ds, const value_list_t *vl, + __attribute__((unused)) + user_data_t *ud) { /* {{{ */ threshold_t *th; gauge_t *values; int status; @@ -775,32 +702,29 @@ static int ut_check_threshold (const data_set_t *ds, const value_list_t *vl, /* Is this lock really necessary? So far, thresholds are only inserted at * startup. -octo */ - pthread_mutex_lock (&threshold_lock); - th = threshold_search (vl); - pthread_mutex_unlock (&threshold_lock); + pthread_mutex_lock(&threshold_lock); + th = threshold_search(vl); + pthread_mutex_unlock(&threshold_lock); if (th == NULL) return (0); - DEBUG ("ut_check_threshold: Found matching threshold(s)"); + DEBUG("ut_check_threshold: Found matching threshold(s)"); - values = uc_get_rate (ds, vl); + values = uc_get_rate(ds, vl); if (values == NULL) return (0); - while (th != NULL) - { + while (th != NULL) { int ds_index = -1; - status = ut_check_one_threshold (ds, vl, th, values, &ds_index); - if (status < 0) - { - ERROR ("ut_check_threshold: ut_check_one_threshold failed."); - sfree (values); + status = ut_check_one_threshold(ds, vl, th, values, &ds_index); + if (status < 0) { + ERROR("ut_check_threshold: ut_check_one_threshold failed."); + sfree(values); return (-1); } - if (worst_state < status) - { + if (worst_state < status) { worst_state = status; worst_th = th; worst_ds_index = ds_index; @@ -809,16 +733,15 @@ static int ut_check_threshold (const data_set_t *ds, const value_list_t *vl, th = th->next; } /* while (th) */ - status = ut_report_state (ds, vl, worst_th, values, - worst_ds_index, worst_state); - if (status != 0) - { - ERROR ("ut_check_threshold: ut_report_state failed."); - sfree (values); + status = + ut_report_state(ds, vl, worst_th, values, worst_ds_index, worst_state); + if (status != 0) { + ERROR("ut_check_threshold: ut_report_state failed."); + sfree(values); return (-1); } - sfree (values); + sfree(values); return (0); } /* }}} int ut_check_threshold */ @@ -828,9 +751,8 @@ static int ut_check_threshold (const data_set_t *ds, const value_list_t *vl, * * This function is called whenever a value goes "missing". */ -static int ut_missing (const value_list_t *vl, - __attribute__((unused)) user_data_t *ud) -{ /* {{{ */ +static int ut_missing(const value_list_t *vl, + __attribute__((unused)) user_data_t *ud) { /* {{{ */ threshold_t *th; cdtime_t missing_time; char identifier[6 * DATA_MAX_NAME_LEN]; @@ -840,62 +762,57 @@ static int ut_missing (const value_list_t *vl, if (threshold_tree == NULL) return (0); - th = threshold_search (vl); + th = threshold_search(vl); /* dispatch notifications for "interesting" values only */ if ((th == NULL) || ((th->flags & UT_FLAG_INTERESTING) == 0)) return (0); - now = cdtime (); + now = cdtime(); missing_time = now - vl->time; - FORMAT_VL (identifier, sizeof (identifier), vl); + FORMAT_VL(identifier, sizeof(identifier), vl); - NOTIFICATION_INIT_VL (&n, vl); - ssnprintf (n.message, sizeof (n.message), - "%s has not been updated for %.3f seconds.", - identifier, CDTIME_T_TO_DOUBLE (missing_time)); + NOTIFICATION_INIT_VL(&n, vl); + ssnprintf(n.message, sizeof(n.message), + "%s has not been updated for %.3f seconds.", identifier, + CDTIME_T_TO_DOUBLE(missing_time)); n.time = now; - plugin_dispatch_notification (&n); + plugin_dispatch_notification(&n); return (0); } /* }}} int ut_missing */ -static int ut_config (oconfig_item_t *ci) -{ /* {{{ */ +static int ut_config(oconfig_item_t *ci) { /* {{{ */ int status = 0; - int old_size = c_avl_size (threshold_tree); + int old_size = c_avl_size(threshold_tree); - if (threshold_tree == NULL) - { - threshold_tree = c_avl_create ((int (*) (const void *, const void *)) strcmp); - if (threshold_tree == NULL) - { - ERROR ("ut_config: c_avl_create failed."); + if (threshold_tree == NULL) { + threshold_tree = c_avl_create((int (*)(const void *, const void *))strcmp); + if (threshold_tree == NULL) { + ERROR("ut_config: c_avl_create failed."); return (-1); } } threshold_t th = { - .warning_min = NAN, - .warning_max = NAN, - .failure_min = NAN, - .failure_max = NAN, - .flags = UT_FLAG_INTERESTING /* interesting by default */ + .warning_min = NAN, + .warning_max = NAN, + .failure_min = NAN, + .failure_max = NAN, + .flags = UT_FLAG_INTERESTING /* interesting by default */ }; - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; - if (strcasecmp ("Type", option->key) == 0) - status = ut_config_type (&th, option); - else if (strcasecmp ("Plugin", option->key) == 0) - status = ut_config_plugin (&th, option); - else if (strcasecmp ("Host", option->key) == 0) - status = ut_config_host (&th, option); - else - { - WARNING ("threshold values: Option `%s' not allowed here.", option->key); + if (strcasecmp("Type", option->key) == 0) + status = ut_config_type(&th, option); + else if (strcasecmp("Plugin", option->key) == 0) + status = ut_config_plugin(&th, option); + else if (strcasecmp("Host", option->key) == 0) + status = ut_config_host(&th, option); + else { + WARNING("threshold values: Option `%s' not allowed here.", option->key); status = -1; } @@ -904,20 +821,18 @@ static int ut_config (oconfig_item_t *ci) } /* register callbacks if this is the first time we see a valid config */ - if ((old_size == 0) && (c_avl_size (threshold_tree) > 0)) - { - plugin_register_missing ("threshold", ut_missing, - /* user data = */ NULL); - plugin_register_write ("threshold", ut_check_threshold, - /* user data = */ NULL); + if ((old_size == 0) && (c_avl_size(threshold_tree) > 0)) { + plugin_register_missing("threshold", ut_missing, + /* user data = */ NULL); + plugin_register_write("threshold", ut_check_threshold, + /* user data = */ NULL); } return (status); } /* }}} int um_config */ -void module_register (void) -{ - plugin_register_complex_config ("threshold", ut_config); +void module_register(void) { + plugin_register_complex_config("threshold", ut_config); } /* vim: set sw=2 ts=8 sts=2 tw=78 et fdm=marker : */ diff --git a/src/tokyotyrant.c b/src/tokyotyrant.c index 154215f8..cb366d38 100644 --- a/src/tokyotyrant.c +++ b/src/tokyotyrant.c @@ -21,8 +21,8 @@ #include "collectd.h" -#include "plugin.h" #include "common.h" +#include "plugin.h" #include "utils_cache.h" #include @@ -30,148 +30,125 @@ #define DEFAULT_HOST "127.0.0.1" #define DEFAULT_PORT 1978 -static const char *config_keys[] = -{ - "Host", - "Port" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"Host", "Port"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static char *config_host = NULL; static char *config_port = NULL; static TCRDB *rdb = NULL; -static int tt_config (const char *key, const char *value) -{ - if (strcasecmp ("Host", key) == 0) - { - char *temp; - - temp = strdup (value); - if (temp == NULL) - { - ERROR("tokyotyrant plugin: Host strdup failed."); - return (1); - } - sfree (config_host); - config_host = temp; - } - else if (strcasecmp ("Port", key) == 0) - { - char *temp; - - temp = strdup (value); - if (temp == NULL) - { - ERROR("tokyotyrant plugin: Port strdup failed."); - return (1); - } - sfree (config_port); - config_port = temp; - } - else - { - ERROR ("tokyotyrant plugin: error: unrecognized configuration key %s", key); - return (-1); - } - - return (0); +static int tt_config(const char *key, const char *value) { + if (strcasecmp("Host", key) == 0) { + char *temp; + + temp = strdup(value); + if (temp == NULL) { + ERROR("tokyotyrant plugin: Host strdup failed."); + return (1); + } + sfree(config_host); + config_host = temp; + } else if (strcasecmp("Port", key) == 0) { + char *temp; + + temp = strdup(value); + if (temp == NULL) { + ERROR("tokyotyrant plugin: Port strdup failed."); + return (1); + } + sfree(config_port); + config_port = temp; + } else { + ERROR("tokyotyrant plugin: error: unrecognized configuration key %s", key); + return (-1); + } + + return (0); } -static void printerr (void) -{ - int ecode = tcrdbecode(rdb); - ERROR ("tokyotyrant plugin: error: %d, %s", - ecode, tcrdberrmsg(ecode)); +static void printerr(void) { + int ecode = tcrdbecode(rdb); + ERROR("tokyotyrant plugin: error: %d, %s", ecode, tcrdberrmsg(ecode)); } -static void tt_submit (gauge_t value, const char* type) -{ - value_list_t vl = VALUE_LIST_INIT; +static void tt_submit(gauge_t value, const char *type) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; - sstrncpy (vl.host, config_host, sizeof (vl.host)); - sstrncpy (vl.plugin, "tokyotyrant", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, config_port, - sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); + sstrncpy(vl.host, config_host, sizeof(vl.host)); + sstrncpy(vl.plugin, "tokyotyrant", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, config_port, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static void tt_open_db (void) -{ - const char *host; - int port = DEFAULT_PORT; - - if (rdb != NULL) - return; - - host = ((config_host != NULL) ? config_host : DEFAULT_HOST); - - if (config_port != NULL) - { - port = service_name_to_port_number (config_port); - if (port <= 0) - return; - } - - rdb = tcrdbnew (); - if (rdb == NULL) - return; - else if (!tcrdbopen(rdb, host, port)) - { - printerr (); - tcrdbdel (rdb); - rdb = NULL; - } +static void tt_open_db(void) { + const char *host; + int port = DEFAULT_PORT; + + if (rdb != NULL) + return; + + host = ((config_host != NULL) ? config_host : DEFAULT_HOST); + + if (config_port != NULL) { + port = service_name_to_port_number(config_port); + if (port <= 0) + return; + } + + rdb = tcrdbnew(); + if (rdb == NULL) + return; + else if (!tcrdbopen(rdb, host, port)) { + printerr(); + tcrdbdel(rdb); + rdb = NULL; + } } /* void tt_open_db */ -static int tt_read (void) { - gauge_t rnum, size; +static int tt_read(void) { + gauge_t rnum, size; - tt_open_db (); - if (rdb == NULL) - return (-1); + tt_open_db(); + if (rdb == NULL) + return (-1); - rnum = tcrdbrnum(rdb); - tt_submit (rnum, "records"); + rnum = tcrdbrnum(rdb); + tt_submit(rnum, "records"); - size = tcrdbsize(rdb); - tt_submit (size, "file_size"); + size = tcrdbsize(rdb); + tt_submit(size, "file_size"); - return (0); + return (0); } -static int tt_shutdown(void) -{ - sfree(config_host); - sfree(config_port); - - if (rdb != NULL) - { - if (!tcrdbclose(rdb)) - { - printerr (); - tcrdbdel (rdb); - return (1); - } - tcrdbdel (rdb); - rdb = NULL; - } - - return(0); +static int tt_shutdown(void) { + sfree(config_host); + sfree(config_port); + + if (rdb != NULL) { + if (!tcrdbclose(rdb)) { + printerr(); + tcrdbdel(rdb); + return (1); + } + tcrdbdel(rdb); + rdb = NULL; + } + + return (0); } -void module_register (void) -{ - plugin_register_config("tokyotyrant", tt_config, - config_keys, config_keys_num); - plugin_register_read("tokyotyrant", tt_read); - plugin_register_shutdown("tokyotyrant", tt_shutdown); +void module_register(void) { + plugin_register_config("tokyotyrant", tt_config, config_keys, + config_keys_num); + plugin_register_read("tokyotyrant", tt_read); + plugin_register_shutdown("tokyotyrant", tt_shutdown); } /* vim: set sw=8 ts=8 tw=78 : */ diff --git a/src/turbostat.c b/src/turbostat.c index c242b6ee..62bd92b1 100644 --- a/src/turbostat.c +++ b/src/turbostat.c @@ -50,9 +50,12 @@ #define PLUGIN_NAME "turbostat" /* - * This tool uses the Model-Specific Registers (MSRs) present on Intel processors. - * The general description each of these registers, depending on the architecture, - * can be found in the Intel® 64 and IA-32 Architectures Software Developer Manual, + * This tool uses the Model-Specific Registers (MSRs) present on Intel + * processors. + * The general description each of these registers, depending on the + * architecture, + * can be found in the Intel® 64 and IA-32 Architectures Software Developer + * Manual, * Volume 3 Chapter 35. */ @@ -86,7 +89,8 @@ static unsigned int config_pkg_cstate; static _Bool apply_config_pkg_cstate; /* - * Boolean indicating if the processor supports 'I/O System-Management Interrupt counter' + * Boolean indicating if the processor supports 'I/O System-Management Interrupt + * counter' */ static _Bool do_smi; static _Bool config_smi; @@ -97,7 +101,8 @@ static _Bool apply_config_smi; * This feature enables the monitoring of the temperature of each core * * This feature has two limitations: - * - if MSR_IA32_TEMPERATURE_TARGET is not supported, the absolute temperature might be wrong + * - if MSR_IA32_TEMPERATURE_TARGET is not supported, the absolute temperature + * might be wrong * - Temperatures above the tcc_activation_temp are not recorded */ static _Bool do_dts; @@ -109,7 +114,8 @@ static _Bool apply_config_dts; * This feature allows the monitoring of the temperature of each package * * This feature has two limitations: - * - if MSR_IA32_TEMPERATURE_TARGET is not supported, the absolute temperature might be wrong + * - if MSR_IA32_TEMPERATURE_TARGET is not supported, the absolute temperature + * might be wrong * - Temperatures above the tcc_activation_temp are not recorded */ static _Bool do_ptm; @@ -128,62 +134,63 @@ static unsigned int config_rapl; static _Bool apply_config_rapl; static double rapl_energy_units; -#define RAPL_PKG (1 << 0) - /* 0x610 MSR_PKG_POWER_LIMIT */ - /* 0x611 MSR_PKG_ENERGY_STATUS */ -#define RAPL_DRAM (1 << 1) - /* 0x618 MSR_DRAM_POWER_LIMIT */ - /* 0x619 MSR_DRAM_ENERGY_STATUS */ - /* 0x61c MSR_DRAM_POWER_INFO */ -#define RAPL_CORES (1 << 2) - /* 0x638 MSR_PP0_POWER_LIMIT */ - /* 0x639 MSR_PP0_ENERGY_STATUS */ - -#define RAPL_GFX (1 << 3) - /* 0x640 MSR_PP1_POWER_LIMIT */ - /* 0x641 MSR_PP1_ENERGY_STATUS */ - /* 0x642 MSR_PP1_POLICY */ -#define TJMAX_DEFAULT 100 +#define RAPL_PKG (1 << 0) +/* 0x610 MSR_PKG_POWER_LIMIT */ +/* 0x611 MSR_PKG_ENERGY_STATUS */ +#define RAPL_DRAM (1 << 1) +/* 0x618 MSR_DRAM_POWER_LIMIT */ +/* 0x619 MSR_DRAM_ENERGY_STATUS */ +/* 0x61c MSR_DRAM_POWER_INFO */ +#define RAPL_CORES (1 << 2) +/* 0x638 MSR_PP0_POWER_LIMIT */ +/* 0x639 MSR_PP0_ENERGY_STATUS */ + +#define RAPL_GFX (1 << 3) +/* 0x640 MSR_PP1_POWER_LIMIT */ +/* 0x641 MSR_PP1_ENERGY_STATUS */ +/* 0x642 MSR_PP1_POLICY */ +#define TJMAX_DEFAULT 100 static cpu_set_t *cpu_present_set, *cpu_affinity_set, *cpu_saved_affinity_set; -static size_t cpu_present_setsize, cpu_affinity_setsize, cpu_saved_affinity_setsize; +static size_t cpu_present_setsize, cpu_affinity_setsize, + cpu_saved_affinity_setsize; static struct thread_data { - unsigned long long tsc; - unsigned long long aperf; - unsigned long long mperf; - unsigned long long c1; - unsigned int smi_count; - unsigned int cpu_id; - unsigned int flags; -#define CPU_IS_FIRST_THREAD_IN_CORE 0x2 -#define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4 -} *thread_delta, *thread_even, *thread_odd; + unsigned long long tsc; + unsigned long long aperf; + unsigned long long mperf; + unsigned long long c1; + unsigned int smi_count; + unsigned int cpu_id; + unsigned int flags; +#define CPU_IS_FIRST_THREAD_IN_CORE 0x2 +#define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4 +} * thread_delta, *thread_even, *thread_odd; static struct core_data { - unsigned long long c3; - unsigned long long c6; - unsigned long long c7; - unsigned int core_temp_c; - unsigned int core_id; -} *core_delta, *core_even, *core_odd; + unsigned long long c3; + unsigned long long c6; + unsigned long long c7; + unsigned int core_temp_c; + unsigned int core_id; +} * core_delta, *core_even, *core_odd; static struct pkg_data { - unsigned long long pc2; - unsigned long long pc3; - unsigned long long pc6; - unsigned long long pc7; - unsigned long long pc8; - unsigned long long pc9; - unsigned long long pc10; - unsigned int package_id; - uint32_t energy_pkg; /* MSR_PKG_ENERGY_STATUS */ - uint32_t energy_dram; /* MSR_DRAM_ENERGY_STATUS */ - uint32_t energy_cores; /* MSR_PP0_ENERGY_STATUS */ - uint32_t energy_gfx; /* MSR_PP1_ENERGY_STATUS */ - unsigned int tcc_activation_temp; - unsigned int pkg_temp_c; -} *package_delta, *package_even, *package_odd; + unsigned long long pc2; + unsigned long long pc3; + unsigned long long pc6; + unsigned long long pc7; + unsigned long long pc8; + unsigned long long pc9; + unsigned long long pc10; + unsigned int package_id; + uint32_t energy_pkg; /* MSR_PKG_ENERGY_STATUS */ + uint32_t energy_dram; /* MSR_DRAM_ENERGY_STATUS */ + uint32_t energy_cores; /* MSR_PP0_ENERGY_STATUS */ + uint32_t energy_gfx; /* MSR_PP1_ENERGY_STATUS */ + unsigned int tcc_activation_temp; + unsigned int pkg_temp_c; +} * package_delta, *package_even, *package_odd; #define DELTA_COUNTERS thread_delta, core_delta, package_delta #define ODD_COUNTERS thread_odd, core_odd, package_odd @@ -193,46 +200,41 @@ static _Bool is_even = 1; static _Bool allocated = 0; static _Bool initialized = 0; -#define GET_THREAD(thread_base, thread_no, core_no, pkg_no) \ - (thread_base + \ - (pkg_no) * topology.num_cores * topology.num_threads + \ - (core_no) * topology.num_threads + \ - (thread_no)) -#define GET_CORE(core_base, core_no, pkg_no) \ - (core_base + \ - (pkg_no) * topology.num_cores + \ - (core_no)) +#define GET_THREAD(thread_base, thread_no, core_no, pkg_no) \ + (thread_base + (pkg_no)*topology.num_cores * topology.num_threads + \ + (core_no)*topology.num_threads + (thread_no)) +#define GET_CORE(core_base, core_no, pkg_no) \ + (core_base + (pkg_no)*topology.num_cores + (core_no)) #define GET_PKG(pkg_base, pkg_no) (pkg_base + pkg_no) struct cpu_topology { - unsigned int package_id; - unsigned int core_id; - _Bool first_core_in_package; - _Bool first_thread_in_core; + unsigned int package_id; + unsigned int core_id; + _Bool first_core_in_package; + _Bool first_thread_in_core; }; static struct topology { - unsigned int max_cpu_id; - unsigned int num_packages; - unsigned int num_cores; - unsigned int num_threads; - struct cpu_topology *cpus; + unsigned int max_cpu_id; + unsigned int num_packages; + unsigned int num_cores; + unsigned int num_threads; + struct cpu_topology *cpus; } topology; static cdtime_t time_even, time_odd, time_delta; -static const char *config_keys[] = -{ - "CoreCstates", - "PackageCstates", - "SystemManagementInterrupt", - "DigitalTemperatureSensor", - "PackageThermalManagement", - "TCCActivationTemp", - "RunningAveragePowerLimit", - "LogicalCoreNames", +static const char *config_keys[] = { + "CoreCstates", + "PackageCstates", + "SystemManagementInterrupt", + "DigitalTemperatureSensor", + "PackageThermalManagement", + "TCCActivationTemp", + "RunningAveragePowerLimit", + "LogicalCoreNames", }; -static const int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const int config_keys_num = STATIC_ARRAY_SIZE(config_keys); /***************************** * MSR Manipulation helpers * @@ -240,55 +242,54 @@ static const int config_keys_num = STATIC_ARRAY_SIZE (config_keys); /* * Open a MSR device for reading - * Can change the scheduling affinity of the current process if multiple_read is 1 + * Can change the scheduling affinity of the current process if multiple_read is + * 1 */ static int __attribute__((warn_unused_result)) -open_msr(unsigned int cpu, _Bool multiple_read) -{ - char pathname[32]; - int fd; - - /* - * If we need to do multiple read, let's migrate to the CPU - * Otherwise, we would lose time calling functions on another CPU - * - * If we are not yet initialized (cpu_affinity_setsize = 0), - * we need to skip this optimisation. - */ - if (multiple_read && cpu_affinity_setsize) { - CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set); - CPU_SET_S(cpu, cpu_affinity_setsize, cpu_affinity_set); - if (sched_setaffinity(0, cpu_affinity_setsize, cpu_affinity_set) == -1) { - ERROR("turbostat plugin: Could not migrate to CPU %d", cpu); - return -1; - } - } - - ssnprintf(pathname, sizeof(pathname), "/dev/cpu/%d/msr", cpu); - fd = open(pathname, O_RDONLY); - if (fd < 0) { - ERROR("turbostat plugin: failed to open %s", pathname); - return -1; - } - return fd; +open_msr(unsigned int cpu, _Bool multiple_read) { + char pathname[32]; + int fd; + + /* + * If we need to do multiple read, let's migrate to the CPU + * Otherwise, we would lose time calling functions on another CPU + * + * If we are not yet initialized (cpu_affinity_setsize = 0), + * we need to skip this optimisation. + */ + if (multiple_read && cpu_affinity_setsize) { + CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set); + CPU_SET_S(cpu, cpu_affinity_setsize, cpu_affinity_set); + if (sched_setaffinity(0, cpu_affinity_setsize, cpu_affinity_set) == -1) { + ERROR("turbostat plugin: Could not migrate to CPU %d", cpu); + return -1; + } + } + + ssnprintf(pathname, sizeof(pathname), "/dev/cpu/%d/msr", cpu); + fd = open(pathname, O_RDONLY); + if (fd < 0) { + ERROR("turbostat plugin: failed to open %s", pathname); + return -1; + } + return fd; } /* * Read a single MSR from an open file descriptor */ static int __attribute__((warn_unused_result)) -read_msr(int fd, off_t offset, unsigned long long *msr) -{ - ssize_t retval; - - retval = pread(fd, msr, sizeof *msr, offset); - - if (retval != sizeof *msr) { - ERROR("turbostat plugin: MSR offset 0x%llx read failed", - (unsigned long long)offset); - return -1; - } - return 0; +read_msr(int fd, off_t offset, unsigned long long *msr) { + ssize_t retval; + + retval = pread(fd, msr, sizeof *msr, offset); + + if (retval != sizeof *msr) { + ERROR("turbostat plugin: MSR offset 0x%llx read failed", + (unsigned long long)offset); + return -1; + } + return 0; } /* @@ -296,20 +297,18 @@ read_msr(int fd, off_t offset, unsigned long long *msr) * This call will not affect the scheduling affinity of this thread. */ static ssize_t __attribute__((warn_unused_result)) -get_msr(unsigned int cpu, off_t offset, unsigned long long *msr) -{ - ssize_t retval; - int fd; - - fd = open_msr(cpu, 0); - if (fd < 0) - return fd; - retval = read_msr(fd, offset, msr); - close(fd); - return retval; +get_msr(unsigned int cpu, off_t offset, unsigned long long *msr) { + ssize_t retval; + int fd; + + fd = open_msr(cpu, 0); + if (fd < 0) + return fd; + retval = read_msr(fd, offset, msr); + close(fd); + return retval; } - /******************************** * Raw data acquisition (1 CPU) * ********************************/ @@ -317,108 +316,108 @@ get_msr(unsigned int cpu, off_t offset, unsigned long long *msr) /* * Read every data avalaible for a single CPU * - * Core data is shared for all threads in one core: extracted only for the first thread - * Package data is shared for all core in one package: extracted only for the first thread of the first core + * Core data is shared for all threads in one core: extracted only for the first + * thread + * Package data is shared for all core in one package: extracted only for the + * first thread of the first core * * Side effect: migrates to the targeted CPU */ static int __attribute__((warn_unused_result)) -get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) -{ - unsigned int cpu = t->cpu_id; - unsigned long long msr; - int msr_fd; - int retval = 0; - - msr_fd = open_msr(cpu, 1); - if (msr_fd < 0) - return msr_fd; - -#define READ_MSR(msr, dst) \ -do { \ - if (read_msr(msr_fd, msr, dst)) { \ - ERROR("turbostat plugin: Unable to read " #msr); \ - retval = -1; \ - goto out; \ - } \ -} while (0) - - READ_MSR(MSR_IA32_TSC, &t->tsc); - - READ_MSR(MSR_IA32_APERF, &t->aperf); - READ_MSR(MSR_IA32_MPERF, &t->mperf); - - if (do_smi) { - READ_MSR(MSR_SMI_COUNT, &msr); - t->smi_count = msr & 0xFFFFFFFF; - } - - /* collect core counters only for 1st thread in core */ - if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) { - retval = 0; - goto out; - } - - if (do_core_cstate & (1 << 3)) - READ_MSR(MSR_CORE_C3_RESIDENCY, &c->c3); - if (do_core_cstate & (1 << 6)) - READ_MSR(MSR_CORE_C6_RESIDENCY, &c->c6); - if (do_core_cstate & (1 << 7)) - READ_MSR(MSR_CORE_C7_RESIDENCY, &c->c7); - - if (do_dts) { - READ_MSR(MSR_IA32_THERM_STATUS, &msr); - c->core_temp_c = p->tcc_activation_temp - ((msr >> 16) & 0x7F); - } - - /* collect package counters only for 1st core in package */ - if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) { - retval = 0; - goto out; - } - - if (do_pkg_cstate & (1 << 2)) - READ_MSR(MSR_PKG_C2_RESIDENCY, &p->pc2); - if (do_pkg_cstate & (1 << 3)) - READ_MSR(MSR_PKG_C3_RESIDENCY, &p->pc3); - if (do_pkg_cstate & (1 << 6)) - READ_MSR(MSR_PKG_C6_RESIDENCY, &p->pc6); - if (do_pkg_cstate & (1 << 7)) - READ_MSR(MSR_PKG_C7_RESIDENCY, &p->pc7); - if (do_pkg_cstate & (1 << 8)) - READ_MSR(MSR_PKG_C8_RESIDENCY, &p->pc8); - if (do_pkg_cstate & (1 << 9)) - READ_MSR(MSR_PKG_C9_RESIDENCY, &p->pc9); - if (do_pkg_cstate & (1 << 10)) - READ_MSR(MSR_PKG_C10_RESIDENCY, &p->pc10); - - if (do_rapl & RAPL_PKG) { - READ_MSR(MSR_PKG_ENERGY_STATUS, &msr); - p->energy_pkg = msr & 0xFFFFFFFF; - } - if (do_rapl & RAPL_CORES) { - READ_MSR(MSR_PP0_ENERGY_STATUS, &msr); - p->energy_cores = msr & 0xFFFFFFFF; - } - if (do_rapl & RAPL_DRAM) { - READ_MSR(MSR_DRAM_ENERGY_STATUS, &msr); - p->energy_dram = msr & 0xFFFFFFFF; - } - if (do_rapl & RAPL_GFX) { - READ_MSR(MSR_PP1_ENERGY_STATUS, &msr); - p->energy_gfx = msr & 0xFFFFFFFF; - } - if (do_ptm) { - READ_MSR(MSR_IA32_PACKAGE_THERM_STATUS, &msr); - p->pkg_temp_c = p->tcc_activation_temp - ((msr >> 16) & 0x7F); - } +get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) { + unsigned int cpu = t->cpu_id; + unsigned long long msr; + int msr_fd; + int retval = 0; + + msr_fd = open_msr(cpu, 1); + if (msr_fd < 0) + return msr_fd; + +#define READ_MSR(msr, dst) \ + do { \ + if (read_msr(msr_fd, msr, dst)) { \ + ERROR("turbostat plugin: Unable to read " #msr); \ + retval = -1; \ + goto out; \ + } \ + } while (0) + + READ_MSR(MSR_IA32_TSC, &t->tsc); + + READ_MSR(MSR_IA32_APERF, &t->aperf); + READ_MSR(MSR_IA32_MPERF, &t->mperf); + + if (do_smi) { + READ_MSR(MSR_SMI_COUNT, &msr); + t->smi_count = msr & 0xFFFFFFFF; + } + + /* collect core counters only for 1st thread in core */ + if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) { + retval = 0; + goto out; + } + + if (do_core_cstate & (1 << 3)) + READ_MSR(MSR_CORE_C3_RESIDENCY, &c->c3); + if (do_core_cstate & (1 << 6)) + READ_MSR(MSR_CORE_C6_RESIDENCY, &c->c6); + if (do_core_cstate & (1 << 7)) + READ_MSR(MSR_CORE_C7_RESIDENCY, &c->c7); + + if (do_dts) { + READ_MSR(MSR_IA32_THERM_STATUS, &msr); + c->core_temp_c = p->tcc_activation_temp - ((msr >> 16) & 0x7F); + } + + /* collect package counters only for 1st core in package */ + if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) { + retval = 0; + goto out; + } + + if (do_pkg_cstate & (1 << 2)) + READ_MSR(MSR_PKG_C2_RESIDENCY, &p->pc2); + if (do_pkg_cstate & (1 << 3)) + READ_MSR(MSR_PKG_C3_RESIDENCY, &p->pc3); + if (do_pkg_cstate & (1 << 6)) + READ_MSR(MSR_PKG_C6_RESIDENCY, &p->pc6); + if (do_pkg_cstate & (1 << 7)) + READ_MSR(MSR_PKG_C7_RESIDENCY, &p->pc7); + if (do_pkg_cstate & (1 << 8)) + READ_MSR(MSR_PKG_C8_RESIDENCY, &p->pc8); + if (do_pkg_cstate & (1 << 9)) + READ_MSR(MSR_PKG_C9_RESIDENCY, &p->pc9); + if (do_pkg_cstate & (1 << 10)) + READ_MSR(MSR_PKG_C10_RESIDENCY, &p->pc10); + + if (do_rapl & RAPL_PKG) { + READ_MSR(MSR_PKG_ENERGY_STATUS, &msr); + p->energy_pkg = msr & 0xFFFFFFFF; + } + if (do_rapl & RAPL_CORES) { + READ_MSR(MSR_PP0_ENERGY_STATUS, &msr); + p->energy_cores = msr & 0xFFFFFFFF; + } + if (do_rapl & RAPL_DRAM) { + READ_MSR(MSR_DRAM_ENERGY_STATUS, &msr); + p->energy_dram = msr & 0xFFFFFFFF; + } + if (do_rapl & RAPL_GFX) { + READ_MSR(MSR_PP1_ENERGY_STATUS, &msr); + p->energy_gfx = msr & 0xFFFFFFFF; + } + if (do_ptm) { + READ_MSR(MSR_IA32_PACKAGE_THERM_STATUS, &msr); + p->pkg_temp_c = p->tcc_activation_temp - ((msr >> 16) & 0x7F); + } out: - close(msr_fd); - return retval; + close(msr_fd); + return retval; } - /********************************** * Evaluating the changes (1 CPU) * **********************************/ @@ -427,35 +426,35 @@ out: * Extract the evolution old->new in delta at a package level * (some are not new-delta, e.g. temperature) */ -static inline void -delta_package(struct pkg_data *delta, const struct pkg_data *new, const struct pkg_data *old) -{ - delta->pc2 = new->pc2 - old->pc2; - delta->pc3 = new->pc3 - old->pc3; - delta->pc6 = new->pc6 - old->pc6; - delta->pc7 = new->pc7 - old->pc7; - delta->pc8 = new->pc8 - old->pc8; - delta->pc9 = new->pc9 - old->pc9; - delta->pc10 = new->pc10 - old->pc10; - delta->pkg_temp_c = new->pkg_temp_c; - - delta->energy_pkg = new->energy_pkg - old->energy_pkg; - delta->energy_cores = new->energy_cores - old->energy_cores; - delta->energy_gfx = new->energy_gfx - old->energy_gfx; - delta->energy_dram = new->energy_dram - old->energy_dram; +static inline void delta_package(struct pkg_data *delta, + const struct pkg_data *new, + const struct pkg_data *old) { + delta->pc2 = new->pc2 - old->pc2; + delta->pc3 = new->pc3 - old->pc3; + delta->pc6 = new->pc6 - old->pc6; + delta->pc7 = new->pc7 - old->pc7; + delta->pc8 = new->pc8 - old->pc8; + delta->pc9 = new->pc9 - old->pc9; + delta->pc10 = new->pc10 - old->pc10; + delta->pkg_temp_c = new->pkg_temp_c; + + delta->energy_pkg = new->energy_pkg - old->energy_pkg; + delta->energy_cores = new->energy_cores - old->energy_cores; + delta->energy_gfx = new->energy_gfx - old->energy_gfx; + delta->energy_dram = new->energy_dram - old->energy_dram; } /* * Extract the evolution old->new in delta at a core level * (some are not new-delta, e.g. temperature) */ -static inline void -delta_core(struct core_data *delta, const struct core_data *new, const struct core_data *old) -{ - delta->c3 = new->c3 - old->c3; - delta->c6 = new->c6 - old->c6; - delta->c7 = new->c7 - old->c7; - delta->core_temp_c = new->core_temp_c; +static inline void delta_core(struct core_data *delta, + const struct core_data *new, + const struct core_data *old) { + delta->c3 = new->c3 - old->c3; + delta->c6 = new->c6 - old->c6; + delta->c7 = new->c7 - old->c7; + delta->core_temp_c = new->core_temp_c; } /* @@ -463,58 +462,57 @@ delta_core(struct core_data *delta, const struct core_data *new, const struct co * core_delta is required for c1 estimation (tsc - c0 - all core cstates) */ static inline int __attribute__((warn_unused_result)) -delta_thread(struct thread_data *delta, const struct thread_data *new, const struct thread_data *old, - const struct core_data *cdelta) -{ - delta->tsc = new->tsc - old->tsc; - - /* check for TSC < 1 Mcycles over interval */ - if (delta->tsc < (1000 * 1000)) { - WARNING("turbostat plugin: Insanely slow TSC rate, TSC stops " - "in idle? You can disable all c-states by booting with" - " 'idle=poll' or just the deep ones with" - " 'processor.max_cstate=1'"); - return -1; - } - - delta->c1 = new->c1 - old->c1; - - if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) { - delta->aperf = new->aperf - old->aperf; - delta->mperf = new->mperf - old->mperf; - } else { - if (!aperf_mperf_unstable) { - WARNING("turbostat plugin: APERF or MPERF went " - "backwards. Frequency results do not cover " - "the entire interval. Fix this by running " - "Linux-2.6.30 or later."); - - aperf_mperf_unstable = 1; - } - } - - /* - * As counter collection is not atomic, - * it is possible for mperf's non-halted cycles + idle states - * to exceed TSC's all cycles: show c1 = 0% in that case. - */ - if ((delta->mperf + cdelta->c3 + cdelta->c6 + cdelta->c7) > delta->tsc) - delta->c1 = 0; - else { - /* normal case, derive c1 */ - delta->c1 = delta->tsc - delta->mperf - cdelta->c3 - - cdelta->c6 - cdelta->c7; - } - - if (delta->mperf == 0) { - WARNING("turbostat plugin: cpu%d MPERF 0!", old->cpu_id); - delta->mperf = 1; /* divide by 0 protection */ - } - - if (do_smi) - delta->smi_count = new->smi_count - old->smi_count; - - return 0; +delta_thread(struct thread_data *delta, const struct thread_data *new, + const struct thread_data *old, const struct core_data *cdelta) { + delta->tsc = new->tsc - old->tsc; + + /* check for TSC < 1 Mcycles over interval */ + if (delta->tsc < (1000 * 1000)) { + WARNING("turbostat plugin: Insanely slow TSC rate, TSC stops " + "in idle? You can disable all c-states by booting with" + " 'idle=poll' or just the deep ones with" + " 'processor.max_cstate=1'"); + return -1; + } + + delta->c1 = new->c1 - old->c1; + + if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) { + delta->aperf = new->aperf - old->aperf; + delta->mperf = new->mperf - old->mperf; + } else { + if (!aperf_mperf_unstable) { + WARNING("turbostat plugin: APERF or MPERF went " + "backwards. Frequency results do not cover " + "the entire interval. Fix this by running " + "Linux-2.6.30 or later."); + + aperf_mperf_unstable = 1; + } + } + + /* + * As counter collection is not atomic, + * it is possible for mperf's non-halted cycles + idle states + * to exceed TSC's all cycles: show c1 = 0% in that case. + */ + if ((delta->mperf + cdelta->c3 + cdelta->c6 + cdelta->c7) > delta->tsc) + delta->c1 = 0; + else { + /* normal case, derive c1 */ + delta->c1 = + delta->tsc - delta->mperf - cdelta->c3 - cdelta->c6 - cdelta->c7; + } + + if (delta->mperf == 0) { + WARNING("turbostat plugin: cpu%d MPERF 0!", old->cpu_id); + delta->mperf = 1; /* divide by 0 protection */ + } + + if (do_smi) + delta->smi_count = new->smi_count - old->smi_count; + + return 0; } /********************************** @@ -524,119 +522,124 @@ delta_thread(struct thread_data *delta, const struct thread_data *new, const str /* * Submit one gauge value */ -static void -turbostat_submit (const char *plugin_instance, - const char *type, const char *type_instance, - gauge_t value) -{ - value_list_t vl = VALUE_LIST_INIT; - - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, PLUGIN_NAME, sizeof (vl.plugin)); - if (plugin_instance != NULL) - sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); +static void turbostat_submit(const char *plugin_instance, const char *type, + const char *type_instance, gauge_t value) { + value_list_t vl = VALUE_LIST_INIT; + + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, PLUGIN_NAME, sizeof(vl.plugin)); + if (plugin_instance != NULL) + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + if (type_instance != NULL) + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); } /* * Submit every data for a single CPU * - * Core data is shared for all threads in one core: submitted only for the first thread - * Package data is shared for all core in one package: submitted only for the first thread of the first core + * Core data is shared for all threads in one core: submitted only for the first + * thread + * Package data is shared for all core in one package: submitted only for the + * first thread of the first core */ -static int -submit_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) -{ - char name[DATA_MAX_NAME_LEN]; - double interval_float; - - interval_float = CDTIME_T_TO_DOUBLE(time_delta); - - DEBUG("turbostat plugin: submit stats for cpu: %d, core: %d, pkg: %d", - t->cpu_id, c->core_id, p->package_id); - - ssnprintf(name, sizeof(name), "cpu%02d", t->cpu_id); - - if (!aperf_mperf_unstable) - turbostat_submit(name, "percent", "c0", 100.0 * t->mperf/t->tsc); - if (!aperf_mperf_unstable) - turbostat_submit(name, "percent", "c1", 100.0 * t->c1/t->tsc); - - turbostat_submit(name, "frequency", "average", 1.0 / 1000000 * t->aperf / interval_float); - - if ((!aperf_mperf_unstable) || (!(t->aperf > t->tsc || t->mperf > t->tsc))) - turbostat_submit(name, "frequency", "busy", 1.0 * t->tsc / 1000000 * t->aperf / t->mperf / interval_float); - - /* Sanity check (should stay stable) */ - turbostat_submit(name, "gauge", "TSC", 1.0 * t->tsc / 1000000 / interval_float); - - /* SMI */ - if (do_smi) - turbostat_submit(name, "count", NULL, t->smi_count); - - /* submit per-core data only for 1st thread in core */ - if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) - goto done; - - /* If not using logical core numbering, set core id */ - if (!config_lcn) { - ssnprintf(name, sizeof(name), "core%02d", c->core_id); - } - - if (do_core_cstate & (1 << 3)) - turbostat_submit(name, "percent", "c3", 100.0 * c->c3/t->tsc); - if (do_core_cstate & (1 << 6)) - turbostat_submit(name, "percent", "c6", 100.0 * c->c6/t->tsc); - if (do_core_cstate & (1 << 7)) - turbostat_submit(name, "percent", "c7", 100.0 * c->c7/t->tsc); - - if (do_dts) - turbostat_submit(name, "temperature", NULL, c->core_temp_c); - - /* submit per-package data only for 1st core in package */ - if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) - goto done; - - ssnprintf(name, sizeof(name), "pkg%02d", p->package_id); - - if (do_ptm) - turbostat_submit(name, "temperature", NULL, p->pkg_temp_c); - - if (do_pkg_cstate & (1 << 2)) - turbostat_submit(name, "percent", "pc2", 100.0 * p->pc2/t->tsc); - if (do_pkg_cstate & (1 << 3)) - turbostat_submit(name, "percent", "pc3", 100.0 * p->pc3/t->tsc); - if (do_pkg_cstate & (1 << 6)) - turbostat_submit(name, "percent", "pc6", 100.0 * p->pc6/t->tsc); - if (do_pkg_cstate & (1 << 7)) - turbostat_submit(name, "percent", "pc7", 100.0 * p->pc7/t->tsc); - if (do_pkg_cstate & (1 << 8)) - turbostat_submit(name, "percent", "pc8", 100.0 * p->pc8/t->tsc); - if (do_pkg_cstate & (1 << 9)) - turbostat_submit(name, "percent", "pc9", 100.0 * p->pc9/t->tsc); - if (do_pkg_cstate & (1 << 10)) - turbostat_submit(name, "percent", "pc10", 100.0 * p->pc10/t->tsc); - - if (do_rapl) { - if (do_rapl & RAPL_PKG) - turbostat_submit(name, "power", "pkg", p->energy_pkg * rapl_energy_units / interval_float); - if (do_rapl & RAPL_CORES) - turbostat_submit(name, "power", "cores", p->energy_cores * rapl_energy_units / interval_float); - if (do_rapl & RAPL_GFX) - turbostat_submit(name, "power", "GFX", p->energy_gfx * rapl_energy_units / interval_float); - if (do_rapl & RAPL_DRAM) - turbostat_submit(name, "power", "DRAM", p->energy_dram * rapl_energy_units / interval_float); - } +static int submit_counters(struct thread_data *t, struct core_data *c, + struct pkg_data *p) { + char name[DATA_MAX_NAME_LEN]; + double interval_float; + + interval_float = CDTIME_T_TO_DOUBLE(time_delta); + + DEBUG("turbostat plugin: submit stats for cpu: %d, core: %d, pkg: %d", + t->cpu_id, c->core_id, p->package_id); + + ssnprintf(name, sizeof(name), "cpu%02d", t->cpu_id); + + if (!aperf_mperf_unstable) + turbostat_submit(name, "percent", "c0", 100.0 * t->mperf / t->tsc); + if (!aperf_mperf_unstable) + turbostat_submit(name, "percent", "c1", 100.0 * t->c1 / t->tsc); + + turbostat_submit(name, "frequency", "average", + 1.0 / 1000000 * t->aperf / interval_float); + + if ((!aperf_mperf_unstable) || (!(t->aperf > t->tsc || t->mperf > t->tsc))) + turbostat_submit(name, "frequency", "busy", 1.0 * t->tsc / 1000000 * + t->aperf / t->mperf / + interval_float); + + /* Sanity check (should stay stable) */ + turbostat_submit(name, "gauge", "TSC", + 1.0 * t->tsc / 1000000 / interval_float); + + /* SMI */ + if (do_smi) + turbostat_submit(name, "count", NULL, t->smi_count); + + /* submit per-core data only for 1st thread in core */ + if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) + goto done; + + /* If not using logical core numbering, set core id */ + if (!config_lcn) { + ssnprintf(name, sizeof(name), "core%02d", c->core_id); + } + + if (do_core_cstate & (1 << 3)) + turbostat_submit(name, "percent", "c3", 100.0 * c->c3 / t->tsc); + if (do_core_cstate & (1 << 6)) + turbostat_submit(name, "percent", "c6", 100.0 * c->c6 / t->tsc); + if (do_core_cstate & (1 << 7)) + turbostat_submit(name, "percent", "c7", 100.0 * c->c7 / t->tsc); + + if (do_dts) + turbostat_submit(name, "temperature", NULL, c->core_temp_c); + + /* submit per-package data only for 1st core in package */ + if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) + goto done; + + ssnprintf(name, sizeof(name), "pkg%02d", p->package_id); + + if (do_ptm) + turbostat_submit(name, "temperature", NULL, p->pkg_temp_c); + + if (do_pkg_cstate & (1 << 2)) + turbostat_submit(name, "percent", "pc2", 100.0 * p->pc2 / t->tsc); + if (do_pkg_cstate & (1 << 3)) + turbostat_submit(name, "percent", "pc3", 100.0 * p->pc3 / t->tsc); + if (do_pkg_cstate & (1 << 6)) + turbostat_submit(name, "percent", "pc6", 100.0 * p->pc6 / t->tsc); + if (do_pkg_cstate & (1 << 7)) + turbostat_submit(name, "percent", "pc7", 100.0 * p->pc7 / t->tsc); + if (do_pkg_cstate & (1 << 8)) + turbostat_submit(name, "percent", "pc8", 100.0 * p->pc8 / t->tsc); + if (do_pkg_cstate & (1 << 9)) + turbostat_submit(name, "percent", "pc9", 100.0 * p->pc9 / t->tsc); + if (do_pkg_cstate & (1 << 10)) + turbostat_submit(name, "percent", "pc10", 100.0 * p->pc10 / t->tsc); + + if (do_rapl) { + if (do_rapl & RAPL_PKG) + turbostat_submit(name, "power", "pkg", + p->energy_pkg * rapl_energy_units / interval_float); + if (do_rapl & RAPL_CORES) + turbostat_submit(name, "power", "cores", + p->energy_cores * rapl_energy_units / interval_float); + if (do_rapl & RAPL_GFX) + turbostat_submit(name, "power", "GFX", + p->energy_gfx * rapl_energy_units / interval_float); + if (do_rapl & RAPL_DRAM) + turbostat_submit(name, "power", "DRAM", + p->energy_dram * rapl_energy_units / interval_float); + } done: - return 0; + return 0; } - /********************************** * Looping function over all CPUs * **********************************/ @@ -644,10 +647,8 @@ done: /* * Check if a given cpu id is in our compiled list of existing CPUs */ -static int -cpu_is_not_present(unsigned int cpu) -{ - return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set); +static int cpu_is_not_present(unsigned int cpu) { + return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set); } /* @@ -657,33 +658,35 @@ cpu_is_not_present(unsigned int cpu) * Return the error code at the first error or 0 */ static int __attribute__((warn_unused_result)) -for_all_cpus(int (func)(struct thread_data *, struct core_data *, struct pkg_data *), - struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base) -{ - int retval; - - for (unsigned int pkg_no = 0; pkg_no < topology.num_packages; ++pkg_no) { - for (unsigned int core_no = 0; core_no < topology.num_cores; ++core_no) { - for (unsigned int thread_no = 0; thread_no < topology.num_threads; ++thread_no) { - struct thread_data *t; - struct core_data *c; - struct pkg_data *p; - - t = GET_THREAD(thread_base, thread_no, core_no, pkg_no); - - if (cpu_is_not_present(t->cpu_id)) - continue; - - c = GET_CORE(core_base, core_no, pkg_no); - p = GET_PKG(pkg_base, pkg_no); - - retval = func(t, c, p); - if (retval) - return retval; - } - } - } - return 0; +for_all_cpus(int(func)(struct thread_data *, struct core_data *, + struct pkg_data *), + struct thread_data *thread_base, struct core_data *core_base, + struct pkg_data *pkg_base) { + int retval; + + for (unsigned int pkg_no = 0; pkg_no < topology.num_packages; ++pkg_no) { + for (unsigned int core_no = 0; core_no < topology.num_cores; ++core_no) { + for (unsigned int thread_no = 0; thread_no < topology.num_threads; + ++thread_no) { + struct thread_data *t; + struct core_data *c; + struct pkg_data *p; + + t = GET_THREAD(thread_base, thread_no, core_no, pkg_no); + + if (cpu_is_not_present(t->cpu_id)) + continue; + + c = GET_CORE(core_base, core_no, pkg_no); + p = GET_PKG(pkg_base, pkg_no); + + retval = func(t, c, p); + if (retval) + return retval; + } + } + } + return 0; } /* @@ -692,67 +695,72 @@ for_all_cpus(int (func)(struct thread_data *, struct core_data *, struct pkg_dat * Skip non-present cpus * Return the error code at the first error or 0 * - * Core data is shared for all threads in one core: extracted only for the first thread - * Package data is shared for all core in one package: extracted only for the first thread of the first core + * Core data is shared for all threads in one core: extracted only for the first + * thread + * Package data is shared for all core in one package: extracted only for the + * first thread of the first core */ static int __attribute__((warn_unused_result)) -for_all_cpus_delta(const struct thread_data *thread_new_base, const struct core_data *core_new_base, const struct pkg_data *pkg_new_base, - const struct thread_data *thread_old_base, const struct core_data *core_old_base, const struct pkg_data *pkg_old_base) -{ - int retval; - - for (unsigned int pkg_no = 0; pkg_no < topology.num_packages; ++pkg_no) { - for (unsigned int core_no = 0; core_no < topology.num_cores; ++core_no) { - for (unsigned int thread_no = 0; thread_no < topology.num_threads; ++thread_no) { - struct thread_data *t_delta; - const struct thread_data *t_old, *t_new; - struct core_data *c_delta; - - /* Get correct pointers for threads */ - t_delta = GET_THREAD(thread_delta, thread_no, core_no, pkg_no); - t_new = GET_THREAD(thread_new_base, thread_no, core_no, pkg_no); - t_old = GET_THREAD(thread_old_base, thread_no, core_no, pkg_no); - - /* Skip threads that disappeared */ - if (cpu_is_not_present(t_delta->cpu_id)) - continue; - - /* c_delta is always required for delta_thread */ - c_delta = GET_CORE(core_delta, core_no, pkg_no); - - /* calculate core delta only for 1st thread in core */ - if (t_new->flags & CPU_IS_FIRST_THREAD_IN_CORE) { - const struct core_data *c_old, *c_new; - - c_new = GET_CORE(core_new_base, core_no, pkg_no); - c_old = GET_CORE(core_old_base, core_no, pkg_no); - - delta_core(c_delta, c_new, c_old); - } - - /* Always calculate thread delta */ - retval = delta_thread(t_delta, t_new, t_old, c_delta); - if (retval) - return retval; - - /* calculate package delta only for 1st core in package */ - if (t_new->flags & CPU_IS_FIRST_CORE_IN_PACKAGE) { - struct pkg_data *p_delta; - const struct pkg_data *p_old, *p_new; - - p_delta = GET_PKG(package_delta, pkg_no); - p_new = GET_PKG(pkg_new_base, pkg_no); - p_old = GET_PKG(pkg_old_base, pkg_no); - - delta_package(p_delta, p_new, p_old); - } - } - } - } - return 0; +for_all_cpus_delta(const struct thread_data *thread_new_base, + const struct core_data *core_new_base, + const struct pkg_data *pkg_new_base, + const struct thread_data *thread_old_base, + const struct core_data *core_old_base, + const struct pkg_data *pkg_old_base) { + int retval; + + for (unsigned int pkg_no = 0; pkg_no < topology.num_packages; ++pkg_no) { + for (unsigned int core_no = 0; core_no < topology.num_cores; ++core_no) { + for (unsigned int thread_no = 0; thread_no < topology.num_threads; + ++thread_no) { + struct thread_data *t_delta; + const struct thread_data *t_old, *t_new; + struct core_data *c_delta; + + /* Get correct pointers for threads */ + t_delta = GET_THREAD(thread_delta, thread_no, core_no, pkg_no); + t_new = GET_THREAD(thread_new_base, thread_no, core_no, pkg_no); + t_old = GET_THREAD(thread_old_base, thread_no, core_no, pkg_no); + + /* Skip threads that disappeared */ + if (cpu_is_not_present(t_delta->cpu_id)) + continue; + + /* c_delta is always required for delta_thread */ + c_delta = GET_CORE(core_delta, core_no, pkg_no); + + /* calculate core delta only for 1st thread in core */ + if (t_new->flags & CPU_IS_FIRST_THREAD_IN_CORE) { + const struct core_data *c_old, *c_new; + + c_new = GET_CORE(core_new_base, core_no, pkg_no); + c_old = GET_CORE(core_old_base, core_no, pkg_no); + + delta_core(c_delta, c_new, c_old); + } + + /* Always calculate thread delta */ + retval = delta_thread(t_delta, t_new, t_old, c_delta); + if (retval) + return retval; + + /* calculate package delta only for 1st core in package */ + if (t_new->flags & CPU_IS_FIRST_CORE_IN_PACKAGE) { + struct pkg_data *p_delta; + const struct pkg_data *p_old, *p_new; + + p_delta = GET_PKG(package_delta, pkg_no); + p_new = GET_PKG(pkg_new_base, pkg_no); + p_old = GET_PKG(pkg_old_base, pkg_no); + + delta_package(p_delta, p_new, p_old); + } + } + } + } + return 0; } - /*************** * CPU Probing * ***************/ @@ -770,251 +778,255 @@ for_all_cpus_delta(const struct thread_data *thread_new_base, const struct core_ * Package Thermal Management Sensor (PTM), and thermal event thresholds. */ static int __attribute__((warn_unused_result)) -set_temperature_target(struct thread_data *t, struct core_data *c, struct pkg_data *p) -{ - unsigned long long msr; - unsigned int target_c_local; +set_temperature_target(struct thread_data *t, struct core_data *c, + struct pkg_data *p) { + unsigned long long msr; + unsigned int target_c_local; - /* tcc_activation_temp is used only for dts or ptm */ - if (!(do_dts || do_ptm)) - return 0; + /* tcc_activation_temp is used only for dts or ptm */ + if (!(do_dts || do_ptm)) + return 0; - /* this is a per-package concept */ - if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) - return 0; + /* this is a per-package concept */ + if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || + !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) + return 0; - if (tcc_activation_temp != 0) { - p->tcc_activation_temp = tcc_activation_temp; - return 0; - } + if (tcc_activation_temp != 0) { + p->tcc_activation_temp = tcc_activation_temp; + return 0; + } - if (get_msr(t->cpu_id, MSR_IA32_TEMPERATURE_TARGET, &msr)) - goto guess; + if (get_msr(t->cpu_id, MSR_IA32_TEMPERATURE_TARGET, &msr)) + goto guess; - target_c_local = (msr >> 16) & 0xFF; + target_c_local = (msr >> 16) & 0xFF; - if (!target_c_local) - goto guess; + if (!target_c_local) + goto guess; - p->tcc_activation_temp = target_c_local; + p->tcc_activation_temp = target_c_local; - return 0; + return 0; guess: - p->tcc_activation_temp = TJMAX_DEFAULT; - WARNING("turbostat plugin: cpu%d: Guessing tjMax %d C," - " Please use TCCActivationTemp to specify it.", - t->cpu_id, p->tcc_activation_temp); + p->tcc_activation_temp = TJMAX_DEFAULT; + WARNING("turbostat plugin: cpu%d: Guessing tjMax %d C," + " Please use TCCActivationTemp to specify it.", + t->cpu_id, p->tcc_activation_temp); - return 0; + return 0; } /* * Identify the functionality of the CPU */ -static int __attribute__((warn_unused_result)) -probe_cpu(void) -{ - unsigned int eax, ebx, ecx, edx, max_level; - unsigned int fms, family, model; - - /* CPUID(0): - * - EAX: Maximum Input Value for Basic CPUID Information - * - EBX: "Genu" (0x756e6547) - * - EDX: "ineI" (0x49656e69) - * - ECX: "ntel" (0x6c65746e) - */ - max_level = ebx = ecx = edx = 0; - __get_cpuid(0, &max_level, &ebx, &ecx, &edx); - if (ebx != 0x756e6547 && edx != 0x49656e69 && ecx != 0x6c65746e) { - ERROR("turbostat plugin: Unsupported CPU (not Intel)"); - return -1; - } - - /* CPUID(1): - * - EAX: Version Information: Type, Family, Model, and Stepping ID - * + 4-7: Model ID - * + 8-11: Family ID - * + 12-13: Processor type - * + 16-19: Extended Model ID - * + 20-27: Extended Family ID - * - EDX: Feature Information: - * + 5: Support for MSR read/write operations - */ - fms = ebx = ecx = edx = 0; - __get_cpuid(1, &fms, &ebx, &ecx, &edx); - family = (fms >> 8) & 0xf; - model = (fms >> 4) & 0xf; - if (family == 0xf) - family += (fms >> 20) & 0xf; - if (family == 6 || family == 0xf) - model += ((fms >> 16) & 0xf) << 4; - if (!(edx & (1 << 5))) { - ERROR("turbostat plugin: Unsupported CPU (no MSR support)"); - return -1; - } - - /* - * CPUID(6): - * - EAX: - * + 0: Digital temperature sensor is supported if set - * + 6: Package thermal management is supported if set - * - ECX: - * + 0: Hardware Coordination Feedback Capability (Presence of IA32_MPERF and IA32_APERF). - * + 3: The processor supports performance-energy bias preference if set. - * It also implies the presence of a new architectural MSR called IA32_ENERGY_PERF_BIAS - * - * This check is valid for both Intel and AMD - */ - eax = ebx = ecx = edx = 0; - __get_cpuid(0x6, &eax, &ebx, &ecx, &edx); - do_dts = eax & (1 << 0); - do_ptm = eax & (1 << 6); - if (!(ecx & (1 << 0))) { - ERROR("turbostat plugin: Unsupported CPU (No APERF)"); - return -1; - } - - /* - * Enable or disable C states depending on the model and family - */ - if (family == 6) { - switch (model) { - /* Atom (partial) */ - case 0x27: - do_smi = 0; - do_core_cstate = 0; - do_pkg_cstate = (1 << 2) | (1 << 4) | (1 << 6); - break; - /* Silvermont */ - case 0x37: /* BYT */ - case 0x4D: /* AVN */ - do_smi = 1; - do_core_cstate = (1 << 1) | (1 << 6); - do_pkg_cstate = (1 << 6); - break; - /* Nehalem */ - case 0x1A: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */ - case 0x1E: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */ - case 0x1F: /* Core i7 and i5 Processor - Nehalem */ - case 0x2E: /* Nehalem-EX Xeon - Beckton */ - do_smi = 1; - do_core_cstate = (1 << 3) | (1 << 6); - do_pkg_cstate = (1 << 3) | (1 << 6) | (1 << 7); - break; - /* Westmere */ - case 0x25: /* Westmere Client - Clarkdale, Arrandale */ - case 0x2C: /* Westmere EP - Gulftown */ - case 0x2F: /* Westmere-EX Xeon - Eagleton */ - do_smi = 1; - do_core_cstate = (1 << 3) | (1 << 6); - do_pkg_cstate = (1 << 3) | (1 << 6) | (1 << 7); - break; - /* Sandy Bridge */ - case 0x2A: /* SNB */ - case 0x2D: /* SNB Xeon */ - do_smi = 1; - do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7); - do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7); - break; - /* Ivy Bridge */ - case 0x3A: /* IVB */ - case 0x3E: /* IVB Xeon */ - do_smi = 1; - do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7); - do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7); - break; - /* Haswell Bridge */ - case 0x3C: /* HSW */ - case 0x3F: /* HSW */ - case 0x46: /* HSW */ - do_smi = 1; - do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7); - do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7); - break; - case 0x45: /* HSW */ - do_smi = 1; - do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7); - do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10); - break; - /* Broadwel */ - case 0x4F: /* BDW */ - case 0x56: /* BDX-DE */ - do_smi = 1; - do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7); - do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7); - break; - case 0x3D: /* BDW */ - do_smi = 1; - do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7); - do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10); - break; - default: - do_smi = 0; - do_core_cstate = 0; - do_pkg_cstate = 0; - break; - } - switch (model) { - case 0x2A: /* SNB */ - case 0x3A: /* IVB */ - case 0x3C: /* HSW */ - case 0x45: /* HSW */ - case 0x46: /* HSW */ - case 0x3D: /* BDW */ - do_rapl = RAPL_PKG | RAPL_CORES | RAPL_GFX; - break; - case 0x3F: /* HSX */ - case 0x4F: /* BDX */ - case 0x56: /* BDX-DE */ - do_rapl = RAPL_PKG | RAPL_DRAM ; - break; - case 0x2D: /* SNB Xeon */ - case 0x3E: /* IVB Xeon */ - do_rapl = RAPL_PKG | RAPL_CORES | RAPL_DRAM; - break; - case 0x37: /* BYT */ - case 0x4D: /* AVN */ - do_rapl = RAPL_PKG | RAPL_CORES; - break; - default: - do_rapl = 0; - } - } else { - ERROR("turbostat plugin: Unsupported CPU (family: %#x, " - "model: %#x)", family, model); - return -1; - } - - /* Override detected values with configuration */ - if (apply_config_core_cstate) - do_core_cstate = config_core_cstate; - if (apply_config_pkg_cstate) - do_pkg_cstate = config_pkg_cstate; - if (apply_config_smi) - do_smi = config_smi; - if (apply_config_dts) - do_dts = config_dts; - if (apply_config_ptm) - do_ptm = config_ptm; - if (apply_config_rapl) - do_rapl = config_rapl; - - if (do_rapl) { - unsigned long long msr; - if (get_msr(0, MSR_RAPL_POWER_UNIT, &msr)) - return 0; - - if (model == 0x37) - rapl_energy_units = 1.0 * (1 << (msr >> 8 & 0x1F)) / 1000000; - else - rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F)); - } - - return 0; +static int __attribute__((warn_unused_result)) probe_cpu(void) { + unsigned int eax, ebx, ecx, edx, max_level; + unsigned int fms, family, model; + + /* CPUID(0): + * - EAX: Maximum Input Value for Basic CPUID Information + * - EBX: "Genu" (0x756e6547) + * - EDX: "ineI" (0x49656e69) + * - ECX: "ntel" (0x6c65746e) + */ + max_level = ebx = ecx = edx = 0; + __get_cpuid(0, &max_level, &ebx, &ecx, &edx); + if (ebx != 0x756e6547 && edx != 0x49656e69 && ecx != 0x6c65746e) { + ERROR("turbostat plugin: Unsupported CPU (not Intel)"); + return -1; + } + + /* CPUID(1): + * - EAX: Version Information: Type, Family, Model, and Stepping ID + * + 4-7: Model ID + * + 8-11: Family ID + * + 12-13: Processor type + * + 16-19: Extended Model ID + * + 20-27: Extended Family ID + * - EDX: Feature Information: + * + 5: Support for MSR read/write operations + */ + fms = ebx = ecx = edx = 0; + __get_cpuid(1, &fms, &ebx, &ecx, &edx); + family = (fms >> 8) & 0xf; + model = (fms >> 4) & 0xf; + if (family == 0xf) + family += (fms >> 20) & 0xf; + if (family == 6 || family == 0xf) + model += ((fms >> 16) & 0xf) << 4; + if (!(edx & (1 << 5))) { + ERROR("turbostat plugin: Unsupported CPU (no MSR support)"); + return -1; + } + + /* + * CPUID(6): + * - EAX: + * + 0: Digital temperature sensor is supported if set + * + 6: Package thermal management is supported if set + * - ECX: + * + 0: Hardware Coordination Feedback Capability (Presence of IA32_MPERF and + * IA32_APERF). + * + 3: The processor supports performance-energy bias preference if set. + * It also implies the presence of a new architectural MSR called + * IA32_ENERGY_PERF_BIAS + * + * This check is valid for both Intel and AMD + */ + eax = ebx = ecx = edx = 0; + __get_cpuid(0x6, &eax, &ebx, &ecx, &edx); + do_dts = eax & (1 << 0); + do_ptm = eax & (1 << 6); + if (!(ecx & (1 << 0))) { + ERROR("turbostat plugin: Unsupported CPU (No APERF)"); + return -1; + } + + /* + * Enable or disable C states depending on the model and family + */ + if (family == 6) { + switch (model) { + /* Atom (partial) */ + case 0x27: + do_smi = 0; + do_core_cstate = 0; + do_pkg_cstate = (1 << 2) | (1 << 4) | (1 << 6); + break; + /* Silvermont */ + case 0x37: /* BYT */ + case 0x4D: /* AVN */ + do_smi = 1; + do_core_cstate = (1 << 1) | (1 << 6); + do_pkg_cstate = (1 << 6); + break; + /* Nehalem */ + case 0x1A: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */ + case 0x1E: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper + Forest */ + case 0x1F: /* Core i7 and i5 Processor - Nehalem */ + case 0x2E: /* Nehalem-EX Xeon - Beckton */ + do_smi = 1; + do_core_cstate = (1 << 3) | (1 << 6); + do_pkg_cstate = (1 << 3) | (1 << 6) | (1 << 7); + break; + /* Westmere */ + case 0x25: /* Westmere Client - Clarkdale, Arrandale */ + case 0x2C: /* Westmere EP - Gulftown */ + case 0x2F: /* Westmere-EX Xeon - Eagleton */ + do_smi = 1; + do_core_cstate = (1 << 3) | (1 << 6); + do_pkg_cstate = (1 << 3) | (1 << 6) | (1 << 7); + break; + /* Sandy Bridge */ + case 0x2A: /* SNB */ + case 0x2D: /* SNB Xeon */ + do_smi = 1; + do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7); + do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7); + break; + /* Ivy Bridge */ + case 0x3A: /* IVB */ + case 0x3E: /* IVB Xeon */ + do_smi = 1; + do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7); + do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7); + break; + /* Haswell Bridge */ + case 0x3C: /* HSW */ + case 0x3F: /* HSW */ + case 0x46: /* HSW */ + do_smi = 1; + do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7); + do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7); + break; + case 0x45: /* HSW */ + do_smi = 1; + do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7); + do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7) | (1 << 8) | + (1 << 9) | (1 << 10); + break; + /* Broadwel */ + case 0x4F: /* BDW */ + case 0x56: /* BDX-DE */ + do_smi = 1; + do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7); + do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7); + break; + case 0x3D: /* BDW */ + do_smi = 1; + do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7); + do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7) | (1 << 8) | + (1 << 9) | (1 << 10); + break; + default: + do_smi = 0; + do_core_cstate = 0; + do_pkg_cstate = 0; + break; + } + switch (model) { + case 0x2A: /* SNB */ + case 0x3A: /* IVB */ + case 0x3C: /* HSW */ + case 0x45: /* HSW */ + case 0x46: /* HSW */ + case 0x3D: /* BDW */ + do_rapl = RAPL_PKG | RAPL_CORES | RAPL_GFX; + break; + case 0x3F: /* HSX */ + case 0x4F: /* BDX */ + case 0x56: /* BDX-DE */ + do_rapl = RAPL_PKG | RAPL_DRAM; + break; + case 0x2D: /* SNB Xeon */ + case 0x3E: /* IVB Xeon */ + do_rapl = RAPL_PKG | RAPL_CORES | RAPL_DRAM; + break; + case 0x37: /* BYT */ + case 0x4D: /* AVN */ + do_rapl = RAPL_PKG | RAPL_CORES; + break; + default: + do_rapl = 0; + } + } else { + ERROR("turbostat plugin: Unsupported CPU (family: %#x, " + "model: %#x)", + family, model); + return -1; + } + + /* Override detected values with configuration */ + if (apply_config_core_cstate) + do_core_cstate = config_core_cstate; + if (apply_config_pkg_cstate) + do_pkg_cstate = config_pkg_cstate; + if (apply_config_smi) + do_smi = config_smi; + if (apply_config_dts) + do_dts = config_dts; + if (apply_config_ptm) + do_ptm = config_ptm; + if (apply_config_rapl) + do_rapl = config_rapl; + + if (do_rapl) { + unsigned long long msr; + if (get_msr(0, MSR_RAPL_POWER_UNIT, &msr)) + return 0; + + if (model == 0x37) + rapl_energy_units = 1.0 * (1 << (msr >> 8 & 0x1F)) / 1000000; + else + rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F)); + } + + return 0; } - /******************** * Topology Probing * ********************/ @@ -1022,58 +1034,56 @@ probe_cpu(void) /* * Read a single int from a file. */ -static int __attribute__ ((format(printf,1,2))) -parse_int_file(const char *fmt, ...) -{ - va_list args; - char path[PATH_MAX]; - int len; - - va_start(args, fmt); - len = vsnprintf(path, sizeof(path), fmt, args); - va_end(args); - if (len < 0 || len >= PATH_MAX) { - ERROR("turbostat plugin: path truncated: '%s'", path); - return -1; - } - - value_t v; - if (parse_value_file (path, &v, DS_TYPE_DERIVE) != 0) { - ERROR ("turbostat plugin: Parsing \"%s\" failed.", path); - return -1; - } - - return (int) v.derive; +static int __attribute__((format(printf, 1, 2))) +parse_int_file(const char *fmt, ...) { + va_list args; + char path[PATH_MAX]; + int len; + + va_start(args, fmt); + len = vsnprintf(path, sizeof(path), fmt, args); + va_end(args); + if (len < 0 || len >= PATH_MAX) { + ERROR("turbostat plugin: path truncated: '%s'", path); + return -1; + } + + value_t v; + if (parse_value_file(path, &v, DS_TYPE_DERIVE) != 0) { + ERROR("turbostat plugin: Parsing \"%s\" failed.", path); + return -1; + } + + return (int)v.derive; } -static int -get_threads_on_core(unsigned int cpu) -{ - char path[80]; - FILE *filep; - int sib1, sib2; - int matches; - char character; - - ssnprintf(path, sizeof(path), "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", cpu); - filep = fopen(path, "r"); - if (!filep) { - ERROR("turbostat plugin: Failed to open '%s'", path); - return -1; - } - /* - * file format: - * if a pair of number with a character between: 2 siblings (eg. 1-2, or 1,4) - * otherwinse 1 sibling (self). - */ - matches = fscanf(filep, "%d%c%d\n", &sib1, &character, &sib2); - - fclose(filep); - - if (matches == 3) - return 2; - else - return 1; +static int get_threads_on_core(unsigned int cpu) { + char path[80]; + FILE *filep; + int sib1, sib2; + int matches; + char character; + + ssnprintf(path, sizeof(path), + "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", cpu); + filep = fopen(path, "r"); + if (!filep) { + ERROR("turbostat plugin: Failed to open '%s'", path); + return -1; + } + /* + * file format: + * if a pair of number with a character between: 2 siblings (eg. 1-2, or 1,4) + * otherwinse 1 sibling (self). + */ + matches = fscanf(filep, "%d%c%d\n", &sib1, &character, &sib2); + + fclose(filep); + + if (matches == 3) + return 2; + else + return 1; } /* @@ -1081,532 +1091,508 @@ get_threads_on_core(unsigned int cpu) * return max_cpu number */ static int __attribute__((warn_unused_result)) -for_all_proc_cpus(int (func)(unsigned int)) -{ - FILE *fp; - unsigned int cpu_num; - int retval; - - fp = fopen("/proc/stat", "r"); - if (!fp) { - ERROR("turbostat plugin: Failed to open /proc/stat"); - return -1; - } - - retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n"); - if (retval != 0) { - ERROR("turbostat plugin: Failed to parse /proc/stat"); - fclose(fp); - return -1; - } - - while (1) { - retval = fscanf(fp, "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n", &cpu_num); - if (retval != 1) - break; - - retval = func(cpu_num); - if (retval) { - fclose(fp); - return(retval); - } - } - fclose(fp); - return 0; +for_all_proc_cpus(int(func)(unsigned int)) { + FILE *fp; + unsigned int cpu_num; + int retval; + + fp = fopen("/proc/stat", "r"); + if (!fp) { + ERROR("turbostat plugin: Failed to open /proc/stat"); + return -1; + } + + retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n"); + if (retval != 0) { + ERROR("turbostat plugin: Failed to parse /proc/stat"); + fclose(fp); + return -1; + } + + while (1) { + retval = + fscanf(fp, "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n", &cpu_num); + if (retval != 1) + break; + + retval = func(cpu_num); + if (retval) { + fclose(fp); + return (retval); + } + } + fclose(fp); + return 0; } /* * Update the stored topology.max_cpu_id */ -static int -update_max_cpu_id(unsigned int cpu) -{ - if (topology.max_cpu_id < cpu) - topology.max_cpu_id = cpu; - return 0; +static int update_max_cpu_id(unsigned int cpu) { + if (topology.max_cpu_id < cpu) + topology.max_cpu_id = cpu; + return 0; } -static int -mark_cpu_present(unsigned int cpu) -{ - CPU_SET_S(cpu, cpu_present_setsize, cpu_present_set); - return 0; +static int mark_cpu_present(unsigned int cpu) { + CPU_SET_S(cpu, cpu_present_setsize, cpu_present_set); + return 0; } static int __attribute__((warn_unused_result)) -allocate_cpu_set(cpu_set_t ** set, size_t * size) { - *set = CPU_ALLOC(topology.max_cpu_id + 1); - if (*set == NULL) { - ERROR("turbostat plugin: Unable to allocate CPU state"); - return -1; - } - *size = CPU_ALLOC_SIZE(topology.max_cpu_id + 1); - CPU_ZERO_S(*size, *set); - return 0; +allocate_cpu_set(cpu_set_t **set, size_t *size) { + *set = CPU_ALLOC(topology.max_cpu_id + 1); + if (*set == NULL) { + ERROR("turbostat plugin: Unable to allocate CPU state"); + return -1; + } + *size = CPU_ALLOC_SIZE(topology.max_cpu_id + 1); + CPU_ZERO_S(*size, *set); + return 0; } /* * Build a local representation of the cpu distribution */ -static int __attribute__((warn_unused_result)) -topology_probe(void) -{ - int ret; - unsigned int max_package_id, max_core_id, max_threads; - max_package_id = max_core_id = max_threads = 0; - - /* Clean topology */ - free(topology.cpus); - memset(&topology, 0, sizeof(topology)); - - ret = for_all_proc_cpus(update_max_cpu_id); - if (ret != 0) - goto err; - - topology.cpus = calloc(1, (topology.max_cpu_id + 1) * sizeof(struct cpu_topology)); - if (topology.cpus == NULL) { - ERROR("turbostat plugin: Unable to allocate memory for CPU topology"); - return -1; - } - - ret = allocate_cpu_set(&cpu_present_set, &cpu_present_setsize); - if (ret != 0) - goto err; - ret = allocate_cpu_set(&cpu_affinity_set, &cpu_affinity_setsize); - if (ret != 0) - goto err; - ret = allocate_cpu_set(&cpu_saved_affinity_set, &cpu_saved_affinity_setsize); - if (ret != 0) - goto err; - - ret = for_all_proc_cpus(mark_cpu_present); - if (ret != 0) - goto err; - - /* - * For online cpus - * find max_core_id, max_package_id - */ - for (unsigned int i = 0; i <= topology.max_cpu_id; ++i) { - unsigned int num_threads; - struct cpu_topology *cpu = &topology.cpus[i]; - - if (cpu_is_not_present(i)) { - WARNING("turbostat plugin: cpu%d NOT PRESENT", i); - continue; - } - - ret = parse_int_file("/sys/devices/system/cpu/cpu%d/topology/physical_package_id", i); - if (ret < 0) - goto err; - else - cpu->package_id = (unsigned int) ret; - if (cpu->package_id > max_package_id) - max_package_id = cpu->package_id; - - ret = parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", i); - if (ret < 0) - goto err; - else - cpu->core_id = (unsigned int) ret; - if (cpu->core_id > max_core_id) - max_core_id = cpu->core_id; - ret = parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_siblings_list", i); - if (ret < 0) - goto err; - else if ((unsigned int) ret == i) - cpu->first_core_in_package = 1; - - ret = get_threads_on_core(i); - if (ret < 0) - goto err; - else - num_threads = (unsigned int) ret; - if (num_threads > max_threads) - max_threads = num_threads; - ret = parse_int_file("/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", i); - if (ret < 0) - goto err; - else if ((unsigned int) ret == i) - cpu->first_thread_in_core = 1; - - DEBUG("turbostat plugin: cpu %d pkg %d core %d\n", - i, cpu->package_id, cpu->core_id); - } - /* Num is max + 1 (need to count 0) */ - topology.num_packages = max_package_id + 1; - topology.num_cores = max_core_id + 1; - topology.num_threads = max_threads; - - return 0; +static int __attribute__((warn_unused_result)) topology_probe(void) { + int ret; + unsigned int max_package_id, max_core_id, max_threads; + max_package_id = max_core_id = max_threads = 0; + + /* Clean topology */ + free(topology.cpus); + memset(&topology, 0, sizeof(topology)); + + ret = for_all_proc_cpus(update_max_cpu_id); + if (ret != 0) + goto err; + + topology.cpus = + calloc(1, (topology.max_cpu_id + 1) * sizeof(struct cpu_topology)); + if (topology.cpus == NULL) { + ERROR("turbostat plugin: Unable to allocate memory for CPU topology"); + return -1; + } + + ret = allocate_cpu_set(&cpu_present_set, &cpu_present_setsize); + if (ret != 0) + goto err; + ret = allocate_cpu_set(&cpu_affinity_set, &cpu_affinity_setsize); + if (ret != 0) + goto err; + ret = allocate_cpu_set(&cpu_saved_affinity_set, &cpu_saved_affinity_setsize); + if (ret != 0) + goto err; + + ret = for_all_proc_cpus(mark_cpu_present); + if (ret != 0) + goto err; + + /* + * For online cpus + * find max_core_id, max_package_id + */ + for (unsigned int i = 0; i <= topology.max_cpu_id; ++i) { + unsigned int num_threads; + struct cpu_topology *cpu = &topology.cpus[i]; + + if (cpu_is_not_present(i)) { + WARNING("turbostat plugin: cpu%d NOT PRESENT", i); + continue; + } + + ret = parse_int_file( + "/sys/devices/system/cpu/cpu%d/topology/physical_package_id", i); + if (ret < 0) + goto err; + else + cpu->package_id = (unsigned int)ret; + if (cpu->package_id > max_package_id) + max_package_id = cpu->package_id; + + ret = parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", i); + if (ret < 0) + goto err; + else + cpu->core_id = (unsigned int)ret; + if (cpu->core_id > max_core_id) + max_core_id = cpu->core_id; + ret = parse_int_file( + "/sys/devices/system/cpu/cpu%d/topology/core_siblings_list", i); + if (ret < 0) + goto err; + else if ((unsigned int)ret == i) + cpu->first_core_in_package = 1; + + ret = get_threads_on_core(i); + if (ret < 0) + goto err; + else + num_threads = (unsigned int)ret; + if (num_threads > max_threads) + max_threads = num_threads; + ret = parse_int_file( + "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", i); + if (ret < 0) + goto err; + else if ((unsigned int)ret == i) + cpu->first_thread_in_core = 1; + + DEBUG("turbostat plugin: cpu %d pkg %d core %d\n", i, cpu->package_id, + cpu->core_id); + } + /* Num is max + 1 (need to count 0) */ + topology.num_packages = max_package_id + 1; + topology.num_cores = max_core_id + 1; + topology.num_threads = max_threads; + + return 0; err: - free(topology.cpus); - return ret; + free(topology.cpus); + return ret; } - /************************ * Main alloc/init/free * ************************/ -static int -allocate_counters(struct thread_data **threads, struct core_data **cores, struct pkg_data **packages) -{ - unsigned int total_threads, total_cores; - - if ((topology.num_threads == 0) - || (topology.num_cores == 0) - || (topology.num_packages == 0)) - { - ERROR ("turbostat plugin: Invalid topology: %u threads, %u cores, %u packages", - topology.num_threads, topology.num_cores, topology.num_packages); - return -1; - } - - total_threads = topology.num_threads * topology.num_cores * topology.num_packages; - *threads = calloc(total_threads, sizeof(struct thread_data)); - if (*threads == NULL) - { - ERROR ("turbostat plugin: calloc failed"); - return -1; - } - - for (unsigned int i = 0; i < total_threads; ++i) - (*threads)[i].cpu_id = topology.max_cpu_id + 1; - - total_cores = topology.num_cores * topology.num_packages; - *cores = calloc(total_cores, sizeof(struct core_data)); - if (*cores == NULL) - { - ERROR ("turbostat plugin: calloc failed"); - sfree (threads); - return -1; - } - - *packages = calloc(topology.num_packages, sizeof(struct pkg_data)); - if (*packages == NULL) - { - ERROR ("turbostat plugin: calloc failed"); - sfree (cores); - sfree (threads); - return -1; - } - - return 0; +static int allocate_counters(struct thread_data **threads, + struct core_data **cores, + struct pkg_data **packages) { + unsigned int total_threads, total_cores; + + if ((topology.num_threads == 0) || (topology.num_cores == 0) || + (topology.num_packages == 0)) { + ERROR( + "turbostat plugin: Invalid topology: %u threads, %u cores, %u packages", + topology.num_threads, topology.num_cores, topology.num_packages); + return -1; + } + + total_threads = + topology.num_threads * topology.num_cores * topology.num_packages; + *threads = calloc(total_threads, sizeof(struct thread_data)); + if (*threads == NULL) { + ERROR("turbostat plugin: calloc failed"); + return -1; + } + + for (unsigned int i = 0; i < total_threads; ++i) + (*threads)[i].cpu_id = topology.max_cpu_id + 1; + + total_cores = topology.num_cores * topology.num_packages; + *cores = calloc(total_cores, sizeof(struct core_data)); + if (*cores == NULL) { + ERROR("turbostat plugin: calloc failed"); + sfree(threads); + return -1; + } + + *packages = calloc(topology.num_packages, sizeof(struct pkg_data)); + if (*packages == NULL) { + ERROR("turbostat plugin: calloc failed"); + sfree(cores); + sfree(threads); + return -1; + } + + return 0; } -static void -init_counter(struct thread_data *thread_base, struct core_data *core_base, - struct pkg_data *pkg_base, unsigned int cpu_id) -{ - struct thread_data *t; - struct core_data *c; - struct pkg_data *p; - struct cpu_topology *cpu = &topology.cpus[cpu_id]; - - t = GET_THREAD(thread_base, !(cpu->first_thread_in_core), cpu->core_id, cpu->package_id); - c = GET_CORE(core_base, cpu->core_id, cpu->package_id); - p = GET_PKG(pkg_base, cpu->package_id); - - t->cpu_id = cpu_id; - if (cpu->first_thread_in_core) - t->flags |= CPU_IS_FIRST_THREAD_IN_CORE; - if (cpu->first_core_in_package) - t->flags |= CPU_IS_FIRST_CORE_IN_PACKAGE; - - c->core_id = cpu->core_id; - p->package_id = cpu->package_id; +static void init_counter(struct thread_data *thread_base, + struct core_data *core_base, struct pkg_data *pkg_base, + unsigned int cpu_id) { + struct thread_data *t; + struct core_data *c; + struct pkg_data *p; + struct cpu_topology *cpu = &topology.cpus[cpu_id]; + + t = GET_THREAD(thread_base, !(cpu->first_thread_in_core), cpu->core_id, + cpu->package_id); + c = GET_CORE(core_base, cpu->core_id, cpu->package_id); + p = GET_PKG(pkg_base, cpu->package_id); + + t->cpu_id = cpu_id; + if (cpu->first_thread_in_core) + t->flags |= CPU_IS_FIRST_THREAD_IN_CORE; + if (cpu->first_core_in_package) + t->flags |= CPU_IS_FIRST_CORE_IN_PACKAGE; + + c->core_id = cpu->core_id; + p->package_id = cpu->package_id; } -static void -initialize_counters(void) -{ - for (unsigned int cpu_id = 0; cpu_id <= topology.max_cpu_id; ++cpu_id) { - if (cpu_is_not_present(cpu_id)) - continue; - init_counter(EVEN_COUNTERS, cpu_id); - init_counter(ODD_COUNTERS, cpu_id); - init_counter(DELTA_COUNTERS, cpu_id); - } +static void initialize_counters(void) { + for (unsigned int cpu_id = 0; cpu_id <= topology.max_cpu_id; ++cpu_id) { + if (cpu_is_not_present(cpu_id)) + continue; + init_counter(EVEN_COUNTERS, cpu_id); + init_counter(ODD_COUNTERS, cpu_id); + init_counter(DELTA_COUNTERS, cpu_id); + } } +static void free_all_buffers(void) { + allocated = 0; + initialized = 0; + CPU_FREE(cpu_present_set); + cpu_present_set = NULL; + cpu_present_setsize = 0; -static void -free_all_buffers(void) -{ - allocated = 0; - initialized = 0; + CPU_FREE(cpu_affinity_set); + cpu_affinity_set = NULL; + cpu_affinity_setsize = 0; - CPU_FREE(cpu_present_set); - cpu_present_set = NULL; - cpu_present_setsize = 0; + CPU_FREE(cpu_saved_affinity_set); + cpu_saved_affinity_set = NULL; + cpu_saved_affinity_setsize = 0; - CPU_FREE(cpu_affinity_set); - cpu_affinity_set = NULL; - cpu_affinity_setsize = 0; + free(thread_even); + free(core_even); + free(package_even); - CPU_FREE(cpu_saved_affinity_set); - cpu_saved_affinity_set = NULL; - cpu_saved_affinity_setsize = 0; + thread_even = NULL; + core_even = NULL; + package_even = NULL; - free(thread_even); - free(core_even); - free(package_even); + free(thread_odd); + free(core_odd); + free(package_odd); - thread_even = NULL; - core_even = NULL; - package_even = NULL; + thread_odd = NULL; + core_odd = NULL; + package_odd = NULL; - free(thread_odd); - free(core_odd); - free(package_odd); + free(thread_delta); + free(core_delta); + free(package_delta); - thread_odd = NULL; - core_odd = NULL; - package_odd = NULL; - - free(thread_delta); - free(core_delta); - free(package_delta); - - thread_delta = NULL; - core_delta = NULL; - package_delta = NULL; + thread_delta = NULL; + core_delta = NULL; + package_delta = NULL; } - /********************** * Collectd functions * **********************/ -#define DO_OR_GOTO_ERR(something) \ -do { \ - ret = (something); \ - if (ret < 0) \ - goto err; \ -} while (0) - -static int setup_all_buffers(void) -{ - int ret; - - DO_OR_GOTO_ERR(topology_probe()); - DO_OR_GOTO_ERR(allocate_counters(&thread_even, &core_even, &package_even)); - DO_OR_GOTO_ERR(allocate_counters(&thread_odd, &core_odd, &package_odd)); - DO_OR_GOTO_ERR(allocate_counters(&thread_delta, &core_delta, &package_delta)); - initialize_counters(); - DO_OR_GOTO_ERR(for_all_cpus(set_temperature_target, EVEN_COUNTERS)); - DO_OR_GOTO_ERR(for_all_cpus(set_temperature_target, ODD_COUNTERS)); - - allocated = 1; - return 0; +#define DO_OR_GOTO_ERR(something) \ + do { \ + ret = (something); \ + if (ret < 0) \ + goto err; \ + } while (0) + +static int setup_all_buffers(void) { + int ret; + + DO_OR_GOTO_ERR(topology_probe()); + DO_OR_GOTO_ERR(allocate_counters(&thread_even, &core_even, &package_even)); + DO_OR_GOTO_ERR(allocate_counters(&thread_odd, &core_odd, &package_odd)); + DO_OR_GOTO_ERR(allocate_counters(&thread_delta, &core_delta, &package_delta)); + initialize_counters(); + DO_OR_GOTO_ERR(for_all_cpus(set_temperature_target, EVEN_COUNTERS)); + DO_OR_GOTO_ERR(for_all_cpus(set_temperature_target, ODD_COUNTERS)); + + allocated = 1; + return 0; err: - free_all_buffers(); - return ret; + free_all_buffers(); + return ret; } -static int -turbostat_read(void) -{ - int ret; - - if (!allocated) { - if ((ret = setup_all_buffers()) < 0) - return ret; - } - - if (for_all_proc_cpus(cpu_is_not_present)) { - free_all_buffers(); - if ((ret = setup_all_buffers()) < 0) - return ret; - if (for_all_proc_cpus(cpu_is_not_present)) { - ERROR("turbostat plugin: CPU appeared just after " - "initialization"); - return -1; - } - } - - /* Saving the scheduling affinity, as it will be modified by get_counters */ - if (sched_getaffinity(0, cpu_saved_affinity_setsize, cpu_saved_affinity_set) != 0) { - ERROR("turbostat plugin: Unable to save the CPU affinity"); - return -1; - } - - if (!initialized) { - if ((ret = for_all_cpus(get_counters, EVEN_COUNTERS)) < 0) - goto out; - time_even = cdtime(); - is_even = 1; - initialized = 1; - ret = 0; - goto out; - } - - if (is_even) { - if ((ret = for_all_cpus(get_counters, ODD_COUNTERS)) < 0) - goto out; - time_odd = cdtime(); - is_even = 0; - time_delta = time_odd - time_even; - if ((ret = for_all_cpus_delta(ODD_COUNTERS, EVEN_COUNTERS)) < 0) - goto out; - if ((ret = for_all_cpus(submit_counters, DELTA_COUNTERS)) < 0) - goto out; - } else { - if ((ret = for_all_cpus(get_counters, EVEN_COUNTERS)) < 0) - goto out; - time_even = cdtime(); - is_even = 1; - time_delta = time_even - time_odd; - if ((ret = for_all_cpus_delta(EVEN_COUNTERS, ODD_COUNTERS)) < 0) - goto out; - if ((ret = for_all_cpus(submit_counters, DELTA_COUNTERS)) < 0) - goto out; - } - ret = 0; +static int turbostat_read(void) { + int ret; + + if (!allocated) { + if ((ret = setup_all_buffers()) < 0) + return ret; + } + + if (for_all_proc_cpus(cpu_is_not_present)) { + free_all_buffers(); + if ((ret = setup_all_buffers()) < 0) + return ret; + if (for_all_proc_cpus(cpu_is_not_present)) { + ERROR("turbostat plugin: CPU appeared just after " + "initialization"); + return -1; + } + } + + /* Saving the scheduling affinity, as it will be modified by get_counters */ + if (sched_getaffinity(0, cpu_saved_affinity_setsize, + cpu_saved_affinity_set) != 0) { + ERROR("turbostat plugin: Unable to save the CPU affinity"); + return -1; + } + + if (!initialized) { + if ((ret = for_all_cpus(get_counters, EVEN_COUNTERS)) < 0) + goto out; + time_even = cdtime(); + is_even = 1; + initialized = 1; + ret = 0; + goto out; + } + + if (is_even) { + if ((ret = for_all_cpus(get_counters, ODD_COUNTERS)) < 0) + goto out; + time_odd = cdtime(); + is_even = 0; + time_delta = time_odd - time_even; + if ((ret = for_all_cpus_delta(ODD_COUNTERS, EVEN_COUNTERS)) < 0) + goto out; + if ((ret = for_all_cpus(submit_counters, DELTA_COUNTERS)) < 0) + goto out; + } else { + if ((ret = for_all_cpus(get_counters, EVEN_COUNTERS)) < 0) + goto out; + time_even = cdtime(); + is_even = 1; + time_delta = time_even - time_odd; + if ((ret = for_all_cpus_delta(EVEN_COUNTERS, ODD_COUNTERS)) < 0) + goto out; + if ((ret = for_all_cpus(submit_counters, DELTA_COUNTERS)) < 0) + goto out; + } + ret = 0; out: - /* - * Let's restore the affinity - * This might fail if the number of CPU changed, but we can't do anything in that case.. - */ - (void)sched_setaffinity(0, cpu_saved_affinity_setsize, cpu_saved_affinity_set); - return ret; + /* + * Let's restore the affinity + * This might fail if the number of CPU changed, but we can't do anything in + * that case.. + */ + (void)sched_setaffinity(0, cpu_saved_affinity_setsize, + cpu_saved_affinity_set); + return ret; } -static int -check_permissions(void) -{ +static int check_permissions(void) { - if (getuid() == 0) { - /* We have everything we need */ - return 0; + if (getuid() == 0) { + /* We have everything we need */ + return 0; #if !defined(HAVE_SYS_CAPABILITY_H) && !defined(CAP_SYS_RAWIO) - } else { - ERROR("turbostat plugin: Initialization failed: this plugin " - "requires collectd to run as root"); - return -1; - } -#else /* HAVE_SYS_CAPABILITY_H && CAP_SYS_RAWIO */ - } - - int ret = 0; - - if (check_capability(CAP_SYS_RAWIO) != 0) { - WARNING("turbostat plugin: Collectd doesn't have the " - "CAP_SYS_RAWIO capability. If you don't want to run " - "collectd as root, try running \"setcap " - "cap_sys_rawio=ep\" on collectd binary"); - ret = -1; - } - - if (euidaccess("/dev/cpu/0/msr", R_OK)) { - WARNING("turbostat plugin: Collectd cannot open " - "/dev/cpu/0/msr. If you don't want to run collectd as " - "root, you need to change the ownership (chown) and " - "permissions on /dev/cpu/*/msr to allow such access"); - ret = -1; - } - - if (ret != 0) - ERROR("turbostat plugin: Initialization failed: this plugin " - "requires collectd to either to run as root or give " - "collectd a special capability (CAP_SYS_RAWIO) and read " - "access to /dev/cpu/*/msr (see previous warnings)"); - return ret; + } else { + ERROR("turbostat plugin: Initialization failed: this plugin " + "requires collectd to run as root"); + return -1; + } +#else /* HAVE_SYS_CAPABILITY_H && CAP_SYS_RAWIO */ + } + + int ret = 0; + + if (check_capability(CAP_SYS_RAWIO) != 0) { + WARNING("turbostat plugin: Collectd doesn't have the " + "CAP_SYS_RAWIO capability. If you don't want to run " + "collectd as root, try running \"setcap " + "cap_sys_rawio=ep\" on collectd binary"); + ret = -1; + } + + if (euidaccess("/dev/cpu/0/msr", R_OK)) { + WARNING("turbostat plugin: Collectd cannot open " + "/dev/cpu/0/msr. If you don't want to run collectd as " + "root, you need to change the ownership (chown) and " + "permissions on /dev/cpu/*/msr to allow such access"); + ret = -1; + } + + if (ret != 0) + ERROR("turbostat plugin: Initialization failed: this plugin " + "requires collectd to either to run as root or give " + "collectd a special capability (CAP_SYS_RAWIO) and read " + "access to /dev/cpu/*/msr (see previous warnings)"); + return ret; #endif /* HAVE_SYS_CAPABILITY_H && CAP_SYS_RAWIO */ } -static int -turbostat_init(void) -{ - struct stat sb; - int ret; +static int turbostat_init(void) { + struct stat sb; + int ret; - if (stat("/dev/cpu/0/msr", &sb)) { - ERROR("turbostat plugin: Initialization failed: /dev/cpu/0/msr " - "does not exist while the CPU supports MSR. You may be " - "missing the corresponding kernel module, please try '# " - "modprobe msr'"); - return -1; - } + if (stat("/dev/cpu/0/msr", &sb)) { + ERROR("turbostat plugin: Initialization failed: /dev/cpu/0/msr " + "does not exist while the CPU supports MSR. You may be " + "missing the corresponding kernel module, please try '# " + "modprobe msr'"); + return -1; + } - DO_OR_GOTO_ERR(check_permissions()); + DO_OR_GOTO_ERR(check_permissions()); - DO_OR_GOTO_ERR(probe_cpu()); + DO_OR_GOTO_ERR(probe_cpu()); - DO_OR_GOTO_ERR(setup_all_buffers()); + DO_OR_GOTO_ERR(setup_all_buffers()); - plugin_register_read(PLUGIN_NAME, turbostat_read); + plugin_register_read(PLUGIN_NAME, turbostat_read); - return 0; + return 0; err: - free_all_buffers(); - return ret; + free_all_buffers(); + return ret; } -static int -turbostat_config(const char *key, const char *value) -{ - long unsigned int tmp_val; - char *end; - - if (strcasecmp("CoreCstates", key) == 0) { - tmp_val = strtoul(value, &end, 0); - if (*end != '\0' || tmp_val > UINT_MAX) { - ERROR("turbostat plugin: Invalid CoreCstates '%s'", - value); - return -1; - } - config_core_cstate = (unsigned int) tmp_val; - apply_config_core_cstate = 1; - } else if (strcasecmp("PackageCstates", key) == 0) { - tmp_val = strtoul(value, &end, 0); - if (*end != '\0' || tmp_val > UINT_MAX) { - ERROR("turbostat plugin: Invalid PackageCstates '%s'", - value); - return -1; - } - config_pkg_cstate = (unsigned int) tmp_val; - apply_config_pkg_cstate = 1; - } else if (strcasecmp("SystemManagementInterrupt", key) == 0) { - config_smi = IS_TRUE(value); - apply_config_smi = 1; - } else if (strcasecmp("DigitalTemperatureSensor", key) == 0) { - config_dts = IS_TRUE(value); - apply_config_dts = 1; - } else if (strcasecmp("PackageThermalManagement", key) == 0) { - config_ptm = IS_TRUE(value); - apply_config_ptm = 1; - } else if (strcasecmp("LogicalCoreNames", key) == 0) { - config_lcn = IS_TRUE(value); - } else if (strcasecmp("RunningAveragePowerLimit", key) == 0) { - tmp_val = strtoul(value, &end, 0); - if (*end != '\0' || tmp_val > UINT_MAX) { - ERROR("turbostat plugin: Invalid RunningAveragePowerLimit '%s'", - value); - return -1; - } - config_rapl = (unsigned int) tmp_val; - apply_config_rapl = 1; - } else if (strcasecmp("TCCActivationTemp", key) == 0) { - tmp_val = strtoul(value, &end, 0); - if (*end != '\0' || tmp_val > UINT_MAX) { - ERROR("turbostat plugin: Invalid TCCActivationTemp '%s'", - value); - return -1; - } - tcc_activation_temp = (unsigned int) tmp_val; - } else { - ERROR("turbostat plugin: Invalid configuration option '%s'", - key); - return -1; - } - return 0; +static int turbostat_config(const char *key, const char *value) { + long unsigned int tmp_val; + char *end; + + if (strcasecmp("CoreCstates", key) == 0) { + tmp_val = strtoul(value, &end, 0); + if (*end != '\0' || tmp_val > UINT_MAX) { + ERROR("turbostat plugin: Invalid CoreCstates '%s'", value); + return -1; + } + config_core_cstate = (unsigned int)tmp_val; + apply_config_core_cstate = 1; + } else if (strcasecmp("PackageCstates", key) == 0) { + tmp_val = strtoul(value, &end, 0); + if (*end != '\0' || tmp_val > UINT_MAX) { + ERROR("turbostat plugin: Invalid PackageCstates '%s'", value); + return -1; + } + config_pkg_cstate = (unsigned int)tmp_val; + apply_config_pkg_cstate = 1; + } else if (strcasecmp("SystemManagementInterrupt", key) == 0) { + config_smi = IS_TRUE(value); + apply_config_smi = 1; + } else if (strcasecmp("DigitalTemperatureSensor", key) == 0) { + config_dts = IS_TRUE(value); + apply_config_dts = 1; + } else if (strcasecmp("PackageThermalManagement", key) == 0) { + config_ptm = IS_TRUE(value); + apply_config_ptm = 1; + } else if (strcasecmp("LogicalCoreNames", key) == 0) { + config_lcn = IS_TRUE(value); + } else if (strcasecmp("RunningAveragePowerLimit", key) == 0) { + tmp_val = strtoul(value, &end, 0); + if (*end != '\0' || tmp_val > UINT_MAX) { + ERROR("turbostat plugin: Invalid RunningAveragePowerLimit '%s'", value); + return -1; + } + config_rapl = (unsigned int)tmp_val; + apply_config_rapl = 1; + } else if (strcasecmp("TCCActivationTemp", key) == 0) { + tmp_val = strtoul(value, &end, 0); + if (*end != '\0' || tmp_val > UINT_MAX) { + ERROR("turbostat plugin: Invalid TCCActivationTemp '%s'", value); + return -1; + } + tcc_activation_temp = (unsigned int)tmp_val; + } else { + ERROR("turbostat plugin: Invalid configuration option '%s'", key); + return -1; + } + return 0; } -void module_register(void) -{ - plugin_register_init(PLUGIN_NAME, turbostat_init); - plugin_register_config(PLUGIN_NAME, turbostat_config, config_keys, config_keys_num); +void module_register(void) { + plugin_register_init(PLUGIN_NAME, turbostat_init); + plugin_register_config(PLUGIN_NAME, turbostat_config, config_keys, + config_keys_num); } diff --git a/src/unixsock.c b/src/unixsock.c index 2df4e096..f61360ef 100644 --- a/src/unixsock.c +++ b/src/unixsock.c @@ -30,11 +30,11 @@ #include "plugin.h" #include "utils_cmd_flush.h" -#include "utils_cmd_getval.h" #include "utils_cmd_getthreshold.h" +#include "utils_cmd_getval.h" #include "utils_cmd_listval.h" -#include "utils_cmd_putval.h" #include "utils_cmd_putnotif.h" +#include "utils_cmd_putval.h" #include #include @@ -42,460 +42,392 @@ #include #ifndef UNIX_PATH_MAX -# define UNIX_PATH_MAX sizeof (((struct sockaddr_un *)0)->sun_path) +#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *)0)->sun_path) #endif -#define US_DEFAULT_PATH LOCALSTATEDIR"/run/"PACKAGE_NAME"-unixsock" +#define US_DEFAULT_PATH LOCALSTATEDIR "/run/" PACKAGE_NAME "-unixsock" /* * Private variables */ /* valid configuration file keys */ -static const char *config_keys[] = -{ - "SocketFile", - "SocketGroup", - "SocketPerms", - "DeleteSocket" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"SocketFile", "SocketGroup", "SocketPerms", + "DeleteSocket"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static int loop = 0; /* socket configuration */ -static int sock_fd = -1; -static char *sock_file = NULL; +static int sock_fd = -1; +static char *sock_file = NULL; static char *sock_group = NULL; -static int sock_perms = S_IRWXU | S_IRWXG; +static int sock_perms = S_IRWXU | S_IRWXG; static _Bool delete_socket = 0; -static pthread_t listen_thread = (pthread_t) 0; +static pthread_t listen_thread = (pthread_t)0; /* * Functions */ -static int us_open_socket (void) -{ - struct sockaddr_un sa = { 0 }; - int status; - - sock_fd = socket (PF_UNIX, SOCK_STREAM, 0); - if (sock_fd < 0) - { - char errbuf[1024]; - ERROR ("unixsock plugin: socket failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - sa.sun_family = AF_UNIX; - sstrncpy (sa.sun_path, (sock_file != NULL) ? sock_file : US_DEFAULT_PATH, - sizeof (sa.sun_path)); - - DEBUG ("unixsock plugin: socket path = %s", sa.sun_path); - - if (delete_socket) - { - errno = 0; - status = unlink (sa.sun_path); - if ((status != 0) && (errno != ENOENT)) - { - char errbuf[1024]; - WARNING ("unixsock plugin: Deleting socket file \"%s\" failed: %s", - sa.sun_path, - sstrerror (errno, errbuf, sizeof (errbuf))); - } - else if (status == 0) - { - INFO ("unixsock plugin: Successfully deleted socket file \"%s\".", - sa.sun_path); - } - } - - status = bind (sock_fd, (struct sockaddr *) &sa, sizeof (sa)); - if (status != 0) - { - char errbuf[1024]; - sstrerror (errno, errbuf, sizeof (errbuf)); - ERROR ("unixsock plugin: bind failed: %s", errbuf); - close (sock_fd); - sock_fd = -1; - return (-1); - } - - status = chmod (sa.sun_path, sock_perms); - if (status == -1) - { - char errbuf[1024]; - ERROR ("unixsock plugin: chmod failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - close (sock_fd); - sock_fd = -1; - return (-1); - } - - status = listen (sock_fd, 8); - if (status != 0) - { - char errbuf[1024]; - ERROR ("unixsock plugin: listen failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - close (sock_fd); - sock_fd = -1; - return (-1); - } - - do - { - const char *grpname; - struct group *g; - struct group sg; - char grbuf[2048]; - - grpname = (sock_group != NULL) ? sock_group : COLLECTD_GRP_NAME; - g = NULL; - - status = getgrnam_r (grpname, &sg, grbuf, sizeof (grbuf), &g); - if (status != 0) - { - char errbuf[1024]; - WARNING ("unixsock plugin: getgrnam_r (%s) failed: %s", grpname, - sstrerror (errno, errbuf, sizeof (errbuf))); - break; - } - if (g == NULL) - { - WARNING ("unixsock plugin: No such group: `%s'", - grpname); - break; - } - - if (chown ((sock_file != NULL) ? sock_file : US_DEFAULT_PATH, - (uid_t) -1, g->gr_gid) != 0) - { - char errbuf[1024]; - WARNING ("unixsock plugin: chown (%s, -1, %i) failed: %s", - (sock_file != NULL) ? sock_file : US_DEFAULT_PATH, - (int) g->gr_gid, - sstrerror (errno, errbuf, sizeof (errbuf))); - } - } while (0); - - return (0); +static int us_open_socket(void) { + struct sockaddr_un sa = {0}; + int status; + + sock_fd = socket(PF_UNIX, SOCK_STREAM, 0); + if (sock_fd < 0) { + char errbuf[1024]; + ERROR("unixsock plugin: socket failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + sa.sun_family = AF_UNIX; + sstrncpy(sa.sun_path, (sock_file != NULL) ? sock_file : US_DEFAULT_PATH, + sizeof(sa.sun_path)); + + DEBUG("unixsock plugin: socket path = %s", sa.sun_path); + + if (delete_socket) { + errno = 0; + status = unlink(sa.sun_path); + if ((status != 0) && (errno != ENOENT)) { + char errbuf[1024]; + WARNING("unixsock plugin: Deleting socket file \"%s\" failed: %s", + sa.sun_path, sstrerror(errno, errbuf, sizeof(errbuf))); + } else if (status == 0) { + INFO("unixsock plugin: Successfully deleted socket file \"%s\".", + sa.sun_path); + } + } + + status = bind(sock_fd, (struct sockaddr *)&sa, sizeof(sa)); + if (status != 0) { + char errbuf[1024]; + sstrerror(errno, errbuf, sizeof(errbuf)); + ERROR("unixsock plugin: bind failed: %s", errbuf); + close(sock_fd); + sock_fd = -1; + return (-1); + } + + status = chmod(sa.sun_path, sock_perms); + if (status == -1) { + char errbuf[1024]; + ERROR("unixsock plugin: chmod failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(sock_fd); + sock_fd = -1; + return (-1); + } + + status = listen(sock_fd, 8); + if (status != 0) { + char errbuf[1024]; + ERROR("unixsock plugin: listen failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(sock_fd); + sock_fd = -1; + return (-1); + } + + do { + const char *grpname; + struct group *g; + struct group sg; + char grbuf[2048]; + + grpname = (sock_group != NULL) ? sock_group : COLLECTD_GRP_NAME; + g = NULL; + + status = getgrnam_r(grpname, &sg, grbuf, sizeof(grbuf), &g); + if (status != 0) { + char errbuf[1024]; + WARNING("unixsock plugin: getgrnam_r (%s) failed: %s", grpname, + sstrerror(errno, errbuf, sizeof(errbuf))); + break; + } + if (g == NULL) { + WARNING("unixsock plugin: No such group: `%s'", grpname); + break; + } + + if (chown((sock_file != NULL) ? sock_file : US_DEFAULT_PATH, (uid_t)-1, + g->gr_gid) != 0) { + char errbuf[1024]; + WARNING("unixsock plugin: chown (%s, -1, %i) failed: %s", + (sock_file != NULL) ? sock_file : US_DEFAULT_PATH, (int)g->gr_gid, + sstrerror(errno, errbuf, sizeof(errbuf))); + } + } while (0); + + return (0); } /* int us_open_socket */ -static void *us_handle_client (void *arg) -{ - int fdin; - int fdout; - FILE *fhin, *fhout; - - fdin = *((int *) arg); - free (arg); - arg = NULL; - - DEBUG ("unixsock plugin: us_handle_client: Reading from fd #%i", fdin); - - fdout = dup (fdin); - if (fdout < 0) - { - char errbuf[1024]; - ERROR ("unixsock plugin: dup failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - close (fdin); - pthread_exit ((void *) 1); - } - - fhin = fdopen (fdin, "r"); - if (fhin == NULL) - { - char errbuf[1024]; - ERROR ("unixsock plugin: fdopen failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - close (fdin); - close (fdout); - pthread_exit ((void *) 1); - return ((void *) 1); - } - - fhout = fdopen (fdout, "w"); - if (fhout == NULL) - { - char errbuf[1024]; - ERROR ("unixsock plugin: fdopen failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - fclose (fhin); /* this closes fdin as well */ - close (fdout); - pthread_exit ((void *) 1); - return ((void *) 1); - } - - /* change output buffer to line buffered mode */ - if (setvbuf (fhout, NULL, _IOLBF, 0) != 0) - { - char errbuf[1024]; - ERROR ("unixsock plugin: setvbuf failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - fclose (fhin); - fclose (fhout); - pthread_exit ((void *) 1); - return ((void *) 0); - } - - while (42) - { - char buffer[1024]; - char buffer_copy[1024]; - char *fields[128]; - int fields_num; - int len; - - errno = 0; - if (fgets (buffer, sizeof (buffer), fhin) == NULL) - { - if ((errno == EINTR) || (errno == EAGAIN)) - continue; - - if (errno != 0) - { - char errbuf[1024]; - WARNING ("unixsock plugin: failed to read from socket #%i: %s", - fileno (fhin), - sstrerror (errno, errbuf, sizeof (errbuf))); - } - break; - } - - len = strlen (buffer); - while ((len > 0) - && ((buffer[len - 1] == '\n') || (buffer[len - 1] == '\r'))) - buffer[--len] = '\0'; - - if (len == 0) - continue; - - sstrncpy (buffer_copy, buffer, sizeof (buffer_copy)); - - fields_num = strsplit (buffer_copy, fields, - sizeof (fields) / sizeof (fields[0])); - if (fields_num < 1) - { - fprintf (fhout, "-1 Internal error\n"); - fclose (fhin); - fclose (fhout); - pthread_exit ((void *) 1); - return ((void *) 1); - } - - if (strcasecmp (fields[0], "getval") == 0) - { - cmd_handle_getval (fhout, buffer); - } - else if (strcasecmp (fields[0], "getthreshold") == 0) - { - handle_getthreshold (fhout, buffer); - } - else if (strcasecmp (fields[0], "putval") == 0) - { - cmd_handle_putval (fhout, buffer); - } - else if (strcasecmp (fields[0], "listval") == 0) - { - cmd_handle_listval (fhout, buffer); - } - else if (strcasecmp (fields[0], "putnotif") == 0) - { - handle_putnotif (fhout, buffer); - } - else if (strcasecmp (fields[0], "flush") == 0) - { - cmd_handle_flush (fhout, buffer); - } - else - { - if (fprintf (fhout, "-1 Unknown command: %s\n", fields[0]) < 0) - { - char errbuf[1024]; - WARNING ("unixsock plugin: failed to write to socket #%i: %s", - fileno (fhout), - sstrerror (errno, errbuf, sizeof (errbuf))); - break; - } - } - } /* while (fgets) */ - - DEBUG ("unixsock plugin: us_handle_client: Exiting.."); - fclose (fhin); - fclose (fhout); - - pthread_exit ((void *) 0); - return ((void *) 0); +static void *us_handle_client(void *arg) { + int fdin; + int fdout; + FILE *fhin, *fhout; + + fdin = *((int *)arg); + free(arg); + arg = NULL; + + DEBUG("unixsock plugin: us_handle_client: Reading from fd #%i", fdin); + + fdout = dup(fdin); + if (fdout < 0) { + char errbuf[1024]; + ERROR("unixsock plugin: dup failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(fdin); + pthread_exit((void *)1); + } + + fhin = fdopen(fdin, "r"); + if (fhin == NULL) { + char errbuf[1024]; + ERROR("unixsock plugin: fdopen failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(fdin); + close(fdout); + pthread_exit((void *)1); + return ((void *)1); + } + + fhout = fdopen(fdout, "w"); + if (fhout == NULL) { + char errbuf[1024]; + ERROR("unixsock plugin: fdopen failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + fclose(fhin); /* this closes fdin as well */ + close(fdout); + pthread_exit((void *)1); + return ((void *)1); + } + + /* change output buffer to line buffered mode */ + if (setvbuf(fhout, NULL, _IOLBF, 0) != 0) { + char errbuf[1024]; + ERROR("unixsock plugin: setvbuf failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + fclose(fhin); + fclose(fhout); + pthread_exit((void *)1); + return ((void *)0); + } + + while (42) { + char buffer[1024]; + char buffer_copy[1024]; + char *fields[128]; + int fields_num; + int len; + + errno = 0; + if (fgets(buffer, sizeof(buffer), fhin) == NULL) { + if ((errno == EINTR) || (errno == EAGAIN)) + continue; + + if (errno != 0) { + char errbuf[1024]; + WARNING("unixsock plugin: failed to read from socket #%i: %s", + fileno(fhin), sstrerror(errno, errbuf, sizeof(errbuf))); + } + break; + } + + len = strlen(buffer); + while ((len > 0) && + ((buffer[len - 1] == '\n') || (buffer[len - 1] == '\r'))) + buffer[--len] = '\0'; + + if (len == 0) + continue; + + sstrncpy(buffer_copy, buffer, sizeof(buffer_copy)); + + fields_num = + strsplit(buffer_copy, fields, sizeof(fields) / sizeof(fields[0])); + if (fields_num < 1) { + fprintf(fhout, "-1 Internal error\n"); + fclose(fhin); + fclose(fhout); + pthread_exit((void *)1); + return ((void *)1); + } + + if (strcasecmp(fields[0], "getval") == 0) { + cmd_handle_getval(fhout, buffer); + } else if (strcasecmp(fields[0], "getthreshold") == 0) { + handle_getthreshold(fhout, buffer); + } else if (strcasecmp(fields[0], "putval") == 0) { + cmd_handle_putval(fhout, buffer); + } else if (strcasecmp(fields[0], "listval") == 0) { + cmd_handle_listval(fhout, buffer); + } else if (strcasecmp(fields[0], "putnotif") == 0) { + handle_putnotif(fhout, buffer); + } else if (strcasecmp(fields[0], "flush") == 0) { + cmd_handle_flush(fhout, buffer); + } else { + if (fprintf(fhout, "-1 Unknown command: %s\n", fields[0]) < 0) { + char errbuf[1024]; + WARNING("unixsock plugin: failed to write to socket #%i: %s", + fileno(fhout), sstrerror(errno, errbuf, sizeof(errbuf))); + break; + } + } + } /* while (fgets) */ + + DEBUG("unixsock plugin: us_handle_client: Exiting.."); + fclose(fhin); + fclose(fhout); + + pthread_exit((void *)0); + return ((void *)0); } /* void *us_handle_client */ -static void *us_server_thread (void __attribute__((unused)) *arg) -{ - int status; - int *remote_fd; - pthread_t th; - pthread_attr_t th_attr; - - pthread_attr_init (&th_attr); - pthread_attr_setdetachstate (&th_attr, PTHREAD_CREATE_DETACHED); - - if (us_open_socket () != 0) - pthread_exit ((void *) 1); - - while (loop != 0) - { - DEBUG ("unixsock plugin: Calling accept.."); - status = accept (sock_fd, NULL, NULL); - if (status < 0) - { - char errbuf[1024]; - - if (errno == EINTR) - continue; - - ERROR ("unixsock plugin: accept failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - close (sock_fd); - sock_fd = -1; - pthread_attr_destroy (&th_attr); - pthread_exit ((void *) 1); - } - - remote_fd = malloc (sizeof (*remote_fd)); - if (remote_fd == NULL) - { - char errbuf[1024]; - WARNING ("unixsock plugin: malloc failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - close (status); - continue; - } - *remote_fd = status; - - DEBUG ("Spawning child to handle connection on fd #%i", *remote_fd); - - status = plugin_thread_create (&th, &th_attr, - us_handle_client, (void *) remote_fd, "unixsock conn"); - if (status != 0) - { - char errbuf[1024]; - WARNING ("unixsock plugin: pthread_create failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - close (*remote_fd); - free (remote_fd); - continue; - } - } /* while (loop) */ - - close (sock_fd); - sock_fd = -1; - pthread_attr_destroy (&th_attr); - - status = unlink ((sock_file != NULL) ? sock_file : US_DEFAULT_PATH); - if (status != 0) - { - char errbuf[1024]; - NOTICE ("unixsock plugin: unlink (%s) failed: %s", - (sock_file != NULL) ? sock_file : US_DEFAULT_PATH, - sstrerror (errno, errbuf, sizeof (errbuf))); - } - - return ((void *) 0); +static void *us_server_thread(void __attribute__((unused)) * arg) { + int status; + int *remote_fd; + pthread_t th; + pthread_attr_t th_attr; + + pthread_attr_init(&th_attr); + pthread_attr_setdetachstate(&th_attr, PTHREAD_CREATE_DETACHED); + + if (us_open_socket() != 0) + pthread_exit((void *)1); + + while (loop != 0) { + DEBUG("unixsock plugin: Calling accept.."); + status = accept(sock_fd, NULL, NULL); + if (status < 0) { + char errbuf[1024]; + + if (errno == EINTR) + continue; + + ERROR("unixsock plugin: accept failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(sock_fd); + sock_fd = -1; + pthread_attr_destroy(&th_attr); + pthread_exit((void *)1); + } + + remote_fd = malloc(sizeof(*remote_fd)); + if (remote_fd == NULL) { + char errbuf[1024]; + WARNING("unixsock plugin: malloc failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(status); + continue; + } + *remote_fd = status; + + DEBUG("Spawning child to handle connection on fd #%i", *remote_fd); + + status = plugin_thread_create(&th, &th_attr, us_handle_client, + (void *)remote_fd, "unixsock conn"); + if (status != 0) { + char errbuf[1024]; + WARNING("unixsock plugin: pthread_create failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(*remote_fd); + free(remote_fd); + continue; + } + } /* while (loop) */ + + close(sock_fd); + sock_fd = -1; + pthread_attr_destroy(&th_attr); + + status = unlink((sock_file != NULL) ? sock_file : US_DEFAULT_PATH); + if (status != 0) { + char errbuf[1024]; + NOTICE("unixsock plugin: unlink (%s) failed: %s", + (sock_file != NULL) ? sock_file : US_DEFAULT_PATH, + sstrerror(errno, errbuf, sizeof(errbuf))); + } + + return ((void *)0); } /* void *us_server_thread */ -static int us_config (const char *key, const char *val) -{ - if (strcasecmp (key, "SocketFile") == 0) - { - char *new_sock_file = strdup (val); - if (new_sock_file == NULL) - return (1); - - sfree (sock_file); - sock_file = new_sock_file; - } - else if (strcasecmp (key, "SocketGroup") == 0) - { - char *new_sock_group = strdup (val); - if (new_sock_group == NULL) - return (1); - - sfree (sock_group); - sock_group = new_sock_group; - } - else if (strcasecmp (key, "SocketPerms") == 0) - { - sock_perms = (int) strtol (val, NULL, 8); - } - else if (strcasecmp (key, "DeleteSocket") == 0) - { - if (IS_TRUE (val)) - delete_socket = 1; - else - delete_socket = 0; - } - else - { - return (-1); - } - - return (0); +static int us_config(const char *key, const char *val) { + if (strcasecmp(key, "SocketFile") == 0) { + char *new_sock_file = strdup(val); + if (new_sock_file == NULL) + return (1); + + sfree(sock_file); + sock_file = new_sock_file; + } else if (strcasecmp(key, "SocketGroup") == 0) { + char *new_sock_group = strdup(val); + if (new_sock_group == NULL) + return (1); + + sfree(sock_group); + sock_group = new_sock_group; + } else if (strcasecmp(key, "SocketPerms") == 0) { + sock_perms = (int)strtol(val, NULL, 8); + } else if (strcasecmp(key, "DeleteSocket") == 0) { + if (IS_TRUE(val)) + delete_socket = 1; + else + delete_socket = 0; + } else { + return (-1); + } + + return (0); } /* int us_config */ -static int us_init (void) -{ - static int have_init = 0; +static int us_init(void) { + static int have_init = 0; - int status; + int status; - /* Initialize only once. */ - if (have_init != 0) - return (0); - have_init = 1; + /* Initialize only once. */ + if (have_init != 0) + return (0); + have_init = 1; - loop = 1; + loop = 1; - status = plugin_thread_create (&listen_thread, NULL, - us_server_thread, NULL, "unixsock listen"); - if (status != 0) - { - char errbuf[1024]; - ERROR ("unixsock plugin: pthread_create failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } + status = plugin_thread_create(&listen_thread, NULL, us_server_thread, NULL, + "unixsock listen"); + if (status != 0) { + char errbuf[1024]; + ERROR("unixsock plugin: pthread_create failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } - return (0); + return (0); } /* int us_init */ -static int us_shutdown (void) -{ - void *ret; +static int us_shutdown(void) { + void *ret; - loop = 0; + loop = 0; - if (listen_thread != (pthread_t) 0) - { - pthread_kill (listen_thread, SIGTERM); - pthread_join (listen_thread, &ret); - listen_thread = (pthread_t) 0; - } + if (listen_thread != (pthread_t)0) { + pthread_kill(listen_thread, SIGTERM); + pthread_join(listen_thread, &ret); + listen_thread = (pthread_t)0; + } - plugin_unregister_init ("unixsock"); - plugin_unregister_shutdown ("unixsock"); + plugin_unregister_init("unixsock"); + plugin_unregister_shutdown("unixsock"); - return (0); + return (0); } /* int us_shutdown */ -void module_register (void) -{ - plugin_register_config ("unixsock", us_config, - config_keys, config_keys_num); - plugin_register_init ("unixsock", us_init); - plugin_register_shutdown ("unixsock", us_shutdown); +void module_register(void) { + plugin_register_config("unixsock", us_config, config_keys, config_keys_num); + plugin_register_init("unixsock", us_init); + plugin_register_shutdown("unixsock", us_shutdown); } /* void module_register (void) */ /* vim: set sw=4 ts=4 sts=4 tw=78 : */ diff --git a/src/uptime.c b/src/uptime.c index f0e1a6f4..96a227d9 100644 --- a/src/uptime.c +++ b/src/uptime.c @@ -25,27 +25,29 @@ #include "plugin.h" #if KERNEL_LINUX -# define STAT_FILE "/proc/stat" +#define STAT_FILE "/proc/stat" /* Using /proc filesystem to retrieve the boot time, Linux only. */ /* #endif KERNEL_LINUX */ #elif HAVE_LIBKSTAT -/* Using kstats chain to retrieve the boot time on Solaris / OpenSolaris systems */ +/* Using kstats chain to retrieve the boot time on Solaris / OpenSolaris systems + */ /* #endif HAVE_LIBKSTAT */ #elif HAVE_SYS_SYSCTL_H -# include -/* Using sysctl interface to retrieve the boot time on *BSD / Darwin / OS X systems */ +#include +/* Using sysctl interface to retrieve the boot time on *BSD / Darwin / OS X + * systems */ /* #endif HAVE_SYS_SYSCTL_H */ #elif HAVE_PERFSTAT -# include -# include +#include +#include /* Using perfstat_cpu_total to retrive the boot time in AIX */ /* #endif HAVE_PERFSTAT */ #else -# error "No applicable input method." +#error "No applicable input method." #endif /* @@ -58,194 +60,179 @@ static time_t boottime; extern kstat_ctl_t *kc; #endif /* #endif HAVE_LIBKSTAT */ -static void uptime_submit (gauge_t value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void uptime_submit(gauge_t value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; - sstrncpy (vl.plugin, "uptime", sizeof (vl.plugin)); - sstrncpy (vl.type, "uptime", sizeof (vl.type)); + sstrncpy(vl.plugin, "uptime", sizeof(vl.plugin)); + sstrncpy(vl.type, "uptime", sizeof(vl.type)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static int uptime_init (void) /* {{{ */ +static int uptime_init(void) /* {{{ */ { - /* - * On most unix systems the uptime is calculated by looking at the boot - * time (stored in unix time, since epoch) and the current one. We are - * going to do the same, reading the boot time value while executing - * the uptime_init function (there is no need to read, every time the - * plugin_read is called, a value that won't change). However, since - * uptime_init is run only once, if the function fails in retrieving - * the boot time, the plugin is unregistered and there is no chance to - * try again later. Nevertheless, this is very unlikely to happen. - */ +/* + * On most unix systems the uptime is calculated by looking at the boot + * time (stored in unix time, since epoch) and the current one. We are + * going to do the same, reading the boot time value while executing + * the uptime_init function (there is no need to read, every time the + * plugin_read is called, a value that won't change). However, since + * uptime_init is run only once, if the function fails in retrieving + * the boot time, the plugin is unregistered and there is no chance to + * try again later. Nevertheless, this is very unlikely to happen. + */ #if KERNEL_LINUX - unsigned long starttime; - char buffer[1024]; - int ret; - FILE *fh; - - ret = 0; - - fh = fopen (STAT_FILE, "r"); - - if (fh == NULL) - { - char errbuf[1024]; - ERROR ("uptime plugin: Cannot open "STAT_FILE": %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - while (fgets (buffer, 1024, fh) != NULL) - { - /* look for the btime string and read the value */ - ret = sscanf (buffer, "btime %lu", &starttime); - /* avoid further loops if btime has been found and read - * correctly (hopefully) */ - if (ret == 1) - break; - } - - fclose (fh); - - /* loop done, check if no value has been found/read */ - if (ret != 1) - { - ERROR ("uptime plugin: No value read from "STAT_FILE""); - return (-1); - } - - boottime = (time_t) starttime; - - if (boottime == 0) - { - ERROR ("uptime plugin: btime read from "STAT_FILE", " - "but `boottime' is zero!"); - return (-1); - } + unsigned long starttime; + char buffer[1024]; + int ret; + FILE *fh; + + ret = 0; + + fh = fopen(STAT_FILE, "r"); + + if (fh == NULL) { + char errbuf[1024]; + ERROR("uptime plugin: Cannot open " STAT_FILE ": %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + while (fgets(buffer, 1024, fh) != NULL) { + /* look for the btime string and read the value */ + ret = sscanf(buffer, "btime %lu", &starttime); + /* avoid further loops if btime has been found and read + * correctly (hopefully) */ + if (ret == 1) + break; + } + + fclose(fh); + + /* loop done, check if no value has been found/read */ + if (ret != 1) { + ERROR("uptime plugin: No value read from " STAT_FILE ""); + return (-1); + } + + boottime = (time_t)starttime; + + if (boottime == 0) { + ERROR("uptime plugin: btime read from " STAT_FILE ", " + "but `boottime' is zero!"); + return (-1); + } /* #endif KERNEL_LINUX */ #elif HAVE_LIBKSTAT - kstat_t *ksp; - kstat_named_t *knp; - - ksp = NULL; - knp = NULL; - - /* kstats chain already opened by update_kstat (using *kc), verify everything went fine. */ - if (kc == NULL) - { - ERROR ("uptime plugin: kstat chain control structure not available."); - return (-1); - } - - ksp = kstat_lookup (kc, "unix", 0, "system_misc"); - if (ksp == NULL) - { - ERROR ("uptime plugin: Cannot find unix:0:system_misc kstat."); - return (-1); - } - - if (kstat_read (kc, ksp, NULL) < 0) - { - ERROR ("uptime plugin: kstat_read failed."); - return (-1); - } - - knp = (kstat_named_t *) kstat_data_lookup (ksp, "boot_time"); - if (knp == NULL) - { - ERROR ("uptime plugin: kstat_data_lookup (boot_time) failed."); - return (-1); - } - - boottime = (time_t) knp->value.ui32; - - if (boottime == 0) - { - ERROR ("uptime plugin: kstat_data_lookup returned success, " - "but `boottime' is zero!"); - return (-1); - } + kstat_t *ksp; + kstat_named_t *knp; + + ksp = NULL; + knp = NULL; + + /* kstats chain already opened by update_kstat (using *kc), verify everything + * went fine. */ + if (kc == NULL) { + ERROR("uptime plugin: kstat chain control structure not available."); + return (-1); + } + + ksp = kstat_lookup(kc, "unix", 0, "system_misc"); + if (ksp == NULL) { + ERROR("uptime plugin: Cannot find unix:0:system_misc kstat."); + return (-1); + } + + if (kstat_read(kc, ksp, NULL) < 0) { + ERROR("uptime plugin: kstat_read failed."); + return (-1); + } + + knp = (kstat_named_t *)kstat_data_lookup(ksp, "boot_time"); + if (knp == NULL) { + ERROR("uptime plugin: kstat_data_lookup (boot_time) failed."); + return (-1); + } + + boottime = (time_t)knp->value.ui32; + + if (boottime == 0) { + ERROR("uptime plugin: kstat_data_lookup returned success, " + "but `boottime' is zero!"); + return (-1); + } /* #endif HAVE_LIBKSTAT */ -# elif HAVE_SYS_SYSCTL_H - struct timeval boottv = { 0 }; - size_t boottv_len; - int status; - - int mib[] = { CTL_KERN, KERN_BOOTTIME }; - - boottv_len = sizeof (boottv); - - status = sysctl (mib, STATIC_ARRAY_SIZE (mib), &boottv, &boottv_len, - /* new_value = */ NULL, /* new_length = */ 0); - if (status != 0) - { - char errbuf[1024]; - ERROR ("uptime plugin: No value read from sysctl interface: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - boottime = boottv.tv_sec; - - if (boottime == 0) - { - ERROR ("uptime plugin: sysctl(3) returned success, " - "but `boottime' is zero!"); - return (-1); - } +#elif HAVE_SYS_SYSCTL_H + struct timeval boottv = {0}; + size_t boottv_len; + int status; + + int mib[] = {CTL_KERN, KERN_BOOTTIME}; + + boottv_len = sizeof(boottv); + + status = sysctl(mib, STATIC_ARRAY_SIZE(mib), &boottv, &boottv_len, + /* new_value = */ NULL, /* new_length = */ 0); + if (status != 0) { + char errbuf[1024]; + ERROR("uptime plugin: No value read from sysctl interface: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + boottime = boottv.tv_sec; + + if (boottime == 0) { + ERROR("uptime plugin: sysctl(3) returned success, " + "but `boottime' is zero!"); + return (-1); + } /* #endif HAVE_SYS_SYSCTL_H */ #elif HAVE_PERFSTAT - int status; - perfstat_cpu_total_t cputotal; - int hertz; - - status = perfstat_cpu_total(NULL, &cputotal, - sizeof(perfstat_cpu_total_t), 1); - if (status < 0) - { - char errbuf[1024]; - ERROR ("uptime plugin: perfstat_cpu_total: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - hertz = sysconf(_SC_CLK_TCK); - if (hertz <= 0) - hertz = HZ; - - boottime = time(NULL) - cputotal.lbolt / hertz; + int status; + perfstat_cpu_total_t cputotal; + int hertz; + + status = perfstat_cpu_total(NULL, &cputotal, sizeof(perfstat_cpu_total_t), 1); + if (status < 0) { + char errbuf[1024]; + ERROR("uptime plugin: perfstat_cpu_total: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + hertz = sysconf(_SC_CLK_TCK); + if (hertz <= 0) + hertz = HZ; + + boottime = time(NULL) - cputotal.lbolt / hertz; #endif /* HAVE_PERFSTAT */ - return (0); + return (0); } /* }}} int uptime_init */ -static int uptime_read (void) -{ - gauge_t uptime; - time_t elapsed; +static int uptime_read(void) { + gauge_t uptime; + time_t elapsed; - /* calculate the amount of time elapsed since boot, AKA uptime */ - elapsed = time (NULL) - boottime; + /* calculate the amount of time elapsed since boot, AKA uptime */ + elapsed = time(NULL) - boottime; - uptime = (gauge_t) elapsed; + uptime = (gauge_t)elapsed; - uptime_submit (uptime); + uptime_submit(uptime); - return (0); + return (0); } -void module_register (void) -{ - plugin_register_init ("uptime", uptime_init); - plugin_register_read ("uptime", uptime_read); +void module_register(void) { + plugin_register_init("uptime", uptime_init); + plugin_register_read("uptime", uptime_read); } /* void module_register */ diff --git a/src/users.c b/src/users.c index e0c51168..ff8c047a 100644 --- a/src/users.c +++ b/src/users.c @@ -31,96 +31,93 @@ #include "plugin.h" #if HAVE_STATGRAB_H -# include +#include #endif /* HAVE_STATGRAB_H */ #if HAVE_UTMPX_H -# include +#include /* #endif HAVE_UTMPX_H */ #elif HAVE_UTMP_H -# include +#include /* #endif HAVE_UTMP_H */ #endif -static void users_submit (gauge_t value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void users_submit(gauge_t value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "users", sizeof (vl.plugin)); - sstrncpy (vl.type, "users", sizeof (vl.plugin)); + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "users", sizeof(vl.plugin)); + sstrncpy(vl.type, "users", sizeof(vl.plugin)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* void users_submit */ -static int users_read (void) -{ +static int users_read(void) { #if HAVE_GETUTXENT - unsigned int users = 0; - struct utmpx *entry = NULL; + unsigned int users = 0; + struct utmpx *entry = NULL; - /* according to the *utent(3) man page none of the functions sets errno - in case of an error, so we cannot do any error-checking here */ - setutxent(); + /* according to the *utent(3) man page none of the functions sets errno + in case of an error, so we cannot do any error-checking here */ + setutxent(); - while (NULL != (entry = getutxent())) { - if (USER_PROCESS == entry->ut_type) { - ++users; - } - } - endutxent(); + while (NULL != (entry = getutxent())) { + if (USER_PROCESS == entry->ut_type) { + ++users; + } + } + endutxent(); - users_submit (users); + users_submit(users); /* #endif HAVE_GETUTXENT */ #elif HAVE_GETUTENT - unsigned int users = 0; - struct utmp *entry = NULL; + unsigned int users = 0; + struct utmp *entry = NULL; - /* according to the *utent(3) man page none of the functions sets errno - in case of an error, so we cannot do any error-checking here */ - setutent(); + /* according to the *utent(3) man page none of the functions sets errno + in case of an error, so we cannot do any error-checking here */ + setutent(); - while (NULL != (entry = getutent())) { - if (USER_PROCESS == entry->ut_type) { - ++users; - } - } - endutent(); + while (NULL != (entry = getutent())) { + if (USER_PROCESS == entry->ut_type) { + ++users; + } + } + endutent(); - users_submit (users); + users_submit(users); /* #endif HAVE_GETUTENT */ #elif HAVE_LIBSTATGRAB - sg_user_stats *us; - -# if HAVE_LIBSTATGRAB_0_90 - size_t num_entries; - us = sg_get_user_stats (&num_entries); -# else - us = sg_get_user_stats (); -# endif - if (us == NULL) - return (-1); - - users_submit ((gauge_t) -# if HAVE_LIBSTATGRAB_0_90 - num_entries); -# else - us->num_entries); -# endif + sg_user_stats *us; + +#if HAVE_LIBSTATGRAB_0_90 + size_t num_entries; + us = sg_get_user_stats(&num_entries); +#else + us = sg_get_user_stats(); +#endif + if (us == NULL) + return (-1); + + users_submit((gauge_t) +#if HAVE_LIBSTATGRAB_0_90 + num_entries); +#else + us->num_entries); +#endif /* #endif HAVE_LIBSTATGRAB */ #else -# error "No applicable input method." +#error "No applicable input method." #endif - return (0); + return (0); } /* int users_read */ -void module_register (void) -{ - plugin_register_read ("users", users_read); +void module_register(void) { + plugin_register_read("users", users_read); } /* void module_register(void) */ diff --git a/src/utils_cmd_flush.c b/src/utils_cmd_flush.c index 9ef50ffb..48243e6d 100644 --- a/src/utils_cmd_flush.c +++ b/src/utils_cmd_flush.c @@ -30,184 +30,153 @@ #include "common.h" #include "plugin.h" -#include "utils_parse_option.h" #include "utils_cmd_flush.h" +#include "utils_parse_option.h" -cmd_status_t cmd_parse_flush (size_t argc, char **argv, - cmd_flush_t *ret_flush, const cmd_options_t *opts, - cmd_error_handler_t *err) -{ - - if ((ret_flush == NULL) || (opts == NULL)) - { - errno = EINVAL; - cmd_error (CMD_ERROR, err, "Invalid arguments to cmd_parse_flush."); - return (CMD_ERROR); - } - - for (size_t i = 0; i < argc; i++) - { - char *opt_key; - char *opt_value; - int status; - - opt_key = NULL; - opt_value = NULL; - status = cmd_parse_option (argv[i], &opt_key, &opt_value, err); - if (status != 0) - { - if (status == CMD_NO_OPTION) - cmd_error (CMD_PARSE_ERROR, err, - "Invalid option string `%s'.", argv[i]); - cmd_destroy_flush (ret_flush); - return (CMD_PARSE_ERROR); - } - - if (strcasecmp ("plugin", opt_key) == 0) - { - strarray_add (&ret_flush->plugins, &ret_flush->plugins_num, - opt_value); - } - else if (strcasecmp ("identifier", opt_key) == 0) - { - identifier_t *id = realloc (ret_flush->identifiers, - (ret_flush->identifiers_num + 1) * sizeof (*id)); - if (id == NULL) - { - cmd_error (CMD_ERROR, err, "realloc failed."); - cmd_destroy_flush (ret_flush); - return (CMD_ERROR); - } - - ret_flush->identifiers = id; - id = ret_flush->identifiers + ret_flush->identifiers_num; - ret_flush->identifiers_num++; - if (parse_identifier (opt_value, - &id->host, &id->plugin, &id->plugin_instance, - &id->type, &id->type_instance, - opts->identifier_default_host) != 0) - { - cmd_error (CMD_PARSE_ERROR, err, - "Invalid identifier `%s'.", opt_value); - cmd_destroy_flush (ret_flush); - return (CMD_PARSE_ERROR); - } - } - else if (strcasecmp ("timeout", opt_key) == 0) - { - char *endptr; - - errno = 0; - endptr = NULL; - ret_flush->timeout = strtod (opt_value, &endptr); - - if ((endptr == opt_value) || (errno != 0) - || (!isfinite (ret_flush->timeout))) - { - cmd_error (CMD_PARSE_ERROR, err, - "Invalid value for option `timeout': %s", - opt_value); - cmd_destroy_flush (ret_flush); - return (CMD_PARSE_ERROR); - } - else if (ret_flush->timeout < 0.0) - { - ret_flush->timeout = 0.0; - } - } - else - { - cmd_error (CMD_PARSE_ERROR, err, - "Cannot parse option `%s'.", opt_key); - cmd_destroy_flush (ret_flush); - return (CMD_PARSE_ERROR); - } - } - - return (CMD_OK); +cmd_status_t cmd_parse_flush(size_t argc, char **argv, cmd_flush_t *ret_flush, + const cmd_options_t *opts, + cmd_error_handler_t *err) { + + if ((ret_flush == NULL) || (opts == NULL)) { + errno = EINVAL; + cmd_error(CMD_ERROR, err, "Invalid arguments to cmd_parse_flush."); + return (CMD_ERROR); + } + + for (size_t i = 0; i < argc; i++) { + char *opt_key; + char *opt_value; + int status; + + opt_key = NULL; + opt_value = NULL; + status = cmd_parse_option(argv[i], &opt_key, &opt_value, err); + if (status != 0) { + if (status == CMD_NO_OPTION) + cmd_error(CMD_PARSE_ERROR, err, "Invalid option string `%s'.", argv[i]); + cmd_destroy_flush(ret_flush); + return (CMD_PARSE_ERROR); + } + + if (strcasecmp("plugin", opt_key) == 0) { + strarray_add(&ret_flush->plugins, &ret_flush->plugins_num, opt_value); + } else if (strcasecmp("identifier", opt_key) == 0) { + identifier_t *id = + realloc(ret_flush->identifiers, + (ret_flush->identifiers_num + 1) * sizeof(*id)); + if (id == NULL) { + cmd_error(CMD_ERROR, err, "realloc failed."); + cmd_destroy_flush(ret_flush); + return (CMD_ERROR); + } + + ret_flush->identifiers = id; + id = ret_flush->identifiers + ret_flush->identifiers_num; + ret_flush->identifiers_num++; + if (parse_identifier(opt_value, &id->host, &id->plugin, + &id->plugin_instance, &id->type, &id->type_instance, + opts->identifier_default_host) != 0) { + cmd_error(CMD_PARSE_ERROR, err, "Invalid identifier `%s'.", opt_value); + cmd_destroy_flush(ret_flush); + return (CMD_PARSE_ERROR); + } + } else if (strcasecmp("timeout", opt_key) == 0) { + char *endptr; + + errno = 0; + endptr = NULL; + ret_flush->timeout = strtod(opt_value, &endptr); + + if ((endptr == opt_value) || (errno != 0) || + (!isfinite(ret_flush->timeout))) { + cmd_error(CMD_PARSE_ERROR, err, + "Invalid value for option `timeout': %s", opt_value); + cmd_destroy_flush(ret_flush); + return (CMD_PARSE_ERROR); + } else if (ret_flush->timeout < 0.0) { + ret_flush->timeout = 0.0; + } + } else { + cmd_error(CMD_PARSE_ERROR, err, "Cannot parse option `%s'.", opt_key); + cmd_destroy_flush(ret_flush); + return (CMD_PARSE_ERROR); + } + } + + return (CMD_OK); } /* cmd_status_t cmd_parse_flush */ -cmd_status_t cmd_handle_flush (FILE *fh, char *buffer) -{ - cmd_error_handler_t err = { cmd_error_fh, fh }; - cmd_t cmd; - - int success = 0; - int error = 0; - int status; - - if ((fh == NULL) || (buffer == NULL)) - return (-1); - - DEBUG ("utils_cmd_flush: cmd_handle_flush (fh = %p, buffer = %s);", - (void *) fh, buffer); - - if ((status = cmd_parse (buffer, &cmd, NULL, &err)) != CMD_OK) - return (status); - if (cmd.type != CMD_FLUSH) - { - cmd_error (CMD_UNKNOWN_COMMAND, &err, "Unexpected command: `%s'.", - CMD_TO_STRING (cmd.type)); - cmd_destroy (&cmd); - return (CMD_UNKNOWN_COMMAND); - } - - for (size_t i = 0; (i == 0) || (i < cmd.cmd.flush.plugins_num); i++) - { - char *plugin = NULL; - - if (cmd.cmd.flush.plugins_num != 0) - plugin = cmd.cmd.flush.plugins[i]; - - for (size_t j = 0; (j == 0) || (j < cmd.cmd.flush.identifiers_num); j++) - { - char *identifier = NULL; - char buffer[1024]; - int status; - - if (cmd.cmd.flush.identifiers_num != 0) - { - identifier_t *id = cmd.cmd.flush.identifiers + j; - if (format_name (buffer, sizeof (buffer), - id->host, id->plugin, id->plugin_instance, - id->type, id->type_instance) != 0) - { - error++; - continue; - } - identifier = buffer; - } - - status = plugin_flush (plugin, - DOUBLE_TO_CDTIME_T (cmd.cmd.flush.timeout), - identifier); - if (status == 0) - success++; - else - error++; - } - } - - cmd_error (CMD_OK, &err, "Done: %i successful, %i errors", - success, error); - - cmd_destroy (&cmd); - return (0); +cmd_status_t cmd_handle_flush(FILE *fh, char *buffer) { + cmd_error_handler_t err = {cmd_error_fh, fh}; + cmd_t cmd; + + int success = 0; + int error = 0; + int status; + + if ((fh == NULL) || (buffer == NULL)) + return (-1); + + DEBUG("utils_cmd_flush: cmd_handle_flush (fh = %p, buffer = %s);", (void *)fh, + buffer); + + if ((status = cmd_parse(buffer, &cmd, NULL, &err)) != CMD_OK) + return (status); + if (cmd.type != CMD_FLUSH) { + cmd_error(CMD_UNKNOWN_COMMAND, &err, "Unexpected command: `%s'.", + CMD_TO_STRING(cmd.type)); + cmd_destroy(&cmd); + return (CMD_UNKNOWN_COMMAND); + } + + for (size_t i = 0; (i == 0) || (i < cmd.cmd.flush.plugins_num); i++) { + char *plugin = NULL; + + if (cmd.cmd.flush.plugins_num != 0) + plugin = cmd.cmd.flush.plugins[i]; + + for (size_t j = 0; (j == 0) || (j < cmd.cmd.flush.identifiers_num); j++) { + char *identifier = NULL; + char buffer[1024]; + int status; + + if (cmd.cmd.flush.identifiers_num != 0) { + identifier_t *id = cmd.cmd.flush.identifiers + j; + if (format_name(buffer, sizeof(buffer), id->host, id->plugin, + id->plugin_instance, id->type, + id->type_instance) != 0) { + error++; + continue; + } + identifier = buffer; + } + + status = plugin_flush(plugin, DOUBLE_TO_CDTIME_T(cmd.cmd.flush.timeout), + identifier); + if (status == 0) + success++; + else + error++; + } + } + + cmd_error(CMD_OK, &err, "Done: %i successful, %i errors", success, error); + + cmd_destroy(&cmd); + return (0); #undef PRINT_TO_SOCK } /* cmd_status_t cmd_handle_flush */ -void cmd_destroy_flush (cmd_flush_t *flush) -{ - if (flush == NULL) - return; +void cmd_destroy_flush(cmd_flush_t *flush) { + if (flush == NULL) + return; - strarray_free (flush->plugins, flush->plugins_num); - flush->plugins = NULL; - flush->plugins_num = 0; + strarray_free(flush->plugins, flush->plugins_num); + flush->plugins = NULL; + flush->plugins_num = 0; - sfree (flush->identifiers); - flush->identifiers_num = 0; + sfree(flush->identifiers); + flush->identifiers_num = 0; } /* void cmd_destroy_flush */ /* vim: set sw=4 ts=4 tw=78 noexpandtab : */ - diff --git a/src/utils_cmds.c b/src/utils_cmds.c index 1f53ad1d..3ea7c9d0 100644 --- a/src/utils_cmds.c +++ b/src/utils_cmds.c @@ -26,327 +26,288 @@ * Sebastian 'tokkee' Harl **/ -#include "utils_cmds.h" +#include "daemon/common.h" #include "utils_cmd_flush.h" #include "utils_cmd_getval.h" #include "utils_cmd_listval.h" #include "utils_cmd_putval.h" +#include "utils_cmds.h" #include "utils_parse_option.h" -#include "daemon/common.h" #include #include static cmd_options_t default_options = { - /* identifier_default_host = */ NULL, + /* identifier_default_host = */ NULL, }; /* * private helper functions */ -static cmd_status_t cmd_split (char *buffer, - size_t *ret_len, char ***ret_fields, - cmd_error_handler_t *err) -{ - char *field; - bool in_field, in_quotes; - - size_t estimate, len; - char **fields; - - estimate = 0; - in_field = false; - for (char *string = buffer; *string != '\0'; ++string) - { - /* Make a quick worst-case estimate of the number of fields by - * counting spaces and ignoring quotation marks. */ - if (!isspace ((int)*string)) - { - if (!in_field) - { - estimate++; - in_field = true; - } - } - else - { - in_field = false; - } - } - - /* fields will be NULL-terminated */ - fields = malloc ((estimate + 1) * sizeof (*fields)); - if (fields == NULL) { - cmd_error (CMD_ERROR, err, "malloc failed."); - return (CMD_ERROR); - } - -#define END_FIELD() \ - do { \ - *field = '\0'; \ - field = NULL; \ - in_field = false; \ - } while (0) -#define NEW_FIELD() \ - do { \ - field = string; \ - in_field = true; \ - assert (len < estimate); \ - fields[len] = field; \ - field++; \ - len++; \ - } while (0) - - len = 0; - field = NULL; - in_field = false; - in_quotes = false; - for (char *string = buffer; *string != '\0'; string++) - { - if (isspace ((int)string[0])) - { - if (! in_quotes) - { - if (in_field) - END_FIELD (); - - /* skip space */ - continue; - } - } - else if (string[0] == '"') - { - /* Note: Two consecutive quoted fields not separated by space are - * treated as different fields. This is the collectd 5.x behavior - * around splitting fields. */ - - if (in_quotes) - { - /* end of quoted field */ - if (! in_field) /* empty quoted string */ - NEW_FIELD (); - END_FIELD (); - in_quotes = false; - continue; - } - - in_quotes = true; - /* if (! in_field): add new field on next iteration - * else: quoted string following an unquoted string (one field) - * in either case: skip quotation mark */ - continue; - } - else if ((string[0] == '\\') && in_quotes) - { - /* Outside of quotes, a backslash is a regular character (mostly - * for backward compatibility). */ - - if (string[1] == '\0') - { - free (fields); - cmd_error (CMD_PARSE_ERROR, err, - "Backslash at end of string."); - return (CMD_PARSE_ERROR); - } - - /* un-escape the next character; skip backslash */ - string++; - } - - if (! in_field) - NEW_FIELD (); - else { - *field = string[0]; - field++; - } - } - - if (in_quotes) - { - free (fields); - cmd_error (CMD_PARSE_ERROR, err, "Unterminated quoted string."); - return (CMD_PARSE_ERROR); - } +static cmd_status_t cmd_split(char *buffer, size_t *ret_len, char ***ret_fields, + cmd_error_handler_t *err) { + char *field; + bool in_field, in_quotes; + + size_t estimate, len; + char **fields; + + estimate = 0; + in_field = false; + for (char *string = buffer; *string != '\0'; ++string) { + /* Make a quick worst-case estimate of the number of fields by + * counting spaces and ignoring quotation marks. */ + if (!isspace((int)*string)) { + if (!in_field) { + estimate++; + in_field = true; + } + } else { + in_field = false; + } + } + + /* fields will be NULL-terminated */ + fields = malloc((estimate + 1) * sizeof(*fields)); + if (fields == NULL) { + cmd_error(CMD_ERROR, err, "malloc failed."); + return (CMD_ERROR); + } + +#define END_FIELD() \ + do { \ + *field = '\0'; \ + field = NULL; \ + in_field = false; \ + } while (0) +#define NEW_FIELD() \ + do { \ + field = string; \ + in_field = true; \ + assert(len < estimate); \ + fields[len] = field; \ + field++; \ + len++; \ + } while (0) + + len = 0; + field = NULL; + in_field = false; + in_quotes = false; + for (char *string = buffer; *string != '\0'; string++) { + if (isspace((int)string[0])) { + if (!in_quotes) { + if (in_field) + END_FIELD(); + + /* skip space */ + continue; + } + } else if (string[0] == '"') { + /* Note: Two consecutive quoted fields not separated by space are + * treated as different fields. This is the collectd 5.x behavior + * around splitting fields. */ + + if (in_quotes) { + /* end of quoted field */ + if (!in_field) /* empty quoted string */ + NEW_FIELD(); + END_FIELD(); + in_quotes = false; + continue; + } + + in_quotes = true; + /* if (! in_field): add new field on next iteration + * else: quoted string following an unquoted string (one field) + * in either case: skip quotation mark */ + continue; + } else if ((string[0] == '\\') && in_quotes) { + /* Outside of quotes, a backslash is a regular character (mostly + * for backward compatibility). */ + + if (string[1] == '\0') { + free(fields); + cmd_error(CMD_PARSE_ERROR, err, "Backslash at end of string."); + return (CMD_PARSE_ERROR); + } + + /* un-escape the next character; skip backslash */ + string++; + } + + if (!in_field) + NEW_FIELD(); + else { + *field = string[0]; + field++; + } + } + + if (in_quotes) { + free(fields); + cmd_error(CMD_PARSE_ERROR, err, "Unterminated quoted string."); + return (CMD_PARSE_ERROR); + } #undef NEW_FIELD #undef END_FIELD - fields[len] = NULL; - if (ret_len != NULL) - *ret_len = len; - if (ret_fields != NULL) - *ret_fields = fields; - else - free (fields); - return (CMD_OK); + fields[len] = NULL; + if (ret_len != NULL) + *ret_len = len; + if (ret_fields != NULL) + *ret_fields = fields; + else + free(fields); + return (CMD_OK); } /* int cmd_split */ /* * public API */ -void cmd_error (cmd_status_t status, cmd_error_handler_t *err, - const char *format, ...) -{ - va_list ap; +void cmd_error(cmd_status_t status, cmd_error_handler_t *err, + const char *format, ...) { + va_list ap; - if ((err == NULL) || (err->cb == NULL)) - return; + if ((err == NULL) || (err->cb == NULL)) + return; - va_start (ap, format); - err->cb (err->ud, status, format, ap); - va_end (ap); + va_start(ap, format); + err->cb(err->ud, status, format, ap); + va_end(ap); } /* void cmd_error */ -cmd_status_t cmd_parsev (size_t argc, char **argv, cmd_t *ret_cmd, - const cmd_options_t *opts, cmd_error_handler_t *err) -{ - char *command = NULL; - cmd_status_t status; - - if ((argc < 1) || (argv == NULL) || (ret_cmd == NULL)) - { - errno = EINVAL; - cmd_error (CMD_ERROR, err, "Missing command."); - return CMD_ERROR; - } - - if (opts == NULL) - opts = &default_options; - - memset (ret_cmd, 0, sizeof (*ret_cmd)); - command = argv[0]; - if (strcasecmp ("FLUSH", command) == 0) - { - ret_cmd->type = CMD_FLUSH; - status = cmd_parse_flush (argc - 1, argv + 1, - &ret_cmd->cmd.flush, opts, err); - } - else if (strcasecmp ("GETVAL", command) == 0) - { - ret_cmd->type = CMD_GETVAL; - status = cmd_parse_getval (argc - 1, argv + 1, - &ret_cmd->cmd.getval, opts, err); - } - else if (strcasecmp ("LISTVAL", command) == 0) - { - ret_cmd->type = CMD_LISTVAL; - status = cmd_parse_listval (argc - 1, argv + 1, - &ret_cmd->cmd.listval, opts, err); - } - else if (strcasecmp ("PUTVAL", command) == 0) - { - ret_cmd->type = CMD_PUTVAL; - status = cmd_parse_putval (argc - 1, argv + 1, - &ret_cmd->cmd.putval, opts, err); - } - else - { - ret_cmd->type = CMD_UNKNOWN; - cmd_error (CMD_UNKNOWN_COMMAND, err, - "Unknown command `%s'.", command); - return (CMD_UNKNOWN_COMMAND); - } - - if (status != CMD_OK) - ret_cmd->type = CMD_UNKNOWN; - return (status); +cmd_status_t cmd_parsev(size_t argc, char **argv, cmd_t *ret_cmd, + const cmd_options_t *opts, cmd_error_handler_t *err) { + char *command = NULL; + cmd_status_t status; + + if ((argc < 1) || (argv == NULL) || (ret_cmd == NULL)) { + errno = EINVAL; + cmd_error(CMD_ERROR, err, "Missing command."); + return CMD_ERROR; + } + + if (opts == NULL) + opts = &default_options; + + memset(ret_cmd, 0, sizeof(*ret_cmd)); + command = argv[0]; + if (strcasecmp("FLUSH", command) == 0) { + ret_cmd->type = CMD_FLUSH; + status = + cmd_parse_flush(argc - 1, argv + 1, &ret_cmd->cmd.flush, opts, err); + } else if (strcasecmp("GETVAL", command) == 0) { + ret_cmd->type = CMD_GETVAL; + status = + cmd_parse_getval(argc - 1, argv + 1, &ret_cmd->cmd.getval, opts, err); + } else if (strcasecmp("LISTVAL", command) == 0) { + ret_cmd->type = CMD_LISTVAL; + status = + cmd_parse_listval(argc - 1, argv + 1, &ret_cmd->cmd.listval, opts, err); + } else if (strcasecmp("PUTVAL", command) == 0) { + ret_cmd->type = CMD_PUTVAL; + status = + cmd_parse_putval(argc - 1, argv + 1, &ret_cmd->cmd.putval, opts, err); + } else { + ret_cmd->type = CMD_UNKNOWN; + cmd_error(CMD_UNKNOWN_COMMAND, err, "Unknown command `%s'.", command); + return (CMD_UNKNOWN_COMMAND); + } + + if (status != CMD_OK) + ret_cmd->type = CMD_UNKNOWN; + return (status); } /* cmd_status_t cmd_parsev */ -cmd_status_t cmd_parse (char *buffer, cmd_t *ret_cmd, - const cmd_options_t *opts, cmd_error_handler_t *err) -{ - char **fields = NULL; - size_t fields_num = 0; - cmd_status_t status; +cmd_status_t cmd_parse(char *buffer, cmd_t *ret_cmd, const cmd_options_t *opts, + cmd_error_handler_t *err) { + char **fields = NULL; + size_t fields_num = 0; + cmd_status_t status; - if ((status = cmd_split (buffer, &fields_num, &fields, err)) != CMD_OK) - return status; + if ((status = cmd_split(buffer, &fields_num, &fields, err)) != CMD_OK) + return status; - status = cmd_parsev (fields_num, fields, ret_cmd, opts, err); - free (fields); - return (status); + status = cmd_parsev(fields_num, fields, ret_cmd, opts, err); + free(fields); + return (status); } /* cmd_status_t cmd_parse */ -void cmd_destroy (cmd_t *cmd) -{ - if (cmd == NULL) - return; - - switch (cmd->type) - { - case CMD_UNKNOWN: - /* nothing to do */ - break; - case CMD_FLUSH: - cmd_destroy_flush (&cmd->cmd.flush); - break; - case CMD_GETVAL: - cmd_destroy_getval (&cmd->cmd.getval); - break; - case CMD_LISTVAL: - cmd_destroy_listval (&cmd->cmd.listval); - break; - case CMD_PUTVAL: - cmd_destroy_putval (&cmd->cmd.putval); - break; - } +void cmd_destroy(cmd_t *cmd) { + if (cmd == NULL) + return; + + switch (cmd->type) { + case CMD_UNKNOWN: + /* nothing to do */ + break; + case CMD_FLUSH: + cmd_destroy_flush(&cmd->cmd.flush); + break; + case CMD_GETVAL: + cmd_destroy_getval(&cmd->cmd.getval); + break; + case CMD_LISTVAL: + cmd_destroy_listval(&cmd->cmd.listval); + break; + case CMD_PUTVAL: + cmd_destroy_putval(&cmd->cmd.putval); + break; + } } /* void cmd_destroy */ -cmd_status_t cmd_parse_option (char *field, - char **ret_key, char **ret_value, cmd_error_handler_t *err) -{ - char *key, *value; - - if (field == NULL) - { - errno = EINVAL; - cmd_error (CMD_ERROR, err, "Invalid argument to cmd_parse_option."); - return (CMD_ERROR); - } - key = value = field; - - /* Look for the equal sign. */ - while (isalnum ((int)value[0]) || (value[0] == '_') || (value[0] == ':')) - value++; - if ((value[0] != '=') || (value == key)) - { - /* Whether this is a fatal error is up to the caller. */ - return (CMD_NO_OPTION); - } - *value = '\0'; - value++; - - if (ret_key != NULL) - *ret_key = key; - if (ret_value != NULL) - *ret_value = value; - - return (CMD_OK); +cmd_status_t cmd_parse_option(char *field, char **ret_key, char **ret_value, + cmd_error_handler_t *err) { + char *key, *value; + + if (field == NULL) { + errno = EINVAL; + cmd_error(CMD_ERROR, err, "Invalid argument to cmd_parse_option."); + return (CMD_ERROR); + } + key = value = field; + + /* Look for the equal sign. */ + while (isalnum((int)value[0]) || (value[0] == '_') || (value[0] == ':')) + value++; + if ((value[0] != '=') || (value == key)) { + /* Whether this is a fatal error is up to the caller. */ + return (CMD_NO_OPTION); + } + *value = '\0'; + value++; + + if (ret_key != NULL) + *ret_key = key; + if (ret_value != NULL) + *ret_value = value; + + return (CMD_OK); } /* cmd_status_t cmd_parse_option */ -void cmd_error_fh (void *ud, cmd_status_t status, - const char *format, va_list ap) -{ - FILE *fh = ud; - int code = -1; - char buf[1024]; - - if (status == CMD_OK) - code = 0; - - vsnprintf (buf, sizeof(buf), format, ap); - buf[sizeof (buf) - 1] = '\0'; - if (fprintf (fh, "%i %s\n", code, buf) < 0) - { - char errbuf[1024]; - WARNING ("utils_cmds: failed to write to file-handle #%i: %s", - fileno (fh), sstrerror (errno, errbuf, sizeof (errbuf))); - return; - } - - fflush (fh); +void cmd_error_fh(void *ud, cmd_status_t status, const char *format, + va_list ap) { + FILE *fh = ud; + int code = -1; + char buf[1024]; + + if (status == CMD_OK) + code = 0; + + vsnprintf(buf, sizeof(buf), format, ap); + buf[sizeof(buf) - 1] = '\0'; + if (fprintf(fh, "%i %s\n", code, buf) < 0) { + char errbuf[1024]; + WARNING("utils_cmds: failed to write to file-handle #%i: %s", fileno(fh), + sstrerror(errno, errbuf, sizeof(errbuf))); + return; + } + + fflush(fh); } /* void cmd_error_fh */ /* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/utils_cmds_test.c b/src/utils_cmds_test.c index 9e9eae3b..b540146d 100644 --- a/src/utils_cmds_test.c +++ b/src/utils_cmds_test.c @@ -28,293 +28,197 @@ #include "testing.h" #include "utils_cmds.h" -static void error_cb (void *ud, cmd_status_t status, - const char *format, va_list ap) -{ - if (status == CMD_OK) - return; - - printf ("ERROR[%d]: ", status); - vprintf (format, ap); - printf ("\n"); - fflush (stdout); +static void error_cb(void *ud, cmd_status_t status, const char *format, + va_list ap) { + if (status == CMD_OK) + return; + + printf("ERROR[%d]: ", status); + vprintf(format, ap); + printf("\n"); + fflush(stdout); } /* void error_cb */ static cmd_options_t default_host_opts = { - /* identifier_default_host = */ "dummy-host", + /* identifier_default_host = */ "dummy-host", }; static struct { - char *input; - cmd_options_t *opts; - cmd_status_t expected_status; - cmd_type_t expected_type; + char *input; + cmd_options_t *opts; + cmd_status_t expected_status; + cmd_type_t expected_type; } parse_data[] = { - /* Valid FLUSH commands. */ - { - "FLUSH", - NULL, - CMD_OK, - CMD_FLUSH, - }, - { - "FLUSH identifier=myhost/magic/MAGIC", - NULL, - CMD_OK, - CMD_FLUSH, - }, - { - "FLUSH identifier=magic/MAGIC", - &default_host_opts, - CMD_OK, - CMD_FLUSH, - }, - { - "FLUSH timeout=123 plugin=\"A\"", - NULL, - CMD_OK, - CMD_FLUSH, - }, - /* Invalid FLUSH commands. */ - { - /* Missing hostname; no default. */ - "FLUSH identifier=magic/MAGIC", - NULL, - CMD_PARSE_ERROR, - CMD_UNKNOWN, - }, - { - /* Missing 'identifier' key. */ - "FLUSH myhost/magic/MAGIC", - NULL, - CMD_PARSE_ERROR, - CMD_UNKNOWN, - }, - { - /* Invalid timeout. */ - "FLUSH timeout=A", - NULL, - CMD_PARSE_ERROR, - CMD_UNKNOWN, - }, - { - /* Invalid identifier. */ - "FLUSH identifier=invalid", - NULL, - CMD_PARSE_ERROR, - CMD_UNKNOWN, - }, - { - /* Invalid option. */ - "FLUSH invalid=option", - NULL, - CMD_PARSE_ERROR, - CMD_UNKNOWN, - }, - - /* Valid GETVAL commands. */ - { - "GETVAL myhost/magic/MAGIC", - NULL, - CMD_OK, - CMD_GETVAL, - }, - { - "GETVAL magic/MAGIC", - &default_host_opts, - CMD_OK, - CMD_GETVAL, - }, - - /* Invalid GETVAL commands. */ - { - "GETVAL magic/MAGIC", - NULL, - CMD_PARSE_ERROR, - CMD_UNKNOWN, - }, - { - "GETVAL", - NULL, - CMD_PARSE_ERROR, - CMD_UNKNOWN, - }, - { - "GETVAL invalid", - NULL, - CMD_PARSE_ERROR, - CMD_UNKNOWN, - }, - - /* Valid LISTVAL commands. */ - { - "LISTVAL", - NULL, - CMD_OK, - CMD_LISTVAL, - }, - - /* Invalid LISTVAL commands. */ - { - "LISTVAL invalid", - NULL, - CMD_PARSE_ERROR, - CMD_UNKNOWN, - }, - - /* Valid PUTVAL commands. */ - { - "PUTVAL magic/MAGIC N:42", - &default_host_opts, - CMD_OK, - CMD_PUTVAL, - }, - { - "PUTVAL myhost/magic/MAGIC N:42", - NULL, - CMD_OK, - CMD_PUTVAL, - }, - { - "PUTVAL myhost/magic/MAGIC 1234:42", - NULL, - CMD_OK, - CMD_PUTVAL, - }, - { - "PUTVAL myhost/magic/MAGIC 1234:42 2345:23", - NULL, - CMD_OK, - CMD_PUTVAL, - }, - { - "PUTVAL myhost/magic/MAGIC interval=2 1234:42", - NULL, - CMD_OK, - CMD_PUTVAL, - }, - { - "PUTVAL myhost/magic/MAGIC interval=2 1234:42 interval=5 2345:23", - NULL, - CMD_OK, - CMD_PUTVAL, - }, - - /* Invalid PUTVAL commands. */ - { - "PUTVAL magic/MAGIC N:42", - NULL, - CMD_PARSE_ERROR, - CMD_UNKNOWN, - }, - { - "PUTVAL", - NULL, - CMD_PARSE_ERROR, - CMD_UNKNOWN, - }, - { - "PUTVAL invalid N:42", - NULL, - CMD_PARSE_ERROR, - CMD_UNKNOWN, - }, - { - "PUTVAL myhost/magic/MAGIC A:42", - NULL, - CMD_PARSE_ERROR, - CMD_UNKNOWN, - }, - { - "PUTVAL myhost/magic/MAGIC 1234:A", - NULL, - CMD_PARSE_ERROR, - CMD_UNKNOWN, - }, - { - "PUTVAL myhost/magic/MAGIC", - NULL, - CMD_PARSE_ERROR, - CMD_UNKNOWN, - }, - { - "PUTVAL 1234:A", - NULL, - CMD_PARSE_ERROR, - CMD_UNKNOWN, - }, - { - "PUTVAL myhost/magic/UNKNOWN 1234:42", - NULL, - CMD_PARSE_ERROR, - CMD_UNKNOWN, - }, - /* - * As of collectd 5.x, PUTVAL accepts invalid options. - { - "PUTVAL myhost/magic/MAGIC invalid=2 1234:42", - NULL, - CMD_PARSE_ERROR, - CMD_UNKNOWN, - }, - */ - - /* Invalid commands. */ - { - "INVALID", - NULL, - CMD_UNKNOWN_COMMAND, - CMD_UNKNOWN, - }, - { - "INVALID interval=2", - NULL, - CMD_UNKNOWN_COMMAND, - CMD_UNKNOWN, - }, + /* Valid FLUSH commands. */ + { + "FLUSH", NULL, CMD_OK, CMD_FLUSH, + }, + { + "FLUSH identifier=myhost/magic/MAGIC", NULL, CMD_OK, CMD_FLUSH, + }, + { + "FLUSH identifier=magic/MAGIC", &default_host_opts, CMD_OK, CMD_FLUSH, + }, + { + "FLUSH timeout=123 plugin=\"A\"", NULL, CMD_OK, CMD_FLUSH, + }, + /* Invalid FLUSH commands. */ + { + /* Missing hostname; no default. */ + "FLUSH identifier=magic/MAGIC", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN, + }, + { + /* Missing 'identifier' key. */ + "FLUSH myhost/magic/MAGIC", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN, + }, + { + /* Invalid timeout. */ + "FLUSH timeout=A", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN, + }, + { + /* Invalid identifier. */ + "FLUSH identifier=invalid", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN, + }, + { + /* Invalid option. */ + "FLUSH invalid=option", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN, + }, + + /* Valid GETVAL commands. */ + { + "GETVAL myhost/magic/MAGIC", NULL, CMD_OK, CMD_GETVAL, + }, + { + "GETVAL magic/MAGIC", &default_host_opts, CMD_OK, CMD_GETVAL, + }, + + /* Invalid GETVAL commands. */ + { + "GETVAL magic/MAGIC", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN, + }, + { + "GETVAL", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN, + }, + { + "GETVAL invalid", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN, + }, + + /* Valid LISTVAL commands. */ + { + "LISTVAL", NULL, CMD_OK, CMD_LISTVAL, + }, + + /* Invalid LISTVAL commands. */ + { + "LISTVAL invalid", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN, + }, + + /* Valid PUTVAL commands. */ + { + "PUTVAL magic/MAGIC N:42", &default_host_opts, CMD_OK, CMD_PUTVAL, + }, + { + "PUTVAL myhost/magic/MAGIC N:42", NULL, CMD_OK, CMD_PUTVAL, + }, + { + "PUTVAL myhost/magic/MAGIC 1234:42", NULL, CMD_OK, CMD_PUTVAL, + }, + { + "PUTVAL myhost/magic/MAGIC 1234:42 2345:23", NULL, CMD_OK, CMD_PUTVAL, + }, + { + "PUTVAL myhost/magic/MAGIC interval=2 1234:42", NULL, CMD_OK, + CMD_PUTVAL, + }, + { + "PUTVAL myhost/magic/MAGIC interval=2 1234:42 interval=5 2345:23", NULL, + CMD_OK, CMD_PUTVAL, + }, + + /* Invalid PUTVAL commands. */ + { + "PUTVAL magic/MAGIC N:42", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN, + }, + { + "PUTVAL", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN, + }, + { + "PUTVAL invalid N:42", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN, + }, + { + "PUTVAL myhost/magic/MAGIC A:42", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN, + }, + { + "PUTVAL myhost/magic/MAGIC 1234:A", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN, + }, + { + "PUTVAL myhost/magic/MAGIC", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN, + }, + { + "PUTVAL 1234:A", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN, + }, + { + "PUTVAL myhost/magic/UNKNOWN 1234:42", NULL, CMD_PARSE_ERROR, + CMD_UNKNOWN, + }, + /* + * As of collectd 5.x, PUTVAL accepts invalid options. + { + "PUTVAL myhost/magic/MAGIC invalid=2 1234:42", + NULL, + CMD_PARSE_ERROR, + CMD_UNKNOWN, + }, + */ + + /* Invalid commands. */ + { + "INVALID", NULL, CMD_UNKNOWN_COMMAND, CMD_UNKNOWN, + }, + { + "INVALID interval=2", NULL, CMD_UNKNOWN_COMMAND, CMD_UNKNOWN, + }, }; -DEF_TEST(parse) -{ - cmd_error_handler_t err = { error_cb, NULL }; - int test_result = 0; +DEF_TEST(parse) { + cmd_error_handler_t err = {error_cb, NULL}; + int test_result = 0; - for (size_t i = 0; i < STATIC_ARRAY_SIZE (parse_data); i++) { - char *input = strdup (parse_data[i].input); + for (size_t i = 0; i < STATIC_ARRAY_SIZE(parse_data); i++) { + char *input = strdup(parse_data[i].input); - char description[1024]; - cmd_status_t status; - cmd_t cmd; + char description[1024]; + cmd_status_t status; + cmd_t cmd; - _Bool result; + _Bool result; - memset (&cmd, 0, sizeof (cmd)); + memset(&cmd, 0, sizeof(cmd)); - status = cmd_parse (input, &cmd, parse_data[i].opts, &err); - snprintf (description, sizeof (description), - "cmd_parse (\"%s\", opts=%p) = %d (type=%d [%s]); want %d (type=%d [%s])", - parse_data[i].input, parse_data[i].opts, status, - cmd.type, CMD_TO_STRING (cmd.type), - parse_data[i].expected_status, - parse_data[i].expected_type, - CMD_TO_STRING (parse_data[i].expected_type)); - result = (status == parse_data[i].expected_status) - && (cmd.type == parse_data[i].expected_type); - LOG (result, description); + status = cmd_parse(input, &cmd, parse_data[i].opts, &err); + snprintf(description, sizeof(description), "cmd_parse (\"%s\", opts=%p) = " + "%d (type=%d [%s]); want %d " + "(type=%d [%s])", + parse_data[i].input, parse_data[i].opts, status, cmd.type, + CMD_TO_STRING(cmd.type), parse_data[i].expected_status, + parse_data[i].expected_type, + CMD_TO_STRING(parse_data[i].expected_type)); + result = (status == parse_data[i].expected_status) && + (cmd.type == parse_data[i].expected_type); + LOG(result, description); - /* Run all tests before failing. */ - if (! result) - test_result = -1; + /* Run all tests before failing. */ + if (!result) + test_result = -1; - cmd_destroy (&cmd); - free (input); - } + cmd_destroy(&cmd); + free(input); + } - return (test_result); + return (test_result); } -int main (int argc, char **argv) -{ - RUN_TEST(parse); - END_TEST; +int main(int argc, char **argv) { + RUN_TEST(parse); + END_TEST; } diff --git a/src/utils_latency_config.c b/src/utils_latency_config.c index 133678e5..674e2752 100644 --- a/src/utils_latency_config.c +++ b/src/utils_latency_config.c @@ -25,9 +25,9 @@ * Pavel Rochnyack */ +#include "common.h" #include "utils_latency_config.h" #include "collectd.h" -#include "common.h" static int latency_config_add_percentile(latency_config_t *conf, oconfig_item_t *ci, diff --git a/src/utils_lua.c b/src/utils_lua.c index f7466551..dcb84afa 100644 --- a/src/utils_lua.c +++ b/src/utils_lua.c @@ -28,8 +28,8 @@ * GCC will complain about the macro definition. */ #define DONT_POISON_SPRINTF_YET -#include "utils_lua.h" #include "common.h" +#include "utils_lua.h" static int ltoc_values(lua_State *L, /* {{{ */ const data_set_t *ds, value_t *ret_values) { @@ -166,7 +166,7 @@ int luaC_tostringbuffer(lua_State *L, int idx, /* {{{ */ value_t luaC_tovalue(lua_State *L, int idx, int ds_type) /* {{{ */ { - value_t v = { 0 }; + value_t v = {0}; if (!lua_isnumber(L, idx)) return (v); @@ -223,8 +223,7 @@ value_list_t *luaC_tovaluelist(lua_State *L, int idx) /* {{{ */ else if (strcasecmp("type", key) == 0) luaC_tostringbuffer(L, -1, vl->type, sizeof(vl->type)); else if (strcasecmp("type_instance", key) == 0) - luaC_tostringbuffer(L, -1, vl->type_instance, - sizeof(vl->type_instance)); + luaC_tostringbuffer(L, -1, vl->type_instance, sizeof(vl->type_instance)); else if (strcasecmp("time", key) == 0) vl->time = luaC_tocdtime(L, -1); else if (strcasecmp("interval", key) == 0) diff --git a/src/utils_lua.h b/src/utils_lua.h index b5941904..8ff507c7 100644 --- a/src/utils_lua.h +++ b/src/utils_lua.h @@ -27,8 +27,8 @@ #ifndef UTILS_LUA_H #define UTILS_LUA_H 1 -#include "collectd.h" #include "plugin.h" +#include "collectd.h" #ifndef DONT_POISON_SPRINTF_YET #error "Files including utils_lua.h need to define DONT_POISON_SPRINTF_YET." diff --git a/src/utils_mount.c b/src/utils_mount.c index e527c258..660e0852 100644 --- a/src/utils_mount.c +++ b/src/utils_mount.c @@ -21,7 +21,7 @@ **/ #if HAVE_CONFIG_H -# include "config.h" +#include "config.h" #endif #define _GNU_SOURCE @@ -31,7 +31,7 @@ #include "utils_mount.h" #if HAVE_XFS_XQM_H -# include +#include #define XFS_SUPER_MAGIC_STR "XFSB" #define XFS_SUPER_MAGIC2_STR "BSFX" #endif @@ -39,55 +39,54 @@ #include "common.h" /* sstrncpy() et alii */ #include "plugin.h" /* ERROR() macro */ - #if HAVE_GETVFSSTAT -# if HAVE_SYS_TYPES_H -# include -# endif -# if HAVE_SYS_STATVFS_H -# include -# endif +#if HAVE_SYS_TYPES_H +#include +#endif +#if HAVE_SYS_STATVFS_H +#include +#endif /* #endif HAVE_GETVFSSTAT */ #elif HAVE_GETFSSTAT -# if HAVE_SYS_PARAM_H -# include -# endif -# if HAVE_SYS_UCRED_H -# include -# endif -# if HAVE_SYS_MOUNT_H -# include -# endif +#if HAVE_SYS_PARAM_H +#include +#endif +#if HAVE_SYS_UCRED_H +#include +#endif +#if HAVE_SYS_MOUNT_H +#include +#endif #endif /* HAVE_GETFSSTAT */ #if HAVE_MNTENT_H -# include +#include #endif #if HAVE_SYS_MNTTAB_H -# include +#include #endif #if HAVE_PATHS_H -# include +#include #endif #ifdef COLLECTD_MNTTAB -# undef COLLECTD_MNTTAB +#undef COLLECTD_MNTTAB #endif #if defined(_PATH_MOUNTED) /* glibc */ -# define COLLECTD_MNTTAB _PATH_MOUNTED +#define COLLECTD_MNTTAB _PATH_MOUNTED #elif defined(MNTTAB) /* Solaris */ -# define COLLECTD_MNTTAB MNTTAB +#define COLLECTD_MNTTAB MNTTAB #elif defined(MNT_MNTTAB) -# define COLLECTD_MNTTAB MNT_MNTTAB +#define COLLECTD_MNTTAB MNT_MNTTAB #elif defined(MNTTABNAME) -# define COLLECTD_MNTTAB MNTTABNAME +#define COLLECTD_MNTTAB MNTTABNAME #elif defined(KMTAB) -# define COLLECTD_MNTTAB KMTAB +#define COLLECTD_MNTTAB KMTAB #else -# define COLLECTD_MNTTAB "/etc/mnttab" +#define COLLECTD_MNTTAB "/etc/mnttab" #endif /* *** *** *** ********************************************* *** *** *** */ @@ -97,590 +96,544 @@ /* stolen from quota-3.13 (quota-tools) */ #define PROC_PARTITIONS "/proc/partitions" -#define DEVLABELDIR "/dev" -#define UUID 1 -#define VOL 2 +#define DEVLABELDIR "/dev" +#define UUID 1 +#define VOL 2 static struct uuidCache_s { - struct uuidCache_s *next; - char uuid[16]; - char *label; - char *device; + struct uuidCache_s *next; + char uuid[16]; + char *label; + char *device; } *uuidCache = NULL; #define EXT2_SUPER_MAGIC 0xEF53 struct ext2_super_block { - unsigned char s_dummy1[56]; - unsigned char s_magic[2]; - unsigned char s_dummy2[46]; - unsigned char s_uuid[16]; - char s_volume_name[16]; + unsigned char s_dummy1[56]; + unsigned char s_magic[2]; + unsigned char s_dummy2[46]; + unsigned char s_uuid[16]; + char s_volume_name[16]; }; -#define ext2magic(s) ((unsigned int)s.s_magic[0] \ - + (((unsigned int)s.s_magic[1]) << 8)) +#define ext2magic(s) \ + ((unsigned int)s.s_magic[0] + (((unsigned int)s.s_magic[1]) << 8)) #if HAVE_XFS_XQM_H struct xfs_super_block { - unsigned char s_magic[4]; - unsigned char s_dummy[28]; - unsigned char s_uuid[16]; - unsigned char s_dummy2[60]; - char s_fsname[12]; + unsigned char s_magic[4]; + unsigned char s_dummy[28]; + unsigned char s_uuid[16]; + unsigned char s_dummy2[60]; + char s_fsname[12]; }; #endif /* HAVE_XFS_XQM_H */ #define REISER_SUPER_MAGIC "ReIsEr2Fs" struct reiserfs_super_block { - unsigned char s_dummy1[52]; - unsigned char s_magic[10]; - unsigned char s_dummy2[22]; - unsigned char s_uuid[16]; - char s_volume_name[16]; + unsigned char s_dummy1[52]; + unsigned char s_magic[10]; + unsigned char s_dummy2[22]; + unsigned char s_uuid[16]; + char s_volume_name[16]; }; /* for now, only ext2 and xfs are supported */ -static int -get_label_uuid(const char *device, char **label, char *uuid) -{ - /* start with ext2 and xfs tests, taken from mount_guess_fstype */ - /* should merge these later */ - int fd, rv = 1; - size_t namesize; - struct ext2_super_block e2sb; +static int get_label_uuid(const char *device, char **label, char *uuid) { + /* start with ext2 and xfs tests, taken from mount_guess_fstype */ + /* should merge these later */ + int fd, rv = 1; + size_t namesize; + struct ext2_super_block e2sb; #if HAVE_XFS_XQM_H - struct xfs_super_block xfsb; + struct xfs_super_block xfsb; #endif - struct reiserfs_super_block reisersb; - - fd = open(device, O_RDONLY); - if(fd == -1) { - return rv; - } - - if(lseek(fd, 1024, SEEK_SET) == 1024 - && read(fd, (char *)&e2sb, sizeof(e2sb)) == sizeof(e2sb) - && ext2magic(e2sb) == EXT2_SUPER_MAGIC) { - memcpy(uuid, e2sb.s_uuid, sizeof(e2sb.s_uuid)); - namesize = sizeof(e2sb.s_volume_name); - *label = smalloc(namesize + 1); - sstrncpy(*label, e2sb.s_volume_name, namesize); - rv = 0; + struct reiserfs_super_block reisersb; + + fd = open(device, O_RDONLY); + if (fd == -1) { + return rv; + } + + if (lseek(fd, 1024, SEEK_SET) == 1024 && + read(fd, (char *)&e2sb, sizeof(e2sb)) == sizeof(e2sb) && + ext2magic(e2sb) == EXT2_SUPER_MAGIC) { + memcpy(uuid, e2sb.s_uuid, sizeof(e2sb.s_uuid)); + namesize = sizeof(e2sb.s_volume_name); + *label = smalloc(namesize + 1); + sstrncpy(*label, e2sb.s_volume_name, namesize); + rv = 0; #if HAVE_XFS_XQM_H - } else if(lseek(fd, 0, SEEK_SET) == 0 - && read(fd, (char *)&xfsb, sizeof(xfsb)) == sizeof(xfsb) - && (strncmp((char *)&xfsb.s_magic, XFS_SUPER_MAGIC_STR, 4) == 0 || - strncmp((char *)&xfsb.s_magic, XFS_SUPER_MAGIC2_STR, 4) == 0)) { - memcpy(uuid, xfsb.s_uuid, sizeof(xfsb.s_uuid)); - namesize = sizeof(xfsb.s_fsname); - *label = smalloc(namesize + 1); - sstrncpy(*label, xfsb.s_fsname, namesize); - rv = 0; + } else if (lseek(fd, 0, SEEK_SET) == 0 && + read(fd, (char *)&xfsb, sizeof(xfsb)) == sizeof(xfsb) && + (strncmp((char *)&xfsb.s_magic, XFS_SUPER_MAGIC_STR, 4) == 0 || + strncmp((char *)&xfsb.s_magic, XFS_SUPER_MAGIC2_STR, 4) == 0)) { + memcpy(uuid, xfsb.s_uuid, sizeof(xfsb.s_uuid)); + namesize = sizeof(xfsb.s_fsname); + *label = smalloc(namesize + 1); + sstrncpy(*label, xfsb.s_fsname, namesize); + rv = 0; #endif /* HAVE_XFS_XQM_H */ - } else if(lseek(fd, 65536, SEEK_SET) == 65536 - && read(fd, (char *)&reisersb, sizeof(reisersb)) == sizeof(reisersb) - && !strncmp((char *)&reisersb.s_magic, REISER_SUPER_MAGIC, 9)) { - memcpy(uuid, reisersb.s_uuid, sizeof(reisersb.s_uuid)); - namesize = sizeof(reisersb.s_volume_name); - *label = smalloc(namesize + 1); - sstrncpy(*label, reisersb.s_volume_name, namesize); - rv = 0; - } - close(fd); - return rv; + } else if (lseek(fd, 65536, SEEK_SET) == 65536 && + read(fd, (char *)&reisersb, sizeof(reisersb)) == + sizeof(reisersb) && + !strncmp((char *)&reisersb.s_magic, REISER_SUPER_MAGIC, 9)) { + memcpy(uuid, reisersb.s_uuid, sizeof(reisersb.s_uuid)); + namesize = sizeof(reisersb.s_volume_name); + *label = smalloc(namesize + 1); + sstrncpy(*label, reisersb.s_volume_name, namesize); + rv = 0; + } + close(fd); + return rv; } -static void -uuidcache_addentry(char *device, char *label, char *uuid) -{ - struct uuidCache_s *last; - - if(!uuidCache) { - last = uuidCache = smalloc(sizeof(*uuidCache)); - } else { - for(last = uuidCache; last->next; last = last->next); - last->next = smalloc(sizeof(*uuidCache)); - last = last->next; - } - last->next = NULL; - last->device = device; - last->label = label; - memcpy(last->uuid, uuid, sizeof(last->uuid)); +static void uuidcache_addentry(char *device, char *label, char *uuid) { + struct uuidCache_s *last; + + if (!uuidCache) { + last = uuidCache = smalloc(sizeof(*uuidCache)); + } else { + for (last = uuidCache; last->next; last = last->next) + ; + last->next = smalloc(sizeof(*uuidCache)); + last = last->next; + } + last->next = NULL; + last->device = device; + last->label = label; + memcpy(last->uuid, uuid, sizeof(last->uuid)); } -static void -uuidcache_init(void) -{ - char line[100]; - char *s; - int ma, mi, sz; - static char ptname[100]; - FILE *procpt; - char uuid[16], *label = NULL; - char device[110]; - int handleOnFirst; - - if(uuidCache) { - return; - } - - procpt = fopen(PROC_PARTITIONS, "r"); - if(procpt == NULL) { - return; - } - - for(int firstPass = 1; firstPass >= 0; firstPass--) { - fseek(procpt, 0, SEEK_SET); - while(fgets(line, sizeof(line), procpt)) { - if(sscanf(line, " %d %d %d %[^\n ]", - &ma, &mi, &sz, ptname) != 4) - { - continue; - } - - /* skip extended partitions (heuristic: size 1) */ - if(sz == 1) { - continue; - } - - /* look only at md devices on first pass */ - handleOnFirst = !strncmp(ptname, "md", 2); - if(firstPass != handleOnFirst) { - continue; - } - - /* skip entire disk (minor 0, 64, ... on ide; - 0, 16, ... on sd) */ - /* heuristic: partition name ends in a digit */ - - for(s = ptname; *s; s++); - - if(isdigit((int)s[-1])) { - /* - * Note: this is a heuristic only - there is no reason - * why these devices should live in /dev. - * Perhaps this directory should be specifiable by option. - * One might for example have /devlabel with links to /dev - * for the devices that may be accessed in this way. - * (This is useful, if the cdrom on /dev/hdc must not - * be accessed.) - */ - ssnprintf(device, sizeof(device), "%s/%s", - DEVLABELDIR, ptname); - if(!get_label_uuid(device, &label, uuid)) { - uuidcache_addentry(sstrdup(device), - label, uuid); - } - } - } - } - fclose(procpt); +static void uuidcache_init(void) { + char line[100]; + char *s; + int ma, mi, sz; + static char ptname[100]; + FILE *procpt; + char uuid[16], *label = NULL; + char device[110]; + int handleOnFirst; + + if (uuidCache) { + return; + } + + procpt = fopen(PROC_PARTITIONS, "r"); + if (procpt == NULL) { + return; + } + + for (int firstPass = 1; firstPass >= 0; firstPass--) { + fseek(procpt, 0, SEEK_SET); + while (fgets(line, sizeof(line), procpt)) { + if (sscanf(line, " %d %d %d %[^\n ]", &ma, &mi, &sz, ptname) != 4) { + continue; + } + + /* skip extended partitions (heuristic: size 1) */ + if (sz == 1) { + continue; + } + + /* look only at md devices on first pass */ + handleOnFirst = !strncmp(ptname, "md", 2); + if (firstPass != handleOnFirst) { + continue; + } + + /* skip entire disk (minor 0, 64, ... on ide; + 0, 16, ... on sd) */ + /* heuristic: partition name ends in a digit */ + + for (s = ptname; *s; s++) + ; + + if (isdigit((int)s[-1])) { + /* + * Note: this is a heuristic only - there is no reason + * why these devices should live in /dev. + * Perhaps this directory should be specifiable by option. + * One might for example have /devlabel with links to /dev + * for the devices that may be accessed in this way. + * (This is useful, if the cdrom on /dev/hdc must not + * be accessed.) + */ + ssnprintf(device, sizeof(device), "%s/%s", DEVLABELDIR, ptname); + if (!get_label_uuid(device, &label, uuid)) { + uuidcache_addentry(sstrdup(device), label, uuid); + } + } + } + } + fclose(procpt); } -static unsigned char -fromhex(char c) -{ - if(isdigit((int)c)) { - return (c - '0'); - } else if(islower((int)c)) { - return (c - 'a' + 10); - } else { - return (c - 'A' + 10); - } +static unsigned char fromhex(char c) { + if (isdigit((int)c)) { + return (c - '0'); + } else if (islower((int)c)) { + return (c - 'a' + 10); + } else { + return (c - 'A' + 10); + } } -static char * -get_spec_by_x(int n, const char *t) -{ - struct uuidCache_s *uc; - - uuidcache_init(); - uc = uuidCache; - - while(uc) { - switch(n) { - case UUID: - if(!memcmp(t, uc->uuid, sizeof(uc->uuid))) { - return sstrdup(uc->device); - } - break; - case VOL: - if(!strcmp(t, uc->label)) { - return sstrdup(uc->device); - } - break; - } - uc = uc->next; - } - return NULL; +static char *get_spec_by_x(int n, const char *t) { + struct uuidCache_s *uc; + + uuidcache_init(); + uc = uuidCache; + + while (uc) { + switch (n) { + case UUID: + if (!memcmp(t, uc->uuid, sizeof(uc->uuid))) { + return sstrdup(uc->device); + } + break; + case VOL: + if (!strcmp(t, uc->label)) { + return sstrdup(uc->device); + } + break; + } + uc = uc->next; + } + return NULL; } -static char * -get_spec_by_uuid(const char *s) -{ - char uuid[16]; - - if(strlen(s) != 36 - || s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-') { - goto bad_uuid; - } - - for(int i=0; i<16; i++) { - if(*s == '-') { - s++; - } - if(!isxdigit((int)s[0]) || !isxdigit((int)s[1])) { - goto bad_uuid; - } - uuid[i] = ((fromhex(s[0]) << 4) | fromhex(s[1])); - s += 2; - } - return get_spec_by_x(UUID, uuid); - - bad_uuid: - DEBUG("utils_mount: Found an invalid UUID: %s", s); - return NULL; +static char *get_spec_by_uuid(const char *s) { + char uuid[16]; + + if (strlen(s) != 36 || s[8] != '-' || s[13] != '-' || s[18] != '-' || + s[23] != '-') { + goto bad_uuid; + } + + for (int i = 0; i < 16; i++) { + if (*s == '-') { + s++; + } + if (!isxdigit((int)s[0]) || !isxdigit((int)s[1])) { + goto bad_uuid; + } + uuid[i] = ((fromhex(s[0]) << 4) | fromhex(s[1])); + s += 2; + } + return get_spec_by_x(UUID, uuid); + +bad_uuid: + DEBUG("utils_mount: Found an invalid UUID: %s", s); + return NULL; } -static char *get_spec_by_volume_label(const char *s) -{ - return get_spec_by_x (VOL, s); +static char *get_spec_by_volume_label(const char *s) { + return get_spec_by_x(VOL, s); } -static char *get_device_name(const char *optstr) -{ - char *rc; - - if (optstr == NULL) - { - return (NULL); - } - else if (strncmp (optstr, "UUID=", 5) == 0) - { - DEBUG ("utils_mount: TODO: check UUID= code!"); - rc = get_spec_by_uuid (optstr + 5); - } - else if (strncmp (optstr, "LABEL=", 6) == 0) - { - DEBUG ("utils_mount: TODO: check LABEL= code!"); - rc = get_spec_by_volume_label (optstr + 6); - } - else - { - rc = sstrdup (optstr); - } - - if(!rc) - { - DEBUG ("utils_mount: Error checking device name: optstr = %s", optstr); - } - return rc; +static char *get_device_name(const char *optstr) { + char *rc; + + if (optstr == NULL) { + return (NULL); + } else if (strncmp(optstr, "UUID=", 5) == 0) { + DEBUG("utils_mount: TODO: check UUID= code!"); + rc = get_spec_by_uuid(optstr + 5); + } else if (strncmp(optstr, "LABEL=", 6) == 0) { + DEBUG("utils_mount: TODO: check LABEL= code!"); + rc = get_spec_by_volume_label(optstr + 6); + } else { + rc = sstrdup(optstr); + } + + if (!rc) { + DEBUG("utils_mount: Error checking device name: optstr = %s", optstr); + } + return rc; } /* What weird OS is this..? I can't find any info with google :/ -octo */ #if HAVE_LISTMNTENT && 0 -static cu_mount_t *cu_mount_listmntent (void) -{ - cu_mount_t *last = *list; - struct mntent *mnt; +static cu_mount_t *cu_mount_listmntent(void) { + cu_mount_t *last = *list; + struct mntent *mnt; - struct tabmntent *mntlist; - if(listmntent(&mntlist, COLLECTD_MNTTAB, NULL, NULL) < 0) { + struct tabmntent *mntlist; + if (listmntent(&mntlist, COLLECTD_MNTTAB, NULL, NULL) < 0) { #if COLLECT_DEBUG - char errbuf[1024]; - DEBUG("utils_mount: calling listmntent() failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + char errbuf[1024]; + DEBUG("utils_mount: calling listmntent() failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); #endif /* COLLECT_DEBUG */ - } - - for(struct tabmntent *p = mntlist; p; p = p->next) { - char *loop = NULL, *device = NULL; - - mnt = p->ment; - loop = cu_mount_getoptionvalue(mnt->mnt_opts, "loop="); - if(loop == NULL) { /* no loop= mount */ - device = get_device_name(mnt->mnt_fsname); - if(device == NULL) { - DEBUG("utils_mount: can't get devicename for fs (%s) %s (%s)" - ": ignored", mnt->mnt_type, - mnt->mnt_dir, mnt->mnt_fsname); - continue; - } - } else { - device = loop; - } - if(*list == NULL) { - *list = (cu_mount_t *)smalloc(sizeof(cu_mount_t)); - last = *list; - } else { - while(last->next != NULL) { /* is last really last? */ - last = last->next; - } - last->next = (cu_mount_t *)smalloc(sizeof(cu_mount_t)); - last = last->next; - } - last->dir = sstrdup(mnt->mnt_dir); - last->spec_device = sstrdup(mnt->mnt_fsname); - last->device = device; - last->type = sstrdup(mnt->mnt_type); - last->options = sstrdup(mnt->mnt_opts); - last->next = NULL; - } /* for(p = mntlist; p; p = p->next) */ - - return(last); + } + + for (struct tabmntent *p = mntlist; p; p = p->next) { + char *loop = NULL, *device = NULL; + + mnt = p->ment; + loop = cu_mount_getoptionvalue(mnt->mnt_opts, "loop="); + if (loop == NULL) { /* no loop= mount */ + device = get_device_name(mnt->mnt_fsname); + if (device == NULL) { + DEBUG("utils_mount: can't get devicename for fs (%s) %s (%s)" + ": ignored", + mnt->mnt_type, mnt->mnt_dir, mnt->mnt_fsname); + continue; + } + } else { + device = loop; + } + if (*list == NULL) { + *list = (cu_mount_t *)smalloc(sizeof(cu_mount_t)); + last = *list; + } else { + while (last->next != NULL) { /* is last really last? */ + last = last->next; + } + last->next = (cu_mount_t *)smalloc(sizeof(cu_mount_t)); + last = last->next; + } + last->dir = sstrdup(mnt->mnt_dir); + last->spec_device = sstrdup(mnt->mnt_fsname); + last->device = device; + last->type = sstrdup(mnt->mnt_type); + last->options = sstrdup(mnt->mnt_opts); + last->next = NULL; + } /* for(p = mntlist; p; p = p->next) */ + + return (last); } /* cu_mount_t *cu_mount_listmntent(void) */ /* #endif HAVE_LISTMNTENT */ /* 4.4BSD and Mac OS X (getfsstat) or NetBSD (getvfsstat) */ #elif HAVE_GETVFSSTAT || HAVE_GETFSSTAT -static cu_mount_t *cu_mount_getfsstat (void) -{ +static cu_mount_t *cu_mount_getfsstat(void) { #if HAVE_GETFSSTAT -# define STRUCT_STATFS struct statfs -# define CMD_STATFS getfsstat -# define FLAGS_STATFS MNT_NOWAIT +#define STRUCT_STATFS struct statfs +#define CMD_STATFS getfsstat +#define FLAGS_STATFS MNT_NOWAIT /* #endif HAVE_GETFSSTAT */ #elif HAVE_GETVFSSTAT -# define STRUCT_STATFS struct statvfs -# define CMD_STATFS getvfsstat -# define FLAGS_STATFS ST_NOWAIT +#define STRUCT_STATFS struct statvfs +#define CMD_STATFS getvfsstat +#define FLAGS_STATFS ST_NOWAIT #endif /* HAVE_GETVFSSTAT */ - int bufsize; - STRUCT_STATFS *buf; + int bufsize; + STRUCT_STATFS *buf; - int num; + int num; - cu_mount_t *first = NULL; - cu_mount_t *last = NULL; - cu_mount_t *new = NULL; + cu_mount_t *first = NULL; + cu_mount_t *last = NULL; + cu_mount_t *new = NULL; - /* Get the number of mounted file systems */ - if ((bufsize = CMD_STATFS (NULL, 0, FLAGS_STATFS)) < 1) - { + /* Get the number of mounted file systems */ + if ((bufsize = CMD_STATFS(NULL, 0, FLAGS_STATFS)) < 1) { #if COLLECT_DEBUG - char errbuf[1024]; - DEBUG ("utils_mount: getv?fsstat failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + char errbuf[1024]; + DEBUG("utils_mount: getv?fsstat failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); #endif /* COLLECT_DEBUG */ - return (NULL); - } + return (NULL); + } - if ((buf = calloc (bufsize, sizeof (*buf))) == NULL) - return (NULL); + if ((buf = calloc(bufsize, sizeof(*buf))) == NULL) + return (NULL); - /* The bufsize needs to be passed in bytes. Really. This is not in the - * manpage.. -octo */ - if ((num = CMD_STATFS (buf, bufsize * sizeof (STRUCT_STATFS), FLAGS_STATFS)) < 1) - { + /* The bufsize needs to be passed in bytes. Really. This is not in the + * manpage.. -octo */ + if ((num = CMD_STATFS(buf, bufsize * sizeof(STRUCT_STATFS), FLAGS_STATFS)) < + 1) { #if COLLECT_DEBUG - char errbuf[1024]; - DEBUG ("utils_mount: getv?fsstat failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + char errbuf[1024]; + DEBUG("utils_mount: getv?fsstat failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); #endif /* COLLECT_DEBUG */ - free (buf); - return (NULL); - } - - for (int i = 0; i < num; i++) - { - if ((new = calloc (1, sizeof (*new))) == NULL) - break; - - /* Copy values from `struct mnttab' */ - new->dir = sstrdup (buf[i].f_mntonname); - new->spec_device = sstrdup (buf[i].f_mntfromname); - new->type = sstrdup (buf[i].f_fstypename); - new->options = NULL; - new->device = get_device_name (new->options); - new->next = NULL; - - /* Append to list */ - if (first == NULL) - { - first = new; - last = new; - } - else - { - last->next = new; - last = new; - } - } - - free (buf); - - return (first); + free(buf); + return (NULL); + } + + for (int i = 0; i < num; i++) { + if ((new = calloc(1, sizeof(*new))) == NULL) + break; + + /* Copy values from `struct mnttab' */ + new->dir = sstrdup(buf[i].f_mntonname); + new->spec_device = sstrdup(buf[i].f_mntfromname); + new->type = sstrdup(buf[i].f_fstypename); + new->options = NULL; + new->device = get_device_name(new->options); + new->next = NULL; + + /* Append to list */ + if (first == NULL) { + first = new; + last = new; + } else { + last->next = new; + last = new; + } + } + + free(buf); + + return (first); } /* #endif HAVE_GETVFSSTAT || HAVE_GETFSSTAT */ /* Solaris (SunOS 10): int getmntent(FILE *fp, struct mnttab *mp); */ #elif HAVE_TWO_GETMNTENT || HAVE_GEN_GETMNTENT || HAVE_SUN_GETMNTENT -static cu_mount_t *cu_mount_gen_getmntent (void) -{ - struct mnttab mt; - FILE *fp; - - cu_mount_t *first = NULL; - cu_mount_t *last = NULL; - cu_mount_t *new = NULL; - - DEBUG ("utils_mount: (void); COLLECTD_MNTTAB = %s", COLLECTD_MNTTAB); - - if ((fp = fopen (COLLECTD_MNTTAB, "r")) == NULL) - { - char errbuf[1024]; - ERROR ("fopen (%s): %s", COLLECTD_MNTTAB, - sstrerror (errno, errbuf, sizeof (errbuf))); - return (NULL); - } - - while (getmntent (fp, &mt) == 0) - { - if ((new = calloc (1, sizeof (*new))) == NULL) - break; - - /* Copy values from `struct mnttab' */ - new->dir = sstrdup (mt.mnt_mountp); - new->spec_device = sstrdup (mt.mnt_special); - new->type = sstrdup (mt.mnt_fstype); - new->options = sstrdup (mt.mnt_mntopts); - new->device = get_device_name (new->options); - new->next = NULL; - - /* Append to list */ - if (first == NULL) - { - first = new; - last = new; - } - else - { - last->next = new; - last = new; - } - } - - fclose (fp); - - return (first); +static cu_mount_t *cu_mount_gen_getmntent(void) { + struct mnttab mt; + FILE *fp; + + cu_mount_t *first = NULL; + cu_mount_t *last = NULL; + cu_mount_t *new = NULL; + + DEBUG("utils_mount: (void); COLLECTD_MNTTAB = %s", COLLECTD_MNTTAB); + + if ((fp = fopen(COLLECTD_MNTTAB, "r")) == NULL) { + char errbuf[1024]; + ERROR("fopen (%s): %s", COLLECTD_MNTTAB, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (NULL); + } + + while (getmntent(fp, &mt) == 0) { + if ((new = calloc(1, sizeof(*new))) == NULL) + break; + + /* Copy values from `struct mnttab' */ + new->dir = sstrdup(mt.mnt_mountp); + new->spec_device = sstrdup(mt.mnt_special); + new->type = sstrdup(mt.mnt_fstype); + new->options = sstrdup(mt.mnt_mntopts); + new->device = get_device_name(new->options); + new->next = NULL; + + /* Append to list */ + if (first == NULL) { + first = new; + last = new; + } else { + last->next = new; + last = new; + } + } + + fclose(fp); + + return (first); } /* static cu_mount_t *cu_mount_gen_getmntent (void) */ -/* #endif HAVE_TWO_GETMNTENT || HAVE_GEN_GETMNTENT || HAVE_SUN_GETMNTENT */ + /* #endif HAVE_TWO_GETMNTENT || HAVE_GEN_GETMNTENT || HAVE_SUN_GETMNTENT */ #elif HAVE_SEQ_GETMNTENT #warn "This version of `getmntent' hat not yet been implemented!" /* #endif HAVE_SEQ_GETMNTENT */ #elif HAVE_GETMNTENT_R -static cu_mount_t *cu_mount_getmntent (void) -{ - FILE *fp; - struct mntent me; - char mntbuf[1024]; - - cu_mount_t *first = NULL; - cu_mount_t *last = NULL; - cu_mount_t *new = NULL; - - DEBUG ("utils_mount: (void); COLLECTD_MNTTAB = %s", COLLECTD_MNTTAB); - - if ((fp = setmntent (COLLECTD_MNTTAB, "r")) == NULL) - { - char errbuf[1024]; - ERROR ("setmntent (%s): %s", COLLECTD_MNTTAB, - sstrerror (errno, errbuf, sizeof (errbuf))); - return (NULL); - } - - while (getmntent_r (fp, &me, mntbuf, sizeof (mntbuf) )) - { - if ((new = calloc (1, sizeof (*new))) == NULL) - break; - - /* Copy values from `struct mntent *' */ - new->dir = sstrdup (me.mnt_dir); - new->spec_device = sstrdup (me.mnt_fsname); - new->type = sstrdup (me.mnt_type); - new->options = sstrdup (me.mnt_opts); - new->device = get_device_name (new->options); - new->next = NULL; - - DEBUG ("utils_mount: new = {dir = %s, spec_device = %s, type = %s, options = %s, device = %s}", - new->dir, new->spec_device, new->type, new->options, new->device); - - /* Append to list */ - if (first == NULL) - { - first = new; - last = new; - } - else - { - last->next = new; - last = new; - } - } - - endmntent (fp); - - DEBUG ("utils_mount: return (0x%p)", (void *) first); - - return (first); +static cu_mount_t *cu_mount_getmntent(void) { + FILE *fp; + struct mntent me; + char mntbuf[1024]; + + cu_mount_t *first = NULL; + cu_mount_t *last = NULL; + cu_mount_t *new = NULL; + + DEBUG("utils_mount: (void); COLLECTD_MNTTAB = %s", COLLECTD_MNTTAB); + + if ((fp = setmntent(COLLECTD_MNTTAB, "r")) == NULL) { + char errbuf[1024]; + ERROR("setmntent (%s): %s", COLLECTD_MNTTAB, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (NULL); + } + + while (getmntent_r(fp, &me, mntbuf, sizeof(mntbuf))) { + if ((new = calloc(1, sizeof(*new))) == NULL) + break; + + /* Copy values from `struct mntent *' */ + new->dir = sstrdup(me.mnt_dir); + new->spec_device = sstrdup(me.mnt_fsname); + new->type = sstrdup(me.mnt_type); + new->options = sstrdup(me.mnt_opts); + new->device = get_device_name(new->options); + new->next = NULL; + + DEBUG("utils_mount: new = {dir = %s, spec_device = %s, type = %s, options " + "= %s, device = %s}", + new->dir, new->spec_device, new->type, new->options, new->device); + + /* Append to list */ + if (first == NULL) { + first = new; + last = new; + } else { + last->next = new; + last = new; + } + } + + endmntent(fp); + + DEBUG("utils_mount: return (0x%p)", (void *)first); + + return (first); } /* HAVE_GETMNTENT_R */ #elif HAVE_ONE_GETMNTENT -static cu_mount_t *cu_mount_getmntent (void) -{ - FILE *fp; - struct mntent *me; - - cu_mount_t *first = NULL; - cu_mount_t *last = NULL; - cu_mount_t *new = NULL; - - DEBUG ("utils_mount: (void); COLLECTD_MNTTAB = %s", COLLECTD_MNTTAB); - - if ((fp = setmntent (COLLECTD_MNTTAB, "r")) == NULL) - { - char errbuf[1024]; - ERROR ("setmntent (%s): %s", COLLECTD_MNTTAB, - sstrerror (errno, errbuf, sizeof (errbuf))); - return (NULL); - } - - while ((me = getmntent (fp)) != NULL) - { - if ((new = calloc (1, sizeof (*new))) == NULL) - break; - - /* Copy values from `struct mntent *' */ - new->dir = sstrdup (me->mnt_dir); - new->spec_device = sstrdup (me->mnt_fsname); - new->type = sstrdup (me->mnt_type); - new->options = sstrdup (me->mnt_opts); - new->device = get_device_name (new->options); - new->next = NULL; - - DEBUG ("utils_mount: new = {dir = %s, spec_device = %s, type = %s, options = %s, device = %s}", - new->dir, new->spec_device, new->type, new->options, new->device); - - /* Append to list */ - if (first == NULL) - { - first = new; - last = new; - } - else - { - last->next = new; - last = new; - } - } - - endmntent (fp); - - DEBUG ("utils_mount: return (0x%p)", (void *) first); - - return (first); +static cu_mount_t *cu_mount_getmntent(void) { + FILE *fp; + struct mntent *me; + + cu_mount_t *first = NULL; + cu_mount_t *last = NULL; + cu_mount_t *new = NULL; + + DEBUG("utils_mount: (void); COLLECTD_MNTTAB = %s", COLLECTD_MNTTAB); + + if ((fp = setmntent(COLLECTD_MNTTAB, "r")) == NULL) { + char errbuf[1024]; + ERROR("setmntent (%s): %s", COLLECTD_MNTTAB, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (NULL); + } + + while ((me = getmntent(fp)) != NULL) { + if ((new = calloc(1, sizeof(*new))) == NULL) + break; + + /* Copy values from `struct mntent *' */ + new->dir = sstrdup(me->mnt_dir); + new->spec_device = sstrdup(me->mnt_fsname); + new->type = sstrdup(me->mnt_type); + new->options = sstrdup(me->mnt_opts); + new->device = get_device_name(new->options); + new->next = NULL; + + DEBUG("utils_mount: new = {dir = %s, spec_device = %s, type = %s, options " + "= %s, device = %s}", + new->dir, new->spec_device, new->type, new->options, new->device); + + /* Append to list */ + if (first == NULL) { + first = new; + last = new; + } else { + last->next = new; + last = new; + } + } + + endmntent(fp); + + DEBUG("utils_mount: return (0x%p)", (void *)first); + + return (first); } #endif /* HAVE_ONE_GETMNTENT */ @@ -688,145 +641,136 @@ static cu_mount_t *cu_mount_getmntent (void) /* *** *** *** *** *** *** public functions *** *** *** *** *** *** */ /* *** *** *** ******************************************** *** *** *** */ -cu_mount_t *cu_mount_getlist(cu_mount_t **list) -{ - cu_mount_t *new; - cu_mount_t *first = NULL; - cu_mount_t *last = NULL; +cu_mount_t *cu_mount_getlist(cu_mount_t **list) { + cu_mount_t *new; + cu_mount_t *first = NULL; + cu_mount_t *last = NULL; - if (list == NULL) - return (NULL); + if (list == NULL) + return (NULL); - if (*list != NULL) - { - first = *list; - last = first; - while (last->next != NULL) - last = last->next; - } + if (*list != NULL) { + first = *list; + last = first; + while (last->next != NULL) + last = last->next; + } #if HAVE_LISTMNTENT && 0 - new = cu_mount_listmntent (); + new = cu_mount_listmntent(); #elif HAVE_GETVFSSTAT || HAVE_GETFSSTAT - new = cu_mount_getfsstat (); + new = cu_mount_getfsstat(); #elif HAVE_TWO_GETMNTENT || HAVE_GEN_GETMNTENT || HAVE_SUN_GETMNTENT - new = cu_mount_gen_getmntent (); + new = cu_mount_gen_getmntent(); #elif HAVE_SEQ_GETMNTENT -# error "This version of `getmntent' hat not yet been implemented!" +#error "This version of `getmntent' hat not yet been implemented!" #elif HAVE_ONE_GETMNTENT - new = cu_mount_getmntent (); + new = cu_mount_getmntent(); #else -# error "Could not determine how to find mountpoints." +#error "Could not determine how to find mountpoints." #endif - if (first != NULL) - { - last->next = new; - } - else - { - first = new; - last = new; - *list = first; - } - - while ((last != NULL) && (last->next != NULL)) - last = last->next; - - return (last); + if (first != NULL) { + last->next = new; + } else { + first = new; + last = new; + *list = first; + } + + while ((last != NULL) && (last->next != NULL)) + last = last->next; + + return (last); } /* cu_mount_t *cu_mount_getlist(cu_mount_t **list) */ -void cu_mount_freelist (cu_mount_t *list) -{ - cu_mount_t *next; - - for (cu_mount_t *this = list; this != NULL; this = next) - { - next = this->next; - - sfree (this->dir); - sfree (this->spec_device); - sfree (this->device); - sfree (this->type); - sfree (this->options); - sfree (this); - } +void cu_mount_freelist(cu_mount_t *list) { + cu_mount_t *next; + + for (cu_mount_t *this = list; this != NULL; this = next) { + next = this->next; + + sfree(this->dir); + sfree(this->spec_device); + sfree(this->device); + sfree(this->type); + sfree(this->options); + sfree(this); + } } /* void cu_mount_freelist(cu_mount_t *list) */ -char * -cu_mount_checkoption(char *line, const char *keyword, int full) -{ - char *line2, *l2, *p1, *p2; - int l; - - if(line == NULL || keyword == NULL) { - return NULL; - } - - if(full != 0) { - full = 1; - } - - line2 = sstrdup(line); - l2 = line2; - while(*l2 != '\0') { - if(*l2 == ',') { - *l2 = '\0'; - } - l2++; - } - - l = strlen(keyword); - p1 = line - 1; - p2 = strchr(line, ','); - do { - if(strncmp(line2+(p1-line)+1, keyword, l+full) == 0) { - free(line2); - return p1+1; - } - p1 = p2; - if(p1 != NULL) { - p2 = strchr(p1+1, ','); - } - } while(p1 != NULL); - - free(line2); - return NULL; +char *cu_mount_checkoption(char *line, const char *keyword, int full) { + char *line2, *l2, *p1, *p2; + int l; + + if (line == NULL || keyword == NULL) { + return NULL; + } + + if (full != 0) { + full = 1; + } + + line2 = sstrdup(line); + l2 = line2; + while (*l2 != '\0') { + if (*l2 == ',') { + *l2 = '\0'; + } + l2++; + } + + l = strlen(keyword); + p1 = line - 1; + p2 = strchr(line, ','); + do { + if (strncmp(line2 + (p1 - line) + 1, keyword, l + full) == 0) { + free(line2); + return p1 + 1; + } + p1 = p2; + if (p1 != NULL) { + p2 = strchr(p1 + 1, ','); + } + } while (p1 != NULL); + + free(line2); + return NULL; } /* char *cu_mount_checkoption(char *line, char *keyword, int full) */ -char * -cu_mount_getoptionvalue(char *line, const char *keyword) -{ - char *r; - - r = cu_mount_checkoption(line, keyword, 0); - if(r != NULL) { - char *p; - r += strlen(keyword); - p = strchr(r, ','); - if(p == NULL) { - return sstrdup(r); - } else { - char *m; - if((p-r) == 1) { - return NULL; - } - m = smalloc(p-r+1); - sstrncpy(m, r, p-r+1); - return m; - } - } - return r; +char *cu_mount_getoptionvalue(char *line, const char *keyword) { + char *r; + + r = cu_mount_checkoption(line, keyword, 0); + if (r != NULL) { + char *p; + r += strlen(keyword); + p = strchr(r, ','); + if (p == NULL) { + return sstrdup(r); + } else { + char *m; + if ((p - r) == 1) { + return NULL; + } + m = smalloc(p - r + 1); + sstrncpy(m, r, p - r + 1); + return m; + } + } + return r; } /* char *cu_mount_getoptionvalue(char *line, const char *keyword) */ -int -cu_mount_type(const char *type) -{ - if(strcmp(type, "ext3") == 0) return CUMT_EXT3; - if(strcmp(type, "ext2") == 0) return CUMT_EXT2; - if(strcmp(type, "ufs") == 0) return CUMT_UFS; - if(strcmp(type, "vxfs") == 0) return CUMT_VXFS; - if(strcmp(type, "zfs") == 0) return CUMT_ZFS; - return CUMT_UNKNOWN; +int cu_mount_type(const char *type) { + if (strcmp(type, "ext3") == 0) + return CUMT_EXT3; + if (strcmp(type, "ext2") == 0) + return CUMT_EXT2; + if (strcmp(type, "ufs") == 0) + return CUMT_UFS; + if (strcmp(type, "vxfs") == 0) + return CUMT_VXFS; + if (strcmp(type, "zfs") == 0) + return CUMT_ZFS; + return CUMT_UNKNOWN; } /* int cu_mount_type(const char *type) */ - diff --git a/src/utils_mount_test.c b/src/utils_mount_test.c index c084debe..695038dd 100644 --- a/src/utils_mount_test.c +++ b/src/utils_mount_test.c @@ -34,79 +34,76 @@ kstat_ctl_t *kc; #endif /* HAVE_LIBKSTAT */ -DEF_TEST(cu_mount_checkoption) -{ +DEF_TEST(cu_mount_checkoption) { char line_opts[] = "foo=one,bar=two,qux=three"; - char *foo = strstr (line_opts, "foo"); - char *bar = strstr (line_opts, "bar"); - char *qux = strstr (line_opts, "qux"); + char *foo = strstr(line_opts, "foo"); + char *bar = strstr(line_opts, "bar"); + char *qux = strstr(line_opts, "qux"); char line_bool[] = "one,two,three"; - char *one = strstr (line_bool, "one"); - char *two = strstr (line_bool, "two"); - char *three = strstr (line_bool, "three"); + char *one = strstr(line_bool, "one"); + char *two = strstr(line_bool, "two"); + char *three = strstr(line_bool, "three"); /* Normal operation */ - OK (foo == cu_mount_checkoption (line_opts, "foo", 0)); - OK (bar == cu_mount_checkoption (line_opts, "bar", 0)); - OK (qux == cu_mount_checkoption (line_opts, "qux", 0)); - OK (NULL == cu_mount_checkoption (line_opts, "unknown", 0)); + OK(foo == cu_mount_checkoption(line_opts, "foo", 0)); + OK(bar == cu_mount_checkoption(line_opts, "bar", 0)); + OK(qux == cu_mount_checkoption(line_opts, "qux", 0)); + OK(NULL == cu_mount_checkoption(line_opts, "unknown", 0)); - OK (one == cu_mount_checkoption (line_bool, "one", 0)); - OK (two == cu_mount_checkoption (line_bool, "two", 0)); - OK (three == cu_mount_checkoption (line_bool, "three", 0)); - OK (NULL == cu_mount_checkoption (line_bool, "four", 0)); + OK(one == cu_mount_checkoption(line_bool, "one", 0)); + OK(two == cu_mount_checkoption(line_bool, "two", 0)); + OK(three == cu_mount_checkoption(line_bool, "three", 0)); + OK(NULL == cu_mount_checkoption(line_bool, "four", 0)); /* Shorter and longer parts */ - OK (foo == cu_mount_checkoption (line_opts, "fo", 0)); - OK (bar == cu_mount_checkoption (line_opts, "bar=", 0)); - OK (qux == cu_mount_checkoption (line_opts, "qux=thr", 0)); + OK(foo == cu_mount_checkoption(line_opts, "fo", 0)); + OK(bar == cu_mount_checkoption(line_opts, "bar=", 0)); + OK(qux == cu_mount_checkoption(line_opts, "qux=thr", 0)); - OK (one == cu_mount_checkoption (line_bool, "o", 0)); - OK (two == cu_mount_checkoption (line_bool, "tw", 0)); - OK (three == cu_mount_checkoption (line_bool, "thr", 0)); + OK(one == cu_mount_checkoption(line_bool, "o", 0)); + OK(two == cu_mount_checkoption(line_bool, "tw", 0)); + OK(three == cu_mount_checkoption(line_bool, "thr", 0)); /* "full" flag */ - OK (one == cu_mount_checkoption (line_bool, "one", 1)); - OK (two == cu_mount_checkoption (line_bool, "two", 1)); - OK (three == cu_mount_checkoption (line_bool, "three", 1)); - OK (NULL == cu_mount_checkoption (line_bool, "four", 1)); + OK(one == cu_mount_checkoption(line_bool, "one", 1)); + OK(two == cu_mount_checkoption(line_bool, "two", 1)); + OK(three == cu_mount_checkoption(line_bool, "three", 1)); + OK(NULL == cu_mount_checkoption(line_bool, "four", 1)); - OK (NULL == cu_mount_checkoption (line_bool, "o", 1)); - OK (NULL == cu_mount_checkoption (line_bool, "tw", 1)); - OK (NULL == cu_mount_checkoption (line_bool, "thr", 1)); + OK(NULL == cu_mount_checkoption(line_bool, "o", 1)); + OK(NULL == cu_mount_checkoption(line_bool, "tw", 1)); + OK(NULL == cu_mount_checkoption(line_bool, "thr", 1)); return (0); } -DEF_TEST(cu_mount_getoptionvalue) -{ +DEF_TEST(cu_mount_getoptionvalue) { char line_opts[] = "foo=one,bar=two,qux=three"; char line_bool[] = "one,two,three"; char *v; - EXPECT_EQ_STR ("one", v = cu_mount_getoptionvalue (line_opts, "foo=")); - sfree (v); - EXPECT_EQ_STR ("two", v = cu_mount_getoptionvalue (line_opts, "bar=")); - sfree (v); - EXPECT_EQ_STR ("three", v = cu_mount_getoptionvalue (line_opts, "qux=")); - sfree (v); - OK (NULL == (v = cu_mount_getoptionvalue (line_opts, "unknown="))); - sfree (v); - - EXPECT_EQ_STR ("", v = cu_mount_getoptionvalue (line_bool, "one")); - sfree (v); - EXPECT_EQ_STR ("", v = cu_mount_getoptionvalue (line_bool, "two")); - sfree (v); - EXPECT_EQ_STR ("", v = cu_mount_getoptionvalue (line_bool, "three")); - sfree (v); - OK (NULL == (v = cu_mount_getoptionvalue (line_bool, "four"))); - sfree (v); + EXPECT_EQ_STR("one", v = cu_mount_getoptionvalue(line_opts, "foo=")); + sfree(v); + EXPECT_EQ_STR("two", v = cu_mount_getoptionvalue(line_opts, "bar=")); + sfree(v); + EXPECT_EQ_STR("three", v = cu_mount_getoptionvalue(line_opts, "qux=")); + sfree(v); + OK(NULL == (v = cu_mount_getoptionvalue(line_opts, "unknown="))); + sfree(v); + + EXPECT_EQ_STR("", v = cu_mount_getoptionvalue(line_bool, "one")); + sfree(v); + EXPECT_EQ_STR("", v = cu_mount_getoptionvalue(line_bool, "two")); + sfree(v); + EXPECT_EQ_STR("", v = cu_mount_getoptionvalue(line_bool, "three")); + sfree(v); + OK(NULL == (v = cu_mount_getoptionvalue(line_bool, "four"))); + sfree(v); return (0); } -int main (void) -{ +int main(void) { RUN_TEST(cu_mount_checkoption); RUN_TEST(cu_mount_getoptionvalue); diff --git a/src/utils_parse_option.c b/src/utils_parse_option.c index 3652a666..ba37f03e 100644 --- a/src/utils_parse_option.c +++ b/src/utils_parse_option.c @@ -28,8 +28,7 @@ #include "utils_parse_option.h" -int parse_string (char **ret_buffer, char **ret_string) -{ +int parse_string(char **ret_buffer, char **ret_string) { char *buffer; char *string; @@ -37,14 +36,13 @@ int parse_string (char **ret_buffer, char **ret_string) /* Eat up leading spaces. */ string = buffer; - while (isspace ((int) *string)) + while (isspace((int)*string)) string++; if (*string == 0) return (1); /* A quoted string */ - if (*string == '"') - { + if (*string == '"') { char *dst; string++; @@ -53,11 +51,9 @@ int parse_string (char **ret_buffer, char **ret_string) dst = string; buffer = string; - while ((*buffer != '"') && (*buffer != 0)) - { + while ((*buffer != '"') && (*buffer != 0)) { /* Un-escape backslashes */ - if (*buffer == '\\') - { + if (*buffer == '\\') { buffer++; /* Catch a backslash at the end of buffer */ if (*buffer == 0) @@ -77,23 +73,21 @@ int parse_string (char **ret_buffer, char **ret_string) buffer++; /* Check for trailing spaces. */ - if ((*buffer != 0) && !isspace ((int) *buffer)) + if ((*buffer != 0) && !isspace((int)*buffer)) return (-1); - } - else /* an unquoted string */ + } else /* an unquoted string */ { buffer = string; - while ((*buffer != 0) && !isspace ((int) *buffer)) + while ((*buffer != 0) && !isspace((int)*buffer)) buffer++; - if (*buffer != 0) - { + if (*buffer != 0) { *buffer = 0; buffer++; } } /* Eat up trailing spaces */ - while (isspace ((int) *buffer)) + while (isspace((int)*buffer)) buffer++; *ret_buffer = buffer; @@ -113,8 +107,7 @@ int parse_string (char **ret_buffer, char **ret_string) * However, if the value does *not* contain a space character, you can skip * the quotes. */ -int parse_option (char **ret_buffer, char **ret_key, char **ret_value) -{ +int parse_option(char **ret_buffer, char **ret_key, char **ret_value) { char *buffer; char *key; char *value; @@ -124,24 +117,24 @@ int parse_option (char **ret_buffer, char **ret_key, char **ret_value) /* Eat up leading spaces */ key = buffer; - while (isspace ((int) *key)) + while (isspace((int)*key)) key++; if (*key == 0) return (1); /* Look for the equal sign */ buffer = key; - while (isalnum ((int) *buffer) || *buffer == '_' || *buffer == ':') + while (isalnum((int)*buffer) || *buffer == '_' || *buffer == ':') buffer++; if ((*buffer != '=') || (buffer == key)) return (1); *buffer = 0; buffer++; /* Empty values must be written as "" */ - if (isspace ((int) *buffer) || (*buffer == 0)) + if (isspace((int)*buffer) || (*buffer == 0)) return (-1); - status = parse_string (&buffer, &value); + status = parse_string(&buffer, &value); if (status != 0) return (-1); diff --git a/src/utils_parse_option.h b/src/utils_parse_option.h index 885a6a33..a638e694 100644 --- a/src/utils_parse_option.h +++ b/src/utils_parse_option.h @@ -27,8 +27,8 @@ #ifndef UTILS_PARSE_OPTION #define UTILS_PARSE_OPTION 1 -int parse_string (char **ret_buffer, char **ret_string); -int parse_option (char **ret_buffer, char **ret_key, char **ret_value); +int parse_string(char **ret_buffer, char **ret_string); +int parse_option(char **ret_buffer, char **ret_key, char **ret_value); #endif /* UTILS_PARSE_OPTION */ diff --git a/src/utils_rrdcreate.c b/src/utils_rrdcreate.c index 884de8f9..750d2656 100644 --- a/src/utils_rrdcreate.c +++ b/src/utils_rrdcreate.c @@ -32,8 +32,7 @@ #include #include -struct srrd_create_args_s -{ +struct srrd_create_args_s { char *filename; unsigned long pdp_step; time_t last_up; @@ -44,8 +43,7 @@ typedef struct srrd_create_args_s srrd_create_args_t; struct async_create_file_s; typedef struct async_create_file_s async_create_file_t; -struct async_create_file_s -{ +struct async_create_file_s { char *filename; async_create_file_t *next; }; @@ -53,23 +51,11 @@ struct async_create_file_s /* * Private variables */ -static int rra_timespans[] = -{ - 3600, - 86400, - 604800, - 2678400, - 31622400 -}; -static int rra_timespans_num = STATIC_ARRAY_SIZE (rra_timespans); +static int rra_timespans[] = {3600, 86400, 604800, 2678400, 31622400}; +static int rra_timespans_num = STATIC_ARRAY_SIZE(rra_timespans); -static const char *const rra_types[] = -{ - "AVERAGE", - "MIN", - "MAX" -}; -static int rra_types_num = STATIC_ARRAY_SIZE (rra_types); +static const char *const rra_types[] = {"AVERAGE", "MIN", "MAX"}; +static int rra_types_num = STATIC_ARRAY_SIZE(rra_types); #if !defined(HAVE_THREADSAFE_LIBRRD) static pthread_mutex_t librrd_lock = PTHREAD_MUTEX_INITIALIZER; @@ -81,40 +67,36 @@ static pthread_mutex_t async_creation_lock = PTHREAD_MUTEX_INITIALIZER; /* * Private functions */ -static void rra_free (int rra_num, char **rra_def) /* {{{ */ +static void rra_free(int rra_num, char **rra_def) /* {{{ */ { - for (int i = 0; i < rra_num; i++) - { - sfree (rra_def[i]); + for (int i = 0; i < rra_num; i++) { + sfree(rra_def[i]); } - sfree (rra_def); + sfree(rra_def); } /* }}} void rra_free */ -static void srrd_create_args_destroy (srrd_create_args_t *args) -{ +static void srrd_create_args_destroy(srrd_create_args_t *args) { if (args == NULL) return; - sfree (args->filename); - if (args->argv != NULL) - { + sfree(args->filename); + if (args->argv != NULL) { for (int i = 0; i < args->argc; i++) - sfree (args->argv[i]); - sfree (args->argv); + sfree(args->argv[i]); + sfree(args->argv); } - sfree (args); + sfree(args); } /* void srrd_create_args_destroy */ -static srrd_create_args_t *srrd_create_args_create (const char *filename, - unsigned long pdp_step, time_t last_up, - int argc, const char **argv) -{ +static srrd_create_args_t *srrd_create_args_create(const char *filename, + unsigned long pdp_step, + time_t last_up, int argc, + const char **argv) { srrd_create_args_t *args; - args = calloc (1, sizeof (*args)); - if (args == NULL) - { - ERROR ("srrd_create_args_create: calloc failed."); + args = calloc(1, sizeof(*args)); + if (args == NULL) { + ERROR("srrd_create_args_create: calloc failed."); return (NULL); } args->filename = NULL; @@ -122,33 +104,29 @@ static srrd_create_args_t *srrd_create_args_create (const char *filename, args->last_up = last_up; args->argv = NULL; - args->filename = strdup (filename); - if (args->filename == NULL) - { - ERROR ("srrd_create_args_create: strdup failed."); - srrd_create_args_destroy (args); + args->filename = strdup(filename); + if (args->filename == NULL) { + ERROR("srrd_create_args_create: strdup failed."); + srrd_create_args_destroy(args); return (NULL); } - args->argv = calloc ((size_t) (argc + 1), sizeof (*args->argv)); - if (args->argv == NULL) - { - ERROR ("srrd_create_args_create: calloc failed."); - srrd_create_args_destroy (args); + args->argv = calloc((size_t)(argc + 1), sizeof(*args->argv)); + if (args->argv == NULL) { + ERROR("srrd_create_args_create: calloc failed."); + srrd_create_args_destroy(args); return (NULL); } - for (args->argc = 0; args->argc < argc; args->argc++) - { - args->argv[args->argc] = strdup (argv[args->argc]); - if (args->argv[args->argc] == NULL) - { - ERROR ("srrd_create_args_create: strdup failed."); - srrd_create_args_destroy (args); + for (args->argc = 0; args->argc < argc; args->argc++) { + args->argv[args->argc] = strdup(argv[args->argc]); + if (args->argv[args->argc] == NULL) { + ERROR("srrd_create_args_create: strdup failed."); + srrd_create_args_destroy(args); return (NULL); } } - assert (args->argc == argc); + assert(args->argc == argc); args->argv[args->argc] = NULL; return (args); @@ -157,14 +135,13 @@ static srrd_create_args_t *srrd_create_args_create (const char *filename, /* * * * * * * * * * * WARNING: Magic * * * * * * * * * * */ -static int rra_get (char ***ret, const value_list_t *vl, /* {{{ */ - const rrdcreate_config_t *cfg) -{ +static int rra_get(char ***ret, const value_list_t *vl, /* {{{ */ + const rrdcreate_config_t *cfg) { char **rra_def; int rra_num; int *rts; - int rts_num; + int rts_num; int rra_max; @@ -175,14 +152,12 @@ static int rra_get (char ***ret, const value_list_t *vl, /* {{{ */ * interval of the value-list. */ int ss; - if (cfg->rrarows <= 0) - { + if (cfg->rrarows <= 0) { *ret = NULL; return (-1); } - if ((cfg->xff < 0) || (cfg->xff >= 1.0)) - { + if ((cfg->xff < 0) || (cfg->xff >= 1.0)) { *ret = NULL; return (-1); } @@ -190,35 +165,30 @@ static int rra_get (char ***ret, const value_list_t *vl, /* {{{ */ if (cfg->stepsize > 0) ss = cfg->stepsize; else - ss = (int) CDTIME_T_TO_TIME_T (vl->interval); - if (ss <= 0) - { + ss = (int)CDTIME_T_TO_TIME_T(vl->interval); + if (ss <= 0) { *ret = NULL; return (-1); } /* Use the configured timespans or fall back to the built-in defaults */ - if (cfg->timespans_num != 0) - { + if (cfg->timespans_num != 0) { rts = cfg->timespans; rts_num = cfg->timespans_num; - } - else - { + } else { rts = rra_timespans; rts_num = rra_timespans_num; } rra_max = rts_num * rra_types_num; - assert (rra_max > 0); + assert(rra_max > 0); - if ((rra_def = calloc (rra_max + 1, sizeof (*rra_def))) == NULL) + if ((rra_def = calloc(rra_max + 1, sizeof(*rra_def))) == NULL) return (-1); rra_num = 0; cdp_len = 0; - for (int i = 0; i < rts_num; i++) - { + for (int i = 0; i < rts_num; i++) { int span = rts[i]; if ((span / ss) < cfg->rrarows) @@ -227,36 +197,31 @@ static int rra_get (char ***ret, const value_list_t *vl, /* {{{ */ if (cdp_len == 0) cdp_len = 1; else - cdp_len = (int) floor (((double) span) - / ((double) (cfg->rrarows * ss))); + cdp_len = (int)floor(((double)span) / ((double)(cfg->rrarows * ss))); - cdp_num = (int) ceil (((double) span) - / ((double) (cdp_len * ss))); + cdp_num = (int)ceil(((double)span) / ((double)(cdp_len * ss))); - for (int j = 0; j < rra_types_num; j++) - { + for (int j = 0; j < rra_types_num; j++) { char buffer[128]; int status; if (rra_num >= rra_max) break; - status = ssnprintf (buffer, sizeof (buffer), "RRA:%s:%.10f:%u:%u", - rra_types[j], cfg->xff, cdp_len, cdp_num); + status = ssnprintf(buffer, sizeof(buffer), "RRA:%s:%.10f:%u:%u", + rra_types[j], cfg->xff, cdp_len, cdp_num); - if ((status < 0) || ((size_t) status >= sizeof (buffer))) - { - ERROR ("rra_get: Buffer would have been truncated."); + if ((status < 0) || ((size_t)status >= sizeof(buffer))) { + ERROR("rra_get: Buffer would have been truncated."); continue; } - rra_def[rra_num++] = sstrdup (buffer); + rra_def[rra_num++] = sstrdup(buffer); } } - if (rra_num <= 0) - { - sfree (rra_def); + if (rra_num <= 0) { + sfree(rra_def); return (0); } @@ -264,18 +229,17 @@ static int rra_get (char ***ret, const value_list_t *vl, /* {{{ */ return (rra_num); } /* }}} int rra_get */ -static void ds_free (int ds_num, char **ds_def) /* {{{ */ +static void ds_free(int ds_num, char **ds_def) /* {{{ */ { for (int i = 0; i < ds_num; i++) if (ds_def[i] != NULL) - free (ds_def[i]); - free (ds_def); + free(ds_def[i]); + free(ds_def); } /* }}} void ds_free */ -static int ds_get (char ***ret, /* {{{ */ - const data_set_t *ds, const value_list_t *vl, - const rrdcreate_config_t *cfg) -{ +static int ds_get(char ***ret, /* {{{ */ + const data_set_t *ds, const value_list_t *vl, + const rrdcreate_config_t *cfg) { char **ds_def; size_t ds_num; @@ -283,19 +247,17 @@ static int ds_get (char ***ret, /* {{{ */ char max[32]; char buffer[128]; - assert (ds->ds_num > 0); + assert(ds->ds_num > 0); - ds_def = calloc (ds->ds_num, sizeof (*ds_def)); - if (ds_def == NULL) - { + ds_def = calloc(ds->ds_num, sizeof(*ds_def)); + if (ds_def == NULL) { char errbuf[1024]; - ERROR ("rrdtool plugin: calloc failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("rrdtool plugin: calloc failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } - for (ds_num = 0; ds_num < ds->ds_num; ds_num++) - { + for (ds_num = 0; ds_num < ds->ds_num; ds_num++) { data_source_t *d = ds->ds + ds_num; const char *type; int status; @@ -310,49 +272,39 @@ static int ds_get (char ***ret, /* {{{ */ type = "DERIVE"; else if (d->type == DS_TYPE_ABSOLUTE) type = "ABSOLUTE"; - else - { - ERROR ("rrdtool plugin: Unknown DS type: %i", - d->type); + else { + ERROR("rrdtool plugin: Unknown DS type: %i", d->type); break; } - if (isnan (d->min)) - { - sstrncpy (min, "U", sizeof (min)); - } - else - ssnprintf (min, sizeof (min), "%f", d->min); - - if (isnan (d->max)) - { - sstrncpy (max, "U", sizeof (max)); - } - else - ssnprintf (max, sizeof (max), "%f", d->max); - - status = ssnprintf (buffer, sizeof (buffer), - "DS:%s:%s:%i:%s:%s", - d->name, type, - (cfg->heartbeat > 0) - ? cfg->heartbeat - : (int) CDTIME_T_TO_TIME_T (2 * vl->interval), - min, max); - if ((status < 1) || ((size_t) status >= sizeof (buffer))) + if (isnan(d->min)) { + sstrncpy(min, "U", sizeof(min)); + } else + ssnprintf(min, sizeof(min), "%f", d->min); + + if (isnan(d->max)) { + sstrncpy(max, "U", sizeof(max)); + } else + ssnprintf(max, sizeof(max), "%f", d->max); + + status = ssnprintf(buffer, sizeof(buffer), "DS:%s:%s:%i:%s:%s", d->name, + type, (cfg->heartbeat > 0) + ? cfg->heartbeat + : (int)CDTIME_T_TO_TIME_T(2 * vl->interval), + min, max); + if ((status < 1) || ((size_t)status >= sizeof(buffer))) break; - ds_def[ds_num] = sstrdup (buffer); + ds_def[ds_num] = sstrdup(buffer); } /* for ds_num = 0 .. ds->ds_num */ - if (ds_num != ds->ds_num) - { - ds_free (ds_num, ds_def); + if (ds_num != ds->ds_num) { + ds_free(ds_num, ds_def); return (-1); } - if (ds_num == 0) - { - sfree (ds_def); + if (ds_num == 0) { + sfree(ds_def); return (0); } @@ -361,10 +313,9 @@ static int ds_get (char ***ret, /* {{{ */ } /* }}} int ds_get */ #if HAVE_THREADSAFE_LIBRRD -static int srrd_create (const char *filename, /* {{{ */ - unsigned long pdp_step, time_t last_up, - int argc, const char **argv) -{ +static int srrd_create(const char *filename, /* {{{ */ + unsigned long pdp_step, time_t last_up, int argc, + const char **argv) { int status; char *filename_copy; @@ -374,36 +325,32 @@ static int srrd_create (const char *filename, /* {{{ */ /* Some versions of librrd don't have the `const' qualifier for the first * argument, so we have to copy the pointer here to avoid warnings. It sucks, * but what else can we do? :( -octo */ - filename_copy = strdup (filename); - if (filename_copy == NULL) - { - ERROR ("srrd_create: strdup failed."); + filename_copy = strdup(filename); + if (filename_copy == NULL) { + ERROR("srrd_create: strdup failed."); return (-ENOMEM); } optind = 0; /* bug in librrd? */ - rrd_clear_error (); + rrd_clear_error(); - status = rrd_create_r (filename_copy, pdp_step, last_up, - argc, (void *) argv); + status = rrd_create_r(filename_copy, pdp_step, last_up, argc, (void *)argv); - if (status != 0) - { - WARNING ("rrdtool plugin: rrd_create_r (%s) failed: %s", - filename, rrd_get_error ()); + if (status != 0) { + WARNING("rrdtool plugin: rrd_create_r (%s) failed: %s", filename, + rrd_get_error()); } - sfree (filename_copy); + sfree(filename_copy); return (status); } /* }}} int srrd_create */ /* #endif HAVE_THREADSAFE_LIBRRD */ -#else /* !HAVE_THREADSAFE_LIBRRD */ -static int srrd_create (const char *filename, /* {{{ */ - unsigned long pdp_step, time_t last_up, - int argc, const char **argv) -{ +#else /* !HAVE_THREADSAFE_LIBRRD */ +static int srrd_create(const char *filename, /* {{{ */ + unsigned long pdp_step, time_t last_up, int argc, + const char **argv) { int status; int new_argc; @@ -413,235 +360,214 @@ static int srrd_create (const char *filename, /* {{{ */ char last_up_str[16]; new_argc = 6 + argc; - new_argv = malloc ((new_argc + 1) * sizeof (*new_argv)); - if (new_argv == NULL) - { - ERROR ("rrdtool plugin: malloc failed."); + new_argv = malloc((new_argc + 1) * sizeof(*new_argv)); + if (new_argv == NULL) { + ERROR("rrdtool plugin: malloc failed."); return (-1); } if (last_up == 0) - last_up = time (NULL) - 10; + last_up = time(NULL) - 10; - ssnprintf (pdp_step_str, sizeof (pdp_step_str), "%lu", pdp_step); - ssnprintf (last_up_str, sizeof (last_up_str), "%lu", (unsigned long) last_up); + ssnprintf(pdp_step_str, sizeof(pdp_step_str), "%lu", pdp_step); + ssnprintf(last_up_str, sizeof(last_up_str), "%lu", (unsigned long)last_up); new_argv[0] = "create"; - new_argv[1] = (void *) filename; + new_argv[1] = (void *)filename; new_argv[2] = "-s"; new_argv[3] = pdp_step_str; new_argv[4] = "-b"; new_argv[5] = last_up_str; - memcpy (new_argv + 6, argv, argc * sizeof (char *)); + memcpy(new_argv + 6, argv, argc * sizeof(char *)); new_argv[new_argc] = NULL; - pthread_mutex_lock (&librrd_lock); + pthread_mutex_lock(&librrd_lock); optind = 0; /* bug in librrd? */ - rrd_clear_error (); + rrd_clear_error(); - status = rrd_create (new_argc, new_argv); - pthread_mutex_unlock (&librrd_lock); + status = rrd_create(new_argc, new_argv); + pthread_mutex_unlock(&librrd_lock); - if (status != 0) - { - WARNING ("rrdtool plugin: rrd_create (%s) failed: %s", - filename, rrd_get_error ()); + if (status != 0) { + WARNING("rrdtool plugin: rrd_create (%s) failed: %s", filename, + rrd_get_error()); } - sfree (new_argv); + sfree(new_argv); return (status); } /* }}} int srrd_create */ #endif /* !HAVE_THREADSAFE_LIBRRD */ -static int lock_file (char const *filename) /* {{{ */ +static int lock_file(char const *filename) /* {{{ */ { async_create_file_t *ptr; struct stat sb; int status; - pthread_mutex_lock (&async_creation_lock); + pthread_mutex_lock(&async_creation_lock); for (ptr = async_creation_list; ptr != NULL; ptr = ptr->next) - if (strcmp (filename, ptr->filename) == 0) + if (strcmp(filename, ptr->filename) == 0) break; - if (ptr != NULL) - { - pthread_mutex_unlock (&async_creation_lock); + if (ptr != NULL) { + pthread_mutex_unlock(&async_creation_lock); return (EEXIST); } - status = stat (filename, &sb); - if ((status == 0) || (errno != ENOENT)) - { - pthread_mutex_unlock (&async_creation_lock); + status = stat(filename, &sb); + if ((status == 0) || (errno != ENOENT)) { + pthread_mutex_unlock(&async_creation_lock); return (EEXIST); } - ptr = malloc (sizeof (*ptr)); - if (ptr == NULL) - { - pthread_mutex_unlock (&async_creation_lock); + ptr = malloc(sizeof(*ptr)); + if (ptr == NULL) { + pthread_mutex_unlock(&async_creation_lock); return (ENOMEM); } - ptr->filename = strdup (filename); - if (ptr->filename == NULL) - { - pthread_mutex_unlock (&async_creation_lock); - sfree (ptr); + ptr->filename = strdup(filename); + if (ptr->filename == NULL) { + pthread_mutex_unlock(&async_creation_lock); + sfree(ptr); return (ENOMEM); } ptr->next = async_creation_list; async_creation_list = ptr; - pthread_mutex_unlock (&async_creation_lock); + pthread_mutex_unlock(&async_creation_lock); return (0); } /* }}} int lock_file */ -static int unlock_file (char const *filename) /* {{{ */ +static int unlock_file(char const *filename) /* {{{ */ { async_create_file_t *this; async_create_file_t *prev; - - pthread_mutex_lock (&async_creation_lock); + pthread_mutex_lock(&async_creation_lock); prev = NULL; - for (this = async_creation_list; this != NULL; this = this->next) - { - if (strcmp (filename, this->filename) == 0) + for (this = async_creation_list; this != NULL; this = this->next) { + if (strcmp(filename, this->filename) == 0) break; prev = this; } - if (this == NULL) - { - pthread_mutex_unlock (&async_creation_lock); + if (this == NULL) { + pthread_mutex_unlock(&async_creation_lock); return (ENOENT); } - if (prev == NULL) - { - assert (this == async_creation_list); + if (prev == NULL) { + assert(this == async_creation_list); async_creation_list = this->next; - } - else - { - assert (this == prev->next); + } else { + assert(this == prev->next); prev->next = this->next; } this->next = NULL; - pthread_mutex_unlock (&async_creation_lock); + pthread_mutex_unlock(&async_creation_lock); - sfree (this->filename); - sfree (this); + sfree(this->filename); + sfree(this); return (0); } /* }}} int unlock_file */ -static void *srrd_create_thread (void *targs) /* {{{ */ +static void *srrd_create_thread(void *targs) /* {{{ */ { srrd_create_args_t *args = targs; char tmpfile[PATH_MAX]; int status; - status = lock_file (args->filename); - if (status != 0) - { + status = lock_file(args->filename); + if (status != 0) { if (status == EEXIST) - NOTICE ("srrd_create_thread: File \"%s\" is already being created.", - args->filename); + NOTICE("srrd_create_thread: File \"%s\" is already being created.", + args->filename); else - ERROR ("srrd_create_thread: Unable to lock file \"%s\".", - args->filename); - srrd_create_args_destroy (args); + ERROR("srrd_create_thread: Unable to lock file \"%s\".", args->filename); + srrd_create_args_destroy(args); return (0); } - ssnprintf (tmpfile, sizeof (tmpfile), "%s.async", args->filename); + ssnprintf(tmpfile, sizeof(tmpfile), "%s.async", args->filename); - status = srrd_create (tmpfile, args->pdp_step, args->last_up, - args->argc, (void *) args->argv); - if (status != 0) - { - WARNING ("srrd_create_thread: srrd_create (%s) returned status %i.", - args->filename, status); - unlink (tmpfile); - unlock_file (args->filename); - srrd_create_args_destroy (args); + status = srrd_create(tmpfile, args->pdp_step, args->last_up, args->argc, + (void *)args->argv); + if (status != 0) { + WARNING("srrd_create_thread: srrd_create (%s) returned status %i.", + args->filename, status); + unlink(tmpfile); + unlock_file(args->filename); + srrd_create_args_destroy(args); return (0); } - status = rename (tmpfile, args->filename); - if (status != 0) - { + status = rename(tmpfile, args->filename); + if (status != 0) { char errbuf[1024]; - ERROR ("srrd_create_thread: rename (\"%s\", \"%s\") failed: %s", - tmpfile, args->filename, - sstrerror (errno, errbuf, sizeof (errbuf))); - unlink (tmpfile); - unlock_file (args->filename); - srrd_create_args_destroy (args); + ERROR("srrd_create_thread: rename (\"%s\", \"%s\") failed: %s", tmpfile, + args->filename, sstrerror(errno, errbuf, sizeof(errbuf))); + unlink(tmpfile); + unlock_file(args->filename); + srrd_create_args_destroy(args); return (0); } - DEBUG ("srrd_create_thread: Successfully created RRD file \"%s\".", - args->filename); + DEBUG("srrd_create_thread: Successfully created RRD file \"%s\".", + args->filename); - unlock_file (args->filename); - srrd_create_args_destroy (args); + unlock_file(args->filename); + srrd_create_args_destroy(args); return (0); } /* }}} void *srrd_create_thread */ -static int srrd_create_async (const char *filename, /* {{{ */ - unsigned long pdp_step, time_t last_up, - int argc, const char **argv) -{ +static int srrd_create_async(const char *filename, /* {{{ */ + unsigned long pdp_step, time_t last_up, int argc, + const char **argv) { srrd_create_args_t *args; pthread_t thread; pthread_attr_t attr; int status; - DEBUG ("srrd_create_async: Creating \"%s\" in the background.", filename); + DEBUG("srrd_create_async: Creating \"%s\" in the background.", filename); - args = srrd_create_args_create (filename, pdp_step, last_up, argc, argv); + args = srrd_create_args_create(filename, pdp_step, last_up, argc, argv); if (args == NULL) return (-1); - status = pthread_attr_init (&attr); - if (status != 0) - { - srrd_create_args_destroy (args); + status = pthread_attr_init(&attr); + if (status != 0) { + srrd_create_args_destroy(args); return (-1); } status = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - if (status != 0) - { - pthread_attr_destroy (&attr); - srrd_create_args_destroy (args); + if (status != 0) { + pthread_attr_destroy(&attr); + srrd_create_args_destroy(args); return (-1); } - status = pthread_create (&thread, &attr, srrd_create_thread, args); - if (status != 0) - { + status = pthread_create(&thread, &attr, srrd_create_thread, args); + if (status != 0) { char errbuf[1024]; - ERROR ("srrd_create_async: pthread_create failed: %s", - sstrerror (status, errbuf, sizeof (errbuf))); - pthread_attr_destroy (&attr); - srrd_create_args_destroy (args); + ERROR("srrd_create_async: pthread_create failed: %s", + sstrerror(status, errbuf, sizeof(errbuf))); + pthread_attr_destroy(&attr); + srrd_create_args_destroy(args); return (status); } - pthread_attr_destroy (&attr); + pthread_attr_destroy(&attr); /* args is freed in srrd_create_thread(). */ return (0); } /* }}} int srrd_create_async */ @@ -649,10 +575,9 @@ static int srrd_create_async (const char *filename, /* {{{ */ /* * Public functions */ -int cu_rrd_create_file (const char *filename, /* {{{ */ - const data_set_t *ds, const value_list_t *vl, - const rrdcreate_config_t *cfg) -{ +int cu_rrd_create_file(const char *filename, /* {{{ */ + const data_set_t *ds, const value_list_t *vl, + const rrdcreate_config_t *cfg) { char **argv; int argc; char **rra_def = NULL; @@ -663,91 +588,79 @@ int cu_rrd_create_file (const char *filename, /* {{{ */ time_t last_up; unsigned long stepsize; - if (check_create_dir (filename)) + if (check_create_dir(filename)) return (-1); - if ((rra_num = rra_get (&rra_def, vl, cfg)) < 1) - { - ERROR ("cu_rrd_create_file failed: Could not calculate RRAs"); + if ((rra_num = rra_get(&rra_def, vl, cfg)) < 1) { + ERROR("cu_rrd_create_file failed: Could not calculate RRAs"); return (-1); } - if ((ds_num = ds_get (&ds_def, ds, vl, cfg)) < 1) - { - ERROR ("cu_rrd_create_file failed: Could not calculate DSes"); - rra_free (rra_num, rra_def); + if ((ds_num = ds_get(&ds_def, ds, vl, cfg)) < 1) { + ERROR("cu_rrd_create_file failed: Could not calculate DSes"); + rra_free(rra_num, rra_def); return (-1); } argc = ds_num + rra_num; - if ((argv = malloc (sizeof (*argv) * (argc + 1))) == NULL) - { + if ((argv = malloc(sizeof(*argv) * (argc + 1))) == NULL) { char errbuf[1024]; - ERROR ("cu_rrd_create_file failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - rra_free (rra_num, rra_def); - ds_free (ds_num, ds_def); + ERROR("cu_rrd_create_file failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + rra_free(rra_num, rra_def); + ds_free(ds_num, ds_def); return (-1); } - memcpy (argv, ds_def, ds_num * sizeof (char *)); - memcpy (argv + ds_num, rra_def, rra_num * sizeof (char *)); + memcpy(argv, ds_def, ds_num * sizeof(char *)); + memcpy(argv + ds_num, rra_def, rra_num * sizeof(char *)); argv[ds_num + rra_num] = NULL; - last_up = CDTIME_T_TO_TIME_T (vl->time); + last_up = CDTIME_T_TO_TIME_T(vl->time); if (last_up <= 0) - last_up = time (NULL); + last_up = time(NULL); last_up -= 1; if (cfg->stepsize > 0) stepsize = cfg->stepsize; else - stepsize = (unsigned long) CDTIME_T_TO_TIME_T (vl->interval); + stepsize = (unsigned long)CDTIME_T_TO_TIME_T(vl->interval); - if (cfg->async) - { - status = srrd_create_async (filename, stepsize, last_up, - argc, (const char **) argv); + if (cfg->async) { + status = srrd_create_async(filename, stepsize, last_up, argc, + (const char **)argv); if (status != 0) - WARNING ("cu_rrd_create_file: srrd_create_async (%s) " - "returned status %i.", - filename, status); - } - else /* synchronous */ + WARNING("cu_rrd_create_file: srrd_create_async (%s) " + "returned status %i.", + filename, status); + } else /* synchronous */ { - status = lock_file (filename); - if (status != 0) - { + status = lock_file(filename); + if (status != 0) { if (status == EEXIST) - NOTICE ("cu_rrd_create_file: File \"%s\" is already being created.", - filename); - else - ERROR ("cu_rrd_create_file: Unable to lock file \"%s\".", - filename); - } - else - { - status = srrd_create (filename, stepsize, last_up, - argc, (const char **) argv); - - if (status != 0) - { - WARNING ("cu_rrd_create_file: srrd_create (%s) returned status %i.", - filename, status); - } + NOTICE("cu_rrd_create_file: File \"%s\" is already being created.", + filename); else - { - DEBUG ("cu_rrd_create_file: Successfully created RRD file \"%s\".", - filename); + ERROR("cu_rrd_create_file: Unable to lock file \"%s\".", filename); + } else { + status = + srrd_create(filename, stepsize, last_up, argc, (const char **)argv); + + if (status != 0) { + WARNING("cu_rrd_create_file: srrd_create (%s) returned status %i.", + filename, status); + } else { + DEBUG("cu_rrd_create_file: Successfully created RRD file \"%s\".", + filename); } - unlock_file (filename); + unlock_file(filename); } } - free (argv); - ds_free (ds_num, ds_def); - rra_free (rra_num, rra_def); + free(argv); + ds_free(ds_num, ds_def); + rra_free(rra_num, rra_def); return (status); } /* }}} int cu_rrd_create_file */ diff --git a/src/utils_rrdcreate.h b/src/utils_rrdcreate.h index 14daadfa..9bc67aed 100644 --- a/src/utils_rrdcreate.h +++ b/src/utils_rrdcreate.h @@ -31,11 +31,10 @@ #include -struct rrdcreate_config_s -{ +struct rrdcreate_config_s { unsigned long stepsize; - int heartbeat; - int rrarows; + int heartbeat; + int rrarows; double xff; int *timespans; @@ -48,9 +47,8 @@ struct rrdcreate_config_s }; typedef struct rrdcreate_config_s rrdcreate_config_t; -int cu_rrd_create_file (const char *filename, - const data_set_t *ds, const value_list_t *vl, - const rrdcreate_config_t *cfg); +int cu_rrd_create_file(const char *filename, const data_set_t *ds, + const value_list_t *vl, const rrdcreate_config_t *cfg); #endif /* UTILS_RRDCREATE_H */ diff --git a/src/utils_vl_lookup.c b/src/utils_vl_lookup.c index 226ba0ba..8bcaf408 100644 --- a/src/utils_vl_lookup.c +++ b/src/utils_vl_lookup.c @@ -26,40 +26,38 @@ #include "collectd.h" - #include #include #include "common.h" -#include "utils_vl_lookup.h" #include "utils_avltree.h" +#include "utils_vl_lookup.h" #if HAVE_LIBKSTAT kstat_ctl_t *kc; #endif /* HAVE_LIBKSTAT */ #if BUILD_TEST -# define sstrncpy strncpy -# define plugin_log(s, ...) do { \ - printf ("[severity %i] ", s); \ - printf (__VA_ARGS__); \ - printf ("\n"); \ -} while (0) +#define sstrncpy strncpy +#define plugin_log(s, ...) \ + do { \ + printf("[severity %i] ", s); \ + printf(__VA_ARGS__); \ + printf("\n"); \ + } while (0) #endif /* * Types */ -struct part_match_s -{ +struct part_match_s { char str[DATA_MAX_NAME_LEN]; regex_t regex; _Bool is_regex; }; typedef struct part_match_s part_match_t; -struct identifier_match_s -{ +struct identifier_match_s { part_match_t host; part_match_t plugin; part_match_t plugin_instance; @@ -70,8 +68,7 @@ struct identifier_match_s }; typedef struct identifier_match_s identifier_match_t; -struct lookup_s -{ +struct lookup_s { c_avl_tree_t *by_type_tree; lookup_class_callback_t cb_user_class; @@ -82,16 +79,14 @@ struct lookup_s struct user_obj_s; typedef struct user_obj_s user_obj_t; -struct user_obj_s -{ +struct user_obj_s { void *user_obj; lookup_identifier_t ident; user_obj_t *next; }; -struct user_class_s -{ +struct user_class_s { pthread_mutex_t lock; void *user_class; identifier_match_t match; @@ -101,14 +96,12 @@ typedef struct user_class_s user_class_t; struct user_class_list_s; typedef struct user_class_list_s user_class_list_t; -struct user_class_list_s -{ +struct user_class_list_s { user_class_t entry; user_class_list_t *next; }; -struct by_type_entry_s -{ +struct by_type_entry_s { c_avl_tree_t *by_plugin_tree; /* plugin -> user_class_list_t */ user_class_list_t *wildcard_plugin_list; }; @@ -117,56 +110,50 @@ typedef struct by_type_entry_s by_type_entry_t; /* * Private functions */ -static _Bool lu_part_matches (part_match_t const *match, /* {{{ */ - char const *str) -{ - if (match->is_regex) - { +static _Bool lu_part_matches(part_match_t const *match, /* {{{ */ + char const *str) { + if (match->is_regex) { /* Short cut popular catch-all regex. */ - if (strcmp (".*", match->str) == 0) + if (strcmp(".*", match->str) == 0) return (1); - int status = regexec (&match->regex, str, - /* nmatch = */ 0, /* pmatch = */ NULL, - /* flags = */ 0); + int status = regexec(&match->regex, str, + /* nmatch = */ 0, /* pmatch = */ NULL, + /* flags = */ 0); if (status == 0) return (1); else return (0); - } - else if (strcmp (match->str, str) == 0) + } else if (strcmp(match->str, str) == 0) return (1); else return (0); } /* }}} _Bool lu_part_matches */ -static int lu_copy_ident_to_match_part (part_match_t *match_part, /* {{{ */ - char const *ident_part) -{ - size_t len = strlen (ident_part); +static int lu_copy_ident_to_match_part(part_match_t *match_part, /* {{{ */ + char const *ident_part) { + size_t len = strlen(ident_part); int status; - if ((len < 3) || (ident_part[0] != '/') || (ident_part[len - 1] != '/')) - { - sstrncpy (match_part->str, ident_part, sizeof (match_part->str)); + if ((len < 3) || (ident_part[0] != '/') || (ident_part[len - 1] != '/')) { + sstrncpy(match_part->str, ident_part, sizeof(match_part->str)); match_part->is_regex = 0; return (0); } /* Copy string without the leading slash. */ - sstrncpy (match_part->str, ident_part + 1, sizeof (match_part->str)); - assert (sizeof (match_part->str) > len); + sstrncpy(match_part->str, ident_part + 1, sizeof(match_part->str)); + assert(sizeof(match_part->str) > len); /* strip trailing slash */ match_part->str[len - 2] = 0; - status = regcomp (&match_part->regex, match_part->str, - /* flags = */ REG_EXTENDED); - if (status != 0) - { + status = regcomp(&match_part->regex, match_part->str, + /* flags = */ REG_EXTENDED); + if (status != 0) { char errbuf[1024]; - regerror (status, &match_part->regex, errbuf, sizeof (errbuf)); - ERROR ("utils_vl_lookup: Compiling regular expression \"%s\" failed: %s", - match_part->str, errbuf); + regerror(status, &match_part->regex, errbuf, sizeof(errbuf)); + ERROR("utils_vl_lookup: Compiling regular expression \"%s\" failed: %s", + match_part->str, errbuf); return (EINVAL); } match_part->is_regex = 1; @@ -174,24 +161,25 @@ static int lu_copy_ident_to_match_part (part_match_t *match_part, /* {{{ */ return (0); } /* }}} int lu_copy_ident_to_match_part */ -static int lu_copy_ident_to_match (identifier_match_t *match, /* {{{ */ - lookup_identifier_t const *ident, unsigned int group_by) -{ - memset (match, 0, sizeof (*match)); +static int lu_copy_ident_to_match(identifier_match_t *match, /* {{{ */ + lookup_identifier_t const *ident, + unsigned int group_by) { + memset(match, 0, sizeof(*match)); match->group_by = group_by; -#define COPY_FIELD(field) do { \ - int status = lu_copy_ident_to_match_part (&match->field, ident->field); \ - if (status != 0) \ - return (status); \ -} while (0) +#define COPY_FIELD(field) \ + do { \ + int status = lu_copy_ident_to_match_part(&match->field, ident->field); \ + if (status != 0) \ + return (status); \ + } while (0) - COPY_FIELD (host); - COPY_FIELD (plugin); - COPY_FIELD (plugin_instance); - COPY_FIELD (type); - COPY_FIELD (type_instance); + COPY_FIELD(host); + COPY_FIELD(plugin); + COPY_FIELD(plugin_instance); + COPY_FIELD(type); + COPY_FIELD(type_instance); #undef COPY_FIELD @@ -199,50 +187,46 @@ static int lu_copy_ident_to_match (identifier_match_t *match, /* {{{ */ } /* }}} int lu_copy_ident_to_match */ /* user_class->lock must be held when calling this function */ -static void *lu_create_user_obj (lookup_t *obj, /* {{{ */ - data_set_t const *ds, value_list_t const *vl, - user_class_t *user_class) -{ +static void *lu_create_user_obj(lookup_t *obj, /* {{{ */ + data_set_t const *ds, value_list_t const *vl, + user_class_t *user_class) { user_obj_t *user_obj; - user_obj = calloc (1, sizeof (*user_obj)); - if (user_obj == NULL) - { - ERROR ("utils_vl_lookup: calloc failed."); + user_obj = calloc(1, sizeof(*user_obj)); + if (user_obj == NULL) { + ERROR("utils_vl_lookup: calloc failed."); return (NULL); } user_obj->next = NULL; - user_obj->user_obj = obj->cb_user_class (ds, vl, user_class->user_class); - if (user_obj->user_obj == NULL) - { - sfree (user_obj); + user_obj->user_obj = obj->cb_user_class(ds, vl, user_class->user_class); + if (user_obj->user_obj == NULL) { + sfree(user_obj); WARNING("utils_vl_lookup: User-provided constructor failed."); return (NULL); } -#define COPY_FIELD(field, group_mask) do { \ - if (user_class->match.field.is_regex \ - && ((user_class->match.group_by & group_mask) == 0)) \ - sstrncpy (user_obj->ident.field, "/.*/", sizeof (user_obj->ident.field)); \ - else \ - sstrncpy (user_obj->ident.field, vl->field, sizeof (user_obj->ident.field)); \ -} while (0) - - COPY_FIELD (host, LU_GROUP_BY_HOST); - COPY_FIELD (plugin, LU_GROUP_BY_PLUGIN); - COPY_FIELD (plugin_instance, LU_GROUP_BY_PLUGIN_INSTANCE); - COPY_FIELD (type, 0); - COPY_FIELD (type_instance, LU_GROUP_BY_TYPE_INSTANCE); +#define COPY_FIELD(field, group_mask) \ + do { \ + if (user_class->match.field.is_regex && \ + ((user_class->match.group_by & group_mask) == 0)) \ + sstrncpy(user_obj->ident.field, "/.*/", sizeof(user_obj->ident.field)); \ + else \ + sstrncpy(user_obj->ident.field, vl->field, \ + sizeof(user_obj->ident.field)); \ + } while (0) + + COPY_FIELD(host, LU_GROUP_BY_HOST); + COPY_FIELD(plugin, LU_GROUP_BY_PLUGIN); + COPY_FIELD(plugin_instance, LU_GROUP_BY_PLUGIN_INSTANCE); + COPY_FIELD(type, 0); + COPY_FIELD(type_instance, LU_GROUP_BY_TYPE_INSTANCE); #undef COPY_FIELD - if (user_class->user_obj_list == NULL) - { + if (user_class->user_obj_list == NULL) { user_class->user_obj_list = user_obj; - } - else - { + } else { user_obj_t *last = user_class->user_obj_list; while (last->next != NULL) last = last->next; @@ -253,30 +237,26 @@ static void *lu_create_user_obj (lookup_t *obj, /* {{{ */ } /* }}} void *lu_create_user_obj */ /* user_class->lock must be held when calling this function */ -static user_obj_t *lu_find_user_obj (user_class_t *user_class, /* {{{ */ - value_list_t const *vl) -{ +static user_obj_t *lu_find_user_obj(user_class_t *user_class, /* {{{ */ + value_list_t const *vl) { user_obj_t *ptr; - for (ptr = user_class->user_obj_list; - ptr != NULL; - ptr = ptr->next) - { - if (user_class->match.host.is_regex - && (user_class->match.group_by & LU_GROUP_BY_HOST) - && (strcmp (vl->host, ptr->ident.host) != 0)) + for (ptr = user_class->user_obj_list; ptr != NULL; ptr = ptr->next) { + if (user_class->match.host.is_regex && + (user_class->match.group_by & LU_GROUP_BY_HOST) && + (strcmp(vl->host, ptr->ident.host) != 0)) continue; - if (user_class->match.plugin.is_regex - && (user_class->match.group_by & LU_GROUP_BY_PLUGIN) - && (strcmp (vl->plugin, ptr->ident.plugin) != 0)) + if (user_class->match.plugin.is_regex && + (user_class->match.group_by & LU_GROUP_BY_PLUGIN) && + (strcmp(vl->plugin, ptr->ident.plugin) != 0)) continue; - if (user_class->match.plugin_instance.is_regex - && (user_class->match.group_by & LU_GROUP_BY_PLUGIN_INSTANCE) - && (strcmp (vl->plugin_instance, ptr->ident.plugin_instance) != 0)) + if (user_class->match.plugin_instance.is_regex && + (user_class->match.group_by & LU_GROUP_BY_PLUGIN_INSTANCE) && + (strcmp(vl->plugin_instance, ptr->ident.plugin_instance) != 0)) continue; - if (user_class->match.type_instance.is_regex - && (user_class->match.group_by & LU_GROUP_BY_TYPE_INSTANCE) - && (strcmp (vl->type_instance, ptr->ident.type_instance) != 0)) + if (user_class->match.type_instance.is_regex && + (user_class->match.group_by & LU_GROUP_BY_TYPE_INSTANCE) && + (strcmp(vl->type_instance, ptr->ident.type_instance) != 0)) continue; return (ptr); @@ -285,42 +265,40 @@ static user_obj_t *lu_find_user_obj (user_class_t *user_class, /* {{{ */ return (NULL); } /* }}} user_obj_t *lu_find_user_obj */ -static int lu_handle_user_class (lookup_t *obj, /* {{{ */ - data_set_t const *ds, value_list_t const *vl, - user_class_t *user_class) -{ +static int lu_handle_user_class(lookup_t *obj, /* {{{ */ + data_set_t const *ds, value_list_t const *vl, + user_class_t *user_class) { user_obj_t *user_obj; int status; - assert (strcmp (vl->type, user_class->match.type.str) == 0); - assert (user_class->match.plugin.is_regex - || (strcmp (vl->plugin, user_class->match.plugin.str)) == 0); + assert(strcmp(vl->type, user_class->match.type.str) == 0); + assert(user_class->match.plugin.is_regex || + (strcmp(vl->plugin, user_class->match.plugin.str)) == 0); - if (!lu_part_matches (&user_class->match.type_instance, vl->type_instance) - || !lu_part_matches (&user_class->match.plugin_instance, vl->plugin_instance) - || !lu_part_matches (&user_class->match.plugin, vl->plugin) - || !lu_part_matches (&user_class->match.host, vl->host)) + if (!lu_part_matches(&user_class->match.type_instance, vl->type_instance) || + !lu_part_matches(&user_class->match.plugin_instance, + vl->plugin_instance) || + !lu_part_matches(&user_class->match.plugin, vl->plugin) || + !lu_part_matches(&user_class->match.host, vl->host)) return (1); - pthread_mutex_lock (&user_class->lock); - user_obj = lu_find_user_obj (user_class, vl); - if (user_obj == NULL) - { - /* call lookup_class_callback_t() and insert into the list of user objects. */ - user_obj = lu_create_user_obj (obj, ds, vl, user_class); + pthread_mutex_lock(&user_class->lock); + user_obj = lu_find_user_obj(user_class, vl); + if (user_obj == NULL) { + /* call lookup_class_callback_t() and insert into the list of user objects. + */ + user_obj = lu_create_user_obj(obj, ds, vl, user_class); if (user_obj == NULL) { - pthread_mutex_unlock (&user_class->lock); + pthread_mutex_unlock(&user_class->lock); return (-1); } } - pthread_mutex_unlock (&user_class->lock); + pthread_mutex_unlock(&user_class->lock); - status = obj->cb_user_obj (ds, vl, - user_class->user_class, user_obj->user_obj); - if (status != 0) - { - ERROR ("utils_vl_lookup: The user object callback failed with status %i.", - status); + status = obj->cb_user_obj(ds, vl, user_class->user_class, user_obj->user_obj); + if (status != 0) { + ERROR("utils_vl_lookup: The user object callback failed with status %i.", + status); /* Returning a negative value means: abort! */ if (status < 0) return (status); @@ -331,18 +309,17 @@ static int lu_handle_user_class (lookup_t *obj, /* {{{ */ return (0); } /* }}} int lu_handle_user_class */ -static int lu_handle_user_class_list (lookup_t *obj, /* {{{ */ - data_set_t const *ds, value_list_t const *vl, - user_class_list_t *user_class_list) -{ +static int lu_handle_user_class_list(lookup_t *obj, /* {{{ */ + data_set_t const *ds, + value_list_t const *vl, + user_class_list_t *user_class_list) { user_class_list_t *ptr; int retval = 0; - for (ptr = user_class_list; ptr != NULL; ptr = ptr->next) - { + for (ptr = user_class_list; ptr != NULL; ptr = ptr->next) { int status; - status = lu_handle_user_class (obj, ds, vl, &ptr->entry); + status = lu_handle_user_class(obj, ds, vl, &ptr->entry); if (status < 0) return (status); else if (status == 0) @@ -352,115 +329,105 @@ static int lu_handle_user_class_list (lookup_t *obj, /* {{{ */ return (retval); } /* }}} int lu_handle_user_class_list */ -static by_type_entry_t *lu_search_by_type (lookup_t *obj, /* {{{ */ - char const *type, _Bool allocate_if_missing) -{ +static by_type_entry_t *lu_search_by_type(lookup_t *obj, /* {{{ */ + char const *type, + _Bool allocate_if_missing) { by_type_entry_t *by_type; char *type_copy; int status; - status = c_avl_get (obj->by_type_tree, type, (void *) &by_type); + status = c_avl_get(obj->by_type_tree, type, (void *)&by_type); if (status == 0) return (by_type); if (!allocate_if_missing) return (NULL); - type_copy = strdup (type); - if (type_copy == NULL) - { - ERROR ("utils_vl_lookup: strdup failed."); + type_copy = strdup(type); + if (type_copy == NULL) { + ERROR("utils_vl_lookup: strdup failed."); return (NULL); } - by_type = calloc (1, sizeof (*by_type)); - if (by_type == NULL) - { - ERROR ("utils_vl_lookup: calloc failed."); - sfree (type_copy); + by_type = calloc(1, sizeof(*by_type)); + if (by_type == NULL) { + ERROR("utils_vl_lookup: calloc failed."); + sfree(type_copy); return (NULL); } by_type->wildcard_plugin_list = NULL; - by_type->by_plugin_tree = c_avl_create ((int (*) (const void *, const void *)) strcmp); - if (by_type->by_plugin_tree == NULL) - { - ERROR ("utils_vl_lookup: c_avl_create failed."); - sfree (by_type); - sfree (type_copy); + by_type->by_plugin_tree = + c_avl_create((int (*)(const void *, const void *))strcmp); + if (by_type->by_plugin_tree == NULL) { + ERROR("utils_vl_lookup: c_avl_create failed."); + sfree(by_type); + sfree(type_copy); return (NULL); } - status = c_avl_insert (obj->by_type_tree, - /* key = */ type_copy, /* value = */ by_type); - assert (status <= 0); /* >0 => entry exists => race condition. */ - if (status != 0) - { - ERROR ("utils_vl_lookup: c_avl_insert failed."); - c_avl_destroy (by_type->by_plugin_tree); - sfree (by_type); - sfree (type_copy); + status = c_avl_insert(obj->by_type_tree, + /* key = */ type_copy, /* value = */ by_type); + assert(status <= 0); /* >0 => entry exists => race condition. */ + if (status != 0) { + ERROR("utils_vl_lookup: c_avl_insert failed."); + c_avl_destroy(by_type->by_plugin_tree); + sfree(by_type); + sfree(type_copy); return (NULL); } return (by_type); } /* }}} by_type_entry_t *lu_search_by_type */ -static int lu_add_by_plugin (by_type_entry_t *by_type, /* {{{ */ - user_class_list_t *user_class_list) -{ +static int lu_add_by_plugin(by_type_entry_t *by_type, /* {{{ */ + user_class_list_t *user_class_list) { user_class_list_t *ptr = NULL; identifier_match_t const *match = &user_class_list->entry.match; /* Lookup user_class_list from the per-plugin structure. If this is the first * user_class to be added, the block returns immediately. Otherwise they will * set "ptr" to non-NULL. */ - if (match->plugin.is_regex) - { - if (by_type->wildcard_plugin_list == NULL) - { + if (match->plugin.is_regex) { + if (by_type->wildcard_plugin_list == NULL) { by_type->wildcard_plugin_list = user_class_list; return (0); } ptr = by_type->wildcard_plugin_list; - } /* if (plugin is wildcard) */ + } /* if (plugin is wildcard) */ else /* (plugin is not wildcard) */ { int status; - status = c_avl_get (by_type->by_plugin_tree, - match->plugin.str, (void *) &ptr); + status = + c_avl_get(by_type->by_plugin_tree, match->plugin.str, (void *)&ptr); if (status != 0) /* plugin not yet in tree */ { - char *plugin_copy = strdup (match->plugin.str); + char *plugin_copy = strdup(match->plugin.str); - if (plugin_copy == NULL) - { - ERROR ("utils_vl_lookup: strdup failed."); - sfree (user_class_list); + if (plugin_copy == NULL) { + ERROR("utils_vl_lookup: strdup failed."); + sfree(user_class_list); return (ENOMEM); } - status = c_avl_insert (by_type->by_plugin_tree, - plugin_copy, user_class_list); - if (status != 0) - { - ERROR ("utils_vl_lookup: c_avl_insert(\"%s\") failed with status %i.", - plugin_copy, status); - sfree (plugin_copy); - sfree (user_class_list); + status = + c_avl_insert(by_type->by_plugin_tree, plugin_copy, user_class_list); + if (status != 0) { + ERROR("utils_vl_lookup: c_avl_insert(\"%s\") failed with status %i.", + plugin_copy, status); + sfree(plugin_copy); + sfree(user_class_list); return (status); - } - else - { + } else { return (0); } } /* if (plugin not yet in tree) */ - } /* if (plugin is not wildcard) */ + } /* if (plugin is not wildcard) */ - assert (ptr != NULL); + assert(ptr != NULL); while (ptr->next != NULL) ptr = ptr->next; @@ -469,107 +436,99 @@ static int lu_add_by_plugin (by_type_entry_t *by_type, /* {{{ */ return (0); } /* }}} int lu_add_by_plugin */ -static void lu_destroy_user_obj (lookup_t *obj, /* {{{ */ - user_obj_t *user_obj) -{ - while (user_obj != NULL) - { +static void lu_destroy_user_obj(lookup_t *obj, /* {{{ */ + user_obj_t *user_obj) { + while (user_obj != NULL) { user_obj_t *next = user_obj->next; if (obj->cb_free_obj != NULL) - obj->cb_free_obj (user_obj->user_obj); + obj->cb_free_obj(user_obj->user_obj); user_obj->user_obj = NULL; - sfree (user_obj); + sfree(user_obj); user_obj = next; } } /* }}} void lu_destroy_user_obj */ -static void lu_destroy_user_class_list (lookup_t *obj, /* {{{ */ - user_class_list_t *user_class_list) -{ - while (user_class_list != NULL) - { +static void lu_destroy_user_class_list(lookup_t *obj, /* {{{ */ + user_class_list_t *user_class_list) { + while (user_class_list != NULL) { user_class_list_t *next = user_class_list->next; if (obj->cb_free_class != NULL) - obj->cb_free_class (user_class_list->entry.user_class); + obj->cb_free_class(user_class_list->entry.user_class); user_class_list->entry.user_class = NULL; -#define CLEAR_FIELD(field) do { \ - if (user_class_list->entry.match.field.is_regex) { \ - regfree (&user_class_list->entry.match.field.regex); \ - user_class_list->entry.match.field.is_regex = 0; \ - } \ -} while (0) +#define CLEAR_FIELD(field) \ + do { \ + if (user_class_list->entry.match.field.is_regex) { \ + regfree(&user_class_list->entry.match.field.regex); \ + user_class_list->entry.match.field.is_regex = 0; \ + } \ + } while (0) - CLEAR_FIELD (host); - CLEAR_FIELD (plugin); - CLEAR_FIELD (plugin_instance); - CLEAR_FIELD (type); - CLEAR_FIELD (type_instance); + CLEAR_FIELD(host); + CLEAR_FIELD(plugin); + CLEAR_FIELD(plugin_instance); + CLEAR_FIELD(type); + CLEAR_FIELD(type_instance); #undef CLEAR_FIELD - lu_destroy_user_obj (obj, user_class_list->entry.user_obj_list); + lu_destroy_user_obj(obj, user_class_list->entry.user_obj_list); user_class_list->entry.user_obj_list = NULL; - pthread_mutex_destroy (&user_class_list->entry.lock); + pthread_mutex_destroy(&user_class_list->entry.lock); - sfree (user_class_list); + sfree(user_class_list); user_class_list = next; } } /* }}} void lu_destroy_user_class_list */ -static void lu_destroy_by_type (lookup_t *obj, /* {{{ */ - by_type_entry_t *by_type) -{ +static void lu_destroy_by_type(lookup_t *obj, /* {{{ */ + by_type_entry_t *by_type) { - while (42) - { + while (42) { char *plugin = NULL; user_class_list_t *user_class_list = NULL; int status; - status = c_avl_pick (by_type->by_plugin_tree, - (void *) &plugin, (void *) &user_class_list); + status = c_avl_pick(by_type->by_plugin_tree, (void *)&plugin, + (void *)&user_class_list); if (status != 0) break; - DEBUG ("utils_vl_lookup: lu_destroy_by_type: Destroying plugin \"%s\".", - plugin); - sfree (plugin); - lu_destroy_user_class_list (obj, user_class_list); + DEBUG("utils_vl_lookup: lu_destroy_by_type: Destroying plugin \"%s\".", + plugin); + sfree(plugin); + lu_destroy_user_class_list(obj, user_class_list); } - c_avl_destroy (by_type->by_plugin_tree); + c_avl_destroy(by_type->by_plugin_tree); by_type->by_plugin_tree = NULL; - lu_destroy_user_class_list (obj, by_type->wildcard_plugin_list); + lu_destroy_user_class_list(obj, by_type->wildcard_plugin_list); by_type->wildcard_plugin_list = NULL; - sfree (by_type); + sfree(by_type); } /* }}} int lu_destroy_by_type */ /* * Public functions */ -lookup_t *lookup_create (lookup_class_callback_t cb_user_class, /* {{{ */ - lookup_obj_callback_t cb_user_obj, - lookup_free_class_callback_t cb_free_class, - lookup_free_obj_callback_t cb_free_obj) -{ - lookup_t *obj = calloc (1, sizeof (*obj)); - if (obj == NULL) - { - ERROR ("utils_vl_lookup: calloc failed."); +lookup_t *lookup_create(lookup_class_callback_t cb_user_class, /* {{{ */ + lookup_obj_callback_t cb_user_obj, + lookup_free_class_callback_t cb_free_class, + lookup_free_obj_callback_t cb_free_obj) { + lookup_t *obj = calloc(1, sizeof(*obj)); + if (obj == NULL) { + ERROR("utils_vl_lookup: calloc failed."); return (NULL); } - obj->by_type_tree = c_avl_create ((int (*) (const void *, const void *)) strcmp); - if (obj->by_type_tree == NULL) - { - ERROR ("utils_vl_lookup: c_avl_create failed."); - sfree (obj); + obj->by_type_tree = c_avl_create((int (*)(const void *, const void *))strcmp); + if (obj->by_type_tree == NULL) { + ERROR("utils_vl_lookup: c_avl_create failed."); + sfree(obj); return (NULL); } @@ -581,62 +540,59 @@ lookup_t *lookup_create (lookup_class_callback_t cb_user_class, /* {{{ */ return (obj); } /* }}} lookup_t *lookup_create */ -void lookup_destroy (lookup_t *obj) /* {{{ */ +void lookup_destroy(lookup_t *obj) /* {{{ */ { int status; if (obj == NULL) return; - while (42) - { + while (42) { char *type = NULL; by_type_entry_t *by_type = NULL; - status = c_avl_pick (obj->by_type_tree, (void *) &type, (void *) &by_type); + status = c_avl_pick(obj->by_type_tree, (void *)&type, (void *)&by_type); if (status != 0) break; - DEBUG ("utils_vl_lookup: lookup_destroy: Destroying type \"%s\".", type); - sfree (type); - lu_destroy_by_type (obj, by_type); + DEBUG("utils_vl_lookup: lookup_destroy: Destroying type \"%s\".", type); + sfree(type); + lu_destroy_by_type(obj, by_type); } - c_avl_destroy (obj->by_type_tree); + c_avl_destroy(obj->by_type_tree); obj->by_type_tree = NULL; - sfree (obj); + sfree(obj); } /* }}} void lookup_destroy */ -int lookup_add (lookup_t *obj, /* {{{ */ - lookup_identifier_t const *ident, unsigned int group_by, void *user_class) -{ +int lookup_add(lookup_t *obj, /* {{{ */ + lookup_identifier_t const *ident, unsigned int group_by, + void *user_class) { by_type_entry_t *by_type = NULL; user_class_list_t *user_class_obj; - by_type = lu_search_by_type (obj, ident->type, /* allocate = */ 1); + by_type = lu_search_by_type(obj, ident->type, /* allocate = */ 1); if (by_type == NULL) return (-1); - user_class_obj = calloc (1, sizeof (*user_class_obj)); - if (user_class_obj == NULL) - { - ERROR ("utils_vl_lookup: calloc failed."); + user_class_obj = calloc(1, sizeof(*user_class_obj)); + if (user_class_obj == NULL) { + ERROR("utils_vl_lookup: calloc failed."); return (ENOMEM); } - pthread_mutex_init (&user_class_obj->entry.lock, /* attr = */ NULL); + pthread_mutex_init(&user_class_obj->entry.lock, /* attr = */ NULL); user_class_obj->entry.user_class = user_class; - lu_copy_ident_to_match (&user_class_obj->entry.match, ident, group_by); + lu_copy_ident_to_match(&user_class_obj->entry.match, ident, group_by); user_class_obj->entry.user_obj_list = NULL; user_class_obj->next = NULL; - return (lu_add_by_plugin (by_type, user_class_obj)); + return (lu_add_by_plugin(by_type, user_class_obj)); } /* }}} int lookup_add */ /* returns the number of successful calls to the callback function */ -int lookup_search (lookup_t *obj, /* {{{ */ - data_set_t const *ds, value_list_t const *vl) -{ +int lookup_search(lookup_t *obj, /* {{{ */ + data_set_t const *ds, value_list_t const *vl) { by_type_entry_t *by_type = NULL; user_class_list_t *user_class_list = NULL; int retval = 0; @@ -645,24 +601,22 @@ int lookup_search (lookup_t *obj, /* {{{ */ if ((obj == NULL) || (ds == NULL) || (vl == NULL)) return (-EINVAL); - by_type = lu_search_by_type (obj, vl->type, /* allocate = */ 0); + by_type = lu_search_by_type(obj, vl->type, /* allocate = */ 0); if (by_type == NULL) return (0); - status = c_avl_get (by_type->by_plugin_tree, - vl->plugin, (void *) &user_class_list); - if (status == 0) - { - status = lu_handle_user_class_list (obj, ds, vl, user_class_list); + status = + c_avl_get(by_type->by_plugin_tree, vl->plugin, (void *)&user_class_list); + if (status == 0) { + status = lu_handle_user_class_list(obj, ds, vl, user_class_list); if (status < 0) return (status); retval += status; } - if (by_type->wildcard_plugin_list != NULL) - { - status = lu_handle_user_class_list (obj, ds, vl, - by_type->wildcard_plugin_list); + if (by_type->wildcard_plugin_list != NULL) { + status = + lu_handle_user_class_list(obj, ds, vl, by_type->wildcard_plugin_list); if (status < 0) return (status); retval += status; diff --git a/src/utils_vl_lookup.h b/src/utils_vl_lookup.h index e46e7637..90a4ee52 100644 --- a/src/utils_vl_lookup.h +++ b/src/utils_vl_lookup.h @@ -36,25 +36,25 @@ struct lookup_s; typedef struct lookup_s lookup_t; /* Given a user_class, constructs a new user_obj. */ -typedef void *(*lookup_class_callback_t) (data_set_t const *ds, - value_list_t const *vl, void *user_class); +typedef void *(*lookup_class_callback_t)(data_set_t const *ds, + value_list_t const *vl, + void *user_class); /* Given a user_class and a ds/vl combination, does stuff with the data. * This is the main working horse of the module. */ -typedef int (*lookup_obj_callback_t) (data_set_t const *ds, - value_list_t const *vl, - void *user_class, void *user_obj); +typedef int (*lookup_obj_callback_t)(data_set_t const *ds, + value_list_t const *vl, void *user_class, + void *user_obj); /* Used to free user_class pointers. May be NULL in which case nothing is * freed. */ -typedef void (*lookup_free_class_callback_t) (void *user_class); +typedef void (*lookup_free_class_callback_t)(void *user_class); /* Used to free user_obj pointers. May be NULL in which case nothing is * freed. */ -typedef void (*lookup_free_obj_callback_t) (void *user_obj); +typedef void (*lookup_free_obj_callback_t)(void *user_obj); -struct lookup_identifier_s -{ +struct lookup_identifier_s { char host[DATA_MAX_NAME_LEN]; char plugin[DATA_MAX_NAME_LEN]; char plugin_instance[DATA_MAX_NAME_LEN]; @@ -63,27 +63,25 @@ struct lookup_identifier_s }; typedef struct lookup_identifier_s lookup_identifier_t; -#define LU_GROUP_BY_HOST 0x01 -#define LU_GROUP_BY_PLUGIN 0x02 +#define LU_GROUP_BY_HOST 0x01 +#define LU_GROUP_BY_PLUGIN 0x02 #define LU_GROUP_BY_PLUGIN_INSTANCE 0x04 /* #define LU_GROUP_BY_TYPE 0x00 */ -#define LU_GROUP_BY_TYPE_INSTANCE 0x10 +#define LU_GROUP_BY_TYPE_INSTANCE 0x10 /* * Functions */ -__attribute__((nonnull(1,2))) -lookup_t *lookup_create (lookup_class_callback_t, - lookup_obj_callback_t, - lookup_free_class_callback_t, - lookup_free_obj_callback_t); -void lookup_destroy (lookup_t *obj); +__attribute__((nonnull(1, 2))) +lookup_t *lookup_create(lookup_class_callback_t, lookup_obj_callback_t, + lookup_free_class_callback_t, + lookup_free_obj_callback_t); +void lookup_destroy(lookup_t *obj); -int lookup_add (lookup_t *obj, - lookup_identifier_t const *ident, unsigned int group_by, void *user_class); +int lookup_add(lookup_t *obj, lookup_identifier_t const *ident, + unsigned int group_by, void *user_class); /* TODO(octo): Pass lookup_obj_callback_t to lookup_search()? */ -int lookup_search (lookup_t *obj, - data_set_t const *ds, value_list_t const *vl); +int lookup_search(lookup_t *obj, data_set_t const *ds, value_list_t const *vl); #endif /* UTILS_VL_LOOKUP_H */ diff --git a/src/utils_vl_lookup_test.c b/src/utils_vl_lookup_test.c index b5a8e61a..776a520a 100644 --- a/src/utils_vl_lookup_test.c +++ b/src/utils_vl_lookup_test.c @@ -35,209 +35,203 @@ static _Bool have_new_obj = 0; static lookup_identifier_t last_class_ident; static lookup_identifier_t last_obj_ident; -static data_source_t dsrc_test = { "value", DS_TYPE_DERIVE, 0.0, NAN }; -static data_set_t const ds_test = { "test", 1, &dsrc_test }; +static data_source_t dsrc_test = {"value", DS_TYPE_DERIVE, 0.0, NAN}; +static data_set_t const ds_test = {"test", 1, &dsrc_test}; -static data_source_t dsrc_unknown = { "value", DS_TYPE_DERIVE, 0.0, NAN }; -static data_set_t const ds_unknown = { "unknown", 1, &dsrc_unknown }; +static data_source_t dsrc_unknown = {"value", DS_TYPE_DERIVE, 0.0, NAN}; +static data_set_t const ds_unknown = {"unknown", 1, &dsrc_unknown}; -static int lookup_obj_callback (data_set_t const *ds, - value_list_t const *vl, - void *user_class, void *user_obj) -{ +static int lookup_obj_callback(data_set_t const *ds, value_list_t const *vl, + void *user_class, void *user_obj) { lookup_identifier_t *class = user_class; lookup_identifier_t *obj = user_obj; OK1(expect_new_obj == have_new_obj, (expect_new_obj ? "New obj is created." : "Updating existing obj.")); - memcpy (&last_class_ident, class, sizeof (last_class_ident)); - memcpy (&last_obj_ident, obj, sizeof (last_obj_ident)); + memcpy(&last_class_ident, class, sizeof(last_class_ident)); + memcpy(&last_obj_ident, obj, sizeof(last_obj_ident)); - if (strcmp (obj->plugin_instance, "failure") == 0) + if (strcmp(obj->plugin_instance, "failure") == 0) return (-1); return (0); } -static void *lookup_class_callback (data_set_t const *ds, - value_list_t const *vl, void *user_class) -{ +static void *lookup_class_callback(data_set_t const *ds, value_list_t const *vl, + void *user_class) { lookup_identifier_t *class = user_class; lookup_identifier_t *obj; - assert (expect_new_obj); + assert(expect_new_obj); - memcpy (&last_class_ident, class, sizeof (last_class_ident)); + memcpy(&last_class_ident, class, sizeof(last_class_ident)); - obj = malloc (sizeof (*obj)); - strncpy (obj->host, vl->host, sizeof (obj->host)); - strncpy (obj->plugin, vl->plugin, sizeof (obj->plugin)); - strncpy (obj->plugin_instance, vl->plugin_instance, sizeof (obj->plugin_instance)); - strncpy (obj->type, vl->type, sizeof (obj->type)); - strncpy (obj->type_instance, vl->type_instance, sizeof (obj->type_instance)); + obj = malloc(sizeof(*obj)); + strncpy(obj->host, vl->host, sizeof(obj->host)); + strncpy(obj->plugin, vl->plugin, sizeof(obj->plugin)); + strncpy(obj->plugin_instance, vl->plugin_instance, + sizeof(obj->plugin_instance)); + strncpy(obj->type, vl->type, sizeof(obj->type)); + strncpy(obj->type_instance, vl->type_instance, sizeof(obj->type_instance)); have_new_obj = 1; - return ((void *) obj); + return ((void *)obj); } -static int checked_lookup_add (lookup_t *obj, /* {{{ */ - char const *host, - char const *plugin, char const *plugin_instance, - char const *type, char const *type_instance, - unsigned int group_by) -{ +static int checked_lookup_add(lookup_t *obj, /* {{{ */ + char const *host, char const *plugin, + char const *plugin_instance, char const *type, + char const *type_instance, + unsigned int group_by) { lookup_identifier_t ident; void *user_class; - strncpy (ident.host, host, sizeof (ident.host)); - strncpy (ident.plugin, plugin, sizeof (ident.plugin)); - strncpy (ident.plugin_instance, plugin_instance, sizeof (ident.plugin_instance)); - strncpy (ident.type, type, sizeof (ident.type)); - strncpy (ident.type_instance, type_instance, sizeof (ident.type_instance)); + strncpy(ident.host, host, sizeof(ident.host)); + strncpy(ident.plugin, plugin, sizeof(ident.plugin)); + strncpy(ident.plugin_instance, plugin_instance, + sizeof(ident.plugin_instance)); + strncpy(ident.type, type, sizeof(ident.type)); + strncpy(ident.type_instance, type_instance, sizeof(ident.type_instance)); - user_class = malloc (sizeof (ident)); - memmove (user_class, &ident, sizeof (ident)); + user_class = malloc(sizeof(ident)); + memmove(user_class, &ident, sizeof(ident)); - OK(lookup_add (obj, &ident, group_by, user_class) == 0); + OK(lookup_add(obj, &ident, group_by, user_class) == 0); return 0; } /* }}} int checked_lookup_add */ -static int checked_lookup_search (lookup_t *obj, - char const *host, - char const *plugin, char const *plugin_instance, - char const *type, char const *type_instance, - _Bool expect_new) -{ +static int checked_lookup_search(lookup_t *obj, char const *host, + char const *plugin, + char const *plugin_instance, char const *type, + char const *type_instance, _Bool expect_new) { int status; value_list_t vl = VALUE_LIST_INIT; data_set_t const *ds = &ds_unknown; - strncpy (vl.host, host, sizeof (vl.host)); - strncpy (vl.plugin, plugin, sizeof (vl.plugin)); - strncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); - strncpy (vl.type, type, sizeof (vl.type)); - strncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + strncpy(vl.host, host, sizeof(vl.host)); + strncpy(vl.plugin, plugin, sizeof(vl.plugin)); + strncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + strncpy(vl.type, type, sizeof(vl.type)); + strncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - if (strcmp (vl.type, "test") == 0) + if (strcmp(vl.type, "test") == 0) ds = &ds_test; expect_new_obj = expect_new; have_new_obj = 0; - status = lookup_search (obj, ds, &vl); + status = lookup_search(obj, ds, &vl); return (status); } -DEF_TEST(group_by_specific_host) -{ +DEF_TEST(group_by_specific_host) { lookup_t *obj; - CHECK_NOT_NULL (obj = lookup_create ( - lookup_class_callback, lookup_obj_callback, (void *) free, (void *) free)); - - checked_lookup_add (obj, "/.*/", "test", "", "test", "/.*/", LU_GROUP_BY_HOST); - checked_lookup_search (obj, "host0", "test", "", "test", "0", - /* expect new = */ 1); - checked_lookup_search (obj, "host0", "test", "", "test", "1", - /* expect new = */ 0); - checked_lookup_search (obj, "host1", "test", "", "test", "0", - /* expect new = */ 1); - checked_lookup_search (obj, "host1", "test", "", "test", "1", - /* expect new = */ 0); - - lookup_destroy (obj); + CHECK_NOT_NULL(obj = lookup_create(lookup_class_callback, lookup_obj_callback, + (void *)free, (void *)free)); + + checked_lookup_add(obj, "/.*/", "test", "", "test", "/.*/", LU_GROUP_BY_HOST); + checked_lookup_search(obj, "host0", "test", "", "test", "0", + /* expect new = */ 1); + checked_lookup_search(obj, "host0", "test", "", "test", "1", + /* expect new = */ 0); + checked_lookup_search(obj, "host1", "test", "", "test", "0", + /* expect new = */ 1); + checked_lookup_search(obj, "host1", "test", "", "test", "1", + /* expect new = */ 0); + + lookup_destroy(obj); return (0); } -DEF_TEST(group_by_any_host) -{ +DEF_TEST(group_by_any_host) { lookup_t *obj; - CHECK_NOT_NULL (obj = lookup_create ( - lookup_class_callback, lookup_obj_callback, (void *) free, (void *) free)); - - checked_lookup_add (obj, "/.*/", "/.*/", "/.*/", "test", "/.*/", LU_GROUP_BY_HOST); - checked_lookup_search (obj, "host0", "plugin0", "", "test", "0", - /* expect new = */ 1); - checked_lookup_search (obj, "host0", "plugin0", "", "test", "1", - /* expect new = */ 0); - checked_lookup_search (obj, "host0", "plugin1", "", "test", "0", - /* expect new = */ 0); - checked_lookup_search (obj, "host0", "plugin1", "", "test", "1", - /* expect new = */ 0); - checked_lookup_search (obj, "host1", "plugin0", "", "test", "0", - /* expect new = */ 1); - checked_lookup_search (obj, "host1", "plugin0", "", "test", "1", - /* expect new = */ 0); - checked_lookup_search (obj, "host1", "plugin1", "", "test", "0", - /* expect new = */ 0); - checked_lookup_search (obj, "host1", "plugin1", "", "test", "1", - /* expect new = */ 0); - - lookup_destroy (obj); + CHECK_NOT_NULL(obj = lookup_create(lookup_class_callback, lookup_obj_callback, + (void *)free, (void *)free)); + + checked_lookup_add(obj, "/.*/", "/.*/", "/.*/", "test", "/.*/", + LU_GROUP_BY_HOST); + checked_lookup_search(obj, "host0", "plugin0", "", "test", "0", + /* expect new = */ 1); + checked_lookup_search(obj, "host0", "plugin0", "", "test", "1", + /* expect new = */ 0); + checked_lookup_search(obj, "host0", "plugin1", "", "test", "0", + /* expect new = */ 0); + checked_lookup_search(obj, "host0", "plugin1", "", "test", "1", + /* expect new = */ 0); + checked_lookup_search(obj, "host1", "plugin0", "", "test", "0", + /* expect new = */ 1); + checked_lookup_search(obj, "host1", "plugin0", "", "test", "1", + /* expect new = */ 0); + checked_lookup_search(obj, "host1", "plugin1", "", "test", "0", + /* expect new = */ 0); + checked_lookup_search(obj, "host1", "plugin1", "", "test", "1", + /* expect new = */ 0); + + lookup_destroy(obj); return (0); } -DEF_TEST(multiple_lookups) -{ +DEF_TEST(multiple_lookups) { lookup_t *obj; int status; - CHECK_NOT_NULL (obj = lookup_create ( - lookup_class_callback, lookup_obj_callback, (void *) free, (void *) free)); - - checked_lookup_add (obj, "/.*/", "plugin0", "", "test", "/.*/", LU_GROUP_BY_HOST); - checked_lookup_add (obj, "/.*/", "/.*/", "", "test", "ti0", LU_GROUP_BY_HOST); - - status = checked_lookup_search (obj, "host0", "plugin1", "", "test", "", - /* expect new = */ 0); - assert (status == 0); - status = checked_lookup_search (obj, "host0", "plugin0", "", "test", "", - /* expect new = */ 1); - assert (status == 1); - status = checked_lookup_search (obj, "host0", "plugin1", "", "test", "ti0", - /* expect new = */ 1); - assert (status == 1); - status = checked_lookup_search (obj, "host0", "plugin0", "", "test", "ti0", - /* expect new = */ 0); - assert (status == 2); - - lookup_destroy (obj); + CHECK_NOT_NULL(obj = lookup_create(lookup_class_callback, lookup_obj_callback, + (void *)free, (void *)free)); + + checked_lookup_add(obj, "/.*/", "plugin0", "", "test", "/.*/", + LU_GROUP_BY_HOST); + checked_lookup_add(obj, "/.*/", "/.*/", "", "test", "ti0", LU_GROUP_BY_HOST); + + status = checked_lookup_search(obj, "host0", "plugin1", "", "test", "", + /* expect new = */ 0); + assert(status == 0); + status = checked_lookup_search(obj, "host0", "plugin0", "", "test", "", + /* expect new = */ 1); + assert(status == 1); + status = checked_lookup_search(obj, "host0", "plugin1", "", "test", "ti0", + /* expect new = */ 1); + assert(status == 1); + status = checked_lookup_search(obj, "host0", "plugin0", "", "test", "ti0", + /* expect new = */ 0); + assert(status == 2); + + lookup_destroy(obj); return (0); } -DEF_TEST(regex) -{ +DEF_TEST(regex) { lookup_t *obj; - CHECK_NOT_NULL (obj = lookup_create ( - lookup_class_callback, lookup_obj_callback, (void *) free, (void *) free)); - - checked_lookup_add (obj, "/^db[0-9]\\./", "cpu", "/.*/", "cpu", "/.*/", - LU_GROUP_BY_TYPE_INSTANCE); - checked_lookup_search (obj, "db0.example.com", "cpu", "0", "cpu", "user", - /* expect new = */ 1); - checked_lookup_search (obj, "db0.example.com", "cpu", "0", "cpu", "idle", - /* expect new = */ 1); - checked_lookup_search (obj, "db0.example.com", "cpu", "1", "cpu", "user", - /* expect new = */ 0); - checked_lookup_search (obj, "db0.example.com", "cpu", "1", "cpu", "idle", - /* expect new = */ 0); - checked_lookup_search (obj, "app0.example.com", "cpu", "0", "cpu", "user", - /* expect new = */ 0); - checked_lookup_search (obj, "app0.example.com", "cpu", "0", "cpu", "idle", - /* expect new = */ 0); - checked_lookup_search (obj, "db1.example.com", "cpu", "0", "cpu", "user", - /* expect new = */ 0); - checked_lookup_search (obj, "db1.example.com", "cpu", "0", "cpu", "idle", - /* expect new = */ 0); - checked_lookup_search (obj, "db1.example.com", "cpu", "0", "cpu", "system", - /* expect new = */ 1); - - lookup_destroy (obj); + CHECK_NOT_NULL(obj = lookup_create(lookup_class_callback, lookup_obj_callback, + (void *)free, (void *)free)); + + checked_lookup_add(obj, "/^db[0-9]\\./", "cpu", "/.*/", "cpu", "/.*/", + LU_GROUP_BY_TYPE_INSTANCE); + checked_lookup_search(obj, "db0.example.com", "cpu", "0", "cpu", "user", + /* expect new = */ 1); + checked_lookup_search(obj, "db0.example.com", "cpu", "0", "cpu", "idle", + /* expect new = */ 1); + checked_lookup_search(obj, "db0.example.com", "cpu", "1", "cpu", "user", + /* expect new = */ 0); + checked_lookup_search(obj, "db0.example.com", "cpu", "1", "cpu", "idle", + /* expect new = */ 0); + checked_lookup_search(obj, "app0.example.com", "cpu", "0", "cpu", "user", + /* expect new = */ 0); + checked_lookup_search(obj, "app0.example.com", "cpu", "0", "cpu", "idle", + /* expect new = */ 0); + checked_lookup_search(obj, "db1.example.com", "cpu", "0", "cpu", "user", + /* expect new = */ 0); + checked_lookup_search(obj, "db1.example.com", "cpu", "0", "cpu", "idle", + /* expect new = */ 0); + checked_lookup_search(obj, "db1.example.com", "cpu", "0", "cpu", "system", + /* expect new = */ 1); + + lookup_destroy(obj); return (0); } -int main (int argc, char **argv) /* {{{ */ +int main(int argc, char **argv) /* {{{ */ { RUN_TEST(group_by_specific_host); RUN_TEST(group_by_any_host); diff --git a/src/uuid.c b/src/uuid.c index 8bae3761..89c9e7dd 100644 --- a/src/uuid.c +++ b/src/uuid.c @@ -38,105 +38,92 @@ #endif #define UUID_RAW_LENGTH 16 -#define UUID_PRINTABLE_COMPACT_LENGTH (UUID_RAW_LENGTH * 2) -#define UUID_PRINTABLE_NORMAL_LENGTH (UUID_PRINTABLE_COMPACT_LENGTH + 4) +#define UUID_PRINTABLE_COMPACT_LENGTH (UUID_RAW_LENGTH * 2) +#define UUID_PRINTABLE_NORMAL_LENGTH (UUID_PRINTABLE_COMPACT_LENGTH + 4) static char *uuidfile = NULL; -static const char *config_keys[] = { - "UUIDFile" -}; +static const char *config_keys[] = {"UUIDFile"}; -static int -looks_like_a_uuid (const char *uuid) -{ - int len; +static int looks_like_a_uuid(const char *uuid) { + int len; - if (!uuid) - return (0); + if (!uuid) + return (0); - len = strlen (uuid); + len = strlen(uuid); - if (len < UUID_PRINTABLE_COMPACT_LENGTH) - return (0); + if (len < UUID_PRINTABLE_COMPACT_LENGTH) + return (0); - while (*uuid) { - if (!isxdigit ((int)*uuid) && *uuid != '-') - return (0); - uuid++; - } - return (1); + while (*uuid) { + if (!isxdigit((int)*uuid) && *uuid != '-') + return (0); + uuid++; + } + return (1); } -static char * -uuid_parse_dmidecode(FILE *file) -{ - char line[1024]; +static char *uuid_parse_dmidecode(FILE *file) { + char line[1024]; - while (fgets (line, sizeof (line), file) != NULL) - { - char *fields[4]; - int fields_num; + while (fgets(line, sizeof(line), file) != NULL) { + char *fields[4]; + int fields_num; - strstripnewline (line); + strstripnewline(line); - /* Look for a line reading: - * UUID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ - fields_num = strsplit (line, fields, STATIC_ARRAY_SIZE (fields)); - if (fields_num != 2) - continue; + /* Look for a line reading: + * UUID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ + fields_num = strsplit(line, fields, STATIC_ARRAY_SIZE(fields)); + if (fields_num != 2) + continue; - if (strcmp("UUID:", fields[0]) != 0) - continue; + if (strcmp("UUID:", fields[0]) != 0) + continue; - if (!looks_like_a_uuid (fields[1])) - continue; + if (!looks_like_a_uuid(fields[1])) + continue; - return (strdup (fields[1])); - } - return (NULL); + return (strdup(fields[1])); + } + return (NULL); } -static char * -uuid_get_from_dmidecode(void) -{ - FILE *dmidecode = popen("dmidecode -t system 2>/dev/null", "r"); - char *uuid; +static char *uuid_get_from_dmidecode(void) { + FILE *dmidecode = popen("dmidecode -t system 2>/dev/null", "r"); + char *uuid; - if (!dmidecode) - return (NULL); + if (!dmidecode) + return (NULL); - uuid = uuid_parse_dmidecode(dmidecode); + uuid = uuid_parse_dmidecode(dmidecode); - pclose(dmidecode); - return (uuid); + pclose(dmidecode); + return (uuid); } #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) -static char * -uuid_get_from_sysctlbyname(const char *name) -{ - char uuid[UUID_PRINTABLE_NORMAL_LENGTH + 1]; - size_t len = sizeof (uuid); - if (sysctlbyname(name, &uuid, &len, NULL, 0) == -1) - return NULL; - return (strdup (uuid)); +static char *uuid_get_from_sysctlbyname(const char *name) { + char uuid[UUID_PRINTABLE_NORMAL_LENGTH + 1]; + size_t len = sizeof(uuid); + if (sysctlbyname(name, &uuid, &len, NULL, 0) == -1) + return NULL; + return (strdup(uuid)); } #elif defined(__OpenBSD__) -static char * -uuid_get_from_sysctl(void) -{ - char uuid[UUID_PRINTABLE_NORMAL_LENGTH + 1]; - size_t len = sizeof (uuid); - int mib[2]; - - mib[0] = CTL_HW; - mib[1] = HW_UUID; - - if (sysctl(mib, 2, uuid, &len, NULL, 0) == -1) - return NULL; - return (strdup (uuid)); +static char *uuid_get_from_sysctl(void) { + char uuid[UUID_PRINTABLE_NORMAL_LENGTH + 1]; + size_t len = sizeof(uuid); + int mib[2]; + + mib[0] = CTL_HW; + mib[1] = HW_UUID; + + if (sysctl(mib, 2, uuid, &len, NULL, 0) == -1) + return NULL; + return (strdup(uuid)); } #endif @@ -145,152 +132,135 @@ uuid_get_from_sysctl(void) #define UUID_PATH "/org/freedesktop/Hal/devices/computer" #define UUID_PROPERTY "smbios.system.uuid" -static char * -uuid_get_from_hal(void) -{ - LibHalContext *ctx; +static char *uuid_get_from_hal(void) { + LibHalContext *ctx; - DBusError error; - DBusConnection *con; + DBusError error; + DBusConnection *con; - dbus_error_init(&error); + dbus_error_init(&error); - if (!(con = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) - goto bailout_nobus; + if (!(con = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) + goto bailout_nobus; - ctx = libhal_ctx_new(); - libhal_ctx_set_dbus_connection(ctx, con); + ctx = libhal_ctx_new(); + libhal_ctx_set_dbus_connection(ctx, con); - if (!libhal_ctx_init(ctx, &error)) - goto bailout; + if (!libhal_ctx_init(ctx, &error)) + goto bailout; - if (!libhal_device_property_exists(ctx, - UUID_PATH, - UUID_PROPERTY, - &error)) - goto bailout; + if (!libhal_device_property_exists(ctx, UUID_PATH, UUID_PROPERTY, &error)) + goto bailout; - char *uuid = libhal_device_get_property_string(ctx, - UUID_PATH, - UUID_PROPERTY, - &error); - if (looks_like_a_uuid (uuid)) - return (uuid); + char *uuid = + libhal_device_get_property_string(ctx, UUID_PATH, UUID_PROPERTY, &error); + if (looks_like_a_uuid(uuid)) + return (uuid); - bailout: - { - DBusError ctxerror; - dbus_error_init(&ctxerror); - if (!(libhal_ctx_shutdown(ctx, &ctxerror))) - dbus_error_free(&ctxerror); - } +bailout : { + DBusError ctxerror; + dbus_error_init(&ctxerror); + if (!(libhal_ctx_shutdown(ctx, &ctxerror))) + dbus_error_free(&ctxerror); +} - libhal_ctx_free(ctx); + libhal_ctx_free(ctx); - bailout_nobus: - if (dbus_error_is_set(&error)) - dbus_error_free(&error); - return (NULL); +bailout_nobus: + if (dbus_error_is_set(&error)) + dbus_error_free(&error); + return (NULL); } #endif -static char * -uuid_get_from_file(const char *path) -{ - FILE *file; - char uuid[UUID_PRINTABLE_NORMAL_LENGTH + 1] = ""; +static char *uuid_get_from_file(const char *path) { + FILE *file; + char uuid[UUID_PRINTABLE_NORMAL_LENGTH + 1] = ""; - file = fopen (path, "r"); - if (file == NULL) - return (NULL); + file = fopen(path, "r"); + if (file == NULL) + return (NULL); - if (!fgets(uuid, sizeof(uuid), file)) { - fclose(file); - return (NULL); - } + if (!fgets(uuid, sizeof(uuid), file)) { fclose(file); - strstripnewline (uuid); + return (NULL); + } + fclose(file); + strstripnewline(uuid); - return (strdup (uuid)); + return (strdup(uuid)); } -static char * -uuid_get_local(void) -{ - char *uuid; +static char *uuid_get_local(void) { + char *uuid; - /* Check /etc/uuid / UUIDFile before any other method. */ - if ((uuid = uuid_get_from_file(uuidfile ? uuidfile : "/etc/uuid")) != NULL) - return (uuid); + /* Check /etc/uuid / UUIDFile before any other method. */ + if ((uuid = uuid_get_from_file(uuidfile ? uuidfile : "/etc/uuid")) != NULL) + return (uuid); #if defined(__APPLE__) - if ((uuid = uuid_get_from_sysctlbyname("kern.uuid")) != NULL) - return (uuid); + if ((uuid = uuid_get_from_sysctlbyname("kern.uuid")) != NULL) + return (uuid); #elif defined(__FreeBSD__) - if ((uuid = uuid_get_from_sysctlbyname("kern.hostuuid")) != NULL) - return (uuid); + if ((uuid = uuid_get_from_sysctlbyname("kern.hostuuid")) != NULL) + return (uuid); #elif defined(__NetBSD__) - if ((uuid = uuid_get_from_sysctlbyname("machdep.dmi.system-uuid")) != NULL) - return (uuid); + if ((uuid = uuid_get_from_sysctlbyname("machdep.dmi.system-uuid")) != NULL) + return (uuid); #elif defined(__OpenBSD__) - if ((uuid = uuid_get_from_sysctl()) != NULL) - return (uuid); + if ((uuid = uuid_get_from_sysctl()) != NULL) + return (uuid); #elif defined(__linux__) - if ((uuid = uuid_get_from_file("/sys/class/dmi/id/product_uuid")) != NULL) - return (uuid); + if ((uuid = uuid_get_from_file("/sys/class/dmi/id/product_uuid")) != NULL) + return (uuid); #endif #if HAVE_LIBHAL_H - if ((uuid = uuid_get_from_hal()) != NULL) - return (uuid); + if ((uuid = uuid_get_from_hal()) != NULL) + return (uuid); #endif - if ((uuid = uuid_get_from_dmidecode()) != NULL) - return (uuid); + if ((uuid = uuid_get_from_dmidecode()) != NULL) + return (uuid); #if defined(__linux__) - if ((uuid = uuid_get_from_file("/sys/hypervisor/uuid")) != NULL) - return (uuid); + if ((uuid = uuid_get_from_file("/sys/hypervisor/uuid")) != NULL) + return (uuid); #endif - return (NULL); + return (NULL); } -static int -uuid_config (const char *key, const char *value) -{ - if (strcasecmp (key, "UUIDFile") == 0) { - char *tmp = strdup (value); - if (tmp == NULL) - return (-1); - sfree (uuidfile); - uuidfile = tmp; - return (0); - } - - return (1); -} +static int uuid_config(const char *key, const char *value) { + if (strcasecmp(key, "UUIDFile") == 0) { + char *tmp = strdup(value); + if (tmp == NULL) + return (-1); + sfree(uuidfile); + uuidfile = tmp; + return (0); + } -static int -uuid_init (void) -{ - char *uuid = uuid_get_local (); + return (1); +} - if (uuid) { - sstrncpy (hostname_g, uuid, DATA_MAX_NAME_LEN); - sfree (uuid); - return (0); - } +static int uuid_init(void) { + char *uuid = uuid_get_local(); - WARNING ("uuid: could not read UUID using any known method"); + if (uuid) { + sstrncpy(hostname_g, uuid, DATA_MAX_NAME_LEN); + sfree(uuid); return (0); + } + + WARNING("uuid: could not read UUID using any known method"); + return (0); } -void module_register (void) -{ - plugin_register_config ("uuid", uuid_config, - config_keys, STATIC_ARRAY_SIZE (config_keys)); - plugin_register_init ("uuid", uuid_init); +void module_register(void) { + plugin_register_config("uuid", uuid_config, config_keys, + STATIC_ARRAY_SIZE(config_keys)); + plugin_register_init("uuid", uuid_init); } /* diff --git a/src/varnish.c b/src/varnish.c index e1464dc4..41b60d85 100644 --- a/src/varnish.c +++ b/src/varnish.c @@ -29,8 +29,8 @@ #include "plugin.h" #if HAVE_VARNISH_V4 -#include #include +#include typedef struct VSC_C_main c_varnish_stats_t; #endif @@ -47,1116 +47,1289 @@ typedef struct varnish_stats c_varnish_stats_t; /* {{{ user_config_s */ struct user_config_s { - char *instance; + char *instance; - _Bool collect_cache; - _Bool collect_connections; - _Bool collect_esi; - _Bool collect_backend; + _Bool collect_cache; + _Bool collect_connections; + _Bool collect_esi; + _Bool collect_backend; #ifdef HAVE_VARNISH_V3 - _Bool collect_dirdns; + _Bool collect_dirdns; #endif - _Bool collect_fetch; - _Bool collect_hcb; - _Bool collect_objects; + _Bool collect_fetch; + _Bool collect_hcb; + _Bool collect_objects; #if HAVE_VARNISH_V2 - _Bool collect_purge; + _Bool collect_purge; #else - _Bool collect_ban; + _Bool collect_ban; #endif - _Bool collect_session; - _Bool collect_shm; - _Bool collect_sms; + _Bool collect_session; + _Bool collect_shm; + _Bool collect_sms; #if HAVE_VARNISH_V2 - _Bool collect_sm; - _Bool collect_sma; + _Bool collect_sm; + _Bool collect_sma; #endif - _Bool collect_struct; - _Bool collect_totals; + _Bool collect_struct; + _Bool collect_totals; #if HAVE_VARNISH_V3 || HAVE_VARNISH_V4 - _Bool collect_uptime; + _Bool collect_uptime; #endif - _Bool collect_vcl; - _Bool collect_workers; + _Bool collect_vcl; + _Bool collect_workers; #if HAVE_VARNISH_V4 - _Bool collect_vsm; + _Bool collect_vsm; #endif }; typedef struct user_config_s user_config_t; /* }}} */ static _Bool have_instance = 0; -static int varnish_submit (const char *plugin_instance, /* {{{ */ - const char *category, const char *type, const char *type_instance, value_t value) -{ - value_list_t vl = VALUE_LIST_INIT; +static int varnish_submit(const char *plugin_instance, /* {{{ */ + const char *category, const char *type, + const char *type_instance, value_t value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &value; - vl.values_len = 1; + vl.values = &value; + vl.values_len = 1; - sstrncpy (vl.plugin, "varnish", sizeof (vl.plugin)); + sstrncpy(vl.plugin, "varnish", sizeof(vl.plugin)); - if (plugin_instance == NULL) - plugin_instance = "default"; - ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), - "%s-%s", plugin_instance, category); + if (plugin_instance == NULL) + plugin_instance = "default"; + ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%s", + plugin_instance, category); - sstrncpy (vl.type, type, sizeof (vl.type)); + sstrncpy(vl.type, type, sizeof(vl.type)); - if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, - sizeof (vl.type_instance)); + if (type_instance != NULL) + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - return (plugin_dispatch_values (&vl)); + return (plugin_dispatch_values(&vl)); } /* }}} int varnish_submit */ -static int varnish_submit_gauge (const char *plugin_instance, /* {{{ */ - const char *category, const char *type, const char *type_instance, - uint64_t gauge_value) -{ - return (varnish_submit (plugin_instance, category, type, type_instance, - (value_t) { .gauge = (gauge_t) gauge_value })); +static int varnish_submit_gauge(const char *plugin_instance, /* {{{ */ + const char *category, const char *type, + const char *type_instance, + uint64_t gauge_value) { + return (varnish_submit(plugin_instance, category, type, type_instance, + (value_t){.gauge = (gauge_t)gauge_value})); } /* }}} int varnish_submit_gauge */ -static int varnish_submit_derive (const char *plugin_instance, /* {{{ */ - const char *category, const char *type, const char *type_instance, - uint64_t derive_value) -{ - return (varnish_submit (plugin_instance, category, type, type_instance, - (value_t) { .derive = (derive_t) derive_value })); +static int varnish_submit_derive(const char *plugin_instance, /* {{{ */ + const char *category, const char *type, + const char *type_instance, + uint64_t derive_value) { + return (varnish_submit(plugin_instance, category, type, type_instance, + (value_t){.derive = (derive_t)derive_value})); } /* }}} int varnish_submit_derive */ #if HAVE_VARNISH_V3 || HAVE_VARNISH_V4 -static int varnish_monitor (void *priv, const struct VSC_point * const pt) /* {{{ */ +static int varnish_monitor(void *priv, + const struct VSC_point *const pt) /* {{{ */ { - uint64_t val; - const user_config_t *conf; - const char *class; - const char *name; + uint64_t val; + const user_config_t *conf; + const char *class; + const char *name; - if (pt == NULL) - return (0); + if (pt == NULL) + return (0); - conf = priv; + conf = priv; #if HAVE_VARNISH_V4 - class = pt->section->fantom->type; - name = pt->desc->name; + class = pt->section->fantom->type; + name = pt->desc->name; - if (strcmp(class, "MAIN") != 0) - return (0); + if (strcmp(class, "MAIN") != 0) + return (0); #elif HAVE_VARNISH_V3 - class = pt->class; - name = pt->name; + class = pt->class; + name = pt->name; - if (strcmp(class, "") != 0) - return (0); + if (strcmp(class, "") != 0) + return (0); #endif - val = *(const volatile uint64_t*) pt->ptr; - - if (conf->collect_cache) - { - if (strcmp(name, "cache_hit") == 0) - return varnish_submit_derive (conf->instance, "cache", "cache_result", "hit", val); - else if (strcmp(name, "cache_miss") == 0) - return varnish_submit_derive (conf->instance, "cache", "cache_result", "miss", val); - else if (strcmp(name, "cache_hitpass") == 0) - return varnish_submit_derive (conf->instance, "cache", "cache_result", "hitpass", val); - } - - if (conf->collect_connections) - { - if (strcmp(name, "client_conn") == 0) - return varnish_submit_derive (conf->instance, "connections", "connections", "accepted", val); - else if (strcmp(name, "client_drop") == 0) - return varnish_submit_derive (conf->instance, "connections", "connections", "dropped" , val); - else if (strcmp(name, "client_req") == 0) - return varnish_submit_derive (conf->instance, "connections", "connections", "received", val); - } + val = *(const volatile uint64_t *)pt->ptr; + + if (conf->collect_cache) { + if (strcmp(name, "cache_hit") == 0) + return varnish_submit_derive(conf->instance, "cache", "cache_result", + "hit", val); + else if (strcmp(name, "cache_miss") == 0) + return varnish_submit_derive(conf->instance, "cache", "cache_result", + "miss", val); + else if (strcmp(name, "cache_hitpass") == 0) + return varnish_submit_derive(conf->instance, "cache", "cache_result", + "hitpass", val); + } + + if (conf->collect_connections) { + if (strcmp(name, "client_conn") == 0) + return varnish_submit_derive(conf->instance, "connections", "connections", + "accepted", val); + else if (strcmp(name, "client_drop") == 0) + return varnish_submit_derive(conf->instance, "connections", "connections", + "dropped", val); + else if (strcmp(name, "client_req") == 0) + return varnish_submit_derive(conf->instance, "connections", "connections", + "received", val); + } #ifdef HAVE_VARNISH_V3 - if (conf->collect_dirdns) - { - if (strcmp(name, "dir_dns_lookups") == 0) - return varnish_submit_derive (conf->instance, "dirdns", "cache_operation", "lookups", val); - else if (strcmp(name, "dir_dns_failed") == 0) - return varnish_submit_derive (conf->instance, "dirdns", "cache_result", "failed", val); - else if (strcmp(name, "dir_dns_hit") == 0) - return varnish_submit_derive (conf->instance, "dirdns", "cache_result", "hits", val); - else if (strcmp(name, "dir_dns_cache_full") == 0) - return varnish_submit_derive (conf->instance, "dirdns", "cache_result", "cache_full", val); - } + if (conf->collect_dirdns) { + if (strcmp(name, "dir_dns_lookups") == 0) + return varnish_submit_derive(conf->instance, "dirdns", "cache_operation", + "lookups", val); + else if (strcmp(name, "dir_dns_failed") == 0) + return varnish_submit_derive(conf->instance, "dirdns", "cache_result", + "failed", val); + else if (strcmp(name, "dir_dns_hit") == 0) + return varnish_submit_derive(conf->instance, "dirdns", "cache_result", + "hits", val); + else if (strcmp(name, "dir_dns_cache_full") == 0) + return varnish_submit_derive(conf->instance, "dirdns", "cache_result", + "cache_full", val); + } #endif - if (conf->collect_esi) - { - if (strcmp(name, "esi_errors") == 0) - return varnish_submit_derive (conf->instance, "esi", "total_operations", "error", val); - else if (strcmp(name, "esi_parse") == 0) - return varnish_submit_derive (conf->instance, "esi", "total_operations", "parsed", val); - else if (strcmp(name, "esi_warnings") == 0) - return varnish_submit_derive (conf->instance, "esi", "total_operations", "warning", val); - } - - if (conf->collect_backend) - { - if (strcmp(name, "backend_conn") == 0) - return varnish_submit_derive (conf->instance, "backend", "connections", "success", val); - else if (strcmp(name, "backend_unhealthy") == 0) - return varnish_submit_derive (conf->instance, "backend", "connections", "not-attempted", val); - else if (strcmp(name, "backend_busy") == 0) - return varnish_submit_derive (conf->instance, "backend", "connections", "too-many", val); - else if (strcmp(name, "backend_fail") == 0) - return varnish_submit_derive (conf->instance, "backend", "connections", "failures", val); - else if (strcmp(name, "backend_reuse") == 0) - return varnish_submit_derive (conf->instance, "backend", "connections", "reuses", val); - else if (strcmp(name, "backend_toolate") == 0) - return varnish_submit_derive (conf->instance, "backend", "connections", "was-closed", val); - else if (strcmp(name, "backend_recycle") == 0) - return varnish_submit_derive (conf->instance, "backend", "connections", "recycled", val); - else if (strcmp(name, "backend_unused") == 0) - return varnish_submit_derive (conf->instance, "backend", "connections", "unused", val); - else if (strcmp(name, "backend_retry") == 0) - return varnish_submit_derive (conf->instance, "backend", "connections", "retries", val); - else if (strcmp(name, "backend_req") == 0) - return varnish_submit_derive (conf->instance, "backend", "http_requests", "requests", val); - else if (strcmp(name, "n_backend") == 0) - return varnish_submit_gauge (conf->instance, "backend", "backends", "n_backends", val); - } - - if (conf->collect_fetch) - { - if (strcmp(name, "fetch_head") == 0) - return varnish_submit_derive (conf->instance, "fetch", "http_requests", "head", val); - else if (strcmp(name, "fetch_length") == 0) - return varnish_submit_derive (conf->instance, "fetch", "http_requests", "length", val); - else if (strcmp(name, "fetch_chunked") == 0) - return varnish_submit_derive (conf->instance, "fetch", "http_requests", "chunked", val); - else if (strcmp(name, "fetch_eof") == 0) - return varnish_submit_derive (conf->instance, "fetch", "http_requests", "eof", val); - else if (strcmp(name, "fetch_bad") == 0) - return varnish_submit_derive (conf->instance, "fetch", "http_requests", "bad_headers", val); - else if (strcmp(name, "fetch_close") == 0) - return varnish_submit_derive (conf->instance, "fetch", "http_requests", "close", val); - else if (strcmp(name, "fetch_oldhttp") == 0) - return varnish_submit_derive (conf->instance, "fetch", "http_requests", "oldhttp", val); - else if (strcmp(name, "fetch_zero") == 0) - return varnish_submit_derive (conf->instance, "fetch", "http_requests", "zero", val); - else if (strcmp(name, "fetch_failed") == 0) - return varnish_submit_derive (conf->instance, "fetch", "http_requests", "failed", val); - else if (strcmp(name, "fetch_1xx") == 0) - return varnish_submit_derive (conf->instance, "fetch", "http_requests", "no_body_1xx", val); - else if (strcmp(name, "fetch_204") == 0) - return varnish_submit_derive (conf->instance, "fetch", "http_requests", "no_body_204", val); - else if (strcmp(name, "fetch_304") == 0) - return varnish_submit_derive (conf->instance, "fetch", "http_requests", "no_body_304", val); - } - - if (conf->collect_hcb) - { - if (strcmp(name, "hcb_nolock") == 0) - return varnish_submit_derive (conf->instance, "hcb", "cache_operation", "lookup_nolock", val); - else if (strcmp(name, "hcb_lock") == 0) - return varnish_submit_derive (conf->instance, "hcb", "cache_operation", "lookup_lock", val); - else if (strcmp(name, "hcb_insert") == 0) - return varnish_submit_derive (conf->instance, "hcb", "cache_operation", "insert", val); - } - - if (conf->collect_objects) - { - if (strcmp(name, "n_expired") == 0) - return varnish_submit_derive (conf->instance, "objects", "total_objects", "expired", val); - else if (strcmp(name, "n_lru_nuked") == 0) - return varnish_submit_derive (conf->instance, "objects", "total_objects", "lru_nuked", val); - else if (strcmp(name, "n_lru_saved") == 0) - return varnish_submit_derive (conf->instance, "objects", "total_objects", "lru_saved", val); - else if (strcmp(name, "n_lru_moved") == 0) - return varnish_submit_derive (conf->instance, "objects", "total_objects", "lru_moved", val); - else if (strcmp(name, "n_deathrow") == 0) - return varnish_submit_derive (conf->instance, "objects", "total_objects", "deathrow", val); - else if (strcmp(name, "losthdr") == 0) - return varnish_submit_derive (conf->instance, "objects", "total_objects", "header_overflow", val); - else if (strcmp(name, "n_obj_purged") == 0) - return varnish_submit_derive (conf->instance, "objects", "total_objects", "purged", val); - else if (strcmp(name, "n_objsendfile") == 0) - return varnish_submit_derive (conf->instance, "objects", "total_objects", "sent_sendfile", val); - else if (strcmp(name, "n_objwrite") == 0) - return varnish_submit_derive (conf->instance, "objects", "total_objects", "sent_write", val); - else if (strcmp(name, "n_objoverflow") == 0) - return varnish_submit_derive (conf->instance, "objects", "total_objects", "workspace_overflow", val); - } + if (conf->collect_esi) { + if (strcmp(name, "esi_errors") == 0) + return varnish_submit_derive(conf->instance, "esi", "total_operations", + "error", val); + else if (strcmp(name, "esi_parse") == 0) + return varnish_submit_derive(conf->instance, "esi", "total_operations", + "parsed", val); + else if (strcmp(name, "esi_warnings") == 0) + return varnish_submit_derive(conf->instance, "esi", "total_operations", + "warning", val); + } + + if (conf->collect_backend) { + if (strcmp(name, "backend_conn") == 0) + return varnish_submit_derive(conf->instance, "backend", "connections", + "success", val); + else if (strcmp(name, "backend_unhealthy") == 0) + return varnish_submit_derive(conf->instance, "backend", "connections", + "not-attempted", val); + else if (strcmp(name, "backend_busy") == 0) + return varnish_submit_derive(conf->instance, "backend", "connections", + "too-many", val); + else if (strcmp(name, "backend_fail") == 0) + return varnish_submit_derive(conf->instance, "backend", "connections", + "failures", val); + else if (strcmp(name, "backend_reuse") == 0) + return varnish_submit_derive(conf->instance, "backend", "connections", + "reuses", val); + else if (strcmp(name, "backend_toolate") == 0) + return varnish_submit_derive(conf->instance, "backend", "connections", + "was-closed", val); + else if (strcmp(name, "backend_recycle") == 0) + return varnish_submit_derive(conf->instance, "backend", "connections", + "recycled", val); + else if (strcmp(name, "backend_unused") == 0) + return varnish_submit_derive(conf->instance, "backend", "connections", + "unused", val); + else if (strcmp(name, "backend_retry") == 0) + return varnish_submit_derive(conf->instance, "backend", "connections", + "retries", val); + else if (strcmp(name, "backend_req") == 0) + return varnish_submit_derive(conf->instance, "backend", "http_requests", + "requests", val); + else if (strcmp(name, "n_backend") == 0) + return varnish_submit_gauge(conf->instance, "backend", "backends", + "n_backends", val); + } + + if (conf->collect_fetch) { + if (strcmp(name, "fetch_head") == 0) + return varnish_submit_derive(conf->instance, "fetch", "http_requests", + "head", val); + else if (strcmp(name, "fetch_length") == 0) + return varnish_submit_derive(conf->instance, "fetch", "http_requests", + "length", val); + else if (strcmp(name, "fetch_chunked") == 0) + return varnish_submit_derive(conf->instance, "fetch", "http_requests", + "chunked", val); + else if (strcmp(name, "fetch_eof") == 0) + return varnish_submit_derive(conf->instance, "fetch", "http_requests", + "eof", val); + else if (strcmp(name, "fetch_bad") == 0) + return varnish_submit_derive(conf->instance, "fetch", "http_requests", + "bad_headers", val); + else if (strcmp(name, "fetch_close") == 0) + return varnish_submit_derive(conf->instance, "fetch", "http_requests", + "close", val); + else if (strcmp(name, "fetch_oldhttp") == 0) + return varnish_submit_derive(conf->instance, "fetch", "http_requests", + "oldhttp", val); + else if (strcmp(name, "fetch_zero") == 0) + return varnish_submit_derive(conf->instance, "fetch", "http_requests", + "zero", val); + else if (strcmp(name, "fetch_failed") == 0) + return varnish_submit_derive(conf->instance, "fetch", "http_requests", + "failed", val); + else if (strcmp(name, "fetch_1xx") == 0) + return varnish_submit_derive(conf->instance, "fetch", "http_requests", + "no_body_1xx", val); + else if (strcmp(name, "fetch_204") == 0) + return varnish_submit_derive(conf->instance, "fetch", "http_requests", + "no_body_204", val); + else if (strcmp(name, "fetch_304") == 0) + return varnish_submit_derive(conf->instance, "fetch", "http_requests", + "no_body_304", val); + } + + if (conf->collect_hcb) { + if (strcmp(name, "hcb_nolock") == 0) + return varnish_submit_derive(conf->instance, "hcb", "cache_operation", + "lookup_nolock", val); + else if (strcmp(name, "hcb_lock") == 0) + return varnish_submit_derive(conf->instance, "hcb", "cache_operation", + "lookup_lock", val); + else if (strcmp(name, "hcb_insert") == 0) + return varnish_submit_derive(conf->instance, "hcb", "cache_operation", + "insert", val); + } + + if (conf->collect_objects) { + if (strcmp(name, "n_expired") == 0) + return varnish_submit_derive(conf->instance, "objects", "total_objects", + "expired", val); + else if (strcmp(name, "n_lru_nuked") == 0) + return varnish_submit_derive(conf->instance, "objects", "total_objects", + "lru_nuked", val); + else if (strcmp(name, "n_lru_saved") == 0) + return varnish_submit_derive(conf->instance, "objects", "total_objects", + "lru_saved", val); + else if (strcmp(name, "n_lru_moved") == 0) + return varnish_submit_derive(conf->instance, "objects", "total_objects", + "lru_moved", val); + else if (strcmp(name, "n_deathrow") == 0) + return varnish_submit_derive(conf->instance, "objects", "total_objects", + "deathrow", val); + else if (strcmp(name, "losthdr") == 0) + return varnish_submit_derive(conf->instance, "objects", "total_objects", + "header_overflow", val); + else if (strcmp(name, "n_obj_purged") == 0) + return varnish_submit_derive(conf->instance, "objects", "total_objects", + "purged", val); + else if (strcmp(name, "n_objsendfile") == 0) + return varnish_submit_derive(conf->instance, "objects", "total_objects", + "sent_sendfile", val); + else if (strcmp(name, "n_objwrite") == 0) + return varnish_submit_derive(conf->instance, "objects", "total_objects", + "sent_write", val); + else if (strcmp(name, "n_objoverflow") == 0) + return varnish_submit_derive(conf->instance, "objects", "total_objects", + "workspace_overflow", val); + } #if HAVE_VARNISH_V3 - if (conf->collect_ban) - { - if (strcmp(name, "n_ban") == 0) - return varnish_submit_derive (conf->instance, "ban", "total_operations", "total", val); - else if (strcmp(name, "n_ban_add") == 0) - return varnish_submit_derive (conf->instance, "ban", "total_operations", "added", val); - else if (strcmp(name, "n_ban_retire") == 0) - return varnish_submit_derive (conf->instance, "ban", "total_operations", "deleted", val); - else if (strcmp(name, "n_ban_obj_test") == 0) - return varnish_submit_derive (conf->instance, "ban", "total_operations", "objects_tested", val); - else if (strcmp(name, "n_ban_re_test") == 0) - return varnish_submit_derive (conf->instance, "ban", "total_operations", "regexps_tested", val); - else if (strcmp(name, "n_ban_dups") == 0) - return varnish_submit_derive (conf->instance, "ban", "total_operations", "duplicate", val); - } + if (conf->collect_ban) { + if (strcmp(name, "n_ban") == 0) + return varnish_submit_derive(conf->instance, "ban", "total_operations", + "total", val); + else if (strcmp(name, "n_ban_add") == 0) + return varnish_submit_derive(conf->instance, "ban", "total_operations", + "added", val); + else if (strcmp(name, "n_ban_retire") == 0) + return varnish_submit_derive(conf->instance, "ban", "total_operations", + "deleted", val); + else if (strcmp(name, "n_ban_obj_test") == 0) + return varnish_submit_derive(conf->instance, "ban", "total_operations", + "objects_tested", val); + else if (strcmp(name, "n_ban_re_test") == 0) + return varnish_submit_derive(conf->instance, "ban", "total_operations", + "regexps_tested", val); + else if (strcmp(name, "n_ban_dups") == 0) + return varnish_submit_derive(conf->instance, "ban", "total_operations", + "duplicate", val); + } #endif #if HAVE_VARNISH_V4 - if (conf->collect_ban) - { - if (strcmp(name, "bans") == 0) - return varnish_submit_derive (conf->instance, "ban", "total_operations", "total", val); - else if (strcmp(name, "bans_added") == 0) - return varnish_submit_derive (conf->instance, "ban", "total_operations", "added", val); - else if (strcmp(name, "bans_obj") == 0) - return varnish_submit_derive (conf->instance, "ban", "total_operations", "obj", val); - else if (strcmp(name, "bans_req") == 0) - return varnish_submit_derive (conf->instance, "ban", "total_operations", "req", val); - else if (strcmp(name, "bans_completed") == 0) - return varnish_submit_derive (conf->instance, "ban", "total_operations", "completed", val); - else if (strcmp(name, "bans_deleted") == 0) - return varnish_submit_derive (conf->instance, "ban", "total_operations", "deleted", val); - else if (strcmp(name, "bans_tested") == 0) - return varnish_submit_derive (conf->instance, "ban", "total_operations", "tested", val); - else if (strcmp(name, "bans_dups") == 0) - return varnish_submit_derive (conf->instance, "ban", "total_operations", "duplicate", val); - } + if (conf->collect_ban) { + if (strcmp(name, "bans") == 0) + return varnish_submit_derive(conf->instance, "ban", "total_operations", + "total", val); + else if (strcmp(name, "bans_added") == 0) + return varnish_submit_derive(conf->instance, "ban", "total_operations", + "added", val); + else if (strcmp(name, "bans_obj") == 0) + return varnish_submit_derive(conf->instance, "ban", "total_operations", + "obj", val); + else if (strcmp(name, "bans_req") == 0) + return varnish_submit_derive(conf->instance, "ban", "total_operations", + "req", val); + else if (strcmp(name, "bans_completed") == 0) + return varnish_submit_derive(conf->instance, "ban", "total_operations", + "completed", val); + else if (strcmp(name, "bans_deleted") == 0) + return varnish_submit_derive(conf->instance, "ban", "total_operations", + "deleted", val); + else if (strcmp(name, "bans_tested") == 0) + return varnish_submit_derive(conf->instance, "ban", "total_operations", + "tested", val); + else if (strcmp(name, "bans_dups") == 0) + return varnish_submit_derive(conf->instance, "ban", "total_operations", + "duplicate", val); + } #endif - if (conf->collect_session) - { - if (strcmp(name, "sess_closed") == 0) - return varnish_submit_derive (conf->instance, "session", "total_operations", "closed", val); - else if (strcmp(name, "sess_pipeline") == 0) - return varnish_submit_derive (conf->instance, "session", "total_operations", "pipeline", val); - else if (strcmp(name, "sess_readahead") == 0) - return varnish_submit_derive (conf->instance, "session", "total_operations", "readahead", val); - else if (strcmp(name, "sess_conn") == 0) - return varnish_submit_derive (conf->instance, "session", "total_operations", "accepted", val); - else if (strcmp(name, "sess_drop") == 0) - return varnish_submit_derive (conf->instance, "session", "total_operations", "dropped", val); - else if (strcmp(name, "sess_fail") == 0) - return varnish_submit_derive (conf->instance, "session", "total_operations", "failed", val); - else if (strcmp(name, "sess_pipe_overflow") == 0) - return varnish_submit_derive (conf->instance, "session", "total_operations", "overflow", val); - else if (strcmp(name, "sess_queued") == 0) - return varnish_submit_derive (conf->instance, "session", "total_operations", "queued", val); - else if (strcmp(name, "sess_linger") == 0) - return varnish_submit_derive (conf->instance, "session", "total_operations", "linger", val); - else if (strcmp(name, "sess_herd") == 0) - return varnish_submit_derive (conf->instance, "session", "total_operations", "herd", val); - } - - if (conf->collect_shm) - { - if (strcmp(name, "shm_records") == 0) - return varnish_submit_derive (conf->instance, "shm", "total_operations", "records", val); - else if (strcmp(name, "shm_writes") == 0) - return varnish_submit_derive (conf->instance, "shm", "total_operations", "writes", val); - else if (strcmp(name, "shm_flushes") == 0) - return varnish_submit_derive (conf->instance, "shm", "total_operations", "flushes", val); - else if (strcmp(name, "shm_cont") == 0) - return varnish_submit_derive (conf->instance, "shm", "total_operations", "contention", val); - else if (strcmp(name, "shm_cycles") == 0) - return varnish_submit_derive (conf->instance, "shm", "total_operations", "cycles", val); - } - - if (conf->collect_sms) - { - if (strcmp(name, "sms_nreq") == 0) - return varnish_submit_derive (conf->instance, "sms", "total_requests", "allocator", val); - else if (strcmp(name, "sms_nobj") == 0) - return varnish_submit_gauge (conf->instance, "sms", "requests", "outstanding", val); - else if (strcmp(name, "sms_nbytes") == 0) - return varnish_submit_gauge (conf->instance, "sms", "bytes", "outstanding", val); - else if (strcmp(name, "sms_balloc") == 0) - return varnish_submit_derive (conf->instance, "sms", "total_bytes", "allocated", val); - else if (strcmp(name, "sms_bfree") == 0) - return varnish_submit_derive (conf->instance, "sms", "total_bytes", "free", val); - } - - if (conf->collect_struct) - { - if (strcmp(name, "n_sess_mem") == 0) - return varnish_submit_gauge (conf->instance, "struct", "current_sessions", "sess_mem", val); - else if (strcmp(name, "n_sess") == 0) - return varnish_submit_gauge (conf->instance, "struct", "current_sessions", "sess", val); - else if (strcmp(name, "n_object") == 0) - return varnish_submit_gauge (conf->instance, "struct", "objects", "object", val); - else if (strcmp(name, "n_vampireobject") == 0) - return varnish_submit_gauge (conf->instance, "struct", "objects", "vampireobject", val); - else if (strcmp(name, "n_objectcore") == 0) - return varnish_submit_gauge (conf->instance, "struct", "objects", "objectcore", val); - else if (strcmp(name, "n_waitinglist") == 0) - return varnish_submit_gauge (conf->instance, "struct", "objects", "waitinglist", val); - else if (strcmp(name, "n_objecthead") == 0) - return varnish_submit_gauge (conf->instance, "struct", "objects", "objecthead", val); - else if (strcmp(name, "n_smf") == 0) - return varnish_submit_gauge (conf->instance, "struct", "objects", "smf", val); - else if (strcmp(name, "n_smf_frag") == 0) - return varnish_submit_gauge (conf->instance, "struct", "objects", "smf_frag", val); - else if (strcmp(name, "n_smf_large") == 0) - return varnish_submit_gauge (conf->instance, "struct", "objects", "smf_large", val); - else if (strcmp(name, "n_vbe_conn") == 0) - return varnish_submit_gauge (conf->instance, "struct", "objects", "vbe_conn", val); - } - - if (conf->collect_totals) - { - if (strcmp(name, "s_sess") == 0) - return varnish_submit_derive (conf->instance, "totals", "total_sessions", "sessions", val); - else if (strcmp(name, "s_req") == 0) - return varnish_submit_derive (conf->instance, "totals", "total_requests", "requests", val); - else if (strcmp(name, "s_pipe") == 0) - return varnish_submit_derive (conf->instance, "totals", "total_operations", "pipe", val); - else if (strcmp(name, "s_pass") == 0) - return varnish_submit_derive (conf->instance, "totals", "total_operations", "pass", val); - else if (strcmp(name, "s_fetch") == 0) - return varnish_submit_derive (conf->instance, "totals", "total_operations", "fetches", val); - else if (strcmp(name, "s_synth") == 0) - return varnish_submit_derive (conf->instance, "totals", "total_bytes", "synth", val); - else if (strcmp(name, "s_req_hdrbytes") == 0) - return varnish_submit_derive (conf->instance, "totals", "total_bytes", "req_header", val); - else if (strcmp(name, "s_req_bodybytes") == 0) - return varnish_submit_derive (conf->instance, "totals", "total_bytes", "req_body", val); - else if (strcmp(name, "s_resp_hdrbytes") == 0) - return varnish_submit_derive (conf->instance, "totals", "total_bytes", "resp_header", val); - else if (strcmp(name, "s_resp_bodybytes") == 0) - return varnish_submit_derive (conf->instance, "totals", "total_bytes", "resp_body", val); - else if (strcmp(name, "s_pipe_hdrbytes") == 0) - return varnish_submit_derive (conf->instance, "totals", "total_bytes", "pipe_header", val); - else if (strcmp(name, "s_pipe_in") == 0) - return varnish_submit_derive (conf->instance, "totals", "total_bytes", "pipe_in", val); - else if (strcmp(name, "s_pipe_out") == 0) - return varnish_submit_derive (conf->instance, "totals", "total_bytes", "pipe_out", val); - else if (strcmp(name, "n_purges") == 0) - return varnish_submit_derive (conf->instance, "totals", "total_operations", "purges", val); - else if (strcmp(name, "s_hdrbytes") == 0) - return varnish_submit_derive (conf->instance, "totals", "total_bytes", "header-bytes", val); - else if (strcmp(name, "s_bodybytes") == 0) - return varnish_submit_derive (conf->instance, "totals", "total_bytes", "body-bytes", val); - else if (strcmp(name, "n_gzip") == 0) - return varnish_submit_derive (conf->instance, "totals", "total_operations", "gzip", val); - else if (strcmp(name, "n_gunzip") == 0) - return varnish_submit_derive (conf->instance, "totals", "total_operations", "gunzip", val); - } - - if (conf->collect_uptime) - { - if (strcmp(name, "uptime") == 0) - return varnish_submit_gauge (conf->instance, "uptime", "uptime", "client_uptime", val); - } - - if (conf->collect_vcl) - { - if (strcmp(name, "n_vcl") == 0) - return varnish_submit_gauge (conf->instance, "vcl", "vcl", "total_vcl", val); - else if (strcmp(name, "n_vcl_avail") == 0) - return varnish_submit_gauge (conf->instance, "vcl", "vcl", "avail_vcl", val); - else if (strcmp(name, "n_vcl_discard") == 0) - return varnish_submit_gauge (conf->instance, "vcl", "vcl", "discarded_vcl", val); - else if (strcmp(name, "vmods") == 0) - return varnish_submit_gauge (conf->instance, "vcl", "objects", "vmod", val); - } - - if (conf->collect_workers) - { - if (strcmp(name, "threads") == 0) - return varnish_submit_gauge (conf->instance, "workers", "threads", "worker", val); - else if (strcmp(name, "threads_created") == 0) - return varnish_submit_derive (conf->instance, "workers", "total_threads", "created", val); - else if (strcmp(name, "threads_failed") == 0) - return varnish_submit_derive (conf->instance, "workers", "total_threads", "failed", val); - else if (strcmp(name, "threads_limited") == 0) - return varnish_submit_derive (conf->instance, "workers", "total_threads", "limited", val); - else if (strcmp(name, "threads_destroyed") == 0) - return varnish_submit_derive (conf->instance, "workers", "total_threads", "dropped", val); - else if (strcmp(name, "thread_queue_len") == 0) - return varnish_submit_derive (conf->instance, "workers", "queue_length", "threads", val); - else if (strcmp(name, "n_wrk") == 0) - return varnish_submit_gauge (conf->instance, "workers", "threads", "worker", val); - else if (strcmp(name, "n_wrk_create") == 0) - return varnish_submit_derive (conf->instance, "workers", "total_threads", "created", val); - else if (strcmp(name, "n_wrk_failed") == 0) - return varnish_submit_derive (conf->instance, "workers", "total_threads", "failed", val); - else if (strcmp(name, "n_wrk_max") == 0) - return varnish_submit_derive (conf->instance, "workers", "total_threads", "limited", val); - else if (strcmp(name, "n_wrk_drop") == 0) - return varnish_submit_derive (conf->instance, "workers", "total_threads", "dropped", val); - else if (strcmp(name, "n_wrk_queue") == 0) - return varnish_submit_derive (conf->instance, "workers", "total_requests", "queued", val); - else if (strcmp(name, "n_wrk_overflow") == 0) - return varnish_submit_derive (conf->instance, "workers", "total_requests", "overflowed", val); - else if (strcmp(name, "n_wrk_queued") == 0) - return varnish_submit_derive (conf->instance, "workers", "total_requests", "queued", val); - else if (strcmp(name, "n_wrk_lqueue") == 0) - return varnish_submit_derive (conf->instance, "workers", "total_requests", "queue_length", val); - } + if (conf->collect_session) { + if (strcmp(name, "sess_closed") == 0) + return varnish_submit_derive(conf->instance, "session", + "total_operations", "closed", val); + else if (strcmp(name, "sess_pipeline") == 0) + return varnish_submit_derive(conf->instance, "session", + "total_operations", "pipeline", val); + else if (strcmp(name, "sess_readahead") == 0) + return varnish_submit_derive(conf->instance, "session", + "total_operations", "readahead", val); + else if (strcmp(name, "sess_conn") == 0) + return varnish_submit_derive(conf->instance, "session", + "total_operations", "accepted", val); + else if (strcmp(name, "sess_drop") == 0) + return varnish_submit_derive(conf->instance, "session", + "total_operations", "dropped", val); + else if (strcmp(name, "sess_fail") == 0) + return varnish_submit_derive(conf->instance, "session", + "total_operations", "failed", val); + else if (strcmp(name, "sess_pipe_overflow") == 0) + return varnish_submit_derive(conf->instance, "session", + "total_operations", "overflow", val); + else if (strcmp(name, "sess_queued") == 0) + return varnish_submit_derive(conf->instance, "session", + "total_operations", "queued", val); + else if (strcmp(name, "sess_linger") == 0) + return varnish_submit_derive(conf->instance, "session", + "total_operations", "linger", val); + else if (strcmp(name, "sess_herd") == 0) + return varnish_submit_derive(conf->instance, "session", + "total_operations", "herd", val); + } + + if (conf->collect_shm) { + if (strcmp(name, "shm_records") == 0) + return varnish_submit_derive(conf->instance, "shm", "total_operations", + "records", val); + else if (strcmp(name, "shm_writes") == 0) + return varnish_submit_derive(conf->instance, "shm", "total_operations", + "writes", val); + else if (strcmp(name, "shm_flushes") == 0) + return varnish_submit_derive(conf->instance, "shm", "total_operations", + "flushes", val); + else if (strcmp(name, "shm_cont") == 0) + return varnish_submit_derive(conf->instance, "shm", "total_operations", + "contention", val); + else if (strcmp(name, "shm_cycles") == 0) + return varnish_submit_derive(conf->instance, "shm", "total_operations", + "cycles", val); + } + + if (conf->collect_sms) { + if (strcmp(name, "sms_nreq") == 0) + return varnish_submit_derive(conf->instance, "sms", "total_requests", + "allocator", val); + else if (strcmp(name, "sms_nobj") == 0) + return varnish_submit_gauge(conf->instance, "sms", "requests", + "outstanding", val); + else if (strcmp(name, "sms_nbytes") == 0) + return varnish_submit_gauge(conf->instance, "sms", "bytes", "outstanding", + val); + else if (strcmp(name, "sms_balloc") == 0) + return varnish_submit_derive(conf->instance, "sms", "total_bytes", + "allocated", val); + else if (strcmp(name, "sms_bfree") == 0) + return varnish_submit_derive(conf->instance, "sms", "total_bytes", "free", + val); + } + + if (conf->collect_struct) { + if (strcmp(name, "n_sess_mem") == 0) + return varnish_submit_gauge(conf->instance, "struct", "current_sessions", + "sess_mem", val); + else if (strcmp(name, "n_sess") == 0) + return varnish_submit_gauge(conf->instance, "struct", "current_sessions", + "sess", val); + else if (strcmp(name, "n_object") == 0) + return varnish_submit_gauge(conf->instance, "struct", "objects", "object", + val); + else if (strcmp(name, "n_vampireobject") == 0) + return varnish_submit_gauge(conf->instance, "struct", "objects", + "vampireobject", val); + else if (strcmp(name, "n_objectcore") == 0) + return varnish_submit_gauge(conf->instance, "struct", "objects", + "objectcore", val); + else if (strcmp(name, "n_waitinglist") == 0) + return varnish_submit_gauge(conf->instance, "struct", "objects", + "waitinglist", val); + else if (strcmp(name, "n_objecthead") == 0) + return varnish_submit_gauge(conf->instance, "struct", "objects", + "objecthead", val); + else if (strcmp(name, "n_smf") == 0) + return varnish_submit_gauge(conf->instance, "struct", "objects", "smf", + val); + else if (strcmp(name, "n_smf_frag") == 0) + return varnish_submit_gauge(conf->instance, "struct", "objects", + "smf_frag", val); + else if (strcmp(name, "n_smf_large") == 0) + return varnish_submit_gauge(conf->instance, "struct", "objects", + "smf_large", val); + else if (strcmp(name, "n_vbe_conn") == 0) + return varnish_submit_gauge(conf->instance, "struct", "objects", + "vbe_conn", val); + } + + if (conf->collect_totals) { + if (strcmp(name, "s_sess") == 0) + return varnish_submit_derive(conf->instance, "totals", "total_sessions", + "sessions", val); + else if (strcmp(name, "s_req") == 0) + return varnish_submit_derive(conf->instance, "totals", "total_requests", + "requests", val); + else if (strcmp(name, "s_pipe") == 0) + return varnish_submit_derive(conf->instance, "totals", "total_operations", + "pipe", val); + else if (strcmp(name, "s_pass") == 0) + return varnish_submit_derive(conf->instance, "totals", "total_operations", + "pass", val); + else if (strcmp(name, "s_fetch") == 0) + return varnish_submit_derive(conf->instance, "totals", "total_operations", + "fetches", val); + else if (strcmp(name, "s_synth") == 0) + return varnish_submit_derive(conf->instance, "totals", "total_bytes", + "synth", val); + else if (strcmp(name, "s_req_hdrbytes") == 0) + return varnish_submit_derive(conf->instance, "totals", "total_bytes", + "req_header", val); + else if (strcmp(name, "s_req_bodybytes") == 0) + return varnish_submit_derive(conf->instance, "totals", "total_bytes", + "req_body", val); + else if (strcmp(name, "s_resp_hdrbytes") == 0) + return varnish_submit_derive(conf->instance, "totals", "total_bytes", + "resp_header", val); + else if (strcmp(name, "s_resp_bodybytes") == 0) + return varnish_submit_derive(conf->instance, "totals", "total_bytes", + "resp_body", val); + else if (strcmp(name, "s_pipe_hdrbytes") == 0) + return varnish_submit_derive(conf->instance, "totals", "total_bytes", + "pipe_header", val); + else if (strcmp(name, "s_pipe_in") == 0) + return varnish_submit_derive(conf->instance, "totals", "total_bytes", + "pipe_in", val); + else if (strcmp(name, "s_pipe_out") == 0) + return varnish_submit_derive(conf->instance, "totals", "total_bytes", + "pipe_out", val); + else if (strcmp(name, "n_purges") == 0) + return varnish_submit_derive(conf->instance, "totals", "total_operations", + "purges", val); + else if (strcmp(name, "s_hdrbytes") == 0) + return varnish_submit_derive(conf->instance, "totals", "total_bytes", + "header-bytes", val); + else if (strcmp(name, "s_bodybytes") == 0) + return varnish_submit_derive(conf->instance, "totals", "total_bytes", + "body-bytes", val); + else if (strcmp(name, "n_gzip") == 0) + return varnish_submit_derive(conf->instance, "totals", "total_operations", + "gzip", val); + else if (strcmp(name, "n_gunzip") == 0) + return varnish_submit_derive(conf->instance, "totals", "total_operations", + "gunzip", val); + } + + if (conf->collect_uptime) { + if (strcmp(name, "uptime") == 0) + return varnish_submit_gauge(conf->instance, "uptime", "uptime", + "client_uptime", val); + } + + if (conf->collect_vcl) { + if (strcmp(name, "n_vcl") == 0) + return varnish_submit_gauge(conf->instance, "vcl", "vcl", "total_vcl", + val); + else if (strcmp(name, "n_vcl_avail") == 0) + return varnish_submit_gauge(conf->instance, "vcl", "vcl", "avail_vcl", + val); + else if (strcmp(name, "n_vcl_discard") == 0) + return varnish_submit_gauge(conf->instance, "vcl", "vcl", "discarded_vcl", + val); + else if (strcmp(name, "vmods") == 0) + return varnish_submit_gauge(conf->instance, "vcl", "objects", "vmod", + val); + } + + if (conf->collect_workers) { + if (strcmp(name, "threads") == 0) + return varnish_submit_gauge(conf->instance, "workers", "threads", + "worker", val); + else if (strcmp(name, "threads_created") == 0) + return varnish_submit_derive(conf->instance, "workers", "total_threads", + "created", val); + else if (strcmp(name, "threads_failed") == 0) + return varnish_submit_derive(conf->instance, "workers", "total_threads", + "failed", val); + else if (strcmp(name, "threads_limited") == 0) + return varnish_submit_derive(conf->instance, "workers", "total_threads", + "limited", val); + else if (strcmp(name, "threads_destroyed") == 0) + return varnish_submit_derive(conf->instance, "workers", "total_threads", + "dropped", val); + else if (strcmp(name, "thread_queue_len") == 0) + return varnish_submit_derive(conf->instance, "workers", "queue_length", + "threads", val); + else if (strcmp(name, "n_wrk") == 0) + return varnish_submit_gauge(conf->instance, "workers", "threads", + "worker", val); + else if (strcmp(name, "n_wrk_create") == 0) + return varnish_submit_derive(conf->instance, "workers", "total_threads", + "created", val); + else if (strcmp(name, "n_wrk_failed") == 0) + return varnish_submit_derive(conf->instance, "workers", "total_threads", + "failed", val); + else if (strcmp(name, "n_wrk_max") == 0) + return varnish_submit_derive(conf->instance, "workers", "total_threads", + "limited", val); + else if (strcmp(name, "n_wrk_drop") == 0) + return varnish_submit_derive(conf->instance, "workers", "total_threads", + "dropped", val); + else if (strcmp(name, "n_wrk_queue") == 0) + return varnish_submit_derive(conf->instance, "workers", "total_requests", + "queued", val); + else if (strcmp(name, "n_wrk_overflow") == 0) + return varnish_submit_derive(conf->instance, "workers", "total_requests", + "overflowed", val); + else if (strcmp(name, "n_wrk_queued") == 0) + return varnish_submit_derive(conf->instance, "workers", "total_requests", + "queued", val); + else if (strcmp(name, "n_wrk_lqueue") == 0) + return varnish_submit_derive(conf->instance, "workers", "total_requests", + "queue_length", val); + } #if HAVE_VARNISH_V4 - if (conf->collect_vsm) - { - if (strcmp(name, "vsm_free") == 0) - return varnish_submit_gauge (conf->instance, "vsm", "bytes", "free", val); - else if (strcmp(name, "vsm_used") == 0) - return varnish_submit_gauge (conf->instance, "vsm", "bytes", "used", val); - else if (strcmp(name, "vsm_cooling") == 0) - return varnish_submit_gauge (conf->instance, "vsm", "bytes", "cooling", val); - else if (strcmp(name, "vsm_overflow") == 0) - return varnish_submit_gauge (conf->instance, "vsm", "bytes", "overflow", val); - else if (strcmp(name, "vsm_overflowed") == 0) - return varnish_submit_derive (conf->instance, "vsm", "total_bytes", "overflowed", val); - } + if (conf->collect_vsm) { + if (strcmp(name, "vsm_free") == 0) + return varnish_submit_gauge(conf->instance, "vsm", "bytes", "free", val); + else if (strcmp(name, "vsm_used") == 0) + return varnish_submit_gauge(conf->instance, "vsm", "bytes", "used", val); + else if (strcmp(name, "vsm_cooling") == 0) + return varnish_submit_gauge(conf->instance, "vsm", "bytes", "cooling", + val); + else if (strcmp(name, "vsm_overflow") == 0) + return varnish_submit_gauge(conf->instance, "vsm", "bytes", "overflow", + val); + else if (strcmp(name, "vsm_overflowed") == 0) + return varnish_submit_derive(conf->instance, "vsm", "total_bytes", + "overflowed", val); + } #endif - return (0); + return (0); } /* }}} static int varnish_monitor */ #else /* if HAVE_VARNISH_V2 */ -static void varnish_monitor (const user_config_t *conf, /* {{{ */ - const c_varnish_stats_t *stats) -{ - if (conf->collect_cache) - { - /* Cache hits */ - varnish_submit_derive (conf->instance, "cache", "cache_result", "hit", stats->cache_hit); - /* Cache misses */ - varnish_submit_derive (conf->instance, "cache", "cache_result", "miss", stats->cache_miss); - /* Cache hits for pass */ - varnish_submit_derive (conf->instance, "cache", "cache_result", "hitpass", stats->cache_hitpass); - } - - if (conf->collect_connections) - { - /* Client connections accepted */ - varnish_submit_derive (conf->instance, "connections", "connections", "accepted", stats->client_conn); - /* Connection dropped, no sess */ - varnish_submit_derive (conf->instance, "connections", "connections", "dropped" , stats->client_drop); - /* Client requests received */ - varnish_submit_derive (conf->instance, "connections", "connections", "received", stats->client_req); - } - - if (conf->collect_esi) - { - /* ESI parse errors (unlock) */ - varnish_submit_derive (conf->instance, "esi", "total_operations", "error", stats->esi_errors); - /* Objects ESI parsed (unlock) */ - varnish_submit_derive (conf->instance, "esi", "total_operations", "parsed", stats->esi_parse); - } - - if (conf->collect_backend) - { - /* Backend conn. success */ - varnish_submit_derive (conf->instance, "backend", "connections", "success" , stats->backend_conn); - /* Backend conn. not attempted */ - varnish_submit_derive (conf->instance, "backend", "connections", "not-attempted", stats->backend_unhealthy); - /* Backend conn. too many */ - varnish_submit_derive (conf->instance, "backend", "connections", "too-many" , stats->backend_busy); - /* Backend conn. failures */ - varnish_submit_derive (conf->instance, "backend", "connections", "failures" , stats->backend_fail); - /* Backend conn. reuses */ - varnish_submit_derive (conf->instance, "backend", "connections", "reuses" , stats->backend_reuse); - /* Backend conn. was closed */ - varnish_submit_derive (conf->instance, "backend", "connections", "was-closed" , stats->backend_toolate); - /* Backend conn. recycles */ - varnish_submit_derive (conf->instance, "backend", "connections", "recycled" , stats->backend_recycle); - /* Backend conn. unused */ - varnish_submit_derive (conf->instance, "backend", "connections", "unused" , stats->backend_unused); - /* Backend requests mades */ - varnish_submit_derive (conf->instance, "backend", "http_requests", "requests" , stats->backend_req); - /* N backends */ - varnish_submit_gauge (conf->instance, "backend", "backends", "n_backends" , stats->n_backend); - } - - if (conf->collect_fetch) - { - /* Fetch head */ - varnish_submit_derive (conf->instance, "fetch", "http_requests", "head" , stats->fetch_head); - /* Fetch with length */ - varnish_submit_derive (conf->instance, "fetch", "http_requests", "length" , stats->fetch_length); - /* Fetch chunked */ - varnish_submit_derive (conf->instance, "fetch", "http_requests", "chunked" , stats->fetch_chunked); - /* Fetch EOF */ - varnish_submit_derive (conf->instance, "fetch", "http_requests", "eof" , stats->fetch_eof); - /* Fetch bad headers */ - varnish_submit_derive (conf->instance, "fetch", "http_requests", "bad_headers", stats->fetch_bad); - /* Fetch wanted close */ - varnish_submit_derive (conf->instance, "fetch", "http_requests", "close" , stats->fetch_close); - /* Fetch pre HTTP/1.1 closed */ - varnish_submit_derive (conf->instance, "fetch", "http_requests", "oldhttp" , stats->fetch_oldhttp); - /* Fetch zero len */ - varnish_submit_derive (conf->instance, "fetch", "http_requests", "zero" , stats->fetch_zero); - /* Fetch failed */ - varnish_submit_derive (conf->instance, "fetch", "http_requests", "failed" , stats->fetch_failed); - } - - if (conf->collect_hcb) - { - /* HCB Lookups without lock */ - varnish_submit_derive (conf->instance, "hcb", "cache_operation", "lookup_nolock", stats->hcb_nolock); - /* HCB Lookups with lock */ - varnish_submit_derive (conf->instance, "hcb", "cache_operation", "lookup_lock", stats->hcb_lock); - /* HCB Inserts */ - varnish_submit_derive (conf->instance, "hcb", "cache_operation", "insert", stats->hcb_insert); - } - - if (conf->collect_objects) - { - /* N expired objects */ - varnish_submit_derive (conf->instance, "objects", "total_objects", "expired", stats->n_expired); - /* N LRU nuked objects */ - varnish_submit_derive (conf->instance, "objects", "total_objects", "lru_nuked", stats->n_lru_nuked); - /* N LRU saved objects */ - varnish_submit_derive (conf->instance, "objects", "total_objects", "lru_saved", stats->n_lru_saved); - /* N LRU moved objects */ - varnish_submit_derive (conf->instance, "objects", "total_objects", "lru_moved", stats->n_lru_moved); - /* N objects on deathrow */ - varnish_submit_derive (conf->instance, "objects", "total_objects", "deathrow", stats->n_deathrow); - /* HTTP header overflows */ - varnish_submit_derive (conf->instance, "objects", "total_objects", "header_overflow", stats->losthdr); - /* Objects sent with sendfile */ - varnish_submit_derive (conf->instance, "objects", "total_objects", "sent_sendfile", stats->n_objsendfile); - /* Objects sent with write */ - varnish_submit_derive (conf->instance, "objects", "total_objects", "sent_write", stats->n_objwrite); - /* Objects overflowing workspace */ - varnish_submit_derive (conf->instance, "objects", "total_objects", "workspace_overflow", stats->n_objoverflow); - } - - if (conf->collect_purge) - { - /* N total active purges */ - varnish_submit_derive (conf->instance, "purge", "total_operations", "total", stats->n_purge); - /* N new purges added */ - varnish_submit_derive (conf->instance, "purge", "total_operations", "added", stats->n_purge_add); - /* N old purges deleted */ - varnish_submit_derive (conf->instance, "purge", "total_operations", "deleted", stats->n_purge_retire); - /* N objects tested */ - varnish_submit_derive (conf->instance, "purge", "total_operations", "objects_tested", stats->n_purge_obj_test); - /* N regexps tested against */ - varnish_submit_derive (conf->instance, "purge", "total_operations", "regexps_tested", stats->n_purge_re_test); - /* N duplicate purges removed */ - varnish_submit_derive (conf->instance, "purge", "total_operations", "duplicate", stats->n_purge_dups); - } - - if (conf->collect_session) - { - /* Session Closed */ - varnish_submit_derive (conf->instance, "session", "total_operations", "closed", stats->sess_closed); - /* Session Pipeline */ - varnish_submit_derive (conf->instance, "session", "total_operations", "pipeline", stats->sess_pipeline); - /* Session Read Ahead */ - varnish_submit_derive (conf->instance, "session", "total_operations", "readahead", stats->sess_readahead); - /* Session Linger */ - varnish_submit_derive (conf->instance, "session", "total_operations", "linger", stats->sess_linger); - /* Session herd */ - varnish_submit_derive (conf->instance, "session", "total_operations", "herd", stats->sess_herd); - } - - if (conf->collect_shm) - { - /* SHM records */ - varnish_submit_derive (conf->instance, "shm", "total_operations", "records" , stats->shm_records); - /* SHM writes */ - varnish_submit_derive (conf->instance, "shm", "total_operations", "writes" , stats->shm_writes); - /* SHM flushes due to overflow */ - varnish_submit_derive (conf->instance, "shm", "total_operations", "flushes" , stats->shm_flushes); - /* SHM MTX contention */ - varnish_submit_derive (conf->instance, "shm", "total_operations", "contention", stats->shm_cont); - /* SHM cycles through buffer */ - varnish_submit_derive (conf->instance, "shm", "total_operations", "cycles" , stats->shm_cycles); - } - - if (conf->collect_sm) - { - /* allocator requests */ - varnish_submit_derive (conf->instance, "sm", "total_requests", "nreq", stats->sm_nreq); - /* outstanding allocations */ - varnish_submit_gauge (conf->instance, "sm", "requests", "outstanding", stats->sm_nobj); - /* bytes allocated */ - varnish_submit_derive (conf->instance, "sm", "total_bytes", "allocated", stats->sm_balloc); - /* bytes free */ - varnish_submit_derive (conf->instance, "sm", "total_bytes", "free", stats->sm_bfree); - } - - if (conf->collect_sma) - { - /* SMA allocator requests */ - varnish_submit_derive (conf->instance, "sma", "total_requests", "nreq", stats->sma_nreq); - /* SMA outstanding allocations */ - varnish_submit_gauge (conf->instance, "sma", "requests", "outstanding", stats->sma_nobj); - /* SMA outstanding bytes */ - varnish_submit_gauge (conf->instance, "sma", "bytes", "outstanding", stats->sma_nbytes); - /* SMA bytes allocated */ - varnish_submit_derive (conf->instance, "sma", "total_bytes", "allocated", stats->sma_balloc); - /* SMA bytes free */ - varnish_submit_derive (conf->instance, "sma", "total_bytes", "free" , stats->sma_bfree); - } - - if (conf->collect_sms) - { - /* SMS allocator requests */ - varnish_submit_derive (conf->instance, "sms", "total_requests", "allocator", stats->sms_nreq); - /* SMS outstanding allocations */ - varnish_submit_gauge (conf->instance, "sms", "requests", "outstanding", stats->sms_nobj); - /* SMS outstanding bytes */ - varnish_submit_gauge (conf->instance, "sms", "bytes", "outstanding", stats->sms_nbytes); - /* SMS bytes allocated */ - varnish_submit_derive (conf->instance, "sms", "total_bytes", "allocated", stats->sms_balloc); - /* SMS bytes freed */ - varnish_submit_derive (conf->instance, "sms", "total_bytes", "free", stats->sms_bfree); - } - - if (conf->collect_struct) - { - /* N struct sess_mem */ - varnish_submit_gauge (conf->instance, "struct", "current_sessions", "sess_mem", stats->n_sess_mem); - /* N struct sess */ - varnish_submit_gauge (conf->instance, "struct", "current_sessions", "sess", stats->n_sess); - /* N struct object */ - varnish_submit_gauge (conf->instance, "struct", "objects", "object", stats->n_object); - /* N struct objecthead */ - varnish_submit_gauge (conf->instance, "struct", "objects", "objecthead", stats->n_objecthead); - /* N struct smf */ - varnish_submit_gauge (conf->instance, "struct", "objects", "smf", stats->n_smf); - /* N small free smf */ - varnish_submit_gauge (conf->instance, "struct", "objects", "smf_frag", stats->n_smf_frag); - /* N large free smf */ - varnish_submit_gauge (conf->instance, "struct", "objects", "smf_large", stats->n_smf_large); - /* N struct vbe_conn */ - varnish_submit_gauge (conf->instance, "struct", "objects", "vbe_conn", stats->n_vbe_conn); - } - - if (conf->collect_totals) - { - /* Total Sessions */ - varnish_submit_derive (conf->instance, "totals", "total_sessions", "sessions", stats->s_sess); - /* Total Requests */ - varnish_submit_derive (conf->instance, "totals", "total_requests", "requests", stats->s_req); - /* Total pipe */ - varnish_submit_derive (conf->instance, "totals", "total_operations", "pipe", stats->s_pipe); - /* Total pass */ - varnish_submit_derive (conf->instance, "totals", "total_operations", "pass", stats->s_pass); - /* Total fetch */ - varnish_submit_derive (conf->instance, "totals", "total_operations", "fetches", stats->s_fetch); - /* Total header bytes */ - varnish_submit_derive (conf->instance, "totals", "total_bytes", "header-bytes", stats->s_hdrbytes); - /* Total body byte */ - varnish_submit_derive (conf->instance, "totals", "total_bytes", "body-bytes", stats->s_bodybytes); - } - - if (conf->collect_vcl) - { - /* N vcl total */ - varnish_submit_gauge (conf->instance, "vcl", "vcl", "total_vcl", stats->n_vcl); - /* N vcl available */ - varnish_submit_gauge (conf->instance, "vcl", "vcl", "avail_vcl", stats->n_vcl_avail); - /* N vcl discarded */ - varnish_submit_gauge (conf->instance, "vcl", "vcl", "discarded_vcl", stats->n_vcl_discard); - } - - if (conf->collect_workers) - { - /* worker threads */ - varnish_submit_gauge (conf->instance, "workers", "threads", "worker", stats->n_wrk); - /* worker threads created */ - varnish_submit_derive (conf->instance, "workers", "total_threads", "created", stats->n_wrk_create); - /* worker threads not created */ - varnish_submit_derive (conf->instance, "workers", "total_threads", "failed", stats->n_wrk_failed); - /* worker threads limited */ - varnish_submit_derive (conf->instance, "workers", "total_threads", "limited", stats->n_wrk_max); - /* dropped work requests */ - varnish_submit_derive (conf->instance, "workers", "total_threads", "dropped", stats->n_wrk_drop); - /* queued work requests */ - varnish_submit_derive (conf->instance, "workers", "total_requests", "queued", stats->n_wrk_queue); - /* overflowed work requests */ - varnish_submit_derive (conf->instance, "workers", "total_requests", "overflowed", stats->n_wrk_overflow); - } +static void varnish_monitor(const user_config_t *conf, /* {{{ */ + const c_varnish_stats_t *stats) { + if (conf->collect_cache) { + /* Cache hits */ + varnish_submit_derive(conf->instance, "cache", "cache_result", "hit", + stats->cache_hit); + /* Cache misses */ + varnish_submit_derive(conf->instance, "cache", "cache_result", "miss", + stats->cache_miss); + /* Cache hits for pass */ + varnish_submit_derive(conf->instance, "cache", "cache_result", "hitpass", + stats->cache_hitpass); + } + + if (conf->collect_connections) { + /* Client connections accepted */ + varnish_submit_derive(conf->instance, "connections", "connections", + "accepted", stats->client_conn); + /* Connection dropped, no sess */ + varnish_submit_derive(conf->instance, "connections", "connections", + "dropped", stats->client_drop); + /* Client requests received */ + varnish_submit_derive(conf->instance, "connections", "connections", + "received", stats->client_req); + } + + if (conf->collect_esi) { + /* ESI parse errors (unlock) */ + varnish_submit_derive(conf->instance, "esi", "total_operations", "error", + stats->esi_errors); + /* Objects ESI parsed (unlock) */ + varnish_submit_derive(conf->instance, "esi", "total_operations", "parsed", + stats->esi_parse); + } + + if (conf->collect_backend) { + /* Backend conn. success */ + varnish_submit_derive(conf->instance, "backend", "connections", "success", + stats->backend_conn); + /* Backend conn. not attempted */ + varnish_submit_derive(conf->instance, "backend", "connections", + "not-attempted", stats->backend_unhealthy); + /* Backend conn. too many */ + varnish_submit_derive(conf->instance, "backend", "connections", "too-many", + stats->backend_busy); + /* Backend conn. failures */ + varnish_submit_derive(conf->instance, "backend", "connections", "failures", + stats->backend_fail); + /* Backend conn. reuses */ + varnish_submit_derive(conf->instance, "backend", "connections", "reuses", + stats->backend_reuse); + /* Backend conn. was closed */ + varnish_submit_derive(conf->instance, "backend", "connections", + "was-closed", stats->backend_toolate); + /* Backend conn. recycles */ + varnish_submit_derive(conf->instance, "backend", "connections", "recycled", + stats->backend_recycle); + /* Backend conn. unused */ + varnish_submit_derive(conf->instance, "backend", "connections", "unused", + stats->backend_unused); + /* Backend requests mades */ + varnish_submit_derive(conf->instance, "backend", "http_requests", + "requests", stats->backend_req); + /* N backends */ + varnish_submit_gauge(conf->instance, "backend", "backends", "n_backends", + stats->n_backend); + } + + if (conf->collect_fetch) { + /* Fetch head */ + varnish_submit_derive(conf->instance, "fetch", "http_requests", "head", + stats->fetch_head); + /* Fetch with length */ + varnish_submit_derive(conf->instance, "fetch", "http_requests", "length", + stats->fetch_length); + /* Fetch chunked */ + varnish_submit_derive(conf->instance, "fetch", "http_requests", "chunked", + stats->fetch_chunked); + /* Fetch EOF */ + varnish_submit_derive(conf->instance, "fetch", "http_requests", "eof", + stats->fetch_eof); + /* Fetch bad headers */ + varnish_submit_derive(conf->instance, "fetch", "http_requests", + "bad_headers", stats->fetch_bad); + /* Fetch wanted close */ + varnish_submit_derive(conf->instance, "fetch", "http_requests", "close", + stats->fetch_close); + /* Fetch pre HTTP/1.1 closed */ + varnish_submit_derive(conf->instance, "fetch", "http_requests", "oldhttp", + stats->fetch_oldhttp); + /* Fetch zero len */ + varnish_submit_derive(conf->instance, "fetch", "http_requests", "zero", + stats->fetch_zero); + /* Fetch failed */ + varnish_submit_derive(conf->instance, "fetch", "http_requests", "failed", + stats->fetch_failed); + } + + if (conf->collect_hcb) { + /* HCB Lookups without lock */ + varnish_submit_derive(conf->instance, "hcb", "cache_operation", + "lookup_nolock", stats->hcb_nolock); + /* HCB Lookups with lock */ + varnish_submit_derive(conf->instance, "hcb", "cache_operation", + "lookup_lock", stats->hcb_lock); + /* HCB Inserts */ + varnish_submit_derive(conf->instance, "hcb", "cache_operation", "insert", + stats->hcb_insert); + } + + if (conf->collect_objects) { + /* N expired objects */ + varnish_submit_derive(conf->instance, "objects", "total_objects", "expired", + stats->n_expired); + /* N LRU nuked objects */ + varnish_submit_derive(conf->instance, "objects", "total_objects", + "lru_nuked", stats->n_lru_nuked); + /* N LRU saved objects */ + varnish_submit_derive(conf->instance, "objects", "total_objects", + "lru_saved", stats->n_lru_saved); + /* N LRU moved objects */ + varnish_submit_derive(conf->instance, "objects", "total_objects", + "lru_moved", stats->n_lru_moved); + /* N objects on deathrow */ + varnish_submit_derive(conf->instance, "objects", "total_objects", + "deathrow", stats->n_deathrow); + /* HTTP header overflows */ + varnish_submit_derive(conf->instance, "objects", "total_objects", + "header_overflow", stats->losthdr); + /* Objects sent with sendfile */ + varnish_submit_derive(conf->instance, "objects", "total_objects", + "sent_sendfile", stats->n_objsendfile); + /* Objects sent with write */ + varnish_submit_derive(conf->instance, "objects", "total_objects", + "sent_write", stats->n_objwrite); + /* Objects overflowing workspace */ + varnish_submit_derive(conf->instance, "objects", "total_objects", + "workspace_overflow", stats->n_objoverflow); + } + + if (conf->collect_purge) { + /* N total active purges */ + varnish_submit_derive(conf->instance, "purge", "total_operations", "total", + stats->n_purge); + /* N new purges added */ + varnish_submit_derive(conf->instance, "purge", "total_operations", "added", + stats->n_purge_add); + /* N old purges deleted */ + varnish_submit_derive(conf->instance, "purge", "total_operations", + "deleted", stats->n_purge_retire); + /* N objects tested */ + varnish_submit_derive(conf->instance, "purge", "total_operations", + "objects_tested", stats->n_purge_obj_test); + /* N regexps tested against */ + varnish_submit_derive(conf->instance, "purge", "total_operations", + "regexps_tested", stats->n_purge_re_test); + /* N duplicate purges removed */ + varnish_submit_derive(conf->instance, "purge", "total_operations", + "duplicate", stats->n_purge_dups); + } + + if (conf->collect_session) { + /* Session Closed */ + varnish_submit_derive(conf->instance, "session", "total_operations", + "closed", stats->sess_closed); + /* Session Pipeline */ + varnish_submit_derive(conf->instance, "session", "total_operations", + "pipeline", stats->sess_pipeline); + /* Session Read Ahead */ + varnish_submit_derive(conf->instance, "session", "total_operations", + "readahead", stats->sess_readahead); + /* Session Linger */ + varnish_submit_derive(conf->instance, "session", "total_operations", + "linger", stats->sess_linger); + /* Session herd */ + varnish_submit_derive(conf->instance, "session", "total_operations", "herd", + stats->sess_herd); + } + + if (conf->collect_shm) { + /* SHM records */ + varnish_submit_derive(conf->instance, "shm", "total_operations", "records", + stats->shm_records); + /* SHM writes */ + varnish_submit_derive(conf->instance, "shm", "total_operations", "writes", + stats->shm_writes); + /* SHM flushes due to overflow */ + varnish_submit_derive(conf->instance, "shm", "total_operations", "flushes", + stats->shm_flushes); + /* SHM MTX contention */ + varnish_submit_derive(conf->instance, "shm", "total_operations", + "contention", stats->shm_cont); + /* SHM cycles through buffer */ + varnish_submit_derive(conf->instance, "shm", "total_operations", "cycles", + stats->shm_cycles); + } + + if (conf->collect_sm) { + /* allocator requests */ + varnish_submit_derive(conf->instance, "sm", "total_requests", "nreq", + stats->sm_nreq); + /* outstanding allocations */ + varnish_submit_gauge(conf->instance, "sm", "requests", "outstanding", + stats->sm_nobj); + /* bytes allocated */ + varnish_submit_derive(conf->instance, "sm", "total_bytes", "allocated", + stats->sm_balloc); + /* bytes free */ + varnish_submit_derive(conf->instance, "sm", "total_bytes", "free", + stats->sm_bfree); + } + + if (conf->collect_sma) { + /* SMA allocator requests */ + varnish_submit_derive(conf->instance, "sma", "total_requests", "nreq", + stats->sma_nreq); + /* SMA outstanding allocations */ + varnish_submit_gauge(conf->instance, "sma", "requests", "outstanding", + stats->sma_nobj); + /* SMA outstanding bytes */ + varnish_submit_gauge(conf->instance, "sma", "bytes", "outstanding", + stats->sma_nbytes); + /* SMA bytes allocated */ + varnish_submit_derive(conf->instance, "sma", "total_bytes", "allocated", + stats->sma_balloc); + /* SMA bytes free */ + varnish_submit_derive(conf->instance, "sma", "total_bytes", "free", + stats->sma_bfree); + } + + if (conf->collect_sms) { + /* SMS allocator requests */ + varnish_submit_derive(conf->instance, "sms", "total_requests", "allocator", + stats->sms_nreq); + /* SMS outstanding allocations */ + varnish_submit_gauge(conf->instance, "sms", "requests", "outstanding", + stats->sms_nobj); + /* SMS outstanding bytes */ + varnish_submit_gauge(conf->instance, "sms", "bytes", "outstanding", + stats->sms_nbytes); + /* SMS bytes allocated */ + varnish_submit_derive(conf->instance, "sms", "total_bytes", "allocated", + stats->sms_balloc); + /* SMS bytes freed */ + varnish_submit_derive(conf->instance, "sms", "total_bytes", "free", + stats->sms_bfree); + } + + if (conf->collect_struct) { + /* N struct sess_mem */ + varnish_submit_gauge(conf->instance, "struct", "current_sessions", + "sess_mem", stats->n_sess_mem); + /* N struct sess */ + varnish_submit_gauge(conf->instance, "struct", "current_sessions", "sess", + stats->n_sess); + /* N struct object */ + varnish_submit_gauge(conf->instance, "struct", "objects", "object", + stats->n_object); + /* N struct objecthead */ + varnish_submit_gauge(conf->instance, "struct", "objects", "objecthead", + stats->n_objecthead); + /* N struct smf */ + varnish_submit_gauge(conf->instance, "struct", "objects", "smf", + stats->n_smf); + /* N small free smf */ + varnish_submit_gauge(conf->instance, "struct", "objects", "smf_frag", + stats->n_smf_frag); + /* N large free smf */ + varnish_submit_gauge(conf->instance, "struct", "objects", "smf_large", + stats->n_smf_large); + /* N struct vbe_conn */ + varnish_submit_gauge(conf->instance, "struct", "objects", "vbe_conn", + stats->n_vbe_conn); + } + + if (conf->collect_totals) { + /* Total Sessions */ + varnish_submit_derive(conf->instance, "totals", "total_sessions", + "sessions", stats->s_sess); + /* Total Requests */ + varnish_submit_derive(conf->instance, "totals", "total_requests", + "requests", stats->s_req); + /* Total pipe */ + varnish_submit_derive(conf->instance, "totals", "total_operations", "pipe", + stats->s_pipe); + /* Total pass */ + varnish_submit_derive(conf->instance, "totals", "total_operations", "pass", + stats->s_pass); + /* Total fetch */ + varnish_submit_derive(conf->instance, "totals", "total_operations", + "fetches", stats->s_fetch); + /* Total header bytes */ + varnish_submit_derive(conf->instance, "totals", "total_bytes", + "header-bytes", stats->s_hdrbytes); + /* Total body byte */ + varnish_submit_derive(conf->instance, "totals", "total_bytes", "body-bytes", + stats->s_bodybytes); + } + + if (conf->collect_vcl) { + /* N vcl total */ + varnish_submit_gauge(conf->instance, "vcl", "vcl", "total_vcl", + stats->n_vcl); + /* N vcl available */ + varnish_submit_gauge(conf->instance, "vcl", "vcl", "avail_vcl", + stats->n_vcl_avail); + /* N vcl discarded */ + varnish_submit_gauge(conf->instance, "vcl", "vcl", "discarded_vcl", + stats->n_vcl_discard); + } + + if (conf->collect_workers) { + /* worker threads */ + varnish_submit_gauge(conf->instance, "workers", "threads", "worker", + stats->n_wrk); + /* worker threads created */ + varnish_submit_derive(conf->instance, "workers", "total_threads", "created", + stats->n_wrk_create); + /* worker threads not created */ + varnish_submit_derive(conf->instance, "workers", "total_threads", "failed", + stats->n_wrk_failed); + /* worker threads limited */ + varnish_submit_derive(conf->instance, "workers", "total_threads", "limited", + stats->n_wrk_max); + /* dropped work requests */ + varnish_submit_derive(conf->instance, "workers", "total_threads", "dropped", + stats->n_wrk_drop); + /* queued work requests */ + varnish_submit_derive(conf->instance, "workers", "total_requests", "queued", + stats->n_wrk_queue); + /* overflowed work requests */ + varnish_submit_derive(conf->instance, "workers", "total_requests", + "overflowed", stats->n_wrk_overflow); + } } /* }}} void varnish_monitor */ #endif #if HAVE_VARNISH_V3 || HAVE_VARNISH_V4 -static int varnish_read (user_data_t *ud) /* {{{ */ +static int varnish_read(user_data_t *ud) /* {{{ */ { - struct VSM_data *vd; - const c_varnish_stats_t *stats; - _Bool ok; + struct VSM_data *vd; + const c_varnish_stats_t *stats; + _Bool ok; - user_config_t *conf; + user_config_t *conf; - if ((ud == NULL) || (ud->data == NULL)) - return (EINVAL); + if ((ud == NULL) || (ud->data == NULL)) + return (EINVAL); - conf = ud->data; + conf = ud->data; - vd = VSM_New(); + vd = VSM_New(); #if HAVE_VARNISH_V3 - VSC_Setup(vd); + VSC_Setup(vd); #endif - if (conf->instance != NULL) - { - int status; - - status = VSM_n_Arg (vd, conf->instance); - if (status < 0) - { - VSM_Delete (vd); - ERROR ("varnish plugin: VSM_n_Arg (\"%s\") failed " - "with status %i.", - conf->instance, status); - return (-1); - } - } + if (conf->instance != NULL) { + int status; + + status = VSM_n_Arg(vd, conf->instance); + if (status < 0) { + VSM_Delete(vd); + ERROR("varnish plugin: VSM_n_Arg (\"%s\") failed " + "with status %i.", + conf->instance, status); + return (-1); + } + } #if HAVE_VARNISH_V3 - ok = (VSC_Open (vd, /* diag = */ 1) == 0); + ok = (VSC_Open(vd, /* diag = */ 1) == 0); #else /* if HAVE_VARNISH_V4 */ - ok = (VSM_Open (vd) == 0); + ok = (VSM_Open(vd) == 0); #endif - if (!ok) - { - VSM_Delete (vd); - ERROR ("varnish plugin: Unable to open connection."); + if (!ok) { + VSM_Delete(vd); + ERROR("varnish plugin: Unable to open connection."); - return (-1); - } + return (-1); + } #if HAVE_VARNISH_V3 - stats = VSC_Main(vd); + stats = VSC_Main(vd); #else /* if HAVE_VARNISH_V4 */ - stats = VSC_Main(vd, NULL); + stats = VSC_Main(vd, NULL); #endif - if (!stats) - { - VSM_Delete (vd); - ERROR ("varnish plugin: Unable to get statistics."); + if (!stats) { + VSM_Delete(vd); + ERROR("varnish plugin: Unable to get statistics."); - return (-1); - } + return (-1); + } #if HAVE_VARNISH_V3 - VSC_Iter (vd, varnish_monitor, conf); + VSC_Iter(vd, varnish_monitor, conf); #else /* if HAVE_VARNISH_V4 */ - VSC_Iter (vd, NULL, varnish_monitor, conf); + VSC_Iter(vd, NULL, varnish_monitor, conf); #endif - VSM_Delete (vd); + VSM_Delete(vd); - return (0); + return (0); } /* }}} */ #else /* if HAVE_VARNISH_V2 */ -static int varnish_read (user_data_t *ud) /* {{{ */ +static int varnish_read(user_data_t *ud) /* {{{ */ { - const c_varnish_stats_t *stats; + const c_varnish_stats_t *stats; - user_config_t *conf; + user_config_t *conf; - if ((ud == NULL) || (ud->data == NULL)) - return (EINVAL); + if ((ud == NULL) || (ud->data == NULL)) + return (EINVAL); - conf = ud->data; + conf = ud->data; - stats = VSL_OpenStats (conf->instance); - if (stats == NULL) - { - ERROR ("Varnish plugin : unable to load statistics"); + stats = VSL_OpenStats(conf->instance); + if (stats == NULL) { + ERROR("Varnish plugin : unable to load statistics"); - return (-1); - } + return (-1); + } - varnish_monitor (conf, stats); + varnish_monitor(conf, stats); - return (0); + return (0); } /* }}} */ #endif -static void varnish_config_free (void *ptr) /* {{{ */ +static void varnish_config_free(void *ptr) /* {{{ */ { - user_config_t *conf = ptr; + user_config_t *conf = ptr; - if (conf == NULL) - return; + if (conf == NULL) + return; - sfree (conf->instance); - sfree (conf); + sfree(conf->instance); + sfree(conf); } /* }}} */ -static int varnish_config_apply_default (user_config_t *conf) /* {{{ */ +static int varnish_config_apply_default(user_config_t *conf) /* {{{ */ { - if (conf == NULL) - return (EINVAL); + if (conf == NULL) + return (EINVAL); - conf->collect_backend = 1; - conf->collect_cache = 1; - conf->collect_connections = 1; + conf->collect_backend = 1; + conf->collect_cache = 1; + conf->collect_connections = 1; #ifdef HAVE_VARNISH_V3 - conf->collect_dirdns = 0; + conf->collect_dirdns = 0; #endif - conf->collect_esi = 0; - conf->collect_fetch = 0; - conf->collect_hcb = 0; - conf->collect_objects = 0; + conf->collect_esi = 0; + conf->collect_fetch = 0; + conf->collect_hcb = 0; + conf->collect_objects = 0; #if HAVE_VARNISH_V2 - conf->collect_purge = 0; + conf->collect_purge = 0; #else - conf->collect_ban = 0; + conf->collect_ban = 0; #endif - conf->collect_session = 0; - conf->collect_shm = 1; + conf->collect_session = 0; + conf->collect_shm = 1; #if HAVE_VARNISH_V2 - conf->collect_sm = 0; - conf->collect_sma = 0; + conf->collect_sm = 0; + conf->collect_sma = 0; #endif - conf->collect_sms = 0; - conf->collect_struct = 0; - conf->collect_totals = 0; + conf->collect_sms = 0; + conf->collect_struct = 0; + conf->collect_totals = 0; #if HAVE_VARNISH_V3 || HAVE_VARNISH_V4 - conf->collect_uptime = 0; + conf->collect_uptime = 0; #endif - conf->collect_vcl = 0; - conf->collect_workers = 0; + conf->collect_vcl = 0; + conf->collect_workers = 0; #if HAVE_VARNISH_V4 - conf->collect_vsm = 0; + conf->collect_vsm = 0; #endif - return (0); + return (0); } /* }}} int varnish_config_apply_default */ -static int varnish_init (void) /* {{{ */ +static int varnish_init(void) /* {{{ */ { - user_config_t *conf; + user_config_t *conf; - if (have_instance) - return (0); + if (have_instance) + return (0); - conf = calloc (1, sizeof (*conf)); - if (conf == NULL) - return (ENOMEM); + conf = calloc(1, sizeof(*conf)); + if (conf == NULL) + return (ENOMEM); - /* Default settings: */ - conf->instance = NULL; + /* Default settings: */ + conf->instance = NULL; - varnish_config_apply_default (conf); + varnish_config_apply_default(conf); - plugin_register_complex_read (/* group = */ "varnish", - /* name = */ "varnish/localhost", - /* callback = */ varnish_read, - /* interval = */ 0, - &(user_data_t) { - .data = conf, - .free_func = varnish_config_free, - }); + plugin_register_complex_read( + /* group = */ "varnish", + /* name = */ "varnish/localhost", + /* callback = */ varnish_read, + /* interval = */ 0, &(user_data_t){ + .data = conf, .free_func = varnish_config_free, + }); - return (0); + return (0); } /* }}} int varnish_init */ -static int varnish_config_instance (const oconfig_item_t *ci) /* {{{ */ +static int varnish_config_instance(const oconfig_item_t *ci) /* {{{ */ { - user_config_t *conf; - char callback_name[DATA_MAX_NAME_LEN]; - - conf = calloc (1, sizeof (*conf)); - if (conf == NULL) - return (ENOMEM); - conf->instance = NULL; - - varnish_config_apply_default (conf); - - if (ci->values_num == 1) - { - int status; - - status = cf_util_get_string (ci, &conf->instance); - if (status != 0) - { - sfree (conf); - return (status); - } - assert (conf->instance != NULL); - - if (strcmp ("localhost", conf->instance) == 0) - { - sfree (conf->instance); - conf->instance = NULL; - } - } - else if (ci->values_num > 1) - { - WARNING ("Varnish plugin: \"Instance\" blocks accept only " - "one argument."); - sfree (conf); - return (EINVAL); - } - - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("CollectCache", child->key) == 0) - cf_util_get_boolean (child, &conf->collect_cache); - else if (strcasecmp ("CollectConnections", child->key) == 0) - cf_util_get_boolean (child, &conf->collect_connections); - else if (strcasecmp ("CollectESI", child->key) == 0) - cf_util_get_boolean (child, &conf->collect_esi); - else if (strcasecmp ("CollectDirectorDNS", child->key) == 0) + user_config_t *conf; + char callback_name[DATA_MAX_NAME_LEN]; + + conf = calloc(1, sizeof(*conf)); + if (conf == NULL) + return (ENOMEM); + conf->instance = NULL; + + varnish_config_apply_default(conf); + + if (ci->values_num == 1) { + int status; + + status = cf_util_get_string(ci, &conf->instance); + if (status != 0) { + sfree(conf); + return (status); + } + assert(conf->instance != NULL); + + if (strcmp("localhost", conf->instance) == 0) { + sfree(conf->instance); + conf->instance = NULL; + } + } else if (ci->values_num > 1) { + WARNING("Varnish plugin: \"Instance\" blocks accept only " + "one argument."); + sfree(conf); + return (EINVAL); + } + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("CollectCache", child->key) == 0) + cf_util_get_boolean(child, &conf->collect_cache); + else if (strcasecmp("CollectConnections", child->key) == 0) + cf_util_get_boolean(child, &conf->collect_connections); + else if (strcasecmp("CollectESI", child->key) == 0) + cf_util_get_boolean(child, &conf->collect_esi); + else if (strcasecmp("CollectDirectorDNS", child->key) == 0) #ifdef HAVE_VARNISH_V3 - cf_util_get_boolean (child, &conf->collect_dirdns); + cf_util_get_boolean(child, &conf->collect_dirdns); #else - WARNING ("Varnish plugin: \"%s\" is available for Varnish %s only.", child->key, "v3"); + WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.", + child->key, "v3"); #endif - else if (strcasecmp ("CollectBackend", child->key) == 0) - cf_util_get_boolean (child, &conf->collect_backend); - else if (strcasecmp ("CollectFetch", child->key) == 0) - cf_util_get_boolean (child, &conf->collect_fetch); - else if (strcasecmp ("CollectHCB", child->key) == 0) - cf_util_get_boolean (child, &conf->collect_hcb); - else if (strcasecmp ("CollectObjects", child->key) == 0) - cf_util_get_boolean (child, &conf->collect_objects); - else if (strcasecmp ("CollectPurge", child->key) == 0) + else if (strcasecmp("CollectBackend", child->key) == 0) + cf_util_get_boolean(child, &conf->collect_backend); + else if (strcasecmp("CollectFetch", child->key) == 0) + cf_util_get_boolean(child, &conf->collect_fetch); + else if (strcasecmp("CollectHCB", child->key) == 0) + cf_util_get_boolean(child, &conf->collect_hcb); + else if (strcasecmp("CollectObjects", child->key) == 0) + cf_util_get_boolean(child, &conf->collect_objects); + else if (strcasecmp("CollectPurge", child->key) == 0) #if HAVE_VARNISH_V2 - cf_util_get_boolean (child, &conf->collect_purge); + cf_util_get_boolean(child, &conf->collect_purge); #else - WARNING ("Varnish plugin: \"%s\" is available for Varnish %s only.", child->key, "v2"); + WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.", + child->key, "v2"); #endif - else if (strcasecmp ("CollectBan", child->key) == 0) + else if (strcasecmp("CollectBan", child->key) == 0) #if HAVE_VARNISH_V2 - WARNING ("Varnish plugin: \"%s\" is not available for Varnish %s.", child->key, "v2"); + WARNING("Varnish plugin: \"%s\" is not available for Varnish %s.", + child->key, "v2"); #else - cf_util_get_boolean (child, &conf->collect_ban); + cf_util_get_boolean(child, &conf->collect_ban); #endif - else if (strcasecmp ("CollectSession", child->key) == 0) - cf_util_get_boolean (child, &conf->collect_session); - else if (strcasecmp ("CollectSHM", child->key) == 0) - cf_util_get_boolean (child, &conf->collect_shm); - else if (strcasecmp ("CollectSMS", child->key) == 0) - cf_util_get_boolean (child, &conf->collect_sms); - else if (strcasecmp ("CollectSMA", child->key) == 0) + else if (strcasecmp("CollectSession", child->key) == 0) + cf_util_get_boolean(child, &conf->collect_session); + else if (strcasecmp("CollectSHM", child->key) == 0) + cf_util_get_boolean(child, &conf->collect_shm); + else if (strcasecmp("CollectSMS", child->key) == 0) + cf_util_get_boolean(child, &conf->collect_sms); + else if (strcasecmp("CollectSMA", child->key) == 0) #if HAVE_VARNISH_V2 - cf_util_get_boolean (child, &conf->collect_sma); + cf_util_get_boolean(child, &conf->collect_sma); #else - WARNING ("Varnish plugin: \"%s\" is available for Varnish %s only.", child->key, "v2"); + WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.", + child->key, "v2"); #endif - else if (strcasecmp ("CollectSM", child->key) == 0) + else if (strcasecmp("CollectSM", child->key) == 0) #if HAVE_VARNISH_V2 - cf_util_get_boolean (child, &conf->collect_sm); + cf_util_get_boolean(child, &conf->collect_sm); #else - WARNING ("Varnish plugin: \"%s\" is available for Varnish %s only.", child->key, "v2"); + WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.", + child->key, "v2"); #endif - else if (strcasecmp ("CollectStruct", child->key) == 0) - cf_util_get_boolean (child, &conf->collect_struct); - else if (strcasecmp ("CollectTotals", child->key) == 0) - cf_util_get_boolean (child, &conf->collect_totals); - else if (strcasecmp ("CollectUptime", child->key) == 0) + else if (strcasecmp("CollectStruct", child->key) == 0) + cf_util_get_boolean(child, &conf->collect_struct); + else if (strcasecmp("CollectTotals", child->key) == 0) + cf_util_get_boolean(child, &conf->collect_totals); + else if (strcasecmp("CollectUptime", child->key) == 0) #if HAVE_VARNISH_V3 || HAVE_VARNISH_V4 - cf_util_get_boolean (child, &conf->collect_uptime); + cf_util_get_boolean(child, &conf->collect_uptime); #else - WARNING ("Varnish plugin: \"%s\" is available for Varnish %s only.", child->key, "v3 and v4"); + WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.", + child->key, "v3 and v4"); #endif - else if (strcasecmp ("CollectVCL", child->key) == 0) - cf_util_get_boolean (child, &conf->collect_vcl); - else if (strcasecmp ("CollectWorkers", child->key) == 0) - cf_util_get_boolean (child, &conf->collect_workers); - else if (strcasecmp ("CollectVSM", child->key) == 0) + else if (strcasecmp("CollectVCL", child->key) == 0) + cf_util_get_boolean(child, &conf->collect_vcl); + else if (strcasecmp("CollectWorkers", child->key) == 0) + cf_util_get_boolean(child, &conf->collect_workers); + else if (strcasecmp("CollectVSM", child->key) == 0) #if HAVE_VARNISH_V4 - cf_util_get_boolean (child, &conf->collect_vsm); + cf_util_get_boolean(child, &conf->collect_vsm); #else - WARNING ("Varnish plugin: \"%s\" is available for Varnish %s only.", child->key, "v4"); + WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.", + child->key, "v4"); #endif - else - { - WARNING ("Varnish plugin: Ignoring unknown " - "configuration option: \"%s\". Did " - "you forget to add an " - "block around the configuration?", - child->key); - } - } - - if (!conf->collect_cache - && !conf->collect_connections - && !conf->collect_esi - && !conf->collect_backend + else { + WARNING("Varnish plugin: Ignoring unknown " + "configuration option: \"%s\". Did " + "you forget to add an " + "block around the configuration?", + child->key); + } + } + + if (!conf->collect_cache && !conf->collect_connections && + !conf->collect_esi && !conf->collect_backend #ifdef HAVE_VARNISH_V3 - && !conf->collect_dirdns + && !conf->collect_dirdns #endif - && !conf->collect_fetch - && !conf->collect_hcb - && !conf->collect_objects + && !conf->collect_fetch && !conf->collect_hcb && !conf->collect_objects #if HAVE_VARNISH_V2 - && !conf->collect_purge + && !conf->collect_purge #else - && !conf->collect_ban + && !conf->collect_ban #endif - && !conf->collect_session - && !conf->collect_shm - && !conf->collect_sms + && !conf->collect_session && !conf->collect_shm && !conf->collect_sms #if HAVE_VARNISH_V2 - && !conf->collect_sma - && !conf->collect_sm + && !conf->collect_sma && !conf->collect_sm #endif - && !conf->collect_struct - && !conf->collect_totals + && !conf->collect_struct && !conf->collect_totals #if HAVE_VARNISH_V3 || HAVE_VARNISH_V4 - && !conf->collect_uptime + && !conf->collect_uptime #endif - && !conf->collect_vcl - && !conf->collect_workers + && !conf->collect_vcl && !conf->collect_workers #if HAVE_VARNISH_V4 - && !conf->collect_vsm + && !conf->collect_vsm #endif - ) - { - WARNING ("Varnish plugin: No metric has been configured for " - "instance \"%s\". Disabling this instance.", - (conf->instance == NULL) ? "localhost" : conf->instance); - sfree (conf); - return (EINVAL); - } - - ssnprintf (callback_name, sizeof (callback_name), "varnish/%s", - (conf->instance == NULL) ? "localhost" : conf->instance); - - plugin_register_complex_read (/* group = */ "varnish", - /* name = */ callback_name, - /* callback = */ varnish_read, - /* interval = */ 0, - &(user_data_t) { - .data = conf, - .free_func = varnish_config_free, - }); - - have_instance = 1; - - return (0); + ) { + WARNING("Varnish plugin: No metric has been configured for " + "instance \"%s\". Disabling this instance.", + (conf->instance == NULL) ? "localhost" : conf->instance); + sfree(conf); + return (EINVAL); + } + + ssnprintf(callback_name, sizeof(callback_name), "varnish/%s", + (conf->instance == NULL) ? "localhost" : conf->instance); + + plugin_register_complex_read( + /* group = */ "varnish", + /* name = */ callback_name, + /* callback = */ varnish_read, + /* interval = */ 0, &(user_data_t){ + .data = conf, .free_func = varnish_config_free, + }); + + have_instance = 1; + + return (0); } /* }}} int varnish_config_instance */ -static int varnish_config (oconfig_item_t *ci) /* {{{ */ +static int varnish_config(oconfig_item_t *ci) /* {{{ */ { - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("Instance", child->key) == 0) - varnish_config_instance (child); - else - { - WARNING ("Varnish plugin: Ignoring unknown " - "configuration option: \"%s\"", - child->key); - } - } - - return (0); + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Instance", child->key) == 0) + varnish_config_instance(child); + else { + WARNING("Varnish plugin: Ignoring unknown " + "configuration option: \"%s\"", + child->key); + } + } + + return (0); } /* }}} int varnish_config */ -void module_register (void) /* {{{ */ +void module_register(void) /* {{{ */ { - plugin_register_complex_config ("varnish", varnish_config); - plugin_register_init ("varnish", varnish_init); + plugin_register_complex_config("varnish", varnish_config); + plugin_register_init("varnish", varnish_init); } /* }}} */ /* vim: set sw=8 noet fdm=marker : */ diff --git a/src/virt.c b/src/virt.c index 62b53dcc..c3c07a0d 100644 --- a/src/virt.c +++ b/src/virt.c @@ -23,38 +23,36 @@ #include "common.h" #include "plugin.h" -#include "utils_ignorelist.h" #include "utils_complain.h" +#include "utils_ignorelist.h" +#include /* for basename(3) */ #include #include #include #include #include -#include /* for basename(3) */ /* Plugin name */ #define PLUGIN_NAME "virt" -static const char *config_keys[] = { - "Connection", +static const char *config_keys[] = {"Connection", - "RefreshInterval", + "RefreshInterval", - "Domain", - "BlockDevice", - "BlockDeviceFormat", - "BlockDeviceFormatBasename", - "InterfaceDevice", - "IgnoreSelected", + "Domain", + "BlockDevice", + "BlockDeviceFormat", + "BlockDeviceFormatBasename", + "InterfaceDevice", + "IgnoreSelected", - "HostnameFormat", - "InterfaceFormat", + "HostnameFormat", + "InterfaceFormat", - "PluginInstanceFormat", + "PluginInstanceFormat", - NULL -}; + NULL}; #define NR_CONFIG_KEYS ((sizeof config_keys / sizeof config_keys[0]) - 1) /* Connection. */ @@ -72,79 +70,63 @@ static ignorelist_t *il_block_devices = NULL; /* List of network interface devices, if specified. */ static ignorelist_t *il_interface_devices = NULL; -static int ignore_device_match (ignorelist_t *, - const char *domname, const char *devpath); +static int ignore_device_match(ignorelist_t *, const char *domname, + const char *devpath); /* Actual list of domains found on last refresh. */ static virDomainPtr *domains = NULL; static int nr_domains = 0; -static void free_domains (void); -static int add_domain (virDomainPtr dom); +static void free_domains(void); +static int add_domain(virDomainPtr dom); /* Actual list of block devices found on last refresh. */ struct block_device { - virDomainPtr dom; /* domain */ - char *path; /* name of block device */ + virDomainPtr dom; /* domain */ + char *path; /* name of block device */ }; static struct block_device *block_devices = NULL; static int nr_block_devices = 0; -static void free_block_devices (void); -static int add_block_device (virDomainPtr dom, const char *path); +static void free_block_devices(void); +static int add_block_device(virDomainPtr dom, const char *path); /* Actual list of network interfaces found on last refresh. */ struct interface_device { - virDomainPtr dom; /* domain */ - char *path; /* name of interface device */ - char *address; /* mac address of interface device */ - char *number; /* interface device number */ + virDomainPtr dom; /* domain */ + char *path; /* name of interface device */ + char *address; /* mac address of interface device */ + char *number; /* interface device number */ }; static struct interface_device *interface_devices = NULL; static int nr_interface_devices = 0; -static void free_interface_devices (void); -static int add_interface_device (virDomainPtr dom, const char *path, const char *address, unsigned int number); +static void free_interface_devices(void); +static int add_interface_device(virDomainPtr dom, const char *path, + const char *address, unsigned int number); /* HostnameFormat. */ #define HF_MAX_FIELDS 3 -enum hf_field { - hf_none = 0, - hf_hostname, - hf_name, - hf_uuid -}; +enum hf_field { hf_none = 0, hf_hostname, hf_name, hf_uuid }; -static enum hf_field hostname_format[HF_MAX_FIELDS] = - { hf_name }; +static enum hf_field hostname_format[HF_MAX_FIELDS] = {hf_name}; /* PluginInstanceFormat */ #define PLGINST_MAX_FIELDS 2 -enum plginst_field { - plginst_none = 0, - plginst_name, - plginst_uuid -}; +enum plginst_field { plginst_none = 0, plginst_name, plginst_uuid }; -static enum plginst_field plugin_instance_format[PLGINST_MAX_FIELDS] = - { plginst_none }; +static enum plginst_field plugin_instance_format[PLGINST_MAX_FIELDS] = { + plginst_none}; /* BlockDeviceFormat */ -enum bd_field { - target, - source -}; +enum bd_field { target, source }; /* InterfaceFormat. */ -enum if_field { - if_address, - if_name, - if_number -}; +enum if_field { if_address, if_name, if_number }; /* BlockDeviceFormatBasename */ _Bool blockdevice_format_basename = 0; @@ -152,369 +134,358 @@ static enum bd_field blockdevice_format = target; static enum if_field interface_format = if_name; /* Time that we last refreshed. */ -static time_t last_refresh = (time_t) 0; +static time_t last_refresh = (time_t)0; -static int refresh_lists (void); +static int refresh_lists(void); /* ERROR(...) macro for virterrors. */ -#define VIRT_ERROR(conn,s) do { \ - virErrorPtr err; \ - err = (conn) ? virConnGetLastError ((conn)) : virGetLastError (); \ - if (err) ERROR ("%s: %s", (s), err->message); \ - } while(0) - -static void -init_value_list (value_list_t *vl, virDomainPtr dom) -{ - int n; - const char *name; - char uuid[VIR_UUID_STRING_BUFLEN]; +#define VIRT_ERROR(conn, s) \ + do { \ + virErrorPtr err; \ + err = (conn) ? virConnGetLastError((conn)) : virGetLastError(); \ + if (err) \ + ERROR("%s: %s", (s), err->message); \ + } while (0) - sstrncpy (vl->plugin, PLUGIN_NAME, sizeof (vl->plugin)); +static void init_value_list(value_list_t *vl, virDomainPtr dom) { + int n; + const char *name; + char uuid[VIR_UUID_STRING_BUFLEN]; - vl->host[0] = '\0'; + sstrncpy(vl->plugin, PLUGIN_NAME, sizeof(vl->plugin)); - /* Construct the hostname field according to HostnameFormat. */ - for (int i = 0; i < HF_MAX_FIELDS; ++i) { - if (hostname_format[i] == hf_none) - continue; + vl->host[0] = '\0'; - n = DATA_MAX_NAME_LEN - strlen (vl->host) - 2; + /* Construct the hostname field according to HostnameFormat. */ + for (int i = 0; i < HF_MAX_FIELDS; ++i) { + if (hostname_format[i] == hf_none) + continue; - if (i > 0 && n >= 1) { - strncat (vl->host, ":", 1); - n--; - } + n = DATA_MAX_NAME_LEN - strlen(vl->host) - 2; - switch (hostname_format[i]) { - case hf_none: break; - case hf_hostname: - strncat (vl->host, hostname_g, n); - break; - case hf_name: - name = virDomainGetName (dom); - if (name) - strncat (vl->host, name, n); - break; - case hf_uuid: - if (virDomainGetUUIDString (dom, uuid) == 0) - strncat (vl->host, uuid, n); - break; - } + if (i > 0 && n >= 1) { + strncat(vl->host, ":", 1); + n--; } - vl->host[sizeof (vl->host) - 1] = '\0'; + switch (hostname_format[i]) { + case hf_none: + break; + case hf_hostname: + strncat(vl->host, hostname_g, n); + break; + case hf_name: + name = virDomainGetName(dom); + if (name) + strncat(vl->host, name, n); + break; + case hf_uuid: + if (virDomainGetUUIDString(dom, uuid) == 0) + strncat(vl->host, uuid, n); + break; + } + } - /* Construct the plugin instance field according to PluginInstanceFormat. */ - for (int i = 0; i < PLGINST_MAX_FIELDS; ++i) { - if (plugin_instance_format[i] == plginst_none) - continue; + vl->host[sizeof(vl->host) - 1] = '\0'; - n = sizeof(vl->plugin_instance) - strlen (vl->plugin_instance) - 2; + /* Construct the plugin instance field according to PluginInstanceFormat. */ + for (int i = 0; i < PLGINST_MAX_FIELDS; ++i) { + if (plugin_instance_format[i] == plginst_none) + continue; - if (i > 0 && n >= 1) { - strncat (vl->plugin_instance, ":", 1); - n--; - } + n = sizeof(vl->plugin_instance) - strlen(vl->plugin_instance) - 2; - switch (plugin_instance_format[i]) { - case plginst_none: break; - case plginst_name: - name = virDomainGetName (dom); - if (name) - strncat (vl->plugin_instance, name, n); - break; - case plginst_uuid: - if (virDomainGetUUIDString (dom, uuid) == 0) - strncat (vl->plugin_instance, uuid, n); - break; - } + if (i > 0 && n >= 1) { + strncat(vl->plugin_instance, ":", 1); + n--; } - vl->plugin_instance[sizeof (vl->plugin_instance) - 1] = '\0'; + switch (plugin_instance_format[i]) { + case plginst_none: + break; + case plginst_name: + name = virDomainGetName(dom); + if (name) + strncat(vl->plugin_instance, name, n); + break; + case plginst_uuid: + if (virDomainGetUUIDString(dom, uuid) == 0) + strncat(vl->plugin_instance, uuid, n); + break; + } + } + + vl->plugin_instance[sizeof(vl->plugin_instance) - 1] = '\0'; } /* void init_value_list */ -static void submit (virDomainPtr dom, - char const *type, char const *type_instance, - value_t *values, size_t values_len) -{ - value_list_t vl = VALUE_LIST_INIT; - init_value_list (&vl, dom); +static void submit(virDomainPtr dom, char const *type, + char const *type_instance, value_t *values, + size_t values_len) { + value_list_t vl = VALUE_LIST_INIT; + init_value_list(&vl, dom); - vl.values = values; - vl.values_len = values_len; + vl.values = values; + vl.values_len = values_len; - sstrncpy (vl.type, type, sizeof (vl.type)); - if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + if (type_instance != NULL) + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static void -memory_submit (gauge_t value, virDomainPtr dom) -{ - submit (dom, "memory", "total", &(value_t) { .gauge = value }, 1); +static void memory_submit(gauge_t value, virDomainPtr dom) { + submit(dom, "memory", "total", &(value_t){.gauge = value}, 1); } -static void -memory_stats_submit (gauge_t value, virDomainPtr dom, int tag_index) -{ - static const char *tags[] = { "swap_in", "swap_out", "major_fault", "minor_fault", - "unused", "available", "actual_balloon", "rss"}; +static void memory_stats_submit(gauge_t value, virDomainPtr dom, + int tag_index) { + static const char *tags[] = {"swap_in", "swap_out", "major_fault", + "minor_fault", "unused", "available", + "actual_balloon", "rss"}; - if ((tag_index < 0) || (tag_index >= STATIC_ARRAY_SIZE (tags))) { - ERROR ("virt plugin: Array index out of bounds: tag_index = %d", tag_index); - return; - } + if ((tag_index < 0) || (tag_index >= STATIC_ARRAY_SIZE(tags))) { + ERROR("virt plugin: Array index out of bounds: tag_index = %d", tag_index); + return; + } - submit (dom, "memory", tags[tag_index], &(value_t) { .gauge = value }, 1); + submit(dom, "memory", tags[tag_index], &(value_t){.gauge = value}, 1); } -static void -cpu_submit (unsigned long long value, - virDomainPtr dom, const char *type) -{ - submit (dom, type, NULL, &(value_t) { .derive = (derive_t) value }, 1); +static void cpu_submit(unsigned long long value, virDomainPtr dom, + const char *type) { + submit(dom, type, NULL, &(value_t){.derive = (derive_t)value}, 1); } -static void -vcpu_submit (derive_t value, - virDomainPtr dom, int vcpu_nr, const char *type) -{ - char type_instance[DATA_MAX_NAME_LEN]; +static void vcpu_submit(derive_t value, virDomainPtr dom, int vcpu_nr, + const char *type) { + char type_instance[DATA_MAX_NAME_LEN]; - ssnprintf (type_instance, sizeof (type_instance), "%d", vcpu_nr); + ssnprintf(type_instance, sizeof(type_instance), "%d", vcpu_nr); - submit (dom, type, type_instance, &(value_t) { .derive = value }, 1); + submit(dom, type, type_instance, &(value_t){.derive = value}, 1); } -static void -submit_derive2 (const char *type, derive_t v0, derive_t v1, - virDomainPtr dom, const char *devname) -{ - value_t values[] = { - { .derive = v0 }, - { .derive = v1 }, - }; +static void submit_derive2(const char *type, derive_t v0, derive_t v1, + virDomainPtr dom, const char *devname) { + value_t values[] = { + {.derive = v0}, {.derive = v1}, + }; - submit (dom, type, devname, values, STATIC_ARRAY_SIZE (values)); + submit(dom, type, devname, values, STATIC_ARRAY_SIZE(values)); } /* void submit_derive2 */ -static int -lv_init (void) -{ - if (virInitialize () != 0) - return -1; - else - return 0; +static int lv_init(void) { + if (virInitialize() != 0) + return -1; + else + return 0; } -static int -lv_config (const char *key, const char *value) -{ - if (virInitialize () != 0) - return 1; - - if (il_domains == NULL) - il_domains = ignorelist_create (1); - if (il_block_devices == NULL) - il_block_devices = ignorelist_create (1); - if (il_interface_devices == NULL) - il_interface_devices = ignorelist_create (1); - - if (strcasecmp (key, "Connection") == 0) { - char *tmp = strdup (value); - if (tmp == NULL) { - ERROR (PLUGIN_NAME " plugin: Connection strdup failed."); - return 1; - } - sfree (conn_string); - conn_string = tmp; - return 0; +static int lv_config(const char *key, const char *value) { + if (virInitialize() != 0) + return 1; + + if (il_domains == NULL) + il_domains = ignorelist_create(1); + if (il_block_devices == NULL) + il_block_devices = ignorelist_create(1); + if (il_interface_devices == NULL) + il_interface_devices = ignorelist_create(1); + + if (strcasecmp(key, "Connection") == 0) { + char *tmp = strdup(value); + if (tmp == NULL) { + ERROR(PLUGIN_NAME " plugin: Connection strdup failed."); + return 1; } + sfree(conn_string); + conn_string = tmp; + return 0; + } - if (strcasecmp (key, "RefreshInterval") == 0) { - char *eptr = NULL; - interval = strtol (value, &eptr, 10); - if (eptr == NULL || *eptr != '\0') return 1; - return 0; - } + if (strcasecmp(key, "RefreshInterval") == 0) { + char *eptr = NULL; + interval = strtol(value, &eptr, 10); + if (eptr == NULL || *eptr != '\0') + return 1; + return 0; + } - if (strcasecmp (key, "Domain") == 0) { - if (ignorelist_add (il_domains, value)) return 1; - return 0; + if (strcasecmp(key, "Domain") == 0) { + if (ignorelist_add(il_domains, value)) + return 1; + return 0; + } + if (strcasecmp(key, "BlockDevice") == 0) { + if (ignorelist_add(il_block_devices, value)) + return 1; + return 0; + } + + if (strcasecmp(key, "BlockDeviceFormat") == 0) { + if (strcasecmp(value, "target") == 0) + blockdevice_format = target; + else if (strcasecmp(value, "source") == 0) + blockdevice_format = source; + else { + ERROR(PLUGIN_NAME " plugin: unknown BlockDeviceFormat: %s", value); + return -1; } - if (strcasecmp (key, "BlockDevice") == 0) { - if (ignorelist_add (il_block_devices, value)) return 1; - return 0; + return 0; + } + if (strcasecmp(key, "BlockDeviceFormatBasename") == 0) { + blockdevice_format_basename = IS_TRUE(value); + return 0; + } + if (strcasecmp(key, "InterfaceDevice") == 0) { + if (ignorelist_add(il_interface_devices, value)) + return 1; + return 0; + } + + if (strcasecmp(key, "IgnoreSelected") == 0) { + if (IS_TRUE(value)) { + ignorelist_set_invert(il_domains, 0); + ignorelist_set_invert(il_block_devices, 0); + ignorelist_set_invert(il_interface_devices, 0); + } else { + ignorelist_set_invert(il_domains, 1); + ignorelist_set_invert(il_block_devices, 1); + ignorelist_set_invert(il_interface_devices, 1); } + return 0; + } - if (strcasecmp (key, "BlockDeviceFormat") == 0) { - if (strcasecmp (value, "target") == 0) - blockdevice_format = target; - else if (strcasecmp (value, "source") == 0) - blockdevice_format = source; - else { - ERROR (PLUGIN_NAME " plugin: unknown BlockDeviceFormat: %s", value); - return -1; - } - return 0; - } - if (strcasecmp (key, "BlockDeviceFormatBasename") == 0) { - blockdevice_format_basename = IS_TRUE (value); - return 0; - } - if (strcasecmp (key, "InterfaceDevice") == 0) { - if (ignorelist_add (il_interface_devices, value)) return 1; - return 0; - } + if (strcasecmp(key, "HostnameFormat") == 0) { + char *value_copy; + char *fields[HF_MAX_FIELDS]; + int n; - if (strcasecmp (key, "IgnoreSelected") == 0) { - if (IS_TRUE (value)) - { - ignorelist_set_invert (il_domains, 0); - ignorelist_set_invert (il_block_devices, 0); - ignorelist_set_invert (il_interface_devices, 0); - } - else - { - ignorelist_set_invert (il_domains, 1); - ignorelist_set_invert (il_block_devices, 1); - ignorelist_set_invert (il_interface_devices, 1); - } - return 0; + value_copy = strdup(value); + if (value_copy == NULL) { + ERROR(PLUGIN_NAME " plugin: strdup failed."); + return -1; } - if (strcasecmp (key, "HostnameFormat") == 0) { - char *value_copy; - char *fields[HF_MAX_FIELDS]; - int n; - - value_copy = strdup (value); - if (value_copy == NULL) { - ERROR (PLUGIN_NAME " plugin: strdup failed."); - return -1; - } - - n = strsplit (value_copy, fields, HF_MAX_FIELDS); - if (n < 1) { - sfree (value_copy); - ERROR (PLUGIN_NAME " plugin: HostnameFormat: no fields"); - return -1; - } - - for (int i = 0; i < n; ++i) { - if (strcasecmp (fields[i], "hostname") == 0) - hostname_format[i] = hf_hostname; - else if (strcasecmp (fields[i], "name") == 0) - hostname_format[i] = hf_name; - else if (strcasecmp (fields[i], "uuid") == 0) - hostname_format[i] = hf_uuid; - else { - ERROR (PLUGIN_NAME " plugin: unknown HostnameFormat field: %s", fields[i]); - sfree (value_copy); - return -1; - } - } - sfree (value_copy); - - for (int i = n; i < HF_MAX_FIELDS; ++i) - hostname_format[i] = hf_none; + n = strsplit(value_copy, fields, HF_MAX_FIELDS); + if (n < 1) { + sfree(value_copy); + ERROR(PLUGIN_NAME " plugin: HostnameFormat: no fields"); + return -1; + } - return 0; + for (int i = 0; i < n; ++i) { + if (strcasecmp(fields[i], "hostname") == 0) + hostname_format[i] = hf_hostname; + else if (strcasecmp(fields[i], "name") == 0) + hostname_format[i] = hf_name; + else if (strcasecmp(fields[i], "uuid") == 0) + hostname_format[i] = hf_uuid; + else { + ERROR(PLUGIN_NAME " plugin: unknown HostnameFormat field: %s", + fields[i]); + sfree(value_copy); + return -1; + } } + sfree(value_copy); - if (strcasecmp (key, "PluginInstanceFormat") == 0) { - char *value_copy; - char *fields[PLGINST_MAX_FIELDS]; - int n; + for (int i = n; i < HF_MAX_FIELDS; ++i) + hostname_format[i] = hf_none; - value_copy = strdup (value); - if (value_copy == NULL) { - ERROR (PLUGIN_NAME " plugin: strdup failed."); - return -1; - } + return 0; + } - n = strsplit (value_copy, fields, PLGINST_MAX_FIELDS); - if (n < 1) { - sfree (value_copy); - ERROR (PLUGIN_NAME " plugin: PluginInstanceFormat: no fields"); - return -1; - } + if (strcasecmp(key, "PluginInstanceFormat") == 0) { + char *value_copy; + char *fields[PLGINST_MAX_FIELDS]; + int n; - for (int i = 0; i < n; ++i) { - if (strcasecmp (fields[i], "none") == 0) { - plugin_instance_format[i] = plginst_none; - break; - } else if (strcasecmp (fields[i], "name") == 0) - plugin_instance_format[i] = plginst_name; - else if (strcasecmp (fields[i], "uuid") == 0) - plugin_instance_format[i] = plginst_uuid; - else { - ERROR (PLUGIN_NAME " plugin: unknown PluginInstanceFormat field: %s", fields[i]); - sfree (value_copy); - return -1; - } - } - sfree (value_copy); + value_copy = strdup(value); + if (value_copy == NULL) { + ERROR(PLUGIN_NAME " plugin: strdup failed."); + return -1; + } - for (int i = n; i < PLGINST_MAX_FIELDS; ++i) - plugin_instance_format[i] = plginst_none; + n = strsplit(value_copy, fields, PLGINST_MAX_FIELDS); + if (n < 1) { + sfree(value_copy); + ERROR(PLUGIN_NAME " plugin: PluginInstanceFormat: no fields"); + return -1; + } - return 0; + for (int i = 0; i < n; ++i) { + if (strcasecmp(fields[i], "none") == 0) { + plugin_instance_format[i] = plginst_none; + break; + } else if (strcasecmp(fields[i], "name") == 0) + plugin_instance_format[i] = plginst_name; + else if (strcasecmp(fields[i], "uuid") == 0) + plugin_instance_format[i] = plginst_uuid; + else { + ERROR(PLUGIN_NAME " plugin: unknown PluginInstanceFormat field: %s", + fields[i]); + sfree(value_copy); + return -1; + } } + sfree(value_copy); - if (strcasecmp (key, "InterfaceFormat") == 0) { - if (strcasecmp (value, "name") == 0) - interface_format = if_name; - else if (strcasecmp (value, "address") == 0) - interface_format = if_address; - else if (strcasecmp (value, "number") == 0) - interface_format = if_number; - else { - ERROR (PLUGIN_NAME " plugin: unknown InterfaceFormat: %s", value); - return -1; - } - return 0; + for (int i = n; i < PLGINST_MAX_FIELDS; ++i) + plugin_instance_format[i] = plginst_none; + + return 0; + } + + if (strcasecmp(key, "InterfaceFormat") == 0) { + if (strcasecmp(value, "name") == 0) + interface_format = if_name; + else if (strcasecmp(value, "address") == 0) + interface_format = if_address; + else if (strcasecmp(value, "number") == 0) + interface_format = if_number; + else { + ERROR(PLUGIN_NAME " plugin: unknown InterfaceFormat: %s", value); + return -1; } + return 0; + } - /* Unrecognised option. */ - return -1; + /* Unrecognised option. */ + return -1; } -static int -lv_read (void) -{ - time_t t; +static int lv_read(void) { + time_t t; + if (conn == NULL) { + /* `conn_string == NULL' is acceptable. */ + conn = virConnectOpenReadOnly(conn_string); if (conn == NULL) { - /* `conn_string == NULL' is acceptable. */ - conn = virConnectOpenReadOnly (conn_string); - if (conn == NULL) { - c_complain (LOG_ERR, &conn_complain, - PLUGIN_NAME " plugin: Unable to connect: " - "virConnectOpenReadOnly failed."); - return -1; - } + c_complain(LOG_ERR, &conn_complain, + PLUGIN_NAME " plugin: Unable to connect: " + "virConnectOpenReadOnly failed."); + return -1; } - c_release (LOG_NOTICE, &conn_complain, + } + c_release(LOG_NOTICE, &conn_complain, PLUGIN_NAME " plugin: Connection established."); - time (&t); + time(&t); - /* Need to refresh domain or device lists? */ - if ((last_refresh == (time_t) 0) || - ((interval > 0) && ((last_refresh + interval) <= t))) { - if (refresh_lists () != 0) { - if (conn != NULL) - virConnectClose (conn); - conn = NULL; - return -1; - } - last_refresh = t; + /* Need to refresh domain or device lists? */ + if ((last_refresh == (time_t)0) || + ((interval > 0) && ((last_refresh + interval) <= t))) { + if (refresh_lists() != 0) { + if (conn != NULL) + virConnectClose(conn); + conn = NULL; + return -1; } + last_refresh = t; + } #if 0 for (int i = 0; i < nr_domains; ++i) @@ -529,483 +500,472 @@ lv_read (void) interface_devices[i].path); #endif - /* Get CPU usage, memory, VCPU usage for each domain. */ - for (int i = 0; i < nr_domains; ++i) { - virDomainInfo info; - virVcpuInfoPtr vinfo = NULL; - virDomainMemoryStatPtr minfo = NULL; - int status; - - status = virDomainGetInfo (domains[i], &info); - if (status != 0) - { - ERROR (PLUGIN_NAME " plugin: virDomainGetInfo failed with status %i.", - status); - continue; - } - - if (info.state != VIR_DOMAIN_RUNNING) - { - /* only gather stats for running domains */ - continue; - } - - cpu_submit (info.cpuTime, domains[i], "virt_cpu_total"); - memory_submit ((gauge_t) info.memory * 1024, domains[i]); - - vinfo = malloc (info.nrVirtCpu * sizeof (vinfo[0])); - if (vinfo == NULL) { - ERROR (PLUGIN_NAME " plugin: malloc failed."); - continue; - } - - status = virDomainGetVcpus (domains[i], vinfo, info.nrVirtCpu, - /* cpu map = */ NULL, /* cpu map length = */ 0); - if (status < 0) - { - ERROR (PLUGIN_NAME " plugin: virDomainGetVcpus failed with status %i.", - status); - sfree (vinfo); - continue; - } - - for (int j = 0; j < info.nrVirtCpu; ++j) - vcpu_submit (vinfo[j].cpuTime, - domains[i], vinfo[j].number, "virt_vcpu"); - - sfree (vinfo); - - minfo = malloc (VIR_DOMAIN_MEMORY_STAT_NR * sizeof (virDomainMemoryStatStruct)); - if (minfo == NULL) { - ERROR ("virt plugin: malloc failed."); - continue; - } + /* Get CPU usage, memory, VCPU usage for each domain. */ + for (int i = 0; i < nr_domains; ++i) { + virDomainInfo info; + virVcpuInfoPtr vinfo = NULL; + virDomainMemoryStatPtr minfo = NULL; + int status; + + status = virDomainGetInfo(domains[i], &info); + if (status != 0) { + ERROR(PLUGIN_NAME " plugin: virDomainGetInfo failed with status %i.", + status); + continue; + } - status = virDomainMemoryStats (domains[i], minfo, VIR_DOMAIN_MEMORY_STAT_NR, 0); + if (info.state != VIR_DOMAIN_RUNNING) { + /* only gather stats for running domains */ + continue; + } - if (status < 0) { - ERROR ("virt plugin: virDomainMemoryStats failed with status %i.", - status); - sfree (minfo); - continue; - } + cpu_submit(info.cpuTime, domains[i], "virt_cpu_total"); + memory_submit((gauge_t)info.memory * 1024, domains[i]); - for (int j = 0; j < status; j++) { - memory_stats_submit ((gauge_t) minfo[j].val * 1024, domains[i], minfo[j].tag); - } + vinfo = malloc(info.nrVirtCpu * sizeof(vinfo[0])); + if (vinfo == NULL) { + ERROR(PLUGIN_NAME " plugin: malloc failed."); + continue; + } - sfree (minfo); + status = virDomainGetVcpus(domains[i], vinfo, info.nrVirtCpu, + /* cpu map = */ NULL, /* cpu map length = */ 0); + if (status < 0) { + ERROR(PLUGIN_NAME " plugin: virDomainGetVcpus failed with status %i.", + status); + sfree(vinfo); + continue; } + for (int j = 0; j < info.nrVirtCpu; ++j) + vcpu_submit(vinfo[j].cpuTime, domains[i], vinfo[j].number, "virt_vcpu"); - /* Get block device stats for each domain. */ - for (int i = 0; i < nr_block_devices; ++i) { - struct _virDomainBlockStats stats; + sfree(vinfo); - if (virDomainBlockStats (block_devices[i].dom, block_devices[i].path, - &stats, sizeof stats) != 0) - continue; + minfo = + malloc(VIR_DOMAIN_MEMORY_STAT_NR * sizeof(virDomainMemoryStatStruct)); + if (minfo == NULL) { + ERROR("virt plugin: malloc failed."); + continue; + } - char *type_instance = NULL; - if (blockdevice_format_basename && blockdevice_format == source) - type_instance = strdup(basename(block_devices[i].path)); - else - type_instance = strdup(block_devices[i].path); + status = + virDomainMemoryStats(domains[i], minfo, VIR_DOMAIN_MEMORY_STAT_NR, 0); - if ((stats.rd_req != -1) && (stats.wr_req != -1)) - submit_derive2 ("disk_ops", - (derive_t) stats.rd_req, (derive_t) stats.wr_req, - block_devices[i].dom, type_instance); + if (status < 0) { + ERROR("virt plugin: virDomainMemoryStats failed with status %i.", status); + sfree(minfo); + continue; + } - if ((stats.rd_bytes != -1) && (stats.wr_bytes != -1)) - submit_derive2 ("disk_octets", - (derive_t) stats.rd_bytes, (derive_t) stats.wr_bytes, - block_devices[i].dom, type_instance); + for (int j = 0; j < status; j++) { + memory_stats_submit((gauge_t)minfo[j].val * 1024, domains[i], + minfo[j].tag); + } - sfree (type_instance); - } /* for (nr_block_devices) */ + sfree(minfo); + } - /* Get interface stats for each domain. */ - for (int i = 0; i < nr_interface_devices; ++i) { - struct _virDomainInterfaceStats stats; - char *display_name = NULL; - - switch (interface_format) { - case if_address: - display_name = interface_devices[i].address; - break; - case if_number: - display_name = interface_devices[i].number; - break; - case if_name: - default: - display_name = interface_devices[i].path; - } + /* Get block device stats for each domain. */ + for (int i = 0; i < nr_block_devices; ++i) { + struct _virDomainBlockStats stats; - if (virDomainInterfaceStats (interface_devices[i].dom, - interface_devices[i].path, - &stats, sizeof stats) != 0) - continue; + if (virDomainBlockStats(block_devices[i].dom, block_devices[i].path, &stats, + sizeof stats) != 0) + continue; - if ((stats.rx_bytes != -1) && (stats.tx_bytes != -1)) - submit_derive2 ("if_octets", - (derive_t) stats.rx_bytes, (derive_t) stats.tx_bytes, - interface_devices[i].dom, display_name); + char *type_instance = NULL; + if (blockdevice_format_basename && blockdevice_format == source) + type_instance = strdup(basename(block_devices[i].path)); + else + type_instance = strdup(block_devices[i].path); + + if ((stats.rd_req != -1) && (stats.wr_req != -1)) + submit_derive2("disk_ops", (derive_t)stats.rd_req, (derive_t)stats.wr_req, + block_devices[i].dom, type_instance); + + if ((stats.rd_bytes != -1) && (stats.wr_bytes != -1)) + submit_derive2("disk_octets", (derive_t)stats.rd_bytes, + (derive_t)stats.wr_bytes, block_devices[i].dom, + type_instance); + + sfree(type_instance); + } /* for (nr_block_devices) */ + + /* Get interface stats for each domain. */ + for (int i = 0; i < nr_interface_devices; ++i) { + struct _virDomainInterfaceStats stats; + char *display_name = NULL; + + switch (interface_format) { + case if_address: + display_name = interface_devices[i].address; + break; + case if_number: + display_name = interface_devices[i].number; + break; + case if_name: + default: + display_name = interface_devices[i].path; + } - if ((stats.rx_packets != -1) && (stats.tx_packets != -1)) - submit_derive2 ("if_packets", - (derive_t) stats.rx_packets, (derive_t) stats.tx_packets, - interface_devices[i].dom, display_name); + if (virDomainInterfaceStats(interface_devices[i].dom, + interface_devices[i].path, &stats, + sizeof stats) != 0) + continue; + + if ((stats.rx_bytes != -1) && (stats.tx_bytes != -1)) + submit_derive2("if_octets", (derive_t)stats.rx_bytes, + (derive_t)stats.tx_bytes, interface_devices[i].dom, + display_name); + + if ((stats.rx_packets != -1) && (stats.tx_packets != -1)) + submit_derive2("if_packets", (derive_t)stats.rx_packets, + (derive_t)stats.tx_packets, interface_devices[i].dom, + display_name); + + if ((stats.rx_errs != -1) && (stats.tx_errs != -1)) + submit_derive2("if_errors", (derive_t)stats.rx_errs, + (derive_t)stats.tx_errs, interface_devices[i].dom, + display_name); + + if ((stats.rx_drop != -1) && (stats.tx_drop != -1)) + submit_derive2("if_dropped", (derive_t)stats.rx_drop, + (derive_t)stats.tx_drop, interface_devices[i].dom, + display_name); + } /* for (nr_interface_devices) */ + + return 0; +} - if ((stats.rx_errs != -1) && (stats.tx_errs != -1)) - submit_derive2 ("if_errors", - (derive_t) stats.rx_errs, (derive_t) stats.tx_errs, - interface_devices[i].dom, display_name); +static int refresh_lists(void) { + int n; - if ((stats.rx_drop != -1) && (stats.tx_drop != -1)) - submit_derive2 ("if_dropped", - (derive_t) stats.rx_drop, (derive_t) stats.tx_drop, - interface_devices[i].dom, display_name); - } /* for (nr_interface_devices) */ + n = virConnectNumOfDomains(conn); + if (n < 0) { + VIRT_ERROR(conn, "reading number of domains"); + return -1; + } - return 0; -} + if (n > 0) { + int *domids; -static int -refresh_lists (void) -{ - int n; + /* Get list of domains. */ + domids = malloc(sizeof(*domids) * n); + if (domids == NULL) { + ERROR(PLUGIN_NAME " plugin: malloc failed."); + return -1; + } - n = virConnectNumOfDomains (conn); + n = virConnectListDomains(conn, domids, n); if (n < 0) { - VIRT_ERROR (conn, "reading number of domains"); - return -1; + VIRT_ERROR(conn, "reading list of domains"); + sfree(domids); + return -1; } - if (n > 0) { - int *domids; - - /* Get list of domains. */ - domids = malloc (sizeof (*domids) * n); - if (domids == NULL) { - ERROR (PLUGIN_NAME " plugin: malloc failed."); - return -1; - } - - n = virConnectListDomains (conn, domids, n); - if (n < 0) { - VIRT_ERROR (conn, "reading list of domains"); - sfree (domids); - return -1; - } + free_block_devices(); + free_interface_devices(); + free_domains(); + + /* Fetch each domain and add it to the list, unless ignore. */ + for (int i = 0; i < n; ++i) { + virDomainPtr dom = NULL; + const char *name; + char *xml = NULL; + xmlDocPtr xml_doc = NULL; + xmlXPathContextPtr xpath_ctx = NULL; + xmlXPathObjectPtr xpath_obj = NULL; + + dom = virDomainLookupByID(conn, domids[i]); + if (dom == NULL) { + VIRT_ERROR(conn, "virDomainLookupByID"); + /* Could be that the domain went away -- ignore it anyway. */ + continue; + } + + name = virDomainGetName(dom); + if (name == NULL) { + VIRT_ERROR(conn, "virDomainGetName"); + goto cont; + } + + if (il_domains && ignorelist_match(il_domains, name) != 0) + goto cont; + + if (add_domain(dom) < 0) { + ERROR(PLUGIN_NAME " plugin: malloc failed."); + goto cont; + } + + /* Get a list of devices for this domain. */ + xml = virDomainGetXMLDesc(dom, 0); + if (!xml) { + VIRT_ERROR(conn, "virDomainGetXMLDesc"); + goto cont; + } + + /* Yuck, XML. Parse out the devices. */ + xml_doc = xmlReadDoc((xmlChar *)xml, NULL, NULL, XML_PARSE_NONET); + if (xml_doc == NULL) { + VIRT_ERROR(conn, "xmlReadDoc"); + goto cont; + } + + xpath_ctx = xmlXPathNewContext(xml_doc); + + /* Block devices. */ + char *bd_xmlpath = "/domain/devices/disk/target[@dev]"; + if (blockdevice_format == source) + bd_xmlpath = "/domain/devices/disk/source[@dev]"; + xpath_obj = xmlXPathEval((xmlChar *)bd_xmlpath, xpath_ctx); + + if (xpath_obj == NULL || xpath_obj->type != XPATH_NODESET || + xpath_obj->nodesetval == NULL) + goto cont; + + for (int j = 0; j < xpath_obj->nodesetval->nodeNr; ++j) { + xmlNodePtr node; + char *path = NULL; + + node = xpath_obj->nodesetval->nodeTab[j]; + if (!node) + continue; + path = (char *)xmlGetProp(node, (xmlChar *)"dev"); + if (!path) + continue; + + if (il_block_devices && + ignore_device_match(il_block_devices, name, path) != 0) + goto cont2; + + add_block_device(dom, path); + cont2: + if (path) + xmlFree(path); + } + xmlXPathFreeObject(xpath_obj); + + /* Network interfaces. */ + xpath_obj = xmlXPathEval( + (xmlChar *)"/domain/devices/interface[target[@dev]]", xpath_ctx); + if (xpath_obj == NULL || xpath_obj->type != XPATH_NODESET || + xpath_obj->nodesetval == NULL) + goto cont; + + xmlNodeSetPtr xml_interfaces = xpath_obj->nodesetval; + + for (int j = 0; j < xml_interfaces->nodeNr; ++j) { + char *path = NULL; + char *address = NULL; + xmlNodePtr xml_interface; + + xml_interface = xml_interfaces->nodeTab[j]; + if (!xml_interface) + continue; + + for (xmlNodePtr child = xml_interface->children; child; + child = child->next) { + if (child->type != XML_ELEMENT_NODE) + continue; - free_block_devices (); - free_interface_devices (); - free_domains (); - - /* Fetch each domain and add it to the list, unless ignore. */ - for (int i = 0; i < n; ++i) { - virDomainPtr dom = NULL; - const char *name; - char *xml = NULL; - xmlDocPtr xml_doc = NULL; - xmlXPathContextPtr xpath_ctx = NULL; - xmlXPathObjectPtr xpath_obj = NULL; - - dom = virDomainLookupByID (conn, domids[i]); - if (dom == NULL) { - VIRT_ERROR (conn, "virDomainLookupByID"); - /* Could be that the domain went away -- ignore it anyway. */ - continue; - } - - name = virDomainGetName (dom); - if (name == NULL) { - VIRT_ERROR (conn, "virDomainGetName"); - goto cont; - } - - if (il_domains && ignorelist_match (il_domains, name) != 0) - goto cont; - - if (add_domain (dom) < 0) { - ERROR (PLUGIN_NAME " plugin: malloc failed."); - goto cont; - } - - /* Get a list of devices for this domain. */ - xml = virDomainGetXMLDesc (dom, 0); - if (!xml) { - VIRT_ERROR (conn, "virDomainGetXMLDesc"); - goto cont; - } - - /* Yuck, XML. Parse out the devices. */ - xml_doc = xmlReadDoc ((xmlChar *) xml, NULL, NULL, XML_PARSE_NONET); - if (xml_doc == NULL) { - VIRT_ERROR (conn, "xmlReadDoc"); - goto cont; - } - - xpath_ctx = xmlXPathNewContext (xml_doc); - - /* Block devices. */ - char *bd_xmlpath = "/domain/devices/disk/target[@dev]"; - if (blockdevice_format == source) - bd_xmlpath = "/domain/devices/disk/source[@dev]"; - xpath_obj = xmlXPathEval ((xmlChar *) bd_xmlpath, xpath_ctx); - - if (xpath_obj == NULL || xpath_obj->type != XPATH_NODESET || - xpath_obj->nodesetval == NULL) - goto cont; - - for (int j = 0; j < xpath_obj->nodesetval->nodeNr; ++j) { - xmlNodePtr node; - char *path = NULL; - - node = xpath_obj->nodesetval->nodeTab[j]; - if (!node) continue; - path = (char *) xmlGetProp (node, (xmlChar *) "dev"); - if (!path) continue; - - if (il_block_devices && - ignore_device_match (il_block_devices, name, path) != 0) - goto cont2; - - add_block_device (dom, path); - cont2: - if (path) xmlFree (path); - } - xmlXPathFreeObject (xpath_obj); - - /* Network interfaces. */ - xpath_obj = xmlXPathEval - ((xmlChar *) "/domain/devices/interface[target[@dev]]", - xpath_ctx); - if (xpath_obj == NULL || xpath_obj->type != XPATH_NODESET || - xpath_obj->nodesetval == NULL) - goto cont; - - xmlNodeSetPtr xml_interfaces = xpath_obj->nodesetval; - - for (int j = 0; j < xml_interfaces->nodeNr; ++j) { - char *path = NULL; - char *address = NULL; - xmlNodePtr xml_interface; - - xml_interface = xml_interfaces->nodeTab[j]; - if (!xml_interface) continue; - - for (xmlNodePtr child = xml_interface->children; child; child = child->next) { - if (child->type != XML_ELEMENT_NODE) continue; - - if (xmlStrEqual(child->name, (const xmlChar *) "target")) { - path = (char *) xmlGetProp (child, (const xmlChar *) "dev"); - if (!path) continue; - } else if (xmlStrEqual(child->name, (const xmlChar *) "mac")) { - address = (char *) xmlGetProp (child, (const xmlChar *) "address"); - if (!address) continue; - } - } - - if (il_interface_devices && - (ignore_device_match (il_interface_devices, name, path) != 0 || - ignore_device_match (il_interface_devices, name, address) != 0)) - goto cont3; - - add_interface_device (dom, path, address, j+1); - cont3: - if (path) xmlFree (path); - if (address) xmlFree (address); - } - - cont: - if (xpath_obj) xmlXPathFreeObject (xpath_obj); - if (xpath_ctx) xmlXPathFreeContext (xpath_ctx); - if (xml_doc) xmlFreeDoc (xml_doc); - sfree (xml); + if (xmlStrEqual(child->name, (const xmlChar *)"target")) { + path = (char *)xmlGetProp(child, (const xmlChar *)"dev"); + if (!path) + continue; + } else if (xmlStrEqual(child->name, (const xmlChar *)"mac")) { + address = (char *)xmlGetProp(child, (const xmlChar *)"address"); + if (!address) + continue; + } } - sfree (domids); + if (il_interface_devices && + (ignore_device_match(il_interface_devices, name, path) != 0 || + ignore_device_match(il_interface_devices, name, address) != 0)) + goto cont3; + + add_interface_device(dom, path, address, j + 1); + cont3: + if (path) + xmlFree(path); + if (address) + xmlFree(address); + } + + cont: + if (xpath_obj) + xmlXPathFreeObject(xpath_obj); + if (xpath_ctx) + xmlXPathFreeContext(xpath_ctx); + if (xml_doc) + xmlFreeDoc(xml_doc); + sfree(xml); } - return 0; + sfree(domids); + } + + return 0; } -static void -free_domains (void) -{ - if (domains) { - for (int i = 0; i < nr_domains; ++i) - virDomainFree (domains[i]); - sfree (domains); - } - domains = NULL; - nr_domains = 0; +static void free_domains(void) { + if (domains) { + for (int i = 0; i < nr_domains; ++i) + virDomainFree(domains[i]); + sfree(domains); + } + domains = NULL; + nr_domains = 0; } -static int -add_domain (virDomainPtr dom) -{ - virDomainPtr *new_ptr; - int new_size = sizeof (domains[0]) * (nr_domains+1); +static int add_domain(virDomainPtr dom) { + virDomainPtr *new_ptr; + int new_size = sizeof(domains[0]) * (nr_domains + 1); - if (domains) - new_ptr = realloc (domains, new_size); - else - new_ptr = malloc (new_size); + if (domains) + new_ptr = realloc(domains, new_size); + else + new_ptr = malloc(new_size); - if (new_ptr == NULL) - return -1; + if (new_ptr == NULL) + return -1; - domains = new_ptr; - domains[nr_domains] = dom; - return nr_domains++; + domains = new_ptr; + domains[nr_domains] = dom; + return nr_domains++; } -static void -free_block_devices (void) -{ - if (block_devices) { - for (int i = 0; i < nr_block_devices; ++i) - sfree (block_devices[i].path); - sfree (block_devices); - } - block_devices = NULL; - nr_block_devices = 0; +static void free_block_devices(void) { + if (block_devices) { + for (int i = 0; i < nr_block_devices; ++i) + sfree(block_devices[i].path); + sfree(block_devices); + } + block_devices = NULL; + nr_block_devices = 0; } -static int -add_block_device (virDomainPtr dom, const char *path) -{ - struct block_device *new_ptr; - int new_size = sizeof (block_devices[0]) * (nr_block_devices+1); - char *path_copy; +static int add_block_device(virDomainPtr dom, const char *path) { + struct block_device *new_ptr; + int new_size = sizeof(block_devices[0]) * (nr_block_devices + 1); + char *path_copy; - path_copy = strdup (path); - if (!path_copy) - return -1; + path_copy = strdup(path); + if (!path_copy) + return -1; - if (block_devices) - new_ptr = realloc (block_devices, new_size); - else - new_ptr = malloc (new_size); + if (block_devices) + new_ptr = realloc(block_devices, new_size); + else + new_ptr = malloc(new_size); - if (new_ptr == NULL) { - sfree (path_copy); - return -1; - } - block_devices = new_ptr; - block_devices[nr_block_devices].dom = dom; - block_devices[nr_block_devices].path = path_copy; - return nr_block_devices++; + if (new_ptr == NULL) { + sfree(path_copy); + return -1; + } + block_devices = new_ptr; + block_devices[nr_block_devices].dom = dom; + block_devices[nr_block_devices].path = path_copy; + return nr_block_devices++; } -static void -free_interface_devices (void) -{ - if (interface_devices) { - for (int i = 0; i < nr_interface_devices; ++i) { - sfree (interface_devices[i].path); - sfree (interface_devices[i].address); - sfree (interface_devices[i].number); - } - sfree (interface_devices); +static void free_interface_devices(void) { + if (interface_devices) { + for (int i = 0; i < nr_interface_devices; ++i) { + sfree(interface_devices[i].path); + sfree(interface_devices[i].address); + sfree(interface_devices[i].number); } - interface_devices = NULL; - nr_interface_devices = 0; + sfree(interface_devices); + } + interface_devices = NULL; + nr_interface_devices = 0; } -static int -add_interface_device (virDomainPtr dom, const char *path, const char *address, unsigned int number) -{ - struct interface_device *new_ptr; - int new_size = sizeof (interface_devices[0]) * (nr_interface_devices+1); - char *path_copy, *address_copy, number_string[15]; +static int add_interface_device(virDomainPtr dom, const char *path, + const char *address, unsigned int number) { + struct interface_device *new_ptr; + int new_size = sizeof(interface_devices[0]) * (nr_interface_devices + 1); + char *path_copy, *address_copy, number_string[15]; - if ((path == NULL) || (address == NULL)) - return EINVAL; + if ((path == NULL) || (address == NULL)) + return EINVAL; - path_copy = strdup (path); - if (!path_copy) return -1; + path_copy = strdup(path); + if (!path_copy) + return -1; - address_copy = strdup (address); - if (!address_copy) { - sfree(path_copy); - return -1; - } + address_copy = strdup(address); + if (!address_copy) { + sfree(path_copy); + return -1; + } - snprintf(number_string, sizeof (number_string), "interface-%u", number); + snprintf(number_string, sizeof(number_string), "interface-%u", number); - if (interface_devices) - new_ptr = realloc (interface_devices, new_size); - else - new_ptr = malloc (new_size); + if (interface_devices) + new_ptr = realloc(interface_devices, new_size); + else + new_ptr = malloc(new_size); - if (new_ptr == NULL) { - sfree (path_copy); - sfree (address_copy); - return -1; - } - interface_devices = new_ptr; - interface_devices[nr_interface_devices].dom = dom; - interface_devices[nr_interface_devices].path = path_copy; - interface_devices[nr_interface_devices].address = address_copy; - interface_devices[nr_interface_devices].number = strdup(number_string); - return nr_interface_devices++; + if (new_ptr == NULL) { + sfree(path_copy); + sfree(address_copy); + return -1; + } + interface_devices = new_ptr; + interface_devices[nr_interface_devices].dom = dom; + interface_devices[nr_interface_devices].path = path_copy; + interface_devices[nr_interface_devices].address = address_copy; + interface_devices[nr_interface_devices].number = strdup(number_string); + return nr_interface_devices++; } -static int -ignore_device_match (ignorelist_t *il, const char *domname, const char *devpath) -{ - char *name; - int n, r; +static int ignore_device_match(ignorelist_t *il, const char *domname, + const char *devpath) { + char *name; + int n, r; - if ((domname == NULL) || (devpath == NULL)) - return 0; + if ((domname == NULL) || (devpath == NULL)) + return 0; - n = sizeof (char) * (strlen (domname) + strlen (devpath) + 2); - name = malloc (n); - if (name == NULL) { - ERROR (PLUGIN_NAME " plugin: malloc failed."); - return 0; - } - ssnprintf (name, n, "%s:%s", domname, devpath); - r = ignorelist_match (il, name); - sfree (name); - return r; + n = sizeof(char) * (strlen(domname) + strlen(devpath) + 2); + name = malloc(n); + if (name == NULL) { + ERROR(PLUGIN_NAME " plugin: malloc failed."); + return 0; + } + ssnprintf(name, n, "%s:%s", domname, devpath); + r = ignorelist_match(il, name); + sfree(name); + return r; } -static int -lv_shutdown (void) -{ - free_block_devices (); - free_interface_devices (); - free_domains (); +static int lv_shutdown(void) { + free_block_devices(); + free_interface_devices(); + free_domains(); - if (conn != NULL) - virConnectClose (conn); - conn = NULL; + if (conn != NULL) + virConnectClose(conn); + conn = NULL; - ignorelist_free (il_domains); - il_domains = NULL; - ignorelist_free (il_block_devices); - il_block_devices = NULL; - ignorelist_free (il_interface_devices); - il_interface_devices = NULL; + ignorelist_free(il_domains); + il_domains = NULL; + ignorelist_free(il_block_devices); + il_block_devices = NULL; + ignorelist_free(il_interface_devices); + il_interface_devices = NULL; - return 0; + return 0; } -void -module_register (void) -{ - plugin_register_config (PLUGIN_NAME, - lv_config, - config_keys, NR_CONFIG_KEYS); - plugin_register_init (PLUGIN_NAME, lv_init); - plugin_register_read (PLUGIN_NAME, lv_read); - plugin_register_shutdown (PLUGIN_NAME, lv_shutdown); +void module_register(void) { + plugin_register_config(PLUGIN_NAME, lv_config, config_keys, NR_CONFIG_KEYS); + plugin_register_init(PLUGIN_NAME, lv_init); + plugin_register_read(PLUGIN_NAME, lv_read); + plugin_register_shutdown(PLUGIN_NAME, lv_shutdown); } /* diff --git a/src/vmem.c b/src/vmem.c index 98c4c2a0..cd9e7d28 100644 --- a/src/vmem.c +++ b/src/vmem.c @@ -30,74 +30,62 @@ #include "plugin.h" #if KERNEL_LINUX -static const char *config_keys[] = -{ - "Verbose" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static const char *config_keys[] = {"Verbose"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); static int verbose_output = 0; /* #endif KERNEL_LINUX */ #else -# error "No applicable input method." +#error "No applicable input method." #endif /* HAVE_LIBSTATGRAB */ -static void submit (const char *plugin_instance, const char *type, - const char *type_instance, value_t *values, int values_len) -{ +static void submit(const char *plugin_instance, const char *type, + const char *type_instance, value_t *values, int values_len) { value_list_t vl = VALUE_LIST_INIT; vl.values = values; vl.values_len = values_len; - sstrncpy (vl.plugin, "vmem", sizeof (vl.plugin)); + sstrncpy(vl.plugin, "vmem", sizeof(vl.plugin)); if (plugin_instance != NULL) - sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* void vmem_submit */ -static void submit_two (const char *plugin_instance, const char *type, - const char *type_instance, derive_t c0, derive_t c1) -{ +static void submit_two(const char *plugin_instance, const char *type, + const char *type_instance, derive_t c0, derive_t c1) { value_t values[] = { - { .derive = c0 }, - { .derive = c1 }, + {.derive = c0}, {.derive = c1}, }; - submit (plugin_instance, type, type_instance, - values, STATIC_ARRAY_SIZE (values)); + submit(plugin_instance, type, type_instance, values, + STATIC_ARRAY_SIZE(values)); } /* void submit_one */ -static void submit_one (const char *plugin_instance, const char *type, - const char *type_instance, value_t value) -{ - submit (plugin_instance, type, type_instance, &value, 1); +static void submit_one(const char *plugin_instance, const char *type, + const char *type_instance, value_t value) { + submit(plugin_instance, type, type_instance, &value, 1); } /* void submit_one */ -static int vmem_config (const char *key, const char *value) -{ - if (strcasecmp ("Verbose", key) == 0) - { - if (IS_TRUE (value)) +static int vmem_config(const char *key, const char *value) { + if (strcasecmp("Verbose", key) == 0) { + if (IS_TRUE(value)) verbose_output = 1; else verbose_output = 0; - } - else - { + } else { return (-1); } return (0); } /* int vmem_config */ -static int vmem_read (void) -{ +static int vmem_read(void) { #if KERNEL_LINUX derive_t pgpgin = 0; derive_t pgpgout = 0; @@ -114,17 +102,15 @@ static int vmem_read (void) FILE *fh; char buffer[1024]; - fh = fopen ("/proc/vmstat", "r"); - if (fh == NULL) - { + fh = fopen("/proc/vmstat", "r"); + if (fh == NULL) { char errbuf[1024]; - ERROR ("vmem plugin: fopen (/proc/vmstat) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + ERROR("vmem plugin: fopen (/proc/vmstat) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { + while (fgets(buffer, sizeof(buffer), fh) != NULL) { char *fields[4]; int fields_num; char *key; @@ -132,19 +118,19 @@ static int vmem_read (void) derive_t counter; gauge_t gauge; - fields_num = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields)); + fields_num = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); if (fields_num != 2) continue; key = fields[0]; endptr = NULL; - counter = strtoll (fields[1], &endptr, 10); + counter = strtoll(fields[1], &endptr, 10); if (fields[1] == endptr) continue; endptr = NULL; - gauge = strtod (fields[1], &endptr); + gauge = strtod(fields[1], &endptr); if (fields[1] == endptr) continue; @@ -153,41 +139,30 @@ static int vmem_read (void) * * The total number of {inst} pages, e. g dirty pages. */ - if (strncmp ("nr_", key, strlen ("nr_")) == 0) - { - char *inst = key + strlen ("nr_"); - if (strcmp(inst, "dirtied") == 0 || strcmp(inst, "written") == 0) - { - value_t value = { .derive = counter }; - submit_one (NULL, "vmpage_action", inst, value); - } - else - { - value_t value = { .gauge = gauge }; - submit_one (NULL, "vmpage_number", inst, value); + if (strncmp("nr_", key, strlen("nr_")) == 0) { + char *inst = key + strlen("nr_"); + if (strcmp(inst, "dirtied") == 0 || strcmp(inst, "written") == 0) { + value_t value = {.derive = counter}; + submit_one(NULL, "vmpage_action", inst, value); + } else { + value_t value = {.gauge = gauge}; + submit_one(NULL, "vmpage_number", inst, value); } } /* * Page in and page outs. For memory and swap. */ - else if (strcmp ("pgpgin", key) == 0) - { + else if (strcmp("pgpgin", key) == 0) { pgpgin = counter; pgpgvalid |= 0x01; - } - else if (strcmp ("pgpgout", key) == 0) - { + } else if (strcmp("pgpgout", key) == 0) { pgpgout = counter; pgpgvalid |= 0x02; - } - else if (strcmp ("pswpin", key) == 0) - { + } else if (strcmp("pswpin", key) == 0) { pswpin = counter; pswpvalid |= 0x01; - } - else if (strcmp ("pswpout", key) == 0) - { + } else if (strcmp("pswpout", key) == 0) { pswpout = counter; pswpvalid |= 0x02; } @@ -195,13 +170,10 @@ static int vmem_read (void) /* * Pagefaults */ - else if (strcmp ("pgfault", key) == 0) - { + else if (strcmp("pgfault", key) == 0) { pgfault = counter; pgfaultvalid |= 0x01; - } - else if (strcmp ("pgmajfault", key) == 0) - { + } else if (strcmp("pgmajfault", key) == 0) { pgmajfault = counter; pgfaultvalid |= 0x02; } @@ -216,48 +188,38 @@ static int vmem_read (void) * Number of page allocations, refills, steals and scans. This is collected * ``per zone'', i. e. for DMA, DMA32, normal and possibly highmem. */ - else if (strncmp ("pgalloc_", key, strlen ("pgalloc_")) == 0) - { - char *inst = key + strlen ("pgalloc_"); - value_t value = { .derive = counter }; - submit_one (inst, "vmpage_action", "alloc", value); - } - else if (strncmp ("pgrefill_", key, strlen ("pgrefill_")) == 0) - { - char *inst = key + strlen ("pgrefill_"); - value_t value = { .derive = counter }; - submit_one (inst, "vmpage_action", "refill", value); - } - else if (strncmp ("pgsteal_kswapd_", key, strlen ("pgsteal_kswapd_")) == 0) - { - char *inst = key + strlen ("pgsteal_kswapd_"); - value_t value = { .derive = counter }; - submit_one (inst, "vmpage_action", "steal_kswapd", value); - } - else if (strncmp ("pgsteal_direct_", key, strlen ("pgsteal_direct_")) == 0) - { - char *inst = key + strlen ("pgsteal_direct_"); - value_t value = { .derive = counter }; - submit_one (inst, "vmpage_action", "steal_direct", value); + else if (strncmp("pgalloc_", key, strlen("pgalloc_")) == 0) { + char *inst = key + strlen("pgalloc_"); + value_t value = {.derive = counter}; + submit_one(inst, "vmpage_action", "alloc", value); + } else if (strncmp("pgrefill_", key, strlen("pgrefill_")) == 0) { + char *inst = key + strlen("pgrefill_"); + value_t value = {.derive = counter}; + submit_one(inst, "vmpage_action", "refill", value); + } else if (strncmp("pgsteal_kswapd_", key, strlen("pgsteal_kswapd_")) == + 0) { + char *inst = key + strlen("pgsteal_kswapd_"); + value_t value = {.derive = counter}; + submit_one(inst, "vmpage_action", "steal_kswapd", value); + } else if (strncmp("pgsteal_direct_", key, strlen("pgsteal_direct_")) == + 0) { + char *inst = key + strlen("pgsteal_direct_"); + value_t value = {.derive = counter}; + submit_one(inst, "vmpage_action", "steal_direct", value); } /* For backwards compatibility (somewhen before 4.2.3) */ - else if (strncmp ("pgsteal_", key, strlen ("pgsteal_")) == 0) - { - char *inst = key + strlen ("pgsteal_"); - value_t value = { .derive = counter }; - submit_one (inst, "vmpage_action", "steal", value); - } - else if (strncmp ("pgscan_kswapd_", key, strlen ("pgscan_kswapd_")) == 0) - { - char *inst = key + strlen ("pgscan_kswapd_"); - value_t value = { .derive = counter }; - submit_one (inst, "vmpage_action", "scan_kswapd", value); - } - else if (strncmp ("pgscan_direct_", key, strlen ("pgscan_direct_")) == 0) - { - char *inst = key + strlen ("pgscan_direct_"); - value_t value = { .derive = counter }; - submit_one (inst, "vmpage_action", "scan_direct", value); + else if (strncmp("pgsteal_", key, strlen("pgsteal_")) == 0) { + char *inst = key + strlen("pgsteal_"); + value_t value = {.derive = counter}; + submit_one(inst, "vmpage_action", "steal", value); + } else if (strncmp("pgscan_kswapd_", key, strlen("pgscan_kswapd_")) == 0) { + char *inst = key + strlen("pgscan_kswapd_"); + value_t value = {.derive = counter}; + submit_one(inst, "vmpage_action", "scan_kswapd", value); + } else if (strncmp("pgscan_direct_", key, strlen("pgscan_direct_")) == 0) { + char *inst = key + strlen("pgscan_direct_"); + value_t value = {.derive = counter}; + submit_one(inst, "vmpage_action", "scan_direct", value); } /* @@ -266,44 +228,37 @@ static int vmem_read (void) * number of pages moved to the active or inactive lists and freed, i. e. * removed from either list. */ - else if (strcmp ("pgfree", key) == 0) - { - value_t value = { .derive = counter }; - submit_one (NULL, "vmpage_action", "free", value); - } - else if (strcmp ("pgactivate", key) == 0) - { - value_t value = { .derive = counter }; - submit_one (NULL, "vmpage_action", "activate", value); - } - else if (strcmp ("pgdeactivate", key) == 0) - { - value_t value = { .derive = counter }; - submit_one (NULL, "vmpage_action", "deactivate", value); + else if (strcmp("pgfree", key) == 0) { + value_t value = {.derive = counter}; + submit_one(NULL, "vmpage_action", "free", value); + } else if (strcmp("pgactivate", key) == 0) { + value_t value = {.derive = counter}; + submit_one(NULL, "vmpage_action", "activate", value); + } else if (strcmp("pgdeactivate", key) == 0) { + value_t value = {.derive = counter}; + submit_one(NULL, "vmpage_action", "deactivate", value); } } /* while (fgets) */ - fclose (fh); + fclose(fh); fh = NULL; if (pgfaultvalid == 0x03) - submit_two (NULL, "vmpage_faults", NULL, pgfault, pgmajfault); + submit_two(NULL, "vmpage_faults", NULL, pgfault, pgmajfault); if (pgpgvalid == 0x03) - submit_two (NULL, "vmpage_io", "memory", pgpgin, pgpgout); + submit_two(NULL, "vmpage_io", "memory", pgpgin, pgpgout); if (pswpvalid == 0x03) - submit_two (NULL, "vmpage_io", "swap", pswpin, pswpout); + submit_two(NULL, "vmpage_io", "swap", pswpin, pswpout); #endif /* KERNEL_LINUX */ return (0); } /* int vmem_read */ -void module_register (void) -{ - plugin_register_config ("vmem", vmem_config, - config_keys, config_keys_num); - plugin_register_read ("vmem", vmem_read); +void module_register(void) { + plugin_register_config("vmem", vmem_config, config_keys, config_keys_num); + plugin_register_read("vmem", vmem_read); } /* void module_register */ /* vim: set sw=2 sts=2 ts=8 : */ diff --git a/src/vserver.c b/src/vserver.c index 0e58a971..c5a7fb33 100644 --- a/src/vserver.c +++ b/src/vserver.c @@ -39,317 +39,287 @@ #define PROCDIR "/proc/virtual" #if !KERNEL_LINUX -# error "No applicable input method." +#error "No applicable input method." #endif static int pagesize = 0; -static int vserver_init (void) -{ - /* XXX Should we check for getpagesize () in configure? - * What's the right thing to do, if there is no getpagesize ()? */ - pagesize = getpagesize (); +static int vserver_init(void) { + /* XXX Should we check for getpagesize () in configure? + * What's the right thing to do, if there is no getpagesize ()? */ + pagesize = getpagesize(); - return (0); + return (0); } /* static void vserver_init(void) */ -static void traffic_submit (const char *plugin_instance, - const char *type_instance, derive_t rx, derive_t tx) -{ - value_list_t vl = VALUE_LIST_INIT; - value_t values[] = { - { .derive = rx }, - { .derive = tx }, - }; - - vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - sstrncpy (vl.plugin, "vserver", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, "if_octets", sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); +static void traffic_submit(const char *plugin_instance, + const char *type_instance, derive_t rx, + derive_t tx) { + value_list_t vl = VALUE_LIST_INIT; + value_t values[] = { + {.derive = rx}, {.derive = tx}, + }; + + vl.values = values; + vl.values_len = STATIC_ARRAY_SIZE(values); + sstrncpy(vl.plugin, "vserver", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "if_octets", sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); } /* void traffic_submit */ -static void load_submit (const char *plugin_instance, - gauge_t snum, gauge_t mnum, gauge_t lnum) -{ - value_list_t vl = VALUE_LIST_INIT; - value_t values[] = { - { .gauge = snum }, - { .gauge = mnum }, - { .gauge = lnum }, - }; - - vl.values = values; - vl.values_len = STATIC_ARRAY_SIZE (values); - sstrncpy (vl.plugin, "vserver", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, "load", sizeof (vl.type)); - - plugin_dispatch_values (&vl); +static void load_submit(const char *plugin_instance, gauge_t snum, gauge_t mnum, + gauge_t lnum) { + value_list_t vl = VALUE_LIST_INIT; + value_t values[] = { + {.gauge = snum}, {.gauge = mnum}, {.gauge = lnum}, + }; + + vl.values = values; + vl.values_len = STATIC_ARRAY_SIZE(values); + sstrncpy(vl.plugin, "vserver", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "load", sizeof(vl.type)); + + plugin_dispatch_values(&vl); } -static void submit_gauge (const char *plugin_instance, const char *type, - const char *type_instance, gauge_t value) +static void submit_gauge(const char *plugin_instance, const char *type, + const char *type_instance, gauge_t value) { - value_list_t vl = VALUE_LIST_INIT; + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "vserver", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "vserver", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* void submit_gauge */ -static derive_t vserver_get_sock_bytes(const char *s) -{ - value_t v; - int status; +static derive_t vserver_get_sock_bytes(const char *s) { + value_t v; + int status; - while (s[0] != '/') - ++s; + while (s[0] != '/') + ++s; - /* Remove '/' */ - ++s; + /* Remove '/' */ + ++s; - status = parse_value (s, &v, DS_TYPE_DERIVE); - if (status != 0) - return (-1); - return (v.derive); + status = parse_value(s, &v, DS_TYPE_DERIVE); + if (status != 0) + return (-1); + return (v.derive); } -static int vserver_read (void) -{ - DIR *proc; - - errno = 0; - proc = opendir (PROCDIR); - if (proc == NULL) - { - char errbuf[1024]; - ERROR ("vserver plugin: fopen (%s): %s", PROCDIR, - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - while (42) - { - struct dirent *dent; - int len; - char file[BUFSIZE]; - - FILE *fh; - char buffer[BUFSIZE]; - - struct stat statbuf; - char *cols[4]; - - int status; - - errno = 0; - dent = readdir (proc); - if (dent == NULL) - { - char errbuf[4096]; - - if (errno == 0) /* end of directory */ - break; - - ERROR ("vserver plugin: failed to read directory %s: %s", - PROCDIR, sstrerror (errno, errbuf, sizeof (errbuf))); - closedir (proc); - return (-1); - } - - if (dent->d_name[0] == '.') - continue; - - len = ssnprintf (file, sizeof (file), PROCDIR "/%s", dent->d_name); - if ((len < 0) || (len >= BUFSIZE)) - continue; - - status = stat (file, &statbuf); - if (status != 0) - { - char errbuf[4096]; - WARNING ("vserver plugin: stat (%s) failed: %s", - file, sstrerror (errno, errbuf, sizeof (errbuf))); - continue; - } - - if (!S_ISDIR (statbuf.st_mode)) - continue; - - /* socket message accounting */ - len = ssnprintf (file, sizeof (file), - PROCDIR "/%s/cacct", dent->d_name); - if ((len < 0) || ((size_t) len >= sizeof (file))) - continue; - - if (NULL == (fh = fopen (file, "r"))) - { - char errbuf[1024]; - ERROR ("Cannot open '%s': %s", file, - sstrerror (errno, errbuf, sizeof (errbuf))); - } - - while ((fh != NULL) && (NULL != fgets (buffer, BUFSIZE, fh))) - { - derive_t rx; - derive_t tx; - const char *type_instance; - - if (strsplit (buffer, cols, 4) < 4) - continue; - - if (0 == strcmp (cols[0], "UNIX:")) - type_instance = "unix"; - else if (0 == strcmp (cols[0], "INET:")) - type_instance = "inet"; - else if (0 == strcmp (cols[0], "INET6:")) - type_instance = "inet6"; - else if (0 == strcmp (cols[0], "OTHER:")) - type_instance = "other"; - else if (0 == strcmp (cols[0], "UNSPEC:")) - type_instance = "unspec"; - else - continue; - - rx = vserver_get_sock_bytes (cols[1]); - tx = vserver_get_sock_bytes (cols[2]); - /* cols[3] == errors */ - - traffic_submit (dent->d_name, type_instance, rx, tx); - } /* while (fgets) */ - - if (fh != NULL) - { - fclose (fh); - fh = NULL; - } - - /* thread information and load */ - len = ssnprintf (file, sizeof (file), - PROCDIR "/%s/cvirt", dent->d_name); - if ((len < 0) || ((size_t) len >= sizeof (file))) - continue; - - if (NULL == (fh = fopen (file, "r"))) - { - char errbuf[1024]; - ERROR ("Cannot open '%s': %s", file, - sstrerror (errno, errbuf, sizeof (errbuf))); - } - - while ((fh != NULL) && (NULL != fgets (buffer, BUFSIZE, fh))) - { - int n = strsplit (buffer, cols, 4); - - if (2 == n) - { - const char *type_instance; - gauge_t value; - - if (0 == strcmp (cols[0], "nr_threads:")) - type_instance = "total"; - else if (0 == strcmp (cols[0], "nr_running:")) - type_instance = "running"; - else if (0 == strcmp (cols[0], "nr_unintr:")) - type_instance = "uninterruptable"; - else if (0 == strcmp (cols[0], "nr_onhold:")) - type_instance = "onhold"; - else - continue; - - value = atof (cols[1]); - submit_gauge (dent->d_name, "vs_threads", type_instance, value); - } - else if (4 == n) { - if (0 == strcmp (cols[0], "loadavg:")) - { - gauge_t snum = atof (cols[1]); - gauge_t mnum = atof (cols[2]); - gauge_t lnum = atof (cols[3]); - load_submit (dent->d_name, snum, mnum, lnum); - } - } - } /* while (fgets) */ - - if (fh != NULL) - { - fclose (fh); - fh = NULL; - } - - /* processes and memory usage */ - len = ssnprintf (file, sizeof (file), - PROCDIR "/%s/limit", dent->d_name); - if ((len < 0) || ((size_t) len >= sizeof (file))) - continue; - - if (NULL == (fh = fopen (file, "r"))) - { - char errbuf[1024]; - ERROR ("Cannot open '%s': %s", file, - sstrerror (errno, errbuf, sizeof (errbuf))); - } - - while ((fh != NULL) && (NULL != fgets (buffer, BUFSIZE, fh))) - { - const char *type = "vs_memory"; - const char *type_instance; - gauge_t value; - - if (strsplit (buffer, cols, 2) < 2) - continue; - - if (0 == strcmp (cols[0], "PROC:")) - { - type = "vs_processes"; - type_instance = ""; - value = atof (cols[1]); - } - else - { - if (0 == strcmp (cols[0], "VM:")) - type_instance = "vm"; - else if (0 == strcmp (cols[0], "VML:")) - type_instance = "vml"; - else if (0 == strcmp (cols[0], "RSS:")) - type_instance = "rss"; - else if (0 == strcmp (cols[0], "ANON:")) - type_instance = "anon"; - else - continue; - - value = atof (cols[1]) * pagesize; - } - - submit_gauge (dent->d_name, type, type_instance, value); - } /* while (fgets) */ - - if (fh != NULL) - { - fclose (fh); - fh = NULL; - } - } /* while (readdir) */ - - closedir (proc); - - return (0); +static int vserver_read(void) { + DIR *proc; + + errno = 0; + proc = opendir(PROCDIR); + if (proc == NULL) { + char errbuf[1024]; + ERROR("vserver plugin: fopen (%s): %s", PROCDIR, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + while (42) { + struct dirent *dent; + int len; + char file[BUFSIZE]; + + FILE *fh; + char buffer[BUFSIZE]; + + struct stat statbuf; + char *cols[4]; + + int status; + + errno = 0; + dent = readdir(proc); + if (dent == NULL) { + char errbuf[4096]; + + if (errno == 0) /* end of directory */ + break; + + ERROR("vserver plugin: failed to read directory %s: %s", PROCDIR, + sstrerror(errno, errbuf, sizeof(errbuf))); + closedir(proc); + return (-1); + } + + if (dent->d_name[0] == '.') + continue; + + len = ssnprintf(file, sizeof(file), PROCDIR "/%s", dent->d_name); + if ((len < 0) || (len >= BUFSIZE)) + continue; + + status = stat(file, &statbuf); + if (status != 0) { + char errbuf[4096]; + WARNING("vserver plugin: stat (%s) failed: %s", file, + sstrerror(errno, errbuf, sizeof(errbuf))); + continue; + } + + if (!S_ISDIR(statbuf.st_mode)) + continue; + + /* socket message accounting */ + len = ssnprintf(file, sizeof(file), PROCDIR "/%s/cacct", dent->d_name); + if ((len < 0) || ((size_t)len >= sizeof(file))) + continue; + + if (NULL == (fh = fopen(file, "r"))) { + char errbuf[1024]; + ERROR("Cannot open '%s': %s", file, + sstrerror(errno, errbuf, sizeof(errbuf))); + } + + while ((fh != NULL) && (NULL != fgets(buffer, BUFSIZE, fh))) { + derive_t rx; + derive_t tx; + const char *type_instance; + + if (strsplit(buffer, cols, 4) < 4) + continue; + + if (0 == strcmp(cols[0], "UNIX:")) + type_instance = "unix"; + else if (0 == strcmp(cols[0], "INET:")) + type_instance = "inet"; + else if (0 == strcmp(cols[0], "INET6:")) + type_instance = "inet6"; + else if (0 == strcmp(cols[0], "OTHER:")) + type_instance = "other"; + else if (0 == strcmp(cols[0], "UNSPEC:")) + type_instance = "unspec"; + else + continue; + + rx = vserver_get_sock_bytes(cols[1]); + tx = vserver_get_sock_bytes(cols[2]); + /* cols[3] == errors */ + + traffic_submit(dent->d_name, type_instance, rx, tx); + } /* while (fgets) */ + + if (fh != NULL) { + fclose(fh); + fh = NULL; + } + + /* thread information and load */ + len = ssnprintf(file, sizeof(file), PROCDIR "/%s/cvirt", dent->d_name); + if ((len < 0) || ((size_t)len >= sizeof(file))) + continue; + + if (NULL == (fh = fopen(file, "r"))) { + char errbuf[1024]; + ERROR("Cannot open '%s': %s", file, + sstrerror(errno, errbuf, sizeof(errbuf))); + } + + while ((fh != NULL) && (NULL != fgets(buffer, BUFSIZE, fh))) { + int n = strsplit(buffer, cols, 4); + + if (2 == n) { + const char *type_instance; + gauge_t value; + + if (0 == strcmp(cols[0], "nr_threads:")) + type_instance = "total"; + else if (0 == strcmp(cols[0], "nr_running:")) + type_instance = "running"; + else if (0 == strcmp(cols[0], "nr_unintr:")) + type_instance = "uninterruptable"; + else if (0 == strcmp(cols[0], "nr_onhold:")) + type_instance = "onhold"; + else + continue; + + value = atof(cols[1]); + submit_gauge(dent->d_name, "vs_threads", type_instance, value); + } else if (4 == n) { + if (0 == strcmp(cols[0], "loadavg:")) { + gauge_t snum = atof(cols[1]); + gauge_t mnum = atof(cols[2]); + gauge_t lnum = atof(cols[3]); + load_submit(dent->d_name, snum, mnum, lnum); + } + } + } /* while (fgets) */ + + if (fh != NULL) { + fclose(fh); + fh = NULL; + } + + /* processes and memory usage */ + len = ssnprintf(file, sizeof(file), PROCDIR "/%s/limit", dent->d_name); + if ((len < 0) || ((size_t)len >= sizeof(file))) + continue; + + if (NULL == (fh = fopen(file, "r"))) { + char errbuf[1024]; + ERROR("Cannot open '%s': %s", file, + sstrerror(errno, errbuf, sizeof(errbuf))); + } + + while ((fh != NULL) && (NULL != fgets(buffer, BUFSIZE, fh))) { + const char *type = "vs_memory"; + const char *type_instance; + gauge_t value; + + if (strsplit(buffer, cols, 2) < 2) + continue; + + if (0 == strcmp(cols[0], "PROC:")) { + type = "vs_processes"; + type_instance = ""; + value = atof(cols[1]); + } else { + if (0 == strcmp(cols[0], "VM:")) + type_instance = "vm"; + else if (0 == strcmp(cols[0], "VML:")) + type_instance = "vml"; + else if (0 == strcmp(cols[0], "RSS:")) + type_instance = "rss"; + else if (0 == strcmp(cols[0], "ANON:")) + type_instance = "anon"; + else + continue; + + value = atof(cols[1]) * pagesize; + } + + submit_gauge(dent->d_name, type, type_instance, value); + } /* while (fgets) */ + + if (fh != NULL) { + fclose(fh); + fh = NULL; + } + } /* while (readdir) */ + + closedir(proc); + + return (0); } /* int vserver_read */ -void module_register (void) -{ - plugin_register_init ("vserver", vserver_init); - plugin_register_read ("vserver", vserver_read); +void module_register(void) { + plugin_register_init("vserver", vserver_init); + plugin_register_read("vserver", vserver_read); } /* void module_register(void) */ /* vim: set ts=4 sw=4 noexpandtab : */ diff --git a/src/wireless.c b/src/wireless.c index 16aad50f..ae77ded8 100644 --- a/src/wireless.c +++ b/src/wireless.c @@ -30,7 +30,7 @@ #include "plugin.h" #if !KERNEL_LINUX -# error "No applicable input method." +#error "No applicable input method." #endif #define WIRELESS_PROC_FILE "/proc/net/wireless" @@ -51,120 +51,112 @@ static double wireless_dbm_to_watt (double dbm) } #endif -static void wireless_submit (const char *plugin_instance, const char *type, - double value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void wireless_submit(const char *plugin_instance, const char *type, + double value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "wireless", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, plugin_instance, - sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "wireless", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* void wireless_submit */ #define POWER_MIN -90.0 #define POWER_MAX -50.0 -static double wireless_percent_to_power (double quality) -{ - assert ((quality >= 0.0) && (quality <= 100.0)); +static double wireless_percent_to_power(double quality) { + assert((quality >= 0.0) && (quality <= 100.0)); - return ((quality * (POWER_MAX - POWER_MIN)) + POWER_MIN); + return ((quality * (POWER_MAX - POWER_MIN)) + POWER_MIN); } /* double wireless_percent_to_power */ -static int wireless_read (void) -{ +static int wireless_read(void) { #ifdef KERNEL_LINUX - FILE *fh; - char buffer[1024]; - - char *device; - double quality; - double power; - double noise; - - char *fields[8]; - int numfields; - - int devices_found; - int len; - - /* there are a variety of names for the wireless device */ - if ((fh = fopen (WIRELESS_PROC_FILE, "r")) == NULL) - { - char errbuf[1024]; - WARNING ("wireless: fopen: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - devices_found = 0; - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - char *endptr; - - numfields = strsplit (buffer, fields, 8); - - if (numfields < 5) - continue; - - len = strlen (fields[0]) - 1; - if (len < 1) - continue; - if (fields[0][len] != ':') - continue; - fields[0][len] = '\0'; - - device = fields[0]; - - quality = strtod (fields[2], &endptr); - if (fields[2] == endptr) - quality = -1.0; /* invalid */ - - /* power [dBm] < 0.0 */ - power = strtod (fields[3], &endptr); - if (fields[3] == endptr) - power = 1.0; /* invalid */ - else if ((power >= 0.0) && (power <= 100.0)) - power = wireless_percent_to_power (power); - else if ((power > 100.0) && (power <= 256.0)) - power = power - 256.0; - else if (power > 0.0) - power = 1.0; /* invalid */ - - /* noise [dBm] < 0.0 */ - noise = strtod (fields[4], &endptr); - if (fields[4] == endptr) - noise = 1.0; /* invalid */ - else if ((noise >= 0.0) && (noise <= 100.0)) - noise = wireless_percent_to_power (noise); - else if ((noise > 100.0) && (noise <= 256.0)) - noise = noise - 256.0; - else if (noise > 0.0) - noise = 1.0; /* invalid */ - - wireless_submit (device, "signal_quality", quality); - wireless_submit (device, "signal_power", power); - wireless_submit (device, "signal_noise", noise); - - devices_found++; - } - - fclose (fh); - - /* If no wireless devices are present return an error, so the plugin - * code delays our read function. */ - if (devices_found == 0) - return (-1); + FILE *fh; + char buffer[1024]; + + char *device; + double quality; + double power; + double noise; + + char *fields[8]; + int numfields; + + int devices_found; + int len; + + /* there are a variety of names for the wireless device */ + if ((fh = fopen(WIRELESS_PROC_FILE, "r")) == NULL) { + char errbuf[1024]; + WARNING("wireless: fopen: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + devices_found = 0; + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + char *endptr; + + numfields = strsplit(buffer, fields, 8); + + if (numfields < 5) + continue; + + len = strlen(fields[0]) - 1; + if (len < 1) + continue; + if (fields[0][len] != ':') + continue; + fields[0][len] = '\0'; + + device = fields[0]; + + quality = strtod(fields[2], &endptr); + if (fields[2] == endptr) + quality = -1.0; /* invalid */ + + /* power [dBm] < 0.0 */ + power = strtod(fields[3], &endptr); + if (fields[3] == endptr) + power = 1.0; /* invalid */ + else if ((power >= 0.0) && (power <= 100.0)) + power = wireless_percent_to_power(power); + else if ((power > 100.0) && (power <= 256.0)) + power = power - 256.0; + else if (power > 0.0) + power = 1.0; /* invalid */ + + /* noise [dBm] < 0.0 */ + noise = strtod(fields[4], &endptr); + if (fields[4] == endptr) + noise = 1.0; /* invalid */ + else if ((noise >= 0.0) && (noise <= 100.0)) + noise = wireless_percent_to_power(noise); + else if ((noise > 100.0) && (noise <= 256.0)) + noise = noise - 256.0; + else if (noise > 0.0) + noise = 1.0; /* invalid */ + + wireless_submit(device, "signal_quality", quality); + wireless_submit(device, "signal_power", power); + wireless_submit(device, "signal_noise", noise); + + devices_found++; + } + + fclose(fh); + + /* If no wireless devices are present return an error, so the plugin + * code delays our read function. */ + if (devices_found == 0) + return (-1); #endif /* KERNEL_LINUX */ - return (0); + return (0); } /* int wireless_read */ -void module_register (void) -{ - plugin_register_read ("wireless", wireless_read); +void module_register(void) { + plugin_register_read("wireless", wireless_read); } /* void module_register */ diff --git a/src/write_graphite.c b/src/write_graphite.c index 9feb6b33..b85ab470 100644 --- a/src/write_graphite.c +++ b/src/write_graphite.c @@ -29,18 +29,18 @@ * Based on the write_http plugin. **/ - /* write_graphite plugin configuation example - * - * - * - * Host "localhost" - * Port "2003" - * Protocol "udp" - * LogSendErrors true - * Prefix "collectd" - * - * - */ +/* write_graphite plugin configuation example + * + * + * + * Host "localhost" + * Port "2003" + * Protocol "udp" + * LogSendErrors true + * Prefix "collectd" + * + * + */ #include "collectd.h" @@ -53,587 +53,535 @@ #include #ifndef WG_DEFAULT_NODE -# define WG_DEFAULT_NODE "localhost" +#define WG_DEFAULT_NODE "localhost" #endif #ifndef WG_DEFAULT_SERVICE -# define WG_DEFAULT_SERVICE "2003" +#define WG_DEFAULT_SERVICE "2003" #endif #ifndef WG_DEFAULT_PROTOCOL -# define WG_DEFAULT_PROTOCOL "tcp" +#define WG_DEFAULT_PROTOCOL "tcp" #endif #ifndef WG_DEFAULT_LOG_SEND_ERRORS -# define WG_DEFAULT_LOG_SEND_ERRORS 1 +#define WG_DEFAULT_LOG_SEND_ERRORS 1 #endif #ifndef WG_DEFAULT_ESCAPE -# define WG_DEFAULT_ESCAPE '_' +#define WG_DEFAULT_ESCAPE '_' #endif /* Ethernet - (IPv6 + TCP) = 1500 - (40 + 32) = 1428 */ #ifndef WG_SEND_BUF_SIZE -# define WG_SEND_BUF_SIZE 1428 +#define WG_SEND_BUF_SIZE 1428 #endif #ifndef WG_MIN_RECONNECT_INTERVAL -# define WG_MIN_RECONNECT_INTERVAL TIME_T_TO_CDTIME_T (1) +#define WG_MIN_RECONNECT_INTERVAL TIME_T_TO_CDTIME_T(1) #endif /* * Private variables */ -struct wg_callback -{ - int sock_fd; - - char *name; - - char *node; - char *service; - char *protocol; - _Bool log_send_errors; - char *prefix; - char *postfix; - char escape_char; - - unsigned int format_flags; - - char send_buf[WG_SEND_BUF_SIZE]; - size_t send_buf_free; - size_t send_buf_fill; - cdtime_t send_buf_init_time; - - pthread_mutex_t send_lock; - c_complain_t init_complaint; - cdtime_t last_connect_time; - - /* Force reconnect useful for load balanced environments */ - cdtime_t last_reconnect_time; - cdtime_t reconnect_interval; - _Bool reconnect_interval_reached; +struct wg_callback { + int sock_fd; + + char *name; + + char *node; + char *service; + char *protocol; + _Bool log_send_errors; + char *prefix; + char *postfix; + char escape_char; + + unsigned int format_flags; + + char send_buf[WG_SEND_BUF_SIZE]; + size_t send_buf_free; + size_t send_buf_fill; + cdtime_t send_buf_init_time; + + pthread_mutex_t send_lock; + c_complain_t init_complaint; + cdtime_t last_connect_time; + + /* Force reconnect useful for load balanced environments */ + cdtime_t last_reconnect_time; + cdtime_t reconnect_interval; + _Bool reconnect_interval_reached; }; /* wg_force_reconnect_check closes cb->sock_fd when it was open for longer * than cb->reconnect_interval. Must hold cb->send_lock when calling. */ -static void wg_force_reconnect_check (struct wg_callback *cb) -{ - cdtime_t now; +static void wg_force_reconnect_check(struct wg_callback *cb) { + cdtime_t now; - if (cb->reconnect_interval == 0) - return; + if (cb->reconnect_interval == 0) + return; - /* check if address changes if addr_timeout */ - now = cdtime (); - if ((now - cb->last_reconnect_time) < cb->reconnect_interval) - return; + /* check if address changes if addr_timeout */ + now = cdtime(); + if ((now - cb->last_reconnect_time) < cb->reconnect_interval) + return; - /* here we should close connection on next */ - close (cb->sock_fd); - cb->sock_fd = -1; - cb->last_reconnect_time = now; - cb->reconnect_interval_reached = 1; + /* here we should close connection on next */ + close(cb->sock_fd); + cb->sock_fd = -1; + cb->last_reconnect_time = now; + cb->reconnect_interval_reached = 1; - INFO ("write_graphite plugin: Connection closed after %.3f seconds.", - CDTIME_T_TO_DOUBLE (now - cb->last_reconnect_time)); + INFO("write_graphite plugin: Connection closed after %.3f seconds.", + CDTIME_T_TO_DOUBLE(now - cb->last_reconnect_time)); } /* * Functions */ -static void wg_reset_buffer (struct wg_callback *cb) -{ - memset (cb->send_buf, 0, sizeof (cb->send_buf)); - cb->send_buf_free = sizeof (cb->send_buf); - cb->send_buf_fill = 0; - cb->send_buf_init_time = cdtime (); +static void wg_reset_buffer(struct wg_callback *cb) { + memset(cb->send_buf, 0, sizeof(cb->send_buf)); + cb->send_buf_free = sizeof(cb->send_buf); + cb->send_buf_fill = 0; + cb->send_buf_init_time = cdtime(); } -static int wg_send_buffer (struct wg_callback *cb) -{ - ssize_t status; +static int wg_send_buffer(struct wg_callback *cb) { + ssize_t status; - if (cb->sock_fd < 0) - return (-1); + if (cb->sock_fd < 0) + return (-1); - status = swrite (cb->sock_fd, cb->send_buf, strlen (cb->send_buf)); - if (status != 0) - { - if (cb->log_send_errors) - { - char errbuf[1024]; - ERROR ("write_graphite plugin: send to %s:%s (%s) failed with status %zi (%s)", - cb->node, cb->service, cb->protocol, - status, sstrerror (errno, errbuf, sizeof (errbuf))); - } - - close (cb->sock_fd); - cb->sock_fd = -1; - - return (-1); + status = swrite(cb->sock_fd, cb->send_buf, strlen(cb->send_buf)); + if (status != 0) { + if (cb->log_send_errors) { + char errbuf[1024]; + ERROR("write_graphite plugin: send to %s:%s (%s) failed with status %zi " + "(%s)", + cb->node, cb->service, cb->protocol, status, + sstrerror(errno, errbuf, sizeof(errbuf))); } - return (0); -} + close(cb->sock_fd); + cb->sock_fd = -1; -/* NOTE: You must hold cb->send_lock when calling this function! */ -static int wg_flush_nolock (cdtime_t timeout, struct wg_callback *cb) -{ - int status; - - DEBUG ("write_graphite plugin: wg_flush_nolock: timeout = %.3f; " - "send_buf_fill = %zu;", - (double)timeout, - cb->send_buf_fill); - - /* timeout == 0 => flush unconditionally */ - if (timeout > 0) - { - cdtime_t now; - - now = cdtime (); - if ((cb->send_buf_init_time + timeout) > now) - return (0); - } + return (-1); + } - if (cb->send_buf_fill == 0) - { - cb->send_buf_init_time = cdtime (); - return (0); - } + return (0); +} - status = wg_send_buffer (cb); - wg_reset_buffer (cb); +/* NOTE: You must hold cb->send_lock when calling this function! */ +static int wg_flush_nolock(cdtime_t timeout, struct wg_callback *cb) { + int status; - return (status); -} + DEBUG("write_graphite plugin: wg_flush_nolock: timeout = %.3f; " + "send_buf_fill = %zu;", + (double)timeout, cb->send_buf_fill); -static int wg_callback_init (struct wg_callback *cb) -{ - struct addrinfo *ai_list; + /* timeout == 0 => flush unconditionally */ + if (timeout > 0) { cdtime_t now; - int status; - char connerr[1024] = ""; + now = cdtime(); + if ((cb->send_buf_init_time + timeout) > now) + return (0); + } - if (cb->sock_fd > 0) - return (0); + if (cb->send_buf_fill == 0) { + cb->send_buf_init_time = cdtime(); + return (0); + } - /* Don't try to reconnect too often. By default, one reconnection attempt - * is made per second. */ - now = cdtime (); - if ((now - cb->last_connect_time) < WG_MIN_RECONNECT_INTERVAL) - return (EAGAIN); - cb->last_connect_time = now; + status = wg_send_buffer(cb); + wg_reset_buffer(cb); - struct addrinfo ai_hints = { - .ai_family = AF_UNSPEC, - .ai_flags = AI_ADDRCONFIG - }; + return (status); +} - if (0 == strcasecmp ("tcp", cb->protocol)) - ai_hints.ai_socktype = SOCK_STREAM; - else - ai_hints.ai_socktype = SOCK_DGRAM; +static int wg_callback_init(struct wg_callback *cb) { + struct addrinfo *ai_list; + cdtime_t now; + int status; - status = getaddrinfo (cb->node, cb->service, &ai_hints, &ai_list); - if (status != 0) - { - ERROR ("write_graphite plugin: getaddrinfo (%s, %s, %s) failed: %s", - cb->node, cb->service, cb->protocol, gai_strerror (status)); - return (-1); - } + char connerr[1024] = ""; - assert (ai_list != NULL); - for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) - { - cb->sock_fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, - ai_ptr->ai_protocol); - if (cb->sock_fd < 0) { - char errbuf[1024]; - snprintf (connerr, sizeof (connerr), "failed to open socket: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - continue; - } - - set_sock_opts (cb->sock_fd); - - status = connect (cb->sock_fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); - if (status != 0) - { - char errbuf[1024]; - snprintf (connerr, sizeof (connerr), "failed to connect to remote " - "host: %s", sstrerror (errno, errbuf, sizeof (errbuf))); - close (cb->sock_fd); - cb->sock_fd = -1; - continue; - } - - break; - } + if (cb->sock_fd > 0) + return (0); - freeaddrinfo (ai_list); - - if (cb->sock_fd < 0) - { - if (connerr[0] == '\0') - /* this should not happen but try to get a message anyway */ - sstrerror (errno, connerr, sizeof (connerr)); - c_complain (LOG_ERR, &cb->init_complaint, - "write_graphite plugin: Connecting to %s:%s via %s failed. " - "The last error was: %s", cb->node, cb->service, cb->protocol, connerr); - return (-1); + /* Don't try to reconnect too often. By default, one reconnection attempt + * is made per second. */ + now = cdtime(); + if ((now - cb->last_connect_time) < WG_MIN_RECONNECT_INTERVAL) + return (EAGAIN); + cb->last_connect_time = now; + + struct addrinfo ai_hints = {.ai_family = AF_UNSPEC, + .ai_flags = AI_ADDRCONFIG}; + + if (0 == strcasecmp("tcp", cb->protocol)) + ai_hints.ai_socktype = SOCK_STREAM; + else + ai_hints.ai_socktype = SOCK_DGRAM; + + status = getaddrinfo(cb->node, cb->service, &ai_hints, &ai_list); + if (status != 0) { + ERROR("write_graphite plugin: getaddrinfo (%s, %s, %s) failed: %s", + cb->node, cb->service, cb->protocol, gai_strerror(status)); + return (-1); + } + + assert(ai_list != NULL); + for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; + ai_ptr = ai_ptr->ai_next) { + cb->sock_fd = + socket(ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); + if (cb->sock_fd < 0) { + char errbuf[1024]; + snprintf(connerr, sizeof(connerr), "failed to open socket: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + continue; } - else - { - c_release (LOG_INFO, &cb->init_complaint, - "write_graphite plugin: Successfully connected to %s:%s via %s.", - cb->node, cb->service, cb->protocol); + + set_sock_opts(cb->sock_fd); + + status = connect(cb->sock_fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); + if (status != 0) { + char errbuf[1024]; + snprintf(connerr, sizeof(connerr), "failed to connect to remote " + "host: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(cb->sock_fd); + cb->sock_fd = -1; + continue; } - /* wg_force_reconnect_check does not flush the buffer before closing a - * sending socket, so only call wg_reset_buffer() if the socket was closed - * for a different reason (tracked in cb->reconnect_interval_reached). */ - if (!cb->reconnect_interval_reached || (cb->send_buf_free == 0)) - wg_reset_buffer (cb); - else - cb->reconnect_interval_reached = 0; + break; + } + + freeaddrinfo(ai_list); + + if (cb->sock_fd < 0) { + if (connerr[0] == '\0') + /* this should not happen but try to get a message anyway */ + sstrerror(errno, connerr, sizeof(connerr)); + c_complain(LOG_ERR, &cb->init_complaint, + "write_graphite plugin: Connecting to %s:%s via %s failed. " + "The last error was: %s", + cb->node, cb->service, cb->protocol, connerr); + return (-1); + } else { + c_release(LOG_INFO, &cb->init_complaint, + "write_graphite plugin: Successfully connected to %s:%s via %s.", + cb->node, cb->service, cb->protocol); + } + + /* wg_force_reconnect_check does not flush the buffer before closing a + * sending socket, so only call wg_reset_buffer() if the socket was closed + * for a different reason (tracked in cb->reconnect_interval_reached). */ + if (!cb->reconnect_interval_reached || (cb->send_buf_free == 0)) + wg_reset_buffer(cb); + else + cb->reconnect_interval_reached = 0; - return (0); + return (0); } -static void wg_callback_free (void *data) -{ - struct wg_callback *cb; +static void wg_callback_free(void *data) { + struct wg_callback *cb; - if (data == NULL) - return; + if (data == NULL) + return; - cb = data; + cb = data; - pthread_mutex_lock (&cb->send_lock); + pthread_mutex_lock(&cb->send_lock); - wg_flush_nolock (/* timeout = */ 0, cb); + wg_flush_nolock(/* timeout = */ 0, cb); - if (cb->sock_fd >= 0) - { - close (cb->sock_fd); - cb->sock_fd = -1; - } + if (cb->sock_fd >= 0) { + close(cb->sock_fd); + cb->sock_fd = -1; + } - sfree(cb->name); - sfree(cb->node); - sfree(cb->protocol); - sfree(cb->service); - sfree(cb->prefix); - sfree(cb->postfix); + sfree(cb->name); + sfree(cb->node); + sfree(cb->protocol); + sfree(cb->service); + sfree(cb->prefix); + sfree(cb->postfix); - pthread_mutex_destroy (&cb->send_lock); + pthread_mutex_destroy(&cb->send_lock); - sfree(cb); + sfree(cb); } -static int wg_flush (cdtime_t timeout, - const char *identifier __attribute__((unused)), - user_data_t *user_data) -{ - struct wg_callback *cb; - int status; - - if (user_data == NULL) - return (-EINVAL); - - cb = user_data->data; - - pthread_mutex_lock (&cb->send_lock); - - if (cb->sock_fd < 0) - { - status = wg_callback_init (cb); - if (status != 0) - { - /* An error message has already been printed. */ - pthread_mutex_unlock (&cb->send_lock); - return (-1); - } +static int wg_flush(cdtime_t timeout, + const char *identifier __attribute__((unused)), + user_data_t *user_data) { + struct wg_callback *cb; + int status; + + if (user_data == NULL) + return (-EINVAL); + + cb = user_data->data; + + pthread_mutex_lock(&cb->send_lock); + + if (cb->sock_fd < 0) { + status = wg_callback_init(cb); + if (status != 0) { + /* An error message has already been printed. */ + pthread_mutex_unlock(&cb->send_lock); + return (-1); } + } - status = wg_flush_nolock (timeout, cb); - pthread_mutex_unlock (&cb->send_lock); + status = wg_flush_nolock(timeout, cb); + pthread_mutex_unlock(&cb->send_lock); - return (status); + return (status); } -static int wg_send_message (char const *message, struct wg_callback *cb) -{ - int status; - size_t message_len; +static int wg_send_message(char const *message, struct wg_callback *cb) { + int status; + size_t message_len; - message_len = strlen (message); + message_len = strlen(message); - pthread_mutex_lock (&cb->send_lock); + pthread_mutex_lock(&cb->send_lock); - wg_force_reconnect_check (cb); + wg_force_reconnect_check(cb); - if (cb->sock_fd < 0) - { - status = wg_callback_init (cb); - if (status != 0) - { - /* An error message has already been printed. */ - pthread_mutex_unlock (&cb->send_lock); - return (-1); - } + if (cb->sock_fd < 0) { + status = wg_callback_init(cb); + if (status != 0) { + /* An error message has already been printed. */ + pthread_mutex_unlock(&cb->send_lock); + return (-1); } + } - if (message_len >= cb->send_buf_free) - { - status = wg_flush_nolock (/* timeout = */ 0, cb); - if (status != 0) - { - pthread_mutex_unlock (&cb->send_lock); - return (status); - } + if (message_len >= cb->send_buf_free) { + status = wg_flush_nolock(/* timeout = */ 0, cb); + if (status != 0) { + pthread_mutex_unlock(&cb->send_lock); + return (status); } + } - /* Assert that we have enough space for this message. */ - assert (message_len < cb->send_buf_free); + /* Assert that we have enough space for this message. */ + assert(message_len < cb->send_buf_free); - /* `message_len + 1' because `message_len' does not include the - * trailing null byte. Neither does `send_buffer_fill'. */ - memcpy (cb->send_buf + cb->send_buf_fill, - message, message_len + 1); - cb->send_buf_fill += message_len; - cb->send_buf_free -= message_len; + /* `message_len + 1' because `message_len' does not include the + * trailing null byte. Neither does `send_buffer_fill'. */ + memcpy(cb->send_buf + cb->send_buf_fill, message, message_len + 1); + cb->send_buf_fill += message_len; + cb->send_buf_free -= message_len; - DEBUG ("write_graphite plugin: [%s]:%s (%s) buf %zu/%zu (%.1f %%) \"%s\"", - cb->node, cb->service, cb->protocol, - cb->send_buf_fill, sizeof (cb->send_buf), - 100.0 * ((double) cb->send_buf_fill) / ((double) sizeof (cb->send_buf)), - message); + DEBUG("write_graphite plugin: [%s]:%s (%s) buf %zu/%zu (%.1f %%) \"%s\"", + cb->node, cb->service, cb->protocol, cb->send_buf_fill, + sizeof(cb->send_buf), + 100.0 * ((double)cb->send_buf_fill) / ((double)sizeof(cb->send_buf)), + message); - pthread_mutex_unlock (&cb->send_lock); + pthread_mutex_unlock(&cb->send_lock); - return (0); + return (0); } -static int wg_write_messages (const data_set_t *ds, const value_list_t *vl, - struct wg_callback *cb) -{ - char buffer[WG_SEND_BUF_SIZE] = { 0 }; - int status; - - if (0 != strcmp (ds->type, vl->type)) - { - ERROR ("write_graphite plugin: DS type does not match " - "value list type"); - return -1; - } +static int wg_write_messages(const data_set_t *ds, const value_list_t *vl, + struct wg_callback *cb) { + char buffer[WG_SEND_BUF_SIZE] = {0}; + int status; - status = format_graphite (buffer, sizeof (buffer), ds, vl, - cb->prefix, cb->postfix, cb->escape_char, cb->format_flags); - if (status != 0) /* error message has been printed already. */ - return (status); + if (0 != strcmp(ds->type, vl->type)) { + ERROR("write_graphite plugin: DS type does not match " + "value list type"); + return -1; + } - /* Send the message to graphite */ - status = wg_send_message (buffer, cb); - if (status != 0) /* error message has been printed already. */ - return (status); + status = format_graphite(buffer, sizeof(buffer), ds, vl, cb->prefix, + cb->postfix, cb->escape_char, cb->format_flags); + if (status != 0) /* error message has been printed already. */ + return (status); - return (0); + /* Send the message to graphite */ + status = wg_send_message(buffer, cb); + if (status != 0) /* error message has been printed already. */ + return (status); + + return (0); } /* int wg_write_messages */ -static int wg_write (const data_set_t *ds, const value_list_t *vl, - user_data_t *user_data) -{ - struct wg_callback *cb; - int status; +static int wg_write(const data_set_t *ds, const value_list_t *vl, + user_data_t *user_data) { + struct wg_callback *cb; + int status; - if (user_data == NULL) - return (EINVAL); + if (user_data == NULL) + return (EINVAL); - cb = user_data->data; + cb = user_data->data; - status = wg_write_messages (ds, vl, cb); + status = wg_write_messages(ds, vl, cb); - return (status); + return (status); } -static int config_set_char (char *dest, - oconfig_item_t *ci) -{ - char buffer[4] = { 0 }; - int status; +static int config_set_char(char *dest, oconfig_item_t *ci) { + char buffer[4] = {0}; + int status; - status = cf_util_get_string_buffer (ci, buffer, sizeof (buffer)); - if (status != 0) - return (status); + status = cf_util_get_string_buffer(ci, buffer, sizeof(buffer)); + if (status != 0) + return (status); - if (buffer[0] == 0) - { - ERROR ("write_graphite plugin: Cannot use an empty string for the " - "\"EscapeCharacter\" option."); - return (-1); - } + if (buffer[0] == 0) { + ERROR("write_graphite plugin: Cannot use an empty string for the " + "\"EscapeCharacter\" option."); + return (-1); + } - if (buffer[1] != 0) - { - WARNING ("write_graphite plugin: Only the first character of the " - "\"EscapeCharacter\" option ('%c') will be used.", - (int) buffer[0]); - } + if (buffer[1] != 0) { + WARNING("write_graphite plugin: Only the first character of the " + "\"EscapeCharacter\" option ('%c') will be used.", + (int)buffer[0]); + } - *dest = buffer[0]; + *dest = buffer[0]; - return (0); + return (0); } -static int wg_config_node (oconfig_item_t *ci) -{ - struct wg_callback *cb; - char callback_name[DATA_MAX_NAME_LEN]; - int status = 0; - - cb = calloc (1, sizeof (*cb)); - if (cb == NULL) - { - ERROR ("write_graphite plugin: calloc failed."); - return (-1); +static int wg_config_node(oconfig_item_t *ci) { + struct wg_callback *cb; + char callback_name[DATA_MAX_NAME_LEN]; + int status = 0; + + cb = calloc(1, sizeof(*cb)); + if (cb == NULL) { + ERROR("write_graphite plugin: calloc failed."); + return (-1); + } + cb->sock_fd = -1; + cb->name = NULL; + cb->node = strdup(WG_DEFAULT_NODE); + cb->service = strdup(WG_DEFAULT_SERVICE); + cb->protocol = strdup(WG_DEFAULT_PROTOCOL); + cb->last_reconnect_time = cdtime(); + cb->reconnect_interval = 0; + cb->reconnect_interval_reached = 0; + cb->log_send_errors = WG_DEFAULT_LOG_SEND_ERRORS; + cb->prefix = NULL; + cb->postfix = NULL; + cb->escape_char = WG_DEFAULT_ESCAPE; + cb->format_flags = GRAPHITE_STORE_RATES; + + /* FIXME: Legacy configuration syntax. */ + if (strcasecmp("Carbon", ci->key) != 0) { + status = cf_util_get_string(ci, &cb->name); + if (status != 0) { + wg_callback_free(cb); + return (status); } - cb->sock_fd = -1; - cb->name = NULL; - cb->node = strdup (WG_DEFAULT_NODE); - cb->service = strdup (WG_DEFAULT_SERVICE); - cb->protocol = strdup (WG_DEFAULT_PROTOCOL); - cb->last_reconnect_time = cdtime(); - cb->reconnect_interval = 0; - cb->reconnect_interval_reached = 0; - cb->log_send_errors = WG_DEFAULT_LOG_SEND_ERRORS; - cb->prefix = NULL; - cb->postfix = NULL; - cb->escape_char = WG_DEFAULT_ESCAPE; - cb->format_flags = GRAPHITE_STORE_RATES; - - /* FIXME: Legacy configuration syntax. */ - if (strcasecmp ("Carbon", ci->key) != 0) - { - status = cf_util_get_string (ci, &cb->name); - if (status != 0) - { - wg_callback_free (cb); - return (status); - } - } - - pthread_mutex_init (&cb->send_lock, /* attr = */ NULL); - C_COMPLAIN_INIT (&cb->init_complaint); - - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("Host", child->key) == 0) - cf_util_get_string (child, &cb->node); - else if (strcasecmp ("Port", child->key) == 0) - cf_util_get_service (child, &cb->service); - else if (strcasecmp ("Protocol", child->key) == 0) - { - cf_util_get_string (child, &cb->protocol); - - if (strcasecmp ("UDP", cb->protocol) != 0 && - strcasecmp ("TCP", cb->protocol) != 0) - { - ERROR ("write_graphite plugin: Unknown protocol (%s)", - cb->protocol); - status = -1; - } - } - else if (strcasecmp ("ReconnectInterval", child->key) == 0) - cf_util_get_cdtime (child, &cb->reconnect_interval); - else if (strcasecmp ("LogSendErrors", child->key) == 0) - cf_util_get_boolean (child, &cb->log_send_errors); - else if (strcasecmp ("Prefix", child->key) == 0) - cf_util_get_string (child, &cb->prefix); - else if (strcasecmp ("Postfix", child->key) == 0) - cf_util_get_string (child, &cb->postfix); - else if (strcasecmp ("StoreRates", child->key) == 0) - cf_util_get_flag (child, &cb->format_flags, - GRAPHITE_STORE_RATES); - else if (strcasecmp ("SeparateInstances", child->key) == 0) - cf_util_get_flag (child, &cb->format_flags, - GRAPHITE_SEPARATE_INSTANCES); - else if (strcasecmp ("AlwaysAppendDS", child->key) == 0) - cf_util_get_flag (child, &cb->format_flags, - GRAPHITE_ALWAYS_APPEND_DS); - else if (strcasecmp ("PreserveSeparator", child->key) == 0) - cf_util_get_flag (child, &cb->format_flags, - GRAPHITE_PRESERVE_SEPARATOR); - else if (strcasecmp ("DropDuplicateFields", child->key) == 0) - cf_util_get_flag (child, &cb->format_flags, - GRAPHITE_DROP_DUPE_FIELDS); - else if (strcasecmp ("EscapeCharacter", child->key) == 0) - config_set_char (&cb->escape_char, child); - else - { - ERROR ("write_graphite plugin: Invalid configuration " - "option: %s.", child->key); - status = -1; - } - - if (status != 0) - break; + } + + pthread_mutex_init(&cb->send_lock, /* attr = */ NULL); + C_COMPLAIN_INIT(&cb->init_complaint); + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Host", child->key) == 0) + cf_util_get_string(child, &cb->node); + else if (strcasecmp("Port", child->key) == 0) + cf_util_get_service(child, &cb->service); + else if (strcasecmp("Protocol", child->key) == 0) { + cf_util_get_string(child, &cb->protocol); + + if (strcasecmp("UDP", cb->protocol) != 0 && + strcasecmp("TCP", cb->protocol) != 0) { + ERROR("write_graphite plugin: Unknown protocol (%s)", cb->protocol); + status = -1; + } + } else if (strcasecmp("ReconnectInterval", child->key) == 0) + cf_util_get_cdtime(child, &cb->reconnect_interval); + else if (strcasecmp("LogSendErrors", child->key) == 0) + cf_util_get_boolean(child, &cb->log_send_errors); + else if (strcasecmp("Prefix", child->key) == 0) + cf_util_get_string(child, &cb->prefix); + else if (strcasecmp("Postfix", child->key) == 0) + cf_util_get_string(child, &cb->postfix); + else if (strcasecmp("StoreRates", child->key) == 0) + cf_util_get_flag(child, &cb->format_flags, GRAPHITE_STORE_RATES); + else if (strcasecmp("SeparateInstances", child->key) == 0) + cf_util_get_flag(child, &cb->format_flags, GRAPHITE_SEPARATE_INSTANCES); + else if (strcasecmp("AlwaysAppendDS", child->key) == 0) + cf_util_get_flag(child, &cb->format_flags, GRAPHITE_ALWAYS_APPEND_DS); + else if (strcasecmp("PreserveSeparator", child->key) == 0) + cf_util_get_flag(child, &cb->format_flags, GRAPHITE_PRESERVE_SEPARATOR); + else if (strcasecmp("DropDuplicateFields", child->key) == 0) + cf_util_get_flag(child, &cb->format_flags, GRAPHITE_DROP_DUPE_FIELDS); + else if (strcasecmp("EscapeCharacter", child->key) == 0) + config_set_char(&cb->escape_char, child); + else { + ERROR("write_graphite plugin: Invalid configuration " + "option: %s.", + child->key); + status = -1; } if (status != 0) - { - wg_callback_free (cb); - return (status); - } + break; + } + + if (status != 0) { + wg_callback_free(cb); + return (status); + } - /* FIXME: Legacy configuration syntax. */ - if (cb->name == NULL) - ssnprintf (callback_name, sizeof (callback_name), "write_graphite/%s/%s/%s", - cb->node, cb->service, cb->protocol); - else - ssnprintf (callback_name, sizeof (callback_name), "write_graphite/%s", - cb->name); + /* FIXME: Legacy configuration syntax. */ + if (cb->name == NULL) + ssnprintf(callback_name, sizeof(callback_name), "write_graphite/%s/%s/%s", + cb->node, cb->service, cb->protocol); + else + ssnprintf(callback_name, sizeof(callback_name), "write_graphite/%s", + cb->name); - plugin_register_write (callback_name, wg_write, - &(user_data_t) { - .data = cb, - .free_func = wg_callback_free, - }); + plugin_register_write(callback_name, wg_write, + &(user_data_t){ + .data = cb, .free_func = wg_callback_free, + }); - plugin_register_flush (callback_name, wg_flush, &(user_data_t) { .data = cb }); + plugin_register_flush(callback_name, wg_flush, &(user_data_t){.data = cb}); - return (0); + return (0); } -static int wg_config (oconfig_item_t *ci) -{ - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("Node", child->key) == 0) - wg_config_node (child); - /* FIXME: Remove this legacy mode in version 6. */ - else if (strcasecmp ("Carbon", child->key) == 0) - wg_config_node (child); - else - { - ERROR ("write_graphite plugin: Invalid configuration " - "option: %s.", child->key); - } +static int wg_config(oconfig_item_t *ci) { + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Node", child->key) == 0) + wg_config_node(child); + /* FIXME: Remove this legacy mode in version 6. */ + else if (strcasecmp("Carbon", child->key) == 0) + wg_config_node(child); + else { + ERROR("write_graphite plugin: Invalid configuration " + "option: %s.", + child->key); } + } - return (0); + return (0); } -void module_register (void) -{ - plugin_register_complex_config ("write_graphite", wg_config); +void module_register(void) { + plugin_register_complex_config("write_graphite", wg_config); } /* vim: set sw=4 ts=4 sts=4 tw=78 et : */ diff --git a/src/write_http.c b/src/write_http.c index b3baa555..c1b3f0b0 100644 --- a/src/write_http.c +++ b/src/write_http.c @@ -25,621 +25,568 @@ #include "collectd.h" -#include "plugin.h" #include "common.h" +#include "plugin.h" #include "utils_format_json.h" #include "utils_format_kairosdb.h" #include #ifndef WRITE_HTTP_DEFAULT_BUFFER_SIZE -# define WRITE_HTTP_DEFAULT_BUFFER_SIZE 4096 +#define WRITE_HTTP_DEFAULT_BUFFER_SIZE 4096 #endif /* * Private variables */ -struct wh_callback_s -{ - char *name; - - char *location; - char *user; - char *pass; - char *credentials; - _Bool verify_peer; - _Bool verify_host; - char *cacert; - char *capath; - char *clientkey; - char *clientcert; - char *clientkeypass; - long sslversion; - _Bool store_rates; - _Bool log_http_error; - int low_speed_limit; - time_t low_speed_time; - int timeout; - -#define WH_FORMAT_COMMAND 0 -#define WH_FORMAT_JSON 1 +struct wh_callback_s { + char *name; + + char *location; + char *user; + char *pass; + char *credentials; + _Bool verify_peer; + _Bool verify_host; + char *cacert; + char *capath; + char *clientkey; + char *clientcert; + char *clientkeypass; + long sslversion; + _Bool store_rates; + _Bool log_http_error; + int low_speed_limit; + time_t low_speed_time; + int timeout; + +#define WH_FORMAT_COMMAND 0 +#define WH_FORMAT_JSON 1 #define WH_FORMAT_KAIROSDB 2 - int format; - _Bool send_metrics; - _Bool send_notifications; + int format; + _Bool send_metrics; + _Bool send_notifications; - CURL *curl; - struct curl_slist *headers; - char curl_errbuf[CURL_ERROR_SIZE]; + CURL *curl; + struct curl_slist *headers; + char curl_errbuf[CURL_ERROR_SIZE]; - char *send_buffer; - size_t send_buffer_size; - size_t send_buffer_free; - size_t send_buffer_fill; - cdtime_t send_buffer_init_time; + char *send_buffer; + size_t send_buffer_size; + size_t send_buffer_free; + size_t send_buffer_fill; + cdtime_t send_buffer_init_time; - pthread_mutex_t send_lock; + pthread_mutex_t send_lock; }; typedef struct wh_callback_s wh_callback_t; -static void wh_log_http_error (wh_callback_t *cb) -{ - if (!cb->log_http_error) - return; +static void wh_log_http_error(wh_callback_t *cb) { + if (!cb->log_http_error) + return; - long http_code = 0; + long http_code = 0; - curl_easy_getinfo (cb->curl, CURLINFO_RESPONSE_CODE, &http_code); + curl_easy_getinfo(cb->curl, CURLINFO_RESPONSE_CODE, &http_code); - if (http_code != 200) - INFO ("write_http plugin: HTTP Error code: %lu", http_code); + if (http_code != 200) + INFO("write_http plugin: HTTP Error code: %lu", http_code); } -static void wh_reset_buffer (wh_callback_t *cb) /* {{{ */ +static void wh_reset_buffer(wh_callback_t *cb) /* {{{ */ { - if ((cb == NULL) || (cb->send_buffer == NULL)) - return; - - memset (cb->send_buffer, 0, cb->send_buffer_size); - cb->send_buffer_free = cb->send_buffer_size; - cb->send_buffer_fill = 0; - cb->send_buffer_init_time = cdtime (); - - if (cb->format == WH_FORMAT_JSON || cb->format == WH_FORMAT_KAIROSDB) - { - format_json_initialize (cb->send_buffer, - &cb->send_buffer_fill, - &cb->send_buffer_free); - } + if ((cb == NULL) || (cb->send_buffer == NULL)) + return; + + memset(cb->send_buffer, 0, cb->send_buffer_size); + cb->send_buffer_free = cb->send_buffer_size; + cb->send_buffer_fill = 0; + cb->send_buffer_init_time = cdtime(); + + if (cb->format == WH_FORMAT_JSON || cb->format == WH_FORMAT_KAIROSDB) { + format_json_initialize(cb->send_buffer, &cb->send_buffer_fill, + &cb->send_buffer_free); + } } /* }}} wh_reset_buffer */ /* must hold cb->send_lock when calling */ -static int wh_post_nolock (wh_callback_t *cb, char const *data) /* {{{ */ +static int wh_post_nolock(wh_callback_t *cb, char const *data) /* {{{ */ { - int status = 0; + int status = 0; - curl_easy_setopt (cb->curl, CURLOPT_POSTFIELDS, data); - status = curl_easy_perform (cb->curl); + curl_easy_setopt(cb->curl, CURLOPT_POSTFIELDS, data); + status = curl_easy_perform(cb->curl); - wh_log_http_error (cb); + wh_log_http_error(cb); - if (status != CURLE_OK) - { - ERROR ("write_http plugin: curl_easy_perform failed with " - "status %i: %s", - status, cb->curl_errbuf); - } - return (status); + if (status != CURLE_OK) { + ERROR("write_http plugin: curl_easy_perform failed with " + "status %i: %s", + status, cb->curl_errbuf); + } + return (status); } /* }}} wh_post_nolock */ -static int wh_callback_init (wh_callback_t *cb) /* {{{ */ +static int wh_callback_init(wh_callback_t *cb) /* {{{ */ { - if (cb->curl != NULL) - return (0); - - cb->curl = curl_easy_init (); - if (cb->curl == NULL) - { - ERROR ("curl plugin: curl_easy_init failed."); - return (-1); - } - - if (cb->low_speed_limit > 0 && cb->low_speed_time > 0) - { - curl_easy_setopt (cb->curl, CURLOPT_LOW_SPEED_LIMIT, - (long) (cb->low_speed_limit * cb->low_speed_time)); - curl_easy_setopt (cb->curl, CURLOPT_LOW_SPEED_TIME, - (long) cb->low_speed_time); - } + if (cb->curl != NULL) + return (0); + + cb->curl = curl_easy_init(); + if (cb->curl == NULL) { + ERROR("curl plugin: curl_easy_init failed."); + return (-1); + } + + if (cb->low_speed_limit > 0 && cb->low_speed_time > 0) { + curl_easy_setopt(cb->curl, CURLOPT_LOW_SPEED_LIMIT, + (long)(cb->low_speed_limit * cb->low_speed_time)); + curl_easy_setopt(cb->curl, CURLOPT_LOW_SPEED_TIME, + (long)cb->low_speed_time); + } #ifdef HAVE_CURLOPT_TIMEOUT_MS - if (cb->timeout > 0) - curl_easy_setopt (cb->curl, CURLOPT_TIMEOUT_MS, (long) cb->timeout); + if (cb->timeout > 0) + curl_easy_setopt(cb->curl, CURLOPT_TIMEOUT_MS, (long)cb->timeout); #endif - curl_easy_setopt (cb->curl, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt (cb->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); + curl_easy_setopt(cb->curl, CURLOPT_NOSIGNAL, 1L); + curl_easy_setopt(cb->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); - cb->headers = curl_slist_append (cb->headers, "Accept: */*"); - if (cb->format == WH_FORMAT_JSON || cb->format == WH_FORMAT_KAIROSDB) - cb->headers = curl_slist_append (cb->headers, "Content-Type: application/json"); - else - cb->headers = curl_slist_append (cb->headers, "Content-Type: text/plain"); - cb->headers = curl_slist_append (cb->headers, "Expect:"); - curl_easy_setopt (cb->curl, CURLOPT_HTTPHEADER, cb->headers); + cb->headers = curl_slist_append(cb->headers, "Accept: */*"); + if (cb->format == WH_FORMAT_JSON || cb->format == WH_FORMAT_KAIROSDB) + cb->headers = + curl_slist_append(cb->headers, "Content-Type: application/json"); + else + cb->headers = curl_slist_append(cb->headers, "Content-Type: text/plain"); + cb->headers = curl_slist_append(cb->headers, "Expect:"); + curl_easy_setopt(cb->curl, CURLOPT_HTTPHEADER, cb->headers); - curl_easy_setopt (cb->curl, CURLOPT_ERRORBUFFER, cb->curl_errbuf); - curl_easy_setopt (cb->curl, CURLOPT_URL, cb->location); - curl_easy_setopt (cb->curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt (cb->curl, CURLOPT_MAXREDIRS, 50L); + curl_easy_setopt(cb->curl, CURLOPT_ERRORBUFFER, cb->curl_errbuf); + curl_easy_setopt(cb->curl, CURLOPT_URL, cb->location); + curl_easy_setopt(cb->curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(cb->curl, CURLOPT_MAXREDIRS, 50L); - if (cb->user != NULL) - { + if (cb->user != NULL) { #ifdef HAVE_CURLOPT_USERNAME - curl_easy_setopt (cb->curl, CURLOPT_USERNAME, cb->user); - curl_easy_setopt (cb->curl, CURLOPT_PASSWORD, - (cb->pass == NULL) ? "" : cb->pass); + curl_easy_setopt(cb->curl, CURLOPT_USERNAME, cb->user); + curl_easy_setopt(cb->curl, CURLOPT_PASSWORD, + (cb->pass == NULL) ? "" : cb->pass); #else - size_t credentials_size; - - credentials_size = strlen (cb->user) + 2; - if (cb->pass != NULL) - credentials_size += strlen (cb->pass); - - cb->credentials = malloc (credentials_size); - if (cb->credentials == NULL) - { - ERROR ("curl plugin: malloc failed."); - return (-1); - } - - ssnprintf (cb->credentials, credentials_size, "%s:%s", - cb->user, (cb->pass == NULL) ? "" : cb->pass); - curl_easy_setopt (cb->curl, CURLOPT_USERPWD, cb->credentials); + size_t credentials_size; + + credentials_size = strlen(cb->user) + 2; + if (cb->pass != NULL) + credentials_size += strlen(cb->pass); + + cb->credentials = malloc(credentials_size); + if (cb->credentials == NULL) { + ERROR("curl plugin: malloc failed."); + return (-1); + } + + ssnprintf(cb->credentials, credentials_size, "%s:%s", cb->user, + (cb->pass == NULL) ? "" : cb->pass); + curl_easy_setopt(cb->curl, CURLOPT_USERPWD, cb->credentials); #endif - curl_easy_setopt (cb->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - } - - curl_easy_setopt (cb->curl, CURLOPT_SSL_VERIFYPEER, (long) cb->verify_peer); - curl_easy_setopt (cb->curl, CURLOPT_SSL_VERIFYHOST, - cb->verify_host ? 2L : 0L); - curl_easy_setopt (cb->curl, CURLOPT_SSLVERSION, cb->sslversion); - if (cb->cacert != NULL) - curl_easy_setopt (cb->curl, CURLOPT_CAINFO, cb->cacert); - if (cb->capath != NULL) - curl_easy_setopt (cb->curl, CURLOPT_CAPATH, cb->capath); - - if (cb->clientkey != NULL && cb->clientcert != NULL) - { - curl_easy_setopt (cb->curl, CURLOPT_SSLKEY, cb->clientkey); - curl_easy_setopt (cb->curl, CURLOPT_SSLCERT, cb->clientcert); - - if (cb->clientkeypass != NULL) - curl_easy_setopt (cb->curl, CURLOPT_SSLKEYPASSWD, cb->clientkeypass); - } - - wh_reset_buffer (cb); - - return (0); + curl_easy_setopt(cb->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + } + + curl_easy_setopt(cb->curl, CURLOPT_SSL_VERIFYPEER, (long)cb->verify_peer); + curl_easy_setopt(cb->curl, CURLOPT_SSL_VERIFYHOST, cb->verify_host ? 2L : 0L); + curl_easy_setopt(cb->curl, CURLOPT_SSLVERSION, cb->sslversion); + if (cb->cacert != NULL) + curl_easy_setopt(cb->curl, CURLOPT_CAINFO, cb->cacert); + if (cb->capath != NULL) + curl_easy_setopt(cb->curl, CURLOPT_CAPATH, cb->capath); + + if (cb->clientkey != NULL && cb->clientcert != NULL) { + curl_easy_setopt(cb->curl, CURLOPT_SSLKEY, cb->clientkey); + curl_easy_setopt(cb->curl, CURLOPT_SSLCERT, cb->clientcert); + + if (cb->clientkeypass != NULL) + curl_easy_setopt(cb->curl, CURLOPT_SSLKEYPASSWD, cb->clientkeypass); + } + + wh_reset_buffer(cb); + + return (0); } /* }}} int wh_callback_init */ -static int wh_flush_nolock (cdtime_t timeout, wh_callback_t *cb) /* {{{ */ +static int wh_flush_nolock(cdtime_t timeout, wh_callback_t *cb) /* {{{ */ { - int status; - - DEBUG ("write_http plugin: wh_flush_nolock: timeout = %.3f; " - "send_buffer_fill = %zu;", - CDTIME_T_TO_DOUBLE (timeout), - cb->send_buffer_fill); - - /* timeout == 0 => flush unconditionally */ - if (timeout > 0) - { - cdtime_t now; - - now = cdtime (); - if ((cb->send_buffer_init_time + timeout) > now) - return (0); - } - - if (cb->format == WH_FORMAT_COMMAND) - { - if (cb->send_buffer_fill == 0) - { - cb->send_buffer_init_time = cdtime (); - return (0); - } - - status = wh_post_nolock (cb, cb->send_buffer); - wh_reset_buffer (cb); - } - else if (cb->format == WH_FORMAT_JSON || cb->format == WH_FORMAT_KAIROSDB) - { - if (cb->send_buffer_fill <= 2) - { - cb->send_buffer_init_time = cdtime (); - return (0); - } - - status = format_json_finalize (cb->send_buffer, - &cb->send_buffer_fill, - &cb->send_buffer_free); - if (status != 0) - { - ERROR ("write_http: wh_flush_nolock: " - "format_json_finalize failed."); - wh_reset_buffer (cb); - return (status); - } - - status = wh_post_nolock (cb, cb->send_buffer); - wh_reset_buffer (cb); - } - else - { - ERROR ("write_http: wh_flush_nolock: " - "Unknown format: %i", - cb->format); - return (-1); - } - - return (status); + int status; + + DEBUG("write_http plugin: wh_flush_nolock: timeout = %.3f; " + "send_buffer_fill = %zu;", + CDTIME_T_TO_DOUBLE(timeout), cb->send_buffer_fill); + + /* timeout == 0 => flush unconditionally */ + if (timeout > 0) { + cdtime_t now; + + now = cdtime(); + if ((cb->send_buffer_init_time + timeout) > now) + return (0); + } + + if (cb->format == WH_FORMAT_COMMAND) { + if (cb->send_buffer_fill == 0) { + cb->send_buffer_init_time = cdtime(); + return (0); + } + + status = wh_post_nolock(cb, cb->send_buffer); + wh_reset_buffer(cb); + } else if (cb->format == WH_FORMAT_JSON || cb->format == WH_FORMAT_KAIROSDB) { + if (cb->send_buffer_fill <= 2) { + cb->send_buffer_init_time = cdtime(); + return (0); + } + + status = format_json_finalize(cb->send_buffer, &cb->send_buffer_fill, + &cb->send_buffer_free); + if (status != 0) { + ERROR("write_http: wh_flush_nolock: " + "format_json_finalize failed."); + wh_reset_buffer(cb); + return (status); + } + + status = wh_post_nolock(cb, cb->send_buffer); + wh_reset_buffer(cb); + } else { + ERROR("write_http: wh_flush_nolock: " + "Unknown format: %i", + cb->format); + return (-1); + } + + return (status); } /* }}} wh_flush_nolock */ -static int wh_flush (cdtime_t timeout, /* {{{ */ - const char *identifier __attribute__((unused)), - user_data_t *user_data) -{ - wh_callback_t *cb; - int status; +static int wh_flush(cdtime_t timeout, /* {{{ */ + const char *identifier __attribute__((unused)), + user_data_t *user_data) { + wh_callback_t *cb; + int status; - if (user_data == NULL) - return (-EINVAL); + if (user_data == NULL) + return (-EINVAL); - cb = user_data->data; + cb = user_data->data; - pthread_mutex_lock (&cb->send_lock); + pthread_mutex_lock(&cb->send_lock); - if (wh_callback_init (cb) != 0) - { - ERROR ("write_http plugin: wh_callback_init failed."); - pthread_mutex_unlock (&cb->send_lock); - return (-1); - } + if (wh_callback_init(cb) != 0) { + ERROR("write_http plugin: wh_callback_init failed."); + pthread_mutex_unlock(&cb->send_lock); + return (-1); + } - status = wh_flush_nolock (timeout, cb); - pthread_mutex_unlock (&cb->send_lock); + status = wh_flush_nolock(timeout, cb); + pthread_mutex_unlock(&cb->send_lock); - return (status); + return (status); } /* }}} int wh_flush */ -static void wh_callback_free (void *data) /* {{{ */ +static void wh_callback_free(void *data) /* {{{ */ { - wh_callback_t *cb; - - if (data == NULL) - return; - - cb = data; - - if (cb->send_buffer != NULL) - wh_flush_nolock (/* timeout = */ 0, cb); - - if (cb->curl != NULL) - { - curl_easy_cleanup (cb->curl); - cb->curl = NULL; - } - - if (cb->headers != NULL) - { - curl_slist_free_all (cb->headers); - cb->headers = NULL; - } - - sfree (cb->name); - sfree (cb->location); - sfree (cb->user); - sfree (cb->pass); - sfree (cb->credentials); - sfree (cb->cacert); - sfree (cb->capath); - sfree (cb->clientkey); - sfree (cb->clientcert); - sfree (cb->clientkeypass); - sfree (cb->send_buffer); - - sfree (cb); + wh_callback_t *cb; + + if (data == NULL) + return; + + cb = data; + + if (cb->send_buffer != NULL) + wh_flush_nolock(/* timeout = */ 0, cb); + + if (cb->curl != NULL) { + curl_easy_cleanup(cb->curl); + cb->curl = NULL; + } + + if (cb->headers != NULL) { + curl_slist_free_all(cb->headers); + cb->headers = NULL; + } + + sfree(cb->name); + sfree(cb->location); + sfree(cb->user); + sfree(cb->pass); + sfree(cb->credentials); + sfree(cb->cacert); + sfree(cb->capath); + sfree(cb->clientkey); + sfree(cb->clientcert); + sfree(cb->clientkeypass); + sfree(cb->send_buffer); + + sfree(cb); } /* }}} void wh_callback_free */ -static int wh_write_command (const data_set_t *ds, const value_list_t *vl, /* {{{ */ - wh_callback_t *cb) -{ - char key[10*DATA_MAX_NAME_LEN]; - char values[512]; - char command[1024]; - size_t command_len; - - int status; - - /* sanity checks, primarily to make static analyzers happy. */ - if ((cb == NULL) || (cb->send_buffer == NULL)) - return -1; - - if (strcmp (ds->type, vl->type) != 0) { - ERROR ("write_http plugin: DS type does not match " - "value list type"); - return -1; - } - - /* Copy the identifier to `key' and escape it. */ - status = FORMAT_VL (key, sizeof (key), vl); - if (status != 0) { - ERROR ("write_http plugin: error with format_name"); - return (status); - } - escape_string (key, sizeof (key)); - - /* Convert the values to an ASCII representation and put that into - * `values'. */ - status = format_values (values, sizeof (values), ds, vl, cb->store_rates); - if (status != 0) { - ERROR ("write_http plugin: error with " - "wh_value_list_to_string"); - return (status); - } - - command_len = (size_t) ssnprintf (command, sizeof (command), - "PUTVAL %s interval=%.3f %s\r\n", - key, - CDTIME_T_TO_DOUBLE (vl->interval), - values); - if (command_len >= sizeof (command)) { - ERROR ("write_http plugin: Command buffer too small: " - "Need %zu bytes.", command_len + 1); - return (-1); - } - - pthread_mutex_lock (&cb->send_lock); - if (wh_callback_init (cb) != 0) - { - ERROR ("write_http plugin: wh_callback_init failed."); - pthread_mutex_unlock (&cb->send_lock); - return (-1); - } - - if (command_len >= cb->send_buffer_free) - { - status = wh_flush_nolock (/* timeout = */ 0, cb); - if (status != 0) - { - pthread_mutex_unlock (&cb->send_lock); - return (status); - } - } - assert (command_len < cb->send_buffer_free); - - /* Make scan-build happy. */ - assert (cb->send_buffer != NULL); - - /* `command_len + 1' because `command_len' does not include the - * trailing null byte. Neither does `send_buffer_fill'. */ - memcpy (cb->send_buffer + cb->send_buffer_fill, - command, command_len + 1); - cb->send_buffer_fill += command_len; - cb->send_buffer_free -= command_len; - - DEBUG ("write_http plugin: <%s> buffer %zu/%zu (%g%%) \"%s\"", - cb->location, - cb->send_buffer_fill, cb->send_buffer_size, - 100.0 * ((double) cb->send_buffer_fill) / ((double) cb->send_buffer_size), - command); - - /* Check if we have enough space for this command. */ - pthread_mutex_unlock (&cb->send_lock); - - return (0); +static int wh_write_command(const data_set_t *ds, + const value_list_t *vl, /* {{{ */ + wh_callback_t *cb) { + char key[10 * DATA_MAX_NAME_LEN]; + char values[512]; + char command[1024]; + size_t command_len; + + int status; + + /* sanity checks, primarily to make static analyzers happy. */ + if ((cb == NULL) || (cb->send_buffer == NULL)) + return -1; + + if (strcmp(ds->type, vl->type) != 0) { + ERROR("write_http plugin: DS type does not match " + "value list type"); + return -1; + } + + /* Copy the identifier to `key' and escape it. */ + status = FORMAT_VL(key, sizeof(key), vl); + if (status != 0) { + ERROR("write_http plugin: error with format_name"); + return (status); + } + escape_string(key, sizeof(key)); + + /* Convert the values to an ASCII representation and put that into + * `values'. */ + status = format_values(values, sizeof(values), ds, vl, cb->store_rates); + if (status != 0) { + ERROR("write_http plugin: error with " + "wh_value_list_to_string"); + return (status); + } + + command_len = (size_t)ssnprintf(command, sizeof(command), + "PUTVAL %s interval=%.3f %s\r\n", key, + CDTIME_T_TO_DOUBLE(vl->interval), values); + if (command_len >= sizeof(command)) { + ERROR("write_http plugin: Command buffer too small: " + "Need %zu bytes.", + command_len + 1); + return (-1); + } + + pthread_mutex_lock(&cb->send_lock); + if (wh_callback_init(cb) != 0) { + ERROR("write_http plugin: wh_callback_init failed."); + pthread_mutex_unlock(&cb->send_lock); + return (-1); + } + + if (command_len >= cb->send_buffer_free) { + status = wh_flush_nolock(/* timeout = */ 0, cb); + if (status != 0) { + pthread_mutex_unlock(&cb->send_lock); + return (status); + } + } + assert(command_len < cb->send_buffer_free); + + /* Make scan-build happy. */ + assert(cb->send_buffer != NULL); + + /* `command_len + 1' because `command_len' does not include the + * trailing null byte. Neither does `send_buffer_fill'. */ + memcpy(cb->send_buffer + cb->send_buffer_fill, command, command_len + 1); + cb->send_buffer_fill += command_len; + cb->send_buffer_free -= command_len; + + DEBUG("write_http plugin: <%s> buffer %zu/%zu (%g%%) \"%s\"", cb->location, + cb->send_buffer_fill, cb->send_buffer_size, + 100.0 * ((double)cb->send_buffer_fill) / ((double)cb->send_buffer_size), + command); + + /* Check if we have enough space for this command. */ + pthread_mutex_unlock(&cb->send_lock); + + return (0); } /* }}} int wh_write_command */ -static int wh_write_json (const data_set_t *ds, const value_list_t *vl, /* {{{ */ - wh_callback_t *cb) -{ - int status; - - pthread_mutex_lock (&cb->send_lock); - if (wh_callback_init (cb) != 0) - { - ERROR ("write_http plugin: wh_callback_init failed."); - pthread_mutex_unlock (&cb->send_lock); - return (-1); - } - - status = format_json_value_list (cb->send_buffer, - &cb->send_buffer_fill, - &cb->send_buffer_free, - ds, vl, cb->store_rates); - if (status == -ENOMEM) - { - status = wh_flush_nolock (/* timeout = */ 0, cb); - if (status != 0) - { - wh_reset_buffer (cb); - pthread_mutex_unlock (&cb->send_lock); - return (status); - } - - status = format_json_value_list (cb->send_buffer, - &cb->send_buffer_fill, - &cb->send_buffer_free, - ds, vl, cb->store_rates); - } - if (status != 0) - { - pthread_mutex_unlock (&cb->send_lock); - return (status); - } - - DEBUG ("write_http plugin: <%s> buffer %zu/%zu (%g%%)", - cb->location, - cb->send_buffer_fill, cb->send_buffer_size, - 100.0 * ((double) cb->send_buffer_fill) / ((double) cb->send_buffer_size)); - - /* Check if we have enough space for this command. */ - pthread_mutex_unlock (&cb->send_lock); - - return (0); +static int wh_write_json(const data_set_t *ds, const value_list_t *vl, /* {{{ */ + wh_callback_t *cb) { + int status; + + pthread_mutex_lock(&cb->send_lock); + if (wh_callback_init(cb) != 0) { + ERROR("write_http plugin: wh_callback_init failed."); + pthread_mutex_unlock(&cb->send_lock); + return (-1); + } + + status = + format_json_value_list(cb->send_buffer, &cb->send_buffer_fill, + &cb->send_buffer_free, ds, vl, cb->store_rates); + if (status == -ENOMEM) { + status = wh_flush_nolock(/* timeout = */ 0, cb); + if (status != 0) { + wh_reset_buffer(cb); + pthread_mutex_unlock(&cb->send_lock); + return (status); + } + + status = + format_json_value_list(cb->send_buffer, &cb->send_buffer_fill, + &cb->send_buffer_free, ds, vl, cb->store_rates); + } + if (status != 0) { + pthread_mutex_unlock(&cb->send_lock); + return (status); + } + + DEBUG("write_http plugin: <%s> buffer %zu/%zu (%g%%)", cb->location, + cb->send_buffer_fill, cb->send_buffer_size, + 100.0 * ((double)cb->send_buffer_fill) / + ((double)cb->send_buffer_size)); + + /* Check if we have enough space for this command. */ + pthread_mutex_unlock(&cb->send_lock); + + return (0); } /* }}} int wh_write_json */ -static int wh_write_kairosdb (const data_set_t *ds, const value_list_t *vl, /* {{{ */ - wh_callback_t *cb) -{ - int status; - - pthread_mutex_lock (&cb->send_lock); - - if (cb->curl == NULL) - { - status = wh_callback_init (cb); - if (status != 0) - { - ERROR ("write_http plugin: wh_callback_init failed."); - pthread_mutex_unlock (&cb->send_lock); - return (-1); - } - } - - status = format_kairosdb_value_list (cb->send_buffer, - &cb->send_buffer_fill, - &cb->send_buffer_free, - ds, vl, cb->store_rates); - if (status == -ENOMEM) - { - status = wh_flush_nolock (/* timeout = */ 0, cb); - if (status != 0) - { - wh_reset_buffer (cb); - pthread_mutex_unlock (&cb->send_lock); - return (status); - } - - status = format_kairosdb_value_list (cb->send_buffer, - &cb->send_buffer_fill, - &cb->send_buffer_free, - ds, vl, cb->store_rates); - } - if (status != 0) - { - pthread_mutex_unlock (&cb->send_lock); - return (status); - } - - DEBUG ("write_http plugin: <%s> buffer %zu/%zu (%g%%)", - cb->location, - cb->send_buffer_fill, cb->send_buffer_size, - 100.0 * ((double) cb->send_buffer_fill) / ((double) cb->send_buffer_size)); - - /* Check if we have enough space for this command. */ - pthread_mutex_unlock (&cb->send_lock); - - return (0); +static int wh_write_kairosdb(const data_set_t *ds, + const value_list_t *vl, /* {{{ */ + wh_callback_t *cb) { + int status; + + pthread_mutex_lock(&cb->send_lock); + + if (cb->curl == NULL) { + status = wh_callback_init(cb); + if (status != 0) { + ERROR("write_http plugin: wh_callback_init failed."); + pthread_mutex_unlock(&cb->send_lock); + return (-1); + } + } + + status = format_kairosdb_value_list(cb->send_buffer, &cb->send_buffer_fill, + &cb->send_buffer_free, ds, vl, + cb->store_rates); + if (status == -ENOMEM) { + status = wh_flush_nolock(/* timeout = */ 0, cb); + if (status != 0) { + wh_reset_buffer(cb); + pthread_mutex_unlock(&cb->send_lock); + return (status); + } + + status = format_kairosdb_value_list(cb->send_buffer, &cb->send_buffer_fill, + &cb->send_buffer_free, ds, vl, + cb->store_rates); + } + if (status != 0) { + pthread_mutex_unlock(&cb->send_lock); + return (status); + } + + DEBUG("write_http plugin: <%s> buffer %zu/%zu (%g%%)", cb->location, + cb->send_buffer_fill, cb->send_buffer_size, + 100.0 * ((double)cb->send_buffer_fill) / + ((double)cb->send_buffer_size)); + + /* Check if we have enough space for this command. */ + pthread_mutex_unlock(&cb->send_lock); + + return (0); } /* }}} int wh_write_kairosdb */ -static int wh_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */ - user_data_t *user_data) -{ - wh_callback_t *cb; - int status; - - if (user_data == NULL) - return (-EINVAL); - - cb = user_data->data; - assert (cb->send_metrics); - - switch(cb->format) { - case WH_FORMAT_JSON: - status = wh_write_json (ds, vl, cb); - break; - case WH_FORMAT_KAIROSDB: - status = wh_write_kairosdb (ds, vl, cb); - break; - default: - status = wh_write_command (ds, vl, cb); - break; - } - return (status); +static int wh_write(const data_set_t *ds, const value_list_t *vl, /* {{{ */ + user_data_t *user_data) { + wh_callback_t *cb; + int status; + + if (user_data == NULL) + return (-EINVAL); + + cb = user_data->data; + assert(cb->send_metrics); + + switch (cb->format) { + case WH_FORMAT_JSON: + status = wh_write_json(ds, vl, cb); + break; + case WH_FORMAT_KAIROSDB: + status = wh_write_kairosdb(ds, vl, cb); + break; + default: + status = wh_write_command(ds, vl, cb); + break; + } + return (status); } /* }}} int wh_write */ -static int wh_notify (notification_t const *n, user_data_t *ud) /* {{{ */ +static int wh_notify(notification_t const *n, user_data_t *ud) /* {{{ */ { - wh_callback_t *cb; - char alert[4096]; - int status; - - if ((ud == NULL) || (ud->data == NULL)) - return (EINVAL); - - cb = ud->data; - assert (cb->send_notifications); - - status = format_json_notification (alert, sizeof (alert), n); - if (status != 0) - { - ERROR ("write_http plugin: formatting notification failed"); - return status; - } - - pthread_mutex_lock (&cb->send_lock); - if (wh_callback_init (cb) != 0) - { - ERROR ("write_http plugin: wh_callback_init failed."); - pthread_mutex_unlock (&cb->send_lock); - return (-1); - } - - status = wh_post_nolock (cb, alert); - pthread_mutex_unlock (&cb->send_lock); - - return (status); + wh_callback_t *cb; + char alert[4096]; + int status; + + if ((ud == NULL) || (ud->data == NULL)) + return (EINVAL); + + cb = ud->data; + assert(cb->send_notifications); + + status = format_json_notification(alert, sizeof(alert), n); + if (status != 0) { + ERROR("write_http plugin: formatting notification failed"); + return status; + } + + pthread_mutex_lock(&cb->send_lock); + if (wh_callback_init(cb) != 0) { + ERROR("write_http plugin: wh_callback_init failed."); + pthread_mutex_unlock(&cb->send_lock); + return (-1); + } + + status = wh_post_nolock(cb, alert); + pthread_mutex_unlock(&cb->send_lock); + + return (status); } /* }}} int wh_notify */ -static int config_set_format (wh_callback_t *cb, /* {{{ */ - oconfig_item_t *ci) -{ - char *string; - - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("write_http plugin: The `%s' config option " - "needs exactly one string argument.", ci->key); - return (-1); - } - - string = ci->values[0].value.string; - if (strcasecmp ("Command", string) == 0) - cb->format = WH_FORMAT_COMMAND; - else if (strcasecmp ("JSON", string) == 0) - cb->format = WH_FORMAT_JSON; - else if (strcasecmp ("KAIROSDB", string) == 0) - cb->format = WH_FORMAT_KAIROSDB; - else - { - ERROR ("write_http plugin: Invalid format string: %s", - string); - return (-1); - } - - return (0); +static int config_set_format(wh_callback_t *cb, /* {{{ */ + oconfig_item_t *ci) { + char *string; + + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("write_http plugin: The `%s' config option " + "needs exactly one string argument.", + ci->key); + return (-1); + } + + string = ci->values[0].value.string; + if (strcasecmp("Command", string) == 0) + cb->format = WH_FORMAT_COMMAND; + else if (strcasecmp("JSON", string) == 0) + cb->format = WH_FORMAT_JSON; + else if (strcasecmp("KAIROSDB", string) == 0) + cb->format = WH_FORMAT_KAIROSDB; + else { + ERROR("write_http plugin: Invalid format string: %s", string); + return (-1); + } + + return (0); } /* }}} int config_set_format */ -static int wh_config_append_string (const char *name, struct curl_slist **dest, /* {{{ */ - oconfig_item_t *ci) -{ +static int wh_config_append_string(const char *name, + struct curl_slist **dest, /* {{{ */ + oconfig_item_t *ci) { struct curl_slist *temp = NULL; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("write_http plugin: `%s' needs exactly one string argument.", name); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("write_http plugin: `%s' needs exactly one string argument.", name); return (-1); } @@ -652,231 +599,218 @@ static int wh_config_append_string (const char *name, struct curl_slist **dest, return (0); } /* }}} int wh_config_append_string */ -static int wh_config_node (oconfig_item_t *ci) /* {{{ */ +static int wh_config_node(oconfig_item_t *ci) /* {{{ */ { - wh_callback_t *cb; - int buffer_size = 0; - char callback_name[DATA_MAX_NAME_LEN]; - int status = 0; - - cb = calloc (1, sizeof (*cb)); - if (cb == NULL) - { - ERROR ("write_http plugin: calloc failed."); - return (-1); - } - cb->verify_peer = 1; - cb->verify_host = 1; - cb->format = WH_FORMAT_COMMAND; + wh_callback_t *cb; + int buffer_size = 0; + char callback_name[DATA_MAX_NAME_LEN]; + int status = 0; + + cb = calloc(1, sizeof(*cb)); + if (cb == NULL) { + ERROR("write_http plugin: calloc failed."); + return (-1); + } + cb->verify_peer = 1; + cb->verify_host = 1; + cb->format = WH_FORMAT_COMMAND; + cb->sslversion = CURL_SSLVERSION_DEFAULT; + cb->low_speed_limit = 0; + cb->timeout = 0; + cb->log_http_error = 0; + cb->headers = NULL; + cb->send_metrics = 1; + cb->send_notifications = 0; + + pthread_mutex_init(&cb->send_lock, /* attr = */ NULL); + + cf_util_get_string(ci, &cb->name); + + /* FIXME: Remove this legacy mode in version 6. */ + if (strcasecmp("URL", ci->key) == 0) + cf_util_get_string(ci, &cb->location); + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("URL", child->key) == 0) + status = cf_util_get_string(child, &cb->location); + else if (strcasecmp("User", child->key) == 0) + status = cf_util_get_string(child, &cb->user); + else if (strcasecmp("Password", child->key) == 0) + status = cf_util_get_string(child, &cb->pass); + else if (strcasecmp("VerifyPeer", child->key) == 0) + status = cf_util_get_boolean(child, &cb->verify_peer); + else if (strcasecmp("VerifyHost", child->key) == 0) + status = cf_util_get_boolean(child, &cb->verify_host); + else if (strcasecmp("CACert", child->key) == 0) + status = cf_util_get_string(child, &cb->cacert); + else if (strcasecmp("CAPath", child->key) == 0) + status = cf_util_get_string(child, &cb->capath); + else if (strcasecmp("ClientKey", child->key) == 0) + status = cf_util_get_string(child, &cb->clientkey); + else if (strcasecmp("ClientCert", child->key) == 0) + status = cf_util_get_string(child, &cb->clientcert); + else if (strcasecmp("ClientKeyPass", child->key) == 0) + status = cf_util_get_string(child, &cb->clientkeypass); + else if (strcasecmp("SSLVersion", child->key) == 0) { + char *value = NULL; + + status = cf_util_get_string(child, &value); + if (status != 0) + break; + + if (value == NULL || strcasecmp("default", value) == 0) cb->sslversion = CURL_SSLVERSION_DEFAULT; - cb->low_speed_limit = 0; - cb->timeout = 0; - cb->log_http_error = 0; - cb->headers = NULL; - cb->send_metrics = 1; - cb->send_notifications = 0; - - pthread_mutex_init (&cb->send_lock, /* attr = */ NULL); - - cf_util_get_string (ci, &cb->name); - - /* FIXME: Remove this legacy mode in version 6. */ - if (strcasecmp ("URL", ci->key) == 0) - cf_util_get_string (ci, &cb->location); - - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("URL", child->key) == 0) - status = cf_util_get_string (child, &cb->location); - else if (strcasecmp ("User", child->key) == 0) - status = cf_util_get_string (child, &cb->user); - else if (strcasecmp ("Password", child->key) == 0) - status = cf_util_get_string (child, &cb->pass); - else if (strcasecmp ("VerifyPeer", child->key) == 0) - status = cf_util_get_boolean (child, &cb->verify_peer); - else if (strcasecmp ("VerifyHost", child->key) == 0) - status = cf_util_get_boolean (child, &cb->verify_host); - else if (strcasecmp ("CACert", child->key) == 0) - status = cf_util_get_string (child, &cb->cacert); - else if (strcasecmp ("CAPath", child->key) == 0) - status = cf_util_get_string (child, &cb->capath); - else if (strcasecmp ("ClientKey", child->key) == 0) - status = cf_util_get_string (child, &cb->clientkey); - else if (strcasecmp ("ClientCert", child->key) == 0) - status = cf_util_get_string (child, &cb->clientcert); - else if (strcasecmp ("ClientKeyPass", child->key) == 0) - status = cf_util_get_string (child, &cb->clientkeypass); - else if (strcasecmp ("SSLVersion", child->key) == 0) - { - char *value = NULL; - - status = cf_util_get_string (child, &value); - if (status != 0) - break; - - if (value == NULL || strcasecmp ("default", value) == 0) - cb->sslversion = CURL_SSLVERSION_DEFAULT; - else if (strcasecmp ("SSLv2", value) == 0) - cb->sslversion = CURL_SSLVERSION_SSLv2; - else if (strcasecmp ("SSLv3", value) == 0) - cb->sslversion = CURL_SSLVERSION_SSLv3; - else if (strcasecmp ("TLSv1", value) == 0) - cb->sslversion = CURL_SSLVERSION_TLSv1; -#if (LIBCURL_VERSION_MAJOR > 7) || (LIBCURL_VERSION_MAJOR == 7 && LIBCURL_VERSION_MINOR >= 34) - else if (strcasecmp ("TLSv1_0", value) == 0) - cb->sslversion = CURL_SSLVERSION_TLSv1_0; - else if (strcasecmp ("TLSv1_1", value) == 0) - cb->sslversion = CURL_SSLVERSION_TLSv1_1; - else if (strcasecmp ("TLSv1_2", value) == 0) - cb->sslversion = CURL_SSLVERSION_TLSv1_2; + else if (strcasecmp("SSLv2", value) == 0) + cb->sslversion = CURL_SSLVERSION_SSLv2; + else if (strcasecmp("SSLv3", value) == 0) + cb->sslversion = CURL_SSLVERSION_SSLv3; + else if (strcasecmp("TLSv1", value) == 0) + cb->sslversion = CURL_SSLVERSION_TLSv1; +#if (LIBCURL_VERSION_MAJOR > 7) || \ + (LIBCURL_VERSION_MAJOR == 7 && LIBCURL_VERSION_MINOR >= 34) + else if (strcasecmp("TLSv1_0", value) == 0) + cb->sslversion = CURL_SSLVERSION_TLSv1_0; + else if (strcasecmp("TLSv1_1", value) == 0) + cb->sslversion = CURL_SSLVERSION_TLSv1_1; + else if (strcasecmp("TLSv1_2", value) == 0) + cb->sslversion = CURL_SSLVERSION_TLSv1_2; #endif - else - { - ERROR ("write_http plugin: Invalid SSLVersion " - "option: %s.", value); - status = EINVAL; - } - - sfree(value); - } - else if (strcasecmp ("Format", child->key) == 0) - status = config_set_format (cb, child); - else if (strcasecmp ("Metrics", child->key) == 0) - cf_util_get_boolean (child, &cb->send_metrics); - else if (strcasecmp ("Notifications", child->key) == 0) - cf_util_get_boolean (child, &cb->send_notifications); - else if (strcasecmp ("StoreRates", child->key) == 0) - status = cf_util_get_boolean (child, &cb->store_rates); - else if (strcasecmp ("BufferSize", child->key) == 0) - status = cf_util_get_int (child, &buffer_size); - else if (strcasecmp ("LowSpeedLimit", child->key) == 0) - status = cf_util_get_int (child, &cb->low_speed_limit); - else if (strcasecmp ("Timeout", child->key) == 0) - status = cf_util_get_int (child, &cb->timeout); - else if (strcasecmp ("LogHttpError", child->key) == 0) - status = cf_util_get_boolean (child, &cb->log_http_error); - else if (strcasecmp ("Header", child->key) == 0) - status = wh_config_append_string ("Header", &cb->headers, child); - else - { - ERROR ("write_http plugin: Invalid configuration " - "option: %s.", child->key); - status = EINVAL; - } - - if (status != 0) - break; - } - - if (status != 0) - { - wh_callback_free (cb); - return (status); - } - - if (cb->location == NULL) - { - ERROR ("write_http plugin: no URL defined for instance '%s'", - cb->name); - wh_callback_free (cb); - return (-1); - } - - if (!cb->send_metrics && !cb->send_notifications) - { - ERROR ("write_http plugin: Neither metrics nor notifications " - "are enabled for \"%s\".", cb->name); - wh_callback_free (cb); - return (-1); - } - - if (cb->low_speed_limit > 0) - cb->low_speed_time = CDTIME_T_TO_TIME_T(plugin_get_interval()); - - /* Determine send_buffer_size. */ - cb->send_buffer_size = WRITE_HTTP_DEFAULT_BUFFER_SIZE; - if (buffer_size >= 1024) - cb->send_buffer_size = (size_t) buffer_size; - else if (buffer_size != 0) - ERROR ("write_http plugin: Ignoring invalid BufferSize setting (%d).", - buffer_size); - - /* Allocate the buffer. */ - cb->send_buffer = malloc (cb->send_buffer_size); - if (cb->send_buffer == NULL) - { - ERROR ("write_http plugin: malloc(%zu) failed.", cb->send_buffer_size); - wh_callback_free (cb); - return (-1); - } - /* Nulls the buffer and sets ..._free and ..._fill. */ - wh_reset_buffer (cb); - - ssnprintf (callback_name, sizeof (callback_name), "write_http/%s", - cb->name); - DEBUG ("write_http: Registering write callback '%s' with URL '%s'", - callback_name, cb->location); - - user_data_t user_data = { - .data = cb, - .free_func = wh_callback_free, - }; - - if (cb->send_metrics) - { - plugin_register_write (callback_name, wh_write, &user_data); - user_data.free_func = NULL; - - plugin_register_flush (callback_name, wh_flush, &user_data); - } - - if (cb->send_notifications) - { - plugin_register_notification (callback_name, wh_notify, &user_data); - user_data.free_func = NULL; - } - - return (0); + else { + ERROR("write_http plugin: Invalid SSLVersion " + "option: %s.", + value); + status = EINVAL; + } + + sfree(value); + } else if (strcasecmp("Format", child->key) == 0) + status = config_set_format(cb, child); + else if (strcasecmp("Metrics", child->key) == 0) + cf_util_get_boolean(child, &cb->send_metrics); + else if (strcasecmp("Notifications", child->key) == 0) + cf_util_get_boolean(child, &cb->send_notifications); + else if (strcasecmp("StoreRates", child->key) == 0) + status = cf_util_get_boolean(child, &cb->store_rates); + else if (strcasecmp("BufferSize", child->key) == 0) + status = cf_util_get_int(child, &buffer_size); + else if (strcasecmp("LowSpeedLimit", child->key) == 0) + status = cf_util_get_int(child, &cb->low_speed_limit); + else if (strcasecmp("Timeout", child->key) == 0) + status = cf_util_get_int(child, &cb->timeout); + else if (strcasecmp("LogHttpError", child->key) == 0) + status = cf_util_get_boolean(child, &cb->log_http_error); + else if (strcasecmp("Header", child->key) == 0) + status = wh_config_append_string("Header", &cb->headers, child); + else { + ERROR("write_http plugin: Invalid configuration " + "option: %s.", + child->key); + status = EINVAL; + } + + if (status != 0) + break; + } + + if (status != 0) { + wh_callback_free(cb); + return (status); + } + + if (cb->location == NULL) { + ERROR("write_http plugin: no URL defined for instance '%s'", cb->name); + wh_callback_free(cb); + return (-1); + } + + if (!cb->send_metrics && !cb->send_notifications) { + ERROR("write_http plugin: Neither metrics nor notifications " + "are enabled for \"%s\".", + cb->name); + wh_callback_free(cb); + return (-1); + } + + if (cb->low_speed_limit > 0) + cb->low_speed_time = CDTIME_T_TO_TIME_T(plugin_get_interval()); + + /* Determine send_buffer_size. */ + cb->send_buffer_size = WRITE_HTTP_DEFAULT_BUFFER_SIZE; + if (buffer_size >= 1024) + cb->send_buffer_size = (size_t)buffer_size; + else if (buffer_size != 0) + ERROR("write_http plugin: Ignoring invalid BufferSize setting (%d).", + buffer_size); + + /* Allocate the buffer. */ + cb->send_buffer = malloc(cb->send_buffer_size); + if (cb->send_buffer == NULL) { + ERROR("write_http plugin: malloc(%zu) failed.", cb->send_buffer_size); + wh_callback_free(cb); + return (-1); + } + /* Nulls the buffer and sets ..._free and ..._fill. */ + wh_reset_buffer(cb); + + ssnprintf(callback_name, sizeof(callback_name), "write_http/%s", cb->name); + DEBUG("write_http: Registering write callback '%s' with URL '%s'", + callback_name, cb->location); + + user_data_t user_data = { + .data = cb, .free_func = wh_callback_free, + }; + + if (cb->send_metrics) { + plugin_register_write(callback_name, wh_write, &user_data); + user_data.free_func = NULL; + + plugin_register_flush(callback_name, wh_flush, &user_data); + } + + if (cb->send_notifications) { + plugin_register_notification(callback_name, wh_notify, &user_data); + user_data.free_func = NULL; + } + + return (0); } /* }}} int wh_config_node */ -static int wh_config (oconfig_item_t *ci) /* {{{ */ +static int wh_config(oconfig_item_t *ci) /* {{{ */ { - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("Node", child->key) == 0) - wh_config_node (child); - /* FIXME: Remove this legacy mode in version 6. */ - else if (strcasecmp ("URL", child->key) == 0) { - WARNING ("write_http plugin: Legacy block found. " - "Please use instead."); - wh_config_node (child); - } - else - { - ERROR ("write_http plugin: Invalid configuration " - "option: %s.", child->key); - } - } - - return (0); + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Node", child->key) == 0) + wh_config_node(child); + /* FIXME: Remove this legacy mode in version 6. */ + else if (strcasecmp("URL", child->key) == 0) { + WARNING("write_http plugin: Legacy block found. " + "Please use instead."); + wh_config_node(child); + } else { + ERROR("write_http plugin: Invalid configuration " + "option: %s.", + child->key); + } + } + + return (0); } /* }}} int wh_config */ -static int wh_init (void) /* {{{ */ +static int wh_init(void) /* {{{ */ { - /* Call this while collectd is still single-threaded to avoid - * initialization issues in libgcrypt. */ - curl_global_init (CURL_GLOBAL_SSL); - return (0); + /* Call this while collectd is still single-threaded to avoid + * initialization issues in libgcrypt. */ + curl_global_init(CURL_GLOBAL_SSL); + return (0); } /* }}} int wh_init */ -void module_register (void) /* {{{ */ +void module_register(void) /* {{{ */ { - plugin_register_complex_config ("write_http", wh_config); - plugin_register_init ("write_http", wh_init); + plugin_register_complex_config("write_http", wh_config); + plugin_register_init("write_http", wh_init); } /* }}} void module_register */ /* vim: set fdm=marker sw=8 ts=8 tw=78 et : */ diff --git a/src/write_kafka.c b/src/write_kafka.c index a719cd37..e3fc5a26 100644 --- a/src/write_kafka.c +++ b/src/write_kafka.c @@ -26,33 +26,33 @@ #include "collectd.h" -#include "plugin.h" #include "common.h" +#include "plugin.h" #include "utils_cmd_putval.h" #include "utils_format_graphite.h" #include "utils_format_json.h" -#include -#include #include +#include +#include struct kafka_topic_context { -#define KAFKA_FORMAT_JSON 0 -#define KAFKA_FORMAT_COMMAND 1 -#define KAFKA_FORMAT_GRAPHITE 2 - uint8_t format; - unsigned int graphite_flags; - _Bool store_rates; - rd_kafka_topic_conf_t *conf; - rd_kafka_topic_t *topic; - rd_kafka_conf_t *kafka_conf; - rd_kafka_t *kafka; - char *key; - char *prefix; - char *postfix; - char escape_char; - char *topic_name; - pthread_mutex_t lock; +#define KAFKA_FORMAT_JSON 0 +#define KAFKA_FORMAT_COMMAND 1 +#define KAFKA_FORMAT_GRAPHITE 2 + uint8_t format; + unsigned int graphite_flags; + _Bool store_rates; + rd_kafka_topic_conf_t *conf; + rd_kafka_topic_t *topic; + rd_kafka_conf_t *kafka_conf; + rd_kafka_t *kafka; + char *key; + char *prefix; + char *postfix; + char escape_char; + char *topic_name; + pthread_mutex_t lock; }; static int kafka_handle(struct kafka_topic_context *); @@ -64,437 +64,429 @@ static int32_t kafka_partition(const rd_kafka_topic_t *, const void *, size_t, * rd_kafka_conf_set_log_cb(). This is to make sure we're not using the * deprecated function. */ #ifdef HAVE_LIBRDKAFKA_LOG_CB -# undef HAVE_LIBRDKAFKA_LOGGER +#undef HAVE_LIBRDKAFKA_LOGGER #endif #if defined(HAVE_LIBRDKAFKA_LOGGER) || defined(HAVE_LIBRDKAFKA_LOG_CB) static void kafka_log(const rd_kafka_t *, int, const char *, const char *); -static void kafka_log(const rd_kafka_t *rkt, int level, - const char *fac, const char *msg) -{ - plugin_log(level, "%s", msg); +static void kafka_log(const rd_kafka_t *rkt, int level, const char *fac, + const char *msg) { + plugin_log(level, "%s", msg); } #endif -static uint32_t kafka_hash(const char *keydata, size_t keylen) -{ - uint32_t hash = 5381; - for (; keylen > 0; keylen--) - hash = ((hash << 5) + hash) + keydata[keylen - 1]; - return hash; +static uint32_t kafka_hash(const char *keydata, size_t keylen) { + uint32_t hash = 5381; + for (; keylen > 0; keylen--) + hash = ((hash << 5) + hash) + keydata[keylen - 1]; + return hash; } /* 31 bit -> 4 byte -> 8 byte hex string + null byte */ #define KAFKA_RANDOM_KEY_SIZE 9 -#define KAFKA_RANDOM_KEY_BUFFER (char[KAFKA_RANDOM_KEY_SIZE]) {""} -static char *kafka_random_key(char buffer[static KAFKA_RANDOM_KEY_SIZE]) -{ - ssnprintf(buffer, KAFKA_RANDOM_KEY_SIZE, "%08lX", (unsigned long) mrand48()); - return buffer; +#define KAFKA_RANDOM_KEY_BUFFER \ + (char[KAFKA_RANDOM_KEY_SIZE]) { "" } +static char *kafka_random_key(char buffer[static KAFKA_RANDOM_KEY_SIZE]) { + ssnprintf(buffer, KAFKA_RANDOM_KEY_SIZE, "%08lX", (unsigned long)mrand48()); + return buffer; } -static int32_t kafka_partition(const rd_kafka_topic_t *rkt, - const void *keydata, size_t keylen, - int32_t partition_cnt, void *p, void *m) -{ - uint32_t key = kafka_hash(keydata, keylen); - uint32_t target = key % partition_cnt; - int32_t i = partition_cnt; - - while (--i > 0 && !rd_kafka_topic_partition_available(rkt, target)) { - target = (target + 1) % partition_cnt; - } - return target; +static int32_t kafka_partition(const rd_kafka_topic_t *rkt, const void *keydata, + size_t keylen, int32_t partition_cnt, void *p, + void *m) { + uint32_t key = kafka_hash(keydata, keylen); + uint32_t target = key % partition_cnt; + int32_t i = partition_cnt; + + while (--i > 0 && !rd_kafka_topic_partition_available(rkt, target)) { + target = (target + 1) % partition_cnt; + } + return target; } static int kafka_handle(struct kafka_topic_context *ctx) /* {{{ */ { - char errbuf[1024]; - rd_kafka_conf_t *conf; - rd_kafka_topic_conf_t *topic_conf; + char errbuf[1024]; + rd_kafka_conf_t *conf; + rd_kafka_topic_conf_t *topic_conf; - if (ctx->kafka != NULL && ctx->topic != NULL) - return(0); + if (ctx->kafka != NULL && ctx->topic != NULL) + return (0); - if (ctx->kafka == NULL) { - if ((conf = rd_kafka_conf_dup(ctx->kafka_conf)) == NULL) { - ERROR("write_kafka plugin: cannot duplicate kafka config"); - return(1); - } + if (ctx->kafka == NULL) { + if ((conf = rd_kafka_conf_dup(ctx->kafka_conf)) == NULL) { + ERROR("write_kafka plugin: cannot duplicate kafka config"); + return (1); + } - if ((ctx->kafka = rd_kafka_new(RD_KAFKA_PRODUCER, conf, - errbuf, sizeof(errbuf))) == NULL) { - ERROR("write_kafka plugin: cannot create kafka handle."); - return 1; - } + if ((ctx->kafka = rd_kafka_new(RD_KAFKA_PRODUCER, conf, errbuf, + sizeof(errbuf))) == NULL) { + ERROR("write_kafka plugin: cannot create kafka handle."); + return 1; + } - rd_kafka_conf_destroy(ctx->kafka_conf); - ctx->kafka_conf = NULL; + rd_kafka_conf_destroy(ctx->kafka_conf); + ctx->kafka_conf = NULL; - INFO ("write_kafka plugin: created KAFKA handle : %s", rd_kafka_name(ctx->kafka)); + INFO("write_kafka plugin: created KAFKA handle : %s", + rd_kafka_name(ctx->kafka)); #if defined(HAVE_LIBRDKAFKA_LOGGER) && !defined(HAVE_LIBRDKAFKA_LOG_CB) - rd_kafka_set_logger(ctx->kafka, kafka_log); + rd_kafka_set_logger(ctx->kafka, kafka_log); #endif - } + } - if (ctx->topic == NULL ) { - if ((topic_conf = rd_kafka_topic_conf_dup(ctx->conf)) == NULL) { - ERROR("write_kafka plugin: cannot duplicate kafka topic config"); - return 1; - } + if (ctx->topic == NULL) { + if ((topic_conf = rd_kafka_topic_conf_dup(ctx->conf)) == NULL) { + ERROR("write_kafka plugin: cannot duplicate kafka topic config"); + return 1; + } - if ((ctx->topic = rd_kafka_topic_new(ctx->kafka, ctx->topic_name, - topic_conf)) == NULL) { - ERROR("write_kafka plugin: cannot create topic : %s\n", + if ((ctx->topic = rd_kafka_topic_new(ctx->kafka, ctx->topic_name, + topic_conf)) == NULL) { + ERROR("write_kafka plugin: cannot create topic : %s\n", rd_kafka_err2str(rd_kafka_errno2err(errno))); - return errno; - } + return errno; + } - rd_kafka_topic_conf_destroy(ctx->conf); - ctx->conf = NULL; + rd_kafka_topic_conf_destroy(ctx->conf); + ctx->conf = NULL; - INFO ("write_kafka plugin: handle created for topic : %s", rd_kafka_topic_name(ctx->topic)); - } + INFO("write_kafka plugin: handle created for topic : %s", + rd_kafka_topic_name(ctx->topic)); + } - return(0); + return (0); } /* }}} int kafka_handle */ static int kafka_write(const data_set_t *ds, /* {{{ */ - const value_list_t *vl, - user_data_t *ud) -{ - int status = 0; - void *key; - size_t keylen = 0; - char buffer[8192]; - size_t bfree = sizeof(buffer); - size_t bfill = 0; - size_t blen = 0; - struct kafka_topic_context *ctx = ud->data; - - if ((ds == NULL) || (vl == NULL) || (ctx == NULL)) - return EINVAL; - - pthread_mutex_lock (&ctx->lock); - status = kafka_handle(ctx); - pthread_mutex_unlock (&ctx->lock); - if( status != 0 ) - return status; - - bzero(buffer, sizeof(buffer)); - - switch (ctx->format) { - case KAFKA_FORMAT_COMMAND: - status = cmd_create_putval(buffer, sizeof(buffer), ds, vl); - if (status != 0) { - ERROR("write_kafka plugin: cmd_create_putval failed with status %i.", - status); - return status; - } - blen = strlen(buffer); - break; - case KAFKA_FORMAT_JSON: - format_json_initialize(buffer, &bfill, &bfree); - format_json_value_list(buffer, &bfill, &bfree, ds, vl, - ctx->store_rates); - format_json_finalize(buffer, &bfill, &bfree); - blen = strlen(buffer); - break; - case KAFKA_FORMAT_GRAPHITE: - status = format_graphite(buffer, sizeof(buffer), ds, vl, - ctx->prefix, ctx->postfix, ctx->escape_char, - ctx->graphite_flags); - if (status != 0) { - ERROR("write_kafka plugin: format_graphite failed with status %i.", - status); - return status; - } - blen = strlen(buffer); - break; - default: - ERROR("write_kafka plugin: invalid format %i.", ctx->format); - return -1; + const value_list_t *vl, user_data_t *ud) { + int status = 0; + void *key; + size_t keylen = 0; + char buffer[8192]; + size_t bfree = sizeof(buffer); + size_t bfill = 0; + size_t blen = 0; + struct kafka_topic_context *ctx = ud->data; + + if ((ds == NULL) || (vl == NULL) || (ctx == NULL)) + return EINVAL; + + pthread_mutex_lock(&ctx->lock); + status = kafka_handle(ctx); + pthread_mutex_unlock(&ctx->lock); + if (status != 0) + return status; + + bzero(buffer, sizeof(buffer)); + + switch (ctx->format) { + case KAFKA_FORMAT_COMMAND: + status = cmd_create_putval(buffer, sizeof(buffer), ds, vl); + if (status != 0) { + ERROR("write_kafka plugin: cmd_create_putval failed with status %i.", + status); + return status; + } + blen = strlen(buffer); + break; + case KAFKA_FORMAT_JSON: + format_json_initialize(buffer, &bfill, &bfree); + format_json_value_list(buffer, &bfill, &bfree, ds, vl, ctx->store_rates); + format_json_finalize(buffer, &bfill, &bfree); + blen = strlen(buffer); + break; + case KAFKA_FORMAT_GRAPHITE: + status = + format_graphite(buffer, sizeof(buffer), ds, vl, ctx->prefix, + ctx->postfix, ctx->escape_char, ctx->graphite_flags); + if (status != 0) { + ERROR("write_kafka plugin: format_graphite failed with status %i.", + status); + return status; } + blen = strlen(buffer); + break; + default: + ERROR("write_kafka plugin: invalid format %i.", ctx->format); + return -1; + } - key = (ctx->key != NULL) - ? ctx->key - : kafka_random_key(KAFKA_RANDOM_KEY_BUFFER); - keylen = strlen (key); + key = + (ctx->key != NULL) ? ctx->key : kafka_random_key(KAFKA_RANDOM_KEY_BUFFER); + keylen = strlen(key); - rd_kafka_produce(ctx->topic, RD_KAFKA_PARTITION_UA, - RD_KAFKA_MSG_F_COPY, buffer, blen, - key, keylen, NULL); + rd_kafka_produce(ctx->topic, RD_KAFKA_PARTITION_UA, RD_KAFKA_MSG_F_COPY, + buffer, blen, key, keylen, NULL); - return status; + return status; } /* }}} int kafka_write */ static void kafka_topic_context_free(void *p) /* {{{ */ { - struct kafka_topic_context *ctx = p; - - if (ctx == NULL) - return; - - if (ctx->topic_name != NULL) - sfree(ctx->topic_name); - if (ctx->topic != NULL) - rd_kafka_topic_destroy(ctx->topic); - if (ctx->conf != NULL) - rd_kafka_topic_conf_destroy(ctx->conf); - if (ctx->kafka_conf != NULL) - rd_kafka_conf_destroy(ctx->kafka_conf); - if (ctx->kafka != NULL) - rd_kafka_destroy(ctx->kafka); - - sfree(ctx); + struct kafka_topic_context *ctx = p; + + if (ctx == NULL) + return; + + if (ctx->topic_name != NULL) + sfree(ctx->topic_name); + if (ctx->topic != NULL) + rd_kafka_topic_destroy(ctx->topic); + if (ctx->conf != NULL) + rd_kafka_topic_conf_destroy(ctx->conf); + if (ctx->kafka_conf != NULL) + rd_kafka_conf_destroy(ctx->kafka_conf); + if (ctx->kafka != NULL) + rd_kafka_destroy(ctx->kafka); + + sfree(ctx); } /* }}} void kafka_topic_context_free */ -static void kafka_config_topic(rd_kafka_conf_t *conf, oconfig_item_t *ci) /* {{{ */ +static void kafka_config_topic(rd_kafka_conf_t *conf, + oconfig_item_t *ci) /* {{{ */ { - int status; - struct kafka_topic_context *tctx; - char *key = NULL; - char *val; - char callback_name[DATA_MAX_NAME_LEN]; - char errbuf[1024]; - oconfig_item_t *child; - rd_kafka_conf_res_t ret; - - if ((tctx = calloc(1, sizeof (*tctx))) == NULL) { - ERROR ("write_kafka plugin: calloc failed."); - return; - } + int status; + struct kafka_topic_context *tctx; + char *key = NULL; + char *val; + char callback_name[DATA_MAX_NAME_LEN]; + char errbuf[1024]; + oconfig_item_t *child; + rd_kafka_conf_res_t ret; + + if ((tctx = calloc(1, sizeof(*tctx))) == NULL) { + ERROR("write_kafka plugin: calloc failed."); + return; + } - tctx->escape_char = '.'; - tctx->store_rates = 1; - tctx->format = KAFKA_FORMAT_JSON; - tctx->key = NULL; + tctx->escape_char = '.'; + tctx->store_rates = 1; + tctx->format = KAFKA_FORMAT_JSON; + tctx->key = NULL; - if ((tctx->kafka_conf = rd_kafka_conf_dup(conf)) == NULL) { - sfree(tctx); - ERROR("write_kafka plugin: cannot allocate memory for kafka config"); - return; - } + if ((tctx->kafka_conf = rd_kafka_conf_dup(conf)) == NULL) { + sfree(tctx); + ERROR("write_kafka plugin: cannot allocate memory for kafka config"); + return; + } #ifdef HAVE_LIBRDKAFKA_LOG_CB - rd_kafka_conf_set_log_cb(tctx->kafka_conf, kafka_log); + rd_kafka_conf_set_log_cb(tctx->kafka_conf, kafka_log); #endif - if ((tctx->conf = rd_kafka_topic_conf_new()) == NULL) { - rd_kafka_conf_destroy(tctx->kafka_conf); - sfree(tctx); - ERROR ("write_kafka plugin: cannot create topic configuration."); - return; - } - - if (ci->values_num != 1) { - WARNING("kafka topic name needed."); + if ((tctx->conf = rd_kafka_topic_conf_new()) == NULL) { + rd_kafka_conf_destroy(tctx->kafka_conf); + sfree(tctx); + ERROR("write_kafka plugin: cannot create topic configuration."); + return; + } + + if (ci->values_num != 1) { + WARNING("kafka topic name needed."); + goto errout; + } + + if (ci->values[0].type != OCONFIG_TYPE_STRING) { + WARNING("kafka topic needs a string argument."); + goto errout; + } + + if ((tctx->topic_name = strdup(ci->values[0].value.string)) == NULL) { + ERROR("write_kafka plugin: cannot copy topic name."); + goto errout; + } + + for (int i = 0; i < ci->children_num; i++) { + /* + * The code here could be simplified but makes room + * for easy adding of new options later on. + */ + child = &ci->children[i]; + status = 0; + + if (strcasecmp("Property", child->key) == 0) { + if (child->values_num != 2) { + WARNING("kafka properties need both a key and a value."); goto errout; - } - - if (ci->values[0].type != OCONFIG_TYPE_STRING) { - WARNING("kafka topic needs a string argument."); + } + if (child->values[0].type != OCONFIG_TYPE_STRING || + child->values[1].type != OCONFIG_TYPE_STRING) { + WARNING("kafka properties needs string arguments."); goto errout; - } - - if ((tctx->topic_name = strdup(ci->values[0].value.string)) == NULL) { - ERROR("write_kafka plugin: cannot copy topic name."); + } + key = child->values[0].value.string; + val = child->values[1].value.string; + ret = + rd_kafka_topic_conf_set(tctx->conf, key, val, errbuf, sizeof(errbuf)); + if (ret != RD_KAFKA_CONF_OK) { + WARNING("cannot set kafka topic property %s to %s: %s.", key, val, + errbuf); goto errout; - } - - for (int i = 0; i < ci->children_num; i++) { - /* - * The code here could be simplified but makes room - * for easy adding of new options later on. - */ - child = &ci->children[i]; - status = 0; - - if (strcasecmp ("Property", child->key) == 0) { - if (child->values_num != 2) { - WARNING("kafka properties need both a key and a value."); - goto errout; - } - if (child->values[0].type != OCONFIG_TYPE_STRING || - child->values[1].type != OCONFIG_TYPE_STRING) { - WARNING("kafka properties needs string arguments."); - goto errout; - } - key = child->values[0].value.string; - val = child->values[1].value.string; - ret = rd_kafka_topic_conf_set(tctx->conf,key, val, - errbuf, sizeof(errbuf)); - if (ret != RD_KAFKA_CONF_OK) { - WARNING("cannot set kafka topic property %s to %s: %s.", - key, val, errbuf); - goto errout; - } - - } else if (strcasecmp ("Key", child->key) == 0) { - if (cf_util_get_string (child, &tctx->key) != 0) - continue; - if (strcasecmp ("Random", tctx->key) == 0) { - sfree(tctx->key); - tctx->key = strdup (kafka_random_key (KAFKA_RANDOM_KEY_BUFFER)); - } - } else if (strcasecmp ("Format", child->key) == 0) { - status = cf_util_get_string(child, &key); - if (status != 0) - goto errout; - - assert(key != NULL); - - if (strcasecmp(key, "Command") == 0) { - tctx->format = KAFKA_FORMAT_COMMAND; - - } else if (strcasecmp(key, "Graphite") == 0) { - tctx->format = KAFKA_FORMAT_GRAPHITE; - - } else if (strcasecmp(key, "Json") == 0) { - tctx->format = KAFKA_FORMAT_JSON; - - } else { - WARNING ("write_kafka plugin: Invalid format string: %s", - key); - } - - sfree(key); - - } else if (strcasecmp ("StoreRates", child->key) == 0) { - status = cf_util_get_boolean (child, &tctx->store_rates); - (void) cf_util_get_flag (child, &tctx->graphite_flags, - GRAPHITE_STORE_RATES); - - } else if (strcasecmp ("GraphiteSeparateInstances", child->key) == 0) { - status = cf_util_get_flag (child, &tctx->graphite_flags, - GRAPHITE_SEPARATE_INSTANCES); - - } else if (strcasecmp ("GraphiteAlwaysAppendDS", child->key) == 0) { - status = cf_util_get_flag (child, &tctx->graphite_flags, - GRAPHITE_ALWAYS_APPEND_DS); - - } else if (strcasecmp ("GraphitePreserveSeparator", child->key) == 0) { - status = cf_util_get_flag (child, &tctx->graphite_flags, - GRAPHITE_PRESERVE_SEPARATOR); - - } else if (strcasecmp ("GraphitePrefix", child->key) == 0) { - status = cf_util_get_string (child, &tctx->prefix); - } else if (strcasecmp ("GraphitePostfix", child->key) == 0) { - status = cf_util_get_string (child, &tctx->postfix); - } else if (strcasecmp ("GraphiteEscapeChar", child->key) == 0) { - char *tmp_buff = NULL; - status = cf_util_get_string (child, &tmp_buff); - if (strlen (tmp_buff) > 1) - WARNING ("write_kafka plugin: The option \"GraphiteEscapeChar\" handles " - "only one character. Others will be ignored."); - tctx->escape_char = tmp_buff[0]; - sfree (tmp_buff); - } else { - WARNING ("write_kafka plugin: Invalid directive: %s.", child->key); - } - - if (status != 0) - break; - } - - rd_kafka_topic_conf_set_partitioner_cb(tctx->conf, kafka_partition); - rd_kafka_topic_conf_set_opaque(tctx->conf, tctx); - - ssnprintf(callback_name, sizeof(callback_name), - "write_kafka/%s", tctx->topic_name); - - status = plugin_register_write (callback_name, kafka_write, - &(user_data_t) { - .data = tctx, - .free_func = kafka_topic_context_free, - }); - if (status != 0) { - WARNING ("write_kafka plugin: plugin_register_write (\"%s\") " - "failed with status %i.", - callback_name, status); + } + + } else if (strcasecmp("Key", child->key) == 0) { + if (cf_util_get_string(child, &tctx->key) != 0) + continue; + if (strcasecmp("Random", tctx->key) == 0) { + sfree(tctx->key); + tctx->key = strdup(kafka_random_key(KAFKA_RANDOM_KEY_BUFFER)); + } + } else if (strcasecmp("Format", child->key) == 0) { + status = cf_util_get_string(child, &key); + if (status != 0) goto errout; - } - pthread_mutex_init (&tctx->lock, /* attr = */ NULL); + assert(key != NULL); + + if (strcasecmp(key, "Command") == 0) { + tctx->format = KAFKA_FORMAT_COMMAND; + + } else if (strcasecmp(key, "Graphite") == 0) { + tctx->format = KAFKA_FORMAT_GRAPHITE; + + } else if (strcasecmp(key, "Json") == 0) { + tctx->format = KAFKA_FORMAT_JSON; + + } else { + WARNING("write_kafka plugin: Invalid format string: %s", key); + } + + sfree(key); + + } else if (strcasecmp("StoreRates", child->key) == 0) { + status = cf_util_get_boolean(child, &tctx->store_rates); + (void)cf_util_get_flag(child, &tctx->graphite_flags, + GRAPHITE_STORE_RATES); + + } else if (strcasecmp("GraphiteSeparateInstances", child->key) == 0) { + status = cf_util_get_flag(child, &tctx->graphite_flags, + GRAPHITE_SEPARATE_INSTANCES); + + } else if (strcasecmp("GraphiteAlwaysAppendDS", child->key) == 0) { + status = cf_util_get_flag(child, &tctx->graphite_flags, + GRAPHITE_ALWAYS_APPEND_DS); + + } else if (strcasecmp("GraphitePreserveSeparator", child->key) == 0) { + status = cf_util_get_flag(child, &tctx->graphite_flags, + GRAPHITE_PRESERVE_SEPARATOR); + + } else if (strcasecmp("GraphitePrefix", child->key) == 0) { + status = cf_util_get_string(child, &tctx->prefix); + } else if (strcasecmp("GraphitePostfix", child->key) == 0) { + status = cf_util_get_string(child, &tctx->postfix); + } else if (strcasecmp("GraphiteEscapeChar", child->key) == 0) { + char *tmp_buff = NULL; + status = cf_util_get_string(child, &tmp_buff); + if (strlen(tmp_buff) > 1) + WARNING("write_kafka plugin: The option \"GraphiteEscapeChar\" handles " + "only one character. Others will be ignored."); + tctx->escape_char = tmp_buff[0]; + sfree(tmp_buff); + } else { + WARNING("write_kafka plugin: Invalid directive: %s.", child->key); + } - return; - errout: - if (tctx->topic_name != NULL) - free(tctx->topic_name); - if (tctx->conf != NULL) - rd_kafka_topic_conf_destroy(tctx->conf); - if (tctx->kafka_conf != NULL) - rd_kafka_conf_destroy(tctx->kafka_conf); - sfree(tctx); + if (status != 0) + break; + } + + rd_kafka_topic_conf_set_partitioner_cb(tctx->conf, kafka_partition); + rd_kafka_topic_conf_set_opaque(tctx->conf, tctx); + + ssnprintf(callback_name, sizeof(callback_name), "write_kafka/%s", + tctx->topic_name); + + status = plugin_register_write( + callback_name, kafka_write, + &(user_data_t){ + .data = tctx, .free_func = kafka_topic_context_free, + }); + if (status != 0) { + WARNING("write_kafka plugin: plugin_register_write (\"%s\") " + "failed with status %i.", + callback_name, status); + goto errout; + } + + pthread_mutex_init(&tctx->lock, /* attr = */ NULL); + + return; +errout: + if (tctx->topic_name != NULL) + free(tctx->topic_name); + if (tctx->conf != NULL) + rd_kafka_topic_conf_destroy(tctx->conf); + if (tctx->kafka_conf != NULL) + rd_kafka_conf_destroy(tctx->kafka_conf); + sfree(tctx); } /* }}} int kafka_config_topic */ static int kafka_config(oconfig_item_t *ci) /* {{{ */ { - oconfig_item_t *child; - rd_kafka_conf_t *conf; - rd_kafka_conf_res_t ret; - char errbuf[1024]; - - if ((conf = rd_kafka_conf_new()) == NULL) { - WARNING("cannot allocate kafka configuration."); - return -1; - } - for (int i = 0; i < ci->children_num; i++) { - child = &ci->children[i]; - - if (strcasecmp("Topic", child->key) == 0) { - kafka_config_topic (conf, child); - } else if (strcasecmp(child->key, "Property") == 0) { - char *key = NULL; - char *val = NULL; - - if (child->values_num != 2) { - WARNING("kafka properties need both a key and a value."); - goto errout; - } - if (child->values[0].type != OCONFIG_TYPE_STRING || - child->values[1].type != OCONFIG_TYPE_STRING) { - WARNING("kafka properties needs string arguments."); - goto errout; - } - if ((key = strdup(child->values[0].value.string)) == NULL) { - WARNING("cannot allocate memory for attribute key."); - goto errout; - } - if ((val = strdup(child->values[1].value.string)) == NULL) { - WARNING("cannot allocate memory for attribute value."); - sfree(key); - goto errout; - } - ret = rd_kafka_conf_set(conf, key, val, errbuf, sizeof(errbuf)); - if (ret != RD_KAFKA_CONF_OK) { - WARNING("cannot set kafka property %s to %s: %s", - key, val, errbuf); - sfree(key); - sfree(val); - goto errout; - } - sfree(key); - sfree(val); - } else { - WARNING ("write_kafka plugin: Ignoring unknown " - "configuration option \"%s\" at top level.", - child->key); - } - } - if (conf != NULL) - rd_kafka_conf_destroy(conf); - return (0); - errout: - if (conf != NULL) - rd_kafka_conf_destroy(conf); + oconfig_item_t *child; + rd_kafka_conf_t *conf; + rd_kafka_conf_res_t ret; + char errbuf[1024]; + + if ((conf = rd_kafka_conf_new()) == NULL) { + WARNING("cannot allocate kafka configuration."); return -1; + } + for (int i = 0; i < ci->children_num; i++) { + child = &ci->children[i]; + + if (strcasecmp("Topic", child->key) == 0) { + kafka_config_topic(conf, child); + } else if (strcasecmp(child->key, "Property") == 0) { + char *key = NULL; + char *val = NULL; + + if (child->values_num != 2) { + WARNING("kafka properties need both a key and a value."); + goto errout; + } + if (child->values[0].type != OCONFIG_TYPE_STRING || + child->values[1].type != OCONFIG_TYPE_STRING) { + WARNING("kafka properties needs string arguments."); + goto errout; + } + if ((key = strdup(child->values[0].value.string)) == NULL) { + WARNING("cannot allocate memory for attribute key."); + goto errout; + } + if ((val = strdup(child->values[1].value.string)) == NULL) { + WARNING("cannot allocate memory for attribute value."); + sfree(key); + goto errout; + } + ret = rd_kafka_conf_set(conf, key, val, errbuf, sizeof(errbuf)); + if (ret != RD_KAFKA_CONF_OK) { + WARNING("cannot set kafka property %s to %s: %s", key, val, errbuf); + sfree(key); + sfree(val); + goto errout; + } + sfree(key); + sfree(val); + } else { + WARNING("write_kafka plugin: Ignoring unknown " + "configuration option \"%s\" at top level.", + child->key); + } + } + if (conf != NULL) + rd_kafka_conf_destroy(conf); + return (0); +errout: + if (conf != NULL) + rd_kafka_conf_destroy(conf); + return -1; } /* }}} int kafka_config */ -void module_register(void) -{ - plugin_register_complex_config ("write_kafka", kafka_config); +void module_register(void) { + plugin_register_complex_config("write_kafka", kafka_config); } diff --git a/src/write_log.c b/src/write_log.c index e10a912e..2d34b21b 100644 --- a/src/write_log.c +++ b/src/write_log.c @@ -43,115 +43,98 @@ /* Plugin:WriteLog has to also operate without a config, so use a global. */ int wl_format = WL_FORMAT_GRAPHITE; -static int wl_write_graphite (const data_set_t *ds, const value_list_t *vl) -{ - char buffer[WL_BUF_SIZE] = { 0 }; - int status; +static int wl_write_graphite(const data_set_t *ds, const value_list_t *vl) { + char buffer[WL_BUF_SIZE] = {0}; + int status; - if (0 != strcmp (ds->type, vl->type)) - { - ERROR ("write_log plugin: DS type does not match value list type"); - return -1; - } + if (0 != strcmp(ds->type, vl->type)) { + ERROR("write_log plugin: DS type does not match value list type"); + return -1; + } - status = format_graphite (buffer, sizeof (buffer), ds, vl, - NULL, NULL, '_', 0); - if (status != 0) /* error message has been printed already. */ - return (status); + status = format_graphite(buffer, sizeof(buffer), ds, vl, NULL, NULL, '_', 0); + if (status != 0) /* error message has been printed already. */ + return (status); - INFO ("write_log values:\n%s", buffer); + INFO("write_log values:\n%s", buffer); - return (0); + return (0); } /* int wl_write_graphite */ -static int wl_write_json (const data_set_t *ds, const value_list_t *vl) -{ - char buffer[WL_BUF_SIZE] = { 0 }; - size_t bfree = sizeof(buffer); - size_t bfill = 0; - - if (0 != strcmp (ds->type, vl->type)) - { - ERROR ("write_log plugin: DS type does not match value list type"); - return -1; - } +static int wl_write_json(const data_set_t *ds, const value_list_t *vl) { + char buffer[WL_BUF_SIZE] = {0}; + size_t bfree = sizeof(buffer); + size_t bfill = 0; + + if (0 != strcmp(ds->type, vl->type)) { + ERROR("write_log plugin: DS type does not match value list type"); + return -1; + } - format_json_initialize(buffer, &bfill, &bfree); - format_json_value_list(buffer, &bfill, &bfree, ds, vl, - /* store rates = */ 0); - format_json_finalize(buffer, &bfill, &bfree); + format_json_initialize(buffer, &bfill, &bfree); + format_json_value_list(buffer, &bfill, &bfree, ds, vl, + /* store rates = */ 0); + format_json_finalize(buffer, &bfill, &bfree); - INFO ("write_log values:\n%s", buffer); + INFO("write_log values:\n%s", buffer); - return (0); + return (0); } /* int wl_write_json */ -static int wl_write (const data_set_t *ds, const value_list_t *vl, - __attribute__ ((unused)) user_data_t *user_data) -{ - int status = 0; +static int wl_write(const data_set_t *ds, const value_list_t *vl, + __attribute__((unused)) user_data_t *user_data) { + int status = 0; - if (wl_format == WL_FORMAT_GRAPHITE) - { - status = wl_write_graphite (ds, vl); - } - else if (wl_format == WL_FORMAT_JSON) - { - status = wl_write_json (ds, vl); - } + if (wl_format == WL_FORMAT_GRAPHITE) { + status = wl_write_graphite(ds, vl); + } else if (wl_format == WL_FORMAT_JSON) { + status = wl_write_json(ds, vl); + } - return (status); + return (status); } -static int wl_config (oconfig_item_t *ci) /* {{{ */ +static int wl_config(oconfig_item_t *ci) /* {{{ */ { - _Bool format_seen = 0; - - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("Format", child->key) == 0) - { - char str[16]; - - if (cf_util_get_string_buffer (child, str, sizeof (str)) != 0) - continue; - - if (format_seen) - { - WARNING ("write_log plugin: Redefining option `%s'.", - child->key); - } - format_seen = 1; - - if (strcasecmp ("Graphite", str) == 0) - wl_format = WL_FORMAT_GRAPHITE; - else if (strcasecmp ("JSON", str) == 0) - wl_format = WL_FORMAT_JSON; - else - { - ERROR ("write_log plugin: Unknown format `%s' for option `%s'.", - str, child->key); - return (-EINVAL); - } - } - else - { - ERROR ("write_log plugin: Invalid configuration option: `%s'.", - child->key); - return (-EINVAL); - } + _Bool format_seen = 0; + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Format", child->key) == 0) { + char str[16]; + + if (cf_util_get_string_buffer(child, str, sizeof(str)) != 0) + continue; + + if (format_seen) { + WARNING("write_log plugin: Redefining option `%s'.", child->key); + } + format_seen = 1; + + if (strcasecmp("Graphite", str) == 0) + wl_format = WL_FORMAT_GRAPHITE; + else if (strcasecmp("JSON", str) == 0) + wl_format = WL_FORMAT_JSON; + else { + ERROR("write_log plugin: Unknown format `%s' for option `%s'.", str, + child->key); + return (-EINVAL); + } + } else { + ERROR("write_log plugin: Invalid configuration option: `%s'.", + child->key); + return (-EINVAL); } + } - return (0); + return (0); } /* }}} int wl_config */ -void module_register (void) -{ - plugin_register_complex_config ("write_log", wl_config); - /* If config is supplied, the global wl_format will be set. */ - plugin_register_write ("write_log", wl_write, NULL); +void module_register(void) { + plugin_register_complex_config("write_log", wl_config); + /* If config is supplied, the global wl_format will be set. */ + plugin_register_write("write_log", wl_write, NULL); } /* vim: set sw=4 ts=4 sts=4 tw=78 et : */ diff --git a/src/write_mongodb.c b/src/write_mongodb.c index 796574e7..e175e1f3 100644 --- a/src/write_mongodb.c +++ b/src/write_mongodb.c @@ -30,24 +30,23 @@ #include "collectd.h" -#include "plugin.h" #include "common.h" +#include "plugin.h" #include "utils_cache.h" #if HAVE_STDINT_H -# define MONGO_HAVE_STDINT 1 +#define MONGO_HAVE_STDINT 1 #else -# define MONGO_USE_LONG_LONG_INT 1 +#define MONGO_USE_LONG_LONG_INT 1 #endif #include #if (MONGO_MAJOR == 0) && (MONGO_MINOR < 8) -# define bson_alloc() bson_create() -# define bson_dealloc(b) bson_dispose(b) +#define bson_alloc() bson_create() +#define bson_dealloc(b) bson_dispose(b) #endif -struct wm_node_s -{ +struct wm_node_s { char name[DATA_MAX_NAME_LEN]; char *host; @@ -69,53 +68,45 @@ typedef struct wm_node_s wm_node_t; /* * Functions */ -static bson *wm_create_bson (const data_set_t *ds, /* {{{ */ - const value_list_t *vl, - _Bool store_rates) -{ +static bson *wm_create_bson(const data_set_t *ds, /* {{{ */ + const value_list_t *vl, _Bool store_rates) { bson *ret; gauge_t *rates; - ret = bson_alloc (); /* matched by bson_dealloc() */ - if (ret == NULL) - { - ERROR ("write_mongodb plugin: bson_create failed."); + ret = bson_alloc(); /* matched by bson_dealloc() */ + if (ret == NULL) { + ERROR("write_mongodb plugin: bson_create failed."); return (NULL); } - if (store_rates) - { - rates = uc_get_rate (ds, vl); - if (rates == NULL) - { - ERROR ("write_mongodb plugin: uc_get_rate() failed."); + if (store_rates) { + rates = uc_get_rate(ds, vl); + if (rates == NULL) { + ERROR("write_mongodb plugin: uc_get_rate() failed."); return (NULL); } - } - else - { + } else { rates = NULL; } - bson_init (ret); /* matched by bson_destroy() */ - bson_append_date (ret, "time", (bson_date_t) CDTIME_T_TO_MS (vl->time)); - bson_append_string (ret, "host", vl->host); - bson_append_string (ret, "plugin", vl->plugin); - bson_append_string (ret, "plugin_instance", vl->plugin_instance); - bson_append_string (ret, "type", vl->type); - bson_append_string (ret, "type_instance", vl->type_instance); - - bson_append_start_array (ret, "values"); /* {{{ */ - for (int i = 0; i < ds->ds_num; i++) - { + bson_init(ret); /* matched by bson_destroy() */ + bson_append_date(ret, "time", (bson_date_t)CDTIME_T_TO_MS(vl->time)); + bson_append_string(ret, "host", vl->host); + bson_append_string(ret, "plugin", vl->plugin); + bson_append_string(ret, "plugin_instance", vl->plugin_instance); + bson_append_string(ret, "type", vl->type); + bson_append_string(ret, "type_instance", vl->type_instance); + + bson_append_start_array(ret, "values"); /* {{{ */ + for (int i = 0; i < ds->ds_num; i++) { char key[16]; - ssnprintf (key, sizeof (key), "%i", i); + ssnprintf(key, sizeof(key), "%i", i); if (ds->ds[i].type == DS_TYPE_GAUGE) bson_append_double(ret, key, vl->values[i].gauge); else if (store_rates) - bson_append_double(ret, key, (double) rates[i]); + bson_append_double(ret, key, (double)rates[i]); else if (ds->ds[i].type == DS_TYPE_COUNTER) bson_append_long(ret, key, vl->values[i].counter); else if (ds->ds[i].type == DS_TYPE_DERIVE) @@ -123,255 +114,239 @@ static bson *wm_create_bson (const data_set_t *ds, /* {{{ */ else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) bson_append_long(ret, key, vl->values[i].absolute); else - assert (23 == 42); + assert(23 == 42); } - bson_append_finish_array (ret); /* }}} values */ + bson_append_finish_array(ret); /* }}} values */ - bson_append_start_array (ret, "dstypes"); /* {{{ */ - for (int i = 0; i < ds->ds_num; i++) - { + bson_append_start_array(ret, "dstypes"); /* {{{ */ + for (int i = 0; i < ds->ds_num; i++) { char key[16]; - ssnprintf (key, sizeof (key), "%i", i); + ssnprintf(key, sizeof(key), "%i", i); if (store_rates) - bson_append_string (ret, key, "gauge"); + bson_append_string(ret, key, "gauge"); else - bson_append_string (ret, key, DS_TYPE_TO_STRING (ds->ds[i].type)); + bson_append_string(ret, key, DS_TYPE_TO_STRING(ds->ds[i].type)); } - bson_append_finish_array (ret); /* }}} dstypes */ + bson_append_finish_array(ret); /* }}} dstypes */ - bson_append_start_array (ret, "dsnames"); /* {{{ */ - for (int i = 0; i < ds->ds_num; i++) - { + bson_append_start_array(ret, "dsnames"); /* {{{ */ + for (int i = 0; i < ds->ds_num; i++) { char key[16]; - ssnprintf (key, sizeof (key), "%i", i); - bson_append_string (ret, key, ds->ds[i].name); + ssnprintf(key, sizeof(key), "%i", i); + bson_append_string(ret, key, ds->ds[i].name); } - bson_append_finish_array (ret); /* }}} dsnames */ + bson_append_finish_array(ret); /* }}} dsnames */ - bson_finish (ret); + bson_finish(ret); - sfree (rates); + sfree(rates); return (ret); } /* }}} bson *wm_create_bson */ -static int wm_write (const data_set_t *ds, /* {{{ */ - const value_list_t *vl, - user_data_t *ud) -{ +static int wm_write(const data_set_t *ds, /* {{{ */ + const value_list_t *vl, user_data_t *ud) { wm_node_t *node = ud->data; char collection_name[512]; bson *bson_record; int status; - ssnprintf (collection_name, sizeof (collection_name), "collectd.%s", - vl->plugin); + ssnprintf(collection_name, sizeof(collection_name), "collectd.%s", + vl->plugin); - bson_record = wm_create_bson (ds, vl, node->store_rates); + bson_record = wm_create_bson(ds, vl, node->store_rates); if (bson_record == NULL) return (ENOMEM); - pthread_mutex_lock (&node->lock); + pthread_mutex_lock(&node->lock); - if (!mongo_is_connected (node->conn)) - { - INFO ("write_mongodb plugin: Connecting to [%s]:%i", - (node->host != NULL) ? node->host : "localhost", - (node->port != 0) ? node->port : MONGO_DEFAULT_PORT); - status = mongo_connect (node->conn, node->host, node->port); + if (!mongo_is_connected(node->conn)) { + INFO("write_mongodb plugin: Connecting to [%s]:%i", + (node->host != NULL) ? node->host : "localhost", + (node->port != 0) ? node->port : MONGO_DEFAULT_PORT); + status = mongo_connect(node->conn, node->host, node->port); if (status != MONGO_OK) { - ERROR ("write_mongodb plugin: Connecting to [%s]:%i failed.", - (node->host != NULL) ? node->host : "localhost", - (node->port != 0) ? node->port : MONGO_DEFAULT_PORT); - mongo_destroy (node->conn); - pthread_mutex_unlock (&node->lock); + ERROR("write_mongodb plugin: Connecting to [%s]:%i failed.", + (node->host != NULL) ? node->host : "localhost", + (node->port != 0) ? node->port : MONGO_DEFAULT_PORT); + mongo_destroy(node->conn); + pthread_mutex_unlock(&node->lock); return (-1); } - if ((node->db != NULL) && (node->user != NULL) && (node->passwd != NULL)) - { - status = mongo_cmd_authenticate (node->conn, - node->db, node->user, node->passwd); - if (status != MONGO_OK) - { - ERROR ("write_mongodb plugin: Authenticating to [%s]%i for database " - "\"%s\" as user \"%s\" failed.", - (node->host != NULL) ? node->host : "localhost", - (node->port != 0) ? node->port : MONGO_DEFAULT_PORT, - node->db, node->user); - mongo_destroy (node->conn); - pthread_mutex_unlock (&node->lock); + if ((node->db != NULL) && (node->user != NULL) && (node->passwd != NULL)) { + status = mongo_cmd_authenticate(node->conn, node->db, node->user, + node->passwd); + if (status != MONGO_OK) { + ERROR("write_mongodb plugin: Authenticating to [%s]%i for database " + "\"%s\" as user \"%s\" failed.", + (node->host != NULL) ? node->host : "localhost", + (node->port != 0) ? node->port : MONGO_DEFAULT_PORT, node->db, + node->user); + mongo_destroy(node->conn); + pthread_mutex_unlock(&node->lock); return (-1); } } if (node->timeout > 0) { - status = mongo_set_op_timeout (node->conn, node->timeout); + status = mongo_set_op_timeout(node->conn, node->timeout); if (status != MONGO_OK) { - WARNING ("write_mongodb plugin: mongo_set_op_timeout(%i) failed: %s", - node->timeout, node->conn->errstr); + WARNING("write_mongodb plugin: mongo_set_op_timeout(%i) failed: %s", + node->timeout, node->conn->errstr); } } } /* Assert if the connection has been established */ - assert (mongo_is_connected (node->conn)); - - #if MONGO_MINOR >= 6 - /* There was an API change in 0.6.0 as linked below */ - /* https://github.com/mongodb/mongo-c-driver/blob/master/HISTORY.md */ - status = mongo_insert (node->conn, collection_name, bson_record, NULL); - #else - status = mongo_insert (node->conn, collection_name, bson_record); - #endif - - if (status != MONGO_OK) - { - ERROR ( "write_mongodb plugin: error inserting record: %d", node->conn->err); + assert(mongo_is_connected(node->conn)); + +#if MONGO_MINOR >= 6 + /* There was an API change in 0.6.0 as linked below */ + /* https://github.com/mongodb/mongo-c-driver/blob/master/HISTORY.md */ + status = mongo_insert(node->conn, collection_name, bson_record, NULL); +#else + status = mongo_insert(node->conn, collection_name, bson_record); +#endif + + if (status != MONGO_OK) { + ERROR("write_mongodb plugin: error inserting record: %d", node->conn->err); if (node->conn->err != MONGO_BSON_INVALID) - ERROR ("write_mongodb plugin: %s", node->conn->errstr); + ERROR("write_mongodb plugin: %s", node->conn->errstr); else - ERROR ("write_mongodb plugin: Invalid BSON structure, error = %#x", - (unsigned int) bson_record->err); + ERROR("write_mongodb plugin: Invalid BSON structure, error = %#x", + (unsigned int)bson_record->err); /* Disconnect except on data errors. */ - if ((node->conn->err != MONGO_BSON_INVALID) - && (node->conn->err != MONGO_BSON_NOT_FINISHED)) - mongo_destroy (node->conn); + if ((node->conn->err != MONGO_BSON_INVALID) && + (node->conn->err != MONGO_BSON_NOT_FINISHED)) + mongo_destroy(node->conn); } - pthread_mutex_unlock (&node->lock); + pthread_mutex_unlock(&node->lock); /* free our resource as not to leak memory */ - bson_destroy (bson_record); /* matches bson_init() */ - bson_dealloc (bson_record); /* matches bson_alloc() */ + bson_destroy(bson_record); /* matches bson_init() */ + bson_dealloc(bson_record); /* matches bson_alloc() */ return (0); } /* }}} int wm_write */ -static void wm_config_free (void *ptr) /* {{{ */ +static void wm_config_free(void *ptr) /* {{{ */ { wm_node_t *node = ptr; if (node == NULL) return; - if (mongo_is_connected (node->conn)) - mongo_destroy (node->conn); + if (mongo_is_connected(node->conn)) + mongo_destroy(node->conn); - sfree (node->host); - sfree (node); + sfree(node->host); + sfree(node); } /* }}} void wm_config_free */ -static int wm_config_node (oconfig_item_t *ci) /* {{{ */ +static int wm_config_node(oconfig_item_t *ci) /* {{{ */ { wm_node_t *node; int status; - node = calloc (1, sizeof (*node)); + node = calloc(1, sizeof(*node)); if (node == NULL) return (ENOMEM); - mongo_init (node->conn); + mongo_init(node->conn); node->host = NULL; node->store_rates = 1; - pthread_mutex_init (&node->lock, /* attr = */ NULL); + pthread_mutex_init(&node->lock, /* attr = */ NULL); - status = cf_util_get_string_buffer (ci, node->name, sizeof (node->name)); + status = cf_util_get_string_buffer(ci, node->name, sizeof(node->name)); - if (status != 0) - { - sfree (node); + if (status != 0) { + sfree(node); return (status); } - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Host", child->key) == 0) - status = cf_util_get_string (child, &node->host); - else if (strcasecmp ("Port", child->key) == 0) - { - status = cf_util_get_port_number (child); - if (status > 0) - { + if (strcasecmp("Host", child->key) == 0) + status = cf_util_get_string(child, &node->host); + else if (strcasecmp("Port", child->key) == 0) { + status = cf_util_get_port_number(child); + if (status > 0) { node->port = status; status = 0; } - } - else if (strcasecmp ("Timeout", child->key) == 0) - status = cf_util_get_int (child, &node->timeout); - else if (strcasecmp ("StoreRates", child->key) == 0) - status = cf_util_get_boolean (child, &node->store_rates); - else if (strcasecmp ("Database", child->key) == 0) - status = cf_util_get_string (child, &node->db); - else if (strcasecmp ("User", child->key) == 0) - status = cf_util_get_string (child, &node->user); - else if (strcasecmp ("Password", child->key) == 0) - status = cf_util_get_string (child, &node->passwd); + } else if (strcasecmp("Timeout", child->key) == 0) + status = cf_util_get_int(child, &node->timeout); + else if (strcasecmp("StoreRates", child->key) == 0) + status = cf_util_get_boolean(child, &node->store_rates); + else if (strcasecmp("Database", child->key) == 0) + status = cf_util_get_string(child, &node->db); + else if (strcasecmp("User", child->key) == 0) + status = cf_util_get_string(child, &node->user); + else if (strcasecmp("Password", child->key) == 0) + status = cf_util_get_string(child, &node->passwd); else - WARNING ("write_mongodb plugin: Ignoring unknown config option \"%s\".", - child->key); + WARNING("write_mongodb plugin: Ignoring unknown config option \"%s\".", + child->key); if (status != 0) break; } /* for (i = 0; i < ci->children_num; i++) */ - if ((node->db != NULL) || (node->user != NULL) || (node->passwd != NULL)) - { - if ((node->db == NULL) || (node->user == NULL) || (node->passwd == NULL)) - { - WARNING ("write_mongodb plugin: Authentication requires the " + if ((node->db != NULL) || (node->user != NULL) || (node->passwd != NULL)) { + if ((node->db == NULL) || (node->user == NULL) || (node->passwd == NULL)) { + WARNING( + "write_mongodb plugin: Authentication requires the " "\"Database\", \"User\" and \"Password\" options to be specified, " "but at last one of them is missing. Authentication will NOT be " "used."); - sfree (node->db); - sfree (node->user); - sfree (node->passwd); + sfree(node->db); + sfree(node->user); + sfree(node->passwd); } } - if (status == 0) - { + if (status == 0) { char cb_name[DATA_MAX_NAME_LEN]; - ssnprintf (cb_name, sizeof (cb_name), "write_mongodb/%s", node->name); + ssnprintf(cb_name, sizeof(cb_name), "write_mongodb/%s", node->name); - status = plugin_register_write (cb_name, wm_write, - &(user_data_t) { - .data = node, - .free_func = wm_config_free, - }); - INFO ("write_mongodb plugin: registered write plugin %s %d",cb_name,status); + status = plugin_register_write( + cb_name, wm_write, &(user_data_t){ + .data = node, .free_func = wm_config_free, + }); + INFO("write_mongodb plugin: registered write plugin %s %d", cb_name, + status); } if (status != 0) - wm_config_free (node); + wm_config_free(node); return (status); } /* }}} int wm_config_node */ -static int wm_config (oconfig_item_t *ci) /* {{{ */ +static int wm_config(oconfig_item_t *ci) /* {{{ */ { - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Node", child->key) == 0) - wm_config_node (child); + if (strcasecmp("Node", child->key) == 0) + wm_config_node(child); else - WARNING ("write_mongodb plugin: Ignoring unknown " - "configuration option \"%s\" at top level.", child->key); + WARNING("write_mongodb plugin: Ignoring unknown " + "configuration option \"%s\" at top level.", + child->key); } return (0); } /* }}} int wm_config */ -void module_register (void) -{ - plugin_register_complex_config ("write_mongodb", wm_config); +void module_register(void) { + plugin_register_complex_config("write_mongodb", wm_config); } /* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ diff --git a/src/write_redis.c b/src/write_redis.c index bafbfe51..0a5c5df1 100644 --- a/src/write_redis.c +++ b/src/write_redis.c @@ -26,18 +26,17 @@ #include "collectd.h" -#include "plugin.h" #include "common.h" +#include "plugin.h" -#include #include +#include #ifndef REDIS_DEFAULT_PREFIX -# define REDIS_DEFAULT_PREFIX "collectd/" +#define REDIS_DEFAULT_PREFIX "collectd/" #endif -struct wr_node_s -{ +struct wr_node_s { char name[DATA_MAX_NAME_LEN]; char *host; @@ -56,119 +55,117 @@ typedef struct wr_node_s wr_node_t; /* * Functions */ -static int wr_write (const data_set_t *ds, /* {{{ */ - const value_list_t *vl, - user_data_t *ud) -{ +static int wr_write(const data_set_t *ds, /* {{{ */ + const value_list_t *vl, user_data_t *ud) { wr_node_t *node = ud->data; char ident[512]; char key[512]; - char value[512] = { 0 }; + char value[512] = {0}; char time[24]; size_t value_size; char *value_ptr; int status; - redisReply *rr; + redisReply *rr; - status = FORMAT_VL (ident, sizeof (ident), vl); + status = FORMAT_VL(ident, sizeof(ident), vl); if (status != 0) return (status); - ssnprintf (key, sizeof (key), "%s%s", - (node->prefix != NULL) ? node->prefix : REDIS_DEFAULT_PREFIX, - ident); - ssnprintf (time, sizeof (time), "%.9f", CDTIME_T_TO_DOUBLE(vl->time)); + ssnprintf(key, sizeof(key), "%s%s", + (node->prefix != NULL) ? node->prefix : REDIS_DEFAULT_PREFIX, + ident); + ssnprintf(time, sizeof(time), "%.9f", CDTIME_T_TO_DOUBLE(vl->time)); - value_size = sizeof (value); + value_size = sizeof(value); value_ptr = &value[0]; - status = format_values (value_ptr, value_size, ds, vl, node->store_rates); + status = format_values(value_ptr, value_size, ds, vl, node->store_rates); if (status != 0) return (status); - pthread_mutex_lock (&node->lock); - - if (node->conn == NULL) - { - node->conn = redisConnectWithTimeout ((char *)node->host, node->port, node->timeout); - if (node->conn == NULL) - { - ERROR ("write_redis plugin: Connecting to host \"%s\" (port %i) failed: Unknown reason", - (node->host != NULL) ? node->host : "localhost", - (node->port != 0) ? node->port : 6379); - pthread_mutex_unlock (&node->lock); + pthread_mutex_lock(&node->lock); + + if (node->conn == NULL) { + node->conn = + redisConnectWithTimeout((char *)node->host, node->port, node->timeout); + if (node->conn == NULL) { + ERROR("write_redis plugin: Connecting to host \"%s\" (port %i) failed: " + "Unknown reason", + (node->host != NULL) ? node->host : "localhost", + (node->port != 0) ? node->port : 6379); + pthread_mutex_unlock(&node->lock); return (-1); - } - else if (node->conn->err) - { - ERROR ("write_redis plugin: Connecting to host \"%s\" (port %i) failed: %s", + } else if (node->conn->err) { + ERROR( + "write_redis plugin: Connecting to host \"%s\" (port %i) failed: %s", (node->host != NULL) ? node->host : "localhost", - (node->port != 0) ? node->port : 6379, - node->conn->errstr); - pthread_mutex_unlock (&node->lock); + (node->port != 0) ? node->port : 6379, node->conn->errstr); + pthread_mutex_unlock(&node->lock); return (-1); } rr = redisCommand(node->conn, "SELECT %d", node->database); if (rr == NULL) - WARNING("SELECT command error. database:%d message:%s", node->database, node->conn->errstr); + WARNING("SELECT command error. database:%d message:%s", node->database, + node->conn->errstr); else - freeReplyObject (rr); + freeReplyObject(rr); } - rr = redisCommand (node->conn, "ZADD %s %s %s", key, time, value); + rr = redisCommand(node->conn, "ZADD %s %s %s", key, time, value); if (rr == NULL) WARNING("ZADD command error. key:%s message:%s", key, node->conn->errstr); else - freeReplyObject (rr); + freeReplyObject(rr); - if (node->max_set_size >= 0) - { - rr = redisCommand (node->conn, "ZREMRANGEBYRANK %s %d %d", key, 0, (-1 * node->max_set_size) - 1); + if (node->max_set_size >= 0) { + rr = redisCommand(node->conn, "ZREMRANGEBYRANK %s %d %d", key, 0, + (-1 * node->max_set_size) - 1); if (rr == NULL) - WARNING("ZREMRANGEBYRANK command error. key:%s message:%s", key, node->conn->errstr); + WARNING("ZREMRANGEBYRANK command error. key:%s message:%s", key, + node->conn->errstr); else - freeReplyObject (rr); + freeReplyObject(rr); } /* TODO(octo): This is more overhead than necessary. Use the cache and * metadata to determine if it is a new metric and call SADD only once for * each metric. */ - rr = redisCommand (node->conn, "SADD %svalues %s", - (node->prefix != NULL) ? node->prefix : REDIS_DEFAULT_PREFIX, - ident); - if (rr==NULL) - WARNING("SADD command error. ident:%s message:%s", ident, node->conn->errstr); + rr = redisCommand( + node->conn, "SADD %svalues %s", + (node->prefix != NULL) ? node->prefix : REDIS_DEFAULT_PREFIX, ident); + if (rr == NULL) + WARNING("SADD command error. ident:%s message:%s", ident, + node->conn->errstr); else - freeReplyObject (rr); + freeReplyObject(rr); - pthread_mutex_unlock (&node->lock); + pthread_mutex_unlock(&node->lock); return (0); } /* }}} int wr_write */ -static void wr_config_free (void *ptr) /* {{{ */ +static void wr_config_free(void *ptr) /* {{{ */ { wr_node_t *node = ptr; if (node == NULL) return; - if (node->conn != NULL) - { - redisFree (node->conn); + if (node->conn != NULL) { + redisFree(node->conn); node->conn = NULL; } - sfree (node->host); - sfree (node); + sfree(node->host); + sfree(node); } /* }}} void wr_config_free */ -static int wr_config_node (oconfig_item_t *ci) /* {{{ */ +static int wr_config_node(oconfig_item_t *ci) /* {{{ */ { wr_node_t *node; int timeout; int status; - node = calloc (1, sizeof (*node)); + node = calloc(1, sizeof(*node)); if (node == NULL) return (ENOMEM); node->host = NULL; @@ -180,92 +177,80 @@ static int wr_config_node (oconfig_item_t *ci) /* {{{ */ node->database = 0; node->max_set_size = -1; node->store_rates = 1; - pthread_mutex_init (&node->lock, /* attr = */ NULL); + pthread_mutex_init(&node->lock, /* attr = */ NULL); - status = cf_util_get_string_buffer (ci, node->name, sizeof (node->name)); - if (status != 0) - { - sfree (node); + status = cf_util_get_string_buffer(ci, node->name, sizeof(node->name)); + if (status != 0) { + sfree(node); return (status); } - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Host", child->key) == 0) - status = cf_util_get_string (child, &node->host); - else if (strcasecmp ("Port", child->key) == 0) - { - status = cf_util_get_port_number (child); - if (status > 0) - { + if (strcasecmp("Host", child->key) == 0) + status = cf_util_get_string(child, &node->host); + else if (strcasecmp("Port", child->key) == 0) { + status = cf_util_get_port_number(child); + if (status > 0) { node->port = status; status = 0; } - } - else if (strcasecmp ("Timeout", child->key) == 0) { - status = cf_util_get_int (child, &timeout); - if (status == 0) node->timeout.tv_usec = timeout; - } - else if (strcasecmp ("Prefix", child->key) == 0) { - status = cf_util_get_string (child, &node->prefix); - } - else if (strcasecmp ("Database", child->key) == 0) { - status = cf_util_get_int (child, &node->database); - } - else if (strcasecmp ("MaxSetSize", child->key) == 0) { - status = cf_util_get_int (child, &node->max_set_size); - } - else if (strcasecmp ("StoreRates", child->key) == 0) { - status = cf_util_get_boolean (child, &node->store_rates); - } - else - WARNING ("write_redis plugin: Ignoring unknown config option \"%s\".", - child->key); + } else if (strcasecmp("Timeout", child->key) == 0) { + status = cf_util_get_int(child, &timeout); + if (status == 0) + node->timeout.tv_usec = timeout; + } else if (strcasecmp("Prefix", child->key) == 0) { + status = cf_util_get_string(child, &node->prefix); + } else if (strcasecmp("Database", child->key) == 0) { + status = cf_util_get_int(child, &node->database); + } else if (strcasecmp("MaxSetSize", child->key) == 0) { + status = cf_util_get_int(child, &node->max_set_size); + } else if (strcasecmp("StoreRates", child->key) == 0) { + status = cf_util_get_boolean(child, &node->store_rates); + } else + WARNING("write_redis plugin: Ignoring unknown config option \"%s\".", + child->key); if (status != 0) break; } /* for (i = 0; i < ci->children_num; i++) */ - if (status == 0) - { + if (status == 0) { char cb_name[DATA_MAX_NAME_LEN]; - ssnprintf (cb_name, sizeof (cb_name), "write_redis/%s", node->name); + ssnprintf(cb_name, sizeof(cb_name), "write_redis/%s", node->name); - status = plugin_register_write (cb_name, wr_write, - &(user_data_t) { - .data = node, - .free_func = wr_config_free, - }); + status = plugin_register_write( + cb_name, wr_write, &(user_data_t){ + .data = node, .free_func = wr_config_free, + }); } if (status != 0) - wr_config_free (node); + wr_config_free(node); return (status); } /* }}} int wr_config_node */ -static int wr_config (oconfig_item_t *ci) /* {{{ */ +static int wr_config(oconfig_item_t *ci) /* {{{ */ { - for (int i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Node", child->key) == 0) - wr_config_node (child); + if (strcasecmp("Node", child->key) == 0) + wr_config_node(child); else - WARNING ("write_redis plugin: Ignoring unknown " - "configuration option \"%s\" at top level.", child->key); + WARNING("write_redis plugin: Ignoring unknown " + "configuration option \"%s\" at top level.", + child->key); } return (0); } /* }}} int wr_config */ -void module_register (void) -{ - plugin_register_complex_config ("write_redis", wr_config); +void module_register(void) { + plugin_register_complex_config("write_redis", wr_config); } /* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ diff --git a/src/write_riemann.c b/src/write_riemann.c index 92c8d0ca..3835a3d5 100644 --- a/src/write_riemann.c +++ b/src/write_riemann.c @@ -685,7 +685,8 @@ static int wrr_config_node(oconfig_item_t *ci) /* {{{ */ if (status != 0) break; #else - WARNING("write_riemann plugin: The Timeout option is not supported. Please upgrade the Riemann client to at least 1.8.0."); + WARNING("write_riemann plugin: The Timeout option is not supported. " + "Please upgrade the Riemann client to at least 1.8.0."); #endif } else if (strcasecmp("Port", child->key) == 0) { host->port = cf_util_get_port_number(child); @@ -794,10 +795,7 @@ static int wrr_config_node(oconfig_item_t *ci) /* {{{ */ ssnprintf(callback_name, sizeof(callback_name), "write_riemann/%s", host->name); - user_data_t ud = { - .data = host, - .free_func = wrr_free - }; + user_data_t ud = {.data = host, .free_func = wrr_free}; pthread_mutex_lock(&host->lock); diff --git a/src/write_riemann_threshold.c b/src/write_riemann_threshold.c index d393994b..452c2910 100644 --- a/src/write_riemann_threshold.c +++ b/src/write_riemann_threshold.c @@ -53,61 +53,57 @@ * appropriate. * Does not fail. */ -static int ut_check_one_data_source (const data_set_t *ds, - const value_list_t __attribute__((unused)) *vl, - const threshold_t *th, - const gauge_t *values, - int ds_index) -{ /* {{{ */ +static int ut_check_one_data_source( + const data_set_t *ds, const value_list_t __attribute__((unused)) * vl, + const threshold_t *th, const gauge_t *values, int ds_index) { /* {{{ */ const char *ds_name; int is_warning = 0; int is_failure = 0; int prev_state = STATE_OKAY; /* check if this threshold applies to this data source */ - if (ds != NULL) - { + if (ds != NULL) { ds_name = ds->ds[ds_index].name; - if ((th->data_source[0] != 0) - && (strcmp (ds_name, th->data_source) != 0)) + if ((th->data_source[0] != 0) && (strcmp(ds_name, th->data_source) != 0)) return (STATE_OKAY); } - if ((th->flags & UT_FLAG_INVERT) != 0) - { + if ((th->flags & UT_FLAG_INVERT) != 0) { is_warning--; is_failure--; } /* XXX: This is an experimental code, not optimized, not fast, not reliable, * and probably, do not work as you expect. Enjoy! :D */ - if ( (th->hysteresis > 0) && ((prev_state = uc_get_state(ds,vl)) != STATE_OKAY) ) - { - switch(prev_state) - { - case STATE_ERROR: - if ( (!isnan (th->failure_min) && ((th->failure_min + th->hysteresis) < values[ds_index])) || - (!isnan (th->failure_max) && ((th->failure_max - th->hysteresis) > values[ds_index])) ) - return (STATE_OKAY); - else - is_failure++; - case STATE_WARNING: - if ( (!isnan (th->warning_min) && ((th->warning_min + th->hysteresis) < values[ds_index])) || - (!isnan (th->warning_max) && ((th->warning_max - th->hysteresis) > values[ds_index])) ) - return (STATE_OKAY); - else - is_warning++; - } - } - else { /* no hysteresis */ - if ((!isnan (th->failure_min) && (th->failure_min > values[ds_index])) - || (!isnan (th->failure_max) && (th->failure_max < values[ds_index]))) + if ((th->hysteresis > 0) && + ((prev_state = uc_get_state(ds, vl)) != STATE_OKAY)) { + switch (prev_state) { + case STATE_ERROR: + if ((!isnan(th->failure_min) && + ((th->failure_min + th->hysteresis) < values[ds_index])) || + (!isnan(th->failure_max) && + ((th->failure_max - th->hysteresis) > values[ds_index]))) + return (STATE_OKAY); + else + is_failure++; + case STATE_WARNING: + if ((!isnan(th->warning_min) && + ((th->warning_min + th->hysteresis) < values[ds_index])) || + (!isnan(th->warning_max) && + ((th->warning_max - th->hysteresis) > values[ds_index]))) + return (STATE_OKAY); + else + is_warning++; + } + } else { /* no hysteresis */ + if ((!isnan(th->failure_min) && (th->failure_min > values[ds_index])) || + (!isnan(th->failure_max) && (th->failure_max < values[ds_index]))) is_failure++; - if ((!isnan (th->warning_min) && (th->warning_min > values[ds_index])) - || (!isnan (th->warning_max) && (th->warning_max < values[ds_index]))) + if ((!isnan(th->warning_min) && (th->warning_min > values[ds_index])) || + (!isnan(th->warning_max) && (th->warning_max < values[ds_index]))) is_warning++; - } + } if (is_failure != 0) return (STATE_ERROR); @@ -126,59 +122,53 @@ static int ut_check_one_data_source (const data_set_t *ds, * which is `okay' if nothing has failed. * Returns less than zero if the data set doesn't have any data sources. */ -static int ut_check_one_threshold (const data_set_t *ds, - const value_list_t *vl, - const threshold_t *th, - const gauge_t *values, - int *statuses) -{ /* {{{ */ +static int ut_check_one_threshold(const data_set_t *ds, const value_list_t *vl, + const threshold_t *th, const gauge_t *values, + int *statuses) { /* {{{ */ int ret = -1; int status; gauge_t values_copy[ds->ds_num]; - memcpy (values_copy, values, sizeof (values_copy)); + memcpy(values_copy, values, sizeof(values_copy)); - if ((th->flags & UT_FLAG_PERCENTAGE) != 0) - { + if ((th->flags & UT_FLAG_PERCENTAGE) != 0) { int num = 0; - gauge_t sum=0.0; + gauge_t sum = 0.0; - if (ds->ds_num == 1) - { - WARNING ("ut_check_one_threshold: The %s type has only one data " + if (ds->ds_num == 1) { + WARNING( + "ut_check_one_threshold: The %s type has only one data " "source, but you have configured to check this as a percentage. " "That doesn't make much sense, because the percentage will always " - "be 100%%!", ds->type); + "be 100%%!", + ds->type); } /* Prepare `sum' and `num'. */ for (size_t i = 0; i < ds->ds_num; i++) - if (!isnan (values[i])) - { + if (!isnan(values[i])) { num++; - sum += values[i]; + sum += values[i]; } - if ((num == 0) /* All data sources are undefined. */ + if ((num == 0) /* All data sources are undefined. */ || (sum == 0.0)) /* Sum is zero, cannot calculate percentage. */ { for (size_t i = 0; i < ds->ds_num; i++) values_copy[i] = NAN; - } - else /* We can actually calculate the percentage. */ + } else /* We can actually calculate the percentage. */ { for (size_t i = 0; i < ds->ds_num; i++) values_copy[i] = 100.0 * values[i] / sum; } } /* if (UT_FLAG_PERCENTAGE) */ - for (size_t i = 0; i < ds->ds_num; i++) - { - status = ut_check_one_data_source (ds, vl, th, values_copy, i); + for (size_t i = 0; i < ds->ds_num; i++) { + status = ut_check_one_data_source(ds, vl, th, values_copy, i); if (status != -1) { - ret = 0; - if (statuses[i] < status) - statuses[i] = status; + ret = 0; + if (statuses[i] < status) + statuses[i] = status; } } /* for (ds->ds_num) */ @@ -194,50 +184,46 @@ static int ut_check_one_threshold (const data_set_t *ds, * Returns zero on success and if no threshold has been configured. Returns * less than zero on failure. */ -int write_riemann_threshold_check (const data_set_t *ds, const value_list_t *vl, - int *statuses) -{ /* {{{ */ +int write_riemann_threshold_check(const data_set_t *ds, const value_list_t *vl, + int *statuses) { /* {{{ */ threshold_t *th; gauge_t *values; int status; - assert (vl->values_len > 0); + assert(vl->values_len > 0); memset(statuses, 0, vl->values_len * sizeof(*statuses)); if (threshold_tree == NULL) - return 0; + return 0; /* Is this lock really necessary? So far, thresholds are only inserted at * startup. -octo */ - pthread_mutex_lock (&threshold_lock); - th = threshold_search (vl); - pthread_mutex_unlock (&threshold_lock); + pthread_mutex_lock(&threshold_lock); + th = threshold_search(vl); + pthread_mutex_unlock(&threshold_lock); if (th == NULL) - return (0); + return (0); - DEBUG ("ut_check_threshold: Found matching threshold(s)"); + DEBUG("ut_check_threshold: Found matching threshold(s)"); - values = uc_get_rate (ds, vl); + values = uc_get_rate(ds, vl); if (values == NULL) - return (0); + return (0); - while (th != NULL) - { - status = ut_check_one_threshold (ds, vl, th, values, statuses); - if (status < 0) - { - ERROR ("ut_check_threshold: ut_check_one_threshold failed."); - sfree (values); + while (th != NULL) { + status = ut_check_one_threshold(ds, vl, th, values, statuses); + if (status < 0) { + ERROR("ut_check_threshold: ut_check_one_threshold failed."); + sfree(values); return (-1); } th = th->next; } /* while (th) */ - sfree (values); + sfree(values); return (0); } /* }}} int ut_check_threshold */ - /* vim: set sw=2 ts=8 sts=2 tw=78 et fdm=marker : */ diff --git a/src/write_riemann_threshold.h b/src/write_riemann_threshold.h index bae2b2ac..5299c32d 100644 --- a/src/write_riemann_threshold.h +++ b/src/write_riemann_threshold.h @@ -31,6 +31,6 @@ * Returns zero on success and if no threshold has been configured. Returns * less than zero on failure. */ int write_riemann_threshold_check(const data_set_t *ds, const value_list_t *vl, - int *statuses); + int *statuses); #endif /* WRITE_RIEMANN_THRESHOLD_H */ diff --git a/src/write_sensu.c b/src/write_sensu.c index d764d260..72ed6bc0 100644 --- a/src/write_sensu.c +++ b/src/write_sensu.c @@ -28,18 +28,18 @@ #include "collectd.h" -#include "plugin.h" -#include "common.h" -#include "utils_cache.h" #include #include -#include #include +#include #include +#include "common.h" +#include "plugin.h" +#include "utils_cache.h" #include -#define SENSU_HOST "localhost" -#define SENSU_PORT "3030" +#define SENSU_HOST "localhost" +#define SENSU_PORT "3030" #ifdef HAVE_ASPRINTF #define my_asprintf asprintf @@ -53,497 +53,520 @@ */ static int my_vasprintf(char **str, const char *fmt, va_list args) { - int size = 0; - va_list tmpa; - // copy - va_copy(tmpa, args); - // apply variadic arguments to - // sprintf with format to get size - size = vsnprintf(NULL, size, fmt, tmpa); - // toss args - va_end(tmpa); - // return -1 to be compliant if - // size is less than 0 - if (size < 0) { return -1; } - // alloc with size plus 1 for `\0' - *str = (char *) malloc(size + 1); - // return -1 to be compliant - // if pointer is `NULL' - if (NULL == *str) { return -1; } - // format string with original - // variadic arguments and set new size - size = vsprintf(*str, fmt, args); - return size; + int size = 0; + va_list tmpa; + // copy + va_copy(tmpa, args); + // apply variadic arguments to + // sprintf with format to get size + size = vsnprintf(NULL, size, fmt, tmpa); + // toss args + va_end(tmpa); + // return -1 to be compliant if + // size is less than 0 + if (size < 0) { + return -1; + } + // alloc with size plus 1 for `\0' + *str = (char *)malloc(size + 1); + // return -1 to be compliant + // if pointer is `NULL' + if (NULL == *str) { + return -1; + } + // format string with original + // variadic arguments and set new size + size = vsprintf(*str, fmt, args); + return size; } static int my_asprintf(char **str, const char *fmt, ...) { - int size = 0; - va_list args; - // init variadic argumens - va_start(args, fmt); - // format and get size - size = my_vasprintf(str, fmt, args); - // toss args - va_end(args); - return size; + int size = 0; + va_list args; + // init variadic argumens + va_start(args, fmt); + // format and get size + size = my_vasprintf(str, fmt, args); + // toss args + va_end(args); + return size; } #endif struct str_list { - int nb_strs; - char **strs; + int nb_strs; + char **strs; }; struct sensu_host { - char *name; - char *event_service_prefix; - struct str_list metric_handlers; - struct str_list notification_handlers; -#define F_READY 0x01 - uint8_t flags; - pthread_mutex_t lock; - _Bool notifications; - _Bool metrics; - _Bool store_rates; - _Bool always_append_ds; - char *separator; - char *node; - char *service; - int s; - struct addrinfo *res; - int reference_count; + char *name; + char *event_service_prefix; + struct str_list metric_handlers; + struct str_list notification_handlers; +#define F_READY 0x01 + uint8_t flags; + pthread_mutex_t lock; + _Bool notifications; + _Bool metrics; + _Bool store_rates; + _Bool always_append_ds; + char *separator; + char *node; + char *service; + int s; + struct addrinfo *res; + int reference_count; }; -static char *sensu_tags = NULL; -static char **sensu_attrs = NULL; +static char *sensu_tags = NULL; +static char **sensu_attrs = NULL; static size_t sensu_attrs_num; static int add_str_to_list(struct str_list *strs, - const char *str_to_add) /* {{{ */ + const char *str_to_add) /* {{{ */ { - char **old_strs_ptr = strs->strs; - char *newstr = strdup(str_to_add); - if (newstr == NULL) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return -1; - } - strs->strs = realloc(strs->strs, sizeof(char *) *(strs->nb_strs + 1)); - if (strs->strs == NULL) { - strs->strs = old_strs_ptr; - free(newstr); - ERROR("write_sensu plugin: Unable to alloc memory"); - return -1; - } - strs->strs[strs->nb_strs] = newstr; - strs->nb_strs++; - return 0; + char **old_strs_ptr = strs->strs; + char *newstr = strdup(str_to_add); + if (newstr == NULL) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return -1; + } + strs->strs = realloc(strs->strs, sizeof(char *) * (strs->nb_strs + 1)); + if (strs->strs == NULL) { + strs->strs = old_strs_ptr; + free(newstr); + ERROR("write_sensu plugin: Unable to alloc memory"); + return -1; + } + strs->strs[strs->nb_strs] = newstr; + strs->nb_strs++; + return 0; } /* }}} int add_str_to_list */ static void free_str_list(struct str_list *strs) /* {{{ */ { - for (int i=0; inb_strs; i++) - free(strs->strs[i]); - free(strs->strs); + for (int i = 0; i < strs->nb_strs; i++) + free(strs->strs[i]); + free(strs->strs); } /* }}} void free_str_list */ static int sensu_connect(struct sensu_host *host) /* {{{ */ { - int e; - char const *node; - char const *service; - - // Resolve the target if we haven't done already - if (!(host->flags & F_READY)) { - memset(&service, 0, sizeof(service)); - host->res = NULL; - - node = (host->node != NULL) ? host->node : SENSU_HOST; - service = (host->service != NULL) ? host->service : SENSU_PORT; - - struct addrinfo ai_hints = { - .ai_family = AF_INET, - .ai_flags = AI_ADDRCONFIG, - .ai_socktype = SOCK_STREAM - }; - - if ((e = getaddrinfo(node, service, &ai_hints, &(host->res))) != 0) { - ERROR("write_sensu plugin: Unable to resolve host \"%s\": %s", - node, gai_strerror(e)); - return -1; - } - DEBUG("write_sensu plugin: successfully resolved host/port: %s/%s", - node, service); - host->flags |= F_READY; - } - - struct linger so_linger; - host->s = -1; - for (struct addrinfo *ai = host->res; ai != NULL; ai = ai->ai_next) { - // create the socket - if ((host->s = socket(ai->ai_family, - ai->ai_socktype, - ai->ai_protocol)) == -1) { - continue; - } - - // Set very low close() lingering - so_linger.l_onoff = 1; - so_linger.l_linger = 3; - if (setsockopt(host->s, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger) != 0) - WARNING("write_sensu plugin: failed to set socket close() lingering"); - - set_sock_opts(host->s); - - // connect the socket - if (connect(host->s, ai->ai_addr, ai->ai_addrlen) != 0) { - close(host->s); - host->s = -1; - continue; - } - DEBUG("write_sensu plugin: connected"); - break; - } - - if (host->s < 0) { - WARNING("write_sensu plugin: Unable to connect to sensu client"); - return -1; - } - return 0; + int e; + char const *node; + char const *service; + + // Resolve the target if we haven't done already + if (!(host->flags & F_READY)) { + memset(&service, 0, sizeof(service)); + host->res = NULL; + + node = (host->node != NULL) ? host->node : SENSU_HOST; + service = (host->service != NULL) ? host->service : SENSU_PORT; + + struct addrinfo ai_hints = {.ai_family = AF_INET, + .ai_flags = AI_ADDRCONFIG, + .ai_socktype = SOCK_STREAM}; + + if ((e = getaddrinfo(node, service, &ai_hints, &(host->res))) != 0) { + ERROR("write_sensu plugin: Unable to resolve host \"%s\": %s", node, + gai_strerror(e)); + return -1; + } + DEBUG("write_sensu plugin: successfully resolved host/port: %s/%s", node, + service); + host->flags |= F_READY; + } + + struct linger so_linger; + host->s = -1; + for (struct addrinfo *ai = host->res; ai != NULL; ai = ai->ai_next) { + // create the socket + if ((host->s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) == + -1) { + continue; + } + + // Set very low close() lingering + so_linger.l_onoff = 1; + so_linger.l_linger = 3; + if (setsockopt(host->s, SOL_SOCKET, SO_LINGER, &so_linger, + sizeof so_linger) != 0) + WARNING("write_sensu plugin: failed to set socket close() lingering"); + + set_sock_opts(host->s); + + // connect the socket + if (connect(host->s, ai->ai_addr, ai->ai_addrlen) != 0) { + close(host->s); + host->s = -1; + continue; + } + DEBUG("write_sensu plugin: connected"); + break; + } + + if (host->s < 0) { + WARNING("write_sensu plugin: Unable to connect to sensu client"); + return -1; + } + return 0; } /* }}} int sensu_connect */ static void sensu_close_socket(struct sensu_host *host) /* {{{ */ { - if (host->s != -1) - close(host->s); - host->s = -1; + if (host->s != -1) + close(host->s); + host->s = -1; } /* }}} void sensu_close_socket */ -static char *build_json_str_list(const char *tag, struct str_list const *list) /* {{{ */ +static char *build_json_str_list(const char *tag, + struct str_list const *list) /* {{{ */ { - int res; - char *ret_str = NULL; - char *temp_str; - if (list->nb_strs == 0) { - ret_str = malloc(sizeof(char)); - if (ret_str == NULL) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str[0] = '\0'; - } - - res = my_asprintf(&temp_str, "\"%s\": [\"%s\"", tag, list->strs[0]); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - free(ret_str); - return NULL; - } - for (int i=1; inb_strs; i++) { - res = my_asprintf(&ret_str, "%s, \"%s\"", temp_str, list->strs[i]); - free(temp_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - temp_str = ret_str; - } - res = my_asprintf(&ret_str, "%s]", temp_str); - free(temp_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - - return ret_str; + int res; + char *ret_str = NULL; + char *temp_str; + if (list->nb_strs == 0) { + ret_str = malloc(sizeof(char)); + if (ret_str == NULL) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str[0] = '\0'; + } + + res = my_asprintf(&temp_str, "\"%s\": [\"%s\"", tag, list->strs[0]); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + free(ret_str); + return NULL; + } + for (int i = 1; i < list->nb_strs; i++) { + res = my_asprintf(&ret_str, "%s, \"%s\"", temp_str, list->strs[i]); + free(temp_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + temp_str = ret_str; + } + res = my_asprintf(&ret_str, "%s]", temp_str); + free(temp_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + + return ret_str; } /* }}} char *build_json_str_list*/ -static int sensu_format_name2(char *ret, int ret_len, - const char *hostname, - const char *plugin, const char *plugin_instance, - const char *type, const char *type_instance, - const char *separator) -{ - char *buffer; - size_t buffer_size; - - buffer = ret; - buffer_size = (size_t) ret_len; - -#define APPEND(str) do { \ - size_t l = strlen (str); \ - if (l >= buffer_size) \ - return (ENOBUFS); \ - memcpy (buffer, (str), l); \ - buffer += l; buffer_size -= l; \ -} while (0) - - assert (plugin != NULL); - assert (type != NULL); - - APPEND (hostname); - APPEND (separator); - APPEND (plugin); - if ((plugin_instance != NULL) && (plugin_instance[0] != 0)) - { - APPEND ("-"); - APPEND (plugin_instance); - } - APPEND (separator); - APPEND (type); - if ((type_instance != NULL) && (type_instance[0] != 0)) - { - APPEND ("-"); - APPEND (type_instance); - } - assert (buffer_size > 0); - buffer[0] = 0; +static int sensu_format_name2(char *ret, int ret_len, const char *hostname, + const char *plugin, const char *plugin_instance, + const char *type, const char *type_instance, + const char *separator) { + char *buffer; + size_t buffer_size; + + buffer = ret; + buffer_size = (size_t)ret_len; + +#define APPEND(str) \ + do { \ + size_t l = strlen(str); \ + if (l >= buffer_size) \ + return (ENOBUFS); \ + memcpy(buffer, (str), l); \ + buffer += l; \ + buffer_size -= l; \ + } while (0) + + assert(plugin != NULL); + assert(type != NULL); + + APPEND(hostname); + APPEND(separator); + APPEND(plugin); + if ((plugin_instance != NULL) && (plugin_instance[0] != 0)) { + APPEND("-"); + APPEND(plugin_instance); + } + APPEND(separator); + APPEND(type); + if ((type_instance != NULL) && (type_instance[0] != 0)) { + APPEND("-"); + APPEND(type_instance); + } + assert(buffer_size > 0); + buffer[0] = 0; #undef APPEND - return (0); + return (0); } /* int sensu_format_name2 */ static void in_place_replace_sensu_name_reserved(char *orig_name) /* {{{ */ { - int len=strlen(orig_name); - for (int i=0; imetric_handlers)); - if (handlers_str == NULL) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - - // incorporate the handlers - if (strlen(handlers_str) == 0) { - free(handlers_str); - ret_str = strdup(part1); - if (ret_str == NULL) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - } - else { - res = my_asprintf(&ret_str, "%s, %s", part1, handlers_str); - free(handlers_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - } - - // incorporate the plugin name information - res = my_asprintf(&temp_str, "%s, \"collectd_plugin\": \"%s\"", ret_str, vl->plugin); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - - // incorporate the plugin type - res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", ret_str, vl->type); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - - // incorporate the plugin instance if any - if (vl->plugin_instance[0] != 0) { - res = my_asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", ret_str, vl->plugin_instance); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - } - - // incorporate the plugin type instance if any - if (vl->type_instance[0] != 0) { - res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", ret_str, vl->type_instance); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - } - - // incorporate the data source type - if ((ds->ds[index].type != DS_TYPE_GAUGE) && (rates != NULL)) { - char ds_type[DATA_MAX_NAME_LEN]; - ssnprintf (ds_type, sizeof (ds_type), "%s:rate", DS_TYPE_TO_STRING(ds->ds[index].type)); - res = my_asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", ret_str, ds_type); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - } else { - res = my_asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", ret_str, DS_TYPE_TO_STRING(ds->ds[index].type)); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - } - - // incorporate the data source name - res = my_asprintf(&temp_str, "%s, \"collectd_data_source_name\": \"%s\"", ret_str, ds->ds[index].name); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - - // incorporate the data source index - { - char ds_index[DATA_MAX_NAME_LEN]; - ssnprintf (ds_index, sizeof (ds_index), "%zu", index); - res = my_asprintf(&temp_str, "%s, \"collectd_data_source_index\": %s", ret_str, ds_index); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - } - - // add key value attributes from config if any - for (size_t i = 0; i < sensu_attrs_num; i += 2) { - res = my_asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], sensu_attrs[i+1]); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - } - - // incorporate sensu tags from config if any - if ((sensu_tags != NULL) && (strlen(sensu_tags) != 0)) { - res = my_asprintf(&temp_str, "%s, %s", ret_str, sensu_tags); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - } - - // calculate the value and set to a string - if (ds->ds[index].type == DS_TYPE_GAUGE) { - res = my_asprintf(&value_str, GAUGE_FORMAT, vl->values[index].gauge); - if (res == -1) { - free(ret_str); - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - } else if (rates != NULL) { - res = my_asprintf(&value_str, GAUGE_FORMAT, rates[index]); - if (res == -1) { - free(ret_str); - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - } else { - if (ds->ds[index].type == DS_TYPE_DERIVE) { - res = my_asprintf(&value_str, "%"PRIi64, vl->values[index].derive); - if (res == -1) { - free(ret_str); - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - } - else if (ds->ds[index].type == DS_TYPE_ABSOLUTE) { - res = my_asprintf(&value_str, "%"PRIu64, vl->values[index].absolute); - if (res == -1) { - free(ret_str); - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - } - else { - res = my_asprintf(&value_str, "%llu", vl->values[index].counter); - if (res == -1) { - free(ret_str); - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - } - } - - // Generate the full service name - sensu_format_name2(name_buffer, sizeof(name_buffer), - vl->host, vl->plugin, vl->plugin_instance, - vl->type, vl->type_instance, host->separator); - if (host->always_append_ds || (ds->ds_num > 1)) { - if (host->event_service_prefix == NULL) - ssnprintf(service_buffer, sizeof(service_buffer), "%s.%s", - name_buffer, ds->ds[index].name); - else - ssnprintf(service_buffer, sizeof(service_buffer), "%s%s.%s", - host->event_service_prefix, name_buffer, ds->ds[index].name); - } else { - if (host->event_service_prefix == NULL) - sstrncpy(service_buffer, name_buffer, sizeof(service_buffer)); - else - ssnprintf(service_buffer, sizeof(service_buffer), "%s%s", - host->event_service_prefix, name_buffer); - } - - // Replace collectd sensor name reserved characters so that time series DB is happy - in_place_replace_sensu_name_reserved(service_buffer); - - // finalize the buffer by setting the output and closing curly bracket - res = my_asprintf(&temp_str, "%s, \"output\": \"%s %s %lld\"}\n",ret_str, service_buffer, value_str, (long long)CDTIME_T_TO_TIME_T(vl->time)); - free(ret_str); - free(value_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - - DEBUG("write_sensu plugin: Successfully created json for metric: " - "host = \"%s\", service = \"%s\"", - vl->host, service_buffer); - return ret_str; + data_set_t const *ds, value_list_t const *vl, + size_t index, gauge_t const *rates, + int status) { + char name_buffer[5 * DATA_MAX_NAME_LEN]; + char service_buffer[6 * DATA_MAX_NAME_LEN]; + char *ret_str; + char *temp_str; + char *value_str; + int res; + // First part of the JSON string + const char *part1 = "{\"name\": \"collectd\", \"type\": \"metric\""; + + char *handlers_str = + build_json_str_list("handlers", &(host->metric_handlers)); + if (handlers_str == NULL) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + + // incorporate the handlers + if (strlen(handlers_str) == 0) { + free(handlers_str); + ret_str = strdup(part1); + if (ret_str == NULL) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + } else { + res = my_asprintf(&ret_str, "%s, %s", part1, handlers_str); + free(handlers_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + } + + // incorporate the plugin name information + res = my_asprintf(&temp_str, "%s, \"collectd_plugin\": \"%s\"", ret_str, + vl->plugin); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + + // incorporate the plugin type + res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", ret_str, + vl->type); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + + // incorporate the plugin instance if any + if (vl->plugin_instance[0] != 0) { + res = my_asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", + ret_str, vl->plugin_instance); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + } + + // incorporate the plugin type instance if any + if (vl->type_instance[0] != 0) { + res = + my_asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", + ret_str, vl->type_instance); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + } + + // incorporate the data source type + if ((ds->ds[index].type != DS_TYPE_GAUGE) && (rates != NULL)) { + char ds_type[DATA_MAX_NAME_LEN]; + ssnprintf(ds_type, sizeof(ds_type), "%s:rate", + DS_TYPE_TO_STRING(ds->ds[index].type)); + res = my_asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", + ret_str, ds_type); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + } else { + res = my_asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", + ret_str, DS_TYPE_TO_STRING(ds->ds[index].type)); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + } + + // incorporate the data source name + res = my_asprintf(&temp_str, "%s, \"collectd_data_source_name\": \"%s\"", + ret_str, ds->ds[index].name); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + + // incorporate the data source index + { + char ds_index[DATA_MAX_NAME_LEN]; + ssnprintf(ds_index, sizeof(ds_index), "%zu", index); + res = my_asprintf(&temp_str, "%s, \"collectd_data_source_index\": %s", + ret_str, ds_index); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + } + + // add key value attributes from config if any + for (size_t i = 0; i < sensu_attrs_num; i += 2) { + res = my_asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], + sensu_attrs[i + 1]); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + } + + // incorporate sensu tags from config if any + if ((sensu_tags != NULL) && (strlen(sensu_tags) != 0)) { + res = my_asprintf(&temp_str, "%s, %s", ret_str, sensu_tags); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + } + + // calculate the value and set to a string + if (ds->ds[index].type == DS_TYPE_GAUGE) { + res = my_asprintf(&value_str, GAUGE_FORMAT, vl->values[index].gauge); + if (res == -1) { + free(ret_str); + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + } else if (rates != NULL) { + res = my_asprintf(&value_str, GAUGE_FORMAT, rates[index]); + if (res == -1) { + free(ret_str); + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + } else { + if (ds->ds[index].type == DS_TYPE_DERIVE) { + res = my_asprintf(&value_str, "%" PRIi64, vl->values[index].derive); + if (res == -1) { + free(ret_str); + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + } else if (ds->ds[index].type == DS_TYPE_ABSOLUTE) { + res = my_asprintf(&value_str, "%" PRIu64, vl->values[index].absolute); + if (res == -1) { + free(ret_str); + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + } else { + res = my_asprintf(&value_str, "%llu", vl->values[index].counter); + if (res == -1) { + free(ret_str); + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + } + } + + // Generate the full service name + sensu_format_name2(name_buffer, sizeof(name_buffer), vl->host, vl->plugin, + vl->plugin_instance, vl->type, vl->type_instance, + host->separator); + if (host->always_append_ds || (ds->ds_num > 1)) { + if (host->event_service_prefix == NULL) + ssnprintf(service_buffer, sizeof(service_buffer), "%s.%s", name_buffer, + ds->ds[index].name); + else + ssnprintf(service_buffer, sizeof(service_buffer), "%s%s.%s", + host->event_service_prefix, name_buffer, ds->ds[index].name); + } else { + if (host->event_service_prefix == NULL) + sstrncpy(service_buffer, name_buffer, sizeof(service_buffer)); + else + ssnprintf(service_buffer, sizeof(service_buffer), "%s%s", + host->event_service_prefix, name_buffer); + } + + // Replace collectd sensor name reserved characters so that time series DB is + // happy + in_place_replace_sensu_name_reserved(service_buffer); + + // finalize the buffer by setting the output and closing curly bracket + res = my_asprintf(&temp_str, "%s, \"output\": \"%s %s %lld\"}\n", ret_str, + service_buffer, value_str, + (long long)CDTIME_T_TO_TIME_T(vl->time)); + free(ret_str); + free(value_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + + DEBUG("write_sensu plugin: Successfully created json for metric: " + "host = \"%s\", service = \"%s\"", + vl->host, service_buffer); + return ret_str; } /* }}} char *sensu_value_to_json */ /* @@ -552,668 +575,678 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ * copyright (c) Laird Shaw, under public domain. */ static char *replace_str(const char *str, const char *old, /* {{{ */ - const char *new) -{ - char *ret, *r; - const char *p, *q; - size_t oldlen = strlen(old); - size_t count = strlen(new); - size_t retlen; - size_t newlen = count; - int samesize = (oldlen == newlen); - - if (!samesize) { - for (count = 0, p = str; (q = strstr(p, old)) != NULL; p = q + oldlen) - count++; - /* This is undefined if p - str > PTRDIFF_MAX */ - retlen = p - str + strlen(p) + count * (newlen - oldlen); - } else - retlen = strlen(str); - - ret = calloc(1, retlen + 1); - if (ret == NULL) - return NULL; - // added to original: not optimized, but keeps valgrind happy. - - r = ret; - p = str; - while (1) { - /* If the old and new strings are different lengths - in other - * words we have already iterated through with strstr above, - * and thus we know how many times we need to call it - then we - * can avoid the final (potentially lengthy) call to strstr, - * which we already know is going to return NULL, by - * decrementing and checking count. - */ - if (!samesize && !count--) - break; - /* Otherwise i.e. when the old and new strings are the same - * length, and we don't know how many times to call strstr, - * we must check for a NULL return here (we check it in any - * event, to avoid further conditions, and because there's - * no harm done with the check even when the old and new - * strings are different lengths). - */ - if ((q = strstr(p, old)) == NULL) - break; - /* This is undefined if q - p > PTRDIFF_MAX */ - ptrdiff_t l = q - p; - memcpy(r, p, l); - r += l; - memcpy(r, new, newlen); - r += newlen; - p = q + oldlen; - } - strncpy(r, p, strlen(p)); - - return ret; + const char *new) { + char *ret, *r; + const char *p, *q; + size_t oldlen = strlen(old); + size_t count = strlen(new); + size_t retlen; + size_t newlen = count; + int samesize = (oldlen == newlen); + + if (!samesize) { + for (count = 0, p = str; (q = strstr(p, old)) != NULL; p = q + oldlen) + count++; + /* This is undefined if p - str > PTRDIFF_MAX */ + retlen = p - str + strlen(p) + count * (newlen - oldlen); + } else + retlen = strlen(str); + + ret = calloc(1, retlen + 1); + if (ret == NULL) + return NULL; + // added to original: not optimized, but keeps valgrind happy. + + r = ret; + p = str; + while (1) { + /* If the old and new strings are different lengths - in other + * words we have already iterated through with strstr above, + * and thus we know how many times we need to call it - then we + * can avoid the final (potentially lengthy) call to strstr, + * which we already know is going to return NULL, by + * decrementing and checking count. + */ + if (!samesize && !count--) + break; + /* Otherwise i.e. when the old and new strings are the same + * length, and we don't know how many times to call strstr, + * we must check for a NULL return here (we check it in any + * event, to avoid further conditions, and because there's + * no harm done with the check even when the old and new + * strings are different lengths). + */ + if ((q = strstr(p, old)) == NULL) + break; + /* This is undefined if q - p > PTRDIFF_MAX */ + ptrdiff_t l = q - p; + memcpy(r, p, l); + r += l; + memcpy(r, new, newlen); + r += newlen; + p = q + oldlen; + } + strncpy(r, p, strlen(p)); + + return ret; } /* }}} char *replace_str */ static char *replace_json_reserved(const char *message) /* {{{ */ { - char *msg = replace_str(message, "\\", "\\\\"); - if (msg == NULL) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - char *tmp = replace_str(msg, "\"", "\\\""); - free(msg); - if (tmp == NULL) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - msg = replace_str(tmp, "\n", "\\\n"); - free(tmp); - if (msg == NULL) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - return msg; + char *msg = replace_str(message, "\\", "\\\\"); + if (msg == NULL) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + char *tmp = replace_str(msg, "\"", "\\\""); + free(msg); + if (tmp == NULL) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + msg = replace_str(tmp, "\n", "\\\n"); + free(tmp); + if (msg == NULL) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + return msg; } /* }}} char *replace_json_reserved */ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ - notification_t const *n) -{ - char service_buffer[6 * DATA_MAX_NAME_LEN]; - char const *severity; - char *ret_str; - char *temp_str; - int status; - size_t i; - int res; - // add the severity/status - switch (n->severity) { - case NOTIF_OKAY: - severity = "OK"; - status = 0; - break; - case NOTIF_WARNING: - severity = "WARNING"; - status = 1; - break; - case NOTIF_FAILURE: - severity = "CRITICAL"; - status = 2; - break; - default: - severity = "UNKNOWN"; - status = 3; - } - res = my_asprintf(&temp_str, "{\"status\": %d", status); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - - // incorporate the timestamp - res = my_asprintf(&temp_str, "%s, \"timestamp\": %lld", ret_str, (long long)CDTIME_T_TO_TIME_T(n->time)); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - - char *handlers_str = build_json_str_list("handlers", &(host->notification_handlers)); - if (handlers_str == NULL) { - ERROR("write_sensu plugin: Unable to alloc memory"); - free(ret_str); - return NULL; - } - // incorporate the handlers - if (strlen(handlers_str) != 0) { - res = my_asprintf(&temp_str, "%s, %s", ret_str, handlers_str); - free(ret_str); - free(handlers_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - } else { - free(handlers_str); - } - - // incorporate the plugin name information if any - if (n->plugin[0] != 0) { - res = my_asprintf(&temp_str, "%s, \"collectd_plugin\": \"%s\"", ret_str, n->plugin); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - } - - // incorporate the plugin type if any - if (n->type[0] != 0) { - res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", ret_str, n->type); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - } - - // incorporate the plugin instance if any - if (n->plugin_instance[0] != 0) { - res = my_asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", ret_str, n->plugin_instance); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - } - - // incorporate the plugin type instance if any - if (n->type_instance[0] != 0) { - res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", ret_str, n->type_instance); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - } - - // add key value attributes from config if any - for (i = 0; i < sensu_attrs_num; i += 2) { - res = my_asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], sensu_attrs[i+1]); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - } - - // incorporate sensu tags from config if any - if ((sensu_tags != NULL) && (strlen(sensu_tags) != 0)) { - res = my_asprintf(&temp_str, "%s, %s", ret_str, sensu_tags); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - } - - // incorporate the service name - sensu_format_name2(service_buffer, sizeof(service_buffer), - /* host */ "", n->plugin, n->plugin_instance, - n->type, n->type_instance, host->separator); - // replace sensu event name chars that are considered illegal - in_place_replace_sensu_name_reserved(service_buffer); - res = my_asprintf(&temp_str, "%s, \"name\": \"%s\"", ret_str, &service_buffer[1]); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - - // incorporate the check output - if (n->message[0] != 0) { - char *msg = replace_json_reserved(n->message); - if (msg == NULL) { - ERROR("write_sensu plugin: Unable to alloc memory"); - free(ret_str); - return NULL; - } - res = my_asprintf(&temp_str, "%s, \"output\": \"%s - %s\"", ret_str, severity, msg); - free(ret_str); - free(msg); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - } - - // Pull in values from threshold and add extra attributes - for (notification_meta_t *meta = n->meta; meta != NULL; meta = meta->next) { - if (strcasecmp("CurrentValue", meta->name) == 0 && meta->type == NM_TYPE_DOUBLE) { - res = my_asprintf(&temp_str, "%s, \"current_value\": \"%.8f\"", ret_str, meta->nm_value.nm_double); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - } - if (meta->type == NM_TYPE_STRING) { - res = my_asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, meta->name, meta->nm_value.nm_string); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - } - } - - // close the curly bracket - res = my_asprintf(&temp_str, "%s}\n", ret_str); - free(ret_str); - if (res == -1) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return NULL; - } - ret_str = temp_str; - - DEBUG("write_sensu plugin: Successfully created JSON for notification: " - "host = \"%s\", service = \"%s\", state = \"%s\"", - n->host, service_buffer, severity); - return ret_str; + notification_t const *n) { + char service_buffer[6 * DATA_MAX_NAME_LEN]; + char const *severity; + char *ret_str; + char *temp_str; + int status; + size_t i; + int res; + // add the severity/status + switch (n->severity) { + case NOTIF_OKAY: + severity = "OK"; + status = 0; + break; + case NOTIF_WARNING: + severity = "WARNING"; + status = 1; + break; + case NOTIF_FAILURE: + severity = "CRITICAL"; + status = 2; + break; + default: + severity = "UNKNOWN"; + status = 3; + } + res = my_asprintf(&temp_str, "{\"status\": %d", status); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + + // incorporate the timestamp + res = my_asprintf(&temp_str, "%s, \"timestamp\": %lld", ret_str, + (long long)CDTIME_T_TO_TIME_T(n->time)); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + + char *handlers_str = + build_json_str_list("handlers", &(host->notification_handlers)); + if (handlers_str == NULL) { + ERROR("write_sensu plugin: Unable to alloc memory"); + free(ret_str); + return NULL; + } + // incorporate the handlers + if (strlen(handlers_str) != 0) { + res = my_asprintf(&temp_str, "%s, %s", ret_str, handlers_str); + free(ret_str); + free(handlers_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + } else { + free(handlers_str); + } + + // incorporate the plugin name information if any + if (n->plugin[0] != 0) { + res = my_asprintf(&temp_str, "%s, \"collectd_plugin\": \"%s\"", ret_str, + n->plugin); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + } + + // incorporate the plugin type if any + if (n->type[0] != 0) { + res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", + ret_str, n->type); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + } + + // incorporate the plugin instance if any + if (n->plugin_instance[0] != 0) { + res = my_asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", + ret_str, n->plugin_instance); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + } + + // incorporate the plugin type instance if any + if (n->type_instance[0] != 0) { + res = + my_asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", + ret_str, n->type_instance); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + } + + // add key value attributes from config if any + for (i = 0; i < sensu_attrs_num; i += 2) { + res = my_asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], + sensu_attrs[i + 1]); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + } + + // incorporate sensu tags from config if any + if ((sensu_tags != NULL) && (strlen(sensu_tags) != 0)) { + res = my_asprintf(&temp_str, "%s, %s", ret_str, sensu_tags); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + } + + // incorporate the service name + sensu_format_name2(service_buffer, sizeof(service_buffer), + /* host */ "", n->plugin, n->plugin_instance, n->type, + n->type_instance, host->separator); + // replace sensu event name chars that are considered illegal + in_place_replace_sensu_name_reserved(service_buffer); + res = my_asprintf(&temp_str, "%s, \"name\": \"%s\"", ret_str, + &service_buffer[1]); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + + // incorporate the check output + if (n->message[0] != 0) { + char *msg = replace_json_reserved(n->message); + if (msg == NULL) { + ERROR("write_sensu plugin: Unable to alloc memory"); + free(ret_str); + return NULL; + } + res = my_asprintf(&temp_str, "%s, \"output\": \"%s - %s\"", ret_str, + severity, msg); + free(ret_str); + free(msg); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + } + + // Pull in values from threshold and add extra attributes + for (notification_meta_t *meta = n->meta; meta != NULL; meta = meta->next) { + if (strcasecmp("CurrentValue", meta->name) == 0 && + meta->type == NM_TYPE_DOUBLE) { + res = my_asprintf(&temp_str, "%s, \"current_value\": \"%.8f\"", ret_str, + meta->nm_value.nm_double); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + } + if (meta->type == NM_TYPE_STRING) { + res = my_asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, meta->name, + meta->nm_value.nm_string); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + } + } + + // close the curly bracket + res = my_asprintf(&temp_str, "%s}\n", ret_str); + free(ret_str); + if (res == -1) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return NULL; + } + ret_str = temp_str; + + DEBUG("write_sensu plugin: Successfully created JSON for notification: " + "host = \"%s\", service = \"%s\", state = \"%s\"", + n->host, service_buffer, severity); + return ret_str; } /* }}} char *sensu_notification_to_json */ static int sensu_send_msg(struct sensu_host *host, const char *msg) /* {{{ */ { - int status = 0; - size_t buffer_len; + int status = 0; + size_t buffer_len; - status = sensu_connect(host); - if (status != 0) - return status; + status = sensu_connect(host); + if (status != 0) + return status; - buffer_len = strlen(msg); + buffer_len = strlen(msg); - status = (int) swrite(host->s, msg, buffer_len); - sensu_close_socket(host); + status = (int)swrite(host->s, msg, buffer_len); + sensu_close_socket(host); - if (status != 0) { - char errbuf[1024]; - ERROR("write_sensu plugin: Sending to Sensu at %s:%s failed: %s", - (host->node != NULL) ? host->node : SENSU_HOST, - (host->service != NULL) ? host->service : SENSU_PORT, - sstrerror(errno, errbuf, sizeof(errbuf))); - return -1; - } + if (status != 0) { + char errbuf[1024]; + ERROR("write_sensu plugin: Sending to Sensu at %s:%s failed: %s", + (host->node != NULL) ? host->node : SENSU_HOST, + (host->service != NULL) ? host->service : SENSU_PORT, + sstrerror(errno, errbuf, sizeof(errbuf))); + return -1; + } - return 0; + return 0; } /* }}} int sensu_send_msg */ - static int sensu_send(struct sensu_host *host, char const *msg) /* {{{ */ { - int status = 0; - - status = sensu_send_msg(host, msg); - if (status != 0) { - host->flags &= ~F_READY; - if (host->res != NULL) { - freeaddrinfo(host->res); - host->res = NULL; - } - return status; - } - - return 0; + int status = 0; + + status = sensu_send_msg(host, msg); + if (status != 0) { + host->flags &= ~F_READY; + if (host->res != NULL) { + freeaddrinfo(host->res); + host->res = NULL; + } + return status; + } + + return 0; } /* }}} int sensu_send */ - static int sensu_write(const data_set_t *ds, /* {{{ */ - const value_list_t *vl, - user_data_t *ud) -{ - int status = 0; - int statuses[vl->values_len]; - struct sensu_host *host = ud->data; - gauge_t *rates = NULL; - char *msg; - - pthread_mutex_lock(&host->lock); - memset(statuses, 0, vl->values_len * sizeof(*statuses)); - - if (host->store_rates) { - rates = uc_get_rate(ds, vl); - if (rates == NULL) { - ERROR("write_sensu plugin: uc_get_rate failed."); - pthread_mutex_unlock(&host->lock); - return -1; - } - } - for (size_t i = 0; i < vl->values_len; i++) { - msg = sensu_value_to_json(host, ds, vl, (int) i, rates, statuses[i]); - if (msg == NULL) { - sfree(rates); - pthread_mutex_unlock(&host->lock); - return -1; - } - status = sensu_send(host, msg); - free(msg); - if (status != 0) { - ERROR("write_sensu plugin: sensu_send failed with status %i", status); - pthread_mutex_unlock(&host->lock); - sfree(rates); - return status; - } - } - sfree(rates); - pthread_mutex_unlock(&host->lock); - return status; + const value_list_t *vl, user_data_t *ud) { + int status = 0; + int statuses[vl->values_len]; + struct sensu_host *host = ud->data; + gauge_t *rates = NULL; + char *msg; + + pthread_mutex_lock(&host->lock); + memset(statuses, 0, vl->values_len * sizeof(*statuses)); + + if (host->store_rates) { + rates = uc_get_rate(ds, vl); + if (rates == NULL) { + ERROR("write_sensu plugin: uc_get_rate failed."); + pthread_mutex_unlock(&host->lock); + return -1; + } + } + for (size_t i = 0; i < vl->values_len; i++) { + msg = sensu_value_to_json(host, ds, vl, (int)i, rates, statuses[i]); + if (msg == NULL) { + sfree(rates); + pthread_mutex_unlock(&host->lock); + return -1; + } + status = sensu_send(host, msg); + free(msg); + if (status != 0) { + ERROR("write_sensu plugin: sensu_send failed with status %i", status); + pthread_mutex_unlock(&host->lock); + sfree(rates); + return status; + } + } + sfree(rates); + pthread_mutex_unlock(&host->lock); + return status; } /* }}} int sensu_write */ -static int sensu_notification(const notification_t *n, user_data_t *ud) /* {{{ */ +static int sensu_notification(const notification_t *n, + user_data_t *ud) /* {{{ */ { - int status; - struct sensu_host *host = ud->data; - char *msg; + int status; + struct sensu_host *host = ud->data; + char *msg; - pthread_mutex_lock(&host->lock); + pthread_mutex_lock(&host->lock); - msg = sensu_notification_to_json(host, n); - if (msg == NULL) { - pthread_mutex_unlock(&host->lock); - return -1; - } + msg = sensu_notification_to_json(host, n); + if (msg == NULL) { + pthread_mutex_unlock(&host->lock); + return -1; + } - status = sensu_send(host, msg); - free(msg); - if (status != 0) - ERROR("write_sensu plugin: sensu_send failed with status %i", status); - pthread_mutex_unlock(&host->lock); + status = sensu_send(host, msg); + free(msg); + if (status != 0) + ERROR("write_sensu plugin: sensu_send failed with status %i", status); + pthread_mutex_unlock(&host->lock); - return status; + return status; } /* }}} int sensu_notification */ static void sensu_free(void *p) /* {{{ */ { - struct sensu_host *host = p; - - if (host == NULL) - return; - - pthread_mutex_lock(&host->lock); - - host->reference_count--; - if (host->reference_count > 0) { - pthread_mutex_unlock(&host->lock); - return; - } - - sensu_close_socket(host); - if (host->res != NULL) { - freeaddrinfo(host->res); - host->res = NULL; - } - sfree(host->service); - sfree(host->event_service_prefix); - sfree(host->name); - sfree(host->node); - sfree(host->separator); - free_str_list(&(host->metric_handlers)); - free_str_list(&(host->notification_handlers)); - pthread_mutex_destroy(&host->lock); - sfree(host); + struct sensu_host *host = p; + + if (host == NULL) + return; + + pthread_mutex_lock(&host->lock); + + host->reference_count--; + if (host->reference_count > 0) { + pthread_mutex_unlock(&host->lock); + return; + } + + sensu_close_socket(host); + if (host->res != NULL) { + freeaddrinfo(host->res); + host->res = NULL; + } + sfree(host->service); + sfree(host->event_service_prefix); + sfree(host->name); + sfree(host->node); + sfree(host->separator); + free_str_list(&(host->metric_handlers)); + free_str_list(&(host->notification_handlers)); + pthread_mutex_destroy(&host->lock); + sfree(host); } /* }}} void sensu_free */ - static int sensu_config_node(oconfig_item_t *ci) /* {{{ */ { - struct sensu_host *host = NULL; - int status = 0; - oconfig_item_t *child; - char callback_name[DATA_MAX_NAME_LEN]; - - if ((host = calloc(1, sizeof(*host))) == NULL) { - ERROR("write_sensu plugin: calloc failed."); - return ENOMEM; - } - pthread_mutex_init(&host->lock, NULL); - host->reference_count = 1; - host->node = NULL; - host->service = NULL; - host->notifications = 0; - host->metrics = 0; - host->store_rates = 1; - host->always_append_ds = 0; - host->metric_handlers.nb_strs = 0; - host->metric_handlers.strs = NULL; - host->notification_handlers.nb_strs = 0; - host->notification_handlers.strs = NULL; - host->separator = strdup("/"); - if (host->separator == NULL) { - ERROR("write_sensu plugin: Unable to alloc memory"); - sensu_free(host); - return -1; - } - - status = cf_util_get_string(ci, &host->name); - if (status != 0) { - WARNING("write_sensu plugin: Required host name is missing."); - sensu_free(host); - return -1; - } - - for (int i = 0; i < ci->children_num; i++) { - child = &ci->children[i]; - status = 0; - - if (strcasecmp("Host", child->key) == 0) { - status = cf_util_get_string(child, &host->node); - if (status != 0) - break; - } else if (strcasecmp("Notifications", child->key) == 0) { - status = cf_util_get_boolean(child, &host->notifications); - if (status != 0) - break; - } else if (strcasecmp("Metrics", child->key) == 0) { - status = cf_util_get_boolean(child, &host->metrics); - if (status != 0) - break; - } else if (strcasecmp("EventServicePrefix", child->key) == 0) { - status = cf_util_get_string(child, &host->event_service_prefix); - if (status != 0) - break; - } else if (strcasecmp("Separator", child->key) == 0) { - status = cf_util_get_string(child, &host->separator); - if (status != 0) - break; - } else if (strcasecmp("MetricHandler", child->key) == 0) { - char *temp_str = NULL; - status = cf_util_get_string(child, &temp_str); - if (status != 0) - break; - status = add_str_to_list(&(host->metric_handlers), temp_str); - free(temp_str); - if (status != 0) - break; - } else if (strcasecmp("NotificationHandler", child->key) == 0) { - char *temp_str = NULL; - status = cf_util_get_string(child, &temp_str); - if (status != 0) - break; - status = add_str_to_list(&(host->notification_handlers), temp_str); - free(temp_str); - if (status != 0) - break; - } else if (strcasecmp("Port", child->key) == 0) { - status = cf_util_get_service(child, &host->service); - if (status != 0) { - ERROR("write_sensu plugin: Invalid argument " - "configured for the \"Port\" " - "option."); - break; - } - } else if (strcasecmp("StoreRates", child->key) == 0) { - status = cf_util_get_boolean(child, &host->store_rates); - if (status != 0) - break; - } else if (strcasecmp("AlwaysAppendDS", child->key) == 0) { - status = cf_util_get_boolean(child, - &host->always_append_ds); - if (status != 0) - break; - } else { - WARNING("write_sensu plugin: ignoring unknown config " - "option: \"%s\"", child->key); - } - } - if (status != 0) { - sensu_free(host); - return status; - } - - if (host->metrics && (host->metric_handlers.nb_strs == 0)) { - sensu_free(host); - WARNING("write_sensu plugin: metrics enabled but no MetricHandler defined. Giving up."); - return -1; - } - - if (host->notifications && (host->notification_handlers.nb_strs == 0)) { - sensu_free(host); - WARNING("write_sensu plugin: notifications enabled but no NotificationHandler defined. Giving up."); - return -1; - } - - if ((host->notification_handlers.nb_strs > 0) && (host->notifications == 0)) { - WARNING("write_sensu plugin: NotificationHandler given so forcing notifications to be enabled"); - host->notifications = 1; - } - - if ((host->metric_handlers.nb_strs > 0) && (host->metrics == 0)) { - WARNING("write_sensu plugin: MetricHandler given so forcing metrics to be enabled"); - host->metrics = 1; - } - - if (!(host->notifications || host->metrics)) { - WARNING("write_sensu plugin: neither metrics nor notifications enabled. Giving up."); - sensu_free(host); - return -1; - } - - ssnprintf(callback_name, sizeof(callback_name), "write_sensu/%s", host->name); - - user_data_t ud = { - .data = host, - .free_func = sensu_free - }; - - pthread_mutex_lock(&host->lock); - - if (host->metrics) { - status = plugin_register_write(callback_name, sensu_write, &ud); - if (status != 0) - WARNING("write_sensu plugin: plugin_register_write (\"%s\") " - "failed with status %i.", - callback_name, status); - else /* success */ - host->reference_count++; - } - - if (host->notifications) { - status = plugin_register_notification(callback_name, sensu_notification, &ud); - if (status != 0) - WARNING("write_sensu plugin: plugin_register_notification (\"%s\") " - "failed with status %i.", - callback_name, status); - else - host->reference_count++; - } - - if (host->reference_count <= 1) { - /* Both callbacks failed => free memory. - * We need to unlock here, because sensu_free() will lock. - * This is not a race condition, because we're the only one - * holding a reference. */ - pthread_mutex_unlock(&host->lock); - sensu_free(host); - return -1; - } - - host->reference_count--; - pthread_mutex_unlock(&host->lock); - - return status; + struct sensu_host *host = NULL; + int status = 0; + oconfig_item_t *child; + char callback_name[DATA_MAX_NAME_LEN]; + + if ((host = calloc(1, sizeof(*host))) == NULL) { + ERROR("write_sensu plugin: calloc failed."); + return ENOMEM; + } + pthread_mutex_init(&host->lock, NULL); + host->reference_count = 1; + host->node = NULL; + host->service = NULL; + host->notifications = 0; + host->metrics = 0; + host->store_rates = 1; + host->always_append_ds = 0; + host->metric_handlers.nb_strs = 0; + host->metric_handlers.strs = NULL; + host->notification_handlers.nb_strs = 0; + host->notification_handlers.strs = NULL; + host->separator = strdup("/"); + if (host->separator == NULL) { + ERROR("write_sensu plugin: Unable to alloc memory"); + sensu_free(host); + return -1; + } + + status = cf_util_get_string(ci, &host->name); + if (status != 0) { + WARNING("write_sensu plugin: Required host name is missing."); + sensu_free(host); + return -1; + } + + for (int i = 0; i < ci->children_num; i++) { + child = &ci->children[i]; + status = 0; + + if (strcasecmp("Host", child->key) == 0) { + status = cf_util_get_string(child, &host->node); + if (status != 0) + break; + } else if (strcasecmp("Notifications", child->key) == 0) { + status = cf_util_get_boolean(child, &host->notifications); + if (status != 0) + break; + } else if (strcasecmp("Metrics", child->key) == 0) { + status = cf_util_get_boolean(child, &host->metrics); + if (status != 0) + break; + } else if (strcasecmp("EventServicePrefix", child->key) == 0) { + status = cf_util_get_string(child, &host->event_service_prefix); + if (status != 0) + break; + } else if (strcasecmp("Separator", child->key) == 0) { + status = cf_util_get_string(child, &host->separator); + if (status != 0) + break; + } else if (strcasecmp("MetricHandler", child->key) == 0) { + char *temp_str = NULL; + status = cf_util_get_string(child, &temp_str); + if (status != 0) + break; + status = add_str_to_list(&(host->metric_handlers), temp_str); + free(temp_str); + if (status != 0) + break; + } else if (strcasecmp("NotificationHandler", child->key) == 0) { + char *temp_str = NULL; + status = cf_util_get_string(child, &temp_str); + if (status != 0) + break; + status = add_str_to_list(&(host->notification_handlers), temp_str); + free(temp_str); + if (status != 0) + break; + } else if (strcasecmp("Port", child->key) == 0) { + status = cf_util_get_service(child, &host->service); + if (status != 0) { + ERROR("write_sensu plugin: Invalid argument " + "configured for the \"Port\" " + "option."); + break; + } + } else if (strcasecmp("StoreRates", child->key) == 0) { + status = cf_util_get_boolean(child, &host->store_rates); + if (status != 0) + break; + } else if (strcasecmp("AlwaysAppendDS", child->key) == 0) { + status = cf_util_get_boolean(child, &host->always_append_ds); + if (status != 0) + break; + } else { + WARNING("write_sensu plugin: ignoring unknown config " + "option: \"%s\"", + child->key); + } + } + if (status != 0) { + sensu_free(host); + return status; + } + + if (host->metrics && (host->metric_handlers.nb_strs == 0)) { + sensu_free(host); + WARNING("write_sensu plugin: metrics enabled but no MetricHandler defined. " + "Giving up."); + return -1; + } + + if (host->notifications && (host->notification_handlers.nb_strs == 0)) { + sensu_free(host); + WARNING("write_sensu plugin: notifications enabled but no " + "NotificationHandler defined. Giving up."); + return -1; + } + + if ((host->notification_handlers.nb_strs > 0) && (host->notifications == 0)) { + WARNING("write_sensu plugin: NotificationHandler given so forcing " + "notifications to be enabled"); + host->notifications = 1; + } + + if ((host->metric_handlers.nb_strs > 0) && (host->metrics == 0)) { + WARNING("write_sensu plugin: MetricHandler given so forcing metrics to be " + "enabled"); + host->metrics = 1; + } + + if (!(host->notifications || host->metrics)) { + WARNING("write_sensu plugin: neither metrics nor notifications enabled. " + "Giving up."); + sensu_free(host); + return -1; + } + + ssnprintf(callback_name, sizeof(callback_name), "write_sensu/%s", host->name); + + user_data_t ud = {.data = host, .free_func = sensu_free}; + + pthread_mutex_lock(&host->lock); + + if (host->metrics) { + status = plugin_register_write(callback_name, sensu_write, &ud); + if (status != 0) + WARNING("write_sensu plugin: plugin_register_write (\"%s\") " + "failed with status %i.", + callback_name, status); + else /* success */ + host->reference_count++; + } + + if (host->notifications) { + status = + plugin_register_notification(callback_name, sensu_notification, &ud); + if (status != 0) + WARNING("write_sensu plugin: plugin_register_notification (\"%s\") " + "failed with status %i.", + callback_name, status); + else + host->reference_count++; + } + + if (host->reference_count <= 1) { + /* Both callbacks failed => free memory. + * We need to unlock here, because sensu_free() will lock. + * This is not a race condition, because we're the only one + * holding a reference. */ + pthread_mutex_unlock(&host->lock); + sensu_free(host); + return -1; + } + + host->reference_count--; + pthread_mutex_unlock(&host->lock); + + return status; } /* }}} int sensu_config_node */ static int sensu_config(oconfig_item_t *ci) /* {{{ */ { - oconfig_item_t *child; - int status; - struct str_list sensu_tags_arr; - - sensu_tags_arr.nb_strs = 0; - sensu_tags_arr.strs = NULL; - - for (int i = 0; i < ci->children_num; i++) { - child = &ci->children[i]; - - if (strcasecmp("Node", child->key) == 0) { - sensu_config_node(child); - } else if (strcasecmp(child->key, "attribute") == 0) { - if (child->values_num != 2) { - WARNING("sensu attributes need both a key and a value."); - continue; - } - if (child->values[0].type != OCONFIG_TYPE_STRING || - child->values[1].type != OCONFIG_TYPE_STRING) { - WARNING("sensu attribute needs string arguments."); - continue; - } - - strarray_add(&sensu_attrs, &sensu_attrs_num, child->values[0].value.string); - strarray_add(&sensu_attrs, &sensu_attrs_num, child->values[1].value.string); - - DEBUG("write_sensu plugin: New attribute: %s => %s", - child->values[0].value.string, - child->values[1].value.string); - } else if (strcasecmp(child->key, "tag") == 0) { - char *tmp = NULL; - status = cf_util_get_string(child, &tmp); - if (status != 0) - continue; - - status = add_str_to_list(&sensu_tags_arr, tmp); - sfree(tmp); - if (status != 0) - continue; - DEBUG("write_sensu plugin: Got tag: %s", tmp); - } else { - WARNING("write_sensu plugin: Ignoring unknown " - "configuration option \"%s\" at top level.", - child->key); - } - } - if (sensu_tags_arr.nb_strs > 0) { - sfree (sensu_tags); - sensu_tags = build_json_str_list("tags", &sensu_tags_arr); - free_str_list(&sensu_tags_arr); - if (sensu_tags == NULL) { - ERROR("write_sensu plugin: Unable to alloc memory"); - return -1; - } - } - return 0; + oconfig_item_t *child; + int status; + struct str_list sensu_tags_arr; + + sensu_tags_arr.nb_strs = 0; + sensu_tags_arr.strs = NULL; + + for (int i = 0; i < ci->children_num; i++) { + child = &ci->children[i]; + + if (strcasecmp("Node", child->key) == 0) { + sensu_config_node(child); + } else if (strcasecmp(child->key, "attribute") == 0) { + if (child->values_num != 2) { + WARNING("sensu attributes need both a key and a value."); + continue; + } + if (child->values[0].type != OCONFIG_TYPE_STRING || + child->values[1].type != OCONFIG_TYPE_STRING) { + WARNING("sensu attribute needs string arguments."); + continue; + } + + strarray_add(&sensu_attrs, &sensu_attrs_num, + child->values[0].value.string); + strarray_add(&sensu_attrs, &sensu_attrs_num, + child->values[1].value.string); + + DEBUG("write_sensu plugin: New attribute: %s => %s", + child->values[0].value.string, child->values[1].value.string); + } else if (strcasecmp(child->key, "tag") == 0) { + char *tmp = NULL; + status = cf_util_get_string(child, &tmp); + if (status != 0) + continue; + + status = add_str_to_list(&sensu_tags_arr, tmp); + sfree(tmp); + if (status != 0) + continue; + DEBUG("write_sensu plugin: Got tag: %s", tmp); + } else { + WARNING("write_sensu plugin: Ignoring unknown " + "configuration option \"%s\" at top level.", + child->key); + } + } + if (sensu_tags_arr.nb_strs > 0) { + sfree(sensu_tags); + sensu_tags = build_json_str_list("tags", &sensu_tags_arr); + free_str_list(&sensu_tags_arr); + if (sensu_tags == NULL) { + ERROR("write_sensu plugin: Unable to alloc memory"); + return -1; + } + } + return 0; } /* }}} int sensu_config */ -void module_register(void) -{ - plugin_register_complex_config("write_sensu", sensu_config); +void module_register(void) { + plugin_register_complex_config("write_sensu", sensu_config); } /* vim: set sw=8 sts=8 ts=8 noet : */ diff --git a/src/write_tsdb.c b/src/write_tsdb.c index b670f3ae..0c87c473 100644 --- a/src/write_tsdb.c +++ b/src/write_tsdb.c @@ -51,600 +51,536 @@ #include #ifndef WT_DEFAULT_NODE -# define WT_DEFAULT_NODE "localhost" +#define WT_DEFAULT_NODE "localhost" #endif #ifndef WT_DEFAULT_SERVICE -# define WT_DEFAULT_SERVICE "4242" +#define WT_DEFAULT_SERVICE "4242" #endif #ifndef WT_DEFAULT_ESCAPE -# define WT_DEFAULT_ESCAPE '.' +#define WT_DEFAULT_ESCAPE '.' #endif /* Ethernet - (IPv6 + TCP) = 1500 - (40 + 32) = 1428 */ #ifndef WT_SEND_BUF_SIZE -# define WT_SEND_BUF_SIZE 1428 +#define WT_SEND_BUF_SIZE 1428 #endif /* * Private variables */ -struct wt_callback -{ - int sock_fd; +struct wt_callback { + int sock_fd; - char *node; - char *service; - char *host_tags; + char *node; + char *service; + char *host_tags; - _Bool store_rates; - _Bool always_append_ds; + _Bool store_rates; + _Bool always_append_ds; - char send_buf[WT_SEND_BUF_SIZE]; - size_t send_buf_free; - size_t send_buf_fill; - cdtime_t send_buf_init_time; + char send_buf[WT_SEND_BUF_SIZE]; + size_t send_buf_free; + size_t send_buf_fill; + cdtime_t send_buf_init_time; - pthread_mutex_t send_lock; + pthread_mutex_t send_lock; }; - /* * Functions */ -static void wt_reset_buffer(struct wt_callback *cb) -{ - memset(cb->send_buf, 0, sizeof(cb->send_buf)); - cb->send_buf_free = sizeof(cb->send_buf); - cb->send_buf_fill = 0; - cb->send_buf_init_time = cdtime(); +static void wt_reset_buffer(struct wt_callback *cb) { + memset(cb->send_buf, 0, sizeof(cb->send_buf)); + cb->send_buf_free = sizeof(cb->send_buf); + cb->send_buf_fill = 0; + cb->send_buf_init_time = cdtime(); } -static int wt_send_buffer(struct wt_callback *cb) -{ - ssize_t status = 0; +static int wt_send_buffer(struct wt_callback *cb) { + ssize_t status = 0; - status = swrite(cb->sock_fd, cb->send_buf, strlen(cb->send_buf)); - if (status < 0) - { - char errbuf[1024]; - ERROR("write_tsdb plugin: send failed with status %zi (%s)", - status, sstrerror (errno, errbuf, sizeof (errbuf))); + status = swrite(cb->sock_fd, cb->send_buf, strlen(cb->send_buf)); + if (status < 0) { + char errbuf[1024]; + ERROR("write_tsdb plugin: send failed with status %zi (%s)", status, + sstrerror(errno, errbuf, sizeof(errbuf))); - close (cb->sock_fd); - cb->sock_fd = -1; + close(cb->sock_fd); + cb->sock_fd = -1; - return -1; - } + return -1; + } - return 0; + return 0; } /* NOTE: You must hold cb->send_lock when calling this function! */ -static int wt_flush_nolock(cdtime_t timeout, struct wt_callback *cb) -{ - int status; - - DEBUG("write_tsdb plugin: wt_flush_nolock: timeout = %.3f; " - "send_buf_fill = %zu;", - (double)timeout, - cb->send_buf_fill); - - /* timeout == 0 => flush unconditionally */ - if (timeout > 0) - { - cdtime_t now; - - now = cdtime(); - if ((cb->send_buf_init_time + timeout) > now) - return 0; - } +static int wt_flush_nolock(cdtime_t timeout, struct wt_callback *cb) { + int status; - if (cb->send_buf_fill == 0) - { - cb->send_buf_init_time = cdtime(); - return 0; - } + DEBUG("write_tsdb plugin: wt_flush_nolock: timeout = %.3f; " + "send_buf_fill = %zu;", + (double)timeout, cb->send_buf_fill); + + /* timeout == 0 => flush unconditionally */ + if (timeout > 0) { + cdtime_t now; + + now = cdtime(); + if ((cb->send_buf_init_time + timeout) > now) + return 0; + } + + if (cb->send_buf_fill == 0) { + cb->send_buf_init_time = cdtime(); + return 0; + } - status = wt_send_buffer(cb); - wt_reset_buffer(cb); + status = wt_send_buffer(cb); + wt_reset_buffer(cb); - return status; + return status; } -static int wt_callback_init(struct wt_callback *cb) -{ - struct addrinfo *ai_list; - int status; - - const char *node = cb->node ? cb->node : WT_DEFAULT_NODE; - const char *service = cb->service ? cb->service : WT_DEFAULT_SERVICE; - - if (cb->sock_fd > 0) - return 0; - - struct addrinfo ai_hints = { - .ai_family = AF_UNSPEC, - .ai_flags = AI_ADDRCONFIG, - .ai_socktype = SOCK_STREAM - }; - - status = getaddrinfo(node, service, &ai_hints, &ai_list); - if (status != 0) - { - ERROR("write_tsdb plugin: getaddrinfo (%s, %s) failed: %s", - node, service, gai_strerror (status)); - return -1; - } +static int wt_callback_init(struct wt_callback *cb) { + struct addrinfo *ai_list; + int status; - assert (ai_list != NULL); - for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) - { - cb->sock_fd = socket(ai_ptr->ai_family, ai_ptr->ai_socktype, - ai_ptr->ai_protocol); - if (cb->sock_fd < 0) - continue; - - set_sock_opts(cb->sock_fd); - - status = connect(cb->sock_fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); - if (status != 0) - { - close(cb->sock_fd); - cb->sock_fd = -1; - continue; - } - - break; - } + const char *node = cb->node ? cb->node : WT_DEFAULT_NODE; + const char *service = cb->service ? cb->service : WT_DEFAULT_SERVICE; - freeaddrinfo(ai_list); + if (cb->sock_fd > 0) + return 0; + struct addrinfo ai_hints = {.ai_family = AF_UNSPEC, + .ai_flags = AI_ADDRCONFIG, + .ai_socktype = SOCK_STREAM}; + + status = getaddrinfo(node, service, &ai_hints, &ai_list); + if (status != 0) { + ERROR("write_tsdb plugin: getaddrinfo (%s, %s) failed: %s", node, service, + gai_strerror(status)); + return -1; + } + + assert(ai_list != NULL); + for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; + ai_ptr = ai_ptr->ai_next) { + cb->sock_fd = + socket(ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); if (cb->sock_fd < 0) - { - char errbuf[1024]; - ERROR("write_tsdb plugin: Connecting to %s:%s failed. " - "The last error was: %s", node, service, - sstrerror (errno, errbuf, sizeof(errbuf))); - return -1; + continue; + + set_sock_opts(cb->sock_fd); + + status = connect(cb->sock_fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); + if (status != 0) { + close(cb->sock_fd); + cb->sock_fd = -1; + continue; } - wt_reset_buffer(cb); + break; + } - return 0; + freeaddrinfo(ai_list); + + if (cb->sock_fd < 0) { + char errbuf[1024]; + ERROR("write_tsdb plugin: Connecting to %s:%s failed. " + "The last error was: %s", + node, service, sstrerror(errno, errbuf, sizeof(errbuf))); + return -1; + } + + wt_reset_buffer(cb); + + return 0; } -static void wt_callback_free(void *data) -{ - struct wt_callback *cb; +static void wt_callback_free(void *data) { + struct wt_callback *cb; - if (data == NULL) - return; + if (data == NULL) + return; - cb = data; + cb = data; - pthread_mutex_lock(&cb->send_lock); + pthread_mutex_lock(&cb->send_lock); - wt_flush_nolock(0, cb); + wt_flush_nolock(0, cb); - close(cb->sock_fd); - cb->sock_fd = -1; + close(cb->sock_fd); + cb->sock_fd = -1; - sfree(cb->node); - sfree(cb->service); - sfree(cb->host_tags); + sfree(cb->node); + sfree(cb->service); + sfree(cb->host_tags); - pthread_mutex_destroy(&cb->send_lock); + pthread_mutex_destroy(&cb->send_lock); - sfree(cb); + sfree(cb); } static int wt_flush(cdtime_t timeout, const char *identifier __attribute__((unused)), - user_data_t *user_data) -{ - struct wt_callback *cb; - int status; + user_data_t *user_data) { + struct wt_callback *cb; + int status; - if (user_data == NULL) - return -EINVAL; + if (user_data == NULL) + return -EINVAL; - cb = user_data->data; + cb = user_data->data; - pthread_mutex_lock(&cb->send_lock); + pthread_mutex_lock(&cb->send_lock); - if (cb->sock_fd < 0) - { - status = wt_callback_init(cb); - if (status != 0) - { - ERROR("write_tsdb plugin: wt_callback_init failed."); - pthread_mutex_unlock(&cb->send_lock); - return -1; - } + if (cb->sock_fd < 0) { + status = wt_callback_init(cb); + if (status != 0) { + ERROR("write_tsdb plugin: wt_callback_init failed."); + pthread_mutex_unlock(&cb->send_lock); + return -1; } + } - status = wt_flush_nolock(timeout, cb); - pthread_mutex_unlock(&cb->send_lock); + status = wt_flush_nolock(timeout, cb); + pthread_mutex_unlock(&cb->send_lock); - return status; + return status; } -static int wt_format_values(char *ret, size_t ret_len, - int ds_num, const data_set_t *ds, - const value_list_t *vl, - _Bool store_rates) -{ - size_t offset = 0; - int status; - 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) - - if (ds->ds[ds_num].type == DS_TYPE_GAUGE) - BUFFER_ADD(GAUGE_FORMAT, vl->values[ds_num].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(GAUGE_FORMAT, rates[ds_num]); - } - else if (ds->ds[ds_num].type == DS_TYPE_COUNTER) - BUFFER_ADD("%llu", vl->values[ds_num].counter); - else if (ds->ds[ds_num].type == DS_TYPE_DERIVE) - BUFFER_ADD("%" PRIi64, vl->values[ds_num].derive); - else if (ds->ds[ds_num].type == DS_TYPE_ABSOLUTE) - BUFFER_ADD("%" PRIu64, vl->values[ds_num].absolute); - else - { - ERROR("format_values plugin: Unknown data source type: %i", - ds->ds[ds_num].type); - sfree(rates); - return -1; +static int wt_format_values(char *ret, size_t ret_len, int ds_num, + const data_set_t *ds, const value_list_t *vl, + _Bool store_rates) { + size_t offset = 0; + int status; + 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) + + if (ds->ds[ds_num].type == DS_TYPE_GAUGE) + BUFFER_ADD(GAUGE_FORMAT, vl->values[ds_num].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(GAUGE_FORMAT, rates[ds_num]); + } else if (ds->ds[ds_num].type == DS_TYPE_COUNTER) + BUFFER_ADD("%llu", vl->values[ds_num].counter); + else if (ds->ds[ds_num].type == DS_TYPE_DERIVE) + BUFFER_ADD("%" PRIi64, vl->values[ds_num].derive); + else if (ds->ds[ds_num].type == DS_TYPE_ABSOLUTE) + BUFFER_ADD("%" PRIu64, vl->values[ds_num].absolute); + else { + ERROR("format_values plugin: Unknown data source type: %i", + ds->ds[ds_num].type); + sfree(rates); + return -1; + } #undef BUFFER_ADD - sfree(rates); - return 0; + sfree(rates); + return 0; } -static int wt_format_name(char *ret, int ret_len, - const value_list_t *vl, - const struct wt_callback *cb, - const char *ds_name) -{ - int status; - char *temp = NULL; - const char *prefix = ""; - const char *meta_prefix = "tsdb_prefix"; - - if (vl->meta) { - status = meta_data_get_string(vl->meta, meta_prefix, &temp); - if (status == -ENOENT) { - /* defaults to empty string */ - } else if (status < 0) { - sfree(temp); - return status; - } else { - prefix = temp; - } +static int wt_format_name(char *ret, int ret_len, const value_list_t *vl, + const struct wt_callback *cb, const char *ds_name) { + int status; + char *temp = NULL; + const char *prefix = ""; + const char *meta_prefix = "tsdb_prefix"; + + if (vl->meta) { + status = meta_data_get_string(vl->meta, meta_prefix, &temp); + if (status == -ENOENT) { + /* defaults to empty string */ + } else if (status < 0) { + sfree(temp); + return status; + } else { + prefix = temp; } - - if (ds_name != NULL) { - if (vl->plugin_instance[0] == '\0') { - if (vl->type_instance[0] == '\0') { - ssnprintf(ret, ret_len, "%s%s.%s.%s", prefix, vl->plugin, - vl->type, ds_name); - } else { - ssnprintf(ret, ret_len, "%s%s.%s.%s.%s", prefix, vl->plugin, - vl->type, vl->type_instance, ds_name); - } - } else { /* vl->plugin_instance != "" */ - if (vl->type_instance[0] == '\0') { - ssnprintf(ret, ret_len, "%s%s.%s.%s.%s", prefix, vl->plugin, - vl->plugin_instance, vl->type, ds_name); - } else { - ssnprintf(ret, ret_len, "%s%s.%s.%s.%s.%s", prefix, - vl->plugin, vl->plugin_instance, vl->type, - vl->type_instance, ds_name); - } - } - } else { /* ds_name == NULL */ - if (vl->plugin_instance[0] == '\0') { - if (vl->type_instance[0] == '\0') { - ssnprintf(ret, ret_len, "%s%s.%s", prefix, vl->plugin, - vl->type); - } else { - ssnprintf(ret, ret_len, "%s%s.%s.%s", prefix, vl->plugin, - vl->type_instance, vl->type); - } - } else { /* vl->plugin_instance != "" */ - if (vl->type_instance[0] == '\0') { - ssnprintf(ret, ret_len, "%s%s.%s.%s", prefix, vl->plugin, - vl->plugin_instance, vl->type); - } else { - ssnprintf(ret, ret_len, "%s%s.%s.%s.%s", prefix, vl->plugin, - vl->plugin_instance, vl->type, vl->type_instance); - } - } + } + + if (ds_name != NULL) { + if (vl->plugin_instance[0] == '\0') { + if (vl->type_instance[0] == '\0') { + ssnprintf(ret, ret_len, "%s%s.%s.%s", prefix, vl->plugin, vl->type, + ds_name); + } else { + ssnprintf(ret, ret_len, "%s%s.%s.%s.%s", prefix, vl->plugin, vl->type, + vl->type_instance, ds_name); + } + } else { /* vl->plugin_instance != "" */ + if (vl->type_instance[0] == '\0') { + ssnprintf(ret, ret_len, "%s%s.%s.%s.%s", prefix, vl->plugin, + vl->plugin_instance, vl->type, ds_name); + } else { + ssnprintf(ret, ret_len, "%s%s.%s.%s.%s.%s", prefix, vl->plugin, + vl->plugin_instance, vl->type, vl->type_instance, ds_name); + } } + } else { /* ds_name == NULL */ + if (vl->plugin_instance[0] == '\0') { + if (vl->type_instance[0] == '\0') { + ssnprintf(ret, ret_len, "%s%s.%s", prefix, vl->plugin, vl->type); + } else { + ssnprintf(ret, ret_len, "%s%s.%s.%s", prefix, vl->plugin, + vl->type_instance, vl->type); + } + } else { /* vl->plugin_instance != "" */ + if (vl->type_instance[0] == '\0') { + ssnprintf(ret, ret_len, "%s%s.%s.%s", prefix, vl->plugin, + vl->plugin_instance, vl->type); + } else { + ssnprintf(ret, ret_len, "%s%s.%s.%s.%s", prefix, vl->plugin, + vl->plugin_instance, vl->type, vl->type_instance); + } + } + } - sfree(temp); - return 0; + sfree(temp); + return 0; } -static int wt_send_message (const char* key, const char* value, - cdtime_t time, struct wt_callback *cb, - const char* host, meta_data_t *md) -{ - int status; - size_t message_len; - char *temp = NULL; - const char *tags = ""; - char message[1024]; - const char *host_tags = cb->host_tags ? cb->host_tags : ""; - const char *meta_tsdb = "tsdb_tags"; - - /* skip if value is NaN */ - if (value[0] == 'n') - return 0; - - if (md) { - status = meta_data_get_string(md, meta_tsdb, &temp); - if (status == -ENOENT) { - /* defaults to empty string */ - } else if (status < 0) { - ERROR("write_tsdb plugin: tags metadata get failure"); - sfree(temp); - pthread_mutex_unlock(&cb->send_lock); - return status; - } else { - tags = temp; - } - } +static int wt_send_message(const char *key, const char *value, cdtime_t time, + struct wt_callback *cb, const char *host, + meta_data_t *md) { + int status; + size_t message_len; + char *temp = NULL; + const char *tags = ""; + char message[1024]; + const char *host_tags = cb->host_tags ? cb->host_tags : ""; + const char *meta_tsdb = "tsdb_tags"; + + /* skip if value is NaN */ + if (value[0] == 'n') + return 0; - status = ssnprintf (message, - sizeof(message), - "put %s %.0f %s fqdn=%s %s %s\r\n", - key, - CDTIME_T_TO_DOUBLE(time), - value, - host, - tags, - host_tags); - sfree(temp); - if (status < 0) - return -1; - message_len = (size_t) status; - - if (message_len >= sizeof(message)) { - ERROR("write_tsdb plugin: message buffer too small: " - "Need %zu bytes.", message_len + 1); - return -1; + if (md) { + status = meta_data_get_string(md, meta_tsdb, &temp); + if (status == -ENOENT) { + /* defaults to empty string */ + } else if (status < 0) { + ERROR("write_tsdb plugin: tags metadata get failure"); + sfree(temp); + pthread_mutex_unlock(&cb->send_lock); + return status; + } else { + tags = temp; } - - pthread_mutex_lock(&cb->send_lock); - - if (cb->sock_fd < 0) - { - status = wt_callback_init(cb); - if (status != 0) - { - ERROR("write_tsdb plugin: wt_callback_init failed."); - pthread_mutex_unlock(&cb->send_lock); - return -1; - } + } + + status = + ssnprintf(message, sizeof(message), "put %s %.0f %s fqdn=%s %s %s\r\n", + key, CDTIME_T_TO_DOUBLE(time), value, host, tags, host_tags); + sfree(temp); + if (status < 0) + return -1; + message_len = (size_t)status; + + if (message_len >= sizeof(message)) { + ERROR("write_tsdb plugin: message buffer too small: " + "Need %zu bytes.", + message_len + 1); + return -1; + } + + pthread_mutex_lock(&cb->send_lock); + + if (cb->sock_fd < 0) { + status = wt_callback_init(cb); + if (status != 0) { + ERROR("write_tsdb plugin: wt_callback_init failed."); + pthread_mutex_unlock(&cb->send_lock); + return -1; } + } - if (message_len >= cb->send_buf_free) - { - status = wt_flush_nolock(0, cb); - if (status != 0) - { - pthread_mutex_unlock(&cb->send_lock); - return status; - } + if (message_len >= cb->send_buf_free) { + status = wt_flush_nolock(0, cb); + if (status != 0) { + pthread_mutex_unlock(&cb->send_lock); + return status; } + } - /* Assert that we have enough space for this message. */ - assert(message_len < cb->send_buf_free); + /* Assert that we have enough space for this message. */ + assert(message_len < cb->send_buf_free); - /* `message_len + 1' because `message_len' does not include the - * trailing null byte. Neither does `send_buffer_fill'. */ - memcpy(cb->send_buf + cb->send_buf_fill, - message, message_len + 1); - cb->send_buf_fill += message_len; - cb->send_buf_free -= message_len; + /* `message_len + 1' because `message_len' does not include the + * trailing null byte. Neither does `send_buffer_fill'. */ + memcpy(cb->send_buf + cb->send_buf_fill, message, message_len + 1); + cb->send_buf_fill += message_len; + cb->send_buf_free -= message_len; - DEBUG("write_tsdb plugin: [%s]:%s buf %zu/%zu (%.1f %%) \"%s\"", - cb->node, - cb->service, - cb->send_buf_fill, sizeof(cb->send_buf), - 100.0 * ((double) cb->send_buf_fill) / - ((double) sizeof(cb->send_buf)), - message); + DEBUG("write_tsdb plugin: [%s]:%s buf %zu/%zu (%.1f %%) \"%s\"", cb->node, + cb->service, cb->send_buf_fill, sizeof(cb->send_buf), + 100.0 * ((double)cb->send_buf_fill) / ((double)sizeof(cb->send_buf)), + message); - pthread_mutex_unlock(&cb->send_lock); + pthread_mutex_unlock(&cb->send_lock); - return 0; + return 0; } static int wt_write_messages(const data_set_t *ds, const value_list_t *vl, - struct wt_callback *cb) -{ - char key[10*DATA_MAX_NAME_LEN]; - char values[512]; - - int status; - - if (0 != strcmp(ds->type, vl->type)) - { - ERROR("write_tsdb plugin: DS type does not match " - "value list type"); - return -1; + struct wt_callback *cb) { + char key[10 * DATA_MAX_NAME_LEN]; + char values[512]; + + int status; + + if (0 != strcmp(ds->type, vl->type)) { + ERROR("write_tsdb plugin: DS type does not match " + "value list type"); + return -1; + } + + for (size_t i = 0; i < ds->ds_num; i++) { + const char *ds_name = NULL; + + if (cb->always_append_ds || (ds->ds_num > 1)) + ds_name = ds->ds[i].name; + + /* Copy the identifier to 'key' and escape it. */ + status = wt_format_name(key, sizeof(key), vl, cb, ds_name); + if (status != 0) { + ERROR("write_tsdb plugin: error with format_name"); + return status; } - for (size_t i = 0; i < ds->ds_num; i++) - { - const char *ds_name = NULL; - - if (cb->always_append_ds || (ds->ds_num > 1)) - ds_name = ds->ds[i].name; - - /* Copy the identifier to 'key' and escape it. */ - status = wt_format_name(key, sizeof(key), vl, cb, ds_name); - if (status != 0) - { - ERROR("write_tsdb plugin: error with format_name"); - return status; - } - - escape_string(key, sizeof(key)); - /* Convert the values to an ASCII representation and put that into - * 'values'. */ - status = wt_format_values(values, sizeof(values), i, ds, vl, - cb->store_rates); - if (status != 0) - { - ERROR("write_tsdb plugin: error with " - "wt_format_values"); - return status; - } - - /* Send the message to tsdb */ - status = wt_send_message(key, values, vl->time, cb, vl->host, vl->meta); - if (status != 0) - { - ERROR("write_tsdb plugin: error with " - "wt_send_message"); - return status; - } + escape_string(key, sizeof(key)); + /* Convert the values to an ASCII representation and put that into + * 'values'. */ + status = + wt_format_values(values, sizeof(values), i, ds, vl, cb->store_rates); + if (status != 0) { + ERROR("write_tsdb plugin: error with " + "wt_format_values"); + return status; } - return 0; + /* Send the message to tsdb */ + status = wt_send_message(key, values, vl->time, cb, vl->host, vl->meta); + if (status != 0) { + ERROR("write_tsdb plugin: error with " + "wt_send_message"); + return status; + } + } + + return 0; } static int wt_write(const data_set_t *ds, const value_list_t *vl, - user_data_t *user_data) -{ - struct wt_callback *cb; - int status; + user_data_t *user_data) { + struct wt_callback *cb; + int status; - if (user_data == NULL) - return EINVAL; + if (user_data == NULL) + return EINVAL; - cb = user_data->data; + cb = user_data->data; - status = wt_write_messages(ds, vl, cb); + status = wt_write_messages(ds, vl, cb); - return status; + return status; } -static int wt_config_tsd(oconfig_item_t *ci) -{ - struct wt_callback *cb; - char callback_name[DATA_MAX_NAME_LEN]; - - cb = calloc(1, sizeof(*cb)); - if (cb == NULL) - { - ERROR("write_tsdb plugin: calloc failed."); - return -1; - } - cb->sock_fd = -1; - cb->node = NULL; - cb->service = NULL; - cb->host_tags = NULL; - cb->store_rates = 0; - - pthread_mutex_init (&cb->send_lock, NULL); - - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp("Host", child->key) == 0) - cf_util_get_string(child, &cb->node); - else if (strcasecmp("Port", child->key) == 0) - cf_util_get_service(child, &cb->service); - else if (strcasecmp("HostTags", child->key) == 0) - cf_util_get_string(child, &cb->host_tags); - else if (strcasecmp("StoreRates", child->key) == 0) - cf_util_get_boolean(child, &cb->store_rates); - else if (strcasecmp("AlwaysAppendDS", child->key) == 0) - cf_util_get_boolean(child, &cb->always_append_ds); - else - { - ERROR("write_tsdb plugin: Invalid configuration " - "option: %s.", child->key); - } +static int wt_config_tsd(oconfig_item_t *ci) { + struct wt_callback *cb; + char callback_name[DATA_MAX_NAME_LEN]; + + cb = calloc(1, sizeof(*cb)); + if (cb == NULL) { + ERROR("write_tsdb plugin: calloc failed."); + return -1; + } + cb->sock_fd = -1; + cb->node = NULL; + cb->service = NULL; + cb->host_tags = NULL; + cb->store_rates = 0; + + pthread_mutex_init(&cb->send_lock, NULL); + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Host", child->key) == 0) + cf_util_get_string(child, &cb->node); + else if (strcasecmp("Port", child->key) == 0) + cf_util_get_service(child, &cb->service); + else if (strcasecmp("HostTags", child->key) == 0) + cf_util_get_string(child, &cb->host_tags); + else if (strcasecmp("StoreRates", child->key) == 0) + cf_util_get_boolean(child, &cb->store_rates); + else if (strcasecmp("AlwaysAppendDS", child->key) == 0) + cf_util_get_boolean(child, &cb->always_append_ds); + else { + ERROR("write_tsdb plugin: Invalid configuration " + "option: %s.", + child->key); } + } - ssnprintf(callback_name, sizeof(callback_name), "write_tsdb/%s/%s", - cb->node != NULL ? cb->node : WT_DEFAULT_NODE, - cb->service != NULL ? cb->service : WT_DEFAULT_SERVICE); + ssnprintf(callback_name, sizeof(callback_name), "write_tsdb/%s/%s", + cb->node != NULL ? cb->node : WT_DEFAULT_NODE, + cb->service != NULL ? cb->service : WT_DEFAULT_SERVICE); - user_data_t user_data = { - .data = cb, - .free_func = wt_callback_free - }; + user_data_t user_data = {.data = cb, .free_func = wt_callback_free}; - plugin_register_write(callback_name, wt_write, &user_data); + plugin_register_write(callback_name, wt_write, &user_data); - user_data.free_func = NULL; - plugin_register_flush(callback_name, wt_flush, &user_data); + user_data.free_func = NULL; + plugin_register_flush(callback_name, wt_flush, &user_data); - return 0; + return 0; } -static int wt_config(oconfig_item_t *ci) -{ - for (int i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp("Node", child->key) == 0) - wt_config_tsd(child); - else - { - ERROR("write_tsdb plugin: Invalid configuration " - "option: %s.", child->key); - } +static int wt_config(oconfig_item_t *ci) { + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Node", child->key) == 0) + wt_config_tsd(child); + else { + ERROR("write_tsdb plugin: Invalid configuration " + "option: %s.", + child->key); } + } - return 0; + return 0; } -void module_register(void) -{ - plugin_register_complex_config("write_tsdb", wt_config); +void module_register(void) { + plugin_register_complex_config("write_tsdb", wt_config); } /* vim: set sw=4 ts=4 sts=4 tw=78 et : */ diff --git a/src/xencpu.c b/src/xencpu.c index de375d26..01904b28 100644 --- a/src/xencpu.c +++ b/src/xencpu.c @@ -28,13 +28,13 @@ #ifdef XENCTRL_HAS_XC_INTERFACE -//Xen-4.1+ -#define XC_INTERFACE_INIT_ARGS NULL,NULL,0 +// Xen-4.1+ +#define XC_INTERFACE_INIT_ARGS NULL, NULL, 0 xc_interface *xc_handle; #else /* XENCTRL_HAS_XC_INTERFACE */ -//For xen-3.4/xen-4.0 +// For xen-3.4/xen-4.0 #include #define xc_strerror(xc_interface, errcode) strerror(errcode) #define XC_INTERFACE_INIT_ARGS @@ -47,115 +47,104 @@ uint32_t num_cpus = 0; xc_cpuinfo_t *cpu_info; static value_to_rate_state_t *cpu_states; -static int xencpu_init (void) -{ - xc_handle = xc_interface_open(XC_INTERFACE_INIT_ARGS); - if (!xc_handle) - { - ERROR ("xencpu: xc_interface_open() failed"); - return (-1); - } - - xc_physinfo_t *physinfo; +static int xencpu_init(void) { + xc_handle = xc_interface_open(XC_INTERFACE_INIT_ARGS); + if (!xc_handle) { + ERROR("xencpu: xc_interface_open() failed"); + return (-1); + } - physinfo = calloc(1, sizeof(xc_physinfo_t)); - if (physinfo == NULL) - { - ERROR ("xencpu plugin: calloc() for physinfo failed."); - xc_interface_close(xc_handle); - return (ENOMEM); - } + xc_physinfo_t *physinfo; - if (xc_physinfo(xc_handle, physinfo) < 0) - { - ERROR ("xencpu plugin: xc_physinfo() failed"); - xc_interface_close(xc_handle); - free(physinfo); - return (-1); - } + physinfo = calloc(1, sizeof(xc_physinfo_t)); + if (physinfo == NULL) { + ERROR("xencpu plugin: calloc() for physinfo failed."); + xc_interface_close(xc_handle); + return (ENOMEM); + } - num_cpus = physinfo->nr_cpus; + if (xc_physinfo(xc_handle, physinfo) < 0) { + ERROR("xencpu plugin: xc_physinfo() failed"); + xc_interface_close(xc_handle); free(physinfo); + return (-1); + } - INFO ("xencpu plugin: Found %"PRIu32" processors.", num_cpus); + num_cpus = physinfo->nr_cpus; + free(physinfo); - cpu_info = calloc(num_cpus, sizeof(xc_cpuinfo_t)); - if (cpu_info == NULL) - { - ERROR ("xencpu plugin: calloc() for num_cpus failed."); - xc_interface_close(xc_handle); - return (ENOMEM); - } + INFO("xencpu plugin: Found %" PRIu32 " processors.", num_cpus); - cpu_states = calloc (num_cpus, sizeof (value_to_rate_state_t)); - if (cpu_states == NULL) - { - ERROR ("xencpu plugin: calloc() for cpu_states failed."); - xc_interface_close(xc_handle); - free(cpu_info); - return (ENOMEM); - } + cpu_info = calloc(num_cpus, sizeof(xc_cpuinfo_t)); + if (cpu_info == NULL) { + ERROR("xencpu plugin: calloc() for num_cpus failed."); + xc_interface_close(xc_handle); + return (ENOMEM); + } + + cpu_states = calloc(num_cpus, sizeof(value_to_rate_state_t)); + if (cpu_states == NULL) { + ERROR("xencpu plugin: calloc() for cpu_states failed."); + xc_interface_close(xc_handle); + free(cpu_info); + return (ENOMEM); + } - return (0); + return (0); } /* static int xencpu_init */ -static int xencpu_shutdown (void) -{ - free(cpu_states); - free(cpu_info); - xc_interface_close(xc_handle); +static int xencpu_shutdown(void) { + free(cpu_states); + free(cpu_info); + xc_interface_close(xc_handle); - return 0; + return 0; } /* static int xencpu_shutdown */ -static void submit_value (int cpu_num, gauge_t value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void submit_value(int cpu_num, gauge_t value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; - sstrncpy (vl.plugin, "xencpu", sizeof (vl.plugin)); - sstrncpy (vl.type, "percent", sizeof (vl.type)); - sstrncpy (vl.type_instance, "load", sizeof (vl.type_instance)); + sstrncpy(vl.plugin, "xencpu", sizeof(vl.plugin)); + sstrncpy(vl.type, "percent", sizeof(vl.type)); + sstrncpy(vl.type_instance, "load", sizeof(vl.type_instance)); - if (cpu_num >= 0) { - ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), - "%i", cpu_num); - } - plugin_dispatch_values (&vl); + if (cpu_num >= 0) { + ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", cpu_num); + } + plugin_dispatch_values(&vl); } /* static void submit_value */ -static int xencpu_read (void) -{ - cdtime_t now = cdtime (); +static int xencpu_read(void) { + cdtime_t now = cdtime(); - int rc, nr_cpus; + int rc, nr_cpus; - rc = xc_getcpuinfo(xc_handle, num_cpus, cpu_info, &nr_cpus); - if (rc < 0) { - ERROR ("xencpu: xc_getcpuinfo() Failed: %d %s\n", rc, xc_strerror(xc_handle,errno)); - return (-1); - } + rc = xc_getcpuinfo(xc_handle, num_cpus, cpu_info, &nr_cpus); + if (rc < 0) { + ERROR("xencpu: xc_getcpuinfo() Failed: %d %s\n", rc, + xc_strerror(xc_handle, errno)); + return (-1); + } - int status; - for (int cpu = 0; cpu < nr_cpus; cpu++) { - gauge_t rate = NAN; + int status; + for (int cpu = 0; cpu < nr_cpus; cpu++) { + gauge_t rate = NAN; - status = value_to_rate (&rate, - (value_t) { .derive = cpu_info[cpu].idletime }, DS_TYPE_DERIVE, - now, &cpu_states[cpu]); - if (status == 0) { - submit_value(cpu, 100 - rate/10000000); - } + status = value_to_rate(&rate, (value_t){.derive = cpu_info[cpu].idletime}, + DS_TYPE_DERIVE, now, &cpu_states[cpu]); + if (status == 0) { + submit_value(cpu, 100 - rate / 10000000); } + } - return (0); + return (0); } /* static int xencpu_read */ -void module_register (void) -{ - plugin_register_init ("xencpu", xencpu_init); - plugin_register_read ("xencpu", xencpu_read); - plugin_register_shutdown ("xencpu", xencpu_shutdown); +void module_register(void) { + plugin_register_init("xencpu", xencpu_init); + plugin_register_read("xencpu", xencpu_read); + plugin_register_shutdown("xencpu", xencpu_shutdown); } /* void module_register */ diff --git a/src/xmms.c b/src/xmms.c index 5a2774bb..87e3564f 100644 --- a/src/xmms.c +++ b/src/xmms.c @@ -26,48 +26,45 @@ #include "collectd.h" -#include "plugin.h" #include "common.h" +#include "plugin.h" #include static gint xmms_session; -static void cxmms_submit (const char *type, gauge_t value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void cxmms_submit(const char *type, gauge_t value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "xmms", sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof (vl.type)); + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "xmms", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* void cxmms_submit */ -static int cxmms_read (void) -{ +static int cxmms_read(void) { gint rate; gint freq; gint nch; - if (!xmms_remote_is_running (xmms_session)) + if (!xmms_remote_is_running(xmms_session)) return (0); - xmms_remote_get_info (xmms_session, &rate, &freq, &nch); + xmms_remote_get_info(xmms_session, &rate, &freq, &nch); if ((freq == 0) || (nch == 0)) return (-1); - cxmms_submit ("bitrate", rate); - cxmms_submit ("frequency", freq); + cxmms_submit("bitrate", rate); + cxmms_submit("frequency", freq); return (0); } /* int read */ -void module_register (void) -{ - plugin_register_read ("xmms", cxmms_read); +void module_register(void) { + plugin_register_read("xmms", cxmms_read); } /* void module_register */ /* diff --git a/src/zfs_arc.c b/src/zfs_arc.c index fd8188b4..af5130aa 100644 --- a/src/zfs_arc.c +++ b/src/zfs_arc.c @@ -40,79 +40,71 @@ #include "utils_llist.h" #define ZOL_ARCSTATS_FILE "/proc/spl/kstat/zfs/arcstats" -typedef llist_t kstat_t; +typedef llist_t kstat_t; -static int put_zfs_value (kstat_t *ksp, char const *k, value_t v) -{ - llentry_t *e; - char *k_copy; - value_t *v_copy; - - k_copy = strdup (k); - if (k_copy == NULL) - return ENOMEM; - - v_copy = malloc (sizeof (*v_copy)); - if (v_copy == NULL) - { - sfree (k_copy); - return ENOMEM; - } - *v_copy = v; - - e = llentry_create (k_copy, v_copy); - if (e == NULL) - { - sfree (v_copy); - sfree (k_copy); - return ENOMEM; - } - - llist_append (ksp, e); - return 0; +static int put_zfs_value(kstat_t *ksp, char const *k, value_t v) { + llentry_t *e; + char *k_copy; + value_t *v_copy; + + k_copy = strdup(k); + if (k_copy == NULL) + return ENOMEM; + + v_copy = malloc(sizeof(*v_copy)); + if (v_copy == NULL) { + sfree(k_copy); + return ENOMEM; + } + *v_copy = v; + + e = llentry_create(k_copy, v_copy); + if (e == NULL) { + sfree(v_copy); + sfree(k_copy); + return ENOMEM; + } + + llist_append(ksp, e); + return 0; } -static long long get_zfs_value(kstat_t *ksp, const char *key) -{ - llentry_t *e; - value_t *v; - - e = llist_search (ksp, key); - if (e == NULL) - { - ERROR ("zfs_arc plugin: `llist_search` failed for key: '%s'.", key); - return (-1); - } - - v = e->value; - return ((long long) v->derive); +static long long get_zfs_value(kstat_t *ksp, const char *key) { + llentry_t *e; + value_t *v; + + e = llist_search(ksp, key); + if (e == NULL) { + ERROR("zfs_arc plugin: `llist_search` failed for key: '%s'.", key); + return (-1); + } + + v = e->value; + return ((long long)v->derive); } -static void free_zfs_values (kstat_t *ksp) -{ - if (ksp == NULL) - return; +static void free_zfs_values(kstat_t *ksp) { + if (ksp == NULL) + return; - for (llentry_t *e = llist_head (ksp); e != NULL; e = e->next) - { - sfree (e->key); - sfree (e->value); - } + for (llentry_t *e = llist_head(ksp); e != NULL; e = e->next) { + sfree(e->key); + sfree(e->value); + } - llist_destroy (ksp); + llist_destroy(ksp); } #elif defined(KERNEL_SOLARIS) extern kstat_ctl_t *kc; -static long long get_zfs_value(kstat_t *ksp, char *name) -{ +static long long get_zfs_value(kstat_t *ksp, char *name) { - return (get_kstat_value(ksp, name)); + return (get_kstat_value(ksp, name)); } #elif defined(KERNEL_FREEBSD) -#include #include +#include const char zfs_arcstat[] = "kstat.zfs.misc.arcstats."; @@ -121,233 +113,230 @@ typedef void kstat_t; #endif static long long get_zfs_value(kstat_t *dummy __attribute__((unused)), - char const *name) -{ - char buffer[256]; - long long value; - size_t valuelen = sizeof(value); - int rv; - - ssnprintf (buffer, sizeof (buffer), "%s%s", zfs_arcstat, name); - rv = sysctlbyname (buffer, (void *) &value, &valuelen, - /* new value = */ NULL, /* new length = */ (size_t) 0); - if (rv == 0) - return (value); - - return (-1); + char const *name) { + char buffer[256]; + long long value; + size_t valuelen = sizeof(value); + int rv; + + ssnprintf(buffer, sizeof(buffer), "%s%s", zfs_arcstat, name); + rv = sysctlbyname(buffer, (void *)&value, &valuelen, + /* new value = */ NULL, /* new length = */ (size_t)0); + if (rv == 0) + return (value); + + return (-1); } #endif -static void za_submit (const char* type, const char* type_instance, value_t* values, size_t values_len) -{ - value_list_t vl = VALUE_LIST_INIT; +static void za_submit(const char *type, const char *type_instance, + value_t *values, size_t values_len) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = values; - vl.values_len = values_len; + vl.values = values; + vl.values_len = values_len; - sstrncpy (vl.plugin, "zfs_arc", sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + sstrncpy(vl.plugin, "zfs_arc", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static void za_submit_gauge (const char* type, const char* type_instance, gauge_t value) -{ - za_submit (type, type_instance, &(value_t) { .gauge = value }, 1); +static void za_submit_gauge(const char *type, const char *type_instance, + gauge_t value) { + za_submit(type, type_instance, &(value_t){.gauge = value}, 1); } -static int za_read_derive (kstat_t *ksp, const char *kstat_value, - const char *type, const char *type_instance) -{ - long long tmp = get_zfs_value (ksp, (char *)kstat_value); - if (tmp == -1LL) - { - WARNING ("zfs_arc plugin: Reading kstat value \"%s\" failed.", kstat_value); +static int za_read_derive(kstat_t *ksp, const char *kstat_value, + const char *type, const char *type_instance) { + long long tmp = get_zfs_value(ksp, (char *)kstat_value); + if (tmp == -1LL) { + WARNING("zfs_arc plugin: Reading kstat value \"%s\" failed.", kstat_value); return (-1); } - za_submit (type, type_instance, &(value_t) { .derive = (derive_t) tmp }, /* values_num = */ 1); + za_submit(type, type_instance, &(value_t){.derive = (derive_t)tmp}, + /* values_num = */ 1); return (0); } -static int za_read_gauge (kstat_t *ksp, const char *kstat_value, - const char *type, const char *type_instance) -{ - long long tmp = get_zfs_value (ksp, (char *)kstat_value); - if (tmp == -1LL) - { - WARNING ("zfs_arc plugin: Reading kstat value \"%s\" failed.", kstat_value); +static int za_read_gauge(kstat_t *ksp, const char *kstat_value, + const char *type, const char *type_instance) { + long long tmp = get_zfs_value(ksp, (char *)kstat_value); + if (tmp == -1LL) { + WARNING("zfs_arc plugin: Reading kstat value \"%s\" failed.", kstat_value); return (-1); } - za_submit (type, type_instance, &(value_t) { .gauge = (gauge_t) tmp }, /* values_num = */ 1); + za_submit(type, type_instance, &(value_t){.gauge = (gauge_t)tmp}, + /* values_num = */ 1); return (0); } -static void za_submit_ratio (const char* type_instance, gauge_t hits, gauge_t misses) -{ - gauge_t ratio = NAN; +static void za_submit_ratio(const char *type_instance, gauge_t hits, + gauge_t misses) { + gauge_t ratio = NAN; - if (!isfinite (hits) || (hits < 0.0)) - hits = 0.0; - if (!isfinite (misses) || (misses < 0.0)) - misses = 0.0; + if (!isfinite(hits) || (hits < 0.0)) + hits = 0.0; + if (!isfinite(misses) || (misses < 0.0)) + misses = 0.0; - if ((hits != 0.0) || (misses != 0.0)) - ratio = hits / (hits + misses); + if ((hits != 0.0) || (misses != 0.0)) + ratio = hits / (hits + misses); - za_submit_gauge ("cache_ratio", type_instance, ratio); + za_submit_gauge("cache_ratio", type_instance, ratio); } -static int za_read (void) -{ - gauge_t arc_hits, arc_misses, l2_hits, l2_misses; - kstat_t *ksp = NULL; +static int za_read(void) { + gauge_t arc_hits, arc_misses, l2_hits, l2_misses; + kstat_t *ksp = NULL; #if defined(KERNEL_LINUX) - FILE *fh; - char buffer[1024]; - - fh = fopen (ZOL_ARCSTATS_FILE, "r"); - if (fh == NULL) - { - char errbuf[1024]; - ERROR ("zfs_arc plugin: Opening \"%s\" failed: %s", ZOL_ARCSTATS_FILE, - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - ksp = llist_create (); - if (ksp == NULL) - { - ERROR ("zfs_arc plugin: `llist_create' failed."); - fclose (fh); - return (-1); - } - - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - char *fields[3]; - value_t v; - int status; - - status = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields)); - if (status != 3) - continue; - - status = parse_value (fields[2], &v, DS_TYPE_DERIVE); - if (status != 0) - continue; - - put_zfs_value (ksp, fields[0], v); - } - - fclose (fh); + FILE *fh; + char buffer[1024]; + + fh = fopen(ZOL_ARCSTATS_FILE, "r"); + if (fh == NULL) { + char errbuf[1024]; + ERROR("zfs_arc plugin: Opening \"%s\" failed: %s", ZOL_ARCSTATS_FILE, + sstrerror(errno, errbuf, sizeof(errbuf))); + return (-1); + } + + ksp = llist_create(); + if (ksp == NULL) { + ERROR("zfs_arc plugin: `llist_create' failed."); + fclose(fh); + return (-1); + } + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + char *fields[3]; + value_t v; + int status; + + status = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + if (status != 3) + continue; + + status = parse_value(fields[2], &v, DS_TYPE_DERIVE); + if (status != 0) + continue; + + put_zfs_value(ksp, fields[0], v); + } + + fclose(fh); #elif defined(KERNEL_SOLARIS) - get_kstat (&ksp, "zfs", 0, "arcstats"); - if (ksp == NULL) - { - ERROR ("zfs_arc plugin: Cannot find zfs:0:arcstats kstat."); - return (-1); - } + get_kstat(&ksp, "zfs", 0, "arcstats"); + if (ksp == NULL) { + ERROR("zfs_arc plugin: Cannot find zfs:0:arcstats kstat."); + return (-1); + } #endif - /* Sizes */ - za_read_gauge (ksp, "anon_size", "cache_size", "anon_size"); - za_read_gauge (ksp, "c", "cache_size", "c"); - za_read_gauge (ksp, "c_max", "cache_size", "c_max"); - za_read_gauge (ksp, "c_min", "cache_size", "c_min"); - za_read_gauge (ksp, "hdr_size", "cache_size", "hdr_size"); - za_read_gauge (ksp, "metadata_size", "cache_size", "metadata_size"); - za_read_gauge (ksp, "mfu_ghost_size", "cache_size", "mfu_ghost_size"); - za_read_gauge (ksp, "mfu_size", "cache_size", "mfu_size"); - za_read_gauge (ksp, "mru_ghost_size", "cache_size", "mru_ghost_size"); - za_read_gauge (ksp, "mru_size", "cache_size", "mru_size"); - za_read_gauge (ksp, "other_size", "cache_size", "other_size"); - za_read_gauge (ksp, "p", "cache_size", "p"); - za_read_gauge (ksp, "size", "cache_size", "arc"); - - /* The "l2_size" value has disappeared from Solaris some time in - * early 2013, and has only reappeared recently in Solaris 11.2. - * Stop trying if we ever fail to read it, so we don't spam the log. - */ - static int l2_size_avail = 1; - if (l2_size_avail && za_read_gauge (ksp, "l2_size", "cache_size", "L2") != 0) - l2_size_avail = 0; - - /* Operations */ - za_read_derive (ksp, "deleted", "cache_operation", "deleted"); + /* Sizes */ + za_read_gauge(ksp, "anon_size", "cache_size", "anon_size"); + za_read_gauge(ksp, "c", "cache_size", "c"); + za_read_gauge(ksp, "c_max", "cache_size", "c_max"); + za_read_gauge(ksp, "c_min", "cache_size", "c_min"); + za_read_gauge(ksp, "hdr_size", "cache_size", "hdr_size"); + za_read_gauge(ksp, "metadata_size", "cache_size", "metadata_size"); + za_read_gauge(ksp, "mfu_ghost_size", "cache_size", "mfu_ghost_size"); + za_read_gauge(ksp, "mfu_size", "cache_size", "mfu_size"); + za_read_gauge(ksp, "mru_ghost_size", "cache_size", "mru_ghost_size"); + za_read_gauge(ksp, "mru_size", "cache_size", "mru_size"); + za_read_gauge(ksp, "other_size", "cache_size", "other_size"); + za_read_gauge(ksp, "p", "cache_size", "p"); + za_read_gauge(ksp, "size", "cache_size", "arc"); + + /* The "l2_size" value has disappeared from Solaris some time in + * early 2013, and has only reappeared recently in Solaris 11.2. + * Stop trying if we ever fail to read it, so we don't spam the log. + */ + static int l2_size_avail = 1; + if (l2_size_avail && za_read_gauge(ksp, "l2_size", "cache_size", "L2") != 0) + l2_size_avail = 0; + + /* Operations */ + za_read_derive(ksp, "deleted", "cache_operation", "deleted"); #if defined(KERNEL_FREEBSD) - za_read_derive (ksp, "allocated","cache_operation", "allocated"); + za_read_derive(ksp, "allocated", "cache_operation", "allocated"); #endif - /* Issue indicators */ - za_read_derive (ksp, "mutex_miss", "mutex_operations", "miss"); - za_read_derive (ksp, "hash_collisions", "hash_collisions", ""); - za_read_derive (ksp, "memory_throttle_count", "memory_throttle_count", ""); - - /* Evictions */ - za_read_derive (ksp, "evict_l2_cached", "cache_eviction", "cached"); - za_read_derive (ksp, "evict_l2_eligible", "cache_eviction", "eligible"); - za_read_derive (ksp, "evict_l2_ineligible", "cache_eviction", "ineligible"); - - /* Hits / misses */ - za_read_derive (ksp, "demand_data_hits", "cache_result", "demand_data-hit"); - za_read_derive (ksp, "demand_metadata_hits", "cache_result", "demand_metadata-hit"); - za_read_derive (ksp, "prefetch_data_hits", "cache_result", "prefetch_data-hit"); - za_read_derive (ksp, "prefetch_metadata_hits", "cache_result", "prefetch_metadata-hit"); - za_read_derive (ksp, "demand_data_misses", "cache_result", "demand_data-miss"); - za_read_derive (ksp, "demand_metadata_misses", "cache_result", "demand_metadata-miss"); - za_read_derive (ksp, "prefetch_data_misses", "cache_result", "prefetch_data-miss"); - za_read_derive (ksp, "prefetch_metadata_misses", "cache_result", "prefetch_metadata-miss"); - za_read_derive (ksp, "mfu_hits", "cache_result", "mfu-hit"); - za_read_derive (ksp, "mfu_ghost_hits", "cache_result", "mfu_ghost-hit"); - za_read_derive (ksp, "mru_hits", "cache_result", "mru-hit"); - za_read_derive (ksp, "mru_ghost_hits", "cache_result", "mru_ghost-hit"); - - /* Ratios */ - arc_hits = (gauge_t) get_zfs_value(ksp, "hits"); - arc_misses = (gauge_t) get_zfs_value(ksp, "misses"); - l2_hits = (gauge_t) get_zfs_value(ksp, "l2_hits"); - l2_misses = (gauge_t) get_zfs_value(ksp, "l2_misses"); - - za_submit_ratio ("arc", arc_hits, arc_misses); - za_submit_ratio ("L2", l2_hits, l2_misses); - - /* I/O */ - value_t l2_io[] = { - { .derive = (derive_t) get_zfs_value(ksp, "l2_read_bytes") }, - { .derive = (derive_t) get_zfs_value(ksp, "l2_write_bytes") }, - }; - za_submit ("io_octets", "L2", l2_io, STATIC_ARRAY_SIZE (l2_io)); + /* Issue indicators */ + za_read_derive(ksp, "mutex_miss", "mutex_operations", "miss"); + za_read_derive(ksp, "hash_collisions", "hash_collisions", ""); + za_read_derive(ksp, "memory_throttle_count", "memory_throttle_count", ""); + + /* Evictions */ + za_read_derive(ksp, "evict_l2_cached", "cache_eviction", "cached"); + za_read_derive(ksp, "evict_l2_eligible", "cache_eviction", "eligible"); + za_read_derive(ksp, "evict_l2_ineligible", "cache_eviction", "ineligible"); + + /* Hits / misses */ + za_read_derive(ksp, "demand_data_hits", "cache_result", "demand_data-hit"); + za_read_derive(ksp, "demand_metadata_hits", "cache_result", + "demand_metadata-hit"); + za_read_derive(ksp, "prefetch_data_hits", "cache_result", + "prefetch_data-hit"); + za_read_derive(ksp, "prefetch_metadata_hits", "cache_result", + "prefetch_metadata-hit"); + za_read_derive(ksp, "demand_data_misses", "cache_result", "demand_data-miss"); + za_read_derive(ksp, "demand_metadata_misses", "cache_result", + "demand_metadata-miss"); + za_read_derive(ksp, "prefetch_data_misses", "cache_result", + "prefetch_data-miss"); + za_read_derive(ksp, "prefetch_metadata_misses", "cache_result", + "prefetch_metadata-miss"); + za_read_derive(ksp, "mfu_hits", "cache_result", "mfu-hit"); + za_read_derive(ksp, "mfu_ghost_hits", "cache_result", "mfu_ghost-hit"); + za_read_derive(ksp, "mru_hits", "cache_result", "mru-hit"); + za_read_derive(ksp, "mru_ghost_hits", "cache_result", "mru_ghost-hit"); + + /* Ratios */ + arc_hits = (gauge_t)get_zfs_value(ksp, "hits"); + arc_misses = (gauge_t)get_zfs_value(ksp, "misses"); + l2_hits = (gauge_t)get_zfs_value(ksp, "l2_hits"); + l2_misses = (gauge_t)get_zfs_value(ksp, "l2_misses"); + + za_submit_ratio("arc", arc_hits, arc_misses); + za_submit_ratio("L2", l2_hits, l2_misses); + + /* I/O */ + value_t l2_io[] = { + {.derive = (derive_t)get_zfs_value(ksp, "l2_read_bytes")}, + {.derive = (derive_t)get_zfs_value(ksp, "l2_write_bytes")}, + }; + za_submit("io_octets", "L2", l2_io, STATIC_ARRAY_SIZE(l2_io)); #if defined(KERNEL_LINUX) - free_zfs_values (ksp); + free_zfs_values(ksp); #endif - return (0); + return (0); } /* int za_read */ -static int za_init (void) /* {{{ */ +static int za_init(void) /* {{{ */ { #if defined(KERNEL_SOLARIS) - /* kstats chain already opened by update_kstat (using *kc), verify everything went fine. */ - if (kc == NULL) - { - ERROR ("zfs_arc plugin: kstat chain control structure not available."); - return (-1); - } + /* kstats chain already opened by update_kstat (using *kc), verify everything + * went fine. */ + if (kc == NULL) { + ERROR("zfs_arc plugin: kstat chain control structure not available."); + return (-1); + } #endif - return (0); + return (0); } /* }}} int za_init */ -void module_register (void) -{ - plugin_register_init ("zfs_arc", za_init); - plugin_register_read ("zfs_arc", za_read); +void module_register(void) { + plugin_register_init("zfs_arc", za_init); + plugin_register_read("zfs_arc", za_read); } /* void module_register */ /* vmi: set sw=8 noexpandtab fdm=marker : */ diff --git a/src/zone.c b/src/zone.c index bd51c55e..5b7bd00f 100644 --- a/src/zone.c +++ b/src/zone.c @@ -21,13 +21,14 @@ **/ #if HAVE_CONFIG_H -# include "config.h" -# undef HAVE_CONFIG_H +#include "config.h" +#undef HAVE_CONFIG_H #endif -/* avoid procfs.h error "Cannot use procfs in the large file compilation environment" */ +/* avoid procfs.h error "Cannot use procfs in the large file compilation + * environment" */ #if !defined(_LP64) && _FILE_OFFSET_BITS == 64 -# undef _FILE_OFFSET_BITS -# undef _LARGEFILE64_SOURCE +#undef _FILE_OFFSET_BITS +#undef _LARGEFILE64_SOURCE #endif #include "collectd.h" @@ -40,165 +41,151 @@ #include "utils_avltree.h" -#define MAX_PROCFS_PATH 40 -#define FRC2PCT(pp)(((float)(pp))/0x8000*100) +#define MAX_PROCFS_PATH 40 +#define FRC2PCT(pp) (((float)(pp)) / 0x8000 * 100) typedef struct zone_stats { - ushort_t pctcpu; - ushort_t pctmem; + ushort_t pctcpu; + ushort_t pctmem; } zone_stats_t; -static int -zone_compare(const void *a, const void *b) -{ - if (*(const zoneid_t *)a == *(const zoneid_t *)b) - return(0); - if (*(const zoneid_t *)a < *(const zoneid_t *)b) - return(-1); - return(1); +static int zone_compare(const void *a, const void *b) { + if (*(const zoneid_t *)a == *(const zoneid_t *)b) + return (0); + if (*(const zoneid_t *)a < *(const zoneid_t *)b) + return (-1); + return (1); } -static int -zone_read_procfile(char const *pidstr, char const *name, void *buf, size_t bufsize) -{ - int fd; - - char procfile[MAX_PROCFS_PATH]; - (void)snprintf(procfile, sizeof(procfile), "/proc/%s/%s", pidstr, name); - if ((fd = open(procfile, O_RDONLY)) == -1) { - return (1); - } - - if (sread(fd, buf, bufsize) != 0) { - char errbuf[1024]; - ERROR ("zone plugin: Reading \"%s\" failed: %s", procfile, - sstrerror (errno, errbuf, sizeof (errbuf))); - close(fd); - return (1); - } - - close(fd); - return (0); +static int zone_read_procfile(char const *pidstr, char const *name, void *buf, + size_t bufsize) { + int fd; + + char procfile[MAX_PROCFS_PATH]; + (void)snprintf(procfile, sizeof(procfile), "/proc/%s/%s", pidstr, name); + if ((fd = open(procfile, O_RDONLY)) == -1) { + return (1); + } + + if (sread(fd, buf, bufsize) != 0) { + char errbuf[1024]; + ERROR("zone plugin: Reading \"%s\" failed: %s", procfile, + sstrerror(errno, errbuf, sizeof(errbuf))); + close(fd); + return (1); + } + + close(fd); + return (0); } -static int -zone_submit_value(char *zone, gauge_t value) -{ - value_list_t vl = VALUE_LIST_INIT; - value_t values[1]; +static int zone_submit_value(char *zone, gauge_t value) { + value_list_t vl = VALUE_LIST_INIT; + value_t values[1]; - values[0].gauge = value; + values[0].gauge = value; - vl.values = values; - vl.values_len = 1; /*STATIC_ARRAY_SIZE (values);*/ - sstrncpy (vl.plugin, "zone", sizeof (vl.plugin)); - sstrncpy (vl.type, "percent", sizeof (vl.type)); - sstrncpy (vl.type_instance, zone, sizeof (vl.type_instance)); + vl.values = values; + vl.values_len = 1; /*STATIC_ARRAY_SIZE (values);*/ + sstrncpy(vl.plugin, "zone", sizeof(vl.plugin)); + sstrncpy(vl.type, "percent", sizeof(vl.type)); + sstrncpy(vl.type_instance, zone, sizeof(vl.type_instance)); - return(plugin_dispatch_values (&vl)); + return (plugin_dispatch_values(&vl)); } -static zone_stats_t * -zone_find_stats(c_avl_tree_t *tree, zoneid_t zoneid) -{ - zone_stats_t *ret = NULL; - zoneid_t *key = NULL; - - if (c_avl_get(tree, (void **)&zoneid, (void **)&ret)) { - if (!(ret = malloc(sizeof(*ret)))) { - WARNING("zone plugin: no memory"); - return(NULL); - } - if (!(key = malloc(sizeof(*key)))) { - WARNING("zone plugin: no memory"); - free(ret); - return(NULL); - } - *key = zoneid; - if (c_avl_insert(tree, key, ret)) { - WARNING("zone plugin: error inserting into tree"); - return(NULL); - } - } - return(ret); +static zone_stats_t *zone_find_stats(c_avl_tree_t *tree, zoneid_t zoneid) { + zone_stats_t *ret = NULL; + zoneid_t *key = NULL; + + if (c_avl_get(tree, (void **)&zoneid, (void **)&ret)) { + if (!(ret = malloc(sizeof(*ret)))) { + WARNING("zone plugin: no memory"); + return (NULL); + } + if (!(key = malloc(sizeof(*key)))) { + WARNING("zone plugin: no memory"); + free(ret); + return (NULL); + } + *key = zoneid; + if (c_avl_insert(tree, key, ret)) { + WARNING("zone plugin: error inserting into tree"); + return (NULL); + } + } + return (ret); } -static void -zone_submit_values(c_avl_tree_t *tree) -{ - char zonename[ZONENAME_MAX]; - zoneid_t *zoneid = NULL; - zone_stats_t *stats = NULL; - - while (c_avl_pick (tree, (void **)&zoneid, (void **)&stats) == 0) - { - if (getzonenamebyid(*zoneid, zonename, sizeof( zonename )) == -1) { - WARNING("zone plugin: error retrieving zonename"); - } else { - zone_submit_value(zonename, (gauge_t)FRC2PCT(stats->pctcpu)); - } - free(stats); - free(zoneid); - } - c_avl_destroy(tree); +static void zone_submit_values(c_avl_tree_t *tree) { + char zonename[ZONENAME_MAX]; + zoneid_t *zoneid = NULL; + zone_stats_t *stats = NULL; + + while (c_avl_pick(tree, (void **)&zoneid, (void **)&stats) == 0) { + if (getzonenamebyid(*zoneid, zonename, sizeof(zonename)) == -1) { + WARNING("zone plugin: error retrieving zonename"); + } else { + zone_submit_value(zonename, (gauge_t)FRC2PCT(stats->pctcpu)); + } + free(stats); + free(zoneid); + } + c_avl_destroy(tree); } -static c_avl_tree_t * -zone_scandir(DIR *procdir) -{ - pid_t pid; - dirent_t *direntp; - psinfo_t psinfo; - c_avl_tree_t *tree; - zone_stats_t *stats; - - if (!(tree=c_avl_create(zone_compare))) { - WARNING("zone plugin: Failed to create tree"); - return(NULL); - } - - rewinddir(procdir); - while ((direntp = readdir(procdir))) { - char const *pidstr = direntp->d_name; - if (pidstr[0] == '.') /* skip "." and ".." */ - continue; - - pid = atoi(pidstr); - if (pid == 0 || pid == 2 || pid == 3) - continue; /* skip sched, pageout and fsflush */ - - if (zone_read_procfile(pidstr, "psinfo", &psinfo, sizeof(psinfo_t)) != 0) - continue; - - stats = zone_find_stats(tree, psinfo.pr_zoneid); - if( stats ) { - stats->pctcpu += psinfo.pr_pctcpu; - stats->pctmem += psinfo.pr_pctmem; - } - } - return(tree); +static c_avl_tree_t *zone_scandir(DIR *procdir) { + pid_t pid; + dirent_t *direntp; + psinfo_t psinfo; + c_avl_tree_t *tree; + zone_stats_t *stats; + + if (!(tree = c_avl_create(zone_compare))) { + WARNING("zone plugin: Failed to create tree"); + return (NULL); + } + + rewinddir(procdir); + while ((direntp = readdir(procdir))) { + char const *pidstr = direntp->d_name; + if (pidstr[0] == '.') /* skip "." and ".." */ + continue; + + pid = atoi(pidstr); + if (pid == 0 || pid == 2 || pid == 3) + continue; /* skip sched, pageout and fsflush */ + + if (zone_read_procfile(pidstr, "psinfo", &psinfo, sizeof(psinfo_t)) != 0) + continue; + + stats = zone_find_stats(tree, psinfo.pr_zoneid); + if (stats) { + stats->pctcpu += psinfo.pr_pctcpu; + stats->pctmem += psinfo.pr_pctmem; + } + } + return (tree); } -static int zone_read (void) -{ - DIR *procdir; - c_avl_tree_t *tree; - - if ((procdir = opendir("/proc")) == NULL) { - ERROR("zone plugin: cannot open /proc directory\n"); - return (-1); - } - - tree=zone_scandir(procdir); - closedir(procdir); - if (tree == NULL) { - return (-1); - } - zone_submit_values(tree); /* this also frees tree */ - return (0); +static int zone_read(void) { + DIR *procdir; + c_avl_tree_t *tree; + + if ((procdir = opendir("/proc")) == NULL) { + ERROR("zone plugin: cannot open /proc directory\n"); + return (-1); + } + + tree = zone_scandir(procdir); + closedir(procdir); + if (tree == NULL) { + return (-1); + } + zone_submit_values(tree); /* this also frees tree */ + return (0); } -void module_register (void) -{ - plugin_register_read ("zone", zone_read); +void module_register(void) { + plugin_register_read("zone", zone_read); } /* void module_register */ diff --git a/src/zookeeper.c b/src/zookeeper.c index 539112e8..a42b04c8 100644 --- a/src/zookeeper.c +++ b/src/zookeeper.c @@ -30,9 +30,9 @@ #include "plugin.h" #include -#include #include #include +#include #define ZOOKEEPER_DEF_HOST "127.0.0.1" #define ZOOKEEPER_DEF_PORT "2181" @@ -40,269 +40,209 @@ static char *zk_host = NULL; static char *zk_port = NULL; -static const char *config_keys[] = -{ - "Host", - "Port" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); - -static int zookeeper_config(const char *key, const char *value) -{ - if (strncmp(key, "Host", strlen("Host")) == 0) - { - sfree (zk_host); - zk_host = strdup (value); - } - else if (strncmp(key, "Port", strlen("Port")) == 0) - { - sfree (zk_port); - zk_port = strdup (value); - } - else - { - return -1; - } - return 0; +static const char *config_keys[] = {"Host", "Port"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); + +static int zookeeper_config(const char *key, const char *value) { + if (strncmp(key, "Host", strlen("Host")) == 0) { + sfree(zk_host); + zk_host = strdup(value); + } else if (strncmp(key, "Port", strlen("Port")) == 0) { + sfree(zk_port); + zk_port = strdup(value); + } else { + return -1; + } + return 0; } -static void zookeeper_submit_gauge (const char * type, const char * type_inst, gauge_t value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void zookeeper_submit_gauge(const char *type, const char *type_inst, + gauge_t value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .gauge = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "zookeeper", sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof (vl.type)); - if (type_inst != NULL) - sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance)); + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "zookeeper", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); + if (type_inst != NULL) + sstrncpy(vl.type_instance, type_inst, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* zookeeper_submit_gauge */ -static void zookeeper_submit_derive (const char * type, const char * type_inst, derive_t value) -{ - value_list_t vl = VALUE_LIST_INIT; +static void zookeeper_submit_derive(const char *type, const char *type_inst, + derive_t value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &(value_t) { .derive = value }; - vl.values_len = 1; - sstrncpy (vl.plugin, "zookeeper", sizeof (vl.plugin)); - sstrncpy (vl.type, type, sizeof (vl.type)); - if (type_inst != NULL) - sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance)); + vl.values = &(value_t){.derive = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "zookeeper", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); + if (type_inst != NULL) + sstrncpy(vl.type_instance, type_inst, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* zookeeper_submit_derive */ -static int zookeeper_connect (void) -{ - int sk = -1; - int status; - struct addrinfo *ai_list; - const char *host; - const char *port; - - host = (zk_host != NULL) ? zk_host : ZOOKEEPER_DEF_HOST; - port = (zk_port != NULL) ? zk_port : ZOOKEEPER_DEF_PORT; - - struct addrinfo ai_hints = { - .ai_family = AF_UNSPEC, - .ai_socktype = SOCK_STREAM - }; - - status = getaddrinfo (host, port, &ai_hints, &ai_list); - if (status != 0) - { - char errbuf[1024]; - INFO ("getaddrinfo failed: %s", - (status == EAI_SYSTEM) - ? sstrerror (errno, errbuf, sizeof (errbuf)) - : gai_strerror (status)); - return (-1); - } - - for (struct addrinfo *ai = ai_list; ai != NULL; ai = ai->ai_next) - { - sk = socket (ai->ai_family, SOCK_STREAM, 0); - if (sk < 0) - { - char errbuf[1024]; - WARNING ("zookeeper: socket(2) failed: %s", - sstrerror (errno, errbuf, sizeof(errbuf))); - continue; - } - status = (int) connect (sk, ai->ai_addr, ai->ai_addrlen); - if (status != 0) - { - char errbuf[1024]; - close (sk); - sk = -1; - WARNING ("zookeeper: connect(2) failed: %s", - sstrerror (errno, errbuf, sizeof(errbuf))); - continue; - } - - /* connected */ - break; - } - - freeaddrinfo(ai_list); - return (sk); +static int zookeeper_connect(void) { + int sk = -1; + int status; + struct addrinfo *ai_list; + const char *host; + const char *port; + + host = (zk_host != NULL) ? zk_host : ZOOKEEPER_DEF_HOST; + port = (zk_port != NULL) ? zk_port : ZOOKEEPER_DEF_PORT; + + struct addrinfo ai_hints = {.ai_family = AF_UNSPEC, + .ai_socktype = SOCK_STREAM}; + + status = getaddrinfo(host, port, &ai_hints, &ai_list); + if (status != 0) { + char errbuf[1024]; + INFO("getaddrinfo failed: %s", + (status == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf)) + : gai_strerror(status)); + return (-1); + } + + for (struct addrinfo *ai = ai_list; ai != NULL; ai = ai->ai_next) { + sk = socket(ai->ai_family, SOCK_STREAM, 0); + if (sk < 0) { + char errbuf[1024]; + WARNING("zookeeper: socket(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + continue; + } + status = (int)connect(sk, ai->ai_addr, ai->ai_addrlen); + if (status != 0) { + char errbuf[1024]; + close(sk); + sk = -1; + WARNING("zookeeper: connect(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + continue; + } + + /* connected */ + break; + } + + freeaddrinfo(ai_list); + return (sk); } /* int zookeeper_connect */ -static int zookeeper_query (char *buffer, size_t buffer_size) -{ - int sk, status; - size_t buffer_fill; - - sk = zookeeper_connect(); - if (sk < 0) - { - ERROR ("zookeeper: Could not connect to daemon"); - return (-1); - } - - status = (int) swrite (sk, "mntr\r\n", strlen("mntr\r\n")); - if (status != 0) - { - char errbuf[1024]; - ERROR ("zookeeper: write(2) failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - close (sk); - return (-1); - } - - memset (buffer, 0, buffer_size); - buffer_fill = 0; - - while ((status = (int) recv (sk, buffer + buffer_fill, - buffer_size - buffer_fill, /* flags = */ 0)) != 0) - { - if (status < 0) - { - char errbuf[1024]; - if ((errno == EAGAIN) || (errno == EINTR)) - continue; - ERROR ("zookeeper: Error reading from socket: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - close (sk); - return (-1); - } - - buffer_fill += (size_t) status; - } /* while (recv) */ - - status = 0; - if (buffer_fill == 0) - { - WARNING ("zookeeper: No data returned by MNTR command."); - status = -1; - } - - close(sk); - return (status); +static int zookeeper_query(char *buffer, size_t buffer_size) { + int sk, status; + size_t buffer_fill; + + sk = zookeeper_connect(); + if (sk < 0) { + ERROR("zookeeper: Could not connect to daemon"); + return (-1); + } + + status = (int)swrite(sk, "mntr\r\n", strlen("mntr\r\n")); + if (status != 0) { + char errbuf[1024]; + ERROR("zookeeper: write(2) failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(sk); + return (-1); + } + + memset(buffer, 0, buffer_size); + buffer_fill = 0; + + while ((status = (int)recv(sk, buffer + buffer_fill, + buffer_size - buffer_fill, /* flags = */ 0)) != + 0) { + if (status < 0) { + char errbuf[1024]; + if ((errno == EAGAIN) || (errno == EINTR)) + continue; + ERROR("zookeeper: Error reading from socket: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(sk); + return (-1); + } + + buffer_fill += (size_t)status; + } /* while (recv) */ + + status = 0; + if (buffer_fill == 0) { + WARNING("zookeeper: No data returned by MNTR command."); + status = -1; + } + + close(sk); + return (status); } /* int zookeeper_query */ - -static int zookeeper_read (void) { - char buf[4096]; - char *ptr; - char *save_ptr; - char *line; - char *fields[2]; - - if (zookeeper_query (buf, sizeof (buf)) < 0) - { - return (-1); - } - - ptr = buf; - save_ptr = NULL; - while ((line = strtok_r (ptr, "\n\r", &save_ptr)) != NULL) - { - ptr = NULL; - if (strsplit(line, fields, 2) != 2) - { - continue; - } -#define FIELD_CHECK(check, expected) \ - (strncmp (check, expected, strlen(expected)) == 0) - - if (FIELD_CHECK (fields[0], "zk_avg_latency")) - { - zookeeper_submit_gauge ("latency", "avg", atol(fields[1])); - } - else if (FIELD_CHECK(fields[0], "zk_min_latency")) - { - zookeeper_submit_gauge ("latency", "min", atol(fields[1])); - } - else if (FIELD_CHECK (fields[0], "zk_max_latency")) - { - zookeeper_submit_gauge ("latency", "max", atol(fields[1])); - } - else if (FIELD_CHECK (fields[0], "zk_packets_received")) - { - zookeeper_submit_derive ("packets", "received", atol(fields[1])); - } - else if (FIELD_CHECK (fields[0], "zk_packets_sent")) - { - zookeeper_submit_derive ("packets", "sent", atol(fields[1])); - } - else if (FIELD_CHECK (fields[0], "zk_num_alive_connections")) - { - zookeeper_submit_gauge ("current_connections", NULL, atol(fields[1])); - } - else if (FIELD_CHECK (fields[0], "zk_outstanding_requests")) - { - zookeeper_submit_gauge ("requests", "outstanding", atol(fields[1])); - } - else if (FIELD_CHECK (fields[0], "zk_znode_count")) - { - zookeeper_submit_gauge ("gauge", "znode", atol(fields[1])); - } - else if (FIELD_CHECK (fields[0], "zk_watch_count")) - { - zookeeper_submit_gauge ("gauge", "watch", atol(fields[1])); - } - else if (FIELD_CHECK (fields[0], "zk_ephemerals_count")) - { - zookeeper_submit_gauge ("gauge", "ephemerals", atol(fields[1])); - } - else if (FIELD_CHECK (fields[0], "zk_ephemerals_count")) - { - zookeeper_submit_gauge ("gauge", "ephemerals", atol(fields[1])); - } - else if (FIELD_CHECK (fields[0], "zk_ephemerals_count")) - { - zookeeper_submit_gauge ("gauge", "ephemerals", atol(fields[1])); - } - else if (FIELD_CHECK (fields[0], "zk_approximate_data_size")) - { - zookeeper_submit_gauge ("bytes", "approximate_data_size", atol(fields[1])); - } - else if (FIELD_CHECK (fields[0], "zk_followers")) - { - zookeeper_submit_gauge ("count", "followers", atol(fields[1])); - } - else if (FIELD_CHECK (fields[0], "zk_synced_followers")) - { - zookeeper_submit_gauge ("count", "synced_followers", atol(fields[1])); - } - else if (FIELD_CHECK (fields[0], "zk_pending_syncs")) - { - zookeeper_submit_gauge ("count", "pending_syncs", atol(fields[1])); - } - else - { - DEBUG("Uncollected zookeeper MNTR field %s", fields[0]); - } - } - - return (0); +static int zookeeper_read(void) { + char buf[4096]; + char *ptr; + char *save_ptr; + char *line; + char *fields[2]; + + if (zookeeper_query(buf, sizeof(buf)) < 0) { + return (-1); + } + + ptr = buf; + save_ptr = NULL; + while ((line = strtok_r(ptr, "\n\r", &save_ptr)) != NULL) { + ptr = NULL; + if (strsplit(line, fields, 2) != 2) { + continue; + } +#define FIELD_CHECK(check, expected) \ + (strncmp(check, expected, strlen(expected)) == 0) + + if (FIELD_CHECK(fields[0], "zk_avg_latency")) { + zookeeper_submit_gauge("latency", "avg", atol(fields[1])); + } else if (FIELD_CHECK(fields[0], "zk_min_latency")) { + zookeeper_submit_gauge("latency", "min", atol(fields[1])); + } else if (FIELD_CHECK(fields[0], "zk_max_latency")) { + zookeeper_submit_gauge("latency", "max", atol(fields[1])); + } else if (FIELD_CHECK(fields[0], "zk_packets_received")) { + zookeeper_submit_derive("packets", "received", atol(fields[1])); + } else if (FIELD_CHECK(fields[0], "zk_packets_sent")) { + zookeeper_submit_derive("packets", "sent", atol(fields[1])); + } else if (FIELD_CHECK(fields[0], "zk_num_alive_connections")) { + zookeeper_submit_gauge("current_connections", NULL, atol(fields[1])); + } else if (FIELD_CHECK(fields[0], "zk_outstanding_requests")) { + zookeeper_submit_gauge("requests", "outstanding", atol(fields[1])); + } else if (FIELD_CHECK(fields[0], "zk_znode_count")) { + zookeeper_submit_gauge("gauge", "znode", atol(fields[1])); + } else if (FIELD_CHECK(fields[0], "zk_watch_count")) { + zookeeper_submit_gauge("gauge", "watch", atol(fields[1])); + } else if (FIELD_CHECK(fields[0], "zk_ephemerals_count")) { + zookeeper_submit_gauge("gauge", "ephemerals", atol(fields[1])); + } else if (FIELD_CHECK(fields[0], "zk_ephemerals_count")) { + zookeeper_submit_gauge("gauge", "ephemerals", atol(fields[1])); + } else if (FIELD_CHECK(fields[0], "zk_ephemerals_count")) { + zookeeper_submit_gauge("gauge", "ephemerals", atol(fields[1])); + } else if (FIELD_CHECK(fields[0], "zk_approximate_data_size")) { + zookeeper_submit_gauge("bytes", "approximate_data_size", atol(fields[1])); + } else if (FIELD_CHECK(fields[0], "zk_followers")) { + zookeeper_submit_gauge("count", "followers", atol(fields[1])); + } else if (FIELD_CHECK(fields[0], "zk_synced_followers")) { + zookeeper_submit_gauge("count", "synced_followers", atol(fields[1])); + } else if (FIELD_CHECK(fields[0], "zk_pending_syncs")) { + zookeeper_submit_gauge("count", "pending_syncs", atol(fields[1])); + } else { + DEBUG("Uncollected zookeeper MNTR field %s", fields[0]); + } + } + + return (0); } /* zookeeper_read */ -void module_register (void) -{ - plugin_register_config ("zookeeper", zookeeper_config, config_keys, config_keys_num); - plugin_register_read ("zookeeper", zookeeper_read); +void module_register(void) { + plugin_register_config("zookeeper", zookeeper_config, config_keys, + config_keys_num); + plugin_register_read("zookeeper", zookeeper_read); } /* void module_register */ -- 2.30.2