36 使用 QEMU 监控器管理虚拟机 #
通过 qemu-system-ARCH
命令(例如 qemu-system-x86_64
)调用虚拟机时,会提供一个监控器控制台用来与用户交互。使用监控器控制台中提供的命令可以检查运行中的操作系统、更改可移动媒体、截取屏幕截图或音频片段,以及控制虚拟机的其他方面。
下列章节列出了精选的实用 QEMU 监控器命令及其用途。要获取完整列表,请在 QEMU 监控器命令行中输入 help
。
36.1 访问监控器控制台 #
libvirt
没有监控器控制台
仅当您直接使用 qemu-system-ARCH
命令启动虚拟机并在内置 QEMU 窗口中查看其图形输出时,才可以访问监控器控制台。
如果您使用 libvirt
启动了虚拟机(例如,使用 virt-manager
)并通过 VNC 或 Spice 会话查看其输出,则无法直接访问监控器控制台。不过,您可以通过 virsh
将监控器命令发送到虚拟机:
#
virsh qemu-monitor-command COMMAND
访问监控器控制台的方式取决于您使用哪种显示设备来查看虚拟机的输出。第 35.3.2.2 节 “显示选项”中提供了有关显示器的更多细节。例如,要在使用 -display gtk
选项的情况下查看监控器,请按 Ctrl–Alt–2。同样,在使用 -nographic
选项时,可按组合键 Ctrl–AC 切换到监控器控制台。
在使用控制台时如需帮助,请使用 help
或 ?
。要获取有关特定命令的帮助,请使用 help
COMMAND。
36.2 获取有关 Guest 系统的信息 #
要获取有关 Guest 系统的信息,请使用 info
。如果不结合任何选项使用该命令,将列显可能的选项的列表。选项可确定要分析系统的哪个部分:
info version
显示 QEMU 的版本。
info commands
列出可用的 QMP 命令。
info network
显示网络状态。
info chardev
显示字符设备。
info block
有关块设备(例如硬盘、软盘驱动器或 CD-ROM)的信息。
info blockstats
块设备的读取和写入统计数据。
info registers
显示 CPU 寄存器。
info cpus
显示有关可用 CPU 的信息。
info history
显示命令行历史。
info irq
显示中断统计数据。
info pic
显示 i8259 (PIC) 状态。
info pci
显示 PCI 信息。
info tlb
显示虚拟内存到物理内存的映射。
info mem
显示活动的虚拟内存映射。
info jit
显示动态编译器信息。
info kvm
显示 KVM 信息。
info numa
显示 NUMA 信息。
info usb
显示 Guest USB 设备。
info usbhost
显示主机 USB 设备。
info profile
显示分析信息。
info capture
显示捕获(音频抓取)信息。
info snapshots
显示当前保存的虚拟机快照。
info status
显示当前虚拟机的状态。
info mice
显示哪些 Guest 鼠标正在接收事件。
info vnc
显示 VNC 服务器状态。
info name
显示当前虚拟机的名称。
info uuid
显示当前虚拟机的 UUID。
info usernet
显示用户网络堆栈连接状态。
info migrate
显示迁移状态。
info balloon
显示气球设备信息。
info qtree
显示设备树。
info qdm
显示 qdev 设备型号列表。
info roms
显示 ROM。
info migrate_cache_size
显示当前迁移 xbzrle(“基于 Xor 的零运行长度编码”)缓存大小。
info migrate_capabilities
显示多个迁移功能(例如 xbzrle 压缩)的状态。
info mtree
显示 VM Guest 内存层次结构。
info trace-events
显示可用的跟踪事件及其状态。
36.3 更改 VNC 口令 #
要更改 VNC 口令,请使用 change vnc
password
命令并输入新口令:
(qemu) change vnc password Password: ******** (qemu)
36.4 管理设备 #
要在 Guest 运行时添加新磁盘(热插入),请使用 drive_add
和 device_add
命令。首先定义要作为设备添加到总线 0 的新驱动器:
(qemu) drive_add 0 if=none,file=/tmp/test.img,format=raw,id=disk1 OK
可以通过查询块子系统来确认新设备:
(qemu) info block [...] disk1: removable=1 locked=0 tray-open=0 file=/tmp/test.img ro=0 drv=raw \ encrypted=0 bps=0 bps_rd=0 bps_wr=0 iops=0 iops_rd=0 iops_wr=0
定义新驱动器后,需将它连接到某个设备,使 Guest 能够看到它。典型的设备是 virtio-blk-pci
或 scsi-disk
。要获取可用值的完整列表,请运行:
(qemu) device_add ? name "VGA", bus PCI name "usb-storage", bus usb-bus [...] name "virtio-blk-pci", bus virtio-bus
现在添加设备
(qemu) device_add virtio-blk-pci,drive=disk1,id=myvirtio1
并使用以下命令确认
(qemu) info pci [...] Bus 0, device 4, function 0: SCSI controller: PCI device 1af4:1001 IRQ 0. BAR0: I/O at 0xffffffffffffffff [0x003e]. BAR1: 32 bit memory at 0xffffffffffffffff [0x00000ffe]. id "myvirtio1"
可以使用 device_del
从 Guest 中去除通过 device_add
命令添加的设备。如需详细信息,请在 QEMU 监控器命令行中输入 help device_del
。
要释放与可移动媒体设备连接的设备或文件,请使用 eject
DEVICE 命令。使用可选的 -f
可以强制弹出。
要更改可移动媒体(例如 CD-ROM),请使用 change
DEVICE 命令。可以使用 info
block
命令确定可移动媒体的名称:
(qemu)
info block
ide1-cd0: type=cdrom removable=1 locked=0 file=/dev/sr0 ro=1 drv=host_device(qemu)
change ide1-cd0 /path/to/image
36.5 控制键盘和鼠标 #
如果需要,可以使用监控器控制台来模拟键盘和鼠标输入。例如,如果您的图形用户界面会拦截某些低级别的组合键(例如 X Window 系统中的 Ctrl–Alt–F1),您仍可以使用 sendkey
KEYS 来输入这些组合键:
sendkey ctrl-alt-f1
要列出 KEYS 选项中使用的按键名称,请输入 sendkey
并按 →|。
要控制鼠标,可使用以下命令:
mouse_move
DX dy [DZ]将活动的鼠标指针移到指定的坐标 dx, dy, dz(该滚动轴可选)。
mouse_button
VAL更改鼠标按钮的状态(1=左,2=中,4=右)。
mouse_set
INDEX设置由哪个鼠标设备接收事件。可以使用
info mice
命令获取设备索引号。
36.6 更改可用内存 #
如果启动虚拟机时使用了 -balloon
virtio
选项(如此会启用半虚拟化气球设备),您便可以动态更改可用内存。有关启用气球设备的详细信息,请参见第 34.1 节 “使用 qemu-system-ARCH
进行基本安装”。
要在监控器控制台中获取有关气球设备的信息,并确定该设备是否已启用,请使用 info
balloon
命令:
(qemu) info balloon
如果气球设备已启用,请使用 balloon
MEMORY_IN_MB 命令设置请求的内存量:
(qemu) balloon 400
36.7 转储虚拟机内存 #
要将虚拟机内存的内容保存到磁盘或控制台输出,请使用以下命令:
memsave
ADDRSIZEFILENAME将起始地址为 ADDR、大小为 SIZE 的虚拟内存转储保存到 FILENAME 文件中
pmemsave
ADDRSIZEFILENAME将起始地址为 ADDR、大小为 SIZE 的物理内存转储保存到 FILENAME- 文件中
- x /FMTADDR
创建起始地址为 ADDR 并根据 FMT 字符串设置格式的虚拟内存转储。FMT 字符串由
COUNTFORMATSIZE
这三个参数构成:COUNT 参数是要转储的项数。
FORMAT 可以是
x
(十六进制)、d
(有符号十进制)、u
(无符号十进制)、o
(八进制)、c
(字符)或i
(汇编指令)。SIZE 参数可以是
b
(8 位)、h
(16 位)、w
(32 位)或g
(64 位)。在 x86 上,可以使用i
格式指定h
或w
,以分别选择 16 位或 32 位代码指令大小。- xp /FMTADDR
创建起始地址为 ADDR 并根据 FMT 字符串设置格式的物理内存转储。FMT 字符串由
COUNTFORMATSIZE
这三个参数构成:COUNT 参数是要转储的项数。
FORMAT 可以是
x
(十六进制)、d
(有符号十进制)、u
(无符号十进制)、o
(八进制)、c
(字符)或i
(汇编指令)。SIZE 参数可以是
b
(8 位)、h
(16 位)、w
(32 位)或g
(64 位)。在 x86 上,可以使用i
格式指定h
或w
,以分别选择 16 位或 32 位代码指令大小。
36.8 管理虚拟机快照 #
SUSE 目前不支持在 QEMU 监控器中管理快照。本节中的信息在特定的情形下可能有帮助。
虚拟机快照是整个虚拟机的快照,包括 CPU、RAM 的状态以及所有可写磁盘的内容。要使用虚拟机快照,您必须至少有一个使用 qcow2
磁盘映像格式且不可移动的可写块设备。
当您需要保存特定状态的虚拟机时,快照非常有用。例如,在虚拟化服务器上配置网络服务后,您可以从上次保存的虚拟机状态快速启动虚拟机。您还可以在关闭虚拟机之后创建快照,以便在尝试执行某种会导致 VM Guest 不稳定的试验性操作之前创建备份状态。本节介绍前一种做法,后一种做法已在第 34.2.3 节 “使用 qemu-img 管理虚拟机的快照”中介绍。
可在 QEMU 监控器中使用以下命令管理快照:
savevm
NAME创建一个标记为 NAME 的新虚拟机快照,或替换现有快照。
loadvm
NAME加载标记为 NAME 的虚拟机快照。
delvm
删除虚拟机快照。
info snapshots
列显有关可用快照的信息。
(qemu) info snapshots Snapshot list: ID1 TAG2 VM SIZE3 DATE4 VM CLOCK5 1 booting 4.4M 2013-11-22 10:51:10 00:00:20.476 2 booted 184M 2013-11-22 10:53:03 00:02:05.394 3 logged_in 273M 2013-11-22 11:00:25 00:04:34.843 4 ff_and_term_running 372M 2013-11-22 11:12:27 00:08:44.965
36.9 挂起和恢复虚拟机执行 #
以下命令可用于挂起和恢复虚拟机:
stop
挂起虚拟机的执行。
cont
恢复虚拟机的执行。
system_reset
重置虚拟机。效果类似于物理机上的复位按钮。这可能会使文件系统处于一种不干净状态。
system_powerdown
向计算机发送 ACPI 关机请求。效果类似于物理机上的电源按钮。
q
或quit
立即终止 QEMU。
36.10 动态迁移 #
实时迁移过程可将任何虚拟机从一个主机系统传输到另一个主机系统,而不会对可用性造成任何干扰。您可以永久性更改主机,或者仅在维护期间更改主机。
实时迁移的要求:
第 11.7.1 节 “迁移要求”中所述的所有要求均适用。
只能在具有相同 CPU 功能的 VM 主机服务器之间进行实时迁移。
必须以相同的方式启动源主机和目标主机上的 Guest。
不应使用
-snapshot
qemu 命令行选项进行迁移(不支持此qemu
命令行选项)。
SUSE Linux Enterprise Server 中尚不支持 postcopy
模式。此模式仅发布为技术预览版。有关 postcopy
的详细信息,请参见 https://wiki.qemu.org/Features/PostCopyLiveMigration。
以下网站上提供了更多建议:https://www.linux-kvm.org/page/Migration
实时迁移过程包括以下步骤:
虚拟机实例正在源主机上运行。
虚拟机以冻结侦听模式在目标主机上启动。使用的参数与源主机上相同,不过还要加上
-incoming tcp:IP:PORT
参数,其中 IP 指定 IP 地址,PORT 指定用于侦听传入迁移的端口。如果设置了 0 作为 IP 地址,则虚拟机将侦听所有接口。在源主机上,切换到监控器控制台,并使用
migrate -d tcp:
DESTINATION_IP:PORT 命令启动迁移。要确定迁移状态,请在源主机上的监控器控制台中使用
info migrate
命令。要取消迁移,请在源主机上的监控器控制台中使用
migrate_cancel
命令。要设置迁移时容许的最长停机时间(以秒为单位),请使用
migrate_set_downtime
NUMBER_OF_SECONDS 命令。要设置最大迁移速度(每秒字节数),请使用
migrate_set_speed
BYTES_PER_SECOND 命令。
36.11 QMP - QEMU 计算机协议 #
QMP 是基于 JSON 的协议,可使应用程序(例如 libvirt
)能够与运行中的 QEMU 实例通讯。您可以使用 QMP 命令以多种方式访问 QEMU 监控器。
36.11.1 通过标准输入/输出访问 QMP #
最灵活的 QMP 使用方式是指定 -mon
选项。下面的示例使用标准输入/输出创建了一个 QMP 实例。在以下示例中,->
标记了包含从客户端发送到运行中 QEMU 实例的命令的行,而 <-
标记了包含 QEMU 返回的输出的行。
>
sudo
qemu-system-x86_64 [...] \ -chardev stdio,id=mon0 \ -mon chardev=mon0,mode=control,pretty=on <- { "QMP": { "version": { "qemu": { "micro": 0, "minor": 0, "major": 2 }, "package": "" }, "capabilities": [ ] } }
建立新的 QMP 连接后,QMP 将发送其问候消息并进入功能协商模式。在此模式下,只有 qmp_capabilities
命令能够正常运行。要退出功能协商模式并进入命令模式,必须先发出 qmp_capabilities
命令:
-> { "execute": "qmp_capabilities" } <- { "return": { } }
"return": {}
是 QMP 成功时返回的响应。
QMP 的命令可以附带参数。例如,要弹出 CD-ROM 驱动器,请输入以下命令:
->{ "execute": "eject", "arguments": { "device": "ide1-cd0" } } <- { "timestamp": { "seconds": 1410353381, "microseconds": 763480 }, "event": "DEVICE_TRAY_MOVED", "data": { "device": "ide1-cd0", "tray-open": true } } { "return": { } }
36.11.2 通过 telnet 访问 QMP #
如果不使用标准输入/输出,您可将 QMP 接口连接到某个网络套接字,并通过特定的端口与其通讯:
>
sudo
qemu-system-x86_64 [...] \ -chardev socket,id=mon0,host=localhost,port=4444,server,nowait \ -mon chardev=mon0,mode=control,pretty=on
然后运行 telnet 连接到端口 4444:
>
telnet localhost 4444
Trying ::1...
Connected to localhost.
Escape character is '^]'.
<- {
"QMP": {
"version": {
"qemu": {
"micro": 0,
"minor": 0,
"major": 2
},
"package": ""
},
"capabilities": [
]
}
}
您可以同时创建多个监控器接口。下面的示例在标准输入/输出上创建了一个 HMP 实例(可识别“常规”QEMU 监控器命令的人工监控器),并在 localhost 端口 4444 上创建了一个 QMP 实例:
>
sudo
qemu-system-x86_64 [...] \ -chardev stdio,id=mon0 -mon chardev=mon0,mode=readline \ -chardev socket,id=mon1,host=localhost,port=4444,server,nowait \ -mon chardev=mon1,mode=control,pretty=on
36.11.3 通过 Unix 套接字访问 QMP #
使用 -qmp
选项调用 QEMU,并创建一个 Unix 套接字:
>
sudo
qemu-system-x86_64 [...] \ -qmp unix:/tmp/qmp-sock,server --monitor stdio QEMU waiting for connection on: unix:./qmp-sock,server
要通过 /tmp/qmp-sock
套接字来与 QEMU 实例通讯,请在同一主机上的另一个终端中使用 nc
(有关详细信息,请参见 man 1 nc
):
>
sudo
nc -U /tmp/qmp-sock <- {"QMP": {"version": {"qemu": {"micro": 0, "minor": 0, "major": 2} [...]
36.11.4 通过 libvirt
的 virsh
命令访问 QMP #
如果您在 libvirt
下运行虚拟机(请参见第 II 部分 “使用 libvirt
管理虚拟机”),则可以通过运行 virsh
qemu-monitor-command
来与它的运行中 Guest 通讯:
>
sudo
virsh qemu-monitor-command vm_guest1 \ --pretty '{"execute":"query-kvm"}' <- { "return": { "enabled": true, "present": true }, "id": "libvirt-8" }
在以上示例中,我们运行了简单的 query-kvm
命令来检查主机是否能够运行 KVM,以及是否启用了 KVM。
要使用 QEMU 的直观易懂的标准输出格式而不是 JSON 格式,请使用 --hmp
选项:
>
sudo
virsh qemu-monitor-command vm_guest1 --hmp "query-kvm"