mirror of https://github.com/Icinga/icinga2.git
parent
19afcd894a
commit
33bd909b71
|
@ -61,11 +61,13 @@ start() {
|
|||
chown $ICINGA2_USER:$ICINGA2_COMMAND_GROUP $ICINGA2_STATE_DIR/run/icinga2/cmd
|
||||
chmod 2755 $ICINGA2_STATE_DIR/run/icinga2/cmd
|
||||
|
||||
echo "Starting Icinga 2: "
|
||||
$DAEMON -c $ICINGA2_CONFIG_FILE -d -e $ICINGA2_ERROR_LOG -u $ICINGA2_USER -g $ICINGA2_GROUP
|
||||
|
||||
echo "Done"
|
||||
echo
|
||||
echo "Starting Icinga 2: "
|
||||
if ! $DAEMON -c $ICINGA2_CONFIG_FILE -d -e $ICINGA2_ERROR_LOG -u $ICINGA2_USER -g $ICINGA2_GROUP; then
|
||||
echo "Error starting Icinga."
|
||||
exit 1
|
||||
else
|
||||
echo "Done"
|
||||
fi
|
||||
}
|
||||
|
||||
# Restart Icinga 2
|
||||
|
@ -104,15 +106,9 @@ stop() {
|
|||
# Reload Icinga 2
|
||||
reload() {
|
||||
printf "Reloading Icinga 2: "
|
||||
if [ ! -e $ICINGA2_PID_FILE ]; then
|
||||
echo "The PID file '$ICINGA2_PID_FILE' does not exist."
|
||||
if ! $DAEMON -c $ICINGA2_CONFIG_FILE -d --reload -e $ICINGA2_ERROR_LOG -u $ICINGA2_USER -g $ICINGA2_GROUP; then
|
||||
echo "Error reloading Icinga."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pid=`cat $ICINGA2_PID_FILE`
|
||||
|
||||
if ! kill -HUP $pid >/dev/null 2>&1; then
|
||||
echo "Failed - Icinga 2 is not running."
|
||||
else
|
||||
echo "Done"
|
||||
fi
|
||||
|
@ -162,7 +158,6 @@ case "$1" in
|
|||
start
|
||||
;;
|
||||
reload)
|
||||
checkconfig reload fail
|
||||
reload
|
||||
;;
|
||||
checkconfig)
|
||||
|
|
|
@ -187,6 +187,34 @@ static bool Daemonize(const String& stderrFile)
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminate another process and wait till it has ended
|
||||
*
|
||||
* @params target PID of the process to end
|
||||
*/
|
||||
static void TerminateAndWaitForEnd(pid_t target)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
// allow 15 seconds timeout
|
||||
double timeout = Utility::GetTime() + 15;
|
||||
|
||||
int ret = kill(target, SIGTERM);
|
||||
|
||||
while(Utility::GetTime() < timeout && (ret==0 || errno!=ESRCH))
|
||||
{
|
||||
Utility::Sleep(0.1);
|
||||
ret = kill(target, 0);
|
||||
}
|
||||
|
||||
// timeout and the process still seems to live: kill it
|
||||
if (ret == 0 || errno != ESRCH)
|
||||
kill(target, SIGKILL);
|
||||
|
||||
#else
|
||||
// TODO: implement this for Win32
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
|
||||
int Main(void)
|
||||
{
|
||||
int argc = Application::GetArgC();
|
||||
|
@ -252,6 +280,7 @@ int Main(void)
|
|||
("validate,C", "exit after validating the configuration")
|
||||
("debug,x", "enable debugging")
|
||||
("errorlog,e", po::value<std::string>(), "log fatal errors to the specified log file (only works in combination with --daemonize)")
|
||||
("reload,r", "reload a running icinga instance")
|
||||
#ifndef _WIN32
|
||||
("daemonize,d", "detach from the controlling terminal")
|
||||
("user,u", po::value<std::string>(), "user to run Icinga as")
|
||||
|
@ -405,6 +434,17 @@ int Main(void)
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
pid_t runningpid = Application::ReadPidFile(Application::GetPidPath());
|
||||
if (g_AppParams.count("reload")) {
|
||||
if (runningpid < 0) {
|
||||
Log(LogCritical, "icinga-app", "No instance of Icinga currently running: can't reload.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
} else if (!g_AppParams.count("validate") && runningpid >= 0) {
|
||||
Log(LogCritical, "icinga-app", "Another instance of Icinga already running at PID " + Convert::ToString(runningpid));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!LoadConfigFiles(appType))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
|
@ -413,6 +453,12 @@ int Main(void)
|
|||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (g_AppParams.count("reload")) {
|
||||
Log(LogInformation, "icinga-app", "Terminating previous instance of icinga (PID " + Convert::ToString(runningpid) + ")");
|
||||
TerminateAndWaitForEnd(runningpid);
|
||||
Log(LogInformation, "icinga-app", "Previous instance has ended, taking over now.");
|
||||
}
|
||||
|
||||
if (g_AppParams.count("daemonize")) {
|
||||
String errorLog;
|
||||
|
||||
|
|
|
@ -638,7 +638,7 @@ void Application::UpdatePidFile(const String& filename)
|
|||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
fprintf(m_PidFile, "%d", Utility::GetPid());
|
||||
fprintf(m_PidFile, "%d\n", Utility::GetPid());
|
||||
fflush(m_PidFile);
|
||||
}
|
||||
|
||||
|
@ -656,6 +656,60 @@ void Application::ClosePidFile(void)
|
|||
m_PidFile = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if another process currently owns the pidfile and read it
|
||||
*
|
||||
* @param filename The name of the PID file.
|
||||
* @returns -1: no process owning the pidfile, pid of the process otherwise
|
||||
*/
|
||||
pid_t Application::ReadPidFile(const String& filename)
|
||||
{
|
||||
FILE *pidfile = fopen(filename.CStr(), "r");
|
||||
|
||||
if (pidfile == NULL)
|
||||
return -1;
|
||||
|
||||
#ifndef _WIN32
|
||||
int fd = fileno(pidfile);
|
||||
|
||||
struct flock lock;
|
||||
|
||||
lock.l_start = 0;
|
||||
lock.l_len = 0;
|
||||
lock.l_type = F_WRLCK;
|
||||
lock.l_whence = SEEK_SET;
|
||||
|
||||
if (fcntl(fd, F_GETLK, &lock) < 0) {
|
||||
int error = errno;
|
||||
fclose(pidfile);
|
||||
BOOST_THROW_EXCEPTION(posix_error()
|
||||
<< boost::errinfo_api_function("fcntl")
|
||||
<< boost::errinfo_errno(error));
|
||||
}
|
||||
|
||||
if (lock.l_type == F_UNLCK) {
|
||||
// nobody has locked the file: no icinga running
|
||||
fclose(pidfile);
|
||||
return -1;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
pid_t runningpid;
|
||||
int res = fscanf(pidfile, "%d", &runningpid);
|
||||
fclose(pidfile);
|
||||
|
||||
// bogus result?
|
||||
if (res != 1)
|
||||
return -1;
|
||||
|
||||
#ifdef _WIN32
|
||||
// TODO: add check if the read pid is still running or not
|
||||
#endif /* _WIN32 */
|
||||
|
||||
return runningpid;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the path of the installation prefix.
|
||||
*
|
||||
|
|
|
@ -69,6 +69,7 @@ public:
|
|||
|
||||
void UpdatePidFile(const String& filename);
|
||||
void ClosePidFile(void);
|
||||
static pid_t ReadPidFile(const String& filename);
|
||||
|
||||
static String GetExePath(const String& argv0);
|
||||
|
||||
|
|
Loading…
Reference in New Issue