diff --git a/cmd/restic/cmd_backup.go b/cmd/restic/cmd_backup.go index a20c4ebc7..32d486329 100644 --- a/cmd/restic/cmd_backup.go +++ b/cmd/restic/cmd_backup.go @@ -220,8 +220,8 @@ func (cmd CmdBackup) Execute(args []string) error { return err } - lock, err := restic.NewLock(repo) - defer lock.Unlock() + lock, err := lockRepo(repo) + defer unlockRepo(lock) if err != nil { return err } diff --git a/cmd/restic/cmd_cache.go b/cmd/restic/cmd_cache.go index de0efddb1..39733b997 100644 --- a/cmd/restic/cmd_cache.go +++ b/cmd/restic/cmd_cache.go @@ -34,8 +34,8 @@ func (cmd CmdCache) Execute(args []string) error { return err } - lock, err := restic.NewLock(repo) - defer lock.Unlock() + lock, err := lockRepo(repo) + defer unlockRepo(lock) if err != nil { return err } diff --git a/cmd/restic/cmd_cat.go b/cmd/restic/cmd_cat.go index 36b4aa49a..6f22670ea 100644 --- a/cmd/restic/cmd_cat.go +++ b/cmd/restic/cmd_cat.go @@ -42,8 +42,8 @@ func (cmd CmdCat) Execute(args []string) error { return err } - lock, err := restic.NewLock(repo) - defer lock.Unlock() + lock, err := lockRepo(repo) + defer unlockRepo(lock) if err != nil { return err } diff --git a/cmd/restic/cmd_dump.go b/cmd/restic/cmd_dump.go index e0c4ea702..9a12ea308 100644 --- a/cmd/restic/cmd_dump.go +++ b/cmd/restic/cmd_dump.go @@ -109,8 +109,8 @@ func (cmd CmdDump) Execute(args []string) error { return err } - lock, err := restic.NewLock(repo) - defer lock.Unlock() + lock, err := lockRepo(repo) + defer unlockRepo(lock) if err != nil { return err } diff --git a/cmd/restic/cmd_find.go b/cmd/restic/cmd_find.go index 4e28e2041..33b91fe43 100644 --- a/cmd/restic/cmd_find.go +++ b/cmd/restic/cmd_find.go @@ -162,8 +162,8 @@ func (c CmdFind) Execute(args []string) error { return err } - lock, err := restic.NewLock(repo) - defer lock.Unlock() + lock, err := lockRepo(repo) + defer unlockRepo(lock) if err != nil { return err } diff --git a/cmd/restic/cmd_fsck.go b/cmd/restic/cmd_fsck.go index 76e0a1f8b..b4e8d3e0d 100644 --- a/cmd/restic/cmd_fsck.go +++ b/cmd/restic/cmd_fsck.go @@ -195,8 +195,8 @@ func (cmd CmdFsck) Execute(args []string) error { return err } - lock, err := restic.NewExclusiveLock(repo) - defer lock.Unlock() + lock, err := lockRepoExclusive(repo) + defer unlockRepo(lock) if err != nil { return err } diff --git a/cmd/restic/cmd_key.go b/cmd/restic/cmd_key.go index 47f5333c4..a4a3d7366 100644 --- a/cmd/restic/cmd_key.go +++ b/cmd/restic/cmd_key.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" - "github.com/restic/restic" "github.com/restic/restic/backend" "github.com/restic/restic/repository" ) @@ -122,8 +121,8 @@ func (cmd CmdKey) Execute(args []string) error { return err } - lock, err := restic.NewExclusiveLock(repo) - defer lock.Unlock() + lock, err := lockRepoExclusive(repo) + defer unlockRepo(lock) if err != nil { return err } diff --git a/cmd/restic/cmd_list.go b/cmd/restic/cmd_list.go index dda14aca7..c8ea6c65c 100644 --- a/cmd/restic/cmd_list.go +++ b/cmd/restic/cmd_list.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" - "github.com/restic/restic" "github.com/restic/restic/backend" ) @@ -36,8 +35,8 @@ func (cmd CmdList) Execute(args []string) error { return err } - lock, err := restic.NewLock(repo) - defer lock.Unlock() + lock, err := lockRepo(repo) + defer unlockRepo(lock) if err != nil { return err } diff --git a/cmd/restic/cmd_restore.go b/cmd/restic/cmd_restore.go index e2e7344a8..393d0347d 100644 --- a/cmd/restic/cmd_restore.go +++ b/cmd/restic/cmd_restore.go @@ -35,8 +35,8 @@ func (cmd CmdRestore) Execute(args []string) error { return err } - lock, err := restic.NewLock(repo) - defer lock.Unlock() + lock, err := lockRepo(repo) + defer unlockRepo(lock) if err != nil { return err } diff --git a/cmd/restic/cmd_snapshots.go b/cmd/restic/cmd_snapshots.go index 1947ed476..38e2046ad 100644 --- a/cmd/restic/cmd_snapshots.go +++ b/cmd/restic/cmd_snapshots.go @@ -99,8 +99,8 @@ func (cmd CmdSnapshots) Execute(args []string) error { return err } - lock, err := restic.NewLock(repo) - defer lock.Unlock() + lock, err := lockRepo(repo) + defer unlockRepo(lock) if err != nil { return err } diff --git a/cmd/restic/lock.go b/cmd/restic/lock.go new file mode 100644 index 000000000..e7d6b9976 --- /dev/null +++ b/cmd/restic/lock.go @@ -0,0 +1,80 @@ +package main + +import ( + "fmt" + "os" + "os/signal" + "syscall" + + "github.com/restic/restic" + "github.com/restic/restic/debug" + "github.com/restic/restic/repository" +) + +var globalLocks []*restic.Lock + +func lockRepo(repo *repository.Repository) (*restic.Lock, error) { + lock, err := restic.NewLock(repo) + if err != nil { + return nil, err + } + + globalLocks = append(globalLocks, lock) + + return lock, err +} + +func lockRepoExclusive(repo *repository.Repository) (*restic.Lock, error) { + lock, err := restic.NewExclusiveLock(repo) + if err != nil { + return nil, err + } + + globalLocks = append(globalLocks, lock) + + return lock, err +} + +func unlockRepo(lock *restic.Lock) error { + if err := lock.Unlock(); err != nil { + return err + } + + for i := 0; i < len(globalLocks); i++ { + if lock == globalLocks[i] { + globalLocks = append(globalLocks[:i], globalLocks[i+1:]...) + return nil + } + } + + return nil +} + +func unlockAll() error { + debug.Log("unlockAll", "unlocking %d locks", len(globalLocks)) + for _, lock := range globalLocks { + if err := lock.Unlock(); err != nil { + return err + } + } + + return nil +} + +func init() { + c := make(chan os.Signal) + signal.Notify(c, syscall.SIGINT) + + go CleanupHandler(c) +} + +// CleanupHandler handles the SIGINT signal. +func CleanupHandler(c <-chan os.Signal) { + for s := range c { + debug.Log("CleanupHandler", "signal %v received, cleaning up", s) + fmt.Println("\x1b[2KInterrupt received, cleaning up") + unlockAll() + fmt.Println("exiting") + os.Exit(0) + } +}