[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 |