diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-06-03 11:09:14 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-06-03 11:09:14 +0100 |
commit | 8323478d5bd96cb1c00cd67da33f59a42965d9be (patch) | |
tree | 3d710fd5ec5b81c3e10d65a0c7208224dd23ae55 /extras/mini-os/netfront.c | |
parent | 44d374adc01fc7cd3e516d6475dc5e9ddedf928d (diff) | |
download | xen-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/netfront.c')
-rw-r--r-- | extras/mini-os/netfront.c | 62 |
1 files changed, 48 insertions, 14 deletions
diff --git a/extras/mini-os/netfront.c b/extras/mini-os/netfront.c index a235769377..ea092df074 100644 --- a/extras/mini-os/netfront.c +++ b/extras/mini-os/netfront.c @@ -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); + 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); - - 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); + 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); |