On Thu, Nov 19, 2015 at 01:09:21PM +0100, Jiri Denemark wrote:
Using qemuProcess{Init,Launch,FinishStartup} allows us to run
pre-migration commands on destination before asking QEMU to wait for
incoming migration data.
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/qemu/qemu_migration.c | 68 ++++++++++++++++++++++++++++++-----------------
1 file changed, 44 insertions(+), 24 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index b6525df..fe9b1ff 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3291,14 +3291,16 @@ qemuMigrationPrepareCleanup(virQEMUDriverPtr driver,
qemuDomainObjDiscardAsyncJob(driver, vm);
}
-static char *
+static qemuProcessIncomingDefPtr
qemuMigrationPrepareIncoming(virDomainObjPtr vm,
bool tunnel,
const char *protocol,
const char *listenAddress,
- unsigned short port)
+ unsigned short port,
+ int fd)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
+ qemuProcessIncomingDefPtr inc = NULL;
char *migrateFrom = NULL;
if (tunnel) {
@@ -3361,8 +3363,11 @@ qemuMigrationPrepareIncoming(virDomainObjPtr vm,
goto cleanup;
}
+ inc = qemuProcessIncomingDefNew(priv->qemuCaps, migrateFrom, fd, NULL);
+
cleanup:
- return migrateFrom;
+ VIR_FREE(migrateFrom);
+ return inc;
}
static int
@@ -3393,8 +3398,11 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
char *xmlout = NULL;
unsigned int cookieFlags;
virCapsPtr caps = NULL;
- char *migrateFrom = NULL;
+ qemuProcessIncomingDefPtr incoming = NULL;
bool taint_hook = false;
+ bool stopProcess = false;
+ bool relabel = false;
+ int rv;
virNWFilterReadLockFilterUpdates();
@@ -3528,28 +3536,29 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
goto stopjob;
}
- virObjectUnref(priv->qemuCaps);
- priv->qemuCaps = virQEMUCapsCacheLookupCopy(driver->qemuCapsCache,
- vm->def->emulator,
- vm->def->os.machine);
- if (!priv->qemuCaps)
+ if ((rv = qemuProcessInit(driver, vm, true)) < 0) {
+ if (rv == -1)
+ stopProcess = true;
goto stopjob;
+ }
+ stopProcess = true;
With the changes in 1/7 and 5/7 this could be simple:
if (qemuProcessInit(driver, vm, true) < 0)
goto endjob/endmigjob/stobjob;
And every other goto will jump to 'stop' to make sure that the qemuProcess is
stopped too.
- if (!(migrateFrom = qemuMigrationPrepareIncoming(vm, tunnel, protocol,
- listenAddress, port)))
+ if (!(incoming = qemuMigrationPrepareIncoming(vm, tunnel, protocol,
+ listenAddress, port,
+ dataFD[0])))
goto stopjob;
+ dataFD[0] = -1; /* the FD is now owned by incoming */
- /* Start the QEMU daemon, with the same command-line arguments plus
- * -incoming $migrateFrom
- */
- if (qemuProcessStart(dconn, driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN,
- migrateFrom, dataFD[0], NULL, NULL,
- VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START,
- VIR_QEMU_PROCESS_START_PAUSED |
- VIR_QEMU_PROCESS_START_AUTODESTROY) < 0) {
- virDomainAuditStart(vm, "migrated", false);
+ rv = qemuProcessLaunch(dconn, driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN,
+ incoming, NULL,
+ VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START,
+ VIR_QEMU_PROCESS_START_AUTODESTROY);
+ if (rv < 0) {
+ if (rv == -2)
+ relabel = true;
goto stopjob;
}
+ relabel = true;
if (tunnel) {
if (virFDStreamOpen(st, dataFD[1]) < 0) {
[...]
Otherwise seems ok,
Pavel