1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2026-06-20 01:17:49 +02:00

Throw real SFTP read-open errors instead of masking them as missing.

Previously storageReadSftpOpen() only inspected the failure when the libssh2 error was LIBSSH2_ERROR_SFTP_PROTOCOL or LIBSSH2_ERROR_EAGAIN. Any other error (e.g. a socket error such as LIBSSH2_ERROR_SOCKET_RECV) fell through silently, leaving a NULL handle and causing the storage layer to report the file as missing.

Throw on any open failure except a genuine missing file (SFTP_PROTOCOL + LIBSSH2_FX_NO_SUCH_FILE), which is still returned to the caller via the result so ignoreMissing continues to work. This brings read-open error handling in line with storageWriteSftpOpen().
This commit is contained in:
David Steele
2026-06-19 12:39:40 +07:00
parent 1c57106e2d
commit af586e230e
2 changed files with 36 additions and 13 deletions
+5 -8
View File
@@ -55,16 +55,13 @@ storageReadSftpOpen(THIS_VOID)
if (this->sftpHandle == NULL)
{
const int rc = libssh2_session_last_errno(this->session);
const uint64_t sftpErr = libssh2_sftp_last_error(this->sftpSession);
// Handle errors except missing, which is reported to the caller via the result
if (rc == LIBSSH2_ERROR_SFTP_PROTOCOL || rc == LIBSSH2_ERROR_EAGAIN)
// Throw on any error except missing, which is reported to the caller via the result
if (rc != LIBSSH2_ERROR_SFTP_PROTOCOL || sftpErr != LIBSSH2_FX_NO_SUCH_FILE)
{
if (libssh2_sftp_last_error(this->sftpSession) != LIBSSH2_FX_NO_SUCH_FILE)
{
storageSftpEvalLibSsh2Error(
rc, libssh2_sftp_last_error(this->sftpSession), &FileOpenError,
strNewFmt(STORAGE_ERROR_READ_OPEN, strZ(this->name)), NULL);
}
storageSftpEvalLibSsh2Error(
rc, sftpErr, &FileOpenError, strNewFmt(STORAGE_ERROR_READ_OPEN, strZ(this->name)), NULL);
}
}
// Else success
+31 -5
View File
@@ -2492,21 +2492,47 @@ testRun(void)
HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN),
HRN_LIBSSH2_BLOCK(.resultInt = SSH2_BLOCK_READING_WRITING),
HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_EAGAIN),
HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_OK),
HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_ERROR_NONE));
HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_OK));
TEST_ERROR_FMT(
ioReadOpen(storageReadIo(file)), FileOpenError, STORAGE_ERROR_READ_OPEN ": libssh2 error [-37]", strZ(fileName));
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("read missing - not sftp, not EAGAIN");
TEST_TITLE("read open error - not sftp, not EAGAIN");
HRN_LIBSSH2_SCRIPT_SET(
HRN_LIBSSH2_OPEN_READ(TEST_PATH "/readtest.txt", .resultNull = true),
HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_METHOD_NOT_SUPPORTED),
HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_METHOD_NOT_SUPPORTED));
HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_METHOD_NOT_SUPPORTED),
HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_OK));
TEST_ERROR_FMT(ioReadOpen(storageReadIo(file)), FileMissingError, STORAGE_ERROR_READ_MISSING, strZ(fileName));
TEST_ERROR_FMT(
ioReadOpen(storageReadIo(file)), FileOpenError, STORAGE_ERROR_READ_OPEN ": libssh2 error [-33]", strZ(fileName));
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("read open error - socket error is not masked as missing");
HRN_LIBSSH2_SCRIPT_SET(
HRN_LIBSSH2_OPEN_READ(TEST_PATH "/readtest.txt", .resultNull = true),
HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SOCKET_RECV),
HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SOCKET_RECV),
HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_OK));
TEST_ERROR_FMT(
ioReadOpen(storageReadIo(file)), FileOpenError, STORAGE_ERROR_READ_OPEN ": libssh2 error [-43]", strZ(fileName));
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("read open error - sftp error other than no such file is not masked as missing");
HRN_LIBSSH2_SCRIPT_SET(
HRN_LIBSSH2_OPEN_READ(TEST_PATH "/readtest.txt", .resultNull = true),
HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL),
HRN_LIBSSH2_ERRNO(LIBSSH2_ERROR_SFTP_PROTOCOL),
HRN_LIBSSH2_SFTP_ERROR(LIBSSH2_FX_PERMISSION_DENIED));
TEST_ERROR_FMT(
ioReadOpen(storageReadIo(file)), FileOpenError,
STORAGE_ERROR_READ_OPEN ": libssh2 error [-31]: sftp error [3] permission denied", strZ(fileName));
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("read success");