Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From acd8f51fc654fdcd8c5b220d743063bedf61704b Mon Sep 17 00:00:00 2001
- From: Roger Pau Monne <roger.pau@citrix.com>
- Date: Thu, 21 May 2015 19:06:09 +0200
- Subject: [PATCH] blkback: add support for hotplug scripts
- Hotplug scripts are needed in order to use fancy disk configurations in xl,
- like iSCSI disks. The job of hotplug scripts is to locally attach the disk
- and present it to blkback as a block device or a regular file.
- This change introduces a new xenstore node in the blkback hierarchy, called
- "path". This is a straigh replacement for the "params" node, which was used
- before.
- Hotplug scripts will need to read the "params" node, perform whatever
- actions are necessary and then write the "path" node. The hotplug script is
- also in charge of detaching the disk once the domain has been shutdown.
- Sponsored by: Citrix Systems R&D
- ---
- sys/dev/xen/blkback/blkback.c | 196 +++++++++++++++++++++++++-----------------
- 1 file changed, 118 insertions(+), 78 deletions(-)
- diff --git a/sys/dev/xen/blkback/blkback.c b/sys/dev/xen/blkback/blkback.c
- index a97314b..aef5af1 100644
- --- a/sys/dev/xen/blkback/blkback.c
- +++ b/sys/dev/xen/blkback/blkback.c
- @@ -802,6 +802,9 @@ struct xbb_softc {
- /** How many times we have run out of request structures */
- uint64_t request_shortages;
- +
- + /** Watch to wait for hotplug script execution */
- + struct xs_watch hotplug_watch;
- };
- /*---------------------------- Request Processing ----------------------------*/
- @@ -3310,7 +3313,7 @@ xbb_connect(struct xbb_softc *xbb)
- {
- int error;
- - if (xenbus_get_state(xbb->dev) == XenbusStateConnected)
- + if (xenbus_get_state(xbb->dev) != XenbusStateInitialised)
- return;
- if (xbb_collect_frontend_info(xbb) != 0)
- @@ -3587,61 +3590,23 @@ xbb_setup_sysctl(struct xbb_softc *xbb)
- "communication channel pages (negotiated)");
- }
- -/**
- - * Attach to a XenBus device that has been claimed by our probe routine.
- - *
- - * \param dev NewBus device object representing this Xen Block Back instance.
- - *
- - * \return 0 for success, errno codes for failure.
- - */
- -static int
- -xbb_attach(device_t dev)
- +static void
- +xbb_attach_disk(struct xs_watch *watch, const char **vec, unsigned int len)
- {
- + device_t dev;
- struct xbb_softc *xbb;
- int error;
- - u_int max_ring_page_order;
- - DPRINTF("Attaching to %s\n", xenbus_get_node(dev));
- -
- - /*
- - * Basic initialization.
- - * After this block it is safe to call xbb_detach()
- - * to clean up any allocated data for this instance.
- - */
- + dev = (device_t) watch->callback_data;
- xbb = device_get_softc(dev);
- - xbb->dev = dev;
- - xbb->otherend_id = xenbus_get_otherend_id(dev);
- - TASK_INIT(&xbb->io_task, /*priority*/0, xbb_run_queue, xbb);
- - mtx_init(&xbb->lock, device_get_nameunit(dev), NULL, MTX_DEF);
- - /*
- - * Publish protocol capabilities for consumption by the
- - * front-end.
- - */
- - error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev),
- - "feature-barrier", "1");
- - if (error) {
- - xbb_attach_failed(xbb, error, "writing %s/feature-barrier",
- - xenbus_get_node(xbb->dev));
- - return (error);
- - }
- -
- - error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev),
- - "feature-flush-cache", "1");
- - if (error) {
- - xbb_attach_failed(xbb, error, "writing %s/feature-flush-cache",
- - xenbus_get_node(xbb->dev));
- - return (error);
- - }
- + error = xs_gather(XST_NIL, xenbus_get_node(dev), "path", NULL,
- + &xbb->dev_name, NULL);
- + if (error != 0)
- + return;
- - max_ring_page_order = flsl(XBB_MAX_RING_PAGES) - 1;
- - error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev),
- - "max-ring-page-order", "%u", max_ring_page_order);
- - if (error) {
- - xbb_attach_failed(xbb, error, "writing %s/max-ring-page-order",
- - xenbus_get_node(xbb->dev));
- - return (error);
- - }
- + xs_unregister_watch(watch);
- + free(watch->node, M_XENBLOCKBACK);
- /* Collect physical device information. */
- error = xs_gather(XST_NIL, xenbus_get_otherend_path(xbb->dev),
- @@ -3652,12 +3617,11 @@ xbb_attach(device_t dev)
- error = xs_gather(XST_NIL, xenbus_get_node(dev),
- "mode", NULL, &xbb->dev_mode,
- - "params", NULL, &xbb->dev_name,
- NULL);
- if (error != 0) {
- xbb_attach_failed(xbb, error, "reading backend fields at %s",
- xenbus_get_node(dev));
- - return (ENXIO);
- + return;
- }
- /* Parse fopen style mode flags. */
- @@ -3668,13 +3632,11 @@ xbb_attach(device_t dev)
- * Verify the physical device is present and can support
- * the desired I/O mode.
- */
- - DROP_GIANT();
- error = xbb_open_backend(xbb);
- - PICKUP_GIANT();
- if (error != 0) {
- xbb_attach_failed(xbb, error, "Unable to open %s",
- xbb->dev_name);
- - return (ENXIO);
- + return;
- }
- /* Use devstat(9) for recording statistics. */
- @@ -3706,7 +3668,7 @@ xbb_attach(device_t dev)
- /*contxt*/&xbb->io_taskqueue);
- if (xbb->io_taskqueue == NULL) {
- xbb_attach_failed(xbb, error, "Unable to create taskqueue");
- - return (ENOMEM);
- + return;
- }
- taskqueue_start_threads(&xbb->io_taskqueue,
- @@ -3721,10 +3683,88 @@ xbb_attach(device_t dev)
- if (error) {
- xbb_attach_failed(xbb, error, "writing %s/hotplug-status",
- xenbus_get_node(xbb->dev));
- - return (error);
- + return;
- }
- /* Tell the front end that we are ready to connect. */
- + xenbus_set_state(dev, XenbusStateInitialised);
- +}
- +
- +/**
- + * Attach to a XenBus device that has been claimed by our probe routine.
- + *
- + * \param dev NewBus device object representing this Xen Block Back instance.
- + *
- + * \return 0 for success, errno codes for failure.
- + */
- +static int
- +xbb_attach(device_t dev)
- +{
- + struct xbb_softc *xbb;
- + int error;
- + u_int max_ring_page_order;
- + struct sbuf *watch_path;
- +
- + DPRINTF("Attaching to %s\n", xenbus_get_node(dev));
- +
- + /*
- + * Basic initialization.
- + * After this block it is safe to call xbb_detach()
- + * to clean up any allocated data for this instance.
- + */
- + xbb = device_get_softc(dev);
- + xbb->dev = dev;
- + xbb->otherend_id = xenbus_get_otherend_id(dev);
- + TASK_INIT(&xbb->io_task, /*priority*/0, xbb_run_queue, xbb);
- + mtx_init(&xbb->lock, device_get_nameunit(dev), NULL, MTX_DEF);
- +
- + /*
- + * Publish protocol capabilities for consumption by the
- + * front-end.
- + */
- + error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev),
- + "feature-barrier", "1");
- + if (error) {
- + xbb_attach_failed(xbb, error, "writing %s/feature-barrier",
- + xenbus_get_node(xbb->dev));
- + return (error);
- + }
- +
- + error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev),
- + "feature-flush-cache", "1");
- + if (error) {
- + xbb_attach_failed(xbb, error, "writing %s/feature-flush-cache",
- + xenbus_get_node(xbb->dev));
- + return (error);
- + }
- +
- + max_ring_page_order = flsl(XBB_MAX_RING_PAGES) - 1;
- + error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev),
- + "max-ring-page-order", "%u", max_ring_page_order);
- + if (error) {
- + xbb_attach_failed(xbb, error, "writing %s/max-ring-page-order",
- + xenbus_get_node(xbb->dev));
- + return (error);
- + }
- +
- + /*
- + * We need to wait for hotplug script execution before
- + * moving forward.
- + */
- + watch_path = xs_join(xenbus_get_node(xbb->dev), "path");
- + xbb->hotplug_watch.callback_data = (uintptr_t)dev;
- + xbb->hotplug_watch.callback = xbb_attach_disk;
- + xbb->hotplug_watch.node = strdup(sbuf_data(watch_path), M_XENBLOCKBACK);
- + sbuf_delete(watch_path);
- + error = xs_register_watch(&xbb->hotplug_watch);
- + if (error != 0) {
- + xbb_attach_failed(xbb, error, "failed to create watch on %s",
- + xbb->hotplug_watch.node);
- + free(xbb->hotplug_watch.node, M_XENBLOCKBACK);
- + return (error);
- + }
- +
- + /* Tell the toolstack blkback has attached. */
- xenbus_set_state(dev, XenbusStateInitWait);
- return (0);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement