In QEMU and LXC drivers in a few places just virNetDevBandwidthClear() is called. This means that if an interface is of openvswitch vport profile, its QoS is not removed. And to make matters worse - OVS is designed to remember state even when corresponding interface is gone. This leads to stale QoS settings piling up in OVS database. To resolve this, introduce virDomainInterfaceClearQoS() which looks at given interface and calls corresponding QoS clear function. Then, basically replace virNetDevBandwidthClear() calls in those hypervisor drivers with this new function. Resolves: https://issues.redhat.com/browse/RHEL-30373 Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/hypervisor/domain_interface.c | 36 ++++++++++++++++++++++++++----- src/hypervisor/domain_interface.h | 2 ++ src/libvirt_private.syms | 1 + src/lxc/lxc_driver.c | 5 +---- src/qemu/qemu_hotplug.c | 18 +++------------- 5 files changed, 38 insertions(+), 24 deletions(-) diff --git a/src/hypervisor/domain_interface.c b/src/hypervisor/domain_interface.c index 0a9cad8011..cc6aa8551a 100644 --- a/src/hypervisor/domain_interface.c +++ b/src/hypervisor/domain_interface.c @@ -472,16 +472,42 @@ virDomainInterfaceDeleteDevice(virDomainDef *def, } +/** + * virDomainInterfaceClearQoS + * @def: domain definition + * @net: a net definition in the VM + * + * For given interface @net clear its QoS settings in the + * host. NOP if @net has no QoS or is of a type that doesn't + * support QoS. + * + * Returns: 0 on success, + * -1 otherwise (with appropriate error reported) + */ +int +virDomainInterfaceClearQoS(virDomainDef *def, + virDomainNetDef *net) +{ + if (!virDomainNetGetActualBandwidth(net)) + return 0; + + if (!virNetDevSupportsBandwidth(virDomainNetGetActualType(net))) + return 0; + + if (virDomainNetDefIsOvsport(net)) { + return virNetDevOpenvswitchInterfaceClearQos(net->ifname, def->uuid); + } + + return virNetDevBandwidthClear(net->ifname); +} + + void virDomainClearNetBandwidth(virDomainDef *def) { size_t i; - virDomainNetType type; for (i = 0; i < def->nnets; i++) { - type = virDomainNetGetActualType(def->nets[i]); - if (virDomainNetGetActualBandwidth(def->nets[i]) && - virNetDevSupportsBandwidth(type)) - virNetDevBandwidthClear(def->nets[i]->ifname); + virDomainInterfaceClearQoS(def, def->nets[i]); } } diff --git a/src/hypervisor/domain_interface.h b/src/hypervisor/domain_interface.h index bb212cf3b8..572b4dd8c5 100644 --- a/src/hypervisor/domain_interface.h +++ b/src/hypervisor/domain_interface.h @@ -44,5 +44,7 @@ void virDomainInterfaceDeleteDevice(virDomainDef *def, virDomainNetDef *net, bool priv_net_created, char *stateDir); +int virDomainInterfaceClearQoS(virDomainDef *def, + virDomainNetDef *net); void virDomainClearNetBandwidth(virDomainDef *def) ATTRIBUTE_NONNULL(1); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 328f5b347b..839fe4f545 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1635,6 +1635,7 @@ virDomainDriverSetupPersistentDefBlkioParams; # hypervisor/domain_interface.h virDomainClearNetBandwidth; +virDomainInterfaceClearQoS; virDomainInterfaceDeleteDevice; virDomainInterfaceEthernetConnect; virDomainInterfaceIsVnetCompatModel; diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 89ef9416aa..1842ae8f0e 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -4052,10 +4052,7 @@ lxcDomainDetachDeviceNetLive(virDomainObj *vm, actualType = virDomainNetGetActualType(detach); /* clear network bandwidth */ - if (virDomainNetGetActualBandwidth(detach) && - virNetDevSupportsBandwidth(actualType) && - virNetDevBandwidthClear(detach->ifname)) - goto cleanup; + virDomainInterfaceClearQoS(vm->def, detach); switch (actualType) { case VIR_DOMAIN_NET_TYPE_BRIDGE: diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 054053729c..774962b0df 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -4059,11 +4059,8 @@ qemuDomainChangeNet(virQEMUDriver *driver, goto cleanup; } } else { - /* - * virNetDevBandwidthSet() doesn't clear any existing - * setting unless something new is being set. - */ - virNetDevBandwidthClear(newdev->ifname); + if (virDomainInterfaceClearQoS(vm->def, newdev) < 0) + goto cleanup; } /* If the old bandwidth was cleared out, restore qdisc. */ @@ -4800,16 +4797,7 @@ qemuDomainRemoveNetDevice(virQEMUDriver *driver, if (!(charDevAlias = qemuAliasChardevFromDevAlias(net->info.alias))) return -1; - if (virNetDevSupportsBandwidth(virDomainNetGetActualType(net))) { - if (virDomainNetDefIsOvsport(net)) { - if (virNetDevOpenvswitchInterfaceClearQos(net->ifname, vm->def->uuid) < 0) - VIR_WARN("cannot clear bandwidth setting for ovs device : %s", - net->ifname); - } else if (virNetDevBandwidthClear(net->ifname) < 0) { - VIR_WARN("cannot clear bandwidth setting for device : %s", - net->ifname); - } - } + virDomainInterfaceClearQoS(vm->def, net); /* deactivate the tap/macvtap device on the host, which could also * affect the parent device (e.g. macvtap passthrough mode sets -- 2.43.2 _______________________________________________ Devel mailing list -- devel@xxxxxxxxxxxxxxxxx To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxx