X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Ftools%2Fsysdbd%2Fmain.c;h=c7fad8027b4a0da2fe6175af33001ca6f9fd7145;hb=eb349b8f286dcd4e587c1229fb78c8d6ad41d1c9;hp=195d494ffc77811e127ee7834974b4778466edf5;hpb=edba65afec8c547fb6c02346eda68595ce9a5839;p=sysdb.git diff --git a/src/tools/sysdbd/main.c b/src/tools/sysdbd/main.c index 195d494..c7fad80 100644 --- a/src/tools/sysdbd/main.c +++ b/src/tools/sysdbd/main.c @@ -34,6 +34,7 @@ #include "core/store.h" #include "utils/error.h" +#include "frontend/connection.h" #include "frontend/sock.h" #include "tools/sysdbd/configfile.h" @@ -59,6 +60,9 @@ #include +#include +#include + #ifndef CONFIGFILE # define CONFIGFILE SYSCONFDIR"/sysdb/sysdbd.conf" #endif @@ -70,6 +74,9 @@ 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 *config_filename = NULL; +static int reconfigure = 0; + static char *default_listen_addresses[] = { DEFAULT_SOCKET, }; @@ -80,6 +87,15 @@ sigintterm_handler(int __attribute__((unused)) signo) frontend_main_loop.do_loop = 0; } /* sigintterm_handler */ +static void +sighup_handler(int __attribute__((unused)) signo) +{ + /* (temporarily) terminate the plugin loop ... */ + frontend_main_loop.do_loop = 0; + /* ... and tell the main loop to reconfigure the daemon */ + reconfigure = 1; +} /* sighup_handler */ + static void exit_usage(char *name, int status) { @@ -105,7 +121,7 @@ exit_version(void) printf("SysDBd version "SDB_VERSION_STRING SDB_VERSION_EXTRA", " "built "BUILD_DATE"\n" "using libsysdb version %s%s\n" - "Copyright (C) 2012-2013 "PACKAGE_MAINTAINER"\n" + "Copyright (C) 2012-2014 "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 " @@ -167,6 +183,46 @@ daemonize(void) return 0; } /* daemonize */ +static int +configure(void) +{ + int status; + + 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."); + return 1; + } + + if (! listen_addresses) { + listen_addresses = default_listen_addresses; + listen_addresses_num = SDB_STATIC_ARRAY_LEN(default_listen_addresses); + } + return 0; +} /* configure */ + +static int +do_reconfigure(void) +{ + int status; + + sdb_log(SDB_LOG_INFO, "Reconfiguring SysDB daemon"); + + if (listen_addresses != default_listen_addresses) + daemon_free_listen_addresses(); + listen_addresses = NULL; + + sdb_plugin_reconfigure_init(); + if ((status = configure())) + return status; + sdb_plugin_init_all(); + sdb_plugin_reconfigure_finish(); + return 0; +} /* do_reconfigure */ + static void * backend_handler(void __attribute__((unused)) *data) { @@ -175,15 +231,86 @@ backend_handler(void __attribute__((unused)) *data) return NULL; } /* backend_handler */ +static int +main_loop(void) +{ + sdb_fe_socket_t *sock = sdb_fe_sock_create(); + pthread_t backend_thread; + + int status = 0; + + while (status == 0) { + size_t i; + + plugin_main_loop.do_loop = 1; + frontend_main_loop.do_loop = 1; + + 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; + break; + } + + for (i = 0; i < listen_addresses_num; ++i) { + if (sdb_fe_sock_add_listener(sock, listen_addresses[i], NULL)) { + status = 1; + break; + } + } + + /* break on error */ + if (status) + break; + + sdb_log(SDB_LOG_INFO, "SysDB daemon "SDB_VERSION_STRING + SDB_VERSION_EXTRA " (libsysdb %s%s, pid %i) initialized " + "successfully", sdb_version_string(), sdb_version_extra(), + (int)getpid()); + + sdb_connection_enable_logging(); + 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; + /* send a signal to interrupt the sleep call + * and make the thread shut down faster */ + pthread_kill(backend_thread, SIGINT); + pthread_join(backend_thread, NULL); + + if (! reconfigure) + break; + + reconfigure = 0; + sdb_fe_sock_clear_listeners(sock); + if (do_reconfigure()) { + sdb_log(SDB_LOG_ERR, "Reconfiguration failed"); + status = 1; + break; + } + } + + /* clean up in case we exited the loop on error */ + plugin_main_loop.do_loop = 0; + frontend_main_loop.do_loop = 0; + pthread_kill(backend_thread, SIGINT); + pthread_join(backend_thread, NULL); + + sdb_fe_sock_destroy(sock); + return status; +} /* main_loop */ + int main(int argc, char **argv) { - char *config_filename = NULL; - _Bool do_daemonize = 1; - - pthread_t backend_thread; + bool do_daemonize = 1; struct sigaction sa_intterm; + struct sigaction sa_hup; int status; sdb_error_set_logger(sdb_plugin_log); @@ -218,20 +345,8 @@ main(int argc, char **argv) if (! config_filename) config_filename = CONFIGFILE; - - 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); - } + if ((status = configure())) + exit(status); memset(&sa_intterm, 0, sizeof(sa_intterm)); sa_intterm.sa_handler = sigintterm_handler; @@ -254,44 +369,35 @@ main(int argc, char **argv) if (daemonize()) exit(1); - sdb_log(SDB_LOG_INFO, "SysDB daemon "SDB_VERSION_STRING - SDB_VERSION_EXTRA " (pid %i) initialized successfully", - (int)getpid()); + SSL_load_error_strings(); + OpenSSL_add_ssl_algorithms(); sdb_plugin_init_all(); plugin_main_loop.default_interval = SECS_TO_SDB_TIME(60); - 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))); + memset(&sa_hup, 0, sizeof(sa_hup)); + sa_hup.sa_handler = sighup_handler; + sa_hup.sa_flags = 0; - plugin_main_loop.do_loop = 0; + if (sigaction(SIGHUP, &sa_hup, /* old action */ NULL)) { + char errbuf[1024]; + sdb_log(SDB_LOG_ERR, "Failed to install signal handler for " + "SIGHUP: %s", sdb_strerror(errno, errbuf, sizeof(errbuf))); + exit(1); } - else { - size_t i; - - 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); + /* ignore, we see this, for example, if a client disconnects without + * closing the connection cleanly */ + signal(SIGPIPE, SIG_IGN); - 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); - } + status = main_loop(); sdb_log(SDB_LOG_INFO, "Shutting down SysDB daemon "SDB_VERSION_STRING SDB_VERSION_EXTRA" (pid %i)", (int)getpid()); - return 0; + sdb_plugin_shutdown_all(); + + ERR_free_strings(); + return status; } /* main */ /* vim: set tw=78 sw=4 ts=4 noexpandtab : */