mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
bitkeeper revision 1.1662.1.13 (42a4af81MIF4vpJsgsYgQT--FGFI5w)
channel.py, XendDomainInfo.py: Cleanup event channel code. Signed-off-by: Mike Wray <mike.wray@hp.com> Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
This commit is contained in:
1 parent
a801b2ab6b
commit
66a8df749b
2 files changed
+114
-48
No files matched your search
@@ -17,10 +17,10 @@ import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
|
||||
from xen.util.ip import check_subnet, get_current_ipgw
|
||||
from xen.util.blkif import blkdev_uname_to_file
|
||||
|
||||
from xen.xend.server import channel, controller
|
||||
from xen.xend.server import controller
|
||||
from xen.xend.server import SrvDaemon; xend = SrvDaemon.instance()
|
||||
from xen.xend.server import messages
|
||||
from xen.xend.server.channel import channelFactory
|
||||
from xen.xend.server.channel import EventChannel, channelFactory
|
||||
|
||||
from xen.xend import sxp
|
||||
from xen.xend.PrettyPrint import prettyprintstring
|
||||
@@ -242,7 +242,7 @@ class XendDomainInfo:
|
||||
|
||||
self.channel = None
|
||||
self.store_channel = None
|
||||
self.store_mfs = None
|
||||
self.store_mfn = None
|
||||
self.controllers = {}
|
||||
|
||||
self.info = None
|
||||
@@ -286,6 +286,9 @@ class XendDomainInfo:
|
||||
def getChannel(self):
|
||||
return self.channel
|
||||
|
||||
def getStoreChannel(self):
|
||||
return self.store_channel
|
||||
|
||||
def update(self, info):
|
||||
"""Update with info from xc.domain_getinfo().
|
||||
"""
|
||||
@@ -401,6 +404,8 @@ class XendDomainInfo:
|
||||
|
||||
if self.channel:
|
||||
sxpr.append(self.channel.sxpr())
|
||||
if self.store_channel:
|
||||
sxpr.append(self.store_channel.sxpr())
|
||||
console = self.getConsole()
|
||||
if console:
|
||||
sxpr.append(console.sxpr())
|
||||
@@ -550,8 +555,16 @@ class XendDomainInfo:
|
||||
def destroy(self):
|
||||
"""Completely destroy the vm.
|
||||
"""
|
||||
self.cleanup()
|
||||
self.destroy_domain()
|
||||
try:
|
||||
self.cleanup()
|
||||
except Exception, ex:
|
||||
log.warning("error in domain cleanup: %s", ex)
|
||||
pass
|
||||
try:
|
||||
self.destroy_domain()
|
||||
except Exception, ex:
|
||||
log.warning("error in domain destroy: %s", ex)
|
||||
pass
|
||||
|
||||
def destroy_domain(self):
|
||||
"""Destroy the vm's domain.
|
||||
@@ -559,8 +572,11 @@ class XendDomainInfo:
|
||||
devices have been released.
|
||||
"""
|
||||
if self.channel:
|
||||
self.channel.close()
|
||||
self.channel = None
|
||||
try:
|
||||
self.channel.close()
|
||||
self.channel = None
|
||||
except:
|
||||
pass
|
||||
if self.image:
|
||||
try:
|
||||
self.image.destroy()
|
||||
@@ -617,20 +633,32 @@ class XendDomainInfo:
|
||||
if not self.restore:
|
||||
self.setdom(dom)
|
||||
|
||||
def create_channel(self):
|
||||
"""Create the control channel to the domain.
|
||||
If saved info is available recreate the channel using the saved ports.
|
||||
def openChannel(self, name, local, remote):
|
||||
"""Create a channel to the domain.
|
||||
If saved info is available recreate the channel.
|
||||
|
||||
@param local default local port
|
||||
@param remote default remote port
|
||||
"""
|
||||
local = 0
|
||||
remote = 1
|
||||
if self.savedinfo:
|
||||
info = sxp.child(self.savedinfo, "channel")
|
||||
info = sxp.child(self.savedinfo, name)
|
||||
if info:
|
||||
local = int(sxp.child_value(info, "local_port", 0))
|
||||
remote = int(sxp.child_value(info, "remote_port", 1))
|
||||
self.channel = channelFactory().openChannel(str(self.id),
|
||||
local_port=local,
|
||||
remote_port=remote)
|
||||
chan = channelFactory().openChannel(self.id, local_port=local,
|
||||
remote_port=remote)
|
||||
return chan
|
||||
|
||||
def eventChannel(self, name):
|
||||
return EventChannel.interdomain(0, self.id)
|
||||
|
||||
def create_channel(self):
|
||||
"""Create the channels to the domain.
|
||||
"""
|
||||
self.channel = self.openChannel("channel", 0, 1)
|
||||
self.store_channel = self.eventChannel("store_channel")
|
||||
|
||||
def create_configured_devices(self):
|
||||
devices = sxp.children(self.config, 'device')
|
||||
|
||||
@@ -14,52 +14,90 @@ DEBUG = 0
|
||||
|
||||
RESPONSE_TIMEOUT = 20.0
|
||||
|
||||
def eventChannel(dom1, dom2):
|
||||
"""Create an event channel between domains.
|
||||
The returned dict contains dom1, dom2, port1 and port2 on success.
|
||||
|
||||
@return dict (empty on error)
|
||||
class EventChannel(dict):
|
||||
"""An event channel between domains.
|
||||
"""
|
||||
evtchn = xc.evtchn_bind_interdomain(dom1=dom1, dom2=dom2)
|
||||
if evtchn:
|
||||
evtchn['dom1'] = dom1
|
||||
evtchn['dom2'] = dom2
|
||||
return evtchn
|
||||
|
||||
def interdomain(cls, dom1, dom2, port1=0, port2=0):
|
||||
"""Create an event channel between domains.
|
||||
|
||||
@return EventChannel (None on error)
|
||||
"""
|
||||
v = xc.evtchn_bind_interdomain(dom1=dom1, dom2=dom2,
|
||||
port1=port1, port2=port2)
|
||||
if v:
|
||||
v = cls(dom1, dom2, v)
|
||||
return v
|
||||
|
||||
interdomain = classmethod(interdomain)
|
||||
|
||||
def __init__(self, dom1, dom2, d):
|
||||
d['dom1'] = dom1
|
||||
d['dom2'] = dom2
|
||||
self.update(d)
|
||||
self.dom1 = dom1
|
||||
self.dom2 = dom2
|
||||
self.port1 = d.get('port1')
|
||||
self.port2 = d.get('port2')
|
||||
|
||||
def close(self):
|
||||
"""Close the event channel.
|
||||
"""
|
||||
def evtchn_close(dom, port):
|
||||
try:
|
||||
xc.evtchn_close(dom=dom, port=port)
|
||||
except Exception, ex:
|
||||
pass
|
||||
|
||||
if DEBUG:
|
||||
print 'EventChannel>close>', self
|
||||
evtchn_close(self.dom1, self.port1)
|
||||
evtchn_close(self.dom2, self.port2)
|
||||
|
||||
def sxpr(self):
|
||||
return ['event-channel',
|
||||
['dom1', self.dom1 ],
|
||||
['port1', self.port1 ],
|
||||
['dom2', self.dom2 ],
|
||||
['port2', self.port2 ]
|
||||
]
|
||||
|
||||
def __repr__(self):
|
||||
return ("<EventChannel dom1:%s:%s dom2:%s:%s>"
|
||||
% (self.dom1, self.port1, self.dom2, self.port2))
|
||||
|
||||
def eventChannel(dom1, dom2, port1=0, port2=0):
|
||||
"""Create an event channel between domains.
|
||||
|
||||
@return EventChannel (None on error)
|
||||
"""
|
||||
return EventChannel.interdomain(dom1, dom2, port1=port1, port2=port2)
|
||||
|
||||
def eventChannelClose(evtchn):
|
||||
"""Close an event channel that was opened by eventChannel().
|
||||
"""Close an event channel.
|
||||
"""
|
||||
def evtchn_close(dom, port):
|
||||
if (dom is None) or (port is None): return
|
||||
try:
|
||||
xc.evtchn_close(dom=dom, port=port)
|
||||
except Exception, ex:
|
||||
pass
|
||||
|
||||
if not evtchn: return
|
||||
if DEBUG:
|
||||
print 'eventChannelClose>', evtchn
|
||||
evtchn_close(evtchn.get('dom1'), evtchn.get('port1'))
|
||||
evtchn_close(evtchn.get('dom2'), evtchn.get('port2'))
|
||||
|
||||
evtchn.close()
|
||||
|
||||
class ChannelFactory:
|
||||
"""Factory for creating channels.
|
||||
"""Factory for creating control channels.
|
||||
Maintains a table of channels.
|
||||
"""
|
||||
|
||||
""" Channels indexed by index. """
|
||||
channels = {}
|
||||
channels = None
|
||||
|
||||
thread = None
|
||||
|
||||
notifier = None
|
||||
|
||||
"""Map of ports to the virq they signal."""
|
||||
virqPorts = {}
|
||||
virqPorts = None
|
||||
|
||||
def __init__(self):
|
||||
"""Constructor - do not use. Use the channelFactory function."""
|
||||
self.channels = {}
|
||||
self.virqPorts = {}
|
||||
self.notifier = xu.notifier()
|
||||
# Register interest in virqs.
|
||||
self.bind_virq(xen.lowlevel.xc.VIRQ_DOM_EXC)
|
||||
@@ -70,10 +108,6 @@ class ChannelFactory:
|
||||
self.virqPorts[port] = virq
|
||||
log.info("Virq %s on port %s", virq, port)
|
||||
|
||||
def virq(self):
|
||||
log.error("virq")
|
||||
self.notifier.virq_send(self.virqPort)
|
||||
|
||||
def start(self):
|
||||
"""Fork a thread to read messages.
|
||||
"""
|
||||
@@ -182,9 +216,13 @@ class ChannelFactory:
|
||||
return None
|
||||
|
||||
def openChannel(self, dom, local_port=0, remote_port=0):
|
||||
return (self.findChannel(dom, local_port=local_port, remote_port=remote_port)
|
||||
or
|
||||
self.newChannel(dom, local_port, remote_port))
|
||||
chan = self.findChannel(dom, local_port=local_port,
|
||||
remote_port=remote_port)
|
||||
if chan:
|
||||
return chan
|
||||
chan = self.newChannel(dom, local_port, remote_port)
|
||||
return chan
|
||||
|
||||
|
||||
def createPort(self, dom, local_port=0, remote_port=0):
|
||||
"""Create a port for a channel to the given domain.
|
||||
@@ -218,7 +256,7 @@ def channelFactory():
|
||||
return inst
|
||||
|
||||
class Channel:
|
||||
"""Chanel to a domain.
|
||||
"""Control channel to a domain.
|
||||
Maintains a list of device handlers to dispatch requests to, based
|
||||
on the request type.
|
||||
"""
|
||||
|
||||