CPU虚拟化
XenMon工作机制
一、 背景:
XenMon是一个支持资源分配和功能配置部件,它可以精确地监视和展现分析结果的基础部件,它报告在不同VMs资源利用率,而且还提供一个对Xen的共享内部资源接口和资源安排。
以下为XenMon的架构图:
Xenbaked 是一个高度可配置的模块,它能让用户配置多久记录一帧,保存多久的历史记录。
Xenmon frontend 是作为前段应用,它是基于xentrace事件产生器的数据收集收集到的数据进行展示。
Xentrace是事件触发器,其机制在之后会介绍。
二、 xentrace机制:
Xentrace 是以共享内存的方式来进行操作的,内核部分对Xen中的一些系统调用函数都会对这片共享内存进行写入。在用户区,用户通过一些方法得到共享内存内的数据,并对其进行解析并显示,以下是xentrace工作机制的流程图:
三、 t_buf结构:
在xentrace的代码中会经常发现t_buf这个结构体:
Struct t_buf{
unsigned long cons;
unsigned long prod;
};
这个结构提记录的生产者和消费者的位置指针,而且它还是一个环状结构的共享内存,在代码中不难发现生产者和消费者的地址不是无限增大的,它是有一定大小的限制。
此处讨论的t_buf只是单纯的结构体,而环形缓存的结构大小是由t_buf结构体占用的空间和t_buf中消费者和生产者指针指向的地址data区所占用空间的总和。
四、 t_rec结构:
struct t_rec {
uint32_t event:28; //事件的宏定义,在处理的时候根据宏定义来处理响应的函数
uint32_t extra_u32:3; /* # entries in trailing extra_u32[] array */
uint32_t cycles_included:1; /* u.cycles or u.no_cycles?是否是cycles方式 */
union {
struct {
uint32_t cycles_lo, cycles_hi; /* cycle counter timestamp */
uint32_t extra_u32[7]; /* event data items */
} cycles;
struct {
uint32_t extra_u32[7]; /* event data items */
} nocycles;
} u;
}
t_rec结构是t_buf映射到用户区的内存空间,同样也是一个环状结构的缓存。从t_rec的结构上,可以得到事件类型等信息,然后在对这些事件进行处理。
Xen 源码编译安装总结
关于Xen的源码编译安装文章网上也比较多,我主要从我的实验经历对其进行总结。
- 下载xen和hg源码包。
先从http://xen.org 上下载两个源码包,xen源码和linux的hg文件,本文讨论xen3.3和xen3.4的情况,下面以xen3.tar.gz和linux-2.6.18-xen3.hg为例说明,必要时再做区分 - 依赖包安装
tar xvf xen3.tar.gz 解压下载的文件,并仔细阅读目录下的README文件,打开README文件可以查看安装Xen前必须安装的软件包
* GCC v3.4 or later
* GNU Make
* GNU Binutils
* Development install of zlib (e.g., zlib -dev)
* Development install of Python v2.3 or later (e.g., python-dev)
* Development install of curses (e.g., libncurses -dev)
* Development install of openssl (e.g., openssl -dev)
* Development install of x11 (e.g. xorg-x11-dev)
* bridge-utils package (/sbin/brctl )
* iproute package (/sbin/ip )
* hotplug or udev
进入xen3.3.1/tools/check目录,运行./chk build命令,可查看目前这些必需的软件包的安装状态。
对于这些安装包的补充安装,方法有很多,Linux的发行版本可以大体分为两类,一类是商业公司维护的发行版本,一类是社区组织维护的发行版本,前者以著名的Redhat(RHEL)为代表,后者以Debian为代表。两者方法总结如下:RHEL的包安装
对于RHEL的用户,可直接采用光盘镜像做源的方法,光盘中包括所有需要包,其他用户则可以利用yum在网上下载.yum的配置比较简单,在google中搜索“RHEL yum 源”即可找到网络软件仓库、以及光盘镜像做源的方法。做源的好处在于以后缺什么包或软件可以直接用yum来安装。当然如果不想配置yum源,你可以直接将ISO mount 上linux,进入光盘中的Server文件,在该文件下,可以用 rpm –a|grep openssl 进行相关包的查询,再用rpm –ivh xxx.rpm 对相关的包进行安装,其中特别注意x11包的名字是以libX11开头的。Debian的包安装
对于debian用户而言,配置apt-get的方法,在网上也可以找到响应版本最新的源,根据自己的网络条件进行选择。用ISO做源的方法网上也可以查到。
除此之外,虽然我们以及手动下载了hg文件,但是由于在makefile文件中会调用hg命令做些其他的下载和检查工作,因此还必须安装mercurial,如果上面的yum和apt-get配置好了,则可以直接进行安装即可,若没有配置好源,则可以下载mercurial的源码包自己参照其中的README进行源码安装.最后./chk build全部OK后才能进入下一步安装。 - 上面的准备工作弄好后,关键的步骤就是hg文件的放置位置和相关文件的配置方法
对于xen3.3的版本,直接将hg文件加压到xen3.3的统计目录即可,但是该方法对于xen3.4无效,需要执行如下修
vim buildconfigs/src.hg-clone
去掉hg同步linux内核源码的步骤,如下:
—————————————————————-
# Mercurial
HG ?= hg
LINUX_SRCDIR ?= linux-$(LINUX_VER)-xen.hg
# Repository to clone.
XEN_LINUX_HGREPO ?= $$(sh buildconfigs/select-repository $(LINUX_SRCDIR) $(LINUX_SRC_PATH))
# Set XEN_LINUX_HGREV to update to a particlar revision.
XEN_LINUX_HGREV ?= tip
$(LINUX_SRCDIR)/.valid-src: $(__XEN_LINUX_UPDATE)
set -e ; \
touch $@
—————————————————————-
然后将hg的文件夹拷贝到xen代码的根目录中即可。
- 对编译进行相关配置
make linux-2.6-xen-config CONFIGMODE=menuconfig,这个依据你对xen编译实验的要求进行相关配置,编入内核或是编程模块,比如有些研究xenprof的需要在对oprofile执行./configure命令后在xen的配置中加入内核oprofile选项,相关配置和使用文章我将在后期文章中加上。
- 开始编译模块
特别的,对于stubdom的相关设置,网络条件好则不用担心,但是不好则要预先做些设置和下载。
如果不需要研究stubdom,则直接修改xen目录下的Makefile文件,删掉stubdom相关内容,不影响xen的使用.
在18行(.PHONY: install的下一行反正)把install-stubdom删掉
在40行(.PHONY: dist的下两行,恩)把dist-stubdom删掉
而对于需要stubdom做研究的同志,则需要事先从网站上准备以下软件包:
fuse-2.8.3.tar.gz || grub-0.97.tar.gz || lwip-1.3.0.tar.gz || newlib-1.16.0.tar.gz || pciutils-2.2.9.tar.bz2 || zlib-1.2.3.tar.gz
将这些软件包放到studom文件下,但是特别注意不要执行make world,因为它会执行clean操作使得刚刚拷贝的包删除。推荐使用make dist开始编译,编译时间依机器不同而不同,通常可以使用make dist -j8进行多线程编译,这里8是线程数可以自己设定,有些会在complier.h找不到等错误,或是文档安装需要额外的包,但是不会这些都是不会影响Xen的正常编译和使用。
- make install进行模块安装,生成vmlinz
这一步比较快,会在boot目录下生成一个gzip压缩并包含启动ELF头的vmlinz文件,同时还会生成一个未压缩的vmlinux文件在/lib/modules/2.6.18.8-xen/build,即内核文件,其中未压缩的vmlinux文件在以后的oprofile的测试中–vmlinux选项中可以使用,这里要略微提一下网上关于用gzip解压vmlinz生成vmlinux的做法是不必要且不对的,经比较原生的vmlinux比经解压缩的要大,至于损失哪些信息我还没有做深入的研究。也许你会问,到这一步不是已经编译成功了吗?这里补充说明一下vmlinz和initrd的关系。vmlinuz自然就是内核了,initrd.img是一个小的映象,包含一个最小的linux系统。通常的步骤是先启动内核,然后内核挂载 initrd.img,并执行里面的脚本来进一步挂载各种各样的模块,然后发现真正的root分区,挂载并执行/sbin/init… …。
initrd.img当然是可选的了,如果没有initrd.img,内核就试图直接挂载root分区。
之所以要有initrd,那是为了启动的时候有更大的灵活性。比如,你把ext3支持编译成模块了。偏偏你的root分区又是ext3的。这下就麻烦了。因为内核需要挂载root分区之后才能加载ext3支持。但是没有ext3支持就没法挂载root分区。initrd就是用来解决这个问题的。
类似的用这个东西还可以做其他的事情,比如从usb盘启动linux也会面临上面类似的问题。用initrd就能搞定了。
甚至,我想在有些嵌入式设备里面都不需要真正的root分区,用initrd就足够搞定一切了。主要是为了解决vmlinuz太大的问题,用initrd可以解决这个问题。否则的话在2.6的内核中启动会失败的
- initrd映像制作,安装xen README文件的说法,经测试主要包括以下两种情
对于RHEL等商业公司维护的发行版本来说,多采用如下方式进行
Depending on your config, you may need to use ‘mkinitrd’ to create
an initial ram disk, just like a native system e.g.
# depmod 2.6.18-xen
# mkinitrd -v -f –with=aacraid –with=sd_mod –with=scsi_mod initrd-2.6.18-xen.img 2.6.18-xen
而对于debian平台的用户来说,如ubuntu则一般采用如下方式进行
Other systems may requires the use of ‘mkinitramfs’ to create the
ram disk.
# depmod 2.6.18-xen
# mkinitramfs -o initrd-2.6.18-xen.img 2.6.18-xen
这一步中通常依据机器不同,出现不同的出错,对于缺失的模块可以加上—allow-missing 选项,而对于其他错误这里不一一列举,则用户最好在网上搜一下,一般都会有合适的解决方案 - Grub启动项的制作
特别的,如下面的形式,通常只有kernel和initrid的两项,在xen的启动中,xen.gz作为内核会先启动,随后才是原来的vmlinuz和initrd皆以模块形式加载,如下为grub 2以前的启动方式,在/boot/menu.lst(或者grub.conf)中加上
title Xen 3.4 / XenLinux 2.6
kernel /boot/xen-3.4.gz console=vga
module /boot/vmlinuz-2.6-xen root=<root-dev> ro console=tty0
module /boot/initrd-2.6-xen.img
而对于当前新的grub 2方式,我们会发现,这些命令失效了,在grub2中,会修改/boot/grub/grub.cfg文件,便将其中的原来一项linux启动项复制,并将原来的linux 和initrd命令,替换为
multiboot /boot/xen-3.4.gz console=vga
module /boot/vmlinuz-2.6-xen root=<root-dev> ro console=tty0
module /boot/initrd-2.6-xen.img
至此,整个xen源码编译的过程就结束了,你可以进行重启了,通常如果上述过程中没有出现错误,则会正常启动,如出现mount找不到文件等等,一般是grub中的路径写错了,而如果是kernel panic 错误,则可以先尝试在第7步中用一下其他的配置选项,如果还不行,建议重新检查本文之前的步骤是否有错误未处理,特别是编译的过程。