项目里有一个需求,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的应用层数据交互高效机制的更多相关文章

  1. 基于Xen实现一种domain0和domainU的应用层数据交互高效机制 - 2

    继续昨天的思路,今天先google了类似的实现domain0和domainU之间数据传输的方案 [Xen-devel] XenStore as a data transfer path?  这篇帖子讨 ...

  2. 基于Xen实现一种domain0和domainU的应用层数据交互高效机制 - 3

    继续 上一篇 的研究,结合 xen4.2.3 的代码分析,发现 xen4.2.3 的应用层工具库 tools 包含一个工具叫 libvchan ,其头文件描述如下: * This is a libra ...

  3. html5-websocket实现基于远程方法调用的数据交互

    html5-websocket实现基于远程方法调用的数据交互   一般在传统网页中注册用户信息都是通过post或ajax提交到页面处理,到了HTML5后我们有另一种方法就是通过websocket进行数 ...

  4. 【腾讯Bugly干货分享】基于RxJava的一种MVP实现

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57bfef673c1174283d60bac0 Dev Club 是一个交流移动 ...

  5. 基于MVC4+EasyUI的Web开发框架经验总结(12)--利用Jquery处理数据交互的几种方式

    在基于MVC4+EasyUI的Web开发框架里面,大量采用了Jquery的方法,对数据进行请求或者提交,方便页面和服务器后端进行数据的交互处理.本文主要介绍利用Jquery处理数据交互的几种方式,包括 ...

  6. Android上掌纹识别第一步:基于OpenCV的6种肤色分割 源码和效果图

    Android上掌纹识别第一步:基于OpenCV的6种肤色分割 源码和效果图 分类: OpenCV图像处理2013-02-21 21:35 6459人阅读 评论(8) 收藏 举报   原文链接  ht ...

  7. Spring WebFlux, 它是一种异步的, 非阻塞的, 支持背压(Back pressure)机制的Web 开发WebFlux 支持两种编程风(姿)格(势) 使用@Controller这种基于注解

    概述 什么是 Spring WebFlux, 它是一种异步的, 非阻塞的, 支持背压(Back pressure)机制的Web 开发框架. 要深入了解 Spring WebFlux, 首先要了知道 R ...

  8. 基于Redis的三种分布式爬虫策略

    前言: 爬虫是偏IO型的任务,分布式爬虫的实现难度比分布式计算和分布式存储简单得多. 个人以为分布式爬虫需要考虑的点主要有以下几个: 爬虫任务的统一调度 爬虫任务的统一去重 存储问题 速度问题 足够“ ...

  9. (转)基于MVC4+EasyUI的Web开发框架经验总结(12)--利用Jquery处理数据交互的几种方式

    http://www.cnblogs.com/wuhuacong/p/4085682.html 在基于MVC4+EasyUI的Web开发框架里面,大量采用了Jquery的方法,对数据进行请求或者提交, ...

随机推荐

  1. [Codeforces967C]Stairs and Elevators(二分查找)

    [不稳定的传送门] Sloution 每次试一下最近的2个楼梯或者电梯就行了 Code #include <cstdio> #include <algorithm> #incl ...

  2. [Bzoj2246]迷宫探险(概率+DP)

    Description 题目链接 Solution 用三进制表示陷阱状态,1表示有害,2表示无害,0表示不知道 用\(f[S][i]\)表示状态为S时陷阱i有害的概率,这个可以预处理出 \(d[S][ ...

  3. 【文件处理】xml 文件 DOM解析

    一.Java解析xml.解析xml四种方法.DOM.SAX.JDOM.DOM4j.XPath 此文针对其中的DOM方法具体展开介绍及代码分析 sax.dom是两种对xml文档进行解析的方法(没有具体实 ...

  4. java练习——接口与继承

    父类与子类的构造方法: 如果父类中有一个默认无参的构造方法,那么子类的构造方法中会自动进行调用.如果父类有自己的构造方法,且这时父类没有默认无参的构造方法,那么在子类的构造方法中,必须要调用父类的某个 ...

  5. 网络策略中使用的 VLAN 属性

    TechNet 库 Windows Server Windows Server 2008 R2 und Windows Server 2008 按类别提供的 Windows Server 内容 Win ...

  6. 2016年后web开发趋势是什么?

    2016 年后 Web开发趋势是什么 来源:yafeilee.me 发布时间:2016-05-06 阅读次数:1378 3   近二年的进展 前端发展日新月异, 甚至有一句戏言: "每六星期 ...

  7. 《Cracking the Coding Interview》——第17章:普通题——题目7

    2014-04-28 23:28 题目:给定一个数字,用英语把它读出来. 解法:ZOJ上有相反的题目.如果我要用中文读书来呢? 代码: // 17.7 Read an integer in Engli ...

  8. 《Cracking the Coding Interview》——第9章:递归和动态规划——题目3

    2014-03-20 03:01 题目:给定一个已按升序排序的数组,找出是否有A[i] = i的情况出现. 解法1:如果元素不重复,是可以严格二分查找的. 代码: // 9.3 Given a uni ...

  9. ajax向Asp.NET后端传递数组型数据

    近日,在开发一个组件的过程中,需要通过Ajax对象向Asp.NET后端传递一个比较复杂的表单,表单中的一个字段是数组类型,我能想到的办法是用JSON.stringify将前端的数组对象序列化成字符串, ...

  10. python学习总结---函数使用 and 生成器

    # 函数使用 ### 生成器 - 使用场景 在使用列表时,很多时候我们不会一下子使用全部数据,通常都是一个一个使用,但是当数据量比较大的时候,定义一个大的列表将会是内容使用突然增大.为了解决此类问题, ...