Reload the conf on SIGUSR1/2

This commit is contained in:
Florent Le Coz
2014-02-19 02:24:00 +01:00
parent 754dd898a7
commit 8fd2746696
3 changed files with 36 additions and 8 deletions
+4
View File
@@ -57,6 +57,10 @@ The configuration file uses a simple format of the form
from 0 to 3. 0 is debug, 1 is info, 2 is warning, 3 is error. The from 0 to 3. 0 is debug, 1 is info, 2 is warning, 3 is error. The
default is 0, but a more practical value for production use is 1. default is 0, but a more practical value for production use is 1.
The configuration can be re-read at runtime (you can for example change the
log level without having to restart biboumi) by sending SIGUSR1 or SIGUSR2
(see kill(1)) to the process.
USAGE USAGE
----- -----
-1
View File
@@ -56,7 +56,6 @@ void Config::connect(t_config_changed_callback callback)
void Config::close() void Config::close()
{ {
Config* self = Config::instance().get(); Config* self = Config::instance().get();
self->save_to_file();
self->values.clear(); self->values.clear();
Config::instance().reset(); Config::instance().reset();
} }
+32 -7
View File
@@ -10,7 +10,9 @@
#include <signal.h> #include <signal.h>
// A flag set by the SIGINT signal handler. // A flag set by the SIGINT signal handler.
volatile std::atomic<bool> stop(false); static volatile std::atomic<bool> stop(false);
// Flag set by the SIGUSR1/2 signal handler.
static volatile std::atomic<bool> reload(false);
// A flag indicating that we are wanting to exit the process. i.e: if this // A flag indicating that we are wanting to exit the process. i.e: if this
// flag is set and all connections are closed, we can exit properly. // flag is set and all connections are closed, we can exit properly.
static bool exiting = false; static bool exiting = false;
@@ -35,6 +37,11 @@ static void sigint_handler(int, siginfo_t*, void*)
stop = true; stop = true;
} }
static void sigusr_handler(int, siginfo_t*, void*)
{
reload = true;
}
int main(int ac, char** av) int main(int ac, char** av)
{ {
if (ac > 1) if (ac > 1)
@@ -69,14 +76,21 @@ int main(int ac, char** av)
// config // config
sigset_t mask; sigset_t mask;
sigemptyset(&mask); sigemptyset(&mask);
struct sigaction on_sig; struct sigaction on_sigint;
on_sig.sa_sigaction = &sigint_handler; on_sigint.sa_sigaction = &sigint_handler;
on_sig.sa_mask = mask; on_sigint.sa_mask = mask;
// we want to catch that signal only once. // we want to catch that signal only once.
// Sending SIGINT again will "force" an exit // Sending SIGINT again will "force" an exit
on_sig.sa_flags = SA_RESETHAND; on_sigint.sa_flags = SA_RESETHAND;
sigaction(SIGINT, &on_sig, nullptr); sigaction(SIGINT, &on_sigint, nullptr);
sigaction(SIGTERM, &on_sig, nullptr); sigaction(SIGTERM, &on_sigint, nullptr);
// Install a signal to reload the config on SIGUSR1/2
struct sigaction on_sigusr;
on_sigusr.sa_sigaction = &sigusr_handler;
on_sigusr.sa_mask = mask;
sigaction(SIGUSR1, &on_sigusr, nullptr);
sigaction(SIGUSR2, &on_sigusr, nullptr);
const std::chrono::milliseconds timeout(-1); const std::chrono::milliseconds timeout(-1);
while (p.poll(timeout) != -1 || !exiting) while (p.poll(timeout) != -1 || !exiting)
@@ -91,6 +105,17 @@ int main(int ac, char** av)
stop = false; stop = false;
xmpp_component->shutdown(); xmpp_component->shutdown();
} }
if (reload)
{
// Closing the config will just force it to be reopened the next time
// a configuration option is needed
log_info("Signal received, reloading the config...");
Config::close();
// Destroy the logger instance, to be recreated the next time a log
// line needs to be written
Logger::instance().reset();
reload = false;
}
// If the only existing connection is the one to the XMPP component: // If the only existing connection is the one to the XMPP component:
// close the XMPP stream. // close the XMPP stream.
if (exiting && p.size() == 1 && xmpp_component->is_document_open()) if (exiting && p.size() == 1 && xmpp_component->is_document_open())