|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH v2 09/16] plat/xen/drivers/blk: Start blkfront device
This patch introduces start/stop operations to blkfront device.
This implies connection to backend by communication through Xenstore.
Signed-off-by: Roxana Nicolescu <nicolescu.roxana1996@xxxxxxxxx>
---
plat/xen/drivers/blk/blkfront.c | 39 +++++++++++
plat/xen/drivers/blk/blkfront_xb.h | 17 +++++
plat/xen/drivers/blk/blkfront_xs.c | 129 +++++++++++++++++++++++++++++++++++++
3 files changed, 185 insertions(+)
diff --git a/plat/xen/drivers/blk/blkfront.c b/plat/xen/drivers/blk/blkfront.c
index 98e676e0..64fdd78e 100644
--- a/plat/xen/drivers/blk/blkfront.c
+++ b/plat/xen/drivers/blk/blkfront.c
@@ -272,6 +272,43 @@ out_err:
uk_free(drv_allocator, dev->queues);
goto out;
}
+
+static int blkfront_start(struct uk_blkdev *blkdev)
+{
+ struct blkfront_dev *dev;
+ int err = 0;
+
+ UK_ASSERT(blkdev != NULL);
+ dev = to_blkfront(blkdev);
+ err = blkfront_xb_connect(dev);
+ if (err) {
+ uk_pr_err("Failed to connect to backend: %d.\n", err);
+ return err;
+ }
+
+ uk_pr_info(DRIVER_NAME": %"PRIu16" started\n", dev->uid);
+
+ return err;
+}
+
+static int blkfront_stop(struct uk_blkdev *blkdev)
+{
+ struct blkfront_dev *dev;
+ int err;
+
+ UK_ASSERT(blkdev != NULL);
+
+ dev = to_blkfront(blkdev);
+ err = blkfront_xb_disconnect(dev);
+ if (err) {
+ uk_pr_err(
+ "Failed to disconnect: %d.\n", err);
+ return err;
+ }
+
+ uk_pr_info(DRIVER_NAME": %"PRIu16" stopped\n", dev->uid);
+
+ return err;
}
static void blkfront_unconfigure(struct uk_blkdev *blkdev)
@@ -308,6 +345,8 @@ static const struct uk_blkdev_ops blkfront_ops = {
.queue_get_info = blkfront_queue_get_info,
.queue_setup = blkfront_queue_setup,
.queue_release = blkfront_queue_release,
+ .dev_start = blkfront_start,
+ .dev_stop = blkfront_stop,
.dev_unconfigure = blkfront_unconfigure,
.queue_intr_enable = blkfront_queue_intr_enable,
.queue_intr_disable = blkfront_queue_intr_disable,
diff --git a/plat/xen/drivers/blk/blkfront_xb.h
b/plat/xen/drivers/blk/blkfront_xb.h
index a846fda7..60070d9c 100644
--- a/plat/xen/drivers/blk/blkfront_xb.h
+++ b/plat/xen/drivers/blk/blkfront_xb.h
@@ -64,4 +64,21 @@ void blkfront_xb_fini(struct blkfront_dev *dev);
*/
int blkfront_xb_write_nb_queues(struct blkfront_dev *dev);
+/**
+ * Device changes its state to Connected.
+ * It waits until the backend is connected.
+ *
+ * Return 0 on success, a negative errno value on error.
+ */
+int blkfront_xb_connect(struct blkfront_dev *dev);
+
+/**
+ * Reinitialize the connection with the backend.
+ * The following states are:
+ * Connected -> Closing -> Closed -> Initializing.
+ *
+ * Return 0 on success, a negative errno value on error.
+ */
+int blkfront_xb_disconnect(struct blkfront_dev *dev);
+
#endif /* __BLKFRONT_XB_H__ */
diff --git a/plat/xen/drivers/blk/blkfront_xs.c
b/plat/xen/drivers/blk/blkfront_xs.c
index 13c25969..5ddb38d0 100644
--- a/plat/xen/drivers/blk/blkfront_xs.c
+++ b/plat/xen/drivers/blk/blkfront_xs.c
@@ -163,3 +163,132 @@ int blkfront_xb_write_nb_queues(struct blkfront_dev *dev)
out:
return err;
}
+
+#define WAIT_BE_STATE_CHANGE_WHILE_COND(state_cond) \
+ do { \
+ err = xs_read_integer(XBT_NIL, back_state_path,\
+ (int *) &back_state); \
+ if (err) \
+ goto out; \
+ while (!err && (state_cond)) \
+ err = xenbus_wait_for_state_change(back_state_path, \
+ &back_state, \
+ xendev->otherend_watch); \
+ if (err) \
+ goto out; \
+ } while (0)
+
+
+static int blkfront_xb_wait_be_connect(struct blkfront_dev *blkdev)
+{
+ struct xenbus_device *xendev;
+ char *back_state_path = NULL;
+ XenbusState back_state;
+ int err = 0;
+
+ UK_ASSERT(blkdev != NULL);
+ xendev = blkdev->xendev;
+ err = asprintf(&back_state_path, "%s/state", xendev->otherend);
+ if (err <= 0) {
+ uk_pr_err("Failed to format back_state_path: %d\n", err);
+ goto out;
+ }
+
+ WAIT_BE_STATE_CHANGE_WHILE_COND(back_state < XenbusStateConnected);
+ if (back_state != XenbusStateConnected) {
+ uk_pr_err("Backend not available, state=%s\n",
+ xenbus_state_to_str(back_state));
+ err = -1;
+ goto out;
+ }
+
+out:
+ free(back_state_path);
+ return err;
+}
+
+static int blkfront_xb_wait_be_disconnect(struct blkfront_dev *blkdev)
+{
+ struct xenbus_device *xendev;
+ char *back_state_path = NULL;
+ XenbusState back_state;
+ int err = 0;
+
+ UK_ASSERT(blkdev != NULL);
+ xendev = blkdev->xendev;
+
+ err = asprintf(&back_state_path, "%s/state", xendev->otherend);
+ if (err <= 0) {
+ uk_pr_err("Failed to format back_state_path: %d\n", err);
+ goto out;
+ }
+
+ WAIT_BE_STATE_CHANGE_WHILE_COND(back_state < XenbusStateClosing);
+ err = xenbus_switch_state(XBT_NIL, xendev, XenbusStateClosed);
+ if (err) {
+ uk_pr_err("Failed to switch state to Closed: %d\n", err);
+ goto out;
+ }
+
+ WAIT_BE_STATE_CHANGE_WHILE_COND(back_state < XenbusStateClosed);
+ err = xenbus_switch_state(XBT_NIL, xendev, XenbusStateInitialising);
+ if (err) {
+ uk_pr_err("Failed to switch state to Initialising: %d\n", err);
+ goto out;
+ }
+
+ WAIT_BE_STATE_CHANGE_WHILE_COND(back_state < XenbusStateInitWait ||
+ back_state >= XenbusStateClosed);
+
+out:
+ free(back_state_path);
+ return err;
+}
+
+int blkfront_xb_connect(struct blkfront_dev *blkdev)
+{
+ int err;
+ struct xenbus_device *xendev;
+
+ UK_ASSERT(blkdev != NULL);
+ xendev = blkdev->xendev;
+
+ err = xenbus_switch_state(XBT_NIL, xendev, XenbusStateConnected);
+ if (err)
+ goto err;
+
+ err = blkfront_xb_wait_be_connect(blkdev);
+ if (err)
+ goto err;
+
+err:
+ return err;
+}
+
+int blkfront_xb_disconnect(struct blkfront_dev *blkdev)
+{
+ struct xenbus_device *xendev;
+ int err;
+
+ UK_ASSERT(blkdev != NULL);
+
+ xendev = blkdev->xendev;
+
+ uk_pr_info("Disconnect blkfront: backend at %s\n",
+ xendev->otherend);
+
+ err = xenbus_switch_state(XBT_NIL, xendev, XenbusStateClosing);
+ if (err) {
+ uk_pr_err("Failed to switch state to Closing: %d\n", err);
+ goto out;
+ }
+
+ err = blkfront_xb_wait_be_disconnect(blkdev);
+ if (err) {
+ uk_pr_err("Failed to disconnect: %d\n", err);
+ goto out;
+ }
+
+out:
+ return err;
+}
--
2.11.0
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |