In-Reply-To:
This is an update (of an update :-) of Kyle Mestery's patch series v3
by the same name:
https://www.redhat.com/archives/libvir-list/2012-October/msg00014.html
I've updated it according to the comments in the review of patch 1/3
of that series:
https://www.redhat.com/archives/libvir-list/2012-October/msg01224.html
and also according to Michal and Eric's comments on v4:
https://www.redhat.com/archives/libvir-list/2012-October/msg01227.html
(interdiffs for those last changes are attached to patches 1/3 and 2/3)
It now needs a counter-review from Kyle, along with verification that
it actually works (since I don't have the proper setup to test it
handy).
******************************************
This series of commits has the end goal of allowing per-port data stored
in the Open vSwitch DB to be transported during live migration. This is
done by first providing a generic infrastructure for transporting network
data, adding some utility functions specific to Open vSwitch, and hooking
the two together.
The framework provided is generic in that other networking data could be
transferred as well by simply adding in additional hooks as needed.
Kyle Mestery (3):
Add the ability for the Qemu V3 migration protocol to include
transporting network configuration. A generic framework is proposed
with this patch to allow for the transfer of opaque data.
Add utility functions for Open vSwitch to both save per-port data
before a live migration, and restore the per-port data after a
live migration.
Transport Open vSwitch per-port data during live migration by
using the utility functions
virNetDevOpenvswitchGetMigrateData() and
virNetDevOpenvswitchSetMigrateData().
****************************************************************
interdiff for PATCH 1/3:
* remove extra {} in one place, add them in a couple others (I like
braces when the condition is multi-line too).
* don't emit <network> element at all if all the vporttypes are NONE
* fix position of [i] in comment
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 67276f0..7219e78 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -184,9 +184,8 @@ static void qemuMigrationCookieFree(qemuMigrationCookiePtr mig)
if (mig->flags & QEMU_MIGRATION_COOKIE_GRAPHICS)
qemuMigrationCookieGraphicsFree(mig->graphics);
- if (mig->flags & QEMU_MIGRATION_COOKIE_NETWORK) {
+ if (mig->flags & QEMU_MIGRATION_COOKIE_NETWORK)
qemuMigrationCookieNetworkFree(mig->network);
- }
VIR_FREE(mig->localHostname);
VIR_FREE(mig->remoteHostname);
@@ -506,11 +505,15 @@ qemuMigrationCookieNetworkXMLFormat(virBufferPtr buf,
qemuMigrationCookieNetworkPtr optr)
{
int i;
+ bool empty = true;
- virBufferAsprintf(buf, " <network>\n");
for (i = 0; i < optr->nnets; i++) {
- /* If optr->net.vporttype[i] is not set, there is nothing to transfer */
+ /* If optr->net[i].vporttype is not set, there is nothing to transfer */
if (optr->net[i].vporttype != VIR_NETDEV_VPORT_PROFILE_NONE) {
+ if (empty) {
+ virBufferAsprintf(buf, " <network>\n");
+ empty = false;
+ }
virBufferAsprintf(buf, " <interface index='%d'
vporttype='%s'",
i, virNetDevVPortTypeToString(optr->net[i].vporttype));
if (optr->net[i].portdata) {
@@ -523,7 +526,8 @@ qemuMigrationCookieNetworkXMLFormat(virBufferPtr buf,
}
}
}
- virBufferAddLit(buf, " </network>\n");
+ if (!empty)
+ virBufferAddLit(buf, " </network>\n");
}
@@ -921,8 +925,9 @@ qemuMigrationBakeCookie(qemuMigrationCookiePtr mig,
return -1;
if (flags & QEMU_MIGRATION_COOKIE_NETWORK &&
- qemuMigrationCookieAddNetwork(mig, driver, dom) < 0)
+ qemuMigrationCookieAddNetwork(mig, driver, dom) < 0) {
return -1;
+ }
if (!(*cookieout = qemuMigrationCookieXMLFormatStr(driver, mig)))
return -1;
@@ -2258,8 +2263,9 @@ cleanup:
if (ret == 0 &&
qemuMigrationBakeCookie(mig, driver, vm, cookieout, cookieoutlen,
QEMU_MIGRATION_COOKIE_PERSISTENT |
- QEMU_MIGRATION_COOKIE_NETWORK) < 0)
+ QEMU_MIGRATION_COOKIE_NETWORK) < 0) {
VIR_WARN("Unable to encode migration cookie");
+ }
qemuMigrationCookieFree(mig);
***************************************************************************
interdiff for patch 2/3:
* fix bad indentation I coincidentally just noticed at end of abutting
function
* use "cleanup" label instead of error, and default ret = -1 to be
consistent.
* use virCommandAddArgFormat instead of virBufferAsprintf.
diff --git a/src/util/virnetdevopenvswitch.c b/src/util/virnetdevopenvswitch.c
index 841f693..5bce611 100644
--- a/src/util/virnetdevopenvswitch.c
+++ b/src/util/virnetdevopenvswitch.c
@@ -173,11 +173,11 @@ int virNetDevOpenvswitchRemovePort(const char *brname
ATTRIBUTE_UNUSED, const ch
_("Unable to delete port %s from OVS"), ifname);
goto cleanup;
}
- ret = 0;
- cleanup:
- virCommandFree(cmd);
- return ret;
+ ret = 0;
+cleanup:
+ virCommandFree(cmd);
+ return ret;
}
/**
@@ -192,7 +192,7 @@ int virNetDevOpenvswitchRemovePort(const char *brname
ATTRIBUTE_UNUSED, const ch
int virNetDevOpenvswitchGetMigrateData(char **migrate, const char *ifname)
{
virCommandPtr cmd = NULL;
- int ret = 0;
+ int ret = -1;
cmd = virCommandNewArgList(OVSVSCTL, "--timeout=5", "get",
"Interface",
ifname, "external_ids:PortData", NULL);
@@ -204,14 +204,13 @@ int virNetDevOpenvswitchGetMigrateData(char **migrate, const char
*ifname)
virReportSystemError(VIR_ERR_INTERNAL_ERROR,
_("Unable to run command to get OVS port data for
"
"interface %s"), ifname);
- ret = -1;
- goto error;
+ goto cleanup;
}
/* Wipeout the newline */
(*migrate)[strlen(*migrate) - 1] = '\0';
-
-error:
+ ret = 0;
+cleanup:
return ret;
}
@@ -227,25 +226,21 @@ error:
int virNetDevOpenvswitchSetMigrateData(char *migrate, const char *ifname)
{
virCommandPtr cmd = NULL;
- int ret = 0;
- virBufferPtr buf;
-
- if (VIR_ALLOC(buf) < 0) {
- ret = -1;
- goto error;
- }
+ int ret = -1;
- virBufferAsprintf(buf, "external_ids:PortData=%s", migrate);
+ cmd = virCommandNewArgList(OVSVSCTL, "--timeout=5", "set",
+ "Interface", ifname, NULL);
+ virCommandAddArgFormat(cmd, "external_ids:PortData=%s", migrate);
- cmd = virCommandNewArgList(OVSVSCTL, "--timeout=5", "set",
"Interface", ifname,
- virBufferCurrentContent(buf), NULL);
/* Run the command */
- if ((ret = virCommandRun(cmd, NULL)) < 0) {
+ if (virCommandRun(cmd, NULL) < 0) {
virReportSystemError(VIR_ERR_INTERNAL_ERROR,
_("Unable to run command to set OVS port data for
"
"interface %s"), ifname);
+ goto cleanup;
}
-error:
+ ret = 0;
+cleanup:
return ret;
}