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
|