WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] PATCH: ability to send sysrqs to Linux domains

To: xen-devel@xxxxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] PATCH: ability to send sysrqs to Linux domains
From: Matthew Bloch <matthew@xxxxxxxxxxxxxx>
Date: Thu, 09 Dec 2004 11:44:53 +0000
Delivery-date: Thu, 09 Dec 2004 17:07:34 +0000
Envelope-to: xen+James.Bulpin@xxxxxxxxxxxx
List-archive: <http://sourceforge.net/mailarchive/forum.php?forum=xen-devel>
List-help: <mailto:xen-devel-request@lists.sourceforge.net?subject=help>
List-id: List for Xen developers <xen-devel.lists.sourceforge.net>
List-post: <mailto:xen-devel@lists.sourceforge.net>
List-subscribe: <https://lists.sourceforge.net/lists/listinfo/xen-devel>, <mailto:xen-devel-request@lists.sourceforge.net?subject=subscribe>
List-unsubscribe: <https://lists.sourceforge.net/lists/listinfo/xen-devel>, <mailto:xen-devel-request@lists.sourceforge.net?subject=unsubscribe>
Sender: xen-devel-admin@xxxxxxxxxxxxxxxxxxxxx
User-agent: Mozilla Thunderbird 0.7.3 (X11/20040912)
Here's the promised patch against a recent 2.01 snapshot to allow you to send sysrqs to running Linux kernels. I went with Keir's suggestion of adding a sub-reason code to the shutdown message with a 1-byte payload specifying which key was pressed. Hope it's acceptable for the main tree; I will happily alter it to spec if any of the maintainers have suggestions for better structuring it.

It adds the CONFIG_MAGIC_SYSRQ option to the Linux kernel which you need to turn on for a guest to work with it, then you can just do e.g. "xm sysrq domainname s" to sync your discs.

cheers,

--
Matthew Bloch                             Bytemark Hosting
                                http://www.bytemark.co.uk/
                phone UK: 0845 004 3 004 US: 1-877 BYTEMAR
          Dedicated Linux hosts from 15ukp ($26) per month

diff -urN xen-2.0/linux-2.6.9-xen-sparse/arch/xen/Kconfig 
xen-2.0-sysrq/linux-2.6.9-xen-sparse/arch/xen/Kconfig
--- xen-2.0/linux-2.6.9-xen-sparse/arch/xen/Kconfig     2004-11-17 
22:51:41.000000000 +0000
+++ xen-2.0-sysrq/linux-2.6.9-xen-sparse/arch/xen/Kconfig       2004-12-08 
15:03:23.000000000 +0000
@@ -164,3 +164,20 @@
 source "crypto/Kconfig"
 
 source "lib/Kconfig"
+
+menu "Kernel hacking"
+
+config MAGIC_SYSRQ
+        bool "Magic SysRq key"
+        help
+          If you say Y here, you will have some control over the system even
+          if the system crashes for example during kernel debugging (e.g., you
+          will be able to flush the buffer cache to disk, reboot the system
+          immediately or dump some status information). This is accomplished
+          by pressing various keys while holding SysRq (Alt+PrintScreen). It
+          also works on a serial console (on PC hardware at least), if you
+          send a BREAK and then within 5 seconds a command keypress. The
+          keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
+          unless you really know what this hack does.
+
+endmenu
diff -urN xen-2.0/linux-2.6.9-xen-sparse/arch/xen/kernel/reboot.c 
xen-2.0-sysrq/linux-2.6.9-xen-sparse/arch/xen/kernel/reboot.c
--- xen-2.0/linux-2.6.9-xen-sparse/arch/xen/kernel/reboot.c     2004-11-17 
22:51:41.000000000 +0000
+++ xen-2.0-sysrq/linux-2.6.9-xen-sparse/arch/xen/kernel/reboot.c       
2004-12-08 15:03:23.000000000 +0000
@@ -8,6 +8,7 @@
 #include <linux/unistd.h>
 #include <linux/module.h>
 #include <linux/reboot.h>
+#include <linux/sysrq.h>
 #include <asm/irq.h>
 #include <asm/mmu_context.h>
 #include <asm-xen/ctrl_if.h>
@@ -53,6 +54,7 @@
 
 /* Ignore multiple shutdown requests. */
 static int shutting_down = -1;
+static int pending_sysrq = -1;
 
 static void __do_suspend(void)
 {
@@ -214,9 +216,22 @@
     }
 }
 
+static void __sysrq_handler(void *unused)
+{
+#ifndef CONFIG_MAGIC_SYSRQ
+    printk("CONFIG_MAGIC_SYSRQ not compiled in, will ignore!\n");
+#else
+    handle_sysrq(pending_sysrq, NULL, NULL);
+    pending_sysrq = -1;
+#endif
+}
+
 static void shutdown_handler(ctrl_msg_t *msg, unsigned long id)
 {
     static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL);
+    static DECLARE_WORK(sysrq_work, __sysrq_handler, NULL);
+    
+    printk("msg->subtype = %d, msg->msg[0] = %d", msg->subtype, msg->msg[0]);
 
     if ( (shutting_down == -1) &&
          ((msg->subtype == CMSG_SHUTDOWN_POWEROFF) ||
@@ -226,6 +241,12 @@
         shutting_down = msg->subtype;
         schedule_work(&shutdown_work);
     }
+    else if (msg->subtype == CMSG_SHUTDOWN_SYSRQ)
+    {
+        /* sysrqs are allowed during shutdown in case shutdown stuffs up */
+        pending_sysrq = msg->msg[0];
+        schedule_work(&sysrq_work);
+    }
     else
     {
         printk("Ignore spurious shutdown request\n");
diff -urN xen-2.0/tools/python/xen/xend/XendClient.py 
xen-2.0-sysrq/tools/python/xen/xend/XendClient.py
--- xen-2.0/tools/python/xen/xend/XendClient.py 2004-11-17 22:51:40.000000000 
+0000
+++ xen-2.0-sysrq/tools/python/xen/xend/XendClient.py   2004-12-08 
15:03:23.000000000 +0000
@@ -228,10 +228,11 @@
         return self.xendPost(self.domainurl(id),
                              {'op'      : 'pause' })
 
-    def xend_domain_shutdown(self, id, reason):
+    def xend_domain_shutdown(self, id, reason, key=None):
         return self.xendPost(self.domainurl(id),
                              {'op'      : 'shutdown',
-                              'reason'  : reason })
+                              'reason'  : reason,
+                              'key'     : key })
 
     def xend_domain_destroy(self, id, reason):
         return self.xendPost(self.domainurl(id),
diff -urN xen-2.0/tools/python/xen/xend/XendDomain.py 
xen-2.0-sysrq/tools/python/xen/xend/XendDomain.py
--- xen-2.0/tools/python/xen/xend/XendDomain.py 2004-11-17 22:51:42.000000000 
+0000
+++ xen-2.0-sysrq/tools/python/xen/xend/XendDomain.py   2004-12-09 
10:47:57.000000000 +0000
@@ -455,7 +455,7 @@
         except Exception, ex:
             raise XendError(str(ex))
     
-    def domain_shutdown(self, id, reason='poweroff'):
+    def domain_shutdown(self, id, reason='poweroff', key=None):
         """Shutdown domain (nicely).
          - poweroff: restart according to exit code and restart mode
          - reboot:   restart on exit
@@ -474,7 +474,7 @@
         eserver.inject('xend.domain.shutdown', [dominfo.name, dominfo.id, 
reason])
         if reason == 'halt':
             reason = 'poweroff'
-        val = xend.domain_shutdown(dominfo.id, reason)
+        val = xend.domain_shutdown(dominfo.id, reason, key)
         self.refresh_schedule()
         return val
 
diff -urN xen-2.0/tools/python/xen/xend/server/SrvDaemon.py 
xen-2.0-sysrq/tools/python/xen/xend/server/SrvDaemon.py
--- xen-2.0/tools/python/xen/xend/server/SrvDaemon.py   2004-11-17 
22:51:47.000000000 +0000
+++ xen-2.0-sysrq/tools/python/xen/xend/server/SrvDaemon.py     2004-12-09 
10:51:57.000000000 +0000
@@ -711,14 +711,14 @@
             raise XendError('Invalid console id')
         console.disconnect()
 
-    def domain_shutdown(self, dom, reason):
+    def domain_shutdown(self, dom, reason, key=None):
         """Shutdown a domain.
         """
         dom = int(dom)
         ctrl = self.domainCF.getController(dom)
         if not ctrl:
             raise XendError('No domain controller: %s' % dom)
-        ctrl.shutdown(reason)
+        ctrl.shutdown(reason, key)
         return 0
 
     def domain_mem_target_set(self, dom, target):
diff -urN xen-2.0/tools/python/xen/xend/server/SrvDomain.py 
xen-2.0-sysrq/tools/python/xen/xend/server/SrvDomain.py
--- xen-2.0/tools/python/xen/xend/server/SrvDomain.py   2004-11-17 
22:51:47.000000000 +0000
+++ xen-2.0-sysrq/tools/python/xen/xend/server/SrvDomain.py     2004-12-08 
17:24:07.000000000 +0000
@@ -47,7 +47,8 @@
     def op_shutdown(self, op, req):
         fn = FormFn(self.xd.domain_shutdown,
                     [['dom', 'str'],
-                     ['reason', 'str']])
+                     ['reason', 'str'],
+                     ['key', 'int']])
         val = fn(req.args, {'dom': self.dom.id})
         req.setResponseCode(http.ACCEPTED)
         req.setHeader("Location", "%s/.." % req.prePathURL())
diff -urN xen-2.0/tools/python/xen/xend/server/domain.py 
xen-2.0-sysrq/tools/python/xen/xend/server/domain.py
--- xen-2.0/tools/python/xen/xend/server/domain.py      2004-11-17 
22:51:43.000000000 +0000
+++ xen-2.0-sysrq/tools/python/xen/xend/server/domain.py        2004-12-08 
17:20:02.000000000 +0000
@@ -28,7 +28,8 @@
     """
     reasons = {'poweroff' : 'shutdown_poweroff_t',
                'reboot'   : 'shutdown_reboot_t',
-               'suspend'  : 'shutdown_suspend_t' }
+               'suspend'  : 'shutdown_suspend_t',
+               'sysrq'    : 'shutdown_sysrq_t' }
 
     def __init__(self, factory, dom):
         controller.Controller.__init__(self, factory, dom)
@@ -36,16 +37,19 @@
         self.addMethod(CMSG_MEM_REQUEST, 0, None)
         self.registerChannel()
 
-    def shutdown(self, reason):
+    def shutdown(self, reason, key=None):
         """Shutdown a domain.
 
         reason shutdown reason
+        key    sysrq key (only if reason is 'sysrq')
         """
         msgtype = self.reasons.get(reason)
         if not msgtype:
             raise XendError('invalid reason:' + reason)
-        msg = packMsg(msgtype, {})
-        self.writeRequest(msg)
+        extra = {}
+        if reason == 'sysrq': extra['key'] = key
+        print extra
+        self.writeRequest(packMsg(msgtype, extra))
 
     def mem_target_set(self, target):
         """Set domain memory target in pages.
diff -urN xen-2.0/tools/python/xen/xend/server/messages.py 
xen-2.0-sysrq/tools/python/xen/xend/server/messages.py
--- xen-2.0/tools/python/xen/xend/server/messages.py    2004-11-17 
22:51:42.000000000 +0000
+++ xen-2.0-sysrq/tools/python/xen/xend/server/messages.py      2004-12-08 
15:03:23.000000000 +0000
@@ -197,10 +197,12 @@
 CMSG_SHUTDOWN_POWEROFF  = 0
 CMSG_SHUTDOWN_REBOOT    = 1
 CMSG_SHUTDOWN_SUSPEND   = 2
+CMSG_SHUTDOWN_SYSRQ     = 3
 
 STOPCODE_shutdown       = 0
 STOPCODE_reboot         = 1
 STOPCODE_suspend        = 2
+STOPCODE_sysrq          = 3
 
 shutdown_formats = {
     'shutdown_poweroff_t':
@@ -211,6 +213,9 @@
 
     'shutdown_suspend_t':
     (CMSG_SHUTDOWN, CMSG_SHUTDOWN_SUSPEND),
+    
+    'shutdown_sysrq_t':
+    (CMSG_SHUTDOWN, CMSG_SHUTDOWN_SYSRQ)
     }
 
 msg_formats.update(shutdown_formats)
diff -urN xen-2.0/tools/python/xen/xm/main.py 
xen-2.0-sysrq/tools/python/xen/xm/main.py
--- xen-2.0/tools/python/xen/xm/main.py 2004-11-17 22:51:47.000000000 +0000
+++ xen-2.0-sysrq/tools/python/xen/xm/main.py   2004-12-08 15:03:23.000000000 
+0000
@@ -11,7 +11,7 @@
 from xen.xend import sxp
 from xen.xend.XendClient import XendError, server
 from xen.xend.XendClient import main as xend_client_main
-from xen.xm import create, destroy, migrate, shutdown
+from xen.xm import create, destroy, migrate, shutdown, sysrq
 from xen.xm.opts import *
 
 class Group:
@@ -401,6 +401,19 @@
 
 xm.prog(ProgShutdown)
 
+class ProgSysrq(Prog):
+    group = 'domain'
+    name = "sysrq"
+    info = """Send a sysrq to a domain."""
+
+    def help(self, args):
+        sysrq.main([args[0], '-h'])
+    
+    def main(self, args):
+        sysrq.main(args)
+
+xm.prog(ProgSysrq)
+
 class ProgPause(Prog):
     group = 'domain'
     name = "pause"
diff -urN xen-2.0/tools/python/xen/xm/sysrq.py 
xen-2.0-sysrq/tools/python/xen/xm/sysrq.py
--- xen-2.0/tools/python/xen/xm/sysrq.py        1970-01-01 01:00:00.000000000 
+0100
+++ xen-2.0-sysrq/tools/python/xen/xm/sysrq.py  2004-12-08 17:17:38.000000000 
+0000
@@ -0,0 +1,39 @@
+# (C) Matthew Bloch <matthew@xxxxxxxxxxxxxx> 2004
+
+"""Domain shutdown.
+"""
+import string
+import sys
+import time
+
+from xen.xend.XendClient import server
+from xen.xm.opts import *
+
+DOM0_NAME = 'Domain-0'
+DOM0_ID = '0'
+
+gopts = Opts(use="""[DOM] [letter]
+
+Sends a Linux sysrq to a domain.
+""")
+
+gopts.opt('help', short='h',
+         fn=set_true, default=0,
+         use="Print this help.")
+
+def sysrq(dom, req):
+    server.xend_domain_shutdown(dom, 'sysrq', req)
+
+def main(argv):
+    opts = gopts
+    args = opts.parse(argv)
+    if opts.vals.help:
+        opts.usage()
+        return
+        
+    # no options for the moment
+    if len(args) < 1: opts.err('Missing domain')
+    if len(args) < 2: opts.err('Missing sysrq character')
+    dom = args[0]
+    req = ord(args[1][0])
+    sysrq(dom, req)
<Prev in Thread] Current Thread [Next in Thread>