aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xenmgr/lib/server
diff options
context:
space:
mode:
Diffstat (limited to 'tools/xenmgr/lib/server')
-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
6 files changed, 111 insertions, 57 deletions
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':