[libvirt] [PATCH 0/2] Handle hotplug change on VLAN configuration using OVS

This patch set allow to change VLAN configuration of running guest using OVS as networking backend. Use case here: https://www.redhat.com/archives/libvirt-users/2017-July/msg00043.html "Refactored OVS VLAN configuration" moves the code building the VLAN configuration arguments passed to ovs-vsctl into a separated function to be reused by "Handle hotplug change on VLAN configuration using OVS" which implements the handling of VLAN change into qemuDomainChangeNet. Antoine Millet (2): Refactored OVS VLAN configuration Handle hotplug change on VLAN configuration using OVS src/libvirt_private.syms | 1 + src/qemu/qemu_hotplug.c | 16 ++++- src/util/virnetdevopenvswitch.c | 145 ++++++++++++++++++++++++++++------------ src/util/virnetdevopenvswitch.h | 9 +++ 4 files changed, 127 insertions(+), 44 deletions(-) -- 2.13.2

Moved OVS VLAN configuration arguments construction into a separated function to be reused. --- src/util/virnetdevopenvswitch.c | 104 ++++++++++++++++++++++++---------------- src/util/virnetdevopenvswitch.h | 5 ++ 2 files changed, 68 insertions(+), 41 deletions(-) diff --git a/src/util/virnetdevopenvswitch.c b/src/util/virnetdevopenvswitch.c index a5ecfb691..89ed0c91c 100644 --- a/src/util/virnetdevopenvswitch.c +++ b/src/util/virnetdevopenvswitch.c @@ -64,6 +64,67 @@ virNetDevOpenvswitchAddTimeout(virCommandPtr cmd) } /** + * virNetDevOpenvswitchConstructVlans: + * @cmd: command to construct + * @virtVlan: VLAN configuration to be applied + * + * Construct the VLAN configuration parameters to be passed to ovs-vsctl command. + * + * Returns 0 in case of success or -1 in case of failure. + */ +int virNetDevOpenvswitchConstructVlans(virCommandPtr cmd, virNetDevVlanPtr virtVlan) +{ + int ret = -1; + size_t i = 0; + virBuffer buf = VIR_BUFFER_INITIALIZER; + + if (virtVlan && virtVlan->nTags > 0) { + + switch (virtVlan->nativeMode) { + case VIR_NATIVE_VLAN_MODE_TAGGED: + virCommandAddArg(cmd, "vlan_mode=native-tagged"); + virCommandAddArgFormat(cmd, "tag=%d", virtVlan->nativeTag); + break; + case VIR_NATIVE_VLAN_MODE_UNTAGGED: + virCommandAddArg(cmd, "vlan_mode=native-untagged"); + virCommandAddArgFormat(cmd, "tag=%d", virtVlan->nativeTag); + break; + case VIR_NATIVE_VLAN_MODE_DEFAULT: + default: + break; + } + + if (virtVlan->trunk) { + virBufferAddLit(&buf, "trunk="); + + /* + * Trunk ports have at least one VLAN. Do the first one + * outside the "for" loop so we can put a "," at the + * start of the for loop if there are more than one VLANs + * on this trunk port. + */ + virBufferAsprintf(&buf, "%d", virtVlan->tag[i]); + + for (i = 1; i < virtVlan->nTags; i++) { + virBufferAddLit(&buf, ","); + virBufferAsprintf(&buf, "%d", virtVlan->tag[i]); + } + + if (virBufferCheckError(&buf) < 0) + goto cleanup; + virCommandAddArg(cmd, virBufferCurrentContent(&buf)); + } else if (virtVlan->nTags) { + virCommandAddArgFormat(cmd, "tag=%d", virtVlan->tag[0]); + } + } + + ret = 0; + cleanup: + virBufferFreeAndReset(&buf); + return ret; +} + +/** * virNetDevOpenvswitchAddPort: * @brname: the bridge name * @ifname: the network interface name @@ -82,7 +143,6 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname, virNetDevVlanPtr virtVlan) { int ret = -1; - size_t i = 0; virCommandPtr cmd = NULL; char macaddrstr[VIR_MAC_STRING_BUFLEN]; char ifuuidstr[VIR_UUID_STRING_BUFLEN]; @@ -91,7 +151,6 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname, char *ifaceid_ex_id = NULL; char *profile_ex_id = NULL; char *vmid_ex_id = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; virMacAddrFormat(macaddr, macaddrstr); virUUIDFormat(ovsport->interfaceID, ifuuidstr); @@ -117,44 +176,8 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname, virCommandAddArgList(cmd, "--", "--if-exists", "del-port", ifname, "--", "add-port", brname, ifname, NULL); - if (virtVlan && virtVlan->nTags > 0) { - - switch (virtVlan->nativeMode) { - case VIR_NATIVE_VLAN_MODE_TAGGED: - virCommandAddArg(cmd, "vlan_mode=native-tagged"); - virCommandAddArgFormat(cmd, "tag=%d", virtVlan->nativeTag); - break; - case VIR_NATIVE_VLAN_MODE_UNTAGGED: - virCommandAddArg(cmd, "vlan_mode=native-untagged"); - virCommandAddArgFormat(cmd, "tag=%d", virtVlan->nativeTag); - break; - case VIR_NATIVE_VLAN_MODE_DEFAULT: - default: - break; - } - - if (virtVlan->trunk) { - virBufferAddLit(&buf, "trunk="); - - /* - * Trunk ports have at least one VLAN. Do the first one - * outside the "for" loop so we can put a "," at the - * start of the for loop if there are more than one VLANs - * on this trunk port. - */ - virBufferAsprintf(&buf, "%d", virtVlan->tag[i]); - - for (i = 1; i < virtVlan->nTags; i++) { - virBufferAddLit(&buf, ","); - virBufferAsprintf(&buf, "%d", virtVlan->tag[i]); - } - - if (virBufferCheckError(&buf) < 0) - goto cleanup; - virCommandAddArg(cmd, virBufferCurrentContent(&buf)); - } else if (virtVlan->nTags) { - virCommandAddArgFormat(cmd, "tag=%d", virtVlan->tag[0]); - } + if (virNetDevOpenvswitchConstructVlans(cmd, virtVlan) < 0) { + goto cleanup; } if (ovsport->profileID[0] == '\0') { @@ -185,7 +208,6 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname, ret = 0; cleanup: - virBufferFreeAndReset(&buf); VIR_FREE(attachedmac_ex_id); VIR_FREE(ifaceid_ex_id); VIR_FREE(vmid_ex_id); diff --git a/src/util/virnetdevopenvswitch.h b/src/util/virnetdevopenvswitch.h index 51bb1dd00..94b4c695b 100644 --- a/src/util/virnetdevopenvswitch.h +++ b/src/util/virnetdevopenvswitch.h @@ -30,11 +30,16 @@ # include "internal.h" # include "virnetdevvportprofile.h" # include "virnetdevvlan.h" +# include "vircommand.h" + # define VIR_NETDEV_OVS_DEFAULT_TIMEOUT 5 void virNetDevOpenvswitchSetTimeout(unsigned int timeout); +int virNetDevOpenvswitchConstructVlans(virCommandPtr cmd, virNetDevVlanPtr virtVlan) + ATTRIBUTE_RETURN_CHECK; + int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname, const virMacAddr *macaddr, -- 2.13.2

On 07/17/2017 05:48 PM, Antoine Millet wrote:
Moved OVS VLAN configuration arguments construction into a separated function to be reused. --- src/util/virnetdevopenvswitch.c | 104 ++++++++++++++++++++++++---------------- src/util/virnetdevopenvswitch.h | 5 ++ 2 files changed, 68 insertions(+), 41 deletions(-)
diff --git a/src/util/virnetdevopenvswitch.c b/src/util/virnetdevopenvswitch.c index a5ecfb691..89ed0c91c 100644 --- a/src/util/virnetdevopenvswitch.c +++ b/src/util/virnetdevopenvswitch.c @@ -64,6 +64,67 @@ virNetDevOpenvswitchAddTimeout(virCommandPtr cmd) }
/** + * virNetDevOpenvswitchConstructVlans: + * @cmd: command to construct + * @virtVlan: VLAN configuration to be applied + * + * Construct the VLAN configuration parameters to be passed to ovs-vsctl command. + * + * Returns 0 in case of success or -1 in case of failure. + */ +int virNetDevOpenvswitchConstructVlans(virCommandPtr cmd, virNetDevVlanPtr virtVlan) +{ + int ret = -1; + size_t i = 0; + virBuffer buf = VIR_BUFFER_INITIALIZER; + + if (virtVlan && virtVlan->nTags > 0) {
How about reversing this so that the rest of the function can be indented one level to the left? I mean: if (!virtVlan || !virtVlan->nTags) return 0; switch() { ...
+ + switch (virtVlan->nativeMode) { + case VIR_NATIVE_VLAN_MODE_TAGGED: + virCommandAddArg(cmd, "vlan_mode=native-tagged"); + virCommandAddArgFormat(cmd, "tag=%d", virtVlan->nativeTag); + break; + case VIR_NATIVE_VLAN_MODE_UNTAGGED: + virCommandAddArg(cmd, "vlan_mode=native-untagged"); + virCommandAddArgFormat(cmd, "tag=%d", virtVlan->nativeTag); + break; + case VIR_NATIVE_VLAN_MODE_DEFAULT: + default: + break; + } + + if (virtVlan->trunk) { + virBufferAddLit(&buf, "trunk="); + + /* + * Trunk ports have at least one VLAN. Do the first one + * outside the "for" loop so we can put a "," at the + * start of the for loop if there are more than one VLANs + * on this trunk port. + */ + virBufferAsprintf(&buf, "%d", virtVlan->tag[i]); + + for (i = 1; i < virtVlan->nTags; i++) { + virBufferAddLit(&buf, ","); + virBufferAsprintf(&buf, "%d", virtVlan->tag[i]); + } + + if (virBufferCheckError(&buf) < 0) + goto cleanup; + virCommandAddArg(cmd, virBufferCurrentContent(&buf)); + } else if (virtVlan->nTags) { + virCommandAddArgFormat(cmd, "tag=%d", virtVlan->tag[0]); + } + } + + ret = 0; + cleanup: + virBufferFreeAndReset(&buf); + return ret;
Indent.
+} + +/** * virNetDevOpenvswitchAddPort: * @brname: the bridge name * @ifname: the network interface name @@ -82,7 +143,6 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname, virNetDevVlanPtr virtVlan) { int ret = -1; - size_t i = 0; virCommandPtr cmd = NULL; char macaddrstr[VIR_MAC_STRING_BUFLEN]; char ifuuidstr[VIR_UUID_STRING_BUFLEN]; @@ -91,7 +151,6 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname, char *ifaceid_ex_id = NULL; char *profile_ex_id = NULL; char *vmid_ex_id = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER;
virMacAddrFormat(macaddr, macaddrstr); virUUIDFormat(ovsport->interfaceID, ifuuidstr); @@ -117,44 +176,8 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname, virCommandAddArgList(cmd, "--", "--if-exists", "del-port", ifname, "--", "add-port", brname, ifname, NULL);
- if (virtVlan && virtVlan->nTags > 0) { - - switch (virtVlan->nativeMode) { - case VIR_NATIVE_VLAN_MODE_TAGGED: - virCommandAddArg(cmd, "vlan_mode=native-tagged"); - virCommandAddArgFormat(cmd, "tag=%d", virtVlan->nativeTag); - break; - case VIR_NATIVE_VLAN_MODE_UNTAGGED: - virCommandAddArg(cmd, "vlan_mode=native-untagged"); - virCommandAddArgFormat(cmd, "tag=%d", virtVlan->nativeTag); - break; - case VIR_NATIVE_VLAN_MODE_DEFAULT: - default: - break; - } - - if (virtVlan->trunk) { - virBufferAddLit(&buf, "trunk="); - - /* - * Trunk ports have at least one VLAN. Do the first one - * outside the "for" loop so we can put a "," at the - * start of the for loop if there are more than one VLANs - * on this trunk port. - */ - virBufferAsprintf(&buf, "%d", virtVlan->tag[i]); - - for (i = 1; i < virtVlan->nTags; i++) { - virBufferAddLit(&buf, ","); - virBufferAsprintf(&buf, "%d", virtVlan->tag[i]); - } - - if (virBufferCheckError(&buf) < 0) - goto cleanup; - virCommandAddArg(cmd, virBufferCurrentContent(&buf)); - } else if (virtVlan->nTags) { - virCommandAddArgFormat(cmd, "tag=%d", virtVlan->tag[0]); - } + if (virNetDevOpenvswitchConstructVlans(cmd, virtVlan) < 0) { + goto cleanup; }
We don't use curly braces in this case.
if (ovsport->profileID[0] == '\0') { @@ -185,7 +208,6 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname,
ret = 0; cleanup: - virBufferFreeAndReset(&buf); VIR_FREE(attachedmac_ex_id); VIR_FREE(ifaceid_ex_id); VIR_FREE(vmid_ex_id); diff --git a/src/util/virnetdevopenvswitch.h b/src/util/virnetdevopenvswitch.h index 51bb1dd00..94b4c695b 100644 --- a/src/util/virnetdevopenvswitch.h +++ b/src/util/virnetdevopenvswitch.h @@ -30,11 +30,16 @@ # include "internal.h" # include "virnetdevvportprofile.h" # include "virnetdevvlan.h" +# include "vircommand.h" +
# define VIR_NETDEV_OVS_DEFAULT_TIMEOUT 5
void virNetDevOpenvswitchSetTimeout(unsigned int timeout);
+int virNetDevOpenvswitchConstructVlans(virCommandPtr cmd, virNetDevVlanPtr virtVlan) + ATTRIBUTE_RETURN_CHECK; +
I don't think you need to export this function. It can be static. Then you also don't need to include vircommand.h. Also, if you really were to export the function you'd need to adjust libvirt_private.syms accordingly.
int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname, const virMacAddr *macaddr,
Michal

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. --- src/libvirt_private.syms | 1 + src/qemu/qemu_hotplug.c | 16 +++++++++++++--- src/util/virnetdevopenvswitch.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/util/virnetdevopenvswitch.h | 4 ++++ 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 187b12b32..36caf6fbf 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2206,6 +2206,7 @@ virNetDevOpenvswitchInterfaceStats; virNetDevOpenvswitchRemovePort; virNetDevOpenvswitchSetMigrateData; virNetDevOpenvswitchSetTimeout; +virNetDevOpenvswitchUpdateVlan; # util/virnetdevtap.h diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 4bc49720b..b9ad9e6c8 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2998,6 +2998,7 @@ qemuDomainChangeNet(virQEMUDriverPtr driver, bool needReplaceDevDef = false; bool needBandwidthSet = false; bool needCoalesceChange = false; + bool needVlanUpdate = false; int ret = -1; int changeidx = -1; @@ -3279,12 +3280,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; @@ -3344,6 +3348,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. diff --git a/src/util/virnetdevopenvswitch.c b/src/util/virnetdevopenvswitch.c index 89ed0c91c..a12bc3dbc 100644 --- a/src/util/virnetdevopenvswitch.c +++ b/src/util/virnetdevopenvswitch.c @@ -459,3 +459,44 @@ 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) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to construct vlan configuration for port %s"), ifname); + 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; +} diff --git a/src/util/virnetdevopenvswitch.h b/src/util/virnetdevopenvswitch.h index 94b4c695b..aa69ade6a 100644 --- a/src/util/virnetdevopenvswitch.h +++ b/src/util/virnetdevopenvswitch.h @@ -66,4 +66,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__ */ -- 2.13.2

On 07/17/2017 05:49 PM, Antoine Millet wrote:
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. --- src/libvirt_private.syms | 1 + src/qemu/qemu_hotplug.c | 16 +++++++++++++--- src/util/virnetdevopenvswitch.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/util/virnetdevopenvswitch.h | 4 ++++ 4 files changed, 59 insertions(+), 3 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 187b12b32..36caf6fbf 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2206,6 +2206,7 @@ virNetDevOpenvswitchInterfaceStats; virNetDevOpenvswitchRemovePort; virNetDevOpenvswitchSetMigrateData; virNetDevOpenvswitchSetTimeout; +virNetDevOpenvswitchUpdateVlan;
# util/virnetdevtap.h diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 4bc49720b..b9ad9e6c8 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2998,6 +2998,7 @@ qemuDomainChangeNet(virQEMUDriverPtr driver, bool needReplaceDevDef = false; bool needBandwidthSet = false; bool needCoalesceChange = false; + bool needVlanUpdate = false; int ret = -1; int changeidx = -1;
@@ -3279,12 +3280,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;
@@ -3344,6 +3348,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. diff --git a/src/util/virnetdevopenvswitch.c b/src/util/virnetdevopenvswitch.c index 89ed0c91c..a12bc3dbc 100644 --- a/src/util/virnetdevopenvswitch.c +++ b/src/util/virnetdevopenvswitch.c @@ -459,3 +459,44 @@ 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) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to construct vlan configuration for port %s"), ifname);
This rewrites original error reported by virNetDevOpenvswitchConstructVlans().
+ 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; +}
ACK Michal

On 07/17/2017 05:48 PM, Antoine Millet wrote:
This patch set allow to change VLAN configuration of running guest using OVS as networking backend.
Use case here: https://www.redhat.com/archives/libvirt-users/2017-July/msg00043.html
"Refactored OVS VLAN configuration" moves the code building the VLAN configuration arguments passed to ovs-vsctl into a separated function to be reused by "Handle hotplug change on VLAN configuration using OVS" which implements the handling of VLAN change into qemuDomainChangeNet.
Antoine Millet (2): Refactored OVS VLAN configuration Handle hotplug change on VLAN configuration using OVS
src/libvirt_private.syms | 1 + src/qemu/qemu_hotplug.c | 16 ++++- src/util/virnetdevopenvswitch.c | 145 ++++++++++++++++++++++++++++------------ src/util/virnetdevopenvswitch.h | 9 +++ 4 files changed, 127 insertions(+), 44 deletions(-)
I've fixed all the issues I found, ACKed and pushed. Congratulations on your first libvirt contribution! Michal
participants (2)
-
Antoine Millet
-
Michal Privoznik