Skip to content
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

zfs breaks nvidia-container-toolkit #380

Closed
hansom82 opened this issue May 8, 2024 · 10 comments · Fixed by #401 or #421
Closed

zfs breaks nvidia-container-toolkit #380

hansom82 opened this issue May 8, 2024 · 10 comments · Fixed by #401 or #421
Assignees

Comments

@hansom82
Copy link

hansom82 commented May 8, 2024

Both extensions uses shared library libc.so. If both present on target host then nvidia-device-plugin crashes with error:

Error: failed to create containerd task: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error running hook #0: error running hook: exit status 127, stdout: , stderr: Auto-detected mode as 'legacy'
/usr/local/bin/nvidia-container-cli: error while loading shared libraries: /usr/local/glibc/lib/libc.so: invalid ELF header: unknown

Environment

  • Talos version: v1.7.1
  • Kubernetes version: 1.28.7
  • Platform: metal (Proxmox and Bare Metal)

/fyi @kvaps

@jahanson
Copy link

jahanson commented May 8, 2024

This has caused an issue for me as well
image

The libc.so seems to be an ASCII file when most are symbolic links to their partner .so.# files.
image

amd-ucode                  20240410
nonfree-kmod-nvidia        535.129.03-v1.7.1
nvidia-container-toolkit   535.129.03-v1.14.6
zfs                        2.2.3-v1.7.1

@frezbo
Copy link
Member

frezbo commented May 13, 2024

This is interesting though, zfs should be linked against the musl libc, so i guess the zfs extensions ship some extra libc, which it shouldn't

@frezbo
Copy link
Member

frezbo commented May 13, 2024

This is due to both nvidia and zfs needing libtirpc and the zfs libtirpc is linked against musl while the nvidia one is linked against glibc. These two extensions are mutually incompatible with each other for now

jfroy added a commit to jfroy/flatops that referenced this issue May 21, 2024
jfroy added a commit to jfroy/flatops that referenced this issue May 22, 2024
@rdegez
Copy link

rdegez commented Jun 3, 2024

As heavy zfs users and soon-to-be nvidia extension users as well we would be glad providing assistance to help solving this one.

@frezbo what do you think would be the best way to fix this then ?

Build and use glibc in the zfs extension build as well (based on https://github.com/siderolabs/extensions/blob/main/nvidia-gpu/nvidia-container-toolkit/glibc/pkg.yaml for instance) instead of musl ?

Or somehow trick the build process of https://github.com/siderolabs/extensions/blob/main/nvidia-gpu/nvidia-container-toolkit/nvidia-container-cli/libtirpc/pkg.yaml to use musl instead of the glibc ?

From the libtirpc source package, the autoconf snippet handling libc detection is located in in libtirpc-1.3.4/config.guess :

<...>
case $UNAME_SYSTEM in
Linux|GNU|GNU/*)
        LIBC=unknown

        set_cc_for_build
        cat <<-EOF > "$dummy.c"
        #include <features.h>
        #if defined(__UCLIBC__)
        LIBC=uclibc
        #elif defined(__dietlibc__)
        LIBC=dietlibc
        #elif defined(__GLIBC__)
        LIBC=gnu
        #else
        #include <stdarg.h>
        /* First heuristic to detect musl libc.  */
        #ifdef __DEFINED_va_list
        LIBC=musl
        #endif
        #endif
        EOF
        cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
        eval "$cc_set_libc"

        # Second heuristic to detect musl libc.
        if [ "$LIBC" = unknown ] &&
           command -v ldd >/dev/null &&
           ldd --version 2>&1 | grep -q ^musl; then
                LIBC=musl
        fi

        # If the system lacks a compiler, then just pick glibc.
        # We could probably try harder.
        if [ "$LIBC" = unknown ]; then
                LIBC=gnu
        fi
        ;;
esac
<...>

@frezbo
Copy link
Member

frezbo commented Jun 6, 2024

@rdegez

Build and use glibc in the zfs extension build as well (based on https://github.com/siderolabs/extensions/blob/main/nvidia-gpu/nvidia-container-toolkit/glibc/pkg.yaml for instance) instead of musl ?

We do not want to do this, makes it a crazy hard to follow build steps

Or somehow trick the build process of https://github.com/siderolabs/extensions/blob/main/nvidia-gpu/nvidia-container-toolkit/nvidia-container-cli/libtirpc/pkg.yaml to use musl instead of the glibc ?

Nvidia has strict requirement for glibc and musl will not work at all

What we were discussing internally is to setup some LD_ options to let zfs use the right libtirpc

@rdegez
Copy link

rdegez commented Jun 6, 2024

@rdegez

Build and use glibc in the zfs extension build as well (based on https://github.com/siderolabs/extensions/blob/main/nvidia-gpu/nvidia-container-toolkit/glibc/pkg.yaml for instance) instead of musl ?

We do not want to do this, makes it a crazy hard to follow build steps

Looks like a lot of hassle Indeed...

Or somehow trick the build process of https://github.com/siderolabs/extensions/blob/main/nvidia-gpu/nvidia-container-toolkit/nvidia-container-cli/libtirpc/pkg.yaml to use musl instead of the glibc ?

Nvidia has strict requirement for glibc and musl will not work at all

Yeah... i'm not so surprised about that.

What we were discussing internally is to setup some LD_ options to let zfs use the right libtirpc

Like an alternate $LD_LIBRARY_PATH ?

What about using https://github.com/NixOS/patchelf ?
I wasn't aware of this (quite recent) trick 5 until minutes ago but I find it quite elegant and useful.

See https://stackoverflow.com/a/44710599 or https://www.baeldung.com/linux/multiple-glibc

@frezbo
Copy link
Member

frezbo commented Jun 7, 2024

I want to avoid patchelf, at some point the whole nvidia thing was using a lot of patchelf to fix stuff, it just makes it harder for others and for us internally to keep things up to date, I'll be looking at this issue next week and see what would work great for us and easy to maintain, don't want to make it more complicated

@rdegez
Copy link

rdegez commented Jun 7, 2024

Fair enough :-)
Feel free to bug me here or on slack if I can be of any use to you!

frezbo added a commit to frezbo/extensions that referenced this issue Jun 7, 2024
Use a custom path for libtirpc shipped with zfs-tools so that it doesn't
conflict with libtirpc built for nvidia-container-toolkit (as it's
linked against glibc).

Fixes: siderolabs#380

Signed-off-by: Noel Georgi <git@frezbo.dev>
frezbo added a commit to frezbo/extensions that referenced this issue Jun 7, 2024
Use a custom path for libtirpc shipped with zfs-tools so that it doesn't
conflict with libtirpc built for nvidia-container-toolkit (as it's
linked against glibc).

Fixes: siderolabs#380

Signed-off-by: Noel Georgi <git@frezbo.dev>
@jahanson
Copy link

@frezbo Will this fix be possible on 1.7 or will we have to wait for 1.8?

@frezbo
Copy link
Member

frezbo commented Jun 12, 2024

@frezbo Will this fix be possible on 1.7 or will we have to wait for 1.8?

Sorry, probably only for 1.8, found other issues and fixing them, don't want to backport such major fixes

frezbo added a commit to frezbo/extensions that referenced this issue Jun 24, 2024
Set `glibc/lib` as first `rpath` for `nvidia-container-cli`. Also
install nvidia libraries to `/usr/local/glibc/lib` so any musl libraries
lives separately.

Properly fixes: siderolabs#380

Fixes from siderolabs#401 and siderolabs#410 were not complete.

Manually tested by spinning up a NVIDIA worker in AWS.

Signed-off-by: Noel Georgi <git@frezbo.dev>
frezbo added a commit to frezbo/extensions that referenced this issue Jun 24, 2024
Set `glibc/lib` as first `rpath` for `nvidia-container-cli`. Also
install nvidia libraries to `/usr/local/glibc/lib` so any musl libraries
lives separately.

`nvidia-container-cli` explicitly sets an `RPATH` `$ORIGIN/../$LIB` here:
https://gitlab.com/nvidia/container-toolkit/libnvidia-container/-/blob/v1.14.6/Makefile?ref_type=tags#L183,
this means `/usr/local/lib` would be searched first, since `zfs` and
nvidia ship their own `libtirpc`, `nvidia-container-cli` first tries to
use the `libtirpc` shippeed with `zfs` at `/usr/local/lib` instead of
the one at `/usr/local/glibc/lib`. Fix this by setting an additional
`RPATH` as `$ORIGIN/../glibc/$LIB`, so that libraries in
`/usr/local/glibc/lib` have higher preference.

Properly fixes: siderolabs#380

Fixes from siderolabs#401 and siderolabs#410 were not complete.

Manually tested by spinning up a NVIDIA worker in AWS.

Signed-off-by: Noel Georgi <git@frezbo.dev>
frezbo added a commit to frezbo/extensions that referenced this issue Jun 24, 2024
Set `glibc/lib` as first `rpath` for `nvidia-container-cli`. Also
install nvidia libraries to `/usr/local/glibc/lib` so any musl libraries
lives separately.

`nvidia-container-cli` explicitly sets an `RPATH` as `$ORIGIN/../$LIB` here:
https://gitlab.com/nvidia/container-toolkit/libnvidia-container/-/blob/v1.14.6/Makefile?ref_type=tags#L183,
this means `/usr/local/lib` would be searched first, since `zfs` and
nvidia ship their own `libtirpc`, `nvidia-container-cli` first tries to
use the `libtirpc` shippeed with `zfs` at `/usr/local/lib` instead of
the one at `/usr/local/glibc/lib`. Fix this by setting an additional
`RPATH` as `$ORIGIN/../glibc/$LIB`, so that libraries in
`/usr/local/glibc/lib` have higher preference.

```bash
❯ scanelf -r _out/rootfs/rootfs/usr/local/bin/nvidia-container-cli
 TYPE   RPATH FILE
ET_DYN $ORIGIN/../glibc/$LIB:$ORIGIN/../$LIB _out/rootfs/rootfs/usr/local/bin/nvidia-container-cli
```

Properly fixes: siderolabs#380

Fixes from siderolabs#401 and siderolabs#410 were not complete.

Manually tested by spinning up a NVIDIA worker in AWS.

Signed-off-by: Noel Georgi <git@frezbo.dev>
frezbo added a commit to frezbo/extensions that referenced this issue Jun 24, 2024
Set `glibc/lib` as first `rpath` for `nvidia-container-cli`. Also
install nvidia libraries to `/usr/local/glibc/lib` so any musl libraries
lives separately.

`nvidia-container-cli` explicitly sets an `RPATH` as `$ORIGIN/../$LIB` here:
https://gitlab.com/nvidia/container-toolkit/libnvidia-container/-/blob/v1.14.6/Makefile?ref_type=tags#L183,
this means `/usr/local/lib` would be searched first, since `zfs` and
nvidia ship their own `libtirpc`, `nvidia-container-cli` first tries to
use the `libtirpc` shippeed with `zfs` at `/usr/local/lib` instead of
the one at `/usr/local/glibc/lib`. Fix this by setting an additional
`RPATH` as `$ORIGIN/../glibc/$LIB`, so that libraries in
`/usr/local/glibc/lib` have higher preference.

```bash
❯ scanelf -r _out/rootfs/rootfs/usr/local/bin/nvidia-container-cli
 TYPE   RPATH FILE
ET_DYN $ORIGIN/../glibc/$LIB:$ORIGIN/../$LIB _out/rootfs/rootfs/usr/local/bin/nvidia-container-cli
```

Properly fixes: siderolabs#380

Fixes from siderolabs#401 and siderolabs#410 were not complete.

Manually tested by spinning up a NVIDIA worker in AWS.

Signed-off-by: Noel Georgi <git@frezbo.dev>
frezbo added a commit to frezbo/extensions that referenced this issue Jun 24, 2024
Set `glibc/lib` as first `rpath` for `nvidia-container-cli`. Also
install nvidia libraries to `/usr/local/glibc/lib` so any musl libraries
lives separately.

`nvidia-container-cli` explicitly sets an `RPATH` as `$ORIGIN/../$LIB` here:
https://gitlab.com/nvidia/container-toolkit/libnvidia-container/-/blob/v1.14.6/Makefile?ref_type=tags#L183,
this means `/usr/local/lib` would be searched first, since `zfs` and
nvidia ship their own `libtirpc`, `nvidia-container-cli` first tries to
use the `libtirpc` shippeed with `zfs` at `/usr/local/lib` instead of
the one at `/usr/local/glibc/lib`. Fix this by setting an additional
`RPATH` as `$ORIGIN/../glibc/$LIB`, so that libraries in
`/usr/local/glibc/lib` have higher preference.

```bash
❯ scanelf -r _out/rootfs/rootfs/usr/local/bin/nvidia-container-cli
 TYPE   RPATH FILE
ET_DYN $ORIGIN/../glibc/$LIB:$ORIGIN/../$LIB _out/rootfs/rootfs/usr/local/bin/nvidia-container-cli
```

Properly fixes: siderolabs#380

Fixes from siderolabs#401 and siderolabs#410 were not complete.

Manually tested by spinning up a NVIDIA worker in AWS.

Signed-off-by: Noel Georgi <git@frezbo.dev>
jfroy pushed a commit to jfroy/siderolabs-extensions that referenced this issue Sep 5, 2024
Use a custom path for libtirpc shipped with zfs-tools so that it doesn't
conflict with libtirpc built for nvidia-container-toolkit (as it's
linked against glibc).

Fixes: siderolabs#380

Signed-off-by: Noel Georgi <git@frezbo.dev>
jfroy pushed a commit to jfroy/siderolabs-extensions that referenced this issue Sep 5, 2024
Set `glibc/lib` as first `rpath` for `nvidia-container-cli`. Also
install nvidia libraries to `/usr/local/glibc/lib` so any musl libraries
lives separately.

`nvidia-container-cli` explicitly sets an `RPATH` as `$ORIGIN/../$LIB` here:
https://gitlab.com/nvidia/container-toolkit/libnvidia-container/-/blob/v1.14.6/Makefile?ref_type=tags#L183,
this means `/usr/local/lib` would be searched first, since `zfs` and
nvidia ship their own `libtirpc`, `nvidia-container-cli` first tries to
use the `libtirpc` shippeed with `zfs` at `/usr/local/lib` instead of
the one at `/usr/local/glibc/lib`. Fix this by setting an additional
`RPATH` as `$ORIGIN/../glibc/$LIB`, so that libraries in
`/usr/local/glibc/lib` have higher preference.

```bash
❯ scanelf -r _out/rootfs/rootfs/usr/local/bin/nvidia-container-cli
 TYPE   RPATH FILE
ET_DYN $ORIGIN/../glibc/$LIB:$ORIGIN/../$LIB _out/rootfs/rootfs/usr/local/bin/nvidia-container-cli
```

Properly fixes: siderolabs#380

Fixes from siderolabs#401 and siderolabs#410 were not complete.

Manually tested by spinning up a NVIDIA worker in AWS.

Signed-off-by: Noel Georgi <git@frezbo.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants