Merge pull request #7874 from Icinga/feature/sd_notify-7329

sd_notify() systemd about what we're doing right now
This commit is contained in:
Alexander Aleksandrovič Klimov 2021-06-28 18:20:15 +02:00 committed by GitHub
commit 58e329bc03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 0 deletions

View File

@ -5,6 +5,7 @@ After=syslog.target network-online.target postgresql.service mariadb.service car
[Service]
Type=notify
NotifyAccess=all
Environment="ICINGA2_ERROR_LOG=@ICINGA2_LOGDIR@/error.log"
EnvironmentFile=@ICINGA2_SYSCONFIGFILE@
ExecStartPre=@CMAKE_INSTALL_PREFIX@/lib/icinga2/prepare-dirs @ICINGA2_SYSCONFIGFILE@

View File

@ -105,6 +105,7 @@ static Value ProcessSpawnImpl(struct msghdr *msgh, const Dictionary::Ptr& reques
auto **envp = new char *[envc + (extraEnvironment ? extraEnvironment->GetLength() : 0) + 2];
const char* lcnumeric = "LC_NUMERIC=";
const char* notifySocket = "NOTIFY_SOCKET=";
int j = 0;
for (int i = 0; i < envc; i++) {
@ -112,6 +113,10 @@ static Value ProcessSpawnImpl(struct msghdr *msgh, const Dictionary::Ptr& reques
continue;
}
if (strncmp(environ[i], notifySocket, strlen(notifySocket)) == 0) {
continue;
}
envp[j] = strdup(environ[i]);
++j;
}

View File

@ -45,6 +45,14 @@ static po::variables_map g_AppParams;
REGISTER_CLICOMMAND("daemon", DaemonCommand);
static inline
void NotifyStatus(const char* status)
{
#ifdef HAVE_SYSTEMD
(void)sd_notifyf(0, "STATUS=%s", status);
#endif /* HAVE_SYSTEMD */
}
/*
* Daemonize(). On error, this function logs by itself and exits (i.e. does not return).
*
@ -235,12 +243,14 @@ int RunWorker(const std::vector<std::string>& configs, bool closeConsoleLog = fa
#endif /* I2_DEBUG */
Log(LogInformation, "cli", "Loading configuration file(s).");
NotifyStatus("Loading configuration file(s)...");
{
std::vector<ConfigItem::Ptr> newItems;
if (!DaemonUtility::LoadConfigFiles(configs, newItems, Configuration::ObjectsPath, Configuration::VarsPath)) {
Log(LogCritical, "cli", "Config validation failed. Re-run with 'icinga2 daemon -C' after fixing the config.");
NotifyStatus("Config validation failed.");
return EXIT_FAILURE;
}
@ -253,6 +263,8 @@ int RunWorker(const std::vector<std::string>& configs, bool closeConsoleLog = fa
Log(LogNotice, "cli")
<< "Waiting for the umbrella process to let us doing the actual work";
NotifyStatus("Waiting for the umbrella process to let us doing the actual work...");
if (closeConsoleLog) {
CloseStdIO(stderrFile);
Logger::DisableConsoleLog();
@ -266,18 +278,28 @@ int RunWorker(const std::vector<std::string>& configs, bool closeConsoleLog = fa
<< "The umbrella process let us continuing";
#endif /* _WIN32 */
NotifyStatus("Restoring the previous program state...");
/* restore the previous program state */
try {
ConfigObject::RestoreObjects(Configuration::StatePath);
} catch (const std::exception& ex) {
Log(LogCritical, "cli")
<< "Failed to restore state file: " << DiagnosticInformation(ex);
NotifyStatus("Failed to restore state file.");
return EXIT_FAILURE;
}
NotifyStatus("Activating config objects...");
// activate config only after daemonization: it starts threads and that is not compatible with fork()
if (!ConfigItem::ActivateItems(newItems, false, true, true)) {
Log(LogCritical, "cli", "Error activating configuration.");
NotifyStatus("Error activating configuration.");
return EXIT_FAILURE;
}
}
@ -296,6 +318,8 @@ int RunWorker(const std::vector<std::string>& configs, bool closeConsoleLog = fa
ApiListener::UpdateObjectAuthority();
NotifyStatus("Startup finished.");
return Application::GetInstance()->Run();
}
@ -796,6 +820,8 @@ int DaemonCommand::Run(const po::variables_map& vm, const std::vector<std::strin
Log(LogInformation, "Application")
<< "Reload done, old process shutting down. Child process with PID '" << nextWorker << "' is taking over.";
NotifyStatus("Shutting down old instance...");
(void)kill(currentWorker, SIGTERM);
{
@ -814,6 +840,8 @@ int DaemonCommand::Run(const po::variables_map& vm, const std::vector<std::strin
// Old instance shut down, allow the new one to continue working beyond config validation
(void)kill(nextWorker, SIGUSR2);
NotifyStatus("Shut down old instance.");
currentWorker = nextWorker;
}