mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-29 08:34:20 +02:00
parent
19afcd894a
commit
33bd909b71
@ -61,11 +61,13 @@ start() {
|
|||||||
chown $ICINGA2_USER:$ICINGA2_COMMAND_GROUP $ICINGA2_STATE_DIR/run/icinga2/cmd
|
chown $ICINGA2_USER:$ICINGA2_COMMAND_GROUP $ICINGA2_STATE_DIR/run/icinga2/cmd
|
||||||
chmod 2755 $ICINGA2_STATE_DIR/run/icinga2/cmd
|
chmod 2755 $ICINGA2_STATE_DIR/run/icinga2/cmd
|
||||||
|
|
||||||
echo "Starting Icinga 2: "
|
echo "Starting Icinga 2: "
|
||||||
$DAEMON -c $ICINGA2_CONFIG_FILE -d -e $ICINGA2_ERROR_LOG -u $ICINGA2_USER -g $ICINGA2_GROUP
|
if ! $DAEMON -c $ICINGA2_CONFIG_FILE -d -e $ICINGA2_ERROR_LOG -u $ICINGA2_USER -g $ICINGA2_GROUP; then
|
||||||
|
echo "Error starting Icinga."
|
||||||
echo "Done"
|
exit 1
|
||||||
echo
|
else
|
||||||
|
echo "Done"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Restart Icinga 2
|
# Restart Icinga 2
|
||||||
@ -104,15 +106,9 @@ stop() {
|
|||||||
# Reload Icinga 2
|
# Reload Icinga 2
|
||||||
reload() {
|
reload() {
|
||||||
printf "Reloading Icinga 2: "
|
printf "Reloading Icinga 2: "
|
||||||
if [ ! -e $ICINGA2_PID_FILE ]; then
|
if ! $DAEMON -c $ICINGA2_CONFIG_FILE -d --reload -e $ICINGA2_ERROR_LOG -u $ICINGA2_USER -g $ICINGA2_GROUP; then
|
||||||
echo "The PID file '$ICINGA2_PID_FILE' does not exist."
|
echo "Error reloading Icinga."
|
||||||
exit 1
|
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
|
else
|
||||||
echo "Done"
|
echo "Done"
|
||||||
fi
|
fi
|
||||||
@ -162,7 +158,6 @@ case "$1" in
|
|||||||
start
|
start
|
||||||
;;
|
;;
|
||||||
reload)
|
reload)
|
||||||
checkconfig reload fail
|
|
||||||
reload
|
reload
|
||||||
;;
|
;;
|
||||||
checkconfig)
|
checkconfig)
|
||||||
|
@ -187,6 +187,34 @@ static bool Daemonize(const String& stderrFile)
|
|||||||
return true;
|
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 Main(void)
|
||||||
{
|
{
|
||||||
int argc = Application::GetArgC();
|
int argc = Application::GetArgC();
|
||||||
@ -252,6 +280,7 @@ int Main(void)
|
|||||||
("validate,C", "exit after validating the configuration")
|
("validate,C", "exit after validating the configuration")
|
||||||
("debug,x", "enable debugging")
|
("debug,x", "enable debugging")
|
||||||
("errorlog,e", po::value<std::string>(), "log fatal errors to the specified log file (only works in combination with --daemonize)")
|
("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
|
#ifndef _WIN32
|
||||||
("daemonize,d", "detach from the controlling terminal")
|
("daemonize,d", "detach from the controlling terminal")
|
||||||
("user,u", po::value<std::string>(), "user to run Icinga as")
|
("user,u", po::value<std::string>(), "user to run Icinga as")
|
||||||
@ -405,6 +434,17 @@ int Main(void)
|
|||||||
return EXIT_FAILURE;
|
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))
|
if (!LoadConfigFiles(appType))
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
@ -413,6 +453,12 @@ int Main(void)
|
|||||||
return EXIT_SUCCESS;
|
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")) {
|
if (g_AppParams.count("daemonize")) {
|
||||||
String errorLog;
|
String errorLog;
|
||||||
|
|
||||||
|
@ -638,7 +638,7 @@ void Application::UpdatePidFile(const String& filename)
|
|||||||
}
|
}
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
fprintf(m_PidFile, "%d", Utility::GetPid());
|
fprintf(m_PidFile, "%d\n", Utility::GetPid());
|
||||||
fflush(m_PidFile);
|
fflush(m_PidFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -656,6 +656,60 @@ void Application::ClosePidFile(void)
|
|||||||
m_PidFile = NULL;
|
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.
|
* Retrieves the path of the installation prefix.
|
||||||
*
|
*
|
||||||
|
@ -69,6 +69,7 @@ public:
|
|||||||
|
|
||||||
void UpdatePidFile(const String& filename);
|
void UpdatePidFile(const String& filename);
|
||||||
void ClosePidFile(void);
|
void ClosePidFile(void);
|
||||||
|
static pid_t ReadPidFile(const String& filename);
|
||||||
|
|
||||||
static String GetExePath(const String& argv0);
|
static String GetExePath(const String& argv0);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user