diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index f2395abd74..c82e9921d7 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -1036,6 +1036,9 @@ esxConnectSupportsFeature(virConnectPtr conn, int feature) return priv->vCenter && supportsVMotion == esxVI_Boolean_True ? 1 : 0; + case VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER: + return 1; + case VIR_DRV_FEATURE_FD_PASSING: case VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION: case VIR_DRV_FEATURE_MIGRATION_DIRECT: diff --git a/src/libvirt-network.c b/src/libvirt-network.c index b84389f762..145487d599 100644 --- a/src/libvirt-network.c +++ b/src/libvirt-network.c @@ -543,8 +543,28 @@ virNetworkUpdate(virNetworkPtr network, if (conn->networkDriver && conn->networkDriver->networkUpdate) { int ret; - ret = conn->networkDriver->networkUpdate(network, section, command, - parentIndex, xml, flags); + int rc; + + /* Since its introduction in v0.10.2-rc1~9 the @section and @command + * arguments were mistakenly swapped when passed to driver's callback. + * Detect if the other side is fixed already or not. */ + rc = VIR_DRV_SUPPORTS_FEATURE(conn->driver, conn, + VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER); + + VIR_DEBUG("Argument order feature detection returned: %d", rc); + if (rc < 0) + goto error; + + if (rc == 0) { + /* Feature not supported, preserve swapped order */ + ret = conn->networkDriver->networkUpdate(network, section, command, + parentIndex, xml, flags); + } else { + /* Feature supported, correct order can be used */ + ret = conn->networkDriver->networkUpdate(network, command, section, + parentIndex, xml, flags); + } + if (ret < 0) goto error; return ret; diff --git a/src/libvirt_internal.h b/src/libvirt_internal.h index 2bf7744bd6..f4e592922d 100644 --- a/src/libvirt_internal.h +++ b/src/libvirt_internal.h @@ -126,6 +126,11 @@ typedef enum { * Support for driver close callback rpc */ VIR_DRV_FEATURE_REMOTE_CLOSE_CALLBACK = 15, + + /* + * Whether the virNetworkUpdate() API implementation passes arguments to + * the driver's callback in correct order. */ + VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER = 16, } virDrvFeature; diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 23ef55cf37..0928d27563 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -5743,6 +5743,7 @@ libxlConnectSupportsFeature(virConnectPtr conn, int feature) case VIR_DRV_FEATURE_TYPED_PARAM_STRING: case VIR_DRV_FEATURE_MIGRATION_PARAMS: case VIR_DRV_FEATURE_MIGRATION_P2P: + case VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER: return 1; case VIR_DRV_FEATURE_FD_PASSING: case VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION: diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 3fc15ff2ec..c613019c7f 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1651,6 +1651,7 @@ lxcConnectSupportsFeature(virConnectPtr conn, int feature) switch ((virDrvFeature) feature) { case VIR_DRV_FEATURE_TYPED_PARAM_STRING: + case VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER: return 1; case VIR_DRV_FEATURE_FD_PASSING: case VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION: diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 7c9e36c625..14db9ffc82 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -951,6 +951,8 @@ networkConnectSupportsFeature(virConnectPtr conn, int feature) return -1; switch ((virDrvFeature) feature) { + case VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER: + return 1; case VIR_DRV_FEATURE_MIGRATION_V2: case VIR_DRV_FEATURE_MIGRATION_V3: case VIR_DRV_FEATURE_MIGRATION_P2P: diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index e898af85ab..9f65dff5d1 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -1992,6 +1992,7 @@ openvzConnectSupportsFeature(virConnectPtr conn G_GNUC_UNUSED, int feature) switch ((virDrvFeature) feature) { case VIR_DRV_FEATURE_MIGRATION_PARAMS: case VIR_DRV_FEATURE_MIGRATION_V3: + case VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER: return 1; case VIR_DRV_FEATURE_FD_PASSING: case VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION: diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index b31be76f91..3e9fc88ca1 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1238,6 +1238,7 @@ qemuConnectSupportsFeature(virConnectPtr conn, int feature) case VIR_DRV_FEATURE_XML_MIGRATABLE: case VIR_DRV_FEATURE_MIGRATION_OFFLINE: case VIR_DRV_FEATURE_MIGRATION_PARAMS: + case VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER: return 1; case VIR_DRV_FEATURE_MIGRATION_DIRECT: case VIR_DRV_FEATURE_MIGRATION_V1: diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c index d9181c0ca6..42c03d6cfc 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c @@ -4994,6 +4994,7 @@ static int remoteDispatchConnectSupportsFeature(virNetServerPtr server G_GNUC_UN case VIR_DRV_FEATURE_XML_MIGRATABLE: case VIR_DRV_FEATURE_MIGRATION_OFFLINE: case VIR_DRV_FEATURE_MIGRATION_PARAMS: + case VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER: default: if ((supported = virConnectSupportsFeature(conn, args->feature)) < 0) goto cleanup; diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 0c2ebddd22..3531011a81 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -1590,6 +1590,7 @@ testConnectSupportsFeature(virConnectPtr conn G_GNUC_UNUSED, { switch ((virDrvFeature) feature) { case VIR_DRV_FEATURE_TYPED_PARAM_STRING: + case VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER: return 1; case VIR_DRV_FEATURE_MIGRATION_V2: case VIR_DRV_FEATURE_MIGRATION_V3: