mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-03-05 15:05:48 +02:00
Add forkSafe() to handle fork errors.
fork() rarely fails but we should definitely detect when it does so.
This commit is contained in:
parent
1b48684713
commit
4c63279a19
@ -91,6 +91,10 @@
|
||||
<p>Add locking capability to the remote command.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Add <code>forkSafe()</code> to handle fork errors.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Add <code>httpHeaderDup()</code>.</p>
|
||||
</release-item>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -7,6 +7,7 @@ Fork Handler
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
int forkSafe(void);
|
||||
void forkDetach(void);
|
||||
|
||||
#endif
|
||||
|
@ -38,6 +38,8 @@ There should not be any code outside the HARNESS_FORK_CHILD_BEGIN/END() and HARN
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <common/fork.h>
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
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) \
|
||||
{ \
|
||||
|
@ -12,7 +12,7 @@ testRun(void)
|
||||
FUNCTION_HARNESS_VOID();
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("forkAndDetach()"))
|
||||
if (testBegin("forkSafe() and forkAndDetach()"))
|
||||
{
|
||||
int sessionId = getsid(0);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user