]> git.proxmox.com Git - qemu-server.git/blobdiff - PVE/QemuServer.pm
bump version to 8.2.1
[qemu-server.git] / PVE / QemuServer.pm
index dc0f9c7a33a8bd168a94c36a0c9801e3d9f211d2..82e7d6a6b0dc1e0ef9bad734901f0fe27e4da461 100644 (file)
@@ -124,14 +124,6 @@ PVE::JSONSchema::register_standard_option('pve-qm-stateuri', {
     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 {
@@ -429,7 +421,7 @@ wvista;; Microsoft Windows Vista
 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
@@ -1413,24 +1405,24 @@ sub print_drivedevice_full {
        my $unit = $drive->{index} % $maxdev;
 
        my $machine_version = extract_version($machine_type, kvm_user_version());
-       my $devicetype  = PVE::QemuServer::Drive::get_scsi_devicetype(
+       my $device_type = PVE::QemuServer::Drive::get_scsi_device_type(
            $drive, $storecfg, $machine_version);
 
        if (!$conf->{scsihw} || $conf->{scsihw} =~ m/^lsi/ || $conf->{scsihw} eq 'pvscsi') {
-           $device = "scsi-$devicetype,bus=$controller_prefix$controller.0,scsi-id=$unit";
+           $device = "scsi-$device_type,bus=$controller_prefix$controller.0,scsi-id=$unit";
        } else {
-           $device = "scsi-$devicetype,bus=$controller_prefix$controller.0,channel=0,scsi-id=0"
+           $device = "scsi-$device_type,bus=$controller_prefix$controller.0,channel=0,scsi-id=0"
                .",lun=$drive->{index}";
        }
        $device .= ",drive=drive-$drive_id,id=$drive_id";
 
-       if ($drive->{ssd} && ($devicetype eq 'block' || $devicetype eq 'hd')) {
+       if ($drive->{ssd} && ($device_type eq 'block' || $device_type eq 'hd')) {
            $device .= ",rotation_rate=1";
        }
        $device .= ",wwn=$drive->{wwn}" if $drive->{wwn};
 
        # only scsi-hd and scsi-cd support passing vendor and product information
-       if ($devicetype eq 'hd' || $devicetype eq 'cd') {
+       if ($device_type eq 'hd' || $device_type eq 'cd') {
            if (my $vendor = $drive->{vendor}) {
                $device .= ",vendor=$vendor";
            }
@@ -1454,9 +1446,9 @@ sub print_drivedevice_full {
            $unit = 0;
        }
 
-       my $devicetype = ($drive->{media} && $drive->{media} eq 'cdrom') ? "cd" : "hd";
+       my $device_type = ($drive->{media} && $drive->{media} eq 'cdrom') ? "cd" : "hd";
 
-       $device = "ide-$devicetype";
+       $device = "ide-$device_type";
        if ($drive->{interface} eq 'ide') {
            $device .= ",bus=ide.$controller,unit=$unit";
        } else {
@@ -1464,7 +1456,7 @@ sub print_drivedevice_full {
        }
        $device .= ",drive=drive-$drive_id,id=$drive_id";
 
-       if ($devicetype eq 'hd') {
+       if ($device_type eq 'hd') {
            if (my $model = $drive->{model}) {
                $model = URI::Escape::uri_unescape($model);
                $device .= ",model=$model";
@@ -1804,7 +1796,7 @@ sub print_vga_device {
        }
     }
 
-    die "no devicetype for $vga->{type}\n" if !$type;
+    die "no device-type for $vga->{type}\n" if !$type;
 
     my $memory = "";
     if ($vgamem_mb) {
@@ -2102,8 +2094,9 @@ sub qemu_created_version_fixups {
     # 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
@@ -2597,7 +2590,7 @@ sub check_local_resources {
     foreach my $k (keys %$conf) {
        if ($k =~ m/^usb/) {
            my $entry = parse_property_string('pve-qm-usb', $conf->{$k});
-           next if $entry->{host} =~ m/^spice$/i;
+           next if $entry->{host} && $entry->{host} =~ m/^spice$/i;
            if ($entry->{mapping}) {
                $add_missing_mapping->('usb', $k, $entry->{mapping});
                push @$mapped_res, $k;
@@ -3259,7 +3252,8 @@ sub windows_get_pinned_machine_version {
 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();
@@ -3508,6 +3502,8 @@ sub config_to_command {
     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);
@@ -4084,6 +4080,17 @@ sub config_to_command {
     }
     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);
@@ -7298,9 +7305,6 @@ sub pbs_live_restore {
 sub live_import_from_files {
     my ($mapping, $vmid, $conf, $restore_options) = @_;
 
-    die "only live-restore is implemented for restirng from files\n"
-       if !$restore_options->{live};
-
     my $live_restore_backing = {};
     for my $dev (keys %$mapping) {
        die "disk not support for live-restoring: '$dev'\n"
@@ -8150,7 +8154,8 @@ sub clone_disk {
     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"
@@ -8256,7 +8261,7 @@ no_data_clone:
     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;
 }