diff options
author | Daniel De Graaf <dgdegra@tycho.nsa.gov> | 2012-02-09 18:33:32 +0000 |
---|---|---|
committer | Daniel De Graaf <dgdegra@tycho.nsa.gov> | 2012-02-09 18:33:32 +0000 |
commit | 434a41d81776964364f426e3132489003c05e5df (patch) | |
tree | 1eb8a6a1846c155e049bf71d6c988fd52b3df458 /extras/mini-os/console/xenbus.c | |
parent | 8111e0c59583ac278ecd07ca4c6be04d8802e567 (diff) | |
download | xen-434a41d81776964364f426e3132489003c05e5df.tar.gz xen-434a41d81776964364f426e3132489003c05e5df.tar.bz2 xen-434a41d81776964364f426e3132489003c05e5df.zip |
mini-os: make frontends and xenbus optional
This adds compile-time logic to disable certain frontends in mini-os:
- pcifront is disabled by default, enabled for ioemu
- blkfront, netfront, fbfront, kbdfront, consfront are enabled by default
- xenbus is required for any frontend, and is enabled by default
If all frontends and xenbus are disabled, mini-os will run without
needing to communicate with xenstore, making it suitable to run the
xenstore daemon. The console frontend is not required for the initial
console, only consoles opened via openpt or ptmx.
Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Committed-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
Diffstat (limited to 'extras/mini-os/console/xenbus.c')
-rw-r--r-- | extras/mini-os/console/xenbus.c | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/extras/mini-os/console/xenbus.c b/extras/mini-os/console/xenbus.c new file mode 100644 index 0000000000..77de82a0fa --- /dev/null +++ b/extras/mini-os/console/xenbus.c @@ -0,0 +1,198 @@ +#include <mini-os/types.h> +#include <mini-os/wait.h> +#include <mini-os/mm.h> +#include <mini-os/hypervisor.h> +#include <mini-os/events.h> +#include <mini-os/os.h> +#include <mini-os/lib.h> +#include <mini-os/xenbus.h> +#include <xen/io/console.h> +#include <xen/io/protocols.h> +#include <xen/io/ring.h> +#include <mini-os/xmalloc.h> +#include <mini-os/gnttab.h> +#include "console.h" + +void free_consfront(struct consfront_dev *dev) +{ + char* err = NULL; + XenbusState state; + + char path[strlen(dev->backend) + 1 + 5 + 1]; + char nodename[strlen(dev->nodename) + 1 + 5 + 1]; + + snprintf(path, sizeof(path), "%s/state", dev->backend); + snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename); + + if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosing)) != NULL) { + printk("free_consfront: 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) free(err); + + if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosed)) != NULL) { + printk("free_consfront: error changing state to %d: %s\n", + XenbusStateClosed, err); + goto close; + } + +close: + if (err) free(err); + xenbus_unwatch_path_token(XBT_NIL, path, path); + + mask_evtchn(dev->evtchn); + unbind_evtchn(dev->evtchn); + free(dev->backend); + free(dev->nodename); + + gnttab_end_access(dev->ring_ref); + + free_page(dev->ring); + free(dev); +} + +struct consfront_dev *init_consfront(char *_nodename) +{ + xenbus_transaction_t xbt; + char* err; + char* message=NULL; + int retry=0; + char* msg = NULL; + char nodename[256]; + char path[256]; + static int consfrontends = 3; + struct consfront_dev *dev; + int res; + + if (!_nodename) + snprintf(nodename, sizeof(nodename), "device/console/%d", consfrontends); + else + strncpy(nodename, _nodename, sizeof(nodename)); + + printk("******************* CONSFRONT for %s **********\n\n\n", nodename); + + consfrontends++; + dev = malloc(sizeof(*dev)); + memset(dev, 0, sizeof(*dev)); + dev->nodename = strdup(nodename); +#ifdef HAVE_LIBC + dev->fd = -1; +#endif + + snprintf(path, sizeof(path), "%s/backend-id", nodename); + if ((res = xenbus_read_integer(path)) < 0) + return NULL; + else + dev->dom = res; + evtchn_alloc_unbound(dev->dom, console_handle_input, dev, &dev->evtchn); + + dev->ring = (struct xencons_interface *) alloc_page(); + memset(dev->ring, 0, PAGE_SIZE); + dev->ring_ref = gnttab_grant_access(dev->dom, virt_to_mfn(dev->ring), 0); + + dev->events = NULL; + +again: + err = xenbus_transaction_start(&xbt); + if (err) { + printk("starting transaction\n"); + free(err); + } + + err = xenbus_printf(xbt, nodename, "ring-ref","%u", + dev->ring_ref); + if (err) { + message = "writing ring-ref"; + goto abort_transaction; + } + err = xenbus_printf(xbt, nodename, + "port", "%u", dev->evtchn); + if (err) { + message = "writing event-channel"; + goto abort_transaction; + } + err = xenbus_printf(xbt, nodename, + "protocol", "%s", XEN_IO_PROTO_ABI_NATIVE); + if (err) { + message = "writing protocol"; + goto abort_transaction; + } + + err = xenbus_printf(xbt, nodename, "type", "%s", "ioemu"); + if (err) { + message = "writing type"; + goto abort_transaction; + } + + 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 (err) free(err); + if (retry) { + goto again; + printk("completing transaction\n"); + } + + goto done; + +abort_transaction: + free(err); + err = xenbus_transaction_end(xbt, 1, &retry); + printk("Abort transaction %s\n", message); + goto error; + +done: + + snprintf(path, sizeof(path), "%s/backend", nodename); + msg = xenbus_read(XBT_NIL, path, &dev->backend); + if (msg) { + printk("Error %s when reading the backend path %s\n", msg, path); + goto error; + } + + printk("backend at %s\n", dev->backend); + + { + XenbusState state; + char path[strlen(dev->backend) + 1 + 19 + 1]; + snprintf(path, sizeof(path), "%s/state", dev->backend); + + xenbus_watch_path_token(XBT_NIL, path, path, &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_token(XBT_NIL, path, path); + goto error; + } + } + unmask_evtchn(dev->evtchn); + + printk("**************************\n"); + + return dev; + +error: + free(msg); + free(err); + free_consfront(dev); + return NULL; +} + +void fini_console(struct consfront_dev *dev) +{ + if (dev) free_consfront(dev); +} + |