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


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

    *  This is a library for inter-domain communication.  A standard Xen ring
     34  *  buffer is used, with a datagram-based interface built on top.  The grant
     35  *  reference and event channels are shared in XenStore under the path
     36  *  /local/domain/<srv-id>/data/vchan/<cli-id>/<port>/{ring-ref,event-channel}

    说明这个库是用于domain间交互数据用的,其控制信息放在 xenstore里。 下面就是基于这个库,我在两台 centos domain 之间的实验。

    需要的文件:

     CentOS-6.2-x86_64-minimal.iso  : centos minimal iso 镜像

     kernel-3.10.20-11.el6.centos.alt.x86_64.rpm  :  xen4centos6 项目 维护的rpm包,这些rpm包已经配置为可以用作 xen domain0

    domain0 : 先用 minimal 的 iso 安装系统,然后用 xen4centos6 项目的内核rpm包安装第二个内核,并重启为xen内核,作为domain0

    domainU : 先用 minimal 的 iso 安装系统到 qcow2 文件,然后用 xen4centos6 项目的内核rpm包安装第二个内核,并重启3.10.20的内核

    需要的配置:

    domain0 重启为xen内核,grub.conf  配置如下:

    title CentOS (3.10.20-11.el6.centos.alt.x86_64)
            root (hd0,0)
            kernel /xen.gz dom0_mem=57679020 loglvl=all guest_loglvl=all dom0_max_vcpus=12 dom0_vcpus_pin
            module /vmlinuz-3.10.20-11.el6.centos.alt.x86_64 ro root=/dev/mapper/VolGroup00-LogVol--ROOT rd_NO_LUKS rd_LVM_LV=VolGroup00/LogVol-ROOT rd_LVM_LV=VolGroup00/LogVol-SWAP rd_NO_MD quiet SYSFONT=latarcyrheb-sun16 rhgb crashkernel=auto  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM LANG=en_US.UTF-8
            module /initramfs-3.10.20-11.el6.centos.alt.x86_64.img

    然后配置http服务器,domainU 通过wget 从domainO 获取需要的文件。

    domainU 重启为kernel3.10.20 后,需要做下面的配置:

    modprobe xenfs 
    modprobe xen_gntdev 
    modprobe xen_evtchn 
    modprobe xen_privcmd 
    modprobe xen_gntalloc

    安装的几个驱动为应用层提供libvchan需要的内核接口

    代码的修改:

    tools/libvchan/init.c: init_xs_srv 函数,修改如下:

    #if 0
            domid_str = xs_read(xs, 0, "domid", NULL);
            domid_str = xs_read(xs, 0, buf, NULL);
            printf("%s:%d,domid=%s
    ",__func__,__LINE__,domid_str);
            if (!domid_str)
                    goto fail_xs_open;
            // owner domain is us
            perms[0].id = atoi(domid_str);
    #endif
            perms[0].id = 0;

    这是因为在我的测试里,

    domid_str = xs_read(xs, 0, "domid", NULL); 这句会失败,其读xenstore的domid节点,会找不到节点。所以我直接将 perms[0].id 写死为 0, 这样 vchan_node/vchan_node2 测试例子的server 端只能用 domain0

    接下去我新建了一个目录 tools/test-vchan , 然后执行下面的脚本,将需要的头文件和测试文件拷贝进来,并建立静态库的软连接,之所以要这么搞,主要是想静态编译 xc 库, xs 库 , vchan库
    到测试代码,这样修改调试的时候不需要每次都拷贝一堆so文件,只需要拷贝最终的可执行文件即可
    mkdir lib
    ln -s ../libxc/libxenctrl.a lib/libxenctrl.a
    ln -s ../xenstore/libxenstore.a lib/libxenstore.a
    ln -s ../libvchan/libxenvchan.a lib/libxenvchan.a
    
    mkdir include
    ln -s ../include/xen include/xen
    cp ../libvchan/libxenvchan.h include/
    cp ../xenstore/xenstore.h include/
    cp ../xenstore/xenstore_lib.h include/
    cp ../libxc/xenctrl.h include/
    
    cp ../libvchan/node-select.c .
    cp ../libvchan/node.c .

    tools/test-vchan 的 Makefile 文件如下:
     1 all:
      2         gcc -o vchan-node1 node.c -L./lib -I./include -lxenvchan -lxenstore -lxenctrl -lpthread -ldl
      3         gcc -o vchan-node2 node-select.c -L./lib -I./include -lxenvchan -lxenstore -lxenctrl -lpthread -ldl5 clean:
      6         rm -f vchan-node1 
      7         rm -f vchan-node2 

    执行 make 之后生成 vchan-node2. 将 vchan-node2 拷贝到 doman0,将 vchan-node2 和 xenctrl_osdep_linux.so ,libxenctrl.so 两个动态库拷贝到 domainU ,libxenctrl.so 库提供操作xen hypervisor的接口,xenctrl_osdep_linux.so这是linux平台相关的操作接口。然后 domainU 执行 vchan-node2 之前需要设置环境变量

    export XENSTORED_PATH="/dev/xen/xenbus"
    export XENCTRL_OSDEP="/usr/lib64/xenctrl_osdep_linux.so"

    domain0 启动为 server , 它会映射内存,并将共享内存的引用信息记录在xenstore , 然后监听 eventchannel , 如果有client发来的数据,则打印出来

    domainU 启动为 client, 它从Xenstore得到共享内存的引用信息,mmap共享内存,然后往内存里写入数据


    至此,一个基于libvchan的 inter-domain (domain is linux)数据交互例子就完成了。
  • 相关阅读:
    演示stop暴力停止线程导致数据不一致的问题,但是有些有趣的发现 (2017-07-03 21:25)
    Fragment的startActivityForResult和Activity的startActivityForResult的区别
    Maven实战(七)settings.xml相关配置
    vue-cli脚手架引入element UI的正确打开方式
    node起server--axios做前端请求----进行CORS--跨域请求
    ES6 promise简单实现
    实现一个简单的订阅与发布模式的代码块,和redux
    git使用笔记
    用yeoman搭建react画廊项目笔记
    npm包管理器小节一下
  • 原文地址:https://www.cnblogs.com/jiayy/p/3832593.html
Copyright © 2020-2023  润新知