mirror of https://github.com/Icinga/icinga2.git
Proof of concept how a real reload-handling with systemd could work.
Refs #6118
This commit is contained in:
parent
497e58e4d6
commit
e93a22b440
|
@ -169,8 +169,11 @@ static bool Daemonize(const String& stderrFile)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (pid)
|
||||
if (pid) {
|
||||
// TODO: do a real wait till the pidfile is written by the daemon
|
||||
Utility::Sleep(5);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int fdnull = open("/dev/null", O_RDWR);
|
||||
if (fdnull >= 0) {
|
||||
|
@ -483,7 +486,7 @@ int Main(void)
|
|||
Log(LogInformation, "icinga-app", "Previous instance has ended, taking over now.");
|
||||
}
|
||||
|
||||
if (g_AppParams.count("daemonize")) {
|
||||
if (g_AppParams.count("daemonize") && !g_AppParams.count("reload-internal")) {
|
||||
String errorLog;
|
||||
|
||||
if (g_AppParams.count("errorlog"))
|
||||
|
|
|
@ -46,6 +46,7 @@ REGISTER_TYPE(Application);
|
|||
Application *Application::m_Instance = NULL;
|
||||
bool Application::m_ShuttingDown = false;
|
||||
bool Application::m_RequestRestart = false;
|
||||
pid_t Application::m_ReloadProcess = 0;
|
||||
static bool l_Restarting = false;
|
||||
bool Application::m_Debugging = false;
|
||||
int Application::m_ArgC;
|
||||
|
@ -91,6 +92,13 @@ void Application::Stop(void)
|
|||
WSACleanup();
|
||||
#endif /* _WIN32 */
|
||||
|
||||
// Getting a shutdown-signal when a restart is in progress usually
|
||||
// means that the restart succeeded and the new process wants to take
|
||||
// over. Write the PID of the new process to the pidfile before this
|
||||
// process exits to keep systemd happy.
|
||||
if (l_Restarting)
|
||||
UpdatePidFile(GetPidPath(),m_ReloadProcess);
|
||||
|
||||
ClosePidFile();
|
||||
|
||||
DynamicObject::Stop();
|
||||
|
@ -218,7 +226,7 @@ void Application::SetArgV(char **argv)
|
|||
* Processes events for registered sockets and timers and calls whatever
|
||||
* handlers have been set up for these events.
|
||||
*/
|
||||
void Application::RunEventLoop(void) const
|
||||
void Application::RunEventLoop(void)
|
||||
{
|
||||
Timer::Initialize();
|
||||
|
||||
|
@ -254,7 +262,7 @@ mainloop:
|
|||
goto mainloop;
|
||||
|
||||
l_Restarting = true;
|
||||
StartReloadProcess();
|
||||
m_ReloadProcess = StartReloadProcess();
|
||||
|
||||
goto mainloop;
|
||||
}
|
||||
|
@ -285,7 +293,7 @@ static void ReloadProcessCallback(const ProcessResult& pr)
|
|||
l_Restarting = false;
|
||||
}
|
||||
|
||||
void Application::StartReloadProcess(void) const
|
||||
pid_t Application::StartReloadProcess(void)
|
||||
{
|
||||
Log(LogInformation, "base", "Got reload command: Starting new instance.");
|
||||
|
||||
|
@ -305,6 +313,8 @@ void Application::StartReloadProcess(void) const
|
|||
Process::Ptr process = make_shared<Process>(Process::PrepareCommand(args));
|
||||
process->SetTimeout(300);
|
||||
process->Run(&ReloadProcessCallback);
|
||||
|
||||
return process->GetHandle();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -619,8 +629,9 @@ int Application::Run(void)
|
|||
* if the PID file is already locked by another instance of the application.
|
||||
*
|
||||
* @param filename The name of the PID file.
|
||||
* @param pid The PID to write; default is the current PID
|
||||
*/
|
||||
void Application::UpdatePidFile(const String& filename)
|
||||
void Application::UpdatePidFile(const String& filename, pid_t pid)
|
||||
{
|
||||
ASSERT(!OwnsLock());
|
||||
ObjectLock olock(this);
|
||||
|
@ -663,7 +674,7 @@ void Application::UpdatePidFile(const String& filename)
|
|||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
fprintf(m_PidFile, "%d\n", Utility::GetPid());
|
||||
fprintf(m_PidFile, "%d\n", pid);
|
||||
fflush(m_PidFile);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "base/i2-base.h"
|
||||
#include "base/application.th"
|
||||
#include "base/threadpool.h"
|
||||
#include "base/utility.h"
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
@ -67,7 +68,7 @@ public:
|
|||
static void SetDebugging(bool debug);
|
||||
static bool IsDebugging(void);
|
||||
|
||||
void UpdatePidFile(const String& filename);
|
||||
void UpdatePidFile(const String& filename, pid_t pid = Utility::GetPid());
|
||||
void ClosePidFile(void);
|
||||
static pid_t ReadPidFile(const String& filename);
|
||||
|
||||
|
@ -113,9 +114,9 @@ protected:
|
|||
virtual void OnConfigLoaded(void);
|
||||
virtual void Stop(void);
|
||||
|
||||
void RunEventLoop(void) const;
|
||||
void RunEventLoop(void);
|
||||
|
||||
void StartReloadProcess(void) const;
|
||||
pid_t StartReloadProcess(void);
|
||||
|
||||
virtual void OnShutdown(void);
|
||||
|
||||
|
@ -124,7 +125,10 @@ private:
|
|||
|
||||
static bool m_ShuttingDown; /**< Whether the application is in the process of
|
||||
shutting down. */
|
||||
static bool m_RequestRestart;
|
||||
static bool m_RequestRestart; /**< A restart was requested through SIGHUP */
|
||||
static pid_t m_ReloadProcess; /**< The PID of a subprocess doing a reload,
|
||||
only valid when l_Restarting==true */
|
||||
|
||||
static int m_ArgC; /**< The number of command-line arguments. */
|
||||
static char **m_ArgV; /**< Command-line arguments. */
|
||||
FILE *m_PidFile; /**< The PID file */
|
||||
|
|
|
@ -636,6 +636,12 @@ bool Process::DoEvents(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
Process::ProcessHandle Process::GetHandle(void) const
|
||||
{
|
||||
return m_Process;
|
||||
}
|
||||
|
||||
|
||||
int Process::GetTID(void) const
|
||||
{
|
||||
return (reinterpret_cast<uintptr_t>(this) / sizeof(void *)) % IOTHREADS;
|
||||
|
|
|
@ -73,6 +73,8 @@ public:
|
|||
|
||||
void Run(const boost::function<void (const ProcessResult&)>& callback = boost::function<void (const ProcessResult&)>());
|
||||
|
||||
ProcessHandle GetHandle(void) const;
|
||||
|
||||
static Arguments PrepareCommand(const Value& command);
|
||||
|
||||
static void StaticInitialize(void);
|
||||
|
|
Loading…
Reference in New Issue