virtio-win / virtio-win-guest-tools-installer

113 stars 19 forks source link

ocasionally fail to uninstall virtio-win-guest-tools on Win10 #52

Closed ChendongSun closed 9 months ago

ChendongSun commented 10 months ago

When I use the command "virtio-win-guest-tools.exe /uninstall /passive /norestart" to uninstall virtio-win-guest-tools.exe on windows10, there is a small chance that it will get stuck. How to use the command line in a script to automatically uninstall an exe without error

YanVugenfirer commented 10 months ago

@ChendongSun Can you please check the status of all virtio devices in the device manager then this happens?

ChendongSun commented 10 months ago

There are 6 virtio drivers "virtio-serial,pvpanic,bollon,netKvm,virtio-vioster,virio-scsi" installed by default on my system. Now it seems that the status of all the drivers is normal. After I tried to uninstall these drivers one by one, qga still cannot be uninstalled. Among them, the serial port driver prompts that the system needs to be restarted, but the problem cannot be reproduced after restarting qemu-ga or restarting win10.

ChendongSun commented 10 months ago

In addition, when an error occurred, I found that there was an error in the event viewer: Product: Qemu guest agent --Error 1921.Service 'QEMU Guest Agent'(QEMU-GA) could not be stopped. Verify that you have sufficient privileges to stop system services . but is already a root user

kostyanf14 commented 10 months ago

Hi @ChendongSun,

I tried to reproduce this several times but no luck. Please reproduce the issue with the following command line virtio-win-guest-tools.exe /uninstall /passive /norestart /log log.txt and share all generated logs. There will be multiple files log_<number>_*.txt please attach all of them.

wanglmb commented 10 months ago

hello @kostyanf14

I can reproduce this case by following test script: the virtio-win-guest-tools.exe is from : https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.229-1/virtio-win-guest-tools.exe the test was performed on windows profesional 21H2, and the test script hung at the 17th iteration, another test hung at 82th iteration.

d:\vmtools\test.bat:

@echo off set loop=1000 for /l %%i in (1,1,%loop%) do ( echo %%i d:\vmtools\upgrade.bat )

d:\vmtools\upgrade.bat:

REM @echo off set filename=virtio-win-guest-tools.exe set dir=C:\ProgramData\Package Cache pushd "%dir%"

for /f "delims=" %%i in ('dir /b /s %filename% 2^>null') do ( if exist %%i ( cd /d "%%~dpi" d:\vmtools\virtio-win-guest-tools.exe /uninstall /passive /norestart /log log.txt ) ) popd d:\vmtools\virtio-win-guest-tools.exe /install /passive /norestart timeout /t 10 > null

wanglmb commented 10 months ago

append test scripts and log files:

win-qga-test.zip

vrozenfe commented 10 months ago

@wanglmb Can you please post the qemu command line?

Thanks, Vadim.

wanglmb commented 10 months ago

@vrozenfe

Actrually,the problem was first found against guest-tools upgrad testing senario. We enhance the guest-tools with extra channel to perform upgrade operation, the full upgrading steps should be:

  1. host attache guest-tools iso to a VM
  2. vm qga copy the iso contents to vm disk
  3. qga call the above upgrade.bat script to execute upgreading.

But, we found sometimes the upgrade process will hung at the uninstall step.

I write a test.bat to reproduce the issue and simplify the test case: the test.bat was executed in windows vm directlly with adminstrator privilege, not from host over qemu command. Only repeating install/uninstall with the the published virtio-win-guest-tools.exe .

Thanks. wanglmb

YanVugenfirer commented 10 months ago

@wanglmb I think if qga calls upgrade.bat we might hit some corner case issue when upgrade tries to remove qga and the virtio-serial driver while qga is still processing the command, and the best way is to schedule an upgrade from qga instead of calling it directly.

vrozenfe commented 10 months ago

I think we might need to review vioserial port Read/Write requests cancellation logic. Best, Vadim.

wanglmb commented 10 months ago

@YanVugenfirer I try to set extra task to perform upgrade, and sync task with a registry key, let's observe the testing results tomorrow~

test.bat

@echo off set key="HKEY_CURRENT_USER\vmtools-upgrading" set loop=1000 for /l %%i in (1,1,%loop%) do ( @echo on echo ++++%%i+++++++ @echo off reg add %key% /v value /d "upgrading" /f start /min cmd /c d:\vmtools\upgrade.bat call:wait ) reg delete %key% /f pause

:wait timeout /t 2 > null Setlocal enabledelayedexpansion for /f "skip=1 tokens=3 delims= " %%j in ('reg query %key% /v value') do ( set var=%%j set "var=!var:"=!" if not "!var:~-1!"=="=" set result="!var!" ) if %result%=="upgrading" goto wait goto:eof

upgrade.bat

REM @echo off set filename=virtio-win-guest-tools.exe set dir=C:\ProgramData\Package Cache set key="HKEY_CURRENT_USER\vmtools-upgrading" Setlocal enabledelayedexpansion pushd "%dir%" for /f "delims=" %%i in ('dir /b /s %filename% 2^>null') do ( if exist %%i ( cd /d "%%~dpi" d:\vmtools\virtio-win-guest-tools.exe /uninstall /passive /norestart /log log.txt ) ) popd d:\vmtools\virtio-win-guest-tools.exe /install /passive /norestart timeout /t 10 > null reg add %key% /v value /d "finsish" /f

ChendongSun commented 10 months ago

the best way is to schedule an upgrade from qga

There is no upgrade interface provided inside qga, how to use qga to schedule an upgrade? and I wonder if it is possible to close the channel before upgrading?Because upgrade failures often occur during the installation and uninstallation of qemu-ga.msi,it most likely related to vioserial or vss-provider

YanVugenfirer commented 10 months ago

@ChendongSun For example use https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/schtasks

wanglmb commented 10 months ago

looks like this CVE fix the problem: https://gitlab.com/qemu-project/qemu/-/commit/07ce178a2b0768eb9e712bb5ad0cf6dc7fcf0158

kostyanf14 commented 10 months ago

Hi @wanglmb,

The latest public release contains this fix. Also, this CVE fix does not change provider installation/uninstallation logic, just changes the entry point.

Before commit: installer -> qemu-ga.exe -> qga-vss.dll -> COMRegister After commit: installer -> rundll32.exe -> qga-vss.dll -> DLLCOMRegister (wrapper) -> COMRegister