nix
nix copied to clipboard
Allow memfd_create to be used with older glibc (<2.27)
Hi! Thank you for your great work!
What does this PR do
While upgrading to more recent version of nix I've faced an issue on a system that has older glibc.
Since this commit nix started to refer to memfd_create symbol instead of using a syscall. Glibc started to export this symbol since 2.27 and lowest version supported by rust project is now 2.17, so it would be nice to keep compatibility on a similar level if possible. See comments in code.
Found that there was similar issue in libsystemd-rs: https://github.com/lucab/libsystemd-rs/pull/144
Thanks in advance!
Checklist:
- [X] I have read
CONTRIBUTING.md - [X] I have written necessary tests and rustdoc comments
- [x] A change log has been added if this PR modifies nix's API
Are you trying to create a dylib target? If so, your trouble should be fixed by #2049 .
Thanks for quick response! No, I’m building a binary target
Thanks for quick response! No, I’m building a binary target
Do you mean an executable? Ordinary Rust executables should not have a problem with this, as I understand, unless you're using a very old compiler or something. Is there anything unusual in your setup, and have you tested with the lastest Nix release?
Sorry for long response
Do you mean an executable?
Yes
Is there anything unusual in your setup, and have you tested with the lastest Nix release?
The only unusual thing here is old glibc. I've prepared a reproducer that gives the same error: https://github.com/LizardWizzard/nix_memfd_create_repro it uses latest nix version available on crates io (0.27.1) and latest stable release of rustc (1.72.1)
My exact conditions are a bit different, but this is a small reproducer that shows the same problem. See code that triggers the problem here: https://github.com/LizardWizzard/nix_memfd_create_repro/blob/master/pure_nix_repro/src/main.rs
docker image I use is a default centos:7 with some installed packages.
To run the example in this repo only call to docker build . is needed. There will be an error during build phase. Relevant part of it is: undefined reference to memfd_create
Thank you!
I rebased the patch on top of current master to resolve conflict in changelog. All pipelines that failed have this error message: Failed to start an instance: FAILED_PRECONDITION: Monthly free compute limit exceeded!
Hey @SteveLauC! Sorry for the ping, will you have some time to take a look at the PR? Thanks in advance!
Hey @SteveLauC! Sorry for the ping
No worry about the ping, feel free to do so when needed:)
Are you trying to create a dylib target? If so, your trouble should be fixed by #2049
Do you mean an executable? Ordinary Rust executables should not have a problem with this, as I understand, unless you're using a very old compiler or something. Is there anything unusual in your setup, and have you tested with the lastest Nix release?
Different from the problem #2049 tries to solve, the author actually uses the memfd_create() symbol on a system with glibc 2.17
To address this issue, we should either:
- Merge this PR, use the raw syscall
- Done some runtime check, use the libc binding if available, fall back to syscall if not
For solution 2, this is actually what std and rustix do when they encounter a problem like this
Yeah, I briefly looked at weak stuff. Apparently it has a bigger scope compared to reverting to raw syscalls, because I havent seen weak being already used anywhere in nix. If there are no objections option 1 looks ok to me. Otherwise probably weak needs to be introduced separately and then used here and maybe in other API's
@SteveLauC what do you think if we merge this one? Do you have any objections?
I do tend to use the libc wrapper as syscalls are inherently unsafe, so I prefer approach 2
cc @asomers, thoughts on this?