domain_interface: Introduce and use virDomainInterfaceClearQoS()

In QEMU and LXC drivers in a few places only
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@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
Michal Privoznik 2024-04-12 09:26:20 +02:00
parent 93ff328ea0
commit 812a146dfe
5 changed files with 38 additions and 24 deletions

View File

@ -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 void
virDomainClearNetBandwidth(virDomainDef *def) virDomainClearNetBandwidth(virDomainDef *def)
{ {
size_t i; size_t i;
virDomainNetType type;
for (i = 0; i < def->nnets; i++) { for (i = 0; i < def->nnets; i++) {
type = virDomainNetGetActualType(def->nets[i]); virDomainInterfaceClearQoS(def, def->nets[i]);
if (virDomainNetGetActualBandwidth(def->nets[i]) &&
virNetDevSupportsBandwidth(type))
virNetDevBandwidthClear(def->nets[i]->ifname);
} }
} }

View File

@ -44,5 +44,7 @@ void virDomainInterfaceDeleteDevice(virDomainDef *def,
virDomainNetDef *net, virDomainNetDef *net,
bool priv_net_created, bool priv_net_created,
char *stateDir); char *stateDir);
int virDomainInterfaceClearQoS(virDomainDef *def,
virDomainNetDef *net);
void virDomainClearNetBandwidth(virDomainDef *def) void virDomainClearNetBandwidth(virDomainDef *def)
ATTRIBUTE_NONNULL(1); ATTRIBUTE_NONNULL(1);

View File

@ -1635,6 +1635,7 @@ virDomainDriverSetupPersistentDefBlkioParams;
# hypervisor/domain_interface.h # hypervisor/domain_interface.h
virDomainClearNetBandwidth; virDomainClearNetBandwidth;
virDomainInterfaceClearQoS;
virDomainInterfaceDeleteDevice; virDomainInterfaceDeleteDevice;
virDomainInterfaceEthernetConnect; virDomainInterfaceEthernetConnect;
virDomainInterfaceIsVnetCompatModel; virDomainInterfaceIsVnetCompatModel;

View File

@ -4052,10 +4052,7 @@ lxcDomainDetachDeviceNetLive(virDomainObj *vm,
actualType = virDomainNetGetActualType(detach); actualType = virDomainNetGetActualType(detach);
/* clear network bandwidth */ /* clear network bandwidth */
if (virDomainNetGetActualBandwidth(detach) && virDomainInterfaceClearQoS(vm->def, detach);
virNetDevSupportsBandwidth(actualType) &&
virNetDevBandwidthClear(detach->ifname))
goto cleanup;
switch (actualType) { switch (actualType) {
case VIR_DOMAIN_NET_TYPE_BRIDGE: case VIR_DOMAIN_NET_TYPE_BRIDGE:

View File

@ -4059,11 +4059,8 @@ qemuDomainChangeNet(virQEMUDriver *driver,
goto cleanup; goto cleanup;
} }
} else { } else {
/* if (virDomainInterfaceClearQoS(vm->def, newdev) < 0)
* virNetDevBandwidthSet() doesn't clear any existing goto cleanup;
* setting unless something new is being set.
*/
virNetDevBandwidthClear(newdev->ifname);
} }
/* If the old bandwidth was cleared out, restore qdisc. */ /* If the old bandwidth was cleared out, restore qdisc. */
@ -4800,16 +4797,7 @@ qemuDomainRemoveNetDevice(virQEMUDriver *driver,
if (!(charDevAlias = qemuAliasChardevFromDevAlias(net->info.alias))) if (!(charDevAlias = qemuAliasChardevFromDevAlias(net->info.alias)))
return -1; return -1;
if (virNetDevSupportsBandwidth(virDomainNetGetActualType(net))) { virDomainInterfaceClearQoS(vm->def, 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);
}
}
/* deactivate the tap/macvtap device on the host, which could also /* deactivate the tap/macvtap device on the host, which could also
* affect the parent device (e.g. macvtap passthrough mode sets * affect the parent device (e.g. macvtap passthrough mode sets