Re: [libvirt] [PATCH V2 03/13] libxl: Add job support to libxl driver

2014-02-19 Thread Daniel P. Berrange
On Wed, Feb 12, 2014 at 06:56:17PM -0700, Jim Fehlig wrote:
 Follows the pattern used in the QEMU driver for managing multiple,
 simultaneous jobs within the driver.
 
 Signed-off-by: Jim Fehlig jfeh...@suse.com
 ---
 
 V2:
   Add ATTRIBUTE_RETURN_CHECK to libxlDomainObjEndJob
 
  src/libxl/libxl_domain.c | 128 
 +++
  src/libxl/libxl_domain.h |  38 ++
  2 files changed, 166 insertions(+)

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 V2 03/13] libxl: Add job support to libxl driver

2014-02-12 Thread Jim Fehlig
Follows the pattern used in the QEMU driver for managing multiple,
simultaneous jobs within the driver.

Signed-off-by: Jim Fehlig jfeh...@suse.com
---

V2:
  Add ATTRIBUTE_RETURN_CHECK to libxlDomainObjEndJob

 src/libxl/libxl_domain.c | 128 +++
 src/libxl/libxl_domain.h |  38 ++
 2 files changed, 166 insertions(+)

diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
index eb2e50e..fdc4661 100644
--- a/src/libxl/libxl_domain.c
+++ b/src/libxl/libxl_domain.c
@@ -30,10 +30,18 @@
 #include virerror.h
 #include virlog.h
 #include virstring.h
+#include virtime.h
 
 #define VIR_FROM_THIS VIR_FROM_LIBXL
 
 
+VIR_ENUM_IMPL(libxlDomainJob, LIBXL_JOB_LAST,
+  none,
+  query,
+  destroy,
+  modify,
+);
+
 /* Object used to store info related to libxl event registrations */
 typedef struct _libxlEventHookInfo libxlEventHookInfo;
 typedef libxlEventHookInfo *libxlEventHookInfoPtr;
@@ -284,6 +292,119 @@ static const libxl_osevent_hooks libxl_event_callbacks = {
 .timeout_deregister = libxlDomainObjTimeoutDeregisterEventHook,
 };
 
+static int
+libxlDomainObjInitJob(libxlDomainObjPrivatePtr priv)
+{
+memset(priv-job, 0, sizeof(priv-job));
+
+if (virCondInit(priv-job.cond)  0)
+return -1;
+
+return 0;
+}
+
+static void
+libxlDomainObjResetJob(libxlDomainObjPrivatePtr priv)
+{
+struct libxlDomainJobObj *job = priv-job;
+
+job-active = LIBXL_JOB_NONE;
+job-owner = 0;
+}
+
+static void
+libxlDomainObjFreeJob(libxlDomainObjPrivatePtr priv)
+{
+ignore_value(virCondDestroy(priv-job.cond));
+}
+
+/* Give up waiting for mutex after 30 seconds */
+#define LIBXL_JOB_WAIT_TIME (1000ull * 30)
+
+/*
+ * obj must be locked before calling, libxlDriverPrivatePtr must NOT be locked
+ *
+ * This must be called by anything that will change the VM state
+ * in any way
+ *
+ * Upon successful return, the object will have its ref count increased,
+ * successful calls must be followed by EndJob eventually
+ */
+int
+libxlDomainObjBeginJob(libxlDriverPrivatePtr driver ATTRIBUTE_UNUSED,
+   virDomainObjPtr obj,
+   enum libxlDomainJob job)
+{
+libxlDomainObjPrivatePtr priv = obj-privateData;
+unsigned long long now;
+unsigned long long then;
+
+if (virTimeMillisNow(now)  0)
+return -1;
+then = now + LIBXL_JOB_WAIT_TIME;
+
+virObjectRef(obj);
+
+while (priv-job.active) {
+VIR_DEBUG(Wait normal job condition for starting job: %s,
+  libxlDomainJobTypeToString(job));
+if (virCondWaitUntil(priv-job.cond, obj-parent.lock, then)  0)
+goto error;
+}
+
+libxlDomainObjResetJob(priv);
+
+VIR_DEBUG(Starting job: %s, libxlDomainJobTypeToString(job));
+priv-job.active = job;
+priv-job.owner = virThreadSelfID();
+
+return 0;
+
+error:
+VIR_WARN(Cannot start job (%s) for domain %s;
+  current job is (%s) owned by (%d),
+ libxlDomainJobTypeToString(job),
+ obj-def-name,
+ libxlDomainJobTypeToString(priv-job.active),
+ priv-job.owner);
+
+if (errno == ETIMEDOUT)
+virReportError(VIR_ERR_OPERATION_TIMEOUT,
+   %s, _(cannot acquire state change lock));
+else
+virReportSystemError(errno,
+ %s, _(cannot acquire job mutex));
+
+virObjectUnref(obj);
+return -1;
+}
+
+/*
+ * obj must be locked before calling
+ *
+ * To be called after completing the work associated with the
+ * earlier libxlDomainBeginJob() call
+ *
+ * Returns true if the remaining reference count on obj is
+ * non-zero, false if the reference count has dropped to zero
+ * and obj is disposed.
+ */
+bool
+libxlDomainObjEndJob(libxlDriverPrivatePtr driver ATTRIBUTE_UNUSED,
+ virDomainObjPtr obj)
+{
+libxlDomainObjPrivatePtr priv = obj-privateData;
+enum libxlDomainJob job = priv-job.active;
+
+VIR_DEBUG(Stopping job: %s,
+  libxlDomainJobTypeToString(job));
+
+libxlDomainObjResetJob(priv);
+virCondSignal(priv-job.cond);
+
+return virObjectUnref(obj);
+}
+
 static void *
 libxlDomainObjPrivateAlloc(void)
 {
@@ -300,6 +421,12 @@ libxlDomainObjPrivateAlloc(void)
 return NULL;
 }
 
+if (libxlDomainObjInitJob(priv)  0) {
+virChrdevFree(priv-devs);
+virObjectUnref(priv);
+return NULL;
+}
+
 return priv;
 }
 
@@ -311,6 +438,7 @@ libxlDomainObjPrivateDispose(void *obj)
 if (priv-deathW)
 libxl_evdisable_domain_death(priv-ctx, priv-deathW);
 
+libxlDomainObjFreeJob(priv);
 virChrdevFree(priv-devs);
 libxl_ctx_free(priv-ctx);
 if (priv-logger_file)
diff --git a/src/libxl/libxl_domain.h b/src/libxl/libxl_domain.h
index 8565820..0a29d38 100644
--- a/src/libxl/libxl_domain.h
+++ b/src/libxl/libxl_domain.h
@@ -30,6 +30,31 @@
 # include libxl_conf.h