Skip to contentSkip to conversation

Change xs_read_watch interface to return a sized array (in userspace and in kernel).

PATCH In review Anthony Liguori 1 participant 1 message Oct 4, 2005 Arm/actions semi architecture

lore
Share & tools
lore
#0 lore raw

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.

# HG changeset patch
# User [email protected]
# 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.

linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c +37 -28
diff -r 85f92475b943 -r 355bc8009bb6 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
@@ -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);
 	}
 }
tools/blktap/xenbus.c +5 -4
diff -r 85f92475b943 -r 355bc8009bb6 tools/blktap/xenbus.c
@@ -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)
tools/console/daemon/io.c +5 -4
diff -r 85f92475b943 -r 355bc8009bb6 tools/console/daemon/io.c
@@ -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);
tools/python/xen/lowlevel/xs/xs.c +9 -8
diff -r 85f92475b943 -r 355bc8009bb6 tools/python/xen/lowlevel/xs/xs.c
@@ -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);
tools/xenstore/xenstored.h +8 -0
diff -r 85f92475b943 -r 355bc8009bb6 tools/xenstore/xenstored.h
@@ -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 */
tools/xenstore/xs.c +30 -11

55 lines not on this page · raw message

tools/xenstore/xs.h +11 -3
diff -r 85f92475b943 -r 355bc8009bb6 tools/xenstore/xs.h
@@ -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.
tools/xenstore/xs_test.c +10 -5
diff -r 85f92475b943 -r 355bc8009bb6 tools/xenstore/xs_test.c
@@ -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
[email protected]
http://lists.xensource.com/xen-devel