ia64/xen-unstable
changeset 7266:402b5eb85905
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@us.ibm.com>
kernel).
Add index macros (XS_WATCH_*) for accessing the array to allow for future
expansion.
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Fri Oct 07 15:51:53 2005 +0100 (2005-10-07) |
parents | 4b9c9b85b3a5 |
children | c45c3d6b1a60 |
files | linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c tools/blktap/xenbus.c tools/console/daemon/io.c tools/python/xen/lowlevel/xs/xs.c tools/xenstore/xenstored.h tools/xenstore/xs.c tools/xenstore/xs.h tools/xenstore/xs_test.c |
line diff
1.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Fri Oct 07 15:49:33 2005 +0100 1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Fri Oct 07 15:51:53 2005 +0100 1.3 @@ -200,14 +200,9 @@ static char *join(const char *dir, const 1.4 return buffer; 1.5 } 1.6 1.7 -char **xenbus_directory(const char *dir, const char *node, unsigned int *num) 1.8 +static char **split(char *strings, unsigned int len, unsigned int *num) 1.9 { 1.10 - char *strings, *p, **ret; 1.11 - unsigned int len; 1.12 - 1.13 - strings = xs_single(XS_DIRECTORY, join(dir, node), &len); 1.14 - if (IS_ERR(strings)) 1.15 - return (char **)strings; 1.16 + char *p, **ret; 1.17 1.18 /* Count the strings. */ 1.19 *num = count_strings(strings, len); 1.20 @@ -224,8 +219,21 @@ char **xenbus_directory(const char *dir, 1.21 strings = (char *)&ret[*num]; 1.22 for (p = strings, *num = 0; p < strings + len; p += strlen(p) + 1) 1.23 ret[(*num)++] = p; 1.24 + 1.25 return ret; 1.26 } 1.27 + 1.28 +char **xenbus_directory(const char *dir, const char *node, unsigned int *num) 1.29 +{ 1.30 + char *strings; 1.31 + unsigned int len; 1.32 + 1.33 + strings = xs_single(XS_DIRECTORY, join(dir, node), &len); 1.34 + if (IS_ERR(strings)) 1.35 + return (char **)strings; 1.36 + 1.37 + return split(strings, len, num); 1.38 +} 1.39 EXPORT_SYMBOL(xenbus_directory); 1.40 1.41 /* Check if a path exists. Return 1 if it does. */ 1.42 @@ -425,18 +433,19 @@ static int xs_watch(const char *path, co 1.43 return xs_error(xs_talkv(XS_WATCH, iov, ARRAY_SIZE(iov), NULL)); 1.44 } 1.45 1.46 -static char *xs_read_watch(char **token) 1.47 +static char **xs_read_watch(unsigned int *num) 1.48 { 1.49 enum xsd_sockmsg_type type; 1.50 - char *ret; 1.51 + char *strings; 1.52 + unsigned int len; 1.53 1.54 - ret = read_reply(&type, NULL); 1.55 - if (IS_ERR(ret)) 1.56 - return ret; 1.57 + strings = read_reply(&type, &len); 1.58 + if (IS_ERR(strings)) 1.59 + return (char **)strings; 1.60 1.61 BUG_ON(type != XS_WATCH_EVENT); 1.62 - *token = ret + strlen(ret) + 1; 1.63 - return ret; 1.64 + 1.65 + return split(strings, len, num); 1.66 } 1.67 1.68 static int xs_acknowledge_watch(const char *token) 1.69 @@ -519,8 +528,8 @@ void reregister_xenbus_watches(void) 1.70 static int watch_thread(void *unused) 1.71 { 1.72 for (;;) { 1.73 - char *token; 1.74 - char *node = NULL; 1.75 + char **vec = NULL; 1.76 + unsigned int num; 1.77 1.78 wait_event(xb_waitq, xs_input_avail()); 1.79 1.80 @@ -530,23 +539,23 @@ static int watch_thread(void *unused) 1.81 */ 1.82 down(&xenbus_lock); 1.83 if (xs_input_avail()) 1.84 - node = xs_read_watch(&token); 1.85 + vec = xs_read_watch(&num); 1.86 1.87 - if (node && !IS_ERR(node)) { 1.88 + if (vec && !IS_ERR(vec)) { 1.89 struct xenbus_watch *w; 1.90 int err; 1.91 1.92 - err = xs_acknowledge_watch(token); 1.93 + err = xs_acknowledge_watch(vec[XS_WATCH_TOKEN]); 1.94 if (err) 1.95 printk(KERN_WARNING "XENBUS ack %s fail %i\n", 1.96 - node, err); 1.97 - w = find_watch(token); 1.98 + vec[XS_WATCH_TOKEN], err); 1.99 + w = find_watch(vec[XS_WATCH_TOKEN]); 1.100 BUG_ON(!w); 1.101 - w->callback(w, node); 1.102 - kfree(node); 1.103 - } else if (node) 1.104 + w->callback(w, vec[XS_WATCH_PATH]); 1.105 + kfree(vec); 1.106 + } else if (vec) 1.107 printk(KERN_WARNING "XENBUS xs_read_watch: %li\n", 1.108 - PTR_ERR(node)); 1.109 + PTR_ERR(vec)); 1.110 up(&xenbus_lock); 1.111 } 1.112 }
2.1 --- a/tools/blktap/xenbus.c Fri Oct 07 15:49:33 2005 +0100 2.2 +++ b/tools/blktap/xenbus.c Fri Oct 07 15:51:53 2005 +0100 2.3 @@ -251,13 +251,14 @@ int xs_fire_next_watch(struct xs_handle 2.4 char *node = NULL; 2.5 struct xenbus_watch *w; 2.6 int er; 2.7 + unsigned int num; 2.8 2.9 - res = xs_read_watch(h); 2.10 + res = xs_read_watch(h, &num); 2.11 if (res == NULL) 2.12 return -EAGAIN; /* in O_NONBLOCK, read_watch returns 0... */ 2.13 2.14 - node = res[0]; 2.15 - token = res[1]; 2.16 + node = res[XS_WATCH_PATH]; 2.17 + token = res[XS_WATCH_TOKEN]; 2.18 2.19 er = xs_acknowledge_watch(h, token); 2.20 if (er == 0)
3.1 --- a/tools/console/daemon/io.c Fri Oct 07 15:49:33 2005 +0100 3.2 +++ b/tools/console/daemon/io.c Fri Oct 07 15:51:53 2005 +0100 3.3 @@ -491,14 +491,15 @@ static void handle_xs(int fd) 3.4 char **vec; 3.5 int domid; 3.6 struct domain *dom; 3.7 + unsigned int num; 3.8 3.9 - vec = xs_read_watch(xs); 3.10 + vec = xs_read_watch(xs, &num); 3.11 if (!vec) 3.12 return; 3.13 3.14 - if (!strcmp(vec[1], "domlist")) 3.15 + if (!strcmp(vec[XS_WATCH_TOKEN], "domlist")) 3.16 enum_domains(); 3.17 - else if (sscanf(vec[1], "dom%u", &domid) == 1) { 3.18 + else if (sscanf(vec[XS_WATCH_TOKEN], "dom%u", &domid) == 1) { 3.19 dom = lookup_domain(domid); 3.20 if (dom->is_dead == false) 3.21 domain_create_ring(dom);
4.1 --- a/tools/python/xen/lowlevel/xs/xs.c Fri Oct 07 15:49:33 2005 +0100 4.2 +++ b/tools/python/xen/lowlevel/xs/xs.c Fri Oct 07 15:51:53 2005 +0100 4.3 @@ -462,19 +462,20 @@ static PyObject *xspy_read_watch(PyObjec 4.4 char **xsval = NULL; 4.5 PyObject *token; 4.6 int i; 4.7 + unsigned int num; 4.8 4.9 if (!xh) 4.10 goto exit; 4.11 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec)) 4.12 goto exit; 4.13 Py_BEGIN_ALLOW_THREADS 4.14 - xsval = xs_read_watch(xh); 4.15 + xsval = xs_read_watch(xh, &num); 4.16 Py_END_ALLOW_THREADS 4.17 if (!xsval) { 4.18 PyErr_SetFromErrno(PyExc_RuntimeError); 4.19 goto exit; 4.20 } 4.21 - if (sscanf(xsval[1], "%li", (unsigned long *)&token) != 1) { 4.22 + if (sscanf(xsval[XS_WATCH_TOKEN], "%li", (unsigned long *)&token) != 1) { 4.23 PyErr_SetString(PyExc_RuntimeError, "invalid token"); 4.24 goto exit; 4.25 } 4.26 @@ -487,7 +488,7 @@ static PyObject *xspy_read_watch(PyObjec 4.27 goto exit; 4.28 } 4.29 /* Create tuple (path, token). */ 4.30 - val = Py_BuildValue("(sO)", xsval[0], token); 4.31 + val = Py_BuildValue("(sO)", xsval[XS_WATCH_PATH], token); 4.32 exit: 4.33 if (xsval) 4.34 free(xsval);
5.1 --- a/tools/xenstore/xenstored.h Fri Oct 07 15:49:33 2005 +0100 5.2 +++ b/tools/xenstore/xenstored.h Fri Oct 07 15:51:53 2005 +0100 5.3 @@ -86,4 +86,12 @@ struct xsd_sockmsg 5.4 /* Generally followed by nul-terminated string(s). */ 5.5 }; 5.6 5.7 +/* FIXME we shouldn't have to declare this in two places, what's the right 5.8 + way to share things between xenstored.h and xs.h? */ 5.9 +enum xs_watch_type 5.10 +{ 5.11 + XS_WATCH_PATH = 0, 5.12 + XS_WATCH_TOKEN, 5.13 +}; 5.14 + 5.15 #endif /* _XENSTORED_H */
6.1 --- a/tools/xenstore/xs.c Fri Oct 07 15:49:33 2005 +0100 6.2 +++ b/tools/xenstore/xs.c Fri Oct 07 15:51:53 2005 +0100 6.3 @@ -449,25 +449,44 @@ bool xs_watch(struct xs_handle *h, const 6.4 * Returns array of two pointers: path and token, or NULL. 6.5 * Call free() after use. 6.6 */ 6.7 -char **xs_read_watch(struct xs_handle *h) 6.8 +char **xs_read_watch(struct xs_handle *h, unsigned int *num) 6.9 { 6.10 struct xsd_sockmsg msg; 6.11 char **ret; 6.12 + char *strings; 6.13 + unsigned int num_strings, i; 6.14 6.15 if (!read_all(h->fd, &msg, sizeof(msg))) 6.16 return NULL; 6.17 6.18 assert(msg.type == XS_WATCH_EVENT); 6.19 - ret = malloc(sizeof(char *)*2 + msg.len); 6.20 - if (!ret) 6.21 + strings = malloc(msg.len); 6.22 + if (!strings) 6.23 return NULL; 6.24 6.25 - ret[0] = (char *)(ret + 2); 6.26 - if (!read_all(h->fd, ret[0], msg.len)) { 6.27 - free_no_errno(ret); 6.28 + if (!read_all(h->fd, strings, msg.len)) { 6.29 + free_no_errno(strings); 6.30 + return NULL; 6.31 + } 6.32 + 6.33 + num_strings = xs_count_strings(strings, msg.len); 6.34 + 6.35 + ret = malloc(sizeof(char*) * num_strings + msg.len); 6.36 + if (!ret) { 6.37 + free_no_errno(strings); 6.38 return NULL; 6.39 } 6.40 - ret[1] = ret[0] + strlen(ret[0]) + 1; 6.41 + 6.42 + ret[0] = (char *)(ret + num_strings); 6.43 + memcpy(ret[0], strings, msg.len); 6.44 + free(strings); 6.45 + 6.46 + for (i = 1; i < num_strings; i++) { 6.47 + ret[i] = ret[i - 1] + strlen(ret[i - 1]) + 1; 6.48 + } 6.49 + 6.50 + *num = num_strings; 6.51 + 6.52 return ret; 6.53 } 6.54
7.1 --- a/tools/xenstore/xs.h Fri Oct 07 15:49:33 2005 +0100 7.2 +++ b/tools/xenstore/xs.h Fri Oct 07 15:51:53 2005 +0100 7.3 @@ -24,6 +24,14 @@ 7.4 7.5 struct xs_handle; 7.6 7.7 +/* FIXME we shouldn't have to declare this in two places, what's the right 7.8 + way to share things between xenstored.h and xs.h? */ 7.9 +enum xs_watch_type 7.10 +{ 7.11 + XS_WATCH_PATH = 0, 7.12 + XS_WATCH_TOKEN, 7.13 +}; 7.14 + 7.15 /* On failure, these routines set errno. */ 7.16 7.17 /* Connect to the xs daemon. 7.18 @@ -91,10 +99,10 @@ bool xs_watch(struct xs_handle *h, const 7.19 int xs_fileno(struct xs_handle *h); 7.20 7.21 /* Find out what node change was on (will block if nothing pending). 7.22 - * Returns array of two pointers: path and token, or NULL. 7.23 - * Call free() after use. 7.24 + * Returns array containing the path and token. Use XS_WATCH_* to access these 7.25 + * elements. Call free() after use. 7.26 */ 7.27 -char **xs_read_watch(struct xs_handle *h); 7.28 +char **xs_read_watch(struct xs_handle *h, unsigned int *num); 7.29 7.30 /* Acknowledge watch on node. Watches must be acknowledged before 7.31 * any other watches can be read.
8.1 --- a/tools/xenstore/xs_test.c Fri Oct 07 15:49:33 2005 +0100 8.2 +++ b/tools/xenstore/xs_test.c Fri Oct 07 15:51:53 2005 +0100 8.3 @@ -489,8 +489,11 @@ static void do_watch(unsigned int handle 8.4 8.5 /* Convenient for testing... */ 8.6 if (swallow_event) { 8.7 - char **vec = xs_read_watch(handles[handle]); 8.8 - if (!vec || !streq(vec[0], node) || !streq(vec[1], token)) 8.9 + unsigned int num; 8.10 + char **vec = xs_read_watch(handles[handle], &num); 8.11 + if (!vec || 8.12 + !streq(vec[XS_WATCH_PATH], node) || 8.13 + !streq(vec[XS_WATCH_TOKEN], token)) 8.14 failed(handle); 8.15 if (!xs_acknowledge_watch(handles[handle], token)) 8.16 failed(handle); 8.17 @@ -522,6 +525,7 @@ static void do_waitwatch(unsigned int ha 8.18 struct timeval tv = {.tv_sec = timeout_ms/1000, 8.19 .tv_usec = (timeout_ms*1000)%1000000 }; 8.20 fd_set set; 8.21 + unsigned int num; 8.22 8.23 if (xs_fileno(handles[handle]) != -2) { 8.24 /* Manually select here so we can time out gracefully. */ 8.25 @@ -537,16 +541,17 @@ static void do_waitwatch(unsigned int ha 8.26 set_timeout(); 8.27 } 8.28 8.29 - vec = xs_read_watch(handles[handle]); 8.30 + vec = xs_read_watch(handles[handle], &num); 8.31 if (!vec) { 8.32 failed(handle); 8.33 return; 8.34 } 8.35 8.36 if (handle) 8.37 - output("%i:%s:%s\n", handle, vec[0], vec[1]); 8.38 + output("%i:%s:%s\n", handle, 8.39 + vec[XS_WATCH_PATH], vec[XS_WATCH_TOKEN]); 8.40 else 8.41 - output("%s:%s\n", vec[0], vec[1]); 8.42 + output("%s:%s\n", vec[XS_WATCH_PATH], vec[XS_WATCH_TOKEN]); 8.43 free(vec); 8.44 } 8.45