diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm index 9117588b..9c20a7ce 100644 --- a/PVE/QemuServer.pm +++ b/PVE/QemuServer.pm @@ -6163,6 +6163,11 @@ sub vm_commandline { my $defaults = load_defaults(); my $cmd = config_to_command($storecfg, $vmid, $conf, $defaults, $forcemachine, $forcecpu); + # if the vm is not running, we need to clean up the reserved/created devices + if (!PVE::QemuServer::Helpers::vm_running_locally($vmid)) { + eval { cleanup_pci_devices($vmid, $conf) }; + warn $@ if $@; + } return PVE::Tools::cmd2string($cmd); } diff --git a/PVE/QemuServer/PCI.pm b/PVE/QemuServer/PCI.pm index 3b0da39d..3aa260d6 100644 --- a/PVE/QemuServer/PCI.pm +++ b/PVE/QemuServer/PCI.pm @@ -523,6 +523,9 @@ sub parse_hostpci_devices { my sub choose_hostpci_devices { my ($devices, $vmid) = @_; + # if the vm is running, we must be in 'showcmd', so don't actually reserve or create anything + my $is_running = PVE::QemuServer::Helpers::vm_running_locally($vmid) ? 1 : 0; + my $used = {}; my $add_used_device = sub { @@ -555,8 +558,10 @@ my sub choose_hostpci_devices { my $ids = [map { $_->{id} } @$alternative]; next if grep { defined($used->{$_}) } @$ids; # already used - eval { reserve_pci_usage($ids, $vmid, 10, undef) }; - next if $@; + if (!$is_running) { + eval { reserve_pci_usage($ids, $vmid, 10, undef) }; + next if $@; + } # found one that is not used or reserved $add_used_device->($alternative); diff --git a/test/run_config2command_tests.pl b/test/run_config2command_tests.pl index d48ef562..9b5e87ff 100755 --- a/test/run_config2command_tests.pl +++ b/test/run_config2command_tests.pl @@ -196,7 +196,10 @@ $qemu_server_module->mock( }, get_initiator_name => sub { return 'iqn.1993-08.org.debian:01:aabbccddeeff'; - } + }, + cleanup_pci_devices => { + # do nothing + }, ); my $qemu_server_config;