WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 1/2] Change xs_read_watch interface to return a sized

To: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>, Rusty Russell <rusty@xxxxxxxxxxxxxxx>, xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH 1/2] Change xs_read_watch interface to return a sized array (in userspace and in kernel).
From: Anthony Liguori <aliguori@xxxxxxxxxx>
Date: Mon, 03 Oct 2005 23:44:53 -0500
Delivery-date: Tue, 04 Oct 2005 04:42:34 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mozilla Thunderbird 1.0.6 (X11/20050912)
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
<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH 1/2] Change xs_read_watch interface to return a sized array (in userspace and in kernel)., Anthony Liguori <=