You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-07-17 01:12:23 +02:00
Use zero-based indexes when referring to option indexes.
There were a number of places in the code where "hostId" was used, but hostId is just the option group index + 1 so this led to a lot of +1 and -1 to convert the id to an index and vice versa. Instead just use the zero based index wherever possible. This is pretty much everywhere except when the host-id option is read or set, or where a message is being formatted for the user. Also fix a bug in protocolRemoteParam() where remotes spawned from the main process could get process ids that were not 0. Only the locals should spawn remotes with process id > 0. This seems to have been harmless since the process id is only a label, but it could be confusing when debugging.
This commit is contained in:
@ -58,6 +58,14 @@
|
||||
<p>Add option groups.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<release-item-contributor-list>
|
||||
<release-item-reviewer id="cynthia.shang"/>
|
||||
</release-item-contributor-list>
|
||||
|
||||
<p>Use zero-based indexes when referring to option indexes.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<release-item-contributor-list>
|
||||
<release-item-reviewer id="stephen.frost"/>
|
||||
|
@ -339,7 +339,7 @@ cmdArchiveGetAsync(void)
|
||||
(TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * MSEC_PER_SEC) / 2, archiveGetAsyncCallback, &jobData);
|
||||
|
||||
for (unsigned int processIdx = 1; processIdx <= cfgOptionUInt(cfgOptProcessMax); processIdx++)
|
||||
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypeRepo, 1, processIdx));
|
||||
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypeRepo, 0, processIdx));
|
||||
|
||||
// Process jobs
|
||||
do
|
||||
|
@ -504,7 +504,7 @@ cmdArchivePushAsync(void)
|
||||
(TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * MSEC_PER_SEC) / 2, archivePushAsyncCallback, &jobData);
|
||||
|
||||
for (unsigned int processIdx = 1; processIdx <= cfgOptionUInt(cfgOptProcessMax); processIdx++)
|
||||
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypeRepo, 1, processIdx));
|
||||
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypeRepo, 0, processIdx));
|
||||
|
||||
// Process jobs
|
||||
do
|
||||
|
@ -175,12 +175,12 @@ Get the postgres database and storage objects
|
||||
|
||||
typedef struct BackupData
|
||||
{
|
||||
unsigned int pgIdPrimary; // Configuration id of the primary
|
||||
unsigned int pgIdxPrimary; // cfgOptGrpPg index of the primary
|
||||
Db *dbPrimary; // Database connection to the primary
|
||||
const Storage *storagePrimary; // Storage object for the primary
|
||||
const String *hostPrimary; // Host name of the primary
|
||||
|
||||
unsigned int pgIdStandby; // Configuration id of the standby
|
||||
unsigned int pgIdxStandby; // cfgOptGrpPg index of the standby
|
||||
Db *dbStandby; // Database connection to the standby
|
||||
const Storage *storageStandby; // Storage object for the standby
|
||||
const String *hostStandby; // Host name of the standby
|
||||
@ -200,7 +200,7 @@ backupInit(const InfoBackup *infoBackup)
|
||||
|
||||
// Initialize for offline backup
|
||||
BackupData *result = memNew(sizeof(BackupData));
|
||||
*result = (BackupData){.pgIdPrimary = 1};
|
||||
*result = (BackupData){0};
|
||||
|
||||
// Check that the PostgreSQL version supports backup from standby. The check is done using the stanza info because pg_control
|
||||
// cannot be loaded until a primary is found -- which will also lead to an error if the version does not support standby. If the
|
||||
@ -228,23 +228,23 @@ backupInit(const InfoBackup *infoBackup)
|
||||
bool backupStandby = cfgOptionBool(cfgOptBackupStandby);
|
||||
DbGetResult dbInfo = dbGet(!backupStandby, true, backupStandby);
|
||||
|
||||
result->pgIdPrimary = dbInfo.primaryId;
|
||||
result->pgIdxPrimary = dbInfo.primaryIdx;
|
||||
result->dbPrimary = dbInfo.primary;
|
||||
|
||||
if (backupStandby)
|
||||
{
|
||||
ASSERT(dbInfo.standbyId != 0);
|
||||
ASSERT(dbInfo.standby != NULL);
|
||||
|
||||
result->pgIdStandby = dbInfo.standbyId;
|
||||
result->pgIdxStandby = dbInfo.standbyIdx;
|
||||
result->dbStandby = dbInfo.standby;
|
||||
result->storageStandby = storagePgId(result->pgIdStandby);
|
||||
result->hostStandby = cfgOptionStrNull(cfgOptPgHost + result->pgIdStandby - 1);
|
||||
result->storageStandby = storagePgIdx(result->pgIdxStandby);
|
||||
result->hostStandby = cfgOptionStrNull(cfgOptPgHost + result->pgIdxStandby);
|
||||
}
|
||||
}
|
||||
|
||||
// Add primary info
|
||||
result->storagePrimary = storagePgId(result->pgIdPrimary);
|
||||
result->hostPrimary = cfgOptionStrNull(cfgOptPgHost + result->pgIdPrimary - 1);
|
||||
result->storagePrimary = storagePgIdx(result->pgIdxPrimary);
|
||||
result->hostPrimary = cfgOptionStrNull(cfgOptPgHost + result->pgIdxPrimary);
|
||||
|
||||
// Get pg_control info from the primary
|
||||
PgControl pgControl = pgControlFromFile(result->storagePrimary);
|
||||
@ -864,7 +864,7 @@ backupStart(BackupData *backupData)
|
||||
else
|
||||
{
|
||||
// Check database configuration
|
||||
checkDbConfig(backupData->version, backupData->pgIdPrimary, backupData->dbPrimary, false);
|
||||
checkDbConfig(backupData->version, backupData->pgIdxPrimary, backupData->dbPrimary, false);
|
||||
|
||||
// Start backup
|
||||
LOG_INFO_FMT(
|
||||
@ -897,7 +897,7 @@ backupStart(BackupData *backupData)
|
||||
dbFree(backupData->dbStandby);
|
||||
|
||||
// The standby protocol connection won't be used anymore so free it
|
||||
protocolRemoteFree(backupData->pgIdStandby);
|
||||
protocolRemoteFree(backupData->pgIdxStandby);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1588,15 +1588,15 @@ backupProcess(BackupData *backupData, Manifest *manifest, const String *lsnStart
|
||||
(TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * MSEC_PER_SEC) / 2, backupJobCallback, &jobData);
|
||||
|
||||
// First client is always on the primary
|
||||
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypePg, backupData->pgIdPrimary, 1));
|
||||
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypePg, backupData->pgIdxPrimary, 1));
|
||||
|
||||
// Create the rest of the clients on the primary or standby depending on the value of backup-standby. Note that standby
|
||||
// backups don't count the primary client in process-max.
|
||||
unsigned int processMax = cfgOptionUInt(cfgOptProcessMax) + (backupStandby ? 1 : 0);
|
||||
unsigned int pgId = backupStandby ? backupData->pgIdStandby : backupData->pgIdPrimary;
|
||||
unsigned int pgIdx = backupStandby ? backupData->pgIdxStandby : backupData->pgIdxPrimary;
|
||||
|
||||
for (unsigned int processIdx = 2; processIdx <= processMax; processIdx++)
|
||||
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypePg, pgId, processIdx));
|
||||
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypePg, pgIdx, processIdx));
|
||||
|
||||
// Maintain a list of files that need to be removed from the manifest when the backup is complete
|
||||
StringList *fileRemove = strLstNew();
|
||||
@ -1625,7 +1625,7 @@ backupProcess(BackupData *backupData, Manifest *manifest, const String *lsnStart
|
||||
manifest,
|
||||
backupStandby && protocolParallelJobProcessId(job) > 1 ? backupData->hostStandby : backupData->hostPrimary,
|
||||
storagePathP(
|
||||
protocolParallelJobProcessId(job) > 1 ? storagePgId(pgId) : backupData->storagePrimary,
|
||||
protocolParallelJobProcessId(job) > 1 ? storagePgIdx(pgIdx) : backupData->storagePrimary,
|
||||
manifestPathPg(manifestFileFind(manifest, varStr(protocolParallelJobKey(job)))->name)),
|
||||
fileRemove, job, sizeTotal, sizeCopied);
|
||||
}
|
||||
@ -1997,7 +1997,7 @@ cmdBackup(void)
|
||||
// The primary protocol connection won't be used anymore so free it. This needs to happen after backupArchiveCheckCopy() so
|
||||
// the backup lock is held on the remote which allows conditional archiving based on the backup lock. Any further access to
|
||||
// the primary storage object may result in an error (likely eof).
|
||||
protocolRemoteFree(backupData->pgIdPrimary);
|
||||
protocolRemoteFree(backupData->pgIdxPrimary);
|
||||
|
||||
// Complete the backup
|
||||
LOG_INFO_FMT("new backup label = %s", strZ(manifestData(manifest)->backupLabel));
|
||||
|
@ -36,7 +36,7 @@ checkManifest(void)
|
||||
{
|
||||
result++;
|
||||
// ??? Placeholder for manifest build
|
||||
storageListP(storagePgId(pgIdx + 1), varStr(cfgOption(cfgOptPgPath + pgIdx)));
|
||||
storageListP(storagePgIdx(pgIdx), varStr(cfgOption(cfgOptPgPath + pgIdx)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -70,10 +70,10 @@ checkStandby(const DbGetResult dbGroup, unsigned int pgPathDefinedTotal)
|
||||
}
|
||||
|
||||
// Validate the standby database config
|
||||
PgControl pgControl = pgControlFromFile(storagePgId(dbGroup.standbyId));
|
||||
PgControl pgControl = pgControlFromFile(storagePgIdx(dbGroup.standbyIdx));
|
||||
|
||||
// Check the user configured path and version against the database
|
||||
checkDbConfig(pgControl.version, dbGroup.standbyId, dbGroup.standby, true);
|
||||
checkDbConfig(pgControl.version, dbGroup.standbyIdx, dbGroup.standby, true);
|
||||
|
||||
// Get the repo storage in case it is remote and encryption settings need to be pulled down (performed here for testing)
|
||||
storageRepo();
|
||||
@ -108,10 +108,10 @@ checkPrimary(const DbGetResult dbGroup)
|
||||
if (dbGroup.primary != NULL)
|
||||
{
|
||||
// Validate the primary database config
|
||||
PgControl pgControl = pgControlFromFile(storagePgId(dbGroup.primaryId));
|
||||
PgControl pgControl = pgControlFromFile(storagePgIdx(dbGroup.primaryIdx));
|
||||
|
||||
// Check the user configured path and version against the database
|
||||
checkDbConfig(pgControl.version, dbGroup.primaryId, dbGroup.primary, false);
|
||||
checkDbConfig(pgControl.version, dbGroup.primaryIdx, dbGroup.primary, false);
|
||||
|
||||
// Get the repo storage in case it is remote and encryption settings need to be pulled down (performed here for testing)
|
||||
storageRepo();
|
||||
|
@ -42,23 +42,22 @@ checkArchiveCommand(const String *archiveCommand)
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
void
|
||||
checkDbConfig(const unsigned int pgVersion, const unsigned int dbIdx, const Db *dbObject, bool isStandby)
|
||||
checkDbConfig(const unsigned int pgVersion, const unsigned int pgIdx, const Db *dbObject, bool isStandby)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(UINT, pgVersion);
|
||||
FUNCTION_TEST_PARAM(UINT, dbIdx);
|
||||
FUNCTION_TEST_PARAM(UINT, pgIdx);
|
||||
FUNCTION_TEST_PARAM(DB, dbObject);
|
||||
FUNCTION_TEST_PARAM(BOOL, isStandby);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(dbIdx > 0);
|
||||
ASSERT(dbObject != NULL);
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
unsigned int dbVersion = dbPgVersion(dbObject);
|
||||
const String *dbPath = dbPgDataPath(dbObject);
|
||||
unsigned int pgPath = cfgOptPgPath + (dbIdx - 1);
|
||||
unsigned int pgPath = cfgOptPgPath + pgIdx;
|
||||
|
||||
// Error if the version from the control file and the configured pg-path do not match the values obtained from the database
|
||||
if (pgVersion != dbVersion || strCmp(cfgOptionStr(pgPath), dbPath) != 0)
|
||||
@ -67,7 +66,7 @@ checkDbConfig(const unsigned int pgVersion, const unsigned int dbIdx, const Db *
|
||||
DbMismatchError, "version '%s' and path '%s' queried from cluster do not match version '%s' and '%s' read from '%s/"
|
||||
PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL "'\nHINT: the %s and %s settings likely reference different clusters.",
|
||||
strZ(pgVersionToStr(dbVersion)), strZ(dbPath), strZ(pgVersionToStr(pgVersion)), strZ(cfgOptionStr(pgPath)),
|
||||
strZ(cfgOptionStr(pgPath)), cfgOptionName(pgPath), cfgOptionName(cfgOptPgPort + (dbIdx - 1)));
|
||||
strZ(cfgOptionStr(pgPath)), cfgOptionName(pgPath), cfgOptionName(cfgOptPgPort + pgIdx));
|
||||
}
|
||||
|
||||
// Check archive configuration if option is valid for the command and set
|
||||
|
@ -12,7 +12,7 @@ Check Command Common
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
// Check the database path and version are configured correctly
|
||||
void checkDbConfig(const unsigned int pgVersion, const unsigned int dbIdx, const Db *dbObject, bool isStandby);
|
||||
void checkDbConfig(const unsigned int pgVersion, const unsigned int pgIdx, const Db *dbObject, bool isStandby);
|
||||
|
||||
// Validate the archive and backup info files
|
||||
void checkStanzaInfo(const InfoPgData *archiveInfo, const InfoPgData *backupInfo);
|
||||
|
@ -2094,7 +2094,7 @@ cmdRestore(void)
|
||||
(TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * MSEC_PER_SEC) / 2, restoreJobCallback, &jobData);
|
||||
|
||||
for (unsigned int processIdx = 1; processIdx <= cfgOptionUInt(cfgOptProcessMax); processIdx++)
|
||||
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypeRepo, 1, processIdx));
|
||||
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypeRepo, 0, processIdx));
|
||||
|
||||
// Process jobs
|
||||
uint64_t sizeRestored = 0;
|
||||
|
@ -52,10 +52,10 @@ pgValidate(void)
|
||||
DbGetResult dbObject = dbGet(false, true, false);
|
||||
|
||||
// Get the pgControl information from the pg*-path deemed to be the master
|
||||
result = pgControlFromFile(storagePgId(dbObject.primaryId));
|
||||
result = pgControlFromFile(storagePgIdx(dbObject.primaryIdx));
|
||||
|
||||
// Check the user configured path and version against the database
|
||||
checkDbConfig(result.version, dbObject.primaryId, dbObject.primary, false);
|
||||
checkDbConfig(result.version, dbObject.primaryIdx, dbObject.primary, false);
|
||||
}
|
||||
// If the database is not online, assume that pg1 is the master
|
||||
else
|
||||
|
@ -980,7 +980,7 @@ verifyProcess(unsigned int *errorTotal)
|
||||
(TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * MSEC_PER_SEC) / 2, verifyJobCallback, &jobData);
|
||||
|
||||
for (unsigned int processIdx = 1; processIdx <= cfgOptionUInt(cfgOptProcessMax); processIdx++)
|
||||
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypeRepo, 1, processIdx));
|
||||
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypeRepo, 0, processIdx));
|
||||
|
||||
// Process jobs
|
||||
do
|
||||
|
@ -12,13 +12,13 @@ Database Helper
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
static Db *
|
||||
dbGetId(unsigned int pgId)
|
||||
dbGetIdx(unsigned int pgIdx)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(UINT, pgId);
|
||||
FUNCTION_LOG_PARAM(UINT, pgIdx);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(pgId > 0);
|
||||
ASSERT(pgIdx < cfgOptionGroupIdxTotal(cfgOptGrpPg));
|
||||
|
||||
Db *result = NULL;
|
||||
|
||||
@ -26,16 +26,16 @@ dbGetId(unsigned int pgId)
|
||||
{
|
||||
const String *applicationName = strNewFmt(PROJECT_NAME " [%s]", cfgCommandName(cfgCommand()));
|
||||
|
||||
if (pgIsLocal(pgId))
|
||||
if (pgIsLocal(pgIdx))
|
||||
{
|
||||
result = dbNew(
|
||||
pgClientNew(
|
||||
cfgOptionStrNull(cfgOptPgSocketPath + pgId - 1), cfgOptionUInt(cfgOptPgPort + pgId - 1), PG_DB_POSTGRES_STR,
|
||||
cfgOptionStrNull(cfgOptPgUser + pgId - 1), (TimeMSec)(cfgOptionDbl(cfgOptDbTimeout) * MSEC_PER_SEC)),
|
||||
cfgOptionStrNull(cfgOptPgSocketPath + pgIdx), cfgOptionUInt(cfgOptPgPort + pgIdx), PG_DB_POSTGRES_STR,
|
||||
cfgOptionStrNull(cfgOptPgUser + pgIdx), (TimeMSec)(cfgOptionDbl(cfgOptDbTimeout) * MSEC_PER_SEC)),
|
||||
NULL, applicationName);
|
||||
}
|
||||
else
|
||||
result = dbNew(NULL, protocolRemoteGet(protocolStorageTypePg, pgId), applicationName);
|
||||
result = dbNew(NULL, protocolRemoteGet(protocolStorageTypePg, pgIdx), applicationName);
|
||||
|
||||
dbMove(result, memContextPrior());
|
||||
}
|
||||
@ -72,7 +72,7 @@ dbGet(bool primaryOnly, bool primaryRequired, bool standbyRequired)
|
||||
|
||||
TRY_BEGIN()
|
||||
{
|
||||
db = dbGetId(pgIdx + 1);
|
||||
db = dbGetIdx(pgIdx);
|
||||
|
||||
// This needs to be nested because db can be reset to NULL on an error in the outer try but we need the pointer
|
||||
// to be able to free it.
|
||||
@ -102,9 +102,9 @@ dbGet(bool primaryOnly, bool primaryRequired, bool standbyRequired)
|
||||
if (standby)
|
||||
{
|
||||
// If a standby has not already been found then assign it
|
||||
if (result.standbyId == 0 && !primaryOnly)
|
||||
if (result.standby == NULL && !primaryOnly)
|
||||
{
|
||||
result.standbyId = pgIdx + 1;
|
||||
result.standbyIdx = pgIdx;
|
||||
result.standby = db;
|
||||
}
|
||||
// Else close the connection since we don't need it
|
||||
@ -115,10 +115,10 @@ dbGet(bool primaryOnly, bool primaryRequired, bool standbyRequired)
|
||||
else
|
||||
{
|
||||
// Error if more than one primary was found
|
||||
if (result.primaryId != 0)
|
||||
if (result.primary != NULL)
|
||||
THROW(DbConnectError, "more than one primary cluster found");
|
||||
|
||||
result.primaryId = pgIdx + 1;
|
||||
result.primaryIdx = pgIdx;
|
||||
result.primary = db;
|
||||
}
|
||||
}
|
||||
@ -126,11 +126,11 @@ dbGet(bool primaryOnly, bool primaryRequired, bool standbyRequired)
|
||||
}
|
||||
|
||||
// Error if no primary was found
|
||||
if (result.primaryId == 0 && primaryRequired)
|
||||
if (result.primary == NULL && primaryRequired)
|
||||
THROW(DbConnectError, "unable to find primary cluster - cannot proceed");
|
||||
|
||||
// Error if no standby was found
|
||||
if (result.standbyId == 0 && standbyRequired)
|
||||
if (result.standby == NULL && standbyRequired)
|
||||
THROW(DbConnectError, "unable to find standby cluster - cannot proceed");
|
||||
|
||||
dbMove(result.primary, memContextPrior());
|
||||
|
@ -16,10 +16,10 @@ Functions
|
||||
// Get specified cluster(s)
|
||||
typedef struct DbGetResult
|
||||
{
|
||||
unsigned int primaryId;
|
||||
Db *primary;
|
||||
unsigned int standbyId;
|
||||
Db *standby;
|
||||
unsigned int primaryIdx; // cfgOptGrpPg index of the primary
|
||||
Db *primary; // Primary db object (NULL if none requested)
|
||||
unsigned int standbyIdx; // cfgOptGrpPg index of the standby
|
||||
Db *standby; // Standby db object (NULL if none requested)
|
||||
} DbGetResult;
|
||||
|
||||
DbGetResult dbGet(bool primaryOnly, bool primaryRequired, bool standbyRequired);
|
||||
|
@ -90,15 +90,13 @@ repoIsLocalVerify(void)
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
bool
|
||||
pgIsLocal(unsigned int hostId)
|
||||
pgIsLocal(unsigned int pgIdx)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(UINT, hostId);
|
||||
FUNCTION_LOG_PARAM(UINT, pgIdx);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(hostId > 0);
|
||||
|
||||
FUNCTION_LOG_RETURN(BOOL, !cfgOptionTest(cfgOptPgHost + hostId - 1));
|
||||
FUNCTION_LOG_RETURN(BOOL, !cfgOptionTest(cfgOptPgHost + pgIdx));
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
@ -107,7 +105,7 @@ pgIsLocalVerify(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
|
||||
if (!pgIsLocal(1))
|
||||
if (!pgIsLocal(0))
|
||||
THROW_FMT(HostInvalidError, "%s command must be run on the " PG_NAME " host", cfgCommandName(cfgCommand()));
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
@ -117,16 +115,14 @@ pgIsLocalVerify(void)
|
||||
Get the command line required for local protocol execution
|
||||
***********************************************************************************************************************************/
|
||||
static StringList *
|
||||
protocolLocalParam(ProtocolStorageType protocolStorageType, unsigned int hostId, unsigned int protocolId)
|
||||
protocolLocalParam(ProtocolStorageType protocolStorageType, unsigned int hostIdx, unsigned int processId)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(ENUM, protocolStorageType);
|
||||
FUNCTION_LOG_PARAM(UINT, hostId);
|
||||
FUNCTION_LOG_PARAM(UINT, protocolId);
|
||||
FUNCTION_LOG_PARAM(UINT, hostIdx);
|
||||
FUNCTION_LOG_PARAM(UINT, processId);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(hostId > 0);
|
||||
|
||||
StringList *result = NULL;
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
@ -135,10 +131,10 @@ protocolLocalParam(ProtocolStorageType protocolStorageType, unsigned int hostId,
|
||||
KeyValue *optionReplace = kvNew();
|
||||
|
||||
// Add the process id -- used when more than one process will be called
|
||||
kvPut(optionReplace, VARSTR(CFGOPT_PROCESS_STR), VARUINT(protocolId));
|
||||
kvPut(optionReplace, VARSTR(CFGOPT_PROCESS_STR), VARUINT(processId));
|
||||
|
||||
// Add the host id
|
||||
kvPut(optionReplace, VARSTR(CFGOPT_HOST_ID_STR), VARUINT(hostId));
|
||||
kvPut(optionReplace, VARSTR(CFGOPT_HOST_ID_STR), VARUINT(hostIdx + 1));
|
||||
|
||||
// Add the remote type
|
||||
kvPut(optionReplace, VARSTR(CFGOPT_REMOTE_TYPE_STR), VARSTR(protocolStorageTypeStr(protocolStorageType)));
|
||||
@ -163,16 +159,14 @@ protocolLocalParam(ProtocolStorageType protocolStorageType, unsigned int hostId,
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
ProtocolClient *
|
||||
protocolLocalGet(ProtocolStorageType protocolStorageType, unsigned int hostId, unsigned int protocolId)
|
||||
protocolLocalGet(ProtocolStorageType protocolStorageType, unsigned int hostIdx, unsigned int processId)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(ENUM, protocolStorageType);
|
||||
FUNCTION_LOG_PARAM(UINT, hostId);
|
||||
FUNCTION_LOG_PARAM(UINT, protocolId);
|
||||
FUNCTION_LOG_PARAM(UINT, hostIdx);
|
||||
FUNCTION_LOG_PARAM(UINT, processId);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(hostId > 0);
|
||||
|
||||
protocolHelperInit();
|
||||
|
||||
// Allocate the client cache
|
||||
@ -189,10 +183,10 @@ protocolLocalGet(ProtocolStorageType protocolStorageType, unsigned int hostId, u
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
|
||||
ASSERT(protocolId <= protocolHelper.clientLocalSize);
|
||||
ASSERT(processId <= protocolHelper.clientLocalSize);
|
||||
|
||||
// Create protocol object
|
||||
ProtocolHelperClient *protocolHelperClient = &protocolHelper.clientLocal[protocolId - 1];
|
||||
ProtocolHelperClient *protocolHelperClient = &protocolHelper.clientLocal[processId - 1];
|
||||
|
||||
if (protocolHelperClient->client == NULL)
|
||||
{
|
||||
@ -200,14 +194,14 @@ protocolLocalGet(ProtocolStorageType protocolStorageType, unsigned int hostId, u
|
||||
{
|
||||
// Execute the protocol command
|
||||
protocolHelperClient->exec = execNew(
|
||||
cfgExe(), protocolLocalParam(protocolStorageType, hostId, protocolId),
|
||||
strNewFmt(PROTOCOL_SERVICE_LOCAL "-%u process", protocolId),
|
||||
cfgExe(), protocolLocalParam(protocolStorageType, hostIdx, processId),
|
||||
strNewFmt(PROTOCOL_SERVICE_LOCAL "-%u process", processId),
|
||||
(TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * 1000));
|
||||
execOpen(protocolHelperClient->exec);
|
||||
|
||||
// Create protocol object
|
||||
protocolHelperClient->client = protocolClientNew(
|
||||
strNewFmt(PROTOCOL_SERVICE_LOCAL "-%u protocol", protocolId),
|
||||
strNewFmt(PROTOCOL_SERVICE_LOCAL "-%u protocol", processId),
|
||||
PROTOCOL_SERVICE_LOCAL_STR, execIoRead(protocolHelperClient->exec), execIoWrite(protocolHelperClient->exec));
|
||||
|
||||
protocolClientMove(protocolHelperClient->client, execMemContext(protocolHelperClient->exec));
|
||||
@ -262,18 +256,16 @@ protocolHelperClientFree(ProtocolHelperClient *protocolHelperClient)
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
void
|
||||
protocolLocalFree(unsigned int protocolId)
|
||||
protocolLocalFree(unsigned int processId)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(UINT, protocolId);
|
||||
FUNCTION_LOG_PARAM(UINT, processId);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(protocolId > 0);
|
||||
|
||||
if (protocolHelper.clientLocal != NULL)
|
||||
{
|
||||
ASSERT(protocolId <= protocolHelper.clientLocalSize);
|
||||
protocolHelperClientFree(&protocolHelper.clientLocal[protocolId - 1]);
|
||||
ASSERT(processId <= protocolHelper.clientLocalSize);
|
||||
protocolHelperClientFree(&protocolHelper.clientLocal[processId - 1]);
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
@ -283,11 +275,10 @@ protocolLocalFree(unsigned int protocolId)
|
||||
Get the command line required for remote protocol execution
|
||||
***********************************************************************************************************************************/
|
||||
static StringList *
|
||||
protocolRemoteParam(ProtocolStorageType protocolStorageType, unsigned int protocolId, unsigned int hostIdx)
|
||||
protocolRemoteParam(ProtocolStorageType protocolStorageType, unsigned int hostIdx)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(ENUM, protocolStorageType);
|
||||
FUNCTION_LOG_PARAM(UINT, protocolId);
|
||||
FUNCTION_LOG_PARAM(UINT, hostIdx);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
@ -410,9 +401,10 @@ protocolRemoteParam(ProtocolStorageType protocolStorageType, unsigned int protoc
|
||||
// Don't pass host-id to the remote. The host will always be in index 0.
|
||||
kvPut(optionReplace, VARSTR(CFGOPT_HOST_ID_STR), NULL);
|
||||
|
||||
// Add the process id (or use the current process id if it is valid)
|
||||
// Add the process id if not set. This means that the remote is being started from the main process and should always get a
|
||||
// process id of 0.
|
||||
if (!cfgOptionTest(cfgOptProcess))
|
||||
kvPut(optionReplace, VARSTR(CFGOPT_PROCESS_STR), VARINT((int)protocolId));
|
||||
kvPut(optionReplace, VARSTR(CFGOPT_PROCESS_STR), VARINT(0));
|
||||
|
||||
// Don't pass log-path or lock-path since these are host specific
|
||||
kvPut(optionReplace, VARSTR(CFGOPT_LOG_PATH_STR), NULL);
|
||||
@ -452,15 +444,13 @@ protocolRemoteParam(ProtocolStorageType protocolStorageType, unsigned int protoc
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
ProtocolClient *
|
||||
protocolRemoteGet(ProtocolStorageType protocolStorageType, unsigned int hostId)
|
||||
protocolRemoteGet(ProtocolStorageType protocolStorageType, unsigned int hostIdx)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(ENUM, protocolStorageType);
|
||||
FUNCTION_LOG_PARAM(UINT, hostId);
|
||||
FUNCTION_LOG_PARAM(UINT, hostIdx);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(hostId > 0);
|
||||
|
||||
// Is this a repo remote?
|
||||
bool isRepo = protocolStorageType == protocolStorageTypeRepo;
|
||||
|
||||
@ -488,35 +478,32 @@ protocolRemoteGet(ProtocolStorageType protocolStorageType, unsigned int hostId)
|
||||
// Determine protocol id for the remote. If the process option is set then use that since we want the remote protocol id to
|
||||
// match the local protocol id. Otherwise set to 0 since the remote is being started from a main process and there should only
|
||||
// be one remote per host.
|
||||
unsigned int protocolId = 0;
|
||||
|
||||
// Use hostId to determine where to cache to remote
|
||||
unsigned int protocolIdx = hostId - 1;
|
||||
unsigned int processId = 0;
|
||||
|
||||
if (cfgOptionTest(cfgOptProcess))
|
||||
protocolId = cfgOptionUInt(cfgOptProcess);
|
||||
processId = cfgOptionUInt(cfgOptProcess);
|
||||
|
||||
CHECK(protocolIdx < protocolHelper.clientRemoteSize);
|
||||
CHECK(hostIdx < protocolHelper.clientRemoteSize);
|
||||
|
||||
// Create protocol object
|
||||
ProtocolHelperClient *protocolHelperClient = &protocolHelper.clientRemote[protocolIdx];
|
||||
ProtocolHelperClient *protocolHelperClient = &protocolHelper.clientRemote[hostIdx];
|
||||
|
||||
if (protocolHelperClient->client == NULL)
|
||||
{
|
||||
MEM_CONTEXT_BEGIN(protocolHelper.memContext)
|
||||
{
|
||||
unsigned int optHost = isRepo ? cfgOptRepoHost : cfgOptPgHost + hostId - 1;
|
||||
unsigned int optHost = isRepo ? cfgOptRepoHost : cfgOptPgHost + hostIdx;
|
||||
|
||||
// Execute the protocol command
|
||||
protocolHelperClient->exec = execNew(
|
||||
cfgOptionStr(cfgOptCmdSsh), protocolRemoteParam(protocolStorageType, protocolId, hostId - 1),
|
||||
strNewFmt(PROTOCOL_SERVICE_REMOTE "-%u process on '%s'", protocolId, strZ(cfgOptionStr(optHost))),
|
||||
cfgOptionStr(cfgOptCmdSsh), protocolRemoteParam(protocolStorageType, hostIdx),
|
||||
strNewFmt(PROTOCOL_SERVICE_REMOTE "-%u process on '%s'", processId, strZ(cfgOptionStr(optHost))),
|
||||
(TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * 1000));
|
||||
execOpen(protocolHelperClient->exec);
|
||||
|
||||
// Create protocol object
|
||||
protocolHelperClient->client = protocolClientNew(
|
||||
strNewFmt(PROTOCOL_SERVICE_REMOTE "-%u protocol on '%s'", protocolId, strZ(cfgOptionStr(optHost))),
|
||||
strNewFmt(PROTOCOL_SERVICE_REMOTE "-%u protocol on '%s'", processId, strZ(cfgOptionStr(optHost))),
|
||||
PROTOCOL_SERVICE_REMOTE_STR, execIoRead(protocolHelperClient->exec), execIoWrite(protocolHelperClient->exec));
|
||||
|
||||
// Get cipher options from the remote if none are locally configured
|
||||
@ -546,16 +533,14 @@ protocolRemoteGet(ProtocolStorageType protocolStorageType, unsigned int hostId)
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
void
|
||||
protocolRemoteFree(unsigned int hostId)
|
||||
protocolRemoteFree(unsigned int hostIdx)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(UINT, hostId);
|
||||
FUNCTION_LOG_PARAM(UINT, hostIdx);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(hostId > 0);
|
||||
|
||||
if (protocolHelper.clientRemote != NULL)
|
||||
protocolHelperClientFree(&protocolHelper.clientRemote[hostId - 1]);
|
||||
protocolHelperClientFree(&protocolHelper.clientRemote[hostIdx]);
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
@ -627,7 +612,7 @@ protocolFree(void)
|
||||
{
|
||||
// Free remotes
|
||||
for (unsigned int clientIdx = 0; clientIdx < protocolHelper.clientRemoteSize; clientIdx++)
|
||||
protocolRemoteFree(clientIdx + 1);
|
||||
protocolRemoteFree(clientIdx);
|
||||
|
||||
// Free locals
|
||||
for (unsigned int clientIdx = 1; clientIdx <= protocolHelper.clientLocalSize; clientIdx++)
|
||||
|
@ -48,7 +48,7 @@ void protocolRemoteFree(unsigned int hostId);
|
||||
Getters/Setters
|
||||
***********************************************************************************************************************************/
|
||||
// Is pg local?
|
||||
bool pgIsLocal(unsigned int hostId);
|
||||
bool pgIsLocal(unsigned int pgIdx);
|
||||
|
||||
// Error if PostgreSQL is not local, i.e. pg-host is set
|
||||
void pgIsLocalVerify(void);
|
||||
|
@ -164,26 +164,26 @@ storageLocalWrite(void)
|
||||
Get pg storage for the specified host id
|
||||
***********************************************************************************************************************************/
|
||||
static Storage *
|
||||
storagePgGet(unsigned int hostId, bool write)
|
||||
storagePgGet(unsigned int pgIdx, bool write)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(UINT, hostId);
|
||||
FUNCTION_TEST_PARAM(UINT, pgIdx);
|
||||
FUNCTION_TEST_PARAM(BOOL, write);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
Storage *result = NULL;
|
||||
|
||||
// Use remote storage
|
||||
if (!pgIsLocal(hostId))
|
||||
if (!pgIsLocal(pgIdx))
|
||||
{
|
||||
result = storageRemoteNew(
|
||||
STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, write, NULL,
|
||||
protocolRemoteGet(protocolStorageTypePg, hostId), cfgOptionUInt(cfgOptCompressLevelNetwork));
|
||||
protocolRemoteGet(protocolStorageTypePg, pgIdx), cfgOptionUInt(cfgOptCompressLevelNetwork));
|
||||
}
|
||||
// Use Posix storage
|
||||
else
|
||||
{
|
||||
result = storagePosixNewP(cfgOptionStr(cfgOptPgPath + hostId - 1), .write = write);
|
||||
result = storagePosixNewP(cfgOptionStr(cfgOptPgPath + pgIdx), .write = write);
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN(result);
|
||||
@ -191,13 +191,13 @@ storagePgGet(unsigned int hostId, bool write)
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
const Storage *
|
||||
storagePgId(unsigned int hostId)
|
||||
storagePgIdx(unsigned int pgIdx)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(UINT, hostId);
|
||||
FUNCTION_TEST_PARAM(UINT, pgIdx);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
if (storageHelper.storagePg == NULL || storageHelper.storagePg[hostId - 1] == NULL)
|
||||
if (storageHelper.storagePg == NULL || storageHelper.storagePg[pgIdx] == NULL)
|
||||
{
|
||||
storageHelperInit();
|
||||
|
||||
@ -206,33 +206,33 @@ storagePgId(unsigned int hostId)
|
||||
if (storageHelper.storagePg == NULL)
|
||||
storageHelper.storagePg = memNewPtrArray(cfgDefOptionIndexTotal(cfgDefOptPgPath));
|
||||
|
||||
storageHelper.storagePg[hostId - 1] = storagePgGet(hostId, false);
|
||||
storageHelper.storagePg[pgIdx] = storagePgGet(pgIdx, false);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN(storageHelper.storagePg[hostId - 1]);
|
||||
FUNCTION_TEST_RETURN(storageHelper.storagePg[pgIdx]);
|
||||
}
|
||||
|
||||
const Storage *
|
||||
storagePg(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
FUNCTION_TEST_RETURN(storagePgId(cfgOptionTest(cfgOptHostId) ? cfgOptionUInt(cfgOptHostId) : 1));
|
||||
FUNCTION_TEST_RETURN(storagePgIdx(cfgOptionTest(cfgOptHostId) ? cfgOptionUInt(cfgOptHostId) - 1 : 0));
|
||||
}
|
||||
|
||||
const Storage *
|
||||
storagePgIdWrite(unsigned int hostId)
|
||||
storagePgIdxWrite(unsigned int pgIdx)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(UINT, hostId);
|
||||
FUNCTION_TEST_PARAM(UINT, pgIdx);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
// Writes not allowed in dry-run mode
|
||||
if (!storageHelper.dryRunInit || storageHelper.dryRun)
|
||||
THROW(AssertError, WRITABLE_WHILE_DRYRUN);
|
||||
|
||||
if (storageHelper.storagePgWrite == NULL || storageHelper.storagePgWrite[hostId - 1] == NULL)
|
||||
if (storageHelper.storagePgWrite == NULL || storageHelper.storagePgWrite[pgIdx] == NULL)
|
||||
{
|
||||
storageHelperInit();
|
||||
|
||||
@ -241,19 +241,19 @@ storagePgIdWrite(unsigned int hostId)
|
||||
if (storageHelper.storagePgWrite == NULL)
|
||||
storageHelper.storagePgWrite = memNewPtrArray(cfgDefOptionIndexTotal(cfgDefOptPgPath));
|
||||
|
||||
storageHelper.storagePgWrite[hostId - 1] = storagePgGet(hostId, true);
|
||||
storageHelper.storagePgWrite[pgIdx] = storagePgGet(pgIdx, true);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN(storageHelper.storagePgWrite[hostId - 1]);
|
||||
FUNCTION_TEST_RETURN(storageHelper.storagePgWrite[pgIdx]);
|
||||
}
|
||||
|
||||
const Storage *
|
||||
storagePgWrite(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
FUNCTION_TEST_RETURN(storagePgIdWrite(cfgOptionTest(cfgOptHostId) ? cfgOptionUInt(cfgOptHostId) : 1));
|
||||
FUNCTION_TEST_RETURN(storagePgIdxWrite(cfgOptionTest(cfgOptHostId) ? cfgOptionUInt(cfgOptHostId) - 1 : 0));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -349,7 +349,7 @@ storageRepoGet(const String *type, bool write)
|
||||
{
|
||||
result = storageRemoteNew(
|
||||
STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, write, storageRepoPathExpression,
|
||||
protocolRemoteGet(protocolStorageTypeRepo, 1), cfgOptionUInt(cfgOptCompressLevelNetwork));
|
||||
protocolRemoteGet(protocolStorageTypeRepo, 0), cfgOptionUInt(cfgOptCompressLevelNetwork));
|
||||
}
|
||||
// Use Azure storage
|
||||
else if (strEqZ(type, STORAGE_AZURE_TYPE))
|
||||
|
@ -37,11 +37,11 @@ void storageHelperDryRunInit(bool dryRun);
|
||||
const Storage *storageLocal(void);
|
||||
const Storage *storageLocalWrite(void);
|
||||
|
||||
// PostgreSQL storage by Id
|
||||
const Storage *storagePgId(unsigned int hostId);
|
||||
const Storage *storagePgIdWrite(unsigned int hostId);
|
||||
// PostgreSQL storage by cfgOptGrpPg index
|
||||
const Storage *storagePgIdx(unsigned int pgIdx);
|
||||
const Storage *storagePgIdxWrite(unsigned int pgIdx);
|
||||
|
||||
// PostgreSQL storage for the host-id or the default of 1
|
||||
// PostgreSQL storage default (calculated from host-id, when set, or the first cfgOptGrpPg index)
|
||||
const Storage *storagePg(void);
|
||||
const Storage *storagePgWrite(void);
|
||||
|
||||
|
@ -2107,28 +2107,28 @@ testRun(void)
|
||||
|
||||
// Create file to copy from the standby. This file will be zero-length on the primary and non-zero-length on the standby
|
||||
// but no bytes will be copied.
|
||||
storagePutP(storageNewWriteP(storagePgIdWrite(1), STRDEF(PG_PATH_BASE "/1/1"), .timeModified = backupTimeStart), NULL);
|
||||
storagePutP(storageNewWriteP(storagePgIdWrite(2), STRDEF(PG_PATH_BASE "/1/1")), BUFSTRDEF("1234"));
|
||||
storagePutP(storageNewWriteP(storagePgIdxWrite(0), STRDEF(PG_PATH_BASE "/1/1"), .timeModified = backupTimeStart), NULL);
|
||||
storagePutP(storageNewWriteP(storagePgIdxWrite(1), STRDEF(PG_PATH_BASE "/1/1")), BUFSTRDEF("1234"));
|
||||
|
||||
// Create file to copy from the standby. This file will be smaller on the primary than the standby and have no common
|
||||
// data in the bytes that exist on primary and standby. If the file is copied from the primary instead of the standby
|
||||
// the checksum will change but not the size.
|
||||
storagePutP(
|
||||
storageNewWriteP(storagePgIdWrite(1), STRDEF(PG_PATH_BASE "/1/2"), .timeModified = backupTimeStart),
|
||||
storageNewWriteP(storagePgIdxWrite(0), STRDEF(PG_PATH_BASE "/1/2"), .timeModified = backupTimeStart),
|
||||
BUFSTRDEF("DA"));
|
||||
storagePutP(storageNewWriteP(storagePgIdWrite(2), STRDEF(PG_PATH_BASE "/1/2")), BUFSTRDEF("5678"));
|
||||
storagePutP(storageNewWriteP(storagePgIdxWrite(1), STRDEF(PG_PATH_BASE "/1/2")), BUFSTRDEF("5678"));
|
||||
|
||||
// Create file to copy from the standby. This file will be larger on the primary than the standby and have no common
|
||||
// data in the bytes that exist on primary and standby. If the file is copied from the primary instead of the standby
|
||||
// the checksum and size will change.
|
||||
storagePutP(
|
||||
storageNewWriteP(storagePgIdWrite(1), STRDEF(PG_PATH_BASE "/1/3"), .timeModified = backupTimeStart),
|
||||
storageNewWriteP(storagePgIdxWrite(0), STRDEF(PG_PATH_BASE "/1/3"), .timeModified = backupTimeStart),
|
||||
BUFSTRDEF("TEST"));
|
||||
storagePutP(storageNewWriteP(storagePgIdWrite(2), STRDEF(PG_PATH_BASE "/1/3")), BUFSTRDEF("ABC"));
|
||||
storagePutP(storageNewWriteP(storagePgIdxWrite(1), STRDEF(PG_PATH_BASE "/1/3")), BUFSTRDEF("ABC"));
|
||||
|
||||
// Create a file on the primary that does not exist on the standby to test that the file is removed from the manifest
|
||||
storagePutP(
|
||||
storageNewWriteP(storagePgIdWrite(1), STRDEF(PG_PATH_BASE "/1/0"), .timeModified = backupTimeStart),
|
||||
storageNewWriteP(storagePgIdxWrite(0), STRDEF(PG_PATH_BASE "/1/0"), .timeModified = backupTimeStart),
|
||||
BUFSTRDEF("DATA"));
|
||||
|
||||
// Set log level to warn because the following test uses multiple processes so the log order will not be deterministic
|
||||
@ -2200,7 +2200,7 @@ testRun(void)
|
||||
"compare file list");
|
||||
|
||||
// Remove test files
|
||||
storagePathRemoveP(storagePgIdWrite(2), NULL, .recurse = true);
|
||||
storagePathRemoveP(storagePgIdxWrite(1), NULL, .recurse = true);
|
||||
storagePathRemoveP(storagePgWrite(), STRDEF("base/1"), .recurse = true);
|
||||
}
|
||||
|
||||
|
@ -371,12 +371,12 @@ testRun(void)
|
||||
|
||||
TEST_ASSIGN(db, dbGet(false, false, false), "get primary and standby");
|
||||
|
||||
TEST_RESULT_VOID(checkDbConfig(PG_VERSION_92, db.primaryId, db.primary, false), "valid db config");
|
||||
TEST_RESULT_VOID(checkDbConfig(PG_VERSION_92, db.primaryIdx, db.primary, false), "valid db config");
|
||||
|
||||
// Version mismatch
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ERROR_FMT(
|
||||
checkDbConfig(PG_VERSION_94, db.primaryId, db.primary, false), DbMismatchError,
|
||||
checkDbConfig(PG_VERSION_94, db.primaryIdx, db.primary, false), DbMismatchError,
|
||||
"version '%s' and path '%s' queried from cluster do not match version '%s' and '%s' read from '%s/"
|
||||
PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL "'\n"
|
||||
"HINT: the pg1-path and pg1-port settings likely reference different clusters.",
|
||||
@ -385,7 +385,7 @@ testRun(void)
|
||||
// Path mismatch
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ERROR_FMT(
|
||||
checkDbConfig(PG_VERSION_92, db.standbyId, db.standby, true), DbMismatchError,
|
||||
checkDbConfig(PG_VERSION_92, db.standbyIdx, db.standby, true), DbMismatchError,
|
||||
"version '%s' and path '%s' queried from cluster do not match version '%s' and '%s' read from '%s/"
|
||||
PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL "'\n"
|
||||
"HINT: the pg8-path and pg8-port settings likely reference different clusters.",
|
||||
@ -397,7 +397,7 @@ testRun(void)
|
||||
strLstAddZ(argList, "--no-archive-check");
|
||||
harnessCfgLoad(cfgCmdCheck, argList);
|
||||
|
||||
TEST_RESULT_VOID(checkDbConfig(PG_VERSION_92, db.primaryId, db.primary, false), "valid db config --no-archive-check");
|
||||
TEST_RESULT_VOID(checkDbConfig(PG_VERSION_92, db.primaryIdx, db.primary, false), "valid db config --no-archive-check");
|
||||
|
||||
// archive-check not valid for command
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
@ -410,7 +410,7 @@ testRun(void)
|
||||
harnessCfgLoad(cfgCmdStanzaCreate, argList);
|
||||
|
||||
TEST_RESULT_VOID(
|
||||
checkDbConfig(PG_VERSION_92, db.primaryId, db.primary, false), "valid db config, archive-check not valid for command");
|
||||
checkDbConfig(PG_VERSION_92, db.primaryIdx, db.primary, false), "valid db config, archive-check not valid for command");
|
||||
|
||||
TEST_RESULT_VOID(dbFree(db.primary), "free primary");
|
||||
TEST_RESULT_VOID(dbFree(db.standby), "free standby");
|
||||
@ -432,7 +432,7 @@ testRun(void)
|
||||
|
||||
TEST_ASSIGN(db, dbGet(true, true, false), "get primary");
|
||||
TEST_ERROR_FMT(
|
||||
checkDbConfig(PG_VERSION_92, db.primaryId, db.primary, false), FeatureNotSupportedError,
|
||||
checkDbConfig(PG_VERSION_92, db.primaryIdx, db.primary, false), FeatureNotSupportedError,
|
||||
"archive_mode=always not supported");
|
||||
|
||||
TEST_RESULT_VOID(dbFree(db.primary), "free primary");
|
||||
|
@ -213,7 +213,7 @@ testRun(void)
|
||||
HRNPQ_MACRO_DONE()
|
||||
});
|
||||
|
||||
DbGetResult db = {.primaryId = 0};
|
||||
DbGetResult db = {0};
|
||||
TEST_ASSIGN(db, dbGet(true, true, false), "get primary");
|
||||
|
||||
TEST_RESULT_STR_Z(dbBackupStart(db.primary, false, false).lsn, "1/1", "start backup");
|
||||
@ -558,9 +558,9 @@ testRun(void)
|
||||
|
||||
TEST_ASSIGN(result, dbGet(true, true, false), "get primary only");
|
||||
|
||||
TEST_RESULT_INT(result.primaryId, 1, " check primary id");
|
||||
TEST_RESULT_INT(result.primaryIdx, 0, " check primary id");
|
||||
TEST_RESULT_BOOL(result.primary != NULL, true, " check primary");
|
||||
TEST_RESULT_INT(result.standbyId, 0, " check standby id");
|
||||
TEST_RESULT_INT(result.standbyIdx, 0, " check standby id");
|
||||
TEST_RESULT_BOOL(result.standby == NULL, true, " check standby");
|
||||
TEST_RESULT_INT(dbPgVersion(result.primary), PG_VERSION_84, " version set");
|
||||
TEST_RESULT_STR_Z(dbPgDataPath(result.primary), "/pgdata", " path set");
|
||||
@ -620,9 +620,9 @@ testRun(void)
|
||||
|
||||
TEST_ASSIGN(result, dbGet(false, false, false), "get standbys");
|
||||
|
||||
TEST_RESULT_INT(result.primaryId, 0, " check primary id");
|
||||
TEST_RESULT_INT(result.primaryIdx, 0, " check primary id");
|
||||
TEST_RESULT_BOOL(result.primary == NULL, true, " check primary");
|
||||
TEST_RESULT_INT(result.standbyId, 1, " check standby id");
|
||||
TEST_RESULT_INT(result.standbyIdx, 0, " check standby id");
|
||||
TEST_RESULT_BOOL(result.standby != NULL, true, " check standby");
|
||||
|
||||
TEST_RESULT_VOID(dbFree(result.standby), "free standby");
|
||||
@ -671,12 +671,12 @@ testRun(void)
|
||||
"P00 WARN: unable to check pg-5: [DbConnectError] raised from remote-0 protocol on 'localhost':"
|
||||
" unable to connect to 'dbname='postgres' port=5432': could not connect to server: [NO SUCH FILE OR DIRECTORY]");
|
||||
|
||||
TEST_RESULT_INT(result.primaryId, 8, " check primary id");
|
||||
TEST_RESULT_INT(result.primaryIdx, 7, " check primary id");
|
||||
TEST_RESULT_BOOL(result.primary != NULL, true, " check primary");
|
||||
TEST_RESULT_STR_Z(dbArchiveMode(result.primary), "on", " dbArchiveMode");
|
||||
TEST_RESULT_STR_Z(dbArchiveCommand(result.primary), PROJECT_BIN, " dbArchiveCommand");
|
||||
TEST_RESULT_STR_Z(dbWalSwitch(result.primary), "000000010000000200000003", " wal switch");
|
||||
TEST_RESULT_INT(result.standbyId, 1, " check standby id");
|
||||
TEST_RESULT_INT(result.standbyIdx, 0, " check standby id");
|
||||
TEST_RESULT_BOOL(result.standby != NULL, true, " check standby");
|
||||
|
||||
TEST_RESULT_VOID(dbFree(result.primary), "free primary");
|
||||
|
@ -159,7 +159,7 @@ testRun(void)
|
||||
strLstAddZ(argList, "backup");
|
||||
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
TEST_RESULT_BOOL(pgIsLocal(1), true, "pg is local");
|
||||
TEST_RESULT_BOOL(pgIsLocal(0), true, "pg is local");
|
||||
TEST_RESULT_VOID(pgIsLocalVerify(), "verify pg is local");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
@ -173,7 +173,7 @@ testRun(void)
|
||||
strLstAddZ(argList, "restore");
|
||||
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
TEST_RESULT_BOOL(pgIsLocal(1), false, "pg is remote");
|
||||
TEST_RESULT_BOOL(pgIsLocal(0), false, "pg1 is remote");
|
||||
TEST_ERROR_FMT(pgIsLocalVerify(), HostInvalidError, "restore command must be run on the PostgreSQL host");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
@ -192,7 +192,7 @@ testRun(void)
|
||||
strLstAddZ(argList, CFGCMD_BACKUP ":" CONFIG_COMMAND_ROLE_LOCAL);
|
||||
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
TEST_RESULT_BOOL(pgIsLocal(7), false, "pg is remote");
|
||||
TEST_RESULT_BOOL(pgIsLocal(6), false, "pg7 is remote");
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
@ -227,7 +227,7 @@ testRun(void)
|
||||
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
TEST_RESULT_STR_Z(
|
||||
strLstJoin(protocolLocalParam(protocolStorageTypeRepo, 1, 0), "|"),
|
||||
strLstJoin(protocolLocalParam(protocolStorageTypeRepo, 0, 0), "|"),
|
||||
"--host-id=1|--log-level-console=off|--log-level-file=off|--log-level-stderr=error|--pg1-path=/path/to/pg|--process=0"
|
||||
"|--remote-type=repo|--stanza=test1|archive-get:local",
|
||||
"local repo protocol params");
|
||||
@ -243,8 +243,8 @@ testRun(void)
|
||||
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
TEST_RESULT_STR_Z(
|
||||
strLstJoin(protocolLocalParam(protocolStorageTypePg, 2, 1), "|"),
|
||||
"--host-id=2|--log-level-console=off|--log-level-file=info|--log-level-stderr=error|--log-subprocess|--pg1-path=/pg"
|
||||
strLstJoin(protocolLocalParam(protocolStorageTypePg, 0, 1), "|"),
|
||||
"--host-id=1|--log-level-console=off|--log-level-file=info|--log-level-stderr=error|--log-subprocess|--pg1-path=/pg"
|
||||
"|--process=1|--remote-type=pg|--repo1-retention-full=1|--stanza=test1|backup:local",
|
||||
"local pg protocol params");
|
||||
}
|
||||
@ -268,7 +268,7 @@ testRun(void)
|
||||
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
TEST_RESULT_STR_Z(
|
||||
strLstJoin(protocolRemoteParam(protocolStorageTypeRepo, 0, 0), "|"),
|
||||
strLstJoin(protocolRemoteParam(protocolStorageTypeRepo, 0), "|"),
|
||||
"-o|LogLevel=error|-o|Compression=no|-o|PasswordAuthentication=no|repo-host-user@repo-host"
|
||||
"|pgbackrest --log-level-console=off --log-level-file=off --log-level-stderr=error --pg1-path=/path/to/pg"
|
||||
" --process=0 --remote-type=repo --repo1-local --stanza=test1 archive-get:remote",
|
||||
@ -291,11 +291,11 @@ testRun(void)
|
||||
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
TEST_RESULT_STR_Z(
|
||||
strLstJoin(protocolRemoteParam(protocolStorageTypeRepo, 1, 0), "|"),
|
||||
strLstJoin(protocolRemoteParam(protocolStorageTypeRepo, 0), "|"),
|
||||
"-o|LogLevel=error|-o|Compression=no|-o|PasswordAuthentication=no|-p|444|repo-host-user@repo-host"
|
||||
"|pgbackrest --config=/path/pgbackrest.conf --config-include-path=/path/include --config-path=/path/config"
|
||||
" --log-level-console=off --log-level-file=info --log-level-stderr=error --log-subprocess --pg1-path=/unused"
|
||||
" --process=1 --remote-type=repo --repo1-local --stanza=test1 check:remote",
|
||||
" --process=0 --remote-type=repo --repo1-local --stanza=test1 check:remote",
|
||||
"remote protocol params with replacements");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
@ -311,7 +311,7 @@ testRun(void)
|
||||
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
TEST_RESULT_STR_Z(
|
||||
strLstJoin(protocolRemoteParam(protocolStorageTypeRepo, 66, 0), "|"),
|
||||
strLstJoin(protocolRemoteParam(protocolStorageTypeRepo, 0), "|"),
|
||||
"-o|LogLevel=error|-o|Compression=no|-o|PasswordAuthentication=no|pgbackrest@repo-host"
|
||||
"|pgbackrest --log-level-console=off --log-level-file=off --log-level-stderr=error --pg1-path=/path/to/pg"
|
||||
" --process=3 --remote-type=repo --repo1-local --stanza=test1 archive-get:remote",
|
||||
@ -328,10 +328,10 @@ testRun(void)
|
||||
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
TEST_RESULT_STR_Z(
|
||||
strLstJoin(protocolRemoteParam(protocolStorageTypePg, 1, 0), "|"),
|
||||
strLstJoin(protocolRemoteParam(protocolStorageTypePg, 0), "|"),
|
||||
"-o|LogLevel=error|-o|Compression=no|-o|PasswordAuthentication=no|postgres@pg1-host"
|
||||
"|pgbackrest --log-level-console=off --log-level-file=off --log-level-stderr=error --pg1-local"
|
||||
" --pg1-path=/path/to/1 --process=1 --remote-type=pg --stanza=test1 backup:remote",
|
||||
" --pg1-path=/path/to/1 --process=0 --remote-type=pg --stanza=test1 backup:remote",
|
||||
"remote protocol params for db backup");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
@ -351,7 +351,7 @@ testRun(void)
|
||||
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
TEST_RESULT_STR_Z(
|
||||
strLstJoin(protocolRemoteParam(protocolStorageTypePg, 1, 1), "|"),
|
||||
strLstJoin(protocolRemoteParam(protocolStorageTypePg, 1), "|"),
|
||||
"-o|LogLevel=error|-o|Compression=no|-o|PasswordAuthentication=no|postgres@pg2-host"
|
||||
"|pgbackrest --log-level-console=off --log-level-file=off --log-level-stderr=error --pg1-local"
|
||||
" --pg1-path=/path/to/2 --process=4 --remote-type=pg --stanza=test1 backup:remote",
|
||||
@ -374,7 +374,7 @@ testRun(void)
|
||||
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
TEST_RESULT_STR_Z(
|
||||
strLstJoin(protocolRemoteParam(protocolStorageTypePg, 1, 2), "|"),
|
||||
strLstJoin(protocolRemoteParam(protocolStorageTypePg, 2), "|"),
|
||||
"-o|LogLevel=error|-o|Compression=no|-o|PasswordAuthentication=no|postgres@pg3-host"
|
||||
"|pgbackrest --log-level-console=off --log-level-file=off --log-level-stderr=error --pg1-local"
|
||||
" --pg1-path=/path/to/3 --pg1-port=3333 --pg1-socket-path=/socket3 --process=4 --remote-type=pg --stanza=test1"
|
||||
@ -953,8 +953,8 @@ testRun(void)
|
||||
|
||||
TEST_RESULT_VOID(protocolFree(), "free protocol objects before anything has been created");
|
||||
|
||||
TEST_ASSIGN(client, protocolRemoteGet(protocolStorageTypeRepo, 1), "get remote protocol");
|
||||
TEST_RESULT_PTR(protocolRemoteGet(protocolStorageTypeRepo, 1), client, "get remote cached protocol");
|
||||
TEST_ASSIGN(client, protocolRemoteGet(protocolStorageTypeRepo, 0), "get remote protocol");
|
||||
TEST_RESULT_PTR(protocolRemoteGet(protocolStorageTypeRepo, 0), client, "get remote cached protocol");
|
||||
TEST_RESULT_PTR(protocolHelper.clientRemote[0].client, client, "check position in cache");
|
||||
TEST_RESULT_VOID(protocolKeepAlive(), "keep alive");
|
||||
TEST_RESULT_VOID(protocolFree(), "free remote protocol objects");
|
||||
@ -983,7 +983,7 @@ testRun(void)
|
||||
harnessCfgLoadRole(cfgCmdArchiveGet, cfgCmdRoleLocal, argList);
|
||||
|
||||
TEST_RESULT_STR_Z(cfgOptionStr(cfgOptRepoCipherPass), "acbd", "check cipher pass before");
|
||||
TEST_ASSIGN(client, protocolRemoteGet(protocolStorageTypeRepo, 1), "get remote protocol");
|
||||
TEST_ASSIGN(client, protocolRemoteGet(protocolStorageTypeRepo, 0), "get remote protocol");
|
||||
TEST_RESULT_PTR(protocolHelper.clientRemote[0].client, client, "check position in cache");
|
||||
TEST_RESULT_STR_Z(cfgOptionStr(cfgOptRepoCipherPass), "acbd", "check cipher pass after");
|
||||
|
||||
@ -1008,7 +1008,7 @@ testRun(void)
|
||||
harnessCfgLoad(cfgCmdInfo, argList);
|
||||
|
||||
TEST_RESULT_PTR(cfgOptionStrNull(cfgOptRepoCipherPass), NULL, "check cipher pass before");
|
||||
TEST_ASSIGN(client, protocolRemoteGet(protocolStorageTypeRepo, 1), "get remote protocol");
|
||||
TEST_ASSIGN(client, protocolRemoteGet(protocolStorageTypeRepo, 0), "get remote protocol");
|
||||
TEST_RESULT_STR_Z(cfgOptionStr(cfgOptRepoCipherPass), "dcba", "check cipher pass after");
|
||||
|
||||
TEST_RESULT_VOID(protocolFree(), "free remote protocol objects");
|
||||
@ -1024,7 +1024,9 @@ testRun(void)
|
||||
strLstAdd(argList, strNewFmt("--pg1-path=%s", testPath()));
|
||||
harnessCfgLoad(cfgCmdBackup, argList);
|
||||
|
||||
TEST_ASSIGN(client, protocolRemoteGet(protocolStorageTypePg, 1), "get remote protocol");
|
||||
TEST_ASSIGN(client, protocolRemoteGet(protocolStorageTypePg, 0), "get remote protocol");
|
||||
|
||||
TEST_RESULT_VOID(protocolFree(), "free local and remote protocol objects");
|
||||
|
||||
// Start local protocol
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
@ -1035,8 +1037,8 @@ testRun(void)
|
||||
strLstAddZ(argList, "--process-max=2");
|
||||
harnessCfgLoad(cfgCmdArchiveGet, argList);
|
||||
|
||||
TEST_ASSIGN(client, protocolLocalGet(protocolStorageTypeRepo, 1, 1), "get local protocol");
|
||||
TEST_RESULT_PTR(protocolLocalGet(protocolStorageTypeRepo, 1, 1), client, "get local cached protocol");
|
||||
TEST_ASSIGN(client, protocolLocalGet(protocolStorageTypeRepo, 0, 1), "get local protocol");
|
||||
TEST_RESULT_PTR(protocolLocalGet(protocolStorageTypeRepo, 0, 1), client, "get local cached protocol");
|
||||
TEST_RESULT_PTR(protocolHelper.clientLocal[0].client, client, "check location in cache");
|
||||
|
||||
TEST_RESULT_VOID(protocolFree(), "free local and remote protocol objects");
|
||||
|
@ -68,7 +68,7 @@ testRun(void)
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("writable storage fails when dry-run is not initialized");
|
||||
|
||||
TEST_ERROR(storagePgIdWrite(1), AssertError, WRITABLE_WHILE_DRYRUN);
|
||||
TEST_ERROR(storagePgIdxWrite(0), AssertError, WRITABLE_WHILE_DRYRUN);
|
||||
TEST_ERROR(storageRepoWrite(), AssertError, WRITABLE_WHILE_DRYRUN);
|
||||
TEST_ERROR(storageSpoolWrite(), AssertError, WRITABLE_WHILE_DRYRUN);
|
||||
|
||||
@ -77,7 +77,7 @@ testRun(void)
|
||||
|
||||
storageHelperDryRunInit(true);
|
||||
|
||||
TEST_ERROR(storagePgIdWrite(1), AssertError, WRITABLE_WHILE_DRYRUN);
|
||||
TEST_ERROR(storagePgIdxWrite(0), AssertError, WRITABLE_WHILE_DRYRUN);
|
||||
TEST_ERROR(storageRepoWrite(), AssertError, WRITABLE_WHILE_DRYRUN);
|
||||
TEST_ERROR(storageSpoolWrite(), AssertError, WRITABLE_WHILE_DRYRUN);
|
||||
}
|
||||
@ -1282,24 +1282,17 @@ testRun(void)
|
||||
|
||||
TEST_RESULT_STR(storage->path, strNewFmt("%s/db", testPath()), "check pg storage path");
|
||||
TEST_RESULT_BOOL(storage->write, false, "check pg storage write");
|
||||
TEST_RESULT_STR(storagePgId(2)->path, strNewFmt("%s/db2", testPath()), "check pg 2 storage path");
|
||||
TEST_RESULT_STR(storagePgIdx(1)->path, strNewFmt("%s/db2", testPath()), "check pg 2 storage path");
|
||||
|
||||
TEST_RESULT_PTR(storageHelper.storagePgWrite, NULL, "pg write storage not cached");
|
||||
TEST_ASSIGN(storage, storagePgWrite(), "new pg write storage");
|
||||
TEST_RESULT_PTR(storageHelper.storagePgWrite[0], storage, "pg write storage cached");
|
||||
TEST_RESULT_PTR(storagePgWrite(), storage, "get cached pg write storage");
|
||||
TEST_RESULT_STR(storagePgIdWrite(2)->path, strNewFmt("%s/db2", testPath()), "check pg 2 write storage path");
|
||||
TEST_RESULT_STR(storagePgIdxWrite(1)->path, strNewFmt("%s/db2", testPath()), "check pg 2 write storage path");
|
||||
|
||||
TEST_RESULT_STR(storage->path, strNewFmt("%s/db", testPath()), "check pg write storage path");
|
||||
TEST_RESULT_BOOL(storage->write, true, "check pg write storage write");
|
||||
|
||||
// Pg storage from another host id
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
cfgOptionSet(cfgOptHostId, cfgSourceParam, VARUINT64(2));
|
||||
cfgOptionValidSet(cfgOptHostId, true);
|
||||
|
||||
TEST_RESULT_STR(storagePg()->path, strNewFmt("%s/db2", testPath()), "check pg-2 storage path");
|
||||
|
||||
// Change the stanza to NULL, stanzaInit flag to false and make sure helper fails because stanza is required
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
storageHelper.storageSpool = NULL;
|
||||
|
Reference in New Issue
Block a user