From 76c06c5f2ad2f53aa581c60803dd6f1c522c2103 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sat, 11 Feb 2017 14:13:58 +0100 Subject: [PATCH 1/5] Add check for modified index --- src/restic/checker/checker_test.go | 42 ++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/restic/checker/checker_test.go b/src/restic/checker/checker_test.go index 7c93623d9..65e764137 100644 --- a/src/restic/checker/checker_test.go +++ b/src/restic/checker/checker_test.go @@ -179,6 +179,48 @@ func TestUnreferencedBlobs(t *testing.T) { test.Equals(t, unusedBlobsBySnapshot, blobs) } +func TestModifiedIndex(t *testing.T) { + repodir, cleanup := test.Env(t, checkerTestData) + defer cleanup() + + repo := repository.TestOpenLocal(t, repodir) + + done := make(chan struct{}) + defer close(done) + + h := restic.Handle{ + Type: restic.IndexFile, + Name: "90f838b4ac28735fda8644fe6a08dbc742e57aaf81b30977b4fefa357010eafd", + } + f, err := repo.Backend().Load(h, 0, 0) + test.OK(t, err) + + // save the index again with a modified name so that the hash doesn't match + // the content any more + h2 := restic.Handle{ + Type: restic.IndexFile, + Name: "80f838b4ac28735fda8644fe6a08dbc742e57aaf81b30977b4fefa357010eafd", + } + err = repo.Backend().Save(h2, f) + test.OK(t, err) + + test.OK(t, f.Close()) + + chkr := checker.New(repo) + hints, errs := chkr.LoadIndex() + if len(errs) == 0 { + t.Fatalf("expected errors not found") + } + + for _, err := range errs { + t.Logf("found expected error %v", err) + } + + if len(hints) > 0 { + t.Errorf("expected no hints, got %v: %v", len(hints), hints) + } +} + var checkerDuplicateIndexTestData = filepath.Join("testdata", "duplicate-packs-in-index-test-repo.tar.gz") func TestDuplicatePacksInIndex(t *testing.T) { From b40aa66985699fbfeb3a62b3e2f67a69a4a0c39e Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sat, 11 Feb 2017 14:22:04 +0100 Subject: [PATCH 2/5] errors: Add method Wrapf --- src/restic/errors/wrap.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/restic/errors/wrap.go b/src/restic/errors/wrap.go index 5906bd617..99d6e88ba 100644 --- a/src/restic/errors/wrap.go +++ b/src/restic/errors/wrap.go @@ -18,3 +18,7 @@ var Errorf = errors.Errorf // Wrap wraps an error retrieved from outside of restic. Wrapped so that this // package does not appear in the stack trace. var Wrap = errors.Wrap + +// Wrapf returns an error annotating err with the format specifier. If err is +// nil, Wrapf returns nil. +var Wrapf = errors.Wrapf From 7797e084f9f3139371d4bd0b043fe3e84ff84d3c Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sat, 11 Feb 2017 14:22:14 +0100 Subject: [PATCH 3/5] checker: Pass on error loading an index --- src/restic/checker/checker.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/restic/checker/checker.go b/src/restic/checker/checker.go index 7a7170499..1fd73888c 100644 --- a/src/restic/checker/checker.go +++ b/src/restic/checker/checker.go @@ -80,6 +80,7 @@ func (c *Checker) LoadIndex() (hints []error, errs []error) { debug.Log("Start") type indexRes struct { Index *repository.Index + err error ID string } @@ -95,39 +96,40 @@ func (c *Checker) LoadIndex() (hints []error, errs []error) { idx, err = repository.LoadIndexWithDecoder(c.repo, id, repository.DecodeOldIndex) } - if err != nil { - return err - } + err = errors.Wrapf(err, "error loading index %v", id.Str()) select { - case indexCh <- indexRes{Index: idx, ID: id.String()}: + case indexCh <- indexRes{Index: idx, ID: id.String(), err: err}: case <-done: } return nil } - var perr error go func() { defer close(indexCh) debug.Log("start loading indexes in parallel") - perr = repository.FilesInParallel(c.repo.Backend(), restic.IndexFile, defaultParallelism, + err := repository.FilesInParallel(c.repo.Backend(), restic.IndexFile, defaultParallelism, repository.ParallelWorkFuncParseID(worker)) - debug.Log("loading indexes finished, error: %v", perr) + debug.Log("loading indexes finished, error: %v", err) + if err != nil { + panic(err) + } }() done := make(chan struct{}) defer close(done) - if perr != nil { - errs = append(errs, perr) - return hints, errs - } - packToIndex := make(map[restic.ID]restic.IDSet) for res := range indexCh { - debug.Log("process index %v", res.ID) + debug.Log("process index %v, err %v", res.ID, res.err) + + if res.err != nil { + errs = append(errs, res.err) + continue + } + idxID, err := restic.ParseID(res.ID) if err != nil { errs = append(errs, errors.Errorf("unable to parse as index ID: %v", res.ID)) @@ -154,8 +156,6 @@ func (c *Checker) LoadIndex() (hints []error, errs []error) { debug.Log("%d blobs processed", cnt) } - debug.Log("done, error %v", perr) - debug.Log("checking for duplicate packs") for packID := range c.packs { debug.Log(" check pack %v: contained in %d indexes", packID.Str(), len(packToIndex[packID])) From 0492eabff1a973f57049295d1477e8cace93a088 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sat, 11 Feb 2017 14:24:11 +0100 Subject: [PATCH 4/5] Improve error messages --- src/restic/repository/repository.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/restic/repository/repository.go b/src/restic/repository/repository.go index 45046dac2..fe10ef9bf 100644 --- a/src/restic/repository/repository.go +++ b/src/restic/repository/repository.go @@ -56,12 +56,12 @@ func (r *Repository) LoadAndDecrypt(t restic.FileType, id restic.ID) ([]byte, er h := restic.Handle{Type: t, Name: id.String()} buf, err := backend.LoadAll(r.be, h) if err != nil { - debug.Log("error loading %v: %v", id.Str(), err) + debug.Log("error loading %v: %v", h, err) return nil, err } if t != restic.ConfigFile && !restic.Hash(buf).Equal(id) { - return nil, errors.New("invalid data returned") + return nil, errors.Errorf("%v: invalid data returned", h) } // decrypt From 8c34eaad15261ae5717e1ac6074e4d823dae7973 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sat, 11 Feb 2017 14:28:15 +0100 Subject: [PATCH 5/5] Improve error message --- src/restic/repository/repository.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/restic/repository/repository.go b/src/restic/repository/repository.go index fe10ef9bf..dc3536d06 100644 --- a/src/restic/repository/repository.go +++ b/src/restic/repository/repository.go @@ -61,7 +61,7 @@ func (r *Repository) LoadAndDecrypt(t restic.FileType, id restic.ID) ([]byte, er } if t != restic.ConfigFile && !restic.Hash(buf).Equal(id) { - return nil, errors.Errorf("%v: invalid data returned", h) + return nil, errors.Errorf("load %v: invalid data returned", h) } // decrypt