X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/7b66bdcccfa4aad5a8e4110bf4769bc13c15dcfd..d3b6a58593b94c9ff41c30a7517086d607f28f10:/projects/stargazer/main.cpp diff --git a/projects/stargazer/main.cpp b/projects/stargazer/main.cpp index 7cab078d..1e4c677e 100644 --- a/projects/stargazer/main.cpp +++ b/projects/stargazer/main.cpp @@ -46,9 +46,7 @@ #include "stg/plugin.h" #include "stg/logger.h" #include "stg/scriptexecuter.h" -#include "stg/conffiles.h" #include "stg/version.h" -#include "stg/pinger.h" #include "stg_timer.h" #include "settings_impl.h" #include "users_impl.h" @@ -62,9 +60,6 @@ #include "pidfile.h" #include "eventloop.h" -using namespace std; -uint32_t eip; - #ifdef DEBUG #define MAIN_DEBUG (1) #define NO_DAEMON (1) @@ -72,12 +67,16 @@ uint32_t eip; #define START_FILE "/._ST_ART_ED_" -static bool needRulesReloading = false; -static bool childExited = false; -//static pid_t executerPid; -set executersPid; -static pid_t stgChildPid; +namespace +{ +std::set executersPid; +bool StartModCmp(const PLUGIN_RUNNER & lhs, const PLUGIN_RUNNER & rhs); +bool StopModCmp(const PLUGIN_RUNNER & lhs, const PLUGIN_RUNNER & rhs); +void StartTimer(); +int StartScriptExecuter(char * procName, int msgKey, int * msgID, SETTINGS_IMPL * settings); +int ForkAndWait(const std::string & confDir); +void KillExecuters(); //----------------------------------------------------------------------------- bool StartModCmp(const PLUGIN_RUNNER & lhs, const PLUGIN_RUNNER & rhs) @@ -90,29 +89,7 @@ bool StopModCmp(const PLUGIN_RUNNER & lhs, const PLUGIN_RUNNER & rhs) return lhs.GetStopPosition() > rhs.GetStopPosition(); } //----------------------------------------------------------------------------- -class STG_STOPPER -{ -public: - STG_STOPPER() { nonstop = true; } - bool GetStatus() const { return nonstop; }; - #ifdef NO_DAEMON - void Stop(const char * __file__, int __line__) - #else - void Stop(const char *, int) - #endif - { - #ifdef NO_DAEMON - printfd(__FILE__, "Stg stopped at %s:%d\n", __file__, __line__); - #endif - nonstop = false; - } -private: - bool nonstop; -}; -//----------------------------------------------------------------------------- -STG_STOPPER nonstop; -//----------------------------------------------------------------------------- -static void StartTimer() +void StartTimer() { STG_LOGGER & WriteServLog = GetStgLogger(); @@ -129,186 +106,11 @@ else } } //----------------------------------------------------------------------------- -void CatchUSR1(int) -{ - -} -//----------------------------------------------------------------------------- -void CatchTERM(int sig) -{ -/* - *Function Name:CatchINT - *Parameters: sig_num - ÎÏÍÅÒ ÓÉÇÎÁÌÁ - *Description: ïÂÒÁÂÏÔÞÉË ÓÉÇÎÁÌÁ INT - *Returns: îÉÞÅÇÏ - */ -STG_LOGGER & WriteServLog = GetStgLogger(); -WriteServLog("Shutting down... %d", sig); - -//nonstop = false; -nonstop.Stop(__FILE__, __LINE__); - -struct sigaction newsa, oldsa; -sigset_t sigmask; - -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGTERM); -newsa.sa_handler = SIG_IGN; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGTERM, &newsa, &oldsa); - -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGINT); -newsa.sa_handler = SIG_IGN; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGINT, &newsa, &oldsa); -} -//----------------------------------------------------------------------------- -void CatchPIPE(int) -{ -STG_LOGGER & WriteServLog = GetStgLogger(); -WriteServLog("Broken pipe!"); -} -//----------------------------------------------------------------------------- -void CatchHUP(int) -{ -needRulesReloading = true; -} -//----------------------------------------------------------------------------- -void CatchCHLD(int) -{ -int status; -pid_t childPid; -childPid = waitpid(-1, &status, WNOHANG); - -set::iterator pid; -pid = executersPid.find(childPid); -if (pid != executersPid.end()) - { - executersPid.erase(pid); - if (executersPid.empty() && nonstop.GetStatus()) - { - nonstop.Stop(__FILE__, __LINE__); - } - } -if (childPid == stgChildPid) - { - childExited = true; - } -} -/*//----------------------------------------------------------------------------- -void CatchSEGV(int, siginfo_t *, void *) -{ -char fileName[50]; -sprintf(fileName, "/tmp/stg_segv.%d", getpid()); -FILE * f = fopen(fileName, "wt"); -if (f) - { - fprintf(f, "\nSignal info:\n~~~~~~~~~~~~\n"); - fprintf(f, "numb:\t %d (%d)\n", sinfo->si_signo, sig); - fprintf(f, "errn:\t %d\n", sinfo->si_errno); - fprintf(f, "code:\t %d ", sinfo->si_code); - - switch (sinfo->si_code) - { - case SEGV_MAPERR: - fprintf(f, "(SEGV_MAPERR - address not mapped to object)\n"); - break; - - case SEGV_ACCERR: - fprintf(f, "(SEGV_ACCERR - invalid permissions for mapped object)\n"); - break; - - default: - fprintf(f, "???\n"); - } - - fprintf(f, "addr:\t 0x%.8X\n", - (unsigned int)sinfo->si_addr); - - Dl_info dlinfo; - //asm("movl %eip, eip"); - if (dladdr((void*)CatchCHLD, &dlinfo)) - { - fprintf(f, "SEGV point: %s %s\n", dlinfo.dli_fname, dlinfo.dli_sname); - } - else - { - fprintf(f, "Cannot find SEGV point\n"); - } - - fclose(f); - } - -struct sigaction segv_action, segv_action_old; - -segv_action.sa_handler = SIG_DFL; -segv_action.sa_sigaction = NULL; -segv_action.sa_flags = SA_SIGINFO; -segv_action.sa_restorer = NULL; - -sigaction(SIGSEGV, &segv_action, &segv_action_old); -}*/ -//----------------------------------------------------------------------------- -static void SetSignalHandlers() -{ -struct sigaction newsa, oldsa; -sigset_t sigmask; -/////// -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGTERM); -newsa.sa_handler = CatchTERM; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGTERM, &newsa, &oldsa); -/////// -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGUSR1); -newsa.sa_handler = CatchUSR1; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGUSR1, &newsa, &oldsa); -/////// -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGINT); -newsa.sa_handler = CatchTERM; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGINT, &newsa, &oldsa); -////// -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGPIPE); -newsa.sa_handler = CatchPIPE; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGPIPE, &newsa, &oldsa); -////// -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGHUP); -newsa.sa_handler = CatchHUP; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGHUP, &newsa, &oldsa); -////// -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGCHLD); -newsa.sa_handler = CatchCHLD; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGCHLD, &newsa, &oldsa); - -/*newsa.sa_handler = NULL; -newsa.sa_sigaction = CatchSEGV; -newsa.sa_flags = SA_SIGINFO; -newsa.sa_restorer = NULL; -sigaction(SIGSEGV, &newsa, &oldsa);*/ - -return; -} -//----------------------------------------------------------------------------- +#if defined(LINUX) || defined(DARWIN) int StartScriptExecuter(char * procName, int msgKey, int * msgID, SETTINGS_IMPL * settings) +#else +int StartScriptExecuter(char *, int msgKey, int * msgID, SETTINGS_IMPL * settings) +#endif { STG_LOGGER & WriteServLog = GetStgLogger(); @@ -349,12 +151,20 @@ switch (executerPid) case 0: delete settings; +#if defined(LINUX) || defined(DARWIN) Executer(*msgID, executerPid, procName); +#else + Executer(*msgID, executerPid); +#endif return 1; default: if (executersPid.empty()) { +#if defined(LINUX) || defined(DARWIN) Executer(*msgID, executerPid, NULL); +#else + Executer(*msgID, executerPid); +#endif } executersPid.insert(executerPid); } @@ -362,17 +172,17 @@ return 0; } //----------------------------------------------------------------------------- #ifndef NO_DAEMON -int ForkAndWait(const string & confDir) +int ForkAndWait(const std::string & confDir) #else -int ForkAndWait(const string &) +int ForkAndWait(const std::string &) #endif { #ifndef NO_DAEMON -stgChildPid = fork(); -string startFile = confDir + START_FILE; +pid_t childPid = fork(); +std::string startFile = confDir + START_FILE; unlink(startFile.c_str()); -switch (stgChildPid) +switch (childPid) { case -1: return -1; @@ -394,11 +204,6 @@ switch (stgChildPid) exit(0); } - if (childExited) - { - unlink(startFile.c_str()); - exit(1); - } nanosleep(&ts, NULL); } unlink(startFile.c_str()); @@ -411,7 +216,7 @@ return 0; //----------------------------------------------------------------------------- void KillExecuters() { -set::iterator pid; +std::set::iterator pid; pid = executersPid.begin(); while (pid != executersPid.end()) { @@ -421,27 +226,10 @@ while (pid != executersPid.end()) } } //----------------------------------------------------------------------------- +} // namespace anonymous +//----------------------------------------------------------------------------- int main(int argc, char * argv[]) { - -/* - Initialization order: - - Logger - - Stg timer - - Settings - - Plugins - - Plugins settings - - Read Admins - - Read Tariffs - - Read Users - - Start Users - - Start Traffcounter - - Start Plugins - - Start pinger - - Set signal nandlers - - Fork and exit - * */ - SETTINGS_IMPL * settings = NULL; STORE * dataStore = NULL; TARIFFS_IMPL * tariffs = NULL; @@ -457,10 +245,10 @@ int msgID = -11; WriteServLog.SetLogFileName("/var/log/stargazer.log"); } -vector modSettings; -list modules; +std::vector modSettings; +std::list modules; -list::iterator modIter; +std::list::iterator modIter; if (getuid()) { @@ -483,9 +271,8 @@ if (settings->ReadSettings()) WriteServLog("ReadSettings error. %s", settings->GetStrError().c_str()); exit(1); } - #ifndef NO_DAEMON -string startFile(settings->GetConfDir() + START_FILE); +std::string startFile(settings->GetConfDir() + START_FILE); #endif if (ForkAndWait(settings->GetConfDir()) < 0) @@ -517,6 +304,10 @@ for (size_t i = 0; i < settings->GetExecutersNum(); i++) PIDFile pidFile(settings->GetPIDFileName()); +sigset_t signalSet; +sigfillset(&signalSet); +pthread_sigmask(SIG_BLOCK, &signalSet, NULL); + StartTimer(); WaitTimer(); if (!IsStgTimerRunning()) @@ -555,7 +346,7 @@ modSettings = settings->GetModulesSettings(); for (size_t i = 0; i < modSettings.size(); i++) { - string modulePath = settings->GetModulesPath(); + std::string modulePath = settings->GetModulesPath(); modulePath += "/mod_"; modulePath += modSettings[i].moduleName; modulePath += ".so"; @@ -578,17 +369,16 @@ modIter = modules.begin(); while (modIter != modules.end()) { - //Loading modules if (modIter->Load()) { - WriteServLog("Error: %s", + WriteServLog("Error loading module '%s': %s", + modIter->GetPlugin()->GetVersion().c_str(), modIter->GetStrError().c_str()); goto exitLblNotStarted; } ++modIter; } -//Start section if (users->Start()) { goto exitLblNotStarted; @@ -609,31 +399,16 @@ while (modIter != modules.end()) { if (modIter->Start()) { - WriteServLog("Error: %s", + WriteServLog("Error starting module '%s': %s", + modIter->GetPlugin()->GetVersion().c_str(), modIter->GetStrError().c_str()); - //printfd(__FILE__, "Error: %s\n", capRunner.GetStrError().c_str()); goto exitLbl; } WriteServLog("Module: '%s'. Start successfull.", modIter->GetPlugin()->GetVersion().c_str()); ++modIter; } -SetSignalHandlers(); -srandom(stgTime); - -/* - * Note that an implementation in which nice returns the new nice value - * can legitimately return -1. To reliably detect an error, set - * errno to 0 before the call, and check its value when nice returns -1. - * - * - * (c) man 2 nice - */ -/*errno = 0; -if (nice(-19) && errno) { - printfd(__FILE__, "nice failed: '%s'\n", strerror(errno)); - WriteServLog("nice failed: '%s'", strerror(errno)); -}*/ +srandom(static_cast(stgTime)); WriteServLog("Stg started successfully."); WriteServLog("+++++++++++++++++++++++++++++++++++++++++++++"); @@ -642,26 +417,57 @@ WriteServLog("+++++++++++++++++++++++++++++++++++++++++++++"); creat(startFile.c_str(), S_IRUSR); #endif -while (nonstop.GetStatus()) +while (true) { - if (needRulesReloading) + sigfillset(&signalSet); + int sig = 0; + sigwait(&signalSet, &sig); + bool stop = false; + int status; + pid_t childPid; + std::set::iterator it; + switch (sig) { - needRulesReloading = false; - traffCnt->Reload(); + case SIGHUP: + traffCnt->Reload(); + modIter = modules.begin(); + for (; modIter != modules.end(); ++modIter) + { + if (modIter->Reload()) + { + WriteServLog("Error reloading module '%s': '%s'", modIter->GetPlugin()->GetVersion().c_str(), + modIter->GetStrError().c_str()); + printfd(__FILE__, "Error reloading module '%s': '%s'\n", modIter->GetPlugin()->GetVersion().c_str(), + modIter->GetStrError().c_str()); + } + } + break; + case SIGTERM: + stop = true; + break; + case SIGINT: + stop = true; + break; + case SIGPIPE: + WriteServLog("Broken pipe!"); + break; + case SIGCHLD: + childPid = waitpid(-1, &status, WNOHANG); - modIter = modules.begin(); - for (; modIter != modules.end(); ++modIter) - { - if (modIter->Reload()) + it = executersPid.find(childPid); + if (it != executersPid.end()) { - WriteServLog("Error reloading %s ('%s')", modIter->GetPlugin()->GetVersion().c_str(), - modIter->GetStrError().c_str()); - printfd(__FILE__, "Error reloading %s ('%s')\n", modIter->GetPlugin()->GetVersion().c_str(), - modIter->GetStrError().c_str()); + executersPid.erase(it); + if (executersPid.empty()) + stop = true; } - } + break; + default: + WriteServLog("Ignore signal %d", sig); + break; } - stgUsleep(100000); + if (stop) + break; } exitLbl: @@ -677,14 +483,15 @@ while (modIter != modules.end()) printfd(__FILE__, "Stopping module '%s'\n", name.c_str()); if (modIter->Stop()) { - WriteServLog("Module \'%s\': Error: %s", + WriteServLog("Error stopping module '%s': %s", modIter->GetPlugin()->GetVersion().c_str(), modIter->GetStrError().c_str()); - printfd(__FILE__, "Failed to stop module '%s'\n", name.c_str()); - //printfd(__FILE__, "Error: %s\n", capRunner.GetStrError().c_str()); - //goto exitLbl; + printfd(__FILE__, "Error stopping module '%s': '%s'\n", modIter->GetPlugin()->GetVersion().c_str(), modIter->GetStrError().c_str()); + } + else + { + WriteServLog("Module: '%s'. Stop successfull.", modIter->GetPlugin()->GetVersion().c_str()); } - WriteServLog("Module: \'%s\'. Stop successfull.", modIter->GetPlugin()->GetVersion().c_str()); ++modIter; } @@ -699,13 +506,20 @@ modIter = modules.begin(); while (modIter != modules.end()) { std::string name = modIter->GetFileName(); - printfd(__FILE__, "Unloading module '%s'\n", name.c_str()); - if (modIter->Unload()) + if (modIter->IsRunning()) { - WriteServLog("Module \'%s\': Error: %s", - name.c_str(), - modIter->GetStrError().c_str()); - printfd(__FILE__, "Failed to unload module '%s'\n", name.c_str()); + printfd(__FILE__, "Passing module '%s' `cause it's still running\n", name.c_str()); + } + else + { + printfd(__FILE__, "Unloading module '%s'\n", name.c_str()); + if (modIter->Unload()) + { + WriteServLog("Error unloading module '%s': '%s'", + modIter->GetPlugin()->GetVersion().c_str(), + modIter->GetStrError().c_str()); + printfd(__FILE__, "Error unloading module '%s': '%s'\n", modIter->GetPlugin()->GetVersion().c_str(), modIter->GetStrError().c_str()); + } } ++modIter; }