aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/xenmgr/lib/XendDomain.py9
-rw-r--r--tools/xenmgr/lib/XendDomainInfo.py6
-rw-r--r--tools/xenmgr/lib/server/SrvConsoleServer.py44
-rw-r--r--tools/xenmgr/lib/server/SrvDomain.py4
-rwxr-xr-xtools/xenmgr/lib/server/channel.py8
-rwxr-xr-xtools/xenmgr/lib/server/controller.py7
-rw-r--r--tools/xenmgr/lib/server/domain.py41
-rw-r--r--tools/xenmgr/lib/server/messages.py64
-rw-r--r--tools/xenmgr/lib/xm/create.py2
-rw-r--r--tools/xenmgr/lib/xm/shutdown.py8
10 files changed, 127 insertions, 66 deletions
diff --git a/tools/xenmgr/lib/XendDomain.py b/tools/xenmgr/lib/XendDomain.py
index e37cb5d05c..d3cddc4e75 100644
--- a/tools/xenmgr/lib/XendDomain.py
+++ b/tools/xenmgr/lib/XendDomain.py
@@ -203,21 +203,22 @@ class XendDomain:
"""Pause domain execution.
"""
dom = int(id)
+ eserver.inject('xend.domain.pause', id)
return xc.domain_pause(dom=dom)
- def domain_shutdown(self, id):
+ def domain_shutdown(self, id, reason='poweroff'):
"""Shutdown domain (nicely).
"""
dom = int(id)
if dom <= 0:
return 0
- eserver.inject('xend.domain.shutdown', id)
- val = xc.domain_destroy(dom=dom) # FIXME -- send CMSG_SHUTDOWN
+ eserver.inject('xend.domain.shutdown', [id, reason])
+ val = xend.domain_shutdown(dom, reason)
self.refresh()
return val
def domain_halt(self, id):
- """Shutdown domain immediately.
+ """Terminate domain immediately.
"""
dom = int(id)
if dom <= 0:
diff --git a/tools/xenmgr/lib/XendDomainInfo.py b/tools/xenmgr/lib/XendDomainInfo.py
index 8283584f38..88598cd9c6 100644
--- a/tools/xenmgr/lib/XendDomainInfo.py
+++ b/tools/xenmgr/lib/XendDomainInfo.py
@@ -122,8 +122,12 @@ class XendDomainInfo:
susp = (self.info['shutdown'] and 's') or '-'
crash = (self.info['crashed'] and 'c') or '-'
state = run + block + stop + susp + crash
- sxpr.append(['cpu', self.info['cpu']])
sxpr.append(['state', state])
+ if self.info['shutdown']:
+ reasons = ["poweroff", "reboot", "suspend"]
+ reason = reasons[info['shutdown_reason']]
+ sxpr.append(['shutdown_reason', reason])
+ sxpr.append(['cpu', self.info['cpu']])
sxpr.append(['cpu_time', self.info['cpu_time']/1e9])
if self.console:
sxpr.append(self.console.sxpr())
diff --git a/tools/xenmgr/lib/server/SrvConsoleServer.py b/tools/xenmgr/lib/server/SrvConsoleServer.py
index 6059ef2ebf..21d39140b2 100644
--- a/tools/xenmgr/lib/server/SrvConsoleServer.py
+++ b/tools/xenmgr/lib/server/SrvConsoleServer.py
@@ -36,6 +36,7 @@ import channel
import blkif
import netif
import console
+import domain
from params import *
DEBUG = 1
@@ -408,6 +409,16 @@ class EventFactory(protocol.Factory):
proto.factory = self
return proto
+class VirqClient:
+ def __init__(self, daemon):
+ self.daemon = daemon
+
+ def virqReceived(self, virq):
+ print 'VirqClient.virqReceived>', virq
+
+ def lostChannel(self, channel):
+ print 'VirqClient.lostChannel>', channel
+
class Daemon:
"""The xend daemon.
"""
@@ -537,11 +548,13 @@ class Daemon:
self.listenMgmt()
self.listenEvent()
self.listenNotifier()
+ self.listenVirq()
SrvServer.create()
reactor.run()
def createFactories(self):
self.channelF = channel.channelFactory()
+ self.domainCF = domain.DomainControllerFactory()
self.blkifCF = blkif.BlkifControllerFactory()
self.netifCF = netif.NetifControllerFactory()
self.consoleCF = console.ConsoleControllerFactory()
@@ -563,6 +576,10 @@ class Daemon:
p.startListening()
return p
+ def listenVirq(self):
+ virqChan = self.channelF.virqChannel(channel.VIRQ_DOM_EXC)
+ virqChan.registerClient(VirqClient(self))
+
def exit(self):
reactor.diconnectAll()
sys.exit(0)
@@ -650,28 +667,15 @@ class Daemon:
if console.conn:
console.conn.loseConnection()
- def domain_start(self, id):
- """Start domain running.
+ def domain_shutdown(self, dom, reason):
+ """Shutdown a domain.
"""
- dom = int(id)
- if dom <= 0: return 0
- return xc.domain_start(dom=dom)
+ ctrl = self.domainCF.getInstanceByDom(dom)
+ if not ctrl:
+ raise ValueError('No domain controller: %d' % dom)
+ ctrl.shutdown(reason)
+ return 0
- def domain_stop(self, id):
- """Stop domain running.
- """
- dom = int(id)
- if dom <= 0: return 0
- xc.domain_stop(dom=dom)
-
- def domain_destroy(self, id, force=0):
- """Destroy a domain. Shutdown if force=0, terminate immediately if force=1.
- """
- dom = int(id)
- if dom <= 0: return 0
- return xc.domain_destroy(dom=dom, force=force)
-
-
def instance():
global inst
try:
diff --git a/tools/xenmgr/lib/server/SrvDomain.py b/tools/xenmgr/lib/server/SrvDomain.py
index 07d3cfa7de..5034869e63 100644
--- a/tools/xenmgr/lib/server/SrvDomain.py
+++ b/tools/xenmgr/lib/server/SrvDomain.py
@@ -193,8 +193,8 @@ class SrvDomain(SrvDir):
def form(self, req):
req.write('<form method="post" action="%s">' % req.prePathURL())
- req.write('<input type="submit" name="op" value="start">')
- req.write('<input type="submit" name="op" value="stop">')
+ req.write('<input type="submit" name="op" value="unpause">')
+ req.write('<input type="submit" name="op" value="pause">')
req.write('<input type="submit" name="op" value="shutdown">')
req.write('<input type="submit" name="op" value="halt">')
req.write('<br><input type="submit" name="op" value="migrate">')
diff --git a/tools/xenmgr/lib/server/channel.py b/tools/xenmgr/lib/server/channel.py
index 130d23254f..3f2a7a6382 100755
--- a/tools/xenmgr/lib/server/channel.py
+++ b/tools/xenmgr/lib/server/channel.py
@@ -2,6 +2,12 @@ import Xc; xc = Xc.new()
import xend.utils
from messages import msgTypeName
+VIRQ_MISDIRECT = 0 # Catch-all interrupt for unbound VIRQs.
+VIRQ_TIMER = 1 # Timebase update, and/or requested timeout.
+VIRQ_DEBUG = 2 # Request guest to dump debug info.
+VIRQ_CONSOLE = 3 # (DOM0) bytes received on emergency console.
+VIRQ_DOM_EXC = 4 # (DOM0) Exceptional event for some domain.
+
def eventChannel(dom1, dom2):
return xc.evtchn_bind_interdomain(dom1=dom1, dom2=dom2)
@@ -143,7 +149,7 @@ class VirqChannel(BaseChannel):
self.virq = virq
# Notification port (int).
self.port = xc.evtchn_bind_virq(virq)
- self.idx = port
+ self.idx = self.port
# Clients to call when a virq arrives.
self.clients = []
diff --git a/tools/xenmgr/lib/server/controller.py b/tools/xenmgr/lib/server/controller.py
index 23b0f7fde1..791e987511 100755
--- a/tools/xenmgr/lib/server/controller.py
+++ b/tools/xenmgr/lib/server/controller.py
@@ -36,12 +36,14 @@ class CtrlMsgRcvr:
pass
def registerChannel(self):
+ print 'CtrlMsgRcvr>registerChannel>', self
self.channel = self.channelFactory.domChannel(self.dom)
self.idx = self.channel.getIndex()
if self.majorTypes:
self.channel.registerDevice(self.majorTypes, self)
def deregisterChannel(self):
+ print 'CtrlMsgRcvr>deregisterChannel>', self
if self.channel:
self.channel.deregisterDevice(self)
del self.channel
@@ -71,6 +73,8 @@ class ControllerFactory(CtrlMsgRcvr):
self.instances = {}
self.dlist = []
self.dom = 0
+ # Timeout (in seconds) for deferreds.
+ self.timeout = 10
def addInstance(self, instance):
self.instances[instance.idx] = instance
@@ -99,6 +103,9 @@ class ControllerFactory(CtrlMsgRcvr):
def addDeferred(self):
d = defer.Deferred()
+ if self.timeout > 0:
+ # The deferred will error if not called before timeout.
+ d.setTimeout(self.timeout)
self.dlist.append(d)
return d
diff --git a/tools/xenmgr/lib/server/domain.py b/tools/xenmgr/lib/server/domain.py
new file mode 100644
index 0000000000..ab22234480
--- /dev/null
+++ b/tools/xenmgr/lib/server/domain.py
@@ -0,0 +1,41 @@
+import channel
+import controller
+from messages import *
+
+class DomainControllerFactory(controller.ControllerFactory):
+ """Factory for creating domain controllers.
+ """
+
+ def createInstance(self, dom):
+ d = DomainController(self, dom)
+ self.addInstance(d)
+ return d
+
+ def getInstanceByDom(self, dom):
+ for inst in self.instances.values():
+ if inst.dom == dom:
+ return inst
+ inst = self.createInstance(dom)
+ return inst
+
+
+class DomainController(controller.Controller):
+ """Generic controller for a domain.
+ """
+
+ reasons = {'poweroff' : 'shutdown_poweroff_t',
+ 'reboot' : 'shutdown_reboot_t',
+ 'suspend' : 'shutdown_suspend_t' }
+
+ def __init__(self, factory, dom):
+ controller.Controller.__init__(self, factory, dom)
+ self.majorTypes = [ CMSG_SHUTDOWN ]
+ self.registerChannel()
+ print 'DomainController>', self, self.channel, self.idx
+
+ def shutdown(self, reason):
+ msgtype = self.reasons.get(reason)
+ if not msgtype:
+ raise ValueError('invalid reason:' + reason)
+ msg = packMsg(msgtype, {})
+ self.writeRequest(msg)
diff --git a/tools/xenmgr/lib/server/messages.py b/tools/xenmgr/lib/server/messages.py
index 649629105c..78bc24526f 100644
--- a/tools/xenmgr/lib/server/messages.py
+++ b/tools/xenmgr/lib/server/messages.py
@@ -16,7 +16,7 @@ msg_formats = {}
CMSG_CONSOLE = 0
-console_formats = { 'console_data': (CMSG_CONSOLE, 0, "?") }
+console_formats = { 'console_data': (CMSG_CONSOLE, 0) }
msg_formats.update(console_formats)
@@ -62,28 +62,28 @@ BLKIF_BE_STATUS_MAPPING_ERROR = 9
blkif_formats = {
'blkif_be_connect_t':
- (CMSG_BLKIF_BE, CMSG_BLKIF_BE_CONNECT, "QIILI"),
+ (CMSG_BLKIF_BE, CMSG_BLKIF_BE_CONNECT),
'blkif_be_create_t':
- (CMSG_BLKIF_BE, CMSG_BLKIF_BE_CREATE, "QII"),
+ (CMSG_BLKIF_BE, CMSG_BLKIF_BE_CREATE),
'blkif_be_destroy_t':
- (CMSG_BLKIF_BE, CMSG_BLKIF_BE_DESTROY, "QII"),
+ (CMSG_BLKIF_BE, CMSG_BLKIF_BE_DESTROY),
'blkif_be_vbd_create_t':
- (CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_CREATE, "QIHII"),
+ (CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_CREATE),
'blkif_be_vbd_grow_t':
- (CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_GROW , "QIHHHQQI"),
+ (CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_GROW),
'blkif_fe_interface_status_changed_t':
- (CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED, "III"),
+ (CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED),
'blkif_fe_driver_status_changed_t':
- (CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED, "?"),
+ (CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED),
'blkif_fe_interface_connect_t':
- (CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_CONNECT, "IL"),
+ (CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_CONNECT),
}
msg_formats.update(blkif_formats)
@@ -115,59 +115,55 @@ NETIF_DRIVER_STATUS_UP = 1
netif_formats = {
'netif_be_connect_t':
- (CMSG_NETIF_BE, CMSG_NETIF_BE_CONNECT, "QIILLI"),
+ (CMSG_NETIF_BE, CMSG_NETIF_BE_CONNECT),
'netif_be_create_t':
- (CMSG_NETIF_BE, CMSG_NETIF_BE_CREATE, "QIBBBBBBBBI"),
+ (CMSG_NETIF_BE, CMSG_NETIF_BE_CREATE),
'netif_be_destroy_t':
- (CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY, "QII"),
+ (CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY),
'netif_be_disconnect_t':
- (CMSG_NETIF_BE, CMSG_NETIF_BE_DISCONNECT, "QII"),
+ (CMSG_NETIF_BE, CMSG_NETIF_BE_DISCONNECT),
'netif_be_driver_status_changed_t':
- (CMSG_NETIF_BE, CMSG_NETIF_BE_DRIVER_STATUS_CHANGED, "QII"),
+ (CMSG_NETIF_BE, CMSG_NETIF_BE_DRIVER_STATUS_CHANGED),
'netif_fe_driver_status_changed_t':
- (CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED, "II"),
+ (CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED),
'netif_fe_interface_connect_t':
- (CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_CONNECT, "ILL"),
+ (CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_CONNECT),
'netif_fe_interface_status_changed_t':
- (CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED, "IIIBBBBBBBB"),
+ (CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED),
}
msg_formats.update(netif_formats)
#============================================================================
-CMSG_SUSPEND = 5
CMSG_SHUTDOWN = 6
-CMSG_SHUTDOWN_HALT = 0
-CMSG_SHUTDOWN_POWEROFF = 1
-CMSG_SHUTDOWN_REBOOT = 2
+CMSG_SHUTDOWN_POWEROFF = 0
+CMSG_SHUTDOWN_REBOOT = 1
+CMSG_SHUTDOWN_SUSPEND = 2
STOPCODE_shutdown = 0
STOPCODE_reboot = 1
STOPCODE_suspend = 2
-ctrlif_formats = {
- 'ctrlif_suspend_t':
- (CMSG_SUSPEND, 0, "??"),
-
- 'ctrlif_shutdown_halt_t':
- (CMSG_SHUTDOWN, CMSG_SHUTDOWN_HALT, "??"),
-
- 'ctrlif_shutdown_poweroff_t':
- (CMSG_SHUTDOWN, CMSG_SHUTDOWN_POWEROFF, "??"),
+shutdown_formats = {
+ 'shutdown_poweroff_t':
+ (CMSG_SHUTDOWN, CMSG_SHUTDOWN_POWEROFF),
- 'ctrlif_shutdown_reboot_t':
- (CMSG_SHUTDOWN, CMSG_SHUTDOWN_REBOOT, "??"),
+ 'shutdown_reboot_t':
+ (CMSG_SHUTDOWN, CMSG_SHUTDOWN_REBOOT),
+
+ 'shutdown_suspend_t':
+ (CMSG_SHUTDOWN, CMSG_SHUTDOWN_SUSPEND),
}
-msg_formats.update(ctrlif_formats)
+msg_formats.update(shutdown_formats)
#============================================================================
@@ -176,7 +172,7 @@ class Msg:
def packMsg(ty, params):
if DEBUG: print '>packMsg', ty, params
- (major, minor, packing) = msg_formats[ty]
+ (major, minor) = msg_formats[ty]
args = {}
for (k, v) in params.items():
if k == 'mac':
diff --git a/tools/xenmgr/lib/xm/create.py b/tools/xenmgr/lib/xm/create.py
index a365424acf..29b4c7b6dc 100644
--- a/tools/xenmgr/lib/xm/create.py
+++ b/tools/xenmgr/lib/xm/create.py
@@ -235,7 +235,7 @@ def preprocess_ip(opts):
setip = (opts.hostname or opts.netmask
or opts.gateway or opts.dhcp or opts.interface)
if not setip: return
- if not opts
+ #if not opts
ip = (opts.ip
+ ':'
+ ':' + opts.gateway
diff --git a/tools/xenmgr/lib/xm/shutdown.py b/tools/xenmgr/lib/xm/shutdown.py
index 8c7a517e96..0108a8df0f 100644
--- a/tools/xenmgr/lib/xm/shutdown.py
+++ b/tools/xenmgr/lib/xm/shutdown.py
@@ -10,7 +10,7 @@ gopts = Opts(use="""[options] [DOM]
Shutdown one or more domains gracefully.""")
gopts.opt('help', short='h',
- fn=set_value, default=0,
+ fn=set_true, default=0,
use="Print this help.")
gopts.opt('all', short='a',
@@ -46,8 +46,8 @@ def main_all(opts, args):
shutdown(opts, None, opts.wait)
def main_dom(opts, args):
- if len(args) < 2: opts.err('Missing domain')
- dom = argv[1]
+ if len(args) < 1: opts.err('Missing domain')
+ dom = args[0]
try:
domid = int(dom)
except:
@@ -59,6 +59,8 @@ def main(argv):
args = opts.parse(argv)
if opts.help:
opts.usage()
+ return
+ print 'shutdown.main>', len(args), args
if opts.all:
main_all(opts, args)
else: