diff --git a/include/maxscale/maxscale.h b/include/maxscale/maxscale.h index 93d43bd19..e6b1a0abf 100644 --- a/include/maxscale/maxscale.h +++ b/include/maxscale/maxscale.h @@ -44,4 +44,14 @@ void maxscale_reset_starttime(void); time_t maxscale_started(void); int maxscale_uptime(void); +/** + * Initiate shutdown of MaxScale. + * + * This functions informs all threads that they should stop the + * processing and exit. + * + * @return How many times maxscale_shutdown() has been called. + */ +int maxscale_shutdown(void); + MXS_END_DECLS diff --git a/server/core/gateway.c b/server/core/gateway.c index 8b7b07d82..138bc60bd 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -181,7 +181,6 @@ static int set_user(const char* user); bool pid_file_exists(); void write_child_exit_code(int fd, int code); static bool change_cwd(); -void shutdown_server(); static void log_exit_status(); static bool daemonize(); static bool sniff_configuration(const char* filepath); @@ -288,20 +287,45 @@ static void sigusr1_handler (int i) } static const char shutdown_msg[] = "\n\nShutting down MaxScale\n\n"; +static const char patience_msg[] = + "\n" + "Patience is a virtue...\n" + "Shutdown in progress, but one more Ctrl-C or SIGTERM and MaxScale goes down,\n" + "no questions asked.\n"; static void sigterm_handler(int i) { last_signal = i; - shutdown_server(); - write(STDERR_FILENO, shutdown_msg, sizeof(shutdown_msg) - 1); + int n_shutdowns = maxscale_shutdown(); + + if (n_shutdowns == 1) + { + write(STDERR_FILENO, shutdown_msg, sizeof(shutdown_msg) - 1); + } + else + { + exit(EXIT_FAILURE); + } } static void sigint_handler(int i) { last_signal = i; - shutdown_server(); - write(STDERR_FILENO, shutdown_msg, sizeof(shutdown_msg) - 1); + int n_shutdowns = maxscale_shutdown(); + + if (n_shutdowns == 1) + { + write(STDERR_FILENO, shutdown_msg, sizeof(shutdown_msg) - 1); + } + else if (n_shutdowns == 2) + { + write(STDERR_FILENO, patience_msg, sizeof(patience_msg) - 1); + } + else + { + exit(EXIT_FAILURE); + } } static void @@ -2041,14 +2065,22 @@ return_main: /*< * Shutdown MaxScale server */ -void -shutdown_server() +int maxscale_shutdown() { - service_shutdown(); - poll_shutdown(); - hkshutdown(); - memlog_flush_all(); - log_flush_shutdown(); + static int n_shutdowns = 0; + + int n = atomic_add(&n_shutdowns, 1); + + if (n == 0) + { + service_shutdown(); + poll_shutdown(); + hkshutdown(); + memlog_flush_all(); + log_flush_shutdown(); + } + + return n + 1; } static void log_flush_shutdown(void) diff --git a/server/core/secrets.c b/server/core/secrets.c index b197ff1e0..60cc244b5 100644 --- a/server/core/secrets.c +++ b/server/core/secrets.c @@ -175,8 +175,8 @@ secrets_readKeys(const char* path) if (secret_stats.st_mode != (S_IRUSR | S_IFREG)) { close(fd); - MXS_ERROR("Ignoring secrets file " - "%s, invalid permissions.", + MXS_ERROR("Ignoring secrets file %s, invalid permissions." + "The only permission on the file should be owner:read.", secret_file); return NULL; } diff --git a/server/modules/routing/debugcli/debugcmd.c b/server/modules/routing/debugcli/debugcmd.c index 950f0882a..3e828bc77 100644 --- a/server/modules/routing/debugcli/debugcmd.c +++ b/server/modules/routing/debugcli/debugcmd.c @@ -70,6 +70,7 @@ #include #include #include +#include #include #include @@ -276,7 +277,11 @@ struct subcommand listoptions[] = { {0, 0, 0} } }; -extern void shutdown_server(); +static void shutdown_server() +{ + maxscale_shutdown(); +} + static void shutdown_service(DCB *dcb, SERVICE *service); static void shutdown_monitor(DCB *dcb, MONITOR *monitor);