]> git.ipfire.org Git - thirdparty/collectd.git/commitdiff
Notify upstart/systemd after initialization is complete. 4164/head
authorFlorian Forster <octo@collectd.org>
Fri, 24 Nov 2023 22:31:03 +0000 (23:31 +0100)
committerFlorian Forster <octo@collectd.org>
Sat, 25 Nov 2023 13:26:47 +0000 (14:26 +0100)
Fixes: #4152
src/daemon/cmd.c
src/daemon/cmd.h
src/daemon/collectd.c

index 09aee6abb16268c3021cb72d2d2979a99e105f0b..4ca0cbab394508e60c2cedba258f0707720f974f 100644 (file)
@@ -83,42 +83,45 @@ static int pidfile_remove(void) {
 #endif /* COLLECT_DAEMON */
 
 #ifdef KERNEL_LINUX
-static int notify_upstart(void) {
+static bool using_upstart(void) {
   char const *upstart_job = getenv("UPSTART_JOB");
-
   if (upstart_job == NULL)
-    return 0;
+    return false;
 
   if (strcmp(upstart_job, "collectd") != 0) {
     WARNING("Environment specifies unexpected UPSTART_JOB=\"%s\", expected "
             "\"collectd\". Ignoring the variable.",
             upstart_job);
-    return 0;
+    return false;
   }
 
+  return true;
+}
+
+static void notify_upstart(void) {
   NOTICE("Upstart detected, stopping now to signal readiness.");
   raise(SIGSTOP);
   unsetenv("UPSTART_JOB");
-
-  return 1;
 }
 
-static int notify_systemd(void) {
-  size_t su_size;
+static bool using_systemd(void) {
   const char *notifysocket = getenv("NOTIFY_SOCKET");
   if (notifysocket == NULL)
-    return 0;
+    return false;
 
   if ((strlen(notifysocket) < 2) ||
       ((notifysocket[0] != '@') && (notifysocket[0] != '/'))) {
     ERROR("invalid notification socket NOTIFY_SOCKET=\"%s\": path must be "
           "absolute",
           notifysocket);
-    return 0;
+    return false;
   }
-  NOTICE("Systemd detected, trying to signal readiness.");
 
-  unsetenv("NOTIFY_SOCKET");
+  return true;
+}
+
+static void notify_systemd(void) {
+  NOTICE("Systemd detected, trying to signal readiness.");
 
   int fd;
 #if defined(SOCK_CLOEXEC)
@@ -128,11 +131,15 @@ static int notify_systemd(void) {
 #endif
   if (fd < 0) {
     ERROR("creating UNIX socket failed: %s", STRERRNO);
-    return 0;
+    return;
   }
 
-  struct sockaddr_un su = {0};
-  su.sun_family = AF_UNIX;
+  struct sockaddr_un su = {
+      .sun_family = AF_UNIX,
+  };
+
+  const char *notifysocket = getenv("NOTIFY_SOCKET");
+  size_t su_size = 0;
   if (notifysocket[0] != '@') {
     /* regular UNIX socket */
     sstrncpy(su.sun_path, notifysocket, sizeof(su.sun_path));
@@ -154,12 +161,11 @@ static int notify_systemd(void) {
              (socklen_t)su_size) < 0) {
     ERROR("sendto(\"%s\") failed: %s", notifysocket, STRERRNO);
     close(fd);
-    return 0;
+    return;
   }
 
   unsetenv("NOTIFY_SOCKET");
   close(fd);
-  return 1;
 }
 #endif /* KERNEL_LINUX */
 
@@ -178,11 +184,13 @@ int main(int argc, char **argv) {
    * Only daemonize if we're not being supervised
    * by upstart or systemd (when using Linux).
    */
-  if (config.daemonize
 #ifdef KERNEL_LINUX
-      && notify_upstart() == 0 && notify_systemd() == 0
+  if (using_upstart() || using_systemd()) {
+    config.daemonize = false;
+  }
 #endif
-  ) {
+
+  if (config.daemonize) {
     pid_t pid;
     if ((pid = fork()) == -1) {
       /* error */
@@ -260,7 +268,16 @@ int main(int argc, char **argv) {
     return 1;
   }
 
-  int exit_status = run_loop(config.test_readall);
+  void (*notify_func)(void) = NULL;
+#ifdef KERNEL_LINUX
+  if (using_upstart()) {
+    notify_func = notify_upstart;
+  } else if (using_systemd()) {
+    notify_func = notify_systemd;
+  }
+#endif
+
+  int exit_status = run_loop(config.test_readall, notify_func);
 
 #if COLLECT_DAEMON
   if (config.daemonize)
index 152ee63e3dd0d261c09ecf23b378758c5fbd0d76..97ddacc9b41371f6af576a86418804864b475120 100644 (file)
@@ -36,6 +36,6 @@ struct cmdline_config {
 
 void stop_collectd(void);
 struct cmdline_config init_config(int argc, char **argv);
-int run_loop(bool test_readall);
+int run_loop(bool test_readall, void (*notify_func)(void));
 
 #endif /* CMD_H */
index cad82d4d5ad37aeb5f44dcc2c27b7790940bd3f6..7e50811302ba2de5098c0e83f974c1ef05143ca9 100644 (file)
@@ -409,7 +409,7 @@ struct cmdline_config init_config(int argc, char **argv) {
   return config;
 }
 
-int run_loop(bool test_readall) {
+int run_loop(bool test_readall, void (*notify_func)(void)) {
   int exit_status = 0;
 
   if (do_init() != 0) {
@@ -423,6 +423,10 @@ int run_loop(bool test_readall) {
       exit_status = 1;
     }
   } else {
+    if (notify_func != NULL) {
+      /* notify upstart or systemd that initialization has completed. */
+      notify_func();
+    }
     INFO("Initialization complete, entering read-loop.");
     do_loop();
   }