zoukankan      html  css  js  c++  java
  • Virtio-vsock Device + aF_UNIX 套接字通信

    irtio是Linux虚拟机平台上统一的虚拟IO接口驱动。通常主机为了让客户机像在真实环境中一样运行,需要为客户机创建各式各样的虚拟设备,
    如磁盘,网卡,显卡,时钟,USB 等。这些虚拟设备大大降低了客户机的性能。使用virtio。虚拟机guest不用关注如何创建各种虚拟硬件设备
    (如磁盘,网卡,显卡等),可以用统一的虚拟设备,因此大大提高虚拟机的性能。这个统一的虚拟设备就是virtio。

    关于virtio原理以及在kvm和libvirt中的使用,可以参考:

    理解Virtio的原理:http://www.ibm.com/developerworks/cn/linux/l-virtio/

    Virtio在kvm中的使用:http://www.linux-kvm.org/page/Virtio

    Virtio在libvirt中的使用:http://wiki.libvirt.org/page/Virtio

    本文会侧重于virtio一个有趣的应用:如何使用virtio在虚拟机guest和主机host之间传递消息。这里的消息既包括控制指令,也包括文件传输(比如通过主机向虚拟机传递脚本的场景)。使用virtio传递消息有两点优势:

    1,对虚拟机和主机的网络设置没有任何要求

    2,效率更高

    使用virtio来传递消息的示意图为:



    以下看虚拟机和主机的相关程序如何构建

    1,通过libvirt在虚拟机创建时启动virtio通道

    以上图中启动两个virtio通道为例(数据通道和控制通道),libvirt启动配置xml中需要加入:

    <channel type=’unix’>
    
    <source mode=’bind’ path=’vm.ctl’/>
    
    <target type=’virtio’ address=’virtio-serial’ port=’0′/>
    
    </channel>
    
    <channel type=’unix’>
    
    <source mode=’bind’ path=’vm.data’/>
    
    <target type=’virtio’ address=’virtio-serial’ port=’1′/>
    
    </channel>
    
    <controller type=’virtio-serial’ index=’0′ ports=’16′/>




    1)vm.ctl与vm.data为两个virtio通道在主机本地的映射节点文件,主机应用可以基于这两个映射文件通过unix sock实现与虚拟机的通信

    2)index=’0′ ports=’16′表示使用的是virtio的0号总线,这个总线总共可以开辟16个虚拟端口

    3)port=’0′和port=’1′表示两个virtio通道对应在虚拟机的端口号

    虚拟机启动后,在虚拟机操作系统中可以发现两个新的字符设备

    /dev/vport0p0,对应控制通道

    /dev/vport0p1,对应数据通道

    对应xml中的定义,vport0表示使用的是0号virtio总线,p0和p1则分别对应每个通道指定的端口号。虚拟机中对这两个字符设备的读写操作即相当于对virtio通道的读写,以此可以实现与主机的通信。

    2,虚拟机端的背板程序(back-end app)

    在上面xml定义的应用场景,虚拟机中会发现两个新的字符设备,其中/dev/vport0p0对应控制通道,/dev/vport0p1对应数 据通道。虚拟机中的背板程序是一个运行于虚机os的后台进程,基于poll(没有并发需求,使用poll即可)对控制端口/dev/vport0p0进行 异步监听,读取主机向控制通道发送的请求,并完成响应。为充分利用虚拟机资源,数据端口/dev/vport0p1在背板程序中初始是关闭的,当主机需要 向虚拟机传递文件时,首先通过控制通道向虚拟机的背板程序发送请求,虚拟机背板程序异步监听到该请求后,打开/dev/vport0p1数据端口,数据传 输完毕后,背板程序会重新关闭该端口。

    对于部分虚拟机的os,可能没有默认加入virtio的支持,因此需要在启动背板程序前加载相关模块:

    insmod virtio.ko

    insmod virtio_ring.ko

    insmod virtio_pci.ko

    insmod hvc_console.ko

    insmod nscatterlist.ko

    insmod virtio_console.ko

    下面的链接中包括一个不错的背板程序的示例:(此链接可能失效,大家自己去找找!)

    http://fedorapeople.org/gitweb?p=amitshah/public_git/test-virtserial.git;a=blob;f=auto-virtserial-guest.c;hb=HEAD

    3,主机端的应用程序

    由于virtio通道通过libvirt启动配置xml中的相关定义,在host本地映射为两个文件,主机程序可以通过unix套接字的方式对virtio通道进行读写,实现与虚拟机的消息数据传递:

    sock = socket(AF_UNIX, SOCK_STREAM, 0);

    sockaddr_un.sun_family = AF_UNIX;

    memcpy(&sockaddr_un.sun_path, “vm.ctl”, sizeof(sockaddr_un.sun_path));

    connect(sock, sockaddr_un, sizeof(sockaddr_un));

  • 相关阅读:
    notification(浏览器通知)
    面试的信心来源于过硬的基础
    碰撞检测
    使用自定义的鼠标图标 --- cursor url
    js中json字符串转成js对象
    【php学习】字符串操作
    Car的旅行路线(codevs 1041)
    Find them, Catch them(poj 1703)
    Period(poj 1961)
    Power Strings(poj 2406)
  • 原文地址:https://www.cnblogs.com/dream397/p/13865988.html
Copyright © 2011-2022 走看看