162306a36Sopenharmony_ci.. include:: ../disclaimer-zh_CN.rst
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci:Original: Documentation/admin-guide/sysrq.rst
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci:翻译:
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci 黄军华 Junhua Huang <huang.junhua@zte.com.cn>
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci:校译:
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci 司延腾 Yanteng Si <siyanteng@loongson.cn>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci.. _cn_admin-guide_sysrq:
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ciLinux 魔法系统请求键骇客
1662306a36Sopenharmony_ci========================
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci针对 sysrq.c 的文档说明
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci什么是魔法 SysRq 键?
2162306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci它是一个你可以输入的具有魔法般的组合键。
2462306a36Sopenharmony_ci无论内核在做什么,内核都会响应 SysRq 键的输入,除非内核完全卡死。
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci如何使能魔法 SysRq 键?
2762306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci在配置内核时,我们需要设置 'Magic SysRq key (CONFIG_MAGIC_SYSRQ)' 为 'Y'。
3062306a36Sopenharmony_ci当运行一个编译进 sysrq 功能的内核时,/proc/sys/kernel/sysrq 控制着被
3162306a36Sopenharmony_ciSysRq 键调用的功能许可。这个文件的默认值由 CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE
3262306a36Sopenharmony_ci配置符号设定,文件本身默认设置为 1。以下是 /proc/sys/kernel/sysrq 中可能的
3362306a36Sopenharmony_ci值列表:
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci   -  0 - 完全不使能 SysRq 键
3662306a36Sopenharmony_ci   -  1 - 使能 SysRq 键的全部功能
3762306a36Sopenharmony_ci   - >1 - 对于允许的 SysRq 键功能的比特掩码(参见下面更详细的功能描述)::
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci          2 =   0x2 - 使能对控制台日志记录级别的控制
4062306a36Sopenharmony_ci          4 =   0x4 - 使能对键盘的控制 (SAK, unraw)
4162306a36Sopenharmony_ci          8 =   0x8 - 使能对进程的调试导出等
4262306a36Sopenharmony_ci         16 =  0x10 - 使能同步命令
4362306a36Sopenharmony_ci         32 =  0x20 - 使能重新挂载只读
4462306a36Sopenharmony_ci         64 =  0x40 - 使能对进程的信号操作 (term, kill, oom-kill)
4562306a36Sopenharmony_ci        128 =  0x80 - 允许重启、断电
4662306a36Sopenharmony_ci        256 = 0x100 - 允许让所有实时任务变普通任务
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci你可以通过如下命令把值设置到这个文件中::
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci    echo "number" >/proc/sys/kernel/sysrq
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci这里被写入的 number 可以是 10 进制数,或者是带着 0x 前缀的 16 进制数。
5362306a36Sopenharmony_ciCONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE 必须是以 16 进制数写入。
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci注意,``/proc/sys/kernel/sysrq`` 的值只影响通过键盘触发 SySRq 的调用,对于
5662306a36Sopenharmony_ci通过 ``/proc/sysrq-trigger`` 的任何操作调用都是允许的
5762306a36Sopenharmony_ci(通过具有系统权限的用户)。
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci如何使用魔法 SysRq 键?
6062306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci在 x86 架构上
6362306a36Sopenharmony_ci	你可以按下键盘组合键 :kbd:`ALT-SysRq-<command key>`。
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci	.. note::
6662306a36Sopenharmony_ci	   一些键盘可能没有标识 'SySRq' 键。'SySRq' 键也被当做 'Print Screen'键。
6762306a36Sopenharmony_ci	   同时有些键盘无法处理同时按下这么多键,因此你可以先按下键盘 :kbd:`Alt` 键,
6862306a36Sopenharmony_ci	   然后按下键盘 :kbd:`SysRq` 键,再释放键盘 :kbd:`SysRq` 键,之后按下键盘上命令键
6962306a36Sopenharmony_ci	   :kbd:`<command key>`,最后释放所有键。
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci在 SPARC 架构上
7262306a36Sopenharmony_ci	你可以按下键盘组合键 :kbd:`ALT-STOP-<command key>` 。
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci在串行控制台(只针对 PC 类型的标准串口)
7562306a36Sopenharmony_ci        你可以发一个 ``BREAK`` ,然后在 5 秒内发送一个命令键,
7662306a36Sopenharmony_ci	发送 ``BREAK`` 两次将被翻译为一个正常的 BREAK 操作。
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci在 PowerPC 架构上
7962306a36Sopenharmony_ci	按下键盘组合键 :kbd:`ALT - Print Screen` (或者 :kbd:`F13`) - :kbd:`<命令键>` 。
8062306a36Sopenharmony_ci        :kbd:`Print Screen` (或者 :kbd:`F13`) - :kbd:`<命令键>` 或许也能实现。
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci在其他架构上
8362306a36Sopenharmony_ci	如果你知道其他架构的组合键,请告诉我,我可以把它们添加到这部分。
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci在所有架构上
8662306a36Sopenharmony_ci	写一个字符到 /proc/sysrq-trigger 文件,例如::
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci		echo t > /proc/sysrq-trigger
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci这个命令键 :kbd:`<command key>` 是区分大小写的。
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci什么是命令键?
9362306a36Sopenharmony_ci~~~~~~~~~~~~~~
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci=========== ================================================================
9662306a36Sopenharmony_ci命令键	    功能
9762306a36Sopenharmony_ci=========== ================================================================
9862306a36Sopenharmony_ci``b``	    将立即重启系统,不会同步或者卸载磁盘。
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci``c``	    将执行系统 crash,如果配置了系统 crashdump,将执行 crashdump。
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci``d``	    显示所有持有的锁。
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci``e``	    发送 SIGTERM 信号给所有进程,除了 init 进程。
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci``f``	    将调用 oom killer 杀掉一个过度占用内存的进程,如果什么任务都没杀,
10762306a36Sopenharmony_ci            也不会 panic。
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci``g``	    kgdb 使用(内核调试器)。
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci``h``	    将会显示帮助。(实际上除了这里列举的键,其他的都将显示帮助,
11262306a36Sopenharmony_ci	    但是 ``h`` 容易记住):-)
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci``i``	    发送 SIGKILL 给所有进程,除了 init 进程。
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci``j``	    强制性的 “解冻它” - 用于被 FIFREEZE ioctl 操作冻住的文件系统。
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci``k``	    安全访问秘钥(SAK)杀掉在当前虚拟控制台的所有程序,注意:参考
11962306a36Sopenharmony_ci            下面 SAK 节重要论述。
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci``l``	    显示所有活动 cpu 的栈回溯。
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci``m``	    将导出当前内存信息到你的控制台。
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci``n``	    用于使所有实时任务变成普通任务。
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci``o``	    将关闭系统(如果配置和支持的话)。
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci``p``	    将导出当前寄存器和标志位到控制台。
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci``q``	    将导出每个 cpu 上所有已装备的高精度定时器(不是完整的
13262306a36Sopenharmony_ci            time_list 文件显示的 timers)和所有时钟事件设备的详细信息。
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci``r``	    关闭键盘的原始模式,设置为转换模式。
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci``s``	    将尝试同步所有的已挂载文件系统。
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci``t``	    将导出当前所有任务列表和它们的信息到控制台。
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci``u``	    将尝试重新挂载已挂载文件系统为只读。
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci``v``	    强制恢复帧缓存控制台。
14362306a36Sopenharmony_ci``v``	    触发 ETM 缓存导出 [ARM 架构特有]
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci``w``	    导出处于不可中断状态(阻塞)的任务。
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci``x``	    在 ppc/powerpc 架构上用于 xmon 接口。
14862306a36Sopenharmony_ci            在 sparc64 架构上用于显示全局的 PMU(性能监控单元)寄存器。
14962306a36Sopenharmony_ci            在 MIPS 架构上导出所有的 tlb 条目。
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci``y``	    显示全局 cpu 寄存器 [SPARC-64 架构特有]
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci``z``	    导出 ftrace 缓存信息
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci``0``-``9`` 设置控制台日志级别,该级别控制什么样的内核信息将被打印到你的
15662306a36Sopenharmony_ci	    控制台。(比如 ``0`` ,将使得只有紧急信息,像 PANICs or OOPSes
15762306a36Sopenharmony_ci	    才能到你的控制台。)
15862306a36Sopenharmony_ci=========== ================================================================
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci好了,我能用他们做什么呢?
16162306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci嗯,当你的 X 服务端或者 svgalib 程序崩溃,unraw(r) 非原始模式命令键是非常
16462306a36Sopenharmony_ci方便的。
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_cisak(k)(安全访问秘钥)在你尝试登陆的同时,又想确保当前控制台没有可以获取你的
16762306a36Sopenharmony_ci密码的特洛伊木马程序运行时是有用的。它会杀掉给定控制台的所有程序,这样你
16862306a36Sopenharmony_ci就可以确认当前的登陆提示程序是实际来自 init 进程的程序,而不是某些特洛伊
16962306a36Sopenharmony_ci木马程序。
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci.. important::
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci   在其实际的形式中,在兼容 C2 安全标准的系统上,它不是一个真正的 SAK,
17462306a36Sopenharmony_ci   它也不应该误认为此。
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci似乎其他人发现其可以作为(系统终端联机键)当你想退出一个程序,
17762306a36Sopenharmony_ci同时不会让你切换控制台的方法。(比如,X 服务端或者 svgalib 程序)
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci``reboot(b)`` 是个好方法,当你不能关闭机器时,它等同于按下"复位"按钮。
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci``crash(c)`` 可以用于手动触发一个 crashdump,当系统卡住时。
18262306a36Sopenharmony_ci注意当 crashdump 机制不可用时,这个只是触发一个内核 crash。
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci``sync(s)`` 在拔掉可移动介质之前,或者在使用不提供优雅关机的
18562306a36Sopenharmony_ci救援 shell 之后很方便 -- 它将确保你的数据被安全地写入磁盘。注意,在你看到
18662306a36Sopenharmony_ci屏幕上出现 "OK" 和 "Done" 之前,同步还没有发生。
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci``umount(u)`` 可以用来标记文件系统正常卸载,从正在运行的系统角度来看,它们将
18962306a36Sopenharmony_ci被重新挂载为只读。这个重新挂载动作直到你看到 "OK" 和 "Done" 信息出现在屏幕上
19062306a36Sopenharmony_ci才算完成。
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci日志级别 ``0`` - ``9`` 用于当你的控制台被大量的内核信息冲击,你不想看见的时候。
19362306a36Sopenharmony_ci选择 ``0`` 将禁止除了最紧急的内核信息外的所有的内核信息输出到控制台。(但是如果
19462306a36Sopenharmony_cisyslogd/klogd 进程是运行的,它们仍将被记录。)
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci``term(e)`` 和 ``kill(i)`` 用于当你有些有点失控的进程,你无法通过其他方式杀掉
19762306a36Sopenharmony_ci它们的时候,特别是它正在创建其他进程。
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci"just thaw ``it(j)`` " 用于当你的系统由于一个 FIFREEZE ioctl 调用而产生的文件
20062306a36Sopenharmony_ci系统冻结,而导致的不响应时。
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci有的时候 SysRq 键在使用它之后,看起来像是“卡住”了,我能做些什么?
20362306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci这也会发生在我这,我发现轻敲键盘两侧的 shift、alt 和 control 键,然后再次敲击
20662306a36Sopenharmony_ci一个无效的 SysRq 键序列可以解决问题。(比如,像键盘组合键 :kbd:`alt-sysrq-z` )
20762306a36Sopenharmony_ci切换到另一个虚拟控制台(键盘操作 :kbd:`ALT+Fn` ),然后再切回来应该也有帮助。
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci我敲击了 SysRq 键,但像是什么都没发生,发生了什么错误?
21062306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci有一些键盘对于 SysRq 键设置了不同的键值,而不是提前定义的 99
21362306a36Sopenharmony_ci(查看在 ``include/uapi/linux/input-event-codes.h`` 文件中 ``KEY_SYSRQ`` 的定义)
21462306a36Sopenharmony_ci或者就根本没有 SysRq 键。在这些场景下,执行 ``showkey -s`` 命令来找到一个合适
21562306a36Sopenharmony_ci的扫描码序列,然后使用 ``setkeycodes <sequence> 99`` 命令映射这个序列值到通用
21662306a36Sopenharmony_ci的 SysRq 键编码上(比如 ``setkeycodes e05b 99`` )。最好将这个命令放在启动脚本
21762306a36Sopenharmony_ci中。
21862306a36Sopenharmony_ci哦,顺便说一句,你十秒钟不输入任何东西就将退出 “showkey”。
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci我想添加一个 SysRq 键事件到一个模块中,如何去做呢?
22162306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci为了注册一个基础函数到这个表中,首先你必须包含 ``include/linux/sysrq.h`` 头
22462306a36Sopenharmony_ci文件,这个头文件定义了你所需要的所有东西。然后你必须创建一个 ``sysrq_key_op``
22562306a36Sopenharmony_ci结构体,然后初始化它,使用如下内容,A) 你将使用的这个键的处理函数, B) 一个
22662306a36Sopenharmony_cihelp_msg 字符串,在 SysRq 键打印帮助信息时将打印出来,C) 一个 action_msg 字
22762306a36Sopenharmony_ci符串,就在你的处理函数调用前打印出来。你的处理函数必须符合在 'sysrq.h' 文件中
22862306a36Sopenharmony_ci的函数原型。
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci在 ``sysrq_key_op`` 结构体被创建后,你可以调用内核函数
23162306a36Sopenharmony_ci``register_sysrq_key(int key, const struct sysrq_key_op *op_p);``,
23262306a36Sopenharmony_ci该函数在表中的 'key' 对应位置内容是空的情况下,将通过 ``op_p`` 指针注册这个操作
23362306a36Sopenharmony_ci函数到表中 'key' 对应位置上。在模块卸载的时候,你必须调用
23462306a36Sopenharmony_ci``unregister_sysrq_key(int key, const struct sysrq_key_op *op_p)`` 函数,该函数
23562306a36Sopenharmony_ci只有在当前该键对应的处理函数被注册到了 'key' 对应位置时,才会移除 'op_p' 指针
23662306a36Sopenharmony_ci对应的键值操作函数。这是为了防止在你注册之后,该位置被改写的情况。
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci魔法 SysRq 键系统的工作原理是将键对应操作函数注册到键的操作查找表,
23962306a36Sopenharmony_ci该表定义在 'drivers/tty/sysrq.c' 文件中。
24062306a36Sopenharmony_ci该键表有许多在编译时候就注册进去的操作函数,但是是可变的。
24162306a36Sopenharmony_ci并且有两个函数作为操作该表的接口被导出::
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci	register_sysrq_key 和 unregister_sysrq_key.
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci当然,永远不要在表中留下无效指针,即,当你的模块存在调用 register_sysrq_key()
24662306a36Sopenharmony_ci函数,它一定要调用 unregister_sysrq_key() 来清除它使用过的 SysRq 键表条目。
24762306a36Sopenharmony_ci表中的空指针是安全的。:)
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci如果对于某种原因,在 handle_sysrq 调用的处理函数中,你认为有必要调用
25062306a36Sopenharmony_cihandle_sysrq 函数时,你必须意识到当前你处于一个锁中(你同时也处于一个中断处理
25162306a36Sopenharmony_ci函数中,这意味着不能睡眠)。所以这时你必须使用 ``__handle_sysrq_nolock`` 替代。
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci当我敲击一个 SysRq 组合键时,只有标题打印出现在控制台?
25462306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ciSysRq 键的输出和所有其他控制台输出一样,受制于控制台日志级别控制。
25762306a36Sopenharmony_ci这意味着,如果内核以发行版内核中常见的 "quiet" 方式启动,则输出可能不会出现在实际
25862306a36Sopenharmony_ci的控制台上,即使它会出现在 dmesg 缓存中,也可以通过 dmesg 命令和 ``/proc/kmsg``
25962306a36Sopenharmony_ci文件的消费访问到。作为一个特例,来自 sysrq 命令的标题行将被传递给所有控制台
26062306a36Sopenharmony_ci使用者,就好像当前日志级别是最大的一样。如果只发出标题头,则几乎可以肯定内核日志
26162306a36Sopenharmony_ci级别太低。如果你需要控制台上的输出,那么你将需要临时提高控制台日志级别,通过使用
26262306a36Sopenharmony_ci键盘组合键 :kbd:`alt-sysrq-8` 或者::
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ci    echo 8 > /proc/sysrq-trigger
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci在触发了你感兴趣的 SysRq 键命令后,记得恢复日志级别到正常情况。
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci我有很多问题时,可以请教谁?
26962306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ci请教在内核邮件列表上的人,邮箱:
27262306a36Sopenharmony_ci	linux-kernel@vger.kernel.org
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci致谢
27562306a36Sopenharmony_ci~~~~
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci- Mydraal <vulpyne@vulpyne.net> 撰写了该文件
27862306a36Sopenharmony_ci- Adam Sulmicki <adam@cfar.umd.edu> 进行了更新
27962306a36Sopenharmony_ci- Jeremy M. Dolan <jmd@turbogeek.org> 在 2001/01/28 10:15:59 进行了更新
28062306a36Sopenharmony_ci- Crutcher Dunnavant <crutcher+kernel@datastacks.com> 添加键注册部分
281