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 { if !gopts.JSON {
progressPrinter.V("lock repository") progressPrinter.V("lock repository")
} }
lock, err := lockRepo(ctx, repo) lock, ctx, err := lockRepo(ctx, repo)
defer unlockRepo(lock) defer unlockRepo(lock)
if err != nil { if err != nil {
return err return err

View File

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

View File

@ -210,7 +210,8 @@ func runCheck(ctx context.Context, opts CheckOptions, gopts GlobalOptions, args
if !gopts.NoLock { if !gopts.NoLock {
Verbosef("create exclusive lock for repository\n") 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) defer unlockRepo(lock)
if err != nil { if err != nil {
return err return err

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -209,7 +209,7 @@ func runKey(ctx context.Context, gopts GlobalOptions, args []string) error {
switch args[0] { switch args[0] {
case "list": case "list":
lock, err := lockRepo(ctx, repo) lock, ctx, err := lockRepo(ctx, repo)
defer unlockRepo(lock) defer unlockRepo(lock)
if err != nil { if err != nil {
return err return err
@ -217,7 +217,7 @@ func runKey(ctx context.Context, gopts GlobalOptions, args []string) error {
return listKeys(ctx, repo, gopts) return listKeys(ctx, repo, gopts)
case "add": case "add":
lock, err := lockRepo(ctx, repo) lock, ctx, err := lockRepo(ctx, repo)
defer unlockRepo(lock) defer unlockRepo(lock)
if err != nil { if err != nil {
return err return err
@ -225,7 +225,7 @@ func runKey(ctx context.Context, gopts GlobalOptions, args []string) error {
return addKey(ctx, repo, gopts) return addKey(ctx, repo, gopts)
case "remove": case "remove":
lock, err := lockRepoExclusive(ctx, repo) lock, ctx, err := lockRepoExclusive(ctx, repo)
defer unlockRepo(lock) defer unlockRepo(lock)
if err != nil { if err != nil {
return err return err
@ -238,7 +238,7 @@ func runKey(ctx context.Context, gopts GlobalOptions, args []string) error {
return deleteKey(ctx, repo, id) return deleteKey(ctx, repo, id)
case "passwd": case "passwd":
lock, err := lockRepoExclusive(ctx, repo) lock, ctx, err := lockRepoExclusive(ctx, repo)
defer unlockRepo(lock) defer unlockRepo(lock)
if err != nil { if err != nil {
return err 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" { if !opts.NoLock && args[0] != "locks" {
lock, err := lockRepo(ctx, repo) var lock *restic.Lock
lock, ctx, err = lockRepo(ctx, repo)
defer unlockRepo(lock) defer unlockRepo(lock)
if err != nil { if err != nil {
return err return err

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -110,7 +110,8 @@ func runTag(ctx context.Context, opts TagOptions, gopts GlobalOptions, args []st
if !gopts.NoLock { if !gopts.NoLock {
Verbosef("create exclusive lock for repository\n") 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) defer unlockRepo(lock)
if err != nil { if err != nil {
return err return err

View File

@ -19,15 +19,15 @@ var globalLocks struct {
sync.Once 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) 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) 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 // make sure that a repository is unlocked properly and after cancel() was
// called by the cleanup handler in global.go // called by the cleanup handler in global.go
globalLocks.Do(func() { globalLocks.Do(func() {
@ -41,7 +41,7 @@ func lockRepository(ctx context.Context, repo *repository.Repository, exclusive
lock, err := lockFn(ctx, repo) lock, err := lockFn(ctx, repo)
if err != nil { 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) 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.locks = append(globalLocks.locks, lock)
globalLocks.Unlock() globalLocks.Unlock()
return lock, err return lock, ctx, err
} }
var refreshInterval = 5 * time.Minute var refreshInterval = 5 * time.Minute