接上文,通过跟踪 libvirt 的源码,找到 virsh domblkinfo
最终是使用 QMP 协议从 QEMU 获取到关键字为 query-block
的数据,其中带有 wr_highest_offset
字段,该字段被 libvirt 认定为 磁盘利用率中 Allocation
值的来源。
今天就尝试在 QEMU 中找到获取 wr_highest_offset
字段的方法。
环境准备
- QEMU 4.0
- Centos
- 鲲鹏 ARM
首先需要编译 QEMU 加入函数表,重新编译 QEMU在其中加入该字段即可,编译方法可以参考源码目录:
./configure --enable-debug
跟踪前需要定位到 QEMU 中填充该字段的函数,首先在源码中全局搜索 wr_highest_offset
,最终确定 block/qapi.c
文件中的 bdrv_query_bds_stats
函数最有可能是填充该字段的位置,下面就来跟踪这个函数的走向吧。
跟踪记录
一个虚拟机在宿主机中表现为一个 QEMU
的进程,在这里仅保留一个虚拟机,查询该虚拟机状态时 libvirt 回使用 unix socket
的方式发往该进程监听的 unix socket
服务。因此跟踪该虚拟机所在进程即可。
# ps -aux | grep qemu
qemu 2185346 0.6 0.5 3562240 333440 ? Sl 10:05 2:20 /usr/bin/qemu-system-aarch64 -name guest=instance-000001bb,...imestamp=on
root 2472547 0.0 0.0 110784 2496 pts/3 S+ 16:03 0:00 grep --color=auto qemu
GDB 开始跟踪:
gdb qemu-system-aarch64 2185346
在之前找到的目标函数处打上断点:
(gdb) b bdrv_query_bds_stats
之后 c
继续执行,尝试查询一下磁盘状态。
$ virsh domblkinfo 25 vda --human
Breakpoint 1, bdrv_query_bds_stats (bs=0x3b549940, blk_level=true) at /root/stl/qemu-4.0.0/block/qapi.c:509
509 BlockStats *s = NULL;
会发现终端卡住了,此时 gdb 中断了进程,说明我们找对函数了,下面我们继续追踪吧。
发现这个函数是在 qmp_query_blockstats
中被调用多次,最终得出结果。
544 }
(gdb) n
qmp_query_blockstats (has_query_nodes=false, query_nodes=false, errp=0xffffe3963110) at /root/stl/qemu-4.0.0/block/qapi.c:609
609 s->has_device = true;
(gdb) p s->stats->wr_highest_offset
$3 = 3072
下面主要就是跟着源码来看了,本文主要是讲了如何使用 GDB 跟踪 QEMU 源码,若有疑问欢迎留言。
1 条评论
没有看到获取磁盘信息为什么不准以及解决方法