[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] PATCH: ability to send sysrqs to Linux domains
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)
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |