From 730d10449b24276d623a9f246171a67fe4efd13f Mon Sep 17 00:00:00 2001 From: Piotr Mlocek Date: Wed, 1 Apr 2026 12:05:12 -0700 Subject: [PATCH] fix(gpu): gate Tegra-specific runtime adjustments --- crates/openshell-bootstrap/src/docker.rs | 2 +- crates/openshell-sandbox/src/process.rs | 74 +++++++++++++++---- .../nvidia-device-plugin-helmchart.yaml | 3 - 3 files changed, 62 insertions(+), 17 deletions(-) diff --git a/crates/openshell-bootstrap/src/docker.rs b/crates/openshell-bootstrap/src/docker.rs index 403a680f7..4c08b35b1 100644 --- a/crates/openshell-bootstrap/src/docker.rs +++ b/crates/openshell-bootstrap/src/docker.rs @@ -603,7 +603,7 @@ pub async fn ensure_container( // nvidia runtime or CDI spec generation running inside k3s (for sandbox // pods) can apply the same config. const HOST_FILES_DIR: &str = "/etc/nvidia-container-runtime/host-files-for-container.d"; - if std::path::Path::new(HOST_FILES_DIR).is_dir() { + if !device_ids.is_empty() && std::path::Path::new(HOST_FILES_DIR).is_dir() { let mut binds = host_config.binds.take().unwrap_or_default(); binds.push(format!("{HOST_FILES_DIR}:{HOST_FILES_DIR}:ro")); host_config.binds = Some(binds); diff --git a/crates/openshell-sandbox/src/process.rs b/crates/openshell-sandbox/src/process.rs index 9726e4b75..8de5a4fcd 100644 --- a/crates/openshell-sandbox/src/process.rs +++ b/crates/openshell-sandbox/src/process.rs @@ -34,6 +34,25 @@ fn scrub_sensitive_env(cmd: &mut Command) { cmd.env_remove(SSH_HANDSHAKE_SECRET_ENV); } +#[cfg(not(any( + target_os = "macos", + target_os = "ios", + target_os = "haiku", + target_os = "redox" +)))] +fn has_gpu_devices() -> bool { + const GPU_DEVICE_PATHS: &[&str] = &[ + "/dev/nvidiactl", + "/dev/nvidia-uvm", + "/dev/nvidia-uvm-tools", + "/dev/nvidia-modeset", + "/dev/nvmap", + ]; + GPU_DEVICE_PATHS + .iter() + .any(|path| std::path::Path::new(path).exists()) +} + /// Handle to a running process. pub struct ProcessHandle { child: Child, @@ -414,26 +433,33 @@ pub fn drop_privileges(policy: &SandboxPolicy) -> Result<()> { target_os = "redox" )))] { + let preserve_gpu_groups = has_gpu_devices(); // Snapshot the container-level supplemental GIDs (e.g. injected by // CDI for GPU device access) before initgroups replaces them. // Exclude GID 0 (root) to avoid inadvertent privilege retention. let root_gid = nix::unistd::Gid::from_raw(0); - let container_gids: Vec = nix::unistd::getgroups() - .unwrap_or_default() - .into_iter() - .filter(|&g| g != root_gid) - .collect(); + let container_gids: Vec = if preserve_gpu_groups { + nix::unistd::getgroups() + .unwrap_or_default() + .into_iter() + .filter(|&g| g != root_gid) + .collect() + } else { + Vec::new() + }; nix::unistd::initgroups(user_cstr.as_c_str(), group.gid).into_diagnostic()?; - // Merge back any CDI-injected GIDs that initgroups dropped so that - // exec'd processes retain access to GPU devices (e.g. /dev/nvmap on - // Tegra requires the video GID). - let mut merged: Vec = nix::unistd::getgroups().unwrap_or_default(); - for gid in container_gids { - if !merged.contains(&gid) { - merged.push(gid); + if preserve_gpu_groups { + // Merge back CDI-injected GIDs that initgroups dropped so that + // exec'd processes retain access to GPU devices. + let mut merged: Vec = + nix::unistd::getgroups().unwrap_or_default(); + for gid in container_gids { + if !merged.contains(&gid) { + merged.push(gid); + } } + nix::unistd::setgroups(&merged).into_diagnostic()?; } - nix::unistd::setgroups(&merged).into_diagnostic()?; } } @@ -629,6 +655,28 @@ mod tests { ); } + #[cfg(not(any( + target_os = "macos", + target_os = "ios", + target_os = "haiku", + target_os = "redox" + )))] + #[test] + fn has_gpu_devices_detects_present_nodes() { + assert_eq!( + has_gpu_devices(), + [ + "/dev/nvidiactl", + "/dev/nvidia-uvm", + "/dev/nvidia-uvm-tools", + "/dev/nvidia-modeset", + "/dev/nvmap", + ] + .iter() + .any(|path| std::path::Path::new(path).exists()) + ); + } + #[tokio::test] async fn scrub_sensitive_env_removes_ssh_handshake_secret() { let mut cmd = Command::new("/usr/bin/env"); diff --git a/deploy/kube/gpu-manifests/nvidia-device-plugin-helmchart.yaml b/deploy/kube/gpu-manifests/nvidia-device-plugin-helmchart.yaml index 737efdb54..1cb0ca70a 100644 --- a/deploy/kube/gpu-manifests/nvidia-device-plugin-helmchart.yaml +++ b/deploy/kube/gpu-manifests/nvidia-device-plugin-helmchart.yaml @@ -31,9 +31,6 @@ spec: targetNamespace: nvidia-device-plugin createNamespace: true valuesContent: |- - image: - repository: ghcr.io/nvidia/k8s-device-plugin - tag: "2ab68c16" runtimeClassName: nvidia deviceListStrategy: cdi-cri deviceIDStrategy: index