退出qemu_qemu虚拟机的关机方式
qemu虛擬機的關閉方式主要包括如下幾種方式:通過qemu monitor的system_powerdown命令進行關閉,
在libvirt對qemu進行管理的情況下,通過virsh shutdown命令進行關閉。
在虛擬機內使用Guest OS自帶的關機按鈕進行關閉。
通過qemu monitor的quit命令進行關閉。
在libvirt對qemu進行管理的情況下,通過virsh destroy命令進行關閉。
在主機端通過Ctrl+C強制關閉qemu進程關閉虛擬機。
kill/pkill命令結束進程
1. qemu monitor的system_powerdown命令
system_powerdown是qemu monitor中支持的一個命令。
qemu進程的主循環位于vl.c:main_loop(),在主循環會循環調用main_loop_should_exit()判斷是否結束主循環。
main_loog_should_exit()函數中會通過qemu_powerdown_requested()函數判斷qemu虛擬機是否接收到了powerdown的請求,如果有該請求,則調用qemu_system_powerdown(),該函數先發出POWERDOWN的事件,然后通知注冊到powerdown的notifier函數
不同的主板,會注冊不同的powerdown notifier
以piix4為例,在piix4_pm_realize函數中,會將piix4_pm_powerdwon_req()這個notify handler注冊到qemu虛擬機的powerdown notifier中。
該notifier handler主要是調用acpi_pm1_evt_power_down()函數,在該函數中,會檢測在該虛擬機主板上,電源鍵(Power Button)是否被使能,如果被使能了,則模擬該電源鍵被按下,發送SCI(System Control Interrupt)中斷,觸發Guest OS進行關機。
所以qemu monitor的system_powerdown命令本質上是模擬電源鍵被按下觸發SCI中斷的動作。至于Guest OS是否會關機,則由Guest OS的行為配置決定的,如在Windows中,如果在電源設置中,將Windows的電源按鍵設置為不響應,則發送system_powrdown命令后,Windows將不做響應,無法實現虛擬機關機,除非Windows中將電源鍵功能設置為關機。
2. virsh shutdown命令
virsh shutdown命令會調用到libvirt的virDomainShutdown()函數,該函數會繼續調用不同類型hypervisor的shutdown函數,如對于qemu而言,它會調用到qemu dirver對應的domainShutdown,即qemuDomainShutdown(),在該函數中,會執行如下操作:檢測Qemu Guest Agent是否存在,如果存在并且可用,則通過Qemu Guest Agent告知Guest OS進行關機操作。
如果Qemu Guest Agent不存在,則檢測qemu虛擬機是否支持ACPI Power Button,如果支持,則調用qemuMonitorSystemPowerdown()函數,即在qemu monitor中,發送system_powerdown命令,模擬電源鍵被按下并出發SCI的動作,觸發Guest OS進行關機。
所以,在不用Qemu Guest Agent的情況下,virsh shutdown命令其實就對應到qemu monitor中的system_powerdown命令,只是該命令由libvirt發送。
3. Guest OS關機接口
在虛擬機內使用Guest OS自帶的關機按鈕/功能進行關機,以Ubuntu為例,通過systemctl poweroff命令對Ubuntu進行關機,該命令會調用到kernel/power/poweroff.c文件中定義個poweroff_work對應的工作,該工作主要是執行do_poweroff()對系統進行關機。
kernel/power/poweroff.c:do_poweroff() -> kernel_power_off() ,該函數關閉所有的用戶程序和設備,最后調用machine_power_off()函數。
machine_power_off() -> power_off() -> native_machine_poweroff() -> pm_power_off() 若該Ubuntu運行的虛擬機支持ACPI標準,則pm_power_off將指向acpi_power_off()函數。
acpi_power_off() -> acpi_enter_sleep_state()
該函數將會往ACPI標準中規定的寄存器PM1 Control Registers Fixed Hardware Feature Control Bits中的SLP_TYPE和SLP_EN域寫相應的數據,讓虛擬機主板進入到指定的睡眠狀態,即ACPI標準中定義的S0 ~ S5狀態。
而在qemu模擬器方面,在hw/acpi/core.c中會對PM1 Control Registers Fixed Hardware Feature Control Bits的寫進行監控,當向SLY_TYP和SLY_EN寫特定值的時候,會觸發qemu調用qemu_system_shutdown_request()發出shutdown的請求。
qemu進程的主要循環函數main_loop()中,會循環調用main_loop_should_exit()函數,該函數會檢測系統中是否有shutdown的請求發出。若有shutdown的請求,則qemu進程退出主循環,結束并退出qemu虛擬機。
4. qemu monitor的quit命令
qemu monitor的quit命令讓qemu進程直接退出。
直接在qemu monitor中輸入quit命令,將觸發qemu虛擬機直接退出,Guest OS完全不知道虛擬機即將關閉,所以對Guest OS來說,將會直接閃退,類似物理機的直接掉電。
quit命令將調度到qemu的hmp_quit()函數,該函數將會告知qemu進程在虛擬機關閉的時候退出,同時發出shutdown的請求,qemu進程的主循環main_loop()在執行main_loop_should_exit()檢查是否需要退出主循環的時候,將檢測到該事件,然后直接退出。
5. virsh destroy命令
libvirt提供的virsh destroy命令,將調用到qemu driver的qemuDomainDestroy() -> qemuDomainDestroyFlags() -> qemuProcessStop() -> qemuProcessKill()接口,將qemu進程關掉。
qemuProcessKill()中,將會向qemu進程發送SIGKILL或SIGTERM信號,讓qemu進程退出。
在qemu這邊,qemu的主進程中,會通過os_setup_signal_handling()設置對信號的響應。
termsig_handler() -> qemu_system_killed(),在qemu_system_killed()中,將會生成shutdown的請求,并且shutdown請求的原因是host signal。該請求將會讓qemu進程的主循環退出,不等Guest OS準備好關機。
6. Ctrl+C組合鍵
在主機端通過Ctrl+C組合鍵,讓qemu進程退出,其實是向qemu進程發送SIGINT信號,該信號的處理方式和SIGTERM是一樣的,也就是最后調用到qemu_system_killed()函數,發出shutdown請求,讓qemu主進程退出,同時記錄下shutdown的原因為host signal。
7. kill/pkill命令
在主機端使用kill -9 pid或者pkill -9 pname的方式,也是向主機進程發送SIGKILL信號,讓進程退出的。
總結
以上是生活随笔為你收集整理的退出qemu_qemu虚拟机的关机方式的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: HBuilderX插件安装系统找不到指定
 - 下一篇: 【ZT】2D动画制作工具比较