You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2026-10-23 21:28:56 +03:00
Remove unused function parameters.
Each of these was left behind when the code that used it was changed or removed. The compiler does not report them because the FUNCTION_LOG_PARAM*() macros count as a use. * backupFilePut() backupData: never used, present since1f2ce45eadded the function. * backupJobResult() bundle: decided whether the job key held a bundle id.efc09db7replaced that with a check on the key variant type. * restoreRecoveryWriteConf() manifest: found the pgdata path to get the owner for chown().3ff88ffbremoved the chown(). * restoreRecoveryWriteAutoConf() manifest: read backupOptionOnline to decide whether to write recovery.signal.9cceed6areplaced that condition. * exitSafe() signalType: built the "terminated on signal [SIGxxx]" message for command end.e13c4629moved that logging into the signal handler. * cmdEnd() code: selected the "completed successfully" message at command end.6361a061switched the test to errorMessage == NULL. * infoPgSet() type: set the catalog/control versions and validated the type.0a96764cremoved both.77c721ebrestored the catalog version logic using this->type, which the object already stores from infoPgNew(), so the parameter stayed unused. * walSegmentNext() pgVersion: skipped the FF segment for PostgreSQL < 9.3.77c721ebremoved that along with support for 9.0/9.1/9.2. walSegmentRange() and queueNeed() passed pgVersion only to reach walSegmentNext(), so remove it from those as well. * tlsSessionResultProcess() errorSys: passed errno to THROW_SYS_ERROR_CODE() for syscall errors.08242ee6removed that throw. The errno read there was not informative (usually 0), and the capture in tlsSessionResult() goes with it. * storageWriteSftpNew() user, group, timeModified, truncate: passed to the write interface initializer.a953aa74replaced the per-driver interface with a shared static, so the driver stopped passing them. storageSftpNewWrite() is the only caller and asserts that user and group are NULL, timeModified is 0, and truncate is true, so the values were fixed. Also remove the common/user.h include from the SFTP write driver, unused since87087facadded it.
This commit is contained in:
@@ -350,12 +350,11 @@ walIsSegment(const String *const walSegment)
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
FN_EXTERN String *
|
||||
walSegmentNext(const String *const walSegment, const size_t walSegmentSize, const unsigned int pgVersion)
|
||||
walSegmentNext(const String *const walSegment, const size_t walSegmentSize)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STRING, walSegment);
|
||||
FUNCTION_LOG_PARAM(SIZE, walSegmentSize);
|
||||
FUNCTION_LOG_PARAM(UINT, pgVersion);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(walSegment != NULL);
|
||||
@@ -389,13 +388,11 @@ walSegmentNext(const String *const walSegment, const size_t walSegmentSize, cons
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
FN_EXTERN StringList *
|
||||
walSegmentRange(
|
||||
const String *const walSegmentBegin, const size_t walSegmentSize, const unsigned int pgVersion, const unsigned int range)
|
||||
walSegmentRange(const String *const walSegmentBegin, const size_t walSegmentSize, const unsigned int range)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STRING, walSegmentBegin);
|
||||
FUNCTION_LOG_PARAM(SIZE, walSegmentSize);
|
||||
FUNCTION_LOG_PARAM(UINT, pgVersion);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(range > 0);
|
||||
@@ -412,7 +409,7 @@ walSegmentRange(
|
||||
|
||||
for (unsigned int rangeIdx = 0; rangeIdx < range - 1; rangeIdx++)
|
||||
{
|
||||
String *const next = walSegmentNext(current, walSegmentSize, pgVersion);
|
||||
String *const next = walSegmentNext(current, walSegmentSize);
|
||||
|
||||
strLstAdd(result, next);
|
||||
|
||||
|
||||
@@ -92,10 +92,9 @@ FN_EXTERN bool walIsSegment(const String *walSegment);
|
||||
FN_EXTERN String *walPath(const String *walFile, const String *pgPath, const String *command);
|
||||
|
||||
// Get the next WAL segment given a WAL segment and WAL segment size
|
||||
FN_EXTERN String *walSegmentNext(const String *walSegment, size_t walSegmentSize, unsigned int pgVersion);
|
||||
FN_EXTERN String *walSegmentNext(const String *walSegment, size_t walSegmentSize);
|
||||
|
||||
// Build a list of WAL segments based on a beginning WAL and number of WAL in the range (inclusive)
|
||||
FN_EXTERN StringList *walSegmentRange(
|
||||
const String *walSegmentBegin, size_t walSegmentSize, unsigned int pgVersion, unsigned int range);
|
||||
FN_EXTERN StringList *walSegmentRange(const String *walSegmentBegin, size_t walSegmentSize, unsigned int range);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -532,16 +532,13 @@ archiveGetCheck(const StringList *const archiveRequestList)
|
||||
Clean the queue and prepare a list of WAL segments that the async process should get
|
||||
***********************************************************************************************************************************/
|
||||
static StringList *
|
||||
queueNeed(
|
||||
const String *const walSegment, const bool found, const uint64_t queueSize, const size_t walSegmentSize,
|
||||
const unsigned int pgVersion)
|
||||
queueNeed(const String *const walSegment, const bool found, const uint64_t queueSize, const size_t walSegmentSize)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STRING, walSegment);
|
||||
FUNCTION_LOG_PARAM(BOOL, found);
|
||||
FUNCTION_LOG_PARAM(UINT64, queueSize);
|
||||
FUNCTION_LOG_PARAM(SIZE, walSegmentSize);
|
||||
FUNCTION_LOG_PARAM(UINT, pgVersion);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(walSegment != NULL);
|
||||
@@ -553,7 +550,7 @@ queueNeed(
|
||||
// Determine the first WAL segment for the async process to get. If the WAL segment requested by PostgreSQL was not found
|
||||
// then use that. If the segment was found but the queue is not full then start with the next segment.
|
||||
const String *const walSegmentFirst =
|
||||
found ? walSegmentNext(walSegment, walSegmentSize, pgVersion) : walSegment;
|
||||
found ? walSegmentNext(walSegment, walSegmentSize) : walSegment;
|
||||
|
||||
// Determine how many WAL segments should be in the queue. The queue total must be at least 2 or it doesn't make sense to
|
||||
// have async turned on at all.
|
||||
@@ -564,7 +561,7 @@ queueNeed(
|
||||
|
||||
// Build the ideal queue -- the WAL segments we want in the queue after the async process has run
|
||||
const StringList *const idealQueue = strLstSort(
|
||||
walSegmentRange(walSegmentFirst, walSegmentSize, pgVersion, walSegmentQueueTotal), sortOrderAsc);
|
||||
walSegmentRange(walSegmentFirst, walSegmentSize, walSegmentQueueTotal), sortOrderAsc);
|
||||
|
||||
// Get the list of files actually in the queue
|
||||
const StringList *const actualQueue = strLstSort(
|
||||
@@ -812,8 +809,7 @@ cmdArchiveGet(void)
|
||||
// Clean the current queue using the list of WAL that we ideally want in the queue. queueNeed() will return the
|
||||
// list of WAL needed to fill the queue and this will be passed to the async process.
|
||||
const StringList *const queue = queueNeed(
|
||||
walSegment, found, cfgOptionUInt64(cfgOptArchiveGetQueueMax), pgControl.walSegmentSize,
|
||||
pgControl.version);
|
||||
walSegment, found, cfgOptionUInt64(cfgOptArchiveGetQueueMax), pgControl.walSegmentSize);
|
||||
|
||||
for (unsigned int queueIdx = 0; queueIdx < strLstSize(queue); queueIdx++)
|
||||
strLstAdd(commandExec, strLstGet(queue, queueIdx));
|
||||
|
||||
@@ -178,11 +178,9 @@ Stop the backup
|
||||
// Helper to write a file from a string to the repository and update the manifest
|
||||
static void
|
||||
backupFilePut(
|
||||
const BackupData *const backupData, Manifest *const manifest, const String *const name, const time_t timestamp,
|
||||
const String *const content)
|
||||
Manifest *const manifest, const String *const name, const time_t timestamp, const String *const content)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(BACKUP_DATA, backupData);
|
||||
FUNCTION_LOG_PARAM(MANIFEST, manifest);
|
||||
FUNCTION_LOG_PARAM(STRING, name);
|
||||
FUNCTION_LOG_PARAM(TIME, timestamp);
|
||||
@@ -310,8 +308,8 @@ backupStop(BackupData *const backupData, Manifest *const manifest)
|
||||
LOG_INFO_FMT("backup stop archive = %s, lsn = %s", strZ(result.walSegmentName), strZ(result.lsn));
|
||||
|
||||
// Save files returned by stop backup
|
||||
backupFilePut(backupData, manifest, STRDEF(PG_FILE_BACKUPLABEL), result.timestamp, dbBackupStopResult.backupLabel);
|
||||
backupFilePut(backupData, manifest, STRDEF(PG_FILE_TABLESPACEMAP), result.timestamp, dbBackupStopResult.tablespaceMap);
|
||||
backupFilePut(manifest, STRDEF(PG_FILE_BACKUPLABEL), result.timestamp, dbBackupStopResult.backupLabel);
|
||||
backupFilePut(manifest, STRDEF(PG_FILE_TABLESPACEMAP), result.timestamp, dbBackupStopResult.tablespaceMap);
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ Log the results of a job and throw errors
|
||||
static void
|
||||
backupJobResult(
|
||||
Manifest *const manifest, const String *const host, const Storage *const storagePg, StringList *const fileRemove,
|
||||
ProtocolParallelJob *const job, const bool bundle, const PgPageSize pageSize, const uint64_t sizeTotal,
|
||||
ProtocolParallelJob *const job, const PgPageSize pageSize, const uint64_t sizeTotal,
|
||||
uint64_t *const sizeProgress, unsigned int *const currentPercentComplete)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
@@ -109,7 +109,6 @@ backupJobResult(
|
||||
FUNCTION_LOG_PARAM(STORAGE, storagePg);
|
||||
FUNCTION_LOG_PARAM(STRING_LIST, fileRemove);
|
||||
FUNCTION_LOG_PARAM(PROTOCOL_PARALLEL_JOB, job);
|
||||
FUNCTION_LOG_PARAM(BOOL, bundle);
|
||||
FUNCTION_LOG_PARAM(ENUM, pageSize);
|
||||
FUNCTION_LOG_PARAM(UINT64, sizeTotal);
|
||||
FUNCTION_LOG_PARAM_P(UINT64, sizeProgress);
|
||||
@@ -914,7 +913,7 @@ backupProcess(const BackupData *const backupData, Manifest *const manifest, cons
|
||||
manifest,
|
||||
backupStandby && protocolParallelJobProcessId(job) > 1 ? backupData->hostStandby : backupData->hostPrimary,
|
||||
protocolParallelJobProcessId(job) > 1 ? storagePgIdx(pgIdx) : backupData->storagePrimary,
|
||||
fileRemove, job, jobData.bundle, jobData.pageSize, sizeTotal, &sizeProgress, ¤tPercentComplete);
|
||||
fileRemove, job, jobData.pageSize, sizeTotal, &sizeProgress, ¤tPercentComplete);
|
||||
}
|
||||
|
||||
// A keep-alive is required here for the remote holding open the backup connection
|
||||
|
||||
@@ -196,10 +196,9 @@ cmdBegin(void)
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
FN_EXTERN void
|
||||
cmdEnd(const int code, const String *const errorMessage)
|
||||
cmdEnd(const String *const errorMessage)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(INT, code);
|
||||
FUNCTION_LOG_PARAM(STRING, errorMessage);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ FN_EXTERN void cmdBegin(void);
|
||||
FN_EXTERN const String *cmdOption(void);
|
||||
|
||||
// End the command
|
||||
FN_EXTERN void cmdEnd(int code, const String *errorMessage);
|
||||
FN_EXTERN void cmdEnd(const String *errorMessage);
|
||||
|
||||
// Execute an async process. This function will only return in the calling process and the implementation is platform dependent.
|
||||
FN_EXTERN void cmdAsyncExec(const char *command, const StringList *commandExec);
|
||||
|
||||
@@ -123,12 +123,11 @@ exitErrorDetail(void)
|
||||
}
|
||||
|
||||
FN_EXTERN int
|
||||
exitSafe(int result, const bool error, const SignalType signalType)
|
||||
exitSafe(int result, const bool error)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(INT, result);
|
||||
FUNCTION_LOG_PARAM(BOOL, error);
|
||||
FUNCTION_LOG_PARAM(ENUM, signalType);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
// Report error if one was thrown
|
||||
@@ -163,7 +162,7 @@ exitSafe(int result, const bool error, const SignalType signalType)
|
||||
if (result != 0 && error)
|
||||
errorMessage = strNewFmt("aborted with exception [%03d]", result);
|
||||
|
||||
cmdEnd(result, errorMessage);
|
||||
cmdEnd(errorMessage);
|
||||
strFree(errorMessage);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,6 @@ Functions
|
||||
FN_EXTERN void exitInit(void);
|
||||
|
||||
// Do cleanup and return result code
|
||||
FN_EXTERN int exitSafe(int result, bool error, SignalType signalType);
|
||||
FN_EXTERN int exitSafe(int result, bool error);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -201,12 +201,9 @@ restoreRecoveryConf(const unsigned int pgVersion, const String *const restoreLab
|
||||
|
||||
// Helper to write recovery options into recovery.conf
|
||||
static void
|
||||
restoreRecoveryWriteConf(
|
||||
const Manifest *const manifest, const StorageInfo *const fileInfo, const unsigned int pgVersion,
|
||||
const String *const restoreLabel)
|
||||
restoreRecoveryWriteConf(const StorageInfo *const fileInfo, const unsigned int pgVersion, const String *const restoreLabel)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(MANIFEST, manifest);
|
||||
FUNCTION_LOG_PARAM(STORAGE_INFO, fileInfo);
|
||||
FUNCTION_LOG_PARAM(UINT, pgVersion);
|
||||
FUNCTION_LOG_PARAM(STRING, restoreLabel);
|
||||
@@ -234,12 +231,9 @@ restoreRecoveryWriteConf(
|
||||
|
||||
// Helper to write recovery options into postgresql.auto.conf
|
||||
static void
|
||||
restoreRecoveryWriteAutoConf(
|
||||
const Manifest *const manifest, const StorageInfo *const fileInfo, const unsigned int pgVersion,
|
||||
const String *const restoreLabel)
|
||||
restoreRecoveryWriteAutoConf(const StorageInfo *const fileInfo, const unsigned int pgVersion, const String *const restoreLabel)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(MANIFEST, manifest);
|
||||
FUNCTION_LOG_PARAM(STORAGE_INFO, fileInfo);
|
||||
FUNCTION_LOG_PARAM(UINT, pgVersion);
|
||||
FUNCTION_LOG_PARAM(STRING, restoreLabel);
|
||||
@@ -400,9 +394,9 @@ restoreRecoveryWrite(const Manifest *const manifest, const StorageInfo *const fi
|
||||
|
||||
// Write recovery file based on PostgreSQL version
|
||||
if (pgVersion >= PG_VERSION_RECOVERY_GUC)
|
||||
restoreRecoveryWriteAutoConf(manifest, fileInfo, pgVersion, restoreLabel);
|
||||
restoreRecoveryWriteAutoConf(fileInfo, pgVersion, restoreLabel);
|
||||
else
|
||||
restoreRecoveryWriteConf(manifest, fileInfo, pgVersion, restoreLabel);
|
||||
restoreRecoveryWriteConf(fileInfo, pgVersion, restoreLabel);
|
||||
}
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
@@ -597,7 +597,7 @@ verifyCreateArchiveIdRange(
|
||||
// Initialize the range if it has not yet been initialized and continue to next
|
||||
if (walRange == NULL ||
|
||||
!strEq(
|
||||
walSegmentNext(walRange->stop, (size_t)archiveIdResult->pgWalInfo.size, archiveIdResult->pgWalInfo.version),
|
||||
walSegmentNext(walRange->stop, (size_t)archiveIdResult->pgWalInfo.size),
|
||||
walSegment))
|
||||
{
|
||||
// Add the initialized wal range to the range list
|
||||
|
||||
@@ -110,13 +110,12 @@ Returns:
|
||||
// Helper to process error conditions
|
||||
static int
|
||||
tlsSessionResultProcess(
|
||||
TlsSession *const this, const int errorTls, const long unsigned int errorTlsDetail, const int errorSys, const bool closeOk)
|
||||
TlsSession *const this, const int errorTls, const long unsigned int errorTlsDetail, const bool closeOk)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(TLS_SESSION, this);
|
||||
FUNCTION_LOG_PARAM(INT, errorTls);
|
||||
FUNCTION_LOG_PARAM(UINT64, errorTlsDetail);
|
||||
FUNCTION_LOG_PARAM(INT, errorSys);
|
||||
FUNCTION_LOG_PARAM(BOOL, closeOk);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
@@ -184,12 +183,11 @@ tlsSessionResult(TlsSession *const this, int result, const bool closeOk)
|
||||
// Process errors
|
||||
if (result <= 0)
|
||||
{
|
||||
// Get TLS error and store errno in case of syscall error
|
||||
// Get TLS error
|
||||
const int errorTls = SSL_get_error(this->session, result);
|
||||
const long unsigned int errorTlsDetail = ERR_get_error();
|
||||
const int errorSys = errno;
|
||||
|
||||
result = tlsSessionResultProcess(this, errorTls, errorTlsDetail, errorSys, closeOk);
|
||||
result = tlsSessionResultProcess(this, errorTls, errorTlsDetail, closeOk);
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN(INT, result);
|
||||
|
||||
@@ -197,7 +197,7 @@ infoArchivePgSet(InfoArchive *const this, const unsigned int pgVersion, const ui
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
this->pub.infoPg = infoPgSet(infoArchivePg(this), infoPgArchive, pgVersion, pgSystemId, 0);
|
||||
this->pub.infoPg = infoPgSet(infoArchivePg(this), pgVersion, pgSystemId, 0);
|
||||
|
||||
FUNCTION_LOG_RETURN(INFO_ARCHIVE, this);
|
||||
}
|
||||
|
||||
@@ -384,7 +384,7 @@ infoBackupPgSet(
|
||||
FUNCTION_LOG_PARAM(UINT, pgCatalogVersion);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
this->pub.infoPg = infoPgSet(infoBackupPg(this), infoPgBackup, pgVersion, pgSystemId, pgCatalogVersion);
|
||||
this->pub.infoPg = infoPgSet(infoBackupPg(this), pgVersion, pgSystemId, pgCatalogVersion);
|
||||
this->pub.updated = true;
|
||||
|
||||
FUNCTION_LOG_RETURN(INFO_BACKUP, this);
|
||||
|
||||
@@ -227,13 +227,10 @@ infoPgAdd(InfoPg *const this, const InfoPgData *const infoPgData)
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
FN_EXTERN InfoPg *
|
||||
infoPgSet(
|
||||
InfoPg *const this, const InfoPgType type, const unsigned int pgVersion, const uint64_t pgSystemId,
|
||||
const unsigned int pgCatalogVersion)
|
||||
infoPgSet(InfoPg *const this, const unsigned int pgVersion, const uint64_t pgSystemId, const unsigned int pgCatalogVersion)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(INFO_PG, this);
|
||||
FUNCTION_LOG_PARAM(STRING_ID, type);
|
||||
FUNCTION_LOG_PARAM(UINT, pgVersion);
|
||||
FUNCTION_LOG_PARAM(UINT64, pgSystemId);
|
||||
FUNCTION_LOG_PARAM(UINT, pgCatalogVersion);
|
||||
|
||||
@@ -109,7 +109,7 @@ FN_EXTERN void infoPgSave(InfoPg *this, IoWrite *write, InfoSaveCallback *callba
|
||||
|
||||
// Set the InfoPg object data based on values passed
|
||||
FN_EXTERN InfoPg *infoPgSet(
|
||||
InfoPg *this, InfoPgType type, const unsigned int pgVersion, const uint64_t pgSystemId, const unsigned int pgCatalogVersion);
|
||||
InfoPg *this, const unsigned int pgVersion, const uint64_t pgSystemId, const unsigned int pgCatalogVersion);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
|
||||
@@ -148,7 +148,7 @@ main(int argListSize, const char *argList[])
|
||||
if (cfgOptionBool(cfgOptExpireAuto))
|
||||
{
|
||||
// Switch to expire command
|
||||
cmdEnd(0, NULL);
|
||||
cmdEnd(NULL);
|
||||
cfgCommandSet(cfgCmdExpire, cfgCmdRoleMain);
|
||||
cfgLoadLogFile();
|
||||
cmdBegin();
|
||||
@@ -288,12 +288,12 @@ main(int argListSize, const char *argList[])
|
||||
CATCH_FATAL()
|
||||
{
|
||||
error = true;
|
||||
result = exitSafe(result, true, 0);
|
||||
result = exitSafe(result, true);
|
||||
}
|
||||
TRY_END();
|
||||
|
||||
// Free protocol objects
|
||||
protocolFree();
|
||||
|
||||
FUNCTION_LOG_RETURN(INT, error ? result : exitSafe(result, false, 0));
|
||||
FUNCTION_LOG_RETURN(INT, error ? result : exitSafe(result, false));
|
||||
}
|
||||
|
||||
@@ -955,8 +955,7 @@ storageSftpNewWrite(THIS_VOID, const String *const file, const StorageInterfaceN
|
||||
FUNCTION_LOG_RETURN(
|
||||
STORAGE_WRITE_SFTP,
|
||||
storageWriteSftpNew(
|
||||
this, file, param.modeFile, param.modePath, param.user, param.group, param.timeModified, param.createPath,
|
||||
param.syncFile, param.atomic, param.truncate));
|
||||
this, file, param.modeFile, param.modePath, param.createPath, param.syncFile, param.atomic));
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
|
||||
@@ -7,7 +7,6 @@ SFTP Storage File Write
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/log.h"
|
||||
#include "common/user.h"
|
||||
#include "storage/sftp/write.h"
|
||||
#include "storage/write.h"
|
||||
|
||||
@@ -342,22 +341,17 @@ static const StorageWriteInterface storageWriteSftpInterface =
|
||||
|
||||
FN_EXTERN StorageWriteSftp *
|
||||
storageWriteSftpNew(
|
||||
StorageSftp *const storage, const String *const name, const mode_t modeFile, const mode_t modePath, const String *const user,
|
||||
const String *const group, const time_t timeModified, const bool createPath, const bool syncFile, const bool atomic,
|
||||
const bool truncate)
|
||||
StorageSftp *const storage, const String *const name, const mode_t modeFile, const mode_t modePath, const bool createPath,
|
||||
const bool syncFile, const bool atomic)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(STORAGE_SFTP, storage);
|
||||
FUNCTION_LOG_PARAM(STRING, name);
|
||||
FUNCTION_LOG_PARAM(MODE, modeFile);
|
||||
FUNCTION_LOG_PARAM(MODE, modePath);
|
||||
FUNCTION_LOG_PARAM(STRING, user);
|
||||
FUNCTION_LOG_PARAM(STRING, group);
|
||||
FUNCTION_LOG_PARAM(TIME, timeModified);
|
||||
FUNCTION_LOG_PARAM(BOOL, createPath);
|
||||
FUNCTION_LOG_PARAM(BOOL, syncFile);
|
||||
FUNCTION_LOG_PARAM(BOOL, atomic);
|
||||
FUNCTION_LOG_PARAM(BOOL, truncate);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(storage != NULL);
|
||||
|
||||
@@ -17,8 +17,7 @@ typedef struct StorageWriteSftp StorageWriteSftp;
|
||||
Constructors
|
||||
***********************************************************************************************************************************/
|
||||
FN_EXTERN StorageWriteSftp *storageWriteSftpNew(
|
||||
StorageSftp *storage, const String *name, mode_t modeFile, mode_t modePath, const String *user, const String *group,
|
||||
time_t timeModified, bool createPath, bool syncFile, bool atomic, bool truncate);
|
||||
StorageSftp *storage, const String *name, mode_t modeFile, mode_t modePath, bool createPath, bool syncFile, bool atomic);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
|
||||
@@ -399,23 +399,23 @@ testRun(void)
|
||||
TEST_TITLE("beginning and end range");
|
||||
|
||||
TEST_RESULT_STR_Z(
|
||||
walSegmentNext(STRDEF("000000010000000100000001"), 16 * 1024 * 1024, PG_VERSION_10), "000000010000000100000002",
|
||||
walSegmentNext(STRDEF("000000010000000100000001"), 16 * 1024 * 1024), "000000010000000100000002",
|
||||
"get next");
|
||||
TEST_RESULT_STR_Z(
|
||||
walSegmentNext(STRDEF("0000000100000001000000FE"), 16 * 1024 * 1024, PG_VERSION_18), "0000000100000001000000FF",
|
||||
walSegmentNext(STRDEF("0000000100000001000000FE"), 16 * 1024 * 1024), "0000000100000001000000FF",
|
||||
"get next");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("check overflow by version");
|
||||
|
||||
TEST_RESULT_STR_Z(
|
||||
walSegmentNext(STRDEF("0000009900000001000000FF"), 16 * 1024 * 1024, PG_VERSION_10), "000000990000000200000000",
|
||||
walSegmentNext(STRDEF("0000009900000001000000FF"), 16 * 1024 * 1024), "000000990000000200000000",
|
||||
"get next overflow <= 10");
|
||||
TEST_RESULT_STR_Z(
|
||||
walSegmentNext(STRDEF("000000010000000100000003"), 1024 * 1024 * 1024, PG_VERSION_11), "000000010000000200000000",
|
||||
walSegmentNext(STRDEF("000000010000000100000003"), 1024 * 1024 * 1024), "000000010000000200000000",
|
||||
"get next overflow >= 11/1GB");
|
||||
TEST_RESULT_STR_Z(
|
||||
walSegmentNext(STRDEF("000000010000006700000FFF"), 1024 * 1024, PG_VERSION_11), "000000010000006800000000",
|
||||
walSegmentNext(STRDEF("000000010000006700000FFF"), 1024 * 1024), "000000010000006800000000",
|
||||
"get next overflow >= 11/1MB");
|
||||
}
|
||||
|
||||
@@ -426,23 +426,23 @@ testRun(void)
|
||||
TEST_TITLE("single segment");
|
||||
|
||||
TEST_RESULT_STRLST_Z(
|
||||
walSegmentRange(STRDEF("000000010000000100000000"), 16 * 1024 * 1024, PG_VERSION_10, 1), "000000010000000100000000\n",
|
||||
walSegmentRange(STRDEF("000000010000000100000000"), 16 * 1024 * 1024, 1), "000000010000000100000000\n",
|
||||
"get single");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("check range by version");
|
||||
|
||||
TEST_RESULT_STRLST_Z(
|
||||
walSegmentRange(STRDEF("0000000100000001000000FD"), 16 * 1024 * 1024, PG_VERSION_10, 4),
|
||||
walSegmentRange(STRDEF("0000000100000001000000FD"), 16 * 1024 * 1024, 4),
|
||||
"0000000100000001000000FD\n0000000100000001000000FE\n0000000100000001000000FF\n000000010000000200000000\n",
|
||||
"get range <= 10");
|
||||
TEST_RESULT_STRLST_Z(
|
||||
walSegmentRange(STRDEF("000000080000000A00000000"), 1024 * 1024 * 1024, PG_VERSION_11, 8),
|
||||
walSegmentRange(STRDEF("000000080000000A00000000"), 1024 * 1024 * 1024, 8),
|
||||
"000000080000000A00000000\n000000080000000A00000001\n000000080000000A00000002\n000000080000000A00000003\n"
|
||||
"000000080000000B00000000\n000000080000000B00000001\n000000080000000B00000002\n000000080000000B00000003\n",
|
||||
"get range >= 11/1GB");
|
||||
TEST_RESULT_STRLST_Z(
|
||||
walSegmentRange(STRDEF("000000070000000700000FFE"), 1024 * 1024, PG_VERSION_11, 4),
|
||||
walSegmentRange(STRDEF("000000070000000700000FFE"), 1024 * 1024, 4),
|
||||
"000000070000000700000FFE\n000000070000000700000FFF\n000000070000000800000000\n000000070000000800000001\n",
|
||||
"get range >= 11/1MB");
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ testRun(void)
|
||||
TEST_TITLE("path missing");
|
||||
|
||||
TEST_ERROR(
|
||||
queueNeed(STRDEF("000000010000000100000001"), false, queueSize, walSegmentSize, PG_VERSION_18),
|
||||
queueNeed(STRDEF("000000010000000100000001"), false, queueSize, walSegmentSize),
|
||||
PathMissingError, "unable to list file info for missing path '" TEST_PATH "/spool/archive/test1/in'");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -45,7 +45,7 @@ testRun(void)
|
||||
HRN_STORAGE_PATH_CREATE(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN);
|
||||
|
||||
TEST_RESULT_STRLST_Z(
|
||||
queueNeed(STRDEF("000000010000000100000001"), false, queueSize, walSegmentSize, PG_VERSION_18),
|
||||
queueNeed(STRDEF("000000010000000100000001"), false, queueSize, walSegmentSize),
|
||||
"000000010000000100000001\n000000010000000100000002\n", "queue size smaller than min");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -54,7 +54,7 @@ testRun(void)
|
||||
queueSize = (16 * 1024 * 1024) * 3;
|
||||
|
||||
TEST_RESULT_STRLST_Z(
|
||||
queueNeed(STRDEF("000000010000000100000001"), false, queueSize, walSegmentSize, PG_VERSION_18),
|
||||
queueNeed(STRDEF("000000010000000100000001"), false, queueSize, walSegmentSize),
|
||||
"000000010000000100000001\n000000010000000100000002\n000000010000000100000003\n", "empty queue");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -83,7 +83,7 @@ testRun(void)
|
||||
HRN_STORAGE_PUT_EMPTY(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN "/000000010000000B00000000.ok");
|
||||
|
||||
TEST_RESULT_STRLST_Z(
|
||||
queueNeed(STRDEF("000000010000000A00000FFD"), true, queueSize, walSegmentSize, PG_VERSION_11),
|
||||
queueNeed(STRDEF("000000010000000A00000FFD"), true, queueSize, walSegmentSize),
|
||||
"000000010000000B00000000\n000000010000000B00000001\n000000010000000B00000002\n", "queue has wal");
|
||||
|
||||
TEST_STORAGE_LIST(
|
||||
|
||||
@@ -1855,7 +1855,7 @@ testRun(void)
|
||||
|
||||
TEST_ERROR(
|
||||
backupJobResult(
|
||||
(Manifest *)1, NULL, storageTest, strLstNew(), job, false, pgPageSize8, 0, NULL, ¤tPercentComplete),
|
||||
(Manifest *)1, NULL, storageTest, strLstNew(), job, pgPageSize8, 0, NULL, ¤tPercentComplete),
|
||||
AssertError, "error message");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -1891,7 +1891,7 @@ testRun(void)
|
||||
|
||||
TEST_RESULT_VOID(
|
||||
backupJobResult(
|
||||
manifest, STRDEF("host"), storageTest, strLstNew(), job, false, pgPageSize8, 0, &sizeProgress,
|
||||
manifest, STRDEF("host"), storageTest, strLstNew(), job, pgPageSize8, 0, &sizeProgress,
|
||||
¤tPercentComplete),
|
||||
"log noop result");
|
||||
TEST_RESULT_VOID(cmdLockReleaseP(), "release backup lock");
|
||||
|
||||
@@ -97,19 +97,19 @@ testRun(void)
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("command end does not log when level is too low");
|
||||
|
||||
TEST_RESULT_VOID(cmdEnd(0, NULL), "command end");
|
||||
TEST_RESULT_VOID(cmdEnd(NULL), "command end");
|
||||
harnessLogLevelReset();
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("command end with error");
|
||||
|
||||
TEST_RESULT_VOID(cmdEnd(25, STRDEF("aborted with exception [025]")), "command end");
|
||||
TEST_RESULT_VOID(cmdEnd(STRDEF("aborted with exception [025]")), "command end");
|
||||
TEST_RESULT_LOG("P00 INFO: restore command end: aborted with exception [025]");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("command end with time");
|
||||
|
||||
TEST_RESULT_VOID(cmdEnd(0, NULL), "command end");
|
||||
TEST_RESULT_VOID(cmdEnd(NULL), "command end");
|
||||
hrnLogReplaceAdd("\\([0-9]+ms\\)", "[0-9]+", "TIME", false);
|
||||
TEST_RESULT_LOG(
|
||||
"P00 INFO: restore command end: completed successfully ([TIME]ms)");
|
||||
@@ -122,7 +122,7 @@ testRun(void)
|
||||
|
||||
harnessLogLevelSet(logLevelDetail);
|
||||
|
||||
TEST_RESULT_VOID(cmdEnd(0, NULL), "command end");
|
||||
TEST_RESULT_VOID(cmdEnd(NULL), "command end");
|
||||
TEST_RESULT_LOG(
|
||||
"P00 DETAIL: statistics: {\"test\":{\"total\":1}}\n"
|
||||
"P00 INFO: restore command end: completed successfully");
|
||||
|
||||
@@ -29,7 +29,7 @@ testRun(void)
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("exitInit() and exitOnSignal()"))
|
||||
{
|
||||
TEST_RESULT_INT(exitSafe(0, false, signalTypeNone), 0, "exit with no command");
|
||||
TEST_RESULT_INT(exitSafe(0, false), 0, "exit with no command");
|
||||
TEST_RESULT_VOID(exitOnSignal(signalTypeTerm), "ignore signal when exit in progress");
|
||||
HRN_CFG_LOAD(cfgCmdHelp, strLstNew());
|
||||
|
||||
@@ -66,10 +66,10 @@ testRun(void)
|
||||
hrnCfgArgRawNegate(argList, cfgOptLogTimestamp);
|
||||
HRN_CFG_LOAD(cfgCmdArchivePush, argList);
|
||||
|
||||
TEST_RESULT_INT(exitSafe(0, false, signalTypeNone), 0, "exit with no error");
|
||||
TEST_RESULT_INT(exitSafe(0, false), 0, "exit with no error");
|
||||
TEST_RESULT_LOG("P00 INFO: archive-push command end: completed successfully");
|
||||
|
||||
TEST_RESULT_INT(exitSafe(1, false, signalTypeNone), 1, "exit with no error");
|
||||
TEST_RESULT_INT(exitSafe(1, false), 1, "exit with no error");
|
||||
TEST_RESULT_LOG("P00 INFO: archive-push command end: completed successfully");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -79,7 +79,7 @@ testRun(void)
|
||||
}
|
||||
CATCH_FATAL()
|
||||
{
|
||||
exitSafe(0, true, signalTypeNone);
|
||||
exitSafe(0, true);
|
||||
TEST_RESULT_LOG(
|
||||
"P00 ERROR: [122]: test error message\n"
|
||||
"P00 INFO: archive-push command end: aborted with exception [122]");
|
||||
@@ -100,9 +100,9 @@ testRun(void)
|
||||
}
|
||||
CATCH_FATAL()
|
||||
{
|
||||
exitSafe(0, true, signalTypeNone);
|
||||
exitSafe(0, true);
|
||||
TEST_RESULT_LOG(
|
||||
"P00 DEBUG: " TEST_PGB_PATH "/src/command/exit::exitSafe: (result: 0, error: true, signalType: 0)\n"
|
||||
"P00 DEBUG: " TEST_PGB_PATH "/src/command/exit::exitSafe: (result: 0, error: true)\n"
|
||||
"P00 ERROR: [122]: test debug error message\n"
|
||||
" --------------------------------------------------------------------\n"
|
||||
" If SUBMITTING AN ISSUE please provide the following information:\n"
|
||||
@@ -128,7 +128,7 @@ testRun(void)
|
||||
}
|
||||
CATCH_FATAL()
|
||||
{
|
||||
exitSafe(0, true, signalTypeNone);
|
||||
exitSafe(0, true);
|
||||
TEST_RESULT_LOG(
|
||||
"P00 ASSERT: [025]: test assert message\n"
|
||||
" --------------------------------------------------------------------\n"
|
||||
|
||||
@@ -1891,7 +1891,7 @@ testRun(void)
|
||||
HRN_CFG_LOAD(cfgCmdRestore, argList);
|
||||
|
||||
TEST_ERROR(
|
||||
restoreRecoveryWriteAutoConf(manifest, &fileInfo, PG_VERSION_12, restoreLabel), OptionInvalidError,
|
||||
restoreRecoveryWriteAutoConf(&fileInfo, PG_VERSION_12, restoreLabel), OptionInvalidError,
|
||||
"'standby_mode' setting is not valid for PostgreSQL >= 12\n"
|
||||
"HINT: use --type=standby instead of --recovery-option=standby_mode=on.");
|
||||
|
||||
@@ -1907,7 +1907,7 @@ testRun(void)
|
||||
hrnCfgArgRawZ(argList, cfgOptType, "none");
|
||||
HRN_CFG_LOAD(cfgCmdRestore, argList);
|
||||
|
||||
restoreRecoveryWriteAutoConf(manifest, &fileInfo, PG_VERSION_12, restoreLabel);
|
||||
restoreRecoveryWriteAutoConf(&fileInfo, PG_VERSION_12, restoreLabel);
|
||||
|
||||
TEST_STORAGE_GET_EMPTY(storagePg(), PG_FILE_POSTGRESQLAUTOCONF, .comment = "check postgresql.auto.conf");
|
||||
TEST_STORAGE_LIST(
|
||||
@@ -1927,7 +1927,7 @@ testRun(void)
|
||||
"# DO NOT MODIFY\n"
|
||||
"\t recovery_target_action='promote'\n\n");
|
||||
|
||||
restoreRecoveryWriteAutoConf(manifest, &fileInfo, PG_VERSION_12, restoreLabel);
|
||||
restoreRecoveryWriteAutoConf(&fileInfo, PG_VERSION_12, restoreLabel);
|
||||
|
||||
TEST_STORAGE_GET(
|
||||
storagePg(), PG_FILE_POSTGRESQLAUTOCONF,
|
||||
@@ -1950,7 +1950,7 @@ testRun(void)
|
||||
"# DO NOT MODIFY\n"
|
||||
"\t recovery_target_action='promote'\n\n");
|
||||
|
||||
restoreRecoveryWriteAutoConf(manifest, &fileInfo, PG_VERSION_12, restoreLabel);
|
||||
restoreRecoveryWriteAutoConf(&fileInfo, PG_VERSION_12, restoreLabel);
|
||||
|
||||
TEST_STORAGE_GET(
|
||||
storagePg(), PG_FILE_POSTGRESQLAUTOCONF,
|
||||
@@ -1985,7 +1985,7 @@ testRun(void)
|
||||
hrnCfgArgRawZ(argList, cfgOptRecoveryOption, "restore-command=my_restore_command");
|
||||
HRN_CFG_LOAD(cfgCmdRestore, argList);
|
||||
|
||||
restoreRecoveryWriteAutoConf(manifest, &fileInfo, PG_VERSION_12, restoreLabel);
|
||||
restoreRecoveryWriteAutoConf(&fileInfo, PG_VERSION_12, restoreLabel);
|
||||
|
||||
TEST_STORAGE_GET(
|
||||
storagePg(), PG_FILE_POSTGRESQLAUTOCONF,
|
||||
|
||||
@@ -167,7 +167,7 @@ testRun(void)
|
||||
// signal sent in response to the notification cannot arrive before the exit in progress flag is set.
|
||||
if (pid != getpid())
|
||||
{
|
||||
const int result = exitSafe(0, false, signalTypeNone);
|
||||
const int result = exitSafe(0, false);
|
||||
|
||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||
exit(result);
|
||||
@@ -280,7 +280,7 @@ testRun(void)
|
||||
// signal sent in response to the notification cannot arrive before the exit in progress flag is set.
|
||||
if (pid != getpid())
|
||||
{
|
||||
const int result = exitSafe(0, false, signalTypeNone);
|
||||
const int result = exitSafe(0, false);
|
||||
|
||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||
exit(result);
|
||||
|
||||
@@ -1239,9 +1239,9 @@ testRun(void)
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("uncovered errors");
|
||||
|
||||
TEST_RESULT_INT(tlsSessionResultProcess(tlsSession, SSL_ERROR_WANT_WRITE, 0, 0, false), 0, "write ready");
|
||||
TEST_RESULT_INT(tlsSessionResultProcess(tlsSession, SSL_ERROR_WANT_WRITE, 0, false), 0, "write ready");
|
||||
TEST_ERROR(
|
||||
tlsSessionResultProcess(tlsSession, SSL_ERROR_WANT_X509_LOOKUP, 336031996, 0, false), ServiceError,
|
||||
tlsSessionResultProcess(tlsSession, SSL_ERROR_WANT_X509_LOOKUP, 336031996, false), ServiceError,
|
||||
"TLS error [4:336031996] "
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
"no details available");
|
||||
@@ -1249,10 +1249,10 @@ testRun(void)
|
||||
"unknown protocol");
|
||||
#endif
|
||||
TEST_ERROR(
|
||||
tlsSessionResultProcess(tlsSession, SSL_ERROR_WANT_X509_LOOKUP, 0, 0, false), ServiceError,
|
||||
tlsSessionResultProcess(tlsSession, SSL_ERROR_WANT_X509_LOOKUP, 0, false), ServiceError,
|
||||
"TLS error [4:0] no details available");
|
||||
TEST_ERROR(
|
||||
tlsSessionResultProcess(tlsSession, SSL_ERROR_ZERO_RETURN, 0, 0, false), ProtocolError, "unexpected TLS eof");
|
||||
tlsSessionResultProcess(tlsSession, SSL_ERROR_ZERO_RETURN, 0, false), ProtocolError, "unexpected TLS eof");
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("first protocol exchange");
|
||||
|
||||
@@ -52,8 +52,7 @@ testRun(void)
|
||||
TEST_ASSIGN(
|
||||
infoPg,
|
||||
infoPgSet(
|
||||
infoPgNew(infoPgArchive, NULL), infoPgArchive, PG_VERSION_18, 6569239123849665679,
|
||||
hrnPgCatalogVersion(PG_VERSION_18)),
|
||||
infoPgNew(infoPgArchive, NULL), PG_VERSION_18, 6569239123849665679, hrnPgCatalogVersion(PG_VERSION_18)),
|
||||
"infoPgSet - infoPgArchive");
|
||||
TEST_RESULT_INT(infoPgDataTotal(infoPg), 1, " 1 history");
|
||||
TEST_RESULT_INT(infoPgDataCurrentId(infoPg), 0, " 0 historyCurrent");
|
||||
@@ -64,7 +63,7 @@ testRun(void)
|
||||
TEST_RESULT_UINT(pgData.catalogVersion, 0, " catalog version not set for archive");
|
||||
|
||||
TEST_ASSIGN(
|
||||
infoPg, infoPgSet(infoPg, infoPgArchive, PG_VERSION_18, 6569239123849665999, hrnPgCatalogVersion(PG_VERSION_18)),
|
||||
infoPg, infoPgSet(infoPg, PG_VERSION_18, 6569239123849665999, hrnPgCatalogVersion(PG_VERSION_18)),
|
||||
"infoPgSet - infoPgArchive second db");
|
||||
TEST_RESULT_INT(infoPgDataTotal(infoPg), 2, " 2 history");
|
||||
TEST_RESULT_INT(infoPgDataCurrentId(infoPg), 0, " 0 historyCurrent");
|
||||
@@ -79,9 +78,8 @@ testRun(void)
|
||||
TEST_ASSIGN(
|
||||
infoPg,
|
||||
infoPgSet(
|
||||
infoPgNew(infoPgBackup, cipherSpecNew(cipherTypeAes256Cbc, BUFSTRDEF("123xyz"))), infoPgBackup,
|
||||
PG_VERSION_18, 6569239123849665679,
|
||||
hrnPgCatalogVersion(PG_VERSION_18)),
|
||||
infoPgNew(infoPgBackup, cipherSpecNew(cipherTypeAes256Cbc, BUFSTRDEF("123xyz"))), PG_VERSION_18,
|
||||
6569239123849665679, hrnPgCatalogVersion(PG_VERSION_18)),
|
||||
"infoPgSet - infoPgBackup");
|
||||
TEST_RESULT_INT(infoPgDataTotal(infoPg), 1, " 1 history");
|
||||
TEST_RESULT_INT(infoPgDataCurrentId(infoPg), 0, " 0 historyCurrent");
|
||||
|
||||
Reference in New Issue
Block a user