All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anthony Liguori <aliguori@us.ibm.com>
To: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>,
	Rusty Russell <rusty@rustcorp.com.au>,
	xen-devel <xen-devel@lists.xensource.com>
Subject: [PATCH 1/2] Change xs_read_watch interface to return a sized array (in userspace and in kernel).
Date: Mon, 03 Oct 2005 23:44:53 -0500	[thread overview]
Message-ID: <434208C5.1050601@us.ibm.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 225 bytes --]

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>

[-- Attachment #2: 7162_xs_read_watch.diff --]
[-- Type: text/x-patch, Size: 10034 bytes --]

# HG changeset patch
# User anthony@localhost.localdomain
# 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@us.ibm.com>

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);
 }
 

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

                 reply	other threads:[~2005-10-04  4:44 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=434208C5.1050601@us.ibm.com \
    --to=aliguori@us.ibm.com \
    --cc=Christian.Limpach@cl.cam.ac.uk \
    --cc=rusty@rustcorp.com.au \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.