From 5767c65c624072ddd0982f83a7e6288e369cfe96 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Sun, 2 Aug 2020 12:16:03 +0200 Subject: [PATCH 1/2] delete: properly close fileChan if context is canceled --- cmd/restic/delete.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/cmd/restic/delete.go b/cmd/restic/delete.go index 26ca08196..4b9ac3e4f 100644 --- a/cmd/restic/delete.go +++ b/cmd/restic/delete.go @@ -25,16 +25,21 @@ const numDeleteWorkers = 8 func deleteFiles(gopts GlobalOptions, ignoreError bool, repo restic.Repository, fileList restic.IDSet, fileType restic.FileType) error { totalCount := len(fileList) fileChan := make(chan restic.ID) - go func() { + wg, ctx := errgroup.WithContext(gopts.ctx) + wg.Go(func() error { + defer close(fileChan) for id := range fileList { - fileChan <- id + select { + case fileChan <- id: + case <-ctx.Done(): + return nil + } } - close(fileChan) - }() + return nil + }) bar := newProgressMax(!gopts.JSON && !gopts.Quiet, uint64(totalCount), "files deleted") defer bar.Done() - wg, ctx := errgroup.WithContext(gopts.ctx) for i := 0; i < numDeleteWorkers; i++ { wg.Go(func() error { for id := range fileChan { From fd8bce818458f622bb5c40e6f296eb84aece1c1a Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Sat, 15 May 2021 23:06:12 +0200 Subject: [PATCH 2/2] backup: cleanly shutdown goroutines on error --- cmd/restic/cmd_backup.go | 12 +++++++----- cmd/restic/delete.go | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/cmd/restic/cmd_backup.go b/cmd/restic/cmd_backup.go index afe213732..a285f851d 100644 --- a/cmd/restic/cmd_backup.go +++ b/cmd/restic/cmd_backup.go @@ -708,15 +708,17 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina p.V("start backup on %v", targets) } _, id, err := arch.Snapshot(gopts.ctx, targets, snapshotOpts) - if err != nil { - return errors.Fatalf("unable to save snapshot: %v", err) - } // cleanly shutdown all running goroutines t.Kill(nil) // let's see if one returned an error - err = t.Wait() + werr := t.Wait() + + // return original error + if err != nil { + return errors.Fatalf("unable to save snapshot: %v", err) + } // Report finished execution p.Finish(id) @@ -728,5 +730,5 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina } // Return error if any - return err + return werr } diff --git a/cmd/restic/delete.go b/cmd/restic/delete.go index 4b9ac3e4f..98dd91ece 100644 --- a/cmd/restic/delete.go +++ b/cmd/restic/delete.go @@ -32,7 +32,7 @@ func deleteFiles(gopts GlobalOptions, ignoreError bool, repo restic.Repository, select { case fileChan <- id: case <-ctx.Done(): - return nil + return ctx.Err() } } return nil