晚上好 世界

晚上好 世界

早安

这是一份对 RFC 9767 的中文翻译。请注意,这是一个技术性很强的文档,翻译力求准确传达技术含义,但可能不完全符合文学性的中文表达习惯。关键术语和协议字段名保留了英文原文以便对照。


[文件名称]: rfc9767.txt
[文件内容开始]

Internet Engineering Task Force (IETF)                    J. Richer, Ed.
Request for Comments: 9767                           Bespoke Engineering
Category: Standards Track                                     F. Imbault
ISSN: 2070-1721                                                 acert.io
                                                              April 2025

授权协商与授权协议(GNAP)资源服务器连接

摘要

授权协商与授权协议(GNAP)定义了一种机制,用于将授权委托给一个软件(客户端),并将该委托的结果和凭证传递给该软件。本扩展定义了资源服务器(RS)以可互操作的方式与授权服务器(AS)连接的方法。

More...


通常这是右Alt键被 <备用字符键> 占用导致的,把 <备用字符键> 换到其他的就可以了

2025-09-26T11:18:22.png

More...


死亡就像一个数学意义上无限大竖直平面玻璃那样,把 ObjectA 永远地、和活在世上的 ObjectB 相分隔开,ObjectAB 可以互相透过玻璃看到对方,两人的双手隔了层玻璃贴在一起,但再也不能相拥,也听不到对方的声音。ObjectB 眼睁睁目送着玻璃那头的 ObjectA 渐行渐远至 ,至此,世上再无 ObjectA。ObjectB 查遍世上每一处和 ObjectA 有关的信息,但世上再无 ObjectA。


本文翻译自 https://web.archive.org/web/20230502010825/https://01.org/blogs/rzhang/2015/best-practice-debug-linux-suspend/hibernate-issues ,原文发布于2015年9月25日,请注意时效性。

作者 张锐 (Zhang Rui)陈宇 (CHEN, YU) 于 2015 年 9 月 25 日

1 概述

当谈论 Linux* 挂起/休眠时,我们指的是以下三种受支持的系统睡眠状态:

  • STI (挂起到空闲) 是一种通用的、纯软件的、轻量级的系统睡眠状态。结合平台特定的驱动程序增强功能,此状态可用于在 Intel® 平台上达到 S0i3 状态。要进入此状态,运行 shell 命令:echo freeze > /sys/power/state
  • STR (挂起到内存) 可显著节省功耗,因为系统中除内存外的所有部件都进入低功耗状态。内存应置于自刷新模式以保留其内容。ACPI 平台在挂起到 RAM 后处于 S3 状态。要进入此状态,运行 shell 命令:echo mem > /sys/power/state
  • 休眠 (挂起到磁盘) 的操作方式与挂起到 RAM 类似,但包括一个将内存内容写入磁盘的最终步骤。在恢复时,会读取此内容并将内存恢复到挂起前的状态。通常,ACPI 平台在挂起到磁盘后处于 S4 状态。要进入此状态,运行 shell 命令:echo disk > /sys/power/state

有关每个系统低功耗状态的更多详细信息,请参阅 https://www.kernel.org/doc/Documentation/power/states.txt

有关 Linux 挂起/休眠的 sysfs 接口的更多详细信息,例如上面提到的 /sys/power/state,请参阅 https://www.kernel.org/doc/Documentation/power/interface.txt

英特尔开源技术中心 (OTC) 中国内核电源团队多年来一直致力于改进 Linux 电源管理子系统的质量。我们处理通过 Linux 邮件列表中的电子邮件或通过 https://bugzilla.kernel.org/ 提交的问题的经验表明:

  • 效率低下。这是因为在大多数情况下,开发人员无法在本地重现问题。因此,我们依赖用户提供问题症状的详细描述、必要的调试信息以及一些测试结果(如果需要)。由于不同的时区,准备好进一步调试可能需要数天甚至数周时间。
  • 额外工作。这是因为 Linux STI/STR/HTD 是系统级的低功耗状态,需要硬件、固件、Linux PM 核心以及许多其他内核组件(尤其是设备驱动程序)良好地协同工作。这意味着任何单个组件中的单个错误都可能破坏系统挂起/休眠。对于由其他组件引起的问题,即使我们找到了根本原因,在大多数情况下我们仍然需要依赖组件所有者提供适当的修复。

因此,本文档旨在帮助用户执行一些调试例程,以便他们能够:

  • 尽可能找到根本原因或缩小问题范围。
  • 通过提供以下内容来正确地提出问题:
    • 问题的精确描述。
    • 必要调试例程的测试结果。
    • 精确的组件和所有者,例如:Linux PM 核心、驱动程序、BIOS 等。
    </li>

本文档结构

第 2 章介绍了一些可在第 4 章中使用的常用调试方法。

第 3 章基于我们维护 Linux PM 的经验,介绍了一些可能导致 Linux 挂起/休眠失败的典型问题。

第 4 章根据问题的不同症状提供了分步说明。

因此,当用户遇到与挂起/休眠相关的问题时,我们建议用户在第 4 章中找到描述所遇问题的相应部分,并直接按照该章节的分步说明进行操作。

2 常见的挂起/休眠调试方法

这里列出了一些对遇到挂起/休眠相关问题的人员有用的常见调试方法。

2.1 initcall_debug

initcall_debug 启动选项添加到内核命令行(cmdline)将跟踪启动、挂起和恢复期间的初始化调用(initcalls)和驱动程序电源管理(pm)回调。它对于检查任何指定的驱动程序/组件是否失败非常有用。在调试 STI/STR/HTD 相关问题时,请确保始终启用它。通常,正向结果意味着回调没有错误/警告,并在合理的时间内返回 0。如下所示:

[   76.201970] calling 0000:00:02.0+ @ 2298, parent: pci0000:00
[   76.217006] call 0000:00:02.0+ returned 0 after 14677 usec

负向结果意味着回调要么包含一些错误/警告,要么需要不合理的长长时间才能完成。

2.2 no_console_suspend

no_console_suspend 启动选项添加到内核命令行可禁用挂起/休眠期间控制台的挂起。一旦添加此选项,调试消息可以在系统其余部分进入睡眠状态时到达各种控制台。这可能无法与所有控制台可靠地工作,但已知可与串行和 VGA 控制台一起工作。

2.3 ignore_loglevel

ignore_loglevel 启动选项添加到内核命令行会将所有内核消息打印到控制台,无论当前日志级别是什么,这对调试很有用。

2.4 dynamic debug (动态调试)

对于 STI/STR,添加 dyndbg="file suspend.c +p" 启动选项;对于 HTD,添加 file swap.c +p;file snapshot.c +p;file hibernate.c +p 启动选项可以启用动态调试。这样我们可以在休眠期间收集更多信息。

2.5 serial console (串行控制台)

串行控制台输出对于跟踪某些系统挂起问题非常有用,特别是在 VGA 控制台关闭或无法记录完整崩溃日志时。要启用串行控制台,在内核命令行中添加 console=ttyS0,115200no_console_suspend,然后在另一台机器上使用 minicom 或 GNU screen 等程序将串行端口也设置为 115200 8-N-1 以捕获日志。更多详细信息,请参阅 https://www.kernel.org/doc/Documentation/serial-console.txt

2.6 rtc trace (RTC 跟踪)

rtc trace 是一种功能,用于在挂起/恢复期间以“文件+行号”的形式捕获有问题的驱动程序,将其保存到 CMOS SRAM 中,并在下次启动时恢复。要启用此功能,请确保您的内核使用 CONFIG_PM_TRACE_RTC=y 构建,并且通过 echo 0 > /sys/power/pm_async 禁用 pm 异步。更多详细信息,请参考 https://www.kernel.org/doc/Documentation/power/s2ram.txt

测试结果:从失败的 STI/STR/HTD 重启后的 dmesg 输出。注意,重启必须在三分钟内发生,否则保存在 SRAM 中的数据将被破坏。

2.7 pm_async

目前,Linux 并行地挂起和恢复所有设备以节省时间。通过 echo 0 > /sys/power/pm_async 禁用异步挂起/恢复可用于检查挂起/休眠失败是否由某些未知的设备依赖性问题引起。这也可用于调整驱动程序挂起/恢复延迟。

测试结果:检查禁用异步挂起/恢复后问题是否仍然存在。

2.8 pm_test

pm_test 是一种调试方法,系统可以部分执行 STR/HTD,可用于缩小导致 STI/STR/HTD 失败的代码范围。请参阅 https://www.kernel.org/doc/Documentation/power/basic-pm-debugging.txt 获取更多详细信息。

测试结果:检查哪些测试模式有问题,哪些测试模式没有问题。如果可能,记录失败模式的 dmesg 输出。

2.9 ACPI wakeup (ACPI 唤醒)

/proc/acpi/wakeup 列出了所有 ACPI 设备的唤醒能力,如果可用,还引用了物理设备。如下例所示操作此文件可以启用/禁用设备的唤醒能力。例如,您可以通过执行以下操作来禁用/启用“enabled”/“disabled”设备:

root@linux-machine# cat /proc/acpi/wakeup
Device  S-state   Status   Sysfs node
...
EHC1      S4    *enabled   pci:0000:00:1d.0
...
root@linux-machine# echo EHC1 > /proc/acpi/wakeup
root@linux-machine# cat /proc/acpi/wakeup
Device  S-state   Status   Sysfs node
...
EHC1      S4    *disabled  pci:0000:00:1d.0
...

测试结果:禁用和启用每个设备的唤醒能力是否能解决问题。

2.10 acpidump

acpidump 是一个可用于转储 BIOS 提供的 ACPI 表的工具。这在调试可能由 ACPI 引起的挂起/休眠问题时很有帮助。要获取该工具,只需进入内核源代码的 tools/power/acpi/ 目录并运行 “make”。

2.11 rtcwake

rtcwake 是一个可用于进入系统睡眠状态(挂起/休眠)直到指定唤醒时间的工具。您可以轻松地使用它来执行挂起/休眠压力测试。例如,您可以使用这个简单的脚本轻松运行 1000 次 STR 循环:

for i in $(seq 1000); do
    rtcwake –m mem –s 30
done

2.12 analyze_suspend

analyze_suspend 工具为系统开发人员提供了可视化挂起和恢复之间活动的能力,使他们能够识别低效环节和瓶颈。例如,您可以使用以下命令启动:

./analyze_suspend.py -rtcwake 30 -f -m mem

30 秒后系统会自动恢复,并在 ./suspend-yymmddyy-hhmmss 目录中生成 3 个文件:

mem_dmesg.txt  mem_ftrace.txt  mem.html

您可以首先用浏览器打开 mem.html 文件,然后深入研究 mem_ftrace.txt 以获取数据细节。您可以通过 git 获取 analyze_suspend 工具:

git clone https://github.com/01org/suspendresume.git

更多详细信息,请访问主页:https://01.org/suspendresume

测试结果:mem_dmesg.txt mem_ftrace.txt mem.html

2.13 disk mode (磁盘模式)

这仅用于 HTD。尝试运行 echo {shutdown/reboot} > /sys/power/disk 以在运行 echo disk > /sys/power/state 之前跳过某些可能存在错误的平台特定代码。在 ACPI 平台上,使用此选项时,系统实际上进入的是 S5 状态而不是 S4 状态。

测试结果:当 /sys/power/disk 等于 shutdown 或 reboot 时,问题是否仍然存在。

3 典型的挂起/休眠问题

3.1 回归 (Regression)

回归是指挂起/休眠以前工作良好,但在升级内核后失败。在这种情况下,找到根本原因并解决问题的最快、最有效的方法是使用 git bisect 找出是哪个提交引入了问题,然后将问题报告给提交作者/组件所有者。

3.2 驱动程序特定问题

有问题的驱动程序可能导致:

  • 系统无法挂起(挂起命令返回错误代码)。
  • 系统在挂起/恢复期间挂起。
  • 系统挂起/恢复时间过长。
  • 挂起/恢复后在 dmesg 中生成调试跟踪/错误日志。
  • 驱动程序本身无法工作。

因此,当您遇到挂起/休眠相关问题时,通常首先要验证问题是否是驱动程序特定问题。如果在恢复/挂起失败后系统有响应(您可以通过 VGA/串行控制台、ssh 等访问系统),请尝试使用 initcall_debugno_console_suspend 启动选项重现问题。如果有,请执行以下操作:

  1. 将驱动程序构建为模块
  2. 卸载驱动程序
  3. 挂起并恢复机器
  4. 使用以下命令重新加载驱动程序:modprobe -r foo && echo mem > /sys/power/state & modprobe foo
  5. 如果驱动程序不可卸载,则通过 Kconfig 设置完全不构建该驱动程序。

如果问题无法重现,并且错误/警告在此之后不再出现,那么这就是一个驱动程序特定问题。

如果系统无响应,请执行以下操作:

  1. 启用串行控制台并使用 initcall_debugno_console_suspend 启动。
  2. 检查串行控制台输出中是否有驱动程序引起的错误/警告。
  3. 如果发现任何错误/警告,将驱动程序构建为模块。
  4. 卸载驱动程序。
  5. 如果驱动程序无法在运行时卸载,则通过 Kconfig 设置完全不构建该驱动程序。
  6. 挂起并恢复机器。
  7. 重新加载驱动程序:modprobe -r foo && echo mem > /sys/power/state & modprobe foo

如果问题无法重现,并且错误/警告在这些步骤之后不再出现,那么就是这些驱动程序导致了问题。

如果系统恢复后工作正常,但某些驱动程序不再工作,请执行以下操作:

  1. 将驱动程序构建为模块。
  2. 卸载驱动程序
  3. 挂起并恢复机器
  4. 重新加载驱动程序:modprobe -r foo && echo mem > /sys/power/state & modprobe foo

如果问题不可重现,则这是一个驱动程序特定问题。

对于这些问题,请直接向驱动程序/组件所有者提交错误报告,因为这些问题表明有问题的驱动程序/组件破坏了 Linux 挂起/休眠。

以下部分讨论了一些可能破坏挂起/休眠的典型驱动程序特定问题。

3.2.1 图形问题

每当系统在挂起/休眠期间挂起,或者恢复后显示器不再显示时,请尝试以下步骤:

  1. 禁用您正在使用的内核图形驱动程序。在 Intel 平台上,设置 CONFIG_DRM_I915=n
  2. 注意: 不要在命令行中使用 nomodeset modprobe.blacklist=i915,因为有时 i915 驱动程序可能会被其他组件探测到。
  3. 再次尝试挂起/恢复。
  4. 如果恢复后看到黑屏且没有图形显示,请尝试通过串行控制台或 SSH 访问系统。如果系统仍在工作,则这是一个图形问题。
  5. 如果串行控制台和 SSH 都不可用,请按 PS/2 键盘上的 Num Lock 键。如果按下该键时 Num Lock LED 灯亮起,则使用键盘键入 reboot。虽然显示器没有显示,但如果系统成功重启,则很可能系统工作正常,这是一个图形问题。

对于图形问题,请在 https://bugs.freedesktop.org/ 提交错误报告。例如,我们通过 dmesg 输出中的以下提示行将挂起/休眠问题的根本原因隔离到图形驱动程序:

 

[  218.176542] ------------[ cut here ]------------
[  218.176550] WARNING: CPU: 1 PID: 221 at drivers/gpu/drm/i915/intel_lrc.c:1100 gen8_init_rcs_context+0x15d/0x160()
[  218.176552] WARN_ON(w->count == 0)
[  218.176553] Modules linked in:
[  218.176556] CPU: 1 PID: 221 Comm: kworker/u16:3 Tainted: G        W      3.18.0-eywa-dirty #30
[  218.176558] Hardware name: Intel Corporation Skylake Client platform/Skylake Y LPDDR3 RVP3, BIOS SKLSE2P1.86C.B060.R01.1411140050 11/14/2014
[  218.176564] Workqueue: events_unbound async_run_entry_fn
[  218.176567]  0000000000000009 ffff88009a96fad8 ffffffff82431683 0000000000000001
[  218.176570]  ffff88009a96fb28 ffff88009a96fb18 ffffffff8111e001 00000000fffe6b2d
[  218.176573]  ffff88009b42f300 0000000000000005 ffff88009b670000 ffff88009b671ce8
[  218.176574] Call Trace:
...
[  218.176657] ---[ end trace f587fddb962240b1 ]---

3.2.2 音频问题

我们尚未发现音频驱动程序会破坏挂起/休眠,但音频驱动程序本身可能需要很长时间才能恢复,如下例所示:

[   61.273112] calling  hdaudioC0D2+ @ 1236, parent: 0000:00:1f.3
[   64.295757] snd_hda_intel 0000:00:1f.3: azx_get_response timeout, switching to polling mode: last cmd=0x208f8100
[   65.303916] snd_hda_intel 0000:00:1f.3: No response from codec, disabling MSI: last cmd=0x208f8100
[   66.312147] snd_hda_intel 0000:00:1f.3: azx_get_response timeout, switching to single_cmd mode: last cmd=0x208f8100
[   66.312402] azx_single_wait_for_response: 153 callbacks suppressed
[   66.323406] snd_hda_codec_hdmi hdaudioC0D2: Unable to sync register 0x2f0d00. -5
[   66.323791] snd_hda_codec_hdmi hdaudioC0D2: HDMI: invalid ELD buf size -1
[   66.324179] snd_hda_codec_hdmi hdaudioC0D2: HDMI: invalid ELD buf size -1
[   66.324565] snd_hda_codec_hdmi hdaudioC0D2: HDMI: invalid ELD buf size -1
[   66.324571] call hdaudioC0D2+ returned 0 after 4932188 usecs

在这种情况下,请提交一个音频错误报告

3.2.3 USB 问题

通常,USB 问题不会导致系统挂起,但某些 USB 设备可能在系统恢复后停止工作。如果某些 USB 设备(如 USB 鼠标/键盘/网络)在系统恢复后停止工作,而其他设备(如 PS/2 键盘)似乎工作正常,请检查 dmesg/串行日志中是否有任何 USB 警告。如果发现警告,这很可能是一个 USB 问题。例如:

[   21.203077] xhci-hcd: probe of xhci-hcd.1.auto failed with error -110

在这种情况下,提交一个USB 错误报告

3.2.4 mmc 问题

MMC 故障可能导致挂起操作,尤其是挂起到磁盘,失败。检查挂起期间 dmesg 和串行控制台输出中的 MMC 警告。例如:

[   90.373541] mmc1: Timeout waiting for hardware interrupt.
[  160.493633] mmc1: error -110 during resume (card was removed?)

如果根文件系统(rootfs)不在 MMC 上,请尝试使用 "modprobe.blacklist=mmc_block" 启动选项再次测试。如果根文件系统在 MMC 上,请使用类似 USB 驱动器的方式启动相同的内核/发行版,并在命令行中使用 modprobe.blacklist=mmc_block 再次尝试。如果在黑名单中排除 MMC 驱动程序后问题消失,请提交一个MMC 错误报告

3.2.5 i2c 问题

我们也遇到过几个由 I2C 引起的错误。例如:

calling i2c_designware.0+ @ 2867, parent: 0000:00:15.0
------------[ cut here ]------------
WARNING: CPU: 1 PID: 2867 at drivers/clk/clk.c:845 __clk_disable+0x5b/0x60()
[] warn_slowpath_null+0x1a/0x20
[] __clk_disable+0x5b/0x60
[] clk_disable+0x37/0x50
[] dw_i2c_suspend+0x29/0x40

在这种情况下,提交一个I2C 错误报告

4 调试挂起/休眠问题

4.1 状态不可用

4.1.1 症状

运行 cat /sys/power/state 的输出中没有列出 "freeze"/"mem"/"disk",因此系统无法进入 STI/STR/HTD 状态。

4.1.2 调试步骤

  1. 对于 STI:
    • 检查内核是否使用 CONFIG_SUSPEND 构建。如果没有,请设置它。
    • 检查内核是否使用内核参数 relative_sleep_states=1 启动。如果是,请删除它。
  2. 对于 STR:
    • 检查内核是否使用 CONFIG_SUSPEND 构建。如果没有,请设置它。
    • 检查启动后的 dmesg 输出中是否有类似 ACPI: (supports S0 S3 S4 S5) 的行。如果未列出 S3,通常意味着平台不支持 S3。如果不确定,请提交一个挂起/休眠错误报告。
  3. 对于 HTD:
    • 检查内核是否使用 CONFIG_HIBERNATION 构建。如果没有,请使用 CONFIG_HIBERNATION=y 重新构建。
    • 检查启动后的 dmesg 输出中是否有类似 ACPI: (supports S0 S3 S4 S5) 的行。如果未列出 S4,通常意味着平台不支持 S4。如果不确定,请提交一个挂起/休眠错误报告。
  4. 如果上述测试后问题仍然存在,请提交一个挂起/休眠错误报告 [platform] {STI, STR, HTD}: state not available,并附上您正在使用的 dmesg 输出、acpidump 输出和内核配置文件。

4.2 挂起/休眠失败

4.2.1 症状

命令 echo freeze/mem/disk > /sys/power/state 返回错误代码。

4.2.2 调试步骤

  1. 检查这是否是回归问题。
  2. 如果不是,启用 initcall_debug 和 no_console_suspend。
  3. 如果发现某些设备回调返回错误代码而不是 0,这意味着该设备无法挂起,导致系统挂起/休眠中止。在这种情况下,向驱动程序/组件所有者提交错误报告。
  4. 如果不是,请提交一个挂起/休眠错误报告 [Platform] {STI, STR, HTD}: failed to suspend,并附上挂起失败后的 dmesg 输出以及返回的错误代码。

4.3 系统在挂起/休眠或恢复期间挂起

4.3.1 症状

发出 echo freeze/mem/disk > /sys/power/state 后,屏幕变黑,像成功挂起/休眠一样,但随后系统变得无响应,并且无法唤醒到工作状态。这可能发生在挂起或恢复期间。或者,系统按预期进入睡眠状态,但在恢复时没有响应,只显示黑屏或崩溃日志。例如,风扇开始旋转,任何现有的电源按钮背光发生变化,但系统永远不会恢复到工作状态。

4.3.2 调试步骤

  1. 检查这是否是回归问题。
  2. 如果不是,检查这是否是图形问题。
  3. 如果不是,检查这是否是驱动程序特定问题。
  4. 如果问题仍然存在,请提交一个挂起/休眠错误报告 [Platform] {STI, STR, HTD}: system hangs during suspend/resume,并附上问题重现后的串行控制台输出/屏幕截图、/var/log/kern.log 的内容以及磁盘模式(仅 HTD)、pm_test、pm_async 和 rtc trace 的测试结果。

4.4 系统在挂起/恢复期间重启

4.4.1 症状

屏幕变黑,并且在没有用户操作的情况下开始全新启动。

4.4.2 步骤

  1. 检查这是否是回归问题。
  2. 检查这是否是图形问题。
  3. 检查这是否是驱动程序特定问题。
  4. 如果不是,请提交一个挂起/休眠错误报告 [Platform] {STI, STR, HTD}: system reboot during suspend/resume,并附上问题重现后的串行控制台输出:/var/log/kern.log,以及磁盘模式(仅 HTD)、pm_test、pm_async 和 rtc trace 的测试结果。

4.5 恢复后系统错误

4.5.1 症状

系统可以挂起到 STI/STR/HTD 状态并从其恢复,但某些组件或驱动程序可能无法正常工作,或者在恢复后的 dmesg 中可能有错误或警告。

4.5.2 调试步骤

  1. 检查这是否是回归问题。
  2. 如果不是,检查这是否是驱动程序特定问题。
  3. 如果问题仍然存在,请提交一个挂起/休眠错误报告 [Platform] {STI, STR, HTD}: xxx broken after resume,并附上恢复后的 dmesg 输出。

4.6 挂起后系统立即唤醒

4.6.1 症状

系统在挂起后不久即返回工作状态,用户未进行任何操作。并且 dmesg 显示系统已完成完整的挂起/恢复周期。

4.6.2 调试步骤

  1. 检查这是否是回归问题。
  2. 通过移除任何不必要的外设(如 USB 驱动器、网线等)来检查这是否是驱动程序特定问题。
  3. 如果不是,请提交一个挂起/休眠错误报告 [Platform] {STI, STR, HTD}: system wakes up immediately after suspend,并附上 acpidump 输出、立即恢复后的 dmesg、挂起前后 /proc/interrupts 的内容以及 ACPI wakeup 的测试结果。

4.7 系统无法唤醒

4.7.1 症状

当您按下电源按钮、使用键盘等时,系统不会唤醒。

4.7.2 调试步骤

  1. 检查这是否是回归问题。对于 STI,检查驱动程序是否有自己管理的中断。如果有,检查是否为驱动程序使用的中断调用了 enable_irq_wake()。如果没有,请在驱动程序的 .probe() 或 .suspend() 回调中添加它。例如:
    static int bu21013_suspend(struct device *dev)
    {
        ...
        if (device_may_wakeup(&client->dev))
            enable_irq_wake(bu21013_data->irq);
        else
            disable_irq(bu21013_data->irq);
        ...
        return 0;
    }
  2. 如果问题仍然存在,请为 [Platform] {STI, STR, HTD}: XXX cannot wake up the system 提交一个挂起/休眠错误报告。确保在错误报告中包含 dmesg、acpidump 和 ACPI wakeup 的测试结果。

4.8 挂起/恢复期间延迟过长 (STI/STR/休眠)

4.8.1 症状

整体/特定驱动程序的挂起/恢复时间比预期/要求的要长。

4.8.2 调试步骤

  1. 如果您已经确定某个特定驱动程序挂起/恢复花费了太多时间,请向驱动程序所有者提交错误报告。
  2. 如果整体挂起/恢复延迟很高,请执行以下操作:
    1. 使用 initcall_debug 和 no_console_suspend 启动选项重启。
    2. 禁用异步挂起/恢复。
    3. 使用 analyze_suspend 重新进行挂起/恢复。
    4. 检查测试结果,找出在挂起/恢复期间花费最多时间的驱动程序和组件,并将问题连同 analyze_suspend 的测试结果一起报告给驱动程序/组件所有者。
    </li>

4.9 挂起/休眠偶尔失败

4.9.1 症状

症状可以是上面列出的任何症状,但区别在于这些问题不是 100% 可重现的。有时可能需要数十次甚至数百次挂起/休眠循环才能重现。

4.9.2 调试步骤

  1. 对于 HTD,
    1. 检查用于交换分区的驱动程序。
    2. 如果驱动程序构建为模块,请将驱动程序内置并检查问题是否仍然存在。
    3. 如果不存在,请提交一个挂起/休眠错误报告 [Platform] HTD: hibernate fails when disk driver is built as module
    4. 如果存在,请继续使用以下步骤进行调试。
    </li>
    <li>使用 initcall_debug、no_console_suspend、ignore_loglevel、dynamic debug 和 serial console 重启。</li>
    <li>使用 rtcwake 执行压力测试。</li>
    <li>当挂起/休眠失败时,按照上面最符合症状的章节中的说明进行验证并提出问题。</li>

5 提出问题

如果您已经缩小了问题范围,或者发现问题的根本原因是驱动程序特定问题:

  • 如果您知道在哪里为指定的驱动程序提出问题,请直接在那里提出。例如,对于图形问题,请在 https://bugs.freedesktop.org/ 提交错误报告。
  • 如果不清楚在何处提交问题,推荐的方式是在查阅http://vger.kernel.org/vger-lists.html后订阅相关子系统/驱动邮件列表,并在该列表中提出问题。提交问题时,请抄送[email protected]

如果不是驱动程序特定的问题,或者在调试后仍不确定问题所在,请在 https://bugzilla.kernel.org/enter_bug.cgi?product=Power%20Management 提交错误报告。将组件设置为“Hibernation/Suspend”,并包含所需的调试信息和测试结果。


在Linux系统中,分区文件系统是存储管理的两个关键层级:

  1. 分区:物理磁盘的逻辑划分,由分区表(GPT/MBR)定义边界

    • 操作工具:fdisk, cfdisk, parted
  2. 文件系统:在分区上构建的数据组织结构(ext4, Btrfs, XFS等)

    • 操作工具:mkfs, resize2fs, btrfs

cfdisk的本质:分区表手术刀

重要警告cfdisk 只操作分区表,不触及文件系统!它如同城市规划师重划地块边界,但不管地块上建筑物(文件系统)的死活。

危险操作示例

# 灾难性操作流程:
cfdisk /dev/sda      # 将sda1分区从100G缩小到30G
reboot               # 重启后系统崩溃
e2fsck /dev/sda1     # 报错:超级块损坏!

原因:文件系统实际占用50G空间,但分区被缩小到30G,尾部20G数据被物理截断。


安全分区调整四步法

步骤1:检查文件系统

sudo e2fsck -f /dev/sda1  # 强制检查ext4
sudo btrfs check /dev/sda2 # Btrfs检查

步骤2:缩小文件系统(如需缩小分区)

# ext4示例(缩小到40G):
sudo resize2fs /dev/sda1 40G

# Btrfs示例(先缩小文件系统):
sudo btrfs filesystem resize 40G /mount/point

步骤3:计算最小安全值

# ext4获取最小尺寸
MIN_BLOCKS=$(sudo dumpe2fs /dev/sda1 | grep "Block count" | awk '{print $3}')
BLOCK_SIZE=$(sudo dumpe2fs /dev/sda1 | grep "Block size" | awk '{print $3}')
MIN_SIZE=$((MIN_BLOCKS * BLOCK_SIZE / 1024**2)) # 转换为MB
echo "最小安全尺寸: ${MIN_SIZE}MB"

步骤4:使用cfdisk调整分区

sudo cfdisk /dev/sda

操作指南:

  1. 选择目标分区 → Resize
  2. 输入尺寸 ≥ MIN_SIZE (单位可用G/M,如+40G)
  3. 确认:WriteQuit

分区与文件系统操作对比表

操作类型工具示例影响范围风险等级必备前置操作
分区调整cfdisk fdisk修改分区表⚠️ 高危文件系统缩小/备份
文件系统调整resize2fs btrfs修改数据结构⚠️ 中危e2fsck/btrfs check
文件操作rm cp mv用户数据✅ 低危
元数据操作chmod chown文件属性✅ 低危

灾难恢复方案

情况1:分区误缩小但未重启

# 恢复分区表(需提前备份)
sudo sfdisk /dev/sda < partition-backup.txt

# 或使用testdisk恢复
sudo testdisk /dev/sda

情况2:文件系统已损坏

# ext4恢复超级块
sudo e2fsck -b 32768 /dev/sda1  # 使用备份超级块

# Btrfs恢复
sudo btrfs rescue zero-log /dev/sda2
sudo btrfs rescue fix-device-size /dev/sda2

终极数据抢救

# 创建磁盘镜像
sudo dd if=/dev/sda of=/mnt/external/sda.img conv=noerror,sync

# 使用Photorec扫描
sudo photorec /d /mnt/recovery/ /mnt/external/sda.img

最佳实践清单

  1. 分区操作黄金法则

    备份 → 检查 → 缩文件系统 → 缩分区 → 验证
  2. 必备备份命令

    # 分区表备份
    sudo sfdisk -d /dev/sda > sda-partition-table.bak
    
    # 文件系统备份
    sudo dd if=/dev/sda1 of=sda1-backup.img bs=4M status=progress
    
    # 数据备份
    sudo rsync -aAXv /home/ /backup/home/
  3. 安全调整工作流

    graph LR
    A[备份分区表] --> B[备份数据]
    B --> C[缩小文件系统]
    C --> D[计算最小尺寸]
    D --> E[cfdisk调整分区]
    E --> F[检查文件系统]
    F --> G[重启验证]

专家建议

"操作分区如同在飞行中更换引擎 - 必须遵循严格规程。永远记住:分区是地基,文件系统是建筑。重划地基时,必须先拆除上层的建筑(缩小文件系统)"

  • Linux存储工程师准则

最后忠告:对于生产系统:

  1. 优先考虑LVM动态分区
  2. 使用Btrfs/ZFS等支持在线调整的文件系统
  3. 虚拟机中先测试操作流程
  4. 确保UPS供电(笔记本充满电+插电)

理解分区与文件系统的层次关系,遵循安全操作流程,就能避免"分区缩小惨案"。存储无小事,操作需谨慎!