Prepare for context bound to lock lifetime

This commit is contained in:
Michael Eischer 2021-10-31 23:19:27 +01:00
parent 985722b102
commit 928914f821
21 changed files with 47 additions and 32 deletions

View File

@ -586,7 +586,7 @@ func runBackup(ctx context.Context, opts BackupOptions, gopts GlobalOptions, ter
if !gopts.JSON {
progressPrinter.V("lock repository")
}
lock, err := lockRepo(ctx, repo)
lock, ctx, err := lockRepo(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err

View File

@ -44,12 +44,12 @@ func runCat(ctx context.Context, gopts GlobalOptions, args []string) error {
}
if !gopts.NoLock {
lock, err := lockRepo(ctx, repo)
var lock *restic.Lock
lock, ctx, err = lockRepo(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err
}
defer unlockRepo(lock)
}
tpe := args[0]

View File

@ -210,7 +210,8 @@ func runCheck(ctx context.Context, opts CheckOptions, gopts GlobalOptions, args
if !gopts.NoLock {
Verbosef("create exclusive lock for repository\n")
lock, err := lockRepoExclusive(ctx, repo)
var lock *restic.Lock
lock, ctx, err = lockRepoExclusive(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err

View File

@ -73,14 +73,15 @@ func runCopy(ctx context.Context, opts CopyOptions, gopts GlobalOptions, args []
}
if !gopts.NoLock {
srcLock, err := lockRepo(ctx, srcRepo)
var srcLock *restic.Lock
srcLock, ctx, err = lockRepo(ctx, srcRepo)
defer unlockRepo(srcLock)
if err != nil {
return err
}
}
dstLock, err := lockRepo(ctx, dstRepo)
dstLock, ctx, err := lockRepo(ctx, dstRepo)
defer unlockRepo(dstLock)
if err != nil {
return err

View File

@ -152,7 +152,8 @@ func runDebugDump(ctx context.Context, gopts GlobalOptions, args []string) error
}
if !gopts.NoLock {
lock, err := lockRepo(ctx, repo)
var lock *restic.Lock
lock, ctx, err = lockRepo(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err
@ -453,7 +454,8 @@ func runDebugExamine(ctx context.Context, gopts GlobalOptions, args []string) er
}
if !gopts.NoLock {
lock, err := lockRepo(ctx, repo)
var lock *restic.Lock
lock, ctx, err = lockRepo(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err

View File

@ -332,7 +332,8 @@ func runDiff(ctx context.Context, opts DiffOptions, gopts GlobalOptions, args []
}
if !gopts.NoLock {
lock, err := lockRepo(ctx, repo)
var lock *restic.Lock
lock, ctx, err = lockRepo(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err

View File

@ -131,7 +131,8 @@ func runDump(ctx context.Context, opts DumpOptions, gopts GlobalOptions, args []
}
if !gopts.NoLock {
lock, err := lockRepo(ctx, repo)
var lock *restic.Lock
lock, ctx, err = lockRepo(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err

View File

@ -574,7 +574,8 @@ func runFind(ctx context.Context, opts FindOptions, gopts GlobalOptions, args []
}
if !gopts.NoLock {
lock, err := lockRepo(ctx, repo)
var lock *restic.Lock
lock, ctx, err = lockRepo(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err

View File

@ -115,7 +115,8 @@ func runForget(ctx context.Context, opts ForgetOptions, gopts GlobalOptions, arg
}
if !opts.DryRun || !gopts.NoLock {
lock, err := lockRepoExclusive(ctx, repo)
var lock *restic.Lock
lock, ctx, err = lockRepoExclusive(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err

View File

@ -209,7 +209,7 @@ func runKey(ctx context.Context, gopts GlobalOptions, args []string) error {
switch args[0] {
case "list":
lock, err := lockRepo(ctx, repo)
lock, ctx, err := lockRepo(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err
@ -217,7 +217,7 @@ func runKey(ctx context.Context, gopts GlobalOptions, args []string) error {
return listKeys(ctx, repo, gopts)
case "add":
lock, err := lockRepo(ctx, repo)
lock, ctx, err := lockRepo(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err
@ -225,7 +225,7 @@ func runKey(ctx context.Context, gopts GlobalOptions, args []string) error {
return addKey(ctx, repo, gopts)
case "remove":
lock, err := lockRepoExclusive(ctx, repo)
lock, ctx, err := lockRepoExclusive(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err
@ -238,7 +238,7 @@ func runKey(ctx context.Context, gopts GlobalOptions, args []string) error {
return deleteKey(ctx, repo, id)
case "passwd":
lock, err := lockRepoExclusive(ctx, repo)
lock, ctx, err := lockRepoExclusive(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err

View File

@ -42,7 +42,8 @@ func runList(ctx context.Context, cmd *cobra.Command, opts GlobalOptions, args [
}
if !opts.NoLock && args[0] != "locks" {
lock, err := lockRepo(ctx, repo)
var lock *restic.Lock
lock, ctx, err = lockRepo(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err

View File

@ -122,7 +122,7 @@ func runMigrate(ctx context.Context, opts MigrateOptions, gopts GlobalOptions, a
return err
}
lock, err := lockRepoExclusive(ctx, repo)
lock, ctx, err := lockRepoExclusive(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err

View File

@ -13,6 +13,7 @@ import (
"github.com/restic/restic/internal/debug"
"github.com/restic/restic/internal/errors"
"github.com/restic/restic/internal/restic"
resticfs "github.com/restic/restic/internal/fs"
"github.com/restic/restic/internal/fuse"
@ -121,7 +122,8 @@ func runMount(ctx context.Context, opts MountOptions, gopts GlobalOptions, args
}
if !gopts.NoLock {
lock, err := lockRepo(ctx, repo)
var lock *restic.Lock
lock, ctx, err = lockRepo(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err

View File

@ -165,7 +165,7 @@ func runPrune(ctx context.Context, opts PruneOptions, gopts GlobalOptions) error
opts.unsafeRecovery = true
}
lock, err := lockRepoExclusive(ctx, repo)
lock, ctx, err := lockRepoExclusive(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err

View File

@ -48,7 +48,7 @@ func runRebuildIndex(ctx context.Context, opts RebuildIndexOptions, gopts Global
return err
}
lock, err := lockRepoExclusive(ctx, repo)
lock, ctx, err := lockRepoExclusive(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err

View File

@ -46,7 +46,7 @@ func runRecover(ctx context.Context, gopts GlobalOptions) error {
return err
}
lock, err := lockRepo(ctx, repo)
lock, ctx, err := lockRepo(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err

View File

@ -123,7 +123,8 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions, a
}
if !gopts.NoLock {
lock, err := lockRepo(ctx, repo)
var lock *restic.Lock
lock, ctx, err = lockRepo(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err

View File

@ -64,7 +64,8 @@ func runSnapshots(ctx context.Context, opts SnapshotOptions, gopts GlobalOptions
}
if !gopts.NoLock {
lock, err := lockRepo(ctx, repo)
var lock *restic.Lock
lock, ctx, err = lockRepo(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err

View File

@ -80,7 +80,8 @@ func runStats(ctx context.Context, gopts GlobalOptions, args []string) error {
}
if !gopts.NoLock {
lock, err := lockRepo(ctx, repo)
var lock *restic.Lock
lock, ctx, err = lockRepo(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err

View File

@ -110,7 +110,8 @@ func runTag(ctx context.Context, opts TagOptions, gopts GlobalOptions, args []st
if !gopts.NoLock {
Verbosef("create exclusive lock for repository\n")
lock, err := lockRepoExclusive(ctx, repo)
var lock *restic.Lock
lock, ctx, err = lockRepoExclusive(ctx, repo)
defer unlockRepo(lock)
if err != nil {
return err

View File

@ -19,15 +19,15 @@ var globalLocks struct {
sync.Once
}
func lockRepo(ctx context.Context, repo *repository.Repository) (*restic.Lock, error) {
func lockRepo(ctx context.Context, repo *repository.Repository) (*restic.Lock, context.Context, error) {
return lockRepository(ctx, repo, false)
}
func lockRepoExclusive(ctx context.Context, repo *repository.Repository) (*restic.Lock, error) {
func lockRepoExclusive(ctx context.Context, repo *repository.Repository) (*restic.Lock, context.Context, error) {
return lockRepository(ctx, repo, true)
}
func lockRepository(ctx context.Context, repo *repository.Repository, exclusive bool) (*restic.Lock, error) {
func lockRepository(ctx context.Context, repo *repository.Repository, exclusive bool) (*restic.Lock, context.Context, error) {
// make sure that a repository is unlocked properly and after cancel() was
// called by the cleanup handler in global.go
globalLocks.Do(func() {
@ -41,7 +41,7 @@ func lockRepository(ctx context.Context, repo *repository.Repository, exclusive
lock, err := lockFn(ctx, repo)
if err != nil {
return nil, errors.WithMessage(err, "unable to create lock in backend")
return nil, ctx, errors.WithMessage(err, "unable to create lock in backend")
}
debug.Log("create lock %p (exclusive %v)", lock, exclusive)
@ -57,7 +57,7 @@ func lockRepository(ctx context.Context, repo *repository.Repository, exclusive
globalLocks.locks = append(globalLocks.locks, lock)
globalLocks.Unlock()
return lock, err
return lock, ctx, err
}
var refreshInterval = 5 * time.Minute