kvm是一个内核模块,它实现了一个/dev/kvm的字符设备来与用户进行交互,通过调用一系列ioctl函数可以实现qemu和kvm之间的切换。

1、qemu发起KVM_CREATE_VM的ioctl创建虚拟机

qemu从vl.c/main开始,通过configure_accelerator根据当前current_machine调用对应的accel_init_machine,如果是kvm则具体是kvm_init。当要创建虚拟机,kvm_init函数中会s->fd = qemu_open("/dev/kvm", O_RDWR);打开/dev/kvm设备,获取虚拟机句柄fd,在该fd上ret = kvm_ioctl(s, KVM_CREATE_VM, type); s->vmfd = ret;此ioctl函数在kvm中的实现为kvm_main.c中kvm_dev_ioctl函数。当传入的参数为KVM_CREATE_VM时,该函数会创建一个VM,并且返回一个vm_fd,通过该vm_fd可以操作虚拟机。

2、qemu中创建虚拟机的vcpu和qemu线程关系,并切换到kvm中

在vl.c/main的最开始会module_call_init(MODULE_INIT_MACHINE)本质就是把pc_init1赋值给了mc->init。在kvm_init创建完虚拟机后,会返回到main中,调用machine_class->init(current_machine);即会调用之前注册的pc_init1,该函数中有两个重要的pc_cpus_initpc_memory_init,即CPU和内存的初始化,在pc_cpus_init-》pc_new_cpu-》(1)cpu_x86_create主要就是把CPUX86State填充了一下,涉及到CPUID和其他的feature。(2)object_property_set_bool-》object_property_set_qobject-》object_property_set-》property_set_bool-》device_set_realized-》dc->realize此即为X86_cpu_common_class_init设置了处理函数dc->realize = x86_cpu_realizefn;

执行x86_cpu_realizefn调用qemu_init_vcpu-》qemu_kvm_start_vcpu-》qemu_thread_create该函数创建VCPU对应的qemu线程,线程函数是qemu_kvm_cpu_thread_fn,该线程函数中:

(1)kvm_init_vcpu(1.1)通过ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)kvm_arch_vcpu_id(cpu));创建虚拟机的vcpu。对应到kvm的kvm_main.c中kvm_vm_ioctl函数,当传入的参数为VM_CREATE_VCPU时,与KVM_CREATE_VM过程类似,它创建一个vcpu并且返回可以操作该vcpu的vcpu_fd;(1.2)mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);cpu->kvm_run = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, cpu->kvm_fd, 0);获取kvm_run对应的内存映射(1.3)kvm_arch_init_vcpu则填充对应的kvm_arch内容。

(2)在kvm_init_vcpu返回后会先设置开关qemu_cond_signal(&qemu_cpu_cond);打开这个开关(貌似再经过pc_memory_init设置好内存后,pc_init1完成,即可运行)才会while循环kvm_cpu_exec,该函数会run_ret = kvm_vcpu_ioctl(cpu, KVM_RUN, 0);切换到kvm中运行。对应到kvm的:kvm_main.c中kvm_vcpu_ioctl函数,若传入的参数为KVM_RUN,它最终会调用vcpu_enter_guest函数进入guest vm。

关于开关:

qemu-kvm线程工作过程:
1)启动一个子线程,创建初始化vcpu,主线程等待
2)子线程创建初始化vcpu完毕,子线程等待,并等候通知主线程运行
3)主线程继续初始化虚拟机工作,初始化完成,通知子线程继续运行
4)子线程继续启动虚拟机kvm_run,主线程执行select交互处理

3、主线程main_loop

Thread1:主线程,这个线程loop循环,循环操作select.实际就是查看有无读写文件描述符,有的话进行读写操作

Thread2:子线程,异步进行i/o操作,主要针对磁盘映像操作(block drive)

Thread3:子线程,VCPU线程, kvm_run启动和运行虚拟机

ps –ef|grep qemu

gdb –p $pid

参考:oenhen虚拟机创建和运行

qemu创建vm和vcpu进入kvm的流程的更多相关文章

  1. Qemu创建KVM虚拟机内存初始化流程

    转载请注明:[转载自博客xelatex KVM],并附本文链接.谢谢. [注]文章中采用的版本: Linux-3.11,https://www.kernel.org/pub/linux/kernel/ ...

  2. qemu启动vm后,如何host上使用ssh连接?

    qemu启动vm后,如何从host ssh连接vm? qemu启动参数 启动命令: ${cmd_qemu_system} --enable-kvm \ -machine type=q35,accel= ...

  3. openstack上创建vm实例后,状态为ERROR问题解决

    问题说明:在openstack上创建虚拟机,之前已顺利创建了n个centos6.8镜像的vm现在用ubuntu14.04镜像创建vm,发现vm创建后的状态为ERROR! 1)终端命令行操作vm创建 [ ...

  4. Azure Virtual Machine 之 如何利用Management Class Libraries 创建VM

    之前发的blog简单的介绍了如何使用Management Class Libraries 来控制Azure platform. 但由于官方并没有提供文档,所以我们只能够通过自己研究来摸索使用该类库的方 ...

  5. 从托管映像创建 VM

    可以从 Azure 中托管的 VM 映像创建多个 VM. 托管 VM 映像包含创建 VM 所需的信息,包括 OS 和数据磁盘. 构成映像的 VHD(包括 OS 磁盘和任何数据磁盘)存储为托管磁盘. 先 ...

  6. 由于挂载的nfs存储目录掉下线,导致创建VM时,无法创建

    具体错误,如下截图 重新挂载存储后,在创建VM,将成功

  7. Azure上采用Json Template从已有的VHD创建VM

    从已有的VHD创建VM是使用Azure中经常要操作的内容. 本文将介绍如何采用Json Template从已经有的VHD创建VM. 一.准备VHD 在我的Azure账户中选择一台VM,如下图: 查看其 ...

  8. kvm初体验之八:调整vm的vcpu, memory, disk大小

    假设host上创建的vm的名字为vm1. 1. 查看vm1的domain information [root@tanghuimin thm]# virsh dominfo vm1 Id: 10 Nam ...

  9. opennebula kvm 创建VM oned报错日志

    Thu Jul :: [ReM][D]: Req: UID: VirtualMachineDeploy result SUCCESS, Thu Jul :: [TM][D]: Message rece ...

随机推荐

  1. 问题11:web前端开发规范手册(转)

    一.规范目的 1.1  概述 ..................................................................................... ...

  2. 邮局 100分代码(dfs+多重剪枝)

    蓝桥杯真题-邮局 #include<iostream> #include<algorithm> #include<set> #include<string&g ...

  3. 数位DP HDU - 2089 不要62

    不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  4. [Day19]Collection接口中的子类(List集合、Set集合)

    1.List接口 1.1API总结 (1)是一个元素存取有序的集合 (2)是一个带有索引的集合,通过索引可以精确的操作集合中的元素 (3)集合中有可以重复的元素,通过元素的equals方法,来比较是否 ...

  5. 软件工程第二次作业-VSTS单元测试

    一.选择开发工具 开发工具选择 Visual studio 2017 社区版,开发语言为C 由于之前已经安装完毕,所以不上传安装过程,主界面如下: 二.练习自动单元测试 使用的测试工具是VSTS,具体 ...

  6. robotframework RF使用中需要安装的工具和库

    确保 Python 3.6.2 安装成功 安装 如下 RF使用中需要的工具和库 1. RF 在两个Python中安装 robotframework执行命令 pip install robotframe ...

  7. WinAPI 字符及字符串函数(5): IsCharAlpha - 是否是个字母

    unit Unit1; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, For ...

  8. mybatis模糊查询

    今天遇到一个模糊查询的问题,需求是:根据传入的时间查询当天的所有数据,解决办法是使用$或者contact,具体sql模拟如下: select * from table_name where creat ...

  9. Publisher/Subscriber

    public interface IPublisher { void Publish<T>(T data); void Subscribe<T>(object subscrib ...

  10. GCD的简单使用方法

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/like7xiaoben/article/details/25629365 /* 创建一个队列用来运行 ...