diff --git a/README b/README index 0b50667..e406649 100644 --- a/README +++ b/README @@ -357,8 +357,11 @@ set to zero to ensure quick booster restarts after launches. The boot mode is activated by starting applauncherd with --boot-mode. Normal mode can be entered again by sending SIGUSR1 Unix signal to the launcher. +Boot mode can be activated also by sending SIGUSR2 Unix signal to the launcher. + 3.2 Debug info +Applauncherd logs to syslog. Additional debug messages and logging also to stdout can be enabled with --debug. diff --git a/src/launcherlib/daemon.cpp b/src/launcherlib/daemon.cpp index 589856c..c65fe8d 100644 --- a/src/launcherlib/daemon.cpp +++ b/src/launcherlib/daemon.cpp @@ -75,19 +75,9 @@ Daemon::Daemon(int & argc, char * argv[]) : Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: Creating a pipe for boosters failed!\n"); } - if (pipe(m_sigChldPipeFd) == -1) + if (pipe(m_sigPipeFd) == -1) { - Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: Creating a pipe for SIGCHLD failed!\n"); - } - - if (pipe(m_sigTermPipeFd) == -1) - { - Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: Creating a pipe for SIGTERM failed!\n"); - } - - if (pipe(m_sigUsr1PipeFd) == -1) - { - Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: Creating a pipe for SIGUSR1 failed!\n"); + Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: Creating a pipe for Unix signals failed!\n"); } // Daemonize if desired @@ -202,16 +192,8 @@ void Daemon::run() FD_SET(m_boosterPipeFd[0], &rfds); ndfs = std::max(ndfs, m_boosterPipeFd[0]); - FD_SET(m_sigChldPipeFd[0], &rfds); - ndfs = std::max(ndfs, m_sigChldPipeFd[0]); - - FD_SET(m_sigTermPipeFd[0], &rfds); - ndfs = std::max(ndfs, m_sigTermPipeFd[0]); - - FD_SET(m_sigUsr1PipeFd[0], &rfds); - ndfs = std::max(ndfs, m_sigUsr1PipeFd[0]); - - char buffer; + FD_SET(m_sigPipeFd[0], &rfds); + ndfs = std::max(ndfs, m_sigPipeFd[0]); // Wait for something appearing in the pipes. if (select(ndfs + 1, &rfds, NULL, NULL, NULL) > 0) @@ -225,28 +207,38 @@ void Daemon::run() readFromBoosterPipe(m_boosterPipeFd[0]); } - // Check if we got SIGCHLD - if (FD_ISSET(m_sigChldPipeFd[0], &rfds)) - { - Logger::logDebug("FD_ISSET(m_sigChldPipeFd[0])"); - read(m_sigChldPipeFd[0], &buffer, 1); - reapZombies(); - } - - // Check if we got SIGTERM - if (FD_ISSET(m_sigTermPipeFd[0], &rfds)) + // Check if we got SIGCHLD, SIGTERM, SIGUSR1 or SIGUSR2 + if (FD_ISSET(m_sigPipeFd[0], &rfds)) { - Logger::logDebug("FD_ISSET(m_sigTermPipeFd[0])"); - read(m_sigTermPipeFd[0], &buffer, 1); - exit(EXIT_SUCCESS); - } + Logger::logDebug("FD_ISSET(m_sigPipeFd[0])"); + char dataReceived; + read(m_sigPipeFd[0], &dataReceived, 1); - // Check if we got SIGUSR1 - if (FD_ISSET(m_sigUsr1PipeFd[0], &rfds)) - { - Logger::logDebug("FD_ISSET(m_sigUsr1PipeFd[0])"); - read(m_sigUsr1PipeFd[0], &buffer, 1); - enterNormalMode(); + switch (dataReceived) + { + case SIGCHLD: + Logger::logDebug("SIGCHLD received."); + reapZombies(); + break; + + case SIGTERM: + Logger::logDebug("SIGTERM received."); + exit(EXIT_SUCCESS); + break; + + case SIGUSR1: + Logger::logDebug("SIGUSR1 received."); + enterNormalMode(); + break; + + case SIGUSR2: + Logger::logDebug("SIGUSR2 received."); + enterBootMode(); + break; + + default: + break; + } } } } @@ -418,17 +410,9 @@ void Daemon::forkBooster(char type, int sleepTime) // Close unused read end of the booster pipe close(m_boosterPipeFd[0]); - // Close SIGCHLD pipe - close(m_sigChldPipeFd[0]); - close(m_sigChldPipeFd[1]); - - // Close SIGTERM pipe - close(m_sigTermPipeFd[0]); - close(m_sigTermPipeFd[1]); - - // Close SIGUSR1 pipe - close(m_sigUsr1PipeFd[0]); - close(m_sigUsr1PipeFd[1]); + // Close signal pipe + close(m_sigPipeFd[0]); + close(m_sigPipeFd[1]); // Close unused sockets inherited from daemon closeUnusedSockets(type); @@ -690,7 +674,9 @@ void Daemon::usage(int status) " -b, --boot-mode Start %s in the boot mode. This means that\n" " boosters will not initialize caches and booster\n" " respawn delay is set to zero.\n" - " The normal mode is restored by sending SIGUSR1\n" + " Normal mode is restored by sending SIGUSR1\n" + " to the launcher.\n" + " Boot mode can be activated also by sending SIGUSR2\n" " to the launcher.\n" " -d, --daemon Run as %s a daemon.\n" " --debug Enable debug messages and log everything also to stdout.\n" @@ -701,19 +687,9 @@ void Daemon::usage(int status) exit(status); } -int Daemon::sigChldPipeFd() const -{ - return m_sigChldPipeFd[1]; -} - -int Daemon::sigTermPipeFd() const -{ - return m_sigTermPipeFd[1]; -} - -int Daemon::sigUsr1PipeFd() const +int Daemon::sigPipeFd() const { - return m_sigUsr1PipeFd[1]; + return m_sigPipeFd[1]; } void Daemon::enterNormalMode() @@ -727,6 +703,27 @@ void Daemon::enterNormalMode() Logger::logInfo("Daemon: Exited boot mode."); } + else + { + Logger::logInfo("Daemon: Already in normal mode."); + } +} + +void Daemon::enterBootMode() +{ + if (!m_bootMode) + { + m_bootMode = true; + + // Kill current boosters + killBoosters(); + + Logger::logInfo("Daemon: Entered boot mode."); + } + else + { + Logger::logInfo("Daemon: Already in boot mode."); + } } void Daemon::killBoosters() diff --git a/src/launcherlib/daemon.h b/src/launcherlib/daemon.h index d860bc1..3e3a35e 100644 --- a/src/launcherlib/daemon.h +++ b/src/launcherlib/daemon.h @@ -90,14 +90,11 @@ public: //! Unlock file (lock is not needed in boosters) static void unlock(); - //! Get fd to write when SIGCHLD arrives - int sigChldPipeFd() const; - - //! Get fd to write when SIGTERM arrives - int sigTermPipeFd() const; - - //! Get fd to write when SIGUSR1 arrives - int sigUsr1PipeFd() const; + /*! + * Get fd to which signal handler writes the number + * of an arriving Unix signal. + */ + int sigPipeFd() const; private: @@ -156,6 +153,9 @@ private: //! Enter normal mode (restart boosters with cache enabled) void enterNormalMode(); + //! Enter boot mode (restart boosters with cache disabled) + void enterBootMode(); + //! Kill all active boosters with -9 void killBoosters(); @@ -192,14 +192,8 @@ private: //! some parameters. int m_boosterPipeFd[2]; - //! Pipe used to safely catch SIGCHLD - int m_sigChldPipeFd[2]; - - //! Pipe used to safely catch SIGTERM - int m_sigTermPipeFd[2]; - - //! Pipe used to safely catch SIGUSR1 - int m_sigUsr1PipeFd[2]; + //! Pipe used to safely catch Unix signals + int m_sigPipeFd[2]; //! Argument vector initially given to the launcher process int m_initialArgc; diff --git a/src/launcherlib/main.cpp b/src/launcherlib/main.cpp index 549da10..b46a000 100644 --- a/src/launcherlib/main.cpp +++ b/src/launcherlib/main.cpp @@ -28,25 +28,30 @@ #define DECL_EXPORT extern "C" __attribute__ ((__visibility__("default"))) -int g_sigChldPipeFd = -1; -int g_sigTermPipeFd = -1; -int g_sigUsr1PipeFd = -1; - -char g_dummyPipeData = 0; +int g_sigPipeFd = -1; +char g_pipeDataSigChld = SIGCHLD; +char g_pipeDataSigTerm = SIGTERM; +char g_pipeDataSigUsr1 = SIGUSR1; +char g_pipeDataSigUsr2 = SIGUSR2; static void sigChldHandler(int) { - write(g_sigChldPipeFd, &g_dummyPipeData, 1); + write(g_sigPipeFd, &g_pipeDataSigChld, 1); } static void sigTermHandler(int) { - write(g_sigTermPipeFd, &g_dummyPipeData, 1); + write(g_sigPipeFd, &g_pipeDataSigTerm, 1); } static void sigUsr1Handler(int) { - write(g_sigUsr1PipeFd, &g_dummyPipeData, 1); + write(g_sigPipeFd, &g_pipeDataSigUsr1, 1); +} + +static void sigUsr2Handler(int) +{ + write(g_sigPipeFd, &g_pipeDataSigUsr2, 1); } //! Main function @@ -65,15 +70,14 @@ DECL_EXPORT int main(int argc, char * argv[]) // Create main daemon instance Daemon myDaemon(argc, argv); - // Get fd's for signal pipes. - g_sigChldPipeFd = myDaemon.sigChldPipeFd(); - g_sigTermPipeFd = myDaemon.sigTermPipeFd(); - g_sigUsr1PipeFd = myDaemon.sigUsr1PipeFd(); + // Get fd for signal pipe. + g_sigPipeFd = myDaemon.sigPipeFd(); // Install signal handlers signal(SIGCHLD, sigChldHandler); // reap zombies signal(SIGTERM, sigTermHandler); // exit launcher - signal(SIGUSR1, sigUsr1Handler); // restore normal mode + signal(SIGUSR1, sigUsr1Handler); // enter normal mode from boot mode + signal(SIGUSR2, sigUsr2Handler); // enter boot mode (same as --boot-mode) // Run the main loop myDaemon.run();