Warning

此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。

Note

如果您发现本文档与原始文件有任何不同或者有翻译问题,请联系该文件的译者, 或者请求时奎亮的帮助:<alexs@kernel.org>。

Original:Reporting issues
译者:吴想成 Wu XiangCheng <bobwxc@email.cn>

报告问题

简明指南(亦即 太长不看)

您面临的是否为同系列稳定版或长期支持内核的普通内核的回归?是否仍然受支持? 请搜索 LKML内核邮件列表Linux稳定版邮件列表 存档中匹配的报告并 加入讨论。如果找不到匹配的报告,请安装该系列的最新版本。如果它仍然出现问题, 报告给稳定版邮件列表(stable@vger.kernel.org)。

在所有其他情况下,请尽可能猜测是哪个内核部分导致了问题。查看MAINTAINERS文件, 了解开发人员希望如何得知问题,大多数情况下,报告问题都是通过电子邮件和抄送 相关邮件列表进行的。检查报告目的地的存档中是否已有匹配的报告;也请搜索 LKML 和网络。如果找不到可加入的讨论,请 安装 最新的主线内核 。如果仍存在问题,请发送报告。

问题已经解决了,但是您希望看到它在一个仍然支持的稳定版或长期支持系列中得到 解决?请安装其最新版本。如果它出现了问题,那么在主线中搜索修复它的更改,并 检查是否正在回传(backporting)或者已放弃;如果两者都没有,那么可询问处理 更改的人员。

通用提醒 :当安装和测试上述内核时,请确保它是普通的(即:没有补丁,也没 有使用附加模块)。还要确保它是在一个正常的环境中构建和运行,并且在问题发生 之前没有被污染(tainted)。

在编写报告时,要涵盖与问题相关的所有信息,如使用的内核和发行版。在碰见回归时, 尝试给出引入它的更改的提交ID,二分可以找到它。如果您同时面临Linux内核的多个 问题,请分别报告每个问题。

一旦报告发出,请回答任何出现的问题,并尽可能地提供帮助。这包括通过不时重新 测试新版本并发送状态更新来推动进展。

如何向内核维护人员报告问题的逐步指南

上面的简明指南概述了如何向Linux内核开发人员报告问题。对于已经熟悉向自由和开 源软件(FLOSS)项目报告问题的人来说,这可能是他们所需要的全部内容。对于其他 人,本部分更为详细,并一步一步地描述。为了便于阅读,它仍然尽量简洁,并省略 了许多细节;这些在逐步指南后的参考章节中进行了描述,该章节更详细地解释了每 个步骤。

注意:本节涉及的方面比简明指南多,顺序也稍有不同。这符合你的利益,以确保您 尽早意识到看起来像Linux内核毛病的问题可能实际上是由其他原因引起的。这些步骤 可以确保你最终不会觉得在这一过程中投入的时间是浪费:

  • 您是否面临硬件或软件供应商提供的Linux内核的问题?那么基本上您最好停止阅读 本文档,转而向您的供应商报告问题,除非您愿意自己安装最新的Linux版本。寻找 和解决问题往往需要后者。
  • 使用您喜爱的网络搜索引擎对现有报告进行粗略搜索;此外,请检查 Linux内核邮件列表(LKML) 的存档。如果 找到匹配的报告,请加入讨论而不是发送新报告。
  • 看看你正在处理的问题是否为回归问题、安全问题或非常严重的问题:这些都是需 要在接下来的一些步骤中特别处理的“高优先级问题”。
  • 确保不是内核环境导致了您面临的问题。
  • 创建一个新的备份,并将系统修复和恢复工具放在手边。
  • 确保您的系统不会通过动态构建额外的内核模块来增强其内核,像DKMS这样的解决 方案可能在您不知情的情况下就在本地进行了这样的工作。
  • 当问题发生时,检查您的内核是否被“污染”,因为使内核设置这个标志的事件可能 会导致您面临的问题。
  • 粗略地写下如何重现这个问题。如果您同时处理多个问题,请为每个问题单独写注 释,并确保它们在新启动的系统上独立出现。这是必要的,因为每个问题都需要分 别报告给内核开发人员,除非它们严重纠缠在一起。
  • 如果您正面临稳定版或长期支持版本线的回归(例如从5.10.4更新到5.10.5时出现 故障),请查看后文“报告稳定版和长期支持内核线的回归”小节。
  • 定位可能引起问题的驱动程序或内核子系统。找出其开发人员期望的报告的方式和 位置。注意:大多数情况下不会是 bugzilla.kernel.org,因为问题通常需要通 过邮件发送给维护人员和公共邮件列表。
  • 在缺陷追踪器或问题相关邮件列表的存档中彻底搜索可能与您的问题匹配的报告。 如果你发现了一些相关讨论,请加入讨论而不是发送新的报告。

在完成这些准备之后,你将进入主要部分:

  • 除非您已经在运行最新的“主线”Linux内核,否则最好在报告流程前安装它。在某些 情况下,使用最新的“稳定版”Linux进行测试和报告也是可以接受的替代方案;在 合并窗口期间,这实际上可能是最好的方法,但在开发阶段最好还是暂停几天。无论 你选择什么版本,最好使用“普通”构建。忽略这些建议会大大增加您的报告被拒绝 或忽略的风险。
  • 确保您刚刚安装的内核在运行时不会“污染”自己。
  • 在您刚刚安装的内核中复现这个问题。如果它没有出现,请查看下方只发生在 稳定版和长期支持内核的问题的说明。
  • 优化你的笔记:试着找到并写出最直接的复现问题的方法。确保最终结果包含所有 重要的细节,同时让第一次听说的人容易阅读和理解。如果您在此过程中学到了一 些东西,请考虑再次搜索关于该问题的现有报告。
  • 如果失败涉及“panic”、“Oops”、“warning”或“BUG”,请考虑解码内核日志以查找触 发错误的代码行。
  • 如果您的问题是回归问题,请尽可能缩小引入问题时的范围。
  • 通过详细描述问题来开始编写报告。记得包括以下条目:您为复现而安装的最新内 核版本、使用的Linux发行版以及关于如何复现该问题的说明。如果可能,将内核 构建配置(.config)和 dmesg 的输出放在网上的某个地方,并链接到它。包 含或上传所有其他可能相关的信息,如Oops的输出/截图或来自 lspci 的输出 。一旦你写完了这个主要部分,请在上方插入一个正常长度的段落快速概述问题和 影响。再在此之上添加一个简单描述问题的句子,以得到人们的阅读。现在给出一 个更短的描述性标题或主题。然后就可以像MAINTAINERS文件告诉你的那样发送或 提交报告了,除非你在处理一个“高优先级问题”:它们需要按照下面“高优先级问 题的特殊处理”所述特别关照。
  • 等待别人的反应,继续推进事情,直到你能够接受这样或那样的结果。因此,请公 开和及时地回应任何询问。测试提出的修复。积极地测试:至少重新测试每个新主 线版本的首个候选版本(RC),并报告你的结果。如果出现拖延,就友好地提醒一 下。如果你没有得到任何帮助或者未能满意,请试着自己帮助自己。

报告稳定版和长期支持内核线的回归

如果您发现了稳定版或长期支持内核版本线中的回归问题并按上述流程跳到这里,那么 请阅读本小节。即例如您在从5.10.4更新到5.10.5时出现了问题(从5.9.15到5.10.5则 不是)。开发人员希望尽快修复此类回归,因此有一个简化流程来报告它们:

  • 检查内核开发人员是否仍然维护你关心的Linux内核版本线:去 kernel.org 的首页 ,确保此特定版本线的最新版没有“[EOL]”标记。
  • 检查 Linux稳定版邮件列表 中的现有报告。
  • 从特定的版本线安装最新版本作为纯净内核。确保这个内核没有被污染,并且仍然 存在问题,因为问题可能已经在那里被修复了。如果您第一次发现供应商内核的问题, 请检查已知最新版本的普通构建是否可以正常运行。
  • 向Linux稳定版邮件列表发送一个简短的问题报告(stable@vger.kernel.org)。大致 描述问题,并解释如何复现。讲清楚首个出现问题的版本和最后一个工作正常的版本。 然后等待进一步的指示。

下面的参考章节部分详细解释了这些步骤中的每一步。

报告只发生在较旧内核版本线的问题

若您尝试了上述的最新主线内核,但未能在那里复现问题,那么本小节适用于您;以下 流程有助于使问题在仍然支持的稳定版或长期支持版本线,或者定期基于最新稳定版或 长期支持内核的供应商内核中得到修复。如果是这种情况,请执行以下步骤:

  • 请做好准备,接下来的几个步骤可能无法在旧版本中解决问题:修复可能太大或太 冒险,无法移植到那里。
  • 执行前节“报告稳定版和长期支持内核线的回归”中的前三个步骤。
  • 在Linux内核版本控制系统中搜索修复主线问题的更改,因为它的提交消息可能会 告诉你修复是否已经计划好了支持。如果你没有找到,搜索适当的邮件列表,寻找 讨论此类问题或同行评议可能修复的帖子;然后检查讨论是否认为修复不适合支持。 如果支持根本不被考虑,加入最新的讨论,询问是否有可能。
  • 前面的步骤之一应该会给出一个解决方案。如果仍未能成功,请向可能引起问题的 子系统的维护人员询问建议;抄送特定子系统的邮件列表以及稳定版邮件列表

下面的参考章节部分详细解释了这些步骤中的每一步。

参考章节:向内核维护者报告问题

上面的详细指南简要地列出了所有主要步骤,这对大多数人来说应该足够了。但有时, 即使是有经验的用户也可能想知道如何实际执行这些步骤之一。这就是本节的目的, 因为它将提供关于上述每个步骤的更多细节。请将此作为参考文档:可以从头到尾 阅读它。但它主要是为了浏览和查找如何实际执行这些步骤的详细信息。

在深入挖掘细节之前,我想先给你一些一般性建议:

  • Linux内核开发人员很清楚这个过程很复杂,比其他的FLOSS项目要求更多。我们很 希望让它更简单。但这需要在不同的地方以及一些基础设施上付诸努力,这些基础 设施需要持续的维护;尚未有人站出来做这些工作,所以目前情况就是这样。
  • 与某些供应商签订的保证或支持合同并不能使您有权要求上游Linux内核社区的开 发人员进行修复:这样的合同完全在Linux内核、其开发社区和本文档的范围之外。 这就是为什么在这种情况下,你不能要求任何契约保证,即使开发人员处理的问 题对供应商有效。如果您想主张您的权利,使用供应商的支持渠道代替。当这样做 的时候,你可能想提出你希望看到这个问题在上游Linux内核中修复;可以这是确 保最终修复将被纳入所有Linux发行版的唯一方法来鼓励他们。
  • 如果您从未向FLOSS项目报告过任何问题,那么您应该考虑阅读 如何有效地报告 缺陷如何 以明智的方式提问 , 和 如何提出好问题

解决这些问题之后,可以在下面找到如何正确地向Linux内核报告问题的详细信息。

确保您使用的是上游Linux内核

您是否面临硬件或软件供应商提供的Linux内核的问题?那么基本上您最好停止阅 读本文档,转而向您的供应商报告问题,除非您愿意自己安装最新的Linux版本。 寻找和解决问题往往需要后者。

与大多数程序员一样,Linux内核开发人员不喜欢花时间处理他们维护的源代码中根本 不会发生的问题的报告。这只会浪费每个人的时间,尤其是你的时间。不幸的是,当 涉及到内核时,这样的情况很容易发生,并且常常导致双方气馁。这是因为几乎所有预 装在设备(台式机、笔记本电脑、智能手机、路由器等)上的Linux内核,以及大多数 由Linux发行商提供的内核,都与由kernel.org发行的官方Linux内核相距甚远:从Linux 开发的角度来看,这些供应商提供的内核通常是古老的或者经过了大量修改,通常两点 兼具。

大多数供应商内核都不适合用来向Linux内核开发人员报告问题:您在其中遇到的问题 可能已经由Linux内核开发人员在数月或数年前修复;此外,供应商的修改和增强可能 会导致您面临的问题,即使它们看起来很小或者完全不相关。这就是为什么您应该向 供应商报告这些内核的问题。它的开发者应该查看报告,如果它是一个上游问题,直接 于上游修复或将报告转发到那里。在实践中,这有时行不通。因此,您可能需要考虑 通过自己安装最新的Linux内核内核来绕过供应商。如果如果您选择此方法,那么本指 南后面的步骤将解释如何在排除了其他可能导致您的问题的原因后执行此操作。

注意前段使用的词语是“大多数”,因为有时候开发人员实际上愿意处理供应商内核出现 的问题报告。他们是否这么做很大程度上取决于开发人员和相关问题。如果发行版只 根据最近的Linux版本对内核进行了较小修改,那么机会就比较大;例如对于Debian GNU/Linux Sid或Fedora Rawhide所提供的主线内核。一些开发人员还将接受基于最新 稳定内核的发行版内核问题报告,只要它改动不大;例如Arch Linux、常规Fedora版本 和openSUSE Turboweed。但是请记住,您最好使用主线Linux,并避免在此流程中使用 稳定版内核,如“安装一个新的内核进行测试”一节中所详述。

当然,您可以忽略所有这些建议,并向上游Linux开发人员报告旧的或经过大量修改的 供应商内核的问题。但是注意,这样的报告经常被拒绝或忽视,所以自行小心考虑一下。 不过这还是比根本不报告问题要好:有时候这样的报告会直接或间接地帮助解决之后的 问题。

搜索现有报告(第一部分)

使用您喜爱的网络搜索引擎对现有报告进行粗略搜索;此外,请检查Linux内核 邮件列表(LKML)的存档。如果找到匹配的报告,请加入讨论而不是发送新报告。

报告一个别人已经提出的问题,对每个人来说都是浪费时间,尤其是作为报告人的你。 所以彻底检查是否有人已经报告了这个问题,这对你自己是有利的。在流程中的这一步, 可以只执行一个粗略的搜索:一旦您知道您的问题需要报告到哪里,稍后的步骤将告诉 您如何详细搜索。尽管如此,不要仓促完成这一步,它可以节省您的时间和减少麻烦。

只需先用你最喜欢的搜索引擎在互联网上搜索。然后再搜索Linux内核邮件列表(LKML) 存档。

如果搜索结果实在太多,可以考虑让你的搜索引擎将搜索时间范围限制在过去的一个 月或一年。而且无论你在哪里搜索,一定要用恰当的搜索关键词;也要变化几次关键 词。同时,试着从别人的角度看问题:这将帮助你想出其他的关键词。另外,一定不 要同时使用过多的关键词。记住搜索时要同时尝试包含和不包含内核驱动程序的名称 或受影响的硬件组件的名称等信息。但其确切的品牌名称(比如说“华硕红魔 Radeon RX 5700 XT Gaming OC”)往往帮助不大,因为它太具体了。相反,尝试搜索术语,如 型号(Radeon 5700 或 Radeon 5000)和核心代号(“Navi”或“Navi10”),以及包含 和不包含其制造商(“AMD”)。

如果你发现了关于你的问题的现有报告,请加入讨论,因为你可能会提供有价值的额 外信息。这一点很重要,即使是在修复程序已经准备好或处于最后阶段,因为开发人 员可能会寻找能够提供额外信息或测试建议修复程序的人。跳到“发布报告后的责任” 一节,了解有关如何正确参与的细节。

注意,搜索 bugzilla.kernel.org 网站可能 也是一个好主意,因为这可能会提供有价值的见解或找到匹配的报告。如果您发现后者, 请记住:大多数子系统都希望在不同的位置报告,如下面“你需要将问题报告到何处” 一节中所述。因此本应处理这个问题的开发人员甚至可能不知道bugzilla的工单。所以 请检查工单中的问题是否已经按照本文档所述得到报告,如果没有,请考虑这样做。

高优先级的问题?

看看你正在处理的问题是否是回归问题、安全问题或非常严重的问题:这些都是 需要在接下来的一些步骤中特别处理的“高优先级问题”。

Linus Torvalds和主要的Linux内核开发人员希望看到一些问题尽快得到解决,因此在 报告过程中有一些“高优先级问题”的处理略有不同。有三种情况符合条件:回归、安全 问题和非常严重的问题。

如果在旧版本的Linux内核中工作的东西不能在新版本的Linux内核中工作,或者某种 程度上在新版本的Linux内核中工作得更差,那么你就需要处理“回归”。因此,当一个 在Linux 5.7中表现良好的WiFi驱动程序在5.8中表现不佳或根本不能工作时,这是一 种回归。如果应用程序在新的内核中出现不稳定的现象,这也是一种回归,这可能是 由于内核和用户空间之间的接口(如procfs和sysfs)发生不兼容的更改造成的。显著 的性能降低或功耗增加也可以称为回归。但是请记住:新内核需要使用与旧内核相似的 配置来构建(参见下面如何实现这一点)。这是因为内核开发人员在实现新特性时有 时无法避免不兼容性;但是为了避免回归,这些特性必须在构建配置期间显式地启用。

什么是安全问题留给您自己判断。在继续之前,请考虑阅读 “安全缺陷”, 因为它提供了如何最恰当地处理安全问题的额外细节。

当发生了完全无法接受的糟糕事情时,此问题就是一个“非常严重的问题”。例如, Linux内核破坏了它处理的数据或损坏了它运行的硬件。当内核突然显示错误消息 (“kernel panic”)并停止工作,或者根本没有任何停止信息时,您也在处理一个严重 的问题。注意:不要混淆“panic”(内核停止自身的致命错误)和“Oops”(可恢复错误), 因为显示后者之后内核仍然在运行。

确保环境健康

确保不是内核所处环境导致了你所面临的问题。

看起来很像内核问题的问题有时是由构建或运行时环境引起的。很难完全排除这种问 题,但你应该尽量减少这种问题:

  • 构建内核时,请使用经过验证的工具,因为编译器或二进制文件中的错误可能会导 致内核出现错误行为。
  • 确保您的计算机组件在其设计规范内运行;这对处理器、内存和主板尤为重要。因 此,当面临潜在的内核问题时,停止低电压或超频。
  • 尽量确保不是硬件故障导致了你的问题。例如,内存损坏会导致大量的问题,这些 问题会表现为看起来像内核问题。
  • 如果你正在处理一个文件系统问题,你可能需要用 fsck 检查一下文件系统, 因为它可能会以某种方式被损坏,从而导致无法预期的内核行为。
  • 在处理回归问题时,要确保没有在更新内核的同时发生了其他变化。例如,这个问 题可能是由同时更新的其他软件引起的。也有可能是在你第一次重启进入新内核时, 某个硬件巧合地坏了。更新系统 BIOS 或改变 BIOS 设置中的某些内容也会导致 一些看起来很像内核回归的问题。

为紧急情况做好准备

创建一个全新的备份,并将系统修复和还原工具放在手边

我得提醒您,您正在和计算机打交道,计算机有时会出现意想不到的事情,尤其是当 您折腾其操作系统的内核等关键部件时。而这就是你在这个过程中要做的事情。因此, 一定要创建一个全新的备份;还要确保你手头有修复或重装操作系统的所有工具, 以及恢复备份所需的一切。

确保你的内核不会被增强

确保您的系统不会通过动态构建额外的内核模块来增强其内核,像DKMS这样的解 决方案可能在您不知情的情况下就在本地进行了这样的工作。

如果内核以任何方式得到增强,那么问题报告被忽略或拒绝的风险就会急剧增加。这就 是为什么您应该删除或禁用像akmods和DKMS这样的机制:这些机制会自动构建额外内核 模块,例如当您安装新的Linux内核或第一次引导它时。也要记得同时删除他们可能安装 的任何模块。然后重新启动再继续。

注意,你可能不知道你的系统正在使用这些解决方案之一:当你安装 Nvidia 专有图 形驱动程序、VirtualBox 或其他需要 Linux 内核以外的模块支持的软件时,它们通 常会静默设置。这就是为什么你可能需要卸载这些软件的软件包,以摆脱任何第三方 内核模块。

检查“污染”标志

当问题发生时,检查您的内核是否被“污染”,因为使内核设置这个标志的事件可 能会导致您面临的问题。

当某些可能会导致看起来完全不相关的后续错误的事情发生时,内核会用“污染 (taint)”标志标记自己。如果您的内核受到污染,那么您面临的可能是这样的错误。 因此在投入更多时间到这个过程中之前,尽早排除此情况可能对你有好处。这是这个 步骤出现在这里的唯一原因,因为这个过程稍后会告诉您安装最新的主线内核;然后 您将需要再次检查污染标志,因为当它出问题的时候内核报告会关注它。

在正在运行的系统上检查内核是否污染非常容易:如果 cat /proc/sys/kernel/tainted 返回“0”,那么内核没有被污染,一切正常。在某些情况下无法检查该文件;这就是 为什么当内核报告内部问题(“kernel bug”)、可恢复错误(“kernel Oops”)或停止 操作前不可恢复的错误(“kernel panic”)时,它也会提到污染状态。当其中一个错 误发生时,查看打印的错误消息的顶部,搜索以“CPU:”开头的行。如果发现问题时内 核未被污染,那么它应该以“Not infected”结束;如果你看到“Tainted:”且后跟一些 空格和字母,那就被污染了。

如果你的内核被污染了,请阅读“受污染的内核” 以找出原因。设法消除污染因素。通常是由以下三种因素之一引起的:

  1. 发生了一个可恢复的错误(“kernel Oops”),内核污染了自己,因为内核知道在 此之后它可能会出现奇怪的行为错乱。在这种情况下,检查您的内核或系统日志, 并寻找以下列文字开头的部分:

    Oops: 0000 [#1] SMP
    

    如方括号中的“#1”所示,这是自启动以来的第一次Oops。每个Oops和此后发生的 任何其他问题都可能是首个Oops的后续问题,即使这两个问题看起来完全不相关。 通过消除首个Oops的原因并在之后复现该问题,可以排除这种情况。有时仅仅 重新启动就足够了,有时更改配置后重新启动可以消除Oops。但是在这个流程中 不要花费太多时间在这一点上,因为引起Oops的原因可能已经在您稍后将按流程 安装的新Linux内核版本中修复了。

  2. 您的系统使用的软件安装了自己的内核模块,例如Nvidia的专有图形驱动程序或 VirtualBox。当内核从外部源(即使它们是开源的)加载此类模块时,它会污染 自己:它们有时会在不相关的内核区域导致错误,从而可能导致您面临的问题。 因此,当您想要向Linux内核开发人员报告问题时,您必须阻止这些模块加载。 大多数情况下最简单的方法是:临时卸载这些软件,包括它们可能已经安装的任 何模块。之后重新启动。

  3. 当内核加载驻留在Linux内核源代码staging树中的模块时,它也会污染自身。这 是一个特殊的区域,代码(主要是驱动程序)还没有达到正常Linux内核的质量 标准。当您报告此种模块的问题时,内核受到污染显然是没有问题的;只需确保 问题模块是造成污染的唯一原因。如果问题发生在一个不相关的区域,重新启动 并通过指定 foo.blacklist=1 作为内核参数临时阻止该模块被加载(用有 问题的模块名替换“foo”)。

记录如何重现问题

粗略地写下如何重现这个问题。如果您同时处理多个问题,请为每个问题单独写 注释,并确保它们在新启动的系统上独立出现。这是必要的,因为每个问题都需 要分别报告给内核开发人员,除非它们严重纠缠在一起。

如果你同时处理多个问题,必须分别报告每个问题,因为它们可能由不同的开发人员 处理。在一份报告中描述多种问题,也会让其他人难以将其分开。因此只有在问题严 重纠缠的情况下,才能将问题合并在一份报告中。

此外,在报告过程中,你必须测试该问题是否发生在其他内核版本上。因此,如果您 知道如何在一个新启动的系统上快速重现问题,将使您的工作更加轻松。

注意:报告只发生过一次的问题往往是没有结果的,因为它们可能是由于宇宙辐射导 致的位翻转。所以你应该尝试通过重现问题来排除这种情况,然后再继续。如果你有 足够的经验来区分由于硬件故障引起的一次性错误和难以重现的罕见内核问题,可以 忽略这个建议。

稳定版或长期支持内核的回归?

如果您正面临稳定版或长期支持版本线的回归(例如从5.10.4更新到5.10.5时出现 故障),请查看后文“报告稳定版和长期支持内核线的回归”小节。

稳定版和长期支持内核版本线中的回归是Linux开发人员非常希望解决的问题,这样的 问题甚至比主线开发分支中的回归更不应出现,因为它们会很快影响到很多人。开发人员 希望尽快了解此类问题,因此有一个简化流程来报告这些问题。注意,使用更新内核版 本线的回归(比如从5.9.15切换到5.10.5时出现故障)不符合条件。

你需要将问题报告到何处

定位可能引起问题的驱动程序或内核子系统。找出其开发人员期望的报告的方式 和位置。注意:大多数情况下不会是bugzilla.kernel.org,因为问题通常需要通 过邮件发送给维护人员和公共邮件列表。

将报告发送给合适的人是至关重要的,因为Linux内核是一个大项目,大多数开发人员 只熟悉其中的一小部分。例如,相当多的程序员只关心一个驱动程序,比如一个WiFi 芯片驱动程序;它的开发人员可能对疏远的或不相关的“子系统”(如TCP堆栈、 PCIe/PCI子系统、内存管理或文件系统)的内部知识了解很少或完全不了解。

问题在于:Linux内核缺少一个,可以简单地将问题归档并让需要了解它的开发人员了 解它的,中心化缺陷跟踪器。这就是为什么你必须找到正确的途径来自己报告问题。 您可以在脚本的帮助下做到这一点(见下文),但它主要针对的是内核开发人员和专 家。对于其他人来说,MAINTAINERS(维护人员)文件是更好的选择。

如何阅读MAINTAINERS维护者文件

为了说明如何使用 MAINTAINERS 文件,让我们假设您的笔记 本电脑中的WiFi在更新内核后突然出现了错误行为。这种情况下可能是WiFi驱动的问 题。显然,它也可能由于驱动基于的某些代码,但除非你怀疑有这样的东西会附着在 驱动程序上。如果真的是其他的问题,驱动程序的开发人员会让合适的人参与进来。

遗憾的是,没有通用且简单的办法来检查哪个代码驱动了特定硬件组件。

在WiFi驱动出现问题的情况下,你可能想查看 lspci -k 的输出,因为它列出了 PCI/PCIe总线上的设备和驱动它的内核模块:

[user@something ~]$ lspci -k
[...]
3a:00.0 Network controller: Qualcomm Atheros QCA6174 802.11ac Wireless Network Adapter (rev 32)
  Subsystem: Bigfoot Networks, Inc. Device 1535
  Kernel driver in use: ath10k_pci
  Kernel modules: ath10k_pci
[...]

但如果你的WiFi芯片通过USB或其他内部总线连接,这种方法就行不通了。在这种情况 下,您可能需要检查您的WiFi管理器或 ip link 的输出。寻找有问题的网络接口 的名称,它可能类似于“wlp58s0”。此名称可以用来找到驱动它的模块:

[user@something ~]$ realpath --relative-to=/sys/module//sys/class/net/wlp58s0/device/driver/module
ath10k_pci

如果这些技巧不能进一步帮助您,请尝试在网上搜索如何缩小相关驱动程序或子系统 的范围。如果你不确定是哪一个:试着猜一下,即使你猜得不好,也会有人会帮助你 的。

一旦您知道了相应的驱动程序或子系统,您就希望在MAINTAINERS文件中搜索它。如果 是“ath10k_pci”,您不会找到任何东西,因为名称太具体了。有时你需要在网上寻找 帮助;但在此之前,请尝试使用一个稍短或修改过的名称来搜索MAINTAINERS文件,因 为这样你可能会发现类似这样的东西:

QUALCOMM ATHEROS ATH10K WIRELESS DRIVER
Mail:          A. Some Human <shuman@example.com>
Mailing list:  ath10k@lists.infradead.org
Status:        Supported
Web-page:      https://wireless.wiki.kernel.org/en/users/Drivers/ath10k
SCM:           git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
Files:         drivers/net/wireless/ath/ath10k/

注意:如果您阅读在Linux源代码树的根目录中找到的原始维护者文件,则行描述将是 缩写。例如,“Mail:(邮件)”将是“M:”,“Mailing list:(邮件列表)”将是“L”, “Status:(状态)”将是“S:”。此文件顶部有一段解释了这些和其他缩写。

首先查看“Status”状态行。理想情况下,它应该得到“Supported(支持)”或 “Maintained(维护)”。如果状态为“Obsolete(过时的)”,那么你在使用一些过时的 方法,需要转换到新的解决方案上。有时候,只有在感到有动力时,才会有人为代码 提供“Odd Fixes”。如果碰见“Orphan”,你就完全不走运了,因为再也没有人关心代码 了,只剩下这些选项:准备好与问题共存,自己修复它,或者找一个愿意修复它的程序员。

检查状态后,寻找以“bug:”开头的一行:它将告诉你在哪里可以找到子系统特定的缺 陷跟踪器来提交你的问题。上面的例子没有此行。大多数部分都是这样,因为 Linux 内核的开发完全是由邮件驱动的。很少有子系统使用缺陷跟踪器,且其中只有一部分 依赖于 bugzilla.kernel.org。

在这种以及其他很多情况下,你必须寻找以“Mail:”开头的行。这些行提到了特定代码 的维护者的名字和电子邮件地址。也可以查找以“Mailing list:”开头的行,它告诉你 开发代码的公共邮件列表。你的报告之后需要通过邮件发到这些地址。另外,对于所有 通过电子邮件发送的问题报告,一定要抄送 Linux Kernel Mailing List(LKML) <linux-kernel@vger.kernel.org>。在以后通过邮件发送问题报告时,不要遗漏任何 一个邮件列表!维护者都是大忙人,可能会把一些工作留给子系统特定列表上的其他开 发者;而 LKML 很重要,因为需要一个可以找到所有问题报告的地方。

借助脚本找到维护者

对于手头有Linux源码的人来说,有第二个可以找到合适的报告地点的选择:脚本 “scripts/get_maintainer.pl”,它尝试找到所有要联系的人。它会查询MAINTAINERS 文件,并需要用相关源代码的路径来调用。对于编译成模块的驱动程序,经常可以用 这样的命令找到:

$ modinfo ath10k_pci | grep filename | sed 's!/lib/modules/.*/kernel/!!; s!filename:!!; s!\.ko\(\|\.xz\)!!'
drivers/net/wireless/ath/ath10k/ath10k_pci.ko

将其中的部分内容传递给脚本:

$ ./scripts/get_maintainer.pl -f drivers/net/wireless/ath/ath10k*
Some Human <shuman@example.com> (supporter:QUALCOMM ATHEROS ATH10K WIRELESS DRIVER)
Another S. Human <asomehuman@example.com> (maintainer:NETWORKING DRIVERS)
ath10k@lists.infradead.org (open list:QUALCOMM ATHEROS ATH10K WIRELESS DRIVER)
linux-wireless@vger.kernel.org (open list:NETWORKING DRIVERS (WIRELESS))
netdev@vger.kernel.org (open list:NETWORKING DRIVERS)
linux-kernel@vger.kernel.org (open list)

不要把你的报告发给所有的人。发送给维护者,脚本称之为“supporter:”;另外抄送 代码最相关的邮件列表,以及 Linux 内核邮件列表(LKML)。在此例中,你需要将报 告发送给 “Some Human <shuman@example.com>” ,并抄送 “ath10k@lists.infradead.org”和“linux-kernel@vger.kernel.org”。

注意:如果你用 git 克隆了 Linux 源代码,你可能需要用–git 再次调用 get_maintainer.pl。脚本会查看提交历史,以找到最近哪些人参与了相关代码的编写, 因为他们可能会提供帮助。但要小心使用这些结果,因为它很容易让你误入歧途。 例如,这种情况常常会发生在很少被修改的地方(比如老旧的或未维护的驱动程序): 有时这样的代码会在树级清理期间被根本不关心此驱动程序的开发者修改。

搜索现有报告(第二部分)

在缺陷追踪器或问题相关邮件列表的存档中彻底搜索可能与您的问题匹配的报告。 如果找到匹配的报告,请加入讨论而不是发送新报告。

如前所述:报告一个别人已经提出的问题,对每个人来说都是浪费时间,尤其是作为报告 人的你。这就是为什么你应该再次搜索现有的报告。现在你已经知道问题需要报告到哪里。 如果是邮件列表,那么一般在 lore.kernel.org 可以 找到相应存档。

但有些列表运行在其他地方。例如前面步骤中当例子的ath10k WiFi驱动程序就是这种 情况。但是你通常可以在网上很容易地找到这些列表的档案。例如搜索“archive ath10k@lists.infradead.org”,将引导您到ath10k邮件列表的信息页,该页面顶部链接 到其 列表存档 。遗憾的是, 这个列表和其他一些列表缺乏搜索其存档的功能。在这种情况下可以使用常规的互联网 搜索引擎,并添加类似“site:lists.infadead.org/pipermail/ath10k/”这 样的搜索条件,这会把结果限制在该链接中的档案。

也请进一步搜索网络、LKML和bugzilla.kernel.org网站。

有关如何搜索以及在找到匹配报告时如何操作的详细信息,请参阅上面的“搜索现有报告 (第一部分)”。

不要急着完成报告过程的这一步:花30到60分钟甚至更多的时间可以为你和其他人节省 / 减少相当多的时间和麻烦。

安装一个新的内核进行测试

除非您已经在运行最新的“主线”Linux内核,否则最好在报告流程前安装它。在 某些情况下,使用最新的“稳定版”Linux进行测试和报告也是可以接受的替代方案; 在合并窗口期间,这实际上可能是最好的方法,但在开发阶段最好还是暂停几天。 无论你选择什么版本,最好使用“普通”构建。忽略这些建议会大大增加您的报告 被拒绝或忽略的风险。

正如第一步的详细解释中所提到的:与大多数程序员一样,与大多数程序员一样,Linux 内核开发人员不喜欢花时间处理他们维护的源代码中根本不会发生的问题的报告。这只 会浪费每个人的时间,尤其是你的时间。这就是为什么在报告问题之前,您必须先确认 问题仍然存在于最新的上游代码中,这符合每个人的利益。您可以忽略此建议,但如前 所述:这样做会极大地增加问题报告被拒绝或被忽略的风险。

内核“最新上游”的范围通常指:

  • 安装一个主线内核;最新的稳定版内核也可以是一个选择,但大多数时候都最好避免。 长期支持内核(有时称为“LTS内核”)不适合此流程。下一小节将更详细地解释所有 这些。
  • 下一小节描述获取和安装这样一个内核的方法。它还指出了使用预编译内核是可以的, 但普通的内核更好,这意味着:它是直接使用从 kernel.org 获得的Linux源代码构建并且没有任何方式修改或增强。

选择适合测试的版本

前往 kernel.org 来决定使用哪个版本。忽略那个写着 “Latest release最新版本”的巨大黄色按钮,往下看有一个表格。在表格的顶部,你会 看到一行以“mainline”开头的字样,大多数情况下它会指向一个版本号类似“5.8-rc2” 的预发布版本。如果是这样的话,你将需要使用这个主线内核进行测试。不要让“rc” 吓到你,这些“开发版内核”实际上非常可靠——而且你已经按照上面的指示做了备份, 不是吗?

大概每九到十周,“mainline”可能会给你指出一个版本号类似“5.7”的正式版本。如果 碰见这种情况,请考虑暂停报告过程,直到下一个版本的第一个预发布(5.8-rc1)出 现在 kernel.org 上。这是因为 Linux 的开发周期正在 两周的“合并窗口”内。大部分的改动和所有干扰性的改动都会在这段时间内被合并到 下一个版本中。在此期间使用主线是比较危险的。内核开发者通常也很忙,可能没有 多余的时间来处理问题报告。这也是很有可能在合并窗口中应用了许多修改来修复你 所面临的问题;这就是为什么你很快就得用一个新的内核版本重新测试,就像下面“发 布报告后的责任”一节中所述的那样。

这就是为什么要等到合并窗口结束后才去做。但是如果你处理的是一些不应该等待的 东西,则无需这样做。在这种情况下,可以考虑通过 git 获取最新的主线内核(见下 文),或者使用 kernel.org 上提供的最新稳定版本。如果 mainline 因为某些原因 不无法正常工作,那么使用它也是可以接受的。总的来说:用它来重现问题也比完全 不报告问题要好。

最好避免在合并窗口外使用最新的稳定版内核,因为所有修复都必须首先应用于主线。 这就是为什么检查最新的主线内核是如此重要:你希望看到在旧版本线修复的任何问题 需要先在主线修复,然后才能得到回传,这可能需要几天或几周。另一个原因是:您 希望的修复对于回传来说可能太难或太冒险;因此再次报告问题不太可能改变任何事情。

这些方面也部分表明了为什么长期支持内核(有时称为“LTS内核”)不适合报告流程: 它们与当前代码的距离太远。因此,先去测试主线,然后再按流程走:如果主线没有 出现问题,流程将指导您如何在旧版本线中修复它。

如何获得新的 Linux 内核

你可以使用预编译或自编译的内核进行测试;如果你选择后者,可以使用 git 获取源 代码,或者下载其 tar 存档包。

使用预编译的内核 :这往往是最快速、最简单、最安全的方法——尤其是在你不熟 悉 Linux 内核的情况下。问题是:发行商或附加存储库提供的大多数版本都是从修改 过的Linux源代码构建的。因此它们不是普通的,通常不适合于测试和问题报告:这些 更改可能会导致您面临的问题或以某种方式影响问题。

但是如果您使用的是流行的Linux发行版,那么您就很幸运了:对于大部分的发行版, 您可以在网上找到包含最新主线或稳定版本Linux内核包的存储库。使用这些是完全可 以的,只要从存储库的描述中确认它们是普通的或者至少接近普通。此外,请确保软件 包包含kernel.org上提供的最新版本内核。如果这些软件包的时间超过一周,那么它们 可能就不合适了,因为新的主线和稳定版内核通常至少每周发布一次。

请注意,您以后可能需要手动构建自己的内核:有时这是调试或测试修复程序所必需的, 如后文所述。还要注意,预编译的内核可能缺少在出现panic、Oops、warning或BUG时 解码内核打印的消息所需的调试符号;如果您计划解码这些消息,最好自己编译内核 (有关详细信息,请参阅本小节结尾和“解码失败信息”小节)。

使用git :熟悉 git 的开发者和有经验的 Linux 用户通常最好直接从 kernel.org 上的官方开发仓库 中获取最新的 Linux 内核源代码。这些很可能比最新的主线预发布版本更新一些。不 用担心:它们和正式的预发布版本一样可靠,除非内核的开发周期目前正处于合并窗 口中。不过即便如此,它们也是相当可靠的。

常规方法 :不熟悉 git 的人通常最好从 kernel.org 下载源码的tar 存档包。

如何实际构建一个内核并不在这里描述,因为许多网站已经解释了必要的步骤。如果 你是新手,可以考虑按照那些建议使用 make localmodconfig 来做,它将尝试获 取你当前内核的配置,然后根据你的系统进行一些调整。这样做并不能使编译出来的 内核更好,但可以更快地编译。

注意:如果您正在处理来自内核的pannc、Oops、warning或BUG,请在配置内核时尝试 启用 CONFIG_KALLSYMS 选项。此外,还可以启用 CONFIG_DEBUG_KERNEL 和 CONFIG_DEBUG_INFO;后者是相关选项,但只有启用前者才能开启。请注意, CONFIG_DEBUG_INFO 会需要更多储存空间来构建内核。但这是值得的,因为这些选项将 允许您稍后精确定位触发问题的确切代码行。下面的“解码失败信息”一节对此进行了更 详细的解释。

但请记住:始终记录遇到的问题,以防难以重现。发送未解码的报告总比不报告要好。

检查“污染”标志

确保您刚刚安装的内核在运行时不会“污染”自己。

正如上面已经详细介绍过的:当发生一些可能会导致一些看起来完全不相关的后续错 误的事情时,内核会设置一个“污染”标志。这就是为什么你需要检查你刚刚安装的内 核是否有设置此标志。如果有的话,几乎在任何情况下你都需要在报告问题之前先消 除它。详细的操作方法请看上面的章节。

用新内核重现问题

在您刚刚安装的内核中复现这个问题。如果它没有出现,请查看下方只发生在 稳定版和长期支持内核的问题的说明。

检查这个问题是否发生在你刚刚安装的新 Linux 内核版本上。如果新内核已经修复了, 可以考虑使用此版本线,放弃报告问题。但是请记住,只要它没有在 kernel.org 的稳定版和长期版(以及由这些版本衍生出来的厂商内核) 中得到修复,其他用户可能仍然会受到它的困扰。如果你喜欢使用其中的一个,或 者只是想帮助它们的用户,请前往下面的“报告只发生在较旧内核版本线的问题”一节。

优化复现问题的描述

优化你的笔记:试着找到并写出最直接的复现问题的方法。确保最终结果包含所 有重要的细节,同时让第一次听说的人容易阅读和理解。如果您在此过程中学到 了一些东西,请考虑再次搜索关于该问题的现有报告。

过于复杂的报告会让别人很难理解。因此请尽量找到一个可以直接描述、易于以书面 形式理解的再现方法。包含所有重要的细节,但同时也要尽量保持简短。

在这在前面的步骤中,你很可能已经了解了一些关于你所面临的问题的点。利用这些 知识,再次搜索可以转而加入的现有报告。

解码失败信息

如果失败涉及“panic”、“Oops”、“warning”或“BUG”,请考虑解码内核日志以查找 触发错误的代码行。

当内核检测到内部问题时,它会记录一些有关已执行代码的信息。这使得在源代码中精 确定位触发问题的行并显示如何调用它成为可能。但只有在配置内核时启用了 CONFIG_DEBUG_INFO 和 CONFIG_KALLSYMS选项时,这种方法才起效。如果已启用此选项, 请考虑解码内核日志中的信息。这将使我们更容易理解是什么导致了“panic”、“Oops”、 “warning”或“BUG”,从而增加了有人提供修复的几率。

解码可以通过Linux源代码树中的脚本来完成。如果您运行的内核是之前自己编译的, 这样这样调用它:

[user@something ~]$ sudo dmesg | ./linux-5.10.5/scripts/decode_stacktrace.sh ./linux-5.10.5/vmlinux
/usr/lib/debug/lib/modules/5.10.10-4.1.x86_64/vmlinux /usr/src/kernels/5.10.10-4.1.x86_64/

如果您运行的是打包好的普通内核,则可能需要安装带有调试符号的相应包。然后按以下 方式调用脚本(如果发行版未打包,则可能需要从Linux源代码获取):

[user@something ~]$ sudo dmesg | ./linux-5.10.5/scripts/decode_stacktrace.sh \
/usr/lib/debug/lib/modules/5.10.10-4.1.x86_64/vmlinux /usr/src/kernels/5.10.10-4.1.x86_64/

脚本将解码如下的日志行,这些日志行显示内核在发生错误时正在执行的代码的地址:

[   68.387301] RIP: 0010:test_module_init+0x5/0xffa [test_module]

解码之后,这些行将变成这样:

[   68.387301] RIP: 0010:test_module_init (/home/username/linux-5.10.5/test-module/test-module.c:16) test_module

在本例中,执行的代码是从文件“~/linux-5.10.5/test-module/test-module.c”构建的, 错误出现在第16行的指令中。

该脚本也会如此解码以“Call trace”开头的部分中提到的地址,该部分显示出现问题的 函数的路径。此外,脚本还会显示内核正在执行的代码部分的汇编输出。

注意,如果你没法做到这一点,只需跳过这一步,并在报告中说明原因。如果你幸运的 话,可能无需解码。如果需要的话,也许有人会帮你做这件事情。还要注意,这只是解 码内核堆栈跟踪的几种方法之一。有时需要采取不同的步骤来检索相关的详细信息。 别担心,如果您碰到的情况需要这样做,开发人员会告诉您该怎么做。

对回归的特别关照

如果您的问题是回归问题,请尽可能缩小引入问题时的范围。

Linux 首席开发者 Linus Torvalds 认为 Linux 内核永远不应恶化,这就是为什么他 认为回归是不可接受的,并希望看到它们被迅速修复。这就是为什么引入了回归的改 动导致的问题若无法通过其他方式快速解决,通常会被迅速撤销。因此,报告回归有 点像“王炸”,会迅速得到修复。但要做到这一点,需要知道导致回归的变化。通常情 况下,要由报告者来追查罪魁祸首,因为维护者往往没有时间或手头设置不便来自行 重现它。

有一个叫做“二分”的过程可以来寻找变化,这在 “二分(bisect)缺陷”文档中进行了详细 的描述,这个过程通常需要你构建十到二十个内核镜像,每次都尝试在构建下一个镜像 之前重现问题。是的,这需要花费一些时间,但不用担心,它比大多数人想象的要快得多。 多亏了“binary search二进制搜索”,这将引导你在源代码管理系统中找到导致回归的提交。 一旦你找到它,就在网上搜索其主题、提交ID和缩短的提交ID(提交ID的前12个字符)。 如果有的话,这将引导您找到关于它的现有报告。

需要注意的是,二分法需要一点窍门,不是每个人都懂得诀窍,也需要相当多的努力, 不是每个人都愿意投入。尽管如此,还是强烈建议自己进行一次二分。如果你真的 不能或者不想走这条路,至少要找出是哪个主线内核引入的回归。比如说从 5.5.15 切换到 5.8.4 的时候出现了一些问题,那么至少可以尝试一下相近的所有的主线版本 (5.6、5.7 和 5.8)来检查它是什么时候出现的。除非你想在一个稳定版或长期支持 内核中找到一个回归,否则要避免测试那些编号有三段的版本(5.6.12、5.7.8),因 为那会使结果难以解释,可能会让你的测试变得无用。一旦你找到了引入回归的主要 版本,就可以放心地继续报告了。但请记住:在不知道罪魁祸首的情况下,开发人员 是否能够提供帮助取决于手头的问题。有时他们可能会从报告中确认是什么出现了问 题,并能修复它;有时他们可能无法提供帮助,除非你进行二分。

当处理回归问题时,请确保你所面临的问题真的是由内核引起的,而不是由其他东西 引起的,如上文所述。

在整个过程中,请记住:只有当旧内核和新内核的配置相似时,问题才算回归。最好 的方法是:把配置文件(.config)从旧的工作内核直接复制到你尝试的每个新内 核版本。之后运行 make oldnoconfig 来调整它以适应新版本的需要,而不启用 任何新的功能,因为那些功能也可能导致回归。

撰写并发送报告

通过详细描述问题来开始编写报告。记得包括以下条目:您为复现而安装的最新 内核版本、使用的Linux发行版以及关于如何复现该问题的说明。如果可能,将内 核构建配置(.config)和 ``dmesg`` 的输出放在网上的某个地方,并链接到它。 包含或上传所有其他可能相关的信息,如Oops的输出/截图或来自 ``lspci`` 的输出。一旦你写完了这个主要部分,请在上方插入一个正常长度的段落快速概 述问题和影响。再在此之上添加一个简单描述问题的句子,以得到人们的阅读。 现在给出一个更短的描述性标题或主题。然后就可以像MAINTAINERS文件告诉你的 那样发送或提交报告了,除非你在处理一个“高优先级问题”:它们需要按照下面 “高优先级问题的特殊处理”所述特别关照。

现在你已经准备好了一切,是时候写你的报告了。上文前言中链接的三篇文档对如何 写报告做了部分解释。这就是为什么本文将只提到一些基本的内容以及 Linux 内核特 有的东西。

有一点是符合这两类的:你的报告中最关键的部分是标题/主题、第一句话和第一段。 开发者经常会收到许多邮件。因此,他们往往只是花几秒钟的时间浏览一下邮件,然 后再决定继续下一封或仔细查看。因此,你报告的开头越好,有人研究并帮助你的机 会就越大。这就是为什么你应该暂时忽略他们,先写出详细的报告。;-)

每份报告都应提及的事项

详细描述你的问题是如何发生在你安装的新纯净内核上的。试着包含你之前写的和优 化过的分步说明,概述你和其他人如何重现这个问题;在极少数无法重现的情况下, 尽量描述你做了什么来触发它。

还应包括其他人为了解该问题及其环境而可能需要的所有相关信息。实际需要的东西 在很大程度上取决于具体问题,但有些事项你总是应该包括在内:

  • cat /proc/version 的输出,其中包含 Linux 内核版本号和构建时的编译器。
  • 机器正在运行的 Linux 发行版( hostnamectl | grep “Operating System“
  • CPU 和操作系统的架构( uname -mi
  • 如果您正在处理回归,并进行了二分,请提及导致回归的变更的主题和提交ID。

许多情况下,让读你报告的人多了解两件事也是明智之举:

  • 用于构建 Linux 内核的配置(“.config”文件)
  • 内核的信息,你从 dmesg 得到的信息写到一个文件里。确保它以像“Linux version 5.8-1 (foobar@example.com) (gcc (GCC) 10.2.1, GNU ld version 2.34) #1 SMP Mon Aug 3 14:54:37 UTC 2020”这样的行开始,如果没有,那么第 一次启动阶段的重要信息已经被丢弃了。在这种情况下,可以考虑使用 journalctl -b 0 -k ;或者你也可以重启,重现这个问题,然后调用 dmesg

这两个文件很大,所以直接把它们放到你的报告中是个坏主意。如果你是在缺陷跟踪 器中提交问题,那么将它们附加到工单中。如果你通过邮件报告问题,不要用附件附 上它们,因为那会使邮件变得太大,可以按下列之一做:

  • 将文件上传到某个公开的地方(你的网站,公共文件粘贴服务,在 bugzilla.kernel.org 上创建的工单……), 并在你的报告中放上链接。理想情况下请使用允许这些文件保存很多年的地方,因 为它们可能在很多年后对别人有用;例如 5 年或 10 年后,一个开发者正在修改 一些代码,而这些代码正是为了修复你的问题。
  • 把文件放在一边,然后说明你会在他人回复时再单独发送。只要记得报告发出去后, 真正做到这一点就可以了。;-)

提供这些东西可能是明智的

根据问题的不同,你可能需要提供更多的背景数据。这里有一些关于提供什么比较好 的建议:

  • 如果你处理的是内核的“warning”、“OOPS”或“panic”,请包含它。如果你不能复制 粘贴它,试着用netconsole网络终端远程跟踪或者至少拍一张屏幕的照片。
  • 如果问题可能与你的电脑硬件有关,请说明你使用的是什么系统。例如,如果你的 显卡有问题,请提及它的制造商,显卡的型号,以及使用的芯片。如果是笔记本电 脑,请提及它的型号名称,但尽量确保意义明确。例如“戴尔 XPS 13”就不很明确, 因为它可能是 2012 年的那款,那款除了看起来和现在销售的没有什么不同之外, 两者没有任何共同之处。因此,在这种情况下,要加上准确的型号,例如 2019 年内推出的 XPS 13 型号为“9380”或“7390”。像“联想 Thinkpad T590”这样的名字 也有些含糊不清:这款笔记本有带独立显卡和不带的子型号,所以要尽量找到准确 的型号名称或注明主要部件。
  • 说明正在使用的相关软件。如果你在加载模块时遇到了问题,你要说明正在使用的 kmod、systemd 和 udev 的版本。如果其中一个 DRM 驱动出现问题,你要说明 libdrm 和 Mesa 的版本;还要说明你的 Wayland 合成器或 X-Server 及其驱动。 如果你有文件系统问题,请注明相应的文件系统实用程序的版本(e2fsprogs, btrfs-progs, xfsprogs……)。
  • 从内核中收集可能有用的额外信息。例如, lspci -nn 的输出可以帮助别人 识别你使用的硬件。如果你的硬件有问题,你甚至可以给出 sudo lspci -vvv 的结果,因为它提供了组件是如何配置的信息。对于一些问题,可能最好包含 /proc/cpuinfo/proc/ioports/proc/iomem/proc/modules/proc/scsi/scsi 等文件的内容。一些子系统还提 供了收集相关信息的工具。 alsa-info.sh 就是这样一个工具,它是音频/声 音子系统开发者提供的

这些例子应该会给你一些知识点,让你知道附上什么数据可能是明智的,但你自己也 要想一想,哪些数据对别人会有帮助。不要太担心忘记一些东西,因为开发人员会要 求提供他们需要的额外细节。但从一开始就把所有重要的东西都提供出来,会增加别 人仔细查看的机会。

重要部分:报告的开头

现在你已经准备好了报告的详细部分,让我们进入最重要的部分:开头几句。现在到 报告的最前面,在你刚才写的部分之前加上类似“The detailed description:”(详细 描述)这样的内容,并在最前面插入两个新行。现在写一个正常长度的段落,大致概 述这个问题。去掉所有枯燥的细节,把重点放在读者需要知道的关键部分,以让人了 解这是怎么回事;如果你认为这个缺陷影响了很多用户,就提一下这点来吸引大家关 注。

做好这一点后,在顶部再插入两行,写一句话的摘要,快速解释报告的内容。之后你 要更加抽象,为报告写一个更短的主题/标题。

现在你已经写好了这部分,请花点时间来优化它,因为它是你的报告中最重要的部分: 很多人会先读这部分,然后才会决定是否值得花时间阅读其他部分。

现在就像 MAINTAINERS 维护者文件告诉你的那样发送或提交 报告,除非它是前面概述的那些“高优先级问题”之一:在这种情况下,请先阅读下一 小节,然后再发送报告。

高优先级问题的特殊处理

高优先级问题的报告需要特殊处理。

非常严重的缺陷 :确保在主题或工单标题以及第一段中明显标出 severeness (非常严重的)。

回归 :如果问题是一个回归,请在邮件的主题或缺陷跟踪器的标题中添加 [REGRESSION]。如果您没有进行二分,请至少注明您测试的最新主线版本(比如 5.7) 和出现问题的最新版本(比如 5.8)。如果您成功地进行了二分,请注明导致回归 的提交ID和主题。也请添加该变更的作者到你的报告中;如果您需要将您的缺陷提交 到缺陷跟踪器中,请将报告以私人邮件的形式转发给他,并注明报告提交地点。

安全问题 :对于这种问题,你将必须评估:如果细节被公开披露,是否会对其他 用户产生短期风险。如果不会,只需按照所述继续报告问题。如果有此风险,你需要 稍微调整一下报告流程。

  • 如果 MAINTAINERS 文件指示您通过邮件报告问题,请不要抄送任何公共邮件列表。
  • 如果你应该在缺陷跟踪器中提交问题,请确保将工单标记为“私有”或“安全问题”。 如果缺陷跟踪器没有提供保持报告私密性的方法,那就别想了,把你的报告以私人 邮件的形式发送给维护者吧。

在这两种情况下,都一定要将报告发到 MAINTAINERS 文件中“安全联络”部分列出的 地址。理想的情况是在发送报告的时候直接抄送他们。如果您在缺陷跟踪器中提交了 报告,请将报告的文本转发到这些地址;但请在报告的顶部加上注释,表明您提交了 报告,并附上工单链接。

更多信息请参见“安全缺陷”。

发布报告后的责任

等待别人的反应,继续推进事情,直到你能够接受这样或那样的结果。因此,请 公开和及时地回应任何询问。测试提出的修复。积极地测试:至少重新测试每个 新主线版本的首个候选版本(RC),并报告你的结果。如果出现拖延,就友好地 提醒一下。如果你没有得到任何帮助或者未能满意,请试着自己帮助自己。

如果你的报告非常优秀,而且你真的很幸运,那么某个开发者可能会立即发现导致问 题的原因;然后他们可能会写一个补丁来修复、测试它,并直接发送给主线集成,同 时标记它以便以后回溯到需要它的稳定版和长期支持内核。那么你需要做的就是回复 一句“Thank you very much”(非常感谢),然后在发布后换上修复好的版本。

但这种理想状况很少发生。这就是为什么你把报告拿出来之后工作才开始。你要做的 事情要视情况而定,但通常会是下面列出的事情。但在深入研究细节之前,这里有几 件重要的事情,你需要记住这部分的过程。

关于进一步互动的一般建议

总是公开回复 :当你在缺陷跟踪器中提交问题时,一定要在那里回复,不要私下 联系任何开发者。对于邮件报告,在回复您收到的任何邮件时,总是使用“全部回复” 功能。这包括带有任何你可能想要添加到你的报告中的额外数据的邮件:进入邮件应 用程序“已发送”文件夹,并在邮件上使用“全部回复”来回复报告。这种方法可以确保 公共邮件列表和其他所有参与者都能及时了解情况;它还能保持邮件线程的完整性, 这对于邮件列表将所有相关邮件归为一类是非常重要的。

只有两种情况不适合在缺陷跟踪器或“全部回复”中发表评论:

  • 有人让你私下发东西。
  • 你被告知要发送一些东西,但注意到其中包含需要保密的敏感信息。在这种情况下, 可以私下发送给要求发送的开发者。但要在工单或邮件中注明你是这么做的,这 样其他人就知道你尊重了这个要求。

在请求解释或帮助之前先研究一下 :在这部分过程中,有人可能会告诉你用尚未 掌握的技能做一些事情。例如你可能会被要求使用一些你从未听说过的测试工具;或 者你可能会被要求在 Linux 内核源代码上应用一个补丁来测试它是否有帮助。在某些 情况下,发个回复询问如何做就可以了。但在走这条路之前,尽量通过在互联网上搜 索自行找到答案;或者考虑在其他地方询问建议。比如询问朋友,或者到你平时常去 的聊天室或论坛发帖咨询。

要有耐心 :如果你真的很幸运,你可能会在几个小时内收到对你的报告的答复。 但大多数情况下会花费更多的时间,因为维护者分散在全球各地,因此可能在不同的 时区——在那里他们已经享受着远离键盘的夜晚。

一般来说,内核开发者需要一到五个工作日来回复报告。有时会花费更长的时间,因 为他们可能正忙于合并窗口、其他工作、参加开发者会议,或者只是在享受一个漫长 的暑假。

“高优先级的问题”(见上面的解释)例外:维护者应该尽快解决这些问题;这就是为 什么你应该最多等待一个星期(如果是紧急的事情,则只需两天),然后再发送友好 的提醒。

有时维护者可能没有及时回复;有时候可能会出现分歧,例如一个问题是否符合回归 的条件。在这种情况下,在邮件列表上提出你的顾虑,并请求其他人公开或私下回复 如何继续推进。如果失败了,可能应该让更高级别的维护者介入。如果是 WiFi 驱动, 那就是无线维护者;如果没有更高级别的维护者,或者其他一切努力都失败了,那 这可能是一种罕见的、可以让 Linus Torvalds 参与进来的情况。

主动测试 :每当一个新的主线内核版本的第一个预发布版本(rc1)发布的时候, 去检查一下这个问题是否得到了解决,或者是否有什么重要的变化。在工单中或在 回复报告的邮件中提及结果(确保所有参与讨论的人都被抄送)。这将表明你的承诺 和你愿意帮忙。如果问题持续存在,它也会提醒开发者确保他们不会忘记它。其他一 些不定期的重新测试(例如用rc3、rc5 和最终版本)也是一个好主意,但只有在相关 的东西发生变化或者你正在写什么东西的时候才报告你的结果。

这些些常规的事情就不说了,我们来谈谈报告后如何帮助解决问题的细节。

查询和测试请求

如果你的报告得到了回复则需履行以下责任:

检查与你打交道的人 :大多数情况下,会是维护者或特定代码区域的开发人员对 你的报告做出回应。但由于问题通常是公开报告的,所以回复的可能是任何人——包括 那些想要帮忙的人,但最后可能会用他们的问题或请求引导你完全偏离轨道。这很少 发生,但这是快速上网搜搜看你正在与谁互动是明智之举的许多原因之一。通过这样 做,你也可以知道你的报告是否被正确的人听到,因为如果讨论没有导致满意的问题 解决方案而淡出,之后可能需要提醒维护者(见下文)。

查询数据 :通常你会被要求测试一些东西或提供更多细节。尽快提供所要求的信 息,因为你已经得到了可能会帮助你的人的注意,你等待的时间越长就有越可能失去 关注;如果你不在数个工作日内提供信息,甚至可能出现这种结果。

测试请求 :当你被要求测试一个诊断补丁或可能的修复时,也要尽量及时测试。 但要做得恰当,一定不要急于求成:混淆事情很容易发生,这会给所有人带来许多困 惑。例如一个常见的错误是以为应用了一个带修复的建议补丁,但事实上并没有。即 使是有经验的测试人员也会偶尔发生这样的事情,但当有修复的内核和没有修复的内 核表现得一样时,他们大多时候会注意到。

当没有任何实质性进展时该怎么办

有些报告不会得到负有相关责任的 Linux 内核开发者的任何反应;或者围绕这个问题 的讨论有所发展,但渐渐淡出,没有任何实质内容产出。

在这种情况下,要等两个星期(最好是三个星期)后再发出友好的提醒:也许当你的 报告到达时,维护者刚刚离开键盘一段时间,或者有更重要的事情要处理。在写提醒 信的时候,要善意地问一下,是否还需要你这边提供什么来让事情推进下去。如果报 告是通过邮件发出来的,那就在邮件的第一行回复你的初始邮件(见上文),其中包 括下方的原始报告的完整引用:这是少数几种情况下,这样的“TOFU”(Text Over, Fullquote Under文字在上,完整引用在下)是正确的做法,因为这样所有的收件人都 会以适当的顺序立即让细节到手头上来。

在提醒之后,再等三周的回复。如果你仍然没有得到适当的反馈,你首先应该重新考 虑你的方法。你是否可能尝试接触了错误的人?是不是报告也许令人反感或者太混乱, 以至于人们决定完全远离它?排除这些因素的最好方法是:把报告给一两个熟悉 FLOSS 问题报告的人看,询问他们的意见。同时征求他们关于如何继续推进的建议。 这可能意味着:准备一份更好的报告,让这些人在你发出去之前对它进行审查。这样 的方法完全可以;只需说明这是关于这个问题的第二份改进的报告,并附上第一份报 告的链接。

如果报告是恰当的,你可以发送第二封提醒信;在其中询问为什么报告没有得到任何 回复。第二封提醒邮件的好时机是在新 Linux 内核版本的首个预发布版本(’rc1’) 发布后不久,因为无论如何你都应该在那个时候重新测试并提供状态更新(见上文)。

如果第二次提醒的结果又在一周内没有任何反应,可以尝试联系上级维护者询问意见: 即使再忙的维护者在这时候也至少应该发过某种确认。

记住要做好失望的准备:理想状况下维护者最好对每一个问题报告做出回应,但他们 只有义务解决之前列出的“高优先级问题”。所以,如果你得到的回复是“谢谢你的报告, 我目前有更重要的问题要处理,在可预见的未来没有时间去研究这个问题”,那请不 要太沮丧。

也有可能在缺陷跟踪器或列表中进行了一些讨论之后,什么都没有发生,提醒也无助 于激励大家进行修复。这种情况可能是毁灭性的,但在 Linux 内核开发中确实会发生。 这些和其他得不到帮助的原因在本文结尾处的“为什么有些问题在被报告后没有得到 任何回应或者仍然没有修复”中进行了解释。

如果你没有得到任何帮助或问题最终没有得到解决,不要沮丧:Linux 内核是 FLOSS, 因此你仍然可以自己帮助自己。例如,你可以试着找到其他受影响的人,和他们一 起合作来解决这个问题。这样的团队可以一起准备一份新的报告,提到团队有多少人, 为什么你们认为这是应该得到解决的事情。也许你们还可以一起缩小确切原因或引 入回归的变化,这往往会使修复更容易。而且如果运气好的话,团队中可能会有懂点 编程的人,也许能写出一个修复方案。

“报告稳定版和长期支持内核线的回归”的参考

本小节提供了在稳定版和长期支持内核线中面对回归时需要执行的步骤的详细信息。

确保特定版本线仍然受支持

检查内核开发人员是否仍然维护你关心的Linux内核版本线:去 kernel.org 的 首页,确保此特定版本线的最新版没有“[EOL]”标记。

大多数内核版本线只支持三个月左右,因为延长维护时间会带来相当多的工作。因此, 每年只会选择一个版本来支持至少两年(通常是六年)。这就是为什么你需要检查 内核开发者是否还支持你关心的版本线。

注意,如果 kernel.org 在首页上列出了两个“稳定”版本, 你应该考虑切换到较新的版本,而忘掉较旧的版本:对它的支持可能很快就会结束。 然后,它将被标记为“生命周期结束”(EOL)。达到这个程度的版本线仍然会在 kernel.org 首页上被显示一两周,但不适合用于测试和 报告。

搜索稳定版邮件列表

检查Linux稳定版邮件列表中的现有报告。

也许你所面临的问题已经被发现,并且已经或即将被修复。因此,请在 Linux 稳定 版邮件列表的档案 中搜索类似问题的报告。 如果你找到任何匹配的问题,可以考虑加入讨论,除非修复工作已经完成并计划很快 得到应用。

用最新版本复现问题

从特定的版本线安装最新版本作为纯净内核。确保这个内核没有被污染,并且仍 然存在问题,因为问题可能已经在那里被修复了。

在投入更多时间到这个过程中之前,你要检查这个问题是否在你关注的版本线的最新 版本中已经得到了修复。这个内核需要是纯净的,在问题发生之前不应该被污染,正 如上面已经在测试主线的过程中详细介绍过的一样。

您是否是第一次注意到供应商内核的回归?供应商的更改可能会发生变化。你需要重新 检查排除来这个问题。当您从5.10.4-vendor.42更新到5.10.5-vendor.43时,记录损坏 的信息。然后在测试了前一段中所述的最新5.10版本之后,检查Linux 5.10.4的普通版本 是否也可以正常工作。如果问题在那里出现,那就不符合上游回归的条件,您需要切换 回主逐步指南来报告问题。

报告回归

向Linux稳定版邮件列表发送一个简短的问题报告(stable@vger.kernel.org)。 大致描述问题,并解释如何复现。讲清楚首个出现问题的版本和最后一个工作正常 的版本。然后等待进一步的指示。

当报告在稳定版或长期支持内核线内发生的回归(例如在从5.10.4更新到5.10.5时), 一份简短的报告足以快速报告问题。因此只需要粗略的描述。

但是请注意,如果您能够指明引入问题的确切版本,这将对开发人员有很大帮助。因此 如果有时间的话,请尝试使用普通内核找到该版本。让我们假设发行版发布Linux内核 5.10.5到5.10.8的更新时发生了故障。那么按照上面的指示,去检查该版本线中的最新 内核,比如5.10.9。如果问题出现,请尝试普通5.10.5,以确保供应商应用的补丁不会 干扰。如果问题没有出现,那么尝试5.10.7,然后直到5.10.8或5.10.6(取决于结果) 找到第一个引入问题的版本。在报告中写明这一点,并指出5.10.9仍然存在故障。

前一段基本粗略地概述了“二分”方法。一旦报告出来,您可能会被要求做一个正确的 报告,因为它允许精确地定位导致问题的确切更改(然后很容易被恢复以快速修复问题)。 因此如果时间允许,考虑立即进行适当的二分。有关如何详细信息,请参阅“对回归的 特别关照”部分和文档“二分(bisect)缺陷”。

“报告仅在旧内核版本线中发生的问题”的参考

本节详细介绍了如果无法用主线内核重现问题,但希望在旧版本线(又称稳定版内核和 长期支持内核)中修复问题时需要采取的步骤。

有些修复太复杂

请做好准备,接下来的几个步骤可能无法在旧版本中解决问题:修复可能太大或 太冒险,无法移植到那里。

即使是微小的、看似明显的代码变化,有时也会带来新的、完全意想不到的问题。稳 定版和长期支持内核的维护者非常清楚这一点,因此他们只对这些内核进行符合 “所有你想知道的事情 - 关于linux稳定版发布”中所列出的 规则的修改。

复杂或有风险的修改不符合条件,因此只能应用于主线。其他的修复很容易被回溯到 最新的稳定版和长期支持内核,但是风险太大,无法集成到旧版内核中。所以要注意 你所希望的修复可能是那些不会被回溯到你所关心的版本线的修复之一。在这种情况 下,你将别无选择,要么忍受这个问题,要么切换到一个较新的 Linux 版本,除非你 想自己把修复补丁应用到你的内核中。

通用准备

执行上面“报告仅在旧内核版本线中发生的问题”一节中的前三个步骤。

您需要执行本指南另一节中已经描述的几个步骤。这些步骤将让您:

  • 检查内核开发人员是否仍然维护您关心的Linux内核版本行。
  • 在Linux稳定邮件列表中搜索退出的报告。
  • 检查最新版本。

检查代码历史和搜索现有的讨论

在Linux内核版本控制系统中搜索修复主线问题的更改,因为它的提交消息可能 会告诉你修复是否已经计划好了支持。如果你没有找到,搜索适当的邮件列表, 寻找讨论此类问题或同行评议可能修复的帖子;然后检查讨论是否认为修复不适 合支持。如果支持根本不被考虑,加入最新的讨论,询问是否有可能。

在许多情况下,你所处理的问题会发生在主线上,但已在主线上得到了解决。修正它 的提交也需要被回溯才能解决这个问题。这就是为什么你要搜索它或任何相关讨论。

  • 首先尝试在存放 Linux 内核源代码的 Git 仓库中找到修复。你可以通过 kernel.org 上的网页GitHub 上的镜像 来实现;如果你 有一个本地克隆,你也可以在命令行用 git log --grep=<pattern> 来搜索。

    如果你找到了修复,请查看提交消息的尾部是否包含了类似这样的“稳定版标签”:

    像上面这行,开发者标记了安全修复可以回传到 5.4 及以后的版本。大多数情况 下,它会在两周内被应用到那里,但有时需要更长的时间。

  • 如果提交没有告诉你任何东西,或者你找不到修复,请再找找关于这个问题的讨论。 用你最喜欢的搜索引擎搜索网络,以及 Linux kernel developers mailing list 内核开发者邮件列表 的档案。也可以 阅读上面的 定位导致问题的内核区域 一节,然后按照说明找到导致问题的子系 统:它的缺陷跟踪器或邮件列表存档中可能有你要找的答案。

  • 如果你看到了一个计划的修复,请按上所述在版本控制系统中搜索它,因为提交可 能会告诉你是否可以进行回溯。

    • 检查讨论中是否有任何迹象表明,该修复程序可能风险太大,无法回溯到你关心 的版本线。如果是这样的话,你必须忍受这个问题,或者切换到应用了修复的内 核版本线。
    • 如果修复的问题未包含稳定版标签,并且没有讨论过回溯问题,请加入讨论:如 果合适的话,请提及你所面对的问题的版本,以及你希望看到它被修复。

请求建议

前面的步骤之一应该会给出一个解决方案。如果仍未能成功,请向可能引起问题 的子系统的维护人员询问建议;抄送特定子系统的邮件列表以及稳定版邮件列表。

如果前面的三个步骤都没有让你更接近解决方案,那么只剩下一个选择:请求建议。 在你发给可能是问题根源的子系统的维护者的邮件中这样做;抄送子系统的邮件列表 以及稳定版邮件列表(stable@vger.kernel.org)。

为什么有些问题在报告后没有任何回应或仍未解决?

当向 Linux 开发者报告问题时,要注意只有“高优先级的问题”(回归、安全问题、严 重问题)才一定会得到解决。如果维护者或其他人都失败了,Linus Torvalds 他自己 会确保这一点。他们和其他内核开发者也会解决很多其他问题。但是要知道,有时他 们也会不能或不愿帮忙;有时甚至没有人发报告给他们。

最好的解释就是那些内核开发者常常是在业余时间为 Linux 内核做出贡献。内核中的 不少驱动程序都是由这样的程序员编写的,往往只是因为他们想让自己的硬件可以在 自己喜欢的操作系统上使用。

这些程序员大多数时候会很乐意修复别人报告的问题。但是没有人可以强迫他们这样 做,因为他们是自愿贡献的。

还有一些情况下,这些开发者真的很想解决一个问题,但却不能解决:有时他们缺乏 硬件编程文档来解决问题。这种情况往往由于公开的文档太简陋,或者驱动程序是通 过逆向工程编写的。

业余开发者迟早也会不再关心某驱动。也许他们的测试硬件坏了,被更高级的玩意取 代了,或者是太老了以至于只能在计算机博物馆里找到。有时开发者根本就不关心他 们的代码和 Linux 了,因为在他们的生活中一些不同的东西变得更重要了。在某些情 况下,没有人愿意接手维护者的工作——也没有人可以被强迫,因为对 Linux 内核的贡 献是自愿的。然而被遗弃的驱动程序仍然存在于内核中:它们对人们仍然有用,删除 它们可能导致回归。

对于那些为 Linux 内核工作而获得报酬的开发者来说,情况并没有什么不同。这些人 现在贡献了大部分的变更。但是他们的雇主迟早也会停止关注他们的代码或者让程序 员专注于其他事情。例如,硬件厂商主要通过销售新硬件来赚钱;因此,他们中的不 少人并没有投入太多时间和精力来维护他们多年前就停止销售的东西的 Linux 内核驱 动。企业级 Linux 发行商往往持续维护的时间比较长,但在新版本中往往会把对老旧 和稀有硬件的支持放在一边,以限制范围。一旦公司抛弃了一些代码,往往由业余贡 献者接手,但正如上面提到的:他们迟早也会放下代码。

优先级是一些问题没有被修复的另一个原因,因为维护者相当多的时候是被迫设置这 些优先级的,因为在 Linux 上工作的时间是有限的。对于业余时间或者雇主给予他们 的开发人员用于上游内核维护工作的时间也是如此。有时维护人员也会被报告淹没, 即使一个驱动程序几乎完美地工作。为了不被完全缠住,程序员可能别无选择,只能 对问题报告进行优先级排序而拒绝其中的一些报告。

不过这些都不用太过担心,很多驱动都有积极的维护者,他们对尽可能多的解决问题 相当感兴趣。

结束语

与其他免费/自由&开源软件(Free/Libre & Open Source Software,FLOSS)相比, 向 Linux 内核开发者报告问题是很难的:这个文档的长度和复杂性以及字里行间的内 涵都说明了这一点。但目前就是这样了。这篇文字的主要作者希望通过记录现状来为 以后改善这种状况打下一些基础。