作者微信:15013593099 欢迎交流
本文的综合介绍了基于Xen3.2(2008年1月)的Xen体系结构,更详尽的描述请参考Xen books。Xen组成要素
一个Xen虚拟化环境由以下部件构成:
- Xen Hypervisor
- Domain 0
- Domain管理和控制工具
- Domain U PV客户系统
- Domain U HVM客户系统
下图是对这些部件组织结构的描述:
Xen Hypervisor
Xen Hypervisor是一个介于硬件和操作系统之间的软件层,它负责在各虚拟机之间进行CPU调度和内存分配(partitioning)。Xen Hypervisor不仅抽象出硬件层,同时控制虚拟机的执行,因为这些虚拟机共享同一个处理环境。Xen Hypervisor不会处理网络、存储设备、视频以及其他I/O。
Domain 0
Domain 0是一个修改过的Linux kernel,是唯一(?)运行在Xen Hypervisor之上的虚拟机,它拥有访问物理I/O资源的权限,同时和系统上运行的其他虚拟机进行交互。Domain 0需要在其它Domain启动之前启动。
Domain 0中包含两个驱动:Network Backend Driver和Block Backend Driver,分别负责处理来自Domain U的网络和本地磁盘请求。Network Backend Driver直接和本地网络硬件进行通信以处理所有来自Domain U上客户操作系统的网络请求。Block Backend Driver和本地存储设备进行通信以处理来自Domain U的读写请求。
Domain U
运行在Xen Hypervisor上的所有半虚拟化(paravirtualized)虚拟机被称为“Domain U PV Guests”,其上运行着被修改过内核的操作系统,如Linux、Solaris、FreeBSD等其它UNIX操作系统。所有的全虚拟化虚拟机被称为 “Domain U HVM Guests”,其上运行着不用修改内核的操作系统,如Windows等。
Domain U PV Guests的内核知道它自己不能直接访问物理硬件,因为他知道有其他的虚拟机也运行在同一个环境中。而Domain U HVM Guests的内核不知道他正在和其他虚拟机共享一个处理环境,它认为它运转在物理硬件上。
Domain U PV Guests包含两个驱动:“PV Network Driver”和“PV Block Driver”。
Domain U HVM Guests虚拟机内没有PV Driver,而是在Domain 0里为每一个HVM Guest启动一个特殊守护进程:Qemu-dm,由Qemu-dm负责客户操作系统的网络和磁盘请求。
Domain U HVM Guests必须进行初始化为某类机器,所以要在Domain U上附加一个软件:Xen虚拟固件,来模拟BIOS。关于Xen虚拟化固件的更多信息请参考后面的内容。
域(Domain)管理和控制
开源社区提供了一系列的域管理和控制工具(Linux守护程序)。这些服务运行在Domain 0,他们支持所有对虚拟化环境的管理和控制,下面的几个图中为了更清楚的说明将这些守护进程画在了Domain 0的外部。
Xend
Xend是一个python应用程序,它是Xen虚拟化环境的系统管理工具。它通过对libxenctrl库的调用实现对Xen Hypervisor的请求。Xend处理的所有请求都是通过Xm工具提供的XML RPC接口提交的,见下图。
Xm
Xm是一个命令行工具,它接受用户的输入并把指令通过XML RPC传输给Xend。
Xenstored
Xenstored维护一个信息档案,包括内存和建立在Domain 0与Domain U之间的事件通道。Domain 0通过改变这个档案来设置和其他虚拟机的设备通道。(具体信息请参考Domain 0和Domain U的通信)
Libxenctrl
Libxenctrl是一个C语言的库,它为Xend提供与Xen Hypervisor通信的能力。privcmd是Domain 0中的一个特殊驱动,它负责提交请求到hypervisor。
Qemu-dm
每一个运行在Xen虚拟化环境下的HVM客户系统都有他自己的Qemu守护进程。该进程处理来自HVM客户系统的所有网络和磁盘请求,以支持Xen虚拟化 环境下的全虚拟化。Qemu必须存在于Xen hypervisor之外,因为它需要访问网络和I/O设备,所以他运行在Domain 0 。
现在已经有一个新的工具来代替Qemu对HVM客户系统的支持,这就是Stub-dm(!!)。它是为Xen的将来版本开发的,Xen3.2还不具备该特性,可能发布在Xen3.3中。
Xen虚拟化固件
Xen虚拟化固件是一个虚拟的BIOS,它被加载到每一个Domain U HVM Guest以提供标准的启动指令,保证客户操作系统在正常启动过程中能得到标准的PC兼容的软件环境。
这部分描述一个半虚拟化的Domain U如何通过Xen hypervisor、Domain 0 与外部的网络以及存储进行通信的。
Domain 0与Domain U的通信
前面讲到过,Xen Hypervisor不会支持网络和磁盘请求的,因此一个PV客户系统必须通过和Xen Hypervisor、Domain 0通信,来实现网络和磁盘请求。下面这个例子描述了PV客户系统如何将一个数据写到本地硬盘。
PV客户系统的开设备驱动程序接收到一个写请求,并且通过Xen Hypervisor写数据到适当的本地内存中,该内存是和Domain 0共享的。在Domain 0 和Domain U之间存在一个事件通道(event channel),通过该通道二者进行异步的域间中断通信。Domain 0会接收到一个来自Xen Hypervisor的中断,触发PV Block Backend Driver访问上述的内存,读取来自PV客户系统的数据,然后将这些数据写入硬件磁盘。
下图中事件通道表示为连接Domain 0与Domain U的一个区域,这是系统工作流的一个简化。事实上事件通道运行在Xen Hypervisor,通过Xenstored中的特定中断实现,提供Domain 0与Domain U之间的快速共享内存。
见下图。
术语表
C: http://www.cprogramming.com/; a computer programming language
Daemons: http://en.wikipedia.org/wiki/Daemon_(computer_software); a program running in the background rather than under direct control of a user
Driver: http://en.wikipedia.org/wiki/Device_driver; program allowing software to interact with hardware
Full Virtualization: http://en.wikipedia.org/wiki/Full_virtualization; a virtual machine not aware of its virtualization
Interrupt: http://en.wikipedia.org/wiki/Interrupt; signal from hardware to software requesting a specific action in software
Kernel: http://en.wikipedia.org/wiki/Linux_kernel; the central component of a computer operating system
Paravirtualized: http://en.wikipedia.org/wiki/Paravirtualization; virtual machine running on a hypervisor that is aware of it being virtualized]
Python: http://www.python.org/; a dynamic object oriented programming language
ROM BIOS: http://en.wikipedia.org/wiki/BIOS; software instructions run on a machine when turned on
XML PRC: http://www.xmlrpc.com/; method for an application to leverage another application using HTTP for the remote procedure call and XML as the encoding
一、 Xen 的整体架构和整体设计
1.Xen的整体架构如图:
(Domain 0) Domain 1
图1 Xen 架构
从图中可以看到,VMM介于硬件和虚拟机之间,截获虚拟机的特权指令并代替它们执行。VMM同时提供Domain间的共享内存和事件通道。 有一个特殊的虚拟机VM0(又称Domain0)运行着Linux,其主要作用是完成VM的创建、管理、配置等工作,并完成设备驱动。其他VM访问设备时,Xen获得该请求,然后将其转交给Domain0;当Domain0 完成请求的操作后,Xen再将结果返回给VM。这种做法的好处是Xen可以利用Linux中已有的驱动,不用在重新开发驱动了。
2. Xen的泛虚拟化设计:
Xen采用的泛虚拟化技术需要对Guest OS进行相应修改。 IA-32平台上Xen的泛虚拟化技术如下:
1)Guest OS使用特权指令的地方要修改为调用Xen提供的API:hypercalls。
2)硬件中断被轻量级的事件机制取代;对于异常,Guest OS要调用hypercalls来注册自己的异常处理函数。
陷阱的处理程序是注册到VMM上的,而不是直接注册到虚拟CPU上的,这样就节省了一步操作,否则要先引起虚拟硬件的陷阱,再由VMM处理。
系统调用注册到处理器。大多数操作系统中,系统调用是通过一个查找表和一个特殊的陷阱队列来处理的。虚拟化后,陷阱队列引起VMM的处理。而Xen跨过这个效率不高的一步,允许虚拟机上的操作系统直接将它们系统调用的处理绑定到处理器上,避免了VMM处理陷阱队列而进行上下文切换的开销。
3)修改内存管理机制:在每个Guest OS的虚拟内存空间保留64M给Xen,物理内存的申请和释放都要经过Xen。每个虚拟机可以对硬件页表进行只读访问,而更新页表的工作则由VMM完成。
4)修改I/O使用方法:Xen只提供给VM一些通用快速的设备,VM只能根据Xen定义的API来访问设备。
Xen的I/O模型如下图所示:
图2 Xen的I/O模型
Xen采用的是泛虚拟化技术,VM(也称为DomainU)的I/O操作不能直接通过自身的驱动程序访问硬件,而是要借助Domain0的驱动来访问。DomainU的I/O操作由两个主要的驱动模块来完成,即Fronten Driver和Backend Driver。Frontend Driver 位于Domain U中,负责接收Domainu的I/O请求,并把请求交给位于Domain 0的Backend Driver,随后由Backend Driver 调用Domain0中的相关驱动来处理,并把处理结果返回给Frontend,从而完成DomainU的一次I/O操作。
由于Frontend和Backend位于不同的OS中,它们之间的通信要依赖共享内存环和事件通道(Event Channel)来进行。通过共享内存环,Frontend和Backend可以把I/O请求放入环中和从环中读取,而I/O请求的处理结果也可以通过环进行传递。而Event Channel则允许Frontend 和Backend给对方发送一个确认信息。
l 控制面板:
控制面板(Control Panel)是Xen中的控制模块,是虚拟机运行的总控制台。所有Domain的创建、销毁、配置、迁移等工作都是在这里下达命令,然后在调用底层的具体函数具体实施。它是虚拟机的用户接口,用户通过向控制面板输入指令来同Hypervisor(VMM)以及设备模型(Device Model)打交道。控制面板在Xen中的架构图如下:
图1 控制面板的架构
由图可只,控制面板位于Domain0 中,Domain管理、设备管理、Guest管理、调度管理等都通过控制面板中的Xend实现。Xend是Control Panel中的核心部件,是Xen中的核心进程。其中Domain管理是Xend管理的中心。
Xend运行在具有特殊优先级的Domain0中,通过Domain0的内核调用底层API来与Hypervisor通信。Xend用HTTP协议来包装它的控制接口。由于大多数编程语言都具有HTTP函数库,所以该接口可被绝大多数流行语言所使用,如Python,C,Java等。Xend采用的是Python语言,这是一种解释型的面向对象语言,易开发,易调试,易扩展,易嵌入到C或C++语言程序项目中。Xend以及Xen中很多工具就是因为Python的这些优点而采用它作为上层实现语言。
Xend的用户接口就是Domain创建与管理的接口。它支持Domain的创建,关闭,重启,销毁,保存,恢复与迁移。
创建Domain时,Xend首先创建Domain的内存映象,与Device Model通信为该Domain配置虚拟设备,并在Domain0中为该Domain新建一个Device Model实例。当Domain关闭时,除非它在Domain0中的Device Model实例被释放,否则其内存映象不会被完全释放。为了防止在Xend重启时丢失配置信息,Xend为每个Domain维护了一个数据库,使得Xend在停止或重启的时候不用担心遗失配置信息,例如,当升级Xend的时候仍然可以保持其维护的Domain信息与未升级前一致。图3-4是Control Panel具体的实现模块。
图2 控制面板实现模块