mirror of
https://github.com/restic/restic.git
synced 2026-06-28 03:24:18 +00:00
find: fix fallback to index if pack cannot be listed
`find` would only look up completely missing pack files in the index. A still existing but broken pack file would result in an error.
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
Enhancement: `find --pack` can handle corrupted pack files
|
||||
|
||||
`restic find --pack <id>` can now also report affected snapshot if a packfile
|
||||
is corrupted but still present in the repository index.
|
||||
|
||||
https://github.com/restic/restic/pull/21883
|
||||
+21
-24
@@ -445,6 +445,17 @@ func (f *Finder) findIDs(ctx context.Context, sn *data.Snapshot) error {
|
||||
|
||||
var errAllPacksFound = errors.New("all packs found")
|
||||
|
||||
func (f *Finder) addBlobHandle(h restic.BlobHandle) {
|
||||
switch h.Type {
|
||||
case restic.DataBlob:
|
||||
f.blobIDs[h.ID.String()] = struct{}{}
|
||||
case restic.TreeBlob:
|
||||
f.treeIDs[h.ID.String()] = struct{}{}
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown type %v in blob list", h.Type.String()))
|
||||
}
|
||||
}
|
||||
|
||||
// packsToBlobs converts the list of pack IDs to a list of blob IDs that
|
||||
// belong to those packs.
|
||||
func (f *Finder) packsToBlobs(ctx context.Context, packs []string) error {
|
||||
@@ -468,37 +479,30 @@ func (f *Finder) packsToBlobs(ctx context.Context, packs []string) error {
|
||||
return nil
|
||||
}
|
||||
delete(packIDs, id.Str())
|
||||
} else {
|
||||
// forget found id
|
||||
delete(packIDs, idStr)
|
||||
packIDs[idStr] = struct{}{}
|
||||
}
|
||||
debug.Log("Found pack %s", idStr)
|
||||
handles, err := f.repo.ListPackHandles(ctx, id, size)
|
||||
if err != nil {
|
||||
return err
|
||||
// ignore error to allow fallback to index
|
||||
return nil
|
||||
}
|
||||
for _, h := range handles {
|
||||
switch h.Type {
|
||||
case restic.DataBlob:
|
||||
f.blobIDs[h.ID.String()] = struct{}{}
|
||||
case restic.TreeBlob:
|
||||
f.treeIDs[h.ID.String()] = struct{}{}
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown type %v in blob list", h.Type.String()))
|
||||
}
|
||||
f.addBlobHandle(h)
|
||||
}
|
||||
// forget successfully processed pack
|
||||
delete(packIDs, idStr)
|
||||
// Stop searching when all packs have been found
|
||||
if len(packIDs) == 0 {
|
||||
return errAllPacksFound
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil && err != errAllPacksFound {
|
||||
if err != nil && !errors.Is(err, errAllPacksFound) {
|
||||
return err
|
||||
}
|
||||
|
||||
if err != errAllPacksFound {
|
||||
if len(packIDs) > 0 {
|
||||
// try to resolve unknown pack ids from the index
|
||||
packIDs, err = f.indexPacksToBlobs(ctx, packIDs)
|
||||
if err != nil {
|
||||
@@ -516,7 +520,7 @@ func (f *Finder) packsToBlobs(ctx context.Context, packs []string) error {
|
||||
return errors.Fatalf("unable to find pack(s): %v", list)
|
||||
}
|
||||
|
||||
debug.Log("%d blobs found", len(f.blobIDs))
|
||||
debug.Log("%d blobs %v trees found", len(f.blobIDs), len(f.treeIDs))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -542,7 +546,7 @@ func (f *Finder) indexPacksToBlobs(ctx context.Context, packIDs map[string]struc
|
||||
}
|
||||
}
|
||||
if matchingID {
|
||||
f.blobIDs[pb.Handle().ID.String()] = struct{}{}
|
||||
f.addBlobHandle(pb.Handle())
|
||||
indexPackIDs[idStr] = struct{}{}
|
||||
}
|
||||
})
|
||||
@@ -554,13 +558,6 @@ func (f *Finder) indexPacksToBlobs(ctx context.Context, packIDs map[string]struc
|
||||
delete(packIDs, id)
|
||||
}
|
||||
|
||||
if len(indexPackIDs) > 0 {
|
||||
list := make([]string, 0, len(indexPackIDs))
|
||||
for h := range indexPackIDs {
|
||||
list = append(list, h)
|
||||
}
|
||||
f.printer.E("some pack files are missing from the repository, getting their blobs from the repository index: %v\n\n", list)
|
||||
}
|
||||
return packIDs, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user