mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-14 10:13:05 +02:00
Improve info error messages introduced in 74b72df9
.
- Add detail to errors when info files are loaded with incorrect encryption settings. - Throw FileMissingError rather than FileOpenError when both copies of the info file are missing. - If one file is present (but errors) and the other is missing, then return the error for the file that was present. Contributed by Cynthia Shang.
This commit is contained in:
parent
80a3e21521
commit
cbf514e191
@ -104,7 +104,12 @@
|
|||||||
</release-item>
|
</release-item>
|
||||||
|
|
||||||
<release-item>
|
<release-item>
|
||||||
<p>Improve error message when info files are missing/corrupt.</p>
|
<release-item-contributor-list>
|
||||||
|
<release-item-contributor id="david.steele"/>
|
||||||
|
<release-item-contributor id="cynthia.shang"/>
|
||||||
|
</release-item-contributor-list>
|
||||||
|
|
||||||
|
<p>Improve error messages when info files are missing/corrupt.</p>
|
||||||
</release-item>
|
</release-item>
|
||||||
|
|
||||||
<release-item>
|
<release-item>
|
||||||
|
@ -146,7 +146,20 @@ infoLoad(Info *this, const Storage *storage, bool copyFile, CipherType cipherTyp
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load and parse the info file
|
// Load and parse the info file
|
||||||
Buffer *buffer = storageGetNP(infoRead);
|
Buffer *buffer = NULL;
|
||||||
|
|
||||||
|
TRY_BEGIN()
|
||||||
|
{
|
||||||
|
buffer = storageGetNP(infoRead);
|
||||||
|
}
|
||||||
|
CATCH(CryptoError)
|
||||||
|
{
|
||||||
|
THROW_FMT(
|
||||||
|
CryptoError, "'%s' %s\nHINT: Is or was the repo encrypted?", strPtr(storagePathNP(storage, fileName)),
|
||||||
|
errorMessage());
|
||||||
|
}
|
||||||
|
TRY_END();
|
||||||
|
|
||||||
iniParse(this->ini, strNewBuf(buffer));
|
iniParse(this->ini, strNewBuf(buffer));
|
||||||
|
|
||||||
// Make sure the ini is valid by testing the checksum
|
// Make sure the ini is valid by testing the checksum
|
||||||
@ -161,7 +174,7 @@ infoLoad(Info *this, const Storage *storage, bool copyFile, CipherType cipherTyp
|
|||||||
bool checksumMissing = strSize(infoChecksum) < 3;
|
bool checksumMissing = strSize(infoChecksum) < 3;
|
||||||
|
|
||||||
THROW_FMT(
|
THROW_FMT(
|
||||||
ChecksumError, "invalid checksum in '%s', expected '%s' but %s%s%s", strPtr(fileName),
|
ChecksumError, "invalid checksum in '%s', expected '%s' but %s%s%s", strPtr(storagePathNP(storage, fileName)),
|
||||||
strPtr(bufHex(cryptoHash(hash))), checksumMissing ? "no checksum found" : "found '",
|
strPtr(bufHex(cryptoHash(hash))), checksumMissing ? "no checksum found" : "found '",
|
||||||
// ??? Temporary hack until get json parser: remove quotes around hash before displaying in messsage
|
// ??? Temporary hack until get json parser: remove quotes around hash before displaying in messsage
|
||||||
checksumMissing ? "" : strPtr(strSubN(infoChecksum, 1, strSize(infoChecksum) - 2)),
|
checksumMissing ? "" : strPtr(strSubN(infoChecksum, 1, strSize(infoChecksum) - 2)),
|
||||||
@ -219,6 +232,8 @@ infoNew(const Storage *storage, const String *fileName, CipherType cipherType, c
|
|||||||
{
|
{
|
||||||
// On error store the error and try to load the copy
|
// On error store the error and try to load the copy
|
||||||
String *primaryError = strNewFmt("%s: %s", errorTypeName(errorType()), errorMessage());
|
String *primaryError = strNewFmt("%s: %s", errorTypeName(errorType()), errorMessage());
|
||||||
|
bool primaryMissing = errorType() == &FileMissingError;
|
||||||
|
const ErrorType *primaryErrorType = errorType();
|
||||||
|
|
||||||
TRY_BEGIN()
|
TRY_BEGIN()
|
||||||
{
|
{
|
||||||
@ -226,8 +241,14 @@ infoNew(const Storage *storage, const String *fileName, CipherType cipherType, c
|
|||||||
}
|
}
|
||||||
CATCH_ANY()
|
CATCH_ANY()
|
||||||
{
|
{
|
||||||
THROW_FMT(
|
// If both copies of the file have the same error then throw that error,
|
||||||
FileOpenError, "unable to load info file '%s' or '%s" INI_COPY_EXT "':\n%s\n%s: %s",
|
// else if one file is missing but the other is in error and it is not missing, throw that error
|
||||||
|
// else throw an open error
|
||||||
|
THROWP_FMT(
|
||||||
|
errorType() == primaryErrorType ? errorType() :
|
||||||
|
(errorType() == &FileMissingError ? primaryErrorType :
|
||||||
|
(primaryMissing ? errorType() : &FileOpenError)),
|
||||||
|
"unable to load info file '%s' or '%s" INI_COPY_EXT "':\n%s\n%s: %s",
|
||||||
strPtr(storagePathNP(storage, this->fileName)), strPtr(storagePathNP(storage, this->fileName)),
|
strPtr(storagePathNP(storage, this->fileName)), strPtr(storagePathNP(storage, this->fileName)),
|
||||||
strPtr(primaryError), errorTypeName(errorType()), errorMessage());
|
strPtr(primaryError), errorTypeName(errorType()), errorMessage());
|
||||||
}
|
}
|
||||||
|
@ -14,14 +14,14 @@ P00 INFO: archive-push command end: aborted with exception [055]
|
|||||||
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get 000000010000000100000001 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG
|
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get 000000010000000100000001 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000001, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG] --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=detail --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --log-subprocess --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=[TEST_PATH]/db-master/repo --stanza=db
|
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000001, [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG] --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=detail --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --log-subprocess --no-log-timestamp --pg1-path=[TEST_PATH]/db-master/db/base --protocol-timeout=60 --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=[TEST_PATH]/db-master/repo --stanza=db
|
||||||
P00 ERROR: [041]: unable to load info file '[TEST_PATH]/db-master/repo/archive/db/archive.info' or '[TEST_PATH]/db-master/repo/archive/db/archive.info.copy':
|
P00 ERROR: [055]: unable to load info file '[TEST_PATH]/db-master/repo/archive/db/archive.info' or '[TEST_PATH]/db-master/repo/archive/db/archive.info.copy':
|
||||||
FileMissingError: unable to open '[TEST_PATH]/db-master/repo/archive/db/archive.info' for read: [2] No such file or directory
|
FileMissingError: unable to open '[TEST_PATH]/db-master/repo/archive/db/archive.info' for read: [2] No such file or directory
|
||||||
FileMissingError: unable to open '[TEST_PATH]/db-master/repo/archive/db/archive.info.copy' for read: [2] No such file or directory
|
FileMissingError: unable to open '[TEST_PATH]/db-master/repo/archive/db/archive.info.copy' for read: [2] No such file or directory
|
||||||
HINT: archive.info cannot be opened but is required to push/get WAL segments.
|
HINT: archive.info cannot be opened but is required to push/get WAL segments.
|
||||||
HINT: is archive_command configured correctly in postgresql.conf?
|
HINT: is archive_command configured correctly in postgresql.conf?
|
||||||
HINT: has a stanza-create been performed?
|
HINT: has a stanza-create been performed?
|
||||||
HINT: use --no-archive-check to disable archive checks during backup if you have an alternate archiving scheme.
|
HINT: use --no-archive-check to disable archive checks during backup if you have an alternate archiving scheme.
|
||||||
P00 INFO: archive-get command end: aborted with exception [041]
|
P00 INFO: archive-get command end: aborted with exception [055]
|
||||||
|
|
||||||
stanza-create db - stanza create (db-master host)
|
stanza-create db - stanza create (db-master host)
|
||||||
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db --log-level-console=detail --no-online --force stanza-create
|
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db --log-level-console=detail --no-online --force stanza-create
|
||||||
|
@ -11,7 +11,7 @@ P00 ERROR: [055]: archive.info does not exist but is required to push/get WAL s
|
|||||||
|
|
||||||
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get 000000010000000100000001 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG
|
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get 000000010000000100000001 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 ERROR: [041]: unable to load info file '/archive/db/archive.info' or '/archive/db/archive.info.copy':
|
P00 ERROR: [055]: unable to load info file '/archive/db/archive.info' or '/archive/db/archive.info.copy':
|
||||||
FileMissingError: unable to open '/archive/db/archive.info': No such file or directory
|
FileMissingError: unable to open '/archive/db/archive.info': No such file or directory
|
||||||
FileMissingError: unable to open '/archive/db/archive.info.copy': No such file or directory
|
FileMissingError: unable to open '/archive/db/archive.info.copy': No such file or directory
|
||||||
HINT: archive.info cannot be opened but is required to push/get WAL segments.
|
HINT: archive.info cannot be opened but is required to push/get WAL segments.
|
||||||
|
@ -135,12 +135,9 @@ sub run
|
|||||||
$strCommandPush . " ${strWalPath}/${strSourceFile1}",
|
$strCommandPush . " ${strWalPath}/${strSourceFile1}",
|
||||||
{iExpectedExitStatus => ERROR_FILE_MISSING, oLogTest => $self->expect()});
|
{iExpectedExitStatus => ERROR_FILE_MISSING, oLogTest => $self->expect()});
|
||||||
|
|
||||||
# ??? C and Perl currently return different errors for info open failures -- this can be removed when Perl is gone
|
|
||||||
my $iExpectedError = !$bRemote ? ERROR_FILE_OPEN : ERROR_FILE_MISSING;
|
|
||||||
|
|
||||||
$oHostDbMaster->executeSimple(
|
$oHostDbMaster->executeSimple(
|
||||||
$strCommandGet . " ${strSourceFile1} ${strWalPath}/RECOVERYXLOG",
|
$strCommandGet . " ${strSourceFile1} ${strWalPath}/RECOVERYXLOG",
|
||||||
{iExpectedExitStatus => $iExpectedError, oLogTest => $self->expect()});
|
{iExpectedExitStatus => ERROR_FILE_MISSING, oLogTest => $self->expect()});
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------------------------------------------
|
||||||
$oHostBackup->stanzaCreate(
|
$oHostBackup->stanzaCreate(
|
||||||
|
@ -345,7 +345,7 @@ testRun(void)
|
|||||||
HARNESS_FORK_CHILD()
|
HARNESS_FORK_CHILD()
|
||||||
{
|
{
|
||||||
TEST_ERROR_FMT(
|
TEST_ERROR_FMT(
|
||||||
cmdArchiveGet(), FileOpenError,
|
cmdArchiveGet(), FileMissingError,
|
||||||
"unable to load info file '%s/archive/test1/archive.info' or '%s/archive/test1/archive.info.copy':\n"
|
"unable to load info file '%s/archive/test1/archive.info' or '%s/archive/test1/archive.info.copy':\n"
|
||||||
"FileMissingError: unable to open '%s/archive/test1/archive.info' for read: [2] No such file or directory\n"
|
"FileMissingError: unable to open '%s/archive/test1/archive.info' for read: [2] No such file or directory\n"
|
||||||
"FileMissingError: unable to open '%s/archive/test1/archive.info.copy' for read: [2] No such file or"
|
"FileMissingError: unable to open '%s/archive/test1/archive.info.copy' for read: [2] No such file or"
|
||||||
@ -375,7 +375,7 @@ testRun(void)
|
|||||||
HARNESS_FORK_CHILD()
|
HARNESS_FORK_CHILD()
|
||||||
{
|
{
|
||||||
TEST_ERROR_FMT(
|
TEST_ERROR_FMT(
|
||||||
cmdArchiveGet(), FileOpenError,
|
cmdArchiveGet(), FileMissingError,
|
||||||
"unable to load info file '%s/archive/test1/archive.info' or '%s/archive/test1/archive.info.copy':\n"
|
"unable to load info file '%s/archive/test1/archive.info' or '%s/archive/test1/archive.info.copy':\n"
|
||||||
"FileMissingError: unable to open '%s/archive/test1/archive.info' for read: [2] No such file or directory\n"
|
"FileMissingError: unable to open '%s/archive/test1/archive.info' for read: [2] No such file or directory\n"
|
||||||
"FileMissingError: unable to open '%s/archive/test1/archive.info.copy' for read: [2] No such file or"
|
"FileMissingError: unable to open '%s/archive/test1/archive.info.copy' for read: [2] No such file or"
|
||||||
|
@ -17,7 +17,7 @@ testRun(void)
|
|||||||
String *fileName = strNewFmt("%s/test.ini", testPath());
|
String *fileName = strNewFmt("%s/test.ini", testPath());
|
||||||
|
|
||||||
TEST_ERROR_FMT(
|
TEST_ERROR_FMT(
|
||||||
infoArchiveNew(storageLocal(), fileName, true, cipherTypeNone, NULL), FileOpenError,
|
infoArchiveNew(storageLocal(), fileName, true, cipherTypeNone, NULL), FileMissingError,
|
||||||
"unable to load info file '%s/test.ini' or '%s/test.ini.copy':\n"
|
"unable to load info file '%s/test.ini' or '%s/test.ini.copy':\n"
|
||||||
"FileMissingError: unable to open '%s/test.ini' for read: [2] No such file or directory\n"
|
"FileMissingError: unable to open '%s/test.ini' for read: [2] No such file or directory\n"
|
||||||
"FileMissingError: unable to open '%s/test.ini.copy' for read: [2] No such file or directory\n"
|
"FileMissingError: unable to open '%s/test.ini.copy' for read: [2] No such file or directory\n"
|
||||||
|
@ -37,7 +37,7 @@ testRun(void)
|
|||||||
// Info files missing and at least one is required
|
// Info files missing and at least one is required
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
TEST_ERROR(
|
TEST_ERROR(
|
||||||
infoNew(storageLocal(), fileName, cipherTypeNone, NULL), FileOpenError,
|
infoNew(storageLocal(), fileName, cipherTypeNone, NULL), FileMissingError,
|
||||||
strPtr(
|
strPtr(
|
||||||
strNewFmt(
|
strNewFmt(
|
||||||
"unable to load info file '%s/test.ini' or '%s/test.ini.copy':\n"
|
"unable to load info file '%s/test.ini' or '%s/test.ini.copy':\n"
|
||||||
@ -121,7 +121,7 @@ testRun(void)
|
|||||||
storagePutNP(storageNewWriteNP(storageLocalWrite(), fileName), bufNewStr(content)), "put invalid br format to file");
|
storagePutNP(storageNewWriteNP(storageLocalWrite(), fileName), bufNewStr(content)), "put invalid br format to file");
|
||||||
|
|
||||||
TEST_ERROR(
|
TEST_ERROR(
|
||||||
infoNew(storageLocal(), fileName, cipherTypeNone, NULL), FileOpenError,
|
infoNew(storageLocal(), fileName, cipherTypeNone, NULL), FormatError,
|
||||||
strPtr(
|
strPtr(
|
||||||
strNewFmt(
|
strNewFmt(
|
||||||
"unable to load info file '%s/test.ini' or '%s/test.ini.copy':\n"
|
"unable to load info file '%s/test.ini' or '%s/test.ini.copy':\n"
|
||||||
@ -129,7 +129,28 @@ testRun(void)
|
|||||||
"FileMissingError: unable to open '%s/test.ini.copy' for read: [2] No such file or directory",
|
"FileMissingError: unable to open '%s/test.ini.copy' for read: [2] No such file or directory",
|
||||||
testPath(), testPath(), testPath(), testPath())));
|
testPath(), testPath(), testPath(), testPath())));
|
||||||
|
|
||||||
storageCopyNP(storageNewReadNP(storageLocal(), fileName), storageNewWriteNP(storageLocalWrite(), fileNameCopy));
|
content = strNew
|
||||||
|
(
|
||||||
|
"[backrest]\n"
|
||||||
|
"backrest-checksum=\"14617b089cb5c9b3224e739bb794e865b9bcdf4b\"\n"
|
||||||
|
"backrest-format=4\n"
|
||||||
|
"backrest-version=\"2.05\"\n"
|
||||||
|
"\n"
|
||||||
|
"[db]\n"
|
||||||
|
"db-catalog-version=201409291\n"
|
||||||
|
"db-control-version=942\n"
|
||||||
|
"db-id=1\n"
|
||||||
|
"db-system-id=6569239123849665679\n"
|
||||||
|
"db-version=\"9.4\"\n"
|
||||||
|
"\n"
|
||||||
|
"[db:history]\n"
|
||||||
|
"1={\"db-catalog-version\":201409291,\"db-control-version\":942,\"db-system-id\":6569239123849665679,"
|
||||||
|
"\"db-version\":\"9.4\"}\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(
|
||||||
|
storagePutNP(
|
||||||
|
storageNewWriteNP(storageLocalWrite(), fileNameCopy), bufNewStr(content)), "put invalid info to copy file");
|
||||||
|
|
||||||
TEST_ERROR(
|
TEST_ERROR(
|
||||||
infoNew(storageLocal(), fileName, cipherTypeNone, NULL), FileOpenError,
|
infoNew(storageLocal(), fileName, cipherTypeNone, NULL), FileOpenError,
|
||||||
@ -137,7 +158,8 @@ testRun(void)
|
|||||||
strNewFmt(
|
strNewFmt(
|
||||||
"unable to load info file '%s/test.ini' or '%s/test.ini.copy':\n"
|
"unable to load info file '%s/test.ini' or '%s/test.ini.copy':\n"
|
||||||
"FormatError: invalid format in '%s/test.ini', expected 5 but found 4\n"
|
"FormatError: invalid format in '%s/test.ini', expected 5 but found 4\n"
|
||||||
"FormatError: invalid format in '%s/test.ini.copy', expected 5 but found 4",
|
"ChecksumError: invalid checksum in '%s/test.ini.copy', expected 'af92308095d6141bcda6b2df6d574f98d1115163'"
|
||||||
|
" but found '14617b089cb5c9b3224e739bb794e865b9bcdf4b'",
|
||||||
testPath(), testPath(), testPath(), testPath())));
|
testPath(), testPath(), testPath(), testPath())));
|
||||||
|
|
||||||
// Invalid checksum
|
// Invalid checksum
|
||||||
@ -189,7 +211,7 @@ testRun(void)
|
|||||||
|
|
||||||
// Copy file error
|
// Copy file error
|
||||||
TEST_ERROR(
|
TEST_ERROR(
|
||||||
infoNew(storageLocal(), fileName, cipherTypeNone, NULL), FileOpenError,
|
infoNew(storageLocal(), fileName, cipherTypeNone, NULL), ChecksumError,
|
||||||
strPtr(
|
strPtr(
|
||||||
strNewFmt(
|
strNewFmt(
|
||||||
"unable to load info file '%s/test.ini' or '%s/test.ini.copy':\n"
|
"unable to load info file '%s/test.ini' or '%s/test.ini.copy':\n"
|
||||||
@ -199,7 +221,19 @@ testRun(void)
|
|||||||
" but found '4306ec205f71417c301e403c4714090e61c8a999'",
|
" but found '4306ec205f71417c301e403c4714090e61c8a999'",
|
||||||
testPath(), testPath(), testPath(), testPath())));
|
testPath(), testPath(), testPath(), testPath())));
|
||||||
|
|
||||||
|
// Encryption error
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
storageRemoveNP(storageLocalWrite(), fileName);
|
storageRemoveNP(storageLocalWrite(), fileName);
|
||||||
|
TEST_ERROR(
|
||||||
|
infoNew(storageLocal(), fileName, cipherTypeAes256Cbc, strNew("12345678")), CryptoError,
|
||||||
|
strPtr(
|
||||||
|
strNewFmt(
|
||||||
|
"unable to load info file '%s/test.ini' or '%s/test.ini.copy':\n"
|
||||||
|
"FileMissingError: unable to open '%s/test.ini' for read: [2] No such file or directory\n"
|
||||||
|
"CryptoError: '%s/test.ini.copy' cipher header invalid\n"
|
||||||
|
"HINT: Is or was the repo encrypted?",
|
||||||
|
testPath(), testPath(), testPath(), testPath())));
|
||||||
|
|
||||||
storageRemoveNP(storageLocalWrite(), fileNameCopy);
|
storageRemoveNP(storageLocalWrite(), fileNameCopy);
|
||||||
|
|
||||||
// infoFree()
|
// infoFree()
|
||||||
|
Loading…
Reference in New Issue
Block a user