[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [MINIOS] Implement XenBus transactions in MiniOS.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID fed18f971f7203a663f4c8b3761f27e57ee65a78
# Parent  8e1ae72e905e0f052de3b61a883a935a08d121fc
[MINIOS] Implement XenBus transactions in MiniOS.
Signed-off-by: Steven Smith <sos22@xxxxxxxxx>
---
 extras/mini-os/include/xenbus.h |   29 ++++++++---
 extras/mini-os/xenbus/xenbus.c  |  103 +++++++++++++++++++++++++++++++---------
 2 files changed, 104 insertions(+), 28 deletions(-)

diff -r 8e1ae72e905e -r fed18f971f72 extras/mini-os/include/xenbus.h
--- a/extras/mini-os/include/xenbus.h   Wed Jul 05 11:24:09 2006 +0100
+++ b/extras/mini-os/include/xenbus.h   Wed Jul 05 11:26:57 2006 +0100
@@ -1,5 +1,8 @@
 #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);
@@ -7,28 +10,42 @@ 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__ */
diff -r 8e1ae72e905e -r fed18f971f72 extras/mini-os/xenbus/xenbus.c
--- a/extras/mini-os/xenbus/xenbus.c    Wed Jul 05 11:24:09 2006 +0100
+++ b/extras/mini-os/xenbus/xenbus.c    Wed Jul 05 11:26:57 2006 +0100
@@ -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_i
    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 
 /* 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 **
     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
     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, con
     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,
 }
 
 #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,
        {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,
     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 *pat
 {
     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_write_test(const char *pa
 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_rm_test(const char *path)
 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);

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.