optional => 1,
});
-PVE::JSONSchema::register_standard_option('pve-qemu-machine', {
- description => "Specifies the QEMU machine type.",
- type => 'string',
- pattern => '(pc|pc(-i440fx)?-\d+(\.\d+)+(\+pve\d+)?(\.pxe)?|q35|pc-q35-\d+(\.\d+)+(\+pve\d+)?(\.pxe)?|virt(?:-\d+(\.\d+)+)?(\+pve\d+)?)',
- maxLength => 40,
- optional => 1,
-});
-
# FIXME: remove in favor of just using the INotify one, it's cached there exactly the same way
my $nodename_cache;
sub nodename {
win7;; Microsoft Windows 7
win8;; Microsoft Windows 8/2012/2012r2
win10;; Microsoft Windows 10/2016/2019
-win11;; Microsoft Windows 11/2022
+win11;; Microsoft Windows 11/2022/2025
l24;; Linux 2.4 Kernel
l26;; Linux 2.6 - 6.X Kernel
solaris;; Solaris/OpenSolaris/OpenIndiania kernel
# check if we need to apply some handling for VMs that always use the latest machine version but
# had a machine version transition happen that affected HW such that, e.g., an OS config change
# would be required (we do not want to pin machine version for non-windows OS type)
+ my $machine_conf = PVE::QemuServer::Machine::parse_machine($conf->{machine});
if (
- (!defined($conf->{machine}) || $conf->{machine} =~ m/^(?:pc|q35|virt)$/) # non-versioned machine
+ (!defined($machine_conf->{type}) || $machine_conf->{type} =~ m/^(?:pc|q35|virt)$/) # non-versioned machine
&& (!defined($meta->{'creation-qemu'}) || !min_version($meta->{'creation-qemu'}, 6, 1)) # created before 6.1
&& (!$forced_vers || min_version($forced_vers, 6, 1)) # handle snapshot-rollback/migrations
&& min_version($kvmver, 6, 1) # only need to apply the change since 6.1
sub get_vm_machine {
my ($conf, $forcemachine, $arch, $add_pve_version, $kvmversion) = @_;
- my $machine = $forcemachine || $conf->{machine};
+ my $machine_conf = PVE::QemuServer::Machine::parse_machine($conf->{machine});
+ my $machine = $forcemachine || $machine_conf->{type};
if (!$machine || $machine =~ m/^(?:pc|q35|virt)$/) {
$kvmversion //= kvm_user_version();
my $kvm = $conf->{kvm};
my $nodename = nodename();
+ my $machine_conf = PVE::QemuServer::Machine::parse_machine($conf->{machine});
+
my $arch = get_vm_arch($conf);
my $kvm_binary = get_command_for_arch($arch);
my $kvmver = kvm_user_version($kvm_binary);
}
push @$machineFlags, "type=${machine_type_min}";
+ PVE::QemuServer::Machine::assert_valid_machine_property($conf, $machine_conf);
+
+ if (my $viommu = $machine_conf->{viommu}) {
+ if ($viommu eq 'intel') {
+ unshift @$devices, '-device', 'intel-iommu,intremap=on,caching-mode=on';
+ push @$machineFlags, 'kernel-irqchip=split';
+ } elsif ($viommu eq 'virtio') {
+ push @$devices, '-device', 'virtio-iommu-pci';
+ }
+ }
+
push @$cmd, @$devices;
push @$cmd, '-rtc', join(',', @$rtcFlags) if scalar(@$rtcFlags);
push @$cmd, '-machine', join(',', @$machineFlags) if scalar(@$machineFlags);
my ($newvmid, $dst_drivename, $efisize) = $dest->@{qw(vmid drivename efisize)};
my ($storage, $format) = $dest->@{qw(storage format)};
- my $use_drive_mirror = $full && $running && $src_drivename && !$snapname;
+ my $unused = defined($src_drivename) && $src_drivename =~ /^unused/;
+ my $use_drive_mirror = $full && $running && $src_drivename && !$snapname && !$unused;
if ($src_drivename && $dst_drivename && $src_drivename ne $dst_drivename) {
die "cloning from/to EFI disk requires EFI disk\n"
my $disk = dclone($drive);
delete $disk->{format};
$disk->{file} = $newvolid;
- $disk->{size} = $size if defined($size);
+ $disk->{size} = $size if defined($size) && !$unused;
return $disk;
}