def get_xattrs_as_blob(fs, filename): # pragma: no cover
tracing.trace('filename=%s' % filename)
try:
names = fs.llistxattr(filename)
except (OSError, IOError), e:
if e.errno in (errno.EOPNOTSUPP, errno.EACCES):
return None
raise
tracing.trace('names=%s' % repr(names))
if not names:
return None
values = []
for name in names[:]:
tracing.trace('trying name %s' % repr(name))
try:
value = fs.lgetxattr(filename, name)
except OSError, e:
# On btrfs, at least, this can happen: the filesystem returns
# a list of attribute names, but then fails when looking up
# the value for one or more of the names. We pretend that the
# name was never returned in that case.
#
# Obviously this can happen due to race conditions as well.
if e.errno == errno.ENODATA:
names.remove(name)
logging.warning(
'%s has extended attribute named %s without value, '
'ignoring attribute',
filename, name)
else:
raise
else:
tracing.trace('lgetxattr(%s)=%s' % (name, value))
values.append(value)
assert len(names) == len(values)
name_blob = ''.join('%s\0' % name for name in names)
lengths = [len(v) for v in values]
fmt = '!' + 'Q' * len(values)
value_blob = struct.pack(fmt, *lengths) + ''.join(values)
return ('%s%s%s' %
(struct.pack('!Q', len(name_blob)),
name_blob,
value_blob))
评论列表
文章目录