mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-03-03 14:52:21 +02:00
Add temporary mem contexts and fix a leak in the command/restore module.
restoreRecoveryConf() and restoreRecoveryWriteConf() do enough work to deserve their own memory contexts. restoreFilePgPath() was leaking a String every time it was called, which could be a lot. Also fix a spacing issue.
This commit is contained in:
parent
4e7414d48f
commit
55a828f999
@ -715,7 +715,7 @@ restoreManifestOwnerReplace(const String *const owner, const String *const owner
|
||||
{ \
|
||||
const String *owner = strLstGet(type##List, ownerIdx); \
|
||||
\
|
||||
if (type##Name() == NULL || !strEq(type##Name(), owner)) \
|
||||
if (type##Name() == NULL || !strEq(type##Name(), owner)) \
|
||||
LOG_WARN_FMT("unknown " #type " '%s' in backup manifest mapped to current " #type, strZ(owner)); \
|
||||
} \
|
||||
} \
|
||||
@ -1664,35 +1664,29 @@ restoreRecoveryOption(unsigned int pgVersion)
|
||||
|
||||
// Helper to convert recovery options to text format
|
||||
static String *
|
||||
restoreRecoveryConf(unsigned int pgVersion, const String *restoreLabel)
|
||||
restoreRecoveryConf(const unsigned int pgVersion, const String *const restoreLabel)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(UINT, pgVersion);
|
||||
FUNCTION_LOG_PARAM(STRING, restoreLabel);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
String *result = NULL;
|
||||
String *const result = strNew();
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
result = strCatFmt(strNew(), "# Recovery settings generated by " PROJECT_NAME " restore on %s\n", strZ(restoreLabel));
|
||||
strCatFmt(result, "# Recovery settings generated by " PROJECT_NAME " restore on %s\n", strZ(restoreLabel));
|
||||
|
||||
// Output all recovery options
|
||||
KeyValue *optionKv = restoreRecoveryOption(pgVersion);
|
||||
const VariantList *optionKeyList = kvKeyList(optionKv);
|
||||
const KeyValue *const optionKv = restoreRecoveryOption(pgVersion);
|
||||
const VariantList *const optionKeyList = kvKeyList(optionKv);
|
||||
|
||||
for (unsigned int optionKeyIdx = 0; optionKeyIdx < varLstSize(optionKeyList); optionKeyIdx++)
|
||||
{
|
||||
const Variant *optionKey = varLstGet(optionKeyList, optionKeyIdx);
|
||||
const Variant *const optionKey = varLstGet(optionKeyList, optionKeyIdx);
|
||||
|
||||
strCatFmt(result, "%s = '%s'\n", strZ(varStr(optionKey)), strZ(varStr(kvGet(optionKv, optionKey))));
|
||||
}
|
||||
|
||||
// Move to prior context
|
||||
MEM_CONTEXT_PRIOR_BEGIN()
|
||||
{
|
||||
result = strDup(result);
|
||||
}
|
||||
MEM_CONTEXT_PRIOR_END();
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
@ -1701,7 +1695,7 @@ restoreRecoveryConf(unsigned int pgVersion, const String *restoreLabel)
|
||||
|
||||
// Helper to write recovery options into recovery.conf
|
||||
static void
|
||||
restoreRecoveryWriteConf(const Manifest *manifest, unsigned int pgVersion, const String *restoreLabel)
|
||||
restoreRecoveryWriteConf(const Manifest *const manifest, const unsigned int pgVersion, const String *const restoreLabel)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(MANIFEST, manifest);
|
||||
@ -1712,18 +1706,22 @@ restoreRecoveryWriteConf(const Manifest *manifest, unsigned int pgVersion, const
|
||||
// Only write recovery.conf if recovery type != none
|
||||
if (cfgOptionStrId(cfgOptType) != CFGOPTVAL_TYPE_NONE)
|
||||
{
|
||||
LOG_INFO_FMT("write %s", strZ(storagePathP(storagePg(), PG_FILE_RECOVERYCONF_STR)));
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
LOG_INFO_FMT("write %s", strZ(storagePathP(storagePg(), PG_FILE_RECOVERYCONF_STR)));
|
||||
|
||||
// Use the data directory to set permissions and ownership for recovery file
|
||||
const ManifestPath *dataPath = manifestPathFind(manifest, MANIFEST_TARGET_PGDATA_STR);
|
||||
mode_t recoveryFileMode = dataPath->mode & (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
// Use the data directory to set permissions and ownership for recovery file
|
||||
const ManifestPath *const dataPath = manifestPathFind(manifest, MANIFEST_TARGET_PGDATA_STR);
|
||||
const mode_t recoveryFileMode = dataPath->mode & (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
|
||||
// Write recovery.conf
|
||||
storagePutP(
|
||||
storageNewWriteP(
|
||||
storagePgWrite(), PG_FILE_RECOVERYCONF_STR, .noCreatePath = true, .modeFile = recoveryFileMode, .noAtomic = true,
|
||||
.noSyncPath = true, .user = dataPath->user, .group = dataPath->group),
|
||||
BUFSTR(restoreRecoveryConf(pgVersion, restoreLabel)));
|
||||
// Write recovery.conf
|
||||
storagePutP(
|
||||
storageNewWriteP(
|
||||
storagePgWrite(), PG_FILE_RECOVERYCONF_STR, .noCreatePath = true, .modeFile = recoveryFileMode,
|
||||
.noAtomic = true, .noSyncPath = true, .user = dataPath->user, .group = dataPath->group),
|
||||
BUFSTR(restoreRecoveryConf(pgVersion, restoreLabel)));
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
@ -2087,7 +2085,7 @@ restoreFileZeroed(const String *manifestName, RegExp *zeroExp)
|
||||
|
||||
// Helper function to construct the absolute pg path for any file
|
||||
static String *
|
||||
restoreFilePgPath(const Manifest *manifest, const String *manifestName)
|
||||
restoreFilePgPath(const Manifest *const manifest, const String *const manifestName)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(MANIFEST, manifest);
|
||||
@ -2097,10 +2095,12 @@ restoreFilePgPath(const Manifest *manifest, const String *manifestName)
|
||||
ASSERT(manifest != NULL);
|
||||
ASSERT(manifestName != NULL);
|
||||
|
||||
String *result = strNewFmt("%s/%s", strZ(manifestTargetBase(manifest)->path), strZ(manifestPathPg(manifestName)));
|
||||
String *const pathPg = manifestPathPg(manifestName);
|
||||
String *const result = strNewFmt(
|
||||
"%s/%s%s", strZ(manifestTargetBase(manifest)->path), strZ(pathPg),
|
||||
strEqZ(manifestName, MANIFEST_TARGET_PGDATA "/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL) ? "." STORAGE_FILE_TEMP_EXT : "");
|
||||
|
||||
if (strEq(manifestName, STRDEF(MANIFEST_TARGET_PGDATA "/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL)))
|
||||
result = strNewFmt("%s." STORAGE_FILE_TEMP_EXT, strZ(result));
|
||||
strFree(pathPg);
|
||||
|
||||
FUNCTION_TEST_RETURN(STRING, result);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user