[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[win-pv-devel] [PATCH] Clear Unplug keys when PDO names change



When upgrading XENBUS the names of PDOs may change because a new
interface version is added.
The co-installer will check for compatibility with child drivers, but
even a compatible child driver will need to re-bind if the name of the PDO
to which is binds has changed. This is a problem for boot-start drivers
because the CDDB was removed in Windows 7, which means the setupapi must
do the re-bind and that means a 0x7B BSOD will ensue if XENVBD's binding
needs to change.
To avoid this problem, if the co-installer detects that PDO names will
change, the Unplug keys are cleared causing a fall-back to emulated devices
on reboot thus allowing the setupapi to run and fix the bindings of other
PV drivers.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 src/coinst/coinst.c | 103 ++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 87 insertions(+), 16 deletions(-)

diff --git a/src/coinst/coinst.c b/src/coinst/coinst.c
index d6700c0..f8ef92e 100644
--- a/src/coinst/coinst.c
+++ b/src/coinst/coinst.c
@@ -49,6 +49,12 @@ __user_code;
 
 #define SERVICES_KEY "SYSTEM\\CurrentControlSet\\Services"
 
+#define SERVICE_KEY(_Driver)    \
+        SERVICES_KEY ## "\\" ## #_Driver
+
+#define UNPLUG_KEY \
+        SERVICE_KEY(XEN) ## "\\Unplug"
+
 #define CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control"
 
 #define CLASS_KEY   \
@@ -981,7 +987,8 @@ static DWORD    DeviceRevision[] = {
 
 static BOOLEAN
 SupportDeviceID(
-    IN  PTCHAR      DeviceID
+    IN  PTCHAR      DeviceID,
+    OUT PBOOLEAN    NewBinding
     )
 {
     unsigned int    Revision;
@@ -1010,6 +1017,11 @@ SupportDeviceID(
     goto fail2;
 
 found:
+    // If we don't match the latest revision then it means the driver
+    // binding will change.
+    if (Index < ARRAYSIZE(DeviceRevision) - 1)
+        *NewBinding = TRUE;
+
     Log("%x", Revision);
 
     return TRUE;
@@ -1116,21 +1128,21 @@ fail1:
 
 static BOOLEAN
 SupportChildDrivers(
-    VOID
+    OUT PBOOLEAN    NewBinding
     )
 {
-    BOOLEAN     Success;
-    HKEY        XenbusKey;
-    HRESULT     Error;
-    DWORD       SubKeys;
-    DWORD       MaxSubKeyLength;
-    DWORD       SubKeyLength;
-    PTCHAR      SubKeyName;
-    HKEY        DeviceKey;
-    PTCHAR      DriverKeyName;
-    HKEY        DriverKey;
-    PTCHAR      MatchingDeviceID;
-    DWORD       Index;
+    BOOLEAN         Success;
+    HKEY            XenbusKey;
+    HRESULT         Error;
+    DWORD           SubKeys;
+    DWORD           MaxSubKeyLength;
+    DWORD           SubKeyLength;
+    PTCHAR          SubKeyName;
+    HKEY            DeviceKey;
+    PTCHAR          DriverKeyName;
+    HKEY            DriverKey;
+    PTCHAR          MatchingDeviceID;
+    DWORD           Index;
 
     Log("====>");
 
@@ -1202,7 +1214,7 @@ SupportChildDrivers(
         if (!Success)
             goto fail8;
 
-        Success = SupportDeviceID(MatchingDeviceID);
+        Success = SupportDeviceID(MatchingDeviceID, NewBinding);
         if (!Success)
             goto fail9;
 
@@ -1402,6 +1414,57 @@ fail1:
     return FALSE;
 }
 
+static BOOLEAN
+ClearUnplugRequest(
+    IN  PTCHAR      ClassName
+    )
+{
+    HKEY            UnplugKey;
+    HRESULT         Error;
+
+    Log("====> (%s)", ClassName);
+
+    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                         UNPLUG_KEY,
+                         0,
+                         KEY_ALL_ACCESS,
+                         &UnplugKey);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail1;
+    }
+
+    Error = RegDeleteValue(UnplugKey, ClassName);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    RegCloseKey(UnplugKey);
+
+    Log("<====");
+
+    return TRUE;
+
+fail2:
+    Log("fail2");
+
+    RegCloseKey(UnplugKey);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
 static HRESULT
 DifInstallPreProcess(
     IN  HDEVINFO                    DeviceInfoSet,
@@ -1412,6 +1475,7 @@ DifInstallPreProcess(
     BOOLEAN                         Success;
     HRESULT                         Error;
     BOOLEAN                         Allow;
+    BOOLEAN                         NewBinding;
 
     UNREFERENCED_PARAMETER(DeviceInfoSet);
     UNREFERENCED_PARAMETER(DeviceInfoData);
@@ -1432,10 +1496,17 @@ DifInstallPreProcess(
     if (!Success)
         goto fail3;
 
-    Success = SupportChildDrivers();
+    NewBinding = FALSE;
+
+    Success = SupportChildDrivers(&NewBinding);
     if (!Success)
         goto fail4;
 
+    if (NewBinding) {
+        (VOID) ClearUnplugRequest("DISKS");
+        (VOID) ClearUnplugRequest("NICS");
+    }
+
     Log("<====");
     
     return NO_ERROR;
-- 
2.1.1


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.