xattr in rsync are mapped differently than via SMB — NAS runs Samba with Mac friendly module vfs_fruit
Use Case & User Goals
- The data superset is on the NAS.
- Occasionally I download files/folders of that superset to my Mac:
- Via Finder (if hand picked) or rsync (for filtering or recursive use cases).
- Then I view the files locally for a while (videos mostly).
- The only aspects I change are the files' tags (metadata), not their content (data fork).
- Prior deleting the local file copies of the superset, I sync up their changed tags (mix of content classification tags and workflow tags) to the NAS.
- Dragging files in Finder from Mac to NAS would copy them fully, not only their changed tags.
- One can only achieve pure Finder tag transfer by manually copying tags. 👍 Very cumbersome.
- Or await the full file transfer although only tags changed. 👍 Wasted bandwidth/time.
- Rsync with the proper arguments (
--archive --xattr) is clever enough to only transfer the xattr. 👎 Very fast!
- Dragging files in Finder from Mac to NAS would copy them fully, not only their changed tags.
Problem
-
rsync --xattr ~/path/ nas.local::Shared-rsync/path/(sender on Mac, receiver on NAS) maps the xattr differently - than when copying from the Mac to a SMB mounted share (served by Samba with the Mac friendly vfs_fruit module)
- 2a) CLI:
cp ~/path/file.txt /Volumes/Shared/path/ - 2b) GUI: In the Finder drag-n-drop
file.txtfrom local~/path/to the mounted SMB share/Volumes/Shared/path/
- 2a) CLI:
- Viewing
~/path/in a Finder window and the mounted SMB share/Volumes/Shared/path/in another Finder window and copying with…- …methods 2a) and 2b) the Finder tags on the remote destination refresh immediately and correctly as they are on the local source.
- …method 1) the Finder tags on the remote destinations get visually lost.
- In reality they are now also there, but got written into the wrong xattr, and the previously correctly mapped xattr got deleted. Hence the tag(s) is/are not shown by the Finder anymore.
Environment
MacBook Pro (Mid 2014)
- MacOS 11.6.7 Big Sur
-
rsync version 3.2.4 protocol version 31 (installed via HomeBrew)
- Capabilities: 64-bit files, 64-bit inums, 64-bit timestamps, 64-bit long ints, socketpairs, symlinks, symtimes, hardlinks, hardlink-specials, hardlink-symlinks, IPv6, atimes, batchfiles, inplace, append, ACLs, xattrs, optional protect-args, iconv, no prealloc, stop-at, crtimes, file-flags
- Optimizations: no SIMD-roll, no asm-roll, openssl-crypto, no asm-MD5
- Checksum list: xxh128 xxh3 xxh64 (xxhash) md5 md4 none
- Compress list: zstd lz4 zlibx zlib none
-
rsync version 3.2.4 protocol version 31 (installed via HomeBrew)
Odroid Home Cloud 2 — Single Board Computer (SBC) acting as a Network Attached Storage (NAS)
-
OpenMediaVault 5.6.21-2 (Debian based) Linux 4.14.222-odroidxu4
-
rsync version 3.1.3 protocol version 31
- Capabilities: 64-bit files, 64-bit inums, 32-bit timestamps, 64-bit long ints, socketpairs, hardlinks, symlinks, IPv6, batchfiles, inplace, append, ACLs, xattrs, iconv, symtimes, prealloc
- Samba, using module vfs_fruit for "Enhanced OS X and Netatalk interoperability", see config file:
-
rsync version 3.1.3 protocol version 31
/etc/samba/smb.conf 👈 Click to expand
# This file is auto-generated by openmediavault (https://www.openmediavault.org)
# WARNING: Do not edit this file, your changes will get lost.
#======================= Global Settings =======================
[global]
workgroup = WORKGROUP
server string = %h server
dns proxy = no
log level = 2
log file = /var/log/samba/log.%m
max log size = 1000
logging = syslog
panic action = /usr/share/samba/panic-action %d
encrypt passwords = true
passdb backend = tdbsam
obey pam restrictions = no
unix password sync = no
passwd program = /usr/bin/passwd %u
passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .
pam password change = yes
socket options = TCP_NODELAY IPTOS_LOWDELAY
guest account = nobody
load printers = no
disable spoolss = yes
printing = bsd
printcap name = /dev/null
unix extensions = yes
wide links = no
create mask = 0777
directory mask = 0777
use sendfile = yes
aio read size = 16384
aio write size = 16384
time server = no
wins support = no
multicast dns register = no
# Special configuration for Apple's Time Machine # Coming from GUI autoconfig
fruit:aapl = yes # Coming from GUI autoconfig
# Extra options
# OMV default extra options
min receivefile size = 16384
write cache size = 524288
getwd cache = yes
socket options = TCP_NODELAY IPTOS_LOWDELAY
# Recommendations from
# https://wiki.samba.org/index.php/Configure_Samba_to_Work_Better_with_Mac_OS_X
# man vfs_fruit
min protocol = SMB2
ea support = yes
vfs objects = fruit streams_xattr # https://support.apple.com//HT207128
# would recommended "catia fruit streams_xattr". Did not try that yet.
fruit:aapl = yes # Manually by me in extra options of GUI
fruit:metadata = stream
fruit:posix_rename = yes
fruit:veto_appledouble = no
fruit:nfs_aces = no
fruit:wipe_intentionally_left_blank_rfork = yes
fruit:delete_empty_adfiles = yes
#======================= Share Definitions =======================
[Shared]
path = /srv/dev-disk-by-label-share/Shared/
guest ok = no
guest only = no
read only = no
browseable = yes
inherit acls = yes
inherit permissions = no
ea support = no
store dos attributes = no
vfs objects = # Coming from GUI autoconfig. Afraid this nullifies.
printable = no
create mask = 0664
force create mode = 0664
directory mask = 0775
force directory mode = 0775
hide special files = yes
follow symlinks = yes
hide dot files = no
# These seem to be derived from the settings for the share folder by the autoconfig:
valid users = "wife","me"
invalid users = @"kids"
read list = "wife"
write list = "me"
vfs objects = fruit streams_xattr # Hence manually aded by me in extra options of GUI.
Background Info
RFC 8276 — File System Extended Attributes in NFSv4 (December 2017)
- The Samba module vfs_fruit seems to be the implementation of that required mapping.
- Rsync as sender on Mac and receiver on the NAS seems to not use that same xattr mapping.
MacOS stores the Finder tags in an xattr named com.apple.metadata:_kMDItemUserTags as a binary PLIST.
- File
8.txthas the Finder Tag "•TODO" which also has the red label color. - File
15.txthas the Finder Tag "Artwork" without any color. Later amended by tags "Automation" & "Billing".
HEX/plaintext output of xattr com.apple.metadata:_kMDItemUserTags 👈 Click to to see the raw BPLIST value in the xattrs
$ xattr -l ~/mac/path/8.txt # With Finder Tag "•TODO" & also having a red label color.
com.apple.FinderInfo:
00000000 00 00 00 00 00 00 00 00 00 0C 00 00 00 00 00 00 |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020
com.apple.metadata:_kMDItemUserTags:
00000000 62 70 6C 69 73 74 30 30 A1 01 67 20 22 00 54 00 |bplist00..g ".T.|
00000010 6F 00 64 00 6F 00 0A 00 36 08 0A 00 00 00 00 00 |o.d.o...6.......|
00000020 00 01 01 00 00 00 00 00 00 00 02 00 00 00 00 00 |................|
00000030 00 00 00 00 00 00 00 00 00 00 19 |...........|
$ xattr -l ~/mac/path/15.txt # With Finder Tag "Artwork" without any color.
com.apple.metadata:_kMDItemUserTags:
00000000 62 70 6C 69 73 74 30 30 A1 01 57 41 72 74 77 6F |bplist00..WArtwo|
00000010 72 6B 08 0A 00 00 00 00 00 00 01 01 00 00 00 00 |rk..............|
00000020 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 00 00 12 |....|
00000034
$ xattr -l ~/mac/path/15.txt # Meanwhile tag "Automation" was added to the end.
com.apple.metadata:_kMDItemUserTags:
00000000 62 70 6C 69 73 74 30 30 A2 01 02 57 41 72 74 77 |bplist00...WArtw|
00000010 6F 72 6B 5A 41 75 74 6F 6D 61 74 69 6F 6E 08 0B |orkZAutomation..|
00000020 13 00 00 00 00 00 00 01 01 00 00 00 00 00 00 00 |................|
00000030 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000040 1E |.|
00000041
$ xattr -l ~/mac/path/15.txt # Meanwhile tag "Billing" was inserted at start.
com.apple.metadata:_kMDItemUserTags:
00000000 62 70 6C 69 73 74 30 30 A3 01 02 03 57 42 69 6C |bplist00....WBil|
00000010 6C 69 6E 67 57 41 72 74 77 6F 72 6B 5A 41 75 74 |lingWArtworkZAut|
00000020 6F 6D 61 74 69 6F 6E 08 0C 14 1C 00 00 00 00 00 |omation.........|
00000030 00 01 01 00 00 00 00 00 00 00 04 00 00 00 00 00 |................|
00000040 00 00 00 00 00 00 00 00 00 00 27 |..........'|
0000004b
Debian's xattr -l crashes with UnicodeDecodeError for com.apple.metadata:_kMDItemUserTags
-
Sadly there's a yet undetected bug in the
xattr command line toolon my NAS "Odroid Home Cloud 2", running Open Media Vault 5, Debian based. -
When attempting to display xattrs in the list output mode which is hardcoded to a combined HEX/plaintext-interpretation output, values which cannot be interpreted as ASCII or UTF-8 as they are present in the proprietary
com.apple.metadata:_kMDItemUserTagscause a crash:attr -l /nas/path/15.txt # Run on the NAS via SSH from the Mac raceback (most recent call last): File "/usr/bin/xattr", line 11, in <module> load_entry_point('xattr==0.9.6', 'console_scripts', 'xattr')() File "/usr/lib/python3/dist-packages/xattr/tool.py", line 196, in main attr_value = attr_value.decode('utf-8') nicodeDecodeError: 'utf-8' codec can't decode byte 0xa3 in position 8: invalid start byte-
Offtopic shortly: Could some Debian user please file this on my behalf? Debian has a really oldschool bug tracker (no web interface like Github or Bugzilla. One needs to install Terminal tool
reportbugand have a Terminal based mail sending infrastructure. Really nerdy 1980ies mailing list backwards compatibility.
-
Offtopic shortly: Could some Debian user please file this on my behalf? Debian has a really oldschool bug tracker (no web interface like Github or Bugzilla. One needs to install Terminal tool
-
When this display bug happens the
xattr command line toolonly shows key/value pairs prior the first problematic key/value pair in encounters, and for that problematic key/value pair it does not even show the key name.- So this made debugging harder. But through trial/error with custom xattr I nevertheless figured out what the genral mapping problem is.
- Therefore to demonstrate the xattr mapping problems to you I use arbitrary self made xattr where both key/value contain ASCII only, so that I can also show how it looks on the NAS itself without any SMB alternate data stream (ADS) transformations.
- But practically I care mostly for the Finder tags which are encoded as a binary PLIST in the xattr
com.apple.metadata:_kMDItemUserTagsworking well in a mixed mode usage of the NAS sometimes accessed via rsync and sometimes via SMB.
Problem in detail
Ad 2) When using rsync <my-arguments> ~/path/ /Volumes/SMB-Mounted-Share/path/
-
rsync works purely locally, and the xattrs transfer with a mapping which works in practise:
-
In the Finder windows
~/path/and/Volumes/SMB-Mounted-Share/path/thefile-with-finder-tags.txtshows the same tags in both windows immediately after sync.-
On the Mac, xattr of the local file:
attr -l ~/file-with-arbitrary-xattr.txt yVar: Thanks -
On the NAS via SSH:
attr -l file-with-arbitrary-xattr.txt ser.DosStream.myVar:$DATA: 000 54 68 61 6E 6B 73 00 Thanks. -
On the Mac, xattr of the SMB accessed file:
attr -l /Volumes/SMB-Mounted-Share/path/file-with-arbitrary-xattr.txt yVar: Thanks -
In this form rsync itself works purely locally: On a local filesystem
~/path/and on a locally mounted remote filesystem/Volumes/SMB-Mounted-Share/path/whose network abstraction is handled by SMB.- 👎 So the delta algorithm between the rsync sender on the Mac and the rsync receiver on the NAS does not get facilitated.
- 💡 In the case that I only change metadata (majority of my use cases) it works fine as it only transfers the metadata changes.
- 👎 But in case there's also a change in the data fork of the file, the whole file gets transfered, no delta transfer gets facilitated.
-
Ad 1) When using rsync <my-arguments> ~/path/ nas.local::Shared-rsync/path/
-
rsync is used both as sender on the Mac and receiver on the NAS
-
👍 So I would benefit from all delta transfer benefits.
-
👎 but the xattr mapping goes practically wrong
-
ℹ️ Prior the next rsync
- I deleted file-with-arbitrary-xattr.txt on the NAS.
- Changed its xattr myVar to the Italian "Grazie".
-
Then ran the rsync:
sync --archive --xattrs --delete --verbose --stats \ -progress --itemize-changes --human-readable \ /path/ odroid.local::Shared-rsync/path/ -
On the Mac, xattr of the local file:
attr -l file-with-arbitrary-xattr.txt yVar: Grazie -
On the NAS via SSH:
attr -l file-with-arbitrary-xattr.txt ser.myVar: Grazie -
On the Mac, xattr of the SMB accessed file:
attr -l /Volumes/SMB-Mounted-Share/path/file-with-arbitrary-xattr.txt Returns NULL. The mapping seems to fail.
-
Followup
- I'm no developer, only a somehow tech-savvy user.
- Hence I do not and cannot say
rsync --xattrfrom Mac to Linux is wrongly implemented. - In its current form it is at best useful when using rsync itself only.
- Hence I do not and cannot say
- But I can state clearly: In a mixed setup, and especially in a GUI setup (Finder) it is useless and dangerous (data-loss!) in its current form.
- I think rsync should offer a mode to map the xattrs like SMB does, to be really of use in normal Mac/NAS practise.
- And to be on the safe side for medium Mac/NAS/SMB-savvy users like me (before 2 days of research & experimentation) that combined "user" plus "DosStream" mapping should be considered to be the safe default when using --xattr on Mac rsync, and there should be rather a switch for a "a pure linux user namespace mode not compatible with SMB/Finder".
I think the mapping is configurable in Samba to match rsync's behavior.
https://www.samba.org/samba/docs/current/man-html/vfs_streams_xattr.8.html
How exactly would that help?
I forgot everything meanwhile, my lengthy/detailed post is 2 years old.
By which concrete mappings could one improve the use case rsync is used both as sender on the Mac and receiver on the NAS ?
You can set the prefix to match rsync (as sender & receiver) and drop the suffix.
streams_xattr:prefix = user.
streams_xattr:store_stream_type = no
It also works for your first usage (rsync into SMB mount). However, when doing that rsync might fail (unrelated to these settings) when one xattr is a prefix of another, due to a bug in Apple SMB client implementation.
Thanks. As I do not have that use case anymore (too often) I currently don't have the time to try it out and give feedback on it. But I gladly come back here, should I need it at a later time. Thanks for having taken the time!