typedef qemuDomainObjPrivate *qemuDomainObjPrivatePtr;
struct _qemuDomainObjPrivate {
virCond jobCond; /* Use in conjunction with main virDomainObjPtr lock */
- int jobActive; /* Non-zero if a job is active. Only 1 job is allowed at any time
- * A job includes *all* monitor commands, even those just querying
- * information, not merely actions */
+ unsigned int jobActive : 1; /* Non-zero if a job is active. Only 1 job is allowed at any time
+ * A job includes *all* monitor commands, even those just querying
+ * information, not merely actions */
+ unsigned int jobCancel : 1; /* Non-zero if a cancel request from client has arrived */
virDomainJobInfo jobInfo;
unsigned long long jobStart;
}
}
priv->jobActive = 1;
+ priv->jobCancel = 0;
priv->jobStart = (now.tv_sec * 1000ull) + (now.tv_usec / 1000);
memset(&priv->jobInfo, 0, sizeof(priv->jobInfo));
}
}
priv->jobActive = 1;
+ priv->jobCancel = 0;
priv->jobStart = (now.tv_sec * 1000ull) + (now.tv_usec / 1000);
memset(&priv->jobInfo, 0, sizeof(priv->jobInfo));
qemuDomainObjPrivatePtr priv = obj->privateData;
priv->jobActive = 0;
+ priv->jobCancel = 0;
priv->jobStart = 0;
memset(&priv->jobInfo, 0, sizeof(priv->jobInfo));
virCondSignal(&priv->jobCond);
struct timeval now;
int rc;
+ if (priv->jobCancel) {
+ priv->jobCancel = 0;
+ VIR_DEBUG0("Cancelling migration at client request");
+ qemuDomainObjEnterMonitorWithDriver(driver, vm);
+ rc = qemuMonitorMigrateCancel(priv->mon);
+ qemuDomainObjExitMonitorWithDriver(driver, vm);
+ if (rc < 0) {
+ VIR_WARN0("Unable to cancel migration");
+ }
+ }
+
qemuDomainObjEnterMonitorWithDriver(driver, vm);
rc = qemuMonitorGetMigrationStatus(priv->mon,
&status,
}
+static int qemuDomainAbortJob(virDomainPtr dom) {
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ int ret = -1;
+ qemuDomainObjPrivatePtr priv;
+
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemuReportError(VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
+ goto cleanup;
+ }
+
+ priv = vm->privateData;
+
+ if (virDomainObjIsActive(vm)) {
+ if (priv->jobActive) {
+ VIR_DEBUG("Requesting cancellation of job on vm %s", vm->def->name);
+ priv->jobCancel = 1;
+ } else {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("no job is active on the domain"));
+ goto cleanup;
+ }
+ } else {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ return ret;
+}
+
+
static virDriver qemuDriver = {
VIR_DRV_QEMU,
"QEMU",
qemuCPUCompare, /* cpuCompare */
qemuCPUBaseline, /* cpuBaseline */
qemuDomainGetJobInfo, /* domainGetJobInfo */
- NULL, /* domainFinishJob */
+ qemuDomainAbortJob, /* domainAbortJob */
};
return ret;
}
+/*
+ * "domjobabort" command
+ */
+static const vshCmdInfo info_domjobabort[] = {
+ {"help", gettext_noop("abort active domain job")},
+ {"desc", gettext_noop("Aborts the currently running domain job")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_domjobabort[] = {
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdDomjobabort(vshControl *ctl, const vshCmd *cmd)
+{
+ virDomainPtr dom;
+ int ret = TRUE;
+ unsigned int id;
+ char *str, uuid[VIR_UUID_STRING_BUFLEN];
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ return FALSE;
+
+ if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
+ return FALSE;
+
+ if (virDomainAbortJob(dom) < 0)
+ ret = FALSE;
+
+cleanup:
+ virDomainFree(dom);
+ return ret;
+}
+
/*
* "freecell" command
*/
{"domuuid", cmdDomuuid, opts_domuuid, info_domuuid},
{"dominfo", cmdDominfo, opts_dominfo, info_dominfo},
{"domjobinfo", cmdDomjobinfo, opts_domjobinfo, info_domjobinfo},
+ {"domjobabort", cmdDomjobabort, opts_domjobabort, info_domjobabort},
{"domname", cmdDomname, opts_domname, info_domname},
{"domstate", cmdDomstate, opts_domstate, info_domstate},
{"domblkstat", cmdDomblkstat, opts_domblkstat, info_domblkstat},