[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [UNIKRAFT PATCH 07/10] plat/xen/drivers/cons: Start Consfront



This patch adds start for the xen console frontend.
Uses XenStore in order to establish connection
to backend.

Signed-off-by: Birlea Costin <costin.birlea@xxxxxxxxx>
---
 plat/xen/drivers/cons/consfront.c    |  38 ++++++++
 plat/xen/drivers/cons/consfront_xb.h |  19 ++++
 plat/xen/drivers/cons/consfront_xs.c | 176 +++++++++++++++++++++++++++++++++++
 3 files changed, 233 insertions(+)

diff --git a/plat/xen/drivers/cons/consfront.c 
b/plat/xen/drivers/cons/consfront.c
index cdbed0f5..4dd57151 100644
--- a/plat/xen/drivers/cons/consfront.c
+++ b/plat/xen/drivers/cons/consfront.c
@@ -216,6 +216,42 @@ static int consfront_release(struct uk_consdev *dev)
        return 0;
 }
 
+static int consfront_start(struct uk_consdev *dev)
+{
+       struct consfront_dev *cfdev;
+       int rc = 0;
+
+       UK_ASSERT(dev);
+
+       cfdev = to_consfront(dev);
+       UK_ASSERT(cfdev);
+
+       rc = consfront_xb_connect(cfdev);
+       if (rc < 0) {
+               uk_pr_err("Error connecting to backend: %d.\n", rc);
+               return rc;
+       }
+       uk_pr_info(DRIVER_NAME": %"PRIu16" started\n", cfdev->uid);
+
+       return rc;
+}
+
+static int consfront_stop(struct uk_consdev *dev)
+{
+       struct consfront_dev *cfdev;
+
+       UK_ASSERT(dev);
+
+       cfdev = to_consfront(dev);
+       UK_ASSERT(cfdev);
+
+       consfront_xb_disconnect(cfdev);
+
+       uk_pr_info(DRIVER_NAME": %"PRIu16" stopped\n", cfdev->uid);
+
+       return 0;
+}
+
 static void consfront_close(struct uk_consdev *dev)
 {
        struct consfront_dev *cfdev;
@@ -240,6 +276,8 @@ static const struct uk_consdev_ops consfront_ops = {
        .rx_configure = consfront_rx_configure,
        .tx_configure = consfront_tx_configure,
        .release = consfront_release,
+       .start = consfront_start,
+       .stop = consfront_stop,
        .close = consfront_close,
 };
 
diff --git a/plat/xen/drivers/cons/consfront_xb.h 
b/plat/xen/drivers/cons/consfront_xb.h
index 0ca1abaf..6b5475f3 100644
--- a/plat/xen/drivers/cons/consfront_xb.h
+++ b/plat/xen/drivers/cons/consfront_xb.h
@@ -44,6 +44,25 @@
 
 #include "consfront.h"
 
+/**
+ * Write ring entries to Xenstore.
+ * Device changes its state to Connected.
+ * It waits until the backend is connected.
+ *
+ * Return 0 on success, a negative errno value on error.
+ */
+int consfront_xb_connect(struct consfront_dev *cfdev);
+
+/**
+ * Stops the connection with the backend.
+ * The following states are:
+ *     Connected -> Closing -> Closed.
+ * Delete ring entries
+ *
+ * Return 0 on success, a negative errno value on error.
+ */
+int consfront_xb_disconnect(struct consfront_dev *cfdev);
+
 /*
  * Get initial info from the xenstore.
  * Ex: backend path.
diff --git a/plat/xen/drivers/cons/consfront_xs.c 
b/plat/xen/drivers/cons/consfront_xs.c
index 066a23d9..a1554ae0 100644
--- a/plat/xen/drivers/cons/consfront_xs.c
+++ b/plat/xen/drivers/cons/consfront_xs.c
@@ -40,6 +40,182 @@
 
 #include "consfront_xb.h"
 
+static void consfront_xb_front_fini(struct consfront_dev *cfdev,
+               xenbus_transaction_t xbt);
+
+#define WAIT_BE_STATE_CHANGE_WHILE_COND(state_cond) \
+       do { \
+               rc = xs_read_integer(XBT_NIL, path, (int *) &be_state); \
+               if (rc < 0) \
+                       goto out; \
+               while (!rc && (state_cond)) \
+                       rc = xenbus_wait_for_state_change(path, &be_state, \
+                                       xendev->otherend_watch); \
+               if (rc < 0) \
+                       goto out; \
+       } while (0)
+
+
+static int consfront_xb_front_init(struct consfront_dev *cfdev,
+               xenbus_transaction_t xbt)
+{
+       int rc = 0;
+       struct xenbus_device *xendev = cfdev->xendev;
+
+       rc = xs_printf(xbt, xendev->nodename, "ring-ref", "%u",
+                               cfdev->ring_ref);
+       if (rc < 0)
+               goto out;
+
+       rc = xs_printf(xbt, xendev->nodename,
+                               "port", "%u", cfdev->evtchn);
+       if (rc < 0)
+               goto out;
+
+out:
+       return rc;
+}
+
+static int consfront_xb_transactions(struct consfront_dev *cfdev)
+{
+       struct xenbus_device *xendev = cfdev->xendev;
+       xenbus_transaction_t xbt;
+       char *message = NULL;
+       int rc = 0;
+
+       rc = xs_transaction_start(&xbt);
+       if (rc < 0) {
+               message = "starting transaction";
+               goto abort_transaction;
+       }
+
+       rc = consfront_xb_front_init(cfdev, xbt);
+       if (rc < 0) {
+               message = "writing something";
+               goto abort_transaction;
+       }
+
+       rc = xenbus_switch_state(xbt, xendev, XenbusStateConnected);
+       if (rc < 0) {
+               message = "switching state";
+               goto abort_transaction;
+       }
+
+       rc = xs_transaction_end(xbt, 0);
+       if (rc < 0) {
+               message = "ending transaction";
+               goto abort_transaction;
+       }
+
+       return rc;
+
+abort_transaction:
+       xs_transaction_end(xbt, 1);
+       uk_pr_info("Abort transaction %s: code: %d\n", message, rc);
+       return rc;
+}
+
+static int consfront_xb_wait_be_connect(struct consfront_dev *cfdev)
+{
+       struct xenbus_device *xendev = cfdev->xendev;
+       char path[strlen(xendev->otherend) + strlen("/state") + 1];
+       XenbusState be_state;
+       int rc = 0;
+
+       snprintf(path, sizeof(path), "%s/state", xendev->otherend);
+
+       xendev->otherend_watch = xs_watch_path(XBT_NIL, path);
+       if (PTRISERR(xendev->otherend_watch)) {
+               rc = PTR2ERR(xendev->otherend_watch);
+               goto out;
+       }
+
+       WAIT_BE_STATE_CHANGE_WHILE_COND(be_state < XenbusStateConnected);
+       if (be_state != XenbusStateConnected) {
+               uk_pr_err("Backend not available, state=%s\n",
+                                               xenbus_state_to_str(be_state));
+               xs_unwatch(XBT_NIL, xendev->otherend_watch);
+       }
+
+out:
+       return rc;
+}
+
+int consfront_xb_connect(struct consfront_dev *cfdev)
+{
+       int rc = 0;
+
+       UK_ASSERT(cfdev);
+
+       rc = consfront_xb_transactions(cfdev);
+       if (rc < 0)
+               goto error;
+
+       rc = consfront_xb_wait_be_connect(cfdev);
+       if (rc < 0)
+               consfront_xb_front_fini(cfdev, XBT_NIL);
+
+error:
+       return rc;
+}
+
+static void consfront_xb_front_fini(struct consfront_dev *cfdev,
+               xenbus_transaction_t xbt)
+{
+       struct xenbus_device *xendev = cfdev->xendev;
+       char path[strlen(xendev->nodename) + sizeof("/ring_ref")];
+
+       sprintf(path, "%s/ring-ref", xendev->nodename);
+       xs_rm(xbt, path);
+
+       sprintf(path, "%s/port", xendev->nodename);
+       xs_rm(xbt, path);
+}
+
+static int consfront_xb_wait_be_disconnect(struct consfront_dev *cfdev)
+{
+       struct xenbus_device *xendev = cfdev->xendev;
+       char path[strlen(xendev->otherend) + strlen("/state") + 1];
+       XenbusState be_state;
+       int rc = 0;
+
+       snprintf(path, sizeof(path), "%s/state", xendev->otherend);
+
+       WAIT_BE_STATE_CHANGE_WHILE_COND(be_state < XenbusStateClosing);
+
+       rc = xenbus_switch_state(XBT_NIL, xendev, XenbusStateClosed);
+       if (rc < 0)
+               goto out;
+
+       WAIT_BE_STATE_CHANGE_WHILE_COND(be_state < XenbusStateClosed);
+
+       xs_unwatch(XBT_NIL, xendev->otherend_watch);
+
+out:
+       return rc;
+}
+
+int consfront_xb_disconnect(struct consfront_dev *cfdev)
+{
+       struct xenbus_device *xendev = cfdev->xendev;
+       int rc = 0;
+
+       uk_pr_info("Close console: backend at %s\n", xendev->otherend);
+
+       rc = xenbus_switch_state(XBT_NIL, xendev, XenbusStateClosing);
+       if (rc < 0)
+               goto out;
+
+       rc = consfront_xb_wait_be_disconnect(cfdev);
+       if (rc < 0)
+               goto out;
+
+       consfront_xb_front_fini(cfdev, XBT_NIL);
+
+out:
+       return rc;
+}
+
 int consfront_xb_init(struct consfront_dev *cfdev)
 {
        struct xenbus_device *xendev;
-- 
2.11.0


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.