public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH-SERIES qemu-server v2 0/4] virtio-net: fix migration between default/non-default MTUs, part one and two
@ 2025-09-03 14:22 Fiona Ebner
  2025-09-03 14:22 ` [pve-devel] [PATCH qemu-server v2 1/4] virtio-net: fix migration between default/non-default MTUs starting with machine version 10.0+pve1 Fiona Ebner
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Fiona Ebner @ 2025-09-03 14:22 UTC (permalink / raw)
  To: pve-devel

Changes in v2:
* push make tidy change already to master
* add part two - migration
* move version_guard() call to outside of print_netdevice_full() call
* add comment about why host_mtu is always set in source code

The virtual hardware is generated differently (at least for i440fx
machines) when host_mtu is set or not set on the netdev command line
[0]. When the MTU is the same value as the default 1500, Proxmox VE
did not add a host_mtu parameter. This is problematic for migration
where host_mtu is present on one end of the migration, but not on the
other [1].

Always set the host_mtu parameter starting with machine version
10.0+pve1 to avoid this issue going forward. For snapshots, the
nets-host-mtu information needs to be recorded in the snapshot config.
When the information is not present, and the machine version is
10.0+pve0, the Proxmox VE 9 behavior can be used. For other machine
versions we need to decide whether to use Proxmox VE 8 or Proxmox VE 9
behavior. The VM start parameter already provides an escape hatch in
any case. This will be the third an final part of these series.

Moreover, the effective setting in the guest (state) will
still be the host_mtu from the source side, even if a different value
is used for host_mtu on the target instance's commandline. This will
not lead to an error loading the migration stream in QEMU, but having
a larger host_mtu than the bridge MTU is still problematic for certain
network traffic like
> iperf3 -c 10.10.10.11 -u -l 2k
when host_mtu=9000 and bridge MTU=1500.

Add the necessary parameter for VM start and pass the values along for
migration to preserve the values going forward.

For Proxmox VE 8, add a dummy setting for VM start and also start
passing along the values.


Fiona Ebner (3):
  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
  migration: preserve host_mtu for virtio-net devices


stable-bookworm:

Fiona Ebner (1):
  migration: preserve host_mtu for virtio-net devices

 src/PVE/API2/Qemu.pm                          | 11 +++
 src/PVE/QemuMigrate.pm                        | 37 ++++++++++
 src/PVE/QemuServer.pm                         | 69 +++++++++++++++++--
 src/PVE/QemuServer/Machine.pm                 |  6 ++
 src/test/MigrationTest/QemuMigrateMock.pm     |  9 +++
 src/test/cfg2cmd/bootorder-empty.conf.cmd     |  4 +-
 src/test/cfg2cmd/bootorder-legacy.conf.cmd    |  4 +-
 src/test/cfg2cmd/bootorder.conf.cmd           |  4 +-
 src/test/cfg2cmd/efidisk-on-rbd.conf.cmd      |  4 +-
 src/test/cfg2cmd/ide.conf.cmd                 |  4 +-
 .../cfg2cmd/netdev-7.1-multiqueues.conf.cmd   |  2 +-
 src/test/cfg2cmd/netdev-7.1.conf.cmd          |  2 +-
 src/test/cfg2cmd/netdev_vxlan.conf.cmd        |  2 +-
 src/test/cfg2cmd/q35-ide.conf.cmd             |  4 +-
 .../q35-linux-hostpci-mapping.conf.cmd        |  4 +-
 .../q35-linux-hostpci-multifunction.conf.cmd  |  4 +-
 ...q35-linux-hostpci-x-pci-overrides.conf.cmd |  4 +-
 src/test/cfg2cmd/q35-linux-hostpci.conf.cmd   |  4 +-
 src/test/cfg2cmd/q35-simple.conf.cmd          |  4 +-
 src/test/cfg2cmd/seabios_serial.conf.cmd      |  4 +-
 src/test/cfg2cmd/simple-btrfs.conf.cmd        |  4 +-
 .../cfg2cmd/simple-disk-passthrough.conf.cmd  |  4 +-
 src/test/cfg2cmd/simple-rbd.conf.cmd          |  4 +-
 src/test/cfg2cmd/simple-virtio-blk.conf.cmd   |  4 +-
 .../cfg2cmd/simple-zfs-over-iscsi.conf.cmd    |  4 +-
 src/test/cfg2cmd/simple1.conf.cmd             |  4 +-
 26 files changed, 165 insertions(+), 45 deletions(-)

-- 
2.47.2



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [pve-devel] [PATCH qemu-server v2 1/4] virtio-net: fix migration between default/non-default MTUs starting with machine version 10.0+pve1
  2025-09-03 14:22 [pve-devel] [PATCH-SERIES qemu-server v2 0/4] virtio-net: fix migration between default/non-default MTUs, part one and two Fiona Ebner
@ 2025-09-03 14:22 ` Fiona Ebner
  2025-09-03 14:22 ` [pve-devel] [PATCH qemu-server v2 2/4] api: vm start: introduce nets-host-mtu parameter for migration compat Fiona Ebner
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 12+ messages in thread
From: Fiona Ebner @ 2025-09-03 14:22 UTC (permalink / raw)
  To: pve-devel

The virtual hardware is generated differently (at least for i440fx
machines) when host_mtu is set or not set on the netdev command line
[0]. When the MTU is the same value as the default 1500, Proxmox VE
did not add a host_mtu parameter. This is problematic for migration
where host_mtu is present on one end of the migration, but not on the
other [1].

Always set the host_mtu parameter starting with machine version
10.0+pve1 to avoid this issue going forward. Handling migrations with
older machine versions is more involved and will be done in separate
patches. Thanks to Stefan Hanreich and Fabian Grünbichler for
discussing this with me!

Since print_netdevice_full() is also called for hotplug, it cannot
always use the $version_guard helper and needs to fallback to
min_version() then.

[0]: https://bugzilla.redhat.com/show_bug.cgi?id=1449346
[1]: https://forum.proxmox.com/threads/live-vm-migration-fails.169537/post-796379

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---

Changes in v2:
* move version_guard() call to outside of print_netdevice_full() call
* add comment about why host_mtu is always set in source code

 src/PVE/QemuServer.pm                                  | 10 +++++++++-
 src/PVE/QemuServer/Machine.pm                          |  6 ++++++
 src/test/cfg2cmd/bootorder-empty.conf.cmd              |  4 ++--
 src/test/cfg2cmd/bootorder-legacy.conf.cmd             |  4 ++--
 src/test/cfg2cmd/bootorder.conf.cmd                    |  4 ++--
 src/test/cfg2cmd/efidisk-on-rbd.conf.cmd               |  4 ++--
 src/test/cfg2cmd/ide.conf.cmd                          |  4 ++--
 src/test/cfg2cmd/netdev-7.1-multiqueues.conf.cmd       |  2 +-
 src/test/cfg2cmd/netdev-7.1.conf.cmd                   |  2 +-
 src/test/cfg2cmd/netdev_vxlan.conf.cmd                 |  2 +-
 src/test/cfg2cmd/q35-ide.conf.cmd                      |  4 ++--
 src/test/cfg2cmd/q35-linux-hostpci-mapping.conf.cmd    |  4 ++--
 .../cfg2cmd/q35-linux-hostpci-multifunction.conf.cmd   |  4 ++--
 .../cfg2cmd/q35-linux-hostpci-x-pci-overrides.conf.cmd |  4 ++--
 src/test/cfg2cmd/q35-linux-hostpci.conf.cmd            |  4 ++--
 src/test/cfg2cmd/q35-simple.conf.cmd                   |  4 ++--
 src/test/cfg2cmd/seabios_serial.conf.cmd               |  4 ++--
 src/test/cfg2cmd/simple-btrfs.conf.cmd                 |  4 ++--
 src/test/cfg2cmd/simple-disk-passthrough.conf.cmd      |  4 ++--
 src/test/cfg2cmd/simple-rbd.conf.cmd                   |  4 ++--
 src/test/cfg2cmd/simple-virtio-blk.conf.cmd            |  4 ++--
 src/test/cfg2cmd/simple-zfs-over-iscsi.conf.cmd        |  4 ++--
 src/test/cfg2cmd/simple1.conf.cmd                      |  4 ++--
 23 files changed, 54 insertions(+), 40 deletions(-)

diff --git a/src/PVE/QemuServer.pm b/src/PVE/QemuServer.pm
index 38fa3f83..5b7087dc 100644
--- a/src/PVE/QemuServer.pm
+++ b/src/PVE/QemuServer.pm
@@ -1495,7 +1495,13 @@ sub print_netdevice_full {
             die "netdev $netid: MTU '$mtu' is bigger than the bridge MTU '$bridge_mtu'\n";
         }
 
-        $tmpstr .= ",host_mtu=$mtu" if $mtu != 1500;
+        if (min_version($machine_version, 10, 0, 1)) {
+            # 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";
@@ -3819,6 +3825,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,
diff --git a/src/PVE/QemuServer/Machine.pm b/src/PVE/QemuServer/Machine.pm
index 9d17344a..4c135a20 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 = {
diff --git a/src/test/cfg2cmd/bootorder-empty.conf.cmd b/src/test/cfg2cmd/bootorder-empty.conf.cmd
index 3516b344..af4a5ba6 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 'type=pc+pve1'
diff --git a/src/test/cfg2cmd/bootorder-legacy.conf.cmd b/src/test/cfg2cmd/bootorder-legacy.conf.cmd
index c86ab6f9..6b848a9b 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 'type=pc+pve1'
diff --git a/src/test/cfg2cmd/bootorder.conf.cmd b/src/test/cfg2cmd/bootorder.conf.cmd
index 48f9da8b..a3c6bd39 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 'type=pc+pve1'
diff --git a/src/test/cfg2cmd/efidisk-on-rbd.conf.cmd b/src/test/cfg2cmd/efidisk-on-rbd.conf.cmd
index 5d0c8aff..dda9d91b 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,type=pc+pve1'
diff --git a/src/test/cfg2cmd/ide.conf.cmd b/src/test/cfg2cmd/ide.conf.cmd
index 6b5a52a9..23282a18 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 'type=pc+pve1'
diff --git a/src/test/cfg2cmd/netdev-7.1-multiqueues.conf.cmd b/src/test/cfg2cmd/netdev-7.1-multiqueues.conf.cmd
index 776bab30..43e40742 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 'type=pc+pve1'
diff --git a/src/test/cfg2cmd/netdev-7.1.conf.cmd b/src/test/cfg2cmd/netdev-7.1.conf.cmd
index 0d6b3ad2..10404de4 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 'type=pc+pve1'
diff --git a/src/test/cfg2cmd/netdev_vxlan.conf.cmd b/src/test/cfg2cmd/netdev_vxlan.conf.cmd
index a2f3579d..7de574a7 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 'type=pc+pve1'
diff --git a/src/test/cfg2cmd/q35-ide.conf.cmd b/src/test/cfg2cmd/q35-ide.conf.cmd
index 475e58d9..9af48002 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 'type=q35+pve1'
diff --git a/src/test/cfg2cmd/q35-linux-hostpci-mapping.conf.cmd b/src/test/cfg2cmd/q35-linux-hostpci-mapping.conf.cmd
index b0c3e587..7413a651 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,type=q35+pve1'
diff --git a/src/test/cfg2cmd/q35-linux-hostpci-multifunction.conf.cmd b/src/test/cfg2cmd/q35-linux-hostpci-multifunction.conf.cmd
index b4aa46f5..f8435778 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,type=q35+pve1'
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..b314b8ad 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,type=q35+pve1'
diff --git a/src/test/cfg2cmd/q35-linux-hostpci.conf.cmd b/src/test/cfg2cmd/q35-linux-hostpci.conf.cmd
index 19e6ba3c..b6914255 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,type=q35+pve1'
diff --git a/src/test/cfg2cmd/q35-simple.conf.cmd b/src/test/cfg2cmd/q35-simple.conf.cmd
index e3f712c3..9cdb5bdb 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,type=q35+pve1'
diff --git a/src/test/cfg2cmd/seabios_serial.conf.cmd b/src/test/cfg2cmd/seabios_serial.conf.cmd
index 8fc0509b..ce2d7cf2 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 'smm=off,type=pc+pve1'
diff --git a/src/test/cfg2cmd/simple-btrfs.conf.cmd b/src/test/cfg2cmd/simple-btrfs.conf.cmd
index f80421ad..b73aae79 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 'type=pc+pve1'
diff --git a/src/test/cfg2cmd/simple-disk-passthrough.conf.cmd b/src/test/cfg2cmd/simple-disk-passthrough.conf.cmd
index 987a6c82..2b3a22e5 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 'type=pc+pve1'
diff --git a/src/test/cfg2cmd/simple-rbd.conf.cmd b/src/test/cfg2cmd/simple-rbd.conf.cmd
index b848672c..29dfaacc 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 'type=pc+pve1'
diff --git a/src/test/cfg2cmd/simple-virtio-blk.conf.cmd b/src/test/cfg2cmd/simple-virtio-blk.conf.cmd
index a9acb0cf..efec4a20 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 'type=pc+pve1'
diff --git a/src/test/cfg2cmd/simple-zfs-over-iscsi.conf.cmd b/src/test/cfg2cmd/simple-zfs-over-iscsi.conf.cmd
index 4fa6a5a9..21bfd638 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 'type=pc+pve1'
diff --git a/src/test/cfg2cmd/simple1.conf.cmd b/src/test/cfg2cmd/simple1.conf.cmd
index 49b848f2..eef2868b 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 'type=pc+pve1'
-- 
2.47.2



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [pve-devel] [PATCH qemu-server v2 2/4] api: vm start: introduce nets-host-mtu parameter for migration compat
  2025-09-03 14:22 [pve-devel] [PATCH-SERIES qemu-server v2 0/4] virtio-net: fix migration between default/non-default MTUs, part one and two Fiona Ebner
  2025-09-03 14:22 ` [pve-devel] [PATCH qemu-server v2 1/4] virtio-net: fix migration between default/non-default MTUs starting with machine version 10.0+pve1 Fiona Ebner
@ 2025-09-03 14:22 ` Fiona Ebner
  2025-09-04  9:11   ` Fabian Grünbichler
  2025-09-03 14:22 ` [pve-devel] [PATCH qemu-server v2 3/4] migration: preserve host_mtu for virtio-net devices Fiona Ebner
  2025-09-03 14:22 ` [pve-devel] [PATCH qemu-server v2 stable-bookworm 4/4] " Fiona Ebner
  3 siblings, 1 reply; 12+ messages in thread
From: Fiona Ebner @ 2025-09-03 14:22 UTC (permalink / raw)
  To: pve-devel

The virtual hardware is generated differently (at least for i440fx
machines) when host_mtu is set or not set on the netdev command line
[0]. When the MTU is the same value as the default 1500, Proxmox VE
did not add a host_mtu parameter. This is problematic for migration
where host_mtu is present on one end of the migration, but not on the
other [1]. Moreover, the effective setting in the guest (state) will
still be the host_mtu from the source side, even if a different value
is used for host_mtu on the target instance's commandline. This will
not lead to an error loading the migration stream in QEMU, but having
a larger host_mtu than the bridge MTU is still problematic for certain
network traffic like
> iperf3 -c 10.10.10.11 -u -l 2k
when host_mtu=9000 and bridge MTU=1500. Preventing migrations in this
case would be a breaking change, so for now, only a warning is added.

Add the necessary parameter for VM start to allow preserving the
values going forward.

[0]: https://bugzilla.redhat.com/show_bug.cgi?id=1449346
[1]: https://forum.proxmox.com/threads/live-vm-migration-fails.169537/post-796379

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
 src/PVE/API2/Qemu.pm  | 11 ++++++++
 src/PVE/QemuServer.pm | 61 ++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 66 insertions(+), 6 deletions(-)

diff --git a/src/PVE/API2/Qemu.pm b/src/PVE/API2/Qemu.pm
index b571e6c1..95db271b 100644
--- a/src/PVE/API2/Qemu.pm
+++ b/src/PVE/API2/Qemu.pm
@@ -3383,6 +3383,15 @@ __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.',
+            },
         },
     },
     returns => {
@@ -3414,6 +3423,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 +3511,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);
diff --git a/src/PVE/QemuServer.pm b/src/PVE/QemuServer.pm
index 5b7087dc..77b8e9c4 100644
--- a/src/PVE/QemuServer.pm
+++ b/src/PVE/QemuServer.pm
@@ -1457,7 +1457,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') {
@@ -1484,10 +1494,37 @@ sub print_netdevice_full {
 
     my $mtu = $net->{mtu};
 
-    if ($net->{model} eq 'virtio' && $net->{bridge}) {
+    if (defined($host_mtu_migration)) {
+        if ($host_mtu_migration) {
+            if (defined($mtu) && $mtu != 1) {
+                if ($mtu != $host_mtu_migration) {
+                    log_warn(
+                        "netdev $netid: using 'host_mtu=$host_mtu_migration' for migration compat,"
+                            . " but value different from value in configuration '$mtu'");
+                } # else avoid being overly verbose if there is an explicit setting
+            } else {
+                print "netdev $netid: using 'host_mtu=$host_mtu_migration' for migration compat\n";
+            }
+        } else {
+            print "netdev $netid: not adding 'host_mtu' parameter for migration compat\n";
+        }
+    }
+
+    if (
+        $net->{model} eq 'virtio'
+        && $net->{bridge}
+        && (!defined($host_mtu_migration) || $host_mtu_migration)
+    ) {
         my $bridge_mtu = PVE::Network::read_bridge_mtu($net->{bridge});
 
-        if (!defined($mtu) || $mtu == 1) {
+        if ($host_mtu_migration) {
+            $mtu = $host_mtu_migration;
+            # TODO PVE 10 - upgrade to failure? Certain network traffic can break like
+            # iperf3 -c 10.10.10.11 -u -l 2k when host_mtu=9000 and bridge MTU=1500
+            if ($mtu > $bridge_mtu) {
+                log_warn("netdev $netid: MTU '$mtu' is bigger than the bridge MTU '$bridge_mtu'");
+            }
+        } elsif (!defined($mtu) || $mtu == 1) {
             $mtu = $bridge_mtu;
         } elsif ($mtu < 576) {
             die "netdev $netid: MTU '$mtu' is smaller than the IP minimum MTU '576'\n";
@@ -1495,7 +1532,7 @@ sub print_netdevice_full {
             die "netdev $netid: MTU '$mtu' is bigger than the bridge MTU '$bridge_mtu'\n";
         }
 
-        if (min_version($machine_version, 10, 0, 1)) {
+        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";
@@ -1503,8 +1540,14 @@ sub print_netdevice_full {
             $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 (defined($host_mtu_migration) && !$host_mtu_migration) {
+            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) {
@@ -3810,6 +3853,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";
 
@@ -3836,6 +3881,7 @@ sub config_to_command {
             $use_old_bios_files,
             $arch,
             $machine_version,
+            $nets_host_mtu->{$netname},
         );
 
         push @$devices, '-device', $netdevicefull;
@@ -5566,6 +5612,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
@@ -5678,6 +5726,7 @@ sub vm_start_nolock {
                 'force-machine' => $forcemachine,
                 'force-cpu' => $forcecpu,
                 'live-restore-backing' => $params->{'live-restore-backing'},
+                'nets-host-mtu' => $params->{'nets-host-mtu'},
             },
         );
 
-- 
2.47.2



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [pve-devel] [PATCH qemu-server v2 3/4] migration: preserve host_mtu for virtio-net devices
  2025-09-03 14:22 [pve-devel] [PATCH-SERIES qemu-server v2 0/4] virtio-net: fix migration between default/non-default MTUs, part one and two Fiona Ebner
  2025-09-03 14:22 ` [pve-devel] [PATCH qemu-server v2 1/4] virtio-net: fix migration between default/non-default MTUs starting with machine version 10.0+pve1 Fiona Ebner
  2025-09-03 14:22 ` [pve-devel] [PATCH qemu-server v2 2/4] api: vm start: introduce nets-host-mtu parameter for migration compat Fiona Ebner
@ 2025-09-03 14:22 ` Fiona Ebner
  2025-09-03 14:22 ` [pve-devel] [PATCH qemu-server v2 stable-bookworm 4/4] " Fiona Ebner
  3 siblings, 0 replies; 12+ messages in thread
From: Fiona Ebner @ 2025-09-03 14:22 UTC (permalink / raw)
  To: pve-devel

The virtual hardware is generated differently (at least for i440fx
machines) when host_mtu is set or not set on the netdev command line
[0]. When the MTU is the same value as the default 1500, Proxmox VE
did not add a host_mtu parameter. This is problematic for migration
where host_mtu is present on one end of the migration, but not on the
other [1]. Moreover, the effective setting in the guest (state) will
still be the host_mtu from the source side, even if a different value
is used for host_mtu on the target instance's commandline. This will
not lead to an error loading the migration stream in QEMU, but having
a larger host_mtu than the bridge MTU is still problematic for certain
network traffic like
> iperf3 -c 10.10.10.11 -u -l 2k
when host_mtu=9000 and bridge MTU=1500.

Pass the values from the source to the target during migration to be
able to preserve them.

[0]: https://bugzilla.redhat.com/show_bug.cgi?id=1449346
[1]: https://forum.proxmox.com/threads/live-vm-migration-fails.169537/post-796379

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
 src/PVE/QemuMigrate.pm                    | 37 +++++++++++++++++++++++
 src/test/MigrationTest/QemuMigrateMock.pm |  9 ++++++
 2 files changed, 46 insertions(+)

diff --git a/src/PVE/QemuMigrate.pm b/src/PVE/QemuMigrate.pm
index e18cc2aa..a43bd615 100644
--- a/src/PVE/QemuMigrate.pm
+++ b/src/PVE/QemuMigrate.pm
@@ -175,6 +175,35 @@ sub target_storage_check_available {
     }
 }
 
+my sub get_nets_host_mtu {
+    my ($self, $vmid) = @_;
+
+    my $conf = $self->{vmconf};
+
+    my $nets_host_mtu = [];
+    for my $opt (sort keys $conf->%*) {
+        next if $opt !~ m/^net(\d+)$/;
+        my $net = PVE::QemuServer::Network::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 = $@) {
+            $self->log('warn', "$opt: could not query host_mtu - $err");
+        } elsif (defined($host_mtu)) {
+            push $nets_host_mtu->@*, "${opt}=${host_mtu}";
+        } else {
+            $self->log('warn', "$opt: got undefined value when querying host_mtu");
+        }
+    }
+    return join(',', $nets_host_mtu->@*);
+}
+
 sub prepare {
     my ($self, $vmid) = @_;
 
@@ -998,6 +1027,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');
     }
@@ -1187,6 +1220,10 @@ sub phase2 {
         },
     };
 
+    if (my $nets_host_mtu = get_nets_host_mtu($self, $vmid)) {
+        $params->{start_params}->{'nets-host-mtu'} = $nets_host_mtu;
+    }
+
     my ($tunnel_info, $spice_port);
 
     my @online_local_volumes = $self->filter_local_volumes('online');
diff --git a/src/test/MigrationTest/QemuMigrateMock.pm b/src/test/MigrationTest/QemuMigrateMock.pm
index b04cf78b..ca88d758 100644
--- a/src/test/MigrationTest/QemuMigrateMock.pm
+++ b/src/test/MigrationTest/QemuMigrateMock.pm
@@ -112,6 +112,15 @@ $qemu_migrate_module->mock(
             return;
         } elsif ($command eq 'migrate_cancel') {
             return;
+        } elsif ($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";
     },
-- 
2.47.2



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [pve-devel] [PATCH qemu-server v2 stable-bookworm 4/4] migration: preserve host_mtu for virtio-net devices
  2025-09-03 14:22 [pve-devel] [PATCH-SERIES qemu-server v2 0/4] virtio-net: fix migration between default/non-default MTUs, part one and two Fiona Ebner
                   ` (2 preceding siblings ...)
  2025-09-03 14:22 ` [pve-devel] [PATCH qemu-server v2 3/4] migration: preserve host_mtu for virtio-net devices Fiona Ebner
@ 2025-09-03 14:22 ` Fiona Ebner
  2025-09-04  9:11   ` Fabian Grünbichler
  3 siblings, 1 reply; 12+ messages in thread
From: Fiona Ebner @ 2025-09-03 14:22 UTC (permalink / raw)
  To: pve-devel

The virtual hardware is generated differently (at least for i440fx
machines) when host_mtu is set or not set on the netdev command line
[0]. When the MTU is the same value as the default 1500, Proxmox VE
did not add a host_mtu parameter. This is problematic for migration
where host_mtu is present on one end of the migration, but not on the
other [1]. Moreover, the effective setting in the guest (state) will
still be the host_mtu from the source side, even if a different value
is used for host_mtu on the target instance's commandline. This will
not lead to an error loading the migration stream in QEMU, but having
a larger host_mtu than the bridge MTU is still problematic for certain
network traffic like
> iperf3 -c 10.10.10.11 -u -l 2k
when host_mtu=9000 and bridge MTU=1500.

Pass the values from the source to the target during migration to be
able to preserve them.

While the setting only takes effect starting with Proxmox VE 9, it is
necessary to add a dummy parameter to the VM start API already in
Proxmox VE 8.

[0]: https://bugzilla.redhat.com/show_bug.cgi?id=1449346
[1]: https://forum.proxmox.com/threads/live-vm-migration-fails.169537/post-796379

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
 src/PVE/API2/Qemu.pm                      |  6 ++++
 src/PVE/QemuMigrate.pm                    | 37 +++++++++++++++++++++++
 src/test/MigrationTest/QemuMigrateMock.pm |  9 ++++++
 3 files changed, 52 insertions(+)

diff --git a/src/PVE/API2/Qemu.pm b/src/PVE/API2/Qemu.pm
index ce6f362d..d15dbc2e 100644
--- a/src/PVE/API2/Qemu.pm
+++ b/src/PVE/API2/Qemu.pm
@@ -3364,6 +3364,12 @@ __PACKAGE__->register_method({
                 default => 'max(30, vm memory in GiB)',
                 optional => 1,
             },
+            'nets-host-mtu' => {
+                type => 'string',
+                pattern => 'net\d+=\d+(,net\d+=\d+)*',
+                optional => 1,
+                description => "Compat only. Parameter is only used starting with Proxmox VE 9.",
+            },
         },
     },
     returns => {
diff --git a/src/PVE/QemuMigrate.pm b/src/PVE/QemuMigrate.pm
index 28d7ac56..f8237692 100644
--- a/src/PVE/QemuMigrate.pm
+++ b/src/PVE/QemuMigrate.pm
@@ -170,6 +170,35 @@ sub target_storage_check_available {
     }
 }
 
+my sub get_nets_host_mtu {
+    my ($self, $vmid) = @_;
+
+    my $conf = $self->{vmconf};
+
+    my $nets_host_mtu = [];
+    for my $opt (sort keys $conf->%*) {
+        next if $opt !~ m/^net(\d+)$/;
+        my $net = PVE::QemuServer::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 = $@) {
+            $self->log('warn', "$opt: could not query host_mtu - $err");
+        } elsif (defined($host_mtu)) {
+            push $nets_host_mtu->@*, "${opt}=${host_mtu}";
+        } else {
+            $self->log('warn', "$opt: got undefined value when querying host_mtu");
+        }
+    }
+    return join(',', $nets_host_mtu->@*);
+}
+
 sub prepare {
     my ($self, $vmid) = @_;
 
@@ -959,6 +988,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');
     }
@@ -1144,6 +1177,10 @@ sub phase2 {
         },
     };
 
+    if (my $nets_host_mtu = get_nets_host_mtu($self, $vmid)) {
+        $params->{start_params}->{'nets-host-mtu'} = $nets_host_mtu;
+    }
+
     my ($tunnel_info, $spice_port);
 
     my @online_local_volumes = $self->filter_local_volumes('online');
diff --git a/src/test/MigrationTest/QemuMigrateMock.pm b/src/test/MigrationTest/QemuMigrateMock.pm
index f678f9ec..18735ed6 100644
--- a/src/test/MigrationTest/QemuMigrateMock.pm
+++ b/src/test/MigrationTest/QemuMigrateMock.pm
@@ -111,6 +111,15 @@ $qemu_migrate_module->mock(
             return;
         } elsif ($command eq 'migrate_cancel') {
             return;
+        } elsif ($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";
     },
-- 
2.39.5



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [pve-devel] [PATCH qemu-server v2 2/4] api: vm start: introduce nets-host-mtu parameter for migration compat
  2025-09-03 14:22 ` [pve-devel] [PATCH qemu-server v2 2/4] api: vm start: introduce nets-host-mtu parameter for migration compat Fiona Ebner
@ 2025-09-04  9:11   ` Fabian Grünbichler
  2025-09-04  9:28     ` Fiona Ebner
  0 siblings, 1 reply; 12+ messages in thread
From: Fabian Grünbichler @ 2025-09-04  9:11 UTC (permalink / raw)
  To: Proxmox VE development discussion

On September 3, 2025 4:22 pm, Fiona Ebner wrote:
> The virtual hardware is generated differently (at least for i440fx
> machines) when host_mtu is set or not set on the netdev command line
> [0]. When the MTU is the same value as the default 1500, Proxmox VE
> did not add a host_mtu parameter. This is problematic for migration
> where host_mtu is present on one end of the migration, but not on the
> other [1]. Moreover, the effective setting in the guest (state) will
> still be the host_mtu from the source side, even if a different value
> is used for host_mtu on the target instance's commandline. This will
> not lead to an error loading the migration stream in QEMU, but having
> a larger host_mtu than the bridge MTU is still problematic for certain
> network traffic like
>> iperf3 -c 10.10.10.11 -u -l 2k
> when host_mtu=9000 and bridge MTU=1500. Preventing migrations in this
> case would be a breaking change, so for now, only a warning is added.
> 
> Add the necessary parameter for VM start to allow preserving the
> values going forward.
> 
> [0]: https://bugzilla.redhat.com/show_bug.cgi?id=1449346
> [1]: https://forum.proxmox.com/threads/live-vm-migration-fails.169537/post-796379
> 
> Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
> ---
>  src/PVE/API2/Qemu.pm  | 11 ++++++++
>  src/PVE/QemuServer.pm | 61 ++++++++++++++++++++++++++++++++++++++-----
>  2 files changed, 66 insertions(+), 6 deletions(-)
> 
> diff --git a/src/PVE/API2/Qemu.pm b/src/PVE/API2/Qemu.pm
> index b571e6c1..95db271b 100644
> --- a/src/PVE/API2/Qemu.pm
> +++ b/src/PVE/API2/Qemu.pm
> @@ -3383,6 +3383,15 @@ __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.',

should we note here as well that `0` means "explicitly don't set host_mtu"?

> +            },
>          },
>      },
>      returns => {
> @@ -3414,6 +3423,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 +3511,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);
> diff --git a/src/PVE/QemuServer.pm b/src/PVE/QemuServer.pm
> index 5b7087dc..77b8e9c4 100644
> --- a/src/PVE/QemuServer.pm
> +++ b/src/PVE/QemuServer.pm
> @@ -1457,7 +1457,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') {
> @@ -1484,10 +1494,37 @@ sub print_netdevice_full {
>  
>      my $mtu = $net->{mtu};
>  
> -    if ($net->{model} eq 'virtio' && $net->{bridge}) {
> +    if (defined($host_mtu_migration)) {
> +        if ($host_mtu_migration) {
> +            if (defined($mtu) && $mtu != 1) {
> +                if ($mtu != $host_mtu_migration) {
> +                    log_warn(
> +                        "netdev $netid: using 'host_mtu=$host_mtu_migration' for migration compat,"
> +                            . " but value different from value in configuration '$mtu'");
> +                } # else avoid being overly verbose if there is an explicit setting

can this happen in practice (without manually editing the config or
manual QMP commands)?

> +            } else {
> +                print "netdev $netid: using 'host_mtu=$host_mtu_migration' for migration compat\n";
> +            }
> +        } else {
> +            print "netdev $netid: not adding 'host_mtu' parameter for migration compat\n";
> +        }
> +    }

this if here

> +
> +    if (
> +        $net->{model} eq 'virtio'
> +        && $net->{bridge}
> +        && (!defined($host_mtu_migration) || $host_mtu_migration)
> +    ) {
>          my $bridge_mtu = PVE::Network::read_bridge_mtu($net->{bridge});
>  
> -        if (!defined($mtu) || $mtu == 1) {
> +        if ($host_mtu_migration) {

and this if here could be combined?

> +            $mtu = $host_mtu_migration;
> +            # TODO PVE 10 - upgrade to failure? Certain network traffic can break like
> +            # iperf3 -c 10.10.10.11 -u -l 2k when host_mtu=9000 and bridge MTU=1500
> +            if ($mtu > $bridge_mtu) {
> +                log_warn("netdev $netid: MTU '$mtu' is bigger than the bridge MTU '$bridge_mtu'");
> +            }
> +        } elsif (!defined($mtu) || $mtu == 1) {

this could still be an if, then the newly added warning above can be
dropped

>              $mtu = $bridge_mtu;
>          } elsif ($mtu < 576) {
>              die "netdev $netid: MTU '$mtu' is smaller than the IP minimum MTU '576'\n";
> @@ -1495,7 +1532,7 @@ sub print_netdevice_full {
>              die "netdev $netid: MTU '$mtu' is bigger than the bridge MTU '$bridge_mtu'\n";

since it is covered by this one here

>          }
>  
> -        if (min_version($machine_version, 10, 0, 1)) {
> +        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";
> @@ -1503,8 +1540,14 @@ sub print_netdevice_full {
>              $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 (defined($host_mtu_migration) && !$host_mtu_migration) {
> +            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) {
> @@ -3810,6 +3853,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";
>  
> @@ -3836,6 +3881,7 @@ sub config_to_command {
>              $use_old_bios_files,
>              $arch,
>              $machine_version,
> +            $nets_host_mtu->{$netname},
>          );
>  
>          push @$devices, '-device', $netdevicefull;
> @@ -5566,6 +5612,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
> @@ -5678,6 +5726,7 @@ sub vm_start_nolock {
>                  'force-machine' => $forcemachine,
>                  'force-cpu' => $forcecpu,
>                  'live-restore-backing' => $params->{'live-restore-backing'},
> +                'nets-host-mtu' => $params->{'nets-host-mtu'},
>              },
>          );
>  
> -- 
> 2.47.2
> 
> 
> 
> _______________________________________________
> pve-devel mailing list
> pve-devel@lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
> 
> 
> 


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [pve-devel] [PATCH qemu-server v2 stable-bookworm 4/4] migration: preserve host_mtu for virtio-net devices
  2025-09-03 14:22 ` [pve-devel] [PATCH qemu-server v2 stable-bookworm 4/4] " Fiona Ebner
@ 2025-09-04  9:11   ` Fabian Grünbichler
  2025-09-04  9:32     ` Fiona Ebner
  0 siblings, 1 reply; 12+ messages in thread
From: Fabian Grünbichler @ 2025-09-04  9:11 UTC (permalink / raw)
  To: Proxmox VE development discussion

On September 3, 2025 4:22 pm, Fiona Ebner wrote:
> The virtual hardware is generated differently (at least for i440fx
> machines) when host_mtu is set or not set on the netdev command line
> [0]. When the MTU is the same value as the default 1500, Proxmox VE
> did not add a host_mtu parameter. This is problematic for migration
> where host_mtu is present on one end of the migration, but not on the
> other [1]. Moreover, the effective setting in the guest (state) will
> still be the host_mtu from the source side, even if a different value
> is used for host_mtu on the target instance's commandline. This will
> not lead to an error loading the migration stream in QEMU, but having
> a larger host_mtu than the bridge MTU is still problematic for certain
> network traffic like
>> iperf3 -c 10.10.10.11 -u -l 2k
> when host_mtu=9000 and bridge MTU=1500.

since the effective actual MTU value is determined by the migration
state, this means 8->8 migrations potentially also break traffic:

VM config: mtu=1 (use bridge MTU)
source node: bridge MTU 9000
host_mtu for starting source VM: 9000

target node: bridge MTU 1500
host_mtu for starting target VM: 1500
effective MTU of the vNIC: 9000, because that's what the source VM's
migration stream tells the target OS?

right? so it might make sense to still detect and handle this also on
8.x? can be done as a follow-up of course..

> 
> Pass the values from the source to the target during migration to be
> able to preserve them.
> 
> While the setting only takes effect starting with Proxmox VE 9, it is
> necessary to add a dummy parameter to the VM start API already in
> Proxmox VE 8.
> 
> [0]: https://bugzilla.redhat.com/show_bug.cgi?id=1449346
> [1]: https://forum.proxmox.com/threads/live-vm-migration-fails.169537/post-796379
> 
> Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
> ---
>  src/PVE/API2/Qemu.pm                      |  6 ++++
>  src/PVE/QemuMigrate.pm                    | 37 +++++++++++++++++++++++
>  src/test/MigrationTest/QemuMigrateMock.pm |  9 ++++++
>  3 files changed, 52 insertions(+)
> 
> diff --git a/src/PVE/API2/Qemu.pm b/src/PVE/API2/Qemu.pm
> index ce6f362d..d15dbc2e 100644
> --- a/src/PVE/API2/Qemu.pm
> +++ b/src/PVE/API2/Qemu.pm
> @@ -3364,6 +3364,12 @@ __PACKAGE__->register_method({
>                  default => 'max(30, vm memory in GiB)',
>                  optional => 1,
>              },
> +            'nets-host-mtu' => {
> +                type => 'string',
> +                pattern => 'net\d+=\d+(,net\d+=\d+)*',
> +                optional => 1,
> +                description => "Compat only. Parameter is only used starting with Proxmox VE 9.",
> +            },
>          },
>      },
>      returns => {
> diff --git a/src/PVE/QemuMigrate.pm b/src/PVE/QemuMigrate.pm
> index 28d7ac56..f8237692 100644
> --- a/src/PVE/QemuMigrate.pm
> +++ b/src/PVE/QemuMigrate.pm
> @@ -170,6 +170,35 @@ sub target_storage_check_available {
>      }
>  }
>  
> +my sub get_nets_host_mtu {
> +    my ($self, $vmid) = @_;
> +
> +    my $conf = $self->{vmconf};
> +
> +    my $nets_host_mtu = [];
> +    for my $opt (sort keys $conf->%*) {
> +        next if $opt !~ m/^net(\d+)$/;
> +        my $net = PVE::QemuServer::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 = $@) {
> +            $self->log('warn', "$opt: could not query host_mtu - $err");
> +        } elsif (defined($host_mtu)) {
> +            push $nets_host_mtu->@*, "${opt}=${host_mtu}";
> +        } else {
> +            $self->log('warn', "$opt: got undefined value when querying host_mtu");
> +        }
> +    }
> +    return join(',', $nets_host_mtu->@*);
> +}
> +
>  sub prepare {
>      my ($self, $vmid) = @_;
>  
> @@ -959,6 +988,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');
>      }
> @@ -1144,6 +1177,10 @@ sub phase2 {
>          },
>      };
>  
> +    if (my $nets_host_mtu = get_nets_host_mtu($self, $vmid)) {
> +        $params->{start_params}->{'nets-host-mtu'} = $nets_host_mtu;
> +    }
> +
>      my ($tunnel_info, $spice_port);
>  
>      my @online_local_volumes = $self->filter_local_volumes('online');
> diff --git a/src/test/MigrationTest/QemuMigrateMock.pm b/src/test/MigrationTest/QemuMigrateMock.pm
> index f678f9ec..18735ed6 100644
> --- a/src/test/MigrationTest/QemuMigrateMock.pm
> +++ b/src/test/MigrationTest/QemuMigrateMock.pm
> @@ -111,6 +111,15 @@ $qemu_migrate_module->mock(
>              return;
>          } elsif ($command eq 'migrate_cancel') {
>              return;
> +        } elsif ($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";
>      },
> -- 
> 2.39.5
> 
> 
> 
> _______________________________________________
> pve-devel mailing list
> pve-devel@lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
> 
> 
> 


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [pve-devel] [PATCH qemu-server v2 2/4] api: vm start: introduce nets-host-mtu parameter for migration compat
  2025-09-04  9:11   ` Fabian Grünbichler
@ 2025-09-04  9:28     ` Fiona Ebner
  2025-09-04  9:52       ` Fabian Grünbichler
  2025-09-04  9:55       ` Fiona Ebner
  0 siblings, 2 replies; 12+ messages in thread
From: Fiona Ebner @ 2025-09-04  9:28 UTC (permalink / raw)
  To: Proxmox VE development discussion, Fabian Grünbichler

Am 04.09.25 um 11:11 AM schrieb Fabian Grünbichler:
> On September 3, 2025 4:22 pm, Fiona Ebner wrote:
>> diff --git a/src/PVE/API2/Qemu.pm b/src/PVE/API2/Qemu.pm
>> index b571e6c1..95db271b 100644
>> --- a/src/PVE/API2/Qemu.pm
>> +++ b/src/PVE/API2/Qemu.pm
>> @@ -3383,6 +3383,15 @@ __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.',
> 
> should we note here as well that `0` means "explicitly don't set host_mtu"?

Will add that.

>> @@ -1484,10 +1494,37 @@ sub print_netdevice_full {
>>  
>>      my $mtu = $net->{mtu};
>>  
>> -    if ($net->{model} eq 'virtio' && $net->{bridge}) {
>> +    if (defined($host_mtu_migration)) {
>> +        if ($host_mtu_migration) {
>> +            if (defined($mtu) && $mtu != 1) {
>> +                if ($mtu != $host_mtu_migration) {
>> +                    log_warn(
>> +                        "netdev $netid: using 'host_mtu=$host_mtu_migration' for migration compat,"
>> +                            . " but value different from value in configuration '$mtu'");
>> +                } # else avoid being overly verbose if there is an explicit setting
> 
> can this happen in practice (without manually editing the config or
> manual QMP commands)?

I don't think so. But since we have the info, I though it'd be good to
warn about it.

> 
>> +            } else {
>> +                print "netdev $netid: using 'host_mtu=$host_mtu_migration' for migration compat\n";
>> +            }
>> +        } else {
>> +            print "netdev $netid: not adding 'host_mtu' parameter for migration compat\n";
>> +        }
>> +    }
> 
> this if here
> 
>> +
>> +    if (
>> +        $net->{model} eq 'virtio'
>> +        && $net->{bridge}
>> +        && (!defined($host_mtu_migration) || $host_mtu_migration)
>> +    ) {
>>          my $bridge_mtu = PVE::Network::read_bridge_mtu($net->{bridge});
>>  
>> -        if (!defined($mtu) || $mtu == 1) {
>> +        if ($host_mtu_migration) {
> 
> and this if here could be combined?

How? You mean setting $mtu = $host_mtu_migration; early if there is a
non-zero value?

> 
>> +            $mtu = $host_mtu_migration;
>> +            # TODO PVE 10 - upgrade to failure? Certain network traffic can break like
>> +            # iperf3 -c 10.10.10.11 -u -l 2k when host_mtu=9000 and bridge MTU=1500
>> +            if ($mtu > $bridge_mtu) {
>> +                log_warn("netdev $netid: MTU '$mtu' is bigger than the bridge MTU '$bridge_mtu'");
>> +            }
>> +        } elsif (!defined($mtu) || $mtu == 1) {
> 
> this could still be an if, then the newly added warning above can be
> dropped
> 
>>              $mtu = $bridge_mtu;
>>          } elsif ($mtu < 576) {
>>              die "netdev $netid: MTU '$mtu' is smaller than the IP minimum MTU '576'\n";
>> @@ -1495,7 +1532,7 @@ sub print_netdevice_full {
>>              die "netdev $netid: MTU '$mtu' is bigger than the bridge MTU '$bridge_mtu'\n";
> 
> since it is covered by this one here

If we want to go for early failure when host_mtu > bridge MTU then yes.
Because this is die, the above is warn ;) Doing that is fine by me, but
I wanted to propose the non-breaking option first. If we consider that
it's problematic in more cases than not, then I'll go for early failure.
And maybe I'll add a little more context to the error message (at least
when it happens for migration).


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [pve-devel] [PATCH qemu-server v2 stable-bookworm 4/4] migration: preserve host_mtu for virtio-net devices
  2025-09-04  9:11   ` Fabian Grünbichler
@ 2025-09-04  9:32     ` Fiona Ebner
  0 siblings, 0 replies; 12+ messages in thread
From: Fiona Ebner @ 2025-09-04  9:32 UTC (permalink / raw)
  To: Proxmox VE development discussion, Fabian Grünbichler

Am 04.09.25 um 11:11 AM schrieb Fabian Grünbichler:
> On September 3, 2025 4:22 pm, Fiona Ebner wrote:
>> The virtual hardware is generated differently (at least for i440fx
>> machines) when host_mtu is set or not set on the netdev command line
>> [0]. When the MTU is the same value as the default 1500, Proxmox VE
>> did not add a host_mtu parameter. This is problematic for migration
>> where host_mtu is present on one end of the migration, but not on the
>> other [1]. Moreover, the effective setting in the guest (state) will
>> still be the host_mtu from the source side, even if a different value
>> is used for host_mtu on the target instance's commandline. This will
>> not lead to an error loading the migration stream in QEMU, but having
>> a larger host_mtu than the bridge MTU is still problematic for certain
>> network traffic like
>>> iperf3 -c 10.10.10.11 -u -l 2k
>> when host_mtu=9000 and bridge MTU=1500.
> 
> since the effective actual MTU value is determined by the migration
> state, this means 8->8 migrations potentially also break traffic:
> 
> VM config: mtu=1 (use bridge MTU)
> source node: bridge MTU 9000
> host_mtu for starting source VM: 9000
> 
> target node: bridge MTU 1500
> host_mtu for starting target VM: 1500
> effective MTU of the vNIC: 9000, because that's what the source VM's
> migration stream tells the target OS?
> 
> right? so it might make sense to still detect and handle this also on
> 8.x? can be done as a follow-up of course..

Yes, we can also backport "api: vm start: introduce nets-host-mtu
parameter for migration compat" too :)


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [pve-devel] [PATCH qemu-server v2 2/4] api: vm start: introduce nets-host-mtu parameter for migration compat
  2025-09-04  9:28     ` Fiona Ebner
@ 2025-09-04  9:52       ` Fabian Grünbichler
  2025-09-04 10:03         ` Fiona Ebner
  2025-09-04  9:55       ` Fiona Ebner
  1 sibling, 1 reply; 12+ messages in thread
From: Fabian Grünbichler @ 2025-09-04  9:52 UTC (permalink / raw)
  To: Fiona Ebner, Proxmox VE development discussion

On September 4, 2025 11:28 am, Fiona Ebner wrote:
> Am 04.09.25 um 11:11 AM schrieb Fabian Grünbichler:
>> On September 3, 2025 4:22 pm, Fiona Ebner wrote:
>>> diff --git a/src/PVE/API2/Qemu.pm b/src/PVE/API2/Qemu.pm
>>> index b571e6c1..95db271b 100644
>>> --- a/src/PVE/API2/Qemu.pm
>>> +++ b/src/PVE/API2/Qemu.pm
>>> @@ -1484,10 +1494,37 @@ sub print_netdevice_full {
>>>  
>>>      my $mtu = $net->{mtu};
>>>  
>>> -    if ($net->{model} eq 'virtio' && $net->{bridge}) {
>>> +    if (defined($host_mtu_migration)) {
>>> +        if ($host_mtu_migration) {
>>> +            if (defined($mtu) && $mtu != 1) {
>>> +                if ($mtu != $host_mtu_migration) {
>>> +                    log_warn(
>>> +                        "netdev $netid: using 'host_mtu=$host_mtu_migration' for migration compat,"
>>> +                            . " but value different from value in configuration '$mtu'");
>>> +                } # else avoid being overly verbose if there is an explicit setting
>> 
>> can this happen in practice (without manually editing the config or
>> manual QMP commands)?
> 
> I don't think so. But since we have the info, I though it'd be good to
> warn about it.
> 

I just figured it makes the code harder to parse ;)

>> 
>>> +            } else {
>>> +                print "netdev $netid: using 'host_mtu=$host_mtu_migration' for migration compat\n";
>>> +            }
>>> +        } else {
>>> +            print "netdev $netid: not adding 'host_mtu' parameter for migration compat\n";
>>> +        }
>>> +    }
>> 
>> this if here
>> 
>>> +
>>> +    if (
>>> +        $net->{model} eq 'virtio'
>>> +        && $net->{bridge}
>>> +        && (!defined($host_mtu_migration) || $host_mtu_migration)
>>> +    ) {
>>>          my $bridge_mtu = PVE::Network::read_bridge_mtu($net->{bridge});
>>>  
>>> -        if (!defined($mtu) || $mtu == 1) {
>>> +        if ($host_mtu_migration) {
>> 
>> and this if here could be combined?
> 
> How? You mean setting $mtu = $host_mtu_migration; early if there is a
> non-zero value?

something like this (untested):

----8<----
diff --git a/src/PVE/QemuServer.pm b/src/PVE/QemuServer.pm
index 77b8e9c4..a76a134a 100644
--- a/src/PVE/QemuServer.pm
+++ b/src/PVE/QemuServer.pm
@@ -1494,7 +1494,13 @@ sub print_netdevice_full {
 
     my $mtu = $net->{mtu};
 
-    if (defined($host_mtu_migration)) {
+    if (
+        $net->{model} eq 'virtio'
+        && $net->{bridge}
+        && (!defined($host_mtu_migration) || $host_mtu_migration)
+    ) {
+        my $bridge_mtu = PVE::Network::read_bridge_mtu($net->{bridge});
+
         if ($host_mtu_migration) {
             if (defined($mtu) && $mtu != 1) {
                 if ($mtu != $host_mtu_migration) {
@@ -1505,26 +1511,10 @@ sub print_netdevice_full {
             } else {
                 print "netdev $netid: using 'host_mtu=$host_mtu_migration' for migration compat\n";
             }
-        } else {
-            print "netdev $netid: not adding 'host_mtu' parameter for migration compat\n";
-        }
-    }
-
-    if (
-        $net->{model} eq 'virtio'
-        && $net->{bridge}
-        && (!defined($host_mtu_migration) || $host_mtu_migration)
-    ) {
-        my $bridge_mtu = PVE::Network::read_bridge_mtu($net->{bridge});
-
-        if ($host_mtu_migration) {
             $mtu = $host_mtu_migration;
-            # TODO PVE 10 - upgrade to failure? Certain network traffic can break like
-            # iperf3 -c 10.10.10.11 -u -l 2k when host_mtu=9000 and bridge MTU=1500
-            if ($mtu > $bridge_mtu) {
-                log_warn("netdev $netid: MTU '$mtu' is bigger than the bridge MTU '$bridge_mtu'");
-            }
-        } elsif (!defined($mtu) || $mtu == 1) {
+        }
+
+        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";
---->8----

I dropped the log statement about host_mtu_migration being an explicit
zero, since that is logged further below already if $mtu is defined, but
it could of course be added back there also for the $mtu == undef case
with a final

} elsif (defined($host_mtu_migration) && $host_mtu_migration == 0) {
    log_warn(..);
}

> 
>> 
>>> +            $mtu = $host_mtu_migration;
>>> +            # TODO PVE 10 - upgrade to failure? Certain network traffic can break like
>>> +            # iperf3 -c 10.10.10.11 -u -l 2k when host_mtu=9000 and bridge MTU=1500
>>> +            if ($mtu > $bridge_mtu) {
>>> +                log_warn("netdev $netid: MTU '$mtu' is bigger than the bridge MTU '$bridge_mtu'");
>>> +            }
>>> +        } elsif (!defined($mtu) || $mtu == 1) {
>> 
>> this could still be an if, then the newly added warning above can be
>> dropped
>> 
>>>              $mtu = $bridge_mtu;
>>>          } elsif ($mtu < 576) {
>>>              die "netdev $netid: MTU '$mtu' is smaller than the IP minimum MTU '576'\n";
>>> @@ -1495,7 +1532,7 @@ sub print_netdevice_full {
>>>              die "netdev $netid: MTU '$mtu' is bigger than the bridge MTU '$bridge_mtu'\n";
>> 
>> since it is covered by this one here
> 
> If we want to go for early failure when host_mtu > bridge MTU then yes.
> Because this is die, the above is warn ;) Doing that is fine by me, but
> I wanted to propose the non-breaking option first. If we consider that
> it's problematic in more cases than not, then I'll go for early failure.
> And maybe I'll add a little more context to the error message (at least
> when it happens for migration).

could still handle it in one place, and warn if $host_mtu_migration
(either inline, or via an elsif coming first that compares
$host_mtu_migration to $bridge_mtu), die otherwise - but I think if we
die on this condition when starting, then making it fatal for migration
starts might make sense as well, since the die would happen early on (so
no harm done).. might want to add a warning in that case as well that
tells the user what to do to make the VM migrateable though?


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [pve-devel] [PATCH qemu-server v2 2/4] api: vm start: introduce nets-host-mtu parameter for migration compat
  2025-09-04  9:28     ` Fiona Ebner
  2025-09-04  9:52       ` Fabian Grünbichler
@ 2025-09-04  9:55       ` Fiona Ebner
  1 sibling, 0 replies; 12+ messages in thread
From: Fiona Ebner @ 2025-09-04  9:55 UTC (permalink / raw)
  To: Proxmox VE development discussion, Fabian Grünbichler

Am 04.09.25 um 11:28 AM schrieb Fiona Ebner:
> Am 04.09.25 um 11:11 AM schrieb Fabian Grünbichler:
>> On September 3, 2025 4:22 pm, Fiona Ebner wrote:
>>> @@ -1484,10 +1494,37 @@ sub print_netdevice_full {
>>>  
>>>      my $mtu = $net->{mtu};
>>>  
>>> -    if ($net->{model} eq 'virtio' && $net->{bridge}) {
>>> +    if (defined($host_mtu_migration)) {
>>> +        if ($host_mtu_migration) {
>>> +            if (defined($mtu) && $mtu != 1) {
>>> +                if ($mtu != $host_mtu_migration) {
>>> +                    log_warn(
>>> +                        "netdev $netid: using 'host_mtu=$host_mtu_migration' for migration compat,"
>>> +                            . " but value different from value in configuration '$mtu'");
>>> +                } # else avoid being overly verbose if there is an explicit setting
>>
>> can this happen in practice (without manually editing the config or
>> manual QMP commands)?
> 
> I don't think so. But since we have the info, I though it'd be good to
> warn about it.
> 
>>
>>> +            } else {
>>> +                print "netdev $netid: using 'host_mtu=$host_mtu_migration' for migration compat\n";
>>> +            }
>>> +        } else {
>>> +            print "netdev $netid: not adding 'host_mtu' parameter for migration compat\n";
>>> +        }
>>> +    }
>>
>> this if here

Oh, I suppose you mean the 'if' further above, not the one right below?
I had that at first, but decided to split out printing the messages to
avoid cluttering the code below.

>>
>>> +
>>> +    if (
>>> +        $net->{model} eq 'virtio'
>>> +        && $net->{bridge}
>>> +        && (!defined($host_mtu_migration) || $host_mtu_migration)
>>> +    ) {
>>>          my $bridge_mtu = PVE::Network::read_bridge_mtu($net->{bridge});
>>>  
>>> -        if (!defined($mtu) || $mtu == 1) {
>>> +        if ($host_mtu_migration) {
>>
>> and this if here could be combined?
> 
> How? You mean setting $mtu = $host_mtu_migration; early if there is a
> non-zero value?


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [pve-devel] [PATCH qemu-server v2 2/4] api: vm start: introduce nets-host-mtu parameter for migration compat
  2025-09-04  9:52       ` Fabian Grünbichler
@ 2025-09-04 10:03         ` Fiona Ebner
  0 siblings, 0 replies; 12+ messages in thread
From: Fiona Ebner @ 2025-09-04 10:03 UTC (permalink / raw)
  To: Fabian Grünbichler, Proxmox VE development discussion

Am 04.09.25 um 11:52 AM schrieb Fabian Grünbichler:
> On September 4, 2025 11:28 am, Fiona Ebner wrote:
>> Am 04.09.25 um 11:11 AM schrieb Fabian Grünbichler:
>>> On September 3, 2025 4:22 pm, Fiona Ebner wrote:
>>>> diff --git a/src/PVE/API2/Qemu.pm b/src/PVE/API2/Qemu.pm
>>>> index b571e6c1..95db271b 100644
>>>> --- a/src/PVE/API2/Qemu.pm
>>>> +++ b/src/PVE/API2/Qemu.pm
>>>> @@ -1484,10 +1494,37 @@ sub print_netdevice_full {
>>>>  
>>>>      my $mtu = $net->{mtu};
>>>>  
>>>> -    if ($net->{model} eq 'virtio' && $net->{bridge}) {
>>>> +    if (defined($host_mtu_migration)) {
>>>> +        if ($host_mtu_migration) {
>>>> +            if (defined($mtu) && $mtu != 1) {
>>>> +                if ($mtu != $host_mtu_migration) {
>>>> +                    log_warn(
>>>> +                        "netdev $netid: using 'host_mtu=$host_mtu_migration' for migration compat,"
>>>> +                            . " but value different from value in configuration '$mtu'");
>>>> +                } # else avoid being overly verbose if there is an explicit setting
>>>
>>> can this happen in practice (without manually editing the config or
>>> manual QMP commands)?
>>
>> I don't think so. But since we have the info, I though it'd be good to
>> warn about it.
>>
> 
> I just figured it makes the code harder to parse ;)

Ack, yes, I guess it's not really that important.

>>>
>>>> +            } else {
>>>> +                print "netdev $netid: using 'host_mtu=$host_mtu_migration' for migration compat\n";
>>>> +            }
>>>> +        } else {
>>>> +            print "netdev $netid: not adding 'host_mtu' parameter for migration compat\n";
>>>> +        }
>>>> +    }
>>>
>>> this if here
>>>
>>>> +
>>>> +    if (
>>>> +        $net->{model} eq 'virtio'
>>>> +        && $net->{bridge}
>>>> +        && (!defined($host_mtu_migration) || $host_mtu_migration)
>>>> +    ) {
>>>>          my $bridge_mtu = PVE::Network::read_bridge_mtu($net->{bridge});
>>>>  
>>>> -        if (!defined($mtu) || $mtu == 1) {
>>>> +        if ($host_mtu_migration) {
>>>
>>> and this if here could be combined?
>>
>> How? You mean setting $mtu = $host_mtu_migration; early if there is a
>> non-zero value?
> 
> something like this (untested):
> 
> ----8<----
> diff --git a/src/PVE/QemuServer.pm b/src/PVE/QemuServer.pm
> index 77b8e9c4..a76a134a 100644
> --- a/src/PVE/QemuServer.pm
> +++ b/src/PVE/QemuServer.pm
> @@ -1494,7 +1494,13 @@ sub print_netdevice_full {
>  
>      my $mtu = $net->{mtu};
>  
> -    if (defined($host_mtu_migration)) {
> +    if (
> +        $net->{model} eq 'virtio'
> +        && $net->{bridge}
> +        && (!defined($host_mtu_migration) || $host_mtu_migration)
> +    ) {
> +        my $bridge_mtu = PVE::Network::read_bridge_mtu($net->{bridge});
> +
>          if ($host_mtu_migration) {
>              if (defined($mtu) && $mtu != 1) {
>                  if ($mtu != $host_mtu_migration) {
> @@ -1505,26 +1511,10 @@ sub print_netdevice_full {
>              } else {
>                  print "netdev $netid: using 'host_mtu=$host_mtu_migration' for migration compat\n";
>              }
> -        } else {
> -            print "netdev $netid: not adding 'host_mtu' parameter for migration compat\n";
> -        }
> -    }
> -
> -    if (
> -        $net->{model} eq 'virtio'
> -        && $net->{bridge}
> -        && (!defined($host_mtu_migration) || $host_mtu_migration)
> -    ) {
> -        my $bridge_mtu = PVE::Network::read_bridge_mtu($net->{bridge});
> -
> -        if ($host_mtu_migration) {
>              $mtu = $host_mtu_migration;
> -            # TODO PVE 10 - upgrade to failure? Certain network traffic can break like
> -            # iperf3 -c 10.10.10.11 -u -l 2k when host_mtu=9000 and bridge MTU=1500
> -            if ($mtu > $bridge_mtu) {
> -                log_warn("netdev $netid: MTU '$mtu' is bigger than the bridge MTU '$bridge_mtu'");
> -            }
> -        } elsif (!defined($mtu) || $mtu == 1) {
> +        }
> +
> +        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";
> ---->8----
> 
> I dropped the log statement about host_mtu_migration being an explicit
> zero, since that is logged further below already if $mtu is defined, but
> it could of course be added back there also for the $mtu == undef case
> with a final
> 
> } elsif (defined($host_mtu_migration) && $host_mtu_migration == 0) {
>     log_warn(..);
> }

Oh, so that's what you meant, heh :) I'll look into it.

> 
>>
>>>
>>>> +            $mtu = $host_mtu_migration;
>>>> +            # TODO PVE 10 - upgrade to failure? Certain network traffic can break like
>>>> +            # iperf3 -c 10.10.10.11 -u -l 2k when host_mtu=9000 and bridge MTU=1500
>>>> +            if ($mtu > $bridge_mtu) {
>>>> +                log_warn("netdev $netid: MTU '$mtu' is bigger than the bridge MTU '$bridge_mtu'");
>>>> +            }
>>>> +        } elsif (!defined($mtu) || $mtu == 1) {
>>>
>>> this could still be an if, then the newly added warning above can be
>>> dropped
>>>
>>>>              $mtu = $bridge_mtu;
>>>>          } elsif ($mtu < 576) {
>>>>              die "netdev $netid: MTU '$mtu' is smaller than the IP minimum MTU '576'\n";
>>>> @@ -1495,7 +1532,7 @@ sub print_netdevice_full {
>>>>              die "netdev $netid: MTU '$mtu' is bigger than the bridge MTU '$bridge_mtu'\n";
>>>
>>> since it is covered by this one here
>>
>> If we want to go for early failure when host_mtu > bridge MTU then yes.
>> Because this is die, the above is warn ;) Doing that is fine by me, but
>> I wanted to propose the non-breaking option first. If we consider that
>> it's problematic in more cases than not, then I'll go for early failure.
>> And maybe I'll add a little more context to the error message (at least
>> when it happens for migration).
> 
> could still handle it in one place, and warn if $host_mtu_migration
> (either inline, or via an elsif coming first that compares
> $host_mtu_migration to $bridge_mtu), die otherwise - but I think if we
> die on this condition when starting, then making it fatal for migration
> starts might make sense as well, since the die would happen early on (so
> no harm done).. might want to add a warning in that case as well that
> tells the user what to do to make the VM migrateable though?

Fair point. Yes, that was what I meant with "more context to the error
message".


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2025-09-04 10:03 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-09-03 14:22 [pve-devel] [PATCH-SERIES qemu-server v2 0/4] virtio-net: fix migration between default/non-default MTUs, part one and two Fiona Ebner
2025-09-03 14:22 ` [pve-devel] [PATCH qemu-server v2 1/4] virtio-net: fix migration between default/non-default MTUs starting with machine version 10.0+pve1 Fiona Ebner
2025-09-03 14:22 ` [pve-devel] [PATCH qemu-server v2 2/4] api: vm start: introduce nets-host-mtu parameter for migration compat Fiona Ebner
2025-09-04  9:11   ` Fabian Grünbichler
2025-09-04  9:28     ` Fiona Ebner
2025-09-04  9:52       ` Fabian Grünbichler
2025-09-04 10:03         ` Fiona Ebner
2025-09-04  9:55       ` Fiona Ebner
2025-09-03 14:22 ` [pve-devel] [PATCH qemu-server v2 3/4] migration: preserve host_mtu for virtio-net devices Fiona Ebner
2025-09-03 14:22 ` [pve-devel] [PATCH qemu-server v2 stable-bookworm 4/4] " Fiona Ebner
2025-09-04  9:11   ` Fabian Grünbichler
2025-09-04  9:32     ` Fiona Ebner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal