* setup.c: updated to use new built-in daemonization
authorArt Cancro <ajc@citadel.org>
Wed, 27 Dec 2006 22:42:05 +0000 (22:42 +0000)
committerArt Cancro <ajc@citadel.org>
Wed, 27 Dec 2006 22:42:05 +0000 (22:42 +0000)
* 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
citadel/control.c
citadel/database_sleepycat.c
citadel/server.h
citadel/setup.c
citadel/sysdep.c

index 747134506c931ab84798027c622fa211b0ab6ecd..e1728a524be21810b06255bba0a3613c03752cb8 100644 (file)
@@ -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
index 0c9dd11b13b8f815fe2b1932d7168712cd5df526..bc7d7958e402a0283caf2db0020b61e3173641c1 100644 (file)
@@ -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);
        }
 }
 
index d2aadb868266df63d46efd05dd6ea997f8a8551e..6038d5869a8b8184b1571a4523c299492171e571 100644 (file)
@@ -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();
index fa424e4606310948c3660397a72f167d3b146845..323f999f448669e0cb8786f26da0528982ac8fb0 100644 (file)
@@ -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.
  *
index e5212930ccfbe0435b0932e813c008b4a8565236..8ff9c297cae6fa6794dc710e7894b2082fc128b8 100644 (file)
@@ -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"
index df4f714f2e1fab35e8f442f2b20188e2585d7ae6..e3bfde3d7ac411ca41a6239fdb4fa668d0f164bb 100644 (file)
@@ -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));
 }