[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |