cmd/restic: Add lock handling, interrupt cleanup

This commit is contained in:
Alexander Neumann 2015-06-27 15:05:20 +02:00
parent 65a0def949
commit 13e9a35f96
11 changed files with 100 additions and 22 deletions

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

80
cmd/restic/lock.go Normal file
View File

@ -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)
}
}