跳到内容跳到页面导航:上一页 [access key p]/下一页 [access key n]
documentation.suse.com / SUSE Linux Enterprise Server 文档 / 管理指南 / 系统 / 使用 kGraft 在线增补 Linux 内核
适用范围 SUSE Linux Enterprise Server 12 SP5

22 使用 kGraft 在线增补 Linux 内核

本文档介绍 kGraft 在线增补技术的基本原理,并提供 SLE Live Patching 服务的使用准则。

kGraft 是一项在线增补技术,使用它可在运行时增补 Linux 内核,而无需停止内核。如此可以最大程度地确保系统运行时间,从而提高系统可用性,这对于任务关键型系统而言非常重要。该技术还允许动态增补内核,支持用户安装关键的安全性更新,不必将它们推迟到安排的停机时间。

kGraft 增补程序是一个内核模块,用于替换内核中的全部函数。kGraft 主要提供内核中基础结构,可在运行时将增补的代码与基本内核代码集成。

SLE Live Patching 是在常规 SUSE Linux Enterprise Server 维护基础之上提供的服务。通过 SLE Live Patching 分发的 kGraft 是对常规 SLES 维护更新的有益补充。可以使用常用的更新堆栈和过程来部署 SLE Live Patching。

本文档中提供的信息与 AMD64/Intel 64 和 POWER 体系结构相关。如果您使用的不是这些体系结构,则相关的过程可能有所不同。

22.1 kGraft 的优势

当需要对紧急情况(已知发生了应该尽力修复的严重漏洞,或者已知的修复程序出现严重的系统稳定性问题)迅速做出响应时,使用 kGraft 进行在线内核增补特别有用。该技术不适合用于非时间关键型的已安排更新。

kGraft 的典型用例包括:配有巨量 RAM,且引导时间经常长达 15 分钟或以上的内存数据库之类的系统、需要持续数周或数月不重启动的大规模仿真,或者向众多消费者持续提供服务的基础架构构建模块。

kGraft 的主要优势是它永不要求停止内核,哪怕是短暂停止。

kGraft 增补程序是 RPM 包中的一个 .ko 内核模块。可以在安装或更新 包时,使用 insmod 命令将它插入内核。kGraft 将替换内核中的全部函数,即使这些函数正在执行。如果需要,可以使用更新的 kGraft 模块替换现有增补程序。

kGraft 也很精简 - 因为利用了其他标准 Linux 技术,它只包含少量的代码。

22.2 kGraft 的底层函数

kGraft 使用 ftrace 基础结构执行增补。下面介绍了在 AMD64/Intel 64 体系结构上的实施过程。

为了增补某个内核函数,kGraft 要求该函数的开头有一定的空间,以便插入指向新函数的跳跃点。此空间是在开启函数分析的情况下,在内核编译期间由 GCC 分配的。具体而言,将在内核函数的开头注入一个 5 字节调用指令。引导此类经过检测的内核时,分析调用将替换为 5 字节 NOP(无操作)指令。

增补开始之后,第一个字节将替换为 INT3(断点)指令。这可以确保 5 字节指令替换的原子性。其他四个字节将替换为新函数的地址。最后,第一个字节将替换为 JMP(长跳跃)操作代码。

在整个过程中,将使用处理器间不可屏蔽中断 (IPI NMI) 来刷新系统中其他 CPU 的推理解码队列。这样,无需停止内核(哪怕是非常短暂的停止),就能切换到新的函数。IPI NMI 产生的中断可用毫秒为单位测量,并且不被视为服务中断,因为无论在哪种情况下,这些中断都是在内核运行时发生的。

永远不会增补调用方。相反,调用者的 NOP 将替换为指向新函数的 JMP。JMP 指令会永久保留。这种工作方式可以处理好函数指针(包括结构中的指针),并且不需要保存任何旧数据就能取消增补。

但是,这些步骤本身并不足够完善:因为函数将以非原子方式替换,内核某个部分中新修复的函数可能仍会调用其他位置的某个旧函数,反之亦然。如果函数接口的语义在增补程序中发生更改,将会造成混乱。

因此,在替换所有函数之前,kGraft 使用基于弹簧床、类似于 RCU(读取-复制-更新)的方案,来确保每个用户空间线程、内核线程和内核中断在全局视图中都保持一致。将对每个内核入口和出口设置一个基于线程的标志。这样,一个旧函数始终会调用另一个旧函数,而一个新函数始终会调用另一个新函数。为所有进程设置“new universe”标志后,增补即告完成,此时,可以去除弹簧床函数,代码可以全速运行,且不会对性能产生影响,不过,每个增补的函数需要经历超长时间的跳转。

22.3 安装 kGraft 增补程序

本节介绍如何激活 SUSE Linux Enterprise Live Patching 扩展以及如何安装 kGraft 增补程序。

22.3.1 激活 SLE Live Patching

要在您的系统上激活 SLE Live Patching,请遵循以下步骤:

  1. 如果您的 SLES 系统尚未注册,现在请注册。可以在安装系统期间完成注册,或者以后使用 YaST 产品注册模块 (yast2 registration) 执行注册。注册后,单击查看可用联机更新的列表。

    如果您的 SLES 系统已注册,但 SLE Live Patching 尚未激活,请打开 YaST 产品注册模块 (yast2 registration),然后单击选择扩展

  2. 在可用扩展列表中选择 SUSE Linux Enterprise Live Patching 12,然后单击下一步

  3. 确认许可条款并单击下一步

  4. 输入 SLE Live Patching 注册代码并单击下一步

  5. 检查安装摘要和选定的模式。应该选择安装 Live Patching 模式。

  6. 单击接受完成安装。这样就会在您的系统上安装 kGraft 基本组件以及初始在线增补程序。

22.3.2 更新系统

  1. SLE Live Patching 更新通过允许使用标准 SLE 更新堆栈来应用增补程序的形式分发。可以使用 zypper patch、YaST 联机更新或等效的方法来更新初始在线增补程序。

  2. 内核将在安装包的过程中自动增补。但是,在所有休眠进程都唤醒并避开前,旧内核函数的调用并不会完全消除。这可以节省大量的时间。尽管如此,使用旧内核函数的休眠进程并不被视为安全问题。不过,在最新的 kGraft 版本中,只有当所有进程都超出了内核用户空间界限时,才可以应用另一个 kGraft 增补程序来停止使用前一增补程序已增补的功能。

    要查看全局增补状态,请检查 /sys/kernel/kgraft/in_progress 中的标志。值 1 表示存在仍需唤醒的休眠进程(增补仍在进行)。值 0 表示所有进程都只使用了增补的函数,并且增补已经完成。或者,可以使用 kgr status 命令获取相同的信息。

    也可以基于每个进程检查标志。针对每个进程单独检查 /proc/PROCESS_NUMBER/kgr_in_progress 中的数字。同样,值 1 表示仍需唤醒的休眠进程。或者,可以使用 kgr blocking 命令输出休眠进程的列表。

22.4 增补程序生命周期

可以使用 zypper lifecycle 来查看在线增补程序的失效日期。确保包 lifecycle-data-sle-live-patching 已安装。

tux > zypper lifecycle

Product end of support
Codestream: SUSE Linux Enterprise Server 12             2024-10-31
SUSE Linux Enterprise Server 12 SP2                     n/a*

Extension end of support
SUSE Linux Enterprise Live Patching                     2017-10-31

Package end of support if different from product:
SUSEConnect                              Now, installed 0.2.41-18.1, update available 0.2.42-19.3.1
apache2-utils                            Now


*) See https://www.suse.com/lifecycle  for latest information

当到了增补程序的失效日期时,将不再提供此内核版本的更多在线增补程序。请计划于在线增补程序生命周期结束前更新内核。

22.5 去除 kGraft 增补程序

要去除 kGraft 增补程序,请执行以下过程:

  1. 首先,使用 Zypper 去除增补程序本身:

    zypper rm kgraft-patch-3_12_32-25-default
  2. 然后重引导计算机。

22.6 阻塞的内核执行线程

需要准备好内核线程才能处理 kGraft。第三方软件不一定能够配合 kGraft,并且其内核模块可能会衍生大量的内核执行线程。这些线程会无限期阻止增补过程。作为应急措施,kGraft 允许强行完成增补过程,而不等待所有执行线程跨越安全检查点。这可以通过在 /sys/kernel/kgraft/in_progress 中写入 0 来实现。在执行此过程之前,请先咨询 SUSE 支持人员。

22.7 kgr 工具

使用 kgr 工具可以简化一些 kGraft 管理任务。可用的命令为:

kgr status

显示 kGraft 增补的总体状态(readyin_progress)。

kgr patches

显示已装载 kGraft 增补程序的列表。

kgr blocking

列出阻止 kGraft 完成增补的进程。默认情况下,只会列出 PID。指定 -v 会列显命令行(如果有)。再指定一个 -v 还会显示堆栈跟踪。

有关详细信息,请参见 man kgr

22.8 kGraft 技术的应用范围

kGraft 的工作原理以替换函数为基础。数据结构的改动只能通过 kGraft 间接完成。因此,更改内核数据结构时需要特别小心,如果更改幅度太大,可能需要重引导。此外,kGraft 可能无法处理使用一个编译器来编译旧内核,使用另一个编译器来编译增补程序的情况。

由于 kGraft 的工作方式,对衍生大量内核线程的第三方模块的支持有限。

22.9 SLE Live Patching 的应用范围

SLE Live Patching 的应用范围包括 SUSE 通用漏洞评分系统 (CVSS) 级别 7 以上漏洞的修复,以及与系统稳定性或数据损坏相关的 Bug 修复。可能无法针对满足上述所有准则的所有修复类型生成在线增补程序。如果出于技术原因而无法生成内核在线增补程序,SUSE 有权不发布修复。有关作为 SUSE CVSS 评级基础的 CVSS 3.0 的详细信息,请参见 https://www.first.org/cvss/

22.10 使用支持流程与我们交互

在与 SUSE 支持人员共同解决技术难题时,您可能会收到一个所谓的程序临时修复 (PTF)。我们可能会针对各种包(包括构成 SLE Live Patching 基础的包)发布 PTF。

您可以像平时一样安装符合上一节中所述条件的 kGraft PTF,SUSE 将确保无需重引导有问题的系统,并且将来的在线更新可以正常应用。

针对基础内核发布的 PTF 会中断在线增补过程。首先,安装 PTF 内核意味着需要重引导,因为在运行时无法替换整个内核。其次,需要再次重引导,以便将 PTF 替换为对其发布了在线增补程序的任何常规维护更新。

可将 SLE Live Patching 中其他包的 PTF 视为享有正常担保的常规 PTF。