mirror of
https://git.proxmox.com/git/qemu-server
synced 2025-07-09 10:27:03 +00:00
vm start/stop: cleanup passed-through pci devices in more situations
if the preparing of PCI devices or the start of the VM fails, we need to cleanup the PCI devices (reservations *and* mdevs), or else it might happen that there are leftovers which must be manually removed. to include also mdevs now, refactor the cleanup code from 'vm_stop_cleanup' into it's own function, and call that instead of only 'remove_pci_reservation' also simplifies the code, such that it now removes all PCI ids reserved for that VMID, since we cannot have multiple VMs with the same VMID anyway Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
parent
76b29aafd7
commit
1b189121fc
@ -5632,7 +5632,7 @@ sub vm_start_nolock {
|
|||||||
push @$cmd, '-uuid', $uuid if defined($uuid);
|
push @$cmd, '-uuid', $uuid if defined($uuid);
|
||||||
};
|
};
|
||||||
if (my $err = $@) {
|
if (my $err = $@) {
|
||||||
eval { PVE::QemuServer::PCI::remove_pci_reservation($pci_id_list) };
|
eval { cleanup_pci_devices($vmid, $conf) };
|
||||||
warn $@ if $@;
|
warn $@ if $@;
|
||||||
die $err;
|
die $err;
|
||||||
}
|
}
|
||||||
@ -5728,7 +5728,9 @@ sub vm_start_nolock {
|
|||||||
if (my $err = $@) {
|
if (my $err = $@) {
|
||||||
# deactivate volumes if start fails
|
# deactivate volumes if start fails
|
||||||
eval { PVE::Storage::deactivate_volumes($storecfg, $vollist); };
|
eval { PVE::Storage::deactivate_volumes($storecfg, $vollist); };
|
||||||
eval { PVE::QemuServer::PCI::remove_pci_reservation($pci_id_list) };
|
warn $@ if $@;
|
||||||
|
eval { cleanup_pci_devices($vmid, $conf) };
|
||||||
|
warn $@ if $@;
|
||||||
|
|
||||||
die "start failed: $err";
|
die "start failed: $err";
|
||||||
}
|
}
|
||||||
@ -5893,6 +5895,19 @@ sub get_vm_volumes {
|
|||||||
return $vollist;
|
return $vollist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub cleanup_pci_devices {
|
||||||
|
my ($vmid, $conf) = @_;
|
||||||
|
|
||||||
|
foreach my $key (keys %$conf) {
|
||||||
|
next if $key !~ m/^hostpci(\d+)$/;
|
||||||
|
my $hostpciindex = $1;
|
||||||
|
my $uuid = PVE::SysFSTools::generate_mdev_uuid($vmid, $hostpciindex);
|
||||||
|
my $d = parse_hostpci($conf->{$key});
|
||||||
|
PVE::SysFSTools::pci_cleanup_mdev_device($uuid) if $d->{mdev};
|
||||||
|
}
|
||||||
|
PVE::QemuServer::PCI::remove_pci_reservation($vmid);
|
||||||
|
}
|
||||||
|
|
||||||
sub vm_stop_cleanup {
|
sub vm_stop_cleanup {
|
||||||
my ($storecfg, $vmid, $conf, $keepActive, $apply_pending_changes) = @_;
|
my ($storecfg, $vmid, $conf, $keepActive, $apply_pending_changes) = @_;
|
||||||
|
|
||||||
@ -5924,20 +5939,7 @@ sub vm_stop_cleanup {
|
|||||||
unlink '/dev/shm/pve-shm-' . ($ivshmem->{name} // $vmid);
|
unlink '/dev/shm/pve-shm-' . ($ivshmem->{name} // $vmid);
|
||||||
}
|
}
|
||||||
|
|
||||||
my $ids = [];
|
cleanup_pci_devices($vmid, $conf);
|
||||||
foreach my $key (keys %$conf) {
|
|
||||||
next if $key !~ m/^hostpci(\d+)$/;
|
|
||||||
my $hostpciindex = $1;
|
|
||||||
my $d = parse_hostpci($conf->{$key});
|
|
||||||
my $uuid = PVE::SysFSTools::generate_mdev_uuid($vmid, $hostpciindex);
|
|
||||||
|
|
||||||
foreach my $pci (@{$d->{pciid}}) {
|
|
||||||
my $pciid = $pci->{id};
|
|
||||||
push @$ids, $pci->{id};
|
|
||||||
PVE::SysFSTools::pci_cleanup_mdev_device($pciid, $uuid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PVE::QemuServer::PCI::remove_pci_reservation($ids);
|
|
||||||
|
|
||||||
vmconfig_apply_pending($vmid, $conf, $storecfg) if $apply_pending_changes;
|
vmconfig_apply_pending($vmid, $conf, $storecfg) if $apply_pending_changes;
|
||||||
};
|
};
|
||||||
|
@ -552,15 +552,17 @@ my $write_pci_reservation_unlocked = sub {
|
|||||||
PVE::Tools::file_set_contents($PCIID_RESERVATION_FILE, $data);
|
PVE::Tools::file_set_contents($PCIID_RESERVATION_FILE, $data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# removes all pci reservations of the given vmid
|
||||||
sub remove_pci_reservation {
|
sub remove_pci_reservation {
|
||||||
my ($dropped_ids) = @_;
|
my ($vmid) = @_;
|
||||||
|
|
||||||
$dropped_ids = [ $dropped_ids ] if !ref($dropped_ids);
|
|
||||||
return if !scalar(@$dropped_ids); # do nothing for empty list
|
|
||||||
|
|
||||||
PVE::Tools::lock_file($PCIID_RESERVATION_LOCK, 2, sub {
|
PVE::Tools::lock_file($PCIID_RESERVATION_LOCK, 2, sub {
|
||||||
my $reservation_list = $parse_pci_reservation_unlocked->();
|
my $reservation_list = $parse_pci_reservation_unlocked->();
|
||||||
delete $reservation_list->@{$dropped_ids->@*};
|
for my $id (keys %$reservation_list) {
|
||||||
|
my $reservation = $reservation_list->{$id};
|
||||||
|
next if $reservation->{vmid} != $vmid;
|
||||||
|
delete $reservation_list->{$id};
|
||||||
|
}
|
||||||
$write_pci_reservation_unlocked->($reservation_list);
|
$write_pci_reservation_unlocked->($reservation_list);
|
||||||
});
|
});
|
||||||
die $@ if $@;
|
die $@ if $@;
|
||||||
|
Loading…
Reference in New Issue
Block a user