




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、一.KVM虛擬機(jī)創(chuàng)建的用戶(hù)操作對(duì)于用戶(hù)或者管理員來(lái)說(shuō),虛擬機(jī)的創(chuàng)建有著很多的方法,例如:kvm自帶命令行工具、使用virsh命令來(lái)創(chuàng)建、使用具有圖形界面的virt-manager等等。但是它們底層實(shí)現(xiàn)的原理都是一樣的,而且它們基本上都是通過(guò)開(kāi)源的虛擬化庫(kù)Libvirt來(lái)開(kāi)發(fā)的。下面就講一講三種用戶(hù)可以創(chuàng)建虛擬機(jī)的方式。1.1 利用kvm自帶命令行工具進(jìn)行創(chuàng)建kvm常用命令如下:參數(shù)示例說(shuō)明-hda-hda /data/windows.img指定windows.img作為硬盤(pán)鏡像-cdrom-cdrom /data/windows.iso指定windows.iso作為光盤(pán)鏡像-boot-boot
2、 c從硬盤(pán)啟動(dòng) -boot d從光盤(pán)啟動(dòng)-m-m 512分配512M內(nèi)存給虛擬系統(tǒng)-vnc-vnc :0作為vnc服務(wù)器-cpu-cpu ?列出支持的CPU -cpu core2duo指定CPU為core2duo-smp-smp 2指定虛擬機(jī)有2個(gè)CPU-net-net nic為虛擬機(jī)網(wǎng)卡(默認(rèn)為tap0) -net tap系統(tǒng)分配tap設(shè)備(默認(rèn)為tap0)1 -net nic -net tap將虛擬機(jī)的網(wǎng)卡eth0連接真機(jī)里的tap0具體創(chuàng)建一個(gè)虛擬機(jī)的步驟如下:(1)生成硬盤(pán)鏡像文件roothost:kvm-img create -f rawtes
3、t.img 10G其中“-f raw”指定鏡像文件的格式為“raw”,“10G”指定鏡像文件大小。(2)從光盤(pán)啟動(dòng)虛擬機(jī)來(lái)安裝操作系統(tǒng)roothost:kvm -boot d -hda test.img-cdrom test.iso -m 512其中“-boot d”指定虛擬機(jī)從光盤(pán)啟動(dòng),“-hda test.img”指定硬盤(pán)鏡像的位置,“-cdrom test.iso”指定光盤(pán)鏡像的位置,“-m 512”指定虛擬機(jī)的內(nèi)存為512M。(3)安裝操作系統(tǒng)后便可直接從硬盤(pán)啟動(dòng)虛擬機(jī)roothost:kvm -boot c -hda test.img-m 5121.2 利用virsh命令行工具進(jìn)行創(chuàng)
4、建1.2.1 virsh工具簡(jiǎn)介Virsh是由一個(gè)名叫l(wèi)ibvirt的軟件提供的管理工具,提供管理虛擬機(jī)比較高級(jí)的能力。Virsh可以管理KVM以及xen等虛擬機(jī)。下面是virsh的一些常見(jiàn)的命令行選項(xiàng):命令Descriptionhelp打印基本幫助信息。list列出所有客戶(hù)端。dumpxml輸出客戶(hù)端 XML 配置文件。create從 XML 配置文件生成客戶(hù)端并啟動(dòng)新客戶(hù)端。start啟動(dòng)未激活的客戶(hù)端。destroy強(qiáng)制客戶(hù)端停止。define為客戶(hù)端輸出 XML 配置文件。domid顯示客戶(hù)端 ID。domuuid顯示客戶(hù)端 UUID。dominfo顯示客戶(hù)端信息。domname顯示客
5、戶(hù)端名稱(chēng)。domstate顯示客戶(hù)端狀態(tài)。quit退出這個(gè)互動(dòng)終端。reboot重新啟動(dòng)客戶(hù)端。restore恢復(fù)以前保存在文件中的客戶(hù)端。resume恢復(fù)暫停的客戶(hù)端。save將客戶(hù)端當(dāng)前狀態(tài)保存到某個(gè)文件中。shutdown關(guān)閉某個(gè)域。suspend暫停客戶(hù)端。undefine刪除與客戶(hù)端關(guān)聯(lián)的所有文件。migrate將客戶(hù)端遷移到另一臺(tái)主機(jī)中。命令Descriptionsetmem為客戶(hù)端設(shè)定分配的內(nèi)存。setmaxmem為管理程序設(shè)定內(nèi)存上限。setvcpus修改為客戶(hù)端分配的虛擬 CPU 數(shù)目。vcpuinfo顯示客戶(hù)端的虛擬 CPU 信息。vcpupin控制客戶(hù)端的虛擬 CPU 親
6、和性。domblkstat顯示正在運(yùn)行的客戶(hù)端的塊設(shè)備統(tǒng)計(jì)。domifstat顯示正在運(yùn)行的客戶(hù)端的網(wǎng)絡(luò)接口統(tǒng)計(jì)。attach-device使用 XML 文件中的設(shè)備定義在客戶(hù)端中添加設(shè)備。attach-disk在客戶(hù)端中附加新磁盤(pán)設(shè)備。attach-interface在客戶(hù)端中附加新網(wǎng)絡(luò)接口。detach-device從客戶(hù)端中分離設(shè)備,使用同樣的 XML 描述作為命令attach-device。detach-disk從客戶(hù)端中分離磁盤(pán)設(shè)備。detach-interface從客戶(hù)端中分離網(wǎng)絡(luò)接口。命令Descriptionversion顯示 virsh 版本nodeinf
7、o有關(guān)管理程序的輸出信息1.2.2 virsh命令來(lái)創(chuàng)建虛擬機(jī)步驟(1)生成硬盤(pán)鏡像文件roothost:kvm-img create -f rawtest.img 10G(2)編寫(xiě)xml配置文件,這一步在1.2.3節(jié)具體介紹(3)創(chuàng)建并運(yùn)行虛擬機(jī)roothost:virsh create test.xml其中“test.xml”指定步驟(2)中創(chuàng)建的xml文件 這樣一個(gè)虛擬機(jī)便創(chuàng)建起來(lái)了。1.2.3 xml配置文件的編寫(xiě)利用virsh工具創(chuàng)建虛擬機(jī)必須編寫(xiě)xml配置文件,該文件指定虛擬機(jī)的各項(xiàng)參數(shù),比如虛擬機(jī)名稱(chēng)、磁盤(pán)鏡
8、像的位置、內(nèi)存大小、顯示配置等等。下面給出一個(gè)簡(jiǎn)單的配置文件的例子。#test.xml <domain type='qemu'> <name>windowsXP</name> <uuid></uuid> <memory>500000</memory> <currentMemory>500000</currentMemory> <vcpu>1</vcpu> <os
9、> <type arch='i686'machine='pc'>hvm</type> <boot dev='hd'/> <boot dev='cdrom'/> </os> <devices> <emulator>/usr/bin/qemu-system
10、-x86_64</emulator> <disk type='file' device='cdrom'> <sourcefile='/home/turnupthesun/kvm/windowsXP.iso'/> <target dev='hdc'/> <readon
11、ly/> </disk> <disk type='file' device='disk'> <sourcefile='/home/turnupthesun/kvm/windowsXP.img'/> <target dev='hda'/> &l
12、t;/disk> <graphicstype='vnc' port='14' listen='127.0.0.1'/> </devices></domain>下面介紹其中幾個(gè)比較重要的元素及屬性。(1)<domain>元素的type屬性指定運(yùn)行域的虛擬機(jī)管理器,針對(duì)kvm應(yīng)當(dāng)選擇“qemu”。(2)<name>元素的內(nèi)容指定域的名字。(3)<memory>元素和<currentMe
13、mory>元素的內(nèi)容非別指定啟動(dòng)時(shí)為域分配的最大內(nèi)存和實(shí)際分配的內(nèi)存。(4)<os></os>元素之間的內(nèi)容用來(lái)指定操作系統(tǒng)啟動(dòng)的一些信息。其中重復(fù)的<boot>元素形成了一個(gè)啟動(dòng)順序表,比如例子中先從磁盤(pán)啟動(dòng),磁盤(pán)無(wú)法啟動(dòng)再?gòu)墓獗P(pán)啟動(dòng)。(5)<disk>元素的device屬性指明不同的設(shè)備,<source>標(biāo)簽的file屬性指明這些設(shè)備的位置。1.3 如何通過(guò)圖形化界面virt-manager來(lái)創(chuàng)建虛擬機(jī) Virt-manger既虛擬機(jī)管理器,是創(chuàng)建和管理虛擬客戶(hù)端的圖形工具。具體的操作步驟為:
14、60; 從控制臺(tái)窗口啟動(dòng)這個(gè)工具,從root身份輸入virt-manager命令,點(diǎn)擊file菜單 的”新建”選項(xiàng)。 virt-manager顯示兩種虛擬化方法:Qemu/KVM或者Xen,這里選擇Qemu/KVM作為hypervisor。 選擇虛擬機(jī)名稱(chēng)和指定一種安裝方法,通過(guò)網(wǎng)絡(luò)安裝服務(wù)器或者本地CD/DVD驅(qū)動(dòng)包括本地ISO文件,在此我用本地ISO的安裝方法。 輸入本地ISO文件路徑和文件名(假設(shè)本地ISO的路徑就在根目錄下,名稱(chēng)為Mini-BT3.6.1.iso) 設(shè)置虛擬機(jī)使用的內(nèi)存容量和處理器數(shù)量。 配置虛擬機(jī)的存儲(chǔ)方法。對(duì)于存儲(chǔ)后
15、端有兩種選擇:物理存儲(chǔ)設(shè)備或者使用之前建立的磁盤(pán)文件。如果處于簡(jiǎn)單測(cè)試,創(chuàng)建文件作為存儲(chǔ)后端。當(dāng)創(chuàng)建虛擬磁盤(pán)時(shí),默認(rèn)為10GB。 網(wǎng)絡(luò)配置,在這里選擇NAT方式。這樣一個(gè)虛擬機(jī)就開(kāi)始啟動(dòng)起來(lái)了,將會(huì)出現(xiàn)啟動(dòng)界面,最后出現(xiàn)虛擬機(jī)中操作系統(tǒng)的界面。 二libvirt函數(shù)庫(kù)如何實(shí)現(xiàn)虛擬機(jī)創(chuàng)建2.1 virsh工具”create”命令源碼 在libvirt軟件包安裝完成之后,就可以看到libvirt的源碼,這個(gè)源碼實(shí)現(xiàn)了很多的開(kāi)發(fā)虛擬化軟件的用戶(hù)接口,也就是開(kāi)發(fā)的API。里面也實(shí)現(xiàn)了工具virsh,這個(gè)工具也實(shí)現(xiàn)了很多的功能。在/tools下面有一個(gè)vir
16、sh.c,這個(gè)文件里面實(shí)現(xiàn)virsh的功能,這里就具體把創(chuàng)建這部分代碼選取出來(lái)。 /* * "create" command */static const vshCmdInfo info_create = "help", N_("create a domain from an XML file"), "desc", N_("Create a domain.&qu
17、ot;), NULL, NULL;static const vshCmdOptDef opts_create= "file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("file containingan XML domain description"),#ifndef WIN32 "console", VSH_OT_BOOL, 0, N_("attach to console after creat
18、ion"),#endif "paused", VSH_OT_BOOL, 0, N_("leave the guest pausedafter creation"), "autodestroy", VSH_OT_BOOL, 0, N_("automatically destroythe guest when virsh disconnects"), NULL, 0, 0, NULL;static boolcmdCrea
19、te(vshControl *ctl, const vshCmd*cmd) virDomainPtr dom; const char *from = NULL; bool ret = true; char *buffer;#ifndef WIN32 int console = vshCommandOptBool(cmd, "console");#endif unsigned
20、 int flags = VIR_DOMAIN_NONE; if (!vshConnectionUsability(ctl, ctl->conn) return false; if (vshCommandOptString(cmd, "file", &from) <= 0) return false; &
21、#160;if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) return false; if (vshCommandOptBool(cmd, "paused") flags |= VIR_DOMAIN_START_PAUSED; if (vshCommandOptB
22、ool(cmd, "autodestroy") flags |= VIR_DOMAIN_START_AUTODESTROY; dom = virDomainCreateXML(ctl->conn, buffer, flags); VIR_FREE(buffer); if (dom != NULL)
23、60;vshPrint(ctl, _("Domain %s created from %sn"), virDomainGetName(dom), from);#ifndef WIN32 if (console)
24、 cmdRunConsole(ctl, dom,NULL);#endif virDomainFree(dom); else vshError(ctl, _("Failed to create domain from %s"), from); ret = fals
25、e; return ret;代碼的講解: typedef struct const char *name; const char *data; vshCmdInfo; 上面這個(gè)結(jié)構(gòu)體是關(guān)于命令的鍵值對(duì)信息,命令一般包含兩個(gè)名稱(chēng):命令的名字和命令的描述信息。
26、60; typedef struct const char *name; vshCmdOptType type; unsigned int flags; const char *help;
27、 vshCmdOptDef; 上面這個(gè)結(jié)構(gòu)體是關(guān)于命令選項(xiàng)的定義,該結(jié)構(gòu)體一般包括四個(gè)字段:選項(xiàng)的名稱(chēng),選項(xiàng)類(lèi)型,標(biāo)志,幫助信息。其中選項(xiàng)類(lèi)型包括:bool類(lèi)型,字符串類(lèi)型,整型,字符數(shù)據(jù),剩余的參數(shù)。 在cmdCreate主程序中有一個(gè)特別重要的函數(shù):virDomainCreateXML(),這個(gè)函數(shù)的最初原型是: virDomainPtr virDomainCreateXML (virConnectPtr conn,const char*xmlDesc,unsigned int flags),這個(gè)函數(shù)是基于一個(gè)
28、指定的XML文件來(lái)創(chuàng)建一個(gè)虛擬機(jī),其中conn表示一個(gè)指向hypervisor的連接,xmlDesc表示一個(gè)XML文件,flags表示命令選項(xiàng)的標(biāo)志。2.2 通過(guò)libvirt創(chuàng)建虛擬機(jī)的關(guān)鍵API通過(guò)分析2.1中的virsh源碼我們可以看出,使用libvirt進(jìn)行虛擬機(jī)創(chuàng)建要調(diào)用兩個(gè)關(guān)鍵的API- virFileReadAll和virDomainCreateXML,下面分別進(jìn)行說(shuō)明。2.2.1 virFileReadAll 該函數(shù)原型為intvirFileReadAll(const char *path, int maxlen, char *buf),功能
29、是將參數(shù)“path”指定路徑的文件內(nèi)容讀到一個(gè)緩沖區(qū)中,并將緩沖區(qū)地址記錄在參數(shù)“*buf”中,而參數(shù)“maxlen”指定文件的最大長(zhǎng)度。利用該API,我們可以將xml配置文件都到一個(gè)緩沖區(qū)中,以方便接下來(lái)的使用。2.2.2virDomainCreateXML該函數(shù)原型為virDomainPtr virDomainCreateXML (virConnectPtrconn, const char * xmlDesc, unsigned int flags),功能是根據(jù)參數(shù)“xm
30、lDesc”定義的配置方式創(chuàng)建一個(gè)域并返回該域的指針。參數(shù)“conn”是指向虛擬機(jī)管理器的指針,而通過(guò)設(shè)置不同的“flags”標(biāo)志,可以使創(chuàng)建的域具有不同的屬性。三 利用libvirt庫(kù)編寫(xiě)自己的虛擬機(jī)創(chuàng)建程序 Virsh命令用來(lái)創(chuàng)建虛擬機(jī)的命令是:virsh create,這個(gè)命令主要是從給定的XML文件生成客戶(hù)端并啟動(dòng)客戶(hù)端。 下面用一個(gè)測(cè)試?yán)觼?lái)說(shuō)明如何通過(guò)virsh命令來(lái)創(chuàng)建虛擬機(jī)的。 具體的操作實(shí)踐步驟是:首先需要?jiǎng)?chuàng)建虛擬硬盤(pán),為了放置操作系統(tǒng)的地方,命令是:kvm-img create 701.img10G,也就
31、是創(chuàng)建一個(gè)大小為10G的虛擬硬盤(pán)。 2. 編寫(xiě)一個(gè)xml文件,這個(gè)文件里面包含啟動(dòng)操作系統(tǒng)的一些特征,比如:內(nèi)存容量,操作系統(tǒng)位置,虛擬硬盤(pán)位置等等,其實(shí)有很多的字段,可以簡(jiǎn)寫(xiě)一個(gè)xml文件,如果有些字段沒(méi)有定義,那么系統(tǒng)就會(huì)默認(rèn),下面給出一個(gè)xml文件,命名為701.xml,程序?yàn)椋?#160; <domain type='qemu'> <name>linux10.0421</name>
32、 <uuid></uuid> <memory>512000</memory> <currentMemory>512000</currentMemory> <vcpu>1</vcpu> <os>
33、60; <type arch='i686' machine='pc'>hvm</type> <boot dev='cdrom'/> <boot dev='hd'/> &
34、#160;</os> <devices> <emulator>/usr/bin/qemu-system-x86_64</emulator> <disk type='file
35、' device='cdrom'> <source file='/usr/src/ubuntu-10.04-desktop-i386.iso'/> <target dev='hdc'/> <
36、readonly/> </disk> <disk type='file' device='disk'> <sourcefile='/var/lib/libvirt/images/701.img'/>
37、160; <target dev='hda'/> </disk> <graphics type='vnc' port='5901'listen='127.0.0.1'/> </devices>
38、 </domain> 3. 接著編寫(xiě)一個(gè)c文件,名稱(chēng)為701.c這個(gè)文件主要實(shí)現(xiàn)的功能就是調(diào)用這個(gè)xml文件來(lái)創(chuàng)建并啟動(dòng)虛擬機(jī)。這個(gè)c程序代碼為: #include<stdio.h> #include<stdlib.h> #include<memory.h>
39、0; #include<libvirt/libvirt.h> const char *from=NULL; static virConnectPtr conn=NULL; #define VIRSH_MAX_XML_FILE 10*1024*1024 void closeConn() &
40、#160; if(conn!=NULL) virConnectClose(conn); int cmdCreate() virDomainPtr dom; char
41、 *buffer; unsigned int flags=VIR_DOMAIN_NONE; conn=virConnectOpen("qemu:/system"); if(conn=NULL)
42、160; fprintf(stderr,"failed to connect tohypervisor/n"); closeConn(); return 0;
43、 if(virFileReadAll(from,VIRSH_MAX_XML_FILE,&buffer)<0) return 0; dom=virDomainCreateXML(conn,buffer,flags); memset(buffer,0,sizeof(buffer);
44、 if(dom!=NULL) fprintf(stdout,"Domain %screated from %sn",virDomainGetName(dom),from); virDomainFree(dom);
45、0; else fprintf(stdout,"Failed to createdomain from %s",from); int main(int a
46、rgc,char *argv) if(argc<2) fprintf(stdout,"there are too fewparameters,should has two more parameters!");
47、 from=*+argv; cmdCreate(); return 0; 4. 在命令窗口中先執(zhí)行g(shù)cc -lvirt -o 701 701.c ,然后執(zhí)行./701 701.xml,就可以看到這個(gè)虛擬機(jī)被創(chuàng)建并啟動(dòng)起來(lái)了。 四KVM內(nèi)核如何實(shí)現(xiàn)底層虛擬機(jī)創(chuàng)建功能4.1 KVM虛擬機(jī)創(chuàng)建和運(yùn)行虛擬機(jī)的流程
48、0; 開(kāi)源的Lbvirt庫(kù)實(shí)現(xiàn)了很多的虛擬化API,這些API的實(shí)現(xiàn)還是要靠底層的KVM內(nèi)核的實(shí)現(xiàn),下面重點(diǎn)講講KVM內(nèi)核中是如何實(shí)現(xiàn)虛擬機(jī)創(chuàng)建和運(yùn)行功能的操作系統(tǒng)層的實(shí)現(xiàn)。 KVM虛擬機(jī)創(chuàng)建和運(yùn)行虛擬機(jī)分為用戶(hù)態(tài)和核心態(tài)兩個(gè)部分,用戶(hù)態(tài)主要提供應(yīng)用程序接口,為虛擬機(jī)創(chuàng)建虛擬機(jī)上下文環(huán)境,在libkvm中提供訪問(wèn)內(nèi)核字符設(shè)備/dev/kvm的接口;內(nèi)核態(tài)為添加到內(nèi)核中的字符設(shè)備/dev/kvm,模塊加載進(jìn)內(nèi)核后,即可進(jìn)行接口用戶(hù)空間調(diào)用創(chuàng)建虛擬機(jī)。在創(chuàng)建虛擬機(jī)過(guò)程中,kvm字符設(shè)備主要為客戶(hù)機(jī)創(chuàng)建kvm數(shù)據(jù)結(jié)構(gòu),創(chuàng)建該虛擬機(jī)的虛擬機(jī)文件描述符及其
49、相應(yīng)的數(shù)據(jù)結(jié)構(gòu)以及創(chuàng)建虛擬機(jī)處理器及其相應(yīng)的數(shù)據(jù)結(jié)構(gòu)。kvm創(chuàng)建虛擬機(jī)的流程如下圖: 根據(jù)上圖就可以大致知道虛擬機(jī)創(chuàng)建和運(yùn)行的流程了。首先申明一個(gè)kvm_context_t變量用以描述用戶(hù)態(tài)虛擬機(jī)上下文信息,然后調(diào)用kvm_init()函數(shù)初始化虛擬機(jī)上下文信息;函數(shù)kvm_create()創(chuàng)建虛擬機(jī)實(shí)例,該函數(shù)通過(guò)ioctl系統(tǒng)調(diào)用創(chuàng)建虛擬機(jī)相關(guān)的內(nèi)核數(shù)據(jù)結(jié)構(gòu)并且返回文件描述符給用戶(hù)態(tài)kvm_context_t數(shù)據(jù)結(jié)構(gòu);創(chuàng)建完內(nèi)核虛擬機(jī)數(shù)據(jù)結(jié)構(gòu)后,再創(chuàng)建內(nèi)核pit以及mmio等外設(shè)模擬設(shè)備,然后調(diào)用kvm_create_vcpu()函數(shù)來(lái)創(chuàng)建虛擬處理器,k
50、vm_create_vcpu()函數(shù)通過(guò)系統(tǒng)調(diào)用向由vm_fd文件描述符指向的虛擬文件調(diào)用創(chuàng)建虛擬處理器,并將虛擬處理器的文件描述符返回給用戶(hù)態(tài)程序,供以后的調(diào)度使用;創(chuàng)建完虛擬處理器后,由用戶(hù)態(tài)的QEMU程序申請(qǐng)客戶(hù)機(jī)用戶(hù)空間,用以加載和運(yùn)行客戶(hù)機(jī)代碼;為了使得客戶(hù)虛擬機(jī)正確執(zhí)行,必須要在內(nèi)核中為客戶(hù)機(jī)建立正確的內(nèi)存映射關(guān)系,即影子頁(yè)表信息。因此,申請(qǐng)客戶(hù)機(jī)內(nèi)存地址空間之后,調(diào)用函數(shù)kvm_create_phys_mem()創(chuàng)建客戶(hù)機(jī)內(nèi)存映射關(guān)系,該函數(shù)主要通過(guò)ioctl系統(tǒng)調(diào)用向vm_fd指向隊(duì)的虛擬文件調(diào)用設(shè)置內(nèi)核數(shù)據(jù)結(jié)構(gòu)中客戶(hù)機(jī)內(nèi)存映射關(guān)系,主要建立影子頁(yè)表信息;當(dāng)創(chuàng)建好虛擬處理器和影
51、子頁(yè)表后,即可讀取客戶(hù)機(jī)到指定分配的空間中,然后調(diào)度虛擬處理器運(yùn)行。調(diào)度虛擬機(jī)的函數(shù)為kvm_run(),該函數(shù)通過(guò)ioctl系統(tǒng)調(diào)用調(diào)用由虛擬處理器文件描述符指向的虛擬文件調(diào)度處理函數(shù)kvm_run()調(diào)度虛擬處理器的執(zhí)行,該系統(tǒng)調(diào)用將虛擬處理器vcpu信息加載到物理處理器中,通過(guò)vm_entry執(zhí)行進(jìn)入客戶(hù)機(jī)執(zhí)行。在客戶(hù)機(jī)正常運(yùn)行期間kvm_run()函數(shù)不返回,只有發(fā)生以下兩種情況時(shí),函數(shù)返回:1,發(fā)生了I/O事件,如客戶(hù)機(jī)發(fā)出讀寫(xiě)I/O的指令;2,產(chǎn)生了客戶(hù)機(jī)和內(nèi)核KVM都無(wú)法處理的異常。I/O事件處理完畢后,通過(guò)重新調(diào)用KVM_RUN()函數(shù)繼續(xù)調(diào)度客戶(hù)機(jī)的執(zhí)行。4.2 KVM虛擬機(jī)
52、創(chuàng)建和運(yùn)行虛擬機(jī)的主要函數(shù)分析以及流程 1.函數(shù)kvm_init():該函數(shù)在用戶(hù)態(tài)創(chuàng)建一個(gè)虛擬機(jī)上下文,用以在用戶(hù)態(tài)保存基本的虛擬機(jī)信息,這個(gè)函數(shù)是創(chuàng)建虛擬機(jī)的第一個(gè)需要調(diào)用的函數(shù),函數(shù)返回一個(gè)kvm_context_t結(jié)構(gòu)體。該函數(shù)原型的實(shí)現(xiàn)在libkvm.c中,該函數(shù)原型是:kvm_context_t kvm_init(struct kvm_callbacks*callbacks,void *opaque);參數(shù):callbacks為結(jié)構(gòu)體kvm_callbacks變量,該結(jié)構(gòu)體包含指向函數(shù)的一組指針,用于在客戶(hù)機(jī)執(zhí)行過(guò)程中因?yàn)镮/O事件退出到用戶(hù)態(tài)的
53、時(shí)候處理的回調(diào)函數(shù)。參數(shù)opaque一般未使用。 函數(shù)執(zhí)行基本過(guò)程:打開(kāi)字符設(shè)備dev/kvm,申請(qǐng)?zhí)摂M機(jī)上下文變量kvm_context_t空間,初始化上下文的基本信息:設(shè)置fd文件描述符指向/dev/kvm,禁止虛擬機(jī)文件描述符vm_fd(-1),設(shè)置I/O事件回調(diào)函數(shù)結(jié)構(gòu)體,設(shè)置IRQ和PIT的標(biāo)志位以及內(nèi)存頁(yè)面記錄的標(biāo)志位。 用戶(hù)態(tài)數(shù)據(jù)結(jié)構(gòu)kvm_context_t用以描述虛擬機(jī)實(shí)例的用戶(hù)態(tài)上下文信息。在kvm_common.h文件里面有kvm_context的結(jié)構(gòu)體定義。structkvm_context
54、60; / Filedescriptor to /dev/kvm int fd; int vm_fd; int vcpu_fdMAX_VCPUS; struct kvm_run *runMAX_VCPUS; / Callbacks that KVM uses to emulatevarious unvirtualizable functionality st
55、ruct kvm_callbacks *callbacks; void *opaque; / A pointer to the memory used as thephysical memory for the guest void *physical_memory; / is dirty pages logging enabled for allregions or not int dirty_pages_log_
56、all; / memory regions parameters struct kvm_memory_regionmem_regionsKVM_MAX_NUM_MEM_REGIONS; / do not create in-kernel irqchip if set int no_irqchip_creation; / in-kernel irqchip status int ir
57、qchip_in_kernel; 各個(gè)數(shù)據(jù)域的解釋為:int fd :指向內(nèi)核標(biāo)準(zhǔn)字符設(shè)備/dev/kvm的文件描述符。int vm_fd:指向所創(chuàng)建的內(nèi)核虛擬機(jī)數(shù)據(jù)結(jié)構(gòu)相關(guān)文件的文件描述符。intvcpu_fdMAX_VCPUS:指向虛擬機(jī)所有的虛擬處理器的文件描述符數(shù)組。struct kvm_run*runMAX_VCPUS:指向虛擬機(jī)運(yùn)行環(huán)境上下文的指針數(shù)組。struct kvm_callbacks*call_backs: 回調(diào)函數(shù)結(jié)構(gòu)體指針,該結(jié)構(gòu)體用于處理用戶(hù)態(tài)I/O事件。void *opaque:指針(還未弄清楚)int dirty_page_log_all
58、:設(shè)置是否記錄臟頁(yè)面的標(biāo)志。int no_ira_creation: 用于設(shè)置是否再kernel里設(shè)置irq芯片。int_irqchip_in_kernel:內(nèi)核中irqchip的狀態(tài)structkvm_callbacks:該結(jié)構(gòu)體用于在用戶(hù)態(tài)中處理I/O事件,在KVM中調(diào)用KVM_QEMU實(shí)現(xiàn),主要包含的數(shù)據(jù)域?yàn)椋篿nt (*inb)(void *opaque, uint16_t addr,uint8_t *data):用于模擬客戶(hù)機(jī)執(zhí)行8位的inb指令。int (*inw)(void *opaque, uint16_t addr,uint16_t *data):用于模擬客戶(hù)機(jī)執(zhí)行16位的i
59、nw指令。int (*inl)(void *opaque, uint16_t addr,uint32_t *data):用于模擬客戶(hù)機(jī)執(zhí)行32位的inl指令。int (*outb)(void *opaque, uint16_t addr,uint8_t data):用于模擬客戶(hù)機(jī)執(zhí)行8位的outb指令。int (*outw)(void *opaque, uint16_t addr,uint16_t data):用于模擬客戶(hù)機(jī)執(zhí)行16位的outw指令。int (*outl)(void *opaque, uint16_t addr,uint32_t data):用于模擬客戶(hù)機(jī)執(zhí)行32位的outl指
60、令。int (*mmio_read)(void *opaque, uint64_taddr, uint8_t *data,int len):用于模擬客戶(hù)機(jī)執(zhí)行mmio讀指令。int (*mmio_write)(void *opaque, uint64_taddr, uint8_t *data,int len):用于模擬客戶(hù)機(jī)執(zhí)行mmio寫(xiě)指令。int (*debug)(void *opaque, void *env,struct kvm_debug_exit_arch *arch_info):用戶(hù)客戶(hù)機(jī)調(diào)試的回調(diào)函數(shù)。int (*halt)(void *opaque, int vcpu):用于
61、客戶(hù)機(jī)執(zhí)行halt指令的響應(yīng)。int (*shutdown)(void *opaque, void *env):用于客戶(hù)機(jī)執(zhí)行shutdown指令的響應(yīng)。int (*io_window)(void *opaque):用于獲得客戶(hù)機(jī)io_windows。int (*try_push_interrupts)(void *opaque):用于注入中斷的回調(diào)函數(shù)。void (*push_nmi)(void *opaque):用于注入nmi中斷的函數(shù)。void (*post_kvm_run)(void *opaque, void*env);用戶(hù)得到kvm運(yùn)行狀態(tài)函數(shù)。int (*pre_kvm_run)
62、(void *opaque, void*env);用于獲得kvm之前運(yùn)行狀態(tài)的函數(shù)int (*tpr_access)(void *opaque, int vcpu,uint64_t rip, int is_write);獲得tpr訪問(wèn)處理函數(shù)int (*powerpc_dcr_read)(int vcpu, uint32_tdcrn, uint32_t *data);用于powerpc的dcr讀操作nt (*powerpc_dcr_write)(int vcpu, uint32_tdcrn, uint32_t data);用于powerpc的dcr寫(xiě)操作int (*s390_handle_in
63、tercept)(kvm_context_tcontext, int vcpu,struct kvm_run *run);用于s390的中斷處理。int (*s390_handle_reset)(kvm_context_tcontext, int vcpu,struct kvm_run *run);用于s390的重設(shè)處理。 當(dāng)客戶(hù)機(jī)執(zhí)行I/O事件或者停機(jī)操作等事件時(shí),KVM會(huì)交給用戶(hù)態(tài)的QEMU模擬外部I/O事件,調(diào)用這個(gè)結(jié)構(gòu)體指向的相關(guān)的函數(shù)進(jìn)行處理。Struct kvm_run: 用于KVM運(yùn)行時(shí)一些的一些狀態(tài)信息。主要包含的數(shù)據(jù)域?yàn)椋篲u8 request_interrupt_
64、window;_u8 padding17;_u32 exit_reason;_u8 ready_for_interrupt_injection;_u8 if_flag;_u8 padding22;/* in (pre_kvm_run), out (post_kvm_run) */_u64 cr8;_u64 apic_base;union /* KVM_EXIT_UNKNOWN */struct _u64 hardware_exit_reason; 記錄退出原因 hw;/* KVM_EXIT_FAIL_ENTRY */ 客戶(hù)機(jī)執(zhí)行過(guò)程中執(zhí)行VM_ENTRY失敗。struct
65、0; _u64hardware_entry_failure_reason; fail_entry;/* KVM_EXIT_EXCEPTION */ 客戶(hù)機(jī)因?yàn)楫惓M顺鰏truct _u32exception; _u32error_code; ex;/* KVM_EXIT_IO */ 客戶(hù)機(jī)因?yàn)镮O事件退出。struct kvm_io #define KVM
66、_EXIT_IO_IN 0#define KVM_EXIT_IO_OUT 1_u8 direction;_u8 size; /* bytes */_u16 port;_u32 count;_u64 data_offset; /* relative to kvm_runstart */ io;struct struct kvm_debug_exit_arch arch; debug;/* KVM_EXIT_MMIO */ 客戶(hù)機(jī)因?yàn)镸MIO退出struct _u64 phys_addr;_u8 data8;_u32 len;_u8 is_write; mmio;/
67、* KVM_EXIT_HYPERCALL */ 客戶(hù)機(jī)退出的超調(diào)用參數(shù)。struct _u64 nr;_u64 args6;_u64 ret;_u32 longmode;_u32 pad; hypercall; /*KVM_EXIT_TPR_ACCESS */ 客戶(hù)機(jī)退出訪問(wèn)TPR參數(shù)struct _u64rip;
68、60; _u32is_write; _u32pad; tpr_access;/* KVM_EXIT_S390_SIEIC */ 和S390相關(guān)數(shù)據(jù)struct _u8 icptcode;_u64 mask; /* psw upper half */_u64 addr; /* psw lower half */_u16 ipa;_u32 ipb; s390_sieic;/* KVM_EXIT_S390_RESET */#define KVM_S390_RESET_POR
69、0; 1#define KVM_S390_RESET_CLEAR 2#define KVM_S390_RESET_SUBSYSTEM 4#define KVM_S390_RESET_CPU_INIT 8#define KVM_S390_RESET_IPL 16_u64 s390_reset_flags;/* KVM_EXIT_DCR */struct _u32dcrn; _u32data; _u8 is_write; dcr;/* Fix the size of th
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 新解讀《CB-T 3916-1999鋼索壓扣》新解讀
- 泥漿循環(huán)系統(tǒng)平面布置圖
- 2025年CT模擬定位機(jī)項(xiàng)目提案報(bào)告模板
- 人教版2019 必修一 Unit 1 Teenage Life Reading and Thinking課件
- 動(dòng)畫(huà)分鏡頭語(yǔ)言設(shè)計(jì)運(yùn)用探析-以畢業(yè)作品《Angle》為例
- 浙江省湖州市2022-2023學(xué)年高二下學(xué)期期末檢測(cè)化學(xué)試題(含答案)
- 汽車(chē)傳感器與檢測(cè)技術(shù)電子教案:大氣壓力傳感器
- 物理中考一輪復(fù)習(xí)教案 第七講 凸透鏡成像規(guī)律復(fù)習(xí)教案
- 倉(cāng)庫(kù)技能比武活動(dòng)方案
- 安全生產(chǎn)獎(jiǎng)懲記錄
- 2025年高中化學(xué)學(xué)業(yè)水平合格性考試模擬試卷試題(含答案)
- 第23課《“蛟龍”探?!氛n件-2024-2025學(xué)年統(tǒng)編版語(yǔ)文七年級(jí)下冊(cè)第六單元
- 四川省綿陽(yáng)市2023-2024學(xué)年八年級(jí)下學(xué)期6月期末數(shù)學(xué)試卷(含詳解)
- 2025-2030中國(guó)哈喹諾行業(yè)市場(chǎng)現(xiàn)狀供需分析及投資評(píng)估規(guī)劃分析研究報(bào)告
- 建設(shè)工程監(jiān)理研究預(yù)測(cè)報(bào)告-中國(guó)建設(shè)工程監(jiān)理行業(yè)現(xiàn)狀與發(fā)展前景預(yù)測(cè)報(bào)告
- 東莞2025年?yáng)|莞日?qǐng)?bào)社公開(kāi)招聘7人筆試歷年參考題庫(kù)附帶答案詳解
- 水利安全風(fēng)險(xiǎn)防控“六項(xiàng)機(jī)制”與安全生產(chǎn)培訓(xùn)
- DBJ50T-147-2025 住宅電氣設(shè)計(jì)標(biāo)準(zhǔn)
- 2025年山東省濰坊安丘市中考一模數(shù)學(xué)試題(含部分答案)
- 《無(wú)人機(jī)攝影技術(shù)》課件
- QGDW12505-2025電化學(xué)儲(chǔ)能電站安全風(fēng)險(xiǎn)評(píng)估規(guī)范
評(píng)論
0/150
提交評(píng)論