-
Notifications
You must be signed in to change notification settings - Fork 201
ENT-14434: Made reactor-plugin into its own forked process #6335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -33,13 +33,23 @@ | |||||
| #include <man.h> | ||||||
| #include <cleanup.h> | ||||||
| #include <prototypes3.h> | ||||||
| #include <signals.h> /* HandleSignalsForDaemon, IsPendingTermination */ | ||||||
| #include <unistd.h> /* sleep */ | ||||||
| #include <signal.h> /* signal, kill */ | ||||||
| #include <errno.h> /* errno, EINTR */ | ||||||
| #include <sys/wait.h> /* waitpid */ | ||||||
| #include <exec_tools.h> | ||||||
|
|
||||||
| /*****************************************************************************/ | ||||||
| /* Globals */ | ||||||
| /*****************************************************************************/ | ||||||
|
|
||||||
| int NO_FORK = false; | ||||||
|
|
||||||
|
|
||||||
| #define REACTOR_RESTART_LIMIT 10 | ||||||
| #define REACTOR_MIN_UPTIME_SECS 60 | ||||||
|
|
||||||
| /*******************************************************************/ | ||||||
| /* Command line options */ | ||||||
| /*******************************************************************/ | ||||||
|
|
@@ -177,6 +187,74 @@ static GenericAgentConfig *CheckOpts(int argc, char **argv) | |||||
| return config; | ||||||
| } | ||||||
|
|
||||||
| #ifndef __MINGW32__ | ||||||
|
|
||||||
| static bool ReactorEnterpriseHasExited(pid_t pid) | ||||||
| { | ||||||
| int status; | ||||||
| pid_t ret = waitpid(pid, &status, WNOHANG); | ||||||
| if (ret == 0) | ||||||
| { | ||||||
| return false; | ||||||
| } | ||||||
|
|
||||||
| if (ret == -1) | ||||||
| { | ||||||
| Log(LOG_LEVEL_ERR, | ||||||
| "Failed to check status of cf-reactor enterprise process %jd (waitpid: %s)", | ||||||
| (intmax_t) pid, GetErrorStr()); | ||||||
| return true; | ||||||
| } | ||||||
|
|
||||||
| if (WIFEXITED(status)) | ||||||
| { | ||||||
| Log(LOG_LEVEL_ERR, "cf-reactor enterprise process %jd exited unexpectedly with code %d", | ||||||
| (intmax_t) pid, WEXITSTATUS(status)); | ||||||
| } | ||||||
| else if (WIFSIGNALED(status)) | ||||||
| { | ||||||
| Log(LOG_LEVEL_ERR, "cf-reactor enterprise process %jd was killed by signal %d", | ||||||
| (intmax_t) pid, WTERMSIG(status)); | ||||||
| } | ||||||
| else | ||||||
| { | ||||||
| Log(LOG_LEVEL_ERR, "cf-reactor enterprise process %jd terminated abnormally", | ||||||
| (intmax_t) pid); | ||||||
| } | ||||||
|
|
||||||
| return true; | ||||||
| } | ||||||
|
|
||||||
| #endif /* !__MINGW32__ */ | ||||||
|
|
||||||
| static void TerminateReactorEnterprise(int pid) | ||||||
| { | ||||||
| #ifndef __MINGW32__ | ||||||
| if (kill((pid_t) pid, SIGINT) == -1) | ||||||
| { | ||||||
| Log(LOG_LEVEL_ERR, "Failed to signal cf-reactor enterprise process %jd (kill: %s)", | ||||||
| (intmax_t) pid, GetErrorStr()); | ||||||
| return; | ||||||
| } | ||||||
|
|
||||||
| int status; | ||||||
| pid_t ret; | ||||||
| while (((ret = waitpid(pid, &status, 0)) == -1) && (errno == EINTR)) | ||||||
| { | ||||||
| /* Interrupted by a signal, try again. */ | ||||||
| } | ||||||
|
|
||||||
| if (ret == -1) | ||||||
| { | ||||||
| Log(LOG_LEVEL_ERR, | ||||||
| "Failed to wait for cf-reactor enterprise process %jd to terminate (waitpid: %s)", | ||||||
| (intmax_t) pid, GetErrorStr()); | ||||||
| } | ||||||
| #else | ||||||
| (void) pid; | ||||||
| #endif /* !__MINGW32__ */ | ||||||
| } | ||||||
|
|
||||||
| /*****************************************************************************/ | ||||||
|
|
||||||
| int main(int argc, char *argv[]) | ||||||
|
|
@@ -185,10 +263,118 @@ 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(SIGUSR1, HandleSignalsForDaemon); | ||||||
| signal(SIGUSR2, HandleSignalsForDaemon); | ||||||
| signal(SIGPIPE, SIG_IGN); | ||||||
|
|
||||||
| int child = ReactorEnterpriseMain(); | ||||||
| if (child == -1) | ||||||
| { | ||||||
| return 1; | ||||||
| } | ||||||
|
|
||||||
| #ifndef __MINGW32__ | ||||||
| time_t child_started_at = time(NULL); | ||||||
| int n_restarts = 0; | ||||||
| #endif /* !__MINGW32__ */ | ||||||
|
|
||||||
| while (!IsPendingTermination()) | ||||||
| { | ||||||
| /* Do something */ | ||||||
| sleep(1); | ||||||
|
|
||||||
| #ifndef __MINGW32__ | ||||||
| /* Here cf-reactor tries to restart the reactor plugin if it exited. It retries | ||||||
| * 10 times before giving up. The counter is set back to 0 after some time without failure */ | ||||||
|
Comment on lines
+322
to
+323
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe the core process should die itself. Otherwise, systemd will think everything is fine. Not sure. We are basically implementing |
||||||
| if ((child > 0) && ReactorEnterpriseHasExited((pid_t) child)) | ||||||
| { | ||||||
| if (IsPendingTermination()) | ||||||
| { | ||||||
| /* Already shutting down, no point in restarting it. */ | ||||||
| child = 0; | ||||||
| break; | ||||||
| } | ||||||
|
|
||||||
| if (time(NULL) - child_started_at > REACTOR_MIN_UPTIME_SECS) | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| { | ||||||
| /* It ran for a while before dying, don't hold that against it. */ | ||||||
| n_restarts = 0; | ||||||
| } | ||||||
|
|
||||||
| if (n_restarts >= REACTOR_RESTART_LIMIT) | ||||||
| { | ||||||
| Log(LOG_LEVEL_CRIT, | ||||||
| "cf-reactor enterprise process has died %d times in a row, " | ||||||
| "giving up on restarting it. cf-reactor will keep running " | ||||||
| "without the enterprise reactor extension until restarted", | ||||||
| n_restarts); | ||||||
| child = 0; | ||||||
| continue; | ||||||
| } | ||||||
|
|
||||||
| n_restarts++; | ||||||
| Log(LOG_LEVEL_ERR, | ||||||
| "Restarting cf-reactor enterprise process (attempt %d/%d)", | ||||||
| n_restarts, REACTOR_RESTART_LIMIT); | ||||||
|
|
||||||
| child = ReactorEnterpriseMain(); | ||||||
| child_started_at = time(NULL); | ||||||
| if (child == -1) | ||||||
| { | ||||||
| Log(LOG_LEVEL_ERR, "Failed to restart cf-reactor enterprise process, " | ||||||
| "will keep running without the enterprise reactor extension"); | ||||||
| child = 0; | ||||||
| continue; | ||||||
| } | ||||||
| } | ||||||
| #endif /* !__MINGW32__ */ | ||||||
| } | ||||||
|
|
||||||
| /* child == 0 means either that no child process was created (the | ||||||
| default value returned by enterprise stubs), or that we already gave | ||||||
| up on / reaped it above. */ | ||||||
| if (child > 0) | ||||||
| { | ||||||
| TerminateReactorEnterprise(child); | ||||||
|
victormlg marked this conversation as resolved.
|
||||||
| } | ||||||
|
|
||||||
| GenericAgentFinalize(ctx, config); | ||||||
| CallCleanupFunctions(); | ||||||
|
|
||||||
| return ret; | ||||||
| return 0; | ||||||
| } | ||||||
Uh oh!
There was an error while loading. Please reload this page.