Fix up basic migration.

Basic live migration was broken by the commit that added
non-shared block support in two ways:

1)  It added a virCheckFlags() to doNativeMigrate().  Besides
the fact that typical usage of virCheckFlags() is in driver
entry points, and doNativeMigrate() is not an entry point,
it was missing important flags like VIR_MIGRATE_LIVE.  Move
the virCheckFlags to the top-level qemuDomainMigratePrepare2
and friends.

2)  It also added a memory leak in qemuMonitorTextMigrate()
by not freeing the memory used by virBufferContentAndReset().
This is fixed by storing the pointer in a temporary variable
and freeing it at the end.

With this patch in place, normal live migration works again.

v3: Instead of the churn for virCheckFlagsUI and UL, instead
always promote flags to an unsigned long and always use %lx
for the fprintf.
v2: Add back flags check, which required adding virCheckFlagsUI
and virCheckFlagsUL

Signed-off-by: Chris Lalancette <clalance@redhat.com>
This commit is contained in:
Chris Lalancette 2010-05-20 15:25:41 -04:00
parent fb3ebd0397
commit 93500040f9
3 changed files with 38 additions and 9 deletions

View File

@ -212,15 +212,16 @@
*/
# define virCheckFlags(supported, retval) \
do { \
if ((flags & ~(supported))) { \
unsigned long __unsuppflags = flags & ~(supported); \
if (__unsuppflags) { \
virReportErrorHelper(NULL, \
VIR_FROM_THIS, \
VIR_ERR_INVALID_ARG, \
__FILE__, \
__FUNCTION__, \
__LINE__, \
_("%s: unsupported flags (0x%x)"), \
__FUNCTION__, flags & ~(supported)); \
_("%s: unsupported flags (0x%lx)"), \
__FUNCTION__, __unsuppflags); \
return retval; \
} \
} while (0)

View File

@ -10174,6 +10174,15 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
int ret = -1;
int internalret;
virCheckFlags(VIR_MIGRATE_LIVE |
VIR_MIGRATE_PEER2PEER |
VIR_MIGRATE_TUNNELLED |
VIR_MIGRATE_PERSIST_DEST |
VIR_MIGRATE_UNDEFINE_SOURCE |
VIR_MIGRATE_PAUSED |
VIR_MIGRATE_NON_SHARED_DISK |
VIR_MIGRATE_NON_SHARED_INC, -1);
*uri_out = NULL;
qemuDriverLock(driver);
@ -10350,9 +10359,6 @@ static int doNativeMigrate(struct qemud_driver *driver,
qemuDomainObjPrivatePtr priv = vm->privateData;
unsigned int background_flags = 0;
virCheckFlags(VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC,
-1);
/* Issue the migrate command. */
if (STRPREFIX(uri, "tcp:") && !STRPREFIX(uri, "tcp://")) {
/* HACK: source host generates bogus URIs, so fix them up */
@ -10773,6 +10779,15 @@ qemudDomainMigratePerform (virDomainPtr dom,
int resume = 0;
qemuDomainObjPrivatePtr priv;
virCheckFlags(VIR_MIGRATE_LIVE |
VIR_MIGRATE_PEER2PEER |
VIR_MIGRATE_TUNNELLED |
VIR_MIGRATE_PERSIST_DEST |
VIR_MIGRATE_UNDEFINE_SOURCE |
VIR_MIGRATE_PAUSED |
VIR_MIGRATE_NON_SHARED_DISK |
VIR_MIGRATE_NON_SHARED_INC, -1);
qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
@ -10876,6 +10891,15 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
virErrorPtr orig_err;
int newVM = 1;
virCheckFlags(VIR_MIGRATE_LIVE |
VIR_MIGRATE_PEER2PEER |
VIR_MIGRATE_TUNNELLED |
VIR_MIGRATE_PERSIST_DEST |
VIR_MIGRATE_UNDEFINE_SOURCE |
VIR_MIGRATE_PAUSED |
VIR_MIGRATE_NON_SHARED_DISK |
VIR_MIGRATE_NON_SHARED_INC, NULL);
/* Migration failed. Save the current error so nothing squashes it */
orig_err = virSaveLastError();

View File

@ -1144,6 +1144,7 @@ static int qemuMonitorTextMigrate(qemuMonitorPtr mon,
int ret = -1;
char *safedest = qemuMonitorEscapeArg(dest);
virBuffer extra = VIR_BUFFER_INITIALIZER;
char *extrastr = NULL;
if (!safedest) {
virReportOOMError();
@ -1159,10 +1160,12 @@ static int qemuMonitorTextMigrate(qemuMonitorPtr mon,
if (virBufferError(&extra)) {
virBufferFreeAndReset(&extra);
virReportOOMError();
free(safedest);
return -1;
goto cleanup;
}
if (virAsprintf(&cmd, "migrate %s\"%s\"", virBufferContentAndReset(&extra), safedest) < 0) {
extrastr = virBufferContentAndReset(&extra);
if (virAsprintf(&cmd, "migrate %s\"%s\"", extrastr ? extrastr : "",
safedest) < 0) {
virReportOOMError();
goto cleanup;
}
@ -1191,6 +1194,7 @@ static int qemuMonitorTextMigrate(qemuMonitorPtr mon,
ret = 0;
cleanup:
VIR_FREE(extrastr);
VIR_FREE(safedest);
VIR_FREE(info);
VIR_FREE(cmd);