rsync
rsync copied to clipboard
Symbolic Link permission when compiled with musl libc on Alpine Linux
When using rsync to copy from a *bsd host to Linux when rsync is compiled against musl libc, rsync issues warnings during the copy :-
rsync: failed to set permissions on "FILENAME": Not supported (95)
and exits with error code 23 :-
HOSTNAME:/tmp/testing# rsync -va SHOST:/etc .
receiving incremental file list
rsync: failed to set permissions on "/tmp/testing/etc/aliases": Not supported (95)
rsync: failed to set permissions on "/tmp/testing/etc/rmt": Not supported (95)
rsync: failed to set permissions on "/tmp/testing/etc/termcap": Not supported (95)
rsync: failed to set permissions on "/tmp/testing/etc/unbound": Not supported (95)
rsync: failed to set permissions on "/tmp/testing/etc/ssl/cert.pem": Not supported (95)
sent 71 bytes received 8,713 bytes 5,856.00 bytes/sec
total size is 1,689,030 speedup is 192.28
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1659) [generator=3.1.3]
HOSTNAME:/tmp/testing# echo $?
23
These are all symbolic links. On the source host (a freebsd box) the symlinks have the following permissions :-
lrwxr-xr-x 1 root wheel 12 Jul 21 2017 aliases -> mail/aliases
lrwxr-xr-x 1 root wheel 15 Jul 21 2017 rmt -> ../usr/sbin/rmt
lrwxr-xr-x 1 root wheel 23 Jul 21 2017 termcap -> /usr/share/misc/termcap
lrwxr-xr-x 1 root wheel 14 Jul 21 2017 unbound -> ../var/unbound
As Linux has no idea of anything other than lrwxrwxrwx permissions for symbolic links, can an option be added to rsync (or even an #ifdef #endif section along the lines of 'quietly ignore not supported error if linux && symlink;' ?
rsync works fine using GNU libc, it's just against musl. There are several articles around this regarding musl but the consensus seems to be that it's not really a musl issue, rather it's a GNU libc quirk that accepts the fact that an lchmod just won't work on Linux.
I was hit by the same problem after a recent upgrade of rsync with some bugfix. :-)
I make incremental backups from a nilfs2 filesystem to a ZFS filesystem. The nilfs2 filesystem, for some unknown but perfectly valid reason, applies the umask when creating symlinks, so my symlinks on nilfs2 are mostly lrwxr-xr-x. The corresponding destination symlinks on ZFS get created lrwxrwxrwx, which is more common amoung Linux filesystems. rsync -p of course detects the difference, and tries to chmod the destination symlink, which is not supported on Linux, which renders lots of unuseful warnings, because it doesn't matter what these bits are.
I'm afraid this is one of those "who's to blame" bugs. Why does Linux VFS store and expose access permissions that are to be ignored? Why does nilfs2 set these bits in a de facto non-standard way? Why doesn't rsync ignore the bits as required by Linux?
Anyways, if rsync could be thought to ignore the access permission bits for Linux symlinks that would be swell.
The symbolic link permission handling is also problematic when rsync is used from a Mac to a Linux machine. Symlinks have 755 permission on the Mac, but they are created with 777 on the Linux machine as it does not support changing symlink permissions.
As symlink permission doesn't matter, this shouldn't be a problem, but it is because on subsequent runs rsync compares the symlink permissions and even if they haven't changed it thinks they differ due to the different permissions, so it copies the links every time.
@WayneD: Would it be possible for rsync to ignore the symlink permissions if the source system (e.g. BSD, Mac) supports setting symlink permissions, but the target (e.g. Linux) does not, or provide a CLI flag to explicitly disable the symlink permission checking/copying of rsync (but still enable it for other files/dirs with the --perms flag)?
This is something that we definitely need to improve a bit more, but it's rather complicated since the lack of symlink permission setting often depends on the destination filesystem, not the OS that compiled rsync. So, rsync doesn't know if it can or cannot set a symlink's permissions until it tries to set its permissions. We probably need some kind of per-device symlink-permission test method and have the code notice if the directory dev_no values are changing at mount boundaries where a new test would be needed.
Note, however, that rsync listing the symlink name for a transfer doesn't mean that it actually made any changes. Hopefully you are using -i
(I'm surprised that a lot of people do not) so that it shows you that it's a difference of permissions, which can be easily ignored or filtered out.
As for the "Not supported" errors, I believe I already fixed that in a commit that should have been released in 3.2.4.
Hey @WayneD I'm glad to hear that the symlink handling might be improved in the future.
I'm using rsync with the -i flag and it shows the difference in the symlink permissions on each run, and my impression was it also copies the symlinks again, but then I just misinterpreted it. Filtering out the L...p from the rsync output is a good enough workaround for me. Thanks for the suggestion!