ia64/xen-unstable

changeset 10650:fed18f971f72

[MINIOS] Implement XenBus transactions in MiniOS.
Signed-off-by: Steven Smith <sos22@cam.ac.uk>
author kfraser@localhost.localdomain
date Wed Jul 05 11:26:57 2006 +0100 (2006-07-05)
parents 8e1ae72e905e
children 09378a9ca8ad
files extras/mini-os/include/xenbus.h extras/mini-os/xenbus/xenbus.c
line diff
     1.1 --- a/extras/mini-os/include/xenbus.h	Wed Jul 05 11:24:09 2006 +0100
     1.2 +++ b/extras/mini-os/include/xenbus.h	Wed Jul 05 11:26:57 2006 +0100
     1.3 @@ -1,34 +1,51 @@
     1.4  #ifndef XENBUS_H__
     1.5  #define XENBUS_H__
     1.6  
     1.7 +typedef unsigned long xenbus_transaction_t;
     1.8 +#define XBT_NIL ((xenbus_transaction_t)0)
     1.9 +
    1.10  /* Initialize the XenBus system. */
    1.11  void init_xenbus(void);
    1.12  
    1.13  /* Read the value associated with a path.  Returns a malloc'd error
    1.14     string on failure and sets *value to NULL.  On success, *value is
    1.15     set to a malloc'd copy of the value. */
    1.16 -char *xenbus_read(const char *path, char **value);
    1.17 +char *xenbus_read(xenbus_transaction_t xbt, const char *path, char **value);
    1.18  
    1.19  /* Associates a value with a path.  Returns a malloc'd error string on
    1.20     failure. */
    1.21 -char *xenbus_write(const char *path, const char *value);
    1.22 +char *xenbus_write(xenbus_transaction_t xbt, const char *path, const char *value);
    1.23  
    1.24  /* Removes the value associated with a path.  Returns a malloc'd error
    1.25     string on failure. */
    1.26 -char *xenbus_rm(const char *path);
    1.27 +char *xenbus_rm(xenbus_transaction_t xbt, const char *path);
    1.28  
    1.29  /* List the contents of a directory.  Returns a malloc'd error string
    1.30     on failure and sets *contents to NULL.  On success, *contents is
    1.31     set to a malloc'd array of pointers to malloc'd strings.  The array
    1.32     is NULL terminated.  May block. */
    1.33 -char *xenbus_ls(const char *prefix, char ***contents);
    1.34 +char *xenbus_ls(xenbus_transaction_t xbt, const char *prefix, char ***contents);
    1.35  
    1.36  /* Reads permissions associated with a path.  Returns a malloc'd error
    1.37     string on failure and sets *value to NULL.  On success, *value is
    1.38     set to a malloc'd copy of the value. */
    1.39 -char *xenbus_get_perms(const char *path, char **value);
    1.40 +char *xenbus_get_perms(xenbus_transaction_t xbt, const char *path, char **value);
    1.41  
    1.42  /* Sets the permissions associated with a path.  Returns a malloc'd
    1.43     error string on failure. */
    1.44 -char *xenbus_set_perms(const char *path, domid_t dom, char perm);
    1.45 +char *xenbus_set_perms(xenbus_transaction_t xbt, const char *path, domid_t dom, char perm);
    1.46 +
    1.47 +/* Start a xenbus transaction.  Returns the transaction in xbt on
    1.48 +   success or a malloc'd error string otherwise. */
    1.49 +char *xenbus_transaction_start(xenbus_transaction_t *xbt);
    1.50 +
    1.51 +/* End a xenbus transaction.  Returns a malloc'd error string if it
    1.52 +   fails.  abort says whether the transaction should be aborted.
    1.53 +   Returns 1 in *retry iff the transaction should be retried. */
    1.54 +char *xenbus_transaction_end(xenbus_transaction_t, int abort,
    1.55 +			     int *retry);
    1.56 +
    1.57 +/* Read path and parse it as an integer.  Returns -1 on error. */
    1.58 +int xenbus_read_integer(char *path);
    1.59 +
    1.60  #endif /* XENBUS_H__ */
     2.1 --- a/extras/mini-os/xenbus/xenbus.c	Wed Jul 05 11:24:09 2006 +0100
     2.2 +++ b/extras/mini-os/xenbus/xenbus.c	Wed Jul 05 11:26:57 2006 +0100
     2.3 @@ -174,7 +174,7 @@ void init_xenbus(void)
     2.4      create_thread("xenstore", xenbus_thread_func, NULL);
     2.5      DEBUG("buf at %p.\n", xenstore_buf);
     2.6      err = bind_evtchn(start_info.store_evtchn,
     2.7 -            xenbus_evtchn_handler);
     2.8 +		      xenbus_evtchn_handler);
     2.9      DEBUG("xenbus on irq %d\n", err);
    2.10  }
    2.11  
    2.12 @@ -187,8 +187,8 @@ struct write_req {
    2.13     by xenbus as if sent atomically.  The header is added
    2.14     automatically, using type %type, req_id %req_id, and trans_id
    2.15     %trans_id. */
    2.16 -static void xb_write(int type, int req_id, int trans_id,
    2.17 -        const struct write_req *req, int nr_reqs)
    2.18 +static void xb_write(int type, int req_id, xenbus_transaction_t trans_id,
    2.19 +		     const struct write_req *req, int nr_reqs)
    2.20  {
    2.21      XENSTORE_RING_IDX prod;
    2.22      int r;
    2.23 @@ -266,9 +266,9 @@ static void xb_write(int type, int req_i
    2.24     freed by the caller. */
    2.25  static struct xsd_sockmsg *
    2.26  xenbus_msg_reply(int type,
    2.27 -        int trans,
    2.28 -        struct write_req *io,
    2.29 -        int nr_reqs)
    2.30 +		 xenbus_transaction_t trans,
    2.31 +		 struct write_req *io,
    2.32 +		 int nr_reqs)
    2.33  {
    2.34      int id;
    2.35      DEFINE_WAIT(w);
    2.36 @@ -322,14 +322,14 @@ static void xenbus_debug_msg(const char 
    2.37  /* List the contents of a directory.  Returns a malloc()ed array of
    2.38     pointers to malloc()ed strings.  The array is NULL terminated.  May
    2.39     block. */
    2.40 -char *xenbus_ls(const char *pre, char ***contents)
    2.41 +char *xenbus_ls(xenbus_transaction_t xbt, const char *pre, char ***contents)
    2.42  {
    2.43      struct xsd_sockmsg *reply, *repmsg;
    2.44      struct write_req req[] = { { pre, strlen(pre)+1 } };
    2.45      int nr_elems, x, i;
    2.46      char **res;
    2.47  
    2.48 -    repmsg = xenbus_msg_reply(XS_DIRECTORY, 0, req, ARRAY_SIZE(req));
    2.49 +    repmsg = xenbus_msg_reply(XS_DIRECTORY, xbt, req, ARRAY_SIZE(req));
    2.50      char *msg = errmsg(repmsg);
    2.51      if (msg) {
    2.52  	*contents = NULL;
    2.53 @@ -351,12 +351,12 @@ char *xenbus_ls(const char *pre, char **
    2.54      return NULL;
    2.55  }
    2.56  
    2.57 -char *xenbus_read(const char *path, char **value)
    2.58 +char *xenbus_read(xenbus_transaction_t xbt, const char *path, char **value)
    2.59  {
    2.60      struct write_req req[] = { {path, strlen(path) + 1} };
    2.61      struct xsd_sockmsg *rep;
    2.62      char *res;
    2.63 -    rep = xenbus_msg_reply(XS_READ, 0, req, ARRAY_SIZE(req));
    2.64 +    rep = xenbus_msg_reply(XS_READ, xbt, req, ARRAY_SIZE(req));
    2.65      char *msg = errmsg(rep);
    2.66      if (msg) {
    2.67  	*value = NULL;
    2.68 @@ -370,14 +370,14 @@ char *xenbus_read(const char *path, char
    2.69      return NULL;
    2.70  }
    2.71  
    2.72 -char *xenbus_write(const char *path, const char *value)
    2.73 +char *xenbus_write(xenbus_transaction_t xbt, const char *path, const char *value)
    2.74  {
    2.75      struct write_req req[] = { 
    2.76  	{path, strlen(path) + 1},
    2.77  	{value, strlen(value) + 1},
    2.78      };
    2.79      struct xsd_sockmsg *rep;
    2.80 -    rep = xenbus_msg_reply(XS_WRITE, 0, req, ARRAY_SIZE(req));
    2.81 +    rep = xenbus_msg_reply(XS_WRITE, xbt, req, ARRAY_SIZE(req));
    2.82      char *msg = errmsg(rep);
    2.83      if (msg)
    2.84  	return msg;
    2.85 @@ -385,11 +385,11 @@ char *xenbus_write(const char *path, con
    2.86      return NULL;
    2.87  }
    2.88  
    2.89 -char *xenbus_rm(const char *path)
    2.90 +char *xenbus_rm(xenbus_transaction_t xbt, const char *path)
    2.91  {
    2.92      struct write_req req[] = { {path, strlen(path) + 1} };
    2.93      struct xsd_sockmsg *rep;
    2.94 -    rep = xenbus_msg_reply(XS_RM, 0, req, ARRAY_SIZE(req));
    2.95 +    rep = xenbus_msg_reply(XS_RM, xbt, req, ARRAY_SIZE(req));
    2.96      char *msg = errmsg(rep);
    2.97      if (msg)
    2.98  	return msg;
    2.99 @@ -397,12 +397,12 @@ char *xenbus_rm(const char *path)
   2.100      return NULL;
   2.101  }
   2.102  
   2.103 -char *xenbus_get_perms(const char *path, char **value)
   2.104 +char *xenbus_get_perms(xenbus_transaction_t xbt, const char *path, char **value)
   2.105  {
   2.106      struct write_req req[] = { {path, strlen(path) + 1} };
   2.107      struct xsd_sockmsg *rep;
   2.108      char *res;
   2.109 -    rep = xenbus_msg_reply(XS_GET_PERMS, 0, req, ARRAY_SIZE(req));
   2.110 +    rep = xenbus_msg_reply(XS_GET_PERMS, xbt, req, ARRAY_SIZE(req));
   2.111      char *msg = errmsg(rep);
   2.112      if (msg) {
   2.113  	*value = NULL;
   2.114 @@ -417,7 +417,7 @@ char *xenbus_get_perms(const char *path,
   2.115  }
   2.116  
   2.117  #define PERM_MAX_SIZE 32
   2.118 -char *xenbus_set_perms(const char *path, domid_t dom, char perm)
   2.119 +char *xenbus_set_perms(xenbus_transaction_t xbt, const char *path, domid_t dom, char perm)
   2.120  {
   2.121      char value[PERM_MAX_SIZE];
   2.122      snprintf(value, PERM_MAX_SIZE, "%c%hu", perm, dom);
   2.123 @@ -426,7 +426,7 @@ char *xenbus_set_perms(const char *path,
   2.124  	{value, strlen(value) + 1},
   2.125      };
   2.126      struct xsd_sockmsg *rep;
   2.127 -    rep = xenbus_msg_reply(XS_SET_PERMS, 0, req, ARRAY_SIZE(req));
   2.128 +    rep = xenbus_msg_reply(XS_SET_PERMS, xbt, req, ARRAY_SIZE(req));
   2.129      char *msg = errmsg(rep);
   2.130      if (msg)
   2.131  	return msg;
   2.132 @@ -434,13 +434,72 @@ char *xenbus_set_perms(const char *path,
   2.133      return NULL;
   2.134  }
   2.135  
   2.136 +char *xenbus_transaction_start(xenbus_transaction_t *xbt)
   2.137 +{
   2.138 +    /* xenstored becomes angry if you send a length 0 message, so just
   2.139 +       shove a nul terminator on the end */
   2.140 +    struct write_req req = { "", 1};
   2.141 +    struct xsd_sockmsg *rep;
   2.142 +    char *err;
   2.143 +
   2.144 +    rep = xenbus_msg_reply(XS_TRANSACTION_START, 0, &req, 1);
   2.145 +    err = errmsg(rep);
   2.146 +    if (err)
   2.147 +	return err;
   2.148 +    sscanf((char *)(rep + 1), "%u", xbt);
   2.149 +    free(rep);
   2.150 +    return NULL;
   2.151 +}
   2.152 +
   2.153 +char *
   2.154 +xenbus_transaction_end(xenbus_transaction_t t, int abort, int *retry)
   2.155 +{
   2.156 +    struct xsd_sockmsg *rep;
   2.157 +    struct write_req req;
   2.158 +    char *err;
   2.159 +
   2.160 +    *retry = 0;
   2.161 +
   2.162 +    req.data = abort ? "F" : "T";
   2.163 +    req.len = 2;
   2.164 +    rep = xenbus_msg_reply(XS_TRANSACTION_END, t, &req, 1);
   2.165 +    err = errmsg(rep);
   2.166 +    if (err) {
   2.167 +	if (!strcmp(err, "EAGAIN")) {
   2.168 +	    *retry = 1;
   2.169 +	    free(err);
   2.170 +	    return NULL;
   2.171 +	} else {
   2.172 +	    return err;
   2.173 +	}
   2.174 +    }
   2.175 +    free(rep);
   2.176 +    return NULL;
   2.177 +}
   2.178 +
   2.179 +int xenbus_read_integer(char *path)
   2.180 +{
   2.181 +    char *res, *buf;
   2.182 +    int t;
   2.183 +
   2.184 +    res = xenbus_read(XBT_NIL, path, &buf);
   2.185 +    if (res) {
   2.186 +	printk("Failed to read %s.\n", path);
   2.187 +	free(res);
   2.188 +	return -1;
   2.189 +    }
   2.190 +    sscanf(buf, "%d", &t);
   2.191 +    free(buf);
   2.192 +    return t;
   2.193 +}
   2.194 +
   2.195  static void do_ls_test(const char *pre)
   2.196  {
   2.197      char **dirs;
   2.198      int x;
   2.199  
   2.200      DEBUG("ls %s...\n", pre);
   2.201 -    char *msg = xenbus_ls(pre, &dirs);
   2.202 +    char *msg = xenbus_ls(XBT_NIL, pre, &dirs);
   2.203      if (msg) {
   2.204  	DEBUG("Error in xenbus ls: %s\n", msg);
   2.205  	free(msg);
   2.206 @@ -458,7 +517,7 @@ static void do_read_test(const char *pat
   2.207  {
   2.208      char *res;
   2.209      DEBUG("Read %s...\n", path);
   2.210 -    char *msg = xenbus_read(path, &res);
   2.211 +    char *msg = xenbus_read(XBT_NIL, path, &res);
   2.212      if (msg) {
   2.213  	DEBUG("Error in xenbus read: %s\n", msg);
   2.214  	free(msg);
   2.215 @@ -471,7 +530,7 @@ static void do_read_test(const char *pat
   2.216  static void do_write_test(const char *path, const char *val)
   2.217  {
   2.218      DEBUG("Write %s to %s...\n", val, path);
   2.219 -    char *msg = xenbus_write(path, val);
   2.220 +    char *msg = xenbus_write(XBT_NIL, path, val);
   2.221      if (msg) {
   2.222  	DEBUG("Result %s\n", msg);
   2.223  	free(msg);
   2.224 @@ -483,7 +542,7 @@ static void do_write_test(const char *pa
   2.225  static void do_rm_test(const char *path)
   2.226  {
   2.227      DEBUG("rm %s...\n", path);
   2.228 -    char *msg = xenbus_rm(path);
   2.229 +    char *msg = xenbus_rm(XBT_NIL, path);
   2.230      if (msg) {
   2.231  	DEBUG("Result %s\n", msg);
   2.232  	free(msg);