vSphere에서 운영 중인 Windows Virtual Machine에 Web Console로 접속할 때, Black Screen이 발생하는 경우 어떻게 접근해 볼 수 있는지에 대해서 다뤄보겠습니다.
Black Screen 이슈가 발생하면 우선 몇 가지 질문을 통해 Scoping을 해야 합니다.
예를 들어,
1. 서버에 RDP(Remote Desktop Protocol)을 통해 접속은 가능한지?
2. 서버에서 실행 중인 서비스들은 외부에서 접근이 가능한지?
3. 서버로 SMB(Server Messaging Block)를 통해 공유 폴더 접근은 가능한지?
4. 다른 서버에서 Event Viewer와 같은 RPC(Remote Procedure Call)을 통해 해당 서버에 접근은 가능한지?
5. Physical Machine인 경우 Console Monitor, Virtual Machine인 경우 Web Console(vSphere의 경우)로 접근했을 때에도 Black Screen인지?
이 번 케이스의 경우, 서비스는 정상이었으나 Web Console과 RDP 접근 시 모두 Black Screen에 빠지는 현상을 보였습니다. 이런 경우 우선 Windows OS 측면에서 Kernel 동작 상 문제는 없고, User-Mode에서 Logon UI를 보여주는 절차 중에 문제가 생겼다고 판단할 수 있습니다.
Windows OS가 Logon 하는 과정에는 아래 프로세스들이 각자의 역할을 담당하게 됩니다.
winlogon은 로그온 프로세스 전체를 담당하고, lsass는 인증 관련된 처리를 그리고 logonui는 로그온 UI Box와 관련된 처리를 담당합니다.
이 과정이 정상적으로 진행되는지를 분석하기 위해서 문제가 발생하고 있는 VM을 vmss2core 파일을 이용하여 Windows Memory Dump로 변환을 합니다.
How to collect guest os memory dump using vmss2core (tistory.com)
1. 먼저, 변환된 Dump를 Windbg로 열어서 사용자가 접속을 시도하는 Session 1의 프로세스 목록을 확인합니다.
프로세스 목록을 확인해보면, 필요한 logonui.exe가 보이지 않습니다.
## lsass.exe 프로세스는 Session 0에 위치합니다.
PROCESS ffffe000e3e218c0 SessionId: 1 Cid: 01b0 Peb: 7ff63c4a8000 ParentCid: 01a0 DirBase: 10ae03000 ObjectTable: ffffc001b7addd40 HandleCount: <Data Not Accessible> Image: csrss.exe PROCESS ffffe000e37b88c0 SessionId: 1 Cid: 01dc Peb: 7ff798da6000 ParentCid: 01a0 DirBase: 10b249000 ObjectTable: ffffc001bf82e040 HandleCount: <Data Not Accessible> Image: winlogon.exe PROCESS ffffe000e41008c0 SessionId: 1 Cid: 02d8 Peb: 7ff73e1bf000 ParentCid: 01dc DirBase: 10c6a5000 ObjectTable: ffffc001b7d7ad40 HandleCount: <Data Not Accessible> Image: dwm.exe PROCESS ffffe000e419c080 SessionId: 1 Cid: 07fc Peb: 7ff7880a4000 ParentCid: 083c DirBase: 1f6d00000 ObjectTable: ffffc001c57b0e80 HandleCount: <Data Not Accessible> Image: vm3dservice.exe |
2. 그렇다면, 이 시점에서 왜 logonui.exe 프로세스가 생성되어 있지 않은가를 궁금해 해야 합니다.
기본적으로 Windows OS에서는 프로세스의 생성을 csrss.exe 가 담당합니다. 덤프만 가지고는 왜 csrss.exe 프로세스가 logonui.exe 프로세스를 생성하지 못했는지 알기 어렵기 때문에, 우선 의심해 볼 수 있는 것들은 OS에 설치된 3rd party driver 들입니다.
이 3rd party driver들을 OS가 부팅될 때 시작되지 못하도록 한 후에도 문제가 동일하게 재현되는지 확인할 필요가 있습니다.
3. OS에 Logon을 못하는 환경이기 때문에 이러한 경우에는 Recovery Mode를 이용하여 OS가 Booting되기 전에 3rd party driver 관련된 registry 값들을 수정해야합니다.
Windows OS가 Virtual Machine 환경이기 때문에 VM이 시작되기 전에 OS ISO를 mount 해놓고 VM이 시작될 때, 설치 시점으로 시작되도록 하여 Recovery Mode로 접근할 수 있습니다.
4. Recovery Mode로 접근하여, Registry Editor를 실행한 후 Windows OS가 가지고 있는 Registry Hive 중 SYSTEM Registry Hive를 Load 합니다.
## 이 과정은 본 주제에서 다소 벗어나기 때문에 자세히 다루지는 않겠습니다.
## 궁금하신 분들은 Registry HIVE의 위치와 Registry Editor를 통해 Load 하는 방법을 찾아보시면 다양한 예제들을 확인하실 수 있습니다.
5. SYSTEM Registry Hive를 Load한 후, HKEY_LOCAL_MACHINE\ControlSet###\Services Key 하위를 살펴보면 다양한 Service 및 Driver 관련된 Registry Key를 확인할 수 있습니다. 다음과 같은 화면을 보실 수 있을 겁니다.
아래 예제는 HKEY_LOCAL_MACHINE\ControlSet###\Services\vm3dmp Key를 선택하였고, 선택 시 우측에 관련된 Registry Value들이 확인됩니다.
6. 5번 단계에서 확인한 Value들 중 OS가 시작될 때 Driver가 Load되지 못하도록 해야하기 때문에, 여러 Value들 중에 Start 값을 수정해야 합니다. Start 값의 정의는 다음과 같이 되어 있습니다.
따라서, 확인 가능한 모든 3rd party driver의 Key를 확인하여, Start 값을 "Disabled"를 의미하는 0x4로 수정합니다.
Value | Identifier | Description |
0x00000000 | Boot | Driver or service controlled by the kernel that is loaded by the boot loader. |
0x00000001 | System | Driver or service controlled by the I/O sub system that is loaded at kernel initialization. |
0x00000002 | Automatic | Driver or service controlled by the Services Control Manager that is loaded at start up. Also referred to as: Auto load |
0x00000003 | On demand | Driver or service controlled by the Services Control Manager that is loaded on demand. Also referred to as: Load on demand or Automatic (Delayed start) |
0x00000004 | Disabled | Driver or service controlled by the Services Control Manager that is disabled. |
7. 값들을 모두 수정한 후 Load 했던 SYSTEM Hive를 Unload하고 OS를 재부팅 하여 문제가 동일한지 확인합니다.
이 케이스의 경우는 3rd party driver를 모두 시작되지 못하도록 했음에도 Black Screen이 계속 발생하였기 때문에 3rd party driver가 load되지 않은 상태에서 다시 한 번 vmss2core를 이용하여, windows memory dump를 수집하였습니다.
8. 덤프를 다시 분석해보면, csrss.exe 프로세스가 DcomLanuch 프로세스의 특정 쓰레드로부터 lpc message를 기다리고 있는 것을 확인할 수 있습니다.
0: kd> !mex.p ffffe00120f665c0 Name Address Ses PID Parent PEB Create Time Mods Handle Thrd User Name ========= ======================== === =========== =========== ================ ========================== ==== ====== ==== ========== csrss.exe ffffe00120f665c0 (E|K|O) 1 170 (0n368) 168 (0n360) 00007ff7ae943000 10/11/2022 12:51:13.190 PM 14 0 10 \MINWINPC$ Command Line: %SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,20480,768 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=sxssrv,4 ProfileControl=Off MaxRequestThreads=16 Memory Details: VM Peak Work Set Commit Size PP Quota NPP Quota ======= ======= ======== =========== ========= ========= 67.3 MB 67.3 MB 7.08 MB 1.33 MB 154.24 KB 10.62 KB Show LPC Port information for process Show Threads: Unique Stacks !mex.listthreads (!lt) ffffe00120f665c0 !process ffffe00120f665c0 7 0: kd> !mex.lt ffffe00120f665c0 Process PID Thread Id State Time Reason Waiting On ========= === ================ === ======= ========== ============= ============================================================ csrss.exe 170 ffffe00120f55880 190 Waiting 18m:25.531 Executive csrss.exe 170 ffffe00120f38080 194 Waiting 27m:31.687 WrLpcReply Thread: ffffe001242c5400 in svchost.exe (DcomLaunch) (0n548) csrss.exe 170 ffffe00120f37080 198 Waiting 14m:25.453 UserRequest csrss.exe 170 ffffe00120f54880 19c Waiting 18m:23.671 WrLpcReceive csrss.exe 170 ffffe00120f36080 1a0 Waiting 27m:32.515 WrLpcReceive csrss.exe 170 ffffe00120f64080 1ac Waiting 18m:23.671 WrLpcReceive csrss.exe 170 ffffe00120f1b080 1b8 Waiting 187ms WrUserRequest csrss.exe 170 ffffe00120f09080 1c4 Waiting 18m:46.843 WrUserRequest csrss.exe 170 ffffe001242c3080 274 Waiting 27m:31.687 WrLpcReceive csrss.exe 170 ffffe0012435b7c0 314 Waiting 18m:23.671 WrLpcReceive Thread Count: 10 |
9. 그렇다면, csrss.exe 프로세스가 기다리고 있는 쓰레드가 어떤 동작을 하고 있길래 lpc message를 기다리는지를 확인하기 위해 해당 쓰레드의 Call Stack을 확인합니다.
문제는 여기서 발생하는데요. 안타깝게도 해당 쓰레드의 Termination flag가 True로 설정되어 있는 것을 알 수 있습니다.
0: kd> !mex.lt ffffe001242b1080 Process PID Thread Id State Time Reason ======================== === ================ === ======= ========== =========== svchost.exe (DcomLaunch) 224 ffffe001242b1880 228 Waiting 27m:31.609 UserRequest svchost.exe (DcomLaunch) 224 ffffe001242a5880 240 Waiting 27m:31.781 WrQueue svchost.exe (DcomLaunch) 224 ffffe001242d2080 260 Waiting 7m:31.484 UserRequest svchost.exe (DcomLaunch) 224 ffffe001242fd080 280 Waiting 27m:27.171 UserRequest svchost.exe (DcomLaunch) 224 ffffe001242e5080 2a8 Waiting 27m:31.609 WrQueue svchost.exe (DcomLaunch) 224 ffffe001242e4080 13c Waiting 9m:39.781 WrQueue Thread Count: 6 0: kd> !mex.t ffffe001242c5400 Could not switch to thread. Error d0000147 Process Thread CID UserTime KernelTime ContextSwitches Wait Reason Time State svchost.exe (DcomLaunch) (ffffe001242b1080) ffffe001242c5400 (E|K|W|R|V) 224.270 0 16ms 43 WrTerminated 27m:01.546 Terminated Kernel stack not resident |
10. 3rd party driver가 실제로 load 되지 않았는지 다시 한 번 확인해봤지만 실제로 load 되지 않은 것으로 확인됩니다.
0: kd> lmvm ATampNt Browse full module list start end module name 0: kd> lmvm TSFLTDRV Browse full module list start end module name 0: kd> lmvm Cdm2DrNt Browse full module list start end module name 0: kd> lmvm AhnRghNt Browse full module list start end module name 0: kd> lmvm MeDCoreD Browse full module list start end module name 0: kd> lmvm ascrts Browse full module list start end module name 0: kd> lmvm vmci Browse full module list start end module name 0: kd> lmvm vmmouse Browse full module list start end module name 0: kd> lmvm vsock Browse full module list start end module name 0: kd> lmvm vmxnet3 Browse full module list start end module name |
이러한 경우에는, 결국 Microsoft 측에 왜 lpc message에 대한 reply를 줘야하는 DcomLaunch 쓰레드가 Terminated 상태로 남아있는지를 확인해야 합니다.
안타깝게도 Microsoft 에서도 해결책이 제시되지 않아 VM의 Data 영역 Disk에 해당하는 VMDK만을 이용하여 다시 구축을 했어야만 했던 케이스였습니다.
정리하자면, Black Screen 현상을 겪었을 때 일차적으로 올바른 Scoping 질문을 통해 User-mode와 Kernel-mode의 문제 위치를 구분하고, Usermode인 경우 Logon과 관련된 프로세스들이 정상적으로 동작하는지를 살펴야 합니다.
## Kernel-mode가 문제 있는 경우 서비스도 정상적으로 할 수 없는 Hang 상태인 경우가 대부분입니다.
## 이러한 경우에는 Memory Dump를 수집하여 왜 System Hang이 발생했는지를 분석해야 합니다.
[참고 자료]
Deep dive: Logging on to Windows
https://techcommunity.microsoft.com/t5/itops-talk-blog/deep-dive-logging-on-to-windows/ba-p/2420705
'Windows' 카테고리의 다른 글
How to Install Windows Server Failover Clustering(WSFC) (0) | 2023.10.19 |
---|---|
Configure Active Directory Federation Server (0) | 2023.04.02 |
Request a Certificate for ADFS Server (0) | 2023.04.02 |
Installing Active Directory Certificate Service (0) | 2023.04.02 |
How to set up WSLv2 (0) | 2022.09.18 |