了解 qemu 虛擬機器關閉(使用 QMP 透過 telnet 啟動)何時完成

了解 qemu 虛擬機器關閉(使用 QMP 透過 telnet 啟動)何時完成

當我啟動 qemu (Windows Server 2003) 虛擬機器時

-qmp tcp:127.0.0.1:4444,server,nowait

我可以使用以下腳本將其關閉

#!/bin/bash
telnet 127.0.0.1 4444 <<JSON 
{ "execute": "qmp_capabilities" } 
{ "execute": "system_powerdown" } 

JSON

但有兩個問題:

  1. 腳本以 $? 退出= 1 並表示「連線被外部主機關閉」。我可以讓它以乾淨的方式退出嗎?

  2. 關閉過程異步發生。因此,腳本立即返回,而不是等待虛擬機器完成關閉。我如何知道它何時完成(無需 grep ps for qemu 或類似的東西)?

背景是我想在 Linux 主機上的虛擬機器內託管 Windows Server 2003 安裝,並且我想使用 UPS。如果發生斷電,我想關閉虛擬機,然後關閉主機——當然,主機應該在虛擬機完成後才開始關閉。

答案1

使用expect是可以的。當虛擬機器完成時,將發出名為「SHUTDOWN」的事件。因此,以下腳本啟動關閉並等待其完成:

#!/usr/bin/expect

set timeout -1

spawn telnet 127.0.0.1 4444

expect "QMP"
send "{ 'execute': 'qmp_capabilities' }\n"

expect "return"
send "{ 'execute': 'system_powerdown' }\n"

expect "SHUTDOWN"

因為我已經對我的問題投了反對票,特別是考慮到以下聲明

如果你正在做類似上面的事情,那麼其他一切可能都是一團糟,只能勉強工作,如果你以錯誤的方式看待它,就會崩潰。

我還得說另一件事。我真的不明白為什麼做這樣的事情“可能一團糟”,尤其是虛擬機器本身。當透過 libvirt 啟動它時,與執行該工作的 shell 腳本相比,完成的事情完全相同。為什麼它“幾乎不起作用”?此外,QMP 已被設計並透過諸如 telnet 之類的方式提供,從而可以以這種方式執行“類似的操作”,不是嗎?

難道 libvirt 只不過是多個虛擬化解決方案介面的包裝器,以便可以以相同的方式處理由不同虛擬機器管理程式執行的多個虛擬機器安裝嗎?那麼,當我只在一個虛擬機器管理程式中執行一台虛擬機器時,為什麼要使用它呢?

也許我在這裡完全錯了,但至少,這就是如何使用(bash)腳本關閉 qemu 虛擬機,並知道它何時以一種體面的方式完成,而無需使用 libvirt。

答案2

遇到了這個問題,希望關閉沒有 libvirtd 的虛擬機器。至於為什麼,libvirtd 由於交換設備故障而無法啟動。我想徹底關閉虛擬機,但無法使用 libvirt 儲存到磁碟。有了上面的內容我想出了

在 /var/lib/libvirt/qemu 中

for sock in $(find | grep Monitor);執行 printf "{ 'execute': 'qmp_capability' }\n{ 'execute': 'system_powerdown' }\n" | socat - UNIX-CONNECT:$sock;完畢

這是針對 UBUNTU 的。總的來說,是的,我通常會使用 libvirt,但我知道它是其他一些關閉命令的介面。知道 libvirt 實際上在做什麼讓我可以乾淨地關閉虛擬機器。

相關內容