Rev 4736: (mbp) cope with empty lockdir info files in file:///home/pqm/archives/thelove/bzr/2.0/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Fri Feb 26 08:00:47 GMT 2010
At file:///home/pqm/archives/thelove/bzr/2.0/
------------------------------------------------------------
revno: 4736 [merge]
revision-id: pqm at pqm.ubuntu.com-20100226080046-0y4iuyq2skuzq19m
parent: pqm at pqm.ubuntu.com-20100219092738-4kfhdlnl9ff36cwg
parent: mbp at canonical.com-20100226065151-ayrxy1hd1et5f89y
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: 2.0
timestamp: Fri 2010-02-26 08:00:46 +0000
message:
(mbp) cope with empty lockdir info files
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/lockdir.py lockdir.py-20060220222025-98258adf27fbdda3
bzrlib/tests/test_lockdir.py test_lockdir.py-20060220222025-33d4221569a3d600
=== modified file 'NEWS'
--- a/NEWS 2010-02-19 07:13:45 +0000
+++ b/NEWS 2010-02-25 07:34:06 +0000
@@ -17,6 +17,11 @@
* Avoid ``malloc(0)`` in ``patiencediff``, which is non-portable.
(Martin Pool, #331095)
+* Cope with the lockdir ``held/info`` file being empty, which seems to
+ happen fairly often if the process is suddenly interrupted while taking
+ a lock.
+ (Martin Pool, #185103)
+
* Handle renames correctly when there are files or directories that
differ only in case. (Chris Jones, Martin Pool, #368931)
=== modified file 'bzrlib/lockdir.py'
--- a/bzrlib/lockdir.py 2009-12-21 06:17:05 +0000
+++ b/bzrlib/lockdir.py 2010-02-26 06:51:51 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2006, 2007, 2008 Canonical Ltd
+# Copyright (C) 2006, 2007, 2008, 2010 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -250,7 +250,7 @@
if info is None:
raise LockFailed(self, "lock was renamed into place, but "
"now is missing!")
- if info['nonce'] != self.nonce:
+ if info.get('nonce') != self.nonce:
self._trace("rename succeeded, "
"but lock is still held by someone else")
raise LockContention(self)
@@ -427,7 +427,7 @@
def peek(self):
"""Check if the lock is held by anyone.
- If it is held, this returns the lock info structure as a rio Stanza,
+ If it is held, this returns the lock info structure as a dict
which contains some information about the current lock holder.
Otherwise returns None.
"""
@@ -456,7 +456,14 @@
return s.to_string()
def _parse_info(self, info_file):
- return rio.read_stanza(info_file.readlines()).as_dict()
+ stanza = rio.read_stanza(info_file.readlines())
+ if stanza is None:
+ # see bug 185013; we fairly often end up with the info file being
+ # empty after an interruption; we could log a message here but
+ # there may not be much we can say
+ return {}
+ else:
+ return stanza.as_dict()
def attempt_lock(self):
"""Take the lock; fail if it's already held.
@@ -604,11 +611,16 @@
def _format_lock_info(self, info):
"""Turn the contents of peek() into something for the user"""
lock_url = self.transport.abspath(self.path)
- delta = time.time() - int(info['start_time'])
+ start_time = info.get('start_time')
+ if start_time is None:
+ time_ago = '(unknown)'
+ else:
+ time_ago = format_delta(time.time() - int(info['start_time']))
return [
'lock %s' % (lock_url,),
- 'held by %(user)s on host %(hostname)s [process #%(pid)s]' % info,
- 'locked %s' % (format_delta(delta),),
+ 'held by %s on host %s [process #%s]' %
+ tuple([info.get(x, '<unknown>') for x in ['user', 'hostname', 'pid']]),
+ 'locked %s' % (time_ago,),
]
def validate_token(self, token):
=== modified file 'bzrlib/tests/test_lockdir.py'
--- a/bzrlib/tests/test_lockdir.py 2009-06-23 08:43:05 +0000
+++ b/bzrlib/tests/test_lockdir.py 2010-02-26 06:51:51 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2006, 2007, 2008 Canonical Ltd
+# Copyright (C) 2006, 2007, 2008, 2010 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -669,6 +669,25 @@
# no kibble
check_dir(['held'])
+ def test_no_lockdir_info(self):
+ """We can cope with empty info files."""
+ # This seems like a fairly common failure case - see
+ # <https://bugs.edge.launchpad.net/bzr/+bug/185103> and all its dupes.
+ # Processes are often interrupted after opening the file
+ # before the actual contents are committed.
+ t = self.get_transport()
+ t.mkdir('test_lock')
+ t.mkdir('test_lock/held')
+ t.put_bytes('test_lock/held/info', '')
+ lf = LockDir(t, 'test_lock')
+ info = lf.peek()
+ formatted_info = lf._format_lock_info(info)
+ self.assertEquals(
+ ['lock %s' % t.abspath('test_lock'),
+ 'held by <unknown> on host <unknown> [process #<unknown>]',
+ 'locked (unknown)'],
+ formatted_info)
+
class TestLockDirHooks(TestCaseWithTransport):
More information about the bazaar-commits
mailing list