qemu monitor和qemu agent的实现
虚拟机配置中:
<channel type='unix'>
<target type='virtio' name='org.qemu.guest_agent.0'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>
With qemu, if name is "org.qemu.guest_agent.0", then libvirt can interact with a guest agent installed in the guest, for actions such as guest shutdown or file system quiescing.
虚拟机启动命令行:
/usr/libexec/qemu-kvm
-chardev socket,id=charmonitor,fd=35,server,nowait
-mon chardev=charmonitor,id=monitor,mode=control
-chardev socket,id=charchannel0,fd=42,server,nowait
-device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=org.qemu.guest_agent.0
启动虚拟机时libvirt会创建一个qemu monitor的unix socket和一个qemu agent的unix socket:
srwxrwxr-x 1 root root 0 Jan 11 16:13 /var/lib/libvirt/qemu/domain-28-Centos7/monitor.sock
srwxrwxr-x 1 qemu qemu 0 Jan 11 16:13 /var/lib/libvirt/qemu/channel/target/domain-28-Centos7/org.qemu.guest_agent.0
qemu monitor和qemu agent通道创建过程
Libvirt-6.9
libvirt启动虚拟机时会打开两个unix socket,作为server,一个用作qemu monitor,一个用作qemu agent,然后启动qemu子进程。
qemuProcessStart
->qemuProcessPrepareDomain
->for循环执行qemuDomainPrepareChannel # 设置channel->source->data.nix.path,例如:/var/lib/libvirt/qemu/channel/target/domain-28-Centos7/org.qemu.guest_agent.0
qemuProcessLaunch
->qemuBuildCommandLine
->qemuBuildMonitorCommandLine
->qemuBuildChrChardevStr
->fd = qemuOpenChrChardevUNIXSocket # dev->type == VIR_DOMAIN_CHR_TYPE_UNIX
->virCommandPassFD(cmd, fd, VIR_COMMAND_PASS_FD_CLOSE_PARENT); # 将要传递的fd放在cmd->passfd中
->qemuBuildChannelsCommandLine
->qemuBuildChrChardevStr # VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO
->fd = qemuOpenChrChardevUNIXSocket(dev); # VIR_DOMAIN_CHR_TYPE_UNIX,打开unix socker listen
->virCommandPassFD(cmd, fd, VIR_COMMAND_PASS_FD_CLOSE_PARENT);
->qemuBuildChrDeviceCommandLine # 生成-device参数
->virCommandRun # 启动qemu子进程,之后libvirt进程关闭cmd->passfd中的fd
->qemuProcessWaitForMonitor
->qemuConnectMonitor
->qemuMonitorOpen # 连接unix socket
->qemuProcessInitMonitor # 发送qmp_capabilities
->qemuMigrationCapsCheck # 发送query-migrate-capabilities
->qemuMonitorGetChardevInfo # 发送query-chardev
->qemuProcessRefreshChannelVirtioState # 增加domain agent生命周期事件
->qemuConnectAgent
->agent = qemuAgentOpen(...)
->agent->fd = qemuAgentOpenUnix(config->data.nix.path); # 通过unix socket连接到qemu agent,config->data.nix.path在之前的qemuDomainPrepareChannel 函数中已经设置好
->qemuAgentRegister(agent); # 使用glib事件循环监测qemu agent事件,处理函数为qemuAgentIO
qemu-5.0
qemu_init
->for循环执行chardev_init_func
->qemu_chr_new_from_opts
->backend = qemu_chr_parse_opts(opts, errp);
->qemu_chr_parse_socket # SOCKET_ADDRESS_LEGACY_KIND_FD
->chr = qemu_chardev_new(...)
->chardev_new
->qemu_char_open
->qmp_chardev_open_socket
->qmp_chardev_open_socket_server
qemu-5.0对qmp命令和qga命令的处理
全局变量qmp_dispatcher_bh用于进行qmp命令
/* Bottom half to dispatch the requests received from I/O thread */
QEMUBH *qmp_dispatcher_bh;
函数monitor_init_globals_core初始化qmp_dispatcher_bh并将其处理函数设置为monitor_qmp_bh_dispatcher
void monitor_init_globals_core(void)
{monitor_qapi_event_init();qemu_mutex_init(&monitor_lock);/** The dispatcher BH must run in the main loop thread, since we* have commands assuming that context. It would be nice to get* rid of those assumptions.*/qmp_dispatcher_bh = aio_bh_new(iohandler_get_aio_context(),monitor_qmp_bh_dispatcher,NULL);
}
qmp命令的入口函数是qmp_dispatch:
virsh qemu-monitor-command --hmp info block调用堆栈如下:
Breakpoint 1, 0x000055fdab6f88a0 in hmp_info_block ()
(gdb) bt
#0 0x000055fdab6f88a0 in hmp_info_block ()
#1 0x000055fdab7e3dd6 in handle_hmp_command ()
#2 0x000055fdab674d12 in qmp_human_monitor_command ()
#3 0x000055fdab807019 in qmp_marshal_human_monitor_command ()
#4 0x000055fdab8c14b0 in qmp_dispatch ()
#5 0x000055fdab7e1111 in monitor_qmp_dispatch ()
#6 0x000055fdab7e17d0 in monitor_qmp_bh_dispatcher ()
#7 0x000055fdab9081e3 in aio_bh_poll ()
#8 0x000055fdab90b59e in aio_dispatch ()
#9 0x000055fdab90807e in aio_ctx_dispatch ()
#10 0x00007f25d5f15099 in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
#11 0x000055fdab90a8e3 in main_loop_wait ()
#12 0x000055fdab67b269 in qemu_main_loop ()
#13 0x000055fdab59c08e in main ()
virsh qemu-monitor-command '{"execute": "query-block"}'调用堆栈如下:
#0 0x000055fdab87b5a0 in qmp_query_block ()
#1 0x000055fdab7fc797 in qmp_marshal_query_block ()
#2 0x000055fdab8c1536 in qmp_dispatch ()
#3 0x000055fdab7e1111 in monitor_qmp_dispatch ()
#4 0x000055fdab7e17d0 in monitor_qmp_bh_dispatcher ()
#5 0x000055fdab9081e3 in aio_bh_poll ()
#6 0x000055fdab90b59e in aio_dispatch ()
#7 0x000055fdab90807e in aio_ctx_dispatch ()
#8 0x00007f25d5f15099 in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
#9 0x000055fdab90a8e3 in main_loop_wait ()
#10 0x000055fdab67b269 in qemu_main_loop ()
#11 0x000055fdab59c08e in main ()
qga命令的入口函数是tcp_chr_read:
tcp_chr_read
->qemu_chr_be_write
->chr_read # virtconsole_realize中调用qemu_chr_fe_set_handlers将backend的读函数设置为chr_read(virtio-console.c)
->virtio_serial_write
->virtqueue_push
->virtio_notify
之后就是通过virtio机制通知到虚拟机内部,虚拟机内部的qemu guest agent打开的virtio串口收到消息进行处理。
qemu monitor和qemu agent的实现相关推荐
- qemu monitor
qemu向外界暴露的唯一接口就是 qemu monitor, 通过monitor可以 查询虚拟机信息, 控制虚拟机.传输数据方式是网络套结字. qemu monitor 支持几种协议类型: qmp 和 ...
- QEMU monitor控制台使用详解
为什么要使用 QEMU monitor命令? 在前面学习ubuntu启动第一个虚拟机时,发现我们在使用启动QEMU之后,我们的终端会卡住.而现在我们在启动QEMU时使用了monitor,终端会进入mo ...
- QEMU多进程(Multi-process QEMU)及vfio-user应用
1.Qemu现状-多线程锁竞争 2.Qemu现状-项目依赖太多 $ readelf -d /usr/bin/qemu-system-x86_64 | grep NEEDED | wc -l 60 $ ...
- 2022CTF培训(十三)虚拟化QEMU架构分析QEMU CVE示例分析
附件下载链接 虚拟化技术基本概念 硬件虚拟化 全虚拟化 提供可以完全模拟基础硬件的VME 可以在VM中运行任何能够在物理硬件上执行的软件,并且可以在每个单独的VM中运行基础硬件支持的任何OS 为每个V ...
- linux下qemu共享文件夹,QEMU Windows来宾和Linux主机之间的共享文件夹
QEMU的内置Samba服务 该-net user,smb选项不起作用是由于与较新的Samba版本(> = 4)不兼容而引起的.QEMU v2.2.0和更高版本中已通过以下更改修复了此问题: ( ...
- qemu里pci设备的热插拔
qemu里pci设备的热插拔 -v0.1 2019.2.17 Sherlock Init -v0.2 2019.2.21 Sherlock Add all related command 本文讨论li ...
- virsh KVM管理工具
virsh所有的命令 Domain Management (help keyword 'domain'):attach-device attach device from an XML fileatt ...
- 【虚拟化】virsh指令大全
文章目录 1 - domain management 2 - Domain Monitoring 3 - Host and Hypervisor 4 - Checkpoint 5 - Interfac ...
- libvirt virsh domain命令解析(一)
virsh是libvirt提供的命令行工具, 了解virsh命令的功能,可以快速了解libvirt的主要功能及功能特性 这里首先介绍domain domain 域, 可以看做是一个虚拟机实例 通过 v ...
最新文章
- python pip 换源
- php怎么删除多条,php 用checkbox一次性删除多条记录的方法
- 使用Git将我的最后一个X提交一起压缩
- mac 苹果多版本jdk自由切换
- 文件服务器和客户模式有什么区别,客户端和服务器端编程有什么区别?
- Mysql JDBC 连接串参数说明
- 地铁上怎么那么多钢管女郎?
- Spark源码分析之DiskBlockMangaer分析
- 解决tomcat在idea控制台乱码
- 计算机团队霸气名称大全,霸气吃鸡游戏团队名字大全
- HZOI20190903模拟36 字符,蛋糕,游戏
- 互联网周刊:深度分析云计算
- 如何给135编辑器推文添加附件
- 达达-京东到家完成新一轮5亿美金融资,沃尔玛、京东分别增持
- android根文件系统目录结构
- 解读人工智能的2021:回顾那些激动人心的重大突破
- msysgit - Windows Git安装配置
- 计算机动画主要学什么,动画专业主要学什么?
- ExecuteScaler的三种返回值
- 在线制作html邮件,HTML邮件设计注意点
热门文章
- QCD-品质、成本、交付
- 计算机app无法删除,电脑出现删除不了软件怎么处理?已经用了腾讯安全管家还是删不干净?...
- mendeley云端容量_除了Endnote,Mendeley也是你值得拥有的文献管理器
- 高等数学(第七版)同济大学 习题3-4 个人解答(后8题)
- 镜头C接口和CS接口的简单区分
- 愿自己余生不再焦虑慌张
- latex 排版笔记
- <Linux开发>驱动开发 -之-platform 驱动
- 线性代数笔记22——特征值和特征向量
- POC [Proof of Concept] 原型 / 概念证明