git: 4772e86beb08 - main - xen/blkback: fix reconnection of backend
Roger Pau Monné
royger at FreeBSD.org
Tue May 11 14:15:42 UTC 2021
The branch main has been updated by royger:
URL: https://cgit.FreeBSD.org/src/commit/?id=4772e86beb089ee08a3bff8ad359e83a4c623238
commit 4772e86beb089ee08a3bff8ad359e83a4c623238
Author: Roger Pau Monné <royger at FreeBSD.org>
AuthorDate: 2021-05-11 10:19:29 +0000
Commit: Roger Pau Monné <royger at FreeBSD.org>
CommitDate: 2021-05-11 13:43:42 +0000
xen/blkback: fix reconnection of backend
The hotplug script will be executed only once for each backend,
regardless of the frontend triggering reconnections. Fix blkback to
deal with the hotplug script being executed only once, so that
reconnections don't stall waiting for a hotplug script execution
that will never happen.
As a result of the fix move the initialization of dev_mode, dev_type
and dev_name to the watch callback, as they should be set only once
the first time the backend connects.
This fix is specially relevant for guests wanting to use UEFI OVMF
firmware, because OVMF will use Xen PV block devices and disconnect
afterwards, thus allowing them to be used by the guest OS. Without
this change the guest OS will stall waiting for the block backed to
attach.
Fixes: de0bad00010c ('blkback: add support for hotplug scripts')
MFC after: 1 week
Sponsored by: Citrix Systems R&D
---
sys/dev/xen/blkback/blkback.c | 83 +++++++++++++++++++++++++------------------
1 file changed, 48 insertions(+), 35 deletions(-)
diff --git a/sys/dev/xen/blkback/blkback.c b/sys/dev/xen/blkback/blkback.c
index 678472cc2ab8..010e737740b8 100644
--- a/sys/dev/xen/blkback/blkback.c
+++ b/sys/dev/xen/blkback/blkback.c
@@ -3412,7 +3412,6 @@ xbb_shutdown(struct xbb_softc *xbb)
free(xbb->hotplug_watch.node, M_XENBLOCKBACK);
xbb->hotplug_watch.node = NULL;
}
- xbb->hotplug_done = false;
if (xenbus_get_state(xbb->dev) < XenbusStateClosing)
xenbus_set_state(xbb->dev, XenbusStateClosing);
@@ -3597,39 +3596,14 @@ xbb_setup_sysctl(struct xbb_softc *xbb)
}
static void
-xbb_attach_disk(struct xs_watch *watch, const char **vec, unsigned int len)
+xbb_attach_disk(device_t dev)
{
- device_t dev;
struct xbb_softc *xbb;
int error;
- dev = (device_t) watch->callback_data;
xbb = device_get_softc(dev);
- error = xs_gather(XST_NIL, xenbus_get_node(dev), "physical-device-path",
- NULL, &xbb->dev_name, NULL);
- if (error != 0)
- return;
-
- xs_unregister_watch(watch);
- free(watch->node, M_XENBLOCKBACK);
- watch->node = NULL;
-
- /* Collect physical device information. */
- error = xs_gather(XST_NIL, xenbus_get_otherend_path(xbb->dev),
- "device-type", NULL, &xbb->dev_type,
- NULL);
- if (error != 0)
- xbb->dev_type = NULL;
-
- error = xs_gather(XST_NIL, xenbus_get_node(dev),
- "mode", NULL, &xbb->dev_mode,
- NULL);
- if (error != 0) {
- xbb_attach_failed(xbb, error, "reading backend fields at %s",
- xenbus_get_node(dev));
- return;
- }
+ KASSERT(xbb->hotplug_done, ("Missing hotplug execution"));
/* Parse fopen style mode flags. */
if (strchr(xbb->dev_mode, 'w') == NULL)
@@ -3693,13 +3667,48 @@ xbb_attach_disk(struct xs_watch *watch, const char **vec, unsigned int len)
return;
}
- xbb->hotplug_done = true;
-
/* The front end might be waiting for the backend, attach if so. */
if (xenbus_get_otherend_state(xbb->dev) == XenbusStateInitialised)
xbb_connect(xbb);
}
+static void
+xbb_attach_cb(struct xs_watch *watch, const char **vec, unsigned int len)
+{
+ device_t dev;
+ struct xbb_softc *xbb;
+ int error;
+
+ dev = (device_t)watch->callback_data;
+ xbb = device_get_softc(dev);
+
+ error = xs_gather(XST_NIL, xenbus_get_node(dev), "physical-device-path",
+ NULL, &xbb->dev_name, NULL);
+ if (error != 0)
+ return;
+
+ xs_unregister_watch(watch);
+ free(watch->node, M_XENBLOCKBACK);
+ watch->node = NULL;
+ xbb->hotplug_done = true;
+
+ /* Collect physical device information. */
+ error = xs_gather(XST_NIL, xenbus_get_otherend_path(dev), "device-type",
+ NULL, &xbb->dev_type, NULL);
+ if (error != 0)
+ xbb->dev_type = NULL;
+
+ error = xs_gather(XST_NIL, xenbus_get_node(dev), "mode", NULL,
+ &xbb->dev_mode, NULL);
+ if (error != 0) {
+ xbb_attach_failed(xbb, error, "reading backend fields at %s",
+ xenbus_get_node(dev));
+ return;
+ }
+
+ xbb_attach_disk(dev);
+}
+
/**
* Attach to a XenBus device that has been claimed by our probe routine.
*
@@ -3757,14 +3766,21 @@ xbb_attach(device_t dev)
return (error);
}
+ /* Tell the toolstack blkback has attached. */
+ xenbus_set_state(dev, XenbusStateInitWait);
+
+ if (xbb->hotplug_done) {
+ xbb_attach_disk(dev);
+ return (0);
+ }
+
/*
* We need to wait for hotplug script execution before
* moving forward.
*/
- KASSERT(!xbb->hotplug_done, ("Hotplug scripts already executed"));
watch_path = xs_join(xenbus_get_node(xbb->dev), "physical-device-path");
xbb->hotplug_watch.callback_data = (uintptr_t)dev;
- xbb->hotplug_watch.callback = xbb_attach_disk;
+ xbb->hotplug_watch.callback = xbb_attach_cb;
KASSERT(xbb->hotplug_watch.node == NULL, ("watch node already setup"));
xbb->hotplug_watch.node = strdup(sbuf_data(watch_path), M_XENBLOCKBACK);
/*
@@ -3782,9 +3798,6 @@ xbb_attach(device_t dev)
return (error);
}
- /* Tell the toolstack blkback has attached. */
- xenbus_set_state(dev, XenbusStateInitWait);
-
return (0);
}
More information about the dev-commits-src-main
mailing list