Author: royger
Date: Tue May 22 08:51:16 2018
New Revision: 334027
URL: https://svnweb.freebsd.org/changeset/base/334027

Log:
  xen-blkback: do not use state 3 (XenbusStateInitialised)
  
  Linux will not connect to a backend that's in state 3
  (XenbusStateInitialised), it needs to be in state 2
  (XenbusStateInitWait) for Linux to attempt to connect to the backend.
  
  The protocol seems to suggest that the backend should indeed wait in
  state 2 for the frontend to connect, which makes state 3 unusable for
  disk backends.
  
  Also make sure blkback will connect to the frontend if the frontend
  reaches state 3 (XenbusStateInitialised) before blkback has processed
  the results from the hotplug script (Submitted by Nathan Friess).
  
  MFC after:    1 week

Modified:
  head/sys/dev/xen/blkback/blkback.c

Modified: head/sys/dev/xen/blkback/blkback.c
==============================================================================
--- head/sys/dev/xen/blkback/blkback.c  Tue May 22 08:27:33 2018        
(r334026)
+++ head/sys/dev/xen/blkback/blkback.c  Tue May 22 08:51:16 2018        
(r334027)
@@ -806,6 +806,9 @@ struct xbb_softc {
 
        /** Watch to wait for hotplug script execution */
        struct xs_watch           hotplug_watch;
+
+       /** Got the needed data from hotplug scripts? */
+       bool                      hotplug_done;
 };
 
 /*---------------------------- Request Processing 
----------------------------*/
@@ -3310,12 +3313,11 @@ xbb_connect(struct xbb_softc *xbb)
 {
        int error;
 
-       if (xenbus_get_state(xbb->dev) != XenbusStateInitialised)
+       if (!xbb->hotplug_done ||
+           (xenbus_get_state(xbb->dev) != XenbusStateInitWait) ||
+           (xbb_collect_frontend_info(xbb) != 0))
                return;
 
-       if (xbb_collect_frontend_info(xbb) != 0)
-               return;
-
        xbb->flags &= ~XBBF_SHUTDOWN;
 
        /*
@@ -3412,6 +3414,7 @@ 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);
@@ -3692,8 +3695,11 @@ xbb_attach_disk(struct xs_watch *watch, const char **v
                return;
        }
 
-       /* Tell the front end that we are ready to connect. */
-       xenbus_set_state(dev, XenbusStateInitialised);
+       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);
 }
 
 /**
@@ -3757,6 +3763,7 @@ xbb_attach(device_t dev)
         * 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;
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to