WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] minios: refactor xenbus state machine

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] minios: refactor xenbus state machine
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 04 Jun 2009 10:25:09 -0700
Delivery-date: Thu, 04 Jun 2009 10:25:32 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1244023754 -3600
# Node ID 18c8270da77cbb970b3b0498b09ad10481c1e6fb
# Parent  f72d26c0000292889cfe3a85008d2c4482fee772
minios: refactor xenbus state machine

Implement xenbus_wait_for_state_change and xenbus_switch_state and
change the various frontends to use the two functions and do proper
error checking.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
---
 extras/mini-os/blkfront.c       |   66 ++++++++++++++++-----
 extras/mini-os/fbfront.c        |  125 ++++++++++++++++++++++++++++++++--------
 extras/mini-os/include/xenbus.h |    4 +
 extras/mini-os/netfront.c       |   66 ++++++++++++++++-----
 extras/mini-os/pcifront.c       |   75 ++++++++++++++++++------
 extras/mini-os/xenbus/xenbus.c  |   64 ++++++++++++++++++++
 6 files changed, 327 insertions(+), 73 deletions(-)

diff -r f72d26c00002 -r 18c8270da77c extras/mini-os/blkfront.c
--- a/extras/mini-os/blkfront.c Tue Jun 02 11:50:16 2009 +0100
+++ b/extras/mini-os/blkfront.c Wed Jun 03 11:09:14 2009 +0100
@@ -149,8 +149,12 @@ again:
         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 @@ done:
     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 @@ done:
 
         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 @@ error:
 
 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);
-
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
-    xenbus_wait_for_value(path, "6", &dev->events);
-
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
-    xenbus_wait_for_value(path, "2", &dev->events);
-
+    snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename);
+
+    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);
+
+    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 f72d26c00002 -r 18c8270da77c extras/mini-os/fbfront.c
--- a/extras/mini-os/fbfront.c  Tue Jun 02 11:50:16 2009 +0100
+++ b/extras/mini-os/fbfront.c  Wed Jun 03 11:09:14 2009 +0100
@@ -121,7 +121,8 @@ again:
         }
     }
 
-    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 @@ done:
     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 @@ int kbdfront_receive(struct kbdfront_dev
 
 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);
-
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
-    xenbus_wait_for_value(path, "6", &dev->events);
-
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
+    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);
+
+    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);
+
+    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 @@ again:
         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 @@ done:
     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 fbfront_resize(struct fbfront_dev *
 
 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);
-
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
-    xenbus_wait_for_value(path, "6", &dev->events);
-
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
+    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);
+
+    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);
+
+    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 f72d26c00002 -r 18c8270da77c extras/mini-os/include/xenbus.h
--- a/extras/mini-os/include/xenbus.h   Tue Jun 02 11:50:16 2009 +0100
+++ b/extras/mini-os/include/xenbus.h   Wed Jun 03 11:09:14 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_
 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 f72d26c00002 -r 18c8270da77c extras/mini-os/netfront.c
--- a/extras/mini-os/netfront.c Tue Jun 02 11:50:16 2009 +0100
+++ b/extras/mini-os/netfront.c Wed Jun 03 11:09:14 2009 +0100
@@ -405,9 +405,12 @@ again:
         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 @@ done:
     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 @@ int netfront_tap_open(char *nodename) {
 
 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);
-
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */
-    xenbus_wait_for_value(path, "5", &dev->events);
-
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
-    xenbus_wait_for_value(path, "6", &dev->events);
-
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
-    xenbus_wait_for_value(path, "2", &dev->events);
-
+    snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename);
+
+    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);
+
+    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);
+
+    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 f72d26c00002 -r 18c8270da77c extras/mini-os/pcifront.c
--- a/extras/mini-os/pcifront.c Tue Jun 02 11:50:16 2009 +0100
+++ b/extras/mini-os/pcifront.c Wed Jun 03 11:09:14 2009 +0100
@@ -111,9 +111,12 @@ again:
         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 @@ done:
 
     {
         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);
-
-        xenbus_printf(xbt, nodename, "state", "%u", 4); /* connected */
+        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;
+        }
+
+        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 pcifront_scan(struct pcifront_dev *
 
 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);
-
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
-    xenbus_wait_for_value(path, "6", &dev->events);
-
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
-    xenbus_wait_for_value(path, "2", &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);
+
+    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);
+
+    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 f72d26c00002 -r 18c8270da77c extras/mini-os/xenbus/xenbus.c
--- a/extras/mini-os/xenbus/xenbus.c    Tue Jun 02 11:50:16 2009 +0100
+++ b/extras/mini-os/xenbus/xenbus.c    Wed Jun 03 11:09:14 2009 +0100
@@ -120,6 +120,70 @@ char* xenbus_wait_for_value(const char* 
     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;
+}
+
 
 static void xenbus_thread_func(void *ign)
 {

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] minios: refactor xenbus state machine, Xen patchbot-unstable <=