了解 qemu vm 关闭(使用 QMP 通过 telnet 启动)何时完成

了解 qemu vm 关闭(使用 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. 关闭过程是异步发生的。因此,脚本会立即返回,而不会等待虚拟机完成关闭。我如何知道它何时完成(无需 grepping 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 中

对于 $(find | grep monitor) 中的 sock;执行 printf "{'execute': 'qmp_capabilities' }\n{'execute': 'system_powerdown' }\n" | socat - UNIX-CONNECT:$sock;完成

这是针对 UBUNTU 的。所以总的来说,我通常会使用 libvirt,但我知道它是其他关闭命令的接口。知道 libvirt 实际在做什么让我可以干净利落地关闭虚拟机。

相关内容