Skip to content

SCHED-1041: Pre-create GPU lib placeholders so a failing nvidia-container-cli cannot break the cluster - #2703

Merged
theyoprst merged 2 commits into
soperator-release-4.0from
yoprst/SCHED-1041/fix
Jul 10, 2026
Merged

theyoprst merged 2 commits into
soperator-release-4.0from
yoprst/SCHED-1041/fix

Conversation

@theyoprst

@theyoprst theyoprst commented Jul 6, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

At cold cluster bring-up all workers run nvidia-container-cli against the shared jail at the same moment. The CLI creates 0-byte placeholder files on the shared jail and bind-mounts the host driver libs over them. Confirmed in 7 e2e reproductions:

  1. The workers race to create the same files. The loser fails (mount error: file creation failed: .../gsp_ga10x.bin: file exists), its container restarts, and the solo re-run succeeds — this worker always recovers by accident.
  2. Before dying, the failing CLI deletes every 0-byte placeholder it had mounted — including the ones under the other worker's live bind mounts. That worker's kernel detaches its mounts, and it stays GPU-broken for the pod's lifetime: prepull-container-image fails the bring-up, or multi-node GPU jobs fail later with file too short.

The second half is not limited to bring-up races: any CLI failure on any worker at any time deletes the placeholders under the whole fleet's mounts.

Solution

Pre-create the placeholders as small non-empty marker files before the CLI runs (precreate_gpu_placeholders in complement_jail.sh):

  • the file set comes from nvidia-container-cli list at runtime, so driver upgrades are handled automatically; the /dev and /run entries resolve to objects already created by the kernel and system daemons, so the existence check skips them;
  • on the first bring-up the missing files are created under a cross-node flock, with the host file's mode; on every later pod start everything already exists and no lock is taken;
  • the CLI then finds every file present and skips creation — no race, no crash;
  • the CLI's failure cleanup only deletes empty files, so a failing CLI can no longer break the other workers, whatever the failure cause.

The CLI result is verified instead of trusted: every mount the CLI created must stay attached and show real content by path (by size — a placeholder passes plain existence checks), whatever file set the enabled driver capabilities select. The libnvidia-ml.so.1 soname is additionally verified after ldconfig (repaired by a local ldconfig run if missing) when NVML is mounted. On any failure the container exits so kubelet restarts it.

The two places that treated "empty file" as "placeholder" (the CPU-worker libdummy mounts and the populate_jail cleanup) now match by size and versioned lib name (lib*.so.* smaller than 64 bytes), covering both old 0-byte and new marker placeholders while leaving the jail image's other small files (ncurses linker scripts, glibc stub archives) alone.

Testing

  • shellcheck + smoke tests with stubbed CLI/flock/stat: cold and warm paths, node-local filtering, failure exits, the size predicates.
  • three green e2e cold bring-ups (28922118210, 28952699476, 28973074103, SB_MAN_H200) together exercised every pre-create path: sole creator, all-present gate, and a worker that queued on the lock mid-creation and found everything present on the re-check. Both CLIs skipped all creations in each run, no anomalies. The [nvml] log telemetry stays for verifying this in production.

Release Notes

Fix: GPU driver lib placeholders in the shared jail are now pre-created as non-empty files, so concurrent nvidia-container-cli runs never race to create them and a failing run can no longer delete them from under the other workers' bind mounts — fixing intermittent NVML load failures ("cannot open shared object file" / "file too short") on multi-worker bring-up.

@theyoprst
theyoprst force-pushed the yoprst/SCHED-1041/fix branch 2 times, most recently from 9be495d to 9be3791 Compare July 7, 2026 09:45
@theyoprst theyoprst changed the title SCHED-1041: Serialize GPU lib propagation, repair NVML symlinks Jul 7, 2026
@theyoprst
theyoprst force-pushed the yoprst/SCHED-1041/fix branch 2 times, most recently from 46e459a to 5f6b894 Compare July 7, 2026 19:04
@theyoprst theyoprst changed the title SCHED-1041: Retry GPU lib propagation until mounts survive, repair NVML symlinks Jul 7, 2026
@theyoprst
theyoprst force-pushed the yoprst/SCHED-1041/fix branch 2 times, most recently from 884787f to daba8dd Compare July 8, 2026 14:11
Comment thread images/common/scripts/complement_jail.sh Outdated
Comment thread images/jail/populate_jail_entrypoint.sh Outdated
…ults so one worker's failing nvidia-container-cli cannot break NVML on the whole cluster.
@theyoprst
theyoprst force-pushed the yoprst/SCHED-1041/fix branch from 8ae4151 to f82840b Compare July 9, 2026 09:27
…esystem filter since stray placeholders are harmless, and scope the umask in a subshell instead of forcing directory modes
Comment thread images/common/scripts/complement_jail.sh

This branch was previously deployed

1 inactive deployment
e2e — 2573e022 Deployed Jul 9, 2026 by theyoprst via e2e-test #7542
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

2 participants