X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fdaemon%2Fcollectd.c;h=fc52933111e79fec0c291d115618d4b57f6032e5;hb=5bf93412e903fb36943088e711031a013495ce11;hp=2e2d821aade194873c923ceabcf8951291d0dc69;hpb=0e363577f4d0a94bef1929f9d9829fb94765ec1e;p=collectd.git diff --git a/src/daemon/collectd.c b/src/daemon/collectd.c index 2e2d821a..fc529331 100644 --- a/src/daemon/collectd.c +++ b/src/daemon/collectd.c @@ -32,7 +32,7 @@ #include "configfile.h" #include -#include +#include #include #include @@ -191,13 +191,15 @@ static int change_basedir (const char *orig_dir) sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } - + dirlen = strlen (dir); while ((dirlen > 0) && (dir[dirlen - 1] == '/')) dir[--dirlen] = '\0'; - if (dirlen <= 0) + if (dirlen <= 0) { + free (dir); return (-1); + } status = chdir (dir); if (status == 0) @@ -269,8 +271,8 @@ static void update_kstat (void) */ static void exit_usage (int status) { - printf ("Usage: "PACKAGE" [OPTIONS]\n\n" - + printf ("Usage: "PACKAGE_NAME" [OPTIONS]\n\n" + "Available options:\n" " General:\n" " -C Configuration file.\n" @@ -288,7 +290,7 @@ static void exit_usage (int status) " PID file "PIDFILE"\n" " Plugin directory "PLUGINDIR"\n" " Data directory "PKGLOCALSTATEDIR"\n" - "\n"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"); exit (status); @@ -307,7 +309,11 @@ static int do_init (void) #endif #if HAVE_LIBSTATGRAB - if (sg_init ()) + if (sg_init ( +# if HAVE_LIBSTATGRAB_0_90 + 0 +# endif + )) { ERROR ("sg_init: %s", sg_str_error (sg_get_error ())); return (-1); @@ -403,12 +409,104 @@ static int pidfile_create (void) static int pidfile_remove (void) { const char *file = global_option_get ("PIDFile"); + if (file == NULL) + return 0; - DEBUG ("unlink (%s)", (file != NULL) ? file : ""); return (unlink (file)); } /* static int pidfile_remove (const char *file) */ #endif /* COLLECT_DAEMON */ +#ifdef KERNEL_LINUX +int notify_upstart (void) +{ + char const *upstart_job = getenv("UPSTART_JOB"); + + 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; + } + + NOTICE("Upstart detected, stopping now to signal readyness."); + raise(SIGSTOP); + unsetenv("UPSTART_JOB"); + + return 1; +} + +int notify_systemd (void) +{ + int fd; + const char *notifysocket; + struct sockaddr_un su; + 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"); + +#if defined(SOCK_CLOEXEC) + fd = socket (AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, /* protocol = */ 0); +#else + 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; + } + + memset (&su, 0, sizeof (su)); + 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"); + close(fd); + return 1; +} +#endif /* KERNEL_LINUX */ + int main (int argc, char **argv) { struct sigaction sig_int_action; @@ -525,7 +623,15 @@ int main (int argc, char **argv) sig_chld_action.sa_handler = SIG_IGN; sigaction (SIGCHLD, &sig_chld_action, NULL); - if (daemonize) + /* + * 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 +#endif + ) { if ((pid = fork ()) == -1) {