-
Notifications
You must be signed in to change notification settings - Fork 338
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Newer glibc versions provide a lchmod() that needs /proc mounted (their bug) #109
Comments
Rsync is telling you that the chmod() or lchmod() call failed (which is used to set permissions). If that is failing, it's an issue with the OS or the C library. |
I did some more tests. It is not related to the rsync version after all, so I updated this issue title. It's caused by something in the build environment that newer distributions have. Specifically:
I'll continue digging, but I'm not too skilled with the configure phase and the build-deps of rsync, so any hints will be appreciated... Strace says that the issue happens when rsync tries to chmod("/proc/self/fd/0"):
|
This is indeed caused by the lchmod() call in rsync/syscall.c. Specifically, when compiling rsync in 20.04, I see: "checking for lchmod... no", From what I read, Linux/POSIX isn't supposed to support lchmod at all, so I'm not sure why printf("lchmod returned: %d\n", lchmod("/tmp/ls", 0755)); Maybe rsync can just disable HAVE_LCHMOD when it detects that it's being compiled under Linux? |
Python did just that, it disabled lchmod when running under Linux: https://bugs.python.org/issue34652 if test "$MACHDEP" != linux; then
AC_CHECK_FUNC(lchmod)
fi I reported this to Ubuntu, in case they want to resolve it with a distro-specific patch, although that way it will continue to fail in the other Linux distributions: https://bugs.launchpad.net/ubuntu/+source/rsync/+bug/1902109 |
I located an upstream bug report for this in glibc: |
Nice investigating. I went ahead and disabled lchmod on Linux in the configure check (for now at least). |
Why not like this?
|
Good point. I decided to use a state-machine like the set_times() call in util.c. So, it now tries to use lchmod(), but if that returns ENOTSUP, it switches over to using chmod(). |
@WayneD Do you think it's possible that the last patch introduced an issue with rsync + libc6 2.31? We added this patch on Debian and it's present on rsync >= 3.2.3-7. Then I noticed that our integration tests started to fail with libc6 2.31 with the error There's also someone saying they had the same issue, though with libc6 2.30: My suspicion is that the last commit done to fix this issue introduces a regression on rsync + libc6 <= 2.31. Do you think that makes sense? |
Try commenting out the |
Thank you @WayneD, Unfortunately I wasn't able to reproduce the issue, I've tried to use a shortcut to avoid setting up everything needed for a full reproduction, but now I'll have to since I don't know whether the issue was caused by something else or I failed by not trying on the same environment where I saw the previous failures. In case I manage to reproduce it, I will let you know if the workaround you mentioned was effective. |
I was now able to reproduce the issue, it doesn't looks like an rsync issue per-se, but there might be room for improvement. The issue arises when one compiles rsync 3.2.3 (with this patch applied 9dd6252) with libc6-dev 2.32 and then uses the binary in a system which has libc6 <= 2.31.
From a packaging POV, this issue can be solved by making the binaries depend on libc6 2.32 if libc6-dev used for compilation was set in that version. On Debian we have a system which automatically tries to guess the minimum required version based on symbols usage, but this systems fails to detect this as libc6's symbol for lchmod didn't "change" (alternative being to manually set that). I can't identify the root cause of this, and I feel like I might still be onto the wrong lead since the patch doesn't seems to change behavior based on compilation time, only runtime. It's possible that I'm still having some weirdness from my reproduction method. But overall it doesn't look like an rsync issue, since one can always bump the dependency of the compiled rsync manually to libc6-2.32. Though there might be something that could be done to allow a "libc6-dev-2.32 compiled rsync" to be run with libc6 <= 2.31. Note: I've tried a few workarounds, like commenting out [0] https://www.gnu.org/software/gnulib/manual/html_node/lchmod.html |
Error 38 should be ENOSYS, which indicates to me that the lchmod() in the compiled rsync is trying to use a function not present in the older glibc. I'm adding that errno to the fallback code, which now only increments the switch_step if errno == ENOSYS (it allows ENOTSUP to fall through to the compatability code without incrementing the step, just in case that might be transient in some circumstances). --- a/syscall.c
+++ b/syscall.c
@@ -238,9 +238,12 @@ int do_chmod(const char *path, mode_t mode)
switch (switch_step) {
#ifdef HAVE_LCHMOD
#include "case_N.h"
- if ((code = lchmod(path, mode & CHMOD_BITS)) == 0 || errno != ENOTSUP)
+ if ((code = lchmod(path, mode & CHMOD_BITS)) == 0)
+ break;
+ if (errno == ENOSYS)
+ switch_step++;
+ else if (errno != ENOTSUP)
break;
- switch_step++;
#endif
#include "case_N.h" While this will work, it would be better if the package required the newer glibc (since lchmod is safer than chmod). |
I can confirm the patch above fixes the issue.
I believe older glibc probably declared the lchmod symbol, even though it wasn't implemented, and thus our mechanism that checks for symbols usage failed to identify that such old versions wouldn't satisfy the dependency.
Right, I can't yet say for sure which way I'd like to go on the packaging side. What I can say for sure is that people can only hit this scenario if they are trying to do something that is not really supported already, like picking a package that was compiled for Debian release X and using it in release Y (this could also happen with other distros). I see that you merged this change, so for now I'll keep the dependency requirement relaxed (automatically set based on symbols). I will try and discuss this issue with Debian's glibc maintainers, mainly to understand the weight of the benefits of lchmod over chmod, and if I should drop support for running rsync with older glibc (at least the versions compiled on newer Debian releases) over it. I will also keep and eye on the commits, so in the case of you wanting to remove the unsafe fallback, I'd add the version requirement. Thank you a lot! |
I had the some issue and now I need to compile my own version of rsync. I think according to the conversation, either 3.2.4dev or 3.2.3-7 should work. I cloned the repo, and could not find any tag related to the above two. I then visited https://download.samba.org/pub/rsync/src/ and could not find any of them, too. Could you please teach me how I can get the source code or binary? I am using ubuntu 21.10 Thanks a lot |
There were a number of commits related to the bug, so I recommend the latest source for the most recent version of the fix. Give the CI build for Ubuntu 20.04 a try and see if it works on 21.10. The CI produces artifacts, so if you click on the Actions tab, click on a recent build, and scroll down, there will be a link to the ubuntu-bin zip file. That will require some library packages, such as libxxhash, libacl1, etc. If you need a list, I'd suggest looking at the INSTALL.md file and installing the non-dev versions of the listed packages (though the dev versions should be fine too). |
Pls. fix typo in title of the page we are currently on: glibc not "glic". I know, it is just a silly typo, but it is significant for better search matching for this important bug report and solution. |
Hi, rsync 3.1.3 in Ubuntu 20.04 worked fine, while 3.2.3 in Ubuntu 20.10 has this problem:
This also happens in Fedora 33 beta with rsync 3.2.2, so I believe it's not distro-specific. Thank you!
The text was updated successfully, but these errors were encountered: