[PATCH v3 8/8] tap: cpr fixes

Ben Chaney posted 8 patches 1 week, 3 days ago
Maintainers: "Michael S. Tsirkin" <mst@redhat.com>, Jason Wang <jasowang@redhat.com>, Alex Williamson <alex@shazbot.org>, "Cédric Le Goater" <clg@redhat.com>, Stefano Garzarella <sgarzare@redhat.com>, Peter Xu <peterx@redhat.com>, Fabiano Rosas <farosas@suse.de>, "Daniel P. Berrangé" <berrange@redhat.com>, Stefan Weil <sw@weilnetz.de>, Eric Blake <eblake@redhat.com>, Markus Armbruster <armbru@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>
[PATCH v3 8/8] tap: cpr fixes
Posted by Ben Chaney 1 week, 3 days ago
From: Steve Sistare <steven.sistare@oracle.com>

Fix "virtio_net_set_queue_pairs: Assertion `!r' failed."
Fix "virtio-net: saved image requires vnet_hdr=on"
Do not change blocking mode of incoming cpr fd's.

Reported-by: Ben Chaney <bchaney@akamai.com>
Reported-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
Signed-off-by: Ben Chaney <bchaney@akamai.com>
---
 hw/net/virtio-net.c | 6 ++++++
 io/channel-socket.c | 4 +++-
 net/tap.c           | 2 ++
 stubs/cpr.c         | 8 ++++++++
 stubs/meson.build   | 1 +
 5 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 38ec7ac109..fd6b30b296 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -37,6 +37,7 @@
 #include "qapi/qapi-types-migration.h"
 #include "qapi/qapi-events-migration.h"
 #include "hw/virtio/virtio-access.h"
+#include "migration/cpr.h"
 #include "migration/misc.h"
 #include "standard-headers/linux/ethtool.h"
 #include "system/system.h"
@@ -789,6 +790,11 @@ static void virtio_net_set_queue_pairs(VirtIONet *n)
     int i;
     int r;
 
+    if (cpr_is_incoming()) {
+        /* peers are already attached, do nothing */
+        return;
+    }
+
     if (n->nic->peer_deleted) {
         return;
     }
diff --git a/io/channel-socket.c b/io/channel-socket.c
index 3053b35ad8..443ca8cb7c 100644
--- a/io/channel-socket.c
+++ b/io/channel-socket.c
@@ -24,6 +24,7 @@
 #include "io/channel-socket.h"
 #include "io/channel-util.h"
 #include "io/channel-watch.h"
+#include "migration/cpr.h"
 #include "trace.h"
 #include "qapi/clone-visitor.h"
 #ifdef CONFIG_LINUX
@@ -521,7 +522,8 @@ static bool qio_channel_handle_fds(int *fds, size_t nfds,
 
         if (!preserve_blocking) {
             /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */
-            if (!qemu_set_blocking(*fd, true, errp)) {
+              if (!cpr_is_incoming() &&
+                  qemu_set_blocking(*fd, true, errp)) {
                 return false;
             }
         }
diff --git a/net/tap.c b/net/tap.c
index 5acda81146..5e04099c87 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -1050,6 +1050,8 @@ free_fail:
                 if (cpr && fd >= 0) {
                     cpr_save_fd(name, TAP_FD_INDEX(i), fd);
                 }
+            } else {
+                vnet_hdr = tap->has_vnet_hdr ? tap->vnet_hdr : 1;
             }
             if (fd == -1) {
                 ret = -1;
diff --git a/stubs/cpr.c b/stubs/cpr.c
new file mode 100644
index 0000000000..1a4dbbb2d7
--- /dev/null
+++ b/stubs/cpr.c
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include "qemu/osdep.h"
+#include "migration/cpr.h"
+
+bool cpr_is_incoming(void)
+{
+    return false;
+}
diff --git a/stubs/meson.build b/stubs/meson.build
index 0b2778c568..87af733528 100644
--- a/stubs/meson.build
+++ b/stubs/meson.build
@@ -10,6 +10,7 @@ stub_ss.add(files('is-daemonized.c'))
 stub_ss.add(files('monitor-core.c'))
 stub_ss.add(files('replay-mode.c'))
 stub_ss.add(files('trace-control.c'))
+stub_ss.add(files('cpr.c'))
 
 if have_block
   stub_ss.add(files('bdrv-next-monitor-owned.c'))

-- 
2.34.1
Re: [PATCH v3 8/8] tap: cpr fixes
Posted by Daniel P. Berrangé 1 week, 2 days ago
On Wed, Dec 03, 2025 at 01:51:25PM -0500, Ben Chaney wrote:
> From: Steve Sistare <steven.sistare@oracle.com>
> 
> Fix "virtio_net_set_queue_pairs: Assertion `!r' failed."
> Fix "virtio-net: saved image requires vnet_hdr=on"
> Do not change blocking mode of incoming cpr fd's.
> 
> Reported-by: Ben Chaney <bchaney@akamai.com>
> Reported-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
> Signed-off-by: Ben Chaney <bchaney@akamai.com>
> ---
>  hw/net/virtio-net.c | 6 ++++++
>  io/channel-socket.c | 4 +++-
>  net/tap.c           | 2 ++
>  stubs/cpr.c         | 8 ++++++++
>  stubs/meson.build   | 1 +
>  5 files changed, 20 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index 38ec7ac109..fd6b30b296 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -37,6 +37,7 @@
>  #include "qapi/qapi-types-migration.h"
>  #include "qapi/qapi-events-migration.h"
>  #include "hw/virtio/virtio-access.h"
> +#include "migration/cpr.h"
>  #include "migration/misc.h"
>  #include "standard-headers/linux/ethtool.h"
>  #include "system/system.h"
> @@ -789,6 +790,11 @@ static void virtio_net_set_queue_pairs(VirtIONet *n)
>      int i;
>      int r;
>  
> +    if (cpr_is_incoming()) {
> +        /* peers are already attached, do nothing */
> +        return;
> +    }
> +
>      if (n->nic->peer_deleted) {
>          return;
>      }
> diff --git a/io/channel-socket.c b/io/channel-socket.c
> index 3053b35ad8..443ca8cb7c 100644
> --- a/io/channel-socket.c
> +++ b/io/channel-socket.c
> @@ -24,6 +24,7 @@
>  #include "io/channel-socket.h"
>  #include "io/channel-util.h"
>  #include "io/channel-watch.h"
> +#include "migration/cpr.h"
>  #include "trace.h"
>  #include "qapi/clone-visitor.h"
>  #ifdef CONFIG_LINUX
> @@ -521,7 +522,8 @@ static bool qio_channel_handle_fds(int *fds, size_t nfds,
>  
>          if (!preserve_blocking) {
>              /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */
> -            if (!qemu_set_blocking(*fd, true, errp)) {
> +              if (!cpr_is_incoming() &&
> +                  qemu_set_blocking(*fd, true, errp)) {
>                  return false;
>              }
>          }

This is wrong - we added the QIO_CHANNEL_READ_FLAG_FD_PRESERVE_BLOCKING
flag precisely so that we don't need to add CPR hacks into QIOChannelSocket
code.

Whatever cares about this blocking state being preserved needs to pass
that QIO_CHANNEL flag when reading from the channel.

> diff --git a/net/tap.c b/net/tap.c
> index 5acda81146..5e04099c87 100644
> --- a/net/tap.c
> +++ b/net/tap.c
> @@ -1050,6 +1050,8 @@ free_fail:
>                  if (cpr && fd >= 0) {
>                      cpr_save_fd(name, TAP_FD_INDEX(i), fd);
>                  }
> +            } else {
> +                vnet_hdr = tap->has_vnet_hdr ? tap->vnet_hdr : 1;
>              }
>              if (fd == -1) {
>                  ret = -1;
> diff --git a/stubs/cpr.c b/stubs/cpr.c
> new file mode 100644
> index 0000000000..1a4dbbb2d7
> --- /dev/null
> +++ b/stubs/cpr.c
> @@ -0,0 +1,8 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +#include "qemu/osdep.h"
> +#include "migration/cpr.h"
> +
> +bool cpr_is_incoming(void)
> +{
> +    return false;
> +}
> diff --git a/stubs/meson.build b/stubs/meson.build
> index 0b2778c568..87af733528 100644
> --- a/stubs/meson.build
> +++ b/stubs/meson.build
> @@ -10,6 +10,7 @@ stub_ss.add(files('is-daemonized.c'))
>  stub_ss.add(files('monitor-core.c'))
>  stub_ss.add(files('replay-mode.c'))
>  stub_ss.add(files('trace-control.c'))
> +stub_ss.add(files('cpr.c'))
>  
>  if have_block
>    stub_ss.add(files('bdrv-next-monitor-owned.c'))
> 
> -- 
> 2.34.1
> 

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|