2
2
mirror of https://github.com/octoleo/restic.git synced 2024-12-23 19:38:57 +00:00

check: suggest using repair packs to repair truncated pack files

Previously, that help message was only shown for running `check
--read-data`.
This commit is contained in:
Michael Eischer 2024-06-30 11:06:49 +02:00
parent da338d5aa8
commit c9a4a95848
2 changed files with 29 additions and 27 deletions

View File

@ -279,14 +279,24 @@ func runCheck(ctx context.Context, opts CheckOptions, gopts GlobalOptions, args
orphanedPacks := 0
errChan := make(chan error)
salvagePacks := restic.NewIDSet()
printer.P("check all packs\n")
go chkr.Packs(ctx, errChan)
for err := range errChan {
if checker.IsOrphanedPack(err) {
orphanedPacks++
printer.P("%v\n", err)
var packErr *checker.PackError
if errors.As(err, &packErr) {
if packErr.Orphaned {
orphanedPacks++
printer.P("%v\n", err)
} else {
if packErr.Truncated {
salvagePacks.Insert(packErr.ID)
}
errorsFound = true
printer.E("%v\n", err)
}
} else if err == checker.ErrLegacyLayout {
errorsFound = true
printer.E("error: repository still uses the S3 legacy layout\nYou must run `restic migrate s3legacy` to correct this.\n")
@ -355,26 +365,14 @@ func runCheck(ctx context.Context, opts CheckOptions, gopts GlobalOptions, args
go chkr.ReadPacks(ctx, packs, p, errChan)
var salvagePacks restic.IDs
for err := range errChan {
errorsFound = true
printer.E("%v\n", err)
if err, ok := err.(*repository.ErrPackData); ok {
salvagePacks = append(salvagePacks, err.PackID)
salvagePacks.Insert(err.PackID)
}
}
p.Done()
if len(salvagePacks) > 0 {
printer.E("\nThe repository contains damaged pack files. These damaged files must be removed to repair the repository. This can be done using the following commands. Please read the troubleshooting guide at https://restic.readthedocs.io/en/stable/077_troubleshooting.html first.\n\n")
var strIDs []string
for _, id := range salvagePacks {
strIDs = append(strIDs, id.String())
}
printer.E("restic repair packs %v\nrestic repair snapshots --forget\n\n", strings.Join(strIDs, " "))
printer.E("Damaged pack files can be caused by backend problem, hardware problems or bugs in restic. Please open an issue at https://github.com/restic/restic/issues/new/choose for further troubleshooting!\n")
}
}
switch {
@ -418,6 +416,16 @@ func runCheck(ctx context.Context, opts CheckOptions, gopts GlobalOptions, args
doReadData(packs)
}
if len(salvagePacks) > 0 {
printer.E("\nThe repository contains damaged pack files. These damaged files must be removed to repair the repository. This can be done using the following commands. Please read the troubleshooting guide at https://restic.readthedocs.io/en/stable/077_troubleshooting.html first.\n\n")
var strIDs []string
for id := range salvagePacks {
strIDs = append(strIDs, id.String())
}
printer.E("restic repair packs %v\nrestic repair snapshots --forget\n\n", strings.Join(strIDs, " "))
printer.E("Damaged pack files can be caused by backend problems, hardware problems or bugs in restic. Please open an issue at https://github.com/restic/restic/issues/new/choose for further troubleshooting!\n")
}
if ctx.Err() != nil {
return ctx.Err()
}

View File

@ -183,22 +183,16 @@ func (c *Checker) LoadIndex(ctx context.Context, p *progress.Counter) (hints []e
// PackError describes an error with a specific pack.
type PackError struct {
ID restic.ID
Orphaned bool
Err error
ID restic.ID
Orphaned bool
Truncated bool
Err error
}
func (e *PackError) Error() string {
return "pack " + e.ID.String() + ": " + e.Err.Error()
}
// IsOrphanedPack returns true if the error describes a pack which is not
// contained in any index.
func IsOrphanedPack(err error) bool {
var e *PackError
return errors.As(err, &e) && e.Orphaned
}
func isS3Legacy(b backend.Backend) bool {
be := backend.AsBackend[*s3.Backend](b)
return be != nil && be.Layout.Name() == "s3legacy"
@ -250,7 +244,7 @@ func (c *Checker) Packs(ctx context.Context, errChan chan<- error) {
select {
case <-ctx.Done():
return
case errChan <- &PackError{ID: id, Err: errors.Errorf("unexpected file size: got %d, expected %d", reposize, size)}:
case errChan <- &PackError{ID: id, Truncated: true, Err: errors.Errorf("unexpected file size: got %d, expected %d", reposize, size)}:
}
}
}