ia64/xen-unstable
changeset 10650:fed18f971f72
[MINIOS] Implement XenBus transactions in MiniOS.
Signed-off-by: Steven Smith <sos22@cam.ac.uk>
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);