aboutsummaryrefslogtreecommitdiffstats
path: root/extras/mini-os/console/xenbus.c
diff options
context:
space:
mode:
authorDaniel De Graaf <dgdegra@tycho.nsa.gov>2012-02-09 18:33:32 +0000
committerDaniel De Graaf <dgdegra@tycho.nsa.gov>2012-02-09 18:33:32 +0000
commit434a41d81776964364f426e3132489003c05e5df (patch)
tree1eb8a6a1846c155e049bf71d6c988fd52b3df458 /extras/mini-os/console/xenbus.c
parent8111e0c59583ac278ecd07ca4c6be04d8802e567 (diff)
downloadxen-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.c198
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);
+}
+