]> xenbits.xensource.com Git - qemu-xen-4.1-testing.git/commitdiff
create a callback mechanism for xenstore watches [PATCH 1/3]
authorIan Jackson <ian.jackson@eu.citrix.com>
Tue, 21 Jul 2009 14:27:00 +0000 (15:27 +0100)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Tue, 21 Jul 2009 14:27:00 +0000 (15:27 +0100)
This is a series of patch to complete the xenstore interface in qemu.

1: create a callback mecanism for xenstore watches.
2: add per domain low level xenstore functions (read/chmod/write/watch).
3: add low level functions from the root (read/write).

Signed-off-by: Jean Guyader <jean.guyader@citrix.com>
qemu-xen.h
xenstore.c

index 7c8e1107f236189b12001ecd0ae2674187682632..09d0539c39e83bfa1952f7cba361f3421c3e744c 100644 (file)
@@ -93,6 +93,9 @@ int xenstore_unsubscribe_from_hotplug_status(struct xs_handle *handle,
                                              const char *inst,
                                              const char *token);
 
+typedef void (*xenstore_callback) (const char *path, void *opaque);
+int xenstore_watch_new_callback(const char *path, xenstore_callback fptr, void *opaque);
+
  /* `danger' means that this parameter, variable or function refers to
   * an area of xenstore which is writeable by the guest and thus must
   * not be trusted by qemu code.  For variables containing xenstore
index 0618c80626d441abf5e9fbd43cc9055fe18bc62d..df5d940d8509501ef743663f00fad08fd62a7a89 100644 (file)
@@ -37,6 +37,52 @@ static QEMUTimer *insert_timer = NULL;
 #define UWAIT_MAX (30*1000000) /* thirty seconds */
 #define UWAIT     (100000)     /* 1/10th second  */
 
+struct xenstore_watch_cb_t
+{
+    char                *path;
+    xenstore_callback   cb;
+    void                *opaque;
+};
+
+static struct xenstore_watch_cb_t *xenstore_watch_callbacks = NULL;
+
+int xenstore_watch_new_callback(const char          *path,
+                                xenstore_callback   fptr,
+                                void                *opaque)
+{
+    int         i = 0, ret = 0;
+
+    ret = xs_watch(xsh, path, path);
+    if (ret == 0)
+        return 0;
+
+    if (!xenstore_watch_callbacks)
+    {
+        xenstore_watch_callbacks = malloc(sizeof (struct xenstore_watch_cb_t));
+        xenstore_watch_callbacks[0].path = NULL;
+    }
+
+    while (xenstore_watch_callbacks[i].path)
+    {
+       if (!strcmp(xenstore_watch_callbacks[i].path, path))
+       {
+           xenstore_watch_callbacks[i].cb = fptr;
+           xenstore_watch_callbacks[i].opaque = opaque;
+           return ret;
+       }
+        i++;
+    }
+
+    xenstore_watch_callbacks = realloc(xenstore_watch_callbacks,
+                                       (i + 2) * sizeof (struct xenstore_watch_cb_t));
+    xenstore_watch_callbacks[i].path = strdup(path);
+    xenstore_watch_callbacks[i].cb = fptr;
+    xenstore_watch_callbacks[i].opaque = opaque;
+    xenstore_watch_callbacks[i + 1].path = NULL;
+    return ret;
+}
+
+
 static int pasprintf(char **buf, const char *fmt, ...)
 {
     va_list ap;
@@ -869,12 +915,18 @@ void xenstore_record_dm_state(const char *state)
 void xenstore_process_event(void *opaque)
 {
     char **vec, *offset, *bpath = NULL, *buf = NULL, *drv = NULL, *image = NULL;
-    unsigned int len, num, hd_index;
+    unsigned int len, num, hd_index, i;
 
     vec = xs_read_watch(xsh, &num);
     if (!vec)
         return;
 
+    for (i = 0; xenstore_watch_callbacks &&  xenstore_watch_callbacks[i].path; i++)
+       if (xenstore_watch_callbacks[i].cb &&
+           !strcmp(vec[XS_WATCH_TOKEN], xenstore_watch_callbacks[i].path))
+            xenstore_watch_callbacks[i].cb(vec[XS_WATCH_TOKEN],
+                                           xenstore_watch_callbacks[i].opaque);
+
     if (!strcmp(vec[XS_WATCH_TOKEN], "logdirty")) {
         xenstore_process_logdirty_event();
         goto out;