2016-03-11 04:40:30

by Eric Wheeler

[permalink] [raw]
Subject: [PATCH-RFC]: sysrq-a: graceful reboot via kernel_restart(), similar to sysrq-o

Hello all,

We were having a discussion on the bcache list about the safest reboot
options via sysrq here:
http://thread.gmane.org/gmane.linux.kernel.bcache.devel/3559/focus=3586

The result of the discussion ended up in a patch for sysrq-a to call
kernel_restart much in the same way as sysrq-ocalls kernel_power_off.

Please comment on the patch and suggest any appropriate changes.

Thank you!

--
Eric Wheeler


===================================================
diff --git a/Documentation/sysrq.txt b/Documentation/sysrq.txt
index 0e307c9..cf43fc8 100644
--- a/Documentation/sysrq.txt
+++ b/Documentation/sysrq.txt
@@ -65,6 +65,11 @@ On all - write a character to /proc/sysrq-trigger. e.g.:

* What are the 'command' keys?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+'a' - Attempt to semi-gracefully reboot via kernel_restart(NULL). This
+ is in-kernel only (bypasses init), but is cleaner than a hard
+ reboot such as sysrq-b. sysrq-a is functionally similar to 'o' but
+ calls kernel_restart() instead of kernel_power_off().
+
'b' - Will immediately reboot the system without syncing or unmounting
your disks.

diff --git a/kernel/reboot.c b/kernel/reboot.c
index d20c85d..8181749 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -16,6 +16,7 @@
#include <linux/syscalls.h>
#include <linux/syscore_ops.h>
#include <linux/uaccess.h>
+#include <linux/sysrq.h>

/*
* this indicates whether you can reboot with ctrl-alt-del: the default is yes
@@ -555,3 +556,42 @@ static int __init reboot_setup(char *str)
return 1;
}
__setup("reboot=", reboot_setup);
+
+
+/*
+ * When the user hits Sys-Rq 'a' to kernel_restart the machine this is the
+ * callback we use.
+ */
+
+static void do_krestart(struct work_struct *dummy)
+{
+ /* are these two necessary? */
+ lockdep_off();
+ local_irq_enable();
+
+ /* restart */
+ kernel_restart(NULL);
+}
+
+static DECLARE_WORK(krestart_work, do_krestart);
+
+static void handle_krestart(int key)
+{
+ /* run sysrq krestart on boot cpu */
+ schedule_work_on(cpumask_first(cpu_online_mask), &krestart_work);
+}
+
+static struct sysrq_key_op sysrq_krestart_op = {
+ .handler = handle_krestart,
+ .help_msg = "kernel_restart(a)",
+ .action_msg = "Gracefullish Restart",
+ .enable_mask = SYSRQ_ENABLE_BOOT,
+};
+
+static int __init pm_sysrq_krestart_init(void)
+{
+ register_sysrq_key('a', &sysrq_krestart_op);
+ return 0;
+}
+
+subsys_initcall(pm_sysrq_krestart_init);
===================================================


2016-03-11 05:13:19

by Marc MERLIN

[permalink] [raw]
Subject: Re: [PATCH-RFC]: sysrq-a: graceful reboot via kernel_restart(), similar to sysrq-o

On Fri, Mar 11, 2016 at 04:35:21AM +0000, Eric Wheeler wrote:
> Hello all,
>
> We were having a discussion on the bcache list about the safest reboot
> options via sysrq here:
> http://thread.gmane.org/gmane.linux.kernel.bcache.devel/3559/focus=3586
>
> The result of the discussion ended up in a patch for sysrq-a to call
> kernel_restart much in the same way as sysrq-ocalls kernel_power_off.
>
> Please comment on the patch and suggest any appropriate changes.

Thanks Eric.

The quick rationale is that sysrq-r is not desirable to use if you're using
bcache, or software raid since it will reboot without giving them a
chance to properly sync their buffers and get into a clean state.

I've been using sysrq-o to get a clean shutdown, but of course that
actually powers off the server, and you then need to rely on something
like WOL to bring the machine back up, which isn't always easy or
possible.

This new reboot with proper flushing (kernel_power_off) allows for safe
reboots that don't upset bcache or software raid.

Thanks,
Marc
--
"A mouse is a device used to point at the xterm you want to type in" - A.S.R.
Microsoft is to operating systems ....
.... what McDonalds is to gourmet cooking
Home page: http://marc.merlins.org/ | PGP 1024R/763BE901