Message ID | 20200818112825.6445-3-andrzej.p@collabora.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add configurable handler to execute a compound action | expand |
On Tue, Aug 18, 2020 at 01:28:25PM +0200, 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 A macro language for sysrq commands, who would have thought... Anyway, _why_ would userland want to do something so crazy as this? What is the use-case here? thanks, greg k-h
Hi, W dniu 02.10.2020 o 14:54, Greg Kroah-Hartman pisze: > On Tue, Aug 18, 2020 at 01:28:25PM +0200, 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 > > A macro language for sysrq commands, who would have thought... > > Anyway, _why_ would userland want to do something so crazy as this? > What is the use-case here? > A use-case is Chromebooks which do want to execute 'w', 's', wait 1000ms and then 'c' under one key combination. Having that supported upstream brings us one little step closer to those machines running upstream kernel. Another argument for such a "macro language" is when a machine's system keeps degrading over time, possibly degrading (relatively) fast. "Raising Elephants Is So Utterly Boring" consists of 6 actions, each of which requires pressing several keys. The user might be unable to complete all the 6 steps, while a "macro" requires user's involvement for carrying out just one step. Regards, Andrzej
On Fri, Oct 02, 2020 at 03:42:52PM +0200, Andrzej Pietrasiewicz wrote: > Hi, > > W dniu 02.10.2020 o 14:54, Greg Kroah-Hartman pisze: > > On Tue, Aug 18, 2020 at 01:28:25PM +0200, 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 > > > > A macro language for sysrq commands, who would have thought... > > > > Anyway, _why_ would userland want to do something so crazy as this? > > What is the use-case here? > > > > A use-case is Chromebooks which do want to execute 'w', 's', > wait 1000ms and then 'c' under one key combination. Having that supported > upstream brings us one little step closer to those machines running > upstream kernel. Who is causing that to "execute"? Some daemon/program? > Another argument for such a "macro language" is when a machine's system > keeps degrading over time, possibly degrading (relatively) fast. > "Raising Elephants Is So Utterly Boring" consists of 6 actions, each > of which requires pressing several keys. The user might be unable > to complete all the 6 steps, while a "macro" requires user's involvement > for carrying out just one step. So you want to "preload" some commands ahead of time, for when you get in trouble? These should just be debugging / last resort types of things, how regular are they being used in your systems? thanks, greg k-h
Hi, W dniu 02.10.2020 o 16:02, Greg Kroah-Hartman pisze: > On Fri, Oct 02, 2020 at 03:42:52PM +0200, Andrzej Pietrasiewicz wrote: >> Hi, >> >> W dniu 02.10.2020 o 14:54, Greg Kroah-Hartman pisze: >>> On Tue, Aug 18, 2020 at 01:28:25PM +0200, 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 >>> >>> A macro language for sysrq commands, who would have thought... >>> >>> Anyway, _why_ would userland want to do something so crazy as this? >>> What is the use-case here? >>> >> >> A use-case is Chromebooks which do want to execute 'w', 's', >> wait 1000ms and then 'c' under one key combination. Having that supported >> upstream brings us one little step closer to those machines running >> upstream kernel. > > Who is causing that to "execute"? Some daemon/program? No, as far as I know they patch the kernel to change the behavior of Sysrq-x combination, so the "execution" is triggered by the user. > >> Another argument for such a "macro language" is when a machine's system >> keeps degrading over time, possibly degrading (relatively) fast. >> "Raising Elephants Is So Utterly Boring" consists of 6 actions, each >> of which requires pressing several keys. The user might be unable >> to complete all the 6 steps, while a "macro" requires user's involvement >> for carrying out just one step. > > So you want to "preload" some commands ahead of time, for when you get > in trouble It can be said this way, yes. > > These should just be debugging / last resort types of things, how > regular are they being used in your systems? > The "REISUB" itself is a kind of a last resort thing. It is true that it's not a very frequent situation, but does its being rare preclude having such a function in the kernel? While preparing this patch I wanted it to be flexible, but perhaps it is too flexible for some reason? If the permissions of the module_param's sysfs entry were changed to 0444 would it be better? Then the compound action would still be configurable but only at boot time rather than at boot time _and_ runtime. Regards, Andrzej
On Fri, Oct 02, 2020 at 05:06:54PM +0200, Andrzej Pietrasiewicz wrote: > Hi, > > W dniu 02.10.2020 o 16:02, Greg Kroah-Hartman pisze: > > On Fri, Oct 02, 2020 at 03:42:52PM +0200, Andrzej Pietrasiewicz wrote: > > > Hi, > > > > > > W dniu 02.10.2020 o 14:54, Greg Kroah-Hartman pisze: > > > > On Tue, Aug 18, 2020 at 01:28:25PM +0200, 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 > > > > > > > > A macro language for sysrq commands, who would have thought... > > > > > > > > Anyway, _why_ would userland want to do something so crazy as this? > > > > What is the use-case here? > > > > > > > > > > A use-case is Chromebooks which do want to execute 'w', 's', > > > wait 1000ms and then 'c' under one key combination. Having that supported > > > upstream brings us one little step closer to those machines running > > > upstream kernel. > > > > Who is causing that to "execute"? Some daemon/program? > > No, as far as I know they patch the kernel to change the behavior > of Sysrq-x combination, so the "execution" is triggered by the user. So this isn't coming from the chromeos team, so there is no guarantee that they will switch to this if it is merged? > > > Another argument for such a "macro language" is when a machine's system > > > keeps degrading over time, possibly degrading (relatively) fast. > > > "Raising Elephants Is So Utterly Boring" consists of 6 actions, each > > > of which requires pressing several keys. The user might be unable > > > to complete all the 6 steps, while a "macro" requires user's involvement > > > for carrying out just one step. > > > > So you want to "preload" some commands ahead of time, for when you get > > in trouble > It can be said this way, yes. > > > > > These should just be debugging / last resort types of things, how > > regular are they being used in your systems? > > > > The "REISUB" itself is a kind of a last resort thing. > > It is true that it's not a very frequent situation, but does its being rare > preclude having such a function in the kernel? > > While preparing this patch I wanted it to be flexible, but perhaps it is > too flexible for some reason? If the permissions of the module_param's > sysfs entry were changed to 0444 would it be better? Then the compound > action would still be configurable but only at boot time rather than at > boot time _and_ runtime. I don't have an issue with it happening at runtime and boot time, just that this is adding additional complexity to the kernel (parsers are fun!) for no real-world user. thanks, greg k-h
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 959f9e121cc6..e4ddea87c6db 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -20,6 +20,7 @@ #include <linux/sched/debug.h> #include <linux/sched/task.h> #include <linux/ctype.h> +#include <linux/delay.h> #include <linux/interrupt.h> #include <linux/mm.h> #include <linux/fs.h> @@ -438,6 +439,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); @@ -500,7 +510,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 */ @@ -633,6 +643,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] = @@ -786,6 +797,62 @@ 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; + unsigned int 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++, ":%u", &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\n", + sysrq_action_compound_op.help_msg); + + return; + } + + if (sysrq_process_compound_action(SYSRQ_COMPOUND_ACTION_VALIDATE)) { + pr_err("Incorrect compound action %s for %s\n", + 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) { @@ -1077,8 +1144,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, + "\tCompound sysrq action to be executed on Alt-Shift-SysRq-C\n" + "\tThe compound action definition consists of known SysRq action letters except 'C',\n" + "\teach letter can be optionally followed by a colon and a number of milliseconds to wait\n" + "\tafter executing the last action.\n" + "\tExample:\n" + "\tTo unRaw, wait 100ms, tErminate, kIll, Sync, wait 1000ms, Unmount, Boot\n" + "\tsysrq.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);
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 | 82 ++++++++++++++++++++++++++++- include/linux/sysrq.h | 1 + 3 files changed, 91 insertions(+), 1 deletion(-)