Code

Merged branch 'master' of git://git.tokkee.org/sysdb.
[sysdb.git] / src / daemon / sysdbd.c
index 5a901a223bf432ad02b542bba11c1b2e32ea03a3..21350f308b15bc75d624baed8f99b878011caf5c 100644 (file)
@@ -33,7 +33,8 @@
 #include "core/plugin.h"
 #include "core/store.h"
 #include "utils/error.h"
-#include "utils/string.h"
+
+#include "frontend/sock.h"
 
 #include "daemon/config.h"
 
 
 #include <unistd.h>
 
+#include <pthread.h>
+
 #ifndef CONFIGFILE
 #      define CONFIGFILE SYSCONFDIR"/sysdb/sysdbd.conf"
 #endif
 
+#ifndef DEFAULT_SOCKET
+#      define DEFAULT_SOCKET "unix:"LOCALSTATEDIR"/run/sysdbd.sock"
+#endif
+
 static sdb_plugin_loop_t plugin_main_loop = SDB_PLUGIN_LOOP_INIT;
+static sdb_fe_loop_t frontend_main_loop = SDB_FE_LOOP_INIT;
+
+static char *default_listen_addresses[] = {
+       DEFAULT_SOCKET,
+};
 
 static void
 sigintterm_handler(int __attribute__((unused)) signo)
 {
-       plugin_main_loop.do_loop = 0;
+       frontend_main_loop.do_loop = 0;
 } /* sigintterm_handler */
 
 static void
@@ -77,7 +89,7 @@ exit_usage(char *name, int status)
 "\nOptions:\n"
 "  -C FILE   the main configuration file\n"
 "            default: "CONFIGFILE"\n"
-"  -d        run in background (daemonize)\n"
+"  -D        do not run in background (daemonize)\n"
 "\n"
 "  -h        display this help and exit\n"
 "  -V        display the version number and copyright\n"
@@ -92,8 +104,8 @@ exit_version(void)
 {
        printf("SysDBd version "SDB_VERSION_STRING SDB_VERSION_EXTRA", "
                        "built "BUILD_DATE"\n"
-                       "using libsysdb verion %s%s\n"
-                       "Copyright (C) 2012 "PACKAGE_MAINTAINER"\n"
+                       "using libsysdb version %s%s\n"
+                       "Copyright (C) 2012-2013 "PACKAGE_MAINTAINER"\n"
 
                        "\nThis is free software under the terms of the BSD license, see "
                        "the source for\ncopying conditions. There is NO WARRANTY; not "
@@ -109,7 +121,7 @@ daemonize(void)
 
        if ((pid = fork()) < 0) {
                char errbuf[1024];
-               sdb_log(SDB_LOG_ERR, "Failed to fork to background: %s\n",
+               sdb_log(SDB_LOG_ERR, "Failed to fork to background: %s",
                                sdb_strerror(errno, errbuf, sizeof(errbuf)));
                return errno;
        }
@@ -121,7 +133,7 @@ daemonize(void)
        if (chdir("/")) {
                char errbuf[1024];
                sdb_log(SDB_LOG_ERR, "Failed to change working directory to "
-                               "the root directory: %s\n",
+                               "the root directory: %s",
                                sdb_strerror(errno, errbuf, sizeof(errbuf)));
                return errno;
        }
@@ -132,39 +144,52 @@ daemonize(void)
        close(0);
        if (open("/dev/null", O_RDWR)) {
                char errbuf[1024];
-               sdb_log(SDB_LOG_ERR, "Failed to connect stdin to '/dev/null': "
-                               "%s\n", sdb_strerror(errno, errbuf, sizeof(errbuf)));
+               sdb_log(SDB_LOG_ERR, "Failed to connect stdin to '/dev/null': %s",
+                               sdb_strerror(errno, errbuf, sizeof(errbuf)));
                return errno;
        }
 
        close(1);
        if (dup(0) != 1) {
                char errbuf[1024];
-               sdb_log(SDB_LOG_ERR, "Could not connect stdout to '/dev/null': "
-                               "%s\n", sdb_strerror(errno, errbuf, sizeof(errbuf)));
+               sdb_log(SDB_LOG_ERR, "Could not connect stdout to '/dev/null': %s",
+                               sdb_strerror(errno, errbuf, sizeof(errbuf)));
                return errno;
        }
 
        close(2);
        if (dup(0) != 2) {
                char errbuf[1024];
-               sdb_log(SDB_LOG_ERR, "Could not connect stderr to '/dev/null': "
-                               "%s\n", sdb_strerror(errno, errbuf, sizeof(errbuf)));
+               sdb_log(SDB_LOG_ERR, "Could not connect stderr to '/dev/null': %s",
+                               sdb_strerror(errno, errbuf, sizeof(errbuf)));
                return errno;
        }
        return 0;
 } /* daemonize */
 
+static void *
+backend_handler(void __attribute__((unused)) *data)
+{
+       sdb_plugin_collector_loop(&plugin_main_loop);
+       sdb_log(SDB_LOG_INFO, "Shutting down backend thread");
+       return NULL;
+} /* backend_handler */
+
 int
 main(int argc, char **argv)
 {
        char *config_filename = NULL;
-       _Bool do_daemonize = 0;
+       _Bool do_daemonize = 1;
+
+       pthread_t backend_thread;
 
        struct sigaction sa_intterm;
+       int status;
+
+       sdb_error_set_logger(sdb_plugin_log);
 
        while (42) {
-               int opt = getopt(argc, argv, "C:dhV");
+               int opt = getopt(argc, argv, "C:DhV");
 
                if (-1 == opt)
                        break;
@@ -173,8 +198,8 @@ main(int argc, char **argv)
                        case 'C':
                                config_filename = optarg;
                                break;
-                       case 'd':
-                               do_daemonize = 1;
+                       case 'D':
+                               do_daemonize = 0;
                                break;
 
                        case 'h':
@@ -194,11 +219,20 @@ main(int argc, char **argv)
        if (! config_filename)
                config_filename = CONFIGFILE;
 
-       if (daemon_parse_config(config_filename)) {
-               sdb_log(SDB_LOG_ERR, "Failed to parse configuration file.\n");
+       if ((status = daemon_parse_config(config_filename))) {
+               if (status > 0)
+                       sdb_log(SDB_LOG_ERR, "Failed to parse configuration file.");
+               else
+                       sdb_log(SDB_LOG_ERR, "Failed to load configuration file.\n"
+                                       "\tCheck other error messages for details.");
                exit(1);
        }
 
+       if (! listen_addresses) {
+               listen_addresses = default_listen_addresses;
+               listen_addresses_num = SDB_STATIC_ARRAY_LEN(default_listen_addresses);
+       }
+
        memset(&sa_intterm, 0, sizeof(sa_intterm));
        sa_intterm.sa_handler = sigintterm_handler;
        sa_intterm.sa_flags = 0;
@@ -206,13 +240,13 @@ main(int argc, char **argv)
        if (sigaction(SIGINT, &sa_intterm, /* old action */ NULL)) {
                char errbuf[1024];
                sdb_log(SDB_LOG_ERR, "Failed to install signal handler for "
-                               "SIGINT: %s\n", sdb_strerror(errno, errbuf, sizeof(errbuf)));
+                               "SIGINT: %s", sdb_strerror(errno, errbuf, sizeof(errbuf)));
                exit(1);
        }
        if (sigaction(SIGTERM, &sa_intterm, /* old action */ NULL)) {
                char errbuf[1024];
                sdb_log(SDB_LOG_ERR, "Failed to install signal handler for "
-                               "SIGTERM: %s\n", sdb_strerror(errno, errbuf, sizeof(errbuf)));
+                               "SIGTERM: %s", sdb_strerror(errno, errbuf, sizeof(errbuf)));
                exit(1);
        }
 
@@ -221,17 +255,42 @@ main(int argc, char **argv)
                        exit(1);
 
        sdb_log(SDB_LOG_INFO, "SysDB daemon "SDB_VERSION_STRING
-                       SDB_VERSION_EXTRA " (pid %i) initialized successfully\n",
+                       SDB_VERSION_EXTRA " (pid %i) initialized successfully",
                        (int)getpid());
 
        sdb_plugin_init_all();
-       sdb_plugin_collector_loop(&plugin_main_loop);
+       plugin_main_loop.default_interval = SECS_TO_SDB_TIME(60);
 
-       sdb_log(SDB_LOG_INFO, "Shutting down SysDB daemon "SDB_VERSION_STRING
-                       SDB_VERSION_EXTRA" (pid %i)\n", (int)getpid());
+       memset(&backend_thread, 0, sizeof(backend_thread));
+       if (pthread_create(&backend_thread, /* attr = */ NULL,
+                               backend_handler, /* arg = */ NULL)) {
+               char buf[1024];
+               sdb_log(SDB_LOG_ERR, "Failed to create backend handler thread: %s",
+                               sdb_strerror(errno, buf, sizeof(buf)));
+
+               plugin_main_loop.do_loop = 0;
+       }
+       else {
+               size_t i;
 
-       fprintf(stderr, "Store dump:\n");
-       sdb_store_dump(stderr);
+               sdb_fe_socket_t *sock = sdb_fe_sock_create();
+               for (i = 0; i < listen_addresses_num; ++i)
+                       if (sdb_fe_sock_add_listener(sock, listen_addresses[i]))
+                               break;
+
+               /* break on error */
+               if (i >= listen_addresses_num)
+                       sdb_fe_sock_listen_and_serve(sock, &frontend_main_loop);
+
+               sdb_log(SDB_LOG_INFO, "Waiting for backend thread to terminate");
+               plugin_main_loop.do_loop = 0;
+               pthread_kill(backend_thread, SIGINT);
+               pthread_join(backend_thread, NULL);
+               sdb_fe_sock_destroy(sock);
+       }
+
+       sdb_log(SDB_LOG_INFO, "Shutting down SysDB daemon "SDB_VERSION_STRING
+                       SDB_VERSION_EXTRA" (pid %i)", (int)getpid());
        return 0;
 } /* main */