From: Florian Forster Date: Wed, 30 Apr 2008 09:04:23 +0000 (+0200) Subject: Merge branch 'collectd-4.4' X-Git-Tag: collectd-4.5.0~159 X-Git-Url: https://git.octo.it/?a=commitdiff_plain;h=cacaa2126020832df99fa6423147bd3de6d4faae;hp=d98487a27d294e31f483b9d43e0d6c02717d248c;p=collectd.git Merge branch 'collectd-4.4' Conflicts: src/collectd-perl.pod src/email.c --- diff --git a/bindings/perl/Collectd.pm b/bindings/perl/Collectd.pm index 43775706..0da6c23b 100644 --- a/bindings/perl/Collectd.pm +++ b/bindings/perl/Collectd.pm @@ -42,6 +42,9 @@ our %EXPORT_TAGS = ( plugin_register plugin_unregister plugin_dispatch_values + plugin_flush + plugin_flush_one + plugin_flush_all plugin_dispatch_notification plugin_log ) ], @@ -52,6 +55,7 @@ our %EXPORT_TAGS = ( TYPE_SHUTDOWN TYPE_LOG TYPE_NOTIF + TYPE_FLUSH TYPE_DATASET ) ], 'ds_types' => [ qw( @@ -101,7 +105,8 @@ my %types = ( TYPE_WRITE, "write", TYPE_SHUTDOWN, "shutdown", TYPE_LOG, "log", - TYPE_NOTIF, "notify" + TYPE_NOTIF, "notify", + TYPE_FLUSH, "flush" ); foreach my $type (keys %types) { @@ -246,7 +251,7 @@ sub plugin_register { my %p : shared; - if ($data !~ m/^$pkg/) { + if ($data !~ m/^$pkg\:\:/) { $data = $pkg . "::" . $data; } @@ -290,6 +295,34 @@ sub plugin_unregister { } } +sub plugin_flush { + my %args = @_; + + my $timeout = -1; + + DEBUG ("Collectd::plugin_flush:" + . (defined ($args{'timeout'}) ? " timeout = $args{'timeout'}" : "") + . (defined ($args{'plugins'}) ? " plugins = $args{'plugins'}" : "")); + + if (defined ($args{'timeout'}) && ($args{'timeout'} > 0)) { + $timeout = $args{'timeout'}; + } + + if (! defined $args{'plugins'}) { + plugin_flush_all ($timeout); + } + else { + if ("ARRAY" eq ref ($args{'plugins'})) { + foreach my $plugin (@{$args{'plugins'}}) { + plugin_flush_one ($timeout, $plugin); + } + } + else { + plugin_flush_one ($timeout, $args{'plugins'}); + } + } +} + 1; # vim: set sw=4 ts=4 tw=78 noexpandtab : diff --git a/configure.in b/configure.in index 7cd36998..e834ffd6 100644 --- a/configure.in +++ b/configure.in @@ -1095,24 +1095,21 @@ AM_CONDITIONAL(BUILD_WITH_LIBCURL, test "x$with_libcurl" = "xyes") ### END of check for libcurl ### with_libiokit="no" -collectd_libiokit=0 AC_CHECK_LIB(IOKit, IOServiceGetMatchingServices, [ with_libiokit="yes" - collectd_libiokit=1 -], +], [ with_libiokit="no" - collectd_libiokit=0 ]) -AC_DEFINE_UNQUOTED(COLLECT_LIBIOKIT, [$collect_libiokit], [Wether or not to use the IOKit library]) AM_CONDITIONAL(BUILD_WITH_LIBIOKIT, test "x$with_libiokit" = "xyes") with_libstatgrab_cflags="" with_libstatgrab_ldflags="" AC_ARG_WITH(libstatgrab, [AS_HELP_STRING([--with-libstatgrab@<:@=PREFIX@:>@], [Path to libstatgrab.])], [ - if test "x$withval" != "xno" -a "x$withval" != "xyes" + if test "x$withval" != "xno" \ + && test "x$withval" != "xyes" then with_libstatgrab_cflags="-I$withval/include" with_libstatgrab_ldflags="-L$withval/lib" @@ -1122,7 +1119,7 @@ AC_ARG_WITH(libstatgrab, [AS_HELP_STRING([--with-libstatgrab@<:@=PREFIX@:>@], [P fi ], [ - if test "x$ac_system" == "xunknown" + if test "x$ac_system" = "xunknown" then with_libstatgrab="yes" else @@ -1211,6 +1208,7 @@ fi AM_CONDITIONAL(BUILD_WITH_LIBSTATGRAB, test "x$with_libstatgrab" = "xyes") if test "x$with_libstatgrab" = "xyes" then + AC_DEFINE(HAVE_LIBSTATGRAB, 1, [Define to 1 if you have the 'statgrab' library (-lstatgrab)]) BUILD_WITH_LIBSTATGRAB_CFLAGS="$with_libstatgrab_cflags" BUILD_WITH_LIBSTATGRAB_LDFLAGS="$with_libstatgrab_ldflags" AC_SUBST(BUILD_WITH_LIBSTATGRAB_CFLAGS) diff --git a/src/collectd-perl.pod b/src/collectd-perl.pod index 5a58d357..b7ae9cac 100644 --- a/src/collectd-perl.pod +++ b/src/collectd-perl.pod @@ -67,7 +67,7 @@ registered by the plugins. Any plugin basically consists of the implementation of these callback functions and initializing code which registers the functions with collectd. See the section "EXAMPLES" below for a really basic example. The following types of B are known to collectd -(all of these are optional): +(all of them are optional): =over 4 @@ -92,6 +92,12 @@ amount of time until it returns B again. This type of function is used to write the dispatched values. It is called once for each call to B. +=item flush functions + +This type of function is used to flush internal caches of plugins. It is +usually triggered by the user only. Any plugin which caches data before +writing it to disk should provide this kind of callback function. + =item log functions This type of function is used to pass messages of plugins or the daemon itself @@ -204,6 +210,8 @@ I can be one of: =item TYPE_WRITE +=item TYPE_FLUSH + =item TYPE_LOG =item TYPE_NOTIF @@ -246,13 +254,18 @@ arguments: =item TYPE_SHUTDOWN -No arguments are passed +No arguments are passed. =item TYPE_WRITE The arguments passed are I, I, and I. I is a string. For the layout of I and I see above. +=item TYPE_FLUSH + +The only argument passed is I which indicates that only data older +than I seconds is to be flushed. + =item TYPE_LOG The arguments are I and I. The log level is small for @@ -286,6 +299,22 @@ as the first argument to B. This syntax is still supported for backwards compatibility but has been deprecated and will be removed in some future version of collectd. +=item B ([B => I,] [B => I<...>]) + +Flush one or more plugins. I is passed on to the registered +flush-callbacks. If omitted, C<-1> is used. If the I argument has +been specified, only named plugins will be flushed. The argument's value may +either be a string or a reference to an array of strings. + +=item B (I, I) + +This is identical to using "plugin_flush (timeout =E I, plugins +=E I". + +=item B (I) + +This is identical to using "plugin_flush (timeout =E I)". + =item B (I) Submits a I to the daemon which will then pass it to all @@ -339,6 +368,12 @@ available (B<:all> will export all of them): =item B () +=item B () + +=item B () + +=item B () + =item B () =item B () @@ -355,6 +390,8 @@ available (B<:all> will export all of them): =item B +=item B + =item B =item B @@ -511,6 +548,18 @@ instead. =back +=head1 KNOWN BUGS + +=over 4 + +=item + +Currently, it is not possible to flush a single Perl plugin only. You can +either flush all Perl plugins or none at all and you have to use C as +plugin name when doing so. + +=back + =head1 SEE ALSO L, diff --git a/src/collectd.c b/src/collectd.c index 2044b49c..38d1b868 100644 --- a/src/collectd.c +++ b/src/collectd.c @@ -32,6 +32,10 @@ #include "plugin.h" #include "configfile.h" +#if HAVE_STATGRAB_H +# include +#endif + /* * Global variables */ diff --git a/src/collectd.h b/src/collectd.h index 59dc5d20..80d86ba8 100644 --- a/src/collectd.h +++ b/src/collectd.h @@ -174,9 +174,6 @@ #if HAVE_PTH_H # include #endif -#if HAVE_STATGRAB_H -# include -#endif #if HAVE_SENSORS_SENSORS_H # include #endif diff --git a/src/email.c b/src/email.c index b255ac79..200b60c1 100644 --- a/src/email.c +++ b/src/email.c @@ -1,6 +1,6 @@ /** * collectd - src/email.c - * Copyright (C) 2006,2007 Sebastian Harl + * Copyright (C) 2006-2008 Sebastian Harl * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -58,17 +58,13 @@ # include #endif /* HAVE_GRP_H */ -#define MODULE_NAME "email" - -/* 256 bytes ought to be enough for anybody ;-) */ -#define BUFSIZE 256 - #define SOCK_PATH LOCALSTATEDIR"/run/"PACKAGE_NAME"-email" #define MAX_CONNS 5 #define MAX_CONNS_LIMIT 16384 -#define log_err(...) ERROR (MODULE_NAME": "__VA_ARGS__) -#define log_warn(...) WARNING (MODULE_NAME": "__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 @@ -90,19 +86,15 @@ typedef struct collector { pthread_t thread; /* socket descriptor of the current/last connection */ - int socket; + FILE *socket; } collector_t; /* linked list of pending connections */ typedef struct conn { /* socket to read data from */ - int socket; - - /* buffer to read data to */ - char *buffer; - int idx; /* current write position in buffer */ - int length; /* length of the current line, i.e. index of '\0' */ + FILE *socket; + /* linked list of connections */ struct conn *next; } conn_t; @@ -125,8 +117,8 @@ static const char *config_keys[] = static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); /* socket configuration */ -static char *sock_file = SOCK_PATH; -static char *sock_group = COLLECTD_GRP_NAME; +static char *sock_file = NULL; +static char *sock_group = NULL; static int sock_perms = S_IRWXU | S_IRWXG; static int max_conns = MAX_CONNS; @@ -154,17 +146,20 @@ static pthread_mutex_t available_mutex = PTHREAD_MUTEX_INITIALIZER; static int available_collectors; static pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER; -static type_list_t count; +static type_list_t list_count; +static type_list_t list_count_copy; static pthread_mutex_t size_mutex = PTHREAD_MUTEX_INITIALIZER; -static type_list_t size; +static type_list_t list_size; +static type_list_t list_size_copy; static pthread_mutex_t score_mutex = PTHREAD_MUTEX_INITIALIZER; static double score; static int score_count; static pthread_mutex_t check_mutex = PTHREAD_MUTEX_INITIALIZER; -static type_list_t check; +static type_list_t list_check; +static type_list_t list_check_copy; /* * Private functions @@ -172,9 +167,13 @@ static type_list_t check; 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")) { @@ -241,139 +240,10 @@ static void type_list_incr (type_list_t *list, char *name, int incr) return; } /* static void type_list_incr (type_list_t *, char *) */ -/* Read a single character from the socket. If an error occurs or end-of-file - * is reached return '\0'. */ -static char read_char (conn_t *src) -{ - char ret = '\0'; - - fd_set fdset; - - FD_ZERO (&fdset); - FD_SET (src->socket, &fdset); - - if (-1 == select (src->socket + 1, &fdset, NULL, NULL, NULL)) { - char errbuf[1024]; - log_err ("select() failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return '\0'; - } - - assert (FD_ISSET (src->socket, &fdset)); - - do { - ssize_t len = 0; - - errno = 0; - if (0 > (len = read (src->socket, (void *)&ret, 1))) { - if (EINTR != errno) { - char errbuf[1024]; - log_err ("read() failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return '\0'; - } - } - - if (0 == len) - return '\0'; - } while (EINTR == errno); - return ret; -} /* static char read_char (conn_t *) */ - -/* Read a single line (terminated by '\n') from the the socket. - * - * The return value is zero terminated and does not contain any newline - * characters. - * - * If an error occurs or end-of-file is reached return NULL. - * - * IMPORTANT NOTE: If there is no newline character found in BUFSIZE - * characters of the input stream, the line will will be ignored! By - * definition we should not get any longer input lines, thus this is - * acceptable in this case ;-) */ -static char *read_line (conn_t *src) -{ - int i = 0; - - assert ((BUFSIZE >= src->idx) && (src->idx >= 0)); - assert ((src->idx > src->length) || (src->length == 0)); - - if (src->length > 0) { /* remove old line */ - src->idx -= (src->length + 1); - memmove (src->buffer, src->buffer + src->length + 1, src->idx); - src->length = 0; - } - - for (i = 0; i < src->idx; ++i) { - if ('\n' == src->buffer[i]) - break; - } - - if (i == src->idx) { - fd_set fdset; - - ssize_t len = 0; - - FD_ZERO (&fdset); - FD_SET (src->socket, &fdset); - - if (-1 == select (src->socket + 1, &fdset, NULL, NULL, NULL)) { - char errbuf[1024]; - log_err ("select() failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return NULL; - } - - assert (FD_ISSET (src->socket, &fdset)); - - do { - errno = 0; - if (0 > (len = read (src->socket, - (void *)(src->buffer + src->idx), - BUFSIZE - src->idx))) { - if (EINTR != errno) { - char errbuf[1024]; - log_err ("read() failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return NULL; - } - } - - if (0 == len) - return NULL; - } while (EINTR == errno); - - src->idx += len; - - for (i = src->idx - len; i < src->idx; ++i) { - if ('\n' == src->buffer[i]) - break; - } - - if (i == src->idx) { - src->length = 0; - - if (BUFSIZE == src->idx) { /* no space left in buffer */ - while ('\n' != read_char (src)) - /* ignore complete line */; - - src->idx = 0; - } - return read_line (src); - } - } - - src->buffer[i] = '\0'; - src->length = i; - - return src->buffer; -} /* static char *read_line (conn_t *) */ - static void *collect (void *arg) { collector_t *this = (collector_t *)arg; - - char *buffer = (char *)smalloc (BUFSIZE); + pthread_t self = pthread_self (); while (1) { int loop = 1; @@ -393,44 +263,51 @@ static void *collect (void *arg) conns.tail = NULL; } - this->socket = connection->socket; - pthread_mutex_unlock (&conns_mutex); - connection->buffer = buffer; - connection->idx = 0; - connection->length = 0; + /* make the socket available to the global + * thread and connection management */ + this->socket = connection->socket; - { /* put the socket in non-blocking mode */ - int flags = 0; + log_debug ("[thread #%5lu] handling connection on fd #%i", + self, fileno (this->socket)); - errno = 0; - if (-1 == fcntl (connection->socket, F_GETFL, &flags)) { - char errbuf[1024]; - log_err ("fcntl() failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - loop = 0; - } + while (loop) { + /* 256 bytes ought to be enough for anybody ;-) */ + char line[256 + 1]; /* line + '\0' */ + int len = 0; errno = 0; - if (-1 == fcntl (connection->socket, F_SETFL, flags | O_NONBLOCK)) { - char errbuf[1024]; - log_err ("fcntl() failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); + if (NULL == fgets (line, sizeof (line), this->socket)) { loop = 0; + + if (0 != errno) { + char errbuf[1024]; + log_err ("[thread #%5lu] reading from socket (fd #%i) " + "failed: %s", self, fileno (this->socket), + sstrerror (errno, errbuf, sizeof (errbuf))); + } + break; } - } - while (loop) { - char *line = read_line (connection); + len = strlen (line); + if (('\n' != line[len - 1]) && ('\r' != line[len - 1])) { + log_warn ("[thread #%5lu] line too long (> %i characters): " + "'%s' (truncated)", self, sizeof (line) - 1, line); - if (NULL == line) { - loop = 0; - break; + while (NULL != fgets (line, sizeof (line), this->socket)) + if (('\n' == line[len - 1]) || ('\r' == line[len - 1])) + break; + continue; } + line[len - 1] = '\0'; + + log_debug ("[thread #%5lu] line = '%s'", self, line); + if (':' != line[1]) { - log_err ("syntax error in line '%s'", line); + log_err ("[thread #%5lu] syntax error in line '%s'", + self, line); continue; } @@ -441,19 +318,20 @@ static void *collect (void *arg) int bytes = 0; if (NULL == tmp) { - log_err ("syntax error in line '%s'", line); + log_err ("[thread #%5lu] syntax error in line '%s'", + self, line); continue; } bytes = atoi (tmp); pthread_mutex_lock (&count_mutex); - type_list_incr (&count, type, 1); + type_list_incr (&list_count, type, 1); pthread_mutex_unlock (&count_mutex); if (bytes > 0) { pthread_mutex_lock (&size_mutex); - type_list_incr (&size, type, bytes); + type_list_incr (&list_size, type, bytes); pthread_mutex_unlock (&size_mutex); } } @@ -470,19 +348,22 @@ static void *collect (void *arg) do { pthread_mutex_lock (&check_mutex); - type_list_incr (&check, type, 1); + type_list_incr (&list_check, type, 1); pthread_mutex_unlock (&check_mutex); } while (NULL != (type = strtok_r (NULL, ",", &ptr))); } else { - log_err ("unknown type '%c'", line[0]); + log_err ("[thread #%5lu] unknown type '%c'", self, line[0]); } } /* while (loop) */ - close (connection->socket); + log_debug ("[thread #%5lu] shutting down connection on fd #%i", + pthread_self (), fileno (this->socket)); + + fclose (connection->socket); free (connection); - this->socket = -1; + this->socket = NULL; pthread_mutex_lock (&available_mutex); ++available_collectors; @@ -491,7 +372,6 @@ static void *collect (void *arg) pthread_cond_signal (&collector_available); } /* while (1) */ - free (buffer); pthread_exit ((void *)0); } /* static void *collect (void *) */ @@ -499,6 +379,9 @@ static void *open_connection (void *arg) { struct sockaddr_un addr; + char *path = (NULL == sock_file) ? SOCK_PATH : sock_file; + 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))) { @@ -511,7 +394,7 @@ static void *open_connection (void *arg) addr.sun_family = AF_UNIX; - sstrncpy (addr.sun_path, sock_file, sizeof (addr.sun_path)); + sstrncpy (addr.sun_path, path, (size_t)(UNIX_PATH_MAX - 1)); unlink (addr.sun_path); errno = 0; @@ -520,7 +403,8 @@ static void *open_connection (void *arg) + strlen(addr.sun_path))) { char errbuf[1024]; disabled = 1; - connector_socket = -1; /* TODO: close? */ + close (connector_socket); + connector_socket = -1; log_err ("bind() failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); pthread_exit ((void *)1); @@ -530,13 +414,13 @@ static void *open_connection (void *arg) if (-1 == listen (connector_socket, 5)) { char errbuf[1024]; disabled = 1; - connector_socket = -1; /* TODO: close? */ + close (connector_socket); + connector_socket = -1; log_err ("listen() failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); pthread_exit ((void *)1); } - if ((uid_t) 0 == geteuid ()) { struct group sg; struct group *grp; @@ -544,36 +428,32 @@ static void *open_connection (void *arg) int status; grp = NULL; - status = getgrnam_r (sock_group, &sg, grbuf, sizeof (grbuf), &grp); + status = getgrnam_r (group, &sg, grbuf, sizeof (grbuf), &grp); if (status != 0) { char errbuf[1024]; - log_warn ("getgrnam_r (%s) failed: %s", sock_group, + log_warn ("getgrnam_r (%s) failed: %s", group, sstrerror (errno, errbuf, sizeof (errbuf))); } else if (grp == NULL) { - log_warn ("No such group: `%s'", sock_group); + log_warn ("No such group: `%s'", group); } else { - status = chown (sock_file, (uid_t) -1, grp->gr_gid); + status = chown (path, (uid_t) -1, grp->gr_gid); if (status != 0) { char errbuf[1024]; log_warn ("chown (%s, -1, %i) failed: %s", - sock_file, (int) grp->gr_gid, + path, (int) grp->gr_gid, sstrerror (errno, errbuf, sizeof (errbuf))); } } } - else /* geteuid != 0 */ - { - log_warn ("not running as root"); - } errno = 0; - if (0 != chmod (sock_file, sock_perms)) { + if (0 != chmod (path, sock_perms)) { char errbuf[1024]; log_warn ("chmod() failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); @@ -598,7 +478,7 @@ static void *open_connection (void *arg) for (i = 0; i < max_conns; ++i) { collectors[i] = (collector_t *)smalloc (sizeof (collector_t)); - collectors[i]->socket = -1; + collectors[i]->socket = NULL; if (0 != (err = pthread_create (&collectors[i]->thread, &ptattr, collect, collectors[i]))) { @@ -633,7 +513,8 @@ static void *open_connection (void *arg) if (EINTR != errno) { char errbuf[1024]; disabled = 1; - connector_socket = -1; /* TODO: close? */ + close (connector_socket); + connector_socket = -1; log_err ("accept() failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); pthread_exit ((void *)1); @@ -643,9 +524,14 @@ static void *open_connection (void *arg) connection = (conn_t *)smalloc (sizeof (conn_t)); - connection->socket = remote; + connection->socket = fdopen (remote, "r"); connection->next = NULL; + if (NULL == connection->socket) { + close (remote); + continue; + } + pthread_mutex_lock (&conns_mutex); if (NULL == conns.head) { @@ -682,6 +568,8 @@ static int email_init (void) static int email_shutdown (void) { + type_t *ptr = NULL; + int i = 0; if (connector != ((pthread_t) 0)) { @@ -697,6 +585,8 @@ static int email_shutdown (void) /* don't allow any more connections to be processed */ pthread_mutex_lock (&conns_mutex); + available_collectors = 0; + if (collectors != NULL) { for (i = 0; i < max_conns; ++i) { if (collectors[i] == NULL) @@ -707,18 +597,52 @@ static int email_shutdown (void) collectors[i]->thread = (pthread_t) 0; } - if (collectors[i]->socket >= 0) { - close (collectors[i]->socket); - collectors[i]->socket = -1; + 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); - unlink (sock_file); - errno = 0; + for (ptr = list_count.head; NULL != ptr; ptr = ptr->next) { + free (ptr->name); + free (ptr); + } + + for (ptr = list_count_copy.head; NULL != ptr; ptr = ptr->next) { + free (ptr->name); + free (ptr); + } + + for (ptr = list_size.head; NULL != ptr; ptr = ptr->next) { + free (ptr->name); + free (ptr); + } + for (ptr = list_size_copy.head; NULL != ptr; ptr = ptr->next) { + free (ptr->name); + free (ptr); + } + + for (ptr = list_check.head; NULL != ptr; ptr = ptr->next) { + free (ptr->name); + free (ptr); + } + + for (ptr = list_check_copy.head; NULL != ptr; ptr = ptr->next) { + free (ptr->name); + free (ptr); + } + + unlink ((NULL == sock_file) ? SOCK_PATH : sock_file); + + sfree (sock_file); + sfree (sock_group); return (0); } /* static void email_shutdown (void) */ @@ -785,47 +709,28 @@ static int email_read (void) double score_old; int score_count_old; - static type_list_t *cnt; - static type_list_t *sz; - static type_list_t *chk; - if (disabled) return (-1); - if (NULL == cnt) { - cnt = (type_list_t *)smalloc (sizeof (type_list_t)); - cnt->head = NULL; - } - - if (NULL == sz) { - sz = (type_list_t *)smalloc (sizeof (type_list_t)); - sz->head = NULL; - } - - if (NULL == chk) { - chk = (type_list_t *)smalloc (sizeof (type_list_t)); - chk->head = NULL; - } - /* email count */ pthread_mutex_lock (&count_mutex); - copy_type_list (&count, cnt); + copy_type_list (&list_count, &list_count_copy); pthread_mutex_unlock (&count_mutex); - for (ptr = cnt->head; NULL != ptr; ptr = ptr->next) { + for (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); - copy_type_list (&size, sz); + copy_type_list (&list_size, &list_size_copy); pthread_mutex_unlock (&size_mutex); - for (ptr = sz->head; NULL != ptr; ptr = ptr->next) { + for (ptr = list_size_copy.head; NULL != ptr; ptr = ptr->next) { email_submit ("email_size", ptr->name, ptr->value); } @@ -845,11 +750,11 @@ static int email_read (void) /* spam checks */ pthread_mutex_lock (&check_mutex); - copy_type_list (&check, chk); + copy_type_list (&list_check, &list_check_copy); pthread_mutex_unlock (&check_mutex); - for (ptr = chk->head; NULL != ptr; ptr = ptr->next) + for (ptr = list_check_copy.head; NULL != ptr; ptr = ptr->next) email_submit ("spam_check", ptr->name, ptr->value); return (0); diff --git a/src/interface.c b/src/interface.c index ef758bc8..ff4a0aa1 100644 --- a/src/interface.c +++ b/src/interface.c @@ -46,6 +46,10 @@ # include #endif +#if HAVE_STATGRAB_H +# include +#endif + /* * Various people have reported problems with `getifaddrs' and varying versions * of `glibc'. That's why it's disabled by default. Since more statistics are diff --git a/src/load.c b/src/load.c index e9ce7be0..7d11b986 100644 --- a/src/load.c +++ b/src/load.c @@ -27,6 +27,10 @@ #include #endif +#if HAVE_STATGRAB_H +# include +#endif + #ifdef HAVE_GETLOADAVG #if !defined(LOADAVG_1MIN) || !defined(LOADAVG_5MIN) || !defined(LOADAVG_15MIN) #define LOADAVG_1MIN 0 @@ -113,7 +117,7 @@ static int load_read (void) load_submit (snum, mnum, lnum); /* #endif KERNEL_LINUX */ -#elif defined(HAVE_LIBSTATGRAB) +#elif HAVE_LIBSTATGRAB gauge_t snum, mnum, lnum; sg_load_stats *ls; diff --git a/src/memory.c b/src/memory.c index c9cb8340..b56fc5a3 100644 --- a/src/memory.c +++ b/src/memory.c @@ -43,6 +43,10 @@ # include #endif +#if HAVE_STATGRAB_H +# include +#endif + /* vm_statistics_data_t */ #if HAVE_HOST_STATISTICS static mach_port_t port_host; @@ -62,6 +66,10 @@ static int pagesize; static kstat_t *ksp; /* #endif HAVE_LIBKSTAT */ +#elif HAVE_LIBSTATGRAB +/* no global variables */ +/* endif HAVE_LIBSTATGRAB */ + #else # error "No applicable input method." #endif @@ -218,7 +226,7 @@ static int memory_read (void) memory_submit ("cache", sysctl_vals[6]); /* #endif HAVE_SYSCTLBYNAME */ -#elif defined(KERNEL_LINUX) +#elif KERNEL_LINUX FILE *fh; char buffer[1024]; @@ -276,9 +284,9 @@ static int memory_read (void) memory_submit ("cached", mem_cached); memory_submit ("free", mem_free); } -/* #endif defined(KERNEL_LINUX) */ +/* #endif KERNEL_LINUX */ -#elif defined(HAVE_LIBKSTAT) +#elif HAVE_LIBKSTAT long long mem_used; long long mem_free; long long mem_lock; @@ -303,9 +311,9 @@ static int memory_read (void) memory_submit ("used", mem_used); memory_submit ("free", mem_free); memory_submit ("locked", mem_lock); -/* #endif defined(HAVE_LIBKSTAT) */ +/* #endif HAVE_LIBKSTAT */ -#elif defined(HAVE_LIBSTATGRAB) +#elif HAVE_LIBSTATGRAB sg_mem_stats *ios; if ((ios = sg_get_mem_stats ()) != NULL) diff --git a/src/perl.c b/src/perl.c index a08cced1..66cac7ef 100644 --- a/src/perl.c +++ b/src/perl.c @@ -61,8 +61,9 @@ #define PLUGIN_SHUTDOWN 3 #define PLUGIN_LOG 4 #define PLUGIN_NOTIF 5 +#define PLUGIN_FLUSH 6 -#define PLUGIN_TYPES 6 +#define PLUGIN_TYPES 7 #define PLUGIN_DATASET 255 @@ -77,6 +78,8 @@ void boot_DynaLoader (PerlInterpreter *, CV *); static XS (Collectd_plugin_register_ds); static XS (Collectd_plugin_unregister_ds); static XS (Collectd_plugin_dispatch_values); +static XS (Collectd_plugin_flush_one); +static XS (Collectd_plugin_flush_all); static XS (Collectd_plugin_dispatch_notification); static XS (Collectd_plugin_log); static XS (Collectd_call_by_name); @@ -130,6 +133,8 @@ static struct { { "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_flush_one", Collectd_plugin_flush_one }, + { "Collectd::plugin_flush_all", Collectd_plugin_flush_all }, { "Collectd::plugin_dispatch_notification", Collectd_plugin_dispatch_notification }, { "Collectd::plugin_log", Collectd_plugin_log }, @@ -148,6 +153,7 @@ struct { { "Collectd::TYPE_SHUTDOWN", PLUGIN_SHUTDOWN }, { "Collectd::TYPE_LOG", PLUGIN_LOG }, { "Collectd::TYPE_NOTIF", PLUGIN_NOTIF }, + { "Collectd::TYPE_FLUSH", PLUGIN_FLUSH }, { "Collectd::TYPE_DATASET", PLUGIN_DATASET }, { "Collectd::DS_TYPE_COUNTER", DS_TYPE_COUNTER }, { "Collectd::DS_TYPE_GAUGE", DS_TYPE_GAUGE }, @@ -754,6 +760,12 @@ static int pplugin_call_all (pTHX_ int type, ...) XPUSHs (sv_2mortal (newRV_noinc ((SV *)notif))); } + else if (PLUGIN_FLUSH == type) { + /* + * $_[0] = $timeout; + */ + XPUSHs (sv_2mortal (newSViv (va_arg (ap, int)))); + } PUTBACK; @@ -900,6 +912,54 @@ static XS (Collectd_plugin_dispatch_values) } /* static XS (Collectd_plugin_dispatch_values) */ /* + * Collectd::plugin_flush_one (timeout, name). + * + * timeout: + * timeout to use when flushing the data + * + * name: + * name of the plugin to flush + */ +static XS (Collectd_plugin_flush_one) +{ + dXSARGS; + + if (2 != items) { + log_err ("Usage: Collectd::plugin_flush_one(timeout, name)"); + XSRETURN_EMPTY; + } + + log_debug ("Collectd::plugin_flush_one: timeout = %i, name = \"%s\"", + (int)SvIV (ST (0)), SvPV_nolen (ST (1))); + + if (0 == plugin_flush_one ((int)SvIV (ST (0)), SvPV_nolen (ST (1)))) + XSRETURN_YES; + else + XSRETURN_EMPTY; +} /* static XS (Collectd_plugin_flush_one) */ + +/* + * Collectd::plugin_flush_all (timeout). + * + * timeout: + * timeout to use when flushing the data + */ +static XS (Collectd_plugin_flush_all) +{ + dXSARGS; + + if (1 != items) { + log_err ("Usage: Collectd::plugin_flush_all(timeout)"); + XSRETURN_EMPTY; + } + + log_debug ("Collectd::plugin_flush_all: timeout = %i", (int)SvIV (ST (0))); + + plugin_flush_all ((int)SvIV (ST (0))); + XSRETURN_YES; +} /* static XS (Collectd_plugin_flush_all) */ + +/* * Collectd::plugin_dispatch_notification (notif). * * notif: @@ -1204,6 +1264,25 @@ static int perl_notify (const notification_t *notif) return pplugin_call_all (aTHX_ PLUGIN_NOTIF, notif); } /* static int perl_notify (const notification_t *) */ +static int perl_flush (const int timeout) +{ + dTHX; + + if (NULL == perl_threads) + return 0; + + 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); + + aTHX = t->interp; + } + return pplugin_call_all (aTHX_ PLUGIN_FLUSH, timeout); +} /* static int perl_flush (const int) */ + static int perl_shutdown (void) { c_ithread_t *t = NULL; @@ -1235,6 +1314,7 @@ static int perl_shutdown (void) plugin_unregister_init ("perl"); plugin_unregister_read ("perl"); plugin_unregister_write ("perl"); + plugin_unregister_flush ("perl"); ret = pplugin_call_all (aTHX_ PLUGIN_SHUTDOWN); @@ -1372,6 +1452,11 @@ static int init_pi (int argc, char **argv) exit (1); } +#ifdef __FreeBSD__ + /* 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_threads = (c_ithread_list_t *)smalloc (sizeof (c_ithread_list_t)); @@ -1414,6 +1499,7 @@ static int init_pi (int argc, char **argv) plugin_register_read ("perl", perl_read); plugin_register_write ("perl", perl_write); + plugin_register_flush ("perl", perl_flush); plugin_register_shutdown ("perl", perl_shutdown); return 0; } /* static int init_pi (const char **, const int) */ diff --git a/src/swap.c b/src/swap.c index 362a2a82..4f0a0ba9 100644 --- a/src/swap.c +++ b/src/swap.c @@ -36,6 +36,10 @@ # include #endif +#if HAVE_STATGRAB_H +# include +#endif + #undef MAX #define MAX(x,y) ((x) > (y) ? (x) : (y))