forked from TrueCloudLab/restic
lock: add help message how to recover from invalid locks
This commit is contained in:
parent
c995b5be52
commit
20ad14e362
2 changed files with 27 additions and 0 deletions
|
@ -44,6 +44,9 @@ func lockRepository(ctx context.Context, repo restic.Repository, exclusive bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
lock, err := lockFn(ctx, repo)
|
lock, err := lockFn(ctx, repo)
|
||||||
|
if restic.IsInvalidLock(err) {
|
||||||
|
return nil, ctx, errors.Fatalf("%v\n\nthe `unlock --remove-all` command can be used to remove invalid locks. Make sure that no other restic process is accessing the repository when running the command", err)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, ctx, errors.Fatalf("unable to create lock in backend: %v", err)
|
return nil, ctx, errors.Fatalf("unable to create lock in backend: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,27 @@ func IsAlreadyLocked(err error) bool {
|
||||||
return errors.As(err, &e)
|
return errors.As(err, &e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// invalidLockError is returned when NewLock or NewExclusiveLock fail due
|
||||||
|
// to an invalid lock.
|
||||||
|
type invalidLockError struct {
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *invalidLockError) Error() string {
|
||||||
|
return fmt.Sprintf("invalid lock file: %v", e.err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *invalidLockError) Unwrap() error {
|
||||||
|
return e.err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsInvalidLock returns true iff err indicates that locking failed due to
|
||||||
|
// an invalid lock.
|
||||||
|
func IsInvalidLock(err error) bool {
|
||||||
|
var e *invalidLockError
|
||||||
|
return errors.As(err, &e)
|
||||||
|
}
|
||||||
|
|
||||||
// NewLock returns a new, non-exclusive lock for the repository. If an
|
// NewLock returns a new, non-exclusive lock for the repository. If an
|
||||||
// exclusive lock is already held by another process, it returns an error
|
// exclusive lock is already held by another process, it returns an error
|
||||||
// that satisfies IsAlreadyLocked.
|
// that satisfies IsAlreadyLocked.
|
||||||
|
@ -168,6 +189,9 @@ func (l *Lock) checkForOtherLocks(ctx context.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if errors.Is(err, ErrInvalidData) {
|
||||||
|
return &invalidLockError{err}
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue