Re: [libvirt] [PATCH 07/19] qemu: Add support for job phase

2011-07-11 Thread Daniel P. Berrange
On Fri, Jul 08, 2011 at 01:34:12AM +0200, Jiri Denemark wrote:
> Asynchronous jobs may take long time to finish and may consist of
> several phases which we need to now about to help with recovery/rollback
> after libvirtd restarts.
> ---
>  src/qemu/qemu_domain.c |   75 
> +++-
>  src/qemu/qemu_domain.h |9 ++
>  2 files changed, 83 insertions(+), 1 deletions(-)

ACK

Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 07/19] qemu: Add support for job phase

2011-07-07 Thread Jiri Denemark
Asynchronous jobs may take long time to finish and may consist of
several phases which we need to now about to help with recovery/rollback
after libvirtd restarts.
---
 src/qemu/qemu_domain.c |   75 +++-
 src/qemu/qemu_domain.h |9 ++
 2 files changed, 83 insertions(+), 1 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index b26308e..d0dd764 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -65,6 +65,46 @@ VIR_ENUM_IMPL(qemuDomainAsyncJob, QEMU_ASYNC_JOB_LAST,
 );
 
 
+const char *
+qemuDomainAsyncJobPhaseToString(enum qemuDomainAsyncJob job,
+int phase ATTRIBUTE_UNUSED)
+{
+switch (job) {
+case QEMU_ASYNC_JOB_MIGRATION_OUT:
+case QEMU_ASYNC_JOB_MIGRATION_IN:
+case QEMU_ASYNC_JOB_SAVE:
+case QEMU_ASYNC_JOB_DUMP:
+case QEMU_ASYNC_JOB_NONE:
+case QEMU_ASYNC_JOB_LAST:
+; /* fall through */
+}
+
+return "none";
+}
+
+int
+qemuDomainAsyncJobPhaseFromString(enum qemuDomainAsyncJob job,
+  const char *phase)
+{
+if (!phase)
+return 0;
+
+switch (job) {
+case QEMU_ASYNC_JOB_MIGRATION_OUT:
+case QEMU_ASYNC_JOB_MIGRATION_IN:
+case QEMU_ASYNC_JOB_SAVE:
+case QEMU_ASYNC_JOB_DUMP:
+case QEMU_ASYNC_JOB_NONE:
+case QEMU_ASYNC_JOB_LAST:
+; /* fall through */
+}
+
+if (STREQ(phase, "none"))
+return 0;
+else
+return -1;
+}
+
 static void qemuDomainEventDispatchFunc(virConnectPtr conn,
 virDomainEventPtr event,
 virConnectDomainEventGenericCallback 
cb,
@@ -135,6 +175,7 @@ qemuDomainObjResetAsyncJob(qemuDomainObjPrivatePtr priv)
 struct qemuDomainJobObj *job = &priv->job;
 
 job->asyncJob = QEMU_ASYNC_JOB_NONE;
+job->phase = 0;
 job->mask = DEFAULT_JOB_MASK;
 job->start = 0;
 memset(&job->info, 0, sizeof(job->info));
@@ -151,6 +192,7 @@ qemuDomainObjRestoreJob(virDomainObjPtr obj,
 memset(job, 0, sizeof(*job));
 job->active = priv->job.active;
 job->asyncJob = priv->job.asyncJob;
+job->phase = priv->job.phase;
 
 qemuDomainObjResetJob(priv);
 qemuDomainObjResetAsyncJob(priv);
@@ -249,9 +291,15 @@ static int qemuDomainObjPrivateXMLFormat(virBufferPtr buf, 
void *data)
 virBufferAsprintf(buf, "  %s\n", 
priv->lockState);
 
 if (priv->job.active || priv->job.asyncJob) {
-virBufferAsprintf(buf, "  \n",
+virBufferAsprintf(buf, "  job.active),
   qemuDomainAsyncJobTypeToString(priv->job.asyncJob));
+if (priv->job.phase) {
+virBufferAsprintf(buf, " phase='%s'",
+  qemuDomainAsyncJobPhaseToString(
+priv->job.asyncJob, priv->job.phase));
+}
+virBufferAddLit(buf, "/>\n");
 }
 
 return 0;
@@ -384,6 +432,17 @@ static int qemuDomainObjPrivateXMLParse(xmlXPathContextPtr 
ctxt, void *data)
 }
 VIR_FREE(tmp);
 priv->job.asyncJob = async;
+
+if ((tmp = virXPathString("string(./job[1]/@phase)", ctxt))) {
+priv->job.phase = qemuDomainAsyncJobPhaseFromString(async, tmp);
+if (priv->job.phase < 0) {
+qemuReportError(VIR_ERR_INTERNAL_ERROR,
+_("Unknown job phase %s"), tmp);
+VIR_FREE(tmp);
+goto error;
+}
+VIR_FREE(tmp);
+}
 }
 
 return 0;
@@ -595,6 +654,20 @@ qemuDomainObjSaveJob(struct qemud_driver *driver, 
virDomainObjPtr obj)
 }
 
 void
+qemuDomainObjSetJobPhase(struct qemud_driver *driver,
+ virDomainObjPtr obj,
+ int phase)
+{
+qemuDomainObjPrivatePtr priv = obj->privateData;
+
+if (!priv->job.asyncJob)
+return;
+
+priv->job.phase = phase;
+qemuDomainObjSaveJob(driver, obj);
+}
+
+void
 qemuDomainObjSetAsyncJobMask(virDomainObjPtr obj,
  unsigned long long allowedJobs)
 {
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 49be3d2..7245e67 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -91,6 +91,7 @@ struct qemuDomainJobObj {
 
 virCond asyncCond;  /* Use to coordinate with async jobs */
 enum qemuDomainAsyncJob asyncJob;   /* Currently active async job */
+int phase;  /* Job phase (mainly for migrations) */
 unsigned long long mask;/* Jobs allowed during async job */
 unsigned long long start;   /* When the async job started */
 virDomainJobInfo info;  /* Async job progress data */
@@ -133,6 +134,11 @@ struct qemuDomainWatchdogEvent
 int action;
 };
 
+const char *qemuDomainAsyncJobPhaseToString(enum qemuDomainAsyncJob job,
+int phase