mirror of
https://github.com/nestriness/nestri.git
synced 2026-11-09 00:42:27 +02:00
feat(build): put virtio-nvgpu's Vulkan layer into the guest rootfs (#356)
On an NVIDIA host, NVIDIA's Vulkan driver in the guest lists ray tracing, optical flow, binary import and CUDA kernel launch, then fails `vkCreateDevice` with `VK_ERROR_INITIALIZATION_FAILED` for each of them. An engine that enables what it is offered does not start. virtio-nvgpu's guest layer (`vklayer/`, nestrilabs/virtio-nvgpu#5) hides those extensions. It acts only on an NVIDIA device in a guest that has the virtio-nvgpu driver, so on AMD and Intel boxes it loads and does nothing. - A new `nvgpu-layer-build` stage builds the layer from virtio-nvgpu at `NVGPU_REF`, the same setting the kernel build uses for the guest driver. The commit is recorded in `/usr/share/nestri/virtio-nvgpu.rev`. - The layer and its manifest go in `/usr/lib` and `/usr/share/vulkan/implicit_layer.d`. The missing-library check covers the layer. **Merge after nestrilabs/virtio-nvgpu#5.** The default `NVGPU_REF=dev` has no `vklayer/` until that PR lands, so `make build` fails at this stage before then. Built on nestripc-1 with `NVGPU_REF=feat/v0.2-compute` (virtio-nvgpu 112eac4) and pushed: - `ghcr.io/nestrilabs/nestri/base:latest` sha256:152a4485… - `ghcr.io/nestrilabs/nesbox/jail:latest` sha256:df813051…, rebuilt on that base from nesbox dev 6d37597, which includes the vhost-user forwarding Measured on box2 (RTX 3060, 595.104.02) with virtio-nvgpu's vkrt probe: with the layer on, a plain device is created and none of the seven extensions are offered. With it off, all seven are offered and fail with -3.
This commit is contained in:
+39
-2
@@ -168,6 +168,40 @@ RUN --mount=type=cache,target=/root/.cargo/registry \
|
||||
find /artifacts/nestri -type f -printf '/%P\n' > /artifacts/nestri/.manifest
|
||||
|
||||
|
||||
# ───────────────────────────────────────────────────────────
|
||||
# virtio-nvgpu's Vulkan layer — for guests on an NVIDIA host
|
||||
#
|
||||
# On an NVIDIA host the guest runs NVIDIA's own Vulkan driver over a
|
||||
# forwarded device, and that driver offers ray tracing, optical flow and a
|
||||
# few others it then cannot create a device with: vkCreateDevice fails, and
|
||||
# an engine that enables what it is offered does not start. The layer hides
|
||||
# them. It acts only on an NVIDIA device in a guest with the virtio-nvgpu
|
||||
# driver, so on an AMD or Intel box it is loaded and does nothing.
|
||||
#
|
||||
# Built from virtio-nvgpu's own tree at NVGPU_REF, the same ref the kernel
|
||||
# build takes the guest driver from (build/Makefile), because the layer's job
|
||||
# is to say what that driver and its backend can do. The commit is recorded
|
||||
# in /usr/share/nestri/virtio-nvgpu.rev.
|
||||
# ───────────────────────────────────────────────────────────
|
||||
FROM builder AS nvgpu-layer-build
|
||||
ARG NVGPU_GIT=https://github.com/nestrilabs/virtio-nvgpu.git
|
||||
ARG NVGPU_REF=dev
|
||||
RUN --mount=type=cache,target=/root/.cargo/registry \
|
||||
git init -q /build/virtio-nvgpu && cd /build/virtio-nvgpu && \
|
||||
git fetch -q --depth=1 "${NVGPU_GIT}" "${NVGPU_REF}" && git checkout -q FETCH_HEAD && \
|
||||
cargo build --release -p nvgpu-vklayer && \
|
||||
install -Dm755 target/release/libVkLayer_nvgpu.so \
|
||||
/artifacts/nvgpu/usr/lib/libVkLayer_nvgpu.so && \
|
||||
mkdir -p /artifacts/nvgpu/usr/share/vulkan/implicit_layer.d /artifacts/nvgpu/usr/share/nestri && \
|
||||
sed 's|"./libVkLayer_nvgpu.so"|"libVkLayer_nvgpu.so"|' vklayer/VkLayer_nvgpu.json \
|
||||
> /artifacts/nvgpu/usr/share/vulkan/implicit_layer.d/VkLayer_nvgpu.json && \
|
||||
grep -q '"library_path": "libVkLayer_nvgpu.so"' \
|
||||
/artifacts/nvgpu/usr/share/vulkan/implicit_layer.d/VkLayer_nvgpu.json && \
|
||||
git rev-parse HEAD > /artifacts/nvgpu/usr/share/nestri/virtio-nvgpu.rev && \
|
||||
cd / && rm -rf /build/virtio-nvgpu && \
|
||||
find /artifacts/nvgpu -type f -printf '/%P\n' > /artifacts/nvgpu/.manifest
|
||||
|
||||
|
||||
# ───────────────────────────────────────────────────────────
|
||||
# umu-launcher — built here, not installed from the distribution
|
||||
#
|
||||
@@ -394,10 +428,12 @@ LABEL org.opencontainers.image.source="https://github.com/nestrilabs/nestri"
|
||||
# purpose, not an oversight.
|
||||
COPY --from=mesa-build /artifacts/mesa/.manifest /tmp/mesa.manifest
|
||||
COPY --from=nestri-build /artifacts/nestri/.manifest /tmp/nestri.manifest
|
||||
RUN cat /tmp/mesa.manifest /tmp/nestri.manifest > /tmp/.strip-manifest && \
|
||||
rm -f /tmp/mesa.manifest /tmp/nestri.manifest
|
||||
COPY --from=nvgpu-layer-build /artifacts/nvgpu/.manifest /tmp/nvgpu.manifest
|
||||
RUN cat /tmp/mesa.manifest /tmp/nestri.manifest /tmp/nvgpu.manifest > /tmp/.strip-manifest && \
|
||||
rm -f /tmp/mesa.manifest /tmp/nestri.manifest /tmp/nvgpu.manifest
|
||||
COPY --from=mesa-build /artifacts/mesa /
|
||||
COPY --from=nestri-build /artifacts/nestri /
|
||||
COPY --from=nvgpu-layer-build /artifacts/nvgpu /
|
||||
COPY --from=umu-build /artifacts/umu /
|
||||
|
||||
# **No Proton here.** It is attached to a box at run time, mounted at
|
||||
@@ -520,6 +556,7 @@ RUN failed=0; \
|
||||
: > /tmp/missing-libs; \
|
||||
for f in /usr/bin/nesinit /usr/bin/nescope /usr/bin/neshub /usr/bin/neswire \
|
||||
/usr/bin/nesgamepad /usr/lib/libnescapture_layer.so /usr/lib/libSDL2-2.0.so.0 \
|
||||
/usr/lib/libVkLayer_nvgpu.so \
|
||||
/usr/bin/dbus-daemon /usr/bin/pipewire \
|
||||
/usr/bin/wireplumber /usr/bin/ip \
|
||||
/usr/lib/libgallium-*.so /usr/lib/libEGL_mesa.so.0 \
|
||||
|
||||
+7
-3
@@ -76,9 +76,11 @@ INFINITY_REV ?= e6c85d841f25e21393a7ea47fdef286318915d8c
|
||||
INFINITY_SERIES := patches/cachyos/tuned-eevdf/$(KERNEL_REF:cachyos-%=%)
|
||||
INFINITY_WORK := $(OUTPUT_DIR)/infinity-sched
|
||||
|
||||
# The guest half of NVIDIA forwarding, built into the kernel. A branch, so each
|
||||
# kernel build takes the driver as it is now; set NVGPU_REF to a tag or commit
|
||||
# to pin it. The commit built is recorded as $(KERNEL_OUTPUT).nvgpu-rev.
|
||||
# The guest half of NVIDIA forwarding: the driver, built into the kernel, and
|
||||
# its Vulkan layer, built into the rootfs. A branch, so each build takes them
|
||||
# as they are now; set NVGPU_REF to a tag or commit to pin it. The commit built
|
||||
# is recorded as $(KERNEL_OUTPUT).nvgpu-rev and, in the image, as
|
||||
# /usr/share/nestri/virtio-nvgpu.rev. Build both from the same ref.
|
||||
NVGPU_GIT ?= https://github.com/nestrilabs/virtio-nvgpu.git
|
||||
NVGPU_REF ?= dev
|
||||
NVGPU_WORK := $(OUTPUT_DIR)/virtio-nvgpu
|
||||
@@ -94,11 +96,13 @@ endif
|
||||
build:
|
||||
DOCKER_BUILDKIT=1 $(CONTAINER_RT) build $(if $(FORCE_REBUILD),--no-cache,) \
|
||||
--build-arg PROTON_IMAGE=$(PROTON_REF) \
|
||||
--build-arg NVGPU_GIT=$(NVGPU_GIT) --build-arg NVGPU_REF=$(NVGPU_REF) \
|
||||
-f Containerfile -t $(IMAGE_NAME):latest --target runtime_prod $(CONTEXT)
|
||||
|
||||
build-debug:
|
||||
DOCKER_BUILDKIT=1 $(CONTAINER_RT) build $(if $(FORCE_REBUILD),--no-cache,) \
|
||||
--build-arg PROTON_IMAGE=$(PROTON_REF) \
|
||||
--build-arg NVGPU_GIT=$(NVGPU_GIT) --build-arg NVGPU_REF=$(NVGPU_REF) \
|
||||
-f Containerfile -t $(IMAGE_NAME):debug --target runtime_debug $(CONTEXT)
|
||||
|
||||
# Hours, and only when PROTON_TAG moves. Two steps: the build runs on the host,
|
||||
|
||||
@@ -166,6 +166,12 @@ modules. The driver's parameters therefore go on the command line as
|
||||
warns that it is doing so.
|
||||
- An AMD or Intel host is unaffected. The driver binds only to the forwarding
|
||||
device, and nothing offers that device to those guests.
|
||||
- **The rootfs carries virtio-nvgpu's Vulkan layer**, built from the same
|
||||
`NVGPU_REF`. NVIDIA's driver in a guest offers ray tracing and a few other
|
||||
extensions it cannot then create a device with; the layer hides them. It
|
||||
acts only on an NVIDIA device in a guest with the forwarding driver, so AMD
|
||||
and Intel boxes are unaffected. Build the kernel and the image from the same
|
||||
ref, or the layer describes a different driver than the one booted.
|
||||
- The NVIDIA libraries are **not** part of the image. They must be the same
|
||||
build as the host's kernel module, so the host shares its own copy with the
|
||||
guest at run time.
|
||||
|
||||
Reference in New Issue
Block a user