bitkeeper revision 1.1159.1.53 (411ccd729CC_RzyLGa4nViY2XcSdig)

Separate controller backend from the controller factory, allowing
each controller to have its own backend domain.
This commit is contained in:
mjw@wray-m-3.hpl.hp.com committed 2004-08-13 14:17:22 +00:00
1 parent 8b1b3b0911
commit 3454fab599
3 files changed
+268 -142

No files matched your search

+113 -102
View File
@@ -13,20 +13,109 @@ import channel
import controller
from messages import *
class BlkifControllerFactory(controller.ControllerFactory):
"""Factory for creating block device interface controllers.
Also handles the 'back-end' channel to the device driver domain.
class BlkifBackendController(controller.BackendController):
""" Handler for the 'back-end' channel to a device driver domain.
"""
def __init__(self):
controller.ControllerFactory.__init__(self)
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.attached = 1
self.registerChannel()
def respond_be_create(self, msg, d):
"""Response handler for a be_create message.
Calls I{d} with the block interface created.
def createInstance(self, dom, recreate=0):
@param msg: message
@type msg: xu message
@param d: deferred to call
@type d: Deferred
"""
val = unpackMsg('blkif_be_create_t', msg)
blkif = self.factory.getInstanceByDom(val['domid'])
d.callback(blkif)
def respond_be_connect(self, msg):
"""Response handler for a be_connect message.
@param msg: message
@type msg: xu message
"""
val = unpackMsg('blkif_be_connect_t', msg)
blkif = self.factory.getInstanceByDom(val['domid'])
if blkif:
blkif.send_fe_interface_status_changed()
else:
pass
def respond_be_vbd_create(self, msg, dev, d):
"""Response handler for a be_vbd_create message.
Tries to grow the vbd, and passes the deferred I{d} on for
the grow to call.
@param msg: message
@type msg: xu message
@param dev: device
@type dev: BlkDev
@param d: deferred to call
@type d: Deferred
"""
val = unpackMsg('blkif_be_vbd_create_t', msg)
blkif = self.factory.getInstanceByDom(val['domid'])
if blkif:
d1 = defer.Deferred()
d1.addCallback(self.respond_be_vbd_grow, dev, d)
if d: d1.addErrback(d.errback)
blkif.send_be_vbd_grow(val['vdevice'], response=d1)
else:
pass
def respond_be_vbd_grow(self, msg, dev, d):
"""Response handler for a be_vbd_grow message.
@param msg: message
@type msg: xu message
@param dev: device
@type dev: BlkDev
@param d: deferred to call
@type d: Deferred or None
"""
val = unpackMsg('blkif_be_vbd_grow_t', msg)
status = val['status']
if status != BLKIF_BE_STATUS_OKAY:
raise XendError("Adding extent to vbd failed: device %x, error %d"
% (val['extent.device'], status))
if d:
d.callback(dev)
def recv_be_driver_status_changed(self, msg, req):
"""Request handler for be_driver_status_changed messages.
@param msg: message
@type msg: xu message
@param req: request flag (true if the msg is a request)
@type req: bool
"""
val = unpackMsg('blkif_be_driver_status_changed_t', msg)
status = val['status']
if status == BLKIF_DRIVER_STATUS_UP and not self.attached:
for blkif in self.factory.getInstances():
if blkif.backendController == self:
blkif.detach()
class BlkifControllerFactory(controller.SplitControllerFactory):
"""Factory for creating block device interface controllers.
"""
def __init__(self):
controller.SplitControllerFactory.__init__(self)
self.attached = 1
def createInstance(self, dom, recreate=0, backend=0):
"""Create a block device controller for a domain.
@param dom: domain
@@ -41,13 +130,13 @@ class BlkifControllerFactory(controller.ControllerFactory):
if blkif:
d.callback(blkif)
else:
blkif = BlkifController(self, dom)
blkif = BlkifController(self, dom, backend)
self.addInstance(blkif)
if recreate:
d.callback(blkif)
else:
d1 = defer.Deferred()
d1.addCallback(self.respond_be_create, d)
d1.addCallback(blkif.backendController.respond_be_create, d)
d1.addErrback(d.errback)
blkif.send_be_create(response=d1)
return d
@@ -76,6 +165,9 @@ class BlkifControllerFactory(controller.ControllerFactory):
blkif = self.getInstanceByDom(dom)
return (blkif and blkif.getDevice(vdev)) or None
def createBackendController(self, dom):
return BlkifBackendController(self, dom)
def setControlDomain(self, dom, recreate=0):
"""Set the back-end block device controller domain.
@@ -134,88 +226,7 @@ class BlkifControllerFactory(controller.ControllerFactory):
for blkif in self.getInstances():
blkif.reattached()
def respond_be_create(self, msg, d):
"""Response handler for a be_create message.
Calls I{d} with the block interface created.
@param msg: message
@type msg: xu message
@param d: deferred to call
@type d: Deferred
"""
val = unpackMsg('blkif_be_create_t', msg)
blkif = self.getInstanceByDom(val['domid'])
d.callback(blkif)
def respond_be_connect(self, msg):
"""Response handler for a be_connect message.
@param msg: message
@type msg: xu message
"""
val = unpackMsg('blkif_be_connect_t', msg)
blkif = self.getInstanceByDom(val['domid'])
if blkif:
blkif.send_fe_interface_status_changed()
else:
pass
def respond_be_vbd_create(self, msg, dev, d):
"""Response handler for a be_vbd_create message.
Tries to grow the vbd, and passes the deferred I{d} on for
the grow to call.
@param msg: message
@type msg: xu message
@param dev: device
@type dev: BlkDev
@param d: deferred to call
@type d: Deferred
"""
val = unpackMsg('blkif_be_vbd_create_t', msg)
blkif = self.getInstanceByDom(val['domid'])
if blkif:
d1 = defer.Deferred()
d1.addCallback(self.respond_be_vbd_grow, dev, d)
if d: d1.addErrback(d.errback)
blkif.send_be_vbd_grow(val['vdevice'], response=d1)
else:
pass
def respond_be_vbd_grow(self, msg, dev, d):
"""Response handler for a be_vbd_grow message.
@param msg: message
@type msg: xu message
@param dev: device
@type dev: BlkDev
@param d: deferred to call
@type d: Deferred or None
"""
val = unpackMsg('blkif_be_vbd_grow_t', msg)
status = val['status']
if status != BLKIF_BE_STATUS_OKAY:
raise XendError("Adding extent to vbd failed: device %x, error %d"
% (val['extent.device'], status))
if self.attached:
if d:
d.callback(dev)
else:
self.reattachDevice(val['domid'], val['vdevice'])
def recv_be_driver_status_changed(self, msg, req):
"""Request handler for be_driver_status_changed messages.
@param msg: message
@type msg: xu message
@param req: request flag (true if the msg is a request)
@type req: bool
"""
val = unpackMsg('blkif_be_driver_status_changed_t', msg)
status = val['status']
if status == BLKIF_DRIVER_STATUS_UP and not self.attached:
for blkif in self.getInstances():
blkif.detach()
class BlkDev(controller.Dev):
"""Info record for a block device.
@@ -251,13 +262,13 @@ class BlkDev(controller.Dev):
log.debug("Destroying vbd domain=%d vdev=%d", self.controller.dom, self.vdev)
self.controller.send_be_vbd_destroy(self.vdev)
class BlkifController(controller.Controller):
class BlkifController(controller.SplitController):
"""Block device interface controller. Handles all block devices
for a domain.
"""
def __init__(self, factory, dom):
controller.Controller.__init__(self, factory, dom)
def __init__(self, factory, dom, backend):
controller.SplitController.__init__(self, factory, dom, backend)
self.devices = {}
self.addMethod(CMSG_BLKIF_FE,
CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED,
@@ -322,7 +333,7 @@ class BlkifController(controller.Controller):
d.callback(dev)
else:
d1 = defer.Deferred()
d1.addCallback(self.factory.respond_be_vbd_create, dev, d)
d1.addCallback(self.backendController.respond_be_vbd_create, dev, d)
d1.addErrback(d.errback)
self.send_be_vbd_create(vdev, response=d1)
return d
@@ -346,7 +357,7 @@ class BlkifController(controller.Controller):
for dev in self.devices.values():
dev.attached = 0
d1 = defer.Deferred()
d1.addCallback(self.factory.respond_be_vbd_create, None, None)
d1.addCallback(self.backendController.respond_be_vbd_create, None, None)
self.send_be_vbd_create(vdev, response=d1)
def reattachDevice(self, vdev):
@@ -389,8 +400,8 @@ class BlkifController(controller.Controller):
'evtchn' : self.evtchn['port1'],
'shmem_frame' : val['shmem_frame'] })
d = defer.Deferred()
d.addCallback(self.factory.respond_be_connect)
self.factory.writeRequest(msg, response=d)
d.addCallback(self.backendController.respond_be_connect)
self.backendController.writeRequest(msg, response=d)
def send_fe_interface_status_changed(self, response=None):
msg = packMsg('blkif_fe_interface_status_changed_t',
@@ -403,21 +414,21 @@ class BlkifController(controller.Controller):
msg = packMsg('blkif_be_create_t',
{ 'domid' : self.dom,
'blkif_handle' : 0 })
self.factory.writeRequest(msg, response=response)
self.backendController.writeRequest(msg, response=response)
def send_be_disconnect(self, response=None):
log.debug('>BlkifController>send_be_disconnect> dom=%d', self.dom)
msg = packMsg('blkif_be_disconnect_t',
{ 'domid' : self.dom,
'blkif_handle' : 0 })
self.factory.writeRequest(msg, response=response)
self.backendController.writeRequest(msg, response=response)
def send_be_destroy(self, response=None):
log.debug('>BlkifController>send_be_destroy> dom=%d', self.dom)
msg = packMsg('blkif_be_destroy_t',
{ 'domid' : self.dom,
'blkif_handle' : 0 })
self.factory.writeRequest(msg, response=response)
self.backendController.writeRequest(msg, response=response)
def send_be_vbd_create(self, vdev, response=None):
dev = self.devices[vdev]
@@ -426,7 +437,7 @@ class BlkifController(controller.Controller):
'blkif_handle' : 0,
'vdevice' : dev.vdev,
'readonly' : dev.readonly() })
self.factory.writeRequest(msg, response=response)
self.backendController.writeRequest(msg, response=response)
def send_be_vbd_grow(self, vdev, response=None):
dev = self.devices[vdev]
@@ -437,7 +448,7 @@ class BlkifController(controller.Controller):
'extent.device' : dev.device,
'extent.sector_start' : dev.start_sector,
'extent.sector_length' : dev.nr_sectors })
self.factory.writeRequest(msg, response=response)
self.backendController.writeRequest(msg, response=response)
def send_be_vbd_destroy(self, vdev, response=None):
log.debug('>BlkifController>send_be_vbd_destroy> dom=%d vdev=%d', self.dom, vdev)
@@ -447,5 +458,5 @@ class BlkifController(controller.Controller):
'blkif_handle' : 0,
'vdevice' : dev.vdev })
del self.devices[vdev]
self.factory.writeRequest(msg, response=response)
self.backendController.writeRequest(msg, response=response)
+107 -2
View File
@@ -270,7 +270,7 @@ class CtrlMsgRcvr:
else:
print 'CtrlMsgRcvr>writeResponse>', 'no channel!', self
class ControllerFactory(CtrlMsgRcvr):
class ControllerFactory:
"""Abstract class for factories creating controllers for a domain.
Maintains a table of instances.
@@ -281,8 +281,8 @@ class ControllerFactory(CtrlMsgRcvr):
"""
def __init__(self):
CtrlMsgRcvr.__init__(self)
self.instances = {}
self.backends = {}
self.dom = 0
def addInstance(self, instance):
@@ -370,6 +370,111 @@ class Controller(CtrlMsgRcvr):
self.deregisterChannel()
self.factory.instanceClosed(self)
class SplitControllerFactory(ControllerFactory):
"""Factory for SplitControllers.
@ivar backends: mapping of domain id to backend
@type backends: {int: BackendController}
"""
def __init__(self):
ControllerFactory.__init__(self)
self.backends = {}
def createInstance(self, dom, recreate=0, backend=0):
"""Create an instance. 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
@param backend: backend domain
@type backend: int
@return: controller instance
@rtype: SplitController (or subclass)
"""
raise NotImplementedError()
def getBackendController(self, dom):
"""Get the backend controller for a domain.
@param dom: domain
@return: backend controller
"""
ctrlr = self.backends.get(dom)
if ctrlr is None:
ctrlr = self.createBackendController(dom)
self.backends[dom] = ctrlr
return ctrlr
def createBackendController(self, dom):
"""Create a backend controller. Define in a subclass.
@param dom: domain
"""
raise NotImplementedError()
def delBackendController(self, ctrlr):
"""Remove a backend controller.
@param ctrlr: backend controller
"""
if ctrlr.dom in self.backends:
del self.backends[ctrlr.dom]
def backendControllerClosed(self, ctrlr):
"""Callback called when a backend is closed.
"""
self.delBackendController(ctrlr)
class BackendController(CtrlMsgRcvr):
"""Abstract class for a backend device controller attached to a domain.
@ivar factory: controller factory
@type factory: ControllerFactory
@ivar dom: domain
@type dom: int
@ivar channel: channel to the domain
@type channel: Channel
"""
def __init__(self, factory, dom):
CtrlMsgRcvr.__init__(self)
self.factory = factory
self.dom = int(dom)
self.channel = None
def close(self):
self.lostChannel()
def lostChannel(self):
self.deregisterChannel()
self.factory.instanceClosed(self)
class SplitController(Controller):
"""Abstract class for a device controller attached to a domain.
A SplitController has a BackendContoller.
"""
def __init__(self, factory, dom, backend):
Controller.__init__(self, factory, dom)
self.backendDomain = None
self.backendController = None
self.setBackendDomain(backend)
def setBackendDomain(self, dom):
ctrlr = self.factory.getBackendController(dom)
self.backendDomain = ctrlr.dom
self.backendController = ctrlr
def getBackendDomain(self):
return self.backendDomain
def getBackendController(self):
return self.backendController
class Dev:
"""Abstract class for a device attached to a device controller.
+48 -38
View File
@@ -18,20 +18,49 @@ import channel
import controller
from messages import *
class NetifControllerFactory(controller.ControllerFactory):
"""Factory for creating network interface controllers.
Also handles the 'back-end' channel to the device driver domain.
class NetifBackendController(controller.BackendController):
"""Handler for the 'back-end' channel to a device driver domain.
"""
def __init__(self):
controller.ControllerFactory.__init__(self)
def __init__(self, factory, dom):
controller.BackendController.__init__(self, factory, dom)
self.addMethod(CMSG_NETIF_BE,
CMSG_NETIF_BE_DRIVER_STATUS_CHANGED,
self.recv_be_driver_status_changed)
self.attached = 1
self.registerChannel()
def createInstance(self, dom, recreate=0):
def respond_be_connect(self, msg):
val = unpackMsg('netif_be_connect_t', msg)
dom = val['domid']
vif = val['netif_handle']
netif = self.factory.getInstanceByDom(dom)
if netif:
netif.send_interface_connected(vif)
else:
log.warning("respond_be_connect> unknown vif dom=%d vif=%d", dom, vif)
pass
def recv_be_driver_status_changed(self, msg, req):
val = unpackMsg('netif_be_driver_status_changed_t', msg)
status = val['status']
if status == NETIF_DRIVER_STATUS_UP and not self.attached:
# If we are not attached the driver domain was changed, and
# this signals the new driver domain is ready.
for netif in self.factory.getInstances():
if netif.backendController == self:
netif.reattach_devices()
self.attached = 1
class NetifControllerFactory(controller.SplitControllerFactory):
"""Factory for creating network interface controllers.
"""
def __init__(self):
controller.ControllerFactory.__init__(self)
self.attached = 1
def createInstance(self, dom, recreate=0, backend=0):
"""Create or find the network interface controller for a domain.
@param dom: domain
@@ -40,7 +69,7 @@ class NetifControllerFactory(controller.ControllerFactory):
"""
netif = self.getInstanceByDom(dom)
if netif is None:
netif = NetifController(self, dom)
netif = NetifController(self, dom, backend=backend)
self.addInstance(netif)
return netif
@@ -63,6 +92,9 @@ class NetifControllerFactory(controller.ControllerFactory):
netif = self.getInstanceByDom(dom)
return (netif and netif.getDevice(vif)) or None
def createBackendController(self, dom):
return NetifBackendController(self, dom)
def setControlDomain(self, dom, recreate=0):
"""Set the 'back-end' device driver domain.
@@ -83,27 +115,6 @@ class NetifControllerFactory(controller.ControllerFactory):
"""
return self.dom
def respond_be_connect(self, msg):
val = unpackMsg('netif_be_connect_t', msg)
dom = val['domid']
vif = val['netif_handle']
netif = self.getInstanceByDom(dom)
if netif:
netif.send_interface_connected(vif)
else:
log.warning("respond_be_connect> unknown vif dom=%d vif=%d", dom, vif)
pass
def recv_be_driver_status_changed(self, msg, req):
val = unpackMsg('netif_be_driver_status_changed_t', msg)
status = val['status']
if status == NETIF_DRIVER_STATUS_UP and not self.attached:
# If we are not attached the driver domain was changed, and
# this signals the new driver domain is ready.
for netif in self.getInstances():
netif.reattach_devices()
self.attached = 1
class NetDev(controller.Dev):
"""Info record for a network device.
"""
@@ -207,14 +218,13 @@ class NetDev(controller.Dev):
self.controller.send_be_disconnect(self.vif, response=d)
class NetifController(controller.Controller):
class NetifController(controller.SplitController):
"""Network interface controller. Handles all network devices for a domain.
"""
def __init__(self, factory, dom):
controller.Controller.__init__(self, factory, dom)
def __init__(self, factory, dom, backend):
controller.SplitController.__init__(self, factory, dom, backend)
self.devices = {}
self.addMethod(CMSG_NETIF_FE,
CMSG_NETIF_FE_DRIVER_STATUS_CHANGED,
self.recv_fe_driver_status_changed)
@@ -317,8 +327,8 @@ class NetifController(controller.Controller):
'tx_shmem_frame' : val['tx_shmem_frame'],
'rx_shmem_frame' : val['rx_shmem_frame'] })
d = defer.Deferred()
d.addCallback(self.factory.respond_be_connect)
self.factory.writeRequest(msg, response=d)
d.addCallback(self.backendController.respond_be_connect)
self.backendController.writeRequest(msg, response=d)
def send_interface_connected(self, vif, response=None):
dev = self.devices[vif]
@@ -335,14 +345,14 @@ class NetifController(controller.Controller):
{ 'domid' : self.dom,
'netif_handle' : dev.vif,
'mac' : dev.mac })
self.factory.writeRequest(msg, response=response)
self.backendController.writeRequest(msg, response=response)
def send_be_disconnect(self, vif, response=None):
dev = self.devices[vif]
msg = packMsg('netif_be_disconnect_t',
{ 'domid' : self.dom,
'netif_handle' : dev.vif })
self.factory.writeRequest(msg, response=response)
self.backendController.writeRequest(msg, response=response)
def send_be_destroy(self, vif, response=None):
dev = self.devices[vif]
@@ -350,4 +360,4 @@ class NetifController(controller.Controller):
msg = packMsg('netif_be_destroy_t',
{ 'domid' : self.dom,
'netif_handle' : vif })
self.factory.writeRequest(msg, response=response)
self.backendController.writeRequest(msg, response=response)
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.