From 0047043f803e4fade3cb26b5b1d13ed40ca75ebb Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Wed, 27 Dec 2006 22:42:05 +0000 Subject: [PATCH] * setup.c: updated to use new built-in daemonization * sysdep.c et al: exit codes 0 and 101-199 cause the watcher to exit without restarting citserver. This allows certain types of initialization failures to cause the whole system to exit without endlessly restarting. --- citadel/config.c | 10 +++++----- citadel/control.c | 2 +- citadel/database_sleepycat.c | 14 +++++++------- citadel/server.h | 15 +++++++++++++++ citadel/setup.c | 19 ++++++++++++------- citadel/sysdep.c | 34 ++++++++++++++++++++++++++++++---- 6 files changed, 70 insertions(+), 24 deletions(-) diff --git a/citadel/config.c b/citadel/config.c index 747134506..e1728a524 100644 --- a/citadel/config.c +++ b/citadel/config.c @@ -37,7 +37,7 @@ void get_config(void) { "Error: %s\n", (home_specified ? ctdl_home_directory : CTDLDIR), strerror(errno)); - exit(1); + exit(CTDLEXIT_HOME); } cfp = fopen(file_citadel_config, "rb"); if (cfp == NULL) { @@ -46,18 +46,18 @@ void get_config(void) { "Error: %s\n", file_citadel_config, strerror(errno)); - exit(1); + exit(CTDLEXIT_CONFIG); } fread((char *) &config, sizeof(struct config), 1, cfp); if (fstat(fileno(cfp), &st)) { perror(file_citadel_config); - exit(1); + exit(CTDLEXIT_CONFIG); } #ifndef __CYGWIN__ if (st.st_uid != CTDLUID || st.st_mode != (S_IFREG | S_IRUSR | S_IWUSR)) { fprintf(stderr, "check the permissions on %s\n", file_citadel_config); // fprintf(stderr, "check the permissions on citadel.config\n"); - exit(1); + exit(CTDLEXIT_CONFIG); } #endif fclose(cfp); @@ -72,7 +72,7 @@ void get_config(void) { " Data files are currently at %d.%02d\n", (config.c_setup_level / 100), (config.c_setup_level % 100)); - exit(1); + exit(CTDLEXIT_OOD); } /* Default maximum message length is 10 megabytes. This is site diff --git a/citadel/control.c b/citadel/control.c index 0c9dd11b1..bc7d7958e 100644 --- a/citadel/control.c +++ b/citadel/control.c @@ -60,7 +60,7 @@ void lock_control(void) if (flock(fileno(control_fp), (LOCK_EX | LOCK_NB))) { lprintf(CTDL_EMERG, "citserver: unable to lock %s.\n", file_citadel_control); lprintf(CTDL_EMERG, "Is another citserver already running?\n"); - exit(1); + exit(CTDLEXIT_CONTROL); } } diff --git a/citadel/database_sleepycat.c b/citadel/database_sleepycat.c index d2aadb868..6038d5869 100644 --- a/citadel/database_sleepycat.c +++ b/citadel/database_sleepycat.c @@ -362,7 +362,7 @@ void open_databases(void) if (ret) { lprintf(CTDL_EMERG, "cdb_*: db_env_create: %s\n", db_strerror(ret)); - exit(ret); + exit(CTDLEXIT_DB); } dbenv->set_errpfx(dbenv, "citserver"); dbenv->set_paniccall(dbenv, dbpanic); @@ -379,14 +379,14 @@ void open_databases(void) lprintf(CTDL_EMERG, "cdb_*: set_cachesize: %s\n", db_strerror(ret)); dbenv->close(dbenv, 0); - exit(ret); + exit(CTDLEXIT_DB); } if ((ret = dbenv->set_lk_detect(dbenv, DB_LOCK_DEFAULT))) { lprintf(CTDL_EMERG, "cdb_*: set_lk_detect: %s\n", db_strerror(ret)); dbenv->close(dbenv, 0); - exit(ret); + exit(CTDLEXIT_DB); } flags = @@ -399,7 +399,7 @@ void open_databases(void) lprintf(CTDL_DEBUG, "cdb_*: dbenv->open: %s\n", db_strerror(ret)); dbenv->close(dbenv, 0); - exit(ret); + exit(CTDLEXIT_DB); } lprintf(CTDL_INFO, "cdb_*: Starting up DB\n"); @@ -411,7 +411,7 @@ void open_databases(void) if (ret) { lprintf(CTDL_DEBUG, "cdb_*: db_create: %s\n", db_strerror(ret)); - exit(ret); + exit(CTDLEXIT_DB); } @@ -430,14 +430,14 @@ void open_databases(void) if (ret) { lprintf(CTDL_EMERG, "cdb_*: db_open[%d]: %s\n", i, db_strerror(ret)); - exit(ret); + exit(CTDLEXIT_DB); } } if ((ret = pthread_key_create(&tsdkey, dest_tsd))) { lprintf(CTDL_EMERG, "cdb_*: pthread_key_create: %s\n", strerror(ret)); - exit(1); + exit(CTDLEXIT_DB); } cdb_allocate_tsd(); diff --git a/citadel/server.h b/citadel/server.h index fa424e460..323f999f4 100644 --- a/citadel/server.h +++ b/citadel/server.h @@ -31,6 +31,21 @@ struct CtdlMessage { #define CM_SKIP_HOOKS 0x01 /* Don't run server-side handlers */ + +/* + * Exit codes 101 through 109 are used for conditions in which + * we deliberately do NOT want the service to automatically + * restart. + */ +#define CTDLEXIT_CONFIG 101 /* Could not read citadel.config */ +#define CTDLEXIT_CONTROL 102 /* Could not acquire lock */ +#define CTDLEXIT_HOME 103 /* Citadel home directory not found */ +#define CTDLEXIT_OOD 104 /* Out Of Date config - rerun setup */ +#define CTDLEXIT_DB 105 /* Unable to initialize database */ + + + + /* * Here's the big one... the Citadel context structure. * diff --git a/citadel/setup.c b/citadel/setup.c index e5212930c..8ff9c297c 100644 --- a/citadel/setup.c +++ b/citadel/setup.c @@ -397,10 +397,14 @@ void install_init_scripts(void) "#\n" "# chkconfig: - 79 30\n" "# description: Citadel service\n" - "# processname: ctdlsvc\n" - "# pidfile: /var/run/citadel.pid\n" + "# processname: citserver\n" + "# pidfile: %s/citadel.pid\n" "\n" - "CITADEL_DIR=%s\n", setup_directory); + "CITADEL_DIR=%s\n" + , + setup_directory, + setup_directory + ); fprintf(fp, "\n" "test -x $CITADEL_DIR/ctdlsvc || exit 0\n" "test -d /var/run || exit 0\n" @@ -408,9 +412,7 @@ void install_init_scripts(void) "case \"$1\" in\n" "\n" "start) echo -n \"Starting Citadel... \"\n" - " if $CITADEL_DIR/ctdlsvc /var/run/citadel.pid " - "$CITADEL_DIR/citserver " - "-t/dev/null\n" + " if $CITADEL_DIR/citserver -d\n" " then\n" " echo \"ok\"\n" " else\n" @@ -423,7 +425,10 @@ void install_init_scripts(void) " else\n" " echo \"failed\"\n" " fi\n" - " rm -f /var/run/citadel.pid 2>/dev/null\n"); + " rm -f %s/citadel.pid 2>/dev/null\n" + , + setup_directory + ); fprintf(fp, " ;;\n" "restart) $0 stop\n" " $0 start\n" diff --git a/citadel/sysdep.c b/citadel/sysdep.c index df4f714f2..e3bfde3d7 100644 --- a/citadel/sysdep.c +++ b/citadel/sysdep.c @@ -765,6 +765,7 @@ void start_daemon(int unused) { int status = 0; pid_t child = 0; FILE *fp; + int do_restart = 0; current_child = 0; @@ -789,7 +790,7 @@ void start_daemon(int unused) { signal(SIGQUIT, SIG_IGN); setsid(); -// umask(0); + umask(0); freopen("/dev/null", "r", stdin); freopen("/dev/null", "w", stdout); freopen("/dev/null", "w", stderr); @@ -812,11 +813,36 @@ void start_daemon(int unused) { waitpid(current_child, &status, 0); } - } while (status != 0); + do_restart = 0; - unlink(file_pid_file); - exit(0); + /* Did the main process exit with an actual exit code? */ + if (WIFEXITED(status)) { + + /* Exit code 0 means the watcher should exit */ + if (WEXITSTATUS(status) == 0) { + do_restart = 0; + } + /* Exit code 101-109 means the watcher should exit */ + else if ( (WEXITSTATUS(status) >= 101) && (WEXITSTATUS(status) <= 109) ) { + do_restart = 0; + } + + /* Any other exit code means we should restart. */ + else { + do_restart = 1; + } + } + + /* Any other type of termination (signals, etc.) should also restart. */ + else { + do_restart = 1; + } + + } while (do_restart); + + unlink(file_pid_file); + exit(WEXITSTATUS(status)); } -- 2.30.2