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

[XENBUS PATCH v2 1/7] 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>
---
 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®.