From e6499f44a49d449e41ba605a0c7476019da432b4 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Sat, 10 Sep 2016 17:20:21 -0400 Subject: [PATCH] Simple concurrency lock to prevent multiple citservers running at the same time --- citadel/citserver.c | 14 ++++++++------ citadel/citserver.h | 2 +- citadel/database.c | 13 ++++--------- citadel/server_main.c | 44 +++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 55 insertions(+), 18 deletions(-) diff --git a/citadel/citserver.c b/citadel/citserver.c index 9f41f35f5..f389ac9f0 100644 --- a/citadel/citserver.c +++ b/citadel/citserver.c @@ -185,9 +185,9 @@ void master_startup(void) { /* - * Cleanup routine to be called when the server is shutting down. + * Cleanup routine to be called when the server is shutting down. Returns the needed exit code. */ -void master_cleanup(int exitcode) { +int master_cleanup(int exitcode) { struct CleanupFunctionHook *fcn; static int already_cleaning_up = 0; @@ -225,11 +225,13 @@ void master_cleanup(int exitcode) { syslog(LOG_NOTICE, "citserver: Exiting with status %d\n", exitcode); fflush(stdout); fflush(stderr); - if (restart_server != 0) - exit(1); - if ((running_as_daemon != 0) && ((exitcode == 0) )) + if (restart_server != 0) { + exitcode = 1; + } + else if ((running_as_daemon != 0) && ((exitcode == 0) )) { exitcode = CTDLEXIT_SHUTDOWN; - exit(exitcode); + } + return(exitcode); } diff --git a/citadel/citserver.h b/citadel/citserver.h index c02492512..61f1964b7 100644 --- a/citadel/citserver.h +++ b/citadel/citserver.h @@ -36,7 +36,7 @@ void cit_backtrace(void); void cit_oneline_backtrace(void); void cit_panic_backtrace(int SigNum); void master_startup (void); -void master_cleanup (int exitcode); +int master_cleanup (int exitcode); void set_wtmpsupp (char *newtext); void set_wtmpsupp_to_current_room(void); void do_command_loop(void); diff --git a/citadel/database.c b/citadel/database.c index e7e57a643..dbfac8dd5 100644 --- a/citadel/database.c +++ b/citadel/database.c @@ -34,17 +34,15 @@ #ifdef HAVE_DB_H #include #elif defined(HAVE_DB4_DB_H) -#include +#include #else -#error Neither nor was found by configure. Install db4-devel. +#error Neither nor was found by configure. Install db5-devel. #endif - -#if DB_VERSION_MAJOR < 4 || DB_VERSION_MINOR < 1 -#error Citadel requires Berkeley DB v4.1 or newer. Please upgrade. +#if DB_VERSION_MAJOR < 5 +#error Citadel requires Berkeley DB v5.0 or newer. Please upgrade. #endif - #include #include "ctdl_module.h" @@ -52,7 +50,6 @@ #include "citserver.h" #include "config.h" - static DB *dbp[MAXCDB]; /* One DB handle for each Citadel database */ static DB_ENV *dbenv; /* The DB environment (global) */ @@ -281,9 +278,7 @@ void open_databases(void) dbenv->set_paniccall(dbenv, dbpanic); dbenv->set_errcall(dbenv, cdb_verbose_err); dbenv->set_errpfx(dbenv, "ctdl"); -#if (DB_VERSION_MAJOR > 4) || ( (DB_VERSION_MAJOR == 4) && (DB_VERSION_MINOR >= 3) ) dbenv->set_msgcall(dbenv, cdb_verbose_log); -#endif dbenv->set_verbose(dbenv, DB_VERB_DEADLOCK, 1); dbenv->set_verbose(dbenv, DB_VERB_RECOVERY, 1); diff --git a/citadel/server_main.c b/citadel/server_main.c index 45312588e..061273a63 100644 --- a/citadel/server_main.c +++ b/citadel/server_main.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "citserver.h" @@ -34,6 +35,42 @@ const char *CitadelServiceTCP="citadel-TCP"; void go_threading(void); + + +/* + * Create or remove a lock file, so we only have one Citadel Server running at a time. + */ +void ctdl_lockfile(int yo) { + static char lockfilename[SIZ]; + static FILE *fp; + + + if (yo) { + syslog(LOG_DEBUG, "Creating lockfile"); + snprintf(lockfilename, sizeof lockfilename, "%s/citadel.lock", ctdl_run_dir); + fp = fopen(lockfilename, "w"); + if (!fp) { + syslog(LOG_ERR, "Cannot open or create %s", lockfilename); + exit(CTDLEXIT_DB); + } + if (flock(fileno(fp), (LOCK_EX|LOCK_NB)) != 0) { + syslog(LOG_ERR, "Cannot lock %s , is another citserver running?", lockfilename); + exit(CTDLEXIT_DB); + } + return; + } + + syslog(LOG_DEBUG, "Removing lockfile"); + unlink(lockfilename); + flock(fileno(fp), LOCK_UN); + fclose(fp); +} + + + + + + /* * Here's where it all begins. */ @@ -232,6 +269,8 @@ int main(int argc, char **argv) #endif + ctdl_lockfile(1); + /* Initialize... */ init_sysdep(); @@ -362,6 +401,7 @@ int main(int argc, char **argv) go_threading(); - master_cleanup(exit_signal); - return(0); + int exit_code = master_cleanup(exit_signal); + ctdl_lockfile(0); + return(exit_code); } -- 2.30.2