All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] minios: xenbus refactoring
@ 2009-06-02 17:45 Stefano Stabellini
  0 siblings, 0 replies; only message in thread
From: Stefano Stabellini @ 2009-06-02 17:45 UTC (permalink / raw)
  To: xen-devel; +Cc: Steven Smith

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@eu.citrix.com>

---

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; 
 }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2009-06-02 17:45 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-06-02 17:45 [PATCH] minios: xenbus refactoring Stefano Stabellini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.