X-Git-Url: https://git.octo.it/?p=collectd.git;a=blobdiff_plain;f=src%2Fdaemon%2Fcollectd.c;h=a656b37dbb8a14f2873ca1d0582224ce27283a03;hp=9ab929b985521e38d40de49ea7ea98d236437985;hb=a0412f28fc15eb04a9a630678a97b6bce2d71fb1;hpb=6b649799dedd72b783e3c24b485fbf3eabd6039e diff --git a/src/daemon/collectd.c b/src/daemon/collectd.c index 9ab929b9..a656b37d 100644 --- a/src/daemon/collectd.c +++ b/src/daemon/collectd.c @@ -43,11 +43,15 @@ #include #endif +#if HAVE_KSTAT_H +#include +#endif + #ifndef COLLECTD_LOCALE #define COLLECTD_LOCALE "C" #endif -static int loop = 0; +static int loop; static void *do_flush(void __attribute__((unused)) * arg) { INFO("Flushing all data."); @@ -76,37 +80,41 @@ static void sig_usr1_handler(int __attribute__((unused)) signal) { } static int init_hostname(void) { - const char *str; - - struct addrinfo *ai_list; - int status; - - str = global_option_get("Hostname"); + const char *str = global_option_get("Hostname"); if ((str != NULL) && (str[0] != 0)) { - sstrncpy(hostname_g, str, hostname_g_size); + hostname_set(str); return 0; } - if (gethostname(hostname_g, hostname_g_size) != 0) { + long hostname_len = sysconf(_SC_HOST_NAME_MAX); + if (hostname_len == -1) { + hostname_len = NI_MAXHOST; + } + char hostname[hostname_len]; + + if (gethostname(hostname, hostname_len) != 0) { fprintf(stderr, "`gethostname' failed and no " "hostname was configured.\n"); return -1; } + hostname_set(hostname); + str = global_option_get("FQDNLookup"); if (IS_FALSE(str)) return 0; + struct addrinfo *ai_list; struct addrinfo ai_hints = {.ai_flags = AI_CANONNAME}; - status = getaddrinfo(hostname_g, NULL, &ai_hints, &ai_list); + int status = getaddrinfo(hostname, 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); + hostname); return -1; } @@ -115,7 +123,7 @@ static int init_hostname(void) { if (ai_ptr->ai_canonname == NULL) continue; - sstrncpy(hostname_g, ai_ptr->ai_canonname, hostname_g_size); + hostname_set(ai_ptr->ai_canonname); break; } @@ -148,15 +156,14 @@ static int init_global_variables(void) { return 0; } /* int init_global_variables */ -static int change_basedir(const char *orig_dir, _Bool create) { +static int change_basedir(const char *orig_dir, bool create) { 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))); + ERROR("strdup failed: %s", STRERRNO); return -1; } @@ -174,27 +181,21 @@ static int change_basedir(const char *orig_dir, _Bool create) { free(dir); return 0; } else if (!create || (errno != ENOENT)) { - char errbuf[1024]; - ERROR("change_basedir: chdir (%s): %s", dir, - sstrerror(errno, errbuf, sizeof(errbuf))); + ERROR("change_basedir: chdir (%s): %s", dir, STRERRNO); 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))); + ERROR("change_basedir: mkdir (%s): %s", dir, STRERRNO); 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))); + ERROR("change_basedir: chdir (%s): %s", dir, STRERRNO); free(dir); return -1; } @@ -204,6 +205,7 @@ static int change_basedir(const char *orig_dir, _Bool create) { } /* static int change_basedir (char *dir) */ #if HAVE_LIBKSTAT +extern kstat_ctl_t *kc; static void update_kstat(void) { if (kc == NULL) { if ((kc = kstat_open()) == NULL) @@ -318,8 +320,7 @@ static int do_loop(void) { while ((loop == 0) && (nanosleep(&ts_wait, &ts_wait) != 0)) { if (errno != EINTR) { - char errbuf[1024]; - ERROR("nanosleep failed: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + ERROR("nanosleep failed: %s", STRERRNO); return -1; } } @@ -338,8 +339,7 @@ static int pidfile_create(void) { 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))); + ERROR("fopen (%s): %s", file, STRERRNO); return 1; } @@ -372,7 +372,7 @@ static int notify_upstart(void) { return 0; } - NOTICE("Upstart detected, stopping now to signal readyness."); + NOTICE("Upstart detected, stopping now to signal readiness."); raise(SIGSTOP); unsetenv("UPSTART_JOB"); @@ -397,7 +397,7 @@ static int notify_systemd(void) { notifysocket); return 0; } - NOTICE("Systemd detected, trying to signal readyness."); + NOTICE("Systemd detected, trying to signal readiness."); unsetenv("NOTIFY_SOCKET"); @@ -407,9 +407,7 @@ static int notify_systemd(void) { 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))); + ERROR("creating UNIX socket failed: %s", STRERRNO); return 0; } @@ -432,9 +430,7 @@ static int notify_systemd(void) { 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))); + ERROR("sendto(\"%s\") failed: %s", notifysocket, STRERRNO); close(fd); return 0; } @@ -445,23 +441,19 @@ static int notify_systemd(void) { } #endif /* KERNEL_LINUX */ -int main(int argc, char **argv) { - const char *configfile = CONFIGFILE; - int test_config = 0; - int test_readall = 0; - const char *basedir; - _Bool opt_create_basedir = 1; -#if COLLECT_DAEMON - pid_t pid; - int daemonize = 1; -#endif - int exit_status = 0; +struct cmdline_config { + bool test_config; + bool test_readall; + bool create_basedir; + const char *configfile; + bool daemonize; +}; +static void read_cmdline(int argc, char **argv, struct cmdline_config *config) { /* read options */ while (1) { int c; - - c = getopt(argc, argv, "BhtTC:" + c = getopt(argc, argv, "htTC:" #if COLLECT_DAEMON "fP:" #endif @@ -472,19 +464,19 @@ int main(int argc, char **argv) { switch (c) { case 'B': - opt_create_basedir = 0; + config->create_basedir = false; break; case 'C': - configfile = optarg; + config->configfile = optarg; break; case 't': - test_config = 1; + config->test_config = true; break; case 'T': - test_readall = 1; + config->test_readall = true; global_option_set("ReadThreads", "-1", 1); #if COLLECT_DAEMON - daemonize = 0; + config->daemonize = false; #endif /* COLLECT_DAEMON */ break; #if COLLECT_DAEMON @@ -492,29 +484,26 @@ int main(int argc, char **argv) { global_option_set("PIDFile", optarg, 1); break; case 'f': - daemonize = 0; + config->daemonize = false; 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(); - +static int configure_collectd(struct cmdline_config *config) { + const char *basedir; /* * 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)) { + if (cf_read(config->configfile)) { fprintf(stderr, "Error: Reading the config file failed!\n" "Read the logs for details.\n"); return 1; @@ -528,23 +517,46 @@ int main(int argc, char **argv) { fprintf(stderr, "Don't have a basedir to use. This should not happen. Ever."); return 1; - } else if (change_basedir(basedir, opt_create_basedir)) { + } else if (change_basedir(basedir, config->create_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 + * Set global variables or, if that fails, 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); + return 1; + + return 0; +} + +int main(int argc, char **argv) { +#if COLLECT_DAEMON + pid_t pid; +#endif + int exit_status = 0; + + struct cmdline_config config = { + .daemonize = true, .create_basedir = true, .configfile = CONFIGFILE, + }; - if (test_config) + read_cmdline(argc, argv, &config); + + if (config.test_config) return 0; + if (optind < argc) + exit_usage(1); + + plugin_init_ctx(); + + if (configure_collectd(&config) != 0) + exit(EXIT_FAILURE); + #if COLLECT_DAEMON /* * fork off child @@ -557,7 +569,7 @@ int main(int argc, char **argv) { * Only daemonize if we're not being supervised * by upstart or systemd (when using Linux). */ - if (daemonize + if (config.daemonize #ifdef KERNEL_LINUX && notify_upstart() == 0 && notify_systemd() == 0 #endif @@ -566,8 +578,7 @@ int main(int argc, char **argv) { if ((pid = fork()) == -1) { /* error */ - char errbuf[1024]; - fprintf(stderr, "fork: %s", sstrerror(errno, errbuf, sizeof(errbuf))); + fprintf(stderr, "fork: %s", STRERRNO); return 1; } else if (pid != 0) { /* parent */ @@ -620,27 +631,24 @@ int main(int argc, char **argv) { 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))); + STRERRNO); 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))); + STRERRNO); 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))); + STRERRNO); return 1; } @@ -652,7 +660,7 @@ int main(int argc, char **argv) { exit_status = 1; } - if (test_readall) { + if (config.test_readall) { if (plugin_read_all_once() != 0) { ERROR("Error: one or more plugin read callbacks failed."); exit_status = 1;