From ba58884565bedf54fda88f87e8507d56b3d65fdb Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 27 Oct 2026 16:38:21 +0100 Subject: [PATCH] fix(dev): stop GPU VM start while host processes use the GPU Co-Authored-By: Claude Opus 5.5 --- .../Development/StartDevelopmentQemuVm.php | 8 ++++++++ tests/Feature/DevelopmentQemuVmTest.php | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/app/Actions/Development/StartDevelopmentQemuVm.php b/app/Actions/Development/StartDevelopmentQemuVm.php index 8e52a6dcc4..11cd1a369c 100644 --- a/app/Actions/Development/StartDevelopmentQemuVm.php +++ b/app/Actions/Development/StartDevelopmentQemuVm.php @@ -155,10 +155,18 @@ class StartDevelopmentQemuVm /** * nvidia-persistenced keeps the GPU open, which blocks libvirt from moving it to vfio-pci. + * Other users of the GPU (for example a desktop session) must stop first: if libvirt unbinds the + * nvidia driver while they hold the GPU open, the GPU stays unusable until the host reboots. */ private function releaseHostGpu(): void { Process::run('systemctl stop nvidia-persistenced'); + + $users = Process::run('fuser -v /dev/nvidia[0-9]* 2>&1'); + + if ($users->successful() && trim($users->output()) !== '') { + throw new RuntimeException("These host processes still use the NVIDIA GPU, so it cannot move to the VM. Stop them (for example the display manager), or remove the GPU from the VM with --fresh and without --gpu:\n".trim($users->output())); + } } private function destroyVm(string $domain): void diff --git a/tests/Feature/DevelopmentQemuVmTest.php b/tests/Feature/DevelopmentQemuVmTest.php index 68c43ba143..3ab9355f24 100644 --- a/tests/Feature/DevelopmentQemuVmTest.php +++ b/tests/Feature/DevelopmentQemuVmTest.php @@ -817,3 +817,21 @@ it('seeds a gpu vm through the container so it installs the driver', function () Process::assertRan("docker exec 'coolify' php artisan dev:qemu:seed 'ubuntu-root' --as-localhost --gpu"); }); + +it('does not start a gpu vm while host processes still use the gpu', function () { + config(['development-qemu.storage_path' => sys_get_temp_dir().'/coolify-qemu-gpu-busy-test-'.uniqid()]); + Process::fake([ + '* net-dumpxml *' => Process::result(output: ''), + '* network inspect *' => Process::result(output: "172.18.0.0/16\n"), + '* dominfo *' => Process::result(output: 'exists'), + '* domstate *' => Process::result(output: "shut off\n"), + '* dumpxml --inactive *' => Process::result(output: ""), + 'fuser *' => Process::result(output: "/dev/nvidia0: root 1210 F...m Xorg\n"), + '*' => Process::result(), + ]); + + expect(fn () => StartDevelopmentQemuVm::run('ubuntu-root')) + ->toThrow(RuntimeException::class, 'Xorg'); + + Process::assertNotRan(fn ($process) => str_contains(remoteProcessScript($process), 'virsh start')); +});