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. 输入、输出与Mad Libs 游戏

    name1=input('请输入一个名字:') name2=input('再输入一个名字:') time1=input('请输入一段时间:') print('{},是傻子,{},{}找不到小栗旬'.f ...

  2. IP欺骗

    通过一番测试,我发现当我连续提交3份问卷,再换一个IP提交3个问卷,也就是连续提交了6份问卷,并没有触发网站的反爬虫机制.所以我们可以猜测对方基于IP提交问卷的频率来识别爬虫程序的.看到这里,大家可能 ...

  3. [LeetCode] Bricks Falling When Hit 碰撞时砖头掉落

    We have a grid of 1s and 0s; the 1s in a cell represent bricks.  A brick will not drop if and only i ...

  4. 浅谈vue性能优化

    基础优化 所谓的基础优化是任何 web 项目都要做的,并且是问题的根源.HTML,CSS,JS 是第一步要优化的点 分别对应到 .vue 文件内的,<template>,<style ...

  5. 在线协作开发工具apizza使用方法(https://apizza.net/projects)

    1. 2. 3. 4. 5. 谷歌浏览器点击选择“更多工具”->“扩展程序”  6. 将刚才解压好的文件夹拖到这个位置即可

  6. springBoot使用@Value标签读取*.properties文件的中文乱码问题

    上次我碰到获取properties文件中的中文出现乱码问题. 查了下资料,原来properties默认的字符编码格式为asci码,所以我们要对字符编码进行转换成UTF-8格式 原先代码:@Proper ...

  7. C# 换行

    要让一个Windows Form的TextBox显示多行文本就得把它的Multiline属性设置为true.  要让TextBox里面的文本换行大家往往会想到直接在要换行的地方加个转义的换行符&quo ...

  8. EXSI6怎么设置虚拟机从光驱启动

    EXSI在安装完系统以后会默认从磁盘启动,假如需要进入救援模式则需要设置成光驱启动 设置

  9. java常用工具包

    1.国外 org.apache.commons.lang3 http://commons.apache.org/proper/commons-lang/javadocs/api-3.8.1/index ...

  10. Codeforces Round #542 题解

    Codeforces Round #542 abstract I决策中的独立性, II联通块染色板子 IIIVoronoi diagram O(N^2 logN) VI环上距离分类讨论加取模,最值中的 ...