]> arthur.barton.de Git - netdata.git/blobdiff - src/main.c
ensure the database is always saved on exit
[netdata.git] / src / main.c
index 1a81993873f9092590cc2c38ba6b73f8182d5a4c..c4869218f76fec08685058321d23f61f8c633d73 100644 (file)
@@ -8,35 +8,29 @@ void netdata_cleanup_and_exit(int ret) {
     error_log_limit_unlimited();
 
     debug(D_EXIT, "Called: netdata_cleanup_and_exit()");
-#ifdef NETDATA_INTERNAL_CHECKS
-    rrdset_free_all();
-#else
+
+    // save the database
     rrdset_save_all();
-#endif
-    // kill_childs();
 
+    // unlink the pid
     if(pidfile[0]) {
         if(unlink(pidfile) != 0)
             error("Cannot unlink pidfile '%s'.", pidfile);
     }
 
-    info("NetData exiting. Bye bye...");
-    exit(ret);
-}
-
-struct netdata_static_thread {
-    char *name;
-
-    char *config_section;
-    char *config_name;
+#ifdef NETDATA_INTERNAL_CHECKS
+    // kill all childs
+    kill_childs();
 
-    int enabled;
+    // free all memory
+    rrdset_free_all();
+#endif
 
-    pthread_t *thread;
+    info("netdata exiting. Bye bye...");
+    exit(ret);
+}
 
-    void (*init_routine) (void);
-    void *(*start_routine) (void *);
-} static_threads[] = {
+struct netdata_static_thread static_threads[] = {
 #ifdef INTERNAL_PLUGIN_NFACCT
 // nfacct requires root access
     // so, we build it as an external plugin with setuid to root
@@ -45,9 +39,16 @@ struct netdata_static_thread {
 
     {"tc",                 "plugins",   "tc",         1, NULL, NULL, tc_main},
     {"idlejitter",         "plugins",   "idlejitter", 1, NULL, NULL, cpuidlejitter_main},
+#if defined(__FreeBSD__)
+    {"freebsd",            "plugins",   "freebsd",    1, NULL, NULL, freebsd_main},
+#elif defined(__APPLE__)
+    {"macos",              "plugins",   "macos",      1, NULL, NULL, macos_main},
+#else
     {"proc",               "plugins",   "proc",       1, NULL, NULL, proc_main},
+#endif /* __FreeBSD__, __APPLE__*/
     {"cgroups",            "plugins",   "cgroups",    1, NULL, NULL, cgroups_main},
     {"check",              "plugins",   "checks",     0, NULL, NULL, checks_main},
+    {"backends",            NULL,       NULL,         1, NULL, NULL, backends_main},
     {"health",              NULL,       NULL,         1, NULL, NULL, health_main},
     {"plugins.d",           NULL,       NULL,         1, NULL, NULL, pluginsd_main},
     {"web",                 NULL,       NULL,         1, NULL, NULL, socket_listen_main_multi_threaded},
@@ -149,27 +150,32 @@ int killpid(pid_t pid, int sig)
 
 void kill_childs()
 {
+    error_log_limit_unlimited();
+
     siginfo_t info;
 
     struct web_client *w;
     for(w = web_clients; w ; w = w->next) {
-        debug(D_EXIT, "Stopping web client %s", w->client_ip);
+        info("Stopping web client %s", w->client_ip);
         pthread_cancel(w->thread);
-        pthread_join(w->thread, NULL);
+        // it is detached
+        // pthread_join(w->thread, NULL);
     }
 
     int i;
     for (i = 0; static_threads[i].name != NULL ; i++) {
-        if(static_threads[i].thread) {
-            debug(D_EXIT, "Stopping %s thread", static_threads[i].name);
+        if(static_threads[i].enabled && static_threads[i].thread) {
+            info("Stopping %s thread", static_threads[i].name);
             pthread_cancel(*static_threads[i].thread);
-            pthread_join(*static_threads[i].thread, NULL);
+            // it is detached
+            // pthread_join(*static_threads[i].thread, NULL);
+
             static_threads[i].thread = NULL;
         }
     }
 
     if(tc_child_pid) {
-        debug(D_EXIT, "Killing tc-qos-helper procees");
+        info("Killing tc-qos-helper process %d", tc_child_pid);
         if(killpid(tc_child_pid, SIGTERM) != -1)
             waitid(P_PID, (id_t) tc_child_pid, &info, WEXITED);
     }
@@ -177,22 +183,33 @@ void kill_childs()
 
     struct plugind *cd;
     for(cd = pluginsd_root ; cd ; cd = cd->next) {
-        debug(D_EXIT, "Stopping %s plugin thread", cd->id);
-        pthread_cancel(cd->thread);
-        pthread_join(cd->thread, NULL);
-
-        if(cd->pid && !cd->obsolete) {
-            debug(D_EXIT, "killing %s plugin process", cd->id);
-            if(killpid(cd->pid, SIGTERM) != -1)
-                waitid(P_PID, (id_t) cd->pid, &info, WEXITED);
+        if(cd->enabled && !cd->obsolete) {
+            if(cd->thread != (pthread_t)NULL) {
+                info("Stopping %s plugin thread", cd->id);
+                pthread_cancel(cd->thread);
+                // they are detached
+                // pthread_join(cd->thread, NULL);
+                cd->thread = (pthread_t)NULL;
+            }
+
+            if(cd->pid) {
+                info("killing %s plugin child process pid %d", cd->id, cd->pid);
+                if(killpid(cd->pid, SIGTERM) != -1)
+                    waitid(P_PID, (id_t) cd->pid, &info, WEXITED);
+
+                cd->pid = 0;
+            }
+
+            cd->obsolete = 1;
         }
     }
 
     // if, for any reason there is any child exited
     // catch it here
+    info("Cleaning up an other children");
     waitid(P_PID, 0, &info, WEXITED|WNOHANG);
 
-    debug(D_EXIT, "All threads/childs stopped.");
+    info("All threads/childs stopped.");
 }
 
 struct option_def options[] = {
@@ -462,7 +479,9 @@ int main(int argc, char **argv)
             if(setrlimit(RLIMIT_CORE, &rl) != 0)
                 error("Cannot request unlimited core dumps for debugging... Proceeding anyway...");
 
+#if !(defined(__FreeBSD__) || defined(__APPLE__))
             prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
+#endif /* __FreeBSD__ || __APPLE__*/
         }
 
         // --------------------------------------------------------------------
@@ -637,16 +656,17 @@ int main(int argc, char **argv)
         struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY };
         if(setrlimit(RLIMIT_CORE, &rl) != 0)
             error("Cannot request unlimited core dumps for debugging... Proceeding anyway...");
+#if !(defined(__FreeBSD__) || defined(__APPLE__))
         prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
+#endif /* __FreeBSD__ || __APPLE__*/
     }
 #endif /* NETDATA_INTERNAL_CHECKS */
 
     // fork, switch user, create pid file, set process priority
     if(become_daemon(dont_fork, user) == -1)
-        fatal("Cannot demonize myself.");
-
-    info("NetData started on pid %d", getpid());
+        fatal("Cannot daemonize myself.");
 
+    info("netdata started on pid %d.", getpid());
 
     // ------------------------------------------------------------------------
     // get default pthread stack size
@@ -695,7 +715,7 @@ int main(int argc, char **argv)
 
             debug(D_SYSTEM, "Starting thread %s.", st->name);
 
-            if(pthread_create(st->thread, &attr, st->start_routine, NULL))
+            if(pthread_create(st->thread, &attr, st->start_routine, st))
                 error("failed to create new thread for %s.", st->name);
 
             else if(pthread_detach(*st->thread))
@@ -704,6 +724,8 @@ int main(int argc, char **argv)
         else debug(D_SYSTEM, "Not starting thread %s.", st->name);
     }
 
+    info("netdata initialization completed. Enjoy real-time performance monitoring!");
+
     // ------------------------------------------------------------------------
     // block signals while initializing threads.
     sigset_t sigset;