ia64/xen-unstable

changeset 2225:f8bc691dd640

bitkeeper revision 1.1159.1.53 (411ccd729CC_RzyLGa4nViY2XcSdig)

Separate controller backend from the controller factory, allowing
each controller to have its own backend domain.
author mjw@wray-m-3.hpl.hp.com
date Fri Aug 13 14:17:22 2004 +0000 (2004-08-13)
parents 6c85a89e99e3
children 54c0a4a84934
files tools/python/xen/xend/server/blkif.py tools/python/xen/xend/server/controller.py tools/python/xen/xend/server/netif.py
line diff
     1.1 --- a/tools/python/xen/xend/server/blkif.py	Fri Aug 13 13:08:23 2004 +0000
     1.2 +++ b/tools/python/xen/xend/server/blkif.py	Fri Aug 13 14:17:22 2004 +0000
     1.3 @@ -13,20 +13,109 @@ import channel
     1.4  import controller
     1.5  from messages import *
     1.6  
     1.7 -class BlkifControllerFactory(controller.ControllerFactory):
     1.8 -    """Factory for creating block device interface controllers.
     1.9 -    Also handles the 'back-end' channel to the device driver domain.
    1.10 +class BlkifBackendController(controller.BackendController):
    1.11 +    """ Handler for the 'back-end' channel to a device driver domain.
    1.12      """
    1.13  
    1.14 -    def __init__(self):
    1.15 -        controller.ControllerFactory.__init__(self)
    1.16 +    def __init__(self, factory, dom):
    1.17 +        controller.BackendController.__init__(self, factory, dom)
    1.18          self.addMethod(CMSG_BLKIF_BE,
    1.19                         CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED,
    1.20                         self.recv_be_driver_status_changed)
    1.21          self.attached = 1
    1.22          self.registerChannel()
    1.23 +        
    1.24 +    def respond_be_create(self, msg, d):
    1.25 +        """Response handler for a be_create message.
    1.26 +        Calls I{d} with the block interface created.
    1.27  
    1.28 -    def createInstance(self, dom, recreate=0):
    1.29 +        @param msg: message
    1.30 +        @type  msg: xu message
    1.31 +        @param d: deferred to call
    1.32 +        @type  d: Deferred
    1.33 +        """
    1.34 +        val = unpackMsg('blkif_be_create_t', msg)
    1.35 +        blkif = self.factory.getInstanceByDom(val['domid'])
    1.36 +        d.callback(blkif)
    1.37 +
    1.38 +    def respond_be_connect(self, msg):
    1.39 +        """Response handler for a be_connect message.
    1.40 +
    1.41 +        @param msg: message
    1.42 +        @type  msg: xu message
    1.43 +        """
    1.44 +        val = unpackMsg('blkif_be_connect_t', msg)
    1.45 +        blkif = self.factory.getInstanceByDom(val['domid'])
    1.46 +        if blkif:
    1.47 +            blkif.send_fe_interface_status_changed()
    1.48 +        else:
    1.49 +            pass
    1.50 +    
    1.51 +    def respond_be_vbd_create(self, msg, dev, d):
    1.52 +        """Response handler for a be_vbd_create message.
    1.53 +        Tries to grow the vbd, and passes the deferred I{d} on for
    1.54 +        the grow to call.
    1.55 +
    1.56 +        @param msg: message
    1.57 +        @type  msg: xu message
    1.58 +        @param dev: device
    1.59 +        @type  dev: BlkDev
    1.60 +        @param d: deferred to call
    1.61 +        @type  d: Deferred
    1.62 +        """
    1.63 +        val = unpackMsg('blkif_be_vbd_create_t', msg)
    1.64 +        blkif = self.factory.getInstanceByDom(val['domid'])
    1.65 +        if blkif:
    1.66 +            d1 = defer.Deferred()
    1.67 +            d1.addCallback(self.respond_be_vbd_grow, dev, d)
    1.68 +            if d: d1.addErrback(d.errback)
    1.69 +            blkif.send_be_vbd_grow(val['vdevice'], response=d1)
    1.70 +        else:
    1.71 +            pass
    1.72 +    
    1.73 +    def respond_be_vbd_grow(self, msg, dev, d):
    1.74 +        """Response handler for a be_vbd_grow message.
    1.75 +
    1.76 +        @param msg: message
    1.77 +        @type  msg: xu message
    1.78 +        @param dev: device
    1.79 +        @type  dev: BlkDev
    1.80 +        @param d: deferred to call
    1.81 +        @type  d: Deferred or None
    1.82 +        """
    1.83 +        val = unpackMsg('blkif_be_vbd_grow_t', msg)
    1.84 +	status = val['status']
    1.85 +	if status != BLKIF_BE_STATUS_OKAY:
    1.86 +            raise XendError("Adding extent to vbd failed: device %x, error %d"
    1.87 +                            % (val['extent.device'], status))
    1.88 +        if d:
    1.89 +            d.callback(dev)
    1.90 +
    1.91 +    def recv_be_driver_status_changed(self, msg, req):
    1.92 +        """Request handler for be_driver_status_changed messages.
    1.93 +        
    1.94 +        @param msg: message
    1.95 +        @type  msg: xu message
    1.96 +        @param req: request flag (true if the msg is a request)
    1.97 +        @type  req: bool
    1.98 +        """
    1.99 +        val = unpackMsg('blkif_be_driver_status_changed_t', msg)
   1.100 +        status = val['status']
   1.101 +        if status == BLKIF_DRIVER_STATUS_UP and not self.attached:
   1.102 +            for blkif in self.factory.getInstances():
   1.103 +                if blkif.backendController == self:
   1.104 +                    blkif.detach()
   1.105 + 
   1.106 +
   1.107 +class BlkifControllerFactory(controller.SplitControllerFactory):
   1.108 +    """Factory for creating block device interface controllers.
   1.109 +    """
   1.110 +
   1.111 +    def __init__(self):
   1.112 +        controller.SplitControllerFactory.__init__(self)
   1.113 +        self.attached = 1
   1.114 +
   1.115 +    def createInstance(self, dom, recreate=0, backend=0):
   1.116          """Create a block device controller for a domain.
   1.117  
   1.118          @param dom: domain
   1.119 @@ -41,13 +130,13 @@ class BlkifControllerFactory(controller.
   1.120          if blkif:
   1.121              d.callback(blkif)
   1.122          else:
   1.123 -            blkif = BlkifController(self, dom)
   1.124 +            blkif = BlkifController(self, dom, backend)
   1.125              self.addInstance(blkif)
   1.126              if recreate:
   1.127                  d.callback(blkif)
   1.128              else:
   1.129                  d1 = defer.Deferred()
   1.130 -                d1.addCallback(self.respond_be_create, d)
   1.131 +                d1.addCallback(blkif.backendController.respond_be_create, d)
   1.132                  d1.addErrback(d.errback)
   1.133                  blkif.send_be_create(response=d1)
   1.134          return d
   1.135 @@ -76,6 +165,9 @@ class BlkifControllerFactory(controller.
   1.136          blkif = self.getInstanceByDom(dom)
   1.137          return (blkif and blkif.getDevice(vdev)) or None
   1.138  
   1.139 +    def createBackendController(self, dom):
   1.140 +        return BlkifBackendController(self, dom)
   1.141 +
   1.142      def setControlDomain(self, dom, recreate=0):
   1.143          """Set the back-end block device controller domain.
   1.144  
   1.145 @@ -134,88 +226,7 @@ class BlkifControllerFactory(controller.
   1.146          for blkif in self.getInstances():
   1.147              blkif.reattached()
   1.148  
   1.149 -    def respond_be_create(self, msg, d):
   1.150 -        """Response handler for a be_create message.
   1.151 -        Calls I{d} with the block interface created.
   1.152  
   1.153 -        @param msg: message
   1.154 -        @type  msg: xu message
   1.155 -        @param d: deferred to call
   1.156 -        @type  d: Deferred
   1.157 -        """
   1.158 -        val = unpackMsg('blkif_be_create_t', msg)
   1.159 -        blkif = self.getInstanceByDom(val['domid'])
   1.160 -        d.callback(blkif)
   1.161 -    
   1.162 -    def respond_be_connect(self, msg):
   1.163 -        """Response handler for a be_connect message.
   1.164 -
   1.165 -        @param msg: message
   1.166 -        @type  msg: xu message
   1.167 -        """
   1.168 -        val = unpackMsg('blkif_be_connect_t', msg)
   1.169 -        blkif = self.getInstanceByDom(val['domid'])
   1.170 -        if blkif:
   1.171 -            blkif.send_fe_interface_status_changed()
   1.172 -        else:
   1.173 -            pass
   1.174 -    
   1.175 -    def respond_be_vbd_create(self, msg, dev, d):
   1.176 -        """Response handler for a be_vbd_create message.
   1.177 -        Tries to grow the vbd, and passes the deferred I{d} on for
   1.178 -        the grow to call.
   1.179 -
   1.180 -        @param msg: message
   1.181 -        @type  msg: xu message
   1.182 -        @param dev: device
   1.183 -        @type  dev: BlkDev
   1.184 -        @param d: deferred to call
   1.185 -        @type  d: Deferred
   1.186 -        """
   1.187 -        val = unpackMsg('blkif_be_vbd_create_t', msg)
   1.188 -        blkif = self.getInstanceByDom(val['domid'])
   1.189 -        if blkif:
   1.190 -            d1 = defer.Deferred()
   1.191 -            d1.addCallback(self.respond_be_vbd_grow, dev, d)
   1.192 -            if d: d1.addErrback(d.errback)
   1.193 -            blkif.send_be_vbd_grow(val['vdevice'], response=d1)
   1.194 -        else:
   1.195 -            pass
   1.196 -    
   1.197 -    def respond_be_vbd_grow(self, msg, dev, d):
   1.198 -        """Response handler for a be_vbd_grow message.
   1.199 -
   1.200 -        @param msg: message
   1.201 -        @type  msg: xu message
   1.202 -        @param dev: device
   1.203 -        @type  dev: BlkDev
   1.204 -        @param d: deferred to call
   1.205 -        @type  d: Deferred or None
   1.206 -        """
   1.207 -        val = unpackMsg('blkif_be_vbd_grow_t', msg)
   1.208 -	status = val['status']
   1.209 -	if status != BLKIF_BE_STATUS_OKAY:
   1.210 -            raise XendError("Adding extent to vbd failed: device %x, error %d"
   1.211 -                            % (val['extent.device'], status))
   1.212 -        if self.attached:
   1.213 -            if d:
   1.214 -                d.callback(dev)
   1.215 -        else:
   1.216 -            self.reattachDevice(val['domid'], val['vdevice'])
   1.217 -
   1.218 -    def recv_be_driver_status_changed(self, msg, req):
   1.219 -        """Request handler for be_driver_status_changed messages.
   1.220 -        
   1.221 -        @param msg: message
   1.222 -        @type  msg: xu message
   1.223 -        @param req: request flag (true if the msg is a request)
   1.224 -        @type  req: bool
   1.225 -        """
   1.226 -        val = unpackMsg('blkif_be_driver_status_changed_t', msg)
   1.227 -        status = val['status']
   1.228 -        if status == BLKIF_DRIVER_STATUS_UP and not self.attached:
   1.229 -            for blkif in self.getInstances():
   1.230 -                blkif.detach()
   1.231  
   1.232  class BlkDev(controller.Dev):
   1.233      """Info record for a block device.
   1.234 @@ -251,13 +262,13 @@ class BlkDev(controller.Dev):
   1.235          log.debug("Destroying vbd domain=%d vdev=%d", self.controller.dom, self.vdev)
   1.236          self.controller.send_be_vbd_destroy(self.vdev)
   1.237          
   1.238 -class BlkifController(controller.Controller):
   1.239 +class BlkifController(controller.SplitController):
   1.240      """Block device interface controller. Handles all block devices
   1.241      for a domain.
   1.242      """
   1.243      
   1.244 -    def __init__(self, factory, dom):
   1.245 -        controller.Controller.__init__(self, factory, dom)
   1.246 +    def __init__(self, factory, dom, backend):
   1.247 +        controller.SplitController.__init__(self, factory, dom, backend)
   1.248          self.devices = {}
   1.249          self.addMethod(CMSG_BLKIF_FE,
   1.250                         CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED,
   1.251 @@ -322,7 +333,7 @@ class BlkifController(controller.Control
   1.252              d.callback(dev)
   1.253          else:
   1.254              d1 = defer.Deferred()
   1.255 -            d1.addCallback(self.factory.respond_be_vbd_create, dev, d)
   1.256 +            d1.addCallback(self.backendController.respond_be_vbd_create, dev, d)
   1.257              d1.addErrback(d.errback)
   1.258              self.send_be_vbd_create(vdev, response=d1)
   1.259          return d
   1.260 @@ -346,7 +357,7 @@ class BlkifController(controller.Control
   1.261          for dev in self.devices.values():
   1.262              dev.attached = 0
   1.263              d1 = defer.Deferred()
   1.264 -            d1.addCallback(self.factory.respond_be_vbd_create, None, None)
   1.265 +            d1.addCallback(self.backendController.respond_be_vbd_create, None, None)
   1.266              self.send_be_vbd_create(vdev, response=d1)
   1.267  
   1.268      def reattachDevice(self, vdev):
   1.269 @@ -389,8 +400,8 @@ class BlkifController(controller.Control
   1.270                          'evtchn'       : self.evtchn['port1'],
   1.271                          'shmem_frame'  : val['shmem_frame'] })
   1.272          d = defer.Deferred()
   1.273 -        d.addCallback(self.factory.respond_be_connect)
   1.274 -        self.factory.writeRequest(msg, response=d)
   1.275 +        d.addCallback(self.backendController.respond_be_connect)
   1.276 +        self.backendController.writeRequest(msg, response=d)
   1.277  
   1.278      def send_fe_interface_status_changed(self, response=None):
   1.279          msg = packMsg('blkif_fe_interface_status_changed_t',
   1.280 @@ -403,21 +414,21 @@ class BlkifController(controller.Control
   1.281          msg = packMsg('blkif_be_create_t',
   1.282                        { 'domid'        : self.dom,
   1.283                          'blkif_handle' : 0 })
   1.284 -        self.factory.writeRequest(msg, response=response)
   1.285 +        self.backendController.writeRequest(msg, response=response)
   1.286  
   1.287      def send_be_disconnect(self, response=None):
   1.288          log.debug('>BlkifController>send_be_disconnect> dom=%d', self.dom)
   1.289          msg = packMsg('blkif_be_disconnect_t',
   1.290                        { 'domid'        : self.dom,
   1.291                          'blkif_handle' : 0 })
   1.292 -        self.factory.writeRequest(msg, response=response)
   1.293 +        self.backendController.writeRequest(msg, response=response)
   1.294  
   1.295      def send_be_destroy(self, response=None):
   1.296          log.debug('>BlkifController>send_be_destroy> dom=%d', self.dom)
   1.297          msg = packMsg('blkif_be_destroy_t',
   1.298                        { 'domid'        : self.dom,
   1.299                          'blkif_handle' : 0 })
   1.300 -        self.factory.writeRequest(msg, response=response)
   1.301 +        self.backendController.writeRequest(msg, response=response)
   1.302  
   1.303      def send_be_vbd_create(self, vdev, response=None):
   1.304          dev = self.devices[vdev]
   1.305 @@ -426,7 +437,7 @@ class BlkifController(controller.Control
   1.306                          'blkif_handle' : 0,
   1.307                          'vdevice'      : dev.vdev,
   1.308                          'readonly'     : dev.readonly() })
   1.309 -        self.factory.writeRequest(msg, response=response)
   1.310 +        self.backendController.writeRequest(msg, response=response)
   1.311          
   1.312      def send_be_vbd_grow(self, vdev, response=None):
   1.313          dev = self.devices[vdev]
   1.314 @@ -437,7 +448,7 @@ class BlkifController(controller.Control
   1.315                          'extent.device'        : dev.device,
   1.316                          'extent.sector_start'  : dev.start_sector,
   1.317                          'extent.sector_length' : dev.nr_sectors })
   1.318 -        self.factory.writeRequest(msg, response=response)
   1.319 +        self.backendController.writeRequest(msg, response=response)
   1.320  
   1.321      def send_be_vbd_destroy(self, vdev, response=None):
   1.322          log.debug('>BlkifController>send_be_vbd_destroy> dom=%d vdev=%d', self.dom, vdev)
   1.323 @@ -447,5 +458,5 @@ class BlkifController(controller.Control
   1.324                          'blkif_handle'         : 0,
   1.325                          'vdevice'              : dev.vdev })
   1.326          del self.devices[vdev]
   1.327 -        self.factory.writeRequest(msg, response=response)
   1.328 +        self.backendController.writeRequest(msg, response=response)
   1.329      
     2.1 --- a/tools/python/xen/xend/server/controller.py	Fri Aug 13 13:08:23 2004 +0000
     2.2 +++ b/tools/python/xen/xend/server/controller.py	Fri Aug 13 14:17:22 2004 +0000
     2.3 @@ -270,7 +270,7 @@ class CtrlMsgRcvr:
     2.4          else:
     2.5              print 'CtrlMsgRcvr>writeResponse>', 'no channel!', self
     2.6              
     2.7 -class ControllerFactory(CtrlMsgRcvr):
     2.8 +class ControllerFactory:
     2.9      """Abstract class for factories creating controllers for a domain.
    2.10      Maintains a table of instances.
    2.11  
    2.12 @@ -281,8 +281,8 @@ class ControllerFactory(CtrlMsgRcvr):
    2.13      """
    2.14  
    2.15      def __init__(self):
    2.16 -        CtrlMsgRcvr.__init__(self)
    2.17          self.instances = {}
    2.18 +        self.backends = {}
    2.19          self.dom = 0
    2.20          
    2.21      def addInstance(self, instance):
    2.22 @@ -370,6 +370,111 @@ class Controller(CtrlMsgRcvr):
    2.23          self.deregisterChannel()
    2.24          self.factory.instanceClosed(self)
    2.25  
    2.26 +class SplitControllerFactory(ControllerFactory):
    2.27 +    """Factory for SplitControllers.
    2.28 +    
    2.29 +    @ivar backends:  mapping of domain id to backend
    2.30 +    @type backends:  {int: BackendController}
    2.31 +    """
    2.32 +    
    2.33 +    def __init__(self):
    2.34 +        ControllerFactory.__init__(self)
    2.35 +        self.backends = {}
    2.36 +
    2.37 +    def createInstance(self, dom, recreate=0, backend=0):
    2.38 +        """Create an instance. Define in a subclass.
    2.39 +
    2.40 +        @param dom: domain
    2.41 +        @type  dom: int
    2.42 +        @param recreate: true if the instance is being recreated (after xend restart)
    2.43 +        @type  recreate: int
    2.44 +        @param backend: backend domain
    2.45 +        @type  backend: int
    2.46 +        @return: controller instance
    2.47 +        @rtype:  SplitController (or subclass)
    2.48 +        """
    2.49 +        raise NotImplementedError()
    2.50 +        
    2.51 +    def getBackendController(self, dom):
    2.52 +        """Get the backend controller for a domain.
    2.53 +
    2.54 +        @param dom: domain
    2.55 +        @return: backend controller
    2.56 +        """
    2.57 +        ctrlr = self.backends.get(dom)
    2.58 +        if ctrlr is None:
    2.59 +            ctrlr = self.createBackendController(dom)
    2.60 +            self.backends[dom] = ctrlr
    2.61 +        return ctrlr
    2.62 +
    2.63 +    def createBackendController(self, dom):
    2.64 +        """Create a backend controller. Define in a subclass.
    2.65 +
    2.66 +        @param dom: domain
    2.67 +        """
    2.68 +        raise NotImplementedError()
    2.69 +
    2.70 +    def delBackendController(self, ctrlr):
    2.71 +        """Remove a backend controller.
    2.72 +
    2.73 +        @param ctrlr: backend controller
    2.74 +        """
    2.75 +        if ctrlr.dom in self.backends:
    2.76 +            del self.backends[ctrlr.dom]
    2.77 +
    2.78 +    def backendControllerClosed(self, ctrlr):
    2.79 +        """Callback called when a backend is closed.
    2.80 +        """
    2.81 +        self.delBackendController(ctrlr)
    2.82 +
    2.83 +class BackendController(CtrlMsgRcvr):
    2.84 +    """Abstract class for a backend device controller attached to a domain.
    2.85 +
    2.86 +    @ivar factory: controller factory
    2.87 +    @type factory: ControllerFactory
    2.88 +    @ivar dom:     domain
    2.89 +    @type dom:     int
    2.90 +    @ivar channel: channel to the domain
    2.91 +    @type channel: Channel
    2.92 +    """
    2.93 +
    2.94 +    
    2.95 +    def __init__(self, factory, dom):
    2.96 +        CtrlMsgRcvr.__init__(self)
    2.97 +        self.factory = factory
    2.98 +        self.dom = int(dom)
    2.99 +        self.channel = None
   2.100 +        
   2.101 +    def close(self):
   2.102 +        self.lostChannel()
   2.103 +
   2.104 +    def lostChannel(self):
   2.105 +        self.deregisterChannel()
   2.106 +        self.factory.instanceClosed(self)
   2.107 +
   2.108 +
   2.109 +class SplitController(Controller):
   2.110 +    """Abstract class for a device controller attached to a domain.
   2.111 +    A SplitController has a BackendContoller.
   2.112 +    """
   2.113 +
   2.114 +    def __init__(self, factory, dom, backend):
   2.115 +        Controller.__init__(self, factory, dom)
   2.116 +        self.backendDomain = None
   2.117 +        self.backendController = None
   2.118 +        self.setBackendDomain(backend)
   2.119 +        
   2.120 +    def setBackendDomain(self, dom):
   2.121 +        ctrlr = self.factory.getBackendController(dom)
   2.122 +        self.backendDomain = ctrlr.dom
   2.123 +        self.backendController = ctrlr
   2.124 +
   2.125 +    def getBackendDomain(self):
   2.126 +        return self.backendDomain
   2.127 +
   2.128 +    def getBackendController(self):
   2.129 +        return self.backendController
   2.130 +
   2.131  class Dev:
   2.132      """Abstract class for a device attached to a device controller.
   2.133  
     3.1 --- a/tools/python/xen/xend/server/netif.py	Fri Aug 13 13:08:23 2004 +0000
     3.2 +++ b/tools/python/xen/xend/server/netif.py	Fri Aug 13 14:17:22 2004 +0000
     3.3 @@ -18,20 +18,49 @@ import channel
     3.4  import controller
     3.5  from messages import *
     3.6  
     3.7 -class NetifControllerFactory(controller.ControllerFactory):
     3.8 -    """Factory for creating network interface controllers.
     3.9 -    Also handles the 'back-end' channel to the device driver domain.
    3.10 +class NetifBackendController(controller.BackendController):
    3.11 +    """Handler for the 'back-end' channel to a device driver domain.
    3.12      """
    3.13 -
    3.14 -    def __init__(self):
    3.15 -        controller.ControllerFactory.__init__(self)
    3.16 +    
    3.17 +    def __init__(self, factory, dom):
    3.18 +        controller.BackendController.__init__(self, factory, dom)
    3.19          self.addMethod(CMSG_NETIF_BE,
    3.20                         CMSG_NETIF_BE_DRIVER_STATUS_CHANGED,
    3.21                         self.recv_be_driver_status_changed)
    3.22          self.attached = 1
    3.23          self.registerChannel()
    3.24  
    3.25 -    def createInstance(self, dom, recreate=0):
    3.26 +    def respond_be_connect(self, msg):
    3.27 +        val = unpackMsg('netif_be_connect_t', msg)
    3.28 +        dom = val['domid']
    3.29 +        vif = val['netif_handle']
    3.30 +        netif = self.factory.getInstanceByDom(dom)
    3.31 +        if netif:
    3.32 +            netif.send_interface_connected(vif)
    3.33 +        else:
    3.34 +            log.warning("respond_be_connect> unknown vif dom=%d vif=%d", dom, vif)
    3.35 +            pass
    3.36 +
    3.37 +    def recv_be_driver_status_changed(self, msg, req):
    3.38 +        val = unpackMsg('netif_be_driver_status_changed_t', msg)
    3.39 +        status = val['status']
    3.40 +        if status == NETIF_DRIVER_STATUS_UP and not self.attached:
    3.41 +            # If we are not attached the driver domain was changed, and
    3.42 +            # this signals the new driver domain is ready.
    3.43 +            for netif in self.factory.getInstances():
    3.44 +                if netif.backendController == self:
    3.45 +                    netif.reattach_devices()
    3.46 +            self.attached = 1
    3.47 +
    3.48 +class NetifControllerFactory(controller.SplitControllerFactory):
    3.49 +    """Factory for creating network interface controllers.
    3.50 +    """
    3.51 +
    3.52 +    def __init__(self):
    3.53 +        controller.ControllerFactory.__init__(self)
    3.54 +        self.attached = 1
    3.55 +
    3.56 +    def createInstance(self, dom, recreate=0, backend=0):
    3.57          """Create or find the network interface controller for a domain.
    3.58  
    3.59          @param dom:      domain
    3.60 @@ -40,7 +69,7 @@ class NetifControllerFactory(controller.
    3.61          """
    3.62          netif = self.getInstanceByDom(dom)
    3.63          if netif is None:
    3.64 -            netif = NetifController(self, dom)
    3.65 +            netif = NetifController(self, dom, backend=backend)
    3.66              self.addInstance(netif)
    3.67          return netif
    3.68  
    3.69 @@ -63,6 +92,9 @@ class NetifControllerFactory(controller.
    3.70          netif = self.getInstanceByDom(dom)
    3.71          return (netif and netif.getDevice(vif)) or None
    3.72          
    3.73 +    def createBackendController(self, dom):
    3.74 +        return NetifBackendController(self, dom)
    3.75 +
    3.76      def setControlDomain(self, dom, recreate=0):
    3.77          """Set the 'back-end' device driver domain.
    3.78  
    3.79 @@ -83,27 +115,6 @@ class NetifControllerFactory(controller.
    3.80          """
    3.81          return self.dom
    3.82  
    3.83 -    def respond_be_connect(self, msg):
    3.84 -        val = unpackMsg('netif_be_connect_t', msg)
    3.85 -        dom = val['domid']
    3.86 -        vif = val['netif_handle']
    3.87 -        netif = self.getInstanceByDom(dom)
    3.88 -        if netif:
    3.89 -            netif.send_interface_connected(vif)
    3.90 -        else:
    3.91 -            log.warning("respond_be_connect> unknown vif dom=%d vif=%d", dom, vif)
    3.92 -            pass
    3.93 -
    3.94 -    def recv_be_driver_status_changed(self, msg, req):
    3.95 -        val = unpackMsg('netif_be_driver_status_changed_t', msg)
    3.96 -        status = val['status']
    3.97 -        if status == NETIF_DRIVER_STATUS_UP and not self.attached:
    3.98 -            # If we are not attached the driver domain was changed, and
    3.99 -            # this signals the new driver domain is ready.
   3.100 -            for netif in self.getInstances():
   3.101 -                netif.reattach_devices()
   3.102 -            self.attached = 1
   3.103 -
   3.104  class NetDev(controller.Dev):
   3.105      """Info record for a network device.
   3.106      """
   3.107 @@ -207,14 +218,13 @@ class NetDev(controller.Dev):
   3.108          self.controller.send_be_disconnect(self.vif, response=d)
   3.109          
   3.110  
   3.111 -class NetifController(controller.Controller):
   3.112 +class NetifController(controller.SplitController):
   3.113      """Network interface controller. Handles all network devices for a domain.
   3.114      """
   3.115      
   3.116 -    def __init__(self, factory, dom):
   3.117 -        controller.Controller.__init__(self, factory, dom)
   3.118 +    def __init__(self, factory, dom, backend):
   3.119 +        controller.SplitController.__init__(self, factory, dom, backend)
   3.120          self.devices = {}
   3.121 -        
   3.122          self.addMethod(CMSG_NETIF_FE,
   3.123                         CMSG_NETIF_FE_DRIVER_STATUS_CHANGED,
   3.124                         self.recv_fe_driver_status_changed)
   3.125 @@ -317,8 +327,8 @@ class NetifController(controller.Control
   3.126                          'tx_shmem_frame' : val['tx_shmem_frame'],
   3.127                          'rx_shmem_frame' : val['rx_shmem_frame'] })
   3.128          d = defer.Deferred()
   3.129 -        d.addCallback(self.factory.respond_be_connect)
   3.130 -        self.factory.writeRequest(msg, response=d)
   3.131 +        d.addCallback(self.backendController.respond_be_connect)
   3.132 +        self.backendController.writeRequest(msg, response=d)
   3.133  
   3.134      def send_interface_connected(self, vif, response=None):
   3.135          dev = self.devices[vif]
   3.136 @@ -335,14 +345,14 @@ class NetifController(controller.Control
   3.137                        { 'domid'        : self.dom,
   3.138                          'netif_handle' : dev.vif,
   3.139                          'mac'          : dev.mac })
   3.140 -        self.factory.writeRequest(msg, response=response)
   3.141 +        self.backendController.writeRequest(msg, response=response)
   3.142  
   3.143      def send_be_disconnect(self, vif, response=None):
   3.144          dev = self.devices[vif]
   3.145          msg = packMsg('netif_be_disconnect_t',
   3.146                        { 'domid'        : self.dom,
   3.147                          'netif_handle' : dev.vif })
   3.148 -        self.factory.writeRequest(msg, response=response)
   3.149 +        self.backendController.writeRequest(msg, response=response)
   3.150  
   3.151      def send_be_destroy(self, vif, response=None):
   3.152          dev = self.devices[vif]
   3.153 @@ -350,4 +360,4 @@ class NetifController(controller.Control
   3.154          msg = packMsg('netif_be_destroy_t',
   3.155                        { 'domid'        : self.dom,
   3.156                          'netif_handle' : vif })
   3.157 -        self.factory.writeRequest(msg, response=response)
   3.158 +        self.backendController.writeRequest(msg, response=response)