The '/dev/kvm' device is the low level kernel interface for creating virtual domains.html
This is not actually used by libvirt at all.python
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.linux
/dev/kvm文件是kvm提供的內核接口,用於建立虛擬機。libvirt經過spawn一個qemu-kvm進程(經過qemuProcessStart()方法),qemu會調用/dev/kvm建立虛擬機(經過ioctl):shell
qemu then takes over the actual communication with the kernel via /dev/kvm to use KVM virtualization
qemu-kvm就是qemu專門爲了模擬提供給kvm使用的器件,是qemu的一個分支模塊;這樣一來,用戶纔可以在用戶空間使用基於KVM的虛擬機;api
Virsh是基於libvirt寫的一個命令行工具;session
抽象驅動層:即libvirt庫和libvird;libvirt庫對不一樣的虛擬化提供對外的一個統一的api,其實質就是對針對不一樣的hypervisor的命令進行了一個封裝,libvirt針對不一樣的開發語言提供了api接口,如python、c等;libvirtd是linux的一個守護進程;dom
用戶經過指定URI,鏈接到特定driver的libvirtd服務:virConnectPtr conn = virConnectOpenReadOnly ("test:///default"); 或virsh -c test:///default listssh
當使用qemu時,鏈接地址多是以下形式:qemu+ssh://root@hail.cloud.example.com/systemsocket
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