diff options
author | Lars Wirzenius <liw@liw.fi> | 2013-03-04 19:18:06 +0000 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2013-03-04 19:18:06 +0000 |
commit | cca1cb28721336085cdee447b4d8ceda2e7c3ca3 (patch) | |
tree | c39d49bdbc310b6a52207b1eb8a98b5a7a42554a | |
parent | d1521cfa06653251896130388a7c896f7cf02079 (diff) | |
parent | 446a065e1de42ae45ddc28784f9325f89bcf6820 (diff) | |
download | obnam-cca1cb28721336085cdee447b4d8ceda2e7c3ca3.tar.gz |
Handle signed/unsigned stat values correctly
-rw-r--r-- | _obnammodule.c | 25 | ||||
-rw-r--r-- | obnamlib/metadata.py | 57 | ||||
-rw-r--r-- | obnamlib/metadata_tests.py | 39 | ||||
-rw-r--r-- | obnamlib/plugins/backup_plugin.py | 3 |
4 files changed, 86 insertions, 38 deletions
diff --git a/_obnammodule.c b/_obnammodule.c index 55d8eef0..f160d5af 100644 --- a/_obnammodule.c +++ b/_obnammodule.c @@ -31,6 +31,8 @@ */ +#define _FILE_OFFSET_BITS 64 + #include <Python.h> @@ -110,24 +112,25 @@ lstat_wrapper(PyObject *self, PyObject *args) ret = lstat(filename, &st); if (ret == -1) ret = errno; - return Py_BuildValue("iLLLLLLLLLLLLLLLL", + + return Py_BuildValue("iKKKKKKKLLLLKLKLK", ret, - (long long) st.st_dev, - (long long) st.st_ino, - (long long) st.st_mode, - (long long) st.st_nlink, - (long long) st.st_uid, - (long long) st.st_gid, - (long long) st.st_rdev, + (unsigned long long) st.st_dev, + (unsigned long long) st.st_ino, + (unsigned long long) st.st_mode, + (unsigned long long) st.st_nlink, + (unsigned long long) st.st_uid, + (unsigned long long) st.st_gid, + (unsigned long long) st.st_rdev, (long long) st.st_size, (long long) st.st_blksize, (long long) st.st_blocks, (long long) st.st_atim.tv_sec, - (long long) st.st_atim.tv_nsec, + (unsigned long long) st.st_atim.tv_nsec, (long long) st.st_mtim.tv_sec, - (long long) st.st_mtim.tv_nsec, + (unsigned long long) st.st_mtim.tv_nsec, (long long) st.st_ctim.tv_sec, - (long long) st.st_ctim.tv_nsec); + (unsigned long long) st.st_ctim.tv_nsec); } diff --git a/obnamlib/metadata.py b/obnamlib/metadata.py index a3c1bea0..bba229fe 100644 --- a/obnamlib/metadata.py +++ b/obnamlib/metadata.py @@ -286,24 +286,45 @@ def encode_metadata(metadata): if getattr(metadata, name) is not None: flags |= (1 << i) - packed = metadata_format.pack(flags, - metadata.st_mode or 0, - metadata.st_mtime_sec or 0, - metadata.st_mtime_nsec or 0, - metadata.st_atime_sec or 0, - metadata.st_atime_nsec or 0, - metadata.st_nlink or 0, - metadata.st_size or 0, - metadata.st_uid or 0, - metadata.st_gid or 0, - metadata.st_dev or 0, - metadata.st_ino or 0, - metadata.st_blocks or 0, - len(metadata.groupname or ''), - len(metadata.username or ''), - len(metadata.target or ''), - len(metadata.md5 or ''), - len(metadata.xattr or '')) + try: + packed = metadata_format.pack(flags, + metadata.st_mode or 0, + metadata.st_mtime_sec or 0, + metadata.st_mtime_nsec or 0, + metadata.st_atime_sec or 0, + metadata.st_atime_nsec or 0, + metadata.st_nlink or 0, + metadata.st_size or 0, + metadata.st_uid or 0, + metadata.st_gid or 0, + metadata.st_dev or 0, + metadata.st_ino or 0, + metadata.st_blocks or 0, + len(metadata.groupname or ''), + len(metadata.username or ''), + len(metadata.target or ''), + len(metadata.md5 or ''), + len(metadata.xattr or '')) + except TypeError, e: # pragma: no cover + logging.error('ERROR: Packing error due to %s' % str(e)) + logging.error('ERROR: st_mode=%s' % repr(metadata.st_mode)) + logging.error('ERROR: st_mtime_sec=%s' % repr(metadata.st_mtime_sec)) + logging.error('ERROR: st_mtime_nsec=%s' % repr(metadata.st_mtime_nsec)) + logging.error('ERROR: st_atime_sec=%s' % repr(metadata.st_atime_sec)) + logging.error('ERROR: st_atime_nsec=%s' % repr(metadata.st_atime_nsec)) + logging.error('ERROR: st_nlink=%s' % repr(metadata.st_nlink)) + logging.error('ERROR: st_size=%s' % repr(metadata.st_size)) + logging.error('ERROR: st_uid=%s' % repr(metadata.st_uid)) + logging.error('ERROR: st_gid=%s' % repr(metadata.st_gid)) + logging.error('ERROR: st_dev=%s' % repr(metadata.st_dev)) + logging.error('ERROR: st_ino=%s' % repr(metadata.st_ino)) + logging.error('ERROR: st_blocks=%s' % repr(metadata.st_blocks)) + logging.error('ERROR: groupname=%s' % repr(metadata.groupname)) + logging.error('ERROR: username=%s' % repr(metadata.username)) + logging.error('ERROR: target=%s' % repr(metadata.target)) + logging.error('ERROR: md5=%s' % repr(metadata.md5)) + logging.error('ERROR: xattr=%s' % repr(metadata.xattr)) + raise return (packed + (metadata.groupname or '') + (metadata.username or '') + diff --git a/obnamlib/metadata_tests.py b/obnamlib/metadata_tests.py index 062b6d83..286a86b9 100644 --- a/obnamlib/metadata_tests.py +++ b/obnamlib/metadata_tests.py @@ -239,6 +239,17 @@ class SetMetadataTests(unittest.TestCase): class MetadataCodingTests(unittest.TestCase): + def equal(self, meta1, meta2): + for name in dir(meta1): + if name in obnamlib.metadata.metadata_fields: + value1 = getattr(meta1, name) + value2 = getattr(meta2, name) + self.assertEqual( + value1, + value2, + 'attribute %s must be equal (%s vs %s)' % + (name, value1, value2)) + def test_round_trip(self): metadata = obnamlib.metadata.Metadata(st_mode=1, st_mtime_sec=2, @@ -258,13 +269,7 @@ class MetadataCodingTests(unittest.TestCase): md5='checksum') encoded = obnamlib.encode_metadata(metadata) decoded = obnamlib.decode_metadata(encoded) - for name in dir(metadata): - if name in obnamlib.metadata.metadata_fields: - self.assertEqual(getattr(metadata, name), - getattr(decoded, name), - 'attribute %s must be equal (%s vs %s)' % - (name, getattr(metadata, name), - getattr(decoded, name))) + self.equal(metadata, decoded) def test_round_trip_for_None_values(self): metadata = obnamlib.metadata.Metadata() @@ -275,3 +280,23 @@ class MetadataCodingTests(unittest.TestCase): self.assertEqual(getattr(decoded, name), None, 'attribute %s must be None' % name) + def test_round_trip_for_maximum_values(self): + unsigned_max = 2**64 - 1 + signed_max = 2**63 - 1 + metadata = obnamlib.metadata.Metadata( + st_mode=unsigned_max, + st_mtime_sec=signed_max, + st_mtime_nsec=unsigned_max, + st_nlink=unsigned_max, + st_size=signed_max, + st_uid=unsigned_max, + st_blocks=signed_max, + st_dev=unsigned_max, + st_gid=unsigned_max, + st_ino=unsigned_max, + st_atime_sec=signed_max, + st_atime_nsec=unsigned_max) + encoded = obnamlib.encode_metadata(metadata) + decoded = obnamlib.decode_metadata(encoded) + self.equal(metadata, decoded) + diff --git a/obnamlib/plugins/backup_plugin.py b/obnamlib/plugins/backup_plugin.py index 9279d748..e04fea19 100644 --- a/obnamlib/plugins/backup_plugin.py +++ b/obnamlib/plugins/backup_plugin.py @@ -327,10 +327,9 @@ class BackupPlugin(obnamlib.ObnamPlugin): 'Attempting to unlock shared trees because of error') self.repo.unlock_shared() except BaseException, e2: - logging.error( + logging.warning( 'Error while unlocking due to error: %s' % str(e2)) logging.debug(traceback.format_exc()) - raise else: logging.info('Successfully unlocked') |