我正在尝试检索串行端口信息,又称Source Path
libvirt 域(使用 qemu/KVM 机器):
Serial Device 1 (Primary Console)
Device type: pty
Source path: /dev/pts/2
但我检查了API参考这里而且它似乎不支持Source Path
.
有没有类似的命令VBoxManage
可以直接列出这些信息?
奇怪,我在libvirt
群里,我可以用 来控制(启动、停止等)KVM 机器virt-manager
,virsh
还显示virsh #
提示。
但我无法使用virsh list --all
命令看到任何内容,我仍然必须使用 root 权限运行它。
答案1
KVM 是用于虚拟化的内核 API。它不涉及串口。qemu
是一个机器(PC 和其他)模拟器,可用于kvm
提高虚拟化性能。它可以模拟标准 8250 UART 串行端口 ( isa-serial
) 或半虚拟化串行端口 ( virtio-serial
)。
在 qemu 中,您可以使用命令行参数定义您的机器,这些参数指定要添加到您的机器的设备以及添加的内容后端这些设备映射到(例如模拟硬盘到图像文件,网络适配器到设备tap
......)。
对于串行端口,您通常将其映射到 qemu 调用的内容查德夫斯。
有很多可能的不同的,通常是任何可以发送和接收字节的东西,比如管道、套接字、文件描述符、伪终端。
例如,如果您运行 qemu:
qemu ... -device isa-serial,chardev=c,id=s -chardev pty,id=c
qemu 分配一个伪终端,在启动时在 stdout 上报告:
char device redirected to /dev/pts/18 (label c)
并将其映射到一个新的伊萨虚拟机添加串口。如果启动 Linux VM,您将在其内核日志中看到:
[ 3.636092] Serial: 8250/16550 driver, 32 ports, IRQ sharing enabled
[ 3.658666] 00:05: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A
如果您/dev/ttyS0
在来宾中写入内容,您将能够在/dev/pts/18
主机上读取它。
qemu VM启动后,您可以通过qemu调用来控制它监视器接口。有两种类型监视器接口:
- 人体监视器:类似 shell 的 CLI
- 机器监视器:一个更加机器友好的界面,实现称为 qemu 机器协议 (QMP) 的文本 (json) 协议。
如果您不指定任何内容并使用默认的 SDL 控制台,您将获得人体监视器在 SDL 控制台中按Ctrl+Alt+2。
但您也可以指定任何查德夫后端(pty、socket、stdio...)。通常,我stdio
在那里使用:
qemu ... -monitor stdio
为了得到监视器在终端上,我从运行 qemu 进行测试时启动 qemu 。
在那里面监视器界面中,您可以运行以下info qtree
命令来获取您机器的设备信息:
(qemu) info qtree
bus: main-system-bus
[...]
dev: i440FX-pcihost, id ""
[...]
bus: pci.0
[...]
dev: PIIX3, id ""
class ISA bridge, addr 00:01.0, pci id 8086:7000 (sub 1af4:1100)
bus: isa.0
type ISA
dev: isa-serial, id "s"
index = 0 (0)
iobase = 1016 (0x3f8)
irq = 4 (0x4)
chardev = "c"
在上面,您可以看到isa-serial
我之前创建的设备,它映射到"c"
查德夫。
您可以使用以下命令从该 chardev 获取信息info chardev
:
(qemu) info chardev
parallel0: filename=vc
c: filename=pty:/dev/pts/18
compat_monitor0: filename=stdio
您会看到c
地图/dev/pts/18
普蒂。
您可以使用 QMP 监视器以编程方式获取相同的信息。如果您使用 启动虚拟机-qmp stdio
,则可以在其中传递命令:
{"execute":"qmp_capabilities"} # enable commands
{"return": {}} # return value
{"execute":"qom-list","arguments":{"path":"/machine/peripheral/s"}}
{"return": [{"name": "parent_bus", "type": "link<bus>"}, {"name": "wakeup", "type": "uint32"}, {"name": "chardev", "type": "str"}, {"name": "irq", "type": "uint32"}, {"name": "iobase", "type": "uint32"}, {"name": "index", "type": "uint32"}, {"name": "hotpluggable", "type": "bool"}, {"name": "realized", "type": "bool"}, {"name": "type", "type": "string"}]}
# query chardev for "s":
{"execute":"qom-get","arguments":{"path":"/machine/peripheral/s","property":"chardev"}}
{"return": "c"}
# query chardevs:
{"execute":"query-chardev"}
{"return": [{"filename": "vc", "label": "parallel0"}, {"filename": "pty:/dev/pts/18", "label": "c"}, {"filename": "stdio", "label": "compat_monitor0"}]}
(看看那些qom-list
and qom-get
(qom 代表 qemu 对象模型)如何让人想起Linux 机器上的ls
and )。cat
/sys
现在你的问题表明你不是直接手动调用 qemu 而是使用libvirt
.libvirt
是众多虚拟化管理基础设施之一。它可以管理 qemu(带或不带 kvm)、xen 或 virtualbox(至少)VM。
对于 qemu VM,当您在 libvirt 中定义 VM(使用 virt-manager 或其他)时,这将转换为要传递给 qemu 命令的参数,并且 libvirt 通常会在启动后使用 qmp 监视器来控制 VM。
对于libvirt
域,您可以通过以下方式获取域的当前配置:
virsh dumpxml the-domain
它将配置转储为 XML。您可以使用xmllint
或xmlstarlet
或您选择的任何 XML 解析解决方案从中提取信息。
$ virsh dumpxml domain | xmllint --xpath '//serial' -
<serial type="pty">
<source path="/dev/pts/4"/>
<target port="0"/>
<alias name="serial0"/>
</serial><serial type="pty">
<source path="/dev/pts/5"/>
<target port="1"/>
<alias name="serial1"/>
</serial><serial type="pty">
<source path="/dev/pts/6"/>
<target port="2"/>
<alias name="serial2"/>
</serial>
$ virsh dumpxml domain |
xmllint --xpath 'string(//serial[target/@port=0]/source/@path)' -
/dev/pts/4
等效的xmlstarlet
:
sudo virsh dumpxml domain | xmlstarlet sel -t -c '//serial'
sudo virsh dumpxml domain |
xmlstarlet sel -t -v '//serial[target/@port=0]/source/@path'
请注意,您还可以使用命令将命令传递到 QMP 监视器virsh qemu-monitor-command
。
例如:
$ virsh qemu-monitor-command domain '{"execute":"qom-get","arguments":
{"path":"/machine/peripheral/serial0","property":"chardev"}}'
{"return":"charserial0","id":"libvirt-84"}