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:
cl349@firebug.cl.cam.ac.uk committed 2005-06-06 20:18:09 +00:00
1 parent a801b2ab6b
commit 66a8df749b
2 files changed
+114 -48

No files matched your search

+42 -14
View File
@@ -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')
+72 -34
View File
@@ -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.
"""
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.