]> xenbits.xensource.com Git - pvdrivers/win/xenvif.git/commitdiff
Cope with unexpected initial backend states
authorPaul Durrant <paul.durrant@citrix.com>
Mon, 22 Sep 2014 11:02:44 +0000 (12:02 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Mon, 22 Sep 2014 11:02:44 +0000 (12:02 +0100)
If the OS is booted via iSCSI, then the backend will already be in the
Connected state when the xenvif driver loads.  The backend is stable
in this state, so __FrontendPrepare() eventually times out waiting for
the backend state to change.

Fix by leading the backend through the Closing and Closed states if we
find it initially in the Connected (or Closing) states.

Signed-off-by: Michael Brown <mbrown@fensystems.co.uk>
Forward ported.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
src/xenvif/frontend.c

index d5197c54143c20668566297ae9d76ce70c7d2b49..305faaf2c22217e6c634a0f83d47fdbdf533db85 100644 (file)
@@ -1029,14 +1029,45 @@ __FrontendPrepare(
     if (!NT_SUCCESS(status))
         goto fail3;
 
+    while (State == XenbusStateConnected) {
+        (VOID) XENBUS_STORE(Printf,
+                            &Frontend->StoreInterface,
+                            NULL,
+                            __FrontendGetPath(Frontend),
+                            "state",
+                            "%u",
+                            XenbusStateClosing);
+        status = __FrontendWaitForStateChange(Frontend, Path, &State);
+        if (!NT_SUCCESS(status))
+            goto fail4;
+    }
+
+    while (State == XenbusStateClosing) {
+        (VOID) XENBUS_STORE(Printf,
+                            &Frontend->StoreInterface,
+                            NULL,
+                            __FrontendGetPath(Frontend),
+                            "state",
+                            "%u",
+                            XenbusStateClosed);
+        status = __FrontendWaitForStateChange(Frontend, Path, &State);
+        if (!NT_SUCCESS(status))
+            goto fail5;
+    }
+
     while (State != XenbusStateClosed &&
            State != XenbusStateInitialising &&
-           State != XenbusStateInitWait) {
+           State != XenbusStateInitWait &&
+           State != XenbusStateUnknown) {
         status = __FrontendWaitForStateChange(Frontend, Path, &State);
         if (!NT_SUCCESS(status))
-            goto fail4;
+            goto fail6;
     }
 
+    status = STATUS_UNSUCCESSFUL;
+    if (State == XenbusStateUnknown)
+        goto fail7;
+
     status = XENBUS_STORE(Printf,
                           &Frontend->StoreInterface,
                           NULL,
@@ -1045,18 +1076,18 @@ __FrontendPrepare(
                           "%u",
                           XenbusStateInitialising);
     if (!NT_SUCCESS(status))
-        goto fail5;
+        goto fail8;
 
     while (State == XenbusStateClosed ||
            State == XenbusStateInitialising) {
         status = __FrontendWaitForStateChange(Frontend, Path, &State);
         if (!NT_SUCCESS(status))
-            goto fail6;
+            goto fail9;
     }
 
     status = STATUS_UNSUCCESSFUL;
     if (State != XenbusStateInitWait)
-        goto fail7;
+        goto fail10;
 
     Frontend->BackendPath = Path;
 
@@ -1083,17 +1114,26 @@ __FrontendPrepare(
                           ThreadGetEvent(Frontend->EjectThread),
                           &Frontend->Watch);
     if (!NT_SUCCESS(status))
-        goto fail8;
+        goto fail11;
 
     Trace("<====\n");
     return STATUS_SUCCESS;
 
-fail8:
-    Error("fail8\n");
+fail11:
+    Error("fail11\n");
 
     Frontend->BackendDomain = DOMID_INVALID;
     Frontend->BackendPath = NULL;
 
+fail10:
+    Error("fail10\n");
+
+fail9:
+    Error("fail9\n");
+
+fail8:
+    Error("fail8\n");
+
 fail7:
     Error("fail7\n");