ia64/xen-unstable

changeset 13413:1fc8fb8ea425

[MINIOS] Support xenbus watches.
Signed-off-by: Jacob Gorm Hansen <jacobg@diku.dk>
author kfraser@localhost.localdomain
date Fri Jan 12 15:15:25 2007 +0000 (2007-01-12)
parents 6a53d3abe7f8
children 2406531dae95
files extras/mini-os/include/xenbus.h extras/mini-os/xenbus/xenbus.c
line diff
     1.1 --- a/extras/mini-os/include/xenbus.h	Fri Jan 12 14:51:27 2007 +0000
     1.2 +++ b/extras/mini-os/include/xenbus.h	Fri Jan 12 15:15:25 2007 +0000
     1.3 @@ -12,6 +12,9 @@ void init_xenbus(void);
     1.4     set to a malloc'd copy of the value. */
     1.5  char *xenbus_read(xenbus_transaction_t xbt, const char *path, char **value);
     1.6  
     1.7 +char *xenbus_watch_path(xenbus_transaction_t xbt, const char *path);
     1.8 +char* xenbus_wait_for_value(const char*,const char*);
     1.9 +
    1.10  /* Associates a value with a path.  Returns a malloc'd error string on
    1.11     failure. */
    1.12  char *xenbus_write(xenbus_transaction_t xbt, const char *path, const char *value);
     2.1 --- a/extras/mini-os/xenbus/xenbus.c	Fri Jan 12 14:51:27 2007 +0000
     2.2 +++ b/extras/mini-os/xenbus/xenbus.c	Fri Jan 12 15:15:25 2007 +0000
     2.3 @@ -45,9 +45,9 @@
     2.4  #define DEBUG(_f, _a...)    ((void)0)
     2.5  #endif
     2.6  
     2.7 -
     2.8  static struct xenstore_domain_interface *xenstore_buf;
     2.9  static DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
    2.10 +static DECLARE_WAIT_QUEUE_HEAD(watch_queue);
    2.11  struct xenbus_req_info 
    2.12  {
    2.13      int in_use:1;
    2.14 @@ -72,6 +72,34 @@ static void memcpy_from_ring(const void 
    2.15      memcpy(dest + c1, ring, c2);
    2.16  }
    2.17  
    2.18 +static inline void wait_for_watch(void)
    2.19 +{
    2.20 +    DEFINE_WAIT(w);
    2.21 +    add_waiter(w,watch_queue);
    2.22 +    schedule();
    2.23 +    wake(current);
    2.24 +}
    2.25 +
    2.26 +char* xenbus_wait_for_value(const char* path,const char* value)
    2.27 +{
    2.28 +    for(;;)
    2.29 +    {
    2.30 +        char *res, *msg;
    2.31 +        int r;
    2.32 +
    2.33 +        msg = xenbus_read(XBT_NIL, path, &res);
    2.34 +        if(msg) return msg;
    2.35 +
    2.36 +        r = strcmp(value,res);
    2.37 +        free(res);
    2.38 +
    2.39 +        if(r==0) break;
    2.40 +        else wait_for_watch();
    2.41 +    }
    2.42 +    return NULL;
    2.43 +}
    2.44 +
    2.45 +
    2.46  static void xenbus_thread_func(void *ign)
    2.47  {
    2.48      struct xsd_sockmsg msg;
    2.49 @@ -101,13 +129,35 @@ static void xenbus_thread_func(void *ign
    2.50                  break;
    2.51  
    2.52              DEBUG("Message is good.\n");
    2.53 -            req_info[msg.req_id].reply = malloc(sizeof(msg) + msg.len);
    2.54 -            memcpy_from_ring(xenstore_buf->rsp,
    2.55 +
    2.56 +            if(msg.type == XS_WATCH_EVENT)
    2.57 +            {
    2.58 +                char* payload = (char*)malloc(sizeof(msg) + msg.len);
    2.59 +                char *path,*token;
    2.60 +
    2.61 +                memcpy_from_ring(xenstore_buf->rsp,
    2.62 +                    payload,
    2.63 +                    MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
    2.64 +                    msg.len + sizeof(msg));
    2.65 +
    2.66 +                path = payload + sizeof(msg);
    2.67 +                token = path + strlen(path) + 1;
    2.68 +
    2.69 +                xenstore_buf->rsp_cons += msg.len + sizeof(msg);
    2.70 +                free(payload);
    2.71 +                wake_up(&watch_queue);
    2.72 +            }
    2.73 +
    2.74 +            else
    2.75 +            {
    2.76 +                req_info[msg.req_id].reply = malloc(sizeof(msg) + msg.len);
    2.77 +                memcpy_from_ring(xenstore_buf->rsp,
    2.78                      req_info[msg.req_id].reply,
    2.79                      MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
    2.80                      msg.len + sizeof(msg));
    2.81 -            wake_up(&req_info[msg.req_id].waitq);
    2.82 -            xenstore_buf->rsp_cons += msg.len + sizeof(msg);
    2.83 +                xenstore_buf->rsp_cons += msg.len + sizeof(msg);
    2.84 +                wake_up(&req_info[msg.req_id].waitq);
    2.85 +            }
    2.86          }
    2.87      }
    2.88  }
    2.89 @@ -381,12 +431,32 @@ char *xenbus_write(xenbus_transaction_t 
    2.90      struct xsd_sockmsg *rep;
    2.91      rep = xenbus_msg_reply(XS_WRITE, xbt, req, ARRAY_SIZE(req));
    2.92      char *msg = errmsg(rep);
    2.93 -    if (msg)
    2.94 -	return msg;
    2.95 +    if (msg) return msg;
    2.96      free(rep);
    2.97      return NULL;
    2.98  }
    2.99  
   2.100 +char* xenbus_watch_path( xenbus_transaction_t xbt, const char *path)
   2.101 +{
   2.102 +	/* in the future one could have multiple watch queues, and use
   2.103 +	 * the token for demuxing. For now the token is 0. */
   2.104 +
   2.105 +    struct xsd_sockmsg *rep;
   2.106 +
   2.107 +    struct write_req req[] = { 
   2.108 +        {path, strlen(path) + 1},
   2.109 +        {"0",2 },
   2.110 +    };
   2.111 +
   2.112 +    rep = xenbus_msg_reply(XS_WATCH, xbt, req, ARRAY_SIZE(req));
   2.113 +
   2.114 +    char *msg = errmsg(rep);
   2.115 +    if (msg) return msg;
   2.116 +    free(rep);
   2.117 +
   2.118 +    return NULL;
   2.119 +}
   2.120 +
   2.121  char *xenbus_rm(xenbus_transaction_t xbt, const char *path)
   2.122  {
   2.123      struct write_req req[] = { {path, strlen(path) + 1} };