From 4edae1724d14cef30ce2e5617e28f5d4b0135724 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Fern=C3=A1ndez=20L=C3=B3pez?= Date: Wed, 15 Oct 2025 16:34:18 +0200 Subject: [PATCH 1/2] nvidia-container-toolkit: wait for all device nodes to be present --- .../nvidia-container-toolkit/default.nix | 47 ++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/nixos/modules/services/hardware/nvidia-container-toolkit/default.nix b/nixos/modules/services/hardware/nvidia-container-toolkit/default.nix index 35a32b9ddcdb..7361b039a1ac 100644 --- a/nixos/modules/services/hardware/nvidia-container-toolkit/default.nix +++ b/nixos/modules/services/hardware/nvidia-container-toolkit/default.nix @@ -188,6 +188,10 @@ ]) ]; + services.udev.extraRules = '' + KERNEL=="nvidia", RUN+="${pkgs.systemd}/bin/systemctl restart nvidia-container-toolkit-cdi-generator.service'" + ''; + virtualisation = { containers.containersConf.settings = { engine = { @@ -289,11 +293,52 @@ systemd.services.nvidia-container-toolkit-cdi-generator = { description = "Container Device Interface (CDI) for Nvidia generator"; + requiredBy = lib.mkMerge [ + (lib.mkIf config.virtualisation.docker.enable [ "docker.service" ]) + (lib.mkIf config.virtualisation.podman.enable [ "podman.service" ]) + ]; wantedBy = [ "multi-user.target" ]; - after = [ "systemd-udev-settle.service" ]; serviceConfig = { RuntimeDirectory = "cdi"; RemainAfterExit = true; + ExecStartPre = pkgs.writeShellScript "wait-for-nvidia-devices" '' + set -eu + + gpus_dir="/proc/driver/nvidia/gpus" + max_wait_seconds=60 + + if [ ! -d "$gpus_dir" ]; then + echo "wait-for-nvidia-devices: $gpus_dir does not exist; nothing to wait for." + exit 0 + fi + + gpu_count=$(find "$gpus_dir" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l | tr -d ' ') + + if [ "$gpu_count" -eq 0 ]; then + echo "wait-for-nvidia-devices: no GPU entries found in $gpus_dir; nothing to wait for." + exit 0 + fi + + echo "wait-for-nvidia-devices: expecting $gpu_count /dev/nvidiaN device node(s)." + + elapsed=0 + while true; do + dev_count=$(find /dev -mindepth 1 -maxdepth 1 -type c -regex '.*/nvidia[0-9]+' 2>/dev/null | wc -l | tr -d ' ') + + if [ "$dev_count" -eq "$gpu_count" ]; then + echo "wait-for-nvidia-devices: found $dev_count matching device node(s)." + exit 0 + fi + + if [ "$elapsed" -ge "$max_wait_seconds" ]; then + echo "wait-for-nvidia-devices: timed out after $max_wait_seconds seconds; expected $gpu_count node(s) but found $dev_count." >&2 + exit 1 + fi + + sleep 1 + elapsed=$((elapsed + 1)) + done + ''; ExecStart = let script = pkgs.callPackage ./cdi-generate.nix { From f246b4444454b43048fed8655ad9651b16dda51a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Fern=C3=A1ndez=20L=C3=B3pez?= Date: Tue, 4 Nov 2025 18:29:23 +0100 Subject: [PATCH 2/2] chore: only pull systemctl binary --- .../services/hardware/nvidia-container-toolkit/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/services/hardware/nvidia-container-toolkit/default.nix b/nixos/modules/services/hardware/nvidia-container-toolkit/default.nix index 7361b039a1ac..9e715762fe9a 100644 --- a/nixos/modules/services/hardware/nvidia-container-toolkit/default.nix +++ b/nixos/modules/services/hardware/nvidia-container-toolkit/default.nix @@ -189,7 +189,7 @@ ]; services.udev.extraRules = '' - KERNEL=="nvidia", RUN+="${pkgs.systemd}/bin/systemctl restart nvidia-container-toolkit-cdi-generator.service'" + KERNEL=="nvidia", RUN+="${lib.getExe' config.systemd.package "systemctl"} restart nvidia-container-toolkit-cdi-generator.service'" ''; virtualisation = {