mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-27 07:34:15 +02:00
On check_timeout first send SIGTERM
... to allow check plugins to terminate gracefully. refs #6162
This commit is contained in:
parent
5f548c8f89
commit
e1bc4d474f
@ -50,10 +50,13 @@ static boost::once_flag l_SpawnHelperOnceFlag = BOOST_ONCE_INIT;
|
|||||||
|
|
||||||
Process::Process(Process::Arguments arguments, Dictionary::Ptr extraEnvironment)
|
Process::Process(Process::Arguments arguments, Dictionary::Ptr extraEnvironment)
|
||||||
: m_Arguments(std::move(arguments)), m_ExtraEnvironment(std::move(extraEnvironment)),
|
: m_Arguments(std::move(arguments)), m_ExtraEnvironment(std::move(extraEnvironment)),
|
||||||
m_Timeout(600), m_AdjustPriority(false), m_ResultAvailable(false)
|
m_Timeout(600)
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
, m_ReadPending(false), m_ReadFailed(false), m_Overlapped()
|
, m_ReadPending(false), m_ReadFailed(false), m_Overlapped()
|
||||||
|
#else /* _WIN32 */
|
||||||
|
, m_SentSigterm(false)
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
, m_AdjustPriority(false), m_ResultAvailable(false)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
m_Overlapped.hEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
|
m_Overlapped.hEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
|
||||||
@ -658,7 +661,7 @@ void Process::IOThreadProc(int tid)
|
|||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
if (process->m_Timeout != 0) {
|
if (process->m_Timeout != 0) {
|
||||||
double delta = process->m_Timeout - (now - process->m_Result.ExecutionStart);
|
double delta = process->GetNextTimeout() - (now - process->m_Result.ExecutionStart);
|
||||||
|
|
||||||
if (timeout == -1 || delta < timeout)
|
if (timeout == -1 || delta < timeout)
|
||||||
timeout = delta;
|
timeout = delta;
|
||||||
@ -716,7 +719,7 @@ void Process::IOThreadProc(int tid)
|
|||||||
bool is_timeout = false;
|
bool is_timeout = false;
|
||||||
|
|
||||||
if (it->second->m_Timeout != 0) {
|
if (it->second->m_Timeout != 0) {
|
||||||
double timeout = it->second->m_Result.ExecutionStart + it->second->m_Timeout;
|
double timeout = it->second->m_Result.ExecutionStart + it->second->GetNextTimeout();
|
||||||
|
|
||||||
if (timeout < now)
|
if (timeout < now)
|
||||||
is_timeout = true;
|
is_timeout = true;
|
||||||
@ -1029,15 +1032,42 @@ bool Process::DoEvents()
|
|||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
if (m_Timeout != 0) {
|
if (m_Timeout != 0) {
|
||||||
double timeout = m_Result.ExecutionStart + m_Timeout;
|
auto now (Utility::GetTime());
|
||||||
|
|
||||||
if (timeout < Utility::GetTime()) {
|
#ifndef _WIN32
|
||||||
|
{
|
||||||
|
auto timeout (GetNextTimeout());
|
||||||
|
auto deadline (m_Result.ExecutionStart + timeout);
|
||||||
|
|
||||||
|
if (deadline < now && !m_SentSigterm) {
|
||||||
|
Log(LogWarning, "Process")
|
||||||
|
<< "Terminating process " << m_PID << " (" << PrettyPrintArguments(m_Arguments)
|
||||||
|
<< ") after timeout of " << timeout << " seconds";
|
||||||
|
|
||||||
|
m_OutputStream << "<Timeout exceeded.>";
|
||||||
|
|
||||||
|
int error = ProcessKill(m_Process, SIGTERM);
|
||||||
|
if (error) {
|
||||||
|
Log(LogWarning, "Process")
|
||||||
|
<< "Couldn't terminate the process " << m_PID << " (" << PrettyPrintArguments(m_Arguments)
|
||||||
|
<< "): [errno " << error << "] " << strerror(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_SentSigterm = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
auto timeout (GetNextTimeout());
|
||||||
|
auto deadline (m_Result.ExecutionStart + timeout);
|
||||||
|
|
||||||
|
if (deadline < now) {
|
||||||
Log(LogWarning, "Process")
|
Log(LogWarning, "Process")
|
||||||
<< "Killing process group " << m_PID << " (" << PrettyPrintArguments(m_Arguments)
|
<< "Killing process group " << m_PID << " (" << PrettyPrintArguments(m_Arguments)
|
||||||
<< ") after timeout of " << m_Timeout << " seconds";
|
<< ") after timeout of " << timeout << " seconds";
|
||||||
|
|
||||||
m_OutputStream << "<Timeout exceeded.>";
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
m_OutputStream << "<Timeout exceeded.>";
|
||||||
TerminateProcess(m_Process, 3);
|
TerminateProcess(m_Process, 3);
|
||||||
#else /* _WIN32 */
|
#else /* _WIN32 */
|
||||||
int error = ProcessKill(-m_Process, SIGKILL);
|
int error = ProcessKill(-m_Process, SIGKILL);
|
||||||
@ -1155,3 +1185,11 @@ int Process::GetTID() const
|
|||||||
return (reinterpret_cast<uintptr_t>(this) / sizeof(void *)) % IOTHREADS;
|
return (reinterpret_cast<uintptr_t>(this) / sizeof(void *)) % IOTHREADS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double Process::GetNextTimeout() const
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return m_Timeout;
|
||||||
|
#else /* _WIN32 */
|
||||||
|
return m_SentSigterm ? m_Timeout * 1.1 : m_Timeout;
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
}
|
||||||
|
@ -82,6 +82,10 @@ private:
|
|||||||
Dictionary::Ptr m_ExtraEnvironment;
|
Dictionary::Ptr m_ExtraEnvironment;
|
||||||
|
|
||||||
double m_Timeout;
|
double m_Timeout;
|
||||||
|
#ifndef _WIN32
|
||||||
|
bool m_SentSigterm;
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
bool m_AdjustPriority;
|
bool m_AdjustPriority;
|
||||||
|
|
||||||
ProcessHandle m_Process;
|
ProcessHandle m_Process;
|
||||||
@ -105,6 +109,7 @@ private:
|
|||||||
static void IOThreadProc(int tid);
|
static void IOThreadProc(int tid);
|
||||||
bool DoEvents();
|
bool DoEvents();
|
||||||
int GetTID() const;
|
int GetTID() const;
|
||||||
|
double GetNextTimeout() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user