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

Re: [XENBUS PATCH] Add forced unplug support



On 09/07/2025 17:47, Tu Dinh wrote:
> 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.

This is broken in case the xenfilt\Parameters\Active* values are deleted 
(or otherwise not present).

> ---
>   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);



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®.