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

[Xen-devel] [PATCH] minios: xenbus refactoring



Hi all,
this patch refactors minios' xenbus state machine: it implements
xenbus_wait_for_state_change and xenbus_switch_state and changes the
various frontends to use the two functions and do proper error checking.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>

---

diff -r 50e048b77ad1 extras/mini-os/blkfront.c
--- a/extras/mini-os/blkfront.c Fri May 29 09:28:15 2009 +0100
+++ b/extras/mini-os/blkfront.c Tue Jun 02 18:14:57 2009 +0100
@@ -149,8 +149,12 @@
         goto abort_transaction;
     }
 
-    err = xenbus_printf(xbt, nodename, "state", "%u",
-            4); /* connected */
+    snprintf(path, sizeof(path), "%s/state", nodename);
+    err = xenbus_switch_state(xbt, path, XenbusStateConnected);
+    if (err) {
+        message = "switching state";
+        goto abort_transaction;
+    }
 
 
     err = xenbus_transaction_end(xbt, 0, &retry);
@@ -179,6 +183,7 @@
     dev->handle = strtoul(strrchr(nodename, '/')+1, NULL, 0);
 
     {
+        XenbusState state;
         char path[strlen(dev->backend) + 1 + 19 + 1];
         snprintf(path, sizeof(path), "%s/mode", dev->backend);
         msg = xenbus_read(XBT_NIL, path, &c);
@@ -196,7 +201,15 @@
 
         xenbus_watch_path_token(XBT_NIL, path, path, &dev->events);
 
-        xenbus_wait_for_value(path, "4", &dev->events);
+        msg = NULL;
+        state = xenbus_read_integer(path);
+        while (msg == NULL && state < XenbusStateConnected)
+            msg = xenbus_wait_for_state_change(path, &state, &dev->events);
+        if (msg != NULL || state != XenbusStateConnected) {
+            printk("backend not available, state=%d\n", state);
+            xenbus_unwatch_path(XBT_NIL, path);
+            goto error;
+        }
 
         snprintf(path, sizeof(path), "%s/info", dev->backend);
         dev->info.info = xenbus_read_integer(path);
@@ -230,25 +243,48 @@
 
 void shutdown_blkfront(struct blkfront_dev *dev)
 {
-    char* err;
-    char *nodename = dev->nodename;
+    char* err = NULL;
+    XenbusState state;
 
     char path[strlen(dev->backend) + 1 + 5 + 1];
+    char nodename[strlen(dev->nodename) + 1 + 5 + 1];
 
     blkfront_sync(dev);
 
-    printk("close blk: backend at %s\n",dev->backend);
+    printk("close blk: backend=%s node=%s\n", dev->backend, dev->nodename);
 
     snprintf(path, sizeof(path), "%s/state", dev->backend);
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */
-    xenbus_wait_for_value(path, "5", &dev->events);
+    snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename);
 
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
-    xenbus_wait_for_value(path, "6", &dev->events);
+    if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosing)) != 
NULL) {
+        printk("shutdown_blkfront: error changing state to %d: %s\n",
+                XenbusStateClosing, err);
+        goto close;
+    }
+    state = xenbus_read_integer(path);
+    while (err == NULL && state < XenbusStateClosing)
+        err = xenbus_wait_for_state_change(path, &state, &dev->events);
 
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
-    xenbus_wait_for_value(path, "2", &dev->events);
+    if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosed)) != 
NULL) {
+        printk("shutdown_blkfront: error changing state to %d: %s\n",
+                XenbusStateClosed, err);
+        goto close;
+    }
+    state = xenbus_read_integer(path);
+    if (state < XenbusStateClosed)
+        xenbus_wait_for_state_change(path, &state, &dev->events);
 
+    if ((err = xenbus_switch_state(XBT_NIL, nodename, 
XenbusStateInitialising)) != NULL) {
+        printk("shutdown_blkfront: error changing state to %d: %s\n",
+                XenbusStateInitialising, err);
+        goto close;
+    }
+    err = NULL;
+    state = xenbus_read_integer(path);
+    while (err == NULL && (state < XenbusStateInitWait || state >= 
XenbusStateClosed))
+        err = xenbus_wait_for_state_change(path, &state, &dev->events);
+
+close:
     xenbus_unwatch_path(XBT_NIL, path);
 
     snprintf(path, sizeof(path), "%s/ring-ref", nodename);
diff -r 50e048b77ad1 extras/mini-os/fbfront.c
--- a/extras/mini-os/fbfront.c  Fri May 29 09:28:15 2009 +0100
+++ b/extras/mini-os/fbfront.c  Tue Jun 02 18:14:57 2009 +0100
@@ -121,7 +121,8 @@
         }
     }
 
-    err = xenbus_printf(xbt, nodename, "state", "%u", 3); /* initialized */
+    snprintf(path, sizeof(path), "%s/state", nodename);
+    err = xenbus_switch_state(xbt, path, XenbusStateInitialised);
     if (err)
         printk("error writing initialized: %s\n", err);
 
@@ -150,17 +151,33 @@
     printk("backend at %s\n", dev->backend);
 
     {
+        XenbusState state;
         char path[strlen(dev->backend) + 1 + 6 + 1];
+        char frontpath[strlen(nodename) + 1 + 6 + 1];
 
         snprintf(path, sizeof(path), "%s/state", dev->backend);
 
         xenbus_watch_path_token(XBT_NIL, path, path, &dev->events);
 
-        xenbus_wait_for_value(path, "4", &dev->events);
+        err = NULL;
+        state = xenbus_read_integer(path);
+        while (err == NULL && state < XenbusStateConnected)
+            err = xenbus_wait_for_state_change(path, &state, &dev->events);
+        if (state != XenbusStateConnected) {
+            printk("backend not available, state=%d\n", state);
+            xenbus_unwatch_path(XBT_NIL, path);
+            goto error;
+        }
 
         printk("%s connected\n", dev->backend);
 
-        err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 4); /* connected 
*/
+        snprintf(frontpath, sizeof(frontpath), "%s/state", nodename);
+        if((err = xenbus_switch_state(XBT_NIL, frontpath, 
XenbusStateConnected))
+            != NULL) {
+            printk("error switching state: %s\n", err);
+            xenbus_unwatch_path(XBT_NIL, path);
+            goto error;
+        }
     }
     unmask_evtchn(dev->evtchn);
 
@@ -211,24 +228,43 @@
 
 void shutdown_kbdfront(struct kbdfront_dev *dev)
 {
-    char* err;
-    char *nodename = dev->nodename;
+    char* err = NULL;
+    XenbusState state;
 
     char path[strlen(dev->backend) + 1 + 5 + 1];
+    char nodename[strlen(dev->nodename) + 1 + 5 + 1];
 
     printk("close kbd: backend at %s\n",dev->backend);
 
     snprintf(path, sizeof(path), "%s/state", dev->backend);
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */
-    xenbus_wait_for_value(path, "5", &dev->events);
+    snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename);
+    if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosing)) != 
NULL) {
+        printk("shutdown_kbdfront: error changing state to %d: %s\n",
+                XenbusStateClosing, err);
+        goto close_kbdfront;
+    }
+    state = xenbus_read_integer(path);
+    while (err == NULL && state < XenbusStateClosing)
+        err = xenbus_wait_for_state_change(path, &state, &dev->events);
 
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
-    xenbus_wait_for_value(path, "6", &dev->events);
+    if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosed)) != 
NULL) {
+        printk("shutdown_kbdfront: error changing state to %d: %s\n",
+                XenbusStateClosed, err);
+        goto close_kbdfront;
+    }
+    state = xenbus_read_integer(path);
+    if (state < XenbusStateClosed)
+        xenbus_wait_for_state_change(path, &state, &dev->events);
 
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
+    if ((err = xenbus_switch_state(XBT_NIL, nodename, 
XenbusStateInitialising)) != NULL) {
+        printk("shutdown_kbdfront: error changing state to %d: %s\n",
+                XenbusStateInitialising, err);
+        goto close_kbdfront;
+    }
     // does not work yet.
     //xenbus_wait_for_value(path, "2", &dev->events);
 
+close_kbdfront:
     xenbus_unwatch_path(XBT_NIL, path);
 
     snprintf(path, sizeof(path), "%s/page-ref", nodename);
@@ -432,8 +468,12 @@
         goto abort_transaction;
     }
 
-    err = xenbus_printf(xbt, nodename, "state", "%u", 3); /* initialized */
-
+    snprintf(path, sizeof(path), "%s/state", nodename);
+    err = xenbus_switch_state(xbt, path, XenbusStateInitialised);
+    if (err) {
+        message = "switching state";
+        goto abort_transaction;
+    }
 
     err = xenbus_transaction_end(xbt, 0, &retry);
     if (retry) {
@@ -459,20 +499,36 @@
     printk("backend at %s\n", dev->backend);
 
     {
+        XenbusState state;
         char path[strlen(dev->backend) + 1 + 14 + 1];
+        char frontpath[strlen(nodename) + 1 + 6 + 1];
 
         snprintf(path, sizeof(path), "%s/state", dev->backend);
 
         xenbus_watch_path_token(XBT_NIL, path, path, &dev->events);
 
-        xenbus_wait_for_value(path, "4", &dev->events);
+        err = NULL;
+        state = xenbus_read_integer(path);
+        while (err == NULL && state < XenbusStateConnected)
+            err = xenbus_wait_for_state_change(path, &state, &dev->events);
+        if (state != XenbusStateConnected) {
+            printk("backend not available, state=%d\n", state);
+            xenbus_unwatch_path(XBT_NIL, path);
+            goto error;
+        }
 
         printk("%s connected\n", dev->backend);
 
         snprintf(path, sizeof(path), "%s/request-update", dev->backend);
         dev->request_update = xenbus_read_integer(path);
 
-        err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 4); /* connected 
*/
+        snprintf(frontpath, sizeof(frontpath), "%s/state", nodename);
+        if ((err = xenbus_switch_state(XBT_NIL, frontpath, 
XenbusStateConnected))
+            != NULL) {
+            printk("error switching state: %s\n", err);
+            xenbus_unwatch_path(XBT_NIL, path);
+            goto error;
+        }
     }
     unmask_evtchn(dev->evtchn);
 
@@ -551,24 +607,43 @@
 
 void shutdown_fbfront(struct fbfront_dev *dev)
 {
-    char* err;
-    char *nodename = dev->nodename;
+    char* err = NULL;
+    XenbusState state;
 
     char path[strlen(dev->backend) + 1 + 5 + 1];
+    char nodename[strlen(dev->nodename) + 1 + 5 + 1];
 
     printk("close fb: backend at %s\n",dev->backend);
 
     snprintf(path, sizeof(path), "%s/state", dev->backend);
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */
-    xenbus_wait_for_value(path, "5", &dev->events);
+    snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename);
+    if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosing)) != 
NULL) {
+        printk("shutdown_fbfront: error changing state to %d: %s\n",
+                XenbusStateClosing, err);
+        goto close_fbfront;
+    }
+    state = xenbus_read_integer(path);
+    while (err == NULL && state < XenbusStateClosing)
+        err = xenbus_wait_for_state_change(path, &state, &dev->events);
 
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
-    xenbus_wait_for_value(path, "6", &dev->events);
+    if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosed)) != 
NULL) {
+        printk("shutdown_fbfront: error changing state to %d: %s\n",
+                XenbusStateClosed, err);
+        goto close_fbfront;
+    }
+    state = xenbus_read_integer(path);
+    if (state < XenbusStateClosed)
+        xenbus_wait_for_state_change(path, &state, &dev->events);
 
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
+    if ((err = xenbus_switch_state(XBT_NIL, nodename, 
XenbusStateInitialising)) != NULL) {
+        printk("shutdown_fbfront: error changing state to %d: %s\n",
+                XenbusStateInitialising, err);
+        goto close_fbfront;
+    }
     // does not work yet
     //xenbus_wait_for_value(path, "2", &dev->events);
 
+close_fbfront:
     xenbus_unwatch_path(XBT_NIL, path);
 
     snprintf(path, sizeof(path), "%s/page-ref", nodename);
diff -r 50e048b77ad1 extras/mini-os/include/xenbus.h
--- a/extras/mini-os/include/xenbus.h   Fri May 29 09:28:15 2009 +0100
+++ b/extras/mini-os/include/xenbus.h   Tue Jun 02 18:14:57 2009 +0100
@@ -1,5 +1,7 @@
 #ifndef XENBUS_H__
 #define XENBUS_H__
+
+#include <xen/io/xenbus.h>
 
 typedef unsigned long xenbus_transaction_t;
 #define XBT_NIL ((xenbus_transaction_t)0)
@@ -27,6 +29,8 @@
 void xenbus_wait_for_watch(xenbus_event_queue *queue);
 char **xenbus_wait_for_watch_return(xenbus_event_queue *queue);
 char* xenbus_wait_for_value(const char *path, const char *value, 
xenbus_event_queue *queue);
+char *xenbus_wait_for_state_change(const char* path, XenbusState *state, 
xenbus_event_queue *queue);
+char *xenbus_switch_state(xenbus_transaction_t xbt, const char* path, 
XenbusState state);
 
 /* When no token is provided, use a global queue. */
 #define XENBUS_WATCH_PATH_TOKEN "xenbus_watch_path"
diff -r 50e048b77ad1 extras/mini-os/netfront.c
--- a/extras/mini-os/netfront.c Fri May 29 09:28:15 2009 +0100
+++ b/extras/mini-os/netfront.c Tue Jun 02 18:14:57 2009 +0100
@@ -405,9 +405,12 @@
         goto abort_transaction;
     }
 
-    err = xenbus_printf(xbt, nodename, "state", "%u",
-            4); /* connected */
-
+    snprintf(path, sizeof(path), "%s/state", nodename);
+    err = xenbus_switch_state(xbt, path, XenbusStateConnected);
+    if (err) {
+        message = "switching state";
+        goto abort_transaction;
+    }
 
     err = xenbus_transaction_end(xbt, 0, &retry);
     if (retry) {
@@ -437,12 +440,21 @@
     printk("mac is %s\n",dev->mac);
 
     {
+        XenbusState state;
         char path[strlen(dev->backend) + 1 + 5 + 1];
         snprintf(path, sizeof(path), "%s/state", dev->backend);
 
         xenbus_watch_path_token(XBT_NIL, path, path, &dev->events);
-
-        xenbus_wait_for_value(path, "4", &dev->events);
+    
+        err = NULL;
+        state = xenbus_read_integer(path);
+        while (err == NULL && state < XenbusStateConnected)
+            err = xenbus_wait_for_state_change(path, &state, &dev->events);
+        if (state != XenbusStateConnected) {
+            printk("backend not avalable, state=%d\n", state);
+            xenbus_unwatch_path(XBT_NIL, path);
+            goto error;
+        }
 
         if (ip) {
             snprintf(path, sizeof(path), "%s/ip", dev->backend);
@@ -490,24 +502,46 @@
 
 void shutdown_netfront(struct netfront_dev *dev)
 {
-    char* err;
-    char *nodename = dev->nodename;
+    char* err = NULL;
+    XenbusState state;
 
     char path[strlen(dev->backend) + 1 + 5 + 1];
+    char nodename[strlen(dev->nodename) + 1 + 5 + 1];
 
     printk("close network: backend at %s\n",dev->backend);
 
     snprintf(path, sizeof(path), "%s/state", dev->backend);
+    snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename);
 
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */
-    xenbus_wait_for_value(path, "5", &dev->events);
+    if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosing)) != 
NULL) {
+        printk("shutdown_netfront: error changing state to %d: %s\n",
+                XenbusStateClosing, err);
+        goto close;
+    }
+    state = xenbus_read_integer(path);
+    while (err == NULL && state < XenbusStateClosing)
+        err = xenbus_wait_for_state_change(path, &state, &dev->events);
 
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
-    xenbus_wait_for_value(path, "6", &dev->events);
+    if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosed)) != 
NULL) {
+        printk("shutdown_netfront: error changing state to %d: %s\n",
+                XenbusStateClosed, err);
+        goto close;
+    }
+    state = xenbus_read_integer(path);
+    if (state < XenbusStateClosed)
+        xenbus_wait_for_state_change(path, &state, &dev->events);
 
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
-    xenbus_wait_for_value(path, "2", &dev->events);
+    if ((err = xenbus_switch_state(XBT_NIL, nodename, 
XenbusStateInitialising)) != NULL) {
+        printk("shutdown_netfront: error changing state to %d: %s\n",
+                XenbusStateInitialising, err);
+        goto close;
+    }
+    err = NULL;
+    state = xenbus_read_integer(path);
+    while (err == NULL && (state < XenbusStateInitWait || state >= 
XenbusStateClosed))
+        err = xenbus_wait_for_state_change(path, &state, &dev->events);
 
+close:
     xenbus_unwatch_path(XBT_NIL, path);
 
     snprintf(path, sizeof(path), "%s/tx-ring-ref", nodename);
diff -r 50e048b77ad1 extras/mini-os/pcifront.c
--- a/extras/mini-os/pcifront.c Fri May 29 09:28:15 2009 +0100
+++ b/extras/mini-os/pcifront.c Tue Jun 02 18:14:57 2009 +0100
@@ -111,9 +111,12 @@
         goto abort_transaction;
     }
 
-    err = xenbus_printf(xbt, nodename, "state", "%u",
-            3); /* initialised */
-
+    snprintf(path, sizeof(path), "%s/state", nodename);
+    err = xenbus_switch_state(xbt, path, XenbusStateInitialised);
+    if (err) {
+        message = "switching state";
+        goto abort_transaction;
+    }
 
     err = xenbus_transaction_end(xbt, 0, &retry);
     if (retry) {
@@ -140,13 +143,29 @@
 
     {
         char path[strlen(dev->backend) + 1 + 5 + 1];
+        char frontpath[strlen(nodename) + 1 + 5 + 1];
+        XenbusState state;
         snprintf(path, sizeof(path), "%s/state", dev->backend);
 
         xenbus_watch_path_token(XBT_NIL, path, path, &dev->events);
 
-        xenbus_wait_for_value(path, "4", &dev->events);
+        err = NULL;
+        state = xenbus_read_integer(path);
+        while (err == NULL && state < XenbusStateConnected)
+            err = xenbus_wait_for_state_change(path, &state, &dev->events);
+        if (state != XenbusStateConnected) {
+            printk("backend not avalable, state=%d\n", state);
+            xenbus_unwatch_path(XBT_NIL, path);
+            goto error;
+        }
 
-        xenbus_printf(xbt, nodename, "state", "%u", 4); /* connected */
+        snprintf(frontpath, sizeof(frontpath), "%s/state", nodename);
+        if ((err = xenbus_switch_state(XBT_NIL, frontpath, 
XenbusStateConnected))
+            != NULL) {
+            printk("error switching state %s\n", err);
+            xenbus_unwatch_path(XBT_NIL, path);
+            goto error;
+        }
     }
     unmask_evtchn(dev->evtchn);
 
@@ -190,23 +209,45 @@
 
 void shutdown_pcifront(struct pcifront_dev *dev)
 {
-    char* err;
-    char *nodename = dev->nodename;
+    char* err = NULL;
+    XenbusState state;
 
     char path[strlen(dev->backend) + 1 + 5 + 1];
+    char nodename[strlen(dev->nodename) + 1 + 5 + 1];
 
     printk("close pci: backend at %s\n",dev->backend);
 
     snprintf(path, sizeof(path), "%s/state", dev->backend);
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */
-    xenbus_wait_for_value(path, "5", &dev->events);
+    snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename);
+    if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosing)) != 
NULL) {
+        printk("shutdown_pcifront: error changing state to %d: %s\n",
+                XenbusStateClosing, err);
+        goto close_pcifront;
+    }
+    state = xenbus_read_integer(path);
+    while (err == NULL && state < XenbusStateClosing)
+        err = xenbus_wait_for_state_change(path, &state, &dev->events);
 
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
-    xenbus_wait_for_value(path, "6", &dev->events);
+    if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosed)) != 
NULL) {
+        printk("shutdown_pcifront: error changing state to %d: %s\n",
+                XenbusStateClosed, err);
+        goto close_pcifront;
+    }
+    state = xenbus_read_integer(path);
+    if (state < XenbusStateClosed)
+        xenbus_wait_for_state_change(path, &state, &dev->events);
 
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
-    xenbus_wait_for_value(path, "2", &dev->events);
+    if ((err = xenbus_switch_state(XBT_NIL, nodename, 
XenbusStateInitialising)) != NULL) {
+        printk("shutdown_pcifront: error changing state to %d: %s\n",
+                XenbusStateInitialising, err);
+        goto close_pcifront;
+    }
+    err = NULL;
+    state = xenbus_read_integer(path);
+    while (err == NULL && (state < XenbusStateInitWait || state >= 
XenbusStateClosed))
+        err = xenbus_wait_for_state_change(path, &state, &dev->events);
 
+close_pcifront:
     xenbus_unwatch_path(XBT_NIL, path);
 
     snprintf(path, sizeof(path), "%s/info-ref", nodename);
diff -r 50e048b77ad1 extras/mini-os/xenbus/xenbus.c
--- a/extras/mini-os/xenbus/xenbus.c    Fri May 29 09:28:15 2009 +0100
+++ b/extras/mini-os/xenbus/xenbus.c    Tue Jun 02 18:14:57 2009 +0100
@@ -118,6 +118,70 @@
         else xenbus_wait_for_watch(queue);
     }
     return NULL;
+}
+
+char *xenbus_switch_state(xenbus_transaction_t xbt, const char* path, 
XenbusState state)
+{
+    char *current_state;
+    char *msg = NULL;
+    char *msg2 = NULL;
+    char value[2];
+    XenbusState rs;
+    int xbt_flag = 0;
+    int retry = 0;
+
+    do {
+        if (xbt == XBT_NIL) {
+            xenbus_transaction_start(&xbt);
+            xbt_flag = 1;
+        }
+
+        msg = xenbus_read(xbt, path, &current_state);
+        if (msg) goto exit;
+
+        rs = (XenbusState) (current_state[0] - '0');
+        free(current_state);
+        if (rs == state) {
+            msg = NULL;
+            goto exit;
+        }
+
+        snprintf(value, 2, "%d", state);
+        msg = xenbus_write(xbt, path, value);
+
+exit:
+        if (xbt_flag)
+            msg2 = xenbus_transaction_end(xbt, 0, &retry);
+        if (msg == NULL && msg2 != NULL)
+            msg = msg2;
+    } while (retry);
+
+    return msg;
+}
+
+char *xenbus_wait_for_state_change(const char* path, XenbusState *state, 
xenbus_event_queue *queue)
+{
+    if (!queue)
+        queue = &xenbus_events;
+    for(;;)
+    {
+        char *res, *msg;
+        XenbusState rs;
+
+        msg = xenbus_read(XBT_NIL, path, &res);
+        if(msg) return msg;
+
+        rs = (XenbusState) (res[0] - 48);
+        free(res);
+
+        if (rs == *state)
+            xenbus_wait_for_watch(queue);
+        else {
+            *state = rs;
+            break;
+        }
+    }
+    return NULL; 
 }
 
 

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


 


Rackspace

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