2
2
mirror of https://github.com/octoleo/restic.git synced 2024-11-25 06:07:44 +00:00

restore: split downloadPack into smaller methods

This commit is contained in:
Michael Eischer 2024-01-07 12:00:32 +01:00
parent e4a7eb09ef
commit 9328f34d43

View File

@ -197,12 +197,13 @@ func (r *fileRestorer) restoreFiles(ctx context.Context) error {
return wg.Wait() return wg.Wait()
} }
func (r *fileRestorer) downloadPack(ctx context.Context, pack *packInfo) error { type blobToFileOffsetsMapping map[restic.ID]struct {
// calculate blob->[]files->[]offsets mappings
blobs := make(map[restic.ID]struct {
files map[*fileInfo][]int64 // file -> offsets (plural!) of the blob in the file files map[*fileInfo][]int64 // file -> offsets (plural!) of the blob in the file
}) }
func (r *fileRestorer) downloadPack(ctx context.Context, pack *packInfo) error {
// calculate blob->[]files->[]offsets mappings
blobs := make(blobToFileOffsetsMapping)
var blobList []restic.Blob var blobList []restic.Blob
for file := range pack.files { for file := range pack.files {
addBlob := func(blob restic.Blob, fileOffset int64) { addBlob := func(blob restic.Blob, fileOffset int64) {
@ -239,21 +240,50 @@ func (r *fileRestorer) downloadPack(ctx context.Context, pack *packInfo) error {
} }
} }
sanitizeError := func(file *fileInfo, err error) error { // track already processed blobs for precise error reporting
processedBlobs := restic.NewBlobSet()
err := r.downloadBlobs(ctx, pack.id, blobList, blobs, processedBlobs)
if err != nil {
// only report error for not yet processed blobs
affectedFiles := make(map[*fileInfo]struct{})
for _, blob := range blobList {
if processedBlobs.Has(blob.BlobHandle) {
continue
}
blob := blobs[blob.ID]
for file := range blob.files {
affectedFiles[file] = struct{}{}
}
}
for file := range affectedFiles {
if errFile := r.sanitizeError(file, err); errFile != nil {
return errFile
}
}
}
return nil
}
func (r *fileRestorer) sanitizeError(file *fileInfo, err error) error {
if err != nil { if err != nil {
err = r.Error(file.location, err) err = r.Error(file.location, err)
} }
return err return err
} }
// track already processed blobs for precise error reporting func (r *fileRestorer) downloadBlobs(ctx context.Context, packID restic.ID, blobList []restic.Blob,
processedBlobs := restic.NewBlobSet() blobs blobToFileOffsetsMapping, processedBlobs restic.BlobSet) error {
err := repository.StreamPack(ctx, r.packLoader, r.key, pack.id, blobList, func(h restic.BlobHandle, blobData []byte, err error) error {
return repository.StreamPack(ctx, r.packLoader, r.key, packID, blobList,
func(h restic.BlobHandle, blobData []byte, err error) error {
processedBlobs.Insert(h) processedBlobs.Insert(h)
blob := blobs[h.ID] blob := blobs[h.ID]
if err != nil { if err != nil {
for file := range blob.files { for file := range blob.files {
if errFile := sanitizeError(file, err); errFile != nil { if errFile := r.sanitizeError(file, err); errFile != nil {
return errFile return errFile
} }
} }
@ -285,7 +315,7 @@ func (r *fileRestorer) downloadPack(ctx context.Context, pack *packInfo) error {
return writeErr return writeErr
} }
err := sanitizeError(file, writeToFile()) err := r.sanitizeError(file, writeToFile())
if err != nil { if err != nil {
return err return err
} }
@ -293,26 +323,4 @@ func (r *fileRestorer) downloadPack(ctx context.Context, pack *packInfo) error {
} }
return nil return nil
}) })
if err != nil {
// only report error for not yet processed blobs
affectedFiles := make(map[*fileInfo]struct{})
for _, blob := range blobList {
if processedBlobs.Has(blob.BlobHandle) {
continue
}
blob := blobs[blob.ID]
for file := range blob.files {
affectedFiles[file] = struct{}{}
}
}
for file := range affectedFiles {
if errFile := sanitizeError(file, err); errFile != nil {
return errFile
}
}
}
return nil
} }