diff --git a/debian/changelog b/debian/changelog index 8b63a739..5cb73077 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,123 @@ +qemu-server (9.0.23) trixie; urgency=medium + + * fix #6713: snapshot volume chain: fix snapshot after disk move with + zeroinit. + + * api: dbus-vmstate: fix return property name in schema. + + * vm status: also queue query-proxmox-support QMP commands to avoid stacking + timeouts. + + * api: add missing snapshot info to get-config return schema. + + * agent: implement fsfreeze helper to better handle lost commands to avoid + unnecessarily blocking the QMP socket for a prolonged time. + + * migration: conntrack: work around systemd issue where scope for VM might + become blocked. + + * fix #6828: remote migration: bump timeout for writing configuration to + accommodate volume activation. Allow for up to 2 minutes instead of just + 10 seconds. + + * fix #6882: backup provider api: fix backup with TPM state by correctly + generating node name. + + * backup: fleecing: avoid warning when querying block node size for TPM + state. + + * cfg2cmd: turn off the high-precision event timer (HPET) for Linux VMs + running at least kernel 2.6 and machine type >= 10.1, which will avoid + slightly increased CPU usage with newer QEMU versions. Further, Linux + kernel since v2.6.26+ (from July 2008!) can use the kvm-clock timer. + + -- Proxmox Support Team Fri, 03 Oct 2025 22:12:22 +0200 + +qemu-server (9.0.22) trixie; urgency=medium + + * partially fix #6805: + - api: modify vm config: privilege checks for VM-state-related + properties. + - api: clone: properly remove all snapshot-related info. + + * api: create/update: disallow setting 'running-nets-host-mtu' via API. + + * resume from suspended: properly handle 'nets-host-mtu'. + + * vm command line: handle 'nets-host-mtu' property in snapshot. + + * vm start: remove left-over VM-state-related properties. + + * api schema: fix broken line continuation in the description for three + properties. + + -- Proxmox Support Team Wed, 17 Sep 2025 18:37:06 +0200 + +qemu-server (9.0.21) trixie; urgency=medium + + * fix #6608: expose vIOMMU driver address space bit width 'aw-bits' option. + + * migration: tell users to upgrade the target node if nets-host-mtu is not + supported by the target qemu-server package version. + + -- Proxmox Support Team Wed, 10 Sep 2025 15:17:11 +0200 + +qemu-server (9.0.20) trixie; urgency=medium + + * api: rrd: add missing ds parameter for generating PNG graph. + + * virtio-net: fix migration between default/non-default MTUs starting with + machine version 10.0+pve1. + + * api: vm start: introduce nets-host-mtu parameter for migration compat. + + * snapshot: introduce running-nets-host-mtu property. + + -- Proxmox Support Team Thu, 04 Sep 2025 19:49:27 +0200 + +qemu-server (9.0.19) trixie; urgency=medium + + * fix generating block-dev option on VM live import. + + * fix #6680: do not use a top throttle node when using scsi-block, like for + passthrough of SCSI devices and 10+ machine version, as passed through + disks do not support bandwidth limitations. + + -- Proxmox Support Team Tue, 26 Aug 2025 09:35:28 +0200 + +qemu-server (9.0.18) trixie; urgency=medium + + * close #6378: expose guest-phys-bits CPU option to cope with using the host + CPU type on CPU models where the CPU address width and the IOMMU address + width are different. On such systems the guest-phys-bits option needs to + be set to properly support huge pages and/or VFIO. + + * fix #6675: template backup: fix regression with IDE/SATA and blockdev. + + * fix #6680: avoid setting nonexistent 'write-cache' and 'drive_id' options + for passed-through disks using SCSI with machine version >= 10.0. + + * dbus-vmstate: fix installation path for script. + + -- Proxmox Support Team Thu, 14 Aug 2025 12:33:11 +0200 + +qemu-server (9.0.17) trixie; urgency=medium + + * fix #6648: api: available machine versions: ensure array of versions is + correctly ordered numerically. + + * prohibit using snapshot-as-volume-chain qcow2 images with VMs that use a + pre-10.0 machine version. + + * blockdev: attach/detach: silence errors for QMP commands for which failure + may be expected. + + * blockdev: delete/replace: re-use common detach helper to avoid + false-positive errors in the syslog for devices that QEMU already + auto-removes itself. + + -- Proxmox Support Team Tue, 12 Aug 2025 15:10:38 +0200 + qemu-server (9.0.16) trixie; urgency=medium * vmstate: always quiesce warnings on VM stop cleanup as at this point, the diff --git a/debian/control b/debian/control index f02ef742..5ac6b0fc 100644 --- a/debian/control +++ b/debian/control @@ -25,7 +25,7 @@ Build-Depends: debhelper-compat (= 13), pve-edk2-firmware-ovmf (>= 4.2025.02-3), pve-firewall, pve-ha-manager , - pve-qemu-kvm (>= 9.2~), + pve-qemu-kvm (>= 10.1~), Standards-Version: 4.5.1 Homepage: https://www.proxmox.com diff --git a/src/Makefile b/src/Makefile index 3f9b8c6f..f8e9a2d9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -6,7 +6,6 @@ install: $(MAKE) -C bin install $(MAKE) -C qmeventd install $(MAKE) -C query-machine-capabilities install - $(MAKE) -C dbus-vmstate install $(MAKE) -C usr install .PHONY: test diff --git a/src/PVE/API2/NodeCapabilities/Qemu/Migration.pm b/src/PVE/API2/NodeCapabilities/Qemu/Migration.pm index 98d683c3..31879007 100644 --- a/src/PVE/API2/NodeCapabilities/Qemu/Migration.pm +++ b/src/PVE/API2/NodeCapabilities/Qemu/Migration.pm @@ -29,7 +29,7 @@ __PACKAGE__->register_method({ type => 'object', additionalProperties => 0, properties => { - 'dbus-vmstate' => { + 'has-dbus-vmstate' => { type => 'boolean', description => 'Whether the host supports live-migrating additional' . ' VM state via the dbus-vmstate helper.', diff --git a/src/PVE/API2/Qemu.pm b/src/PVE/API2/Qemu.pm index 83542482..71bedc1e 100644 --- a/src/PVE/API2/Qemu.pm +++ b/src/PVE/API2/Qemu.pm @@ -732,6 +732,7 @@ my $check_cpu_model_access = sub { my $cpuoptions = { 'cores' => 1, 'cpu' => 1, + 'runningcpu' => 1, 'cpulimit' => 1, 'cpuunits' => 1, 'numa' => 1, @@ -751,6 +752,7 @@ my $hwtypeoptions = { 'hotplug' => 1, 'kvm' => 1, 'machine' => 1, + 'runningmachine' => 1, 'scsihw' => 1, 'smbios1' => 1, 'tablet' => 1, @@ -957,7 +959,7 @@ my $check_vm_modify_config_perm = sub { $rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.PowerMgmt']); } elsif ($diskoptions->{$opt}) { $rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.Config.Disk']); - } elsif ($opt =~ m/^net\d+$/) { + } elsif ($opt =~ m/^net\d+$/ || $opt eq 'running-nets-host-mtu') { $rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.Config.Network']); } elsif ($cloudinitoptions->{$opt} || $opt =~ m/^ipconfig\d+$/) { $rpcenv->check_vm_perm( @@ -1168,6 +1170,12 @@ __PACKAGE__->register_method({ default => 0, description => "Start VM after it was created successfully.", }, + 'ha-managed' => { + optional => 1, + type => 'boolean', + default => 0, + description => "Add the VM as a HA resource after it was created.", + }, 'import-working-storage' => get_standard_option( 'pve-storage-id', { @@ -1202,6 +1210,7 @@ __PACKAGE__->register_method({ my $force = extract_param($param, 'force'); my $pool = extract_param($param, 'pool'); my $start_after_create = extract_param($param, 'start'); + my $ha_managed = extract_param($param, 'ha-managed'); my $storage = extract_param($param, 'storage'); my $unique = extract_param($param, 'unique'); my $live_restore = extract_param($param, 'live-restore'); @@ -1378,6 +1387,15 @@ __PACKAGE__->register_method({ eval { PVE::API2::Qemu->vm_start({ vmid => $vmid, node => $node }) }; warn $@ if $@; } + + if ($ha_managed) { + print "Add as HA resource\n"; + my $state = $start_after_create ? 'started' : 'stopped'; + eval { + PVE::API2::HA::Resources->create({ sid => "vm:$vmid", state => $state }); + }; + warn $@ if $@; + } }; my $createfn = sub { @@ -1461,6 +1479,15 @@ __PACKAGE__->register_method({ PVE::QemuConfig->lock_config_full($vmid, 1, $realcmd); + if ($ha_managed) { + print "Add as HA resource\n"; + my $state = $start_after_create ? 'started' : 'stopped'; + eval { + PVE::API2::HA::Resources->create({ sid => "vm:$vmid", state => $state }); + }; + warn $@ if $@; + } + if ($start_after_create && !$live_restore) { print "Execute autostart\n"; eval { PVE::API2::Qemu->vm_start({ vmid => $vmid, node => $node }) }; @@ -1632,7 +1659,8 @@ __PACKAGE__->register_method({ my $path = "pve-vm-9.0/$param->{vmid}"; $path = "pve2-vm/$param->{vmid}" if !-e "/var/lib/rrdcached/db/${path}"; - return PVE::RRD::create_rrd_graph($path, $param->{timeframe}, $param->{cf}); + return PVE::RRD::create_rrd_graph($path, $param->{timeframe}, $param->{ds}, + $param->{cf}); }, }); @@ -1718,13 +1746,17 @@ __PACKAGE__->register_method({ returns => { description => "The VM configuration.", type => "object", - properties => PVE::QemuServer::json_config_properties({ - digest => { - type => 'string', - description => - 'SHA1 digest of configuration file. This can be used to prevent concurrent modifications.', + properties => PVE::QemuServer::json_config_properties( + { + digest => { + type => 'string', + description => + 'SHA1 digest of configuration file. This can be used to prevent concurrent modifications.', + }, }, - }), + 0, + 1, + ), }, code => sub { my ($param) = @_; @@ -2113,6 +2145,7 @@ my $update_vm_api = sub { } push @delete, 'runningmachine' if $conf->{runningmachine}; push @delete, 'runningcpu' if $conf->{runningcpu}; + push @delete, 'running-nets-host-mtu' if $conf->{'running-nets-host-mtu'}; } PVE::QemuConfig->check_lock($conf) if !$skiplock; @@ -3322,7 +3355,7 @@ __PACKAGE__->register_method({ $status->{spice} = 1 if $spice; $status->{clipboard} = $vga->{clipboard}; } - $status->{agent} = 1 if PVE::QemuServer::get_qga_key($conf, 'enabled'); + $status->{agent} = 1 if PVE::QemuServer::Agent::get_qga_key($conf, 'enabled'); return $status; }, @@ -3383,6 +3416,16 @@ __PACKAGE__->register_method({ default => 0, description => 'Whether to migrate conntrack entries for running VMs.', }, + 'nets-host-mtu' => { + type => 'string', + pattern => 'net\d+=\d+(,net\d+=\d+)*', + optional => 1, + description => + 'Used for migration compat. List of VirtIO network devices and their effective' + . ' host_mtu setting according to the QEMU object model on the source side of' + . ' the migration. A value of 0 means that the host_mtu parameter is to be' + . ' avoided for the corresponding device.', + }, }, }, returns => { @@ -3414,6 +3457,7 @@ __PACKAGE__->register_method({ my $targetstorage = $get_root_param->('targetstorage'); my $force_cpu = $get_root_param->('force-cpu'); my $with_conntrack_state = $get_root_param->('with-conntrack-state'); + my $nets_host_mtu = $get_root_param->('nets-host-mtu'); my $storagemap; @@ -3501,6 +3545,7 @@ __PACKAGE__->register_method({ forcemachine => $machine, timeout => $timeout, forcecpu => $force_cpu, + 'nets-host-mtu' => $nets_host_mtu, }; PVE::QemuServer::vm_start($storecfg, $vmid, $params, $migrate_opts); @@ -4342,7 +4387,10 @@ __PACKAGE__->register_method({ || $opt eq 'parent' || $opt eq 'snaptime' || $opt eq 'vmstate' - || $opt eq 'snapstate'; + || $opt eq 'snapstate' + || $opt eq 'runningcpu' + || $opt eq 'runningmachine' + || $opt eq 'running-nets-host-mtu'; # no need to copy unused images, because VMID(owner) changes anyways next if $opt =~ m/^unused\d+$/; @@ -4623,8 +4671,8 @@ __PACKAGE__->register_method({ digest => { type => 'string', description => - 'Prevent changes if current configuration file has different SHA1" - ." digest. This can be used to prevent concurrent modifications.', + 'Prevent changes if current configuration file has different SHA1' + . ' digest. This can be used to prevent concurrent modifications.', maxLength => 40, optional => 1, }, @@ -4645,8 +4693,8 @@ __PACKAGE__->register_method({ 'target-digest' => { type => 'string', description => - 'Prevent changes if the current config file of the target VM has a" - ." different SHA1 digest. This can be used to detect concurrent modifications.', + 'Prevent changes if the current config file of the target VM has a' + . ' different SHA1 digest. This can be used to detect concurrent modifications.', maxLength => 40, optional => 1, }, @@ -4775,7 +4823,7 @@ __PACKAGE__->register_method({ PVE::QemuConfig->write_config($vmid, $conf); - my $do_trim = PVE::QemuServer::get_qga_key($conf, 'fstrim_cloned_disks'); + my $do_trim = PVE::QemuServer::Agent::get_qga_key($conf, 'fstrim_cloned_disks'); if ($running && $do_trim && PVE::QemuServer::Agent::qga_check_running($vmid)) { eval { mon_cmd($vmid, "guest-fstrim") }; } @@ -6956,7 +7004,7 @@ __PACKAGE__->register_method({ path => '{vmid}/dbus-vmstate', method => 'POST', proxyto => 'node', - description => 'Stop the dbus-vmstate helper for the given VM if running.', + description => 'Control the dbus-vmstate helper for a given running VM.', permissions => { check => ['perm', '/vms/{vmid}', ['VM.Migrate']], }, diff --git a/src/PVE/API2/Qemu/Agent.pm b/src/PVE/API2/Qemu/Agent.pm index 05ef4f50..de36ce1e 100644 --- a/src/PVE/API2/Qemu/Agent.pm +++ b/src/PVE/API2/Qemu/Agent.pm @@ -3,13 +3,16 @@ package PVE::API2::Qemu::Agent; use strict; use warnings; -use PVE::RESTHandler; +use JSON; +use MIME::Base64 qw(encode_base64 decode_base64); + use PVE::JSONSchema qw(get_standard_option); +use PVE::RESTHandler; + +use PVE::QemuConfig; use PVE::QemuServer; use PVE::QemuServer::Agent qw(agent_cmd check_agent_error); use PVE::QemuServer::Monitor qw(mon_cmd); -use MIME::Base64 qw(encode_base64 decode_base64); -use JSON; use base qw(PVE::RESTHandler); @@ -327,7 +330,7 @@ __PACKAGE__->register_method({ type => 'array', description => 'The command as a list of program + arguments.', items => { - format => 'string', + type => 'string', description => 'A single part of the program + arguments.', }, }, diff --git a/src/PVE/API2/Qemu/Machine.pm b/src/PVE/API2/Qemu/Machine.pm index 41281af2..0fc1ea6c 100644 --- a/src/PVE/API2/Qemu/Machine.pm +++ b/src/PVE/API2/Qemu/Machine.pm @@ -81,7 +81,11 @@ __PACKAGE__->register_method({ } } - return [sort { $b->{id} cmp $a->{id} } ($machines->@*, $pve_machines->@*)]; # merge & sort + return [ + sort { + PVE::QemuServer::Machine::machine_version_cmp($b->{id}, $a->{id}) + } ($machines->@*, $pve_machines->@*) + ]; # merge & sort }; die "could not load supported machine versions - $@\n" if $@; return $supported_machine_list; diff --git a/src/PVE/QMPClient.pm b/src/PVE/QMPClient.pm index 87d61144..1935a336 100644 --- a/src/PVE/QMPClient.pm +++ b/src/PVE/QMPClient.pm @@ -86,7 +86,7 @@ sub queue_cmd { # execute a single command sub cmd { - my ($self, $vmid, $cmd, $timeout) = @_; + my ($self, $vmid, $cmd, $timeout, $noerr) = @_; my $result; @@ -110,6 +110,8 @@ sub cmd { } elsif ($cmd->{execute} =~ m/^(eject|change)/) { $timeout = 60; # note: cdrom mount command is slow } elsif ($cmd->{execute} eq 'guest-fsfreeze-freeze') { + # consider using the guest_fsfreeze() helper in Agent.pm + # # freeze syncs all guest FS, if we kill it it stays in an unfreezable # locked state with high probability, so use an generous timeout $timeout = 60 * 60; # 1 hour @@ -155,8 +157,11 @@ sub cmd { $self->queue_execute($timeout, 2); - die "VM $vmid qmp command '$cmd->{execute}' failed - $queue_info->{error}" - if defined($queue_info->{error}); + if (defined($queue_info->{error})) { + die "VM $vmid qmp command '$cmd->{execute}' failed - $queue_info->{error}" if !$noerr; + $result = { error => $queue_info->{error} }; + $result->{'error-is-timeout'} = 1 if $queue_info->{'error-is-timeout'}; + } return $result; } @@ -477,12 +482,12 @@ sub mux_input { &$check_queue($self); } -# This gets called every second to update player info, etc... sub mux_timeout { my ($self, $mux, $fh) = @_; if (my $queue_info = &$lookup_queue_info($self, $fh)) { $queue_info->{error} = "got timeout\n"; + $queue_info->{'error-is-timeout'} = 1; $self->{mux}->inbuffer($fh, ''); # clear to avoid warnings } diff --git a/src/PVE/QemuConfig.pm b/src/PVE/QemuConfig.pm index e0853d65..bb469197 100644 --- a/src/PVE/QemuConfig.pm +++ b/src/PVE/QemuConfig.pm @@ -243,10 +243,11 @@ sub __snapshot_save_vmstate { my $runningmachine = PVE::QemuServer::Machine::get_current_qemu_machine($vmid); # get current QEMU -cpu argument to ensure consistency of custom CPU models - my $runningcpu; - if (my $pid = PVE::QemuServer::check_running($vmid)) { - $runningcpu = PVE::QemuServer::CPUConfig::get_cpu_from_running_vm($pid); - } + my $pid = PVE::QemuServer::Helpers::vm_running_locally($vmid) + or die "cannot obtain PID for VM $vmid!\n"; + my $runningcpu = PVE::QemuServer::CPUConfig::get_cpu_from_running_vm($pid); + + my $nets_host_mtu = PVE::QemuServer::Network::get_nets_host_mtu($vmid, $conf); if (!$suspend) { $conf = $conf->{snapshots}->{$snapname}; @@ -255,6 +256,7 @@ sub __snapshot_save_vmstate { $conf->{vmstate} = $statefile; $conf->{runningmachine} = $runningmachine; $conf->{runningcpu} = $runningcpu; + $conf->{'running-nets-host-mtu'} = $nets_host_mtu; return $statefile; } @@ -295,7 +297,7 @@ sub __snapshot_check_freeze_needed { return ( $running, $running - && PVE::QemuServer::parse_guest_agent($config)->{enabled} + && PVE::QemuServer::Agent::get_qga_key($config, 'enabled') && PVE::QemuServer::Agent::qga_check_running($vmid), ); } else { @@ -310,8 +312,8 @@ sub __snapshot_freeze { eval { mon_cmd($vmid, "guest-fsfreeze-thaw"); }; warn "guest-fsfreeze-thaw problems - $@" if $@; } else { - eval { mon_cmd($vmid, "guest-fsfreeze-freeze"); }; - warn "guest-fsfreeze-freeze problems - $@" if $@; + eval { PVE::QemuServer::Agent::guest_fsfreeze($vmid); }; + warn $@ if $@; } } @@ -474,6 +476,8 @@ sub __snapshot_rollback_hook { # re-initializing its random number generator $conf->{vmgenid} = PVE::QemuServer::generate_uuid(); } + + $data->{'nets-host-mtu'} = delete($conf->{'running-nets-host-mtu'}); } return; @@ -514,6 +518,7 @@ sub __snapshot_rollback_vm_start { statefile => $vmstate, forcemachine => $data->{forcemachine}, forcecpu => $data->{forcecpu}, + 'nets-host-mtu' => $data->{'nets-host-mtu'}, }; PVE::QemuServer::vm_start($storecfg, $vmid, $params); } diff --git a/src/PVE/QemuMigrate.pm b/src/PVE/QemuMigrate.pm index e18cc2aa..78954c20 100644 --- a/src/PVE/QemuMigrate.pm +++ b/src/PVE/QemuMigrate.pm @@ -27,6 +27,7 @@ use PVE::Tunnel; use PVE::QemuConfig; use PVE::QemuMigrate::Helpers; +use PVE::QemuServer::Agent; use PVE::QemuServer::BlockJob; use PVE::QemuServer::CPUConfig; use PVE::QemuServer::Drive qw(checked_volume_format); @@ -195,8 +196,6 @@ sub prepare { # test if VM exists my $conf = $self->{vmconf} = PVE::QemuConfig->load_config($vmid); - my $version = PVE::QemuServer::Helpers::get_node_pvecfg_version($self->{node}); - my $repl_conf = PVE::ReplicationConfig->new(); $self->{replication_jobcfg} = $repl_conf->find_local_replication_job($vmid, $self->{node}); $self->{is_replicated} = $repl_conf->check_for_existing_jobs($vmid, 1); @@ -924,7 +923,7 @@ sub phase1_remote { 'firewall-config' => $fw_conf_str, }; - PVE::Tunnel::write_tunnel($self->{tunnel}, 10, 'config', $params); + PVE::Tunnel::write_tunnel($self->{tunnel}, 120, 'config', $params); } sub phase1_cleanup { @@ -998,6 +997,10 @@ sub phase2_start_local_cluster { push @$cmd, '--force-cpu', $start->{forcecpu}; } + if ($start->{'nets-host-mtu'}) { + push @$cmd, '--nets-host-mtu', $start->{'nets-host-mtu'}; + } + if ($self->{storage_migration}) { push @$cmd, '--targetstorage', ($self->{opts}->{targetstorage} // '1'); } @@ -1049,6 +1052,7 @@ sub phase2_start_local_cluster { }; my $target_replicated_volumes = {}; + my $target_nets_host_mtu_not_supported; # Note: We try to keep $spice_ticket secret (do not pass via command line parameter) # instead we pipe it through STDIN @@ -1106,11 +1110,16 @@ sub phase2_start_local_cluster { }, errfunc => sub { my $line = shift; + $target_nets_host_mtu_not_supported = 1 + if $line =~ m/^Unknown option: nets-host-mtu/; $self->log('info', "[$self->{node}] $line"); }, noerr => 1, ); + die "target node $self->{node} is too old for preserving VirtIO-net MTU, please upgrade\n" + if $target_nets_host_mtu_not_supported; + die "remote command failed with exit code $exitcode\n" if $exitcode; die "unable to detect remote migration address\n" @@ -1187,6 +1196,10 @@ sub phase2 { }, }; + if (my $nets_host_mtu = PVE::QemuServer::Network::get_nets_host_mtu($vmid, $conf)) { + $params->{start_params}->{'nets-host-mtu'} = $nets_host_mtu; + } + my ($tunnel_info, $spice_port); my @online_local_volumes = $self->filter_local_volumes('online'); @@ -1711,7 +1724,7 @@ sub phase3_cleanup { if ( $self->{storage_migration} - && PVE::QemuServer::parse_guest_agent($conf)->{fstrim_cloned_disks} + && PVE::QemuServer::Agent::get_qga_key($conf, 'fstrim_cloned_disks') && $self->{running} ) { if (!$self->{vm_was_paused}) { diff --git a/src/PVE/QemuServer.pm b/src/PVE/QemuServer.pm index e30b27cb..de1c39a5 100644 --- a/src/PVE/QemuServer.pm +++ b/src/PVE/QemuServer.pm @@ -53,9 +53,10 @@ use PVE::QMPClient; use PVE::QemuConfig; use PVE::QemuConfig::NoWrite; use PVE::QemuMigrate::Helpers; -use PVE::QemuServer::Agent qw(qga_check_running); +use PVE::QemuServer::Agent qw(get_qga_key parse_guest_agent qga_check_running); use PVE::QemuServer::Blockdev; use PVE::QemuServer::BlockJob; +use PVE::QemuServer::Cfg2Cmd; use PVE::QemuServer::Helpers qw(config_aware_timeout get_iscsi_initiator_name min_version kvm_user_version windows_version); use PVE::QemuServer::Cloudinit; @@ -67,11 +68,11 @@ use PVE::QemuServer::Drive qw( checked_volume_format drive_is_cloudinit drive_is_cdrom - drive_is_read_only parse_drive print_drive storage_allows_io_uring_default ); +use PVE::QemuServer::DriveDevice qw(print_drivedevice_full scsihw_infos); use PVE::QemuServer::Machine; use PVE::QemuServer::Memory qw(get_current_memory); use PVE::QemuServer::MetaInfo; @@ -148,35 +149,6 @@ my $watchdog_fmt = { }; PVE::JSONSchema::register_format('pve-qm-watchdog', $watchdog_fmt); -my $agent_fmt = { - enabled => { - description => - "Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.", - type => 'boolean', - default => 0, - default_key => 1, - }, - fstrim_cloned_disks => { - description => "Run fstrim after moving a disk or migrating the VM.", - type => 'boolean', - optional => 1, - default => 0, - }, - 'freeze-fs-on-backup' => { - description => "Freeze/thaw guest filesystems on backup for consistency.", - type => 'boolean', - optional => 1, - default => 1, - }, - type => { - description => "Select the agent type", - type => 'string', - default => 'virtio', - optional => 1, - enum => [qw(virtio isa)], - }, -}; - my $vga_fmt = { type => { description => "Select the VGA type. Using type 'cirrus' is not recommended.", @@ -376,6 +348,7 @@ my $confdesc = { type => 'string', # NOTE: When extending, also consider extending `%guest_types` in `Import/ESXi.pm`. enum => [qw(other wxp w2k w2k3 w2k8 wvista win7 win8 win10 win11 l24 l26 solaris)], + default => 'other', description => "Specify guest operating system.", verbose_description => < "Enable/disable communication with the QEMU Guest Agent and its properties.", type => 'string', - format => $agent_fmt, + format => $PVE::QemuServer::Agent::agent_fmt, }, kvm => { optional => 1, @@ -636,6 +609,15 @@ EODESCR pattern => $PVE::QemuServer::CPUConfig::qemu_cmdline_cpu_re, format_description => 'QEMU -cpu parameter', }, + 'running-nets-host-mtu' => { + type => 'string', + pattern => 'net\d+=\d+(,net\d+=\d+)*', + optional => 1, + description => + 'List of VirtIO network devices and their effective host_mtu setting. A value of 0' + . ' means that the host_mtu parameter is to be avoided for the corresponding device.' + . ' This is used internally for snapshots.', + }, machine => get_standard_option('pve-qemu-machine'), arch => { description => "Virtual processor architecture. Defaults to the host.", @@ -739,8 +721,8 @@ my $cicustom_fmt = { meta => { type => 'string', optional => 1, - description => 'Specify a custom file containing all meta data passed to the VM via" - ." cloud-init. This is provider specific meaning configdrive2 and nocloud differ.', + description => 'Specify a custom file containing all meta data passed to the VM via' + . ' cloud-init. This is provider specific meaning configdrive2 and nocloud differ.', format => 'pve-volume-id', format_description => 'volume', }, @@ -1197,132 +1179,6 @@ sub print_keyboarddevice_full { return "usb-kbd,id=keyboard,bus=ehci.0,port=2"; } -sub print_drivedevice_full { - my ($storecfg, $conf, $vmid, $drive, $bridges, $arch, $machine_type) = @_; - - my $device = ''; - my $maxdev = 0; - - my $machine_version = extract_version($machine_type, kvm_user_version()); - - my $drive_id = PVE::QemuServer::Drive::get_drive_id($drive); - if ($drive->{interface} eq 'virtio') { - my $pciaddr = print_pci_addr("$drive_id", $bridges, $arch); - $device = 'virtio-blk-pci'; - # for the switch to -blockdev, there is no blockdev for 'none' - if (!min_version($machine_version, 10, 0) || $drive->{file} ne 'none') { - $device .= ",drive=drive-$drive_id"; - } - $device .= ",id=${drive_id}${pciaddr}"; - $device .= ",iothread=iothread-$drive_id" if $drive->{iothread}; - } elsif ($drive->{interface} eq 'scsi') { - - my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $drive); - my $unit = $drive->{index} % $maxdev; - - 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-$device_type,bus=$controller_prefix$controller.0,scsi-id=$unit"; - } else { - $device = "scsi-$device_type,bus=$controller_prefix$controller.0,channel=0,scsi-id=0" - . ",lun=$drive->{index}"; - } - # for the switch to -blockdev, there is no blockdev for 'none' - if (!min_version($machine_version, 10, 0) || $drive->{file} ne 'none') { - $device .= ",drive=drive-$drive_id"; - } - $device .= ",id=$drive_id"; - - # for the switch to -blockdev, the SCSI device ID needs to be explicitly specified - if (min_version($machine_version, 10, 0)) { - $device .= ",device_id=drive-${drive_id}"; - } - - 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 ($device_type eq 'hd' || $device_type eq 'cd') { - if (my $vendor = $drive->{vendor}) { - $device .= ",vendor=$vendor"; - } - if (my $product = $drive->{product}) { - $device .= ",product=$product"; - } - } - - } elsif ($drive->{interface} eq 'ide' || $drive->{interface} eq 'sata') { - my $maxdev = ($drive->{interface} eq 'sata') ? $PVE::QemuServer::Drive::MAX_SATA_DISKS : 2; - my $controller = int($drive->{index} / $maxdev); - my $unit = $drive->{index} % $maxdev; - - # machine type q35 only supports unit=0 for IDE rather than 2 units. This wasn't handled - # correctly before, so e.g. index=2 was mapped to controller=1,unit=0 rather than - # controller=2,unit=0. Note that odd indices never worked, as they would be mapped to - # unit=1, so to keep backwards compat for migration, it suffices to keep even ones as they - # were before. Move odd ones up by 2 where they don't clash. - if (PVE::QemuServer::Machine::machine_type_is_q35($conf) && $drive->{interface} eq 'ide') { - $controller += 2 * ($unit % 2); - $unit = 0; - } - - my $device_type = ($drive->{media} && $drive->{media} eq 'cdrom') ? "cd" : "hd"; - - $device = "ide-$device_type"; - if ($drive->{interface} eq 'ide') { - $device .= ",bus=ide.$controller,unit=$unit"; - } else { - $device .= ",bus=ahci$controller.$unit"; - } - if (!min_version($machine_version, 10, 0) || $drive->{file} ne 'none') { - $device .= ",drive=drive-$drive_id"; - } - $device .= ",id=$drive_id"; - - if ($device_type eq 'hd') { - if (my $model = $drive->{model}) { - $model = URI::Escape::uri_unescape($model); - $device .= ",model=$model"; - } - if ($drive->{ssd}) { - $device .= ",rotation_rate=1"; - } - } - $device .= ",wwn=$drive->{wwn}" if $drive->{wwn}; - } elsif ($drive->{interface} eq 'usb') { - die "implement me"; - # -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 - } else { - die "unsupported interface type"; - } - - $device .= ",bootindex=$drive->{bootindex}" if $drive->{bootindex}; - - if (my $serial = $drive->{serial}) { - $serial = URI::Escape::uri_unescape($serial); - $device .= ",serial=$serial"; - } - - if (min_version($machine_version, 10, 0)) { # for the switch to -blockdev - if (!drive_is_cdrom($drive)) { - my $write_cache = 'on'; - if (my $cache = $drive->{cache}) { - $write_cache = 'off' if $cache eq 'writethrough' || $cache eq 'directsync'; - } - $device .= ",write-cache=$write_cache"; - } - for my $o (qw(rerror werror)) { - $device .= ",$o=$drive->{$o}" if defined($drive->{$o}); - } - } - - return $device; -} - sub print_drive_commandline_full { my ($storecfg, $vmid, $drive, $live_restore_name) = @_; @@ -1335,6 +1191,13 @@ sub print_drive_commandline_full { my ($path, $format) = PVE::QemuServer::Drive::get_path_and_format($storecfg, $drive, $live_restore_name); + if ($scfg && $scfg->{'snapshot-as-volume-chain'} && $format && $format eq 'qcow2') { + # the print_drive_commandline_full() function is only used if machine version is < 10.0 + die "storage for '$drive->{file}' is configured for snapshots as a volume chain - this" + . " requires QEMU machine version >= 10.0. See" + . " https://pve.proxmox.com/wiki/QEMU_Machine_Version_Upgrade\n"; + } + my $is_rbd = $path =~ m/^rbd:/; my $opts = ''; @@ -1433,7 +1296,17 @@ sub print_pbs_blockdev { } sub print_netdevice_full { - my ($vmid, $conf, $net, $netid, $bridges, $use_old_bios_files, $arch, $machine_version) = @_; + my ( + $vmid, + $conf, + $net, + $netid, + $bridges, + $use_old_bios_files, + $arch, + $machine_version, + $host_mtu_migration, # force this value for host_mtu, 0 means force absence of param + ) = @_; my $device = $net->{model}; if ($net->{model} eq 'virtio') { @@ -1460,21 +1333,44 @@ sub print_netdevice_full { my $mtu = $net->{mtu}; - if ($net->{model} eq 'virtio' && $net->{bridge}) { + my $migration_skip_host_mtu = defined($host_mtu_migration) && $host_mtu_migration == 0; + print "netdev $netid: not adding 'host_mtu' parameter for migration compat\n" + if $migration_skip_host_mtu; + + if ($net->{model} eq 'virtio' && $net->{bridge} && !$migration_skip_host_mtu) { my $bridge_mtu = PVE::Network::read_bridge_mtu($net->{bridge}); + if ($host_mtu_migration) { + print "netdev $netid: using 'host_mtu=$host_mtu_migration' for migration compat\n"; + $mtu = $host_mtu_migration; + } + if (!defined($mtu) || $mtu == 1) { $mtu = $bridge_mtu; } elsif ($mtu < 576) { die "netdev $netid: MTU '$mtu' is smaller than the IP minimum MTU '576'\n"; } elsif ($mtu > $bridge_mtu) { - die "netdev $netid: MTU '$mtu' is bigger than the bridge MTU '$bridge_mtu'\n"; + die "netdev $netid: MTU '$mtu' is bigger than the bridge MTU '$bridge_mtu'" + . " - adjust the MTU for the network device in the VM configuration, while ensuring" + . " that the bridge is configured as desired.\n"; } - $tmpstr .= ",host_mtu=$mtu" if $mtu != 1500; + if (min_version($machine_version, 10, 0, 1) || $host_mtu_migration) { + # Always add host_mtu for migration compatibility, because the presence of host_mtu + # means that the virtual hardware is generated differently (at least for i440fx) + $tmpstr .= ",host_mtu=$mtu"; + } else { + $tmpstr .= ",host_mtu=$mtu" if $mtu != 1500; + } } elsif (defined($mtu)) { - warn - "WARN: netdev $netid: ignoring MTU '$mtu', not using VirtIO or no bridge configured.\n"; + my $msg_prefix = "netdev $netid: ignoring MTU '$mtu'"; + if ($migration_skip_host_mtu) { + log_warn("$msg_prefix, not used on the source side according to migration parameters"); + } elsif (!$net->{bridge}) { + log_warn("$msg_prefix, no bridge configured"); + } else { + log_warn("$msg_prefix, not using VirtIO"); + } } if ($use_old_bios_files) { @@ -1725,27 +1621,6 @@ sub parse_watchdog { return $res; } -sub parse_guest_agent { - my ($conf) = @_; - - return {} if !defined($conf->{agent}); - - my $res = eval { parse_property_string($agent_fmt, $conf->{agent}) }; - warn $@ if $@; - - # if the agent is disabled ignore the other potentially set properties - return {} if !$res->{enabled}; - return $res; -} - -sub get_qga_key { - my ($conf, $key) = @_; - return undef if !defined($conf->{agent}); - - my $agent = parse_guest_agent($conf); - return $agent->{$key}; -} - sub parse_vga { my ($value) = @_; @@ -1784,16 +1659,20 @@ sub qemu_created_version_fixups { # add JSON properties for create and set function sub json_config_properties { - my ($prop, $with_disk_alloc) = @_; + my ($prop, $with_disk_alloc, $with_snapshot_info) = @_; - my $skip_json_config_opts = { - parent => 1, - snaptime => 1, - vmstate => 1, - runningmachine => 1, - runningcpu => 1, - meta => 1, - }; + my $skip_json_config_opts; + if (!$with_snapshot_info) { + $skip_json_config_opts = { + parent => 1, + snaptime => 1, + vmstate => 1, + 'running-nets-host-mtu' => 1, + runningmachine => 1, + runningcpu => 1, + meta => 1, + }; + } foreach my $opt (keys %$confdesc) { next if $skip_json_config_opts->{$opt}; @@ -2664,8 +2543,8 @@ sub vmstatus { $d->{netout} = 0; $d->{netin} = 0; - $d->{diskread} = 0; - $d->{diskwrite} = 0; + $d->{diskread} = undef; + $d->{diskwrite} = undef; $d->{template} = 1 if PVE::QemuConfig->is_template($conf); @@ -2819,9 +2698,15 @@ sub vmstatus { $res->{$vmid}->{'running-qemu'} = $version; }; + my $proxmox_support_cb = sub { + my ($vmid, $resp) = @_; + $res->{$vmid}->{'proxmox-support'} = $resp->{'return'} // {}; + }; + my $statuscb = sub { my ($vmid, $resp) = @_; + $qmpclient->queue_cmd($vmid, $proxmox_support_cb, 'query-proxmox-support'); $qmpclient->queue_cmd($vmid, $blockstatscb, 'query-blockstats'); $qmpclient->queue_cmd($vmid, $machinecb, 'query-machines'); $qmpclient->queue_cmd($vmid, $versioncb, 'query-version'); @@ -2846,16 +2731,6 @@ sub vmstatus { $qmpclient->queue_execute(undef, 2); - foreach my $vmid (keys %$list) { - next if $opt_vmid && ($vmid ne $opt_vmid); - next if !$res->{$vmid}->{pid}; #not running - - # we can't use the $qmpclient since it might have already aborted on - # 'query-balloon', but this might also fail for older versions... - my $qemu_support = eval { mon_cmd($vmid, "query-proxmox-support") }; - $res->{$vmid}->{'proxmox-support'} = $qemu_support // {}; - } - foreach my $vmid (keys %$list) { next if $opt_vmid && ($vmid ne $opt_vmid); $res->{$vmid}->{qmpstatus} = $res->{$vmid}->{status} if !$res->{$vmid}->{qmpstatus}; @@ -3198,9 +3073,11 @@ sub config_to_command { my ($forcemachine, $forcecpu, $live_restore_backing, $dry_run) = $options->@{qw(force-machine force-cpu live-restore-backing dry-run)}; + my $is_template = PVE::QemuConfig->is_template($conf); + # minimize config for templates, they can only start for backup, # so most options besides the disks are irrelevant - if (PVE::QemuConfig->is_template($conf)) { + if ($is_template) { my $newconf = { template => 1, # in case below code checks that kvm => 0, # to prevent an error on hosts without virtualization extensions @@ -3355,7 +3232,7 @@ sub config_to_command { q35 => $q35, }; my ($ovmf_cmd, $ovmf_machine_flags) = PVE::QemuServer::OVMF::print_ovmf_commandline( - $conf, $storecfg, $vmid, $hw_info, $version_guard, + $conf, $storecfg, $vmid, $hw_info, $version_guard, $is_template, ); push $cmd->@*, $ovmf_cmd->@*; push $machineFlags->@*, $ovmf_machine_flags->@*; @@ -3455,7 +3332,7 @@ sub config_to_command { # Add a TPM only if the VM is not a template, # to support backing up template VMs even if the TPM disk is write-protected. - add_tpm_device($vmid, $devices, $conf) if (!PVE::QemuConfig->is_template($conf)); + add_tpm_device($vmid, $devices, $conf) if !$is_template; my $sockets = 1; $sockets = $conf->{smp} if $conf->{smp}; # old style - no longer iused @@ -3504,31 +3381,12 @@ sub config_to_command { push @$cmd, '-nographic'; } - # time drift fix - my $tdf = defined($conf->{tdf}) ? $conf->{tdf} : $defaults->{tdf}; - my $useLocaltime = $conf->{localtime}; - - if ($winversion >= 5) { # windows - $useLocaltime = 1 if !defined($conf->{localtime}); - - # use time drift fix when acpi is enabled - if (!(defined($conf->{acpi}) && $conf->{acpi} == 0)) { - $tdf = 1 if !defined($conf->{tdf}); - } - } - - if ($winversion >= 6) { - push $cmd->@*, '-global', 'kvm-pit.lost_tick_policy=discard'; - push @$machineFlags, 'hpet=off'; - } - - push @$rtcFlags, 'driftfix=slew' if $tdf; - - if ($conf->{startdate} && $conf->{startdate} ne 'now') { - push @$rtcFlags, "base=$conf->{startdate}"; - } elsif ($useLocaltime) { - push @$rtcFlags, 'base=localtime'; - } + # For now, handles only specific parts, but the final goal is to cover everything. + my $cfg2cmd = PVE::QemuServer::Cfg2Cmd->new($conf, $defaults, $version_guard); + my $generated = $cfg2cmd->generate(); + push $cmd->@*, '-global', $_ for ($generated->global_flags() // [])->@*; + push $machineFlags->@*, ($generated->machine_flags() // [])->@*; + push $rtcFlags->@*, ($generated->rtc_flags() // [])->@*; if ($forcecpu) { push @$cmd, '-cpu', $forcecpu; @@ -3686,7 +3544,8 @@ sub config_to_command { if ($drive->{interface} eq 'scsi') { - my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $drive); + my ($maxdev, $controller, $controller_prefix) = + scsihw_infos($conf->{scsihw}, $drive->{index}); die "scsi$drive->{index}: machine version 4.1~pve2 or higher is required to use more than 14 SCSI disks\n" @@ -3743,9 +3602,7 @@ sub config_to_command { my $extra_blockdev_options = {}; $extra_blockdev_options->{'live-restore'} = $live_restore if $live_restore; - # extra protection for templates, but SATA and IDE don't support it.. - $extra_blockdev_options->{'read-only'} = 1 - if drive_is_read_only($conf, $drive); + $extra_blockdev_options->{'read-only'} = 1 if $is_template; my $blockdev = PVE::QemuServer::Blockdev::generate_drive_blockdev( $storecfg, $drive, $machine_version, $extra_blockdev_options, @@ -3762,8 +3619,13 @@ sub config_to_command { my $drive_cmd = print_drive_commandline_full($storecfg, $vmid, $drive, $live_blockdev_name); - # extra protection for templates, but SATA and IDE don't support it.. - $drive_cmd .= ',readonly=on' if drive_is_read_only($conf, $drive); + if ($is_template) { + # TODO PVE 10.x - since the temporary config for starting templates for backup + # uses the latest machine version, this should already be dead code. It's kept + # for now if for whatever reason an older QEMU build is used (e.g. bisecting). + my $interface = $drive->{interface}; + $drive_cmd .= ',readonly=on' if $interface ne 'ide' && $interface ne 'sata'; + } push @$devices, '-drive', $drive_cmd; } @@ -3775,6 +3637,8 @@ sub config_to_command { }, ); + my $nets_host_mtu = + { map { split('=', $_) } PVE::Tools::split_list($options->{'nets-host-mtu'}) }; for (my $i = 0; $i < $MAX_NETS; $i++) { my $netname = "net$i"; @@ -3790,6 +3654,8 @@ sub config_to_command { my $netdevfull = print_netdev_full($vmid, $conf, $arch, $d, $netname); push @$devices, '-netdev', $netdevfull; + # force +pve1 if machine version 10.0, for host_mtu differentiation + $version_guard->(10, 0, 1); my $netdevicefull = print_netdevice_full( $vmid, $conf, @@ -3799,6 +3665,7 @@ sub config_to_command { $use_old_bios_files, $arch, $machine_version, + $nets_host_mtu->{$netname}, ); push @$devices, '-device', $netdevicefull; @@ -3867,11 +3734,22 @@ sub config_to_command { PVE::QemuServer::Machine::assert_valid_machine_property($machine_conf); if (my $viommu = $machine_conf->{viommu}) { + my $viommu_devstr = ''; + if ($machine_conf->{'aw-bits'}) { + $viommu_devstr .= ",aw-bits=$machine_conf->{'aw-bits'}"; + + # TODO remove message once this gets properly checked/warned about in QEMU itself. + print "vIOMMU 'aw-bits' set to $machine_conf->{'aw-bits'}. Sometimes it is necessary to" + . " set the CPU's 'guest-phys-bits' to the same value.\n"; + } + if ($viommu eq 'intel') { - unshift @$devices, '-device', 'intel-iommu,intremap=on,caching-mode=on'; + $viommu_devstr = "intel-iommu,intremap=on,caching-mode=on$viommu_devstr"; + unshift @$devices, '-device', $viommu_devstr; push @$machineFlags, 'kernel-irqchip=split'; } elsif ($viommu eq 'virtio') { - push @$devices, '-device', 'virtio-iommu-pci'; + $viommu_devstr = "virtio-iommu-pci$viommu_devstr"; + push @$devices, '-device', $viommu_devstr; } } @@ -3892,7 +3770,11 @@ sub config_to_command { print "activating and using '$vmstate' as vmstate\n"; } - if (PVE::QemuConfig->is_template($conf)) { + if ($is_template) { + # TODO PVE 10.x - since the temporary config for starting templates for backup uses the + # latest machine version, this should already be dead code. It's kept for now if for + # whatever reason an older QEMU build is used (e.g. bisecting). + # needed to workaround base volumes being read-only push @$cmd, '-snapshot'; } @@ -4237,7 +4119,7 @@ sub qemu_devicedelverify { sub qemu_findorcreatescsihw { my ($storecfg, $conf, $vmid, $device, $arch, $machine_type) = @_; - my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $device); + my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf->{scsihw}, $device->{index}); my $scsihwid = "$controller_prefix$controller"; my $devices_list = vm_devices_list($vmid); @@ -4259,7 +4141,7 @@ sub qemu_deletescsihw { return 1; } - my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $device); + my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf->{scsihw}, $device->{index}); my $devices_list = vm_devices_list($vmid); foreach my $opt (keys %{$devices_list}) { @@ -5461,6 +5343,20 @@ sub vm_migrate_alloc_nbd_disks { return $nbd; } +my sub remove_left_over_vmstate_opts { + my ($vmid, $conf) = @_; + + my $found; + for my $opt (qw(running-nets-host-mtu runningmachine runningcpu)) { + if (defined($conf->{$opt})) { + print "No VM state set, removing left-over option '$opt'\n"; + delete $conf->{$opt}; + $found = 1; + } + } + PVE::QemuConfig->write_config($vmid, $conf) if $found; +} + # see vm_start_nolock for parameters, additionally: # migrate_opts: # storagemap = parsed storage map for allocating NBD disks @@ -5525,6 +5421,8 @@ sub vm_start { # }, # virtio2 => ... # } +# nets-host-mtu => Used for migration compat. List of VirtIO network devices and their effective +# host_mtu setting according to the QEMU object model on the source side of the migration. # migrate_opts: # nbd => volumes for NBD exports (vm_migrate_alloc_nbd_disks) # migratedfrom => source node @@ -5587,10 +5485,12 @@ sub vm_start_nolock { my $forcemachine = $params->{forcemachine}; my $forcecpu = $params->{forcecpu}; + my $nets_host_mtu = $params->{'nets-host-mtu'}; if ($resume) { # enforce machine and CPU type on suspended vm to ensure HW compatibility $forcemachine = $conf->{runningmachine}; $forcecpu = $conf->{runningcpu}; + $nets_host_mtu = $conf->{'running-nets-host-mtu'}; print "Resuming suspended VM\n"; } @@ -5637,6 +5537,7 @@ sub vm_start_nolock { 'force-machine' => $forcemachine, 'force-cpu' => $forcecpu, 'live-restore-backing' => $params->{'live-restore-backing'}, + 'nets-host-mtu' => $nets_host_mtu, }, ); @@ -5695,6 +5596,12 @@ sub vm_start_nolock { } my %silence_std_outs = (outfunc => sub { }, errfunc => sub { }); + eval { # See systemd GH #39141, need to reset failed PartOf units too, or scope might be blocked + run_command( + ['/bin/systemctl', 'reset-failed', "pve-dbus-vmstate\@$vmid.service"], + %silence_std_outs, + ); + }; eval { run_command(['/bin/systemctl', 'reset-failed', "$vmid.scope"], %silence_std_outs) }; eval { run_command(['/bin/systemctl', 'stop', "$vmid.scope"], %silence_std_outs) }; # Issues with the above 'stop' not being fully completed are extremely rare, a very low @@ -5822,6 +5729,28 @@ sub vm_start_nolock { warn $@ if $@; } + # set write threshold for LVM thin provisioning disks + PVE::QemuConfig->foreach_volume( + $conf, + sub { + my ($ds, $drive) = @_; + return if PVE::QemuServer::drive_is_cdrom($drive, 1); + my $volid = $drive->{file}; + if ( $volid ne 'none') { + my $drive_id = PVE::QemuServer::Drive::get_drive_id($drive); + my $snapshots = PVE::Storage::volume_snapshot_info($storecfg, $volid); + my $parentid = $snapshots->{'current'}->{parent}; + # for now only set write_threshold for volumes that have snapshots + # FIX: Change to only thin drives + if ($parentid) { + PVE::QemuServer::Blockdev::set_write_threshold( + $storecfg, $vmid, $drive_id, $volid + ); + } + } + }, + ); + #start nbd server for storage migration if (my $nbd = $migrate_opts->{nbd}) { @@ -5940,8 +5869,10 @@ sub vm_start_nolock { PVE::Storage::deactivate_volumes($storecfg, [$vmstate]); PVE::Storage::vdisk_free($storecfg, $vmstate); } - delete $conf->@{qw(lock vmstate runningmachine runningcpu)}; + delete $conf->@{qw(lock vmstate running-nets-host-mtu runningmachine runningcpu)}; PVE::QemuConfig->write_config($vmid, $conf); + } elsif (!$conf->{vmstate}) { + remove_left_over_vmstate_opts($vmid, $conf); } PVE::GuestHelpers::exec_hookscript($conf, $vmid, 'post-start'); @@ -5971,6 +5902,7 @@ sub vm_commandline { # check for machine or CPU overrides in snapshot $options->{'force-machine'} = $snapshot->{runningmachine}; $options->{'force-cpu'} = $snapshot->{runningcpu}; + $options->{'nets-host-mtu'} = $snapshot->{'running-nets-host-mtu'}; $snapshot->{digest} = $conf->{digest}; # keep file digest for API @@ -7346,7 +7278,10 @@ sub live_import_from_files { my ($interface, $index) = PVE::QemuServer::Drive::parse_drive_interface($dev); my $drive = { file => $volid, interface => $interface, index => $index }; my $blockdev = PVE::QemuServer::Blockdev::generate_drive_blockdev( - $storecfg, $drive, $machine_version, {}, + $storecfg, + $drive, + $machine_version, + { 'no-throttle' => 1 }, ); $live_restore_backing->{$dev}->{blockdev} = $blockdev; } else { @@ -8047,28 +7982,6 @@ sub vm_iothreads_list { return $iothreads; } -sub scsihw_infos { - my ($conf, $drive) = @_; - - my $maxdev = 0; - - if (!$conf->{scsihw} || ($conf->{scsihw} =~ m/^lsi/)) { - $maxdev = 7; - } elsif ($conf->{scsihw} && ($conf->{scsihw} eq 'virtio-scsi-single')) { - $maxdev = 1; - } else { - $maxdev = 256; - } - - my $controller = int($drive->{index} / $maxdev); - my $controller_prefix = - ($conf->{scsihw} && $conf->{scsihw} eq 'virtio-scsi-single') - ? "virtioscsi" - : "scsihw"; - - return ($maxdev, $controller, $controller_prefix); -} - sub resolve_dst_disk_format { my ($storecfg, $storeid, $src_volid, $format) = @_; diff --git a/src/PVE/QemuServer/Agent.pm b/src/PVE/QemuServer/Agent.pm index ee48e83e..5d88b7bd 100644 --- a/src/PVE/QemuServer/Agent.pm +++ b/src/PVE/QemuServer/Agent.pm @@ -6,6 +6,8 @@ use warnings; use JSON; use MIME::Base64 qw(decode_base64 encode_base64); +use PVE::JSONSchema; + use PVE::QemuServer::Helpers; use PVE::QemuServer::Monitor; @@ -14,9 +16,61 @@ use base 'Exporter'; our @EXPORT_OK = qw( check_agent_error agent_cmd + get_qga_key + parse_guest_agent qga_check_running ); +our $agent_fmt = { + enabled => { + description => + "Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.", + type => 'boolean', + default => 0, + default_key => 1, + }, + fstrim_cloned_disks => { + description => "Run fstrim after moving a disk or migrating the VM.", + type => 'boolean', + optional => 1, + default => 0, + }, + 'freeze-fs-on-backup' => { + description => "Freeze/thaw guest filesystems on backup for consistency.", + type => 'boolean', + optional => 1, + default => 1, + }, + type => { + description => "Select the agent type", + type => 'string', + default => 'virtio', + optional => 1, + enum => [qw(virtio isa)], + }, +}; + +sub parse_guest_agent { + my ($conf) = @_; + + return {} if !defined($conf->{agent}); + + my $res = eval { PVE::JSONSchema::parse_property_string($agent_fmt, $conf->{agent}) }; + warn $@ if $@; + + # if the agent is disabled ignore the other potentially set properties + return {} if !$res->{enabled}; + return $res; +} + +sub get_qga_key { + my ($conf, $key) = @_; + return undef if !defined($conf->{agent}); + + my $agent = parse_guest_agent($conf); + return $agent->{$key}; +} + sub qga_check_running { my ($vmid, $nowarn) = @_; @@ -131,4 +185,72 @@ sub qemu_exec_status { return $res; } +=head3 guest_fsfreeze + + guest_fsfreeze($vmid); + +Freeze the file systems of the guest C<$vmid>. Check that the guest agent is enabled and running +before calling this function. Dies if the file systems cannot be frozen. + +With C, it can happen that a guest agent command is read, but then the guest agent never +sends an answer, because the service in the guest is stopped/killed. For example, if a guest reboot +happens before the command can be successfully executed. This is usually not problematic, but the +fsfreeze-freeze command should use a timeout of 1 hour, so the guest agent socket would be blocked +for that amount of time, waiting on a command that is not being executed anymore. + +This function uses a lower timeout for the initial fsfreeze-freeze command, and issues an +fsfreeze-status command afterwards, which will return immediately if the fsfreeze-freeze command +already finished, and which will be queued if not. This is used as a proxy to determine whether the +fsfreeze-freeze command is still running and to check whether it was successful. Using a too low +timeout would mean stuffing/queuing many fsfreeze-status commands while the guest agent might still +be busy actually doing the freeze. In total, fsfreeze-freeze is still allowed to take 1 hour, but +the time the socket is blocked after a lost command is at most 10 minutes. + +=cut + +sub guest_fsfreeze { + my ($vmid) = @_; + + my $timeout = 10 * 60; + + my $result = eval { + PVE::QemuServer::Monitor::mon_cmd($vmid, 'guest-fsfreeze-freeze', timeout => $timeout); + }; + if ($result && ref($result) eq 'HASH' && $result->{error}) { + my $error = $result->{error}->{desc} // 'unknown'; + die "unable to freeze guest fs - $error\n"; + } elsif (defined($result)) { + return; # command successful + } + + my $status; + eval { + my ($i, $last_iteration) = (0, 5); + while ($i < $last_iteration && !defined($status)) { + print "still waiting on guest fs freeze - timeout in " + . ($timeout * ($last_iteration - $i) / 60) + . " minutes\n"; + $i++; + + $status = PVE::QemuServer::Monitor::mon_cmd( + $vmid, 'guest-fsfreeze-status', + timeout => $timeout, + noerr => 1, + ); + + if ($status && ref($status) eq 'HASH' && $status->{'error-is-timeout'}) { + $status = undef; + } else { + check_agent_error($status, 'unknown error'); + } + } + if (!defined($status)) { + die "timeout after " . ($timeout * ($last_iteration + 1) / 60) . " minutes\n"; + } + }; + die "querying status after freezing guest fs failed - $@" if $@; + + die "unable to freeze guest fs - unexpected status '$status'\n" if $status ne 'frozen'; +} + 1; diff --git a/src/PVE/QemuServer/BlockJob.pm b/src/PVE/QemuServer/BlockJob.pm index 633c0b34..506010e1 100644 --- a/src/PVE/QemuServer/BlockJob.pm +++ b/src/PVE/QemuServer/BlockJob.pm @@ -165,7 +165,7 @@ sub qemu_drive_mirror_monitor { my $agent_running = $qga && qga_check_running($vmid); if ($agent_running) { print "freeze filesystem\n"; - eval { mon_cmd($vmid, "guest-fsfreeze-freeze"); }; + eval { PVE::QemuServer::Agent::guest_fsfreeze($vmid); }; warn $@ if $@; } else { print "suspend vm\n"; diff --git a/src/PVE/QemuServer/Blockdev.pm b/src/PVE/QemuServer/Blockdev.pm index d0d7e684..5083fad5 100644 --- a/src/PVE/QemuServer/Blockdev.pm +++ b/src/PVE/QemuServer/Blockdev.pm @@ -43,7 +43,9 @@ my sub tpm_backup_node_name { } my sub fleecing_node_name { - my ($type, $drive_id) = @_; + my ($type, $drive_id, $options) = @_; + + $drive_id .= '-backup' if $options->{'tpm-backup'}; if ($type eq 'fmt') { return "drive-$drive_id-fleecing"; # this is the top node for fleecing @@ -111,10 +113,25 @@ sub get_block_info { return $block_info; } +sub get_block_stats { + my ($vmid) = @_; + + my $block_stats = {}; + + my $qmp_block_stats = mon_cmd($vmid, "query-blockstats"); + for my $info ($qmp_block_stats->@*) { + my $qdev_id = $info->{qdev} or next; + my $drive_id = qdev_id_to_drive_id($qdev_id); + $block_stats->{$drive_id} = $info; + } + + return $block_stats; +} + my sub get_node_name { my ($type, $drive_id, $volid, $options) = @_; - return fleecing_node_name($type, $drive_id) if $options->{fleecing}; + return fleecing_node_name($type, $drive_id, $options) if $options->{fleecing}; return tpm_backup_node_name($type, $drive_id) if $options->{'tpm-backup'}; my $snap = $options->{'snapshot-name'}; @@ -478,6 +495,14 @@ sub generate_drive_blockdev { }; } + if ($drive->{scsiblock}) { + # When using scsi-block for the front-end device, throttling would not work in any case, and + # the throttle block driver doesn't allow doing the necessary ioctls(), so don't attach a + # throttle filter. Implementing live mirroring for such disks would require special care! + $child->{'node-name'} = top_node_name($drive_id); + return $child; + } + # for fleecing and TPM backup, this is already the top node return $child if $options->{fleecing} || $options->{'tpm-backup'} || $options->{'no-throttle'}; @@ -575,7 +600,7 @@ sub attach { eval { if ($throttle_group_id) { # Try to remove potential left-over. - eval { mon_cmd($vmid, 'object-del', id => $throttle_group_id); }; + mon_cmd($vmid, 'object-del', id => $throttle_group_id, noerr => 1); my $throttle_group = generate_throttle_group($drive); mon_cmd($vmid, 'object-add', $throttle_group->%*); @@ -630,8 +655,8 @@ sub detach { while ($node_name) { last if !$block_info->{$node_name}; # already gone - eval { mon_cmd($vmid, 'blockdev-del', 'node-name' => "$node_name"); }; - if (my $err = $@) { + my $res = mon_cmd($vmid, 'blockdev-del', 'node-name' => "$node_name", noerr => 1); + if (my $err = $res->{error}) { last if $err =~ m/Failed to find node with node-name/; # already gone die "deleting blockdev '$node_name' failed : $err\n"; } @@ -700,6 +725,24 @@ sub resize { ); } +sub underlay_resize { + my ($storecfg, $vmid, $drive_id, $volid) = @_; + + my $running = PVE::QemuServer::Helpers::vm_running_locally($vmid); + + # get backing_snap + my $snapshots = PVE::Storage::volume_snapshot_info($storecfg, $volid); + my $backing_snap = $snapshots->{current}->{parent}; + my $size = PVE::Storage::volume_underlay_resize($storecfg, $volid, $backing_snap); + + return if !$running; + my $block_info = get_block_info($vmid); + my $inserted = $block_info->{$drive_id}->{inserted} + or die "no block node inserted for drive '$drive_id'\n"; + + set_write_threshold($storecfg, $vmid, $drive_id, $volid); +} + my sub blockdev_change_medium { my ($storecfg, $vmid, $qdev_id, $drive) = @_; @@ -820,6 +863,49 @@ sub set_io_throttle { } } +sub block_set_write_threshold { + my ($vmid, $nodename, $threshold) = @_; + + print "set threshold $nodename $threshold\n"; + + PVE::QemuServer::mon_cmd( + $vmid, + "block-set-write-threshold", + 'node-name' => $nodename, + 'write-threshold' => int($threshold), + ); +} + +sub compute_write_threshold { + my ($storecfg, $scfg, $volid) = @_; + + my $lv_size = PVE::Storage::volume_underlay_size_info($storecfg, $volid, 5); + + my $write_threshold = $lv_size - $scfg->{chunksize} * (1 - $scfg->{'chunk-percentage'}); + + return $write_threshold; +} + +sub set_write_threshold { + my ($storecfg, $vmid, $drive_id, $volid, $options) = @_; + + my ($storeid) = PVE::Storage::parse_volume_id($volid); + my $scfg = PVE::Storage::storage_config($storecfg, $storeid); + my $support_qemu_snapshots = PVE::Storage::volume_qemu_snapshot_method($storecfg, $volid); + + # set write threshold is only supported for lvm storage using + # qcow2+external snapshots + return if $scfg->{type} ne 'lvm' || $support_qemu_snapshots ne 'mixed'; + # return if drive is not set as thin + # return if !$drive->{thin}; + + my $nodename = get_node_name('file', $drive_id, $volid, $options); + my $write_threshold = compute_write_threshold($storecfg, $scfg, $volid); + + print "setting threshold for $volid from $storeid\n"; + block_set_write_threshold($vmid, $nodename, $write_threshold); +} + sub blockdev_external_snapshot { my ($storecfg, $vmid, $machine_version, $deviceid, $drive, $snap, $parent_snap) = @_; @@ -868,14 +954,17 @@ sub blockdev_external_snapshot { node => $snap_fmt_blockdev->{'node-name'}, overlay => $new_fmt_blockdev->{'node-name'}, ); + + # FIX: only if thin + my $drive_id = PVE::QemuServer::Drive::get_drive_id($drive); + set_write_threshold($storecfg, $vmid, $drive_id, $volid); } sub blockdev_delete { my ($storecfg, $vmid, $drive, $file_blockdev, $fmt_blockdev, $snap) = @_; - #add eval as reopen is auto removing the old nodename automatically only if it was created at vm start in command line argument - eval { mon_cmd($vmid, 'blockdev-del', 'node-name' => $fmt_blockdev->{'node-name'}) }; - eval { mon_cmd($vmid, 'blockdev-del', 'node-name' => $file_blockdev->{'node-name'}) }; + eval { detach($vmid, $fmt_blockdev->{'node-name'}); }; + warn "detaching block node for $file_blockdev->{filename} failed - $@" if $@; #delete the file (don't use vdisk_free as we don't want to delete all snapshot chain) print "delete old $file_blockdev->{filename}\n"; @@ -917,9 +1006,15 @@ sub blockdev_replace { my $volid = $drive->{file}; my $drive_id = PVE::QemuServer::Drive::get_drive_id($drive); - my $src_name_options = $src_snap eq 'current' ? {} : { 'snapshot-name' => $src_snap }; - my $src_file_blockdev_name = get_node_name('file', $drive_id, $volid, $src_name_options); - my $src_fmt_blockdev_name = get_node_name('fmt', $drive_id, $volid, $src_name_options); + my $src_name_options = {}; + my $src_blockdev_name; + if ($src_snap eq 'current') { + # there might be other nodes on top like zeroinit, look up the current node below throttle + $src_blockdev_name = get_node_name_below_throttle($vmid, $deviceid, 1); + } else { + $src_name_options = { 'snapshot-name' => $src_snap }; + $src_blockdev_name = get_node_name('fmt', $drive_id, $volid, $src_name_options); + } my $target_file_blockdev = generate_file_blockdev( $storecfg, @@ -982,9 +1077,8 @@ sub blockdev_replace { } # delete old file|fmt nodes - # add eval as reopen is auto removing the old nodename automatically only if it was created at vm start in command line argument - eval { mon_cmd($vmid, 'blockdev-del', 'node-name' => $src_fmt_blockdev_name) }; - eval { mon_cmd($vmid, 'blockdev-del', 'node-name' => $src_file_blockdev_name) }; + eval { detach($vmid, $src_blockdev_name); }; + warn "detaching block node for $src_snap failed - $@" if $@; } sub blockdev_commit { diff --git a/src/PVE/QemuServer/CPUConfig.pm b/src/PVE/QemuServer/CPUConfig.pm index 1c7c12fc..786a99d8 100644 --- a/src/PVE/QemuServer/CPUConfig.pm +++ b/src/PVE/QemuServer/CPUConfig.pm @@ -223,6 +223,13 @@ my $cpu_fmt = { pattern => qr/$cpu_flag_any_re(;$cpu_flag_any_re)*/, optional => 1, }, + 'guest-phys-bits' => { + type => 'integer', + minimum => 32, # see target/i386/cpu.c in QEMU + maximum => 64, + description => "Number of physical address bits available to the guest.", + optional => 1, + }, 'phys-bits' => { type => 'string', format => 'pve-phys-bits', @@ -680,18 +687,22 @@ sub get_cpu_options { $pve_forced_flags, ); - my $phys_bits = ''; - foreach my $conf ($custom_cpu, $cpu) { - next if !defined($conf); - my $conf_val = $conf->{'phys-bits'}; - next if !$conf_val; - if ($conf_val eq 'host') { - $phys_bits = ",host-phys-bits=true"; - } else { - $phys_bits = ",phys-bits=$conf_val"; + for my $phys_bits_opt (qw(guest-phys-bits phys-bits)) { + my $phys_bits = ''; + foreach my $conf ($custom_cpu, $cpu) { + next if !defined($conf); + my $conf_val = $conf->{$phys_bits_opt}; + next if !$conf_val; + if ($conf_val eq 'host') { + die "unexpected value 'host' for guest-phys-bits" + if $phys_bits_opt eq 'guest-phys-bits'; + $phys_bits = ",host-phys-bits=true"; + } else { + $phys_bits = ",${phys_bits_opt}=${conf_val}"; + } } + $cpu_str .= $phys_bits; } - $cpu_str .= $phys_bits; return ('-cpu', $cpu_str); } diff --git a/src/PVE/QemuServer/Cfg2Cmd.pm b/src/PVE/QemuServer/Cfg2Cmd.pm new file mode 100644 index 00000000..c7ee0165 --- /dev/null +++ b/src/PVE/QemuServer/Cfg2Cmd.pm @@ -0,0 +1,115 @@ +package PVE::QemuServer::Cfg2Cmd; + +use warnings; +use strict; + +use PVE::QemuServer::Cfg2Cmd::Timer; +use PVE::QemuServer::Helpers; + +sub new { + my ($class, $conf, $defaults, $version_guard) = @_; + + my $self = bless { + conf => $conf, + defaults => $defaults, + 'version-guard' => $version_guard, + }, $class; + + $self->{ostype} = $self->get_prop('ostype'); + $self->{'windows-version'} = PVE::QemuServer::Helpers::windows_version($self->{ostype}); + + return $self; +} + +=head3 get_prop + + my $value = $self->get_prop($prop); + +Return the configured value for the property C<$prop>. If no fallback to the default value should be +made, use C<$only_explicit>. Note that any such usage is likely an indication that the default value +is not actually a static default, but that the default depends on context. + +=cut + +sub get_prop { + my ($self, $prop, $only_explicit) = @_; + + my ($conf, $defaults) = $self->@{qw(conf defaults)}; + return $conf->{$prop} if $only_explicit; + return defined($conf->{$prop}) ? $conf->{$prop} : $defaults->{$prop}; +} + +sub add_global_flag { + my ($self, $flag) = @_; + + push $self->{'global-flags'}->@*, $flag; +} + +sub global_flags { + my ($self) = @_; + + return $self->{'global-flags'}; +} + +sub add_machine_flag { + my ($self, $flag) = @_; + + push $self->{'machine-flags'}->@*, $flag; +} + +sub machine_flags { + my ($self) = @_; + + return $self->{'machine-flags'}; +} + +sub add_rtc_flag { + my ($self, $flag) = @_; + + push $self->{'rtc-flags'}->@*, $flag; +} + +sub rtc_flags { + my ($self) = @_; + + return $self->{'rtc-flags'}; +} + +=head3 is_linux + + if ($self->is_linux()) { + do_something_for_linux_vms(); + } + +Check if the virtual machine is configured for running Linux. Does not include the C os type +by default. Specify C<$include_l24> if that is desired. + +=cut + +sub is_linux { + my ($self, $include_l24) = @_; + + return $self->{ostype} eq 'l26' || ($include_l24 && $self->{ostype} eq 'l24'); +} + +sub windows_version { + my ($self) = @_; + + return $self->{'windows-version'}; +} + +sub version_guard { + my ($self, $major, $minor, $pve) = @_; + + $self->{'version-guard'}->($major, $minor, $pve); +} + +sub generate { + my ($self) = @_; + + PVE::QemuServer::Cfg2Cmd::Timer::generate($self); + + return $self; +} + +1; diff --git a/src/PVE/QemuServer/Cfg2Cmd/Makefile b/src/PVE/QemuServer/Cfg2Cmd/Makefile new file mode 100644 index 00000000..1c0ea0b2 --- /dev/null +++ b/src/PVE/QemuServer/Cfg2Cmd/Makefile @@ -0,0 +1,9 @@ +DESTDIR= +PREFIX=/usr +PERLDIR=$(PREFIX)/share/perl5 + +SOURCES=Timer.pm + +.PHONY: install +install: $(SOURCES) + for i in $(SOURCES); do install -D -m 0644 $$i $(DESTDIR)$(PERLDIR)/PVE/QemuServer/Cfg2Cmd/$$i; done diff --git a/src/PVE/QemuServer/Cfg2Cmd/Timer.pm b/src/PVE/QemuServer/Cfg2Cmd/Timer.pm new file mode 100644 index 00000000..452c15b2 --- /dev/null +++ b/src/PVE/QemuServer/Cfg2Cmd/Timer.pm @@ -0,0 +1,39 @@ +package PVE::QemuServer::Cfg2Cmd::Timer; + +use warnings; +use strict; + +sub generate { + my ($cfg2cmd) = @_; + + my $time_drift_fix = $cfg2cmd->get_prop('tdf', 1); + my $acpi = $cfg2cmd->get_prop('acpi'); + my $localtime = $cfg2cmd->get_prop('localtime', 1); + my $startdate = $cfg2cmd->get_prop('startdate'); + + if ($cfg2cmd->windows_version() >= 5) { # windows + $localtime = 1 if !defined($localtime); + + # use time drift fix when acpi is enabled, but prefer explicitly set value + $time_drift_fix = 1 if $acpi && !defined($time_drift_fix); + } + + if ($cfg2cmd->windows_version() >= 6) { + $cfg2cmd->add_global_flag('kvm-pit.lost_tick_policy=discard'); + $cfg2cmd->add_machine_flag('hpet=off'); + } elsif ($cfg2cmd->is_linux() && $cfg2cmd->version_guard(10, 1, 0)) { + $cfg2cmd->add_machine_flag('hpet=off'); + } + + $cfg2cmd->add_rtc_flag('driftfix=slew') if $time_drift_fix; + + if ($startdate ne 'now') { + $cfg2cmd->add_rtc_flag("base=$startdate"); + } elsif ($localtime) { + $cfg2cmd->add_rtc_flag('base=localtime'); + } + + return; +} + +1; diff --git a/src/PVE/QemuServer/DBusVMState.pm b/src/PVE/QemuServer/DBusVMState.pm index 36ff8168..a72d6dd2 100644 --- a/src/PVE/QemuServer/DBusVMState.pm +++ b/src/PVE/QemuServer/DBusVMState.pm @@ -3,10 +3,15 @@ package PVE::QemuServer::DBusVMState; use strict; use warnings; +use Net::DBus; +use Net::DBus::RemoteService; + use PVE::SafeSyslog; use PVE::Systemd; use PVE::Tools; +use PVE::QemuServer::Helpers; + use constant { DBUS_VMSTATE_EXE => '/usr/libexec/qemu-server/dbus-vmstate', }; diff --git a/src/PVE/QemuServer/Drive.pm b/src/PVE/QemuServer/Drive.pm index 9dc4e674..44f477a9 100644 --- a/src/PVE/QemuServer/Drive.pm +++ b/src/PVE/QemuServer/Drive.pm @@ -20,7 +20,6 @@ our @EXPORT_OK = qw( checked_volume_format drive_is_cloudinit drive_is_cdrom - drive_is_read_only parse_drive print_drive storage_allows_io_uring_default @@ -254,6 +253,13 @@ my %drivedesc_base = ( optional => 1, default => 0, }, + thin => { + type => 'boolean', + description => + 'Controls whether a drive should be thin provisioned', + optional => 1, + default => 0, + }, ); my %iothread_fmt = ( @@ -751,15 +757,6 @@ sub drive_is_cdrom { return $drive && $drive->{media} && ($drive->{media} eq 'cdrom'); } -sub drive_is_read_only { - my ($conf, $drive) = @_; - - return 0 if !PVE::QemuConfig->is_template($conf); - - # don't support being marked read-only - return $drive->{interface} ne 'sata' && $drive->{interface} ne 'ide'; -} - sub parse_drive_interface { my ($key) = @_; diff --git a/src/PVE/QemuServer/DriveDevice.pm b/src/PVE/QemuServer/DriveDevice.pm new file mode 100644 index 00000000..ca230ed3 --- /dev/null +++ b/src/PVE/QemuServer/DriveDevice.pm @@ -0,0 +1,188 @@ +package PVE::QemuServer::DriveDevice; + +use strict; +use warnings; + +use URI::Escape; + +use PVE::QemuServer::Drive qw (drive_is_cdrom); +use PVE::QemuServer::Helpers qw(kvm_user_version min_version); +use PVE::QemuServer::Machine; +use PVE::QemuServer::PCI qw(print_pci_addr); + +use base qw(Exporter); + +our @EXPORT_OK = qw( + print_drivedevice_full + scsihw_infos +); + +sub scsihw_infos { + my ($scsihw, $drive_index) = @_; + + my $maxdev = 0; + + if (!$scsihw || ($scsihw =~ m/^lsi/)) { + $maxdev = 7; + } elsif ($scsihw && ($scsihw eq 'virtio-scsi-single')) { + $maxdev = 1; + } else { + $maxdev = 256; + } + + my $controller = int($drive_index / $maxdev); + my $controller_prefix = + ($scsihw && $scsihw eq 'virtio-scsi-single') + ? "virtioscsi" + : "scsihw"; + + return ($maxdev, $controller, $controller_prefix); +} + +sub print_drivedevice_full { + my ($storecfg, $conf, $vmid, $drive, $bridges, $arch, $machine_type) = @_; + + my $device = ''; + my $maxdev = 0; + + my $machine_version = + PVE::QemuServer::Machine::extract_version($machine_type, kvm_user_version()); + my $has_write_cache = 1; # whether the device has a 'write-cache' option + + my $drive_id = PVE::QemuServer::Drive::get_drive_id($drive); + if ($drive->{interface} eq 'virtio') { + my $pciaddr = print_pci_addr("$drive_id", $bridges, $arch); + $device = 'virtio-blk-pci'; + # for the switch to -blockdev, there is no blockdev for 'none' + if (!min_version($machine_version, 10, 0) || $drive->{file} ne 'none') { + $device .= ",drive=drive-$drive_id"; + } + $device .= ",id=${drive_id}${pciaddr}"; + $device .= ",iothread=iothread-$drive_id" if $drive->{iothread}; + } elsif ($drive->{interface} eq 'scsi') { + + my ($maxdev, $controller, $controller_prefix) = + scsihw_infos($conf->{scsihw}, $drive->{index}); + my $unit = $drive->{index} % $maxdev; + + 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-$device_type,bus=$controller_prefix$controller.0,scsi-id=$unit"; + } else { + $device = "scsi-$device_type,bus=$controller_prefix$controller.0,channel=0,scsi-id=0" + . ",lun=$drive->{index}"; + } + # for the switch to -blockdev, there is no blockdev for 'none' + if (!min_version($machine_version, 10, 0) || $drive->{file} ne 'none') { + $device .= ",drive=drive-$drive_id"; + } + $device .= ",id=$drive_id"; + + # For the switch to -blockdev, the SCSI device ID needs to be explicitly specified. Note + # that only ide-cd and ide-hd have a 'device_id' option. + if ( + min_version($machine_version, 10, 0) && ($device_type eq 'cd' || $device_type eq 'hd') + ) { + $device .= ",device_id=drive-${drive_id}"; + } + + 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 and have a + # 'write-cache' option + if ($device_type eq 'hd' || $device_type eq 'cd') { + if (my $vendor = $drive->{vendor}) { + $device .= ",vendor=$vendor"; + } + if (my $product = $drive->{product}) { + $device .= ",product=$product"; + } + + $has_write_cache = 1; + } else { + $has_write_cache = 0; + } + + } elsif ($drive->{interface} eq 'ide' || $drive->{interface} eq 'sata') { + my $maxdev = ($drive->{interface} eq 'sata') ? $PVE::QemuServer::Drive::MAX_SATA_DISKS : 2; + my $controller = int($drive->{index} / $maxdev); + my $unit = $drive->{index} % $maxdev; + + # machine type q35 only supports unit=0 for IDE rather than 2 units. This wasn't handled + # correctly before, so e.g. index=2 was mapped to controller=1,unit=0 rather than + # controller=2,unit=0. Note that odd indices never worked, as they would be mapped to + # unit=1, so to keep backwards compat for migration, it suffices to keep even ones as they + # were before. Move odd ones up by 2 where they don't clash. + if (PVE::QemuServer::Machine::machine_type_is_q35($conf) && $drive->{interface} eq 'ide') { + $controller += 2 * ($unit % 2); + $unit = 0; + } + + my $device_type = ($drive->{media} && $drive->{media} eq 'cdrom') ? "cd" : "hd"; + + # With ide-hd, the inserted block node needs to be marked as writable too, but -blockdev + # will complain if it's marked as writable but the actual backing device is read-only (e.g. + # read-only base LV). IDE/SATA do not support being configured as read-only, the most + # similar is using ide-cd instead of ide-hd, with most of the code and configuration shared + # in QEMU. Since a template is never actually started, the front-end device is never + # accessed. The backup only accesses the inserted block node, so it does not matter for the + # backup if the type is 'ide-cd' instead. + $device_type = 'cd' if $conf->{template}; + + $device = "ide-$device_type"; + if ($drive->{interface} eq 'ide') { + $device .= ",bus=ide.$controller,unit=$unit"; + } else { + $device .= ",bus=ahci$controller.$unit"; + } + if (!min_version($machine_version, 10, 0) || $drive->{file} ne 'none') { + $device .= ",drive=drive-$drive_id"; + } + $device .= ",id=$drive_id"; + + if ($device_type eq 'hd') { + if (my $model = $drive->{model}) { + $model = URI::Escape::uri_unescape($model); + $device .= ",model=$model"; + } + if ($drive->{ssd}) { + $device .= ",rotation_rate=1"; + } + } + $device .= ",wwn=$drive->{wwn}" if $drive->{wwn}; + } elsif ($drive->{interface} eq 'usb') { + die "implement me"; + # -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 + } else { + die "unsupported interface type"; + } + + $device .= ",bootindex=$drive->{bootindex}" if $drive->{bootindex}; + + if (my $serial = $drive->{serial}) { + $serial = URI::Escape::uri_unescape($serial); + $device .= ",serial=$serial"; + } + + if (min_version($machine_version, 10, 0)) { # for the switch to -blockdev + if (!drive_is_cdrom($drive) && $has_write_cache) { + my $write_cache = 'on'; + if (my $cache = $drive->{cache}) { + $write_cache = 'off' if $cache eq 'writethrough' || $cache eq 'directsync'; + } + $device .= ",write-cache=$write_cache"; + } + for my $o (qw(rerror werror)) { + $device .= ",$o=$drive->{$o}" if defined($drive->{$o}); + } + } + + return $device; +} + +1; diff --git a/src/PVE/QemuServer/Machine.pm b/src/PVE/QemuServer/Machine.pm index b2bac932..b2ff7e24 100644 --- a/src/PVE/QemuServer/Machine.pm +++ b/src/PVE/QemuServer/Machine.pm @@ -37,6 +37,12 @@ our $PVE_MACHINE_VERSION = { '+pve1' => 'Disables S3/S4 power states by default.', }, }, + '10.0' => { + highest => 1, + revisions => { + '+pve1' => 'Set host_mtu vNIC option even with default value for migration compat.', + }, + }, }; my $machine_fmt = { @@ -58,6 +64,16 @@ my $machine_fmt = { enum => ['intel', 'virtio'], optional => 1, }, + 'aw-bits' => { + type => 'number', + description => "Specifies the vIOMMU address space bit width.", + verbose_description => "Specifies the vIOMMU address space bit width.\n\n" + . "Intel vIOMMU supports a bit width of either 39 or 48 bits and" + . " VirtIO vIOMMU supports any bit width between 32 and 64 bits.", + minimum => 32, + maximum => 64, + optional => 1, + }, 'enable-s3' => { type => 'boolean', description => @@ -112,10 +128,18 @@ sub default_machine_for_arch { sub assert_valid_machine_property { my ($machine_conf) = @_; - my $q35 = $machine_conf->{type} && ($machine_conf->{type} =~ m/q35/) ? 1 : 0; - if ($machine_conf->{viommu} && $machine_conf->{viommu} eq "intel" && !$q35) { - die "to use Intel vIOMMU please set the machine type to q35\n"; + if ($machine_conf->{viommu} && $machine_conf->{viommu} eq "intel") { + my $q35 = $machine_conf->{type} && ($machine_conf->{type} =~ m/q35/) ? 1 : 0; + die "to use Intel vIOMMU please set the machine type to q35\n" if !$q35; + + die "Intel vIOMMU supports only 39 or 48 bits as address width\n" + if $machine_conf->{'aw-bits'} + && $machine_conf->{'aw-bits'} != 39 + && $machine_conf->{'aw-bits'} != 48; } + + die "cannot set aw-bits if no vIOMMU is configured\n" + if $machine_conf->{'aw-bits'} && !$machine_conf->{viommu}; } sub machine_type_is_q35 { @@ -156,19 +180,37 @@ sub get_current_qemu_machine { return current_from_query_machines($res); } +=head3 extract_version_parts + + my ($major, $minor, $pve) = extract_version_parts($machine_type); + +Returns the major, minor and pve versions from the given C<$machine_type> string. Returns nothing if +the string did not contain any version or if parsing failed. + +=cut + +my sub extract_version_parts { + my ($machine_type) = @_; + + if ($machine_type =~ + m/^(?:pc(?:-i440fx|-q35)?|virt)-(\d+)\.(\d+)(?:\.(\d+))?(?:\+pve(\d+))?(?:\.pxe)?/ + ) { + return ($1, $2, $4); + } + return; +} + # returns a string with major.minor+pve, patch version-part is ignored # as it's seldom resembling a real QEMU machine type, so it would be '0' 99% of # the time anyway.. This explicitly separates pveversion from the machine. sub extract_version { my ($machine_type, $kvmversion) = @_; - if ( - defined($machine_type) - && $machine_type =~ - m/^(?:pc(?:-i440fx|-q35)?|virt)-(\d+)\.(\d+)(?:\.(\d+))?(\+pve\d+)?(?:\.pxe)?/ - ) { - my $versionstr = "$1.$2"; - $versionstr .= $4 if $4; + my ($major, $minor, $pve); + ($major, $minor, $pve) = extract_version_parts($machine_type) if defined($machine_type); + if (defined($major) && defined($minor)) { + my $versionstr = "${major}.${minor}"; + $versionstr .= "+pve${pve}" if $pve; return $versionstr; } elsif (defined($kvmversion)) { if ($kvmversion =~ m/^(\d+)\.(\d+)/) { @@ -180,6 +222,30 @@ sub extract_version { return; } +=head3 machine_version_cmp + + sort { machine_version_cmp($a, $b) } @machine_types + +Comparision function for sorting machine types by version. + +=cut + +sub machine_version_cmp { + my ($machine_type_a, $machine_type_b) = @_; + + my ($major_a, $minor_a, $pve_a) = extract_version_parts($machine_type_a); + my ($major_b, $minor_b, $pve_b) = extract_version_parts($machine_type_b); + + return PVE::QemuServer::Helpers::version_cmp( + $major_a, + $major_b, + $minor_a, + $minor_b, + $pve_a, + $pve_b, + ); +} + sub is_machine_version_at_least { my ($machine_type, $major, $minor, $pve) = @_; diff --git a/src/PVE/QemuServer/Makefile b/src/PVE/QemuServer/Makefile index 23c136bc..63c8d77c 100644 --- a/src/PVE/QemuServer/Makefile +++ b/src/PVE/QemuServer/Makefile @@ -5,11 +5,13 @@ PERLDIR=$(PREFIX)/share/perl5 SOURCES=Agent.pm \ Blockdev.pm \ BlockJob.pm \ + Cfg2Cmd.pm \ CGroup.pm \ Cloudinit.pm \ CPUConfig.pm \ DBusVMState.pm \ Drive.pm \ + DriveDevice.pm \ Helpers.pm \ ImportDisk.pm \ Machine.pm \ @@ -30,3 +32,4 @@ SOURCES=Agent.pm \ .PHONY: install install: $(SOURCES) for i in $(SOURCES); do install -D -m 0644 $$i $(DESTDIR)$(PERLDIR)/PVE/QemuServer/$$i; done + $(MAKE) -C Cfg2Cmd install diff --git a/src/PVE/QemuServer/Monitor.pm b/src/PVE/QemuServer/Monitor.pm index 5956e1c4..0cccdfbe 100644 --- a/src/PVE/QemuServer/Monitor.pm +++ b/src/PVE/QemuServer/Monitor.pm @@ -12,14 +12,49 @@ our @EXPORT_OK = qw( mon_cmd ); +=head3 qmp_cmd + + my $cmd = { execute => $qmp_command_name, arguments => \%params }; + my $result = qmp_cmd($vmid, $cmd); + +Execute the C<$qmp_command_name> with arguments C<%params> for VM C<$vmid>. Dies if the VM is not +running or the monitor socket cannot be reached, even if the C argument is used. Returns the +structured result from the QMP side converted from JSON to structured Perl data. In case the +C argument is used and the QMP command failed or timed out, the result is a hash reference +with an C key containing the error message. + +Parameters: + +=over + +=item C<$vmid>: The ID of the virtual machine. + +=item C<$cmd>: Hash reference containing the QMP command name for the C key and additional +arguments for the QMP command under the C key. The following custom arguments are not +part of the QMP schema and supported for all commands: + +=over + +=item C: wait at most for this amount of time. If there was no actual error, the QMP/QGA +command will still continue to be executed even after the timeout reached. + +=item C: do not die when the command gets an error or the timeout is hit. The caller needs to +handle the error that is returned as a structured result. + +=back + +=back + +=cut + sub qmp_cmd { my ($vmid, $cmd) = @_; my $res; - my $timeout; + my ($noerr, $timeout); if ($cmd->{arguments}) { - $timeout = delete $cmd->{arguments}->{timeout}; + ($noerr, $timeout) = delete($cmd->{arguments}->@{qw(noerr timeout)}); } eval { @@ -28,7 +63,7 @@ sub qmp_cmd { if (-e $sname) { # test if VM is reasonably new and supports qmp/qga my $qmpclient = PVE::QMPClient->new(); - $res = $qmpclient->cmd($vmid, $cmd, $timeout); + $res = $qmpclient->cmd($vmid, $cmd, $timeout, $noerr); } else { die "unable to open monitor socket\n"; } diff --git a/src/PVE/QemuServer/Network.pm b/src/PVE/QemuServer/Network.pm index 56df83fb..eb8222e8 100644 --- a/src/PVE/QemuServer/Network.pm +++ b/src/PVE/QemuServer/Network.pm @@ -11,6 +11,8 @@ use PVE::Network::SDN::Zones; use PVE::RESTEnvironment qw(log_warn); use PVE::Tools qw($IPV6RE file_read_firstline); +use PVE::QemuServer::Monitor qw(mon_cmd); + my $nic_model_list = [ 'e1000', 'e1000-82540em', @@ -330,4 +332,31 @@ sub tap_plug { PVE::Network::SDN::Zones::tap_plug($iface, $bridge, $tag, $firewall, $trunks, $rate); } +sub get_nets_host_mtu { + my ($vmid, $conf) = @_; + + my $nets_host_mtu = []; + for my $opt (sort keys $conf->%*) { + next if $opt !~ m/^net(\d+)$/; + my $net = parse_net($conf->{$opt}); + next if $net->{model} ne 'virtio'; + + my $host_mtu = eval { + mon_cmd( + $vmid, 'qom-get', + path => "/machine/peripheral/$opt", + property => 'host_mtu', + ); + }; + if (my $err = $@) { + log_warn("$opt: could not query host_mtu - $err"); + } elsif (defined($host_mtu)) { + push $nets_host_mtu->@*, "${opt}=${host_mtu}"; + } else { + log_warn("$opt: got undefined value when querying host_mtu"); + } + } + return join(',', $nets_host_mtu->@*); +} + 1; diff --git a/src/PVE/QemuServer/OVMF.pm b/src/PVE/QemuServer/OVMF.pm index 8948651c..08134e30 100644 --- a/src/PVE/QemuServer/OVMF.pm +++ b/src/PVE/QemuServer/OVMF.pm @@ -10,7 +10,7 @@ use PVE::Storage; use PVE::Tools; use PVE::QemuServer::Blockdev; -use PVE::QemuServer::Drive qw(checked_volume_format drive_is_read_only parse_drive print_drive); +use PVE::QemuServer::Drive qw(checked_volume_format parse_drive print_drive); use PVE::QemuServer::QemuImage; my $EDK2_FW_BASE = '/usr/share/pve-edk2-firmware/'; @@ -79,7 +79,7 @@ my sub get_ovmf_files($$$$) { } my sub print_ovmf_drive_commandlines { - my ($conf, $storecfg, $vmid, $hw_info, $version_guard) = @_; + my ($conf, $storecfg, $vmid, $hw_info, $version_guard, $readonly) = @_; my ($amd_sev_type, $arch, $q35) = $hw_info->@{qw(amd-sev-type arch q35)}; @@ -109,7 +109,7 @@ my sub print_ovmf_drive_commandlines { $var_drive_str .= ",size=" . (-s $ovmf_vars) if $format eq 'raw' && $version_guard->(4, 1, 2); - $var_drive_str .= ',readonly=on' if drive_is_read_only($conf, $d); + $var_drive_str .= ',readonly=on' if $readonly; } else { log_warn("no efidisk configured! Using temporary efivars disk."); my $path = "/tmp/$vmid-ovmf.fd"; @@ -145,7 +145,7 @@ sub create_efidisk($$$$$$$$) { } my sub generate_ovmf_blockdev { - my ($conf, $storecfg, $vmid, $hw_info) = @_; + my ($conf, $storecfg, $vmid, $hw_info, $readonly) = @_; my ($amd_sev_type, $arch, $machine_version, $q35) = $hw_info->@{qw(amd-sev-type arch machine-version q35)}; @@ -187,8 +187,7 @@ my sub generate_ovmf_blockdev { $drive->{cache} = 'writeback' if !$drive->{cache}; my $extra_blockdev_options = {}; - # extra protection for templates, but SATA and IDE don't support it.. - $extra_blockdev_options->{'read-only'} = 1 if drive_is_read_only($conf, $drive); + $extra_blockdev_options->{'read-only'} = 1 if $readonly; $extra_blockdev_options->{size} = -s $ovmf_vars if $format eq 'raw'; @@ -202,7 +201,7 @@ my sub generate_ovmf_blockdev { } sub print_ovmf_commandline { - my ($conf, $storecfg, $vmid, $hw_info, $version_guard) = @_; + my ($conf, $storecfg, $vmid, $hw_info, $version_guard, $readonly) = @_; my $amd_sev_type = $hw_info->{'amd-sev-type'}; @@ -217,7 +216,7 @@ sub print_ovmf_commandline { } else { if ($version_guard->(10, 0, 0)) { # for the switch to -blockdev my ($code_blockdev, $vars_blockdev, $throttle_group) = - generate_ovmf_blockdev($conf, $storecfg, $vmid, $hw_info); + generate_ovmf_blockdev($conf, $storecfg, $vmid, $hw_info, $readonly); push $cmd->@*, '-object', to_json($throttle_group, { canonical => 1 }); push $cmd->@*, '-blockdev', to_json($code_blockdev, { canonical => 1 }); @@ -225,8 +224,9 @@ sub print_ovmf_commandline { push $machine_flags->@*, "pflash0=$code_blockdev->{'node-name'}", "pflash1=$vars_blockdev->{'node-name'}"; } else { - my ($code_drive_str, $var_drive_str) = - print_ovmf_drive_commandlines($conf, $storecfg, $vmid, $hw_info, $version_guard); + my ($code_drive_str, $var_drive_str) = print_ovmf_drive_commandlines( + $conf, $storecfg, $vmid, $hw_info, $version_guard, $readonly, + ); push $cmd->@*, '-drive', $code_drive_str; push $cmd->@*, '-drive', $var_drive_str; } diff --git a/src/PVE/QemuServer/RunState.pm b/src/PVE/QemuServer/RunState.pm index 05e7fb47..6a5fdbd7 100644 --- a/src/PVE/QemuServer/RunState.pm +++ b/src/PVE/QemuServer/RunState.pm @@ -104,7 +104,8 @@ sub vm_suspend { warn $@ if $@; PVE::Storage::deactivate_volumes($storecfg, [$vmstate]); PVE::Storage::vdisk_free($storecfg, $vmstate); - delete $conf->@{qw(vmstate runningmachine runningcpu)}; + delete $conf->@{ + qw(vmstate runningmachine runningcpu running-nets-host-mtu)}; PVE::QemuConfig->write_config($vmid, $conf); }; warn $@ if $@; diff --git a/src/PVE/VZDump/QemuServer.pm b/src/PVE/VZDump/QemuServer.pm index 5b94c369..dd789652 100644 --- a/src/PVE/VZDump/QemuServer.pm +++ b/src/PVE/VZDump/QemuServer.pm @@ -659,6 +659,7 @@ my sub attach_fleecing_images { }; my $options = { 'fleecing' => 1 }; + $options->{'tpm-backup'} = 1 if $interface eq 'tpmstate'; # Specify size explicitly, to make it work if storage backend rounded up size for # fleecing image when allocating. $options->{size} = $di->{'block-node-size'} if $format eq 'raw'; @@ -1096,17 +1097,18 @@ sub qga_fs_freeze { return; } - my $freeze = PVE::QemuServer::get_qga_key($self->{vmlist}->{$vmid}, 'freeze-fs-on-backup') // 1; + my $freeze = + PVE::QemuServer::Agent::get_qga_key($self->{vmlist}->{$vmid}, 'freeze-fs-on-backup') // 1; if (!$freeze) { $self->loginfo("skipping guest-agent 'fs-freeze', disabled in VM options"); return; } $self->loginfo("issuing guest-agent 'fs-freeze' command"); - eval { mon_cmd($vmid, "guest-fsfreeze-freeze") }; + eval { PVE::QemuServer::Agent::guest_fsfreeze($vmid); }; $self->logerr($@) if $@; - return 1; # even on mon command error, ensure we always thaw again + return 1; # even on error, ensure we always thaw again } # only call if fs_freeze return 1 @@ -1127,9 +1129,22 @@ sub query_block_node_sizes { for my $diskinfo ($disks->@*) { my $drive_key = $diskinfo->{virtdev}; - $drive_key .= "-backup" if $drive_key eq 'tpmstate0'; - my $block_node_size = - eval { $block_info->{$drive_key}->{inserted}->{image}->{'virtual-size'}; }; + + my $block_node_size; + if ($drive_key eq 'tpmstate0') { + # There is no front-end device for TPM state, so it's not included in the result of + # get_block_info(). Note that it is always attached with the same explicit node name. + my $named_block_node_info = mon_cmd($vmid, 'query-named-block-nodes'); + for my $info ($named_block_node_info->@*) { + next if $info->{'node-name'} ne 'drive-tpmstate0-backup'; + $block_node_size = $info->{image}->{'virtual-size'}; + last; + } + } else { + $block_node_size = + eval { $block_info->{$drive_key}->{inserted}->{image}->{'virtual-size'}; }; + } + if (!$block_node_size) { $self->loginfo( "could not determine block node size of drive '$drive_key' - using fallback"); diff --git a/src/dbus-vmstate/Makefile b/src/dbus-vmstate/Makefile deleted file mode 100644 index ced00264..00000000 --- a/src/dbus-vmstate/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -export LIBEXECDIR := $(DESTDIR)/usr/libexec/$(PACKAGE) -export LIBSYSTEMDDIR := $(DESTDIR)/usr/lib/systemd -export DBUSDIR := $(DESTDIR)/usr/share/dbus-1 - -all: - -.PHONY: install -install: - install -D -m 0755 dbus-vmstate $(LIBEXECDIR)/dbus-vmstate - install -D -m 0644 pve-dbus-vmstate@.service $(LIBSYSTEMDDIR)/system/pve-dbus-vmstate@.service - install -D -m 0644 org.qemu.VMState1.conf $(DBUSDIR)/system.d/org.qemu.VMState1.conf diff --git a/src/qmeventd/qmeventd.c b/src/qmeventd/qmeventd.c index 1d9eb74a..7bae13f9 100644 --- a/src/qmeventd/qmeventd.c +++ b/src/qmeventd/qmeventd.c @@ -43,7 +43,7 @@ #define DEFAULT_KILL_TIMEOUT 60 -static int verbose = 0; +static int verbose = 1; static int kill_timeout = DEFAULT_KILL_TIMEOUT; static int epoll_fd = 0; static const char *progname; @@ -209,6 +209,25 @@ void handle_qmp_event(struct Client *client, struct json_object *obj) { // check if a backup is running and kill QEMU process if not terminate_check(client); + } else if (!strcmp(json_object_get_string(event), "BLOCK_WRITE_THRESHOLD")) { + struct json_object *data; + struct json_object *nodename; + if (json_object_object_get_ex(obj, "data", &data) && + json_object_object_get_ex(data, "node-name", &nodename)) { + + // needs concurrency control + char extend_queue_path[] = "/etc/pve/extend-queue"; + FILE *p_extend_queue = fopen(extend_queue_path, "a"); + if (p_extend_queue == NULL) { + VERBOSE_PRINT( + "%s: Couldn't open extend queue file %s", client->qemu.vmid, extend_queue_path + ); + } else { + const char *nodename_string = json_object_get_string(nodename); + fprintf(p_extend_queue, "%s: %s\n", client->qemu.vmid, nodename_string); + } + fclose(p_extend_queue); + } } } diff --git a/src/test/MigrationTest/QemuMigrateMock.pm b/src/test/MigrationTest/QemuMigrateMock.pm index b04cf78b..421f0bb7 100644 --- a/src/test/MigrationTest/QemuMigrateMock.pm +++ b/src/test/MigrationTest/QemuMigrateMock.pm @@ -225,6 +225,21 @@ $qemu_server_machine_module->mock( my $qemu_server_network_module = Test::MockModule->new("PVE::QemuServer::Network"); $qemu_server_network_module->mock( del_nets_bridge_fdb => sub { return; }, + mon_cmd => sub { + my ($vmid, $command, %params) = @_; + + if ($command eq 'qom-get') { + if ( + $params{path} =~ m|^/machine/peripheral/net\d+$| + && $params{property} eq 'host_mtu' + ) { + return 1500; + } + die "mon_cmd (mocked) - implement me: $command for path '$params{path}' property" + . " '$params{property}'"; + } + die "mon_cmd (mocked) - implement me: $command"; + }, ); my $qemu_server_qmphelpers_module = Test::MockModule->new("PVE::QemuServer::QMPHelpers"); diff --git a/src/test/cfg2cmd/bootorder-empty.conf.cmd b/src/test/cfg2cmd/bootorder-empty.conf.cmd index 3516b344..32b72a27 100644 --- a/src/test/cfg2cmd/bootorder-empty.conf.cmd +++ b/src/test/cfg2cmd/bootorder-empty.conf.cmd @@ -39,5 +39,5 @@ -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"eeb683fb9c516c1a8707c917f0d7a38","read-only":false},"node-name":"feb683fb9c516c1a8707c917f0d7a38","read-only":false},"node-name":"drive-virtio1","read-only":false,"throttle-group":"throttle-drive-virtio1"}' \ -device 'virtio-blk-pci,drive=drive-virtio1,id=virtio1,bus=pci.0,addr=0xb,iothread=iothread-virtio1,write-cache=on' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ - -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256' \ - -machine 'type=pc+pve0' + -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,host_mtu=1500' \ + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/bootorder-legacy.conf.cmd b/src/test/cfg2cmd/bootorder-legacy.conf.cmd index c86ab6f9..9e558167 100644 --- a/src/test/cfg2cmd/bootorder-legacy.conf.cmd +++ b/src/test/cfg2cmd/bootorder-legacy.conf.cmd @@ -39,5 +39,5 @@ -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"eeb683fb9c516c1a8707c917f0d7a38","read-only":false},"node-name":"feb683fb9c516c1a8707c917f0d7a38","read-only":false},"node-name":"drive-virtio1","read-only":false,"throttle-group":"throttle-drive-virtio1"}' \ -device 'virtio-blk-pci,drive=drive-virtio1,id=virtio1,bus=pci.0,addr=0xb,iothread=iothread-virtio1,bootindex=302,write-cache=on' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ - -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=100' \ - -machine 'type=pc+pve0' + -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=100,host_mtu=1500' \ + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/bootorder.conf.cmd b/src/test/cfg2cmd/bootorder.conf.cmd index 48f9da8b..430926c0 100644 --- a/src/test/cfg2cmd/bootorder.conf.cmd +++ b/src/test/cfg2cmd/bootorder.conf.cmd @@ -39,5 +39,5 @@ -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"eeb683fb9c516c1a8707c917f0d7a38","read-only":false},"node-name":"feb683fb9c516c1a8707c917f0d7a38","read-only":false},"node-name":"drive-virtio1","read-only":false,"throttle-group":"throttle-drive-virtio1"}' \ -device 'virtio-blk-pci,drive=drive-virtio1,id=virtio1,bus=pci.0,addr=0xb,iothread=iothread-virtio1,bootindex=100,write-cache=on' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ - -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=101' \ - -machine 'type=pc+pve0' + -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=101,host_mtu=1500' \ + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/cputype-icelake-client-deprecation.conf.cmd b/src/test/cfg2cmd/cputype-icelake-client-deprecation.conf.cmd index e6429c9f..42e97987 100644 --- a/src/test/cfg2cmd/cputype-icelake-client-deprecation.conf.cmd +++ b/src/test/cfg2cmd/cputype-icelake-client-deprecation.conf.cmd @@ -30,4 +30,4 @@ -device 'virtio-scsi-pci,id=scsihw0,bus=pci.0,addr=0x5' \ -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/base-8006-disk-0.qcow2","node-name":"e417d5947e69c5890b1e3ddf8a68167","read-only":false},"node-name":"f417d5947e69c5890b1e3ddf8a68167","read-only":false},"node-name":"drive-scsi0","read-only":false,"throttle-group":"throttle-drive-scsi0"}' \ -device 'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,device_id=drive-scsi0,bootindex=100,write-cache=on' \ - -machine 'type=pc+pve0' + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/custom-cpu-model-defaults.conf.cmd b/src/test/cfg2cmd/custom-cpu-model-defaults.conf.cmd index 2908fdc0..57f6bb34 100644 --- a/src/test/cfg2cmd/custom-cpu-model-defaults.conf.cmd +++ b/src/test/cfg2cmd/custom-cpu-model-defaults.conf.cmd @@ -24,4 +24,4 @@ -device 'VGA,id=vga,bus=pci.0,addr=0x2' \ -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ - -machine 'type=pc+pve0' + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/efidisk-on-rbd.conf.cmd b/src/test/cfg2cmd/efidisk-on-rbd.conf.cmd index 5d0c8aff..fc6d68a4 100644 --- a/src/test/cfg2cmd/efidisk-on-rbd.conf.cmd +++ b/src/test/cfg2cmd/efidisk-on-rbd.conf.cmd @@ -31,5 +31,5 @@ -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ - -device 'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300' \ - -machine 'pflash0=pflash0,pflash1=drive-efidisk0,type=pc+pve0' + -device 'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=1500' \ + -machine 'pflash0=pflash0,pflash1=drive-efidisk0,hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/ide.conf.cmd b/src/test/cfg2cmd/ide.conf.cmd index 6b5a52a9..2503e9a4 100644 --- a/src/test/cfg2cmd/ide.conf.cmd +++ b/src/test/cfg2cmd/ide.conf.cmd @@ -42,5 +42,5 @@ -blockdev '{"detect-zeroes":"on","discard":"ignore","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"on","discard":"ignore","driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"on","discard":"ignore","driver":"file","filename":"/var/lib/vz/images/100/vm-100-disk-2.qcow2","node-name":"ec11e0572184321efc5835152b95d5d","read-only":false},"node-name":"fc11e0572184321efc5835152b95d5d","read-only":false},"node-name":"drive-scsi0","read-only":false,"throttle-group":"throttle-drive-scsi0"}' \ -device 'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,device_id=drive-scsi0,bootindex=100,write-cache=on' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ - -device 'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300' \ - -machine 'type=pc+pve0' + -device 'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=1500' \ + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/memory-hotplug-hugepages.conf.cmd b/src/test/cfg2cmd/memory-hotplug-hugepages.conf.cmd index e069bd6b..0f071ac0 100644 --- a/src/test/cfg2cmd/memory-hotplug-hugepages.conf.cmd +++ b/src/test/cfg2cmd/memory-hotplug-hugepages.conf.cmd @@ -61,4 +61,4 @@ -device 'VGA,id=vga,bus=pci.0,addr=0x2' \ -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ - -machine 'type=pc+pve0' + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/memory-hotplug.conf.cmd b/src/test/cfg2cmd/memory-hotplug.conf.cmd index af80917b..5402b5ee 100644 --- a/src/test/cfg2cmd/memory-hotplug.conf.cmd +++ b/src/test/cfg2cmd/memory-hotplug.conf.cmd @@ -173,4 +173,4 @@ -device 'VGA,id=vga,bus=pci.0,addr=0x2' \ -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ - -machine 'type=pc+pve0' + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/memory-hugepages-1g.conf.cmd b/src/test/cfg2cmd/memory-hugepages-1g.conf.cmd index 73c3036f..e62aa768 100644 --- a/src/test/cfg2cmd/memory-hugepages-1g.conf.cmd +++ b/src/test/cfg2cmd/memory-hugepages-1g.conf.cmd @@ -29,4 +29,4 @@ -device 'VGA,id=vga,bus=pci.0,addr=0x2' \ -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ - -machine 'type=pc+pve0' + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/memory-hugepages-2m.conf.cmd b/src/test/cfg2cmd/memory-hugepages-2m.conf.cmd index 9eb85a72..89e43393 100644 --- a/src/test/cfg2cmd/memory-hugepages-2m.conf.cmd +++ b/src/test/cfg2cmd/memory-hugepages-2m.conf.cmd @@ -29,4 +29,4 @@ -device 'VGA,id=vga,bus=pci.0,addr=0x2' \ -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ - -machine 'type=pc+pve0' + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/netdev-7.1-multiqueues.conf.cmd b/src/test/cfg2cmd/netdev-7.1-multiqueues.conf.cmd index 776bab30..fe2af829 100644 --- a/src/test/cfg2cmd/netdev-7.1-multiqueues.conf.cmd +++ b/src/test/cfg2cmd/netdev-7.1-multiqueues.conf.cmd @@ -25,4 +25,4 @@ -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on,queues=2' \ -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,vectors=6,mq=on,packed=on,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=900' \ - -machine 'type=pc+pve0' + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/netdev-7.1.conf.cmd b/src/test/cfg2cmd/netdev-7.1.conf.cmd index 0d6b3ad2..7b858d92 100644 --- a/src/test/cfg2cmd/netdev-7.1.conf.cmd +++ b/src/test/cfg2cmd/netdev-7.1.conf.cmd @@ -25,4 +25,4 @@ -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=900' \ - -machine 'type=pc+pve0' + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/netdev_vxlan.conf.cmd b/src/test/cfg2cmd/netdev_vxlan.conf.cmd index a2f3579d..3d6c8da7 100644 --- a/src/test/cfg2cmd/netdev_vxlan.conf.cmd +++ b/src/test/cfg2cmd/netdev_vxlan.conf.cmd @@ -25,4 +25,4 @@ -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=1450' \ - -machine 'type=pc+pve0' + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/os-l24.conf b/src/test/cfg2cmd/os-l24.conf new file mode 100644 index 00000000..e6c3ea70 --- /dev/null +++ b/src/test/cfg2cmd/os-l24.conf @@ -0,0 +1,3 @@ +# TEST: Simple test for Linux OS type l24 +ostype: l24 +vga: qxl diff --git a/src/test/cfg2cmd/os-l24.conf.cmd b/src/test/cfg2cmd/os-l24.conf.cmd new file mode 100644 index 00000000..45dbc7cd --- /dev/null +++ b/src/test/cfg2cmd/os-l24.conf.cmd @@ -0,0 +1,29 @@ +/usr/bin/kvm \ + -id 8006 \ + -name 'vm8006,debug-threads=on' \ + -no-shutdown \ + -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \ + -mon 'chardev=qmp,mode=control' \ + -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \ + -mon 'chardev=qmp-event,mode=control' \ + -pidfile /var/run/qemu-server/8006.pid \ + -daemonize \ + -smp '1,sockets=1,cores=1,maxcpus=1' \ + -nodefaults \ + -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ + -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ + -m 512 \ + -global 'PIIX4_PM.disable_s3=1' \ + -global 'PIIX4_PM.disable_s4=1' \ + -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ + -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \ + -device 'piix3-usb-uhci,id=uhci,bus=pci.0,addr=0x1.0x2' \ + -device 'qxl-vga,id=vga,max_outputs=4,bus=pci.0,addr=0x2' \ + -device 'virtio-serial,id=spice,bus=pci.0,addr=0x9' \ + -chardev 'spicevmc,id=vdagent,name=vdagent' \ + -device 'virtserialport,chardev=vdagent,name=com.redhat.spice.0' \ + -spice 'tls-port=61000,addr=127.0.0.1,tls-ciphers=HIGH,seamless-migration=on' \ + -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ + -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ + -machine 'type=pc+pve0' diff --git a/src/test/cfg2cmd/os-other.conf b/src/test/cfg2cmd/os-other.conf new file mode 100644 index 00000000..741e8afb --- /dev/null +++ b/src/test/cfg2cmd/os-other.conf @@ -0,0 +1,2 @@ +# TEST: Simple test for OS type other +ostype: other diff --git a/src/test/cfg2cmd/os-other.conf.cmd b/src/test/cfg2cmd/os-other.conf.cmd new file mode 100644 index 00000000..1f53858b --- /dev/null +++ b/src/test/cfg2cmd/os-other.conf.cmd @@ -0,0 +1,26 @@ +/usr/bin/kvm \ + -id 8006 \ + -name 'vm8006,debug-threads=on' \ + -no-shutdown \ + -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \ + -mon 'chardev=qmp,mode=control' \ + -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \ + -mon 'chardev=qmp-event,mode=control' \ + -pidfile /var/run/qemu-server/8006.pid \ + -daemonize \ + -smp '1,sockets=1,cores=1,maxcpus=1' \ + -nodefaults \ + -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ + -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ + -m 512 \ + -global 'PIIX4_PM.disable_s3=1' \ + -global 'PIIX4_PM.disable_s4=1' \ + -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ + -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \ + -device 'piix3-usb-uhci,id=uhci,bus=pci.0,addr=0x1.0x2' \ + -device 'usb-tablet,id=tablet,bus=uhci.0,port=1' \ + -device 'VGA,id=vga,bus=pci.0,addr=0x2' \ + -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ + -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ + -machine 'type=pc+pve0' diff --git a/src/test/cfg2cmd/os-solaris.conf b/src/test/cfg2cmd/os-solaris.conf new file mode 100644 index 00000000..4684ccbb --- /dev/null +++ b/src/test/cfg2cmd/os-solaris.conf @@ -0,0 +1,2 @@ +# TEST: Simple test for OS type Solaris +ostype: solaris diff --git a/src/test/cfg2cmd/os-solaris.conf.cmd b/src/test/cfg2cmd/os-solaris.conf.cmd new file mode 100644 index 00000000..23e6987f --- /dev/null +++ b/src/test/cfg2cmd/os-solaris.conf.cmd @@ -0,0 +1,26 @@ +/usr/bin/kvm \ + -id 8006 \ + -name 'vm8006,debug-threads=on' \ + -no-shutdown \ + -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \ + -mon 'chardev=qmp,mode=control' \ + -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \ + -mon 'chardev=qmp-event,mode=control' \ + -pidfile /var/run/qemu-server/8006.pid \ + -daemonize \ + -smp '1,sockets=1,cores=1,maxcpus=1' \ + -nodefaults \ + -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ + -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep,-x2apic \ + -m 512 \ + -global 'PIIX4_PM.disable_s3=1' \ + -global 'PIIX4_PM.disable_s4=1' \ + -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ + -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \ + -device 'piix3-usb-uhci,id=uhci,bus=pci.0,addr=0x1.0x2' \ + -device 'usb-tablet,id=tablet,bus=uhci.0,port=1' \ + -device 'VGA,id=vga,bus=pci.0,addr=0x2' \ + -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ + -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ + -machine 'type=pc+pve0' diff --git a/src/test/cfg2cmd/q35-ide.conf.cmd b/src/test/cfg2cmd/q35-ide.conf.cmd index 475e58d9..36f5264e 100644 --- a/src/test/cfg2cmd/q35-ide.conf.cmd +++ b/src/test/cfg2cmd/q35-ide.conf.cmd @@ -41,5 +41,5 @@ -blockdev '{"detect-zeroes":"on","discard":"ignore","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"on","discard":"ignore","driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"on","discard":"ignore","driver":"file","filename":"/var/lib/vz/images/100/vm-100-disk-2.qcow2","node-name":"ec11e0572184321efc5835152b95d5d","read-only":false},"node-name":"fc11e0572184321efc5835152b95d5d","read-only":false},"node-name":"drive-scsi0","read-only":false,"throttle-group":"throttle-drive-scsi0"}' \ -device 'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,device_id=drive-scsi0,bootindex=100,write-cache=on' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ - -device 'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300' \ - -machine 'type=q35+pve0' + -device 'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=1500' \ + -machine 'hpet=off,type=q35+pve0' diff --git a/src/test/cfg2cmd/q35-linux-hostpci-mapping.conf.cmd b/src/test/cfg2cmd/q35-linux-hostpci-mapping.conf.cmd index b0c3e587..b5d8997e 100644 --- a/src/test/cfg2cmd/q35-linux-hostpci-mapping.conf.cmd +++ b/src/test/cfg2cmd/q35-linux-hostpci-mapping.conf.cmd @@ -35,5 +35,5 @@ -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ - -device 'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300' \ - -machine 'pflash0=pflash0,pflash1=drive-efidisk0,type=q35+pve0' + -device 'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=1500' \ + -machine 'pflash0=pflash0,pflash1=drive-efidisk0,hpet=off,type=q35+pve0' diff --git a/src/test/cfg2cmd/q35-linux-hostpci-multifunction.conf.cmd b/src/test/cfg2cmd/q35-linux-hostpci-multifunction.conf.cmd index b4aa46f5..9cfc71a7 100644 --- a/src/test/cfg2cmd/q35-linux-hostpci-multifunction.conf.cmd +++ b/src/test/cfg2cmd/q35-linux-hostpci-multifunction.conf.cmd @@ -35,5 +35,5 @@ -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ - -device 'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300' \ - -machine 'pflash0=pflash0,pflash1=drive-efidisk0,type=q35+pve0' + -device 'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=1500' \ + -machine 'pflash0=pflash0,pflash1=drive-efidisk0,hpet=off,type=q35+pve0' diff --git a/src/test/cfg2cmd/q35-linux-hostpci-x-pci-overrides.conf.cmd b/src/test/cfg2cmd/q35-linux-hostpci-x-pci-overrides.conf.cmd index 6c4937c7..7b3f65f4 100644 --- a/src/test/cfg2cmd/q35-linux-hostpci-x-pci-overrides.conf.cmd +++ b/src/test/cfg2cmd/q35-linux-hostpci-x-pci-overrides.conf.cmd @@ -34,5 +34,5 @@ -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ - -device 'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300' \ - -machine 'pflash0=pflash0,pflash1=drive-efidisk0,type=q35+pve0' + -device 'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=1500' \ + -machine 'pflash0=pflash0,pflash1=drive-efidisk0,hpet=off,type=q35+pve0' diff --git a/src/test/cfg2cmd/q35-linux-hostpci.conf.cmd b/src/test/cfg2cmd/q35-linux-hostpci.conf.cmd index 19e6ba3c..7226d478 100644 --- a/src/test/cfg2cmd/q35-linux-hostpci.conf.cmd +++ b/src/test/cfg2cmd/q35-linux-hostpci.conf.cmd @@ -40,5 +40,5 @@ -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ - -device 'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300' \ - -machine 'pflash0=pflash0,pflash1=drive-efidisk0,type=q35+pve0' + -device 'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=1500' \ + -machine 'pflash0=pflash0,pflash1=drive-efidisk0,hpet=off,type=q35+pve0' diff --git a/src/test/cfg2cmd/q35-no-viommu-with-aw-bits.conf b/src/test/cfg2cmd/q35-no-viommu-with-aw-bits.conf new file mode 100644 index 00000000..06db33ab --- /dev/null +++ b/src/test/cfg2cmd/q35-no-viommu-with-aw-bits.conf @@ -0,0 +1,3 @@ +# TEST: Check that aw-bits cannot be set without viommu +# EXPECT_ERROR: cannot set aw-bits if no vIOMMU is configured +machine: q35,aw-bits=39 diff --git a/src/test/cfg2cmd/q35-simple.conf.cmd b/src/test/cfg2cmd/q35-simple.conf.cmd index e3f712c3..307aeb4a 100644 --- a/src/test/cfg2cmd/q35-simple.conf.cmd +++ b/src/test/cfg2cmd/q35-simple.conf.cmd @@ -28,5 +28,5 @@ -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ - -device 'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300' \ - -machine 'pflash0=pflash0,pflash1=drive-efidisk0,type=q35+pve0' + -device 'virtio-net-pci,mac=2E:01:68:F9:9C:87,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=1500' \ + -machine 'pflash0=pflash0,pflash1=drive-efidisk0,hpet=off,type=q35+pve0' diff --git a/src/test/cfg2cmd/q35-viommu-intel-aw-bits.conf b/src/test/cfg2cmd/q35-viommu-intel-aw-bits.conf new file mode 100644 index 00000000..9e84e42e --- /dev/null +++ b/src/test/cfg2cmd/q35-viommu-intel-aw-bits.conf @@ -0,0 +1,2 @@ +# TEST: Check if aw-bits are propagated correctly to intel-iommu device +machine: q35,viommu=intel,aw-bits=39 diff --git a/src/test/cfg2cmd/q35-viommu-intel-aw-bits.conf.cmd b/src/test/cfg2cmd/q35-viommu-intel-aw-bits.conf.cmd new file mode 100644 index 00000000..030ccaa5 --- /dev/null +++ b/src/test/cfg2cmd/q35-viommu-intel-aw-bits.conf.cmd @@ -0,0 +1,25 @@ +/usr/bin/kvm \ + -id 8006 \ + -name 'vm8006,debug-threads=on' \ + -no-shutdown \ + -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \ + -mon 'chardev=qmp,mode=control' \ + -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \ + -mon 'chardev=qmp-event,mode=control' \ + -pidfile /var/run/qemu-server/8006.pid \ + -daemonize \ + -smp '1,sockets=1,cores=1,maxcpus=1' \ + -nodefaults \ + -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ + -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ + -m 512 \ + -global 'ICH9-LPC.disable_s3=1' \ + -global 'ICH9-LPC.disable_s4=1' \ + -device 'intel-iommu,intremap=on,caching-mode=on,aw-bits=39' \ + -readconfig /usr/share/qemu-server/pve-q35-4.0.cfg \ + -device 'usb-tablet,id=tablet,bus=ehci.0,port=1' \ + -device 'VGA,id=vga,bus=pcie.0,addr=0x1' \ + -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ + -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ + -machine 'type=q35+pve0,kernel-irqchip=split' diff --git a/src/test/cfg2cmd/q35-viommu-intel-guest-phys-bits.conf b/src/test/cfg2cmd/q35-viommu-intel-guest-phys-bits.conf new file mode 100644 index 00000000..7decb63e --- /dev/null +++ b/src/test/cfg2cmd/q35-viommu-intel-guest-phys-bits.conf @@ -0,0 +1,2 @@ +machine: q35,viommu=intel +cpu: host,guest-phys-bits=39 diff --git a/src/test/cfg2cmd/q35-viommu-intel-guest-phys-bits.conf.cmd b/src/test/cfg2cmd/q35-viommu-intel-guest-phys-bits.conf.cmd new file mode 100644 index 00000000..b24baeb0 --- /dev/null +++ b/src/test/cfg2cmd/q35-viommu-intel-guest-phys-bits.conf.cmd @@ -0,0 +1,25 @@ +/usr/bin/kvm \ + -id 8006 \ + -name 'vm8006,debug-threads=on' \ + -no-shutdown \ + -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \ + -mon 'chardev=qmp,mode=control' \ + -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \ + -mon 'chardev=qmp-event,mode=control' \ + -pidfile /var/run/qemu-server/8006.pid \ + -daemonize \ + -smp '1,sockets=1,cores=1,maxcpus=1' \ + -nodefaults \ + -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ + -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \ + -cpu 'host,+kvm_pv_eoi,+kvm_pv_unhalt,guest-phys-bits=39' \ + -m 512 \ + -global 'ICH9-LPC.disable_s3=1' \ + -global 'ICH9-LPC.disable_s4=1' \ + -device 'intel-iommu,intremap=on,caching-mode=on' \ + -readconfig /usr/share/qemu-server/pve-q35-4.0.cfg \ + -device 'usb-tablet,id=tablet,bus=ehci.0,port=1' \ + -device 'VGA,id=vga,bus=pcie.0,addr=0x1' \ + -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ + -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ + -machine 'type=q35+pve0,kernel-irqchip=split' diff --git a/src/test/cfg2cmd/q35-viommu-virtio-aw-bits.conf b/src/test/cfg2cmd/q35-viommu-virtio-aw-bits.conf new file mode 100644 index 00000000..dd8ef1fd --- /dev/null +++ b/src/test/cfg2cmd/q35-viommu-virtio-aw-bits.conf @@ -0,0 +1,2 @@ +# TEST: Check if aw-bits are propagated correctly to virtio-iommu-pci device +machine: q35,viommu=virtio,aw-bits=39 diff --git a/src/test/cfg2cmd/q35-viommu-virtio-aw-bits.conf.cmd b/src/test/cfg2cmd/q35-viommu-virtio-aw-bits.conf.cmd new file mode 100644 index 00000000..c3b12eee --- /dev/null +++ b/src/test/cfg2cmd/q35-viommu-virtio-aw-bits.conf.cmd @@ -0,0 +1,25 @@ +/usr/bin/kvm \ + -id 8006 \ + -name 'vm8006,debug-threads=on' \ + -no-shutdown \ + -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \ + -mon 'chardev=qmp,mode=control' \ + -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \ + -mon 'chardev=qmp-event,mode=control' \ + -pidfile /var/run/qemu-server/8006.pid \ + -daemonize \ + -smp '1,sockets=1,cores=1,maxcpus=1' \ + -nodefaults \ + -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ + -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ + -m 512 \ + -global 'ICH9-LPC.disable_s3=1' \ + -global 'ICH9-LPC.disable_s4=1' \ + -readconfig /usr/share/qemu-server/pve-q35-4.0.cfg \ + -device 'usb-tablet,id=tablet,bus=ehci.0,port=1' \ + -device 'VGA,id=vga,bus=pcie.0,addr=0x1' \ + -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ + -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ + -device 'virtio-iommu-pci,aw-bits=39' \ + -machine 'type=q35+pve0' diff --git a/src/test/cfg2cmd/scsiblk.conf b/src/test/cfg2cmd/scsiblk.conf new file mode 100644 index 00000000..c767cef6 --- /dev/null +++ b/src/test/cfg2cmd/scsiblk.conf @@ -0,0 +1,5 @@ +boot: order=scsi0 +meta: creation-qemu=10.0.2,ctime=1755189639 +scsi0: /dev/sdg,scsiblock=1,size=32G +smbios1: uuid=d47e2d5c-7068-46d4-9733-ff94083e28f6 +vmgenid: 0a212e2f-0d9a-4006-971e-17be9fcf3efe diff --git a/src/test/cfg2cmd/scsiblk.conf.cmd b/src/test/cfg2cmd/scsiblk.conf.cmd new file mode 100644 index 00000000..3f99b405 --- /dev/null +++ b/src/test/cfg2cmd/scsiblk.conf.cmd @@ -0,0 +1,32 @@ +/usr/bin/kvm \ + -id 8006 \ + -name 'vm8006,debug-threads=on' \ + -no-shutdown \ + -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \ + -mon 'chardev=qmp,mode=control' \ + -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \ + -mon 'chardev=qmp-event,mode=control' \ + -pidfile /var/run/qemu-server/8006.pid \ + -daemonize \ + -smbios 'type=1,uuid=d47e2d5c-7068-46d4-9733-ff94083e28f6' \ + -smp '1,sockets=1,cores=1,maxcpus=1' \ + -nodefaults \ + -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ + -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ + -m 512 \ + -object '{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \ + -global 'PIIX4_PM.disable_s3=1' \ + -global 'PIIX4_PM.disable_s4=1' \ + -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ + -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \ + -device 'vmgenid,guid=0a212e2f-0d9a-4006-971e-17be9fcf3efe' \ + -device 'piix3-usb-uhci,id=uhci,bus=pci.0,addr=0x1.0x2' \ + -device 'usb-tablet,id=tablet,bus=uhci.0,port=1' \ + -device 'VGA,id=vga,bus=pci.0,addr=0x2' \ + -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ + -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ + -device 'lsi,id=scsihw0,bus=pci.0,addr=0x5' \ + -blockdev '{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"on","discard":"ignore","driver":"raw","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"on","discard":"ignore","driver":"host_device","filename":"/dev/sdg","node-name":"e8c91179e47ae3eb292a03618be5cf4","read-only":false},"node-name":"drive-scsi0","read-only":false}' \ + -device 'scsi-hd,bus=scsihw0.0,scsi-id=0,drive=drive-scsi0,id=scsi0,device_id=drive-scsi0,bootindex=100,write-cache=on' \ + -machine 'type=pc+pve0' diff --git a/src/test/cfg2cmd/scsihw-lsi.conf b/src/test/cfg2cmd/scsihw-lsi.conf new file mode 100644 index 00000000..fd111842 --- /dev/null +++ b/src/test/cfg2cmd/scsihw-lsi.conf @@ -0,0 +1,9 @@ +# TEST: Simple test for LSI SCSI controller +bootdisk: scsi0 +name: simple +scsi0: lvm-store:vm-8006-disk-0,discard=on,size=104858K +scsi1: lvm-store:vm-8006-disk-1,cache=writeback,discard=on,size=104858K +scsi5: lvm-store:vm-8006-disk-2,cache=writethrough,discard=on,size=104858K +scsi9: lvm-store:vm-8006-disk-3,cache=directsync,discard=on,size=104858K +scsi16: lvm-store:vm-8006-disk-4,cache=directsync,discard=on,size=104858K +scsihw: lsi diff --git a/src/test/cfg2cmd/scsihw-lsi.conf.cmd b/src/test/cfg2cmd/scsihw-lsi.conf.cmd new file mode 100644 index 00000000..0200215d --- /dev/null +++ b/src/test/cfg2cmd/scsihw-lsi.conf.cmd @@ -0,0 +1,45 @@ +/usr/bin/kvm \ + -id 8006 \ + -name 'simple,debug-threads=on' \ + -no-shutdown \ + -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \ + -mon 'chardev=qmp,mode=control' \ + -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \ + -mon 'chardev=qmp-event,mode=control' \ + -pidfile /var/run/qemu-server/8006.pid \ + -daemonize \ + -smp '1,sockets=1,cores=1,maxcpus=1' \ + -nodefaults \ + -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ + -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ + -m 512 \ + -object '{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \ + -object '{"id":"throttle-drive-scsi1","limits":{},"qom-type":"throttle-group"}' \ + -object '{"id":"throttle-drive-scsi5","limits":{},"qom-type":"throttle-group"}' \ + -object '{"id":"throttle-drive-scsi9","limits":{},"qom-type":"throttle-group"}' \ + -object '{"id":"throttle-drive-scsi16","limits":{},"qom-type":"throttle-group"}' \ + -global 'PIIX4_PM.disable_s3=1' \ + -global 'PIIX4_PM.disable_s4=1' \ + -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ + -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \ + -device 'pci-bridge,id=pci.4,chassis_nr=4,bus=pci.1,addr=0x1c' \ + -device 'piix3-usb-uhci,id=uhci,bus=pci.0,addr=0x1.0x2' \ + -device 'usb-tablet,id=tablet,bus=uhci.0,port=1' \ + -device 'VGA,id=vga,bus=pci.0,addr=0x2' \ + -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ + -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ + -device 'lsi,id=scsihw0,bus=pci.0,addr=0x5' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"native","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-0","node-name":"e0378a375d635b0f473569544c7c207","read-only":false},"node-name":"f0378a375d635b0f473569544c7c207","read-only":false},"node-name":"drive-scsi0","read-only":false,"throttle-group":"throttle-drive-scsi0"}' \ + -device 'scsi-hd,bus=scsihw0.0,scsi-id=0,drive=drive-scsi0,id=scsi0,device_id=drive-scsi0,bootindex=100,write-cache=on' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"threads","cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-1","node-name":"e68a63e6c55e4a6fe8c847a8f60af7e","read-only":false},"node-name":"f68a63e6c55e4a6fe8c847a8f60af7e","read-only":false},"node-name":"drive-scsi1","read-only":false,"throttle-group":"throttle-drive-scsi1"}' \ + -device 'scsi-hd,bus=scsihw0.0,scsi-id=1,drive=drive-scsi1,id=scsi1,device_id=drive-scsi1,write-cache=on' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"threads","cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-2","node-name":"e02ef0cb3873a2ecfddb04f546b6b26","read-only":false},"node-name":"f02ef0cb3873a2ecfddb04f546b6b26","read-only":false},"node-name":"drive-scsi5","read-only":false,"throttle-group":"throttle-drive-scsi5"}' \ + -device 'scsi-hd,bus=scsihw0.0,scsi-id=5,drive=drive-scsi5,id=scsi5,device_id=drive-scsi5,write-cache=off' \ + -device 'lsi,id=scsihw1,bus=pci.0,addr=0x6' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"native","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-3","node-name":"e77e7a9ba0adc041419f45894ffb1ed","read-only":false},"node-name":"f77e7a9ba0adc041419f45894ffb1ed","read-only":false},"node-name":"drive-scsi9","read-only":false,"throttle-group":"throttle-drive-scsi9"}' \ + -device 'scsi-hd,bus=scsihw1.0,scsi-id=2,drive=drive-scsi9,id=scsi9,device_id=drive-scsi9,write-cache=off' \ + -device 'lsi,id=scsihw2,bus=pci.4,addr=0x1' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"native","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-4","node-name":"e86ac0b43c3f3cb5be16052b349a9b7","read-only":false},"node-name":"f86ac0b43c3f3cb5be16052b349a9b7","read-only":false},"node-name":"drive-scsi16","read-only":false,"throttle-group":"throttle-drive-scsi16"}' \ + -device 'scsi-hd,bus=scsihw2.0,scsi-id=2,drive=drive-scsi16,id=scsi16,device_id=drive-scsi16,write-cache=off' \ + -machine 'type=pc+pve0' diff --git a/src/test/cfg2cmd/scsihw-lsi53c810.conf b/src/test/cfg2cmd/scsihw-lsi53c810.conf new file mode 100644 index 00000000..58217419 --- /dev/null +++ b/src/test/cfg2cmd/scsihw-lsi53c810.conf @@ -0,0 +1,9 @@ +# TEST: Simple test for LSI 53c810 SCSI controller +bootdisk: scsi0 +name: simple +scsi0: lvm-store:vm-8006-disk-0,discard=on,size=104858K +scsi1: lvm-store:vm-8006-disk-1,cache=writeback,discard=on,size=104858K +scsi5: lvm-store:vm-8006-disk-2,cache=writethrough,discard=on,size=104858K +scsi9: lvm-store:vm-8006-disk-3,cache=directsync,discard=on,size=104858K +scsi16: lvm-store:vm-8006-disk-4,cache=directsync,discard=on,size=104858K +scsihw: lsi53c810 diff --git a/src/test/cfg2cmd/scsihw-lsi53c810.conf.cmd b/src/test/cfg2cmd/scsihw-lsi53c810.conf.cmd new file mode 100644 index 00000000..fc27eaf0 --- /dev/null +++ b/src/test/cfg2cmd/scsihw-lsi53c810.conf.cmd @@ -0,0 +1,45 @@ +/usr/bin/kvm \ + -id 8006 \ + -name 'simple,debug-threads=on' \ + -no-shutdown \ + -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \ + -mon 'chardev=qmp,mode=control' \ + -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \ + -mon 'chardev=qmp-event,mode=control' \ + -pidfile /var/run/qemu-server/8006.pid \ + -daemonize \ + -smp '1,sockets=1,cores=1,maxcpus=1' \ + -nodefaults \ + -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ + -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ + -m 512 \ + -object '{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \ + -object '{"id":"throttle-drive-scsi1","limits":{},"qom-type":"throttle-group"}' \ + -object '{"id":"throttle-drive-scsi5","limits":{},"qom-type":"throttle-group"}' \ + -object '{"id":"throttle-drive-scsi9","limits":{},"qom-type":"throttle-group"}' \ + -object '{"id":"throttle-drive-scsi16","limits":{},"qom-type":"throttle-group"}' \ + -global 'PIIX4_PM.disable_s3=1' \ + -global 'PIIX4_PM.disable_s4=1' \ + -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ + -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \ + -device 'pci-bridge,id=pci.4,chassis_nr=4,bus=pci.1,addr=0x1c' \ + -device 'piix3-usb-uhci,id=uhci,bus=pci.0,addr=0x1.0x2' \ + -device 'usb-tablet,id=tablet,bus=uhci.0,port=1' \ + -device 'VGA,id=vga,bus=pci.0,addr=0x2' \ + -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ + -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ + -device 'lsi53c810,id=scsihw0,bus=pci.0,addr=0x5' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"native","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-0","node-name":"e0378a375d635b0f473569544c7c207","read-only":false},"node-name":"f0378a375d635b0f473569544c7c207","read-only":false},"node-name":"drive-scsi0","read-only":false,"throttle-group":"throttle-drive-scsi0"}' \ + -device 'scsi-hd,bus=scsihw0.0,scsi-id=0,drive=drive-scsi0,id=scsi0,device_id=drive-scsi0,bootindex=100,write-cache=on' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"threads","cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-1","node-name":"e68a63e6c55e4a6fe8c847a8f60af7e","read-only":false},"node-name":"f68a63e6c55e4a6fe8c847a8f60af7e","read-only":false},"node-name":"drive-scsi1","read-only":false,"throttle-group":"throttle-drive-scsi1"}' \ + -device 'scsi-hd,bus=scsihw0.0,scsi-id=1,drive=drive-scsi1,id=scsi1,device_id=drive-scsi1,write-cache=on' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"threads","cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-2","node-name":"e02ef0cb3873a2ecfddb04f546b6b26","read-only":false},"node-name":"f02ef0cb3873a2ecfddb04f546b6b26","read-only":false},"node-name":"drive-scsi5","read-only":false,"throttle-group":"throttle-drive-scsi5"}' \ + -device 'scsi-hd,bus=scsihw0.0,scsi-id=5,drive=drive-scsi5,id=scsi5,device_id=drive-scsi5,write-cache=off' \ + -device 'lsi53c810,id=scsihw1,bus=pci.0,addr=0x6' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"native","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-3","node-name":"e77e7a9ba0adc041419f45894ffb1ed","read-only":false},"node-name":"f77e7a9ba0adc041419f45894ffb1ed","read-only":false},"node-name":"drive-scsi9","read-only":false,"throttle-group":"throttle-drive-scsi9"}' \ + -device 'scsi-hd,bus=scsihw1.0,scsi-id=2,drive=drive-scsi9,id=scsi9,device_id=drive-scsi9,write-cache=off' \ + -device 'lsi53c810,id=scsihw2,bus=pci.4,addr=0x1' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"native","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-4","node-name":"e86ac0b43c3f3cb5be16052b349a9b7","read-only":false},"node-name":"f86ac0b43c3f3cb5be16052b349a9b7","read-only":false},"node-name":"drive-scsi16","read-only":false,"throttle-group":"throttle-drive-scsi16"}' \ + -device 'scsi-hd,bus=scsihw2.0,scsi-id=2,drive=drive-scsi16,id=scsi16,device_id=drive-scsi16,write-cache=off' \ + -machine 'type=pc+pve0' diff --git a/src/test/cfg2cmd/scsihw-megasas.conf b/src/test/cfg2cmd/scsihw-megasas.conf new file mode 100644 index 00000000..eef7b827 --- /dev/null +++ b/src/test/cfg2cmd/scsihw-megasas.conf @@ -0,0 +1,9 @@ +# TEST: Simple test for MegaRAID SAS SCSI controller +bootdisk: scsi0 +name: simple +scsi0: lvm-store:vm-8006-disk-0,discard=on,size=104858K +scsi1: lvm-store:vm-8006-disk-1,cache=writeback,discard=on,size=104858K +scsi5: lvm-store:vm-8006-disk-2,cache=writethrough,discard=on,size=104858K +scsi9: lvm-store:vm-8006-disk-3,cache=directsync,discard=on,size=104858K +scsi16: lvm-store:vm-8006-disk-4,cache=directsync,discard=on,size=104858K +scsihw: megasas diff --git a/src/test/cfg2cmd/scsihw-megasas.conf.cmd b/src/test/cfg2cmd/scsihw-megasas.conf.cmd new file mode 100644 index 00000000..ab15c112 --- /dev/null +++ b/src/test/cfg2cmd/scsihw-megasas.conf.cmd @@ -0,0 +1,42 @@ +/usr/bin/kvm \ + -id 8006 \ + -name 'simple,debug-threads=on' \ + -no-shutdown \ + -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \ + -mon 'chardev=qmp,mode=control' \ + -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \ + -mon 'chardev=qmp-event,mode=control' \ + -pidfile /var/run/qemu-server/8006.pid \ + -daemonize \ + -smp '1,sockets=1,cores=1,maxcpus=1' \ + -nodefaults \ + -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ + -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ + -m 512 \ + -object '{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \ + -object '{"id":"throttle-drive-scsi1","limits":{},"qom-type":"throttle-group"}' \ + -object '{"id":"throttle-drive-scsi5","limits":{},"qom-type":"throttle-group"}' \ + -object '{"id":"throttle-drive-scsi9","limits":{},"qom-type":"throttle-group"}' \ + -object '{"id":"throttle-drive-scsi16","limits":{},"qom-type":"throttle-group"}' \ + -global 'PIIX4_PM.disable_s3=1' \ + -global 'PIIX4_PM.disable_s4=1' \ + -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ + -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \ + -device 'piix3-usb-uhci,id=uhci,bus=pci.0,addr=0x1.0x2' \ + -device 'usb-tablet,id=tablet,bus=uhci.0,port=1' \ + -device 'VGA,id=vga,bus=pci.0,addr=0x2' \ + -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ + -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ + -device 'megasas,id=scsihw0,bus=pci.0,addr=0x5' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"native","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-0","node-name":"e0378a375d635b0f473569544c7c207","read-only":false},"node-name":"f0378a375d635b0f473569544c7c207","read-only":false},"node-name":"drive-scsi0","read-only":false,"throttle-group":"throttle-drive-scsi0"}' \ + -device 'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,device_id=drive-scsi0,bootindex=100,write-cache=on' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"threads","cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-1","node-name":"e68a63e6c55e4a6fe8c847a8f60af7e","read-only":false},"node-name":"f68a63e6c55e4a6fe8c847a8f60af7e","read-only":false},"node-name":"drive-scsi1","read-only":false,"throttle-group":"throttle-drive-scsi1"}' \ + -device 'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=1,drive=drive-scsi1,id=scsi1,device_id=drive-scsi1,write-cache=on' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"threads","cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-2","node-name":"e02ef0cb3873a2ecfddb04f546b6b26","read-only":false},"node-name":"f02ef0cb3873a2ecfddb04f546b6b26","read-only":false},"node-name":"drive-scsi5","read-only":false,"throttle-group":"throttle-drive-scsi5"}' \ + -device 'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=5,drive=drive-scsi5,id=scsi5,device_id=drive-scsi5,write-cache=off' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"native","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-3","node-name":"e77e7a9ba0adc041419f45894ffb1ed","read-only":false},"node-name":"f77e7a9ba0adc041419f45894ffb1ed","read-only":false},"node-name":"drive-scsi9","read-only":false,"throttle-group":"throttle-drive-scsi9"}' \ + -device 'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=9,drive=drive-scsi9,id=scsi9,device_id=drive-scsi9,write-cache=off' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"native","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-4","node-name":"e86ac0b43c3f3cb5be16052b349a9b7","read-only":false},"node-name":"f86ac0b43c3f3cb5be16052b349a9b7","read-only":false},"node-name":"drive-scsi16","read-only":false,"throttle-group":"throttle-drive-scsi16"}' \ + -device 'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=16,drive=drive-scsi16,id=scsi16,device_id=drive-scsi16,write-cache=off' \ + -machine 'type=pc+pve0' diff --git a/src/test/cfg2cmd/scsihw-pvscsi.conf b/src/test/cfg2cmd/scsihw-pvscsi.conf new file mode 100644 index 00000000..16b13469 --- /dev/null +++ b/src/test/cfg2cmd/scsihw-pvscsi.conf @@ -0,0 +1,9 @@ +# TEST: Simple test for PVSCSI controller +bootdisk: scsi0 +name: simple +scsi0: lvm-store:vm-8006-disk-0,discard=on,size=104858K +scsi1: lvm-store:vm-8006-disk-1,cache=writeback,discard=on,size=104858K +scsi5: lvm-store:vm-8006-disk-2,cache=writethrough,discard=on,size=104858K +scsi9: lvm-store:vm-8006-disk-3,cache=directsync,discard=on,size=104858K +scsi16: lvm-store:vm-8006-disk-4,cache=directsync,discard=on,size=104858K +scsihw: pvscsi diff --git a/src/test/cfg2cmd/scsihw-pvscsi.conf.cmd b/src/test/cfg2cmd/scsihw-pvscsi.conf.cmd new file mode 100644 index 00000000..196683d3 --- /dev/null +++ b/src/test/cfg2cmd/scsihw-pvscsi.conf.cmd @@ -0,0 +1,42 @@ +/usr/bin/kvm \ + -id 8006 \ + -name 'simple,debug-threads=on' \ + -no-shutdown \ + -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \ + -mon 'chardev=qmp,mode=control' \ + -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \ + -mon 'chardev=qmp-event,mode=control' \ + -pidfile /var/run/qemu-server/8006.pid \ + -daemonize \ + -smp '1,sockets=1,cores=1,maxcpus=1' \ + -nodefaults \ + -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ + -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ + -m 512 \ + -object '{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \ + -object '{"id":"throttle-drive-scsi1","limits":{},"qom-type":"throttle-group"}' \ + -object '{"id":"throttle-drive-scsi5","limits":{},"qom-type":"throttle-group"}' \ + -object '{"id":"throttle-drive-scsi9","limits":{},"qom-type":"throttle-group"}' \ + -object '{"id":"throttle-drive-scsi16","limits":{},"qom-type":"throttle-group"}' \ + -global 'PIIX4_PM.disable_s3=1' \ + -global 'PIIX4_PM.disable_s4=1' \ + -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ + -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \ + -device 'piix3-usb-uhci,id=uhci,bus=pci.0,addr=0x1.0x2' \ + -device 'usb-tablet,id=tablet,bus=uhci.0,port=1' \ + -device 'VGA,id=vga,bus=pci.0,addr=0x2' \ + -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ + -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ + -device 'pvscsi,id=scsihw0,bus=pci.0,addr=0x5' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"native","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-0","node-name":"e0378a375d635b0f473569544c7c207","read-only":false},"node-name":"f0378a375d635b0f473569544c7c207","read-only":false},"node-name":"drive-scsi0","read-only":false,"throttle-group":"throttle-drive-scsi0"}' \ + -device 'scsi-hd,bus=scsihw0.0,scsi-id=0,drive=drive-scsi0,id=scsi0,device_id=drive-scsi0,bootindex=100,write-cache=on' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"threads","cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-1","node-name":"e68a63e6c55e4a6fe8c847a8f60af7e","read-only":false},"node-name":"f68a63e6c55e4a6fe8c847a8f60af7e","read-only":false},"node-name":"drive-scsi1","read-only":false,"throttle-group":"throttle-drive-scsi1"}' \ + -device 'scsi-hd,bus=scsihw0.0,scsi-id=1,drive=drive-scsi1,id=scsi1,device_id=drive-scsi1,write-cache=on' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"threads","cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-2","node-name":"e02ef0cb3873a2ecfddb04f546b6b26","read-only":false},"node-name":"f02ef0cb3873a2ecfddb04f546b6b26","read-only":false},"node-name":"drive-scsi5","read-only":false,"throttle-group":"throttle-drive-scsi5"}' \ + -device 'scsi-hd,bus=scsihw0.0,scsi-id=5,drive=drive-scsi5,id=scsi5,device_id=drive-scsi5,write-cache=off' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"native","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-3","node-name":"e77e7a9ba0adc041419f45894ffb1ed","read-only":false},"node-name":"f77e7a9ba0adc041419f45894ffb1ed","read-only":false},"node-name":"drive-scsi9","read-only":false,"throttle-group":"throttle-drive-scsi9"}' \ + -device 'scsi-hd,bus=scsihw0.0,scsi-id=9,drive=drive-scsi9,id=scsi9,device_id=drive-scsi9,write-cache=off' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"native","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-4","node-name":"e86ac0b43c3f3cb5be16052b349a9b7","read-only":false},"node-name":"f86ac0b43c3f3cb5be16052b349a9b7","read-only":false},"node-name":"drive-scsi16","read-only":false,"throttle-group":"throttle-drive-scsi16"}' \ + -device 'scsi-hd,bus=scsihw0.0,scsi-id=16,drive=drive-scsi16,id=scsi16,device_id=drive-scsi16,write-cache=off' \ + -machine 'type=pc+pve0' diff --git a/src/test/cfg2cmd/scsihw-virtio-scsi-single.conf b/src/test/cfg2cmd/scsihw-virtio-scsi-single.conf new file mode 100644 index 00000000..0f3d15be --- /dev/null +++ b/src/test/cfg2cmd/scsihw-virtio-scsi-single.conf @@ -0,0 +1,9 @@ +# TEST: Simple test for VirtIO SCSI single controller +bootdisk: scsi0 +name: simple +scsi0: lvm-store:vm-8006-disk-0,discard=on,size=104858K +scsi1: lvm-store:vm-8006-disk-1,cache=writeback,discard=on,size=104858K +scsi5: lvm-store:vm-8006-disk-2,cache=writethrough,discard=on,size=104858K +scsi9: lvm-store:vm-8006-disk-3,cache=directsync,discard=on,size=104858K +scsi16: lvm-store:vm-8006-disk-4,cache=directsync,discard=on,size=104858K +scsihw: virtio-scsi-single diff --git a/src/test/cfg2cmd/scsihw-virtio-scsi-single.conf.cmd b/src/test/cfg2cmd/scsihw-virtio-scsi-single.conf.cmd new file mode 100644 index 00000000..2541eb49 --- /dev/null +++ b/src/test/cfg2cmd/scsihw-virtio-scsi-single.conf.cmd @@ -0,0 +1,47 @@ +/usr/bin/kvm \ + -id 8006 \ + -name 'simple,debug-threads=on' \ + -no-shutdown \ + -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \ + -mon 'chardev=qmp,mode=control' \ + -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \ + -mon 'chardev=qmp-event,mode=control' \ + -pidfile /var/run/qemu-server/8006.pid \ + -daemonize \ + -smp '1,sockets=1,cores=1,maxcpus=1' \ + -nodefaults \ + -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ + -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ + -m 512 \ + -object '{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \ + -object '{"id":"throttle-drive-scsi1","limits":{},"qom-type":"throttle-group"}' \ + -object '{"id":"throttle-drive-scsi5","limits":{},"qom-type":"throttle-group"}' \ + -object '{"id":"throttle-drive-scsi9","limits":{},"qom-type":"throttle-group"}' \ + -object '{"id":"throttle-drive-scsi16","limits":{},"qom-type":"throttle-group"}' \ + -global 'PIIX4_PM.disable_s3=1' \ + -global 'PIIX4_PM.disable_s4=1' \ + -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ + -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \ + -device 'pci-bridge,id=pci.3,chassis_nr=3,bus=pci.0,addr=0x5' \ + -device 'piix3-usb-uhci,id=uhci,bus=pci.0,addr=0x1.0x2' \ + -device 'usb-tablet,id=tablet,bus=uhci.0,port=1' \ + -device 'VGA,id=vga,bus=pci.0,addr=0x2' \ + -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ + -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ + -device 'virtio-scsi-pci,id=virtioscsi0,bus=pci.3,addr=0x1' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"native","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-0","node-name":"e0378a375d635b0f473569544c7c207","read-only":false},"node-name":"f0378a375d635b0f473569544c7c207","read-only":false},"node-name":"drive-scsi0","read-only":false,"throttle-group":"throttle-drive-scsi0"}' \ + -device 'scsi-hd,bus=virtioscsi0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,device_id=drive-scsi0,bootindex=100,write-cache=on' \ + -device 'virtio-scsi-pci,id=virtioscsi1,bus=pci.3,addr=0x2' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"threads","cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-1","node-name":"e68a63e6c55e4a6fe8c847a8f60af7e","read-only":false},"node-name":"f68a63e6c55e4a6fe8c847a8f60af7e","read-only":false},"node-name":"drive-scsi1","read-only":false,"throttle-group":"throttle-drive-scsi1"}' \ + -device 'scsi-hd,bus=virtioscsi1.0,channel=0,scsi-id=0,lun=1,drive=drive-scsi1,id=scsi1,device_id=drive-scsi1,write-cache=on' \ + -device 'virtio-scsi-pci,id=virtioscsi5,bus=pci.3,addr=0x6' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"threads","cache":{"direct":false,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-2","node-name":"e02ef0cb3873a2ecfddb04f546b6b26","read-only":false},"node-name":"f02ef0cb3873a2ecfddb04f546b6b26","read-only":false},"node-name":"drive-scsi5","read-only":false,"throttle-group":"throttle-drive-scsi5"}' \ + -device 'scsi-hd,bus=virtioscsi5.0,channel=0,scsi-id=0,lun=5,drive=drive-scsi5,id=scsi5,device_id=drive-scsi5,write-cache=off' \ + -device 'virtio-scsi-pci,id=virtioscsi9,bus=pci.3,addr=0xa' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"native","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-3","node-name":"e77e7a9ba0adc041419f45894ffb1ed","read-only":false},"node-name":"f77e7a9ba0adc041419f45894ffb1ed","read-only":false},"node-name":"drive-scsi9","read-only":false,"throttle-group":"throttle-drive-scsi9"}' \ + -device 'scsi-hd,bus=virtioscsi9.0,channel=0,scsi-id=0,lun=9,drive=drive-scsi9,id=scsi9,device_id=drive-scsi9,write-cache=off' \ + -device 'virtio-scsi-pci,id=virtioscsi16,bus=pci.3,addr=0x11' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"native","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/veegee/vm-8006-disk-4","node-name":"e86ac0b43c3f3cb5be16052b349a9b7","read-only":false},"node-name":"f86ac0b43c3f3cb5be16052b349a9b7","read-only":false},"node-name":"drive-scsi16","read-only":false,"throttle-group":"throttle-drive-scsi16"}' \ + -device 'scsi-hd,bus=virtioscsi16.0,channel=0,scsi-id=0,lun=16,drive=drive-scsi16,id=scsi16,device_id=drive-scsi16,write-cache=off' \ + -machine 'type=pc+pve0' diff --git a/src/test/cfg2cmd/seabios_serial.conf.cmd b/src/test/cfg2cmd/seabios_serial.conf.cmd index 8fc0509b..e8c66c7b 100644 --- a/src/test/cfg2cmd/seabios_serial.conf.cmd +++ b/src/test/cfg2cmd/seabios_serial.conf.cmd @@ -31,5 +31,5 @@ -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"ecd04be4259153b8293415fefa2a84c","read-only":false},"node-name":"fcd04be4259153b8293415fefa2a84c","read-only":false},"node-name":"drive-scsi0","read-only":false,"throttle-group":"throttle-drive-scsi0"}' \ -device 'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,device_id=drive-scsi0,bootindex=100,write-cache=on' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ - -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300' \ - -machine 'smm=off,type=pc+pve0' + -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=1500' \ + -machine 'hpet=off,smm=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/simple-btrfs.conf.cmd b/src/test/cfg2cmd/simple-btrfs.conf.cmd index f80421ad..812ef7e8 100644 --- a/src/test/cfg2cmd/simple-btrfs.conf.cmd +++ b/src/test/cfg2cmd/simple-btrfs.conf.cmd @@ -40,5 +40,5 @@ -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/butter/bread/images/8006/vm-8006-disk-0/disk.raw","node-name":"e7487c01d831e2b51a5446980170ec9","read-only":false},"node-name":"f7487c01d831e2b51a5446980170ec9","read-only":false},"node-name":"drive-scsi3","read-only":false,"throttle-group":"throttle-drive-scsi3"}' \ -device 'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=3,drive=drive-scsi3,id=scsi3,device_id=drive-scsi3,write-cache=off' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ - -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300' \ - -machine 'type=pc+pve0' + -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=1500' \ + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/simple-cifs.conf.cmd b/src/test/cfg2cmd/simple-cifs.conf.cmd index 4174d061..9819d545 100644 --- a/src/test/cfg2cmd/simple-cifs.conf.cmd +++ b/src/test/cfg2cmd/simple-cifs.conf.cmd @@ -37,4 +37,4 @@ -device 'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=2,drive=drive-scsi2,id=scsi2,device_id=drive-scsi2,write-cache=off' \ -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"native","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/mnt/pve/cifs-store/images/8006/vm-8006-disk-0.raw","node-name":"e7042ee58e764b1296ad54014cb9a03","read-only":false},"node-name":"f7042ee58e764b1296ad54014cb9a03","read-only":false},"node-name":"drive-scsi3","read-only":false,"throttle-group":"throttle-drive-scsi3"}' \ -device 'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=3,drive=drive-scsi3,id=scsi3,device_id=drive-scsi3,write-cache=off' \ - -machine 'type=pc+pve0' + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/simple-disk-passthrough.conf.cmd b/src/test/cfg2cmd/simple-disk-passthrough.conf.cmd index 987a6c82..218db679 100644 --- a/src/test/cfg2cmd/simple-disk-passthrough.conf.cmd +++ b/src/test/cfg2cmd/simple-disk-passthrough.conf.cmd @@ -36,5 +36,5 @@ -blockdev '{"detect-zeroes":"on","discard":"ignore","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"on","discard":"ignore","driver":"raw","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"on","discard":"ignore","driver":"file","filename":"/mnt/file.raw","node-name":"e234a4e3b89ac3adac9bdbf0c3dd6b4","read-only":false},"node-name":"f234a4e3b89ac3adac9bdbf0c3dd6b4","read-only":false},"node-name":"drive-scsi1","read-only":false,"throttle-group":"throttle-drive-scsi1"}' \ -device 'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=1,drive=drive-scsi1,id=scsi1,device_id=drive-scsi1,write-cache=on' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ - -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300' \ - -machine 'type=pc+pve0' + -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=1500' \ + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/simple-rbd.conf.cmd b/src/test/cfg2cmd/simple-rbd.conf.cmd index b848672c..6730fcd0 100644 --- a/src/test/cfg2cmd/simple-rbd.conf.cmd +++ b/src/test/cfg2cmd/simple-rbd.conf.cmd @@ -52,5 +52,5 @@ -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"host_device","filename":"/dev/rbd-pve/fc4181a6-56eb-4f68-b452-8ba1f381ca2a/cpool/vm-8006-disk-0","node-name":"eb0b017124a47505c97a5da052e0141","read-only":false},"node-name":"fb0b017124a47505c97a5da052e0141","read-only":false},"node-name":"drive-scsi7","read-only":false,"throttle-group":"throttle-drive-scsi7"}' \ -device 'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=7,drive=drive-scsi7,id=scsi7,device_id=drive-scsi7,write-cache=off' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ - -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300' \ - -machine 'type=pc+pve0' + -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=1500' \ + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/simple-virtio-blk.conf.cmd b/src/test/cfg2cmd/simple-virtio-blk.conf.cmd index a9acb0cf..de193c5b 100644 --- a/src/test/cfg2cmd/simple-virtio-blk.conf.cmd +++ b/src/test/cfg2cmd/simple-virtio-blk.conf.cmd @@ -31,5 +31,5 @@ -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"edd19f6c1b3a6d5a6248c3376a91a16","read-only":false},"node-name":"fdd19f6c1b3a6d5a6248c3376a91a16","read-only":false},"node-name":"drive-virtio0","read-only":false,"throttle-group":"throttle-drive-virtio0"}' \ -device 'virtio-blk-pci,drive=drive-virtio0,id=virtio0,bus=pci.0,addr=0xa,iothread=iothread-virtio0,bootindex=100,write-cache=on' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ - -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300' \ - -machine 'type=pc+pve0' + -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=1500' \ + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/simple-zfs-over-iscsi.conf.cmd b/src/test/cfg2cmd/simple-zfs-over-iscsi.conf.cmd index 4fa6a5a9..302308b5 100644 --- a/src/test/cfg2cmd/simple-zfs-over-iscsi.conf.cmd +++ b/src/test/cfg2cmd/simple-zfs-over-iscsi.conf.cmd @@ -40,5 +40,5 @@ -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"raw","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"iscsi","lun":0,"node-name":"e915a332310039f7a3feed6901eb5da","portal":"127.0.0.1","read-only":false,"target":"iqn.2019-10.org.test:foobar","transport":"tcp"},"node-name":"f915a332310039f7a3feed6901eb5da","read-only":false},"node-name":"drive-scsi3","read-only":false,"throttle-group":"throttle-drive-scsi3"}' \ -device 'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=3,drive=drive-scsi3,id=scsi3,device_id=drive-scsi3,write-cache=off' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ - -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300' \ - -machine 'type=pc+pve0' + -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=1500' \ + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/simple1-template.conf.cmd b/src/test/cfg2cmd/simple1-template.conf.cmd index df51a4a5..369b4de9 100644 --- a/src/test/cfg2cmd/simple1-template.conf.cmd +++ b/src/test/cfg2cmd/simple1-template.conf.cmd @@ -30,7 +30,7 @@ -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/base-8006-disk-1.qcow2","node-name":"e1085774206ae4a6b6bf8426ff08f16","read-only":true},"node-name":"f1085774206ae4a6b6bf8426ff08f16","read-only":true},"node-name":"drive-scsi0","read-only":true,"throttle-group":"throttle-drive-scsi0"}' \ -device 'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,device_id=drive-scsi0,write-cache=on' \ -device 'ahci,id=ahci0,multifunction=on,bus=pci.0,addr=0x7' \ - -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/base-8006-disk-0.qcow2","node-name":"eab334c2e07734480f33dd80d89871b","read-only":false},"node-name":"fab334c2e07734480f33dd80d89871b","read-only":false},"node-name":"drive-sata0","read-only":false,"throttle-group":"throttle-drive-sata0"}' \ - -device 'ide-hd,bus=ahci0.0,drive=drive-sata0,id=sata0,write-cache=on' \ + -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/base-8006-disk-0.qcow2","node-name":"eab334c2e07734480f33dd80d89871b","read-only":true},"node-name":"fab334c2e07734480f33dd80d89871b","read-only":true},"node-name":"drive-sata0","read-only":true,"throttle-group":"throttle-drive-sata0"}' \ + -device 'ide-cd,bus=ahci0.0,drive=drive-sata0,id=sata0,write-cache=on' \ -machine 'accel=tcg,smm=off,type=pc+pve0' \ -snapshot diff --git a/src/test/cfg2cmd/simple1.conf.cmd b/src/test/cfg2cmd/simple1.conf.cmd index 49b848f2..e0954235 100644 --- a/src/test/cfg2cmd/simple1.conf.cmd +++ b/src/test/cfg2cmd/simple1.conf.cmd @@ -31,5 +31,5 @@ -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"ecd04be4259153b8293415fefa2a84c","read-only":false},"node-name":"fcd04be4259153b8293415fefa2a84c","read-only":false},"node-name":"drive-scsi0","read-only":false,"throttle-group":"throttle-drive-scsi0"}' \ -device 'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,device_id=drive-scsi0,bootindex=100,write-cache=on' \ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ - -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300' \ - -machine 'type=pc+pve0' + -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=1500' \ + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/startdate-l26.conf b/src/test/cfg2cmd/startdate-l26.conf new file mode 100644 index 00000000..eb35a971 --- /dev/null +++ b/src/test/cfg2cmd/startdate-l26.conf @@ -0,0 +1,3 @@ +# TEST: Simple test for startdate parameter with Linux +ostype: l26 +startdate: 2006-06-17T16:01:21 diff --git a/src/test/cfg2cmd/startdate-l26.conf.cmd b/src/test/cfg2cmd/startdate-l26.conf.cmd new file mode 100644 index 00000000..2d3f56e3 --- /dev/null +++ b/src/test/cfg2cmd/startdate-l26.conf.cmd @@ -0,0 +1,27 @@ +/usr/bin/kvm \ + -id 8006 \ + -name 'vm8006,debug-threads=on' \ + -no-shutdown \ + -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \ + -mon 'chardev=qmp,mode=control' \ + -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \ + -mon 'chardev=qmp-event,mode=control' \ + -pidfile /var/run/qemu-server/8006.pid \ + -daemonize \ + -smp '1,sockets=1,cores=1,maxcpus=1' \ + -nodefaults \ + -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ + -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ + -m 512 \ + -global 'PIIX4_PM.disable_s3=1' \ + -global 'PIIX4_PM.disable_s4=1' \ + -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ + -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \ + -device 'piix3-usb-uhci,id=uhci,bus=pci.0,addr=0x1.0x2' \ + -device 'usb-tablet,id=tablet,bus=uhci.0,port=1' \ + -device 'VGA,id=vga,bus=pci.0,addr=0x2' \ + -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ + -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ + -rtc 'base=2006-06-17T16:01:21' \ + -machine 'hpet=off,type=pc+pve0' diff --git a/src/test/cfg2cmd/startdate-win11.conf b/src/test/cfg2cmd/startdate-win11.conf new file mode 100644 index 00000000..ac5dcbcf --- /dev/null +++ b/src/test/cfg2cmd/startdate-win11.conf @@ -0,0 +1,4 @@ +# TEST: Simple test for startdate parameter with Windows and explicitly disabled time drift fix +ostype: win11 +tdf: 0 +startdate: 2020-01-11 diff --git a/src/test/cfg2cmd/startdate-win11.conf.cmd b/src/test/cfg2cmd/startdate-win11.conf.cmd new file mode 100644 index 00000000..a15dc213 --- /dev/null +++ b/src/test/cfg2cmd/startdate-win11.conf.cmd @@ -0,0 +1,26 @@ +/usr/bin/kvm \ + -id 8006 \ + -name 'vm8006,debug-threads=on' \ + -no-shutdown \ + -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \ + -mon 'chardev=qmp,mode=control' \ + -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \ + -mon 'chardev=qmp-event,mode=control' \ + -pidfile /var/run/qemu-server/8006.pid \ + -daemonize \ + -smp '1,sockets=1,cores=1,maxcpus=1' \ + -nodefaults \ + -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ + -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \ + -global 'kvm-pit.lost_tick_policy=discard' \ + -cpu 'kvm64,enforce,hv_ipi,hv_relaxed,hv_reset,hv_runtime,hv_spinlocks=0x1fff,hv_stimer,hv_synic,hv_time,hv_vapic,hv_vpindex,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep' \ + -m 512 \ + -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ + -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \ + -device 'piix3-usb-uhci,id=uhci,bus=pci.0,addr=0x1.0x2' \ + -device 'usb-tablet,id=tablet,bus=uhci.0,port=1' \ + -device 'VGA,id=vga,bus=pci.0,addr=0x2,edid=off' \ + -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3' \ + -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ + -rtc 'base=2020-01-11' \ + -machine 'hpet=off,type=pc-i440fx-5.1+pve0' diff --git a/src/usr/Makefile b/src/usr/Makefile index 321e44c4..1365544b 100644 --- a/src/usr/Makefile +++ b/src/usr/Makefile @@ -3,6 +3,8 @@ DESTDIR= PREFIX=/usr LIBDIR=$(DESTDIR)/$(PREFIX)/lib LIBEXECDIR=$(DESTDIR)/$(PREFIX)/libexec/$(PACKAGE) +LIBSYSTEMDDIR := $(DESTDIR)/usr/lib/systemd +DBUSDIR := $(DESTDIR)/usr/share/dbus-1 SHAREDIR=$(DESTDIR)/$(PREFIX)/share/$(PACKAGE) .PHONY: install @@ -17,6 +19,11 @@ install: pve-usb.cfg pve-q35.cfg pve-q35-4.0.cfg bootsplash.jpg modules-load.con install -m 0755 pve-bridge $(LIBEXECDIR)/pve-bridge install -m 0755 pve-bridge-hotplug $(LIBEXECDIR)/pve-bridge-hotplug install -m 0755 pve-bridgedown $(LIBEXECDIR)/pve-bridgedown + install -D -m 0755 dbus-vmstate $(LIBEXECDIR)/dbus-vmstate + install -d $(LIBSYSTEMDDIR) + install -D -m 0644 pve-dbus-vmstate@.service $(LIBSYSTEMDDIR)/system/pve-dbus-vmstate@.service + install -d $(DBUSDIR) + install -D -m 0644 org.qemu.VMState1.conf $(DBUSDIR)/system.d/org.qemu.VMState1.conf .PHONY: clean clean: diff --git a/src/dbus-vmstate/dbus-vmstate b/src/usr/dbus-vmstate similarity index 100% rename from src/dbus-vmstate/dbus-vmstate rename to src/usr/dbus-vmstate diff --git a/src/dbus-vmstate/org.qemu.VMState1.conf b/src/usr/org.qemu.VMState1.conf similarity index 100% rename from src/dbus-vmstate/org.qemu.VMState1.conf rename to src/usr/org.qemu.VMState1.conf diff --git a/src/dbus-vmstate/pve-dbus-vmstate@.service b/src/usr/pve-dbus-vmstate@.service similarity index 100% rename from src/dbus-vmstate/pve-dbus-vmstate@.service rename to src/usr/pve-dbus-vmstate@.service