mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-01-18 04:58:51 +02:00
Use getcwd() to construct path when WAL path is relative.
Using pg1-path, as we were doing previously, could lead to WAL being copied to/from unexpected places. PostgreSQL sets the current working directory to PGDATA so we can use that to resolve relative paths.
This commit is contained in:
parent
e06db21e35
commit
7168e07440
@ -6,6 +6,7 @@ Archive Common
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "command/archive/common.h"
|
||||
#include "common/debug.h"
|
||||
@ -228,35 +229,25 @@ walIsPartial(const String *walSegment)
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Generates the location of the wal directory using a relative wal path and the supplied pg path
|
||||
Generates the location of the wal directory using either an absolute path or cwd() and a relative path
|
||||
***********************************************************************************************************************************/
|
||||
String *
|
||||
walPath(const String *walFile, const String *pgPath, const String *command)
|
||||
walPath(const String *walFile)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STRING, walFile);
|
||||
FUNCTION_LOG_PARAM(STRING, pgPath);
|
||||
FUNCTION_LOG_PARAM(STRING, command);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(walFile != NULL);
|
||||
ASSERT(command != NULL);
|
||||
|
||||
String *result = NULL;
|
||||
|
||||
if (!strBeginsWithZ(walFile, "/"))
|
||||
{
|
||||
if (pgPath == NULL)
|
||||
{
|
||||
THROW_FMT(
|
||||
OptionRequiredError,
|
||||
"option '" CFGOPT_PG1_PATH "' must be specified when relative wal paths are used\n"
|
||||
"HINT: is %%f passed to %s instead of %%p?\n"
|
||||
"HINT: PostgreSQL may pass relative paths even with %%p depending on the environment.",
|
||||
strPtr(command));
|
||||
}
|
||||
char currentWorkDir[4096];
|
||||
|
||||
result = strNewFmt("%s/%s", strPtr(pgPath), strPtr(walFile));
|
||||
THROW_ON_SYS_ERROR(getcwd(currentWorkDir, sizeof(currentWorkDir)) == NULL, FormatError, "unable to get cwd");
|
||||
result = strNewFmt("%s/%s", currentWorkDir, strPtr(walFile));
|
||||
}
|
||||
else
|
||||
result = strDup(walFile);
|
||||
|
@ -64,7 +64,7 @@ void archiveAsyncStatusErrorWrite(ArchiveMode archiveMode, const String *walSegm
|
||||
|
||||
bool walIsPartial(const String *walSegment);
|
||||
bool walIsSegment(const String *walSegment);
|
||||
String *walPath(const String *walFile, const String *pgPath, const String *command);
|
||||
String *walPath(const String *walFile);
|
||||
String *walSegmentFind(const Storage *storage, const String *archiveId, const String *walSegment, TimeMSec timeout);
|
||||
String *walSegmentNext(const String *walSegment, size_t walSegmentSize, unsigned int pgVersion);
|
||||
StringList *walSegmentRange(const String *walSegmentBegin, size_t walSegmentSize, unsigned int pgVersion, unsigned int range);
|
||||
|
@ -132,8 +132,7 @@ cmdArchiveGet(void)
|
||||
String *walSegment = strBase(strLstGet(commandParam, 0));
|
||||
|
||||
// Destination is wherever we were told to move the WAL segment
|
||||
const String *walDestination =
|
||||
walPath(strLstGet(commandParam, 1), cfgOptionStr(cfgOptPgPath), STR(cfgCommandName(cfgCommand())));
|
||||
const String *walDestination = walPath(strLstGet(commandParam, 1));
|
||||
|
||||
// Async get can only be performed on WAL segments, history or other files must use synchronous mode
|
||||
if (cfgOptionBool(cfgOptArchiveAsync) && walIsSegment(walSegment))
|
||||
|
@ -268,7 +268,7 @@ cmdArchivePush(void)
|
||||
lockStopTest();
|
||||
|
||||
// Get the segment name
|
||||
String *walFile = walPath(strLstGet(commandParam, 0), cfgOptionStr(cfgOptPgPath), STR(cfgCommandName(cfgCommand())));
|
||||
String *walFile = walPath(strLstGet(commandParam, 0));
|
||||
String *archiveFile = strBase(walFile);
|
||||
|
||||
if (cfgOptionBool(cfgOptArchiveAsync))
|
||||
|
@ -172,15 +172,10 @@ testRun(void)
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("walPath()"))
|
||||
{
|
||||
TEST_RESULT_STR(
|
||||
strPtr(walPath(strNew("/absolute/path"), strNew("/pg"), strNew("test"))), "/absolute/path", "absolute path");
|
||||
TEST_RESULT_STR(
|
||||
strPtr(walPath(strNew("relative/path"), strNew("/pg"), strNew("test"))), "/pg/relative/path", "relative path");
|
||||
TEST_ERROR(
|
||||
walPath(strNew("relative/path"), NULL, strNew("test")), OptionRequiredError,
|
||||
"option 'pg1-path' must be specified when relative wal paths are used\n"
|
||||
"HINT: is %f passed to test instead of %p?\n"
|
||||
"HINT: PostgreSQL may pass relative paths even with %p depending on the environment.");
|
||||
THROW_ON_SYS_ERROR(chdir("/tmp") != 0, PathMissingError, "unable to chdir()");
|
||||
|
||||
TEST_RESULT_STR(strPtr(walPath(strNew("/absolute/path"))), "/absolute/path", "absolute path");
|
||||
TEST_RESULT_STR(strPtr(walPath(strNew("relative/path"))), "/tmp/relative/path", "relative path");
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
|
@ -623,6 +623,8 @@ testRun(void)
|
||||
|
||||
// Write out a WAL segment for success
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
THROW_ON_SYS_ERROR(chdir(strPtr(cfgOptionStr(cfgOptPgPath))) != 0, PathMissingError, "unable to chdir()");
|
||||
|
||||
storagePutNP(
|
||||
storageNewWriteNP(storageSpoolWrite(), strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s", strPtr(walSegment))),
|
||||
BUFSTRDEF("SHOULD-BE-A-REAL-WAL-FILE"));
|
||||
|
@ -181,23 +181,12 @@ testRun(void)
|
||||
|
||||
TEST_ERROR(cmdArchivePush(), ParamRequiredError, "WAL segment to push required");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
StringList *argListTemp = strLstDup(argList);
|
||||
strLstAddZ(argListTemp, "pg_wal/000000010000000100000001");
|
||||
harnessCfgLoad(cfgCmdArchivePush, argListTemp);
|
||||
|
||||
TEST_ERROR(
|
||||
cmdArchivePush(), OptionRequiredError,
|
||||
"option 'pg1-path' must be specified when relative wal paths are used"
|
||||
"\nHINT: is %f passed to archive-push instead of %p?"
|
||||
"\nHINT: PostgreSQL may pass relative paths even with %p depending on the environment.");
|
||||
|
||||
// Create pg_control and archive.info
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
strLstAdd(argList, strNewFmt("--pg1-path=%s/pg", testPath()));
|
||||
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
|
||||
|
||||
argListTemp = strLstDup(argList);
|
||||
StringList *argListTemp = strLstDup(argList);
|
||||
strLstAddZ(argListTemp, "pg_wal/000000010000000100000001");
|
||||
harnessCfgLoad(cfgCmdArchivePush, argListTemp);
|
||||
|
||||
@ -223,6 +212,8 @@ testRun(void)
|
||||
|
||||
storagePutNP(storageNewWriteNP(storagePgWrite(), strNew("pg_wal/000000010000000100000001")), walBuffer1);
|
||||
|
||||
THROW_ON_SYS_ERROR(chdir(strPtr(cfgOptionStr(cfgOptPgPath))) != 0, PathMissingError, "unable to chdir()");
|
||||
|
||||
TEST_ERROR(
|
||||
cmdArchivePush(), ArchiveMismatchError,
|
||||
strPtr(
|
||||
@ -424,6 +415,8 @@ testRun(void)
|
||||
strLstAddZ(argList, "pg_wal/bogus");
|
||||
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
THROW_ON_SYS_ERROR(chdir(testPath()) != 0, PathMissingError, "unable to chdir()");
|
||||
|
||||
TEST_ERROR(
|
||||
cmdArchivePush(), ArchiveTimeoutError,
|
||||
"unable to push WAL file 'bogus' to the archive asynchronously after 1 second(s)");
|
||||
@ -475,6 +468,8 @@ testRun(void)
|
||||
strLstAddZ(argListTemp, "--archive-timeout=1");
|
||||
harnessCfgLoad(cfgCmdArchivePush, argListTemp);
|
||||
|
||||
THROW_ON_SYS_ERROR(chdir(strPtr(cfgOptionStr(cfgOptPgPath))) != 0, PathMissingError, "unable to chdir()");
|
||||
|
||||
HARNESS_FORK_BEGIN()
|
||||
{
|
||||
HARNESS_FORK_CHILD_BEGIN(0, true)
|
||||
|
Loading…
x
Reference in New Issue
Block a user