From 4be6e288850bd7277b1f5a7cc3691390f48a0ab4 Mon Sep 17 00:00:00 2001 From: Jorgen Lundman Date: Sat, 22 Jun 2024 19:19:24 +0900 Subject: [PATCH] Skip zvol init if we detech Aomei driver Temporary solution unti we can figure out why we crash if both are loaded. Signed-off-by: Jorgen Lundman --- module/os/windows/driver.c | 22 ++--- module/os/windows/zfs/zfs_windows_zvol.c | 101 ++++++++++++++++++++--- 2 files changed, 99 insertions(+), 24 deletions(-) diff --git a/module/os/windows/driver.c b/module/os/windows/driver.c index f1df2426e05c..d153eb553ab3 100644 --- a/module/os/windows/driver.c +++ b/module/os/windows/driver.c @@ -38,6 +38,9 @@ #include "Trace.h" DRIVER_INITIALIZE DriverEntry; +DRIVER_UNLOAD OpenZFS_Fini; +#pragma alloc_text(INIT, DriverEntry) +#pragma alloc_text(PAGE, OpenZFS_Fini) extern int initDbgCircularBuffer(void); extern int finiDbgCircularBuffer(void); @@ -65,12 +68,10 @@ PDRIVER_DISPATCH STOR_MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; wzvolDriverInfo STOR_wzvolDriverInfo; -DRIVER_UNLOAD OpenZFS_Fini; - -extern _Function_class_(WORKER_THREAD_ROUTINE) +extern _Function_class_(IO_WORKITEM_ROUTINE) void __stdcall -sysctl_os_registry_change(PVOID Parameter); - +sysctl_os_registry_change(DEVICE_OBJECT *DeviceObject, + PVOID Parameter); void OpenZFS_Fini(PDRIVER_OBJECT DriverObject) @@ -84,12 +85,12 @@ OpenZFS_Fini(PDRIVER_OBJECT DriverObject) STOR_DriverUnload = NULL; } + sysctl_os_fini(); + zfs_kmod_fini(); system_taskq_fini(); - sysctl_os_fini(); - spl_stop(); #ifdef DBG if (KD_DEBUGGER_ENABLED && !KD_DEBUGGER_NOT_PRESENT) { @@ -99,11 +100,6 @@ OpenZFS_Fini(PDRIVER_OBJECT DriverObject) #endif finiDbgCircularBuffer(); - if (STOR_wzvolDriverInfo.zvContextArray) { - ExFreePoolWithTag(STOR_wzvolDriverInfo.zvContextArray, - MP_TAG_GENERAL); - STOR_wzvolDriverInfo.zvContextArray = NULL; - } ZFSWppCleanup(DriverObject); KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, @@ -172,7 +168,7 @@ DriverEntry(_In_ PDRIVER_OBJECT DriverObject, zfs_vfsops_init(); /* Start monitoring Registry for changes */ - sysctl_os_registry_change(pRegistryPath); + sysctl_os_registry_change(DriverObject->DeviceObject, pRegistryPath); KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "OpenZFS: Started\n")); diff --git a/module/os/windows/zfs/zfs_windows_zvol.c b/module/os/windows/zfs/zfs_windows_zvol.c index 055d35ebc16c..30e6b88651e4 100644 --- a/module/os/windows/zfs/zfs_windows_zvol.c +++ b/module/os/windows/zfs/zfs_windows_zvol.c @@ -34,18 +34,90 @@ extern PDRIVER_OBJECT WIN_DriverObject; static pHW_HBA_EXT STOR_HBAExt = NULL; -static uint64_t windows_zvol_enabled = 0; +static uint64_t windows_zvol_enabled = 1; ZFS_MODULE_PARAM(, windows_, zvol_enabled, U64, ZMOD_RW, "Windows: enable zvol"); -// Verbose +NTSYSCALLAPI NTSTATUS NTAPI ZwQuerySystemInformation( + ULONG SystemInformationClass, + PVOID SystemInformation, + ULONG SystemInformationLength, + PULONG ReturnLength +); + +typedef struct _SYSTEM_MODULE { + ULONG Reserved[2]; +#ifdef _WIN64 + ULONG Unknown3; + ULONG Unknown4; +#endif + PVOID Base; + ULONG Size; + ULONG Flags; + USHORT Index; + USHORT Unknown; + USHORT LoadCount; + USHORT ModuleNameOffset; + CHAR ImageName[256]; +} SYSTEM_MODULE, *PSYSTEM_MODULE; + +typedef struct _SYSTEM_MODULE_INFORMATION { + ULONG ModulesCount; + SYSTEM_MODULE Modules[1]; +} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; + +#define SystemModuleInformation 11 + +VOID ListLoadedDrivers() +{ + ULONG bufferLength = 0; + boolean_t skipLoad = FALSE; + + ZwQuerySystemInformation(SystemModuleInformation, NULL, 0, &bufferLength); + + PVOID buffer = ExAllocatePoolWithTag(NonPagedPoolNx, bufferLength, 'sysm'); + + if (buffer == NULL) + return; + + if (NT_SUCCESS(ZwQuerySystemInformation(SystemModuleInformation, buffer, bufferLength, &bufferLength))) { + PSYSTEM_MODULE_INFORMATION moduleInformation = (PSYSTEM_MODULE_INFORMATION)buffer; + for (ULONG i = 0; i < moduleInformation->ModulesCount; ++i) { + dprintf("Driver: %s\n", moduleInformation->Modules[i].ImageName); + + if (strncmp("\\SystemRoot\\system32\\ambakdrv.sys", + moduleInformation->Modules[i].ImageName, + sizeof (moduleInformation->Modules[i].ImageName)) == 0) + skipLoad = TRUE; + } + } + + ExFreePoolWithTag(buffer, 'sysm'); + + if (!skipLoad) + return; + + if (windows_zvol_enabled == 1) { + dprintf("Aomei Backupper (ambakdrv.sys) detected as installed.\n"); + dprintf("It is known to crash with OpenZFS's zvol. Set Registry entry\n"); + dprintf("windows_zvol_enabled to 2 to force load OpenZFS with zvol support.\n"); + xprintf("Skipping ZVOL due to ambakdrv.sys\n"); + windows_zvol_enabled = 0; + } else if (windows_zvol_enabled == 2) { + dprintf("Force loading OpenZFS with zvol support, and Aomei ambakdrv.sys installed.\n"); + xprintf("Forcing ZVOL despite ambakdrv.sys\n"); + } + +} int -zvol_start(PDRIVER_OBJECT DriverObject, PUNICODE_STRING pRegistryPath) +zvol_start(PDRIVER_OBJECT DriverObject, PUNICODE_STRING pRegistryPath) { + VIRTUAL_HW_INITIALIZATION_DATA hwInitData; pwzvolDriverInfo pwzvolDrvInfo; NTSTATUS status; - VIRTUAL_HW_INITIALIZATION_DATA hwInitData; + + ListLoadedDrivers(); if (windows_zvol_enabled == 0) return (STATUS_FS_DRIVER_REQUIRED); @@ -652,7 +724,9 @@ wzvol_HandleQueryCapabilities( UNREFERENCED_PARAMETER(pHBAExt); - dprintf("%s: entry\n", __func__); + dprintf("%s: entry: sizeof %d DataTransferLength %d\n", + __func__, sizeof (*pStorageCapabilities), + pSrb->DataTransferLength); RtlZeroMemory(pStorageCapabilities, pSrb->DataTransferLength); @@ -1028,6 +1102,17 @@ wzvol_HwFreeAdapterResources(__in pHW_HBA_EXT pHBAExt) #endif + VERIFY0(pHBAExt->pwzvolDrvObj->DrvInfoNbrMPHBAObj); + + dprintf("Freeing zcContextArray %p\n", + STOR_wzvolDriverInfo.zvContextArray); + + if (STOR_wzvolDriverInfo.zvContextArray) { + ExFreePoolWithTag(STOR_wzvolDriverInfo.zvContextArray, + MP_TAG_GENERAL); + STOR_wzvolDriverInfo.zvContextArray = NULL; + } + if (STOR_HBAExt == pHBAExt) STOR_HBAExt = NULL; } @@ -1088,23 +1173,17 @@ wzvol_ProcServReq( __in pHW_HBA_EXT pHBAExt, __in PIRP pIrp) { - -#if 1 dprintf("MpProcServReq entered\n"); wzvol_QueueServiceIrp(pHBAExt, pIrp); -#endif } void wzvol_CompServReq(__in pHW_HBA_EXT pHBAExt) { - -#if 1 dprintf("MpHwCompServReq entered\n"); wzvol_QueueServiceIrp(pHBAExt, NULL); -#endif } void