From 75f317eaf1d7cc458e8bf0ef7a6030e530a007f0 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Mon, 21 Oct 2024 21:41:56 +0200 Subject: [PATCH] sftp: check for broken connection in Load/List operation --- changelog/unreleased/pull-5101 | 9 +++++++++ internal/backend/sftp/sftp.go | 8 ++++++++ 2 files changed, 17 insertions(+) create mode 100644 changelog/unreleased/pull-5101 diff --git a/changelog/unreleased/pull-5101 b/changelog/unreleased/pull-5101 new file mode 100644 index 000000000..f784d0c47 --- /dev/null +++ b/changelog/unreleased/pull-5101 @@ -0,0 +1,9 @@ +Bugfix: Do not retry load/list operation is SFTP connection is broken + +When using restic with the SFTP backend, backend operations that load +a file or list files were retried even if the SFTP connection is broken. + +This has been fixed now. + +https://github.com/restic/restic/pull/5101 +https://forum.restic.net/t/restic-hanging-on-backup/8559/2 diff --git a/internal/backend/sftp/sftp.go b/internal/backend/sftp/sftp.go index efbd0c8d5..6b9620a36 100644 --- a/internal/backend/sftp/sftp.go +++ b/internal/backend/sftp/sftp.go @@ -421,6 +421,10 @@ func (r *SFTP) checkNoSpace(dir string, size int64, origErr error) error { // Load runs fn with a reader that yields the contents of the file at h at the // given offset. func (r *SFTP) Load(ctx context.Context, h backend.Handle, length int, offset int64, fn func(rd io.Reader) error) error { + if err := r.clientError(); err != nil { + return err + } + return util.DefaultLoad(ctx, h, length, offset, r.openReader, func(rd io.Reader) error { if length == 0 || !feature.Flag.Enabled(feature.BackendErrorRedesign) { return fn(rd) @@ -490,6 +494,10 @@ func (r *SFTP) Remove(_ context.Context, h backend.Handle) error { // List runs fn for each file in the backend which has the type t. When an // error occurs (or fn returns an error), List stops and returns it. func (r *SFTP) List(ctx context.Context, t backend.FileType, fn func(backend.FileInfo) error) error { + if err := r.clientError(); err != nil { + return err + } + basedir, subdirs := r.Basedir(t) walker := r.c.Walk(basedir) for {