KVM初始化过程

本文详细解析了QEMU调用KVM接口初始化的过程,包括打开/dev/kvm设备,创建虚拟机和vCPU,以及调用ioctl函数进入Guest VM。阐述了qemu主函数main中的关键初始化步骤,如configure_accelerator()和machine->init(&args),并展示了gdb调试下函数调用关系。

之前打算整理一下在Guest VM, KVM, QEMU中IO处理的整个流程,通过查阅资料和阅读源码,已经大致知道IO在Guest KVM中的处理流程.当想要整理IO在KVM和QEMU中的处理时,发现很难理清楚QEMU和KVM之间的跳转和交互的过程,于是促使自己去了解QEMU和KVM启动的过程.(本文展示的代码中,qemu版本为1.6.0, linux内核版本为3.7.10)

    为了介绍qemu和kvm的交互过程,我首先介绍一下kvm给用户提供的接口.kvm是一个内核模块,它实现了一个/dev/kvm的字符设备来与用户进行交互,通过调用一系列ioctl函数可以实现qemu和kvm之间的切换.当要创建一个新的虚拟机时,首先打开/dev/kvm设备,在其上调用ioctl函数:

system_fd = open("/dev/kvm", ORDWR);
vm_fd = ioctl(system_fd, KVM_CREATE_VM, 0);

ioctl函数在kvm中的实现为virt/kvm/kvm_main.c中kvm_dev_ioctl函数,当传入的参数为KVM_CREATE_VM时,该函数会创建一个VM,并且返回一个fd,通过该fd可以操作虚拟机.

    创建完虚拟机之后,需要在该虚拟机上面创建vcpu,调用的接口也是ioctl,只是此时对应的fd为创建虚拟机时返回的fd.

vcpu_fd = ioctl(vm_fd, VM_CREATE_VCPU, 0)

此时ioctl函数对应的实现为virt/kvm/kvm_main.c中kvm_vm_ioctl函数,当传入的参数为VM_CREATE_VCPU时,与KVM_CREATE_VM过程类似,它创建一个vcpu并且返回可以操作该vcpu的fd.

    创建完vcpu后,可以在该vcpu上面调用ioctl函数进入guest vm.

ret = ioctl(vcpu_fd, KVM_RUN, 0);

此时ioctl函数对应的实现为virt/kvm/kvm_main.c中kvm_vcpu_ioctl函数,若传入的参数为KVM_RUN,它最终会调用vcpu_enter_guest函数进入guest vm.

 

    qemu作为一个user mode的程序,其入口为main函数,该main函数定义在vl.c文件中.main函数比较长,其中跟KVM初始化相关的主要有两个函数:configure_accelerator()和machine->init(&args). cofigure_accelerator()函数选择运用哪一种虚拟化方案,其应用到的数据结构为accel_list,会调用accel_list[i].init函数.accel_list的初始化如下所示,当使用kvm虚拟化解决方案时,accel_list[i].init对应的函数即为kvm_init.

static struct {
    const char *opt_name;
    const char *name;
    int (*available)(void);
    int (*init)(void);
    bool *allowed;
} accel_list[] = {
    { "tcg", "tcg", tcg_available, tcg_init, &tcg_allowed },
    { "xen", "Xen", xen_available, xen_init, &xen_allowed },
    { "kvm", "KVM", kvm_available, kvm_init, &kvm_allowed },
    { "qtest", "QTest", qtest_available, qtest_init, &qtest_allowed },
};

kvm_init函数定义在kvm-all.c文件中,其主要功能是打开/dev/kvm设备,创建一个虚拟机.

    machine->init(&arg)函数主要初始化硬件设备,并且调用qemu_init_vcpu为每一个vcpu创建一个线程,线程执行的函数为qemu_kvm_cpu_thread_fn.从qemu main到qemu_init_vcpu之间函数调用关系涉及到一些函数指针的赋值源码比较难于读懂,以下是使用gdb调试打出其调用关系.

#0 qemu_init_vcpu (cpu=0x55555681ea90) at /home/dashu/kvm/qemu/qemu-dev-zwu/cpus.c:1084
#1 0x0000555555909f1e in x86_cpu_realizefn (dev=0x55555681ea90, errp=0x7fffffffd8f8) at /home/dashu/kvm/qemu/qemu-dev-zwu/target-i386/cpu.c:2399
#2 0x00005555556c768a in device_set_realized (obj=0x55555681ea90, value=true, err=0x7fffffffda88) at hw/core/qdev.c:699
#3 0x000055555580b93f in property_set_bool (obj=0x55555681ea90, v=0x5555565bab20, opaque=0x5555565375a0, name=0x555555a01f88 "realized", errp=0x7fffffffda88) at qom/object.c:1300
#4 0x000055555580a484 in object_property_set (obj=0x55555681ea90, v=0x5555565bab20, name=0x555555a01f88 "realized", errp=0x7fffffffda88) at qom/object.c:788
#5 0x000055555580bbea in object_property_set_qobject (obj=0x55555681ea90, value=0x555556403e40, name=0x555555a01f88 "realized", errp=0x7fffffffda88) at qom/qom-qobject.c:24
#6 0x000055555580a770 in object_property_set_bool (obj=0x55555681ea90, value=true, name=0x555555a01f88 "realized", errp=0x7fffffffda88) at qom/object.c:851
#7 0x00005555558a7de0 in pc_new_cpu (cpu_model=0x555555a0200b "qemu64", apic_id=0, icc_bridge=0x55555655b2c0, errp=0x7fffffffdac8) at /home/dashu/kvm/qemu/qemu-dev-zwu/hw/i386/pc.c:922
#8 0x00005555558a7fed in pc_cpus_init (cpu_model=0x555555a0200b "qemu64", icc_bridge=0x55555655b2c0) at /home/dashu/kvm/qemu/qemu-dev-zwu/hw/i386/pc.c:978
#9 0x00005555558a923b in pc_init1 (system_memory=0x5555562a7240, system_io=0x5555562a7f60, ram_size=1073741824, boot_device=0x555555a0248a "cad", kernel_filename=0x0, kernel_cmdline=0x5555559f85be "", 
initrd_filename=0x0, cpu_model=0x0, pci_enabled=1, kvmclock_enabled=1) at /home/dashu/kvm/qemu/qemu-dev-zwu/hw/i386/pc_piix.c:105
#10 0x00005555558a9a36 in pc_init_pci (args=0x7fffffffdf10) at /home/dashu/kvm/qemu/qemu-dev-zwu/hw/i386/pc_piix.c:245
#11 0x00005555558a9a7f in pc_init_pci_1_6 (args=0x7fffffffdf10) at /home/dashu/kvm/qemu/qemu-dev-zwu/hw/i386/pc_piix.c:255
#12 0x00005555558584fe in main (argc=10, argv=0x7fffffffe148, envp=0x7fffffffe1a0) at vl.c:4317

 

    qemu_kvm_cpu_thread_fn函数创建vcpu,然后调用kvm_cpu_exec函数.kvm_cpu_exec函数调用ioctl进入kvm并最终进入guest vm.

    以上即为qemu调用kvm的接口初始化kvm的过程.后续我会整理出IO在kvm和qemu之间执行过程,同时描述kvm和qemu之间如何协同工作的.

 

参考资料:

1. qemu-kvm的初始化与客户系统的执行:http://blog.youkuaiyun.com/lux_veritas/article/details/9383643

2. 内核虚拟化kvm/qemu----guest os,kvm,qemu工作流程:http://www.360doc.com/content/12/0619/13/7982302_219186951.shtml

--------------------- 本文来自 dashulu 的优快云 博客 ,全文地址请点击:https://blog.youkuaiyun.com/dashulu/article/details/17074675?utm_source=copy

<think>好的,用户想了解ZStack的安装和初始化方法。首先,我需要回忆相关的引用内容。引用1提到准备安装环境、服务器、安装包和教程,引用2有具体的命令行操作,比如使用ISO更新本地源。引用3详细说明了初始化步骤,包括登录TUI界面、创建区域和集群等步骤。 用户可能需要分步骤的指导,所以应该按照安装前准备、安装过程初始化和后续配置的顺序来组织内容。要注意使用中文,并且按照系统指令正确使用LaTeX格式,虽然这个问题可能涉及技术步骤,数学公式可能不多,但如果有变量或代码,要确保格式正确。 需要检查是否有遗漏的步骤,比如在安装环境准备中,是否需要特定操作系统或硬件要求?引用3提到了KVM或XDragon类型,可能需要说明服务器虚拟化技术的选择。另外,初始化后的云资源创建也是关键步骤,应该包含在回答里。 可能的相关问题包括如何解决安装中的常见错误、不同虚拟化技术的选择影响,或者如何添加物理机等。需要确保回答结构清晰,步骤明确,并正确引用来源。最后,验证所有步骤是否符合引用内容,避免错误信息。</think>### ZStack安装与初始化方法 #### **一、安装前准备** 1. **服务器环境** - 确保服务器满足最低配置要求(至少4核CPU、8GB内存、100GB磁盘空间)[^3]。 - 操作系统需为支持的Linux发行版(如CentOS、Kylin等)[^1]。 2. **软件准备** - 下载ZStack安装包(如`ZStack-DVD-Kylin10SP2.iso`)[^2]。 - 配置本地源(通过命令更新源文件): ```bash bash zstack-upgrade -r ZStack-DVD-Kylin10SP2.iso ``` --- #### **二、安装ZStack** 1. **通过ISO安装系统** - 将ISO镜像挂载至服务器,启动安装程序,按提示完成基础系统安装[^1]。 --- #### **三、初始化ZStack** 1. **登录TUI管理界面** - 访问地址:`服务器IP:5000`(如`192.168.1.204:5000`),使用默认账号`admin`/`password`登录。 2. **初始化向导** - 点击“初始化向导”,按步骤完成以下配置: - **创建区域**:定义机房名称(如默认“Region0”)[^3]。 - **创建集群**:选择虚拟化类型(KVM或XDragon)、CPU架构(X86_64),并添加物理机。 3. **配置镜像服务器** - 为区域分配镜像服务器,用于存储系统模板和镜像。 --- #### **四、后续配置** 1. **创建云资源** - 在UI界面创建网络、存储、虚拟机等资源,按业务需求配置。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值