g/c unused control message code.

Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
This commit is contained in:
cl349@firebug.cl.cam.ac.uk committed 2005-09-07 18:28:04 +00:00
1 parent 7a36d2e972
commit 78552ee77c
11 files changed
+10 -1599

No files matched your search

-1
View File
@@ -36,7 +36,6 @@ from xen.xend import EventServer; eserver = EventServer.instance()
from xen.xend.XendError import XendError
from xen.xend.XendLogging import log
from xen.xend import scheduler
from xen.xend.server import channel
from xen.xend.server import relocate
from xen.xend.uuid import getUuid
from xen.xend.xenstore import XenNode, DBMap
+1 -31
View File
@@ -34,8 +34,7 @@ from xen.util.blkif import blkdev_uname_to_file
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 EventChannel, channelFactory
from xen.xend.server.channel import EventChannel
from xen.util.blkif import blkdev_name_to_number, expand_dev_name
from xen.xend import sxp
@@ -258,7 +257,6 @@ class XendDomainInfo:
self.target = None
self.channel = None
self.store_channel = None
self.store_mfn = None
self.console_channel = None
@@ -296,8 +294,6 @@ class XendDomainInfo:
self.db.saveDB(save=save, sync=sync)
def exportToDB(self, save=False, sync=False):
if self.channel:
self.channel.saveToDB(self.db.addChild("channel"), save=save)
if self.store_channel:
self.store_channel.saveToDB(self.db.addChild("store_channel"),
save=save)
@@ -330,9 +326,6 @@ class XendDomainInfo:
def getName(self):
return self.name
def getChannel(self):
return self.channel
def getStoreChannel(self):
return self.store_channel
@@ -569,8 +562,6 @@ class XendDomainInfo:
sxpr.append(['up_time', str(up_time) ])
sxpr.append(['start_time', str(self.start_time) ])
if self.channel:
sxpr.append(self.channel.sxpr())
if self.store_channel:
sxpr.append(self.store_channel.sxpr())
if self.store_mfn:
@@ -761,12 +752,6 @@ class XendDomainInfo:
"""
self.state = STATE_VM_TERMINATED
self.release_devices()
if self.channel:
try:
self.channel.close()
self.channel = None
except:
pass
if self.store_channel:
try:
self.store_channel.close()
@@ -858,20 +843,6 @@ class XendDomainInfo:
id, self.name, self.memory)
self.setdom(id)
def openChannel(self, key, local, remote):
"""Create a control channel to the domain.
If saved info is available recreate the channel.
@param key db key for the saved data (if any)
@param local default local port
@param remote default remote port
"""
db = self.db.addChild(key)
chan = channelFactory().restoreFromDB(db, self.id, local, remote)
#todo: save here?
#chan.saveToDB(db)
return chan
def eventChannel(self, key):
"""Create an event channel to the domain.
If saved info is available recreate the channel.
@@ -884,7 +855,6 @@ class XendDomainInfo:
def create_channel(self):
"""Create the channels to the domain.
"""
self.channel = self.openChannel("channel", 0, 1)
self.store_channel = self.eventChannel("store_channel")
self.console_channel = self.eventChannel("console/console_channel")
-14
View File
@@ -17,8 +17,6 @@ import traceback
import time
import glob
from xen.lowlevel import xu
from xen.xend import sxp
from xen.xend import PrettyPrint
from xen.xend import EventServer; eserver = EventServer.instance()
@@ -27,7 +25,6 @@ from xen.xend.server import SrvServer
from xen.xend.XendLogging import log
from xen.xend import XendRoot; xroot = XendRoot.instance()
import channel
import controller
import event
import relocate
@@ -37,7 +34,6 @@ class Daemon:
"""The xend daemon.
"""
def __init__(self):
self.channelF = None
self.shutdown = 0
self.traceon = 0
self.tracefile = None
@@ -298,10 +294,8 @@ class Daemon:
_enforce_dom0_cpus()
try:
log.info("Xend Daemon started")
self.createFactories()
event.listenEvent(self)
relocate.listenRelocation()
self.listenChannels()
servers = SrvServer.create()
self.daemonize()
servers.start()
@@ -312,15 +306,7 @@ class Daemon:
log.exception("Exception starting xend (%s)" % ex)
self.exit(1)
def createFactories(self):
self.channelF = channel.channelFactory()
def listenChannels(self):
self.channelF.start()
def exit(self, rc=0):
if self.channelF:
self.channelF.stop()
# Calling sys.exit() raises a SystemExit exception, which only
# kills the current thread. Calling os._exit() makes the whole
# Python process exit immediately. There doesn't seem to be another
+1 -157
View File
@@ -27,9 +27,7 @@ from xen.xend import sxp
from xen.xend import Blkctl
from xen.xend.xenstore import DBVar
from xen.xend.server import channel
from xen.xend.server.controller import CtrlMsgRcvr, Dev, DevController
from xen.xend.server.messages import *
from xen.xend.server.controller import Dev, DevController
class BlkifBackend:
""" Handler for the 'back-end' channel to a block device driver domain
@@ -41,21 +39,15 @@ class BlkifBackend:
self.controller = controller
self.id = id
self.frontendDomain = self.controller.getDomain()
self.frontendChannel = None
self.backendDomain = dom
self.backendChannel = None
self.destroyed = False
self.connected = False
self.evtchn = None
self.status = None
def init(self, recreate=False, reboot=False):
self.destroyed = False
self.status = BLKIF_INTERFACE_STATUS_DISCONNECTED
self.frontendDomain = self.controller.getDomain()
self.frontendChannel = self.controller.getChannel()
cf = channel.channelFactory()
self.backendChannel = cf.openChannel(self.backendDomain)
def __str__(self):
return ('<BlkifBackend frontend=%d backend=%d id=%d>'
@@ -66,29 +58,6 @@ class BlkifBackend:
def getId(self):
return self.id
def getEvtchn(self):
return self.evtchn
def closeEvtchn(self):
if self.evtchn:
channel.eventChannelClose(self.evtchn)
self.evtchn = None
def openEvtchn(self):
self.evtchn = channel.eventChannel(self.backendDomain, self.frontendDomain)
def getEventChannelBackend(self):
val = 0
if self.evtchn:
val = self.evtchn['port1']
return val
def getEventChannelFrontend(self):
val = 0
if self.evtchn:
val = self.evtchn['port2']
return val
def connect(self, recreate=False):
"""Connect to the blkif control interface.
@@ -98,83 +67,19 @@ class BlkifBackend:
if recreate or self.connected:
self.connected = True
pass
else:
self.send_be_create()
def send_be_create(self):
log.debug("send_be_create %s", str(self))
msg = packMsg('blkif_be_create_t',
{ 'domid' : self.frontendDomain,
'blkif_handle' : self.id })
msg = self.backendChannel.requestResponse(msg)
#todo: check return status
self.connected = True
def destroy(self, change=False, reboot=False):
"""Disconnect from the blkif control interface and destroy it.
"""
self.send_be_disconnect()
self.send_be_destroy()
self.closeEvtchn()
self.destroyed = True
# For change true need to notify front-end, or back-end will do it?
def send_be_disconnect(self):
msg = packMsg('blkif_be_disconnect_t',
{ 'domid' : self.frontendDomain,
'blkif_handle' : self.id })
self.backendChannel.requestResponse(msg)
#todo: check return status
self.connected = False
def send_be_destroy(self):
msg = packMsg('blkif_be_destroy_t',
{ 'domid' : self.frontendDomain,
'blkif_handle' : self.id })
self.backendChannel.requestResponse(msg)
#todo: check return status
def connectInterface(self, val):
self.openEvtchn()
log.debug("Connecting blkif to event channel %s ports=%d:%d",
str(self), self.evtchn['port1'], self.evtchn['port2'])
msg = packMsg('blkif_be_connect_t',
{ 'domid' : self.frontendDomain,
'blkif_handle' : self.id,
'evtchn' : self.getEventChannelBackend(),
'shmem_frame' : val['shmem_frame'],
'shmem_ref' : val['shmem_ref'] })
msg = self.backendChannel.requestResponse(msg)
#todo: check return status
val = unpackMsg('blkif_be_connect_t', msg)
self.status = BLKIF_INTERFACE_STATUS_CONNECTED
self.send_fe_interface_status()
def send_fe_interface_status(self):
msg = packMsg('blkif_fe_interface_status_t',
{ 'handle' : self.id,
'status' : self.status,
'domid' : self.backendDomain,
'evtchn' : self.getEventChannelFrontend() })
self.frontendChannel.writeRequest(msg)
def interfaceDisconnected(self):
self.status = BLKIF_INTERFACE_STATUS_DISCONNECTED
#todo?: Close evtchn:
#self.closeEvtchn()
self.send_fe_interface_status()
def interfaceChanged(self):
"""Notify the front-end that devices have been added or removed.
The front-end should then probe for devices.
"""
msg = packMsg('blkif_fe_interface_status_t',
{ 'handle' : self.id,
'status' : BLKIF_INTERFACE_STATUS_CHANGED,
'domid' : self.backendDomain,
'evtchn' : 0 })
self.frontendChannel.writeRequest(msg)
class BlkDev(Dev):
"""Info record for a block device.
"""
@@ -207,24 +112,17 @@ class BlkDev(Dev):
self.nr_sectors = None
self.frontendDomain = self.getDomain()
self.frontendChannel = None
self.backendDomain = None
self.backendChannel = None
self.backendId = 0
self.configure(self.config, recreate=recreate)
def exportToDB(self, save=False):
Dev.exportToDB(self, save=save)
backend = self.getBackend()
if backend and backend.evtchn:
db = self.db.addChild("evtchn")
backend.evtchn.saveToDB(db, save=save)
def init(self, recreate=False, reboot=False):
self.frontendDomain = self.getDomain()
self.frontendChannel = self.getChannel()
backend = self.getBackend()
self.backendChannel = backend.backendChannel
self.backendId = backend.id
def configure(self, config, change=False, recreate=False):
@@ -351,7 +249,6 @@ class BlkDev(Dev):
self.destroyed = True
log.debug("Destroying vbd domain=%d id=%s", self.frontendDomain,
self.id)
self.send_be_vbd_destroy()
if change:
self.interfaceChanged()
self.unbind()
@@ -367,30 +264,6 @@ class BlkDev(Dev):
"""
self.getBackend().connect()
self.send_be_vbd_create()
def send_be_vbd_create(self):
msg = packMsg('blkif_be_vbd_create_t',
{ 'domid' : self.frontendDomain,
'blkif_handle' : self.backendId,
'pdevice' : self.device,
'dev_handle' : self.dev_handle,
'vdevice' : self.vdev,
'readonly' : self.readonly() })
msg = self.backendChannel.requestResponse(msg)
val = unpackMsg('blkif_be_vbd_create_t', msg)
status = val['status']
if status != BLKIF_BE_STATUS_OKAY:
raise XendError("Creating vbd failed: device %s, error %d"
% (sxp.to_string(self.config), status))
def send_be_vbd_destroy(self):
msg = packMsg('blkif_be_vbd_destroy_t',
{ 'domid' : self.frontendDomain,
'blkif_handle' : self.backendId,
'vdevice' : self.vdev })
return self.backendChannel.writeRequest(msg)
class BlkifController(DevController):
"""Block device interface controller. Handles all block devices
@@ -403,19 +276,9 @@ class BlkifController(DevController):
DevController.__init__(self, vm, recreate=recreate)
self.backends = {}
self.backendId = 0
self.rcvr = None
def initController(self, recreate=False, reboot=False):
self.destroyed = False
# Add our handlers for incoming requests.
self.rcvr = CtrlMsgRcvr(self.getChannel())
self.rcvr.addHandler(CMSG_BLKIF_FE,
CMSG_BLKIF_FE_DRIVER_STATUS,
self.recv_fe_driver_status)
self.rcvr.addHandler(CMSG_BLKIF_FE,
CMSG_BLKIF_FE_INTERFACE_CONNECT,
self.recv_fe_interface_connect)
self.rcvr.registerChannel()
if reboot:
self.rebootBackends()
self.rebootDevices()
@@ -465,26 +328,7 @@ class BlkifController(DevController):
log.debug("Destroying blkif domain=%d", self.getDomain())
self.destroyDevices(reboot=reboot)
self.destroyBackends(reboot=reboot)
self.rcvr.deregisterChannel()
def destroyBackends(self, reboot=False):
for backend in self.backends.values():
backend.destroy(reboot=reboot)
def recv_fe_driver_status(self, msg):
val = unpackMsg('blkif_fe_driver_status_t', msg)
for backend in self.backends.values():
backend.interfaceDisconnected()
def recv_fe_interface_connect(self, msg):
val = unpackMsg('blkif_fe_interface_connect_t', msg)
id = val['handle']
backend = self.getBackendById(id)
if backend:
try:
backend.connectInterface(val)
except IOError, ex:
log.error("Exception connecting backend: %s", ex)
else:
log.error('interface connect on unknown interface: id=%d', id)
-472
View File
@@ -23,8 +23,6 @@ from xen.lowlevel import xu
from xen.xend.XendLogging import log
from messages import *
DEBUG = 0
RESPONSE_TIMEOUT = 20.0
@@ -132,473 +130,3 @@ def eventChannelClose(evtchn):
"""
if not evtchn: return
evtchn.close()
class ChannelFactory:
"""Factory for creating control channels.
Maintains a table of channels.
"""
""" Channels indexed by index. """
channels = None
thread = None
notifier = None
def __init__(self):
"""Constructor - do not use. Use the channelFactory function."""
self.channels = {}
self.notifier = xu.notifier()
def start(self):
"""Fork a thread to read messages.
"""
if self.thread: return
self.thread = threading.Thread(name="ChannelFactory",
target=self.main)
self.thread.setDaemon(True)
self.thread.start()
def stop(self):
"""Signal the thread to stop.
"""
self.thread = None
def main(self):
"""Main routine for the thread.
Reads the notifier and dispatches to channels.
"""
while True:
if self.thread == None: return
port = self.notifier.read()
if port:
self.msgReceived(port)
else:
select.select([self.notifier], [], [], 1.0)
def msgReceived(self, port):
# We run the message handlers in their own threads.
# Note we use keyword args to lambda to save the values -
# otherwise lambda will use the variables, which will get
# assigned by the loop and the lambda will get the changed values.
received = 0
for chan in self.channels.values():
if self.thread == None: return
msg = chan.readResponse()
if msg:
received += 1
chan.responseReceived(msg)
for chan in self.channels.values():
if self.thread == None: return
msg = chan.readRequest()
if msg:
received += 1
self.runInThread(lambda chan=chan, msg=msg: chan.requestReceived(msg))
if port and received == 0:
log.warning("Port %s notified, but no messages found", port)
def runInThread(self, thunk):
thread = threading.Thread(target = thunk)
thread.setDaemon(True)
thread.start()
def newChannel(self, dom, local_port, remote_port):
"""Create a new channel.
"""
return self.addChannel(Channel(self, dom, local_port, remote_port))
def addChannel(self, channel):
"""Add a channel.
"""
self.channels[channel.getKey()] = channel
return channel
def delChannel(self, channel):
"""Remove the channel.
"""
key = channel.getKey()
if key in self.channels:
del self.channels[key]
def getChannel(self, dom, local_port, remote_port):
"""Get the channel with the given domain and ports (if any).
"""
key = (dom, local_port, remote_port)
return self.channels.get(key)
def findChannel(self, dom, local_port=0, remote_port=0):
"""Find a channel. Ports given as zero are wildcards.
dom domain
returns channel
"""
chan = self.getChannel(dom, local_port, remote_port)
if chan: return chan
if local_port and remote_port:
return None
for c in self.channels.values():
if c.dom != dom: continue
if local_port and local_port != c.getLocalPort(): continue
if remote_port and remote_port != c.getRemotePort(): continue
return c
return None
def openChannel(self, dom, local_port=0, remote_port=0):
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.
If only the domain is specified, a new channel with new port ids is
created. If one port id is specified and the given port id is in use,
the other port id is filled. If one port id is specified and the
given port id is not in use, a new channel is created with one port
id equal to the given id and a new id for the other end. If both
port ids are specified, a port is reconnected using the given port
ids.
@param dom: domain
@param local: local port id to use
@type local: int
@param remote: remote port id to use
@type remote: int
@return: port object
"""
return xu.port(dom, local_port=local_port, remote_port=remote_port)
def restoreFromDB(self, db, dom, local, remote):
"""Create a channel using ports restored from the db (if available).
Otherwise use the given ports. This is the inverse operation to
saveToDB() on a channel.
@param db db
@param dom domain the channel connects to
@param local default local port
@param remote default remote port
"""
try:
local_port = int(db['local_port'])
except:
local_port = local
try:
remote_port = int(db['remote_port'])
except:
remote_port = remote
try:
chan = self.openChannel(dom, local_port, remote_port)
except:
return None
return chan
def channelFactory():
"""Singleton constructor for the channel factory.
Use this instead of the class constructor.
"""
global inst
try:
inst
except:
inst = ChannelFactory()
return inst
class Channel:
"""Control channel to a domain.
Maintains a list of device handlers to dispatch requests to, based
on the request type.
"""
def __init__(self, factory, dom, local_port, remote_port):
self.factory = factory
self.dom = int(dom)
# Registered device handlers.
self.devs = []
# Handlers indexed by the message types they handle.
self.devs_by_type = {}
self.port = self.factory.createPort(self.dom,
local_port=local_port,
remote_port=remote_port)
self.closed = False
# Queue of waiters for responses to requests.
self.queue = ResponseQueue(self)
# Make sure the port will deliver all the messages.
self.port.register(TYPE_WILDCARD)
def saveToDB(self, db, save=False):
"""Save the channel ports to the db so the channel can be restored later,
using restoreFromDB() on the factory.
@param db db
"""
if self.closed: return
db['local_port'] = str(self.getLocalPort())
db['remote_port'] = str(self.getRemotePort())
db.saveDB(save=save)
def getKey(self):
"""Get the channel key.
"""
return (self.dom, self.getLocalPort(), self.getRemotePort())
def sxpr(self):
val = ['channel']
val.append(['domain', self.dom])
if self.port:
val.append(['local_port', self.port.local_port])
val.append(['remote_port', self.port.remote_port])
return val
def close(self):
"""Close the channel.
"""
if DEBUG:
print 'Channel>close>', self
if self.closed: return
self.closed = True
self.factory.delChannel(self)
for d in self.devs[:]:
d.lostChannel(self)
self.devs = []
self.devs_by_type = {}
if self.port:
self.port.close()
#self.port = None
def getDomain(self):
return self.dom
def getLocalPort(self):
"""Get the local port.
@return: local port
@rtype: int
"""
if self.closed: return -1
return self.port.local_port
def getRemotePort(self):
"""Get the remote port.
@return: remote port
@rtype: int
"""
if self.closed: return -1
return self.port.remote_port
def __repr__(self):
return ('<Channel dom=%d ports=%d:%d>'
% (self.dom,
self.getLocalPort(),
self.getRemotePort()))
def registerDevice(self, types, dev):
"""Register a device message handler.
@param types: message types handled
@type types: array of ints
@param dev: device handler
"""
if self.closed: return
self.devs.append(dev)
for ty in types:
self.devs_by_type[ty] = dev
def deregisterDevice(self, dev):
"""Remove the registration for a device handler.
@param dev: device handler
"""
if dev in self.devs:
self.devs.remove(dev)
types = [ ty for (ty, d) in self.devs_by_type.items() if d == dev ]
for ty in types:
del self.devs_by_type[ty]
def getDevice(self, type):
"""Get the handler for a message type.
@param type: message type
@type type: int
@return: controller or None
@rtype: device handler
"""
return self.devs_by_type.get(type)
def requestReceived(self, msg):
"""A request has been received on the channel.
Disptach it to the device handlers.
Called from the channel factory thread.
"""
if DEBUG:
print 'Channel>requestReceived>', self,
printMsg(msg)
(ty, subty) = getMessageType(msg)
responded = False
dev = self.getDevice(ty)
if dev:
responded = dev.requestReceived(msg, ty, subty)
elif DEBUG:
print "Channel>requestReceived> No device handler", self,
printMsg(msg)
else:
pass
if not responded:
self.writeResponse(msg)
def writeRequest(self, msg):
"""Write a request to the channel.
"""
if DEBUG:
print 'Channel>writeRequest>', self,
printMsg(msg, all=True)
if self.closed: return -1
self.port.write_request(msg)
return 1
def writeResponse(self, msg):
"""Write a response to the channel.
"""
if DEBUG:
print 'Channel>writeResponse>', self,
printMsg(msg, all=True)
if self.port:
self.port.write_response(msg)
return 1
def readRequest(self):
"""Read a request from the channel.
Called internally.
"""
if self.closed:
val = None
else:
val = self.port.read_request()
return val
def readResponse(self):
"""Read a response from the channel.
Called internally.
"""
if self.closed:
val = None
else:
val = self.port.read_response()
if DEBUG and val:
print 'Channel>readResponse>', self,
printMsg(val, all=True)
return val
def requestResponse(self, msg, timeout=None):
"""Write a request and wait for a response.
Raises IOError on timeout.
@param msg request message
@param timeout timeout (0 is forever)
@return response message
"""
if self.closed:
raise IOError("closed")
if self.closed:
return None
if timeout is None:
timeout = RESPONSE_TIMEOUT
elif timeout <= 0:
timeout = None
return self.queue.call(msg, timeout)
def responseReceived(self, msg):
"""A response has been received, look for a waiter to
give it to.
Called internally.
"""
if DEBUG:
print 'Channel>responseReceived>', self,
printMsg(msg)
self.queue.response(getMessageId(msg), msg)
class Response:
"""Entry in the response queue.
Used to signal a response to a message.
"""
def __init__(self, mid):
self.mid = mid
self.msg = None
self.ready = threading.Event()
def response(self, msg):
"""Signal arrival of a response to a waiting thread.
Passing msg None cancels the wait with an IOError.
"""
if msg:
self.msg = msg
else:
self.mid = -1
self.ready.set()
def wait(self, timeout):
"""Wait up to 'timeout' seconds for a response.
Returns the response or raises an IOError.
"""
self.ready.wait(timeout)
if self.mid < 0:
raise IOError("wait canceled")
if self.msg is None:
raise IOError("response timeout")
return self.msg
class ResponseQueue:
"""Response queue. Manages waiters for responses to messages.
"""
def __init__(self, channel):
self.channel = channel
self.lock = threading.Lock()
self.responses = {}
def add(self, mid):
r = Response(mid)
self.responses[mid] = r
return r
def get(self, mid):
return self.responses.get(mid)
def remove(self, mid):
r = self.responses.get(mid)
if r:
del self.responses[mid]
return r
def response(self, mid, msg):
"""Process a response - signals any waiter that a response
has arrived.
"""
try:
self.lock.acquire()
r = self.remove(mid)
finally:
self.lock.release()
if r:
r.response(msg)
def call(self, msg, timeout):
"""Send the message and wait for 'timeout' seconds for a response.
Returns the response.
Raises IOError on timeout.
"""
mid = getMessageId(msg)
try:
self.lock.acquire()
r = self.add(mid)
finally:
self.lock.release()
self.channel.writeRequest(msg)
return r.wait(timeout)
-105
View File
@@ -21,107 +21,9 @@ for a domain.
from xen.xend.XendError import XendError
from xen.xend.xenstore import DBVar
from xen.xend.server.messages import msgTypeName, printMsg, getMessageType
DEBUG = 0
class CtrlMsgRcvr:
"""Utility class to dispatch messages on a control channel.
Once I{registerChannel} has been called, our message types are registered
with the channel. The channel will call I{requestReceived}
when a request arrives if it has one of our message types.
@ivar channel: channel to a domain
@type channel: Channel
@ivar majorTypes: major message types we are interested in
@type majorTypes: {int:{int:method}}
"""
def __init__(self, channel):
self.majorTypes = {}
self.channel = channel
def getHandler(self, type, subtype):
"""Get the method for a type and subtype.
@param type: major message type
@param subtype: minor message type
@return: method or None
"""
method = None
subtypes = self.majorTypes.get(type)
if subtypes:
method = subtypes.get(subtype)
return method
def addHandler(self, type, subtype, method):
"""Add a method to handle a message type and subtype.
@param type: major message type
@param subtype: minor message type
@param method: method
"""
subtypes = self.majorTypes.get(type)
if not subtypes:
subtypes = {}
self.majorTypes[type] = subtypes
subtypes[subtype] = method
def getMajorTypes(self):
"""Get the list of major message types handled.
"""
return self.majorTypes.keys()
def requestReceived(self, msg, type, subtype):
"""Dispatch a request message to handlers.
Called by the channel for requests with one of our types.
@param msg: message
@type msg: xu message
@param type: major message type
@type type: int
@param subtype: minor message type
@type subtype: int
"""
if DEBUG:
print 'requestReceived>',
printMsg(msg, all=True)
responded = 0
method = self.getHandler(type, subtype)
if method:
responded = method(msg)
elif DEBUG:
print ('requestReceived> No handler: Message type %s %d:%d'
% (msgTypeName(type, subtype), type, subtype)), self
return responded
def lostChannel(self):
"""Called when the channel to the domain is lost.
"""
if DEBUG:
print 'CtrlMsgRcvr>lostChannel>',
self.channel = None
def registerChannel(self):
"""Register interest in our major message types with the
channel to our domain. Once we have registered, the channel
will call requestReceived for our messages.
"""
if DEBUG:
print 'CtrlMsgRcvr>registerChannel>', self.channel, self.getMajorTypes()
if self.channel:
self.channel.registerDevice(self.getMajorTypes(), self)
def deregisterChannel(self):
"""Deregister interest in our major message types with the
channel to our domain. After this the channel won't call
us any more.
"""
if self.channel:
self.channel.deregisterDevice(self)
class DevControllerTable:
"""Table of device controller classes, indexed by type name.
"""
@@ -232,10 +134,6 @@ class DevController:
def getDomainName(self):
return self.vm.getName()
def getChannel(self):
chan = self.vm.getChannel()
return chan
def getDomainInfo(self):
return self.vm
@@ -433,9 +331,6 @@ class Dev:
def getDomainName(self):
return self.controller.getDomainName()
def getChannel(self):
return self.controller.getChannel()
def getDomainInfo(self):
return self.controller.getDomainInfo()
-5
View File
@@ -174,11 +174,6 @@ class EventProtocol(protocol.Protocol):
else:
logging.removeLogStderr()
def op_debug_msg(self, name, v):
mode = v[1]
import messages
messages.DEBUG = (mode == 'on')
def op_debug_controller(self, name, v):
mode = v[1]
import controller
-462
View File
@@ -1,462 +0,0 @@
#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
#============================================================================
import sys
import struct
import types
from xen.lowlevel import xu
DEBUG = False
#PORT_WILDCARD = 0xefffffff
"""Wildcard for the control message types."""
TYPE_WILDCARD = 0xffff
""" All message formats.
Added to incrementally for the various message types.
See below.
"""
msg_formats = {}
#============================================================================
# Block interface message types.
#============================================================================
CMSG_BLKIF_BE = 1
CMSG_BLKIF_FE = 2
CMSG_BLKIF_FE_INTERFACE_STATUS = 0
CMSG_BLKIF_FE_DRIVER_STATUS = 32
CMSG_BLKIF_FE_INTERFACE_CONNECT = 33
CMSG_BLKIF_FE_INTERFACE_DISCONNECT = 34
CMSG_BLKIF_FE_INTERFACE_QUERY = 35
CMSG_BLKIF_BE_CREATE = 0
CMSG_BLKIF_BE_DESTROY = 1
CMSG_BLKIF_BE_CONNECT = 2
CMSG_BLKIF_BE_DISCONNECT = 3
CMSG_BLKIF_BE_VBD_CREATE = 4
CMSG_BLKIF_BE_VBD_DESTROY = 5
CMSG_BLKIF_BE_DRIVER_STATUS = 32
BLKIF_DRIVER_STATUS_DOWN = 0
BLKIF_DRIVER_STATUS_UP = 1
BLKIF_INTERFACE_STATUS_CLOSED = 0 #/* Interface doesn't exist. */
BLKIF_INTERFACE_STATUS_DISCONNECTED = 1 #/* Exists but is disconnected. */
BLKIF_INTERFACE_STATUS_CONNECTED = 2 #/* Exists and is connected. */
BLKIF_INTERFACE_STATUS_CHANGED = 3 #/* A device has been added or removed. */
BLKIF_BE_STATUS_OKAY = 0
BLKIF_BE_STATUS_ERROR = 1
BLKIF_BE_STATUS_INTERFACE_EXISTS = 2
BLKIF_BE_STATUS_INTERFACE_NOT_FOUND = 3
BLKIF_BE_STATUS_INTERFACE_CONNECTED = 4
BLKIF_BE_STATUS_VBD_EXISTS = 5
BLKIF_BE_STATUS_VBD_NOT_FOUND = 6
BLKIF_BE_STATUS_OUT_OF_MEMORY = 7
BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND = 8
BLKIF_BE_STATUS_MAPPING_ERROR = 9
blkif_formats = {
'blkif_be_connect_t':
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CONNECT),
# Connect be to fe (in response to blkif_fe_interface_connect_t).
'blkif_be_create_t':
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CREATE),
# Create be.
'blkif_be_disconnect_t':
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DISCONNECT),
# Disconnect be from fe.
'blkif_be_destroy_t':
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DESTROY),
# Destroy be (after disconnect).
# Make be do this even if no disconnect (and destroy all vbd too).
'blkif_be_vbd_create_t':
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_CREATE),
# Create a vbd device.
'blkif_be_vbd_destroy_t':
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_DESTROY),
# Destroy a vbd.
# Add message to query be for state and vbds.
'blkif_fe_interface_status_t':
(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS),
# Notify device status to fe.
# Also used to notify 'any' device change with status BLKIF_INTERFACE_STATUS_CHANGED.
'blkif_fe_driver_status_t':
(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS),
# Comes from fe, treated as notifying that fe has come up/changed.
# Xend sets be(s) to BLKIF_INTERFACE_STATUS_DISCONNECTED,
# sends blkif_fe_interface_status_t to fe (from each be).
#
# Reply with i/f count.
# The i/f sends probes (using -ve trick), we reply with the info.
'blkif_fe_interface_connect_t':
(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_CONNECT),
# Comes from fe, passing shmem frame to use for be.
# fe sends when gets blkif_fe_interface_status_t with state NETIF_INTERFACE_STATUS_DISCONNECTED.
# Xend creates event channel and notifies be.
# Then notifies fe of event channel with blkif_fe_interface_status_t.
# Add message to kick fe to probe for devices.
# Just report new devices to fe?
#
# Add message for fe to probe a device.
# And probing with id -1 should return first.
# And probing with id -n should return first device with id > n.
# Add message to query fe for state and vbds.
}
msg_formats.update(blkif_formats)
#============================================================================
# Network interface message types.
#============================================================================
CMSG_NETIF_BE = 3
CMSG_NETIF_FE = 4
CMSG_NETIF_FE_INTERFACE_STATUS = 0
CMSG_NETIF_FE_DRIVER_STATUS = 32
CMSG_NETIF_FE_INTERFACE_CONNECT = 33
CMSG_NETIF_FE_INTERFACE_DISCONNECT = 34
CMSG_NETIF_FE_INTERFACE_QUERY = 35
CMSG_NETIF_BE_CREATE = 0
CMSG_NETIF_BE_DESTROY = 1
CMSG_NETIF_BE_CONNECT = 2
CMSG_NETIF_BE_DISCONNECT = 3
CMSG_NETIF_BE_CREDITLIMIT = 4
CMSG_NETIF_BE_DRIVER_STATUS = 32
NETIF_INTERFACE_STATUS_CLOSED = 0 #/* Interface doesn't exist. */
NETIF_INTERFACE_STATUS_DISCONNECTED = 1 #/* Exists but is disconnected. */
NETIF_INTERFACE_STATUS_CONNECTED = 2 #/* Exists and is connected. */
NETIF_INTERFACE_STATUS_CHANGED = 3 #/* A device has been added or removed. */
NETIF_DRIVER_STATUS_DOWN = 0
NETIF_DRIVER_STATUS_UP = 1
netif_formats = {
'netif_be_connect_t':
(CMSG_NETIF_BE, CMSG_NETIF_BE_CONNECT),
'netif_be_create_t':
(CMSG_NETIF_BE, CMSG_NETIF_BE_CREATE),
'netif_be_disconnect_t':
(CMSG_NETIF_BE, CMSG_NETIF_BE_DISCONNECT),
'netif_be_destroy_t':
(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY),
'netif_be_creditlimit_t':
(CMSG_NETIF_BE, CMSG_NETIF_BE_CREDITLIMIT),
'netif_be_driver_status_t':
(CMSG_NETIF_BE, CMSG_NETIF_BE_DRIVER_STATUS),
'netif_fe_driver_status_t':
(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS),
'netif_fe_interface_connect_t':
(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_CONNECT),
'netif_fe_interface_status_t':
(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS),
}
msg_formats.update(netif_formats)
#============================================================================
# USB interface message types.
#============================================================================
CMSG_USBIF_BE = 8
CMSG_USBIF_FE = 9
CMSG_USBIF_FE_INTERFACE_STATUS_CHANGED = 0
CMSG_USBIF_FE_DRIVER_STATUS_CHANGED = 32
CMSG_USBIF_FE_INTERFACE_CONNECT = 33
CMSG_USBIF_FE_INTERFACE_DISCONNECT = 34
USBIF_DRIVER_STATUS_DOWN = 0
USBIF_DRIVER_STATUS_UP = 1
USBIF_INTERFACE_STATUS_DESTROYED = 0 #/* Interface doesn't exist. */
USBIF_INTERFACE_STATUS_DISCONNECTED = 1 #/* Exists but is disconnected. */
USBIF_INTERFACE_STATUS_CONNECTED = 2 #/* Exists and is connected. */
CMSG_USBIF_BE_CREATE = 0
CMSG_USBIF_BE_DESTROY = 1
CMSG_USBIF_BE_CONNECT = 2
CMSG_USBIF_BE_DISCONNECT = 3
CMSG_USBIF_BE_CLAIM_PORT = 4
CMSG_USBIF_BE_RELEASE_PORT = 5
CMSG_USBIF_BE_DRIVER_STATUS_CHANGED = 32
USBIF_BE_STATUS_OKAY = 0
USBIF_BE_STATUS_ERROR = 1
USBIF_BE_STATUS_INTERFACE_EXISTS = 2
USBIF_BE_STATUS_INTERFACE_NOT_FOUND = 3
USBIF_BE_STATUS_INTERFACE_CONNECTED = 4
USBIF_BE_STATUS_OUT_OF_MEMORY = 7
USBIF_BE_STATUS_MAPPING_ERROR = 9
usbif_formats = {
'usbif_be_create_t':
(CMSG_USBIF_BE, CMSG_USBIF_BE_CREATE),
'usbif_be_destroy_t':
(CMSG_USBIF_BE, CMSG_USBIF_BE_DESTROY),
'usbif_be_connect_t':
(CMSG_USBIF_BE, CMSG_USBIF_BE_CONNECT),
'usbif_be_disconnect_t':
(CMSG_USBIF_BE, CMSG_USBIF_BE_DISCONNECT),
'usbif_be_claim_port_t':
(CMSG_USBIF_BE, CMSG_USBIF_BE_CLAIM_PORT),
'usbif_be_release_port_t':
(CMSG_USBIF_BE, CMSG_USBIF_BE_RELEASE_PORT),
'usbif_fe_interface_status_changed_t':
(CMSG_USBIF_FE, CMSG_USBIF_FE_INTERFACE_STATUS_CHANGED),
'usbif_fe_driver_status_changed_t':
(CMSG_USBIF_FE, CMSG_USBIF_FE_DRIVER_STATUS_CHANGED),
'usbif_fe_interface_connect_t':
(CMSG_USBIF_FE, CMSG_USBIF_FE_INTERFACE_CONNECT),
'usbif_fe_interface_disconnect_t':
(CMSG_USBIF_FE, CMSG_USBIF_FE_INTERFACE_DISCONNECT),
}
msg_formats.update(usbif_formats)
#============================================================================
# Domain shutdown message types.
#============================================================================
CMSG_SHUTDOWN = 6
CMSG_SHUTDOWN_POWEROFF = 0
CMSG_SHUTDOWN_REBOOT = 1
CMSG_SHUTDOWN_SUSPEND = 2
CMSG_SHUTDOWN_SYSRQ = 3
STOPCODE_shutdown = 0
STOPCODE_reboot = 1
STOPCODE_suspend = 2
STOPCODE_sysrq = 3
shutdown_formats = {
'shutdown_poweroff_t':
(CMSG_SHUTDOWN, CMSG_SHUTDOWN_POWEROFF),
'shutdown_reboot_t':
(CMSG_SHUTDOWN, CMSG_SHUTDOWN_REBOOT),
'shutdown_suspend_t':
(CMSG_SHUTDOWN, CMSG_SHUTDOWN_SUSPEND),
'shutdown_sysrq_t':
(CMSG_SHUTDOWN, CMSG_SHUTDOWN_SYSRQ)
}
msg_formats.update(shutdown_formats)
#============================================================================
# Domain memory reservation message.
#============================================================================
CMSG_MEM_REQUEST = 7
CMSG_MEM_REQUEST_SET = 0
mem_request_formats = {
'mem_request_t':
(CMSG_MEM_REQUEST, CMSG_MEM_REQUEST_SET)
}
msg_formats.update(mem_request_formats)
#============================================================================
# Domain vcpu hotplug message.
#============================================================================
CMSG_VCPU_HOTPLUG = 10
CMSG_VCPU_HOTPLUG_OFF = 0
CMSG_VCPU_HOTPLUG_ON = 1
vcpu_hotplug_formats = {
'vcpu_hotplug_off_t':
(CMSG_VCPU_HOTPLUG, CMSG_VCPU_HOTPLUG_OFF),
'vcpu_hotplug_on_t':
(CMSG_VCPU_HOTPLUG, CMSG_VCPU_HOTPLUG_ON)
}
msg_formats.update(vcpu_hotplug_formats)
#============================================================================
class Msg:
pass
_next_msgid = 0
def nextid():
"""Generate the next message id.
@return: message id
@rtype: int
"""
global _next_msgid
_next_msgid += 1
return _next_msgid
def packMsg(ty, params):
"""Pack a message.
Any I{mac} parameter is passed in as an int[6] array and converted.
@param ty: message type name
@type ty: string
@param params: message parameters
@type params: dicy
@return: message
@rtype: xu message
"""
msgid = nextid()
if DEBUG: print '>packMsg', msgid, ty, params
(major, minor) = msg_formats[ty]
args = {}
for (k, v) in params.items():
if k in ['mac', 'be_mac']:
for i in range(0, 6):
args['%s[%d]' % (k, i)] = v[i]
else:
args[k] = v
msg = xu.message(major, minor, msgid, args)
if DEBUG: print '<packMsg', msg.get_header()['id'], ty, args
return msg
def unpackMsg(ty, msg):
"""Unpack a message.
Any mac addresses in the message are converted to int[6] array
in the return dict.
@param ty: message type
@type ty: string
@param msg: message
@type msg: xu message
@return: parameters
@rtype: dict
"""
args = msg.get_payload()
if DEBUG: print '>unpackMsg', args
if isinstance(args, types.StringType):
args = {'value': args}
else:
mac = [0, 0, 0, 0, 0, 0]
macs = []
for (k, v) in args.items():
if k.startswith('mac['):
macs.append(k)
i = int(k[4:5])
mac[i] = v
else:
pass
if macs:
args['mac'] = mac
#print 'macs=', macs
#print 'args=', args
for k in macs:
del args[k]
if DEBUG:
msgid = msg.get_header()['id']
print '<unpackMsg', msgid, ty, args
return args
def msgTypeName(ty, subty):
"""Convert a message type, subtype pair to a message type name.
@param ty: message type
@type ty: int
@param subty: message subtype
@type ty: int
@return: message type name (or None)
@rtype: string or None
"""
for (name, info) in msg_formats.items():
if info[0] == ty and info[1] == subty:
return name
return None
def printMsg(msg, out=sys.stdout, all=False):
"""Print a message.
@param msg: message
@type msg: xu message
@param out: where to print to
@type out: stream
@param all: print payload if true
@type all: bool
"""
hdr = msg.get_header()
major = hdr['type']
minor = hdr['subtype']
msgid = hdr['id']
ty = msgTypeName(major, minor)
print >>out, 'message:', 'type=', ty, '%d:%d' % (major, minor), 'id=%d' % msgid
if all:
print >>out, 'payload=', msg.get_payload()
def getMessageType(msg):
"""Get a 2-tuple of the message type and subtype.
@param msg: message
@type msg: xu message
@return: type info
@rtype: (int, int)
"""
hdr = msg.get_header()
return (hdr['type'], hdr.get('subtype'))
def getMessageId(msg):
hdr = msg.get_header()
return hdr['id']
+4 -176
View File
@@ -30,9 +30,7 @@ from xen.xend import XendVnet
from xen.xend.XendRoot import get_component
from xen.xend.xenstore import DBVar
from xen.xend.server import channel
from xen.xend.server.controller import CtrlMsgRcvr, Dev, DevController
from xen.xend.server.messages import *
from xen.xend.server.controller import Dev, DevController
class NetDev(Dev):
"""A network device.
@@ -90,12 +88,9 @@ class NetDev(Dev):
def __init__(self, controller, id, config, recreate=False):
Dev.__init__(self, controller, id, config, recreate=recreate)
self.vif = int(self.id)
self.evtchn = None
self.status = None
self.frontendDomain = self.getDomain()
self.frontendChannel = None
self.backendDomain = None
self.backendChannel = None
self.credit = None
self.period = None
self.mac = None
@@ -109,17 +104,11 @@ class NetDev(Dev):
def exportToDB(self, save=False):
Dev.exportToDB(self, save=save)
if self.evtchn:
db = self.db.addChild("evtchn")
self.evtchn.saveToDB(db, save=save)
def init(self, recreate=False, reboot=False):
self.destroyed = False
self.status = NETIF_INTERFACE_STATUS_DISCONNECTED
self.frontendDomain = self.getDomain()
self.frontendChannel = self.getChannel()
cf = channel.channelFactory()
self.backendChannel = cf.openChannel(self.backendDomain)
def _get_config_mac(self, config):
vmac = sxp.child_value(config, 'mac')
@@ -287,10 +276,6 @@ class NetDev(Dev):
val.append(['credit', self.credit])
if self.period:
val.append(['period', self.period])
if self.evtchn:
val.append(['evtchn',
self.evtchn['port1'],
self.evtchn['port2']])
return val
def get_vifname(self):
@@ -348,42 +333,11 @@ class NetDev(Dev):
if recreate:
pass
else:
self.send_be_create()
if self.credit and self.period:
self.send_be_creditlimit(self.credit, self.period)
#self.send_be_creditlimit(self.credit, self.period)
pass
self.vifctl('up', vmname=self.getDomainName())
def closeEvtchn(self):
if self.evtchn:
channel.eventChannelClose(self.evtchn)
self.evtchn = None
def openEvtchn(self):
self.evtchn = channel.eventChannel(self.backendDomain, self.frontendDomain)
def getEventChannelBackend(self):
val = 0
if self.evtchn:
val = self.evtchn['port1']
return val
def getEventChannelFrontend(self):
val = 0
if self.evtchn:
val = self.evtchn['port2']
return val
def send_be_create(self):
msg = packMsg('netif_be_create_t',
{ 'domid' : self.frontendDomain,
'netif_handle' : self.vif,
'be_mac' : self.be_mac or [0, 0, 0, 0, 0, 0],
'mac' : self.mac,
#'vifname' : self.vifname
})
msg = self.backendChannel.requestResponse(msg)
# todo: check return status
def destroy(self, change=False, reboot=False):
"""Destroy the device's resources and disconnect from the back-end
device controller. If 'change' is true notify the front-end interface.
@@ -393,47 +347,14 @@ class NetDev(Dev):
self.destroyed = True
self.status = NETIF_INTERFACE_STATUS_CLOSED
log.debug("Destroying vif domain=%d vif=%d", self.frontendDomain, self.vif)
self.closeEvtchn()
self.vifctl('down')
self.send_be_disconnect()
self.send_be_destroy()
if change:
self.reportStatus()
def send_be_disconnect(self):
msg = packMsg('netif_be_disconnect_t',
{ 'domid' : self.frontendDomain,
'netif_handle' : self.vif })
self.backendChannel.requestResponse(msg)
#todo: check return status
def send_be_destroy(self, response=None):
msg = packMsg('netif_be_destroy_t',
{ 'domid' : self.frontendDomain,
'netif_handle' : self.vif })
self.backendChannel.requestResponse(msg)
#todo: check return status
def recv_fe_interface_connect(self, val):
self.openEvtchn()
msg = packMsg('netif_be_connect_t',
{ 'domid' : self.frontendDomain,
'netif_handle' : self.vif,
'evtchn' : self.getEventChannelBackend(),
'tx_shmem_frame' : val['tx_shmem_frame'],
'tx_shmem_ref' : val['tx_shmem_ref'],
'rx_shmem_frame' : val['rx_shmem_frame'],
'rx_shmem_ref' : val['rx_shmem_ref'] })
msg = self.backendChannel.requestResponse(msg)
#todo: check return status
self.status = NETIF_INTERFACE_STATUS_CONNECTED
self.reportStatus()
def setCreditLimit(self, credit, period):
#todo: these params should be in sxpr and vif config.
self.credit = credit
self.period = period
self.send_be_creditlimit(credit, period)
def getCredit(self):
return self.credit
@@ -441,31 +362,10 @@ class NetDev(Dev):
def getPeriod(self):
return self.period
def send_be_creditlimit(self, credit, period):
msg = packMsg('netif_be_creditlimit_t',
{ 'domid' : self.frontendDomain,
'netif_handle' : self.vif,
'credit_bytes' : credit,
'period_usec' : period })
msg = self.backendChannel.requestResponse(msg)
# todo: check return status
def reportStatus(self, resp=False):
msg = packMsg('netif_fe_interface_status_t',
{ 'handle' : self.vif,
'status' : self.status,
'evtchn' : self.getEventChannelFrontend(),
'domid' : self.backendDomain,
'mac' : self.mac })
if resp:
self.frontendChannel.writeResponse(msg)
else:
self.frontendChannel.writeRequest(msg)
def interfaceChanged(self):
"""Notify the front-end that a device has been added or removed.
"""
self.reportStatus()
pass
class NetifController(DevController):
"""Network interface controller. Handles all network devices for a domain.
@@ -473,25 +373,9 @@ class NetifController(DevController):
def __init__(self, vm, recreate=False):
DevController.__init__(self, vm, recreate=recreate)
self.channel = None
self.rcvr = None
self.channel = None
def initController(self, recreate=False, reboot=False):
self.destroyed = False
self.channel = self.getChannel()
# Register our handlers for incoming requests.
self.rcvr = CtrlMsgRcvr(self.channel)
self.rcvr.addHandler(CMSG_NETIF_FE,
CMSG_NETIF_FE_DRIVER_STATUS,
self.recv_fe_driver_status)
self.rcvr.addHandler(CMSG_NETIF_FE,
CMSG_NETIF_FE_INTERFACE_STATUS,
self.recv_fe_interface_status)
self.rcvr.addHandler(CMSG_NETIF_FE,
CMSG_NETIF_FE_INTERFACE_CONNECT,
self.recv_fe_interface_connect)
self.rcvr.registerChannel()
if reboot:
self.rebootDevices()
@@ -501,8 +385,6 @@ class NetifController(DevController):
self.destroyed = True
log.debug("Destroying netif domain=%d", self.getDomain())
self.destroyDevices(reboot=reboot)
if self.rcvr:
self.rcvr.deregisterChannel()
def sxpr(self):
val = ['netif', ['dom', self.getDomain()]]
@@ -524,57 +406,3 @@ class NetifController(DevController):
dev = self.devices[vif]
return dev.setCreditLimit(credit, period)
def recv_fe_driver_status(self, msg):
msg = packMsg('netif_fe_driver_status_t',
{ 'status' : NETIF_DRIVER_STATUS_UP,
## FIXME: max_handle should be max active interface id
'max_handle' : self.getDeviceCount()
#'max_handle' : self.getMaxDeviceId()
})
# Two ways of doing it:
# 1) front-end requests driver status, we reply with the interface count,
# front-end polls the interfaces,
# front-end checks they are all up
# 2) front-end requests driver status, we reply (with anything),
# we notify the interfaces,
# we notify driver status up with the count
# front-end checks they are all up
#
# We really want to use 1), but at the moment the xenU kernel panics
# in that mode, so we're sticking to 2) for now.
resp = False
if resp:
self.channel.writeResponse(msg)
else:
for dev in self.devices.values():
dev.reportStatus()
self.channel.writeRequest(msg)
return resp
def recv_fe_interface_status(self, msg):
val = unpackMsg('netif_fe_interface_status_t', msg)
vif = val['handle']
dev = self.findDevice(vif)
if dev:
dev.reportStatus(resp=True)
else:
log.error('Received netif_fe_interface_status for unknown vif: dom=%d vif=%d',
self.getDomain(), vif)
msg = packMsg('netif_fe_interface_status_t',
{ 'handle' : -1,
'status' : NETIF_INTERFACE_STATUS_CLOSED,
});
self.channel.writeResponse(msg)
return True
def recv_fe_interface_connect(self, msg):
val = unpackMsg('netif_fe_interface_connect_t', msg)
vif = val['handle']
dev = self.getDevice(vif)
if dev:
dev.recv_fe_interface_connect(val)
else:
log.error('Received netif_fe_interface_connect for unknown vif: dom=%d vif=%d',
self.getDomain(), vif)
+1 -8
View File
@@ -13,9 +13,7 @@ from xen.xend.XendLogging import log
from xen.xend.XendRoot import get_component
from xen.xend.xenstore import DBVar
from xen.xend.server import channel
from xen.xend.server.controller import CtrlMsgRcvr, Dev, DevController
from xen.xend.server.messages import *
from xen.xend.server.controller import Dev, DevController
class TPMifController(DevController):
"""TPM interface controller. Handles all TPM devices for a domain.
@@ -23,20 +21,15 @@ class TPMifController(DevController):
def __init__(self, vm, recreate=False):
DevController.__init__(self, vm, recreate=recreate)
self.rcvr = None
self.channel = None
def initController(self, recreate=False, reboot=False):
self.destroyed = False
self.channel = self.getChannel()
def destroyController(self, reboot=False):
"""Destroy the controller and all devices.
"""
self.destroyed = True
self.destroyDevices(reboot=reboot)
if self.rcvr:
self.rcvr.deregisterChannel()
def sxpr(self):
val = ['tpmif', ['dom', self.getDomain()]]
+3 -168
View File
@@ -9,9 +9,7 @@ from xen.xend.XendLogging import log
from xen.xend.XendError import XendError
from xen.xend.xenstore import DBVar
from xen.xend.server import channel
from xen.xend.server.controller import Dev, DevController
from xen.xend.server.messages import *
class UsbBackend:
"""Handler for the 'back-end' channel to a USB device driver domain
@@ -25,40 +23,16 @@ class UsbBackend:
self.connecting = False
self.frontendDomain = self.controller.getDomain()
self.backendDomain = dom
self.frontendChannel = None
self.backendChannel = None
def init(self, recreate=False, reboot=False):
self.frontendChannel = self.controller.getChannel()
cf = channel.channelFactory()
self.backendChannel = cf.openChannel(self.backendDomain)
pass
def __str__(self):
return ('<UsbifBackend frontend=%d backend=%d id=%d>'
% (self.frontendDomain,
self.backendDomain,
self.id))
def closeEvtchn(self):
if self.evtchn:
channel.eventChannelClose(self.evtchn)
self.evtchn = None
def openEvtchn(self):
self.evtchn = channel.eventChannel(self.backendDomain, self.frontendDomain)
def getEventChannelBackend(self):
val = 0
if self.evtchn:
val = self.evtchn['port1']
return val
def getEventChannelFrontend(self):
val = 0
if self.evtchn:
val = self.evtchn['port2']
return val
def connect(self, recreate=False):
"""Connect the controller to the usbif control interface.
@@ -67,78 +41,14 @@ class UsbBackend:
log.debug("Connecting usbif %s", str(self))
if recreate or self.connected or self.connecting:
pass
else:
self.send_be_create()
def send_be_create(self):
msg = packMsg('usbif_be_create_t',
{ 'domid' : self.frontendDomain })
msg = self.backendChannel.requestResponse(msg)
val = unpackMsg('usbif_be_create_t', msg)
log.debug('>UsbifBackendController>respond_be_create> %s', str(val))
self.connected = True
def destroy(self, reboot=False):
"""Disconnect from the usbif control interface and destroy it.
"""
self.destroyed = True
self.send_be_disconnect()
self.send_be_destroy()
self.closeEvtchn()
def send_be_disconnect(self):
log.debug('>UsbifBackendController>send_be_disconnect> %s', str(self))
msg = packMsg('usbif_be_disconnect_t',
{ 'domid' : self.frontendDomain })
self.backendChannel.requestResponse(msg)
def send_be_destroy(self, response=None):
log.debug('>UsbifBackendController>send_be_destroy> %s', str(self))
msg = packMsg('usbif_be_destroy_t',
{ 'domid' : self.frontendDomain })
self.backendChannel.requestResponse(msg)
#todo: check return status
def connectInterface(self, val):
self.openEvtchn()
log.debug(">UsbifBackendController>connectInterface> connecting usbif to event channel %s ports=%d:%d",
str(self),
self.getEventChannelBackend(),
self.getEventChannelFrontend())
msg = packMsg('usbif_be_connect_t',
{ 'domid' : self.frontendDomain,
'evtchn' : self.getEventChannelBackend(),
'shmem_frame' : val['shmem_frame'],
'bandwidth' : 500 # XXX fix bandwidth!
})
msg = self.backendChannel.requestResponse(msg)
self.respond_be_connect(msg)
def respond_be_connect(self, msg):
"""Response handler for a be_connect message.
@param msg: message
@type msg: xu message
"""
val = unpackMsg('usbif_be_connect_t', msg)
log.debug('>UsbifBackendController>respond_be_connect> %s, %s', str(self), str(val))
self.send_fe_interface_status_changed()
log.debug(">UsbifBackendController> Successfully connected USB interface for domain %d" % self.frontendDomain)
self.controller.claim_ports()
def send_fe_interface_status_changed(self):
msg = packMsg('usbif_fe_interface_status_changed_t',
{ 'status' : USBIF_INTERFACE_STATUS_CONNECTED,
'domid' : self.backendDomain,
'evtchn' : self.getEventChannelFrontend(),
'bandwidth' : 500,
'num_ports' : len(self.controller.devices)
})
self.frontendChannel.writeRequest(msg)
def interfaceChanged(self):
self.send_fe_interface_status_changed()
pass
class UsbDev(Dev):
@@ -153,17 +63,12 @@ class UsbDev(Dev):
self.port = id
self.path = None
self.frontendDomain = self.getDomain()
self.frontendChannel = None
self.backendDomain = 0
self.backendChannel = None
self.configure(self.config, recreate=recreate)
def init(self, recreate=False, reboot=False):
self.destroyed = False
self.frontendDomain = self.getDomain()
self.frontendChannel = self.getChannel()
backend = self.getBackend()
self.backendChannel = backend.backendChannel
def configure(self, config, change=False, recreate=False):
if change:
@@ -204,7 +109,6 @@ class UsbDev(Dev):
"""
self.destroyed = True
log.debug("Destroying usb domain=%d id=%s", self.frontendDomain, self.id)
self.send_be_release_port()
if change:
self.interfaceChanged()
@@ -220,27 +124,6 @@ class UsbDev(Dev):
"""
self.getBackend().connect()
def send_be_claim_port(self):
log.debug(">UsbifBackendController>send_be_claim_port> about to claim port %s" % self.path)
msg = packMsg('usbif_be_claim_port_t',
{ 'domid' : self.frontendDomain,
'path' : self.path,
'usbif_port' : self.port,
'status' : 0})
self.backendChannel.writeRequest(msg)
log.debug(">UsbifBackendController> Claim port completed")
# No need to add any callbacks, since the guest polls its virtual ports
# anyhow, somewhat like a UHCI controller ;-)
def send_be_release_port(self):
msg = packMsg('usbif_be_release_port_t',
{ 'domid' : self.frontendDomain,
'path' : self.path })
self.backendChannel.writeRequest(msg)
log.debug(">UsbifBackendController> Release port completed")
# No need to add any callbacks, since the guest polls its virtual ports
# anyhow, somewhat like a UHCI controller ;-)
class UsbifController(DevController):
"""USB device interface controller. Handles all USB devices
for a domain.
@@ -252,18 +135,9 @@ class UsbifController(DevController):
DevController.__init__(self, vm, recreate=recreate)
self.backends = {}
self.backendId = 0
self.rcvr = None
def init(self, recreate=False, reboot=False):
self.destroyed = False
self.rcvr = CtrlMsgRcvr(self.getChannel())
self.rcvr.addHandler(CMSG_USBIF_FE,
CMSG_USBIF_FE_DRIVER_STATUS_CHANGED,
self.recv_fe_driver_status_changed)
self.rcvr.addHandler(CMSG_USBIF_FE,
CMSG_USBIF_FE_INTERFACE_CONNECT,
self.recv_fe_interface_connect)
self.rcvr.registerChannel()
if reboot:
self.rebootBackends()
self.rebootDevices()
@@ -283,8 +157,6 @@ class UsbifController(DevController):
log.debug("Destroying blkif domain=%d", self.getDomain())
self.destroyDevices(reboot=reboot)
self.destroyBackends(reboot=reboot)
if self.rcvr:
self.rcvr.deregisterChannel()
def rebootBackends(self):
for backend in self.backends.values():
@@ -311,40 +183,3 @@ class UsbifController(DevController):
def destroyBackends(self, reboot=False):
for backend in self.backends.values():
backend.destroy(reboot=reboot)
def recv_fe_driver_status_changed(self, msg):
val = unpackMsg('usbif_fe_driver_status_changed_t', msg)
log.debug('>UsbifController>recv_fe_driver_status_changed> %s', str(val))
#todo: FIXME: For each backend?
msg = packMsg('usbif_fe_interface_status_changed_t',
{ 'status' : USBIF_INTERFACE_STATUS_DISCONNECTED,
'domid' : 0, #todo: FIXME: should be domid of backend
'evtchn' : 0 })
msg = self.getChannel().requestResponse(msg)
self.disconnected_resp(msg)
def disconnected_resp(self, msg):
val = unpackMsg('usbif_fe_interface_status_changed_t', msg)
if val['status'] != USBIF_INTERFACE_STATUS_DISCONNECTED:
log.error(">UsbifController>disconnected_resp> unexpected status change")
else:
log.debug(">UsbifController>disconnected_resp> interface disconnected OK")
def recv_fe_interface_connect(self, msg):
val = unpackMsg('usbif_fe_interface_status_changed_t', msg)
log.debug(">UsbifController>recv_fe_interface_connect> notifying backend")
#todo: FIXME: generalise to more than one backend.
id = 0
backend = self.getBackendById(id)
if backend:
try:
backend.connectInterface(val)
except IOError, ex:
log.error("Exception connecting backend: %s", ex)
else:
log.error('interface connect on unknown interface: id=%d', id)
def claim_ports(self):
for dev in self.devices.values():
dev.send_be_claim_port()
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.