Improved mtime precisoin checking for FUSE.

This commit is contained in:
Jonas Borgström 2013-07-30 14:52:02 +02:00
parent 43a4bf6829
commit 2e237ad006
3 changed files with 29 additions and 13 deletions

View File

@ -6,6 +6,8 @@ import stat
import time
from attic.helpers import daemonize
# Does this version of llfuse support ns precision?
have_fuse_mtime_ns = hasattr(llfuse.EntryAttributes, 'st_mtime_ns')
class AtticOperations(llfuse.Operations):
@ -95,6 +97,11 @@ class AtticOperations(llfuse.Operations):
entry.st_size = size
entry.st_blksize = 512
entry.st_blocks = 1
if have_fuse_mtime_ns:
entry.st_atime_ns = item[b'mtime']
entry.st_mtime_ns = item[b'mtime']
entry.st_ctime_ns = item[b'mtime']
else:
entry.st_atime = item[b'mtime'] / 1e9
entry.st_mtime = item[b'mtime'] / 1e9
entry.st_ctime = item[b'mtime'] / 1e9

View File

@ -8,6 +8,14 @@ import unittest
from attic.helpers import st_mtime_ns
from attic.xattr import get_all
try:
import llfuse
# Does this version of llfuse support ns precision?
have_fuse_mtime_ns = hasattr(llfuse.EntryAttributes, 'st_mtime_ns')
except ImportError:
have_fuse_mtime_ns = False
# The mtime get/set precison varies on different OS and Python versions
if 'HAVE_FUTIMENS' in getattr(posix, '_have_functions', []):
st_mtime_ns_round = 0
@ -34,11 +42,11 @@ class AtticTestCase(unittest.TestCase):
except EnvironmentError:
return {}
def assert_dirs_equal(self, dir1, dir2, fuse=False):
def assert_dirs_equal(self, dir1, dir2):
diff = filecmp.dircmp(dir1, dir2)
self._assert_dirs_equal_cmp(diff, fuse)
self._assert_dirs_equal_cmp(diff)
def _assert_dirs_equal_cmp(self, diff, fuse=False):
def _assert_dirs_equal_cmp(self, diff):
self.assert_equal(diff.left_only, [])
self.assert_equal(diff.right_only, [])
self.assert_equal(diff.diff_files, [])
@ -48,6 +56,8 @@ class AtticTestCase(unittest.TestCase):
path2 = os.path.join(diff.right, filename)
s1 = os.lstat(path1)
s2 = os.lstat(path2)
# Assume path2 is on FUSE if st_dev is different
fuse = s1.st_dev != s2.st_dev
attrs = ['st_mode', 'st_uid', 'st_gid', 'st_rdev']
if not fuse or not os.path.isdir(path1):
# dir nlink is always 1 on our fuse fileystem
@ -55,18 +65,17 @@ class AtticTestCase(unittest.TestCase):
d1 = [filename] + [getattr(s1, a) for a in attrs]
d2 = [filename] + [getattr(s2, a) for a in attrs]
if not os.path.islink(path1) or utime_supports_fd:
# llfuse does not provide ns precision for now
if fuse:
# Older versions of llfuse does not support ns precision properly
if fuse and not have_fuse_mtime_ns:
d1.append(round(st_mtime_ns(s1), -4))
d2.append(round(st_mtime_ns(s2), -4))
else:
d1.append(round(st_mtime_ns(s1), st_mtime_ns_round))
d2.append(round(st_mtime_ns(s2), st_mtime_ns_round))
d1.append(self._get_xattrs(path1))
d2.append(self._get_xattrs(path2))
self.assert_equal(d1, d2)
for sub_diff in diff.subdirs.values():
self._assert_dirs_equal_cmp(sub_diff, fuse)
self._assert_dirs_equal_cmp(sub_diff)
def wait_for_mount(self, path, timeout=5):
"""Wait until a filesystem is mounted on `path`

View File

@ -224,7 +224,7 @@ class ArchiverTestCase(AtticTestCase):
try:
self.attic('mount', self.repository_location + '::archive', mountpoint, fork=True)
self.wait_for_mount(mountpoint)
self.assert_dirs_equal(self.input_path, os.path.join(mountpoint, 'input'), fuse=True)
self.assert_dirs_equal(self.input_path, os.path.join(mountpoint, 'input'))
finally:
if sys.platform.startswith('linux'):
os.system('fusermount -u ' + mountpoint)