[libvirt] [PATCH 8/9] Support job cancellation in QEMU driver
Daniel Veillard
veillard at redhat.com
Fri Feb 26 18:04:27 UTC 2010
On Thu, Feb 18, 2010 at 03:56:14PM +0000, Daniel P. Berrange wrote:
> This supports cancellation of jobs for the QEMU driver against
> the virDomainMigrate, virDomainSave and virDomainCoreDump APIs.
> It is not yet supported for the virDomainRestore API, although
> it is desirable.
>
> * src/qemu/qemu_driver.c: Issue 'migrate_cancel' command if
> virDomainAbortJob is issued during a migration operation
> * tools/virsh.c: Add a domjobabort command
[...]
> - 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
ah a cleanup too
> + * 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;
>
> @@ -331,6 +332,7 @@ static int qemuDomainObjBeginJob(virDomainObjPtr obj)
> }
> }
> priv->jobActive = 1;
> + priv->jobCancel = 0;
> priv->jobStart = (now.tv_sec * 1000ull) + (now.tv_usec / 1000);
> memset(&priv->jobInfo, 0, sizeof(priv->jobInfo));
>
> @@ -377,6 +379,7 @@ static int qemuDomainObjBeginJobWithDriver(struct qemud_driver *driver,
> }
> }
> priv->jobActive = 1;
> + priv->jobCancel = 0;
> priv->jobStart = (now.tv_sec * 1000ull) + (now.tv_usec / 1000);
> memset(&priv->jobInfo, 0, sizeof(priv->jobInfo));
>
> @@ -401,6 +404,7 @@ static int ATTRIBUTE_RETURN_CHECK qemuDomainObjEndJob(virDomainObjPtr obj)
> qemuDomainObjPrivatePtr priv = obj->privateData;
>
> priv->jobActive = 0;
> + priv->jobCancel = 0;
> priv->jobStart = 0;
> memset(&priv->jobInfo, 0, sizeof(priv->jobInfo));
> virCondSignal(&priv->jobCond);
> @@ -3945,6 +3949,17 @@ qemuDomainWaitForMigrationComplete(struct qemud_driver *driver, virDomainObjPtr
> 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,
> @@ -8811,6 +8826,49 @@ cleanup:
> }
>
>
> +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",
> @@ -8891,7 +8949,7 @@ static virDriver qemuDriver = {
> qemuCPUCompare, /* cpuCompare */
> qemuCPUBaseline, /* cpuBaseline */
> qemuDomainGetJobInfo, /* domainGetJobInfo */
> - NULL, /* domainFinishJob */
> + qemuDomainAbortJob, /* domainAbortJob */
> };
>
>
> diff --git a/tools/virsh.c b/tools/virsh.c
> index 0bf03df..cea92fd 100644
> --- a/tools/virsh.c
> +++ b/tools/virsh.c
> @@ -1899,6 +1899,42 @@ cleanup:
> }
>
> /*
> + * "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
> */
> static const vshCmdInfo info_freecell[] = {
> @@ -7613,6 +7649,7 @@ static const vshCmdDef commands[] = {
> {"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},
ACK, but virsh.pod need to be extended with the new entry points,
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel at veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
More information about the libvir-list
mailing list