Skip to content

docs(gpu-operator): document passthrough variant host-driver prerequisite - #2767

Merged
Aleksei Sviridkin (lexfrei) merged 1 commit into
mainfrom
feat/gpu-operator-passthrough-prereqs
Jun 9, 2026
Merged

Aleksei Sviridkin (lexfrei) merged 1 commit into
mainfrom
feat/gpu-operator-passthrough-prereqs

Conversation

@lexfrei

@lexfrei Aleksei Sviridkin (lexfrei) commented May 28, 2026 •

Copy link
Copy Markdown
Contributor

What this PR does

Documents an undocumented prerequisite of the cozystack.gpu-operator default (passthrough) variant: it assumes the GPU is not already claimed by a host-installed NVIDIA driver. The chart's vfio-manager DaemonSet runs the upstream NVIDIA k8s-driver-manager init container, which is hard-coded to exit non-zero and label the node nvidia.com/gpu.deploy.driver=pre-installed the moment chroot /host nvidia-smi returns a driver version (a PATH lookup, not a fixed file path). There is no env-var override in k8s-driver-manager v0.10.0, so today the only working path is a clean host.

The new "Passthrough variant: host preparation" section in docs/gpu-vgpu.md covers:

  • The exact symptom (init log + sandbox-validator crashloop + lspci evidence) so operators can recognise it without spelunking.
  • A clean-host workaround: a build-from-installed purge list (dpkg-query, so a zero-match pattern can't silently abort the whole apt transaction the way a hardcoded 'cuda-*' pattern does on a host without the CUDA repo), /etc/modprobe.d/blacklist-nvidia.conf (incl. nvidia_peermem), update-initramfs -k all, reboot. Warns that autoremove is dangerous on converged GPU + NVIDIA DOCA / Mellanox hosts because of the shared nvidia- prefix.
  • Post-reboot verification (no nvidia modules loaded, no nvidia-smi on PATH, no leftover NVIDIA DKMS module) and a label-cleanup step — the DaemonSet pods crash-loop and retry on their own, but the operator's success path never resets the pre-installed label, so it must be cleared manually.
  • A "Known limitation" subsection that names the upstream constraint and the planned mitigation path (upstream env-var override + a future container variant of the package).

Linked to #2763.

Release note

docs(gpu-operator): document that the passthrough (`default`) variant requires a clean host and explain how to purge a pre-installed NVIDIA host driver before enabling the variant.

Summary by CodeRabbit

  • Documentation
    • Renamed GPU guide to cover passthrough and vGPU scenarios; updated verification/last-verified info.
    • Added passthrough host-preparation and troubleshooting, including a clean-host workaround with driver removal, kernel-module blacklist, initramfs update, reboot, and steps to force a fresh device bind.
    • Clarified FORCE_REINSTALL does not bypass early host-driver detection and noted pending mitigation paths.
    • Updated OS support table: passthrough requires clean-host on Ubuntu 20.04/22.04/24.04; Ubuntu 26.04 includes usr-merge notes and vGPU marked as caution (⚠️).

@coderabbitai

coderabbitai Bot commented May 28, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Documentation updated to cover passthrough and vGPU modes: adds a "Passthrough variant: host preparation" section describing host-driver detection, a clean-host workaround, FORCE_REINSTALL limitation, and updates the OS support table and vGPU/bundle/KubeVirt guidance.

Changes

GPU Documentation: Passthrough and vGPU

Layer / File(s) Summary
Document scope and heading
docs/gpu-vgpu.md
Top-level heading renamed to indicate the document covers both passthrough and vGPU.
Passthrough host preparation
docs/gpu-vgpu.md
New "Passthrough variant: host preparation" section describes operator detection of pre-installed NVIDIA host drivers (isHostDriver short-circuit), vfio-manager skip behavior, nvidia-sandbox-validator crashloop symptom, that FORCE_REINSTALL does not bypass the early host-driver detection, and a "Clean-host workaround" with apt purge patterns, NVIDIA kernel-module blacklist, initramfs update, reboot, and instructions to delete vfio-manager/sandbox-validator DaemonSet pods to force a fresh bind attempt.
vGPU deployment / bundle guidance
docs/gpu-vgpu.md
vGPU section revised to reflect bundles.iaas.gpuOperatorVariant: vgpu, noting bundle-provided image/registry values and clarifying precedence and escape-hatch for hand-crafted Package CRs.
KubeVirt configuration and verification
docs/gpu-vgpu.md
KubeVirt guidance expanded: automatic mirroring of GPU variant when managed by bundles vs manual Package-CR wiring; updates defaults-population logic, mediated-device notes, and allocatable verification/resource-name details.
OS support table clarification
docs/gpu-vgpu.md
OS support summary updated: passthrough (default) requires a clean host for Ubuntu 24.04, 22.04, and 20.04; Ubuntu 26.04 lists clean-host plus usr-merge/patch notes; vGPU (vgpu) for 26.04 is marked ⚠️.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

  • cozystack/cozystack#2766: Related updates around GPU Operator variants and handling of hosts with pre-installed NVIDIA drivers.

Suggested reviewers

  • androndo
  • sircthulhu
  • lllamnyp
  • kvaps

Poem

🐰 I hopped through docs to tidy the trail,
Passthrough needs hosts that don't already hail.
Purge modules, blacklist, rebuild initramfs—then boot,
Restart the pods, let vfio rebind each root.
I twitched my whiskers; the guide is now hale.

🚥 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 accurately summarizes the primary change: documenting a passthrough variant host-driver prerequisite. It is specific, concise, and directly reflects the main objective of the PR.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/gpu-operator-passthrough-prereqs

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 and usage tips.

@github-actions github-actions Bot added size/M This PR changes 30-99 lines, ignoring generated files area/virtualization Issues or PRs related to virtualization (kubevirt, cdi, vmi, vm-import) kind/documentation Categorizes issue or PR as related to documentation labels May 28, 2026
@lexfrei
Aleksei Sviridkin (lexfrei) force-pushed the feat/gpu-operator-passthrough-prereqs branch 5 times, most recently from 83c656c to 4b5601f Compare May 28, 2026 18:20
@github-actions github-actions Bot added size/L This PR changes 100-499 lines, ignoring generated files and removed size/M This PR changes 30-99 lines, ignoring generated files labels May 28, 2026
@lexfrei
Aleksei Sviridkin (lexfrei) force-pushed the feat/gpu-operator-passthrough-prereqs branch from 4b5601f to 6c00af5 Compare May 28, 2026 18:48
@lexfrei
Aleksei Sviridkin (lexfrei) marked this pull request as ready for review May 28, 2026 18:48
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses an undocumented limitation in the cozystack.gpu-operator where the passthrough variant fails if an NVIDIA driver is already present on the host. By providing clear documentation on the root cause, symptoms, and a safe cleanup procedure, this change enables operators to successfully deploy the operator on standard Linux distributions while avoiding common pitfalls like accidental removal of essential RDMA/DOCA components.

Highlights

  • Documentation of Host Prerequisite: Added comprehensive documentation detailing that the 'default' (passthrough) variant of the GPU operator requires a clean host without pre-installed NVIDIA drivers.
  • Workaround and Troubleshooting: Provided a detailed 'Clean-host' workaround, including specific package purge commands, kernel module blacklisting, and post-reboot verification steps.
  • Compatibility Matrix Update: Updated the OS compatibility table to reflect the clean-host requirement for Ubuntu-based distributions.
New Features

🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment Gemini (@gemini-code-assist) Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on Gemini (@gemini-code-assist) comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request updates the docs/gpu-vgpu.md documentation to add a comprehensive guide on host preparation for the GPU Operator's passthrough (default) variant. It explains the issue where pre-installed host drivers prevent the operator from binding GPUs to vfio-pci, details the symptoms, and provides a workaround to purge the host NVIDIA stack and blacklist the modules. It also updates the Host OS compatibility table to reflect these requirements. The review feedback suggests several improvements to the documentation's shell commands, including using command -v to check for nvidia-smi, explicitly purging nvidia-persistenced, and blacklisting nvidia_peermem on converged GPU + RDMA hosts.

Comment thread docs/gpu-vgpu.md Outdated
lsmod | grep -E '^(nvidia|nouveau)'

# Self-evident verification: prints "ok: gone" on success.
test -e /usr/bin/nvidia-smi && echo "STILL PRESENT — purge incomplete" || echo "ok: gone"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

low

Using test -e /usr/bin/nvidia-smi only checks a specific hardcoded path. It is more robust to check if nvidia-smi is available anywhere in the system's PATH using command -v.

Suggested change
test -e /usr/bin/nvidia-smi && echo "STILL PRESENT — purge incomplete" || echo "ok: gone"
command -v nvidia-smi &>/dev/null && echo "STILL PRESENT — purge incomplete" || echo "ok: gone"

Comment thread docs/gpu-vgpu.md Outdated
Comment on lines +68 to +75
sudo apt purge \
'nvidia-driver-*' 'nvidia-dkms-*' 'nvidia-kernel-*' \
'nvidia-firmware-*' 'nvidia-utils-*' \
'nvidia-modprobe' 'nvidia-settings' 'nvidia-prime' \
'libnvidia-cfg1-*' 'libnvidia-compute-*' 'libnvidia-decode-*' \
'libnvidia-encode-*' 'libnvidia-extra-*' 'libnvidia-fbc1-*' \
'libnvidia-gl-*' \
'cuda-toolkit-*' 'cuda-drivers' 'cuda-drivers-*'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

low

On systems where the NVIDIA host driver was installed, the nvidia-persistenced daemon might also be running and installed. It is recommended to explicitly purge nvidia-persistenced to ensure a completely clean host.

Suggested change
sudo apt purge \
'nvidia-driver-*' 'nvidia-dkms-*' 'nvidia-kernel-*' \
'nvidia-firmware-*' 'nvidia-utils-*' \
'nvidia-modprobe' 'nvidia-settings' 'nvidia-prime' \
'libnvidia-cfg1-*' 'libnvidia-compute-*' 'libnvidia-decode-*' \
'libnvidia-encode-*' 'libnvidia-extra-*' 'libnvidia-fbc1-*' \
'libnvidia-gl-*' \
'cuda-toolkit-*' 'cuda-drivers' 'cuda-drivers-*'
sudo apt purge \
'nvidia-driver-*' 'nvidia-dkms-*' 'nvidia-kernel-*' \
'nvidia-firmware-*' 'nvidia-utils-*' \
'nvidia-modprobe' 'nvidia-settings' 'nvidia-prime' 'nvidia-persistenced' \
'libnvidia-cfg1-*' 'libnvidia-compute-*' 'libnvidia-decode-*' \
'libnvidia-encode-*' 'libnvidia-extra-*' 'libnvidia-fbc1-*' \
'libnvidia-gl-*' \
'cuda-toolkit-*' 'cuda-drivers' 'cuda-drivers-*'

Comment thread docs/gpu-vgpu.md
Comment on lines +77 to +83
sudo tee /etc/modprobe.d/blacklist-nvidia.conf > /dev/null <<'EOF'
blacklist nouveau
blacklist nvidia
blacklist nvidia_drm
blacklist nvidia_modeset
blacklist nvidia_uvm
EOF

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

low

On converged GPU + RDMA hosts (which are explicitly mentioned in the guide), the nvidia_peermem module is often loaded for GPUDirect RDMA/Storage. It is safer to also blacklist nvidia_peermem to prevent any automatic loading of NVIDIA-related modules.

Suggested change
sudo tee /etc/modprobe.d/blacklist-nvidia.conf > /dev/null <<'EOF'
blacklist nouveau
blacklist nvidia
blacklist nvidia_drm
blacklist nvidia_modeset
blacklist nvidia_uvm
EOF
sudo tee /etc/modprobe.d/blacklist-nvidia.conf > /dev/null <<'EOF'
blacklist nouveau
blacklist nvidia
blacklist nvidia_drm
blacklist nvidia_modeset
blacklist nvidia_uvm
blacklist nvidia_peermem
EOF

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
docs/gpu-vgpu.md (2)

331-331: 💤 Low value

Consider clarifying the usr-merge patch requirement.

The reference to "a nvidia-driver patch for usr-merge" may be unclear to operators when Ubuntu 26.04 releases. If the patch requirement is known, consider adding a brief inline explanation or a link to tracking documentation. If details aren't finalized, adding "(details pending)" would set expectations.

🤖 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 `@docs/gpu-vgpu.md` at line 331, Update the table cell that currently reads "a
`nvidia-driver` patch for usr-merge" so it clarifies the usr-merge requirement:
either add a short inline explanation of what the patch does and why it’s
required (e.g., how usr-merge changes paths that the driver touches) or append a
link to tracking documentation/issue and, if specifics aren’t finalized, add
"(details pending)"; target the exact phrase "nvidia-driver patch for usr-merge"
in docs/gpu-vgpu.md and keep the note concise.

33-36: ⚡ Quick win

Consider breaking the overview into shorter sentences.

The current paragraph is a single 300+ word sentence with multiple nested parentheses covering detection flow, flag behavior, workarounds, and Talos exceptions. While technically accurate, it's difficult to scan during incident response. Breaking it into 3-4 focused sentences would improve clarity without changing content.

🤖 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 `@docs/gpu-vgpu.md` around lines 33 - 36, The paragraph is a single very long
sentence that bundles multiple concepts and is hard to scan; break it into 3–4
focused sentences that separate: (1) the detection flow (mention the
k8s-driver-manager init container run of uninstall_driver and the Go method
(*DriverManager).isHostDriver that chroots to run nvidia-smi), (2) the observed
behavior on detection (log Host driver detected: <ver>, node label
nvidia.com/gpu.deploy.driver=pre-installed, and crashloop of
nvidia-sandbox-validator due to device not bound to vfio-pci), and (3) the
force/mitigation notes (that FORCE_REINSTALL/--force-reinstall does not bypass
isHostDriver, the only current workaround is removing the host NVIDIA stack, and
the upcoming container variant and Talos exception). Keep wording concise,
preserve all technical symbols (uninstall_driver, (*DriverManager).isHostDriver,
nvidia-smi, FORCE_REINSTALL/--force-reinstall, vfio-manager,
nvidia-sandbox-validator) and the references/links as-is.
🤖 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.

Nitpick comments:
In `@docs/gpu-vgpu.md`:
- Line 331: Update the table cell that currently reads "a `nvidia-driver` patch
for usr-merge" so it clarifies the usr-merge requirement: either add a short
inline explanation of what the patch does and why it’s required (e.g., how
usr-merge changes paths that the driver touches) or append a link to tracking
documentation/issue and, if specifics aren’t finalized, add "(details pending)";
target the exact phrase "nvidia-driver patch for usr-merge" in docs/gpu-vgpu.md
and keep the note concise.
- Around line 33-36: The paragraph is a single very long sentence that bundles
multiple concepts and is hard to scan; break it into 3–4 focused sentences that
separate: (1) the detection flow (mention the k8s-driver-manager init container
run of uninstall_driver and the Go method (*DriverManager).isHostDriver that
chroots to run nvidia-smi), (2) the observed behavior on detection (log Host
driver detected: <ver>, node label nvidia.com/gpu.deploy.driver=pre-installed,
and crashloop of nvidia-sandbox-validator due to device not bound to vfio-pci),
and (3) the force/mitigation notes (that FORCE_REINSTALL/--force-reinstall does
not bypass isHostDriver, the only current workaround is removing the host NVIDIA
stack, and the upcoming container variant and Talos exception). Keep wording
concise, preserve all technical symbols (uninstall_driver,
(*DriverManager).isHostDriver, nvidia-smi, FORCE_REINSTALL/--force-reinstall,
vfio-manager, nvidia-sandbox-validator) and the references/links as-is.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 148737e0-d761-4fd4-ba9a-0317dd9041fb

📥 Commits

Reviewing files that changed from the base of the PR and between 67ba252 and 6c00af5.

📒 Files selected for processing (1)
  • docs/gpu-vgpu.md

@lexfrei
Aleksei Sviridkin (lexfrei) force-pushed the feat/gpu-operator-passthrough-prereqs branch from 6c00af5 to f30f047 Compare May 28, 2026 19:14

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
docs/gpu-vgpu.md (2)

61-76: ⚡ Quick win

Consider clarifying the comment placement.

The comment block (lines 62-67) describes "load-bearing kernel pieces" and "userspace driver pieces", but it's visually separated from the actual apt purge command that starts on line 68. Operators skimming the code might miss the connection.

♻️ Suggested adjustment

Move the comment immediately before the sudo apt purge command to improve clarity:

-# nvidia-dkms-* and nvidia-kernel-* are the load-bearing kernel
-# pieces — without them DKMS rebuilds nvidia.ko on the next reboot
-# and the blacklist below is bypassed by any explicit modprobe.
-# libnvidia-* is intentionally split into the userspace driver
-# pieces only — a bare 'libnvidia-*' glob also matches DOCA-OFED
-# shipped libnvidia packages on converged GPU + RDMA hosts.
 sudo apt purge \
+  # nvidia-dkms-* and nvidia-kernel-* are the load-bearing kernel
+  # pieces — without them DKMS rebuilds nvidia.ko on the next reboot
+  # and the blacklist below is bypassed by any explicit modprobe.
   'nvidia-driver-*' 'nvidia-dkms-*' 'nvidia-kernel-*' \
   'nvidia-firmware-*' 'nvidia-utils-*' \
   'nvidia-modprobe' 'nvidia-settings' 'nvidia-prime' \
+  # libnvidia-* is intentionally split into the userspace driver
+  # pieces only — a bare 'libnvidia-*' glob also matches DOCA-OFED
+  # shipped libnvidia packages on converged GPU + RDMA hosts.
   'libnvidia-cfg1-*' 'libnvidia-compute-*' 'libnvidia-decode-*' \
   'libnvidia-encode-*' 'libnvidia-extra-*' 'libnvidia-fbc1-*' \
   'libnvidia-gl-*' \

Alternatively, keep the current structure but add a blank line to visually separate the explanation from the workaround introduction.

🤖 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 `@docs/gpu-vgpu.md` around lines 61 - 76, The explanatory comment about
"nvidia-dkms-*" and "libnvidia-*" should be visually associated with the apt
purge command; move the comment block so it appears immediately above the sudo
apt purge line (the bash block that begins with sudo apt purge 'nvidia-driver-*'
...) or, at minimum, add a blank line between the explanation and the following
paragraphs so readers immediately see the relation between the comment and the
apt purge command.

35-35: ⚡ Quick win

Break this paragraph into multiple focused sections for readability.

This single paragraph exceeds 1000 characters and covers multiple distinct concepts: the upstream isHostDriver behavior, the FORCE_REINSTALL limitation, the upcoming container variant, Talos compatibility, and cross-references to other docs. Operators diagnosing a live issue will struggle to extract the key points quickly.

♻️ Suggested restructure

Consider breaking this into logical sections:

-The `default` (passthrough) variant assumes the GPU is **owned by the host kernel's `vfio-pci` driver and nothing else**. The chart's `vfio-manager` DaemonSet runs the upstream NVIDIA `k8s-driver-manager` init container with the `uninstall_driver` subcommand; that path calls the Go method `(*DriverManager).isHostDriver`, which runs `chroot /host nvidia-smi --query-gpu=driver_version --format=csv,noheader` and treats any non-empty stdout as "host driver present" (file-existence is not pre-tested — if `nvidia-smi` is missing, the chroot exec errors and `isHostDriver` returns false, which is the intended path on a clean host: the operator then proceeds with the uninstall flow and `vfio-manager` binds `vfio-pci` as designed). On a positive detection the binary logs `Host driver detected: <ver>`, labels the node `nvidia.com/gpu.deploy.driver=pre-installed`, exits, and `nvidia-sandbox-validator` then crashloops with `device not bound to 'vfio-pci'`. `k8s-driver-manager` v0.10.0 exposes a `FORCE_REINSTALL` / `--force-reinstall` env+flag pair (visible in the binary's strings table), but it gates a later "same-config already loaded" branch inside `uninstallDriver`, not the `isHostDriver` short-circuit at the top — operators who set it and expect a bypass will report a false bug. There is currently no opt-out for the `isHostDriver` guard itself. The only mitigation available on `main` today is to remove the host NVIDIA stack before enabling the variant (the "Clean-host workaround" section below). An upcoming `container` variant of `cozystack.gpu-operator` is tracked in [`#2766`](https://github.com/cozystack/cozystack/pull/2766) — once merged it will give operators a no-purge path that keeps the host driver and exposes GPUs to pods rather than VMs — but it is not part of the current package and is **not** a usable workaround until it lands. Talos is unaffected because the Talos image ships only the `vfio-pci` extension; this section applies to Linux distributions where you installed the host driver yourself (typically Ubuntu / Debian / RHEL with `apt install nvidia-driver-*` or equivalent). See also [`packages/system/gpu-operator/examples/README.md`](../packages/system/gpu-operator/examples/README.md) for the native-pod-workload reference flow that predates the `container` variant.
+The `default` (passthrough) variant assumes the GPU is **owned by the host kernel's `vfio-pci` driver and nothing else**.
+
+**How the operator detects a pre-installed host driver:**  
+The chart's `vfio-manager` DaemonSet runs the upstream NVIDIA `k8s-driver-manager` init container with the `uninstall_driver` subcommand. That path calls the Go method `(*DriverManager).isHostDriver`, which runs `chroot /host nvidia-smi --query-gpu=driver_version --format=csv,noheader` and treats any non-empty stdout as "host driver present". File existence is not pre-tested — if `nvidia-smi` is missing, the chroot exec errors and `isHostDriver` returns false, which is the intended path on a clean host. On a positive detection the binary logs `Host driver detected: <ver>`, labels the node `nvidia.com/gpu.deploy.driver=pre-installed`, exits, and `nvidia-sandbox-validator` then crashloops with `device not bound to 'vfio-pci'`.
+
+**`FORCE_REINSTALL` does not bypass this check:**  
+`k8s-driver-manager` v0.10.0 exposes a `FORCE_REINSTALL` / `--force-reinstall` env+flag pair (visible in the binary's strings table), but it gates a later "same-config already loaded" branch inside `uninstallDriver`, not the `isHostDriver` short-circuit at the top — operators who set it and expect a bypass will report a false bug. There is currently no opt-out for the `isHostDriver` guard itself.
+
+**Current mitigation:**  
+The only workaround available on `main` today is to remove the host NVIDIA stack before enabling the variant (see "Clean-host workaround" below).
+
+**Future alternatives (not yet available):**  
+An upcoming `container` variant of `cozystack.gpu-operator` is tracked in [`#2766`](https://github.com/cozystack/cozystack/pull/2766) — once merged it will give operators a no-purge path that keeps the host driver and exposes GPUs to pods rather than VMs — but it is not part of the current package and is **not** a usable workaround until it lands.
+
+**Scope:**  
+Talos is unaffected because the Talos image ships only the `vfio-pci` extension. This section applies to Linux distributions where you installed the host driver yourself (typically Ubuntu / Debian / RHEL with `apt install nvidia-driver-*` or equivalent). See also [`packages/system/gpu-operator/examples/README.md`](../packages/system/gpu-operator/examples/README.md) for the native-pod-workload reference flow that predates the `container` variant.
🤖 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 `@docs/gpu-vgpu.md` at line 35, The paragraph is too long and conflates
multiple topics; split it into focused sections such as: (1) "isHostDriver
behavior" explaining the chroot nvidia-smi check and that
(*DriverManager).isHostDriver short-circuits on any stdout (mention nvidia-smi
and chroot /host), (2) "FORCE_REINSTALL limitation" noting FORCE_REINSTALL /
--force-reinstall only affects uninstallDriver's later branch and does not
bypass isHostDriver, (3) "Current mitigation" describing the Clean-host
workaround and vfio-manager behavior (mention vfio-manager,
nvidia-sandbox-validator crashloop and vfio-pci bind), and (4) "Future option
and scope" covering the upcoming container variant (reference cozystack PR
`#2766`) and Talos exemption; move the cross-reference to
packages/system/gpu-operator/examples/README.md into the "Future option" or
"Native-pod-workload" note. Keep each section to 1–3 sentences and use the
unique symbols isHostDriver, uninstallDriver, FORCE_REINSTALL, nvidia-smi,
vfio-manager, nvidia-sandbox-validator, vfio-pci, and PR `#2766` to anchor
explanations.
🤖 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.

Nitpick comments:
In `@docs/gpu-vgpu.md`:
- Around line 61-76: The explanatory comment about "nvidia-dkms-*" and
"libnvidia-*" should be visually associated with the apt purge command; move the
comment block so it appears immediately above the sudo apt purge line (the bash
block that begins with sudo apt purge 'nvidia-driver-*' ...) or, at minimum, add
a blank line between the explanation and the following paragraphs so readers
immediately see the relation between the comment and the apt purge command.
- Line 35: The paragraph is too long and conflates multiple topics; split it
into focused sections such as: (1) "isHostDriver behavior" explaining the chroot
nvidia-smi check and that (*DriverManager).isHostDriver short-circuits on any
stdout (mention nvidia-smi and chroot /host), (2) "FORCE_REINSTALL limitation"
noting FORCE_REINSTALL / --force-reinstall only affects uninstallDriver's later
branch and does not bypass isHostDriver, (3) "Current mitigation" describing the
Clean-host workaround and vfio-manager behavior (mention vfio-manager,
nvidia-sandbox-validator crashloop and vfio-pci bind), and (4) "Future option
and scope" covering the upcoming container variant (reference cozystack PR
`#2766`) and Talos exemption; move the cross-reference to
packages/system/gpu-operator/examples/README.md into the "Future option" or
"Native-pod-workload" note. Keep each section to 1–3 sentences and use the
unique symbols isHostDriver, uninstallDriver, FORCE_REINSTALL, nvidia-smi,
vfio-manager, nvidia-sandbox-validator, vfio-pci, and PR `#2766` to anchor
explanations.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: dde2945f-8864-41b6-bb95-8a6a0524246f

📥 Commits

Reviewing files that changed from the base of the PR and between 6c00af5 and f30f047.

📒 Files selected for processing (1)
  • docs/gpu-vgpu.md

@lexfrei
Aleksei Sviridkin (lexfrei) force-pushed the feat/gpu-operator-passthrough-prereqs branch from f30f047 to e9f831c Compare June 2, 2026 22:59

@myasnikovdaniil myasnikovdaniil left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Docs-only change documenting a real, previously-undocumented failure mode of the gpu-operator default (vfio-pci passthrough) variant: when the host already has an apt-installed NVIDIA driver, the upstream k8s-driver-manager init container in the nvidia-vfio-manager DaemonSet detects it via chroot /host nvidia-smi, labels the node nvidia.com/gpu.deploy.driver=pre-installed, and bails — so vfio-pci never binds and nvidia-sandbox-validator crashloops. The PR adds symptom recognition, a clean-host purge workaround, an OS-table update, and a Known-limitation section.

I verified the core technical claims against the upstream NVIDIA/k8s-driver-manager v0.10.0 Go source (cmd/driver-manager/main.go) and the vendored chart: the isHostDriver chroot-nvidia-smi check, the non-empty-stdout logic, exec-error→false on clean hosts, the pre-installed label, the preflight_check entrypoint, and — notably — that FORCE_REINSTALL only gates shouldSkipUninstall() and not the isHostDriver short-circuit. All accurate. Version pin matches (charts/gpu-operator/values.yaml → k8s-driver-manager:v0.10.0, chart v26.3.1), the cozy-gpu-operator namespace is correct, and all four cross-refs are live (#2763 open, #2766 open/unmerged, upstream #191 open, examples/README.md exists). Unusually well-researched for a docs PR.

Three substantive issues remain, all verifiable from the same upstream source the doc cites: (1) "will not retry on their own" is wrong — the init container exits non-zero and crash-loops; (2) the workaround leaves the stale pre-installed label behind, which the doc itself uses as diagnostic evidence; (3) the headline apt purge can abort with zero effect on a host without the CUDA repo. Details inline. All are small edits — happy to re-approve once addressed.

Comment thread docs/gpu-vgpu.md Outdated
sudo reboot
```

After the reboot, confirm the host is clean and kick the stuck DaemonSet pods so they re-create against the cleaned state — they have already labeled the node and will not retry on their own:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Factual error — verified against upstream v0.10.0 source. uninstallDriver() returns fmt.Errorf("driver is pre-installed on host") right after the labeling step (cmd/driver-manager/main.go#L272-L281), i.e. the init container exits non-zero. kubelet keeps restarting it under crash-loop backoff, so it does retry on its own — and the reboot in this workaround recreates the pod sandbox and re-runs init containers anyway. The kubectl delete is still worth keeping (it skips the up-to-5-minute backoff wait), but the stated justification is wrong.

Suggested change
After the reboot, confirm the host is clean and kick the stuck DaemonSet pods so they re-create against the cleaned state — they have already labeled the node and will not retry on their own:
After the reboot, confirm the host is clean. The init container exits non-zero after detecting a host driver, so both DaemonSet pods sit in `Init:CrashLoopBackOff`; they *will* retry on their own, but deleting them skips the up-to-5-minute backoff window:

Comment thread docs/gpu-vgpu.md
kubectl -n cozy-gpu-operator get pods -o name \
| grep -E '^pod/(nvidia-vfio-manager|nvidia-sandbox-validator)-' \
| xargs -r kubectl -n cozy-gpu-operator delete
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Stale label left behind — verified against upstream source. disableContainerizedDriver() sets nvidia.com/gpu.deploy.driver=pre-installed, but the success path rescheduleGPUOperatorComponents() only restores the operand labels (validator / toolkit / device-plugin / gfd / dcgm / mig / nvsm / sandbox-validator / sandbox-device-plugin / vgpu-device-manager) — nvidia.com/gpu.deploy.driver is not in that list and is never reset by the binary. So after a successful recovery the node keeps pre-installed indefinitely. That's the exact label the Symptom section tells operators to use as evidence, and it would disable the containerized-driver DaemonSet if the node ever switches to the container workload (directly relevant once #2766 lands). Suggest adding a cleanup step:

# The init container set this label and nothing resets it on the success
# path; clear it so it does not mislead future debugging.
kubectl label node <NODE> nvidia.com/gpu.deploy.driver-

(Worth a quick runtime check that the gpu-operator controller doesn't reconcile it back/away on its own — see the verification note in the review.)

Comment thread docs/gpu-vgpu.md Outdated
# libnvidia-* is intentionally split into the userspace driver
# pieces only — a bare 'libnvidia-*' glob also matches DOCA-OFED
# shipped libnvidia packages on converged GPU + RDMA hosts.
sudo apt purge \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The headline remediation can abort with zero effect on a common host shape. apt/apt-get treat * args as regexes matched against the whole package cache, and a pattern (or a plain name like cuda-drivers) that matches nothing in the cache is a fatal E: Unable to locate package — the entire transaction aborts and nothing is purged. cuda-toolkit-* / cuda-drivers / cuda-drivers-* only exist in the cache when NVIDIA's CUDA repo is configured; on a stock Ubuntu 24.04 host with just nvidia-driver-580-open from the Ubuntu archive (the very host this doc was verified against), this command fails outright. Note also these are substring regexes, not shell globs — broader than they look, which interacts with the DOCA caution above.

Suggest either a dry-run-first instruction (sudo apt-get -s purge … | grep -E '^(Purg|Remv)', review, drop patterns apt can't locate), or build the list from installed packages, which sidesteps both the zero-match abort and the regex over-match:

dpkg-query -W -f '${Package}\n' 'nvidia-*' 'libnvidia-*' 'cuda-*' 2>/dev/null

(dpkg-query patterns are true globs over installed packages.)

Comment thread docs/gpu-vgpu.md Outdated
blacklist nvidia_uvm
EOF

sudo update-initramfs -u

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

update-initramfs -u only rebuilds the running kernel's initramfs. If the node boots a different (e.g. just-upgraded) kernel after this reboot, its initramfs won't carry the blacklist and the host can re-claim the GPU. Use -k all:

Suggested change
sudo update-initramfs -u
sudo update-initramfs -u -k all

Comment thread docs/gpu-vgpu.md Outdated
lsmod | grep -E '^(nvidia|nouveau)'

# Self-evident verification: prints "ok: gone" on success.
test -e /usr/bin/nvidia-smi && echo "STILL PRESENT — purge incomplete" || echo "ok: gone"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

isHostDriver runs chroot /host nvidia-smi resolved via PATH inside the chroot, not pinned to /usr/bin. So test -e /usr/bin/nvidia-smi misses /usr/local/bin/nvidia-smi (typical leftover of a .run-installer or CUDA-toolkit install), and the apt purge above doesn't cover .run-installed drivers at all. Match what the operator actually does:

Suggested change
test -e /usr/bin/nvidia-smi && echo "STILL PRESENT — purge incomplete" || echo "ok: gone"
command -v nvidia-smi && echo "STILL PRESENT — purge incomplete" || echo "ok: gone"

Also worth adding dkms status | grep -i nvidia (a leftover DKMS module rebuilds nvidia.ko on the next kernel update and the blacklist is bypassed by an explicit modprobe), and one sentence: if the driver was installed with NVIDIA's .run installer rather than apt, run nvidia-uninstall instead of the purge.

Comment thread docs/gpu-vgpu.md

The `default` (passthrough) variant assumes the GPU is **owned by the host kernel's `vfio-pci` driver and nothing else**. The chart's `vfio-manager` DaemonSet runs the upstream NVIDIA `k8s-driver-manager` init container with the `uninstall_driver` subcommand; that path calls the Go method `(*DriverManager).isHostDriver`, which runs `chroot /host nvidia-smi --query-gpu=driver_version --format=csv,noheader` and treats any non-empty stdout as "host driver present" (file-existence is not pre-tested — if `nvidia-smi` is missing, the chroot exec errors and `isHostDriver` returns false, which is the intended path on a clean host: the operator then proceeds with the uninstall flow and `vfio-manager` binds `vfio-pci` as designed). On a positive detection the binary logs `Host driver detected: <ver>`, labels the node `nvidia.com/gpu.deploy.driver=pre-installed`, exits, and `nvidia-sandbox-validator` then crashloops with `device not bound to 'vfio-pci'`. `k8s-driver-manager` v0.10.0 exposes a `FORCE_REINSTALL` / `--force-reinstall` env+flag pair (visible in the binary's strings table), but it gates a later "same-config already loaded" branch inside `uninstallDriver`, not the `isHostDriver` short-circuit at the top — operators who set it and expect a bypass will report a false bug. There is currently no opt-out for the `isHostDriver` guard itself. The only mitigation available on `main` today is to remove the host NVIDIA stack before enabling the variant (the "Clean-host workaround" section below). An upcoming `container` variant of `cozystack.gpu-operator` is tracked in [#2766](https://github.com/cozystack/cozystack/pull/2766) — once merged it will give operators a no-purge path that keeps the host driver and exposes GPUs to pods rather than VMs — but it is not part of the current package and is **not** a usable workaround until it lands. Talos is unaffected because the Talos image ships only the `vfio-pci` extension; this section applies to Linux distributions where you installed the host driver yourself (typically Ubuntu / Debian / RHEL with `apt install nvidia-driver-*` or equivalent). See also [`packages/system/gpu-operator/examples/README.md`](../packages/system/gpu-operator/examples/README.md) for the native-pod-workload reference flow that predates the `container` variant.

### Symptom

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Minor: the Symptom section quotes logs but not the first thing an operator sees in kubectl get pods — nvidia-vfio-manager in Init:Error / Init:CrashLoopBackOff. Per the upstream code path the init container exits non-zero (it doesn't complete quietly), so adding one line about the pod state would help, since that's what people grep for first.

@lexfrei
Aleksei Sviridkin (lexfrei) force-pushed the feat/gpu-operator-passthrough-prereqs branch from e9f831c to 10044eb Compare June 8, 2026 16:37
@lexfrei

Copy link
Copy Markdown
Contributor Author

Thanks — all three blocking items plus the inline corrections are addressed in the latest push. I re-verified every claim against the v0.10.0 source you cited.

  1. "will not retry on their own" — fixed. Confirmed: uninstallDriver calls disableContainerizedDriver, sleeps 60s, then returns fmt.Errorf("driver is pre-installed on host"), so the init container exits non-zero and crash-loops. Reworded — pods sit in Init:CrashLoopBackOff and retry on their own; the kubectl delete only skips the up-to-5-minute backoff window.
  2. Stale pre-installed label — cleanup added. Confirmed rescheduleGPUOperatorComponents restores only the operand labels and never resets nvidia.com/gpu.deploy.driver. Added a post-recovery kubectl label node <NODE> nvidia.com/gpu.deploy.driver- with a note on why (and that it would otherwise disable the containerized-driver DaemonSet once feat(gpu-operator): add container variant for preinstalled host driver #2766 lands).
  3. apt purge zero-match abort — remediation rewritten. Switched to a build-from-installed flow: dpkg-query -W -f '${Package}\n' 'nvidia-*' 'libnvidia-*' 'cuda-*' (true globs over installed packages → no zero-match abort, no substring over-match), then review (drop DOCA/Mellanox libnvidia-* on converged hosts; .run-installed → nvidia-uninstall), then purge the reviewed list. I deliberately did not take the bot's suggestion to hardcode cuda-toolkit-*/cuda-drivers* — those are the exact patterns that trigger the abort on a host without the CUDA repo. nvidia-persistenced is now covered automatically by the nvidia-* glob.

Inline corrections also applied:

  • update-initramfs -u → -u -k all (rebuild every installed kernel's initramfs).
  • test -e /usr/bin/nvidia-smi → command -v nvidia-smi (matches the PATH lookup isHostDriver does; catches /usr/local/bin/nvidia-smi); added dkms status | grep -i nvidia.
  • Symptom section now leads with the Init:Error / Init:CrashLoopBackOff pod state from kubectl get pods.
  • Added blacklist nvidia_peermem for converged GPU + RDMA hosts.

Heads-up for whoever merges second: this and #2766 both edit the OS-support table in docs/gpu-vgpu.md and will conflict — trivial to resolve by combining #2766's container column with this PR's passthrough clean-host notes.

@kvaps Andrei Kvapil (kvaps) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM. Docs-only, and every correction from the earlier review is in: init-container retry behavior fixed, stale nvidia.com/gpu.deploy.driver label cleanup added, the apt purge 'cuda-*' footgun replaced with a dpkg-query -W approach (no aborted transaction on hosts without the CUDA repo), update-initramfs -u -k all, command -v nvidia-smi, and the Init:Error symptom line. Technically thorough. CI green.

Note: shares docs/gpu-vgpu.md with #2766/#2768 — expect a docs rebase on whichever merges last.

…site

The vfio-manager DaemonSet's k8s-driver-manager init container exits non-zero and labels the node pre-installed whenever it finds a host NVIDIA driver, leaving vfio-pci unbound and the sandbox validator in CrashLoopBackOff. Upstream offers no override knob, so the only working path today is a clean host. Document the symptom (including the Init:CrashLoopBackOff pod state), a build-from-installed purge plus module-blacklist workaround (with the autoremove-vs-DOCA warning and the apt zero-match-abort caveat), the post-reboot verification, and clearing the stale pre-installed label that the operator's success path never resets.

Assisted-By: Claude <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
@lexfrei
Aleksei Sviridkin (lexfrei) force-pushed the feat/gpu-operator-passthrough-prereqs branch from b2d3842 to cd36b0d Compare June 9, 2026 23:12
@lexfrei
Aleksei Sviridkin (lexfrei) merged commit c6f6fee into main Jun 9, 2026
9 checks passed
@lexfrei
Aleksei Sviridkin (lexfrei) deleted the feat/gpu-operator-passthrough-prereqs branch June 9, 2026 23:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/virtualization Issues or PRs related to virtualization (kubevirt, cdi, vmi, vm-import) kind/documentation Categorizes issue or PR as related to documentation size/L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants