ping-sysrq.patch
authorCarsten Emde <C.Emde@osadl.org>
Tue, 19 Jul 2011 12:51:17 +0000 (13:51 +0100)
committerClark Williams <williams@redhat.com>
Wed, 15 Feb 2012 16:33:02 +0000 (10:33 -0600)
There are (probably rare) situations when a system crashed and the system
console becomes unresponsive but the network icmp layer still is alive.
Wouldn't it be wonderful, if we then could submit a sysreq command via ping?

This patch provides this facility. Please consult the updated documentation
Documentation/sysrq.txt for details.

Signed-off-by: Carsten Emde <C.Emde@osadl.org>
Documentation/sysrq.txt
include/net/netns/ipv4.h
net/ipv4/icmp.c
net/ipv4/sysctl_net_ipv4.c

index 312e3754e8c5599b00c644d64be5b9907bb64ada..9981f307ef0e4256c2dd1b5d09b85dbd6a0c7b58 100644 (file)
@@ -57,10 +57,17 @@ On PowerPC - Press 'ALT - Print Screen (or F13) - <command key>,
 On other - If you know of the key combos for other architectures, please
            let me know so I can add them to this section.
 
-On all -  write a character to /proc/sysrq-trigger.  e.g.:
-
+On all -  write a character to /proc/sysrq-trigger, e.g.:
                echo t > /proc/sysrq-trigger
 
+On all - Enable network SysRq by writing a cookie to icmp_echo_sysrq, e.g.
+               echo 0x01020304 >/proc/sys/net/ipv4/icmp_echo_sysrq
+        Send an ICMP echo request with this pattern plus the particular
+        SysRq command key. Example:
+               # ping -c1 -s57 -p0102030468
+        will trigger the SysRq-H (help) command.
+
+
 *  What are the 'command' keys?
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 'b'     - Will immediately reboot the system without syncing or unmounting
index d786b4fc02a40c0bb0b7e8beeec4b06f4c56bc54..8cef1d197dd2ee617b5b33334562ccf32f47b09b 100644 (file)
@@ -47,6 +47,7 @@ struct netns_ipv4 {
 
        int sysctl_icmp_echo_ignore_all;
        int sysctl_icmp_echo_ignore_broadcasts;
+       int sysctl_icmp_echo_sysrq;
        int sysctl_icmp_ignore_bogus_error_responses;
        int sysctl_icmp_ratelimit;
        int sysctl_icmp_ratemask;
index ab188ae12fd9e64635f47c92a1cc0acf1b9d3a13..028eb47226e8ac227b9c2f318a250fc310638880 100644 (file)
@@ -67,6 +67,7 @@
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
 #include <linux/fcntl.h>
+#include <linux/sysrq.h>
 #include <linux/socket.h>
 #include <linux/in.h>
 #include <linux/inet.h>
@@ -800,6 +801,30 @@ out_err:
        goto out;
 }
 
+/*
+ * 32bit and 64bit have different timestamp length, so we check for
+ * the cookie at offset 20 and verify it is repeated at offset 50
+ */
+#define CO_POS0                20
+#define CO_POS1                50
+#define CO_SIZE                sizeof(int)
+#define ICMP_SYSRQ_SIZE        57
+
+/*
+ * We got a ICMP_SYSRQ_SIZE sized ping request. Check for the cookie
+ * pattern and if it matches send the next byte as a trigger to sysrq.
+ */
+static void icmp_check_sysrq(struct net *net, struct sk_buff *skb)
+{
+       int cookie = htonl(net->ipv4.sysctl_icmp_echo_sysrq);
+       char *p = skb->data;
+
+       if (!memcmp(&cookie, p + CO_POS0, CO_SIZE) &&
+           !memcmp(&cookie, p + CO_POS1, CO_SIZE) &&
+           p[CO_POS0 + CO_SIZE] == p[CO_POS1 + CO_SIZE])
+               handle_sysrq(p[CO_POS0 + CO_SIZE]);
+}
+
 /*
  *     Handle ICMP_ECHO ("ping") requests.
  *
@@ -827,6 +852,11 @@ static void icmp_echo(struct sk_buff *skb)
                icmp_param.data_len        = skb->len;
                icmp_param.head_len        = sizeof(struct icmphdr);
                icmp_reply(&icmp_param, skb);
+
+               if (skb->len == ICMP_SYSRQ_SIZE &&
+                   net->ipv4.sysctl_icmp_echo_sysrq) {
+                       icmp_check_sysrq(net, skb);
+               }
        }
 }
 
index 69fd7201129a742ee748932d52929d7fe548289c..0ecdb72e032ae0e0fdf1bbfba382004a855bdb3a 100644 (file)
@@ -679,6 +679,13 @@ static struct ctl_table ipv4_net_table[] = {
                .mode           = 0644,
                .proc_handler   = proc_dointvec
        },
+       {
+               .procname       = "icmp_echo_sysrq",
+               .data           = &init_net.ipv4.sysctl_icmp_echo_sysrq,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec
+       },
        {
                .procname       = "icmp_ignore_bogus_error_responses",
                .data           = &init_net.ipv4.sysctl_icmp_ignore_bogus_error_responses,