Skip to content

ENT-14434: Move reactor-pluigin logic into cf-reactor daemon loop - #6335

Open
victormlg wants to merge 1 commit into
cfengine:masterfrom
victormlg:cf-reactor-move-around
Open

ENT-14434: Move reactor-pluigin logic into cf-reactor daemon loop#6335
victormlg wants to merge 1 commit into
cfengine:masterfrom
victormlg:cf-reactor-move-around

Conversation

@victormlg

@victormlg victormlg commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Context

So originally, we wanted to have two daemons: one for cf-reactor and one for the agent driven cfengine code. Then it has been decided to merge these two binaries into a single one. In this PR, we move the cf-reactor daemon to core, split the reactor-plugin in different functions, and integrate them inside the daemon loop of cf-reactor

Merge together: https://github.com/cfengine/enterprise/pull/996 https://github.com/cfengine/nova/pull/2696

@victormlg
victormlg marked this pull request as ready for review August 25, 2026 14:45
@victormlg
victormlg force-pushed the cf-reactor-move-around branch from 2e7ed0e to dfd91c6 Compare August 25, 2026 14:46
@victormlg
victormlg requested a review from larsewi August 26, 2026 09:54

@larsewi larsewi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add some more context. E.g., explain why chose to make cf-reactor plugin its own process. Also I expected cf-reactor in nova to already fork out and make it a daemon, but I have not seen this code removed.

@victormlg
victormlg requested a review from larsewi August 28, 2026 07:47

@larsewi larsewi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There one major issue here. If the nova fork dies, then core will continue running and no one will restart the nova reactor again. With this architecture, core must be responsible for restarting the nova fork if it dies.

Comment thread cf-reactor/cf-reactor.c
Comment thread cf-reactor/cf-reactor.c
Comment thread cf-reactor/cf-reactor.c Outdated
Comment thread cf-reactor/cf-reactor.c Outdated
@victormlg
victormlg force-pushed the cf-reactor-move-around branch 3 times, most recently from 553a07c to aa6d538 Compare August 28, 2026 12:44
@victormlg
victormlg requested a review from larsewi August 28, 2026 12:45
@victormlg
victormlg force-pushed the cf-reactor-move-around branch 2 times, most recently from 7228cb8 to be91f14 Compare August 28, 2026 12:50

@larsewi larsewi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please write a test where you kill the nova cf-reactor and see that it comes back. Maybe also test reaching that limit that you set.

Comment thread cf-reactor/cf-reactor.c Outdated
Comment thread cf-reactor/cf-reactor.c Outdated
@victormlg
victormlg force-pushed the cf-reactor-move-around branch from be91f14 to a7fd033 Compare September 1, 2026 09:57
@victormlg victormlg changed the title ENT-14434: Made reactor-plugin into its own forked process ENT-14434: Move reactor-pluigin logic into cf-reactor daemon loop Sep 1, 2026
@victormlg

Copy link
Copy Markdown
Contributor Author

I updated the context of this PR to match what it currently contains

Comment thread cf-reactor/cf-reactor.c Fixed
Comment thread cf-reactor/cf-reactor.c Fixed
Comment thread cf-reactor/cf-reactor.c Fixed
@victormlg
victormlg force-pushed the cf-reactor-move-around branch from a7fd033 to 5d32781 Compare September 1, 2026 10:07
@victormlg
victormlg requested a review from larsewi September 1, 2026 10:41
The code for the reactor-plugin was split up into different functions to be integrated inside the new cf-reactor daemon in core. The implementation was tweaked to use select(2) instead of poll(2), to support cf-reactor on different platforms. However, the reactor-plugin remains linux only.

Ticket: ENT-14434
Signed-off-by: Victor Moene <victor.moene@northern.tech>
Comment thread cf-reactor/cf-reactor.c

int all_fds[N_ALL_FDS];
// the first num_nova_fds fds are populated with nova fds
size_t num_nova_fds = ReactorNovaInitialize(all_fds, N_ALL_FDS);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably need to differentiate between ReactorNovaInitialize failed and ReactorNovaInitialize has no FDs to contribute.

Comment thread cf-reactor/cf-reactor.c
Comment on lines +276 to +286
signal(SIGINT, HandleReactorSignals);
signal(SIGTERM, HandleReactorSignals);
signal(SIGBUS, HandleReactorSignals);
signal(SIGHUP, HandleReactorSignals);
signal(SIGUSR1, HandleReactorSignals);
signal(SIGUSR2, HandleReactorSignals);
/* Writing to a pipe whose spawned process already exited (e.g. cfbs
* rejecting its arguments before reading its stdin) must fail with EPIPE
* rather than terminate the whole daemon. Set after ReactorNovaInitialize(),
* so that the spawner and the processes it execs keep the default handling. */
signal(SIGPIPE, SIG_IGN);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should probably happen before ConnectAndListen because that's the one place where the can sit for an unbound time. And right now it sits there without a way to shut it down cleanly.

Comment thread cf-reactor/cf-reactor.c
Comment on lines +189 to +196
static void HandleReactorSignals(int signum)
{
HandleSignalsForDaemon(signum);
if (IsPendingTermination())
{
ReactorNovaTerminate();
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
static void HandleReactorSignals(int signum)
{
HandleSignalsForDaemon(signum);
if (IsPendingTermination())
{
ReactorNovaTerminate();
}
}
static void HandleReactorSignals(int signum)
{
HandleSignalsForDaemon(signum);
if (IsPendingTermination())
{
TERMINATE = 1;
}
signal(signum, HandleReactorSignals); /* re-arm the wrapper */
}

You will need to re-arm this wrapper, otherwise the internal handler will get call directly the next time the signal is triggered

Comment thread libpromises/prototypes3.h

ENTERPRISE_FUNC_1ARG_DECLARE(int, ReactorEnterpriseMain, bool, no_fork);
ENTERPRISE_VOID_FUNC_0ARG_DECLARE(void, ReactorNovaTerminate);
ENTERPRISE_FUNC_2ARG_DECLARE(size_t, ReactorNovaInitialize, ARG_UNUSED int*, fds, ARG_UNUSED size_t, max_size);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put ARG_UNUSED in the declarations. It belongs on stub definitions only.

@craigcomstock craigcomstock left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

Comment thread cf-reactor/cf-reactor.c
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");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this message be rather "was already running, terminated" since you are calling kill() In the if expression? Maybe it would be good to mention what PID it was that you killed for debugging issues with unexpected running cf-reactor processes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants