一种内核模块的热升级方法、装置及虚拟机系统
技术领域
本发明涉及计算机技术,更具体地,涉及一种内核模块的热升级方法、装置及虚拟机系统。
背景技术
KVM(kernel based virtual machine)是一种基于内核的虚拟机系统,提供了基于虚拟化扩展(Intel VT或者AMD-V)的Linux原生的全虚拟化解决方案。KVM中,虚拟机被实现为常规的Linux进程,由标准Linux调度程序进行调度;虚拟机的每个虚拟CPU被实现为一个常规的Linux进程。这使得KMV能够使用Linux内核的已有功能。但是,KVM本身不执行任何硬件模拟,需要用户空间程序通过/dev/kvm接口设置一个客户机虚拟服务器的地址空间,向它提供模拟的I/O,并将它的视频显示映射回宿主的显示屏。目前这个应用程序是QEMU(Quick Emulator,可称为机器虚拟器)。图1示出了Linux上的用户空间和内核空间。其中的KVM模块运行在内核空间,提供CPU和内存的虚拟化,以及客户机的I/O拦截。用户的I/O被KVM拦截后,交给QEMU模块处理。KVM虚拟机使用的QEMU进程运行在用户空间,提供硬件I/O虚拟化,通过IOCTL/dev/kvm设备和KVM交互。
QEMU原本不是KVM的一部分,它自己就是一个纯软件实现的虚拟化系统。QEMU代码中包含整套的虚拟机实现,包括处理器虚拟化、内存虚拟化,以及KVM需要使用到的虚拟设备模拟(网卡、显卡、存储控制器和硬盘等)。为了简化代码,KVM在QEMU的基础上做了修改。虚拟机运行期间,QEMU会通过KVM模块提供的系统调用进入内核,由KVM负责将虚拟机置于处理的特殊模式运行。遇到虚拟机进行I/O操作,KVM会从上次的系统调用出口处返回QEMU,由QEMU来负责解析和模拟这些设备。从QEMU的角度看,也可以说QEMU使用了KVM模块的虚拟化功能,为自己的虚拟机提供了硬件虚拟化加速。除此以外,虚拟机的配置和创建、虚拟机运行所依赖的虚拟设备、虚拟机运行时的用户环境和交互,以及一些虚拟机的特定技术比如动态迁移,都是QEMU实现的。
在KVM虚拟化中,QEMU依赖一些内核模块提供的功能,如KVM模块、VHOST-NET模块,VFIO模块,这些模块加载后会生成对应的字符设备/dev/kvm,/dev/vhost_net,/dev/vfio/vfio。QEMU通过打开这些字符设备获得文件句柄,然后通过这些文件句柄执行ioctl调用,使用这些内核模块提供的功能。图2示出了QEMU与这些内核模块之间的调用关系,在KVM虚拟化中,QEMU是运行在Host(linux)上的进程,也称之为QEMU模块,是虚拟机的容器,QEMU还负责虚拟机设备(如网卡)的模拟,所以QEMU是KVM虚拟化中非常重要的组件。KVM模块主要利用硬件特性高效实现CPU虚拟化、内存虚拟化、中断虚拟化等功能,VHOST-NET模块用于虚拟机网络转发加速,使虚拟机的网络通讯直接绕过用户空间的虚拟化层,直接可以和内核通讯。VFIO模块实现了一套用户态驱动框架,向用户态提供访问硬件设备和配置IOMMU的接口,可用于物理设备直通给虚拟机使用。
热升级QEMU依赖的内核模块时,不能影响已经引用这些内核模块的QEMU模块的正常使用。在相关技术中,通过两个KVM模块之间的切换来实现KVM模块的热升级,而VHOST-NET模块热升级则是通过将经VHOST-NET的流量切换到用户态后替换VHOST-NET模块,再将流量切换回来。这些方法复杂且不通用。KVM模块热升级,需要修改KVM模块以使得两个KVM模块可以共存,才能在这两个模块这间切换,如果要将一个原来不支持共存的KVM模块升级就无能为力。而VHOST-NET模块热升级需要有另一条可供切换流量的路径,对其他内核模块并不适用。
发明内容
有鉴于此,本发明提供了以下方案。
一种内核模块的热升级方法,包括:
监测待升级的内核模块被引用的状态,并禁止依赖于内核模块的目标模块在初始化过程中引用所述待升级的内核模块;
监测到所述待升级的内核模块没有被引用时,对所述待升级的内核模块进行升级。
一种内核模块的热升级装置,包括依赖于内核模块的目标模块和热升级模块,其中:
所述目标模块设置为:在初始化过程中,在打开每一内核单元对应的字符设备之前,先确定该内核单元是否允许被引用,只有在该内核模块允许被引用时,才打开该内核模块对应的字符设备;
所述热升级模块设置为:对内核模块进行热升级,又包括:
监测单元,设置为:监测待升级的内核单元被所述目标模块引用的状态;
热升级单元,设置为:在所述监测单元监测到所述待升级的内核单元没有被引用时,对所述待升级的内核单元进行升级;
设置单元,设置为:将所述待升级的内核模块设置为禁止被引用。
一种基于内核的虚拟机系统,包括处理器和存储器,其特征在于:
所述存储器设置为:保存程序代码;
所述处理器设置为:读取所述程序代码并执行以下热升级处理:
监测待升级的内核模块被引用的状态,并禁止依赖于内核模块的目标模块在初始化过程中引用所述待升级的内核模块;
监测到所述待升级的内核模块没有被引用时,对所述待升级的内核模块进行升级。
上述内核模块的热升级方案具有通用性,可以升级各种内核模块,且不需要对内核模块进行修改。
附图说明
图1是Linux上用户空间、内核空间及硬件系统之间的关系的示意图;
图2是QEMU进程与其依赖的内核模块之间的调用关系的示意图;
图3是本发明实施例一内核模块的热升级方法的流程图;
图4是本发明实施例一内核模块的热升级装置的模块图;
图5是本发明示例中QEMU依赖的内核模块的热升级过程的示意图。
具体实施方式
为使本发明的目的、技术方案和优点更加清楚明白,下文中将结合附图对本发明的实施例进行详细说明。需要说明的是,在不冲突的情况下,本申请中的实施例及实施例中的特征可以相互任意组合。
实施例一
本实施例涉及一种内核模块的热升级方法,热升级时,系统仍处于工作状态,为了保证内核模块的热升级不影响依赖于内核模块的模块运行,需要在内核模块不被引用时进行升级。为此,一方面要对内核模块被引用的状态进行监测,另一方面要避免对待升级的内核模块产生新的引用。文中,将依赖于内核模块的模块(也即运行时会引用内核模块的模块)称为目标模块。本实施例中,所述目标模块包括基于内核的虚拟机系统中的QEMU模块,还可以包括任何依赖于内核模块的其他模块。
如图3所示,本实施例方法包括:
步骤110,监测待升级的内核模块被引用的状态,并禁止依赖于内核模块的目标模块在初始化过程中引用所述待升级的内核模块;
本实施例中,禁止目标模块在初始化过程中引用所述待升级的内核模块,通过以下方式来实现的:
通过设置引用标记,指示所述待升级的内核模块禁止被引用;
所述目标模块在初始化过程中,在打开每一内核模块对应的字符设备(即引用该内核模块)之前,先检查该内核模块的引用标记以确定该内核模块是否允许被引用,只有在该内核模块允许被引用时,才打开该内核模块对应的字符设备。由于待升级的内核模块禁止被引用,所以目标模块不会打开待升级的内核模块对应的字符设备。对于待升级的内核模块,目标模块可以轮询其引用标记,只到这些内核模块的引用标记被更新,指示这些内核模块允许被引用时,再打开对应的字符设备。
新的目标模块在初始化过程中会引用依赖的内核模块,老的目标模块也可能会再次初始化(如在热升级过程中),这两种情况下都要禁止其引用待升级的内核模块。另外,除了待升级的内核模块禁止被引用外,本发明并不排除有其他原因使得内核模块禁止被引用。
本实施例中,所述引用标记可以采用各种数据结构如bit位、字符串等表示,还可以采用多种形式来指示内核模块是否允许被引用,例如:
所述引用标记是表示内核模块允许被引用的标记,不具有所述引用标记的内核模块为禁止被引用的内核模块;此时,设置引用标志时,应删除待升级的内核模块的引用标记;或者
所述引用标记是表示内核模块禁止被引用的标记,不具有所述引用标记的内核模块为允许被引用的内核模块;此时,设置引用标志时,应为待升级的内核模块添加引用标记;或者
所述引用标记有至少两个可选值如1个bit的两个值“0”和“1”,其中一个值如“1”表示内核模块允许被引用,另一个值如“0”表示内核模块禁止被引用,反之也可以;此时,设置引用标志时,应将待升级的内核模块的引用标记置为“0”。
需要说明的是,内核模块是禁止被引用还是允许被引用并不一定要用引用标记来指示。例如:目标模块在初始化过程中也可以向内核模块的管理模块查询,以确定其依赖的内核模块是否允许被引用。
本实施例中,所述监测待升级的内核模块被引用的状态,包括:轮询所述待升级的内核模块被所述目标模块引用的计数,如发现所述待升级的内核模块被所述目标模块引用的计数为0,表示该待升级的内核模块没有被引用。以QEMU模块为例,内核模块被QEMU模块引用的计数是Linux系统中的参数,如果计数不为0就表示内核模块至少被一个QEMU模块引用,因而该计数可以用来确定内核模块是否被QEMU模块引用。当系统中存在多个目标模块时,内核模块被所述目标模块引用的计数为0,是指内核模块被每一目标模块引用的计数均为0。
在其他实施例中,可以使用其他方式记录内核模块被目标模块引用的状态。例如,对每一内核模块,基于该内核模块被目标模块引用的计数设置一个状态标记,在计数每次变化时,检查该内核模块被所有目标模块引用的计数是否均为0,如为0,将该状态标记置为表示内核模块没有被引用的值,如不为0,将该状态标记置为表示内核模块被引用的值。这样可以通过状态标记来监测待升级的内核模块被引用的状态。
步骤120,监测到所述待升级的内核模块没有被引用时,对所述待升级的内核模块进行升级。
对内核模块升级时,将旧的内核模块更新为新的内核模块(如进行程序的替换)。本实施例中,在待升级的内核模块升级成功后,对升级成功的内核模块的引用标记进行更新,以指示所述升级成功的内核模块允许被引用。随后,目标模块就可以打开这些内核模块对应的字符设备了。在另一实施例中,有多个因素决定内核模块是否允许被引用,则要结合多个因素一起确定是否对升级成功的内核模块的引用标记进行更新。
本实施例中,对所述待升级的内核模块进行升级之前,所述方法还包括:对所述目标模块进行并发热升级,在所述并发热升级的过程中,所述目标模块停止对内核模块的引用。例如,在QEMU模块并发热升级的过程中,QEMU模块会关闭其依赖的内核模块对应的字符设备,也即停止对内核模块的引用。在所有目标模块都进行热升级后,内核模块被目标模块引用的计数就会变成0。通过并发热升级,可以使得所有目标模块在较短时间内停止对内核模块的引用,从而可以尽快对内核模块进行热升级,否则需要等待很长的时间,直到目标模块一个一个关闭后才能开始热升级。
除了并发热升级之外,也可以通过其他方式停止QEMU进程对其依赖的内核模块的引用。如控制系统中的目标模块在某一设定的时间进行重新启动,等等。
本实施例内核模块的热升级方法具有通用性,可以升级各种内核模块,一次可升级多个内核模块,不需要对内核模块进行修改。而且不光能升级现有内核模块,对未来可能新增内核模块也同样适用。
实施例二
本实施例提供一种内核模块的热升级装置,如图4所示,包括依赖于内核模块的目标模块和热升级模块,其中:
所述目标模块10,设置为:在初始化过程中,在打开每一内核单元对应的字符设备之前,先确定该内核单元是否允许被引用,只有在该内核模块允许被引用时,才打开该内核模块对应的字符设备;
所述热升级模块20,设置为:对内核模块进行热升级,又包括:
监测单元201,设置为:监测待升级的内核单元被引用的状态;
热升级单元203,设置为:在所述监测单元监测到所述待升级的内核单元没有被引用时,对所述待升级的内核单元进行升级;
设置单元205,设置为:将待升级的内核模块设置为禁止被引用。
本实施例中,
所述设置单元将待升级的内核模块设置为禁止被引用,包括:通过设置引用标记,指示待升级的内核模块禁止被引用;
所述目标模块确定该内核单元是否允许被引用,包括:通过检查该内核单元的引用标记,确定该内核单元是否允许被引用。
本实施例中,
所述设置单元还设置为:对升级成功的内核单元的引用标记进行更新,以指示所述升级成功的内核单元允许被引用。
本实施例中,
所述引用标记是表示内核模块允许被引用的标记,不具有所述引用标记的内核模块为禁止被引用的内核模块;或者
所述引用标记是表示内核模块禁止被引用的标记,不具有所述引用标记的内核模块为允许被引用的内核模块;或者
所述引用标记有至少两个可选的值,其中一个值表示内核模块允许被引用,另一个值表示内核模块禁止被引用。
本实施例中,
所述监测单元监测待升级的内核单元被所述目标模块引用的状态,包括:轮询所述待升级的内核单元被所述目标模块引用的计数,如其中一个待升级的内核单元被所述目标模块引用的计数为0,表示该待升级的内核单元没有被引用。
本实施例中,
所述目标模块包括基于内核的虚拟机系统中的QEMU模块。上述热升级模块可以用运行在用户空间中的程序实现。
本实施例还提供了一种基于内核的虚拟机系统,包括处理器和存储器,其特征在于:
所述存储器设置为:保存程序代码;
所述处理器设置为:读取所述程序代码并执行以下热升级处理:
监测待升级的内核模块被引用的状态,并禁止依赖于内核模块的目标模块在初始化过程中引用所述待升级的内核模块;
监测到所述待升级的内核模块没有被引用时,对所述待升级的内核模块进行升级。
本实施例中,
所述目标模块包括基于内核的虚拟机系统中的QEMU模块。
本实施例中,
所述禁止目标模块在初始化过程中引用所述待升级的内核模块,包括:通过设置引用标记,指示所述待升级的内核模块禁止被引用;及,所述目标模块在初始化过程中,在打开每一内核模块对应的字符设备之前,先检查该内核模块的引用标记以确定该内核模块是否允许被引用,只有在该内核模块允许被引用时,才打开该内核模块对应的字符设备;
本实施例中,
所述处理器对所述待升级的内核模块进行升级后,还执行以下处理:对升级成功的内核模块的引用标记进行更新,以指示所述升级成功的内核模块允许被引用。
本实施例中,
所述引用标记是表示内核模块允许被引用的标记,不具有所述引用标记的内核模块为禁止被引用的内核模块;或者
所述引用标记是表示内核模块禁止被引用的标记,不具有所述引用标记的内核模块为允许被引用的内核模块;或者
所述引用标记有至少两个可选的值,其中一个值表示内核模块允许被引用,另一个值表示内核模块禁止被引用。
本实施例中,
所述处理器监测待升级的内核单元被所述目标模块引用的状态,包括:轮询所述待升级的内核单元被所述目标模块引用的计数,如其中一个待升级的内核单元被所述目标模块引用的计数为0,表示该待升级的内核单元没有被引用。
本实施例中,
所述处理器对所述待升级的内核模块进行升级之前,还执行以下处理:对所述目标模块进行并发热升级,在所述并发热升级的过程中,所述目标模块停止对其依赖的内核模块的引用。
本实施例虚拟机系统可升级各种内核模块,具有通用性,不需要对内核模块进行修改,可一次升级多个内核模块。而且不光能升级现有内核模块,对未来可能新增的内核模块也同样适用。
下面再用一个具体应用中的示例对本发明进行说明。
本示例是QEMU依赖的内核模块的热升级方法,也即只有QEMU模块依赖于内核模块,该方法包括以下处理过程:
S01,修改QEMU模块的代码,使得其在打开依赖的每一内核模块对应的字符设备之前,检查该内核模块的引用标记,以确定该内核模块是否允许被引用;
S02,删除待升级的内核模块的引用标记,为不需升级的内核模块创建的引用标记;
本示例使用的引用标记表示内核模块允许被引用的标记,因此,如果内核模块的引用标记(比如名为kvm_ready文件)存在就打开对应的字符设备,如果不存在就继续循环检查该引用标记。
S03,启动一个监控程序,以轮询待升级的内核模块被QEMU模块引用的计数;
S04,对QEMU模块进行并发热升级,在热升级过程中,QEMU模块会关闭其依赖的内核模块对应的字符设备,在所有QEMU模块均进行热升级后,相应的内核模块被QEMU模块引用的计数变成0;
S05,监控程序如果发现待升级的内核模块被引用的计数变为0,则对该内核模块进行热升级,即将该内核模块移除并插入新的内核模块;
S06,为升级成功的内核模块创建引用标记,创建后,QEMU模块打开升级后的内核模块对应的字符设备。
上述实施例及示例具有不光能升级现有内核模块,而且对未来可能新增QEMU依赖的一些内核模块也同样适用,且可一次升级多个内核模块,如上面的kvm模块、vhost-net模块、vfio模块以及未来可能出现的新模块,且不需要对内核模块进行修改。
上述本发明实施例序号仅仅为了描述,不代表实施例的优劣。通过以上的实施方式的描述,本领域的技术人员可以清楚地了解到上述实施例方法可借助软件加必需的通用硬件平台的方式来实现,当然也可以通过硬件,但很多情况下前者是更佳的实施方式。基于这样的理解,本发明实施例的技术方案本质上或者说对现有技术做出贡献的部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质(如ROM/RAM、磁碟、光盘)中,包括若干指令用以使得一台终端设备(可以是手机,计算机,服务器,或者网络设备等)执行本发明各个实施例所述的方法。
以上所述仅为本发明的优选实施例而已,并不用于限制本发明,对于本领域的技术人员来说,本发明可以有各种更改和变化。凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。