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>
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