Unlink the pidfile when we really shutdown (not reload).

Refs #6118
This commit is contained in:
Gerd von Egidy 2014-05-18 16:23:16 +02:00 committed by Gunnar Beutner
parent e93a22b440
commit e0d4b9fb80
3 changed files with 51 additions and 12 deletions

View File

@ -161,7 +161,7 @@ static void SigHupHandler(int)
} }
#endif /* _WIN32 */ #endif /* _WIN32 */
static bool Daemonize(const String& stderrFile) static bool Daemonize(void)
{ {
#ifndef _WIN32 #ifndef _WIN32
pid_t pid = fork(); pid_t pid = fork();
@ -170,11 +170,38 @@ static bool Daemonize(const String& stderrFile)
} }
if (pid) { if (pid) {
// TODO: do a real wait till the pidfile is written by the daemon // systemd requires that the pidfile of the daemon is written before the forking
Utility::Sleep(5); // process terminates. So wait till either the forked daemon has written a pidfile or died.
int status;
int ret;
pid_t readpid;
do {
Utility::Sleep(0.1);
readpid = Application::ReadPidFile(Application::GetPidPath());
ret = waitpid(pid, &status, WNOHANG);
} while (readpid != pid && ret == 0);
if (ret == pid) {
Log(LogCritical, "icinga-app", "The daemon could not be started. See logfile for details.");
exit(EXIT_FAILURE);
} else if (ret == -1) {
BOOST_THROW_EXCEPTION(posix_error()
<< boost::errinfo_api_function("waitpid")
<< boost::errinfo_errno(errno));
}
exit(0); exit(0);
} }
#endif /* _WIN32 */
return true;
}
static bool SetDaemonIO(const String& stderrFile)
{
#ifndef _WIN32
int fdnull = open("/dev/null", O_RDWR); int fdnull = open("/dev/null", O_RDWR);
if (fdnull >= 0) { if (fdnull >= 0) {
if (fdnull != 0) if (fdnull != 0)
@ -486,13 +513,17 @@ int Main(void)
Log(LogInformation, "icinga-app", "Previous instance has ended, taking over now."); Log(LogInformation, "icinga-app", "Previous instance has ended, taking over now.");
} }
if (g_AppParams.count("daemonize") && !g_AppParams.count("reload-internal")) { if (g_AppParams.count("daemonize")) {
String errorLog; if (!g_AppParams.count("reload-internal")) {
// no additional fork neccessary on reload
Daemonize();
}
String errorLog;
if (g_AppParams.count("errorlog")) if (g_AppParams.count("errorlog"))
errorLog = g_AppParams["errorlog"].as<std::string>(); errorLog = g_AppParams["errorlog"].as<std::string>();
Daemonize(errorLog); SetDaemonIO(errorLog);
Logger::DisableConsoleLog(); Logger::DisableConsoleLog();
} }

View File

@ -96,10 +96,11 @@ void Application::Stop(void)
// means that the restart succeeded and the new process wants to take // 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 // over. Write the PID of the new process to the pidfile before this
// process exits to keep systemd happy. // process exits to keep systemd happy.
if (l_Restarting) if (l_Restarting) {
UpdatePidFile(GetPidPath(),m_ReloadProcess); UpdatePidFile(GetPidPath(), m_ReloadProcess);
ClosePidFile(false);
ClosePidFile(); } else
ClosePidFile(true);
DynamicObject::Stop(); DynamicObject::Stop();
} }
@ -681,13 +682,20 @@ void Application::UpdatePidFile(const String& filename, pid_t pid)
/** /**
* Closes the PID file. Does nothing if the PID file is not currently open. * Closes the PID file. Does nothing if the PID file is not currently open.
*/ */
void Application::ClosePidFile(void) void Application::ClosePidFile(bool unlink)
{ {
ASSERT(!OwnsLock()); ASSERT(!OwnsLock());
ObjectLock olock(this); ObjectLock olock(this);
if (m_PidFile != NULL) if (m_PidFile != NULL)
{
if (unlink) {
String pidpath = GetPidPath();
::unlink(pidpath.CStr());
}
fclose(m_PidFile); fclose(m_PidFile);
}
m_PidFile = NULL; m_PidFile = NULL;
} }

View File

@ -69,7 +69,7 @@ public:
static bool IsDebugging(void); static bool IsDebugging(void);
void UpdatePidFile(const String& filename, pid_t pid = Utility::GetPid()); void UpdatePidFile(const String& filename, pid_t pid = Utility::GetPid());
void ClosePidFile(void); void ClosePidFile(bool unlink);
static pid_t ReadPidFile(const String& filename); static pid_t ReadPidFile(const String& filename);
static String GetExePath(const String& argv0); static String GetExePath(const String& argv0);