Handle hotplug change on VLAN configuration using OVS

A new function virNetDevOpenvswitchUpdateVlan has been created to instruct
OVS of the changes. qemuDomainChangeNet has been modified to handle the
update of the VLAN configuration for a running guest and rely on
virNetDevOpenvswitchUpdateVlan to do the actual update if needed.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Antoine Millet 2017-07-17 17:49:00 +02:00 committed by Michal Privoznik
parent 695611f99e
commit e484cb3eca
4 changed files with 56 additions and 3 deletions

View File

@ -2206,6 +2206,7 @@ virNetDevOpenvswitchInterfaceStats;
virNetDevOpenvswitchRemovePort;
virNetDevOpenvswitchSetMigrateData;
virNetDevOpenvswitchSetTimeout;
virNetDevOpenvswitchUpdateVlan;
# util/virnetdevtap.h

View File

@ -3005,6 +3005,7 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
bool needReplaceDevDef = false;
bool needBandwidthSet = false;
bool needCoalesceChange = false;
bool needVlanUpdate = false;
int ret = -1;
int changeidx = -1;
@ -3286,12 +3287,15 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
virDomainNetGetActualDirectDev(newdev)) ||
virDomainNetGetActualDirectMode(olddev) != virDomainNetGetActualDirectMode(newdev) ||
!virNetDevVPortProfileEqual(virDomainNetGetActualVirtPortProfile(olddev),
virDomainNetGetActualVirtPortProfile(newdev)) ||
!virNetDevVlanEqual(virDomainNetGetActualVlan(olddev),
virDomainNetGetActualVlan(newdev))) {
virDomainNetGetActualVirtPortProfile(newdev))) {
needReconnect = true;
}
if (!virNetDevVlanEqual(virDomainNetGetActualVlan(olddev),
virDomainNetGetActualVlan(newdev))) {
needVlanUpdate = true;
}
if (olddev->linkstate != newdev->linkstate)
needLinkStateChange = true;
@ -3351,6 +3355,12 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
goto cleanup;
}
if (needVlanUpdate) {
if (virNetDevOpenvswitchUpdateVlan(newdev->ifname, &newdev->vlan) < 0)
goto cleanup;
needReplaceDevDef = true;
}
if (needReplaceDevDef) {
/* the changes above warrant replacing olddev with newdev in
* the domain's nets list.

View File

@ -460,3 +460,41 @@ virNetDevOpenvswitchGetVhostuserIfname(const char *path,
VIR_FREE(ovs_timeout);
return ret;
}
/**
* virNetDevOpenvswitchUpdateVlan:
* @ifname: the network interface name
* @virtVlan: VLAN configuration to be applied
*
* Update VLAN configuration of an OVS port.
*
* Returns 0 in case of success or -1 in case of failure.
*/
int virNetDevOpenvswitchUpdateVlan(const char *ifname,
virNetDevVlanPtr virtVlan)
{
int ret = -1;
virCommandPtr cmd = NULL;
cmd = virCommandNew(OVSVSCTL);
virNetDevOpenvswitchAddTimeout(cmd);
virCommandAddArgList(cmd,
"--", "--if-exists", "clear", "Port", ifname, "tag",
"--", "--if-exists", "clear", "Port", ifname, "trunk",
"--", "--if-exists", "clear", "Port", ifname, "vlan_mode",
"--", "--if-exists", "set", "Port", ifname, NULL);
if (virNetDevOpenvswitchConstructVlans(cmd, virtVlan) < 0)
goto cleanup;
if (virCommandRun(cmd, NULL) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unable to set vlan configuration on port %s"), ifname);
goto cleanup;
}
ret = 0;
cleanup:
virCommandFree(cmd);
return ret;
}

View File

@ -61,4 +61,8 @@ int virNetDevOpenvswitchGetVhostuserIfname(const char *path,
char **ifname)
ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NOINLINE;
int virNetDevOpenvswitchUpdateVlan(const char *ifname,
virNetDevVlanPtr virtVlan)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
#endif /* __VIR_NETDEV_OPENVSWITCH_H__ */