}
+static int
+qemuDomainAbortJobPostcopy(virDomainObj *vm,
+ unsigned int flags)
+{
+ qemuDomainObjPrivate *priv = vm->privateData;
+ int rc;
+
+ if (!(flags & VIR_DOMAIN_ABORT_JOB_POSTCOPY)) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("cannot abort migration in post-copy mode"));
+ return -1;
+ }
+
+ VIR_DEBUG("Suspending post-copy migration at client request");
+
+ qemuDomainObjAbortAsyncJob(vm);
+ qemuDomainObjEnterMonitor(priv->driver, vm);
+ rc = qemuMonitorMigratePause(priv->mon);
+ qemuDomainObjExitMonitor(vm);
+
+ return rc;
+}
+
+
static int
qemuDomainAbortJobFlags(virDomainPtr dom,
unsigned int flags)
virDomainObj *vm;
int ret = -1;
qemuDomainObjPrivate *priv;
- int reason;
VIR_DEBUG("flags=0x%x", flags);
- virCheckFlags(0, -1);
+ virCheckFlags(VIR_DOMAIN_ABORT_JOB_POSTCOPY, -1);
if (!(vm = qemuDomainObjFromDomain(dom)))
goto cleanup;
priv = vm->privateData;
+ if (flags & VIR_DOMAIN_ABORT_JOB_POSTCOPY &&
+ (priv->job.asyncJob != VIR_ASYNC_JOB_MIGRATION_OUT ||
+ !virDomainObjIsPostcopy(vm, VIR_DOMAIN_JOB_OPERATION_MIGRATION_OUT))) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("current job is not outgoing migration in post-copy mode"));
+ goto endjob;
+ }
+
switch (priv->job.asyncJob) {
case VIR_ASYNC_JOB_NONE:
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
break;
case VIR_ASYNC_JOB_MIGRATION_OUT:
- if ((priv->job.current->status == VIR_DOMAIN_JOB_STATUS_POSTCOPY ||
- (virDomainObjGetState(vm, &reason) == VIR_DOMAIN_PAUSED &&
- reason == VIR_DOMAIN_PAUSED_POSTCOPY))) {
- virReportError(VIR_ERR_OPERATION_INVALID, "%s",
- _("cannot abort migration in post-copy mode"));
- goto endjob;
- }
-
- ret = qemuDomainAbortJobMigration(vm);
+ if (virDomainObjIsPostcopy(vm, VIR_DOMAIN_JOB_OPERATION_MIGRATION_OUT))
+ ret = qemuDomainAbortJobPostcopy(vm, flags);
+ else
+ ret = qemuDomainAbortJobMigration(vm);
break;
case VIR_ASYNC_JOB_SAVE:
}
+int
+qemuMonitorJSONMigratePause(qemuMonitor *mon)
+{
+ g_autoptr(virJSONValue) cmd = NULL;
+ g_autoptr(virJSONValue) reply = NULL;
+
+ if (!(cmd = qemuMonitorJSONMakeCommand("migrate-pause", NULL)))
+ return -1;
+
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ return -1;
+
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ return -1;
+
+ return 0;
+}
+
+
/* qemuMonitorJSONQueryDump:
* @mon: Monitor pointer
* @stats: Monitor dump stats
DO_TEST_GEN_DEPRECATED(qemuMonitorJSONSetMigrationDowntime, true);
DO_TEST_GEN(qemuMonitorJSONMigrate);
DO_TEST_GEN(qemuMonitorJSONMigrateRecover);
+ DO_TEST_SIMPLE("migrate-pause", qemuMonitorJSONMigratePause);
DO_TEST_GEN(qemuMonitorJSONDump);
DO_TEST_GEN(qemuMonitorJSONGraphicsRelocate);
DO_TEST_GEN(qemuMonitorJSONRemoveNetdev);