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).
they do not have "
1. BORG_*_PREFIX is checked (avoids lib detection via pkg-config).
2. pkg-config is tried
3. fallback to bundled C code (or failure in case of OpenSSL)
also:
- simplified code again
- removed (c) headers, nothing left of original code
drop BORG_HOSTNAME_IS_UNIQUE (please use BORG_HOST_ID if needed)
borg now always assumes it has a unique hostid - either automatically
from fqdn plus uuid.getnode() or overridden via BORG_HOST_ID.
The O_NONBLOCK caused EAGAIN errors borg did not deal with, so we
better block and wait until read data is available from e.g. a fifo.
Fixed the --read-special test so it creates a FIFO, feeds it from a
thread and backs it up with borg. Then extracts and checks if correct
data has been backed up.
Also: renamed flags_follow to flags_special_follow (its only intended
use is on symlinks to special files with --read-special).
this is needed for the xattr dummy implementation (used e.g.
on openbsd):
- it returns [] for listxattr
- it fails with ENOATTR when trying getxattr for any name
also: reduce code duplication
Didn't add dll folder since it wasn't copied when updating zstd to
1.3.4.
Didn't add extra files from the lib directory (Makefile, README.md, etc)
that were also left out when updating zstd to 1.3.4.
Add new zstd files to setup_zstd.py (DDict was refactored in
facebook/zstd#1388)
before this, it over-eagerly compacted "small" segments ("small"
being < 100MB by default) if there were only a few bytes to be freed.
also:
- improve debug logging
- as compaction is a separate borg command now, use the module logger
scenario:
- x is a regular file
- borg does stat on x: is a regular file
- so borg dispatches to process_file
- attack: x gets replaced by a symlink (mv symlink x)
- in process_file, borg opens x and must not follow the symlink nor
continue processing as a normal file, but rather error in open()
due to NOFOLLOW.
on linux, acls are based on xattrs, so do these closeby:
1. listxattr -> keys (without acl related keys)
2. for all keys: getxattr
3. acl-related getxattr by acl library
for fd-based operations, we would have to open the file, but for
char / block devices this has unwanted effects, even if we do not
read from the device.
thus, we use path (or dir_fd + name) based ops here.
acl_get:
remove assumption that having an FD means it is a regular file, we try
to use FDs a much as possible.
only get the default acl for directories - other fs objects are not
expected to have a default acl.
the path needs to be encoded also for the case when we have an fd,
it is needed to get the default acl for directories.
also: micro-opt: encode path later, not needed for ISLNK check.
acl_set:
remove the "if False" branch, it is the same here: the fd-based api
only supports access ACLs, but not default ACLs, so we always need
to use the path-based api here.
if scandir does not get a path, it can't prefix it in front of the
filename in the direntries it returns, so dirent.path == dirent.name.
thus, we just only use dirent.name and construct the full path.
races via changing path components can be avoided by opening the
parent directory and using parent_fd + file_name combination with
*at style functions to access the directories' contents.
avoiding too large chunks that the repository can not store.
avoiding too small chunks that would create excessively many chunks
and way to much storage and management overhead. we only disallow
extreme cases, this does not mean that everything that is allowed
also makes sense in practice (and does not eat lots of memory and
storage space).