X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fserver_main.c;h=5d73d7a523ceb3899839e031bafb80e8c653365f;hb=1421d26887f154439d2cd27075c7e85dc22f644f;hp=8758de3b5e466f6e6127f01f0807ee73f7ecbc66;hpb=b6595aedb693cac23a2ce5781e13125fb7c70c96;p=citadel.git diff --git a/citadel/server_main.c b/citadel/server_main.c index 8758de3b5..5d73d7a52 100644 --- a/citadel/server_main.c +++ b/citadel/server_main.c @@ -38,9 +38,6 @@ #include #include #include -#ifdef HAVE_PTHREAD_H -#include -#endif #ifdef HAVE_SYS_PRCTL_H #include #endif @@ -49,6 +46,7 @@ #include "server.h" #include "serv_extensions.h" #include "sysdep_decls.h" +#include "threads.h" #include "citserver.h" #include "support.h" #include "config.h" @@ -56,7 +54,10 @@ #include "database.h" #include "user_ops.h" #include "housekeeping.h" -#include "citadel_dirs.c" +#include "svn_revision.h" +#include "citadel_dirs.h" + +#include "context.h" #include "modules_init.h" #include "ecrash.h" @@ -72,8 +73,8 @@ const char *CitadelServiceUDS="citadel-UDS"; const char *CitadelServiceTCP="citadel-TCP"; -void go_threading(void); +void go_threading(void); /* * Here's where it all begins. @@ -99,9 +100,8 @@ int main(int argc, char **argv) // eCrashSymbolTable symbol_table; #endif /* initialise semaphores here. Patch by Matt and davew - * its called here as they are needed by lprintf for thread safety + * its called here as they are needed by CtdlLogPrintf for thread safety */ - CtdlInitBase64Table(); InitialiseSemaphores(); /* initialize the master context */ @@ -133,7 +133,6 @@ int main(int argc, char **argv) else safestrncpy(relhome, &argv[a][2], sizeof relhome); - home_specified = 1; home=1; } @@ -141,10 +140,6 @@ int main(int argc, char **argv) freopen(&argv[a][2], "w", stderr); } - else if (!strncmp(argv[a], "-f", 2)) { - do_defrag = 1; - } - else if (!strncmp(argv[a], "-D", 2)) { dbg = 1; } @@ -157,10 +152,10 @@ int main(int argc, char **argv) /* any other parameter makes it crash and burn */ else { - lprintf(CTDL_EMERG, "citserver: usage: " + CtdlLogPrintf(CTDL_EMERG, "citserver: usage: " "citserver " "[-lLogFacility] " - "[-d] [-f] [-D] " + "[-d] [-D] " " [-tTraceFile]" " [-xLogLevel] [-hHomeDir]\n"); exit(1); @@ -183,19 +178,14 @@ int main(int argc, char **argv) params.debugLevel = ECRASH_DEBUG_VERBOSE; params.dumpAllThreads = TRUE; params.useBacktraceSymbols = 1; -/// BuildSymbolTable(&symbol_table); -// params.symbolTable = &symbol_table; params.signals[0]=SIGSEGV; params.signals[1]=SIGILL; params.signals[2]=SIGBUS; params.signals[3]=SIGABRT; - eCrash_Init(¶ms); - eCrash_RegisterThread("MasterThread", 0); - -/// signal(SIGSEGV, cit_panic_backtrace); #endif + /* Initialize the syslogger. Yes, we are really using 0 as the * facility, because we are going to bitwise-OR the facility to * the severity of each message, allowing us to write to other @@ -207,35 +197,42 @@ int main(int argc, char **argv) } /* Tell 'em who's in da house */ - lprintf(CTDL_NOTICE, "\n"); - lprintf(CTDL_NOTICE, "\n"); - lprintf(CTDL_NOTICE, - "*** Citadel server engine v%d.%02d ***\n", - (REV_LEVEL/100), (REV_LEVEL%100)); - lprintf(CTDL_NOTICE, - "Copyright (C) 1987-2007 by the Citadel development team.\n"); - lprintf(CTDL_NOTICE, - "This program is distributed under the terms of the GNU " - "General Public License.\n"); - lprintf(CTDL_NOTICE, "\n"); - lprintf(CTDL_DEBUG, "Called as: %s\n", argv[0]); - lprintf(CTDL_INFO, "%s\n", libcitadel_version_string()); + CtdlLogPrintf(CTDL_NOTICE, "\n"); + CtdlLogPrintf(CTDL_NOTICE, "\n"); + CtdlLogPrintf(CTDL_NOTICE, + "*** Citadel server engine v%d.%02d (build %s) ***\n", + (REV_LEVEL/100), (REV_LEVEL%100), svn_revision()); + CtdlLogPrintf(CTDL_NOTICE, "Copyright (C) 1987-2008 by the Citadel development team.\n"); + CtdlLogPrintf(CTDL_NOTICE, "This program is distributed under the terms of the GNU " + "General Public License.\n"); + CtdlLogPrintf(CTDL_NOTICE, "\n"); + CtdlLogPrintf(CTDL_DEBUG, "Called as: %s\n", argv[0]); + CtdlLogPrintf(CTDL_INFO, "%s\n", libcitadel_version_string()); /* Load site-specific parameters, and set the ipgm secret */ - lprintf(CTDL_INFO, "Loading citadel.config\n"); + CtdlLogPrintf(CTDL_INFO, "Loading citadel.config\n"); get_config(); config.c_ipgm_secret = rand(); + + /* get_control() MUST MUST MUST be called BEFORE the databases are opened!! */ + CtdlLogPrintf(CTDL_INFO, "Acquiring control record\n"); + get_control(); + put_config(); #ifdef HAVE_RUN_DIR /* on some dists rundir gets purged on startup. so we need to recreate it. */ if (stat(ctdl_run_dir, &filestats)==-1){ +#ifdef HAVE_GETPWUID_R #ifdef SOLARIS_GETPWUID pwp = getpwuid_r(config.c_ctdluid, &pw, pwbuf, sizeof(pwbuf)); -#else +#else // SOLARIS_GETPWUID getpwuid_r(config.c_ctdluid, &pw, pwbuf, sizeof(pwbuf), &pwp); -#endif +#endif // SOLARIS_GETPWUID +#else // HAVE_GETPWUID_R + pwp = NULL; +#endif // HAVE_GETPWUID_R mkdir(ctdl_run_dir, 0755); chown(ctdl_run_dir, config.c_ctdluid, (pwp==NULL)?-1:pw.pw_gid); } @@ -251,9 +248,28 @@ int main(int argc, char **argv) */ master_startup(); - lprintf(CTDL_INFO, "Acquiring control record\n"); - get_control(); - + /* + * Check that the control record is correct and place sensible values if it isn't + */ + check_control(); + + /* + * Run any upgrade entry points + */ + CtdlLogPrintf(CTDL_INFO, "Upgrading modules.\n"); + upgrade_modules(); + +/** + * Load the user for the masterCC or create them if they don't exist + */ + if (CtdlGetUser(&masterCC.user, "SYS_Citadel")) + { + /** User doesn't exist. We can't use create user here as the user number needs to be 0 */ + strcpy (masterCC.user.fullname, "SYS_Citadel") ; + CtdlPutUser(&masterCC.user); + CtdlGetUser(&masterCC.user, "SYS_Citadel"); /** Just to be safe */ + } + /* * Bind the server to a Unix-domain socket. */ @@ -274,10 +290,13 @@ int main(int argc, char **argv) do_async_loop, CitadelServiceTCP); + + + /* * Load any server-side extensions available here. */ - lprintf(CTDL_INFO, "Initializing server extensions\n"); + CtdlLogPrintf(CTDL_INFO, "Initializing server extensions\n"); size = strlen(ctdl_home_directory) + 9; initialise_modules(0); @@ -287,10 +306,18 @@ int main(int argc, char **argv) /* * If we need host auth, start our chkpwd daemon. */ - if (config.c_auth_mode == 1) { + if (config.c_auth_mode == AUTHMODE_HOST) { start_chkpwd_daemon(); } + + /* + * check, whether we're fired up another time after a crash. + * if, post an aide message, so the admin has a chance to react. + */ + checkcrash (); + + /* * Now that we've bound the sockets, change to the Citadel user id and its * corresponding group ids @@ -298,24 +325,29 @@ int main(int argc, char **argv) if (drop_root_perms) { cdb_chmod_data(); /* make sure we own our data files */ +#ifdef HAVE_GETPWUID_R #ifdef SOLARIS_GETPWUID pwp = getpwuid_r(config.c_ctdluid, &pw, pwbuf, sizeof(pwbuf)); -#else +#else // SOLARIS_GETPWUID getpwuid_r(config.c_ctdluid, &pw, pwbuf, sizeof(pwbuf), &pwp); -#endif +#endif // SOLARIS_GETPWUID +#else // HAVE_GETPWUID_R + pwp = NULL; +#endif // HAVE_GETPWUID_R + if (pwp == NULL) - lprintf(CTDL_CRIT, "WARNING: getpwuid(%ld): %s\n" + CtdlLogPrintf(CTDL_CRIT, "WARNING: getpwuid(%ld): %s\n" "Group IDs will be incorrect.\n", (long)CTDLUID, strerror(errno)); else { initgroups(pw.pw_name, pw.pw_gid); if (setgid(pw.pw_gid)) - lprintf(CTDL_CRIT, "setgid(%ld): %s\n", (long)pw.pw_gid, + CtdlLogPrintf(CTDL_CRIT, "setgid(%ld): %s\n", (long)pw.pw_gid, strerror(errno)); } - lprintf(CTDL_INFO, "Changing uid to %ld\n", (long)CTDLUID); + CtdlLogPrintf(CTDL_INFO, "Changing uid to %ld\n", (long)CTDLUID); if (setuid(CTDLUID) != 0) { - lprintf(CTDL_CRIT, "setuid() failed: %s\n", strerror(errno)); + CtdlLogPrintf(CTDL_CRIT, "setuid() failed: %s\n", strerror(errno)); } #if defined (HAVE_SYS_PRCTL_H) && defined (PR_SET_DUMPABLE) prctl(PR_SET_DUMPABLE, 1); @@ -331,126 +363,3 @@ int main(int argc, char **argv) master_cleanup(exit_signal); return(0); } - - - -void go_threading(void) -{ - int i; - struct CtdlThreadNode *last_worker; - - /* We can't use CT_PUSH() here so we do it the long way - * So we can still use CT for current thread */ - struct CtdlThreadNode *_this_cit_thread; - - /* - * Initialise the thread system - */ - ctdl_thread_internal_init(); - _this_cit_thread = CtdlThreadSelf(); - /* - * Now create a bunch of worker threads. - */ - CtdlLogPrintf(CTDL_DEBUG, "Starting %d worker threads\n", config.c_min_workers); - begin_critical_section(S_THREAD_LIST); - i=0; /* Always start at least 1 worker thread */ - do - { - ctdl_internal_create_thread("Worker Thread", CTDLTHREAD_BIGSTACK + CTDLTHREAD_WORKER, worker_thread, NULL); - } while (++i < config.c_min_workers); - end_critical_section(S_THREAD_LIST); - - /* Second call to module init functions now that threading is up */ - initialise_modules(1); - - /* - * This thread is now used for garbage collection of other threads in the thread list - */ - CtdlLogPrintf(CTDL_INFO, "Startup thread %d becoming garbage collector,\n", pthread_self()); - - /* - * We do a lot of locking and unlocking of the thread list in here. - * We do this so that we can repeatedly release time for other threads - * that may be waiting on the thread list. - * We are a low priority thread so we can afford to do this - */ - - while (CtdlThreadGetCount()) - { - if (exit_signal) - CtdlThreadStopAll(); - check_sched_shutdown(); - begin_critical_section(S_THREAD_LIST); - ctdl_thread_internal_calc_loadavg(); - end_critical_section(S_THREAD_LIST); - - /* Reduce the size of the worker thread pool if necessary. */ - if ((CtdlThreadGetWorkers() > config.c_min_workers) && (CtdlThreadWorkerAvg < 20)) - { - /* Ask a worker thread to stop as we no longer need it */ - begin_critical_section(S_THREAD_LIST); - last_worker = CtdlThreadList; - while (last_worker) - { - pthread_mutex_lock(&last_worker->ThreadMutex); - if (last_worker->flags & CTDLTHREAD_WORKER && last_worker->state > CTDL_THREAD_STOPPING) - { - pthread_mutex_unlock(&last_worker->ThreadMutex); - break; - } - pthread_mutex_unlock(&last_worker->ThreadMutex); - last_worker = last_worker->next; - } - end_critical_section(S_THREAD_LIST); - if (last_worker) - { -#ifdef WITH_THREADLOG - CtdlLogPrintf(CTDL_DEBUG, "Thread system, stopping excess worker thread \"%s\" (%ld).\n", - last_worker->name, - last_worker->tid - ); -#endif - CtdlThreadStop(last_worker); - } - } - - /* - * If all our workers are working hard, start some more to help out - * with things - */ - /* FIXME: come up with a better way to dynamically alter the number of threads - * based on the system load - */ -// if ((CtdlThreadGetWorkers() < config.c_max_workers) && (CtdlThreadGetWorkers() < num_sessions)) - // && (CtdlThreadLoadAvg < 90) ) - if ((CtdlThreadGetWorkers() < config.c_max_workers) && (CtdlThreadGetWorkerAvg() > 60) && (CtdlThreadGetLoadAvg() < 90) ) - { - for (i=0; i<5 ; i++) -// for (i=0; i< (num_sessions - CtdlThreadGetWorkers()) ; i++) -// for (i=0; i< (10 - (55 - CtdlThreadWorkerAvg) / CtdlThreadWorkerAvg / CtdlThreadGetWorkers()) ; i++) - { -// begin_critical_section(S_THREAD_LIST); - CtdlThreadCreate("Worker Thread", - CTDLTHREAD_BIGSTACK + CTDLTHREAD_WORKER, - worker_thread, - NULL - ); -// end_critical_section(S_THREAD_LIST); - } - } - - CtdlThreadGC(); - - if (CtdlThreadGetCount() <= 1) // Shutting down clean up the garbage collector - { - CtdlThreadGC(); - } - - if (CtdlThreadGetCount()) - CtdlThreadSleep(1); - } - /* - * If the above loop exits we must be shutting down since we obviously have no threads - */ - ctdl_thread_internal_cleanup(); -}