You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-07-07 00:35:37 +02:00
Move async forking and more error handling to C.
The Perl process was exiting directly when called but that interfered with proper locking for the forked async process. Now Perl returns results to the C process which handles all errors, including signals.
This commit is contained in:
@ -20,7 +20,7 @@ Debug Asserts
|
||||
Begin the command
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
cmdBegin()
|
||||
cmdBegin(bool logOption)
|
||||
{
|
||||
ASSERT_DEBUG_COMMAND_SET();
|
||||
|
||||
@ -30,77 +30,82 @@ cmdBegin()
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
// Basic info on command start
|
||||
String *info = strNewFmt("%s command begin %s:", cfgCommandName(cfgCommand()), PGBACKREST_VERSION);
|
||||
String *info = strNewFmt("%s command begin", cfgCommandName(cfgCommand()));
|
||||
|
||||
// Loop though options and add the ones that are interesting
|
||||
for (ConfigOption optionId = 0; optionId < CFG_OPTION_TOTAL; optionId++)
|
||||
if (logOption)
|
||||
{
|
||||
// Skip the option if it is not valid
|
||||
if (!cfgOptionValid(optionId))
|
||||
continue;
|
||||
strCatFmt(info, " %s:", PGBACKREST_VERSION);
|
||||
|
||||
// If option was negated
|
||||
if (cfgOptionNegate(optionId))
|
||||
strCatFmt(info, " --no-%s", cfgOptionName(optionId));
|
||||
// If option was reset
|
||||
else if (cfgOptionReset(optionId))
|
||||
strCatFmt(info, " --reset-%s", cfgOptionName(optionId));
|
||||
// Else set and not default
|
||||
else if (cfgOptionSource(optionId) != cfgSourceDefault && cfgOptionTest(optionId))
|
||||
// Loop though options and add the ones that are interesting
|
||||
for (ConfigOption optionId = 0; optionId < CFG_OPTION_TOTAL; optionId++)
|
||||
{
|
||||
ConfigDefineOption optionDefId = cfgOptionDefIdFromId(optionId);
|
||||
// Skip the option if it is not valid
|
||||
if (!cfgOptionValid(optionId))
|
||||
continue;
|
||||
|
||||
// Don't show redacted options
|
||||
if (cfgDefOptionSecure(optionDefId))
|
||||
strCatFmt(info, " --%s=<redacted>", cfgOptionName(optionId));
|
||||
// Output boolean option
|
||||
else if (cfgDefOptionType(optionDefId) == cfgDefOptTypeBoolean)
|
||||
strCatFmt(info, " --%s", cfgOptionName(optionId));
|
||||
// Output other options
|
||||
else
|
||||
// If option was negated
|
||||
if (cfgOptionNegate(optionId))
|
||||
strCatFmt(info, " --no-%s", cfgOptionName(optionId));
|
||||
// If option was reset
|
||||
else if (cfgOptionReset(optionId))
|
||||
strCatFmt(info, " --reset-%s", cfgOptionName(optionId));
|
||||
// Else set and not default
|
||||
else if (cfgOptionSource(optionId) != cfgSourceDefault && cfgOptionTest(optionId))
|
||||
{
|
||||
StringList *valueList = NULL;
|
||||
ConfigDefineOption optionDefId = cfgOptionDefIdFromId(optionId);
|
||||
|
||||
// Generate the values of hash options
|
||||
if (cfgDefOptionType(optionDefId) == cfgDefOptTypeHash)
|
||||
{
|
||||
valueList = strLstNew();
|
||||
|
||||
const KeyValue *optionKv = cfgOptionKv(optionId);
|
||||
const VariantList *keyList = kvKeyList(optionKv);
|
||||
|
||||
for (unsigned int keyIdx = 0; keyIdx < varLstSize(keyList); keyIdx++)
|
||||
{
|
||||
strLstAdd(
|
||||
valueList,
|
||||
strNewFmt(
|
||||
"%s=%s", strPtr(varStr(varLstGet(keyList, keyIdx))),
|
||||
strPtr(varStrForce(kvGet(optionKv, varLstGet(keyList, keyIdx))))));
|
||||
}
|
||||
}
|
||||
// Generate values for list options
|
||||
else if (cfgDefOptionType(optionDefId) == cfgDefOptTypeList)
|
||||
{
|
||||
valueList = strLstNewVarLst(cfgOptionLst(optionId));
|
||||
}
|
||||
// Else only one value
|
||||
// Don't show redacted options
|
||||
if (cfgDefOptionSecure(optionDefId))
|
||||
strCatFmt(info, " --%s=<redacted>", cfgOptionName(optionId));
|
||||
// Output boolean option
|
||||
else if (cfgDefOptionType(optionDefId) == cfgDefOptTypeBoolean)
|
||||
strCatFmt(info, " --%s", cfgOptionName(optionId));
|
||||
// Output other options
|
||||
else
|
||||
{
|
||||
valueList = strLstNew();
|
||||
strLstAdd(valueList, varStrForce(cfgOption(optionId)));
|
||||
}
|
||||
StringList *valueList = NULL;
|
||||
|
||||
// Output options and values
|
||||
for (unsigned int valueListIdx = 0; valueListIdx < strLstSize(valueList); valueListIdx++)
|
||||
{
|
||||
const String *value = strLstGet(valueList, valueListIdx);
|
||||
// Generate the values of hash options
|
||||
if (cfgDefOptionType(optionDefId) == cfgDefOptTypeHash)
|
||||
{
|
||||
valueList = strLstNew();
|
||||
|
||||
strCatFmt(info, " --%s", cfgOptionName(optionId));
|
||||
const KeyValue *optionKv = cfgOptionKv(optionId);
|
||||
const VariantList *keyList = kvKeyList(optionKv);
|
||||
|
||||
if (strchr(strPtr(value), ' ') != NULL)
|
||||
value = strNewFmt("\"%s\"", strPtr(value));
|
||||
for (unsigned int keyIdx = 0; keyIdx < varLstSize(keyList); keyIdx++)
|
||||
{
|
||||
strLstAdd(
|
||||
valueList,
|
||||
strNewFmt(
|
||||
"%s=%s", strPtr(varStr(varLstGet(keyList, keyIdx))),
|
||||
strPtr(varStrForce(kvGet(optionKv, varLstGet(keyList, keyIdx))))));
|
||||
}
|
||||
}
|
||||
// Generate values for list options
|
||||
else if (cfgDefOptionType(optionDefId) == cfgDefOptTypeList)
|
||||
{
|
||||
valueList = strLstNewVarLst(cfgOptionLst(optionId));
|
||||
}
|
||||
// Else only one value
|
||||
else
|
||||
{
|
||||
valueList = strLstNew();
|
||||
strLstAdd(valueList, varStrForce(cfgOption(optionId)));
|
||||
}
|
||||
|
||||
strCatFmt(info, "=%s", strPtr(value));
|
||||
// Output options and values
|
||||
for (unsigned int valueListIdx = 0; valueListIdx < strLstSize(valueList); valueListIdx++)
|
||||
{
|
||||
const String *value = strLstGet(valueList, valueListIdx);
|
||||
|
||||
strCatFmt(info, " --%s", cfgOptionName(optionId));
|
||||
|
||||
if (strchr(strPtr(value), ' ') != NULL)
|
||||
value = strNewFmt("\"%s\"", strPtr(value));
|
||||
|
||||
strCatFmt(info, "=%s", strPtr(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -116,9 +121,10 @@ cmdBegin()
|
||||
End the command
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
cmdEnd(int code)
|
||||
cmdEnd(int code, const String *errorMessage)
|
||||
{
|
||||
ASSERT_DEBUG_COMMAND_SET();
|
||||
ASSERT_DEBUG(code == 0 || errorMessage != NULL);
|
||||
|
||||
// Skip this log message if it won't be output. It's not too expensive but since we skipped cmdBegin(), may as well.
|
||||
if (logWill(cfgLogLevelDefault()))
|
||||
@ -131,7 +137,7 @@ cmdEnd(int code)
|
||||
if (code == 0)
|
||||
strCat(info, "completed successfully");
|
||||
else
|
||||
strCatFmt(info, "aborted with exception [%03d]", code);
|
||||
strCat(info, strPtr(errorMessage));
|
||||
|
||||
LOG_ANY(cfgLogLevelDefault(), 0, strPtr(info));
|
||||
}
|
||||
|
Reference in New Issue
Block a user