Closed sbond75 closed 3 months ago
Additionally, I did a test on macOS to find file creation time of a symlink using GetFileInfo -P -d file
, and it was reported properly. However, hfsfuse doesn't report the user.hfsfuse.record.date_created
attribute for symlinks as indicated by my initial comment, saying it has no value.
Yeah, something's going on here. All records (files/folders/links/etc) should have hfsfuse.record.date_created available at least as this comes from the record structure itself (the same is technically true of FinderInfo but by convention that one isn't listed as an xattr if it's empty.) I'll take a look.
This ended up being pretty simple. The Linux kernel actually disallows user extended attributes on anything but regular files.
The filesystem still receives llistxattr
calls since symlinks can contain ACLs, etc, which is why hfsfuse is able to even tell getfattr that these exist, but getfattr is never able to access them. The subsequent lgetxattr
calls are never even passed to FUSE, the kernel just sends ENODATA back.
I think the only way around this is for hfsfuse_listxattr to stop returning attribute names under Linux for things that aren't regular files. At least that info will still be available via hfsdump.
Using a different non-user namespace (like hfsfuse.
) for these does seem to work, but as far as I can tell programs aren't intended to define their own top level xattr namespaces.
I pushed the former change in https://github.com/0x09/hfsfuse/commit/2ab526c09e11aa7a27ffeb9fee122e2f98da5b47 so this should be resolved if you pull master.
I would suggest allowing it for directories as well since those are allowed to have user extended attributes in Linux.
As for the possibility of using a non-user namespace, I would suggest making a mount option for that or just having it by default. Since the program runs as root and is involved with filesystems I would imagine it better to use a non-user namespace, but this is up to you of course.
You're right thanks, directories should be included in the allowed types. That's now fixed.
Unfortunately with custom namespaces it seems that user tools (including rsync) are unable to copy these even for regular files, which is kind of expected, but makes this hard to do in a way that's not confusing to use (e.g. only symlinks get a custom namespace) or results in unexpectedly missing something when moving data around.
I considered while working on xattr support a bit ago adding an xattr mount mode similar to -o rsrc_only
which would offer a consistent way to access these on any system, so this may be an option (this would be useful on Haiku as well for different reasons.) I'll try to think a bit more about what makes sense to do here. Thank you for the suggestions and these detailed bug reports.
I found that it is possible if you use "security", "system", or "trusted" namespaces which all have different purposes, mentioned on the same man page you sent earlier. On Linux the program must run as root or have CAP_SYS_ADMIN
to view, set, or copy "trusted" namespaced attributes. More information from that man page is as follows:
Trusted extended attributes are visible and accessible only to processes that have the CAP_SYS_ADMIN capability. Attributes in this class are used to implement mechanisms in user space (i.e., outside the kernel) which keep information in extended attributes to which ordinary processes should not have access.
Notably, the only difference to hfsfuse's use-case would be the "ordinary processes should not have access" part mentioned at the end. It would be preferable for them to have access to these.
Example usage of the trusted
namespace: touch test.txt && sudo setfattr -n trusted.example -v example test.txt && sudo getfattr --no-dereference -d -m '' -- test.txt
will work, ln -s test.txt testSym && sudo setfattr -n trusted.example -v example2 testSym && sudo getfattr --no-dereference -d -m '' -- testSym
will show the example2
value on the symlink, and finally sudo cp -a testSym testSym2 && sudo getfattr --no-dereference -d -m '' -- testSym2
also prints the copied example
xattr. Note that running cp
as a non-root user causes it to silently not copy the xattrs in these namespaces. Furthermore, it seems getfattr
must be run as root or else No such attribute
error shows for any attribute under these namespaces.
I also set this up as a prefix in my local hfsfuse.c
and it works there.
I tried a few combinations myself, it seems to vary a lot between the 4 (+ custom) as far as what can be read vs written by root and non root and the type of file. I think at minimum making the namespace a build option would be a good idea, since this is OS dependent anyway. That would allow this to be set globally with a make arg or in config.mak. Let me know if this would be more or less sufficient for the use case here.
Otherwise I'm still a bit split on letting this be changed with a runtime option vs coming up with another interface for accessing these, but I'd like to have something to cover these inconsistencies. I wonder how other Linux filesystem drivers even outside of FUSE handle this, since HFS+ is definitely not the only filesystem that supports extended attributes on symlinks.
Yes I would say a Makefile option makes sense. I haven't used config.mak (is it autotools-related?)
For hfsfuse it's just something for convenience to rebuild without specifying options to make every time. It can be created with make config
, there's some info on how it gets used in https://github.com/0x09/hfsfuse?tab=readme-ov-file#configuring
Using the config file is no different from specifying make args directly, but if you want to always build with a particular namespace you'd be able to set it there instead of remembering to use make
XATTR_PREFIX
XATTR_NAMESPACE=theprefix
(once this option is added.)
These should do it https://github.com/0x09/hfsfuse/commit/9a8ff0b7598604741d0615d98372f3ebc686a4b3 / https://github.com/0x09/hfsfuse/commit/5fe04ec66bccd8eeef7ab477b06b86b1af55c6d0.
make XATTR_NAMESPACE=namespace.
or the same setting in config.mak now changes this for all xattrs. Defaults to empty on macOS and user.
on all other systems.
Edit: updated with a change to actually allow the config.mak override mentioned.
After experimenting with some more involved ways of displaying these on the filesystem, I decided to go with the simplest and just add an option to mount with symlinks as regular files as a fallback means for viewing these in https://github.com/0x09/hfsfuse/commit/c528f3cc0b6a2346e211504f3e1eabfa4d7bdbfa. This and the other various system specific xattr quirks are now under OS-specific extended attribute behavior in the README.
Between this and the namespace option there are now at least a few alternative ways to access these, so I'll go ahead and close this. Thanks again for these reports.
Running
getfattr --no-dereference -d -m '' -- file
, wherefile
is the symlink to test and it has no attributes, will output the following:I think the correct behavior should be no output. Symlinks are allowed to have extended attributes (I used xattr on macOS to test this), but this particular symlink doesn't have the above attributes. Maybe these attribute names are somehow built into hfsfuse as attribute names it checks for, like in
hfsfuse_getxattr_offset
. Looking at the code forgetfattr
, hfsfuse might be returning these attributes as built-in attribute names, but they return ENODATA when queried for an attribute value.lgetxattr
, when called onuser.com.apple.FinderInfo
, returns ENODATA since there is no such attribute on the symlink anyway, butllistxattr
is returning those two attributes extraneously.