mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
[MINIOS] Implement XenBus transactions in MiniOS.
Signed-off-by: Steven Smith <sos22@cam.ac.uk>
This commit is contained in:
1 parent
412dc9c9ff
commit
933e1fc274
2 files changed
+104
-28
No files matched your search
@@ -1,34 +1,51 @@
|
||||
#ifndef XENBUS_H__
|
||||
#define XENBUS_H__
|
||||
|
||||
typedef unsigned long xenbus_transaction_t;
|
||||
#define XBT_NIL ((xenbus_transaction_t)0)
|
||||
|
||||
/* Initialize the XenBus system. */
|
||||
void init_xenbus(void);
|
||||
|
||||
/* Read the value associated with a path. Returns a malloc'd error
|
||||
string on failure and sets *value to NULL. On success, *value is
|
||||
set to a malloc'd copy of the value. */
|
||||
char *xenbus_read(const char *path, char **value);
|
||||
char *xenbus_read(xenbus_transaction_t xbt, const char *path, char **value);
|
||||
|
||||
/* Associates a value with a path. Returns a malloc'd error string on
|
||||
failure. */
|
||||
char *xenbus_write(const char *path, const char *value);
|
||||
char *xenbus_write(xenbus_transaction_t xbt, const char *path, const char *value);
|
||||
|
||||
/* Removes the value associated with a path. Returns a malloc'd error
|
||||
string on failure. */
|
||||
char *xenbus_rm(const char *path);
|
||||
char *xenbus_rm(xenbus_transaction_t xbt, const char *path);
|
||||
|
||||
/* List the contents of a directory. Returns a malloc'd error string
|
||||
on failure and sets *contents to NULL. On success, *contents is
|
||||
set to a malloc'd array of pointers to malloc'd strings. The array
|
||||
is NULL terminated. May block. */
|
||||
char *xenbus_ls(const char *prefix, char ***contents);
|
||||
char *xenbus_ls(xenbus_transaction_t xbt, const char *prefix, char ***contents);
|
||||
|
||||
/* Reads permissions associated with a path. Returns a malloc'd error
|
||||
string on failure and sets *value to NULL. On success, *value is
|
||||
set to a malloc'd copy of the value. */
|
||||
char *xenbus_get_perms(const char *path, char **value);
|
||||
char *xenbus_get_perms(xenbus_transaction_t xbt, const char *path, char **value);
|
||||
|
||||
/* Sets the permissions associated with a path. Returns a malloc'd
|
||||
error string on failure. */
|
||||
char *xenbus_set_perms(const char *path, domid_t dom, char perm);
|
||||
char *xenbus_set_perms(xenbus_transaction_t xbt, const char *path, domid_t dom, char perm);
|
||||
|
||||
/* Start a xenbus transaction. Returns the transaction in xbt on
|
||||
success or a malloc'd error string otherwise. */
|
||||
char *xenbus_transaction_start(xenbus_transaction_t *xbt);
|
||||
|
||||
/* End a xenbus transaction. Returns a malloc'd error string if it
|
||||
fails. abort says whether the transaction should be aborted.
|
||||
Returns 1 in *retry iff the transaction should be retried. */
|
||||
char *xenbus_transaction_end(xenbus_transaction_t, int abort,
|
||||
int *retry);
|
||||
|
||||
/* Read path and parse it as an integer. Returns -1 on error. */
|
||||
int xenbus_read_integer(char *path);
|
||||
|
||||
#endif /* XENBUS_H__ */
|
||||
@@ -174,7 +174,7 @@ void init_xenbus(void)
|
||||
create_thread("xenstore", xenbus_thread_func, NULL);
|
||||
DEBUG("buf at %p.\n", xenstore_buf);
|
||||
err = bind_evtchn(start_info.store_evtchn,
|
||||
xenbus_evtchn_handler);
|
||||
xenbus_evtchn_handler);
|
||||
DEBUG("xenbus on irq %d\n", err);
|
||||
}
|
||||
|
||||
@@ -187,8 +187,8 @@ struct write_req {
|
||||
by xenbus as if sent atomically. The header is added
|
||||
automatically, using type %type, req_id %req_id, and trans_id
|
||||
%trans_id. */
|
||||
static void xb_write(int type, int req_id, int trans_id,
|
||||
const struct write_req *req, int nr_reqs)
|
||||
static void xb_write(int type, int req_id, xenbus_transaction_t trans_id,
|
||||
const struct write_req *req, int nr_reqs)
|
||||
{
|
||||
XENSTORE_RING_IDX prod;
|
||||
int r;
|
||||
@@ -266,9 +266,9 @@ static void xb_write(int type, int req_id, int trans_id,
|
||||
freed by the caller. */
|
||||
static struct xsd_sockmsg *
|
||||
xenbus_msg_reply(int type,
|
||||
int trans,
|
||||
struct write_req *io,
|
||||
int nr_reqs)
|
||||
xenbus_transaction_t trans,
|
||||
struct write_req *io,
|
||||
int nr_reqs)
|
||||
{
|
||||
int id;
|
||||
DEFINE_WAIT(w);
|
||||
@@ -322,14 +322,14 @@ static void xenbus_debug_msg(const char *msg)
|
||||
/* List the contents of a directory. Returns a malloc()ed array of
|
||||
pointers to malloc()ed strings. The array is NULL terminated. May
|
||||
block. */
|
||||
char *xenbus_ls(const char *pre, char ***contents)
|
||||
char *xenbus_ls(xenbus_transaction_t xbt, const char *pre, char ***contents)
|
||||
{
|
||||
struct xsd_sockmsg *reply, *repmsg;
|
||||
struct write_req req[] = { { pre, strlen(pre)+1 } };
|
||||
int nr_elems, x, i;
|
||||
char **res;
|
||||
|
||||
repmsg = xenbus_msg_reply(XS_DIRECTORY, 0, req, ARRAY_SIZE(req));
|
||||
repmsg = xenbus_msg_reply(XS_DIRECTORY, xbt, req, ARRAY_SIZE(req));
|
||||
char *msg = errmsg(repmsg);
|
||||
if (msg) {
|
||||
*contents = NULL;
|
||||
@@ -351,12 +351,12 @@ char *xenbus_ls(const char *pre, char ***contents)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *xenbus_read(const char *path, char **value)
|
||||
char *xenbus_read(xenbus_transaction_t xbt, const char *path, char **value)
|
||||
{
|
||||
struct write_req req[] = { {path, strlen(path) + 1} };
|
||||
struct xsd_sockmsg *rep;
|
||||
char *res;
|
||||
rep = xenbus_msg_reply(XS_READ, 0, req, ARRAY_SIZE(req));
|
||||
rep = xenbus_msg_reply(XS_READ, xbt, req, ARRAY_SIZE(req));
|
||||
char *msg = errmsg(rep);
|
||||
if (msg) {
|
||||
*value = NULL;
|
||||
@@ -370,14 +370,14 @@ char *xenbus_read(const char *path, char **value)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *xenbus_write(const char *path, const char *value)
|
||||
char *xenbus_write(xenbus_transaction_t xbt, const char *path, const char *value)
|
||||
{
|
||||
struct write_req req[] = {
|
||||
{path, strlen(path) + 1},
|
||||
{value, strlen(value) + 1},
|
||||
};
|
||||
struct xsd_sockmsg *rep;
|
||||
rep = xenbus_msg_reply(XS_WRITE, 0, req, ARRAY_SIZE(req));
|
||||
rep = xenbus_msg_reply(XS_WRITE, xbt, req, ARRAY_SIZE(req));
|
||||
char *msg = errmsg(rep);
|
||||
if (msg)
|
||||
return msg;
|
||||
@@ -385,11 +385,11 @@ char *xenbus_write(const char *path, const char *value)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *xenbus_rm(const char *path)
|
||||
char *xenbus_rm(xenbus_transaction_t xbt, const char *path)
|
||||
{
|
||||
struct write_req req[] = { {path, strlen(path) + 1} };
|
||||
struct xsd_sockmsg *rep;
|
||||
rep = xenbus_msg_reply(XS_RM, 0, req, ARRAY_SIZE(req));
|
||||
rep = xenbus_msg_reply(XS_RM, xbt, req, ARRAY_SIZE(req));
|
||||
char *msg = errmsg(rep);
|
||||
if (msg)
|
||||
return msg;
|
||||
@@ -397,12 +397,12 @@ char *xenbus_rm(const char *path)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *xenbus_get_perms(const char *path, char **value)
|
||||
char *xenbus_get_perms(xenbus_transaction_t xbt, const char *path, char **value)
|
||||
{
|
||||
struct write_req req[] = { {path, strlen(path) + 1} };
|
||||
struct xsd_sockmsg *rep;
|
||||
char *res;
|
||||
rep = xenbus_msg_reply(XS_GET_PERMS, 0, req, ARRAY_SIZE(req));
|
||||
rep = xenbus_msg_reply(XS_GET_PERMS, xbt, req, ARRAY_SIZE(req));
|
||||
char *msg = errmsg(rep);
|
||||
if (msg) {
|
||||
*value = NULL;
|
||||
@@ -417,7 +417,7 @@ char *xenbus_get_perms(const char *path, char **value)
|
||||
}
|
||||
|
||||
#define PERM_MAX_SIZE 32
|
||||
char *xenbus_set_perms(const char *path, domid_t dom, char perm)
|
||||
char *xenbus_set_perms(xenbus_transaction_t xbt, const char *path, domid_t dom, char perm)
|
||||
{
|
||||
char value[PERM_MAX_SIZE];
|
||||
snprintf(value, PERM_MAX_SIZE, "%c%hu", perm, dom);
|
||||
@@ -426,7 +426,7 @@ char *xenbus_set_perms(const char *path, domid_t dom, char perm)
|
||||
{value, strlen(value) + 1},
|
||||
};
|
||||
struct xsd_sockmsg *rep;
|
||||
rep = xenbus_msg_reply(XS_SET_PERMS, 0, req, ARRAY_SIZE(req));
|
||||
rep = xenbus_msg_reply(XS_SET_PERMS, xbt, req, ARRAY_SIZE(req));
|
||||
char *msg = errmsg(rep);
|
||||
if (msg)
|
||||
return msg;
|
||||
@@ -434,13 +434,72 @@ char *xenbus_set_perms(const char *path, domid_t dom, char perm)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *xenbus_transaction_start(xenbus_transaction_t *xbt)
|
||||
{
|
||||
/* xenstored becomes angry if you send a length 0 message, so just
|
||||
shove a nul terminator on the end */
|
||||
struct write_req req = { "", 1};
|
||||
struct xsd_sockmsg *rep;
|
||||
char *err;
|
||||
|
||||
rep = xenbus_msg_reply(XS_TRANSACTION_START, 0, &req, 1);
|
||||
err = errmsg(rep);
|
||||
if (err)
|
||||
return err;
|
||||
sscanf((char *)(rep + 1), "%u", xbt);
|
||||
free(rep);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *
|
||||
xenbus_transaction_end(xenbus_transaction_t t, int abort, int *retry)
|
||||
{
|
||||
struct xsd_sockmsg *rep;
|
||||
struct write_req req;
|
||||
char *err;
|
||||
|
||||
*retry = 0;
|
||||
|
||||
req.data = abort ? "F" : "T";
|
||||
req.len = 2;
|
||||
rep = xenbus_msg_reply(XS_TRANSACTION_END, t, &req, 1);
|
||||
err = errmsg(rep);
|
||||
if (err) {
|
||||
if (!strcmp(err, "EAGAIN")) {
|
||||
*retry = 1;
|
||||
free(err);
|
||||
return NULL;
|
||||
} else {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
free(rep);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int xenbus_read_integer(char *path)
|
||||
{
|
||||
char *res, *buf;
|
||||
int t;
|
||||
|
||||
res = xenbus_read(XBT_NIL, path, &buf);
|
||||
if (res) {
|
||||
printk("Failed to read %s.\n", path);
|
||||
free(res);
|
||||
return -1;
|
||||
}
|
||||
sscanf(buf, "%d", &t);
|
||||
free(buf);
|
||||
return t;
|
||||
}
|
||||
|
||||
static void do_ls_test(const char *pre)
|
||||
{
|
||||
char **dirs;
|
||||
int x;
|
||||
|
||||
DEBUG("ls %s...\n", pre);
|
||||
char *msg = xenbus_ls(pre, &dirs);
|
||||
char *msg = xenbus_ls(XBT_NIL, pre, &dirs);
|
||||
if (msg) {
|
||||
DEBUG("Error in xenbus ls: %s\n", msg);
|
||||
free(msg);
|
||||
@@ -458,7 +517,7 @@ static void do_read_test(const char *path)
|
||||
{
|
||||
char *res;
|
||||
DEBUG("Read %s...\n", path);
|
||||
char *msg = xenbus_read(path, &res);
|
||||
char *msg = xenbus_read(XBT_NIL, path, &res);
|
||||
if (msg) {
|
||||
DEBUG("Error in xenbus read: %s\n", msg);
|
||||
free(msg);
|
||||
@@ -471,7 +530,7 @@ static void do_read_test(const char *path)
|
||||
static void do_write_test(const char *path, const char *val)
|
||||
{
|
||||
DEBUG("Write %s to %s...\n", val, path);
|
||||
char *msg = xenbus_write(path, val);
|
||||
char *msg = xenbus_write(XBT_NIL, path, val);
|
||||
if (msg) {
|
||||
DEBUG("Result %s\n", msg);
|
||||
free(msg);
|
||||
@@ -483,7 +542,7 @@ static void do_write_test(const char *path, const char *val)
|
||||
static void do_rm_test(const char *path)
|
||||
{
|
||||
DEBUG("rm %s...\n", path);
|
||||
char *msg = xenbus_rm(path);
|
||||
char *msg = xenbus_rm(XBT_NIL, path);
|
||||
if (msg) {
|
||||
DEBUG("Result %s\n", msg);
|
||||
free(msg);
|
||||
|
||||