即将推出的4.0内核的一个重要特性是实时修补-可以将补丁应用到正在运行的内核并解决问题,而又不会中断系统的运行。 然而,事实是,为4.0合并的实时补丁支持仅仅是故事的开始; 要在内核中完全支持此功能,还需要做很多工作。 现在看来,这项工作可能比相关的开发人员所希望的花费更长的时间。 确实,一位杰出的开发人员呼吁重新构思整个框架。
4.0版本合入了支持kpatch和kGraft通用补丁代码.提供了新的API接口,允许把包含了补丁代码的模块插入内核.API还支持罗列和移除补丁,等价于补丁回退.API接口实现了底层重定向功能,用于替换补丁代码.但是目前也只是走到了这一步,还缺少一个非常重要的模块,称为”consistency model”一致性模型,意思是在正常运行的内核打补丁时要保证新旧代码切换时机的安全性,否则可能会导致系统问题. 比较复杂的源码patch修改,受补丁影响的函数在打补丁时不能处于运行过程,不能处于被调用状态. kpatch和kGraft的最大的差异点就是对于consistency model的判定实现.既然这里有争议,那就需要重新议定方案.
kpatch调用stop_machine()让整个系统暂时停下来,然后检查每个进程的内核栈,确保被打补丁的函数没有被调用.满足条件就可以继续补丁过程,否则操作失败.
KGraft 使用two-universe模型(内核空间和用户空间就像是两个完全隔离的世界,阴阳相隔两重天),每个进程都在一个安全点safe point从旧代码切换到新代码.最常见的safe point就是从系统调用退出,这时候肯定没有运行任何内核代码.
统一一致性模型
两种方法都有其优点和缺点。Josh Poimboeuf试图对2月初发布的一致性模型补丁所做的事情是实现一个统一的一致性模型,既保留kGraft的two-universe model,也采用kpatch的栈回溯方式加快进程向新代码的切换. 理论上,这样做提高了成功应用补丁的几率,也摆脱了kpatch调用stop_machine造成的内核停滞.
Peter Zijlstra针对栈检查的异议
Ingo Molnar针对栈回溯的异议
针对上述方案中栈回溯的检查是存在争议的.因为这就要求栈回溯过程100%安全可靠.
而在此之前的栈回溯实现,”只是尽最大努力交付”,是尽可能输出正确的结果.这是个大问题.
一个基本的事实是,在内核空间想保证栈回溯过程的可靠性,并没有想象中那么容易.参考另一篇x86 orc栈回溯的译文.
如果cpu架构相关的栈回溯代码有bug的话,很可能会在打热补丁live patch的过程中触发,危害到系统的安全运行,这就比较尴尬了,打补丁就是希望不要重启系统,如果打补丁的过程有把系统搞挂的风险,那live patch就没有意义了.
即使栈回溯没有多么正确,其实不影响内核正常运行,所以有没有这个必要花时间保证栈回溯过程的100%正确性呢
一种比较简单的方式就是强制所有的用户进程退出内核空间,这就可以保证被打补丁的函数没有被调用.这就是一个安全点. 长时间阻塞在内核空间的进程,需要让它变成非阻塞,在打完补丁之后再重新阻塞在原来的位置,但是这个过程要尽可能对用户态透明 而且还要修改许多系统调用的实现,甚至驱动实现.还有,内核固有的线程又不能采用这种方式,只能另想办法. 基于这些考量,想要在系统运行时尽可能安全地打补丁,真的需要花时间才能搞定.
也可以只采用kGraft two-universe 模型,不采用栈回溯方式.但是想要捕捉到所有进程都执行到安全点,这个过程需要等待的时间无法保证.还有就是没有这个模型,很明显可打补丁的范围会受到限制,但是就实际情况而言,安全类补丁完全不受影响.
实时内核升级
也许感觉到他没有充分地解决问题,Ingo继续提议放弃kpatch和kGraft,他说:“我认为它们在实施和设计上都存在着根本性的误导,这使它们成为了(不愿)扩展的分支”. 他建议,与其尝试修补运行中的内核,不如保存系统的整个运行时状态,引导一个全新的内核,然后在新内核之上还原以前的状态. 这将消除一致性模型,大大扩展可以应用的补丁程序的范围,并且从理论上讲将更加可靠。
当然,这个想法并不新鲜。 从事CRIU(用户空间中的检查点还原)工作的开发人员在其用例列表中进行了无缝内核升级已有一段时间了,显然他们已将其用于某些工作负载。 但是,要使此功能在所有系统上都能正常运行,需要进行大量额外工作才能对整个系统状态(包括设备状态)进行快照,并将其全部还原到任意不同的内核下。 kGraft的一位开发者Vojtech Pavlik估计,要使这种系统正常工作,将需要十年的时间。
可以肯定地说,要求实时修补的用户不会对等待那么长时间感到兴奋。 完全升级的技术一旦真正起作用,还远远不能使这些用户满意。 Ingo估计实时升级可以在十秒钟之内完成,但是对于那些甚至发现亚秒级停顿补丁的用户来说,这是一个永恒的破坏。 因此,尽管人们普遍认为实时升级是一种有趣且可能有用的技术,但目前正在进行实时补丁的任何开发人员都很少有机会决定将精力重新集中在实时升级上。
因此,有关实时修补的工作将继续进行,但是尚不清楚工作的方向。 现在,为4.1合并窗口准备一致性模型代码的希望似乎有些遥不可及。 在可以合并的设计上达成共识可能需要一些时间。 因此,尽管到今年年底内核仍然有可能具有基本完整的实时补丁功能,但它可能会在年底之前发生,而不是所涉及的开发人员所希望的。