[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 1/2] Change xs_read_watch interface to return a sized array (in userspace and in kernel).



Change xs_read_watch interface to return a sized array (in userspace and in
kernel).

Add index macros (XS_WATCH_*) for accessing the array to allow for future
expansion.

Signed-off-by: Anthony Liguori <aliguori@xxxxxxxxxx>
# HG changeset patch
# User anthony@xxxxxxxxxxxxxxxxxxxxx
# Node ID 355bc8009bb6cf6be5b0474b84984acf1dda23fb
# Parent  85f92475b9437fcd10bf1ae105f53b0abe963050
Change xs_read_watch interface to return a sized array (in userspace and in
kernel).

Add index macros (XS_WATCH_*) for accessing the array to allow for future
expansion.

Signed-off-by: Anthony Liguori <aliguori@xxxxxxxxxx>

diff -r 85f92475b943 -r 355bc8009bb6 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Mon Oct  3 
19:14:02 2005 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Mon Oct  3 
23:37:48 2005 -0500
@@ -200,14 +200,9 @@
        return buffer;
 }
 
-char **xenbus_directory(const char *dir, const char *node, unsigned int *num)
-{
-       char *strings, *p, **ret;
-       unsigned int len;
-
-       strings = xs_single(XS_DIRECTORY, join(dir, node), &len);
-       if (IS_ERR(strings))
-               return (char **)strings;
+static char **split(char *strings, unsigned int len, unsigned int *num)
+{
+       char *p, **ret;
 
        /* Count the strings. */
        *num = count_strings(strings, len);
@@ -224,7 +219,20 @@
        strings = (char *)&ret[*num];
        for (p = strings, *num = 0; p < strings + len; p += strlen(p) + 1)
                ret[(*num)++] = p;
+
        return ret;
+}
+
+char **xenbus_directory(const char *dir, const char *node, unsigned int *num)
+{
+       char *strings;
+       unsigned int len;
+
+       strings = xs_single(XS_DIRECTORY, join(dir, node), &len);
+       if (IS_ERR(strings))
+               return (char **)strings;
+
+       return split(strings, len, num);
 }
 EXPORT_SYMBOL(xenbus_directory);
 
@@ -425,18 +433,19 @@
        return xs_error(xs_talkv(XS_WATCH, iov, ARRAY_SIZE(iov), NULL));
 }
 
-static char *xs_read_watch(char **token)
+static char **xs_read_watch(unsigned int *num)
 {
        enum xsd_sockmsg_type type;
-       char *ret;
-
-       ret = read_reply(&type, NULL);
-       if (IS_ERR(ret))
-               return ret;
+       char *strings;
+       unsigned int len;
+
+       strings = read_reply(&type, &len);
+       if (IS_ERR(strings))
+               return (char **)strings;
 
        BUG_ON(type != XS_WATCH_EVENT);
-       *token = ret + strlen(ret) + 1;
-       return ret;
+
+       return split(strings, len, num);
 }
 
 static int xs_acknowledge_watch(const char *token)
@@ -519,8 +528,8 @@
 static int watch_thread(void *unused)
 {
        for (;;) {
-               char *token;
-               char *node = NULL;
+               char **vec = NULL;
+               unsigned int num;
 
                wait_event(xb_waitq, xs_input_avail());
 
@@ -530,23 +539,23 @@
                 */
                down(&xenbus_lock);
                if (xs_input_avail())
-                       node = xs_read_watch(&token);
-
-               if (node && !IS_ERR(node)) {
+                       vec = xs_read_watch(&num);
+
+               if (vec && !IS_ERR(vec)) {
                        struct xenbus_watch *w;
                        int err;
 
-                       err = xs_acknowledge_watch(token);
+                       err = xs_acknowledge_watch(vec[XS_WATCH_TOKEN]);
                        if (err)
                                printk(KERN_WARNING "XENBUS ack %s fail %i\n",
-                                      node, err);
-                       w = find_watch(token);
+                                      vec[XS_WATCH_TOKEN], err);
+                       w = find_watch(vec[XS_WATCH_TOKEN]);
                        BUG_ON(!w);
-                       w->callback(w, node);
-                       kfree(node);
-               } else if (node)
+                       w->callback(w, vec[XS_WATCH_PATH]);
+                       kfree(vec);
+               } else if (vec)
                        printk(KERN_WARNING "XENBUS xs_read_watch: %li\n",
-                              PTR_ERR(node));
+                              PTR_ERR(vec));
                up(&xenbus_lock);
        }
 }
diff -r 85f92475b943 -r 355bc8009bb6 tools/blktap/xenbus.c
--- a/tools/blktap/xenbus.c     Mon Oct  3 19:14:02 2005 +0100
+++ b/tools/blktap/xenbus.c     Mon Oct  3 23:37:48 2005 -0500
@@ -251,13 +251,14 @@
     char *node = NULL;
     struct xenbus_watch *w;
     int er;
-
-    res = xs_read_watch(h);
+    unsigned int num;
+
+    res = xs_read_watch(h, &num);
     if (res == NULL) 
         return -EAGAIN; /* in O_NONBLOCK, read_watch returns 0... */
 
-    node  = res[0];
-    token = res[1];
+    node  = res[XS_WATCH_PATH];
+    token = res[XS_WATCH_TOKEN];
 
     er = xs_acknowledge_watch(h, token);
     if (er == 0)
diff -r 85f92475b943 -r 355bc8009bb6 tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Mon Oct  3 19:14:02 2005 +0100
+++ b/tools/console/daemon/io.c Mon Oct  3 23:37:48 2005 -0500
@@ -477,14 +477,15 @@
        char **vec;
        int domid;
        struct domain *dom;
-
-       vec = xs_read_watch(xs);
+       unsigned int num;
+
+       vec = xs_read_watch(xs, &num);
        if (!vec)
                return;
 
-       if (!strcmp(vec[1], "domlist"))
+       if (!strcmp(vec[XS_WATCH_TOKEN], "domlist"))
                enum_domains();
-       else if (sscanf(vec[1], "dom%u", &domid) == 1) {
+       else if (sscanf(vec[XS_WATCH_TOKEN], "dom%u", &domid) == 1) {
                dom = lookup_domain(domid);
                if (dom->is_dead == false)
                        domain_create_ring(dom);
diff -r 85f92475b943 -r 355bc8009bb6 tools/python/xen/lowlevel/xs/xs.c
--- a/tools/python/xen/lowlevel/xs/xs.c Mon Oct  3 19:14:02 2005 +0100
+++ b/tools/python/xen/lowlevel/xs/xs.c Mon Oct  3 23:37:48 2005 -0500
@@ -462,19 +462,20 @@
     char **xsval = NULL;
     PyObject *token;
     int i;
+    unsigned int num;
 
     if (!xh)
         goto exit;
     if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec))
         goto exit;
     Py_BEGIN_ALLOW_THREADS
-    xsval = xs_read_watch(xh);
-    Py_END_ALLOW_THREADS
-    if (!xsval) {
-        PyErr_SetFromErrno(PyExc_RuntimeError);
-        goto exit;
-    }
-    if (sscanf(xsval[1], "%li", (unsigned long *)&token) != 1) {
+    xsval = xs_read_watch(xh, &num);
+    Py_END_ALLOW_THREADS
+    if (!xsval) {
+        PyErr_SetFromErrno(PyExc_RuntimeError);
+        goto exit;
+    }
+    if (sscanf(xsval[XS_WATCH_TOKEN], "%li", (unsigned long *)&token) != 1) {
         PyErr_SetString(PyExc_RuntimeError, "invalid token");
         goto exit;
     }
@@ -487,7 +488,7 @@
         goto exit;
     }
     /* Create tuple (path, token). */
-    val = Py_BuildValue("(sO)", xsval[0], token);
+    val = Py_BuildValue("(sO)", xsval[XS_WATCH_PATH], token);
  exit:
     if (xsval)
         free(xsval);
diff -r 85f92475b943 -r 355bc8009bb6 tools/xenstore/xenstored.h
--- a/tools/xenstore/xenstored.h        Mon Oct  3 19:14:02 2005 +0100
+++ b/tools/xenstore/xenstored.h        Mon Oct  3 23:37:48 2005 -0500
@@ -86,4 +86,12 @@
        /* Generally followed by nul-terminated string(s). */
 };
 
+/* FIXME we shouldn't have to declare this in two places, what's the right
+   way to share things between xenstored.h and xs.h? */
+enum xs_watch_type
+{
+       XS_WATCH_PATH = 0,
+       XS_WATCH_TOKEN,
+};
+
 #endif /* _XENSTORED_H */
diff -r 85f92475b943 -r 355bc8009bb6 tools/xenstore/xs.c
--- a/tools/xenstore/xs.c       Mon Oct  3 19:14:02 2005 +0100
+++ b/tools/xenstore/xs.c       Mon Oct  3 23:37:48 2005 -0500
@@ -449,25 +449,44 @@
  * Returns array of two pointers: path and token, or NULL.
  * Call free() after use.
  */
-char **xs_read_watch(struct xs_handle *h)
+char **xs_read_watch(struct xs_handle *h, unsigned int *num)
 {
        struct xsd_sockmsg msg;
        char **ret;
+       char *strings;
+       unsigned int num_strings, i;
 
        if (!read_all(h->fd, &msg, sizeof(msg)))
                return NULL;
 
        assert(msg.type == XS_WATCH_EVENT);
-       ret = malloc(sizeof(char *)*2 + msg.len);
-       if (!ret)
-               return NULL;
-
-       ret[0] = (char *)(ret + 2);
-       if (!read_all(h->fd, ret[0], msg.len)) {
-               free_no_errno(ret);
-               return NULL;
-       }
-       ret[1] = ret[0] + strlen(ret[0]) + 1;
+       strings = malloc(msg.len);
+       if (!strings)
+               return NULL;
+
+       if (!read_all(h->fd, strings, msg.len)) {
+               free_no_errno(strings);
+               return NULL;
+       }
+
+       num_strings = xs_count_strings(strings, msg.len);
+
+       ret = malloc(sizeof(char*) * num_strings + msg.len);
+       if (!ret) {
+               free_no_errno(strings);
+               return NULL;
+       }
+
+       ret[0] = (char *)(ret + num_strings);
+       memcpy(ret[0], strings, msg.len);
+       free(strings);
+
+       for (i = 1; i < num_strings; i++) {
+               ret[i] = ret[i - 1] + strlen(ret[i - 1]) + 1;
+       }
+
+       *num = num_strings;
+
        return ret;
 }
 
diff -r 85f92475b943 -r 355bc8009bb6 tools/xenstore/xs.h
--- a/tools/xenstore/xs.h       Mon Oct  3 19:14:02 2005 +0100
+++ b/tools/xenstore/xs.h       Mon Oct  3 23:37:48 2005 -0500
@@ -23,6 +23,14 @@
 #include "xs_lib.h"
 
 struct xs_handle;
+
+/* FIXME we shouldn't have to declare this in two places, what's the right
+   way to share things between xenstored.h and xs.h? */
+enum xs_watch_type
+{
+       XS_WATCH_PATH = 0,
+       XS_WATCH_TOKEN,
+};
 
 /* On failure, these routines set errno. */
 
@@ -91,10 +99,10 @@
 int xs_fileno(struct xs_handle *h);
 
 /* Find out what node change was on (will block if nothing pending).
- * Returns array of two pointers: path and token, or NULL.
- * Call free() after use.
+ * Returns array containing the path and token. Use XS_WATCH_* to access these
+ * elements. Call free() after use.
  */
-char **xs_read_watch(struct xs_handle *h);
+char **xs_read_watch(struct xs_handle *h, unsigned int *num);
 
 /* Acknowledge watch on node.  Watches must be acknowledged before
  * any other watches can be read.
diff -r 85f92475b943 -r 355bc8009bb6 tools/xenstore/xs_test.c
--- a/tools/xenstore/xs_test.c  Mon Oct  3 19:14:02 2005 +0100
+++ b/tools/xenstore/xs_test.c  Mon Oct  3 23:37:48 2005 -0500
@@ -489,8 +489,11 @@
 
        /* Convenient for testing... */
        if (swallow_event) {
-               char **vec = xs_read_watch(handles[handle]);
-               if (!vec || !streq(vec[0], node) || !streq(vec[1], token))
+               unsigned int num;
+               char **vec = xs_read_watch(handles[handle], &num);
+               if (!vec ||
+                   !streq(vec[XS_WATCH_PATH], node) ||
+                   !streq(vec[XS_WATCH_TOKEN], token))
                        failed(handle);
                if (!xs_acknowledge_watch(handles[handle], token))
                        failed(handle);
@@ -522,6 +525,7 @@
        struct timeval tv = {.tv_sec = timeout_ms/1000,
                             .tv_usec = (timeout_ms*1000)%1000000 };
        fd_set set;
+       unsigned int num;
 
        if (xs_fileno(handles[handle]) != -2) {
                /* Manually select here so we can time out gracefully. */
@@ -537,16 +541,17 @@
                set_timeout();
        }
 
-       vec = xs_read_watch(handles[handle]);
+       vec = xs_read_watch(handles[handle], &num);
        if (!vec) {
                failed(handle);
                return;
        }
 
        if (handle)
-               output("%i:%s:%s\n", handle, vec[0], vec[1]);
+               output("%i:%s:%s\n", handle,
+                      vec[XS_WATCH_PATH], vec[XS_WATCH_TOKEN]);
        else
-               output("%s:%s\n", vec[0], vec[1]);
+               output("%s:%s\n", vec[XS_WATCH_PATH], vec[XS_WATCH_TOKEN]);
        free(vec);
 }
 
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.