Skip to content

fix(cdi): expose compat32 NVIDIA libraries - #11

Draft
Eli Bosley (elibosley) wants to merge 1 commit into
masterfrom
codex/cdi-compat32
Draft

fix(cdi): expose compat32 NVIDIA libraries#11
Eli Bosley (elibosley) wants to merge 1 commit into
masterfrom
codex/cdi-compat32

Conversation

@elibosley

@elibosley Eli Bosley (elibosley) commented Aug 2, 2026

Copy link
Copy Markdown
Member

Summary

NVIDIA CDI generation currently omits the host's 32-bit driver stack, causing 32-bit Steam and Proton workloads to fall back to software rendering; this temporarily augments the generated spec until NVIDIA's upstream fix is available.

Why This Exists

The NVIDIA Container Toolkit 1.19.1 CDI generator exposes the 64-bit NVIDIA libraries but not the compatible 32-bit libraries discovered by nvidia-container-cli list --libraries --compat32. A Games on Whales Steam container on Unraid therefore selected llvmpipe for a 32-bit Vulkan probe despite the host's NVIDIA GPU and 32-bit driver libraries being present.

Resolution

Generate CDI into a staging file, discover NVIDIA's compat32 libraries through nvidia-container-cli, validate them as readable ELF32 objects, add both canonical libraries and resolving symlink aliases as read-only mounts, and add their directories to the existing update-ldcache hook. The transformed spec is published atomically only after validation succeeds.

The augmentation is idempotent: paths and ld-cache folders already emitted by a future toolkit release are not duplicated. This makes the shim a no-op for upstream-provided entries and gives us a straightforward removal point after NVIDIA/nvidia-container-toolkit#1968 ships in Unraid.

Reviewer Considerations

  • Review the inline plugin implementation closely: robust spec transformation adds substantial shell and jq logic to nvidia-driver.plg.
  • CDI generation now fails closed. A discovery, validation, or transformation error preserves the previous live spec and causes plugin installation to exit non-zero.
  • The package archive is byte-identical to the prior plugin package and is duplicated only because the plugin's versioned package URL requires a matching 2026.08.01 artifact.
  • The tested 595.84 host adds 48 /usr/lib mounts. All were verified as ELF32, and the existing 40 /usr/lib64 mounts remain intact.
  • This is an explicitly temporary compatibility layer; the linked NVIDIA PR is the removal trigger once its behavior is included in Unraid's toolkit package.

Behavior Changes

  • Newly created NVIDIA CDI containers receive the host's 32-bit NVIDIA libraries and their loader-facing aliases.
  • The CDI update-ldcache hook includes the discovered compat32 library directories.
  • A failed CDI augmentation no longer overwrites a working spec or allows plugin installation to report success.

Implementation Summary

  • Replace in-place text editing with staged JSON generation and atomic publication.
  • Discover and validate compat32 NVIDIA libraries, resolve aliases, and merge mounts and ld-cache folders without duplicates.
  • Preserve the existing GBM compatibility link in the structured transform.
  • Add fixture coverage for discovery failures, malformed specs, broken symlinks, idempotency, and toolkit output that already contains compat32 entries.
  • Add a 32-bit Vulkan regression probe that rejects llvmpipe and requires NVIDIA.

Verification

  • ./tests/generate-cdi-test.sh — passed all fixture cases.
  • bash -n tests/generate-cdi-test.sh tests/probe-compat32-vulkan.sh — passed.
  • git diff --check — passed.
  • Parsed nvidia-driver.plg as XML — passed.
  • Verified packages/nvidia-driver-2026.08.01.txz against its MD5 and confirmed its contents match the plugin source assets.
  • On devgen.local, generated and validated a candidate from this exact commit: 48 ELF32 /usr/lib mounts, 40 /usr/lib64 mounts, critical CUDA/NVML/GLX libraries present, /usr/lib included in the ld-cache hook, and all six CDI devices still enumerated.
  • Baseline 32-bit Vulkan probe on the pre-change running Steam container selected llvmpipe (LLVM 20.1.2, 256 bits), confirming the regression. A newly created Wolf session is required to consume the corrected CDI spec.

Risk

Medium. Driver-library discovery varies by installed driver and host layout. Readability and ELF-class validation, idempotent merging, atomic publication, fail-closed behavior, fixture coverage, and real-host validation limit the rollout risk.

Summary by CodeRabbit

  • New Features

    • Updated the NVIDIA driver package to version 2026.08.01.
    • Added support for required 32-bit NVIDIA libraries and aliases, improving compatibility with 32-bit applications and Vulkan workloads.
    • Improved CDI configuration to include compatibility libraries, graphics support, and required runtime paths.
  • Bug Fixes

    • CDI configuration updates are now validated and published safely.
    • NVIDIA driver installation now stops cleanly when CDI generation fails.
    • Existing CDI configurations are preserved while avoiding duplicate entries.

Signed-off-by: Eli Bosley <eli@bosley.dev>
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The plugin version is updated to 2026.08.01. CDI generation now stages and validates JSON, adds missing compat32 NVIDIA resources, and publishes atomically. Installation fails when CDI generation fails. New tests and a Vulkan compatibility probe cover the behavior.

Changes

Compat32 CDI support

Layer / File(s) Summary
Staged CDI generation and installation failure handling
nvidia-driver.plg, packages/nvidia-driver-2026.08.01.txz, packages/nvidia-driver-2026.08.01.txz.md5
The plugin stages CDI JSON, validates and augments compat32 libraries, aliases, ldconfig folders, and the GBM link, then publishes atomically. Both installation paths now fail when CDI generation fails. The package archive and checksum are updated.
CDI fixture and failure validation
tests/generate-cdi-test.sh
The test suite covers generated mounts, aliases, hooks, preservation, deduplication, malformed output, invalid ELF files, and failure cleanup.
Compat32 Vulkan probe
tests/probe-compat32-vulkan.sh
The probe validates an ELF32 Vulkan executable, runs it in a container, and checks that the selected GPU is NVIDIA.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Installer
  participant generate_cdi
  participant nvidia_ctk
  participant nvidia_container_cli
  participant CDI_JSON
  Installer->>generate_cdi: Generate CDI specification
  generate_cdi->>nvidia_ctk: Create staged JSON
  generate_cdi->>nvidia_container_cli: Discover compat32 libraries
  generate_cdi->>CDI_JSON: Validate and augment mounts and hooks
  generate_cdi-->>Installer: Publish result or return failure
  Installer-->>Installer: Abort installation on failure
Loading

Poem

I’m a rabbit with libraries tucked in my hay,
Compat32 paths now join the display.
CDI JSON is checked before it goes live,
Stable files stay safe while updates arrive.
NVIDIA shines in the probe’s bright view.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title uses the required conventional commit format and accurately describes the CDI compat32 NVIDIA library change.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/cdi-compat32
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch codex/cdi-compat32

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
nvidia-driver.plg (1)

343-497: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract a shared cleanup helper to remove duplicated error-handling code.

The failure branches inside generate_cdi repeat the same three-line cleanup sequence at least seven times: log to stderr, rm -f "${generated}" "${transformed}", rmdir "${staging}" 2>/dev/null || true, then return 1. Extract a helper function so a future edit to the cleanup logic does not need to touch every branch, and so a new failure branch cannot forget the cleanup step.

♻️ Proposed refactor to extract a shared cleanup helper
 generate_cdi() {
   local cdi_path="${NVIDIA_CDI_PATH:-/etc/cdi/nvidia.yaml}"
   local staging generated transformed compat_output compat_json folders_json
   local library canonical candidate header folder scanned target
   local -a compat_libraries=("")
   local -a compat_folders=("")
   local -a compat_targets=("")
   local -a scanned_folders=("")
+
+  fail_cdi() {
+    echo "$1" >&2
+    rm -f "${generated}" "${transformed}"
+    rmdir "${staging}" 2>/dev/null || true
+    return 1
+  }

   if ! mkdir -p "$(dirname "${cdi_path}")" ; then
     echo "Failed to create NVIDIA CDI directory" >&2
     return 1
   fi

   staging="$(mktemp -d "${cdi_path}.stage.XXXXXX")" || return 1
   generated="${staging}/generated.json"
   transformed="${staging}/transformed.json"

   if ! nvidia-ctk cdi generate --format=json --output="${generated}" >/dev/null 2>&1 ; then
-    echo "Failed to generate NVIDIA CDI specification" >&2
-    rm -f "${generated}" "${transformed}"
-    rmdir "${staging}" 2>/dev/null || true
-    return 1
+    fail_cdi "Failed to generate NVIDIA CDI specification" ; return 1
   fi

Apply the same substitution to the remaining branches that discover, validate, and publish the spec.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@nvidia-driver.plg` around lines 343 - 497, In generate_cdi, extract the
repeated generated/transformed file and staging-directory removal into a local
cleanup helper, such as cleanup_cdi_generation, that returns failure after
performing cleanup. Update every failure branch for CDI generation, compat32
discovery/validation, JSON augmentation, and publication to log its specific
error, invoke the helper, and avoid duplicating the cleanup commands; preserve
the existing successful cleanup path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/probe-compat32-vulkan.sh`:
- Around line 25-31: Validate the captured status immediately after the
timeout/docker probe command and before parsing output; when status is nonzero,
exit with failure so "${probe}" failures or timeouts cannot be reported as
successful regression probes. Preserve the existing output parsing only for a
successful status.

---

Nitpick comments:
In `@nvidia-driver.plg`:
- Around line 343-497: In generate_cdi, extract the repeated
generated/transformed file and staging-directory removal into a local cleanup
helper, such as cleanup_cdi_generation, that returns failure after performing
cleanup. Update every failure branch for CDI generation, compat32
discovery/validation, JSON augmentation, and publication to log its specific
error, invoke the helper, and avoid duplicating the cleanup commands; preserve
the existing successful cleanup path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9f67b325-a0f4-4895-9b04-24f8f4e1e2dc

📥 Commits

Reviewing files that changed from the base of the PR and between b09bc53 and 6ee5be7.

📒 Files selected for processing (5)
  • nvidia-driver.plg
  • packages/nvidia-driver-2026.08.01.txz
  • packages/nvidia-driver-2026.08.01.txz.md5
  • tests/generate-cdi-test.sh
  • tests/probe-compat32-vulkan.sh

Comment on lines +25 to +31
set +e
output="$(
timeout 20 docker exec -u "${probe_user}" -e DISPLAY="${display}" "${container}" \
"${probe}" --c 1 --suppress_popups 2>&1
)"
status=$?
set -e

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Require a successful Vulkan probe exit status.

The script records status but never validates it. If vkcube selects NVIDIA and then fails or times out, Lines 35-46 report a successful regression probe.

Exit before parsing output when status is nonzero.

Proposed fix
 status=$?
 set -e
 
 printf '%s\n' "${output}"
 
+if [ "${status}" -ne 0 ]; then
+  echo "The ELF32 Vulkan probe failed (exit ${status})" >&2
+  exit 1
+fi
+
 selected="$(printf '%s\n' "${output}" | sed -n 's/^Selected GPU [^:]*: \([^,]*\).*/\1/p' | head -1)"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/probe-compat32-vulkan.sh` around lines 25 - 31, Validate the captured
status immediately after the timeout/docker probe command and before parsing
output; when status is nonzero, exit with failure so "${probe}" failures or
timeouts cannot be reported as successful regression probes. Preserve the
existing output parsing only for a successful status.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant