diff mbox series

[2/2] tty/sysrq: Add configurable handler to execute a compound action

Message ID 20200804162402.2087-3-andrzej.p@collabora.com (mailing list archive)
State Superseded
Headers show
Series Add configurable handler to execute a compound action | expand

Commit Message

Andrzej Pietrasiewicz Aug. 4, 2020, 4:24 p.m. UTC
Userland might want to execute e.g. 'w' (show blocked tasks), followed
by 's' (sync), followed by 1000 ms delay and then followed by 'c' (crash)
upon a single magic SysRq. Or one might want to execute the famous "Raising
Elephants Is So Utterly Boring" action. This patch adds a configurable
handler, triggered with 'C', for this exact purpose. The user specifies the
composition of the compound action using syntax similar to getopt, where
each letter corresponds to an individual action and a colon followed by a
number corresponds to a delay of that many milliseconds, e.g.:

ws:1000c

or

r:100eis:1000ub

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
---
 Documentation/admin-guide/sysrq.rst |  9 ++++
 drivers/tty/sysrq.c                 | 81 ++++++++++++++++++++++++++++-
 include/linux/sysrq.h               |  1 +
 3 files changed, 90 insertions(+), 1 deletion(-)

Comments

Jiri Slaby Aug. 12, 2020, 11:45 a.m. UTC | #1
On 04. 08. 20, 18:24, Andrzej Pietrasiewicz wrote:
> Userland might want to execute e.g. 'w' (show blocked tasks), followed
> by 's' (sync), followed by 1000 ms delay and then followed by 'c' (crash)
> upon a single magic SysRq. Or one might want to execute the famous "Raising
> Elephants Is So Utterly Boring" action. This patch adds a configurable
> handler, triggered with 'C', for this exact purpose. The user specifies the
> composition of the compound action using syntax similar to getopt, where
> each letter corresponds to an individual action and a colon followed by a
> number corresponds to a delay of that many milliseconds, e.g.:
> 
> ws:1000c
> 
> or
> 
> r:100eis:1000ub

I think I miss what's that good for, given I can do it one-by-one
without setting such strings anywhere (I usually want to do different
things on different kinds of crashes)?

> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
> ---
>  Documentation/admin-guide/sysrq.rst |  9 ++++
>  drivers/tty/sysrq.c                 | 81 ++++++++++++++++++++++++++++-
>  include/linux/sysrq.h               |  1 +
>  3 files changed, 90 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/admin-guide/sysrq.rst b/Documentation/admin-guide/sysrq.rst
> index 67dfa4c29093..80bdd8bf9636 100644
> --- a/Documentation/admin-guide/sysrq.rst
> +++ b/Documentation/admin-guide/sysrq.rst
> @@ -32,6 +32,7 @@ to 1. Here is the list of possible values in /proc/sys/kernel/sysrq:
>           64 =  0x40 - enable signalling of processes (term, kill, oom-kill)
>          128 =  0x80 - allow reboot/poweroff
>          256 = 0x100 - allow nicing of all RT tasks
> +        512 = 0x200 - allow compound action
>  
>  You can set the value in the file by the following command::
>  
> @@ -148,6 +149,14 @@ Command	    Function
>  
>  ``z``	    Dump the ftrace buffer
>  
> +``C``	    Execute a predefined, compound action. The action is defined with
> +	    sysrq.sysrq_compound_action module parameter, whose value contains known
> +	    command keys (except ``C`` to prevent recursion). The command keys can
> +	    be optionally followed by a colon and a number of milliseconds to wait
> +	    after executing the last action. For example:
> +
> +	    sysrq.sysrq_compound_action=r:100eis:1000ub
> +
>  ``0``-``9`` Sets the console log level, controlling which kernel messages
>              will be printed to your console. (``0``, for example would make
>              it so that only emergency messages like PANICs or OOPSes would
> diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
> index 52e344bfe8c0..ffcda1316675 100644
> --- a/drivers/tty/sysrq.c
> +++ b/drivers/tty/sysrq.c
> @@ -19,6 +19,7 @@
>  #include <linux/sched/rt.h>
>  #include <linux/sched/debug.h>
>  #include <linux/sched/task.h>
> +#include <linux/delay.h>
>  #include <linux/interrupt.h>
>  #include <linux/mm.h>
>  #include <linux/fs.h>
> @@ -439,6 +440,15 @@ static const struct sysrq_key_op sysrq_unrt_op = {
>  	.enable_mask	= SYSRQ_ENABLE_RTNICE,
>  };
>  
> +static void sysrq_action_compound(int key);
> +
> +static struct sysrq_key_op sysrq_action_compound_op = {
> +	.handler	= sysrq_action_compound,
> +	.help_msg	= "execute-compound-action(C)",
> +	.action_msg	= "Execute compound action",
> +	.enable_mask	= SYSRQ_ENABLE_COMPOUND,
> +};
> +
>  /* Key Operations table and lock */
>  static DEFINE_SPINLOCK(sysrq_key_table_lock);
>  
> @@ -501,7 +511,7 @@ static const struct sysrq_key_op *sysrq_key_table[62] = {
>  	&sysrq_ftrace_dump_op,		/* z */
>  	NULL,				/* A */
>  	NULL,				/* B */
> -	NULL,				/* C */
> +	&sysrq_action_compound_op,	/* C */
>  	NULL,				/* D */
>  	NULL,				/* E */
>  	NULL,				/* F */
> @@ -634,6 +644,7 @@ EXPORT_SYMBOL(handle_sysrq);
>  
>  #ifdef CONFIG_INPUT
>  static int sysrq_reset_downtime_ms;
> +static char *sysrq_compound_action;
>  
>  /* Simple translation table for the SysRq keys */
>  static const unsigned char sysrq_xlate[KEY_CNT] =
> @@ -787,6 +798,61 @@ static void sysrq_of_get_keyreset_config(void)
>  {
>  }
>  #endif
> +#define SYSRQ_COMPOUND_ACTION_VALIDATE	0
> +#define SYSRQ_COMPOUND_ACTION_RUN	1
> +
> +static int sysrq_process_compound_action(int pass)
> +{
> +	const char *action = sysrq_compound_action;
> +	const struct sysrq_key_op *op_p;
> +	int ret, delay;
> +
> +	while (*action) {
> +		op_p = __sysrq_get_key_op(*action);
> +		if (!op_p)
> +			return -EINVAL;
> +
> +		/* Don't allow calling ourselves recursively */
> +		if (op_p == &sysrq_action_compound_op)
> +			return -EINVAL;
> +
> +		if (pass == SYSRQ_COMPOUND_ACTION_RUN)
> +			__handle_sysrq(*action, false);
> +
> +		if (*++action == ':') {
> +			ret = sscanf(action++, ":%d", &delay);

You likely want %u and unsigned int. No negative delays.

> +			if (ret < 1) /* we want at least ":[0-9]" => 1 item */
> +				return -EINVAL;
> +
> +			while (*action >= '0' && *action <= '9')
> +				++action;
> +			if (pass == SYSRQ_COMPOUND_ACTION_RUN)
> +				mdelay(delay);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static void sysrq_action_compound(int key)
> +{
> +	if (!sysrq_compound_action) {
> +		pr_err("Unconfigured compound action for %s",
> +		       sysrq_action_compound_op.help_msg);

Missing \n.

> +		return;
> +	}
> +
> +	if (sysrq_process_compound_action(SYSRQ_COMPOUND_ACTION_VALIDATE)) {
> +		pr_err("Incorrect compound action %s for %s",

The same.

> +		       sysrq_compound_action,
> +		       sysrq_action_compound_op.help_msg);
> +
> +		return;
> +	}
> +
> +	sysrq_process_compound_action(SYSRQ_COMPOUND_ACTION_RUN);
> +}
>  
>  static void sysrq_reinject_alt_sysrq(struct work_struct *work)
>  {
> @@ -1079,8 +1145,21 @@ module_param_array_named(reset_seq, sysrq_reset_seq, sysrq_reset_seq,
>  
>  module_param_named(sysrq_downtime_ms, sysrq_reset_downtime_ms, int, 0644);
>  
> +module_param(sysrq_compound_action, charp, 0644);
> +MODULE_PARM_DESC(sysrq_compound_action,
> +	"Compound sysrq action to be executed on Alt-Shift-SysRq-C\n"
> +	"The compound action definition consists of known SysRq action letters except 'C',\n"
> +	"each letter can be optionally followed by a colon and a number of milliseconds to wait\n"
> +	"after executing the last action.\n"
> +	"Example:\n"
> +	"To unRaw, wait 100ms, tErminate, kIll, Sync, wait 1000ms, Unmount, Boot\n"
> +	"sysrq.sysrq_compound_action=r:100eis:1000ub");

This looks bad in the output, use at least one \t at the start of a new
line inside the string.
Andrzej Pietrasiewicz Aug. 17, 2020, 1:32 p.m. UTC | #2
Hi Jiri,

W dniu 12.08.2020 o 13:45, Jiri Slaby pisze:
> On 04. 08. 20, 18:24, Andrzej Pietrasiewicz wrote:
>> Userland might want to execute e.g. 'w' (show blocked tasks), followed
>> by 's' (sync), followed by 1000 ms delay and then followed by 'c' (crash)
>> upon a single magic SysRq. Or one might want to execute the famous "Raising
>> Elephants Is So Utterly Boring" action. This patch adds a configurable
>> handler, triggered with 'C', for this exact purpose. The user specifies the
>> composition of the compound action using syntax similar to getopt, where
>> each letter corresponds to an individual action and a colon followed by a
>> number corresponds to a delay of that many milliseconds, e.g.:
>>
>> ws:1000c
>>
>> or
>>
>> r:100eis:1000ub
> 
> I think I miss what's that good for, given I can do it one-by-one
> without setting such strings anywhere (I usually want to do different
> things on different kinds of crashes)?
> 

The "REISUB" action is a common way of handling a bad situation, though,
so having a shortcut for a common way is helpful, yet we are not forcing
this particular action to happen when the 'C' sysrq is invoked and offer
configurability instead.

I addressed the comments you had with regard to the code in a v2 series.

Regards,

Andrzej
kernel test robot Sept. 29, 2021, 10:31 p.m. UTC | #3
Hi Andrzej,

I love your patch! Yet something to improve:

[auto build test ERROR on bcf876870b95592b52519ed4aafcf9d95999bc9c]

url:    https://github.com/0day-ci/linux/commits/Andrzej-Pietrasiewicz/Add-configurable-handler-to-execute-a-compound-action/20210929-183114
base:   bcf876870b95592b52519ed4aafcf9d95999bc9c
config: um-x86_64_defconfig (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/c2e145de22842a121477d2c3dbe2bca210434138
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Andrzej-Pietrasiewicz/Add-configurable-handler-to-execute-a-compound-action/20210929-183114
        git checkout c2e145de22842a121477d2c3dbe2bca210434138
        # save the attached .config to linux build tree
        mkdir build_dir
        make W=1 O=build_dir ARCH=um SUBARCH=x86_64 SHELL=/bin/bash drivers/tty/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All error/warnings (new ones prefixed by >>):

   cc1: warning: arch/um/include/uapi: No such file or directory [-Wmissing-include-dirs]
>> drivers/tty/sysrq.c:1159:1: error: expected identifier or '(' before '{' token
    1159 | {
         | ^
   drivers/tty/sysrq.c: In function 'sysrq_action_compound':
>> drivers/tty/sysrq.c:1164:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    1164 | {
         | ^
   drivers/tty/sysrq.c:1168:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    1168 | {
         | ^
   drivers/tty/sysrq.c:1174:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    1174 | {
         | ^
   In file included from include/linux/linkage.h:7,
                    from include/linux/kernel.h:8,
                    from include/linux/list.h:9,
                    from include/linux/rculist.h:10,
                    from include/linux/sched/signal.h:5,
                    from drivers/tty/sysrq.c:18:
>> drivers/tty/sysrq.c:1188:19: error: storage class specified for parameter 'sysrq_toggle_support'
    1188 | EXPORT_SYMBOL_GPL(sysrq_toggle_support);
         |                   ^~~~~~~~~~~~~~~~~~~~
   include/linux/export.h:98:21: note: in definition of macro '___EXPORT_SYMBOL'
      98 |  extern typeof(sym) sym;       \
         |                     ^~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:159:33: note: in expansion of macro '_EXPORT_SYMBOL'
     159 | #define EXPORT_SYMBOL_GPL(sym)  _EXPORT_SYMBOL(sym, "_gpl")
         |                                 ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1188:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL'
    1188 | EXPORT_SYMBOL_GPL(sysrq_toggle_support);
         | ^~~~~~~~~~~~~~~~~
>> include/linux/export.h:99:20: error: storage class specified for parameter '__kstrtab_sysrq_toggle_support'
      99 |  extern const char __kstrtab_##sym[];     \
         |                    ^~~~~~~~~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:159:33: note: in expansion of macro '_EXPORT_SYMBOL'
     159 | #define EXPORT_SYMBOL_GPL(sym)  _EXPORT_SYMBOL(sym, "_gpl")
         |                                 ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1188:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL'
    1188 | EXPORT_SYMBOL_GPL(sysrq_toggle_support);
         | ^~~~~~~~~~~~~~~~~
>> include/linux/export.h:100:20: error: storage class specified for parameter '__kstrtabns_sysrq_toggle_support'
     100 |  extern const char __kstrtabns_##sym[];     \
         |                    ^~~~~~~~~~~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:159:33: note: in expansion of macro '_EXPORT_SYMBOL'
     159 | #define EXPORT_SYMBOL_GPL(sym)  _EXPORT_SYMBOL(sym, "_gpl")
         |                                 ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1188:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL'
    1188 | EXPORT_SYMBOL_GPL(sysrq_toggle_support);
         | ^~~~~~~~~~~~~~~~~
>> include/linux/export.h:101:24: error: expected declaration specifiers before ';' token
     101 |  __CRC_SYMBOL(sym, sec);       \
         |                        ^
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:159:33: note: in expansion of macro '_EXPORT_SYMBOL'
     159 | #define EXPORT_SYMBOL_GPL(sym)  _EXPORT_SYMBOL(sym, "_gpl")
         |                                 ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1188:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL'
    1188 | EXPORT_SYMBOL_GPL(sysrq_toggle_support);
         | ^~~~~~~~~~~~~~~~~
>> include/linux/export.h:102:2: error: expected declaration specifiers before 'asm'
     102 |  asm(" .section \"__ksymtab_strings\",\"aMS\",%progbits,1 \n" \
         |  ^~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:159:33: note: in expansion of macro '_EXPORT_SYMBOL'
     159 | #define EXPORT_SYMBOL_GPL(sym)  _EXPORT_SYMBOL(sym, "_gpl")
         |                                 ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1188:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL'
    1188 | EXPORT_SYMBOL_GPL(sysrq_toggle_support);
         | ^~~~~~~~~~~~~~~~~
   include/linux/export.h:67:36: error: storage class specified for parameter '__ksymtab_sysrq_toggle_support'
      67 |  static const struct kernel_symbol __ksymtab_##sym  \
         |                                    ^~~~~~~~~~
   include/linux/export.h:108:2: note: in expansion of macro '__KSYMTAB_ENTRY'
     108 |  __KSYMTAB_ENTRY(sym, sec)
         |  ^~~~~~~~~~~~~~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:159:33: note: in expansion of macro '_EXPORT_SYMBOL'
     159 | #define EXPORT_SYMBOL_GPL(sym)  _EXPORT_SYMBOL(sym, "_gpl")
         |                                 ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1188:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL'
    1188 | EXPORT_SYMBOL_GPL(sysrq_toggle_support);
         | ^~~~~~~~~~~~~~~~~
>> include/linux/export.h:67:22: error: parameter '__ksymtab_sysrq_toggle_support' is initialized
      67 |  static const struct kernel_symbol __ksymtab_##sym  \
         |                      ^~~~~~~~~~~~~
   include/linux/export.h:108:2: note: in expansion of macro '__KSYMTAB_ENTRY'
     108 |  __KSYMTAB_ENTRY(sym, sec)
         |  ^~~~~~~~~~~~~~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:159:33: note: in expansion of macro '_EXPORT_SYMBOL'
     159 | #define EXPORT_SYMBOL_GPL(sym)  _EXPORT_SYMBOL(sym, "_gpl")
         |                                 ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1188:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL'
    1188 | EXPORT_SYMBOL_GPL(sysrq_toggle_support);
         | ^~~~~~~~~~~~~~~~~
>> include/linux/export.h:67:36: error: section attribute not allowed for '__ksymtab_sysrq_toggle_support'
      67 |  static const struct kernel_symbol __ksymtab_##sym  \
         |                                    ^~~~~~~~~~
   include/linux/export.h:108:2: note: in expansion of macro '__KSYMTAB_ENTRY'
     108 |  __KSYMTAB_ENTRY(sym, sec)
         |  ^~~~~~~~~~~~~~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:159:33: note: in expansion of macro '_EXPORT_SYMBOL'
     159 | #define EXPORT_SYMBOL_GPL(sym)  _EXPORT_SYMBOL(sym, "_gpl")
         |                                 ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1188:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL'
    1188 | EXPORT_SYMBOL_GPL(sysrq_toggle_support);
         | ^~~~~~~~~~~~~~~~~
>> include/linux/export.h:67:22: warning: 'used' attribute ignored [-Wattributes]
      67 |  static const struct kernel_symbol __ksymtab_##sym  \
         |                      ^~~~~~~~~~~~~
   include/linux/export.h:108:2: note: in expansion of macro '__KSYMTAB_ENTRY'
     108 |  __KSYMTAB_ENTRY(sym, sec)
         |  ^~~~~~~~~~~~~~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:159:33: note: in expansion of macro '_EXPORT_SYMBOL'
     159 | #define EXPORT_SYMBOL_GPL(sym)  _EXPORT_SYMBOL(sym, "_gpl")
         |                                 ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1188:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL'
    1188 | EXPORT_SYMBOL_GPL(sysrq_toggle_support);
         | ^~~~~~~~~~~~~~~~~
>> include/linux/export.h:67:36: error: alignment may not be specified for '__ksymtab_sysrq_toggle_support'
      67 |  static const struct kernel_symbol __ksymtab_##sym  \
         |                                    ^~~~~~~~~~
   include/linux/export.h:108:2: note: in expansion of macro '__KSYMTAB_ENTRY'
     108 |  __KSYMTAB_ENTRY(sym, sec)
         |  ^~~~~~~~~~~~~~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:159:33: note: in expansion of macro '_EXPORT_SYMBOL'
     159 | #define EXPORT_SYMBOL_GPL(sym)  _EXPORT_SYMBOL(sym, "_gpl")
         |                                 ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1188:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL'
    1188 | EXPORT_SYMBOL_GPL(sysrq_toggle_support);
         | ^~~~~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1192:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    1192 | {
         | ^
   drivers/tty/sysrq.c:1215:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    1215 | {
         | ^
   In file included from include/linux/linkage.h:7,
                    from include/linux/kernel.h:8,
                    from include/linux/list.h:9,
                    from include/linux/rculist.h:10,
                    from include/linux/sched/signal.h:5,
                    from drivers/tty/sysrq.c:18:
>> drivers/tty/sysrq.c:1218:15: error: storage class specified for parameter 'register_sysrq_key'
    1218 | EXPORT_SYMBOL(register_sysrq_key);
         |               ^~~~~~~~~~~~~~~~~~
   include/linux/export.h:98:21: note: in definition of macro '___EXPORT_SYMBOL'
      98 |  extern typeof(sym) sym;       \
         |                     ^~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:158:29: note: in expansion of macro '_EXPORT_SYMBOL'
     158 | #define EXPORT_SYMBOL(sym)  _EXPORT_SYMBOL(sym, "")
         |                             ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1218:1: note: in expansion of macro 'EXPORT_SYMBOL'
    1218 | EXPORT_SYMBOL(register_sysrq_key);
         | ^~~~~~~~~~~~~
>> include/linux/export.h:99:20: error: storage class specified for parameter '__kstrtab_register_sysrq_key'
      99 |  extern const char __kstrtab_##sym[];     \
         |                    ^~~~~~~~~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:158:29: note: in expansion of macro '_EXPORT_SYMBOL'
     158 | #define EXPORT_SYMBOL(sym)  _EXPORT_SYMBOL(sym, "")
         |                             ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1218:1: note: in expansion of macro 'EXPORT_SYMBOL'
    1218 | EXPORT_SYMBOL(register_sysrq_key);
         | ^~~~~~~~~~~~~
>> include/linux/export.h:100:20: error: storage class specified for parameter '__kstrtabns_register_sysrq_key'
     100 |  extern const char __kstrtabns_##sym[];     \
         |                    ^~~~~~~~~~~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:158:29: note: in expansion of macro '_EXPORT_SYMBOL'
     158 | #define EXPORT_SYMBOL(sym)  _EXPORT_SYMBOL(sym, "")
         |                             ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1218:1: note: in expansion of macro 'EXPORT_SYMBOL'
    1218 | EXPORT_SYMBOL(register_sysrq_key);
         | ^~~~~~~~~~~~~
>> include/linux/export.h:101:24: error: expected declaration specifiers before ';' token
     101 |  __CRC_SYMBOL(sym, sec);       \
         |                        ^
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:158:29: note: in expansion of macro '_EXPORT_SYMBOL'
     158 | #define EXPORT_SYMBOL(sym)  _EXPORT_SYMBOL(sym, "")
         |                             ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1218:1: note: in expansion of macro 'EXPORT_SYMBOL'
    1218 | EXPORT_SYMBOL(register_sysrq_key);
         | ^~~~~~~~~~~~~
>> include/linux/export.h:102:2: error: expected declaration specifiers before 'asm'
     102 |  asm(" .section \"__ksymtab_strings\",\"aMS\",%progbits,1 \n" \
         |  ^~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:158:29: note: in expansion of macro '_EXPORT_SYMBOL'
     158 | #define EXPORT_SYMBOL(sym)  _EXPORT_SYMBOL(sym, "")
         |                             ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1218:1: note: in expansion of macro 'EXPORT_SYMBOL'
    1218 | EXPORT_SYMBOL(register_sysrq_key);
         | ^~~~~~~~~~~~~
   include/linux/export.h:67:36: error: storage class specified for parameter '__ksymtab_register_sysrq_key'
      67 |  static const struct kernel_symbol __ksymtab_##sym  \
         |                                    ^~~~~~~~~~
   include/linux/export.h:108:2: note: in expansion of macro '__KSYMTAB_ENTRY'
     108 |  __KSYMTAB_ENTRY(sym, sec)
         |  ^~~~~~~~~~~~~~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:158:29: note: in expansion of macro '_EXPORT_SYMBOL'
     158 | #define EXPORT_SYMBOL(sym)  _EXPORT_SYMBOL(sym, "")
         |                             ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1218:1: note: in expansion of macro 'EXPORT_SYMBOL'
    1218 | EXPORT_SYMBOL(register_sysrq_key);
         | ^~~~~~~~~~~~~
>> include/linux/export.h:67:22: error: parameter '__ksymtab_register_sysrq_key' is initialized
      67 |  static const struct kernel_symbol __ksymtab_##sym  \
         |                      ^~~~~~~~~~~~~
   include/linux/export.h:108:2: note: in expansion of macro '__KSYMTAB_ENTRY'
     108 |  __KSYMTAB_ENTRY(sym, sec)
         |  ^~~~~~~~~~~~~~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:158:29: note: in expansion of macro '_EXPORT_SYMBOL'
     158 | #define EXPORT_SYMBOL(sym)  _EXPORT_SYMBOL(sym, "")
         |                             ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1218:1: note: in expansion of macro 'EXPORT_SYMBOL'
    1218 | EXPORT_SYMBOL(register_sysrq_key);
         | ^~~~~~~~~~~~~
>> include/linux/export.h:67:36: error: section attribute not allowed for '__ksymtab_register_sysrq_key'
      67 |  static const struct kernel_symbol __ksymtab_##sym  \
         |                                    ^~~~~~~~~~
   include/linux/export.h:108:2: note: in expansion of macro '__KSYMTAB_ENTRY'
     108 |  __KSYMTAB_ENTRY(sym, sec)
         |  ^~~~~~~~~~~~~~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:158:29: note: in expansion of macro '_EXPORT_SYMBOL'
     158 | #define EXPORT_SYMBOL(sym)  _EXPORT_SYMBOL(sym, "")
         |                             ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1218:1: note: in expansion of macro 'EXPORT_SYMBOL'
    1218 | EXPORT_SYMBOL(register_sysrq_key);
         | ^~~~~~~~~~~~~
>> include/linux/export.h:67:22: warning: 'used' attribute ignored [-Wattributes]
      67 |  static const struct kernel_symbol __ksymtab_##sym  \
         |                      ^~~~~~~~~~~~~
   include/linux/export.h:108:2: note: in expansion of macro '__KSYMTAB_ENTRY'
     108 |  __KSYMTAB_ENTRY(sym, sec)
         |  ^~~~~~~~~~~~~~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:158:29: note: in expansion of macro '_EXPORT_SYMBOL'
     158 | #define EXPORT_SYMBOL(sym)  _EXPORT_SYMBOL(sym, "")
         |                             ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1218:1: note: in expansion of macro 'EXPORT_SYMBOL'
    1218 | EXPORT_SYMBOL(register_sysrq_key);
         | ^~~~~~~~~~~~~
>> include/linux/export.h:67:36: error: alignment may not be specified for '__ksymtab_register_sysrq_key'
      67 |  static const struct kernel_symbol __ksymtab_##sym  \
         |                                    ^~~~~~~~~~
   include/linux/export.h:108:2: note: in expansion of macro '__KSYMTAB_ENTRY'
     108 |  __KSYMTAB_ENTRY(sym, sec)
         |  ^~~~~~~~~~~~~~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:158:29: note: in expansion of macro '_EXPORT_SYMBOL'
     158 | #define EXPORT_SYMBOL(sym)  _EXPORT_SYMBOL(sym, "")
         |                             ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1218:1: note: in expansion of macro 'EXPORT_SYMBOL'
    1218 | EXPORT_SYMBOL(register_sysrq_key);
         | ^~~~~~~~~~~~~
   drivers/tty/sysrq.c:1221:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    1221 | {
         | ^
   In file included from include/linux/linkage.h:7,
                    from include/linux/kernel.h:8,
                    from include/linux/list.h:9,
                    from include/linux/rculist.h:10,
                    from include/linux/sched/signal.h:5,
                    from drivers/tty/sysrq.c:18:
   drivers/tty/sysrq.c:1224:15: error: storage class specified for parameter 'unregister_sysrq_key'
    1224 | EXPORT_SYMBOL(unregister_sysrq_key);
         |               ^~~~~~~~~~~~~~~~~~~~
   include/linux/export.h:98:21: note: in definition of macro '___EXPORT_SYMBOL'
      98 |  extern typeof(sym) sym;       \
         |                     ^~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:158:29: note: in expansion of macro '_EXPORT_SYMBOL'
     158 | #define EXPORT_SYMBOL(sym)  _EXPORT_SYMBOL(sym, "")
         |                             ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1224:1: note: in expansion of macro 'EXPORT_SYMBOL'
    1224 | EXPORT_SYMBOL(unregister_sysrq_key);
         | ^~~~~~~~~~~~~
   include/linux/export.h:99:20: error: storage class specified for parameter '__kstrtab_unregister_sysrq_key'
      99 |  extern const char __kstrtab_##sym[];     \
         |                    ^~~~~~~~~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:158:29: note: in expansion of macro '_EXPORT_SYMBOL'
     158 | #define EXPORT_SYMBOL(sym)  _EXPORT_SYMBOL(sym, "")
         |                             ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1224:1: note: in expansion of macro 'EXPORT_SYMBOL'
    1224 | EXPORT_SYMBOL(unregister_sysrq_key);
         | ^~~~~~~~~~~~~
   include/linux/export.h:100:20: error: storage class specified for parameter '__kstrtabns_unregister_sysrq_key'
     100 |  extern const char __kstrtabns_##sym[];     \
         |                    ^~~~~~~~~~~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:158:29: note: in expansion of macro '_EXPORT_SYMBOL'
     158 | #define EXPORT_SYMBOL(sym)  _EXPORT_SYMBOL(sym, "")
         |                             ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1224:1: note: in expansion of macro 'EXPORT_SYMBOL'
    1224 | EXPORT_SYMBOL(unregister_sysrq_key);
         | ^~~~~~~~~~~~~
   include/linux/export.h:101:24: error: expected declaration specifiers before ';' token
     101 |  __CRC_SYMBOL(sym, sec);       \
         |                        ^
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:158:29: note: in expansion of macro '_EXPORT_SYMBOL'
     158 | #define EXPORT_SYMBOL(sym)  _EXPORT_SYMBOL(sym, "")
         |                             ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1224:1: note: in expansion of macro 'EXPORT_SYMBOL'
    1224 | EXPORT_SYMBOL(unregister_sysrq_key);
         | ^~~~~~~~~~~~~
   include/linux/export.h:102:2: error: expected declaration specifiers before 'asm'
     102 |  asm(" .section \"__ksymtab_strings\",\"aMS\",%progbits,1 \n" \
         |  ^~~
   include/linux/export.h:147:39: note: in expansion of macro '___EXPORT_SYMBOL'
     147 | #define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
         |                                       ^~~~~~~~~~~~~~~~
   include/linux/export.h:155:34: note: in expansion of macro '__EXPORT_SYMBOL'
     155 | #define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "")
         |                                  ^~~~~~~~~~~~~~~
   include/linux/export.h:158:29: note: in expansion of macro '_EXPORT_SYMBOL'
     158 | #define EXPORT_SYMBOL(sym)  _EXPORT_SYMBOL(sym, "")
         |                             ^~~~~~~~~~~~~~
   drivers/tty/sysrq.c:1224:1: note: in expansion of macro 'EXPORT_SYMBOL'
    1224 | EXPORT_SYMBOL(unregister_sysrq_key);


vim +1159 drivers/tty/sysrq.c

  1158	
> 1159	{
  1160	}
  1161	
> 1162	static void sysrq_action_compound(int key)
  1163	static inline void sysrq_register_handler(void)
> 1164	{
  1165	}
  1166	
  1167	static inline void sysrq_unregister_handler(void)
  1168	{
  1169	}
  1170	
  1171	#endif /* CONFIG_INPUT */
  1172	
  1173	int sysrq_toggle_support(int enable_mask)
  1174	{
  1175		bool was_enabled = sysrq_on();
  1176	
  1177		sysrq_enabled = enable_mask;
  1178	
  1179		if (was_enabled != sysrq_on()) {
  1180			if (sysrq_on())
  1181				sysrq_register_handler();
  1182			else
  1183				sysrq_unregister_handler();
  1184		}
  1185	
  1186		return 0;
  1187	}
> 1188	EXPORT_SYMBOL_GPL(sysrq_toggle_support);
  1189	
  1190	static int __sysrq_swap_key_ops(int key, const struct sysrq_key_op *insert_op_p,
  1191	                                const struct sysrq_key_op *remove_op_p)
  1192	{
  1193		int retval;
  1194	
  1195		spin_lock(&sysrq_key_table_lock);
  1196		if (__sysrq_get_key_op(key) == remove_op_p) {
  1197			__sysrq_put_key_op(key, insert_op_p);
  1198			retval = 0;
  1199		} else {
  1200			retval = -1;
  1201		}
  1202		spin_unlock(&sysrq_key_table_lock);
  1203	
  1204		/*
  1205		 * A concurrent __handle_sysrq either got the old op or the new op.
  1206		 * Wait for it to go away before returning, so the code for an old
  1207		 * op is not freed (eg. on module unload) while it is in use.
  1208		 */
  1209		synchronize_rcu();
  1210	
  1211		return retval;
  1212	}
  1213	
  1214	int register_sysrq_key(int key, const struct sysrq_key_op *op_p)
  1215	{
  1216		return __sysrq_swap_key_ops(key, op_p, NULL);
  1217	}
> 1218	EXPORT_SYMBOL(register_sysrq_key);
  1219	
  1220	int unregister_sysrq_key(int key, const struct sysrq_key_op *op_p)
  1221	{
  1222		return __sysrq_swap_key_ops(key, NULL, op_p);
  1223	}
> 1224	EXPORT_SYMBOL(unregister_sysrq_key);
  1225	
  1226	#ifdef CONFIG_PROC_FS
  1227	/*
  1228	 * writing 'C' to /proc/sysrq-trigger is like sysrq-C
  1229	 */
  1230	static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
  1231					   size_t count, loff_t *ppos)
  1232	{
  1233		if (count) {
  1234			char c;
  1235	
  1236			if (get_user(c, buf))
  1237				return -EFAULT;
  1238			__handle_sysrq(c, false);
  1239		}
  1240	
  1241		return count;
  1242	}
  1243	
> 1244	static const struct proc_ops sysrq_trigger_proc_ops = {
> 1245		.proc_write	= write_sysrq_trigger,
  1246		.proc_lseek	= noop_llseek,
  1247	};
  1248	
  1249	static void sysrq_init_procfs(void)
  1250	{
  1251		if (!proc_create("sysrq-trigger", S_IWUSR, NULL,
  1252				 &sysrq_trigger_proc_ops))
  1253			pr_err("Failed to register proc interface\n");
  1254	}
  1255	
  1256	#else
  1257	
  1258	static inline void sysrq_init_procfs(void)
  1259	{
  1260	}
  1261	
  1262	#endif /* CONFIG_PROC_FS */
  1263	
  1264	static int __init sysrq_init(void)
  1265	{
  1266		sysrq_init_procfs();
  1267	
  1268		if (sysrq_on())
  1269			sysrq_register_handler();
  1270	
  1271		return 0;
  1272	}
> 1273	device_initcall(sysrq_init);

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/Documentation/admin-guide/sysrq.rst b/Documentation/admin-guide/sysrq.rst
index 67dfa4c29093..80bdd8bf9636 100644
--- a/Documentation/admin-guide/sysrq.rst
+++ b/Documentation/admin-guide/sysrq.rst
@@ -32,6 +32,7 @@  to 1. Here is the list of possible values in /proc/sys/kernel/sysrq:
          64 =  0x40 - enable signalling of processes (term, kill, oom-kill)
         128 =  0x80 - allow reboot/poweroff
         256 = 0x100 - allow nicing of all RT tasks
+        512 = 0x200 - allow compound action
 
 You can set the value in the file by the following command::
 
@@ -148,6 +149,14 @@  Command	    Function
 
 ``z``	    Dump the ftrace buffer
 
+``C``	    Execute a predefined, compound action. The action is defined with
+	    sysrq.sysrq_compound_action module parameter, whose value contains known
+	    command keys (except ``C`` to prevent recursion). The command keys can
+	    be optionally followed by a colon and a number of milliseconds to wait
+	    after executing the last action. For example:
+
+	    sysrq.sysrq_compound_action=r:100eis:1000ub
+
 ``0``-``9`` Sets the console log level, controlling which kernel messages
             will be printed to your console. (``0``, for example would make
             it so that only emergency messages like PANICs or OOPSes would
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 52e344bfe8c0..ffcda1316675 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -19,6 +19,7 @@ 
 #include <linux/sched/rt.h>
 #include <linux/sched/debug.h>
 #include <linux/sched/task.h>
+#include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/mm.h>
 #include <linux/fs.h>
@@ -439,6 +440,15 @@  static const struct sysrq_key_op sysrq_unrt_op = {
 	.enable_mask	= SYSRQ_ENABLE_RTNICE,
 };
 
+static void sysrq_action_compound(int key);
+
+static struct sysrq_key_op sysrq_action_compound_op = {
+	.handler	= sysrq_action_compound,
+	.help_msg	= "execute-compound-action(C)",
+	.action_msg	= "Execute compound action",
+	.enable_mask	= SYSRQ_ENABLE_COMPOUND,
+};
+
 /* Key Operations table and lock */
 static DEFINE_SPINLOCK(sysrq_key_table_lock);
 
@@ -501,7 +511,7 @@  static const struct sysrq_key_op *sysrq_key_table[62] = {
 	&sysrq_ftrace_dump_op,		/* z */
 	NULL,				/* A */
 	NULL,				/* B */
-	NULL,				/* C */
+	&sysrq_action_compound_op,	/* C */
 	NULL,				/* D */
 	NULL,				/* E */
 	NULL,				/* F */
@@ -634,6 +644,7 @@  EXPORT_SYMBOL(handle_sysrq);
 
 #ifdef CONFIG_INPUT
 static int sysrq_reset_downtime_ms;
+static char *sysrq_compound_action;
 
 /* Simple translation table for the SysRq keys */
 static const unsigned char sysrq_xlate[KEY_CNT] =
@@ -787,6 +798,61 @@  static void sysrq_of_get_keyreset_config(void)
 {
 }
 #endif
+#define SYSRQ_COMPOUND_ACTION_VALIDATE	0
+#define SYSRQ_COMPOUND_ACTION_RUN	1
+
+static int sysrq_process_compound_action(int pass)
+{
+	const char *action = sysrq_compound_action;
+	const struct sysrq_key_op *op_p;
+	int ret, delay;
+
+	while (*action) {
+		op_p = __sysrq_get_key_op(*action);
+		if (!op_p)
+			return -EINVAL;
+
+		/* Don't allow calling ourselves recursively */
+		if (op_p == &sysrq_action_compound_op)
+			return -EINVAL;
+
+		if (pass == SYSRQ_COMPOUND_ACTION_RUN)
+			__handle_sysrq(*action, false);
+
+		if (*++action == ':') {
+			ret = sscanf(action++, ":%d", &delay);
+			if (ret < 1) /* we want at least ":[0-9]" => 1 item */
+				return -EINVAL;
+
+			while (*action >= '0' && *action <= '9')
+				++action;
+			if (pass == SYSRQ_COMPOUND_ACTION_RUN)
+				mdelay(delay);
+		}
+	}
+
+	return 0;
+}
+
+static void sysrq_action_compound(int key)
+{
+	if (!sysrq_compound_action) {
+		pr_err("Unconfigured compound action for %s",
+		       sysrq_action_compound_op.help_msg);
+
+		return;
+	}
+
+	if (sysrq_process_compound_action(SYSRQ_COMPOUND_ACTION_VALIDATE)) {
+		pr_err("Incorrect compound action %s for %s",
+		       sysrq_compound_action,
+		       sysrq_action_compound_op.help_msg);
+
+		return;
+	}
+
+	sysrq_process_compound_action(SYSRQ_COMPOUND_ACTION_RUN);
+}
 
 static void sysrq_reinject_alt_sysrq(struct work_struct *work)
 {
@@ -1079,8 +1145,21 @@  module_param_array_named(reset_seq, sysrq_reset_seq, sysrq_reset_seq,
 
 module_param_named(sysrq_downtime_ms, sysrq_reset_downtime_ms, int, 0644);
 
+module_param(sysrq_compound_action, charp, 0644);
+MODULE_PARM_DESC(sysrq_compound_action,
+	"Compound sysrq action to be executed on Alt-Shift-SysRq-C\n"
+	"The compound action definition consists of known SysRq action letters except 'C',\n"
+	"each letter can be optionally followed by a colon and a number of milliseconds to wait\n"
+	"after executing the last action.\n"
+	"Example:\n"
+	"To unRaw, wait 100ms, tErminate, kIll, Sync, wait 1000ms, Unmount, Boot\n"
+	"sysrq.sysrq_compound_action=r:100eis:1000ub");
 #else
 
+{
+}
+
+static void sysrq_action_compound(int key)
 static inline void sysrq_register_handler(void)
 {
 }
diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h
index 3a582ec7a2f1..6df4442f12a9 100644
--- a/include/linux/sysrq.h
+++ b/include/linux/sysrq.h
@@ -28,6 +28,7 @@ 
 #define SYSRQ_ENABLE_SIGNAL	0x0040
 #define SYSRQ_ENABLE_BOOT	0x0080
 #define SYSRQ_ENABLE_RTNICE	0x0100
+#define SYSRQ_ENABLE_COMPOUND	0x0200
 
 struct sysrq_key_op {
 	void (* const handler)(int);