Merge pull request #1653 from restic/fix-1652

lock: Ignore invalid lock file
This commit is contained in:
Alexander Neumann 2018-03-05 20:49:03 +01:00
commit 6f3c23eba7
2 changed files with 18 additions and 16 deletions

View file

@ -0,0 +1,9 @@
Bugfix: Ignore/remove invalid lock files
This corrects a bug introduced recently: When an invalid lock file in the repo
is encountered (e.g. if the file is empty), the code used to ignore that, but
now returns the error. Now, invalid files are ignored for the normal lock
check, and removed when `restic unlock --remove-all` is run.
https://github.com/restic/restic/issues/1652
https://github.com/restic/restic/pull/1653

View file

@ -138,13 +138,15 @@ func (l *Lock) fillUserInfo() error {
// non-exclusive lock is to be created, an error is only returned when an
// exclusive lock is found.
func (l *Lock) checkForOtherLocks(ctx context.Context) error {
return eachLock(ctx, l.repo, func(id ID, lock *Lock, err error) error {
return l.repo.List(ctx, LockFile, func(id ID, size int64) error {
if l.lockID != nil && id.Equal(*l.lockID) {
return nil
}
// ignore locks that cannot be loaded
lock, err := LoadLock(ctx, l.repo, id)
if err != nil {
// ignore locks that cannot be loaded
debug.Log("ignore lock %v: %v", id, err)
return nil
}
@ -160,17 +162,6 @@ func (l *Lock) checkForOtherLocks(ctx context.Context) error {
})
}
func eachLock(ctx context.Context, repo Repository, f func(ID, *Lock, error) error) error {
return repo.List(ctx, LockFile, func(id ID, size int64) error {
lock, err := LoadLock(ctx, repo, id)
if err != nil {
return err
}
return f(id, lock, err)
})
}
// createLock acquires the lock by creating a file in the repository.
func (l *Lock) createLock(ctx context.Context) (ID, error) {
id, err := l.repo.SaveJSONUnpacked(ctx, LockFile, l)
@ -283,9 +274,11 @@ func LoadLock(ctx context.Context, repo Repository, id ID) (*Lock, error) {
// RemoveStaleLocks deletes all locks detected as stale from the repository.
func RemoveStaleLocks(ctx context.Context, repo Repository) error {
return eachLock(ctx, repo, func(id ID, lock *Lock, err error) error {
// ignore locks that cannot be loaded
return repo.List(ctx, LockFile, func(id ID, size int64) error {
lock, err := LoadLock(ctx, repo, id)
if err != nil {
// ignore locks that cannot be loaded
debug.Log("ignore lock %v: %v", id, err)
return nil
}
@ -299,7 +292,7 @@ func RemoveStaleLocks(ctx context.Context, repo Repository) error {
// RemoveAllLocks removes all locks forcefully.
func RemoveAllLocks(ctx context.Context, repo Repository) error {
return eachLock(ctx, repo, func(id ID, lock *Lock, err error) error {
return repo.List(ctx, LockFile, func(id ID, size int64) error {
return repo.Backend().Remove(context.TODO(), Handle{Type: LockFile, Name: id.String()})
})
}