From dfd91c6a049d2543c906116777685e45581a3f98 Mon Sep 17 00:00:00 2001 From: Victor Moene Date: Tue, 25 Aug 2026 14:52:14 +0200 Subject: [PATCH] Made reactor-plugin into its own forked process Ticket: ENT-14434 Signed-off-by: Victor Moene --- cf-reactor/cf-reactor.c | 74 +++++++++++++++++++++++++++++++++- libpromises/enterprise_stubs.c | 2 +- libpromises/prototypes3.h | 2 +- 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/cf-reactor/cf-reactor.c b/cf-reactor/cf-reactor.c index 9e9e87cb12f..b975314dc7f 100644 --- a/cf-reactor/cf-reactor.c +++ b/cf-reactor/cf-reactor.c @@ -33,6 +33,10 @@ #include #include #include +#include /* HandleSignalsForDaemon, IsPendingTermination */ +#include /* sleep */ +#include /* signal, kill */ +#include /*****************************************************************************/ /* Globals */ @@ -177,6 +181,15 @@ static GenericAgentConfig *CheckOpts(int argc, char **argv) return config; } +static void TerminateReactorEnterprise(int pid) +{ +#ifndef __MINGW32__ + kill((pid_t) pid, SIGINT); +#else + (void) pid; +#endif /* !__MINGW32__ */ +} + /*****************************************************************************/ int main(int argc, char *argv[]) @@ -185,10 +198,67 @@ int main(int argc, char *argv[]) EvalContext *ctx = EvalContextNew(); GenericAgentConfigApply(ctx, config); - int ret = ReactorEnterpriseMain(NO_FORK); +#ifdef __MINGW32__ + + if (!NO_FORK) + { + Log(LOG_LEVEL_VERBOSE, "Windows does not support starting processes in the background - starting in foreground"); + } + +#else /* !__MINGW32__ */ + pid_t existing_pid = ReadPID("cf-reactor.pid"); + if ((existing_pid != -1) && (kill(existing_pid, 0) == 0)) + { + Log(LOG_LEVEL_ERR, "Another instance of cf-reactor is already running, terminating"); + return 1; + } + + if ((!NO_FORK) && (fork() != 0)) + { + Log(LOG_LEVEL_INFO, "cf-reactor: starting"); + _exit(EXIT_SUCCESS); + } + + if (!NO_FORK) + { + ActAsDaemon(); + } + +#endif /* !__MINGW32__ */ + + umask(077); + WritePID("cf-reactor.pid"); + + signal(SIGINT, HandleSignalsForDaemon); + signal(SIGTERM, HandleSignalsForDaemon); + signal(SIGBUS, HandleSignalsForDaemon); + signal(SIGHUP, HandleSignalsForDaemon); + signal(SIGPIPE, SIG_IGN); + signal(SIGUSR1, HandleSignalsForDaemon); + signal(SIGUSR2, HandleSignalsForDaemon); + + int child = ReactorEnterpriseMain(); + if (child == -1) + { + return 1; + } + + for (int i = 0; !IsPendingTermination(); i++) + { + /* Do something */ + Log(LOG_LEVEL_INFO, "cf-reactor: %d", i); + sleep(1); + } + + /* child == 0 means in this case that no child process was created. + It is the default value returned by enterprise stubs */ + if (child > 0) + { + TerminateReactorEnterprise(child); + } GenericAgentFinalize(ctx, config); CallCleanupFunctions(); - return ret; + return 0; } diff --git a/libpromises/enterprise_stubs.c b/libpromises/enterprise_stubs.c index 98ebe1696df..3c21897517c 100644 --- a/libpromises/enterprise_stubs.c +++ b/libpromises/enterprise_stubs.c @@ -232,7 +232,7 @@ ENTERPRISE_VOID_FUNC_2ARG_DEFINE_STUB(void, Nova_ClassHistoryEnable, { } -ENTERPRISE_FUNC_1ARG_DEFINE_STUB(int, ReactorEnterpriseMain, ARG_UNUSED bool, no_fork) +ENTERPRISE_FUNC_0ARG_DEFINE_STUB(int, ReactorEnterpriseMain) { Log(LOG_LEVEL_VERBOSE, "Nova extension library is not available."); Log(LOG_LEVEL_VERBOSE, "Running cf-reactor community edition."); diff --git a/libpromises/prototypes3.h b/libpromises/prototypes3.h index 7ba1d9f051c..657e5023953 100644 --- a/libpromises/prototypes3.h +++ b/libpromises/prototypes3.h @@ -85,7 +85,7 @@ ENTERPRISE_VOID_FUNC_0ARG_DECLARE(void, ReloadHAConfig); ENTERPRISE_VOID_FUNC_2ARG_DECLARE(void, Nova_ClassHistoryAddContextName, const StringSet *, list, const char *, context_name); ENTERPRISE_VOID_FUNC_2ARG_DECLARE(void, Nova_ClassHistoryEnable, StringSet **, list, bool, enable); -ENTERPRISE_FUNC_1ARG_DECLARE(int, ReactorEnterpriseMain, bool, no_fork); +ENTERPRISE_FUNC_0ARG_DECLARE(int, ReactorEnterpriseMain); /* manual.c */