nix icon indicating copy to clipboard operation
nix copied to clipboard

Allow memfd_create to be used with older glibc (<2.27)

Open LizardWizzard opened this issue 2 years ago • 10 comments
trafficstars

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

LizardWizzard avatar Oct 02 '23 09:10 LizardWizzard

Are you trying to create a dylib target? If so, your trouble should be fixed by #2049 .

asomers avatar Oct 02 '23 15:10 asomers

Thanks for quick response! No, I’m building a binary target

LizardWizzard avatar Oct 02 '23 16:10 LizardWizzard

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?

asomers avatar Oct 02 '23 18:10 asomers

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!

LizardWizzard avatar Oct 06 '23 11:10 LizardWizzard

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!

LizardWizzard avatar Oct 06 '23 11:10 LizardWizzard

Hey @SteveLauC! Sorry for the ping, will you have some time to take a look at the PR? Thanks in advance!

LizardWizzard avatar Nov 07 '23 22:11 LizardWizzard

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:

  1. Merge this PR, use the raw syscall
  2. 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

SteveLauC avatar Nov 09 '23 08:11 SteveLauC

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

LizardWizzard avatar Nov 17 '23 09:11 LizardWizzard

@SteveLauC what do you think if we merge this one? Do you have any objections?

LizardWizzard avatar Nov 22 '23 17:11 LizardWizzard

I do tend to use the libc wrapper as syscalls are inherently unsafe, so I prefer approach 2

cc @asomers, thoughts on this?

SteveLauC avatar Nov 23 '23 01:11 SteveLauC