mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 18:21:39 +01:00
bitkeeper revision 1.1159.49.3 (4129e394QGgW6O2xJZjZe-oeDFgvdQ)
Merge xenbk@gandalf:/var/bk/xeno-unstable.bk into wray-m-3.hpl.hp.com:/home/mjw/repos-bk/xeno-unstable.bk
This commit is contained in:
commit
22dcb3b883
7 files changed
+313
-166
No files matched your search
@@ -948,7 +948,7 @@ class XendDomainInfo:
|
||||
@return: deferred
|
||||
"""
|
||||
ctrl = xend.blkif_create(self.dom, recreate=self.recreate)
|
||||
back = ctrl.getBackend(0)
|
||||
back = ctrl.getBackendInterface(0)
|
||||
return back.connect(recreate=self.recreate)
|
||||
|
||||
def dom_construct(self, dom, config):
|
||||
@@ -1049,8 +1049,6 @@ def vm_dev_vif(vm, val, index):
|
||||
@param index: vif index
|
||||
@return: deferred
|
||||
"""
|
||||
#if vm.netif_backend:
|
||||
# raise VmError('vif: vif in netif backend domain')
|
||||
vif = vm.next_device_index('vif')
|
||||
vmac = sxp.child_value(val, "mac")
|
||||
ctrl = xend.netif_create(vm.dom, recreate=vm.recreate)
|
||||
@@ -1071,8 +1069,6 @@ def vm_dev_vbd(vm, val, index):
|
||||
@param index: vbd index
|
||||
@return: deferred
|
||||
"""
|
||||
#if vm.blkif_backend:
|
||||
# raise VmError('vbd: vbd in blkif backend domain')
|
||||
uname = sxp.child_value(val, 'uname')
|
||||
if not uname:
|
||||
raise VmError('vbd: Missing uname')
|
||||
|
||||
@@ -374,6 +374,7 @@ class EventProtocol(protocol.Protocol):
|
||||
id = sxp.child_value(req, 'id')
|
||||
if not id:
|
||||
raise XendError('Missing console id')
|
||||
id = int(id)
|
||||
self.daemon.console_disconnect(id)
|
||||
return ['ok']
|
||||
|
||||
@@ -652,17 +653,17 @@ class Daemon:
|
||||
return self.channelF.getDomChannel(dom)
|
||||
|
||||
def blkif_create(self, dom, recreate=0):
|
||||
"""Create a block device interface controller.
|
||||
"""Create or get a block device interface controller.
|
||||
|
||||
Returns controller
|
||||
"""
|
||||
return self.blkifCF.createInstance(dom, recreate=recreate)
|
||||
return self.blkifCF.getController(dom)
|
||||
|
||||
def blkifs(self):
|
||||
return [ x.sxpr() for x in self.blkifCF.getInstances() ]
|
||||
return [ x.sxpr() for x in self.blkifCF.getControllers() ]
|
||||
|
||||
def blkif_get(self, dom):
|
||||
return self.blkifCF.getInstanceByDom(dom)
|
||||
return self.blkifCF.getControllerByDom(dom)
|
||||
|
||||
def blkif_dev(self, dom, vdev):
|
||||
return self.blkifCF.getDomainDevice(dom, vdev)
|
||||
@@ -672,29 +673,29 @@ class Daemon:
|
||||
|
||||
Returns Deferred
|
||||
"""
|
||||
ctrl = self.blkifCF.getInstanceByDom(dom)
|
||||
ctrl = self.blkifCF.getControllerByDom(dom)
|
||||
if not ctrl:
|
||||
raise XendError('No blkif controller: %d' % dom)
|
||||
d = ctrl.attachDevice(config, vdev, mode, segment, recreate=recreate)
|
||||
return d
|
||||
|
||||
def netif_create(self, dom, recreate=0):
|
||||
"""Create a network interface controller.
|
||||
"""Create or get a network interface controller.
|
||||
|
||||
"""
|
||||
return self.netifCF.createInstance(dom, recreate=recreate)
|
||||
return self.netifCF.getController(dom)
|
||||
|
||||
def netifs(self):
|
||||
return [ x.sxpr() for x in self.netifCF.getInstances() ]
|
||||
return [ x.sxpr() for x in self.netifCF.getControllers() ]
|
||||
|
||||
def netif_get(self, dom):
|
||||
return self.netifCF.getInstanceByDom(dom)
|
||||
return self.netifCF.getControllerByDom(dom)
|
||||
|
||||
def netif_dev_create(self, dom, vif, config, recreate=0):
|
||||
"""Create a network device.
|
||||
|
||||
"""
|
||||
ctrl = self.netifCF.getInstanceByDom(dom)
|
||||
ctrl = self.netifCF.getControllerByDom(dom)
|
||||
if not ctrl:
|
||||
raise XendError('No netif controller: %d' % dom)
|
||||
d = ctrl.attachDevice(vif, config, recreate=recreate)
|
||||
@@ -706,22 +707,22 @@ class Daemon:
|
||||
def console_create(self, dom, console_port=None):
|
||||
"""Create a console for a domain.
|
||||
"""
|
||||
console = self.consoleCF.getInstanceByDom(dom)
|
||||
console = self.consoleCF.getControllerByDom(dom)
|
||||
if console is None:
|
||||
console = self.consoleCF.createInstance(dom, console_port)
|
||||
console = self.consoleCF.createController(dom, console_port)
|
||||
return console
|
||||
|
||||
def consoles(self):
|
||||
return [ c.sxpr() for c in self.consoleCF.getInstances() ]
|
||||
return [ c.sxpr() for c in self.consoleCF.getControllers() ]
|
||||
|
||||
def get_consoles(self):
|
||||
return self.consoleCF.getInstances()
|
||||
return self.consoleCF.getControllers()
|
||||
|
||||
def get_console(self, id):
|
||||
return self.consoleCF.getInstance(id)
|
||||
return self.consoleCF.getControllerByIndex(id)
|
||||
|
||||
def get_domain_console(self, dom):
|
||||
return self.consoleCF.getInstanceByDom(dom)
|
||||
return self.consoleCF.getControllerByDom(dom)
|
||||
|
||||
def console_disconnect(self, id):
|
||||
"""Disconnect any connected console client.
|
||||
@@ -734,9 +735,10 @@ class Daemon:
|
||||
def domain_shutdown(self, dom, reason):
|
||||
"""Shutdown a domain.
|
||||
"""
|
||||
ctrl = self.domainCF.getInstanceByDom(dom)
|
||||
dom = int(dom)
|
||||
ctrl = self.domainCF.getController(dom)
|
||||
if not ctrl:
|
||||
raise XendError('No domain controller: %d' % dom)
|
||||
raise XendError('No domain controller: %s' % dom)
|
||||
ctrl.shutdown(reason)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -14,24 +14,16 @@ import controller
|
||||
from messages import *
|
||||
|
||||
class BlkifBackendController(controller.BackendController):
|
||||
""" Handler for the 'back-end' channel to a device driver domain.
|
||||
Must be connected using connect() before it can be used.
|
||||
Do not create directly - use getBackend() on the BlkifController.
|
||||
""" Handler for the 'back-end' channel to a block device driver domain.
|
||||
"""
|
||||
|
||||
def __init__(self, ctrl, dom, handle):
|
||||
controller.BackendController.__init__(self, ctrl, dom, handle)
|
||||
self.connected = 0
|
||||
self.evtchn = None
|
||||
self.handle = handle
|
||||
def __init__(self, factory, dom):
|
||||
controller.BackendController.__init__(self, factory, dom)
|
||||
self.addMethod(CMSG_BLKIF_BE,
|
||||
CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED,
|
||||
self.recv_be_driver_status_changed)
|
||||
self.registerChannel()
|
||||
|
||||
def __str__(self):
|
||||
return '<BlkifBackendController %d %d>' % (self.controller.dom, self.dom)
|
||||
|
||||
def recv_be_driver_status_changed(self, msg, req):
|
||||
"""Request handler for be_driver_status_changed messages.
|
||||
|
||||
@@ -43,8 +35,23 @@ class BlkifBackendController(controller.BackendController):
|
||||
val = unpackMsg('blkif_be_driver_status_changed_t', msg)
|
||||
status = val['status']
|
||||
|
||||
class BlkifBackendInterface(controller.BackendInterface):
|
||||
""" Handler for the 'back-end' channel to a block device driver domain
|
||||
on behalf of a front-end domain.
|
||||
Must be connected using connect() before it can be used.
|
||||
Do not create directly - use getBackendInterface() on the BlkifController.
|
||||
"""
|
||||
|
||||
def __init__(self, ctrl, dom, handle):
|
||||
controller.BackendInterface.__init__(self, ctrl, dom, handle)
|
||||
self.connected = 0
|
||||
self.evtchn = None
|
||||
|
||||
def __str__(self):
|
||||
return '<BlkifBackendInterface %d %d>' % (self.controller.dom, self.dom)
|
||||
|
||||
def connect(self, recreate=0):
|
||||
"""Connect the controller to the blkif control interface.
|
||||
"""Connect to the blkif control interface.
|
||||
|
||||
@param recreate: true if after xend restart
|
||||
@return: deferred
|
||||
@@ -76,6 +83,7 @@ class BlkifBackendController(controller.BackendController):
|
||||
"""
|
||||
def cb_destroy(val):
|
||||
self.send_be_destroy()
|
||||
self.close()
|
||||
d = defer.Deferred()
|
||||
d.addCallback(cb_destroy)
|
||||
self.send_be_disconnect(response=d)
|
||||
@@ -124,14 +132,14 @@ class BlkifBackendController(controller.BackendController):
|
||||
'evtchn' : self.evtchn['port2'] })
|
||||
self.controller.writeRequest(msg, response=response)
|
||||
|
||||
class BlkifControllerFactory(controller.ControllerFactory):
|
||||
class BlkifControllerFactory(controller.SplitControllerFactory):
|
||||
"""Factory for creating block device interface controllers.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
controller.ControllerFactory.__init__(self)
|
||||
controller.SplitControllerFactory.__init__(self)
|
||||
|
||||
def createInstance(self, dom, recreate=0):
|
||||
def createController(self, dom, recreate=0):
|
||||
"""Create a block device controller for a domain.
|
||||
|
||||
@param dom: domain
|
||||
@@ -141,12 +149,30 @@ class BlkifControllerFactory(controller.ControllerFactory):
|
||||
@return: block device controller
|
||||
@rtype: BlkifController
|
||||
"""
|
||||
blkif = self.getInstanceByDom(dom)
|
||||
blkif = self.getControllerByDom(dom)
|
||||
if blkif is None:
|
||||
blkif = BlkifController(self, dom)
|
||||
self.addInstance(blkif)
|
||||
self.addController(blkif)
|
||||
return blkif
|
||||
|
||||
def createBackendController(self, dom):
|
||||
"""Create a block device backend controller.
|
||||
|
||||
@param dom: backend domain
|
||||
@return: backend controller
|
||||
"""
|
||||
return BlkifBackendController(self, dom)
|
||||
|
||||
def createBackendInterface(self, ctrl, dom, handle):
|
||||
"""Create a block device backend interface.
|
||||
|
||||
@param ctrl: controller
|
||||
@param dom: backend domain
|
||||
@param handle: interface handle
|
||||
@return: backend interface
|
||||
"""
|
||||
return BlkifBackendInterface(ctrl, dom, handle)
|
||||
|
||||
def getDomainDevices(self, dom):
|
||||
"""Get the block devices for a domain.
|
||||
|
||||
@@ -155,7 +181,7 @@ class BlkifControllerFactory(controller.ControllerFactory):
|
||||
@return: devices
|
||||
@rtype: [device]
|
||||
"""
|
||||
blkif = self.getInstanceByDom(dom)
|
||||
blkif = self.getControllerByDom(dom)
|
||||
return (blkif and blkif.getDevices()) or []
|
||||
|
||||
def getDomainDevice(self, dom, vdev):
|
||||
@@ -168,7 +194,7 @@ class BlkifControllerFactory(controller.ControllerFactory):
|
||||
@return: device
|
||||
@rtype: device
|
||||
"""
|
||||
blkif = self.getInstanceByDom(dom)
|
||||
blkif = self.getControllerByDom(dom)
|
||||
return (blkif and blkif.getDevice(vdev)) or None
|
||||
|
||||
class BlkDev(controller.SplitDev):
|
||||
@@ -213,7 +239,7 @@ class BlkDev(controller.SplitDev):
|
||||
"""Attach the device to its controller.
|
||||
|
||||
"""
|
||||
backend = self.getBackend()
|
||||
backend = self.getBackendInterface()
|
||||
d1 = backend.connect()
|
||||
d2 = defer.Deferred()
|
||||
d2.addCallback(self.send_be_vbd_create)
|
||||
@@ -223,7 +249,7 @@ class BlkDev(controller.SplitDev):
|
||||
def send_be_vbd_create(self, val):
|
||||
d = defer.Deferred()
|
||||
d.addCallback(self.respond_be_vbd_create)
|
||||
backend = self.getBackend()
|
||||
backend = self.getBackendInterface()
|
||||
msg = packMsg('blkif_be_vbd_create_t',
|
||||
{ 'domid' : self.controller.dom,
|
||||
'blkif_handle' : backend.handle,
|
||||
@@ -246,7 +272,7 @@ class BlkDev(controller.SplitDev):
|
||||
|
||||
def send_be_vbd_grow(self):
|
||||
d = defer.Deferred()
|
||||
backend = self.getBackend()
|
||||
backend = self.getBackendInterface()
|
||||
msg = packMsg('blkif_be_vbd_grow_t',
|
||||
{ 'domid' : self.controller.dom,
|
||||
'blkif_handle' : backend.handle,
|
||||
@@ -273,7 +299,7 @@ class BlkDev(controller.SplitDev):
|
||||
def send_be_vbd_destroy(self, response=None):
|
||||
log.debug('>BlkDev>send_be_vbd_destroy> dom=%d vdev=%d',
|
||||
self.controller.dom, self.vdev)
|
||||
backend = self.getBackend()
|
||||
backend = self.getBackendInterface()
|
||||
msg = packMsg('blkif_be_vbd_destroy_t',
|
||||
{ 'domid' : self.controller.dom,
|
||||
'blkif_handle' : backend.handle,
|
||||
@@ -289,7 +315,7 @@ class BlkifController(controller.SplitController):
|
||||
|
||||
def __init__(self, factory, dom):
|
||||
"""Create a block device controller.
|
||||
Do not call directly - use createInstance() on the factory instead.
|
||||
Do not call directly - use createController() on the factory instead.
|
||||
"""
|
||||
controller.SplitController.__init__(self, factory, dom)
|
||||
self.devices = {}
|
||||
@@ -305,9 +331,6 @@ class BlkifController(controller.SplitController):
|
||||
val = ['blkif', ['dom', self.dom]]
|
||||
return val
|
||||
|
||||
def createBackend(self, dom, handle):
|
||||
return BlkifBackendController(self, dom, handle)
|
||||
|
||||
def getDevices(self):
|
||||
return self.devices.values()
|
||||
|
||||
@@ -372,7 +395,7 @@ class BlkifController(controller.SplitController):
|
||||
dev.destroy()
|
||||
|
||||
def destroyBackends(self):
|
||||
for backend in self.getBackends():
|
||||
for backend in self.getBackendInterfaces():
|
||||
backend.destroy()
|
||||
|
||||
def recv_fe_driver_status_changed(self, msg, req):
|
||||
@@ -388,7 +411,7 @@ class BlkifController(controller.SplitController):
|
||||
def recv_fe_interface_connect(self, msg, req):
|
||||
val = unpackMsg('blkif_fe_interface_connect_t', msg)
|
||||
handle = val['handle']
|
||||
backend = self.getBackendByHandle(handle)
|
||||
backend = self.getBackendInterfaceByHandle(handle)
|
||||
if backend:
|
||||
backend.connectInterface(val)
|
||||
else:
|
||||
|
||||
@@ -81,14 +81,14 @@ class ConsoleControllerFactory(controller.ControllerFactory):
|
||||
"""Factory for creating console controllers.
|
||||
"""
|
||||
|
||||
def createInstance(self, dom, console_port=None):
|
||||
def createController(self, dom, console_port=None):
|
||||
if console_port is None:
|
||||
console_port = CONSOLE_PORT_BASE + dom
|
||||
for c in self.getInstances():
|
||||
for c in self.getControllers():
|
||||
if c.console_port == console_port:
|
||||
raise XendError('console port in use: ' + str(console_port))
|
||||
console = ConsoleController(self, dom, console_port)
|
||||
self.addInstance(console)
|
||||
self.addController(console)
|
||||
log.info("Created console id=%s domain=%d port=%d",
|
||||
console.idx, console.dom, console.console_port)
|
||||
eserver.inject('xend.console.create',
|
||||
@@ -98,7 +98,7 @@ class ConsoleControllerFactory(controller.ControllerFactory):
|
||||
def consoleClosed(self, console):
|
||||
log.info("Closed console id=%s", console.idx)
|
||||
eserver.inject('xend.console.close', console.idx)
|
||||
self.delInstance(console)
|
||||
self.delController(console)
|
||||
|
||||
class ConsoleController(controller.Controller):
|
||||
"""Console controller for a domain.
|
||||
|
||||
@@ -274,72 +274,80 @@ class CtrlMsgRcvr:
|
||||
|
||||
class ControllerFactory:
|
||||
"""Abstract class for factories creating controllers for a domain.
|
||||
Maintains a table of instances.
|
||||
Maintains a table of controllers.
|
||||
|
||||
@ivar instances: mapping of index to controller instance
|
||||
@type instances: {String: Controller}
|
||||
@ivar controllers: mapping of index to controller instance
|
||||
@type controllers: {String: Controller}
|
||||
@ivar dom: domain
|
||||
@type dom: int
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.instances = {}
|
||||
self.backends = {}
|
||||
self.dom = 0
|
||||
self.controllers = {}
|
||||
|
||||
def addInstance(self, instance):
|
||||
def addController(self, controller):
|
||||
"""Add a controller instance (under its index).
|
||||
"""
|
||||
self.instances[instance.idx] = instance
|
||||
self.controllers[controller.idx] = controller
|
||||
|
||||
def getInstance(self, idx):
|
||||
"""Get a controller instance from its index.
|
||||
def getControllers(self):
|
||||
"""Get a list of all controllers.
|
||||
"""
|
||||
return self.instances.get(idx)
|
||||
return self.controllers.values()
|
||||
|
||||
def getInstances(self):
|
||||
"""Get a list of all controller instances.
|
||||
def getControllerByIndex(self, idx):
|
||||
"""Get a controller from its index.
|
||||
"""
|
||||
return self.instances.values()
|
||||
return self.controllers.get(idx)
|
||||
|
||||
def getInstanceByDom(self, dom):
|
||||
"""Get the controller instance for the given domain.
|
||||
def getControllerByDom(self, dom):
|
||||
"""Get the controller for the given domain.
|
||||
|
||||
@param dom: domain id
|
||||
@type dom: int
|
||||
@return: controller or None
|
||||
"""
|
||||
for inst in self.instances.values():
|
||||
for inst in self.controllers.values():
|
||||
if inst.dom == dom:
|
||||
return inst
|
||||
return None
|
||||
|
||||
def delInstance(self, instance):
|
||||
"""Delete a controller instance from the table.
|
||||
def getController(self, dom):
|
||||
"""Create or find the controller for a domain.
|
||||
|
||||
@param instance: controller instance
|
||||
@param dom: domain
|
||||
@return: controller
|
||||
"""
|
||||
if instance.idx in self.instances:
|
||||
del self.instances[instance.idx]
|
||||
|
||||
def createInstance(self, dom, recreate=0):
|
||||
"""Create an instance. Define in a subclass.
|
||||
ctrl = self.getControllerByDom(dom)
|
||||
if ctrl is None:
|
||||
ctrl = self.createController(dom)
|
||||
self.addController(ctrl)
|
||||
return ctrl
|
||||
|
||||
def createController(self, dom):
|
||||
"""Create a controller. Define in a subclass.
|
||||
|
||||
@param dom: domain
|
||||
@type dom: int
|
||||
@param recreate: true if the instance is being recreated (after xend restart)
|
||||
@type recreate: int
|
||||
@return: controller instance
|
||||
@rtype: Controller (or subclass)
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def instanceClosed(self, instance):
|
||||
"""Callback called when an instance is closed (usually by the instance).
|
||||
|
||||
@param instance: controller instance
|
||||
def delController(self, controller):
|
||||
"""Delete a controller instance from the table.
|
||||
|
||||
@param controller: controller instance
|
||||
"""
|
||||
self.delInstance(instance)
|
||||
if controller.idx in self.controllers:
|
||||
del self.controllers[controller.idx]
|
||||
|
||||
def controllerClosed(self, controller):
|
||||
"""Callback called when a controller is closed (usually by the controller).
|
||||
|
||||
@param controller: controller instance
|
||||
"""
|
||||
self.delController(controller)
|
||||
|
||||
class Controller(CtrlMsgRcvr):
|
||||
"""Abstract class for a device controller attached to a domain.
|
||||
@@ -370,91 +378,204 @@ class Controller(CtrlMsgRcvr):
|
||||
"""The controller channel has been lost.
|
||||
"""
|
||||
self.deregisterChannel()
|
||||
self.factory.instanceClosed(self)
|
||||
self.factory.controllerClosed(self)
|
||||
|
||||
class BackendController(CtrlMsgRcvr):
|
||||
class SplitControllerFactory(ControllerFactory):
|
||||
"""Abstract class for factories creating split controllers for a domain.
|
||||
Maintains a table of backend controllers.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
ControllerFactory.__init__(self)
|
||||
self.backendControllers = {}
|
||||
|
||||
def getBackendControllers(self):
|
||||
return self.backendControllers.values()
|
||||
|
||||
def getBackendControllerByDomain(self, dom):
|
||||
"""Get the backend controller for a domain if there is one.
|
||||
|
||||
@param dom: backend domain
|
||||
@return: backend controller
|
||||
"""
|
||||
return self.backendControllers.get(dom)
|
||||
|
||||
def getBackendController(self, dom):
|
||||
"""Get the backend controller for a domain, creating
|
||||
if necessary.
|
||||
|
||||
@param dom: backend domain
|
||||
@return: backend controller
|
||||
"""
|
||||
b = self.getBackendControllerByDomain(dom)
|
||||
if b is None:
|
||||
b = self.createBackendController(dom)
|
||||
self.backendControllers[b.dom] = b
|
||||
return b
|
||||
|
||||
def createBackendController(self, dom):
|
||||
"""Create a backend controller. Define in a subclass.
|
||||
|
||||
@param dom: backend domain
|
||||
@return: backend controller
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def delBackendController(self, ctrlr):
|
||||
"""Remove a backend controller.
|
||||
|
||||
@param ctrlr: backend controller
|
||||
"""
|
||||
if ctrlr.dom in self.backendControllers:
|
||||
del self.backendControllers[ctrlr.dom]
|
||||
|
||||
def backendControllerClosed(self, ctrlr):
|
||||
"""Callback called when a backend is closed.
|
||||
"""
|
||||
self.delBackendController(ctrlr)
|
||||
|
||||
def createBackendInterface(self, ctrl, dom, handle):
|
||||
"""Create a backend interface. Define in a subclass.
|
||||
|
||||
@param ctrl: frontend controller
|
||||
@param dom: backend domain
|
||||
@return: backend interface
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
class BackendController(Controller):
|
||||
"""Abstract class for a backend device controller attached to a domain.
|
||||
|
||||
@ivar controller: frontend controller
|
||||
@type controller: Controller
|
||||
@ivar dom: domain
|
||||
@ivar factory: backend controller factory
|
||||
@type factory: BackendControllerFactory
|
||||
@ivar dom: backend domain
|
||||
@type dom: int
|
||||
@ivar channel: channel to the domain
|
||||
@type channel: Channel
|
||||
"""
|
||||
|
||||
|
||||
def __init__(self, controller, dom, handle):
|
||||
def __init__(self, factory, dom):
|
||||
CtrlMsgRcvr.__init__(self)
|
||||
self.controller = controller
|
||||
self.factory = factory
|
||||
self.dom = int(dom)
|
||||
self.handle = handle
|
||||
self.channel = None
|
||||
self.backendInterfaces = {}
|
||||
|
||||
def close(self):
|
||||
self.lostChannel()
|
||||
|
||||
def lostChannel(self):
|
||||
self.deregisterChannel()
|
||||
self.controller.backendClosed(self)
|
||||
self.backend.backendClosed(self)
|
||||
|
||||
def registerInterface(self, intf):
|
||||
key = intf.getInterfaceKey()
|
||||
self.backendInterfaces[key] = intf
|
||||
|
||||
def deregisterInterface(self, intf):
|
||||
key = intf.getInterfaceKey()
|
||||
if key in self.backendInterfaces:
|
||||
del self.backendInterfaces[key]
|
||||
|
||||
def getInterface(self, dom, handle):
|
||||
key = (dom, handle)
|
||||
return self.backendInterfaces.get(key)
|
||||
|
||||
|
||||
def createBackendInterface(self, ctrl, dom, handle):
|
||||
"""Create a backend interface. Define in a subclass.
|
||||
|
||||
@param ctrl: controller
|
||||
@param dom: backend domain
|
||||
@param handle: backend handle
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class BackendInterface:
|
||||
"""Abstract class for a domain's interface onto a backend controller.
|
||||
"""
|
||||
|
||||
def __init__(self, controller, dom, handle):
|
||||
"""
|
||||
|
||||
@param controller: front-end controller
|
||||
@param dom: back-end domain
|
||||
@param handle: back-end interface handle
|
||||
"""
|
||||
self.factory = controller.factory
|
||||
self.controller = controller
|
||||
self.dom = int(dom)
|
||||
self.handle = handle
|
||||
self.backend = self.getBackendController()
|
||||
|
||||
def registerInterface(self):
|
||||
self.backend.registerInterface(self)
|
||||
|
||||
def getInterfaceKey(self):
|
||||
return (self.controller.dom, self.handle)
|
||||
|
||||
def getBackendController(self):
|
||||
return self.factory.getBackendController(self.dom)
|
||||
|
||||
def writeRequest(self, msg, response=None):
|
||||
return self.backend.writeRequest(msg, response=response)
|
||||
|
||||
def close(self):
|
||||
self.backend.deregisterInterface(self)
|
||||
self.controller.backendInterfaceClosed(self)
|
||||
|
||||
class SplitController(Controller):
|
||||
"""Abstract class for a device controller attached to a domain.
|
||||
A SplitController manages a BackendController for each backend domain
|
||||
A SplitController manages a BackendInterface for each backend domain
|
||||
it has at least one device for.
|
||||
"""
|
||||
|
||||
def __init__(self, factory, dom):
|
||||
Controller.__init__(self, factory, dom)
|
||||
self.backends = {}
|
||||
self.backendInterfaces = {}
|
||||
self.backendHandle = 0
|
||||
|
||||
def getBackends(self):
|
||||
return self.backends.values()
|
||||
def getBackendInterfaces(self):
|
||||
return self.backendInterfaces.values()
|
||||
|
||||
def getBackendByHandle(self, handle):
|
||||
for b in self.getBackends():
|
||||
def getBackendInterfaceByHandle(self, handle):
|
||||
for b in self.getBackendInterfaces():
|
||||
if b.handle == handle:
|
||||
return b
|
||||
return None
|
||||
|
||||
def getBackendByDomain(self, dom):
|
||||
return self.backends.get(dom)
|
||||
def getBackendInterfaceByDomain(self, dom):
|
||||
return self.backendInterfaces.get(dom)
|
||||
|
||||
def getBackend(self, dom):
|
||||
"""Get the backend controller for a domain.
|
||||
def getBackendInterface(self, dom):
|
||||
"""Get the backend interface for a domain.
|
||||
|
||||
@param dom: domain
|
||||
@return: backend controller
|
||||
"""
|
||||
b = self.getBackendByDomain(dom)
|
||||
b = self.getBackendInterfaceByDomain(dom)
|
||||
if b is None:
|
||||
handle = self.backendHandle
|
||||
self.backendHandle += 1
|
||||
b = self.createBackend(dom, handle)
|
||||
self.backends[b.dom] = b
|
||||
b = self.factory.createBackendInterface(self, dom, handle)
|
||||
b.registerInterface()
|
||||
self.backendInterfaces[b.dom] = b
|
||||
return b
|
||||
|
||||
def createBackend(self, dom, handle):
|
||||
"""Create a backend controller. Define in a subclass.
|
||||
|
||||
@param dom: domain
|
||||
@param handle: controller handle
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def delBackend(self, ctrlr):
|
||||
def delBackendInterface(self, ctrlr):
|
||||
"""Remove a backend controller.
|
||||
|
||||
@param ctrlr: backend controller
|
||||
"""
|
||||
if ctrlr.dom in self.backends:
|
||||
del self.backends[ctrlr.dom]
|
||||
if ctrlr.dom in self.backendInterfaces:
|
||||
del self.backendInterfaces[ctrlr.dom]
|
||||
|
||||
def backendClosed(self, ctrlr):
|
||||
def backendInterfaceClosed(self, ctrlr):
|
||||
"""Callback called when a backend is closed.
|
||||
"""
|
||||
self.delBackend(ctrlr)
|
||||
self.delBackendInterface(ctrlr)
|
||||
|
||||
class Dev:
|
||||
"""Abstract class for a device attached to a device controller.
|
||||
@@ -502,8 +623,8 @@ class SplitDev(Dev):
|
||||
Dev.__init__(self, idx, controller)
|
||||
self.backendDomain = 0
|
||||
|
||||
def getBackend(self):
|
||||
return self.controller.getBackend(self.backendDomain)
|
||||
def getBackendInterface(self):
|
||||
return self.controller.getBackendInterface(self.backendDomain)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -10,30 +10,14 @@ class DomainControllerFactory(controller.ControllerFactory):
|
||||
"""Factory for creating domain controllers.
|
||||
"""
|
||||
|
||||
def createInstance(self, dom):
|
||||
def createController(self, dom):
|
||||
"""Create a domain controller.
|
||||
|
||||
dom domain
|
||||
|
||||
returns domain controller
|
||||
"""
|
||||
d = DomainController(self, dom)
|
||||
self.addInstance(d)
|
||||
return d
|
||||
|
||||
def getInstanceByDom(self, dom):
|
||||
"""Get a domain controller for a domain, creating if necessary.
|
||||
|
||||
dom domain
|
||||
|
||||
returns domain controller
|
||||
"""
|
||||
for inst in self.instances.values():
|
||||
if inst.dom == dom:
|
||||
return inst
|
||||
inst = self.createInstance(dom)
|
||||
return inst
|
||||
|
||||
return DomainController(self, dom)
|
||||
|
||||
class DomainController(controller.Controller):
|
||||
"""Generic controller for a domain.
|
||||
|
||||
@@ -19,11 +19,11 @@ import controller
|
||||
from messages import *
|
||||
|
||||
class NetifBackendController(controller.BackendController):
|
||||
"""Handler for the 'back-end' channel to a device driver domain.
|
||||
"""Handler for the 'back-end' channel to a network device driver domain.
|
||||
"""
|
||||
|
||||
def __init__(self, ctrl, dom, handle):
|
||||
controller.BackendController.__init__(self, ctrl, dom, handle)
|
||||
def __init__(self, ctrl, dom):
|
||||
controller.BackendController.__init__(self, ctrl, dom)
|
||||
self.addMethod(CMSG_NETIF_BE,
|
||||
CMSG_NETIF_BE_DRIVER_STATUS_CHANGED,
|
||||
self.recv_be_driver_status_changed)
|
||||
@@ -33,33 +33,56 @@ class NetifBackendController(controller.BackendController):
|
||||
val = unpackMsg('netif_be_driver_status_changed_t', msg)
|
||||
status = val['status']
|
||||
|
||||
class NetifControllerFactory(controller.ControllerFactory):
|
||||
class NetifBackendInterface(controller.BackendInterface):
|
||||
"""Handler for the 'back-end' channel to a network device driver domain
|
||||
on behalf of a front-end domain.
|
||||
|
||||
Each network device is handled separately, so we add no functionality
|
||||
here.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
class NetifControllerFactory(controller.SplitControllerFactory):
|
||||
"""Factory for creating network interface controllers.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
controller.ControllerFactory.__init__(self)
|
||||
controller.SplitControllerFactory.__init__(self)
|
||||
|
||||
def createInstance(self, dom, recreate=0):
|
||||
"""Create or find the network interface controller for a domain.
|
||||
def createController(self, dom):
|
||||
"""Create a network interface controller for a domain.
|
||||
|
||||
@param dom: domain
|
||||
@param recreate: if true this is a recreate (xend restarted)
|
||||
@return: netif controller
|
||||
"""
|
||||
netif = self.getInstanceByDom(dom)
|
||||
if netif is None:
|
||||
netif = NetifController(self, dom)
|
||||
self.addInstance(netif)
|
||||
return netif
|
||||
return NetifController(self, dom)
|
||||
|
||||
def createBackendController(self, dom):
|
||||
"""Create a network device backend controller.
|
||||
|
||||
@param dom: backend domain
|
||||
@return: backend controller
|
||||
"""
|
||||
return NetifBackendController(self, dom)
|
||||
|
||||
def createBackendInterface(self, ctrl, dom, handle):
|
||||
"""Create a network device backend interface.
|
||||
|
||||
@param ctrl: controller
|
||||
@param dom: backend domain
|
||||
@param handle: interface handle
|
||||
@return: backend interface
|
||||
"""
|
||||
return NetifBackendInterface(ctrl, dom, handle)
|
||||
|
||||
def getDomainDevices(self, dom):
|
||||
"""Get the network device controllers for a domain.
|
||||
"""Get the network devices for a domain.
|
||||
|
||||
@param dom: domain
|
||||
@return: netif controller list
|
||||
"""
|
||||
netif = self.getInstanceByDom(dom)
|
||||
netif = self.getControllerByDom(dom)
|
||||
return (netif and netif.getDevices()) or []
|
||||
|
||||
def getDomainDevice(self, dom, vif):
|
||||
@@ -69,7 +92,7 @@ class NetifControllerFactory(controller.ControllerFactory):
|
||||
@param vif: virtual interface index
|
||||
@return: NetDev
|
||||
"""
|
||||
netif = self.getInstanceByDom(dom)
|
||||
netif = self.getControllerByDom(dom)
|
||||
return (netif and netif.getDevice(vif)) or None
|
||||
|
||||
class NetDev(controller.SplitDev):
|
||||
@@ -179,7 +202,7 @@ class NetDev(controller.SplitDev):
|
||||
{ 'domid' : self.controller.dom,
|
||||
'netif_handle' : self.vif,
|
||||
'mac' : self.mac })
|
||||
self.getBackend().writeRequest(msg, response=d)
|
||||
self.getBackendInterface().writeRequest(msg, response=d)
|
||||
return d
|
||||
|
||||
def respond_be_create(self, msg):
|
||||
@@ -193,6 +216,7 @@ class NetDev(controller.SplitDev):
|
||||
"""
|
||||
def cb_destroy(val):
|
||||
self.send_be_destroy()
|
||||
self.getBackendInterface().close()
|
||||
log.debug("Destroying vif domain=%d vif=%d", self.controller.dom, self.vif)
|
||||
self.vifctl('down')
|
||||
d = self.send_be_disconnect()
|
||||
@@ -203,7 +227,7 @@ class NetDev(controller.SplitDev):
|
||||
msg = packMsg('netif_be_disconnect_t',
|
||||
{ 'domid' : self.controller.dom,
|
||||
'netif_handle' : self.vif })
|
||||
self.getBackend().writeRequest(msg, response=d)
|
||||
self.getBackendInterface().writeRequest(msg, response=d)
|
||||
return d
|
||||
|
||||
def send_be_destroy(self, response=None):
|
||||
@@ -211,7 +235,7 @@ class NetDev(controller.SplitDev):
|
||||
{ 'domid' : self.controller.dom,
|
||||
'netif_handle' : self.vif })
|
||||
self.controller.delDevice(self.vif)
|
||||
self.getBackend().writeRequest(msg, response=response)
|
||||
self.getBackendInterface().writeRequest(msg, response=response)
|
||||
|
||||
def recv_fe_interface_connect(self, val, req):
|
||||
if not req: return
|
||||
@@ -224,7 +248,7 @@ class NetDev(controller.SplitDev):
|
||||
'rx_shmem_frame' : val['rx_shmem_frame'] })
|
||||
d = defer.Deferred()
|
||||
d.addCallback(self.respond_be_connect)
|
||||
self.getBackend().writeRequest(msg, response=d)
|
||||
self.getBackendInterface().writeRequest(msg, response=d)
|
||||
|
||||
def respond_be_connect(self, msg):
|
||||
val = unpackMsg('netif_be_connect_t', msg)
|
||||
@@ -260,9 +284,6 @@ class NetifController(controller.SplitController):
|
||||
self.recv_fe_interface_connect)
|
||||
self.registerChannel()
|
||||
|
||||
def createBackend(self, dom, handle):
|
||||
return NetifBackendController(self, dom, handle)
|
||||
|
||||
def sxpr(self):
|
||||
val = ['netif', ['dom', self.dom]]
|
||||
return val
|
||||
|
||||