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

[XENBUS PATCH] Add forced unplug support



Forced unplug aims to simplify driver servicing by, as its name implies,
forcefully unplugging emulated devices when a driver is present, rather
than when it's active.

Create a Registry key at CurrentControlSet\XEN\ForceUnplug. Drivers can
opt into forced unplug by creating an appropriate value (DISKS/NICS)
in this key.

Older drivers are not affected.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
---
Opting into forced unplug is totally optional. But it has the advantage
of not needing multiple reboots, and avoids situations where both the
emulated and PV drivers are running at the same time.
---
 src/xen/driver.c | 79 ++++++++++++++++++++++++++++++++++++++----------
 src/xen/driver.h |  5 +++
 src/xen/unplug.c | 13 ++++++--
 3 files changed, 79 insertions(+), 18 deletions(-)

diff --git a/src/xen/driver.c b/src/xen/driver.c
index b44753c..7b2621b 100644
--- a/src/xen/driver.c
+++ b/src/xen/driver.c
@@ -63,6 +63,7 @@ typedef struct _XEN_DRIVER {
     PLOG_DISPOSITION    QemuDisposition;
     HANDLE              ParametersKey;
     HANDLE              UnplugKey;
+    HANDLE              ForceUnplugKey;
     HANDLE              MemoryKey;
 } XEN_DRIVER, *PXEN_DRIVER;
 
@@ -144,6 +145,30 @@ DriverGetUnplugKey(
     return __DriverGetUnplugKey();
 }
 
+static FORCEINLINE VOID
+__DriverSetForceUnplugKey(
+    _In_opt_ HANDLE Key
+    )
+{
+    Driver.ForceUnplugKey = Key;
+}
+
+static FORCEINLINE HANDLE
+__DriverGetForceUnplugKey(
+    VOID
+    )
+{
+    return Driver.ForceUnplugKey;
+}
+
+HANDLE
+DriverGetForceUnplugKey(
+    VOID
+    )
+{
+    return __DriverGetForceUnplugKey();
+}
+
 static FORCEINLINE VOID
 __DriverSetMemoryKey(
     _In_opt_ HANDLE Key
@@ -500,6 +525,7 @@ DllInitialize(
     HANDLE                  ServiceKey;
     HANDLE                  ParametersKey;
     HANDLE                  UnplugKey;
+    HANDLE                  ForceUnplugKey;
     HANDLE                  MemoryKey;
     LOG_LEVEL               LogLevel;
     NTSTATUS                status;
@@ -577,12 +603,21 @@ DllInitialize(
 
     __DriverSetUnplugKey(UnplugKey);
 
+    status = RegistryCreateSubKey(ServiceKey,
+                                  "ForceUnplug",
+                                  REG_OPTION_NON_VOLATILE,
+                                  &ForceUnplugKey);
+    if (!NT_SUCCESS(status))
+        goto fail6;
+
+    __DriverSetForceUnplugKey(ForceUnplugKey);
+
     status = RegistryCreateSubKey(ServiceKey,
                                   "Memory",
                                   REG_OPTION_VOLATILE,
                                   &MemoryKey);
     if (!NT_SUCCESS(status))
-        goto fail6;
+        goto fail7;
 
     __DriverSetMemoryKey(MemoryKey);
 
@@ -590,27 +625,27 @@ DllInitialize(
 
     status = AcpiInitialize();
     if (!NT_SUCCESS(status))
-        goto fail7;
+        goto fail8;
 
     status = SystemInitialize();
     if (!NT_SUCCESS(status))
-        goto fail8;
+        goto fail9;
 
     status = BugCheckInitialize();
     if (!NT_SUCCESS(status))
-        goto fail9;
+        goto fail10;
 
     status = ModuleInitialize();
     if (!NT_SUCCESS(status))
-        goto fail10;
+        goto fail11;
 
     status = ProcessInitialize();
     if (!NT_SUCCESS(status))
-        goto fail11;
+        goto fail12;
 
     status = UnplugInitialize();
     if (!NT_SUCCESS(status))
-        goto fail12;
+        goto fail13;
 
     RegistryCloseKey(ServiceKey);
 
@@ -618,39 +653,45 @@ DllInitialize(
 
     return STATUS_SUCCESS;
 
+fail13:
+    Error("fail13\n");
+
+    ProcessTeardown();
+
 fail12:
     Error("fail12\n");
 
-    ProcessTeardown();
+    ModuleTeardown();
 
 fail11:
     Error("fail11\n");
 
-    ModuleTeardown();
+    BugCheckTeardown();
 
 fail10:
     Error("fail10\n");
 
-    BugCheckTeardown();
+    SystemTeardown();
 
 fail9:
     Error("fail9\n");
 
-    SystemTeardown();
+    AcpiTeardown();
 
 fail8:
     Error("fail8\n");
 
-    AcpiTeardown();
-
-fail7:
-    Error("fail7\n");
-
     HypercallTeardown();
 
     RegistryCloseKey(MemoryKey);
     __DriverSetMemoryKey(NULL);
 
+fail7:
+    Error("fail7\n");
+
+    RegistryCloseKey(ForceUnplugKey);
+    __DriverSetForceUnplugKey(NULL);
+
 fail6:
     Error("fail6\n");
 
@@ -698,6 +739,7 @@ DllUnload(
     )
 {
     HANDLE  MemoryKey;
+    HANDLE  ForceUnplugKey;
     HANDLE  UnplugKey;
     HANDLE  ParametersKey;
 
@@ -722,6 +764,11 @@ DllUnload(
     RegistryCloseKey(MemoryKey);
     __DriverSetMemoryKey(NULL);
 
+    ForceUnplugKey = __DriverGetForceUnplugKey();
+
+    RegistryCloseKey(ForceUnplugKey);
+    __DriverSetForceUnplugKey(NULL);
+
     UnplugKey = __DriverGetUnplugKey();
 
     RegistryCloseKey(UnplugKey);
diff --git a/src/xen/driver.h b/src/xen/driver.h
index 21df779..6851e01 100644
--- a/src/xen/driver.h
+++ b/src/xen/driver.h
@@ -43,6 +43,11 @@ DriverGetUnplugKey(
     VOID
     );
 
+extern HANDLE
+DriverGetForceUnplugKey(
+    VOID
+    );
+
 extern PMDL
 DriverGetNamedPages(
     _In_ PSTR   Name,
diff --git a/src/xen/unplug.c b/src/xen/unplug.c
index dbd9a2e..282ed93 100644
--- a/src/xen/unplug.c
+++ b/src/xen/unplug.c
@@ -266,6 +266,7 @@ UnplugSetRequest(
 {
     PUNPLUG_CONTEXT     Context = &UnplugContext;
     HANDLE              UnplugKey;
+    HANDLE              ForceUnplugKey;
     PSTR                ValueName;
     PSTR                EnumName;
     ULONG               Value;
@@ -277,6 +278,7 @@ UnplugSetRequest(
     ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
 
     UnplugKey = DriverGetUnplugKey();
+    ForceUnplugKey = DriverGetForceUnplugKey();
 
     switch (Type) {
     case UNPLUG_DISKS:
@@ -293,17 +295,24 @@ UnplugSetRequest(
         ASSERT(FALSE);
     }
 
+    status = RegistryQueryDwordValue(ForceUnplugKey,
+                                     ValueName,
+                                     &Value);
+    if (NT_SUCCESS(status) && Value)
+        goto unplug;
+
     status = RegistryQueryDwordValue(UnplugKey,
                                      ValueName,
                                      &Value);
     if (!NT_SUCCESS(status))
         goto done;
 
-    (VOID) RegistryDeleteValue(UnplugKey, ValueName);
-
     if (Value != 0)
         (VOID) UnplugCheckEnumKey(EnumName, &Value);
 
+unplug:
+    (VOID) RegistryDeleteValue(UnplugKey, ValueName);
+
     Info("%s (%u)\n", ValueName, Value);
 
     AcquireHighLock(&Context->Lock, &Irql);
-- 
2.50.1.windows.1



Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech




 


Rackspace

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