X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fcollectd.c;h=d96d676790d0d8c730610484637c9322e2a27b5b;hb=4088bccc40644f45971304f4c73bc40dcfb87957;hp=71eb940fb3251b6ffee1af4829fdc92c915460ce;hpb=4765d9e4ae24157cc8772a30fea949b33f5a3e94;p=collectd.git diff --git a/src/collectd.c b/src/collectd.c index 71eb940f..d96d6767 100644 --- a/src/collectd.c +++ b/src/collectd.c @@ -40,33 +40,36 @@ * 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 (NULL, -1, NULL); + 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; @@ -76,6 +79,7 @@ static void sig_usr1_handler (int signal) 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) @@ -102,9 +106,7 @@ static int init_hostname (void) } 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)); @@ -136,19 +138,23 @@ static int init_hostname (void) static int init_global_variables (void) { - const char *str; + 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 ("Interval"); + str = global_option_get ("Timeout"); if (str == NULL) - str = "10"; - interval_g = atoi (str); - if (interval_g <= 0) + str = "2"; + timeout_g = atoi (str); + if (timeout_g <= 1) { - fprintf (stderr, "Cannot set the interval to a correct value.\n" + 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); @@ -159,10 +165,11 @@ static int init_global_variables (void) static int change_basedir (const char *orig_dir) { - char *dir = strdup (orig_dir); - int dirlen; + char *dir; + size_t dirlen; int status; + dir = strdup (orig_dir); if (dir == NULL) { char errbuf[1024]; @@ -179,39 +186,41 @@ static int change_basedir (const char *orig_dir) return (-1); status = chdir (dir); - free (dir); + if (status == 0) + { + free (dir); + return (0); + } + else if (errno != ENOENT) + { + char errbuf[1024]; + ERROR ("change_basedir: chdir (%s): %s", dir, + sstrerror (errno, errbuf, sizeof (errbuf))); + free (dir); + return (-1); + } + status = mkdir (dir, S_IRWXU | S_IRWXG | S_IRWXO); if (status != 0) { - if (errno == ENOENT) - { - if (mkdir (orig_dir, 0755) == -1) - { - char errbuf[1024]; - ERROR ("change_basedir: mkdir (%s): %s", orig_dir, - sstrerror (errno, errbuf, - sizeof (errbuf))); - return (-1); - } - else if (chdir (orig_dir) == -1) - { - char errbuf[1024]; - ERROR ("chdir (%s): %s", orig_dir, - sstrerror (errno, errbuf, - sizeof (errbuf))); - return (-1); - } - } - else - { - char errbuf[1024]; - ERROR ("chdir (%s): %s", orig_dir, - sstrerror (errno, errbuf, - sizeof (errbuf))); - return (-1); - } + char errbuf[1024]; + ERROR ("change_basedir: mkdir (%s): %s", dir, + sstrerror (errno, errbuf, sizeof (errbuf))); + free (dir); + return (-1); } + status = chdir (dir); + if (status != 0) + { + char errbuf[1024]; + ERROR ("change_basedir: chdir (%s): %s", dir, + sstrerror (errno, errbuf, sizeof (errbuf))); + free (dir); + return (-1); + } + + free (dir); return (0); } /* static int change_basedir (char *dir) */ @@ -244,7 +253,7 @@ static void update_kstat (void) /* 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" @@ -253,6 +262,7 @@ static void exit_usage (void) " -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 @@ -260,14 +270,15 @@ static void exit_usage (void) #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 \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) { @@ -298,21 +309,15 @@ static int do_init (void) static int do_loop (void) { - struct timeval tv_now; - struct timeval tv_next; - struct timespec ts_wait; + cdtime_t interval = cf_get_default_interval (); + cdtime_t wait_until; + + wait_until = cdtime () + interval; 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 (); @@ -321,24 +326,20 @@ static int do_loop (void) /* Issue all plugins */ plugin_read_all (); - if (gettimeofday (&tv_now, NULL) < 0) - { - char errbuf[1024]; - ERROR ("gettimeofday failed: %s", - sstrerror (errno, errbuf, - sizeof (errbuf))); - return (-1); - } - - if (timeval_sub_timespec (&tv_next, &tv_now, &ts_wait) != 0) + now = cdtime (); + if (now >= wait_until) { - 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; continue; } - while ((loop == 0) && (nanosleep (&ts_wait, &ts_wait) == -1)) + CDTIME_T_TO_TIMESPEC (wait_until - now, &ts_wait); + wait_until = wait_until + interval; + + while ((loop == 0) && (nanosleep (&ts_wait, &ts_wait) != 0)) { if (errno != EINTR) { @@ -351,7 +352,6 @@ static int do_loop (void) } } /* while (loop == 0) */ - DEBUG ("return (0);"); return (0); } /* int do_loop */ @@ -398,19 +398,21 @@ int main (int argc, char **argv) struct sigaction sig_pipe_action; char *configfile = CONFIGFILE; int test_config = 0; + int test_readall = 0; const char *basedir; #if COLLECT_DAEMON 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 @@ -427,6 +429,13 @@ int main (int argc, char **argv) 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); @@ -436,11 +445,18 @@ int main (int argc, char **argv) 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); + + 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 @@ -575,10 +591,20 @@ int main (int argc, char **argv) * 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 (); @@ -587,5 +613,5 @@ int main (int argc, char **argv) pidfile_remove (); #endif /* COLLECT_DAEMON */ - return (0); + return (exit_status); } /* int main */