提交 c1a7f199 编写于 作者: J Jiri Denemark

qemu: Refactor qemuMigrationUpdateJobStatus

Once we start waiting for migration events instead of polling
query-migrate, priv->job.current will not be regularly updated anymore
because we will get the current status directly from the events. Thus
virDomainGetJob{Info,Stats} will have to query QEMU, but they can't just
blindly update priv->job.current structure. This patch introduces
qemuMigrationFetchJobStatus which just fills in a caller supplied
structure and makes qemuMigrationUpdateJobStatus a tiny wrapper around
it.
Signed-off-by: NJiri Denemark <jdenemar@redhat.com>
上级 30d94bcd
......@@ -2442,67 +2442,110 @@ qemuMigrationWaitForSpice(virDomainObjPtr vm)
return 0;
}
static void
qemuMigrationUpdateJobType(qemuDomainJobInfoPtr jobInfo)
{
switch (jobInfo->status.status) {
case QEMU_MONITOR_MIGRATION_STATUS_COMPLETED:
jobInfo->type = VIR_DOMAIN_JOB_COMPLETED;
break;
case QEMU_MONITOR_MIGRATION_STATUS_INACTIVE:
jobInfo->type = VIR_DOMAIN_JOB_NONE;
break;
case QEMU_MONITOR_MIGRATION_STATUS_ERROR:
jobInfo->type = VIR_DOMAIN_JOB_FAILED;
break;
case QEMU_MONITOR_MIGRATION_STATUS_CANCELLED:
jobInfo->type = VIR_DOMAIN_JOB_CANCELLED;
break;
case QEMU_MONITOR_MIGRATION_STATUS_SETUP:
case QEMU_MONITOR_MIGRATION_STATUS_ACTIVE:
case QEMU_MONITOR_MIGRATION_STATUS_CANCELLING:
break;
}
}
int
qemuMigrationFetchJobStatus(virQEMUDriverPtr driver,
virDomainObjPtr vm,
qemuDomainAsyncJob asyncJob,
qemuDomainJobInfoPtr jobInfo)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
int rv;
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
return -1;
memset(&jobInfo->status, 0, sizeof(jobInfo->status));
rv = qemuMonitorGetMigrationStatus(priv->mon, &jobInfo->status);
if (qemuDomainObjExitMonitor(driver, vm) < 0 || rv < 0)
return -1;
qemuMigrationUpdateJobType(jobInfo);
return qemuDomainJobInfoUpdateTime(jobInfo);
}
static int
qemuMigrationUpdateJobStatus(virQEMUDriverPtr driver,
virDomainObjPtr vm,
const char *job,
qemuDomainAsyncJob asyncJob)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
qemuMonitorMigrationStatus status;
qemuDomainJobInfoPtr jobInfo;
int ret;
qemuDomainJobInfoPtr jobInfo = priv->job.current;
qemuDomainJobInfo newInfo = *jobInfo;
memset(&status, 0, sizeof(status));
if (qemuMigrationFetchJobStatus(driver, vm, asyncJob, &newInfo) < 0)
return -1;
ret = qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob);
if (ret < 0) {
/* Guest already exited or waiting for the job timed out; nothing
* further to update. */
return ret;
}
ret = qemuMonitorGetMigrationStatus(priv->mon, &status);
*jobInfo = newInfo;
return 0;
}
if (qemuDomainObjExitMonitor(driver, vm) < 0)
return -1;
if (ret < 0 ||
qemuDomainJobInfoUpdateTime(priv->job.current) < 0)
return -1;
static int
qemuMigrationCheckJobStatus(virQEMUDriverPtr driver,
virDomainObjPtr vm,
const char *job,
qemuDomainAsyncJob asyncJob)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
qemuDomainJobInfoPtr jobInfo = priv->job.current;
ret = -1;
jobInfo = priv->job.current;
switch (status.status) {
case QEMU_MONITOR_MIGRATION_STATUS_COMPLETED:
jobInfo->type = VIR_DOMAIN_JOB_COMPLETED;
/* fall through */
case QEMU_MONITOR_MIGRATION_STATUS_SETUP:
case QEMU_MONITOR_MIGRATION_STATUS_ACTIVE:
case QEMU_MONITOR_MIGRATION_STATUS_CANCELLING:
ret = 0;
break;
if (qemuMigrationUpdateJobStatus(driver, vm, asyncJob) < 0)
return -1;
case QEMU_MONITOR_MIGRATION_STATUS_INACTIVE:
jobInfo->type = VIR_DOMAIN_JOB_NONE;
switch (jobInfo->type) {
case VIR_DOMAIN_JOB_NONE:
virReportError(VIR_ERR_OPERATION_FAILED,
_("%s: %s"), job, _("is not active"));
break;
return -1;
case QEMU_MONITOR_MIGRATION_STATUS_ERROR:
jobInfo->type = VIR_DOMAIN_JOB_FAILED;
case VIR_DOMAIN_JOB_FAILED:
virReportError(VIR_ERR_OPERATION_FAILED,
_("%s: %s"), job, _("unexpectedly failed"));
break;
return -1;
case QEMU_MONITOR_MIGRATION_STATUS_CANCELLED:
jobInfo->type = VIR_DOMAIN_JOB_CANCELLED;
case VIR_DOMAIN_JOB_CANCELLED:
virReportError(VIR_ERR_OPERATION_ABORTED,
_("%s: %s"), job, _("canceled by client"));
return -1;
case VIR_DOMAIN_JOB_BOUNDED:
case VIR_DOMAIN_JOB_UNBOUNDED:
case VIR_DOMAIN_JOB_COMPLETED:
case VIR_DOMAIN_JOB_LAST:
break;
}
jobInfo->status = status;
return ret;
return 0;
}
......@@ -2543,7 +2586,7 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver,
/* Poll every 50ms for progress & to allow cancellation */
struct timespec ts = { .tv_sec = 0, .tv_nsec = 50 * 1000 * 1000ull };
if (qemuMigrationUpdateJobStatus(driver, vm, job, asyncJob) == -1)
if (qemuMigrationCheckJobStatus(driver, vm, job, asyncJob) < 0)
goto error;
if (storage &&
......@@ -4208,8 +4251,8 @@ qemuMigrationRun(virQEMUDriverPtr driver,
* rather failed later on. Check its status before waiting for a
* connection from qemu which may never be initiated.
*/
if (qemuMigrationUpdateJobStatus(driver, vm, _("migration job"),
QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
if (qemuMigrationCheckJobStatus(driver, vm, _("migration job"),
QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
goto cancel;
while ((fd = accept(spec->dest.unix_socket.sock, NULL, NULL)) < 0) {
......
......@@ -188,4 +188,9 @@ int qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
int qemuMigrationCancel(virQEMUDriverPtr driver,
virDomainObjPtr vm);
int qemuMigrationFetchJobStatus(virQEMUDriverPtr driver,
virDomainObjPtr vm,
qemuDomainAsyncJob asyncJob,
qemuDomainJobInfoPtr jobInfo);
#endif /* __QEMU_MIGRATION_H__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册