基于Xen实现一种domain0和domainU的应用层数据交互高效机制
项目里有一个需求,domain0的应用层需要定时给domainU(hvm windows)的应用层传递一块数据,原来的方案是在domainU的应用层架设一个http服务器,监听在某个端口,然后需要塞数据时,domain0的应用程序连接该端口,并通过http send发送数据。发送完会等待domainU 的应用程序返回一个标记。
无意间看到这篇论文《全虚拟化HVM和半虚拟化PV虚拟平台通信机制分析》,里边介绍hvm情况下domainU与Doamin0用户层的数据交互机制,根据文章介绍,尝试设计一种交互方式: 1. domainU 里增加一个自定义驱动(叫datafront),该驱动对应用层提供接口,当应用层调用特定系统调用或函数时,datafront触发vmexit. 该vmexit对应hypervisor_callback会检测一片共享内存区,如果有特定数据就读取到domainU 应用层。2. domain0里修改应用层的 qemu-dm守护程序,或者自己写一个应用程序,当需要塞数据时,将数据写入共享页,然后发出事件通知。 大概的过程就是这样,具体系统后续再考虑。
参考:这里
全虚拟化HVM和半虚拟化PV虚拟平台通信机制分析
一.半虚拟化PV虚拟平台通信机制
由于基本上所有的设备驱动都假设自己可以直接访问硬件,同时对硬件拥有完全控制权。但在这虚拟机系统中是不可能的,一个设备通常要为多个Guest Domain服务。为了确保管理性和安全访问,Xen的设备虚拟化采用了分离式设备驱动模型。
当Guest Domain是一个准虚拟化的虚拟机时,虚拟机的内核是被修改过的,它知道自己不是运行在真实的硬件上。其设备是由Xen虚拟机出来的分离设备模型,要靠Frontend 和Backend协同工作来完成通信。分离式设备驱动模型如图示。
从图中可以看出,前端驱动(Frontend Driver)位于Guest Domain中,负责接收Guest Domain的I/O处理请求,传递给后端驱动(Backend Driver),并接受来自后端的处理结果返回给Guest Domain。后端驱动在Domain0中,负责接收来自前端的I/O处理请求,并把请求交给Domain0中的相关驱动来处理,随后把处理结果返回给Frontend。从而完成Guest Domain的I/O操作。
由于前端和后端位于不同的OS中,它们之间的通信要依赖共享内存环和事件通道来进行。共享环是由前端分配的一块共享内存,在前端和后端间共享。在ring上存在两对生产者消费者指针。通过共享内存环,前端和后端可以把I/O请求放入环中和从环中读取,而I/O请求的处理结果也可以通过环进行传递。事件通道则允许前端和后端发送给对方一个确认信息。
Xen采用了共享描述符环来实现上述工作,其原理如下图所示。

Guest Domain把数据传输的请求放到I/O环上并更新请求生产者指针;Xen取出请求并更新消费者指针。同样地,当Xen准备好响应数据后,也把一个描述符放到I/O环上并更新应答生产者指针;客户域取出应答交给应用程序并更新响应消费者指针。
需要注意的是,I/O环上的内容并不是共享数据的内容,而是共享数据所在的缓冲区的描述符,这是因为,对于高速DMA设备,用描述符是不合适的。真正的数据传递是借助Grant Table完成的。同时,这里不要求按顺序处理请求:
Guest OS给每个请求都建立了唯一的相关标识符,这个标识符会在相关的响应上被复制。描述符环只是限定了能够处理请求的规模,并不规定处理顺序,谁先被处理谁后被处理是在将数据映射到描述符环上的时候决定的,这就允许Xen出于调度和优先级的考虑,重新排定I/O操作的顺序。Xen使用事件通道作为有I/O描述符进入队列的异步通知,不管是request请求还是response都可以在同时放入多个描述符项,达到一定的阀值后才发送事件通知。
下图详细展示了在Xen虚拟机系统上,两个准虚拟化的Guest, Domain1和Domain2之间是如何进行通信的。当Domain1中的应用程序App1要向Domain2中的应用程序App2发送数据包时,它按照如下的步骤完成:
1. Domain2首先调用send(),将自己用户空间的数据拷贝到内核空间;
2. Domain2的前端将发送请求放到共享环上,通过更新生产者共享指针完成;
3. 前端将会通过事件通道向Domain0发出一个事件(更新,该事件触发Back-end去获得包含了App1数据的页;back-end读取请求,获得页的物理地址,并发送到响应的Driver;
4. Xen将Domain2的请求移出共享描述符环,并移动请求消费者指针,同时调度Domain1;
5. Domain1中的前端在IO环中用一个指向Grant table中空闲页的指针填上接收请求;
6. 当back-end接收到数据报时,它首先检查该数据报属于谁,然后从IO环中移出接收请求,同时从grant table中获取空闲页,然后将空闲页和数据页交换,并通过Event channel发出接收事件;
7. 前端通知内核,App2接收数据。

二、Guest Domain是全虚拟化的虚拟机
当Guest Domian是全虚拟化的虚拟机时,Xen 为它模拟了与真实机器完全一样的抽象平台,Guest Domain不知道自己运行在Hypervisor上。但是,由于硬件虚拟化技术的引入,例如,在VT-x的CPU上,当虚拟机控制结构VMCS(Virtual Machine Control Structure)结构体中定义的那些事件被触发时,就会发生VMExit,从非根状态切换到根状态,导致陷入到Hypervisor中,Guest Domain被切换出去。
VMCS结构包含以下6个组成部分:客户状态域,主机状态域,虚拟机执行控制域,VMExit控制域,VMEntry控制域以及VMExit信息域。虚拟机监控器主要通过配置虚拟机执行控制域来控制虚拟机在非根环境下的执行行为。通过设置虚拟机执行控制域,VMM可以对不同VM的VMCS 分别设置不同虚拟机退出条件,从而实现对不同VM的不同虚拟化策略。
如下图所示,一个全虚拟化的虚拟机要想另外一个目标机器发送数据时,其流程如下:
1. Guest Domain中的内核执行In/Out指令触发VMExit,处理器调用Hypervisor设置的VMExit的处理函数。
2. Hypervisor将I/O指令的具体信息写入DomainU的DM共享的一页I/O共享页中,并通过事件通道通知Domain0,接着Hypervisor阻塞该虚拟机,并调用调度算法。
3. Hypervisor恢复Domain0的状态,并把执行控制交给Domain0。
4. Domain0中首先被执行的是注册的回调函数hypervisor_callback,它再调用evtchn_do_upcall。
5. evtchn_do_upcall里收集有哪些虚拟机有多少I/O请求。
6. 执行控制从Xen0的内核态返回用户程序态。DM本来通过一条select系统调用等待I/O请求,此时得到调度后的DM一旦等到请求到来就返回。
7. 通过读取I/O共享页,DM识别是对哪类外设的访问,调用对应虚拟外设初始化时的回调函数。
8. 根据不同的请求,虚拟外设的回调函数或者只是把虚拟外设的状态写回I/O共享页中,或者发生一次真正的数据拷贝。最后DM仍通过事件通道机制通知Hypervisor处理完毕。
9. Hypervisor得到通知后,解除对应的请求I/O的Guest Domain的阻塞。
未来某一时刻,该Guest Domain就可以再次被调度到,继续运行了。上述整个流程如下图所示:

基于Xen实现一种domain0和domainU的应用层数据交互高效机制的更多相关文章
- 基于Xen实现一种domain0和domainU的应用层数据交互高效机制 - 2
继续昨天的思路,今天先google了类似的实现domain0和domainU之间数据传输的方案 [Xen-devel] XenStore as a data transfer path? 这篇帖子讨 ...
- 基于Xen实现一种domain0和domainU的应用层数据交互高效机制 - 3
继续 上一篇 的研究,结合 xen4.2.3 的代码分析,发现 xen4.2.3 的应用层工具库 tools 包含一个工具叫 libvchan ,其头文件描述如下: * This is a libra ...
- html5-websocket实现基于远程方法调用的数据交互
html5-websocket实现基于远程方法调用的数据交互 一般在传统网页中注册用户信息都是通过post或ajax提交到页面处理,到了HTML5后我们有另一种方法就是通过websocket进行数 ...
- 【腾讯Bugly干货分享】基于RxJava的一种MVP实现
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57bfef673c1174283d60bac0 Dev Club 是一个交流移动 ...
- 基于MVC4+EasyUI的Web开发框架经验总结(12)--利用Jquery处理数据交互的几种方式
在基于MVC4+EasyUI的Web开发框架里面,大量采用了Jquery的方法,对数据进行请求或者提交,方便页面和服务器后端进行数据的交互处理.本文主要介绍利用Jquery处理数据交互的几种方式,包括 ...
- Android上掌纹识别第一步:基于OpenCV的6种肤色分割 源码和效果图
Android上掌纹识别第一步:基于OpenCV的6种肤色分割 源码和效果图 分类: OpenCV图像处理2013-02-21 21:35 6459人阅读 评论(8) 收藏 举报 原文链接 ht ...
- Spring WebFlux, 它是一种异步的, 非阻塞的, 支持背压(Back pressure)机制的Web 开发WebFlux 支持两种编程风(姿)格(势) 使用@Controller这种基于注解
概述 什么是 Spring WebFlux, 它是一种异步的, 非阻塞的, 支持背压(Back pressure)机制的Web 开发框架. 要深入了解 Spring WebFlux, 首先要了知道 R ...
- 基于Redis的三种分布式爬虫策略
前言: 爬虫是偏IO型的任务,分布式爬虫的实现难度比分布式计算和分布式存储简单得多. 个人以为分布式爬虫需要考虑的点主要有以下几个: 爬虫任务的统一调度 爬虫任务的统一去重 存储问题 速度问题 足够“ ...
- (转)基于MVC4+EasyUI的Web开发框架经验总结(12)--利用Jquery处理数据交互的几种方式
http://www.cnblogs.com/wuhuacong/p/4085682.html 在基于MVC4+EasyUI的Web开发框架里面,大量采用了Jquery的方法,对数据进行请求或者提交, ...
随机推荐
- spring源码学习中的知识点
一.循环依赖 循环依赖就是循环引用,就是两个或多个bean之间互相持有对方. 1.构造器循环依赖 表示通过构造器注入造成的循环依赖,此依赖是无法解决的,只能抛出BeanCurrentlyInCreat ...
- win32 signal
Remarks The signal function enables a process to choose one of several ways to handle an interrupt ...
- Python利器一之requests
Python利器一之requests 一.教程涉及开发语言.脚本.框架.数据库等内容 Python + requests 通过 pip 安装: pip install requests 通过 easy ...
- Python面试题(练习三)
1.MySQL索引种类 1.普通索引 2.唯一索引 3.主键索引 4.组合索引 5.全文索引 2.索引在什么情况下遵循最左前缀的规则? 最左前缀原理的一部分,索引index1:(a,b,c),只会走a ...
- Oracle数据库存量数据抽取使用spool控制命令
spool是oracle sqlplus提供的一个控制命令.可以利用spool和select语句的组合动态生成一些失去了脚本或者一些数据. 1.spool作用: 在sqlplus中用来保存或打印查询 ...
- Megacli查看Dell服务器Raid状态
通常我们使用的DELL/HP/IBM三家的机架式PC级服务器阵列卡是从LSI的卡OEM出来的,DELL和IBM两家的阵列卡原生程度较高,没有做太多封装,可以用原厂提供的阵列卡管理工具进行监控:而HP的 ...
- Java TCP通信概念及实例
TCP/UDP 协议 通俗解释: TCP协议和UDP协议的区别类似于电话系统和邮政系统. <1>TCP:类似于电话系统,建立双向的通信通道,确定连接,话音顺序接听. <2>UD ...
- c++ 2.1 编译器何时创建默认构造函数
我们通常会说当生命一个 class 时,如果我们不为该 class 指定一个 constructor,那么编译器会替我们实现一个 connstructor,那么这种说法一定对吗? 事实上,这是不对的. ...
- 使用百度Echarts制作力导向图
最近项目需求制作一个力导向图来展示企业的画像等关系信息,故想到了百度Echarts的关系图,在这使用Echarts3.0版本来实现.先上效果图,再看代吗 哎,本来想整个工程扔出来,发现好像没地方上传附 ...
- easyui中datagrid空数据集不刷新的解决方式
datagrid空间可以异步请求json数据,并将新数据覆盖原有数据,重绘数据表. 但是当回来空数据集的时候,js会产生这样一条错误: TypeError: rows is null for(var ...