libvirt, qemu, kvm关系和交互方式

The '/dev/kvm' device is the low level kernel interface for creating virtual domains.

This is not actually used by libvirt at all.

The QEMU binary has code that talks to /dev/kvm, so all libvirt does is to spawn a QEMU process which in turns creates the virtual machine.

/dev/kvm文件是kvm提供的内核接口,用于创建虚拟机。libvirt通过spawn一个qemu-kvm进程(通过qemuProcessStart()方法),qemu会调用/dev/kvm创建虚拟机(通过ioctl):

qemu then takes over the actual communication with the kernel via
/dev/kvm to use KVM virtualization

qemu-kvm就是qemu专门为了模拟提供给kvm使用的器件,是qemu的一个分支模块;这样一来,用户才能够在用户空间使用基于KVM的虚拟机;

Virsh是基于libvirt写的一个命令行工具;

抽象驱动层:即libvirt库和libvird;libvirt库对不同的虚拟化提供对外的一个统一的api,其实质就是对针对不同的hypervisor的命令进行了一个封装,libvirt针对不同的开发语言提供了api接口,如python、c等;libvirtd是linux的一个守护进程;

用户通过指定URI,连接到特定driver的libvirtd服务:virConnectPtr conn = virConnectOpenReadOnly ("test:///default"); 或virsh -c test:///default list

当使用qemu时,连接地址可能是如下形式:qemu+ssh://root@hail.cloud.example.com/system

  • qemu:///system connects to a system mode daemon.
  • qemu:///session connects to a session mode daemon.

参照上图,来理一下通过virsh命令或接口创建虚拟机实例的代码执行路径:
 (1)virsh命令创建虚拟机  -- 接口层
        virsh create vm.xml

 (2)调用libvirt提供的统一接口        --  抽象驱动层
         conn->driver->domainCreateXML(conn, xmlDesc,flags);  //此处的domainCreateXML即抽象的统一接口,这里并不需要关心底层的driver是kvm,还是xen
 (3)调用底层的相应虚拟化技术的接口 -- 具体驱动层
        domainCreateXML = qemuDomainCreateXML; //如果driver=qemu,那么此处即调用的qemu注册到抽象驱动层上的函数qemuDomainCreateXML
 (4)拼装shell命令,并执行
         以qemu为例,qemuDomainCreateXML首先会拼装一条创建虚拟机的命令,比如qemu -hdadisk.img,然后创建一个新的线程来执行
回过头来思考,libvirt通过4步,将最底层的直接在shell中输入命令来完成的操作进行了抽象封装,给应用程序开发人员提供了统一的,易用的接口。

整体关系:virsh-->libvirtd-->qemu driver-->kvm:

virsh talks to the libvirtd daemon, the libvirtd daemon run those
calls from the qemu driver.

libvirt项目提供了client代码,它通过RPC访问libvirtd,并且提供了libvirtd代码,用于处理RPC请求并且调用real driver的功能:

libvirt is responsible for both libvirt.so (the client code
[src/remote/*], which bundles the RPC request to send to libvirtd) and
for libvirtd (the daemon code [daemon/*], which receives the RPC request
and then calls into the qemu driver code [src/qemu/*] to act on the
request)

qemu driver通过ioctl调用/dev/kvm:

#define KVM_DEVICE "/dev/kvm"
r = ioctl(fd, KVM_CHECK_EXTENSION, KVM_CAP_NR_VCPUS);

libvirt项目与qemu的交互方式使用的是QEMU Machine Protocol和monitor机制:参见【转】QEMU Monitor机制实例分析

libvirt启动qemu-kvm进程时使用的参数:

-chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/domain-70-instance-00003b13/monitor.sock,server,nowait

-mon chardev=charmonitor,id=monitor,mode=control


原文地址:https://www.cnblogs.com/qxxnxxFight/p/11038727.html