diff --git a/kvm-nbd-server-Silence-server-warnings-on-port-probes.patch b/kvm-nbd-server-Silence-server-warnings-on-port-probes.patch new file mode 100644 index 0000000..c28bb0f --- /dev/null +++ b/kvm-nbd-server-Silence-server-warnings-on-port-probes.patch @@ -0,0 +1,105 @@ +From 908997de5fa9470549347d66f7c8e125989fa4b1 Mon Sep 17 00:00:00 2001 +From: Eric Blake +Date: Fri, 15 Nov 2024 13:55:53 -0600 +Subject: [PATCH 1/3] nbd-server: Silence server warnings on port probes + +RH-Author: Eric Blake +RH-MergeRequest: 333: nbd-server: Silence server warnings on port probes +RH-Jira: RHEL-67863 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/1] c09db866ba3028702996ab1db459061cbf9e8bfa (ebblake/centos-qemu-kvm) + +While testing the use of qemu-nbd in a Pod of a Kubernetes cluster, I +got LOTS of log messages of the forms: + +qemu-nbd: option negotiation failed: Failed to read flags: Unexpected end-of-file before all data were read +qemu-nbd: option negotiation failed: Failed to read flags: Unable to read from socket: Connection reset by peer + +While it is nice to warn about clients that aren't following protocol +(in case it helps diagnosing bugs in those clients), a mere port probe +(where the client never write()s any bytes, and where we might even +hit EPIPE in trying to send our greeting to the client) is NOT +abnormal, but merely serves to pollute the log. And Kubernetes +_really_ likes to do port probes to determine whether a given Pod is +up and running. + +Easy ways to demonstrate the above port probes: +$ qemu-nbd -r -f raw path/to/file & +$ nc localhost 10809 +Message-ID: <20241115195638.1132007-2-eblake@redhat.com> +Reviewed-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit efd3dda312129b91986f85976afbda58d40f757f) +Signed-off-by: Eric Blake +--- + nbd/server.c | 26 +++++++++++++++++--------- + 1 file changed, 17 insertions(+), 9 deletions(-) + +diff --git a/nbd/server.c b/nbd/server.c +index c30e687fc8..f64e47270c 100644 +--- a/nbd/server.c ++++ b/nbd/server.c +@@ -1150,8 +1150,8 @@ nbd_negotiate_meta_queries(NBDClient *client, Error **errp) + * Return: + * -errno on error, errp is set + * 0 on successful negotiation, errp is not set +- * 1 if client sent NBD_OPT_ABORT, i.e. on valid disconnect, +- * errp is not set ++ * 1 if client sent NBD_OPT_ABORT (i.e. on valid disconnect) or never ++ * wrote anything (i.e. port probe); errp is not set + */ + static coroutine_fn int + nbd_negotiate_options(NBDClient *client, Error **errp) +@@ -1175,8 +1175,13 @@ nbd_negotiate_options(NBDClient *client, Error **errp) + ... Rest of request + */ + +- if (nbd_read32(client->ioc, &flags, "flags", errp) < 0) { +- return -EIO; ++ /* ++ * Intentionally ignore errors on this first read - we do not want ++ * to be noisy about a mere port probe, but only for clients that ++ * start talking the protocol and then quit abruptly. ++ */ ++ if (nbd_read32(client->ioc, &flags, "flags", NULL) < 0) { ++ return 1; + } + client->mode = NBD_MODE_EXPORT_NAME; + trace_nbd_negotiate_options_flags(flags); +@@ -1383,8 +1388,8 @@ nbd_negotiate_options(NBDClient *client, Error **errp) + * Return: + * -errno on error, errp is set + * 0 on successful negotiation, errp is not set +- * 1 if client sent NBD_OPT_ABORT, i.e. on valid disconnect, +- * errp is not set ++ * 1 if client sent NBD_OPT_ABORT (i.e. on valid disconnect) or never ++ * wrote anything (i.e. port probe); errp is not set + */ + static coroutine_fn int nbd_negotiate(NBDClient *client, Error **errp) + { +@@ -1415,9 +1420,12 @@ static coroutine_fn int nbd_negotiate(NBDClient *client, Error **errp) + stq_be_p(buf + 8, NBD_OPTS_MAGIC); + stw_be_p(buf + 16, NBD_FLAG_FIXED_NEWSTYLE | NBD_FLAG_NO_ZEROES); + +- if (nbd_write(client->ioc, buf, 18, errp) < 0) { +- error_prepend(errp, "write failed: "); +- return -EINVAL; ++ /* ++ * Be silent about failure to write our greeting: there is nothing ++ * wrong with a client testing if our port is alive. ++ */ ++ if (nbd_write(client->ioc, buf, 18, NULL) < 0) { ++ return 1; + } + ret = nbd_negotiate_options(client, errp); + if (ret != 0) { +-- +2.48.1 + diff --git a/kvm-vhost-Add-stubs-for-the-migration-state-transfer-int.patch b/kvm-vhost-Add-stubs-for-the-migration-state-transfer-int.patch new file mode 100644 index 0000000..e3bac53 --- /dev/null +++ b/kvm-vhost-Add-stubs-for-the-migration-state-transfer-int.patch @@ -0,0 +1,87 @@ +From 592361992b26d7f357d45de2e9ee68c1cdb15ab0 Mon Sep 17 00:00:00 2001 +From: Laurent Vivier +Date: Wed, 15 Jan 2025 14:50:43 +0100 +Subject: [PATCH 2/3] vhost: Add stubs for the migration state transfer + interface + +RH-Author: Laurent Vivier +RH-MergeRequest: 337: virtio-net: vhost-user: Implement internal migration +RH-Jira: RHEL-78372 +RH-Acked-by: Hanna Czenczek +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [1/2] f9a24e45e618a22f867de0fd14e1000a9a38ba91 (lvivier/qemu-kvm-centos) + +JIRA: https://issues.redhat.com/browse/RHEL-78372 + +Migration state transfer interface is only used by vhost-user-fs, +so the interface needs to be defined only when vhost is built. + +But I need to use this interface with virtio-net and vhost is not always +enabled, and to avoid undefined reference error during build, define stub +functions for vhost_supports_device_state(), vhost_save_backend_state() and +vhost_load_backend_state(). + +Cc: Hanna Czenczek +Signed-off-by: Laurent Vivier +Message-Id: <20250115135044.799698-2-lvivier@redhat.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 3f65357313e0f928e0bd3ff868b705855d0405bc) +Signed-off-by: Laurent Vivier +--- + include/hw/virtio/vhost.h | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h +index d75faf46e9..1d524f85b9 100644 +--- a/include/hw/virtio/vhost.h ++++ b/include/hw/virtio/vhost.h +@@ -363,7 +363,14 @@ static inline int vhost_reset_device(struct vhost_dev *hdev) + * Returns true if the device supports these commands, and false if it + * does not. + */ ++#ifdef CONFIG_VHOST + bool vhost_supports_device_state(struct vhost_dev *dev); ++#else ++static inline bool vhost_supports_device_state(struct vhost_dev *dev) ++{ ++ return false; ++} ++#endif + + /** + * vhost_set_device_state_fd(): Begin transfer of internal state from/to +@@ -446,7 +453,15 @@ int vhost_check_device_state(struct vhost_dev *dev, Error **errp); + * + * Returns 0 on success, and -errno otherwise. + */ ++#ifdef CONFIG_VHOST + int vhost_save_backend_state(struct vhost_dev *dev, QEMUFile *f, Error **errp); ++#else ++static inline int vhost_save_backend_state(struct vhost_dev *dev, QEMUFile *f, ++ Error **errp) ++{ ++ return -ENOSYS; ++} ++#endif + + /** + * vhost_load_backend_state(): High-level function to load a vhost +@@ -463,6 +478,14 @@ int vhost_save_backend_state(struct vhost_dev *dev, QEMUFile *f, Error **errp); + * + * Returns 0 on success, and -errno otherwise. + */ ++#ifdef CONFIG_VHOST + int vhost_load_backend_state(struct vhost_dev *dev, QEMUFile *f, Error **errp); ++#else ++static inline int vhost_load_backend_state(struct vhost_dev *dev, QEMUFile *f, ++ Error **errp) ++{ ++ return -ENOSYS; ++} ++#endif + + #endif +-- +2.48.1 + diff --git a/kvm-virtio-net-vhost-user-Implement-internal-migration.patch b/kvm-virtio-net-vhost-user-Implement-internal-migration.patch new file mode 100644 index 0000000..50fdaca --- /dev/null +++ b/kvm-virtio-net-vhost-user-Implement-internal-migration.patch @@ -0,0 +1,161 @@ +From f73b4e686c289ef6409c945d16582af16d2c28fc Mon Sep 17 00:00:00 2001 +From: Laurent Vivier +Date: Wed, 15 Jan 2025 14:50:44 +0100 +Subject: [PATCH 3/3] virtio-net: vhost-user: Implement internal migration + +RH-Author: Laurent Vivier +RH-MergeRequest: 337: virtio-net: vhost-user: Implement internal migration +RH-Jira: RHEL-78372 +RH-Acked-by: Hanna Czenczek +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [2/2] 5832e25e230407a36022318a2a1e0d4f6f54bb92 (lvivier/qemu-kvm-centos) + +JIRA: https://issues.redhat.com/browse/RHEL-78372 + +Add support of VHOST_USER_PROTOCOL_F_DEVICE_STATE in virtio-net +with vhost-user backend. + +Cc: Hanna Czenczek +Signed-off-by: Laurent Vivier +Message-Id: <20250115135044.799698-3-lvivier@redhat.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 60f543ad917fad731e39ff8ce2ca83b9a9cc9d90) +Signed-off-by: Laurent Vivier +--- + hw/net/virtio-net.c | 105 ++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 97 insertions(+), 8 deletions(-) + +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index 90d05f94d4..3d2b2460ad 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -3305,6 +3305,102 @@ static const VMStateDescription vmstate_virtio_net_rss = { + }, + }; + ++static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev) ++{ ++ VirtIONet *n = VIRTIO_NET(vdev); ++ NetClientState *nc = qemu_get_queue(n->nic); ++ struct vhost_net *net = get_vhost_net(nc->peer); ++ return &net->dev; ++} ++ ++static int vhost_user_net_save_state(QEMUFile *f, void *pv, size_t size, ++ const VMStateField *field, ++ JSONWriter *vmdesc) ++{ ++ VirtIONet *n = pv; ++ VirtIODevice *vdev = VIRTIO_DEVICE(n); ++ struct vhost_dev *vhdev; ++ Error *local_error = NULL; ++ int ret; ++ ++ vhdev = virtio_net_get_vhost(vdev); ++ if (vhdev == NULL) { ++ error_reportf_err(local_error, ++ "Error getting vhost back-end of %s device %s: ", ++ vdev->name, vdev->parent_obj.canonical_path); ++ return -1; ++ } ++ ++ ret = vhost_save_backend_state(vhdev, f, &local_error); ++ if (ret < 0) { ++ error_reportf_err(local_error, ++ "Error saving back-end state of %s device %s: ", ++ vdev->name, vdev->parent_obj.canonical_path); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int vhost_user_net_load_state(QEMUFile *f, void *pv, size_t size, ++ const VMStateField *field) ++{ ++ VirtIONet *n = pv; ++ VirtIODevice *vdev = VIRTIO_DEVICE(n); ++ struct vhost_dev *vhdev; ++ Error *local_error = NULL; ++ int ret; ++ ++ vhdev = virtio_net_get_vhost(vdev); ++ if (vhdev == NULL) { ++ error_reportf_err(local_error, ++ "Error getting vhost back-end of %s device %s: ", ++ vdev->name, vdev->parent_obj.canonical_path); ++ return -1; ++ } ++ ++ ret = vhost_load_backend_state(vhdev, f, &local_error); ++ if (ret < 0) { ++ error_reportf_err(local_error, ++ "Error loading back-end state of %s device %s: ", ++ vdev->name, vdev->parent_obj.canonical_path); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static bool vhost_user_net_is_internal_migration(void *opaque) ++{ ++ VirtIONet *n = opaque; ++ VirtIODevice *vdev = VIRTIO_DEVICE(n); ++ struct vhost_dev *vhdev; ++ ++ vhdev = virtio_net_get_vhost(vdev); ++ if (vhdev == NULL) { ++ return false; ++ } ++ ++ return vhost_supports_device_state(vhdev); ++} ++ ++static const VMStateDescription vhost_user_net_backend_state = { ++ .name = "virtio-net-device/backend", ++ .version_id = 0, ++ .needed = vhost_user_net_is_internal_migration, ++ .fields = (const VMStateField[]) { ++ { ++ .name = "backend", ++ .info = &(const VMStateInfo) { ++ .name = "virtio-net vhost-user backend state", ++ .get = vhost_user_net_load_state, ++ .put = vhost_user_net_save_state, ++ }, ++ }, ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ + static const VMStateDescription vmstate_virtio_net_device = { + .name = "virtio-net-device", + .version_id = VIRTIO_NET_VM_VERSION, +@@ -3357,6 +3453,7 @@ static const VMStateDescription vmstate_virtio_net_device = { + }, + .subsections = (const VMStateDescription * const []) { + &vmstate_virtio_net_rss, ++ &vhost_user_net_backend_state, + NULL + } + }; +@@ -3902,14 +3999,6 @@ static bool dev_unplug_pending(void *opaque) + return vdc->primary_unplug_pending(dev); + } + +-static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev) +-{ +- VirtIONet *n = VIRTIO_NET(vdev); +- NetClientState *nc = qemu_get_queue(n->nic); +- struct vhost_net *net = get_vhost_net(nc->peer); +- return &net->dev; +-} +- + static const VMStateDescription vmstate_virtio_net = { + .name = "virtio-net", + .minimum_version_id = VIRTIO_NET_VM_VERSION, +-- +2.48.1 + diff --git a/qemu-kvm.spec b/qemu-kvm.spec index 430fc11..fd7ef7c 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -149,7 +149,7 @@ Obsoletes: %{name}-block-ssh <= %{epoch}:%{version} \ Summary: QEMU is a machine emulator and virtualizer Name: qemu-kvm Version: 9.1.0 -Release: 13%{?rcrel}%{?dist}%{?cc_suffix} +Release: 14%{?rcrel}%{?dist}%{?cc_suffix} # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped # Epoch 15 used for RHEL 8 # Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5) @@ -391,6 +391,12 @@ Patch120: kvm-pc-bios-s390-ccw-virtio-Add-a-function-to-reset-a-vi.patch Patch121: kvm-pc-bios-s390-ccw-Fix-boot-problem-with-virtio-net-de.patch # For RHEL-72716 - Boot fall back to cdrom from network not always working Patch122: kvm-pc-bios-s390-ccw-netmain-Fix-error-messages-with-reg.patch +# For RHEL-67863 - Ensure qemu as NBD server does not flood logs [rhel 9.6] +Patch123: kvm-nbd-server-Silence-server-warnings-on-port-probes.patch +# For RHEL-78372 - Add vhost-user internal migration for passt [rhel-9] +Patch124: kvm-vhost-Add-stubs-for-the-migration-state-transfer-int.patch +# For RHEL-78372 - Add vhost-user internal migration for passt [rhel-9] +Patch125: kvm-virtio-net-vhost-user-Implement-internal-migration.patch %if %{have_clang} BuildRequires: clang @@ -1457,6 +1463,15 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %endif %changelog +* Mon Feb 10 2025 Jon Maloy - 9.1.0-14 +- kvm-nbd-server-Silence-server-warnings-on-port-probes.patch [RHEL-67863] +- kvm-vhost-Add-stubs-for-the-migration-state-transfer-int.patch [RHEL-78372] +- kvm-virtio-net-vhost-user-Implement-internal-migration.patch [RHEL-78372] +- Resolves: RHEL-67863 + (Ensure qemu as NBD server does not flood logs [rhel 9.6]) +- Resolves: RHEL-78372 + (Add vhost-user internal migration for passt [rhel-9]) + * Thu Jan 30 2025 Jon Maloy - 9.1.0-13 - kvm-pc-bios-s390-ccw-Abort-IPL-on-invalid-loadparm.patch [RHEL-72716] - kvm-pc-bios-s390-ccw-virtio-Add-a-function-to-reset-a-vi.patch [RHEL-72716]