Added code to provide a preliminary single user mode.
authorDave West <davew@uncensored.citadel.org>
Thu, 17 Jul 2008 19:03:00 +0000 (19:03 +0000)
committerDave West <davew@uncensored.citadel.org>
Thu, 17 Jul 2008 19:03:00 +0000 (19:03 +0000)
CtdlTrySingleUser() - Try to go single user
CtdlEndSingleUser() - End single user
CtdlIsSingleUser() - True is system is single user
CtdlWantSingleUser() - True if system is trying to go single user

The system is said to be in single user mode when there is only one
session active. Which should be the one that asked it to go single user.

When trying to go single user new connections are refused as per the
nologin mechanism and scheduled threads are prevented.

citadel/citserver.c
citadel/include/ctdl_module.h
citadel/modules/vandelay/serv_vandelay.c
citadel/sysdep.c
citadel/threads.c

index ca612b0b0ed9b93261a789a8fa29b5de1d82e474..dbed6366a606240de8e007114c5ec61b24d964b2 100644 (file)
@@ -984,7 +984,7 @@ void begin_session(struct CitContext *con)
        con->dl_is_net = 0;
 
        con->nologin = 0;
-       if ((config.c_maxsessions > 0)&&(num_sessions > config.c_maxsessions)) {
+       if (((config.c_maxsessions > 0)&&(num_sessions > config.c_maxsessions)) || CtdlWantSingleUser()) {
                con->nologin = 1;
        }
 
index 90932ca82e3c3b701a5689ef8a9d645aa04b51e4..754b2e146eab08670361a379e4a3767b33ac53d3 100644 (file)
@@ -149,6 +149,10 @@ void CtdlThreadAllocTSD(void);
 struct CitContext *CtdlGetContextArray (int *count);
 void CtdlFillSystemContext(struct CitContext *context, char *name);
 
+int CtdlTrySingleUser(void);
+void CtdlEndSingleUser(void);
+int CtdlWantSingleUser(void);
+int CtdlIsSingleUser(void);
 
 
 /*
index 138a5e5c4754cc060bcabefc5c158e4eb85d0037..79533aa2f2e9160f0d4bbef2c64e9d63dc8c9ec3 100644 (file)
@@ -904,26 +904,28 @@ void cmd_artv(char *cmdbuf) {
        static int is_running = 0;
 
        if (CtdlAccessCheck(ac_internal)) return;
-       if (is_running) {
+       
+       if (CtdlTrySingleUser())
+       {
+               CtdlMakeTempFileName(artv_tempfilename1, sizeof artv_tempfilename1);
+               CtdlMakeTempFileName(artv_tempfilename2, sizeof artv_tempfilename2);
+
+               extract_token(cmd, cmdbuf, 0, '|', sizeof cmd);
+               if (!strcasecmp(cmd, "export")) artv_do_export();
+               else if (!strcasecmp(cmd, "import")) artv_do_import();
+               else if (!strcasecmp(cmd, "dump")) artv_do_dump();
+               else cprintf("%d illegal command\n", ERROR + ILLEGAL_VALUE);
+
+               unlink(artv_tempfilename1);
+               unlink(artv_tempfilename2);
+               
+               CtdlEndSingleUser();
+       }
+       else
+       {
                cprintf("%d The importer/exporter is already running.\n",
                        ERROR + RESOURCE_BUSY);
-               return;
        }
-       is_running = 1;
-
-       CtdlMakeTempFileName(artv_tempfilename1, sizeof artv_tempfilename1);
-       CtdlMakeTempFileName(artv_tempfilename2, sizeof artv_tempfilename2);
-
-       extract_token(cmd, cmdbuf, 0, '|', sizeof cmd);
-       if (!strcasecmp(cmd, "export")) artv_do_export();
-       else if (!strcasecmp(cmd, "import")) artv_do_import();
-       else if (!strcasecmp(cmd, "dump")) artv_do_dump();
-       else cprintf("%d illegal command\n", ERROR + ILLEGAL_VALUE);
-
-       unlink(artv_tempfilename1);
-       unlink(artv_tempfilename2);
-
-       is_running = 0;
 }
 
 
index c09fd2a06292edca76dae0ebbad3997440b76818..2114fb0e1a1f2150be3c8267626d659d92991c85 100644 (file)
@@ -99,6 +99,52 @@ int syslog_facility = LOG_DAEMON;
 int enable_syslog = 0;
 
 
+/* Flag for single user mode */
+static int want_single_user = 0;
+
+/* Try to go single user */
+
+int CtdlTrySingleUser(void)
+{
+       int can_do = 0;
+       
+       begin_critical_section(S_SINGLE_USER);
+       if (want_single_user)
+               can_do = 0;
+       else
+       {
+               can_do = 1;
+               want_single_user = 1;
+       }
+       end_critical_section(S_SINGLE_USER);
+       return can_do;
+}
+
+void CtdlEndSingleUser(void)
+{
+       begin_critical_section(S_SINGLE_USER);
+       want_single_user = 0;
+       end_critical_section(S_SINGLE_USER);
+}
+
+
+int CtdlWantSingleUser(void)
+{
+       return want_single_user;
+}
+
+int CtdlIsSingleUser(void)
+{
+       if (want_single_user)
+       {
+               /* check for only one context here */
+               if (num_sessions == 1)
+                       return TRUE;
+       }
+       return FALSE;
+}
+
+
 /*
  * CtdlLogPrintf()  ...   Write logging information
  */
index 2d8576e1d49e7b00dd262564a62065927b9bc656..63e6ba0724b72aa7ae708b1da24eab3f10c93aa8 100644 (file)
@@ -1101,6 +1101,10 @@ void ctdl_thread_internal_check_scheduled(void)
        CtdlThreadNode *this_thread, *that_thread;
        time_t now;
        
+       /* Don't start scheduled threads if the system wants single user mode */
+       if (CtdlWantSingleUser())
+               return;
+       
        if (try_critical_section(S_SCHEDULE_LIST))
                return; /* If this list is locked we wait till the next chance */