基于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的方法,对数据进行请求或者提交, ...
随机推荐
- 使用postMan测试insert或者update接口
URL : http://localhost:8099/orderVoice/updateAgentLogin?access_token=7f10e803-f886-47df-b3dc-9ed307d ...
- 14、函数之匿名函数(lambda)
关键字lambda可以创建匿名函数,语法是:lambda 参数s :表达式.匿名函数与普通函数只有以下几点不同:①没有函数名:②只能有一个表达式:③一定会有返回值,返回值就是该表达式的结果. 另外,匿 ...
- 15.4,redis不重启,切换RDB备份到AOF备份
确保redis版本在2.2以上 [root@pyyuc /data ::]#redis-server -v Redis server v= sha=: malloc=jemalloc- bits= ...
- laravel5.5表单验证
1. 在第一次验证失败后停止 有时,你希望在某个属性第一次验证失败后停止运行验证规则.为了达到这个目的,附加 bail 规则到该属性: $this->validate($request, [ ' ...
- 腾讯装扮下拉选项卡特效(QQ空间)
<DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" ...
- css改变光标
<span style="cursor:auto"> Auto</span><br /> <span style="cursor ...
- 《Cracking the Coding Interview》——第1章:数组和字符串——题目1
2014-03-18 01:25 题目:给定一个字符串,判断其中是否有重复字母. 解法:对于可能有n种字符的字符集,用一个长度为n的数组统计每个字符的出现次数,大于1则表示有重复. 代码: // 1. ...
- 【java并发编程实战】第二章:对象的共享
1.重要的属性 可见性,不变性,原子性 1.1可见性 当一个线程修改某个对象状态的时候,我们希望其他线程也能看到发生后的变化. 在没有同步的情况下,编译器和处理器会对代码的执行顺序进行重排.以提高效率 ...
- Spring Boot多数据源配置(一)durid、mysql、jpa整合
目前在做一个统计项目.需要多数据源整合,其中包括mysql和mongo.本节先讲mysql.durid.jpa与spring-boot的整合. 引入Durid包 <dependency> ...
- 孤荷凌寒自学python第十天序列之字符串的常用方法
孤荷凌寒自学python第十天序列之字符串的常用方法 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) Python的字符串操作方法非常丰富,原生支持字符串的多种操作: 1 查找子字符串 str ...