提交 3409f5bc 编写于 作者: J Jiri Denemark

qemu: Wait for migration events on domain condition

Since we already support the MIGRATION event, we just need to make sure
the domain condition is signalled whenever a p2p connection drops or the
domain is paused due to IO error and we can avoid waking up every 50 ms
to check whether something happened.
Signed-off-by: NJiri Denemark <jdenemar@redhat.com>
上级 6d2edb6a
...@@ -199,6 +199,9 @@ struct _qemuDomainObjPrivate { ...@@ -199,6 +199,9 @@ struct _qemuDomainObjPrivate {
/* Bitmaps below hold data from the auto NUMA feature */ /* Bitmaps below hold data from the auto NUMA feature */
virBitmapPtr autoNodeset; virBitmapPtr autoNodeset;
virBitmapPtr autoCpuset; virBitmapPtr autoCpuset;
bool signalIOError; /* true if the domain condition should be signalled on
I/O error */
}; };
# define QEMU_DOMAIN_DISK_PRIVATE(disk) \ # define QEMU_DOMAIN_DISK_PRIVATE(disk) \
......
...@@ -2661,20 +2661,28 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver, ...@@ -2661,20 +2661,28 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver,
{ {
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
qemuDomainJobInfoPtr jobInfo = priv->job.current; qemuDomainJobInfoPtr jobInfo = priv->job.current;
bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT);
int rv; int rv;
jobInfo->type = VIR_DOMAIN_JOB_UNBOUNDED; jobInfo->type = VIR_DOMAIN_JOB_UNBOUNDED;
while ((rv = qemuMigrationCompleted(driver, vm, asyncJob, dconn, while ((rv = qemuMigrationCompleted(driver, vm, asyncJob, dconn,
abort_on_error, storage)) != 1) { abort_on_error, storage)) != 1) {
/* Poll every 50ms for progress & to allow cancellation */
struct timespec ts = { .tv_sec = 0, .tv_nsec = 50 * 1000 * 1000ull };
if (rv < 0) if (rv < 0)
return rv; return rv;
virObjectUnlock(vm); if (events) {
nanosleep(&ts, NULL); if (virDomainObjWait(vm) < 0) {
virObjectLock(vm); jobInfo->type = VIR_DOMAIN_JOB_FAILED;
return -2;
}
} else {
/* Poll every 50ms for progress & to allow cancellation */
struct timespec ts = { .tv_sec = 0, .tv_nsec = 50 * 1000 * 1000ull };
virObjectUnlock(vm);
nanosleep(&ts, NULL);
virObjectLock(vm);
}
} }
qemuDomainJobInfoUpdateDowntime(jobInfo); qemuDomainJobInfoUpdateDowntime(jobInfo);
...@@ -4148,6 +4156,7 @@ qemuMigrationRun(virQEMUDriverPtr driver, ...@@ -4148,6 +4156,7 @@ qemuMigrationRun(virQEMUDriverPtr driver,
virErrorPtr orig_err = NULL; virErrorPtr orig_err = NULL;
unsigned int cookieFlags = 0; unsigned int cookieFlags = 0;
bool abort_on_error = !!(flags & VIR_MIGRATE_ABORT_ON_ERROR); bool abort_on_error = !!(flags & VIR_MIGRATE_ABORT_ON_ERROR);
bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT);
int rc; int rc;
VIR_DEBUG("driver=%p, vm=%p, cookiein=%s, cookieinlen=%d, " VIR_DEBUG("driver=%p, vm=%p, cookiein=%s, cookieinlen=%d, "
...@@ -4178,6 +4187,9 @@ qemuMigrationRun(virQEMUDriverPtr driver, ...@@ -4178,6 +4187,9 @@ qemuMigrationRun(virQEMUDriverPtr driver,
return -1; return -1;
} }
if (events)
priv->signalIOError = abort_on_error;
mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen, mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen,
cookieFlags | QEMU_MIGRATION_COOKIE_GRAPHICS); cookieFlags | QEMU_MIGRATION_COOKIE_GRAPHICS);
if (!mig) if (!mig)
...@@ -4387,6 +4399,9 @@ qemuMigrationRun(virQEMUDriverPtr driver, ...@@ -4387,6 +4399,9 @@ qemuMigrationRun(virQEMUDriverPtr driver,
qemuMigrationCookieFree(mig); qemuMigrationCookieFree(mig);
if (events)
priv->signalIOError = false;
if (orig_err) { if (orig_err) {
virSetError(orig_err); virSetError(orig_err);
virFreeError(orig_err); virFreeError(orig_err);
...@@ -5029,6 +5044,18 @@ doPeer2PeerMigrate3(virQEMUDriverPtr driver, ...@@ -5029,6 +5044,18 @@ doPeer2PeerMigrate3(virQEMUDriverPtr driver,
} }
static void
qemuMigrationConnectionClosed(virConnectPtr conn,
int reason,
void *opaque)
{
virDomainObjPtr vm = opaque;
VIR_DEBUG("conn=%p, reason=%d, vm=%s", conn, reason, vm->def->name);
virDomainObjBroadcast(vm);
}
static int virConnectCredType[] = { static int virConnectCredType[] = {
VIR_CRED_AUTHNAME, VIR_CRED_AUTHNAME,
VIR_CRED_PASSPHRASE, VIR_CRED_PASSPHRASE,
...@@ -5104,6 +5131,11 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver, ...@@ -5104,6 +5131,11 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
cfg->keepAliveCount) < 0) cfg->keepAliveCount) < 0)
goto cleanup; goto cleanup;
if (virConnectRegisterCloseCallback(dconn, qemuMigrationConnectionClosed,
vm, NULL) < 0) {
goto cleanup;
}
qemuDomainObjEnterRemote(vm); qemuDomainObjEnterRemote(vm);
p2p = VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn, p2p = VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
VIR_DRV_FEATURE_MIGRATION_P2P); VIR_DRV_FEATURE_MIGRATION_P2P);
...@@ -5169,6 +5201,7 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver, ...@@ -5169,6 +5201,7 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
cleanup: cleanup:
orig_err = virSaveLastError(); orig_err = virSaveLastError();
qemuDomainObjEnterRemote(vm); qemuDomainObjEnterRemote(vm);
virConnectUnregisterCloseCallback(dconn, qemuMigrationConnectionClosed);
virObjectUnref(dconn); virObjectUnref(dconn);
qemuDomainObjExitRemote(vm); qemuDomainObjExitRemote(vm);
if (orig_err) { if (orig_err) {
......
...@@ -952,6 +952,9 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED, ...@@ -952,6 +952,9 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
VIR_DEBUG("Transitioned guest %s to paused state due to IO error", vm->def->name); VIR_DEBUG("Transitioned guest %s to paused state due to IO error", vm->def->name);
if (priv->signalIOError)
virDomainObjBroadcast(vm);
virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_IOERROR); virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_IOERROR);
lifecycleEvent = virDomainEventLifecycleNewFromObj(vm, lifecycleEvent = virDomainEventLifecycleNewFromObj(vm,
VIR_DOMAIN_EVENT_SUSPENDED, VIR_DOMAIN_EVENT_SUSPENDED,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册