From 8323478d5bd96cb1c00cd67da33f59a42965d9be Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 3 Jun 2009 11:09:14 +0100 Subject: 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 --- extras/mini-os/blkfront.c | 62 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 13 deletions(-) (limited to 'extras/mini-os/blkfront.c') 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); -- cgit v1.2.3