mirror of
https://github.com/borgbackup/borg.git
synced 2025-02-24 23:13:25 +00:00
make freebsd xattr platform code api compatible with linux, fixes #3952
i.e. prefix the keys with the namespace, so it is ns.key like on
linux.
still only dealing with the "user" namespace, like before.
in the "system" namespaces there are ACLs (we deal with them via the acl
api, so no problem) and stuff from pnfsd (not sure what exactly).
this change is needed because FreeBSD's FUSE code expects the xattr
keys to be in that format.
it is also needed for cross-platform data exchange, so e.g. if one wants to:
- create archive on linux, extract on freebsd - with "user.xxx" xattrs.
- or vice versa.
archives made with older borg versions on freebsd will still extract correctly
on freebsd (not on linux though) even though they do not have the
namespace prefixes in the archived metadata (it will be interpreted in
same way as if they were prefixed by "user." as we do not support any
other namespace anyway).
(cherry picked from commit 0686237484
)
This commit is contained in:
parent
0a20a03b7f
commit
98198b34d9
2 changed files with 13 additions and 4 deletions
|
@ -44,13 +44,13 @@ def test(self):
|
|||
def test_listxattr_buffer_growth(self):
|
||||
# make it work even with ext4, which imposes rather low limits
|
||||
buffer.resize(size=64, init=True)
|
||||
# xattr raw key list will be size 9 * (10 + 1), which is > 64
|
||||
keys = ['user.attr%d' % i for i in range(9)]
|
||||
# xattr raw key list will be > 64
|
||||
keys = ['user.attr%d' % i for i in range(20)]
|
||||
for key in keys:
|
||||
setxattr(self.tmpfile.name, key, b'x')
|
||||
got_keys = listxattr(self.tmpfile.name)
|
||||
self.assert_equal_se(got_keys, keys)
|
||||
self.assert_equal(len(buffer), 128)
|
||||
self.assert_true(len(buffer) > 64)
|
||||
|
||||
def test_getxattr_buffer_growth(self):
|
||||
# make it work even with ext4, which imposes rather low limits
|
||||
|
|
|
@ -323,6 +323,7 @@ def func(path, name, value, size):
|
|||
libc.extattr_set_file.argtypes = (c_char_p, c_int, c_char_p, c_char_p, c_size_t)
|
||||
libc.extattr_set_file.restype = c_int
|
||||
ns = EXTATTR_NAMESPACE_USER = 0x0001
|
||||
prefix = 'user.'
|
||||
|
||||
def listxattr(path, *, follow_symlinks=True):
|
||||
def func(path, buf, size):
|
||||
|
@ -335,7 +336,7 @@ def func(path, buf, size):
|
|||
return libc.extattr_list_link(path, ns, buf, size)
|
||||
|
||||
n, buf = _listxattr_inner(func, path)
|
||||
return [os.fsdecode(name) for name in split_lstring(buf[:n]) if name]
|
||||
return [prefix + os.fsdecode(name) for name in split_lstring(buf[:n]) if name]
|
||||
|
||||
def getxattr(path, name, *, follow_symlinks=True):
|
||||
def func(path, name, buf, size):
|
||||
|
@ -347,6 +348,10 @@ def func(path, name, buf, size):
|
|||
else:
|
||||
return libc.extattr_get_link(path, ns, name, buf, size)
|
||||
|
||||
# strip namespace if there, but ignore if not there.
|
||||
# older borg / attic versions did not prefix the namespace to the names.
|
||||
if name.startswith(prefix):
|
||||
name = name[len(prefix):]
|
||||
n, buf = _getxattr_inner(func, path, name)
|
||||
return buf[:n] or None
|
||||
|
||||
|
@ -360,6 +365,10 @@ def func(path, name, value, size):
|
|||
else:
|
||||
return libc.extattr_set_link(path, ns, name, value, size)
|
||||
|
||||
# strip namespace if there, but ignore if not there.
|
||||
# older borg / attic versions did not prefix the namespace to the names.
|
||||
if name.startswith(prefix):
|
||||
name = name[len(prefix):]
|
||||
_setxattr_inner(func, path, name, value)
|
||||
|
||||
else: # pragma: unknown platform only
|
||||
|
|
Loading…
Reference in a new issue