render / rpms / libvirt

Forked from rpms/libvirt a year ago
Clone
9e5a9d
From 39a12e8336d314a1f1e6ed1abf15e4ff10f6f81e Mon Sep 17 00:00:00 2001
9e5a9d
Message-Id: <39a12e8336d314a1f1e6ed1abf15e4ff10f6f81e@dist-git>
9e5a9d
From: Michal Privoznik <mprivozn@redhat.com>
9e5a9d
Date: Mon, 10 Jan 2022 12:08:08 +0100
9e5a9d
Subject: [PATCH] lib: Fix calling of virNetworkUpdate() driver callback
9e5a9d
9e5a9d
The order in which virNetworkUpdate() accepts @section and
9e5a9d
@command arguments is not the same as in which it passes them
9e5a9d
onto networkUpdate() callback. Until recently, it did not really
9e5a9d
matter, because calling the API on client side meant arguments
9e5a9d
were encoded in reversed order (compared to the public API), but
9e5a9d
then on the server it was fixed again - because the server
9e5a9d
decoded RPC (still swapped), called public API (still swapped)
9e5a9d
and in turn called the network driver callback (with reversing
9e5a9d
the order - so magically fixing the order).
9e5a9d
9e5a9d
Long story short, if the public API is called even number of
9e5a9d
times those swaps cancel each other out. The problem is when the
9e5a9d
API is called an odd numbed of times - which happens with split
9e5a9d
daemons and the right URI. There's one call in the client (e.g.
9e5a9d
virsh net-update), the other in a hypervisor daemon (say
9e5a9d
virtqemud) which ends up calling the API in the virnetworkd.
9e5a9d
9e5a9d
The fix is obvious - fix the order in which arguments are passed
9e5a9d
to the callback.
9e5a9d
9e5a9d
But, to maintain compatibility with older, yet unfixed, daemons
9e5a9d
new connection feature is introduced. The feature is detected
9e5a9d
just before calling the callback and allows client to pass
9e5a9d
arguments in correct order (talking to fixed daemon) or in
9e5a9d
reversed order (talking to older daemon).
9e5a9d
9e5a9d
Unfortunately, older client talking to newer daemon can't be
9e5a9d
fixed. Let's hope that it's less frequent scenario.
9e5a9d
9e5a9d
Fixes: 574b9bc66b6b10cc4cf50f299c3f0ff55f2cbefb
9e5a9d
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1870552
9e5a9d
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
9e5a9d
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
9e5a9d
(cherry picked from commit b0f78d626a18bcecae3a4d165540ab88bfbfc9ee)
9e5a9d
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2038812
9e5a9d
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
9e5a9d
Message-Id: <4601f7b2c8ef354e0f8c8020ecd1bb20b20d0f53.1641812574.git.mprivozn@redhat.com>
9e5a9d
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
9e5a9d
---
9e5a9d
 src/esx/esx_driver.c                |  3 +++
9e5a9d
 src/libvirt-network.c               | 24 ++++++++++++++++++++++--
9e5a9d
 src/libvirt_internal.h              |  5 +++++
9e5a9d
 src/libxl/libxl_driver.c            |  1 +
9e5a9d
 src/lxc/lxc_driver.c                |  1 +
9e5a9d
 src/network/bridge_driver.c         |  2 ++
9e5a9d
 src/openvz/openvz_driver.c          |  1 +
9e5a9d
 src/qemu/qemu_driver.c              |  1 +
9e5a9d
 src/remote/remote_daemon_dispatch.c |  1 +
9e5a9d
 src/test/test_driver.c              |  1 +
9e5a9d
 10 files changed, 38 insertions(+), 2 deletions(-)
9e5a9d
9e5a9d
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
9e5a9d
index 0ede65279a..07ce7961b0 100644
9e5a9d
--- a/src/esx/esx_driver.c
9e5a9d
+++ b/src/esx/esx_driver.c
9e5a9d
@@ -1059,6 +1059,9 @@ esxConnectSupportsFeature(virConnectPtr conn, int feature)
9e5a9d
         return priv->vCenter &&
9e5a9d
                supportsVMotion == esxVI_Boolean_True ? 1 : 0;
9e5a9d
 
9e5a9d
+    case VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER:
9e5a9d
+        return 1;
9e5a9d
+
9e5a9d
     case VIR_DRV_FEATURE_FD_PASSING:
9e5a9d
     case VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION:
9e5a9d
     case VIR_DRV_FEATURE_MIGRATION_DIRECT:
9e5a9d
diff --git a/src/libvirt-network.c b/src/libvirt-network.c
9e5a9d
index 09e24fb0a8..9edd30d2b7 100644
9e5a9d
--- a/src/libvirt-network.c
9e5a9d
+++ b/src/libvirt-network.c
9e5a9d
@@ -543,8 +543,28 @@ virNetworkUpdate(virNetworkPtr network,
9e5a9d
 
9e5a9d
     if (conn->networkDriver && conn->networkDriver->networkUpdate) {
9e5a9d
         int ret;
9e5a9d
-        ret = conn->networkDriver->networkUpdate(network, section, command,
9e5a9d
-                                                 parentIndex, xml, flags);
9e5a9d
+        int rc;
9e5a9d
+
9e5a9d
+        /* Since its introduction in v0.10.2-rc1~9 the @section and @command
9e5a9d
+         * arguments were mistakenly swapped when passed to driver's callback.
9e5a9d
+         * Detect if the other side is fixed already or not. */
9e5a9d
+        rc = VIR_DRV_SUPPORTS_FEATURE(conn->driver, conn,
9e5a9d
+                                      VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER);
9e5a9d
+
9e5a9d
+        VIR_DEBUG("Argument order feature detection returned: %d", rc);
9e5a9d
+        if (rc < 0)
9e5a9d
+            goto error;
9e5a9d
+
9e5a9d
+        if (rc == 0) {
9e5a9d
+            /* Feature not supported, preserve swapped order */
9e5a9d
+            ret = conn->networkDriver->networkUpdate(network, section, command,
9e5a9d
+                                                     parentIndex, xml, flags);
9e5a9d
+        } else {
9e5a9d
+            /* Feature supported, correct order can be used */
9e5a9d
+            ret = conn->networkDriver->networkUpdate(network, command, section,
9e5a9d
+                                                     parentIndex, xml, flags);
9e5a9d
+        }
9e5a9d
+
9e5a9d
         if (ret < 0)
9e5a9d
             goto error;
9e5a9d
         return ret;
9e5a9d
diff --git a/src/libvirt_internal.h b/src/libvirt_internal.h
9e5a9d
index 4a74dbc2af..21b7243557 100644
9e5a9d
--- a/src/libvirt_internal.h
9e5a9d
+++ b/src/libvirt_internal.h
9e5a9d
@@ -123,6 +123,11 @@ typedef enum {
9e5a9d
      * Support for driver close callback rpc
9e5a9d
      */
9e5a9d
     VIR_DRV_FEATURE_REMOTE_CLOSE_CALLBACK = 15,
9e5a9d
+
9e5a9d
+    /*
9e5a9d
+     * Whether the virNetworkUpdate() API implementation passes arguments to
9e5a9d
+     * the driver's callback in correct order. */
9e5a9d
+    VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER = 16,
9e5a9d
 } virDrvFeature;
9e5a9d
 
9e5a9d
 
9e5a9d
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
9e5a9d
index 9269e9b475..827a58b2c6 100644
9e5a9d
--- a/src/libxl/libxl_driver.c
9e5a9d
+++ b/src/libxl/libxl_driver.c
9e5a9d
@@ -5714,6 +5714,7 @@ libxlConnectSupportsFeature(virConnectPtr conn, int feature)
9e5a9d
     case VIR_DRV_FEATURE_TYPED_PARAM_STRING:
9e5a9d
     case VIR_DRV_FEATURE_MIGRATION_PARAMS:
9e5a9d
     case VIR_DRV_FEATURE_MIGRATION_P2P:
9e5a9d
+    case VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER:
9e5a9d
         return 1;
9e5a9d
     case VIR_DRV_FEATURE_FD_PASSING:
9e5a9d
     case VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION:
9e5a9d
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
9e5a9d
index 853ddac8b9..8cf4dbab57 100644
9e5a9d
--- a/src/lxc/lxc_driver.c
9e5a9d
+++ b/src/lxc/lxc_driver.c
9e5a9d
@@ -1699,6 +1699,7 @@ lxcConnectSupportsFeature(virConnectPtr conn, int feature)
9e5a9d
 
9e5a9d
     switch ((virDrvFeature) feature) {
9e5a9d
     case VIR_DRV_FEATURE_TYPED_PARAM_STRING:
9e5a9d
+    case VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER:
9e5a9d
         return 1;
9e5a9d
     case VIR_DRV_FEATURE_FD_PASSING:
9e5a9d
     case VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION:
9e5a9d
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
9e5a9d
index 703348888a..cd6d09e164 100644
9e5a9d
--- a/src/network/bridge_driver.c
9e5a9d
+++ b/src/network/bridge_driver.c
9e5a9d
@@ -968,6 +968,8 @@ networkConnectSupportsFeature(virConnectPtr conn, int feature)
9e5a9d
         return -1;
9e5a9d
 
9e5a9d
     switch ((virDrvFeature) feature) {
9e5a9d
+    case VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER:
9e5a9d
+        return 1;
9e5a9d
     case VIR_DRV_FEATURE_MIGRATION_V2:
9e5a9d
     case VIR_DRV_FEATURE_MIGRATION_V3:
9e5a9d
     case VIR_DRV_FEATURE_MIGRATION_P2P:
9e5a9d
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
9e5a9d
index 62644f3129..22715c8e22 100644
9e5a9d
--- a/src/openvz/openvz_driver.c
9e5a9d
+++ b/src/openvz/openvz_driver.c
9e5a9d
@@ -2007,6 +2007,7 @@ openvzConnectSupportsFeature(virConnectPtr conn G_GNUC_UNUSED, int feature)
9e5a9d
     switch ((virDrvFeature) feature) {
9e5a9d
     case VIR_DRV_FEATURE_MIGRATION_PARAMS:
9e5a9d
     case VIR_DRV_FEATURE_MIGRATION_V3:
9e5a9d
+    case VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER:
9e5a9d
         return 1;
9e5a9d
     case VIR_DRV_FEATURE_FD_PASSING:
9e5a9d
     case VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION:
9e5a9d
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
9e5a9d
index 3914d3ff68..73f6247f2e 100644
9e5a9d
--- a/src/qemu/qemu_driver.c
9e5a9d
+++ b/src/qemu/qemu_driver.c
9e5a9d
@@ -1215,6 +1215,7 @@ qemuConnectSupportsFeature(virConnectPtr conn, int feature)
9e5a9d
     case VIR_DRV_FEATURE_XML_MIGRATABLE:
9e5a9d
     case VIR_DRV_FEATURE_MIGRATION_OFFLINE:
9e5a9d
     case VIR_DRV_FEATURE_MIGRATION_PARAMS:
9e5a9d
+    case VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER:
9e5a9d
         return 1;
9e5a9d
     case VIR_DRV_FEATURE_MIGRATION_DIRECT:
9e5a9d
     case VIR_DRV_FEATURE_MIGRATION_V1:
9e5a9d
diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c
9e5a9d
index 9c294ddc39..b82548a999 100644
9e5a9d
--- a/src/remote/remote_daemon_dispatch.c
9e5a9d
+++ b/src/remote/remote_daemon_dispatch.c
9e5a9d
@@ -5009,6 +5009,7 @@ static int remoteDispatchConnectSupportsFeature(virNetServerPtr server G_GNUC_UN
9e5a9d
     case VIR_DRV_FEATURE_XML_MIGRATABLE:
9e5a9d
     case VIR_DRV_FEATURE_MIGRATION_OFFLINE:
9e5a9d
     case VIR_DRV_FEATURE_MIGRATION_PARAMS:
9e5a9d
+    case VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER:
9e5a9d
     default:
9e5a9d
         if ((supported = virConnectSupportsFeature(conn, args->feature)) < 0)
9e5a9d
             goto cleanup;
9e5a9d
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
9e5a9d
index 1908185743..d21fedbcf8 100644
9e5a9d
--- a/src/test/test_driver.c
9e5a9d
+++ b/src/test/test_driver.c
9e5a9d
@@ -1588,6 +1588,7 @@ testConnectSupportsFeature(virConnectPtr conn G_GNUC_UNUSED,
9e5a9d
 {
9e5a9d
     switch ((virDrvFeature) feature) {
9e5a9d
     case VIR_DRV_FEATURE_TYPED_PARAM_STRING:
9e5a9d
+    case VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER:
9e5a9d
         return 1;
9e5a9d
     case VIR_DRV_FEATURE_MIGRATION_V2:
9e5a9d
     case VIR_DRV_FEATURE_MIGRATION_V3:
9e5a9d
-- 
9e5a9d
2.34.1
9e5a9d