mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
The attached patch:
1. Converts the shutdown driver and xend to use the store instead of control messages, 2. Includes Anthony's xenstore notification code, and 3. Changes xend so that sysrq's are no longer sent as "special case" shutdown messages. Store keys are cheap, so making the sysrq delivery less obscure is good. I think I have made all of the appropriate modifications to Xend, but it is complex, so I may have missed something. Comments are welcome. Signed-off-by: Dan Smith <danms@us.ibm.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
1 parent
1126965540
commit
fe0b8e6e6e
8 files changed
+183
-68
No files matched your search
@@ -208,11 +208,15 @@ class Xend:
|
||||
return self.xendPost(self.domainurl(id),
|
||||
{'op' : 'pause' })
|
||||
|
||||
def xend_domain_shutdown(self, id, reason, key=0):
|
||||
def xend_domain_shutdown(self, id, reason):
|
||||
return self.xendPost(self.domainurl(id),
|
||||
{'op' : 'shutdown',
|
||||
'reason' : reason,
|
||||
'key' : key })
|
||||
'reason' : reason})
|
||||
|
||||
def xend_domain_sysrq(self, id, key):
|
||||
return self.xendPost(self.domainurl(id),
|
||||
{'op' : 'sysrq',
|
||||
'key' : key})
|
||||
|
||||
def xend_domain_destroy(self, id, reason):
|
||||
return self.xendPost(self.domainurl(id),
|
||||
|
||||
@@ -386,7 +386,7 @@ class XendDomain:
|
||||
except Exception, ex:
|
||||
raise XendError(str(ex))
|
||||
|
||||
def domain_shutdown(self, id, reason='poweroff', key=0):
|
||||
def domain_shutdown(self, id, reason='poweroff'):
|
||||
"""Shutdown domain (nicely).
|
||||
- poweroff: restart according to exit code and restart mode
|
||||
- reboot: restart on exit
|
||||
@@ -402,11 +402,18 @@ class XendDomain:
|
||||
eserver.inject('xend.domain.shutdown', [dominfo.name, dominfo.id, reason])
|
||||
if reason == 'halt':
|
||||
reason = 'poweroff'
|
||||
val = dominfo.shutdown(reason, key=key)
|
||||
if not reason in ['suspend', 'sysrq']:
|
||||
val = dominfo.shutdown(reason)
|
||||
if not reason in ['suspend']:
|
||||
self.domain_shutdowns()
|
||||
return val
|
||||
|
||||
def domain_sysrq(self, id, key):
|
||||
"""Send a SysRq to a domain
|
||||
"""
|
||||
dominfo = self.domain_lookup(id)
|
||||
val = dominfo.send_sysrq(key)
|
||||
return val
|
||||
|
||||
def domain_shutdowns(self):
|
||||
"""Process pending domain shutdowns.
|
||||
Destroys domains whose shutdowns have timed out.
|
||||
|
||||
@@ -52,13 +52,12 @@ shutdown_reasons = {
|
||||
DOMAIN_CRASH : "crash",
|
||||
}
|
||||
|
||||
"""Map shutdown reasons to the message type to use.
|
||||
"""Map shutdown reasons to codes
|
||||
"""
|
||||
shutdown_messages = {
|
||||
'poweroff' : 'shutdown_poweroff_t',
|
||||
'reboot' : 'shutdown_reboot_t',
|
||||
'suspend' : 'shutdown_suspend_t',
|
||||
'sysrq' : 'shutdown_sysrq_t',
|
||||
shutdown_codes = {
|
||||
'poweroff' : DOMAIN_POWEROFF,
|
||||
'reboot' : DOMAIN_REBOOT,
|
||||
'suspend' : DOMAIN_SUSPEND,
|
||||
}
|
||||
|
||||
RESTART_ALWAYS = 'always'
|
||||
@@ -152,8 +151,6 @@ class XendDomainInfo:
|
||||
vm = cls(db)
|
||||
vm.construct(config)
|
||||
vm.saveToDB(sync=True)
|
||||
# Flush info to xenstore immediately
|
||||
vm.exportToDB()
|
||||
|
||||
return vm
|
||||
|
||||
@@ -941,19 +938,20 @@ class XendDomainInfo:
|
||||
|
||||
self.channel.writeRequest(msg)
|
||||
|
||||
def shutdown(self, reason, key=0):
|
||||
msgtype = shutdown_messages.get(reason)
|
||||
if not msgtype:
|
||||
def shutdown(self, reason):
|
||||
reasonid = shutdown_codes.get(reason)
|
||||
if reasonid == None:
|
||||
raise XendError('invalid reason:' + reason)
|
||||
extra = {}
|
||||
if reason == 'sysrq':
|
||||
extra['key'] = key
|
||||
if self.channel:
|
||||
msg = messages.packMsg(msgtype, extra)
|
||||
self.channel.writeRequest(msg)
|
||||
if not reason in ['suspend', 'sysrq']:
|
||||
self.shutdown_pending = {'start':time.time(), 'reason':reason,
|
||||
'key':key}
|
||||
db = self.db.addChild("/control");
|
||||
db['shutdown'] = '%i' % reasonid;
|
||||
db.saveDB(save=True);
|
||||
if not reason in ['suspend']:
|
||||
self.shutdown_pending = {'start':time.time(), 'reason':reason}
|
||||
|
||||
def send_sysrq(self, key=0):
|
||||
db = self.db.addChild("/control");
|
||||
db['sysrq'] = '%c' % key;
|
||||
db.saveDB(save=True);
|
||||
|
||||
def shutdown_time_left(self, timeout):
|
||||
if not self.shutdown_pending:
|
||||
|
||||
@@ -39,13 +39,21 @@ class SrvDomain(SrvDir):
|
||||
def op_shutdown(self, op, req):
|
||||
fn = FormFn(self.xd.domain_shutdown,
|
||||
[['dom', 'int'],
|
||||
['reason', 'str'],
|
||||
['key', 'int']])
|
||||
['reason', 'str']])
|
||||
val = fn(req.args, {'dom': self.dom.id})
|
||||
req.setResponseCode(http.ACCEPTED)
|
||||
req.setHeader("Location", "%s/.." % req.prePathURL())
|
||||
return val
|
||||
|
||||
def op_sysrq(self, op, req):
|
||||
fn = FormFn(self.xd.domain_sysrq,
|
||||
[['dom', 'int'],
|
||||
['key', 'int']])
|
||||
val = fn(req.args, {'dom' : self.dom.id})
|
||||
req.setResponseCode(http.ACCEPTED)
|
||||
req.setHeader("Location", "%s/.." % req.prePathURL())
|
||||
return val
|
||||
|
||||
def op_destroy(self, op, req):
|
||||
fn = FormFn(self.xd.domain_destroy,
|
||||
[['dom', 'int'],
|
||||
|
||||
@@ -21,9 +21,6 @@ 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)
|
||||
@@ -36,4 +33,4 @@ def main(argv):
|
||||
if len(args) < 2: opts.err('Missing sysrq character')
|
||||
dom = args[0]
|
||||
req = ord(args[1][0])
|
||||
sysrq(dom, req)
|
||||
server.xend_domain_sysrq(dom, req)
|
||||