aboutsummaryrefslogtreecommitdiffstats
path: root/extras/mini-os/blkfront.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-06-03 11:09:14 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-06-03 11:09:14 +0100
commit8323478d5bd96cb1c00cd67da33f59a42965d9be (patch)
tree3d710fd5ec5b81c3e10d65a0c7208224dd23ae55 /extras/mini-os/blkfront.c
parent44d374adc01fc7cd3e516d6475dc5e9ddedf928d (diff)
downloadxen-8323478d5bd96cb1c00cd67da33f59a42965d9be.tar.gz
xen-8323478d5bd96cb1c00cd67da33f59a42965d9be.tar.bz2
xen-8323478d5bd96cb1c00cd67da33f59a42965d9be.zip
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@eu.citrix.com>
Diffstat (limited to 'extras/mini-os/blkfront.c')
-rw-r--r--extras/mini-os/blkfront.c62
1 files changed, 49 insertions, 13 deletions
diff --git a/extras/mini-os/blkfront.c b/extras/mini-os/blkfront.c
index 1534747acb..bba1a2ffa6 100644
--- a/extras/mini-os/blkfront.c
+++ b/extras/mini-os/blkfront.c
@@ -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);
+ snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename);
- 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, 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);