#include "plugin.h"
#include "configfile.h"
+#if HAVE_STATGRAB_H
+# include <statgrab.h>
+#endif
+
/*
* Global variables
*/
char hostname_g[DATA_MAX_NAME_LEN];
-int interval_g;
+cdtime_t interval_g;
+int timeout_g;
#if HAVE_LIBKSTAT
kstat_ctl_t *kc;
#endif /* HAVE_LIBKSTAT */
static int loop = 0;
-static void *do_flush (void *arg)
+static void *do_flush (void __attribute__((unused)) *arg)
{
INFO ("Flushing all data.");
- plugin_flush_all (-1);
+ plugin_flush (/* plugin = */ NULL,
+ /* timeout = */ 0,
+ /* ident = */ NULL);
INFO ("Finished flushing all data.");
pthread_exit (NULL);
return NULL;
}
-static void sig_int_handler (int signal)
+static void sig_int_handler (int __attribute__((unused)) signal)
{
loop++;
}
-static void sig_term_handler (int signal)
+static void sig_term_handler (int __attribute__((unused)) signal)
{
loop++;
}
-static void sig_usr1_handler (int signal)
+static void sig_usr1_handler (int __attribute__((unused)) signal)
{
pthread_t thread;
pthread_attr_t attr;
str = global_option_get ("Hostname");
if (str != NULL)
{
- strncpy (hostname_g, str, sizeof (hostname_g));
- hostname_g[sizeof (hostname_g) - 1] = '\0';
+ sstrncpy (hostname_g, str, sizeof (hostname_g));
return (0);
}
}
str = global_option_get ("FQDNLookup");
- if ((strcasecmp ("false", str) == 0)
- || (strcasecmp ("no", str) == 0)
- || (strcasecmp ("off", str) == 0))
+ if (IS_FALSE (str))
return (0);
memset (&ai_hints, '\0', sizeof (ai_hints));
if (ai_ptr->ai_canonname == NULL)
continue;
- strncpy (hostname_g, ai_ptr->ai_canonname, sizeof (hostname_g));
- hostname_g[sizeof (hostname_g) - 1] = '\0';
+ sstrncpy (hostname_g, ai_ptr->ai_canonname, sizeof (hostname_g));
break;
}
str = global_option_get ("Interval");
if (str == NULL)
- str = "10";
- interval_g = atoi (str);
- if (interval_g <= 0)
{
- fprintf (stderr, "Cannot set the interval to a correct value.\n"
+ interval_g = TIME_T_TO_CDTIME_T (10);
+ }
+ else
+ {
+ double tmp;
+
+ tmp = atof (str);
+ if (tmp <= 0.0)
+ {
+ fprintf (stderr, "Cannot set the interval to a "
+ "correct value.\n"
+ "Please check your settings.\n");
+ return (-1);
+ }
+
+ interval_g = DOUBLE_TO_CDTIME_T (tmp);
+ }
+ DEBUG ("interval_g = %.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 ("interval_g = %i;", interval_g);
+ DEBUG ("timeout_g = %i;", timeout_g);
if (init_hostname () != 0)
return (-1);
/* TODO
* Remove all settings but `-f' and `-C'
*/
-static void exit_usage (void)
+static void exit_usage (int status)
{
printf ("Usage: "PACKAGE" [OPTIONS]\n\n"
" -C <file> Configuration file.\n"
" Default: "CONFIGFILE"\n"
" -t Test config and exit.\n"
+ " -T Test plugin read and exit.\n"
" -P <file> PID-file.\n"
" Default: "PIDFILE"\n"
#if COLLECT_DAEMON
#endif
" -h Display help (this message)\n"
"\nBuiltin defaults:\n"
- " Config-File "CONFIGFILE"\n"
- " PID-File "PIDFILE"\n"
- " Data-Directory "PKGLOCALSTATEDIR"\n"
+ " Config file "CONFIGFILE"\n"
+ " PID file "PIDFILE"\n"
+ " Plugin directory "PLUGINDIR"\n"
+ " Data directory "PKGLOCALSTATEDIR"\n"
"\n"PACKAGE" "VERSION", http://collectd.org/\n"
"by Florian octo Forster <octo@verplant.org>\n"
"for contributions see `AUTHORS'\n");
- exit (0);
-} /* static void exit_usage (char *name) */
+ exit (status);
+} /* static void exit_usage (int status) */
static int do_init (void)
{
static int do_loop (void)
{
- struct timeval tv_now;
- struct timeval tv_next;
- struct timespec ts_wait;
+ cdtime_t wait_until;
+
+ wait_until = cdtime () + interval_g;
while (loop == 0)
{
- if (gettimeofday (&tv_next, NULL) < 0)
- {
- char errbuf[1024];
- ERROR ("gettimeofday failed: %s",
- sstrerror (errno, errbuf,
- sizeof (errbuf)));
- return (-1);
- }
- tv_next.tv_sec += interval_g;
+ struct timespec ts_wait = { 0, 0 };
+ cdtime_t now;
#if HAVE_LIBKSTAT
update_kstat ();
/* Issue all plugins */
plugin_read_all ();
- if (gettimeofday (&tv_now, NULL) < 0)
+ now = cdtime ();
+ if (now >= wait_until)
{
- char errbuf[1024];
- ERROR ("gettimeofday failed: %s",
- sstrerror (errno, errbuf,
- sizeof (errbuf)));
- return (-1);
- }
-
- if (timeval_sub_timespec (&tv_next, &tv_now, &ts_wait) != 0)
- {
- WARNING ("Not sleeping because "
- "`timeval_sub_timespec' returned "
- "non-zero!");
+ WARNING ("Not sleeping because the next interval is "
+ "%.3f seconds in the past!",
+ CDTIME_T_TO_DOUBLE (now - wait_until));
+ wait_until = now + interval_g;
continue;
}
- while ((loop == 0) && (nanosleep (&ts_wait, &ts_wait) == -1))
+ CDTIME_T_TO_TIMESPEC (wait_until - now, &ts_wait);
+ wait_until = wait_until + interval_g;
+
+ while ((loop == 0) && (nanosleep (&ts_wait, &ts_wait) != 0))
{
if (errno != EINTR)
{
}
} /* while (loop == 0) */
- DEBUG ("return (0);");
return (0);
} /* int do_loop */
struct sigaction sig_int_action;
struct sigaction sig_term_action;
struct sigaction sig_usr1_action;
+ struct sigaction sig_pipe_action;
char *configfile = CONFIGFILE;
int test_config = 0;
+ int test_readall = 0;
const char *basedir;
#if COLLECT_DAEMON
- struct sigaction sigChldAction;
+ struct sigaction sig_chld_action;
pid_t pid;
int daemonize = 1;
#endif
+ int exit_status = 0;
/* read options */
while (1)
{
int c;
- c = getopt (argc, argv, "htC:"
+ c = getopt (argc, argv, "htTC:"
#if COLLECT_DAEMON
"fP:"
#endif
case 't':
test_config = 1;
break;
+ case 'T':
+ test_readall = 1;
+ global_option_set ("ReadThreads", "-1");
+#if COLLECT_DAEMON
+ daemonize = 0;
+#endif /* COLLECT_DAEMON */
+ break;
#if COLLECT_DAEMON
case 'P':
global_option_set ("PIDFile", optarg);
break;
#endif /* COLLECT_DAEMON */
case 'h':
+ exit_usage (0);
+ break;
default:
- exit_usage ();
+ exit_usage (1);
} /* switch (c) */
} /* while (1) */
+ if (optind < argc)
+ exit_usage (1);
+
/*
* Read options from the config file, the environment and the command
* line (in that order, with later options overwriting previous ones in
/*
* fork off child
*/
- memset (&sigChldAction, '\0', sizeof (sigChldAction));
- sigChldAction.sa_handler = SIG_IGN;
- sigaction (SIGCHLD, &sigChldAction, NULL);
+ memset (&sig_chld_action, '\0', sizeof (sig_chld_action));
+ sig_chld_action.sa_handler = SIG_IGN;
+ sigaction (SIGCHLD, &sig_chld_action, NULL);
if (daemonize)
{
} /* if (daemonize) */
#endif /* COLLECT_DAEMON */
+ memset (&sig_pipe_action, '\0', sizeof (sig_pipe_action));
+ sig_pipe_action.sa_handler = SIG_IGN;
+ sigaction (SIGPIPE, &sig_pipe_action, NULL);
+
/*
* install signal handlers
*/
* run the actual loops
*/
do_init ();
- do_loop ();
+
+ if (test_readall)
+ {
+ if (plugin_read_all_once () != 0)
+ exit_status = 1;
+ }
+ else
+ {
+ INFO ("Initialization complete, entering read-loop.");
+ do_loop ();
+ }
/* close syslog */
- INFO ("Exiting normally");
+ INFO ("Exiting normally.");
do_shutdown ();
pidfile_remove ();
#endif /* COLLECT_DAEMON */
- return (0);
+ return (exit_status);
} /* int main */