WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] minios: add xenbus token support and sepa

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] minios: add xenbus token support and separate watch event queues
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 17 Jan 2008 15:20:33 -0800
Delivery-date: Thu, 17 Jan 2008 15:21:38 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1200583202 0
# Node ID 76d88d1da324dea962aa5db8b8e7620315fe90a9
# Parent  acb35c1088fda17894763fbc9fc075b86da1e3d8
minios: add xenbus token support and separate watch event queues

Signed-off-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>
---
 extras/mini-os/include/xenbus.h |   43 +++++++++++-
 extras/mini-os/netfront.c       |   14 ----
 extras/mini-os/xenbus/xenbus.c  |  140 ++++++++++++++++++++++++++++++----------
 3 files changed, 148 insertions(+), 49 deletions(-)

diff -r acb35c1088fd -r 76d88d1da324 extras/mini-os/include/xenbus.h
--- a/extras/mini-os/include/xenbus.h   Thu Jan 17 15:18:38 2008 +0000
+++ b/extras/mini-os/include/xenbus.h   Thu Jan 17 15:20:02 2008 +0000
@@ -12,13 +12,45 @@ void init_xenbus(void);
    set to a malloc'd copy of the value. */
 char *xenbus_read(xenbus_transaction_t xbt, const char *path, char **value);
 
-char *xenbus_watch_path(xenbus_transaction_t xbt, const char *path);
-void wait_for_watch(void);
-char* xenbus_wait_for_value(const char*,const char*);
+/* Watch event queue */
+struct xenbus_event {
+    /* Keep these two as this for xs.c */
+    char *path;
+    char *token;
+    struct xenbus_event *next;
+};
+
+char *xenbus_watch_path_token(xenbus_transaction_t xbt, const char *path, 
const char *token, struct xenbus_event *volatile *events);
+char *xenbus_unwatch_path_token(xenbus_transaction_t xbt, const char *path, 
const char *token);
+extern struct wait_queue_head xenbus_watch_queue;
+void xenbus_wait_for_watch(void);
+char **xenbus_wait_for_watch_return(void);
+char* xenbus_wait_for_value(const char *path, const char *value);
+
+/* When no token is provided, use a global queue. */
+#define XENBUS_WATCH_PATH_TOKEN "xenbus_watch_path"
+extern struct xenbus_event * volatile xenbus_events;
+#define xenbus_watch_path(xbt, path) xenbus_watch_path_token(xbt, path, 
XENBUS_WATCH_PATH_TOKEN, NULL)
+#define xenbus_unwatch_path(xbt, path) xenbus_unwatch_path_token(xbt, path, 
XENBUS_WATCH_PATH_TOKEN)
+
 
 /* Associates a value with a path.  Returns a malloc'd error string on
    failure. */
 char *xenbus_write(xenbus_transaction_t xbt, const char *path, const char 
*value);
+
+struct write_req {
+    const void *data;
+    unsigned len;
+};
+
+/* Send a message to xenbus, in the same fashion as xb_write, and
+   block waiting for a reply.  The reply is malloced and should be
+   freed by the caller. */
+struct xsd_sockmsg *
+xenbus_msg_reply(int type,
+                 xenbus_transaction_t trans,
+                 struct write_req *io,
+                 int nr_reqs);
 
 /* Removes the value associated with a path.  Returns a malloc'd error
    string on failure. */
@@ -52,4 +84,9 @@ char *xenbus_transaction_end(xenbus_tran
 /* Read path and parse it as an integer.  Returns -1 on error. */
 int xenbus_read_integer(char *path);
 
+/* Contraction of snprintf and xenbus_write(path/node). */
+char* xenbus_printf(xenbus_transaction_t xbt,
+                                  char* node, char* path,
+                                  char* fmt, ...);
+
 #endif /* XENBUS_H__ */
diff -r acb35c1088fd -r 76d88d1da324 extras/mini-os/netfront.c
--- a/extras/mini-os/netfront.c Thu Jan 17 15:18:38 2008 +0000
+++ b/extras/mini-os/netfront.c Thu Jan 17 15:20:02 2008 +0000
@@ -26,20 +26,6 @@ struct net_info {
 
 } net_info;
 
-
-char* xenbus_printf(xenbus_transaction_t xbt,
-        char* node,char* path,
-        char* fmt,unsigned int arg)
-{
-    char fullpath[256];
-    char val[256];
-
-    sprintf(fullpath,"%s/%s",node,path);
-    sprintf(val,fmt,arg);
-    xenbus_write(xbt,fullpath,val);
-
-    return NULL;
-}
 
 
 #define NET_TX_RING_SIZE __RING_SIZE((struct netif_tx_sring *)0, PAGE_SIZE)
diff -r acb35c1088fd -r 76d88d1da324 extras/mini-os/xenbus/xenbus.c
--- a/extras/mini-os/xenbus/xenbus.c    Thu Jan 17 15:18:38 2008 +0000
+++ b/extras/mini-os/xenbus/xenbus.c    Thu Jan 17 15:20:02 2008 +0000
@@ -43,7 +43,14 @@
 
 static struct xenstore_domain_interface *xenstore_buf;
 static DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
-static DECLARE_WAIT_QUEUE_HEAD(watch_queue);
+DECLARE_WAIT_QUEUE_HEAD(xenbus_watch_queue);
+
+struct xenbus_event *volatile xenbus_events;
+static struct watch {
+    char *token;
+    struct xenbus_event *volatile *events;
+    struct watch *next;
+} *watches;
 struct xenbus_req_info 
 {
     int in_use:1;
@@ -68,16 +75,27 @@ static void memcpy_from_ring(const void 
     memcpy(dest + c1, ring, c2);
 }
 
-void wait_for_watch(void)
-{
+char **xenbus_wait_for_watch_return()
+{
+    struct xenbus_event *event;
     DEFINE_WAIT(w);
-    add_waiter(w,watch_queue);
-    schedule();
+    while (!(event = xenbus_events)) {
+        add_waiter(w, xenbus_watch_queue);
+        schedule();
+    }
     remove_waiter(w);
-    wake(current);
-}
-
-char* xenbus_wait_for_value(const char* path,const char* value)
+    xenbus_events = event->next;
+    return &event->path;
+}
+
+void xenbus_wait_for_watch(void)
+{
+    char **ret;
+    ret = xenbus_wait_for_watch_return();
+    free(ret);
+}
+
+char* xenbus_wait_for_value(const char* path, const char* value)
 {
     for(;;)
     {
@@ -91,7 +109,7 @@ char* xenbus_wait_for_value(const char* 
         free(res);
 
         if(r==0) break;
-        else wait_for_watch();
+        else xenbus_wait_for_watch();
     }
     return NULL;
 }
@@ -129,20 +147,32 @@ static void xenbus_thread_func(void *ign
 
             if(msg.type == XS_WATCH_EVENT)
             {
-                char* payload = (char*)malloc(sizeof(msg) + msg.len);
-                char *path,*token;
+               struct xenbus_event *event = malloc(sizeof(*event) + msg.len),
+                                    *volatile *events = NULL;
+               char *data = (char*)event + sizeof(*event);
+                struct watch *watch;
 
                 memcpy_from_ring(xenstore_buf->rsp,
-                    payload,
-                    MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
-                    msg.len + sizeof(msg));
-
-                path = payload + sizeof(msg);
-                token = path + strlen(path) + 1;
+                   data,
+                    MASK_XENSTORE_IDX(xenstore_buf->rsp_cons + sizeof(msg)),
+                    msg.len);
+
+               event->path = data;
+               event->token = event->path + strlen(event->path) + 1;
 
                 xenstore_buf->rsp_cons += msg.len + sizeof(msg);
-                free(payload);
-                wake_up(&watch_queue);
+
+                for (watch = watches; watch; watch = watch->next)
+                    if (!strcmp(watch->token, event->token)) {
+                        events = watch->events;
+                        break;
+                    }
+                if (!events)
+                    events = &xenbus_events;
+
+               event->next = *events;
+               *events = event;
+                wake_up(&xenbus_watch_queue);
             }
 
             else
@@ -229,11 +259,6 @@ void init_xenbus(void)
               NULL);
     DEBUG("xenbus on irq %d\n", err);
 }
-
-struct write_req {
-    const void *data;
-    unsigned len;
-};
 
 /* Send data to xenbus.  This can block.  All of the requests are seen
    by xenbus as if sent atomically.  The header is added
@@ -316,7 +341,7 @@ static void xb_write(int type, int req_i
 /* Send a mesasge to xenbus, in the same fashion as xb_write, and
    block waiting for a reply.  The reply is malloced and should be
    freed by the caller. */
-static struct xsd_sockmsg *
+struct xsd_sockmsg *
 xenbus_msg_reply(int type,
                 xenbus_transaction_t trans,
                 struct write_req *io,
@@ -437,23 +462,55 @@ char *xenbus_write(xenbus_transaction_t 
     return NULL;
 }
 
-char* xenbus_watch_path( xenbus_transaction_t xbt, const char *path)
-{
-       /* in the future one could have multiple watch queues, and use
-        * the token for demuxing. For now the token is 0. */
-
+char* xenbus_watch_path_token( xenbus_transaction_t xbt, const char *path, 
const char *token, struct xenbus_event *volatile *events)
+{
     struct xsd_sockmsg *rep;
 
     struct write_req req[] = { 
         {path, strlen(path) + 1},
-        {"0",2 },
+       {token, strlen(token) + 1},
     };
+
+    struct watch *watch = malloc(sizeof(*watch));
+
+    watch->token = strdup(token);
+    watch->events = events;
+    watch->next = watches;
+    watches = watch;
 
     rep = xenbus_msg_reply(XS_WATCH, xbt, req, ARRAY_SIZE(req));
 
     char *msg = errmsg(rep);
     if (msg) return msg;
     free(rep);
+
+    return NULL;
+}
+
+char* xenbus_unwatch_path_token( xenbus_transaction_t xbt, const char *path, 
const char *token)
+{
+    struct xsd_sockmsg *rep;
+
+    struct write_req req[] = { 
+        {path, strlen(path) + 1},
+       {token, strlen(token) + 1},
+    };
+
+    struct watch *watch, **prev;
+
+    rep = xenbus_msg_reply(XS_UNWATCH, xbt, req, ARRAY_SIZE(req));
+
+    char *msg = errmsg(rep);
+    if (msg) return msg;
+    free(rep);
+
+    for (prev = &watches, watch = *prev; watch; prev = &watch->next, watch = 
*prev)
+        if (!strcmp(watch->token, token)) {
+            free(watch->token);
+            *prev = watch->next;
+            free(watch);
+            break;
+        }
 
     return NULL;
 }
@@ -566,6 +623,25 @@ int xenbus_read_integer(char *path)
     return t;
 }
 
+char* xenbus_printf(xenbus_transaction_t xbt,
+                                  char* node, char* path,
+                                  char* fmt, ...)
+{
+#define BUFFER_SIZE 256
+    char fullpath[BUFFER_SIZE];
+    char val[BUFFER_SIZE];
+    va_list args;
+
+    BUG_ON(strlen(node) + strlen(path) + 1 >= BUFFER_SIZE);
+    sprintf(fullpath,"%s/%s", node, path);
+    va_start(args, fmt);
+    vsprintf(val, fmt, args);
+    va_end(args);
+    xenbus_write(xbt,fullpath,val);
+
+    return NULL;
+}
+
 static void do_ls_test(const char *pre)
 {
     char **dirs;

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] minios: add xenbus token support and separate watch event queues, Xen patchbot-unstable <=