X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fhousekeeping.c;h=0ca383202c2bb1f27275e2d92cedb5f7d5a860f5;hb=fa2dd842abb5feedea3e2253255722fcaecc3c6f;hp=bde6634b97689f85da0c64bbf5d9490e4db7bac6;hpb=ff9480f7250d97d132a4f4e8623a11db48e07e4c;p=citadel.git diff --git a/citadel/housekeeping.c b/citadel/housekeeping.c index bde6634b9..0ca383202 100644 --- a/citadel/housekeeping.c +++ b/citadel/housekeeping.c @@ -1,90 +1,36 @@ /* - * $Id$ - * * This file contains miscellaneous housekeeping tasks. * + * Copyright (c) 1987-2021 by the citadel.org team + * + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ -#include "sysdep.h" -#include -#include #include -#include - -#if TIME_WITH_SYS_TIME -# include -# include -#else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif - -#include -#include -#include -#include -#include -#ifdef HAVE_SYS_SELECT_H -#include -#endif #include -#include "citadel.h" -#include "server.h" + +#include "ctdl_module.h" #include "serv_extensions.h" -#include "citserver.h" -#include "config.h" -#include "housekeeping.h" -#include "sysdep_decls.h" #include "room_ops.h" -#include "database.h" -#include "msgbase.h" +#include "internet_addressing.h" +#include "config.h" #include "journaling.h" - -#include "ctdl_module.h" -#include "threads.h" - -/* - * Terminate idle sessions. This function pounds through the session table - * comparing the current time to each session's time-of-last-command. If an - * idle session is found it is terminated, then the search restarts at the - * beginning because the pointer to our place in the list becomes invalid. - */ -void terminate_idle_sessions(void) { - struct CitContext *ccptr; - time_t now; - int session_to_kill; - int killed = 0; - - now = time(NULL); - session_to_kill = 0; - begin_critical_section(S_SESSION_TABLE); - for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) { - if ( (ccptr!=CC) - && (config.c_sleeping > 0) - && (now - (ccptr->lastcmd) > config.c_sleeping) ) { - ccptr->kill_me = 1; - ++killed; - } - } - end_critical_section(S_SESSION_TABLE); - if (killed > 0) - CtdlLogPrintf(CTDL_INFO, "Terminated %d idle sessions\n", killed); -} - - +#include "citadel_ldap.h" void check_sched_shutdown(void) { if ((ScheduledShutdown == 1) && (ContextList == NULL)) { - CtdlLogPrintf(CTDL_NOTICE, "Scheduled shutdown initiating.\n"); - CtdlThreadStopAll(); + syslog(LOG_NOTICE, "housekeeping: scheduled shutdown initiating"); + server_shutting_down = 1; } } - /* * Check (and fix) floor reference counts. This doesn't need to be done * very often, since the counts should remain correct during normal operation. @@ -98,19 +44,20 @@ void check_ref_counts_backend(struct ctdlroom *qrbuf, void *data) { ++new_refcounts[(int)qrbuf->QRfloor]; } + void check_ref_counts(void) { struct floor flbuf; int a; int new_refcounts[MAXFLOORS]; - CtdlLogPrintf(CTDL_DEBUG, "Checking floor reference counts\n"); + syslog(LOG_DEBUG, "housekeeping: checking floor reference counts"); for (a=0; a (time_t)60 ) { - do_perminute_housekeeping_now = 1; - last_timer = time(NULL); - } -/* } end_critical_section(S_HOUSEKEEPING); - if (do_housekeeping_now == 0) { + now = time(NULL); + if ( (do_housekeeping_now == 0) && (!CtdlIsSingleUser()) ) { + if ( (now - last_timer) > (time_t)300 ) { + syslog(LOG_WARNING, + "housekeeping: WARNING: housekeeping loop has not run for %ld minutes. Is something stuck?", + ((now - last_timer) / 60) + ); + } return; } -*/ + /* * Ok, at this point we've made the decision to run the housekeeping * loop. Everything below this point is real work. */ + if ( (now - last_timer) > (time_t)60 ) { + do_perminute_housekeeping_now = 1; + last_timer = time(NULL); + } + /* First, do the "as often as needed" stuff... */ - CtdlThreadName("House Keeping - Journal"); JournalRunQueue(); - - CtdlThreadName("House Keeping - EVT_HOUSE"); - PerformSessionHooks(EVT_HOUSE); /* perform as needed housekeeping */ + PerformSessionHooks(EVT_HOUSE); /* Then, do the "once per minute" stuff... */ if (do_perminute_housekeeping_now) { - do_perminute_housekeeping_now = 0; - cdb_check_handles(); /* suggested by Justin Case */ - CtdlThreadName("House Keeping - EVT_TIMER"); - PerformSessionHooks(EVT_TIMER); /* Run any timer hooks */ - } + cdb_check_handles(); + PerformSessionHooks(EVT_TIMER); // Run all registered TIMER hooks + +#ifdef HAVE_LDAP // LDAP sync isn't in a module so we can put it here + static time_t last_ldap_sync = 0L; + if ( (now - last_ldap_sync) > (time_t)CtdlGetConfigLong("c_ldap_sync_freq") ) { + CtdlSynchronizeUsersFromLDAP(); + last_ldap_sync = time(NULL); + } +#endif + + keep_an_eye_on_memory_usage(); } + /* * All done. */ + begin_critical_section(S_HOUSEKEEPING); housekeeping_in_progress = 0; - return NULL; + end_critical_section(S_HOUSEKEEPING); +} + + +void CtdlDisableHouseKeeping(void) { + int ActiveBackgroundJobs; + int do_housekeeping_now = 0; + struct CitContext *nptr; + int nContexts, i; + +retry_block_housekeeping: + syslog(LOG_INFO, "housekeeping: trying to disable services"); + begin_critical_section(S_HOUSEKEEPING); + if (housekeeping_in_progress == 0) { + do_housekeeping_now = 1; + housekeeping_in_progress = 1; + } + end_critical_section(S_HOUSEKEEPING); + if (do_housekeeping_now == 0) { + usleep(1000000); + goto retry_block_housekeeping; + } + + syslog(LOG_INFO, "housekeeping: checking for running server jobs"); + +retry_wait_for_contexts: + /* So that we don't keep the context list locked for a long time + * we create a copy of it first + */ + ActiveBackgroundJobs = 0; + nptr = CtdlGetContextArray(&nContexts) ; + if (nptr) + { + for (i=0; i