diff --git a/doc/xml/release.xml b/doc/xml/release.xml index b57669336..59419a707 100644 --- a/doc/xml/release.xml +++ b/doc/xml/release.xml @@ -91,6 +91,10 @@

Add locking capability to the remote command.

+ +

Add forkSafe() to handle fork errors.

+
+

Add httpHeaderDup().

diff --git a/src/command/archive/get/get.c b/src/command/archive/get/get.c index 753f1ac3f..2f3f40a50 100644 --- a/src/command/archive/get/get.c +++ b/src/command/archive/get/get.c @@ -227,12 +227,11 @@ cmdArchiveGet(void) for (unsigned int queueIdx = 0; queueIdx < strLstSize(queue); queueIdx++) strLstAdd(commandExec, strLstGet(queue, queueIdx)); - // Release the lock and mark the async process as forked + // Release the lock so the child process can acquire it lockRelease(true); - forked = true; // Fork off the async process - if (fork() == 0) + if (forkSafe() == 0) { // Detach from parent process forkDetach(); @@ -242,6 +241,10 @@ cmdArchiveGet(void) execvp(strPtr(cfgExe()), (char ** const)strLstPtr(commandExec)) == -1, ExecuteError, "unable to execute '%s'", cfgCommandName(cfgCmdArchiveGetAsync)); } + + // Mark the async process as forked so it doesn't get forked again. A single run of the async process should be + // enough to do the job, running it again won't help anything. + forked = true; } // Exit loop if WAL was found diff --git a/src/command/archive/push/push.c b/src/command/archive/push/push.c index e07ae962d..63f34decc 100644 --- a/src/command/archive/push/push.c +++ b/src/command/archive/push/push.c @@ -301,12 +301,11 @@ cmdArchivePush(void) strLstInsert(commandExec, 0, cfgExe()); strLstAdd(commandExec, strPath(walFile)); - // Release the lock and mark the async process as forked + // Release the lock so the child process can acquire it lockRelease(true); - forked = true; // Fork off the async process - if (fork() == 0) + if (forkSafe() == 0) { // Detach from parent process forkDetach(); @@ -316,6 +315,10 @@ cmdArchivePush(void) execvp(strPtr(cfgExe()), (char ** const)strLstPtr(commandExec)) == -1, ExecuteError, "unable to execute '%s'", cfgCommandName(cfgCmdArchiveGetAsync)); } + + // Mark the async process as forked so it doesn't get forked again. A single run of the async process should be + // enough to do the job, running it again won't help anything. + forked = true; } // Now that the async process has been launched, confess any errors that are found diff --git a/src/common/fork.c b/src/common/fork.c index eed95bd91..1769c6ac6 100644 --- a/src/common/fork.c +++ b/src/common/fork.c @@ -8,7 +8,22 @@ Fork Handler #include "common/log.h" /*********************************************************************************************************************************** -Fork a new process and detach it so it can continue running after the parent process has exited. This is not a typical daemon +Fork a new process and throw an error if it fails +***********************************************************************************************************************************/ +int +forkSafe(void) +{ + FUNCTION_LOG_VOID(logLevelTrace); + + int result = fork(); + + THROW_ON_SYS_ERROR(result == -1, PathMissingError, "unable to fork"); + + FUNCTION_LOG_RETURN(INT, result); +} + +/*********************************************************************************************************************************** +Detach a forked process and detach it so it can continue running after the parent process has exited. This is not a typical daemon startup because the parent process may continue to run and perform work for some time. ***********************************************************************************************************************************/ void diff --git a/src/common/fork.h b/src/common/fork.h index 8be1e754c..ec7086af2 100644 --- a/src/common/fork.h +++ b/src/common/fork.h @@ -7,6 +7,7 @@ Fork Handler /*********************************************************************************************************************************** Functions ***********************************************************************************************************************************/ +int forkSafe(void); void forkDetach(void); #endif diff --git a/test/src/common/harnessFork.h b/test/src/common/harnessFork.h index 3f1ec5ad8..c131da662 100644 --- a/test/src/common/harnessFork.h +++ b/test/src/common/harnessFork.h @@ -38,6 +38,8 @@ There should not be any code outside the HARNESS_FORK_CHILD_BEGIN/END() and HARN #include #include +#include + /*********************************************************************************************************************************** Define the max number of child processes allowed ***********************************************************************************************************************************/ @@ -133,7 +135,7 @@ Create a child process "unable to create write pipe for child process %u", HARNESS_FORK_PROCESS_TOTAL()); \ } \ \ - HARNESS_FORK_PROCESS_ID(HARNESS_FORK_PROCESS_TOTAL()) = fork(); \ + HARNESS_FORK_PROCESS_ID(HARNESS_FORK_PROCESS_TOTAL()) = forkSafe(); \ \ if (HARNESS_FORK_PROCESS_ID(HARNESS_FORK_PROCESS_TOTAL()) == 0) \ { \ diff --git a/test/src/module/common/forkTest.c b/test/src/module/common/forkTest.c index ab24f1bc9..5b61b4343 100644 --- a/test/src/module/common/forkTest.c +++ b/test/src/module/common/forkTest.c @@ -12,7 +12,7 @@ testRun(void) FUNCTION_HARNESS_VOID(); // ***************************************************************************************************************************** - if (testBegin("forkAndDetach()")) + if (testBegin("forkSafe() and forkAndDetach()")) { int sessionId = getsid(0);