forked from TrueCloudLab/restic
Merge pull request #261 from restic/fix-260
locks: fix testing stale locks created on other hosts
This commit is contained in:
commit
cd4cc1daec
2 changed files with 63 additions and 22 deletions
28
lock.go
28
lock.go
|
@ -194,10 +194,30 @@ func (l *Lock) Stale() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we can reach the process retaining the lock
|
hn, err := os.Hostname()
|
||||||
exists := l.processExists()
|
if err != nil {
|
||||||
if !exists {
|
debug.Log("Lock.Stale", "unable to find current hostnanme: %v", err)
|
||||||
debug.Log("Lock.Stale", "could not reach process, %d, lock is probably stale\n", l.PID)
|
// since we cannot find the current hostname, assume that the lock is
|
||||||
|
// not stale.
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if hn != l.Hostname {
|
||||||
|
// lock was created on a different host, assume the lock is not stale.
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
proc, err := os.FindProcess(l.PID)
|
||||||
|
defer proc.Release()
|
||||||
|
if err != nil {
|
||||||
|
debug.Log("Lock.Stale", "error searching for process %d: %v\n", l.PID, err)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
debug.Log("Lock.Stale", "sending SIGHUP to process %d\n", l.PID)
|
||||||
|
err = proc.Signal(syscall.SIGHUP)
|
||||||
|
if err != nil {
|
||||||
|
debug.Log("Lock.Stale", "signal error: %v, lock is probably stale\n", err)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
25
lock_test.go
25
lock_test.go
|
@ -93,7 +93,12 @@ func TestExclusiveLockOnLockedRepo(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func createFakeLock(repo *repository.Repository, t time.Time, pid int) (backend.ID, error) {
|
func createFakeLock(repo *repository.Repository, t time.Time, pid int) (backend.ID, error) {
|
||||||
newLock := &restic.Lock{Time: t, PID: pid}
|
hostname, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
return backend.ID{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
newLock := &restic.Lock{Time: t, PID: pid, Hostname: hostname}
|
||||||
return repo.SaveJSONUnpacked(backend.Lock, &newLock)
|
return repo.SaveJSONUnpacked(backend.Lock, &newLock)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,40 +109,56 @@ func removeLock(repo *repository.Repository, id backend.ID) error {
|
||||||
var staleLockTests = []struct {
|
var staleLockTests = []struct {
|
||||||
timestamp time.Time
|
timestamp time.Time
|
||||||
stale bool
|
stale bool
|
||||||
|
staleOnOtherHost bool
|
||||||
pid int
|
pid int
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
timestamp: time.Now(),
|
timestamp: time.Now(),
|
||||||
stale: false,
|
stale: false,
|
||||||
|
staleOnOtherHost: false,
|
||||||
pid: os.Getpid(),
|
pid: os.Getpid(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
timestamp: time.Now().Add(-time.Hour),
|
timestamp: time.Now().Add(-time.Hour),
|
||||||
stale: true,
|
stale: true,
|
||||||
|
staleOnOtherHost: true,
|
||||||
pid: os.Getpid(),
|
pid: os.Getpid(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
timestamp: time.Now().Add(3 * time.Minute),
|
timestamp: time.Now().Add(3 * time.Minute),
|
||||||
stale: false,
|
stale: false,
|
||||||
|
staleOnOtherHost: false,
|
||||||
pid: os.Getpid(),
|
pid: os.Getpid(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
timestamp: time.Now(),
|
timestamp: time.Now(),
|
||||||
stale: true,
|
stale: true,
|
||||||
pid: os.Getpid() + 500000,
|
staleOnOtherHost: false,
|
||||||
|
pid: os.Getpid() + 500,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLockStale(t *testing.T) {
|
func TestLockStale(t *testing.T) {
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
OK(t, err)
|
||||||
|
|
||||||
|
otherHostname := "other-" + hostname
|
||||||
|
|
||||||
for i, test := range staleLockTests {
|
for i, test := range staleLockTests {
|
||||||
lock := restic.Lock{
|
lock := restic.Lock{
|
||||||
Time: test.timestamp,
|
Time: test.timestamp,
|
||||||
PID: test.pid,
|
PID: test.pid,
|
||||||
|
Hostname: hostname,
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert(t, lock.Stale() == test.stale,
|
Assert(t, lock.Stale() == test.stale,
|
||||||
"TestStaleLock: test %d failed: expected stale: %v, got %v",
|
"TestStaleLock: test %d failed: expected stale: %v, got %v",
|
||||||
i, test.stale, !test.stale)
|
i, test.stale, !test.stale)
|
||||||
|
|
||||||
|
lock.Hostname = otherHostname
|
||||||
|
Assert(t, lock.Stale() == test.staleOnOtherHost,
|
||||||
|
"TestStaleLock: test %d failed: expected staleOnOtherHost: %v, got %v",
|
||||||
|
i, test.staleOnOtherHost, !test.staleOnOtherHost)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue