summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2012-12-23 12:36:23 +0000
committerLars Wirzenius <liw@liw.fi>2012-12-23 12:36:23 +0000
commit4ffb4565e6b003a08f3e45ecb1656443a63ad490 (patch)
tree5db41c10d3915d88fbdf3e63a194cce1e07e7cc5
parent80e19e829ec48eb0124076975f4d6ff433ee7acd (diff)
downloadobnam-4ffb4565e6b003a08f3e45ecb1656443a63ad490.tar.gz
Fix bug in handling LocalFS listdir2 lstat errors
-rw-r--r--NEWS3
-rw-r--r--obnamlib/vfs.py7
-rw-r--r--obnamlib/vfs_local.py11
3 files changed, 18 insertions, 3 deletions
diff --git a/NEWS b/NEWS
index 1d1509ed..e2fe90d1 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,9 @@ Bug fixes:
* If listing extended attributes for a filesystem that does not support
them, Obnam no longer crashes, just silently does not backup extended
attributes. Which aren't there anyway.
+* A bug in handling stat lookup errors was fixed. Reported by
+ Peter Palfrader. Symptom: `AttributeError: 'exceptions.OSError'
+ object has no attribute 'st_ino'` in an error message or log file.
Version 1.3, released 2012-12-16
--------------------------------
diff --git a/obnamlib/vfs.py b/obnamlib/vfs.py
index de29ebc2..b1dccfc9 100644
--- a/obnamlib/vfs.py
+++ b/obnamlib/vfs.py
@@ -88,7 +88,12 @@ class VirtualFileSystem(object):
'''Return list of basenames of entities at pathname.'''
def listdir2(self, pathname):
- '''Return list of basenames and stats of entities at pathname.'''
+ '''Return list of basenames and stats of entities at pathname.
+
+ The stat entity may be an exception object instead, to indicate
+ an error.
+
+ '''
def lock(self, lockname, data):
'''Create a lock file with the given name.'''
diff --git a/obnamlib/vfs_local.py b/obnamlib/vfs_local.py
index bf736ce6..a55fc601 100644
--- a/obnamlib/vfs_local.py
+++ b/obnamlib/vfs_local.py
@@ -355,6 +355,13 @@ class LocalFS(obnamlib.VirtualFileSystem):
st = self.lstat(os.path.join(dirname, name))
except OSError, e: # pragma: no cover
st = e
- result.append((name, st))
- return sorted(result, key=lambda st: st[1].st_ino)
+ ino = -1
+ else:
+ ino = st.st_ino
+ result.append((ino, name, st))
+
+ # We sort things in inode order, for speed when doing namei lookups
+ # when backing up.
+ result.sort()
+ return [(name, st) for ino, name, st in result]