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:
parent
da338d5aa8
commit
c9a4a95848
@ -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()
|
||||
}
|
||||
|
@ -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)}:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user