direct-io.hg

changeset 2267:45db83f2cdd0

bitkeeper revision 1.1159.38.3 (4123550cLBAC07otAj8ftsT6MzujHQ)

Make backend domain a per-device parameter.
Restructure device controllers and adjust
config handling.
author mjw@wray-m-3.hpl.hp.com
date Wed Aug 18 13:09:32 2004 +0000 (2004-08-18)
parents a63157177284
children dbbb42e06417
files tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/server/SrvDaemon.py tools/python/xen/xend/server/blkif.py tools/python/xen/xend/server/controller.py tools/python/xen/xend/server/netif.py tools/python/xen/xm/create.py
line diff
     1.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Wed Aug 18 13:07:07 2004 +0000
     1.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Wed Aug 18 13:09:32 2004 +0000
     1.3 @@ -137,7 +137,7 @@ def lookup_disk_uname(uname):
     1.4          segments = None
     1.5      return segments
     1.6  
     1.7 -def make_disk(vm, uname, dev, mode, recreate=0):
     1.8 +def make_disk(vm, config, uname, dev, mode, recreate=0):
     1.9      """Create a virtual disk device for a domain.
    1.10  
    1.11      @param vm:       vm
    1.12 @@ -154,13 +154,8 @@ def make_disk(vm, uname, dev, mode, recr
    1.13          raise VmError("vbd: Multi-segment vdisk: uname=%s" % uname)
    1.14      segment = segments[0]
    1.15      vdev = blkdev_name_to_number(dev)
    1.16 -    backend = vm.get_device_backend('vbd')
    1.17 -    ctrl = xend.blkif_create(vm.dom, recreate=recreate, backend=backend)
    1.18 -    
    1.19 -    def fn(ctrl):
    1.20 -        return xend.blkif_dev_create(vm.dom, vdev, mode, segment, recreate=recreate)
    1.21 -    ctrl.addCallback(fn)
    1.22 -    return ctrl
    1.23 +    ctrl = xend.blkif_create(vm.dom, recreate=recreate)
    1.24 +    return ctrl.attachDevice(config, vdev, mode, segment, recreate=recreate)
    1.25          
    1.26  def vif_up(iplist):
    1.27      """send an unsolicited ARP reply for all non link-local IP addresses.
    1.28 @@ -340,22 +335,6 @@ def append_deferred(dlist, v):
    1.29      if isinstance(v, defer.Deferred):
    1.30          dlist.append(v)
    1.31  
    1.32 -def _vm_configure1(val, vm):
    1.33 -    d = vm.create_devices()
    1.34 -    d.addCallback(_vm_configure2, vm)
    1.35 -    return d
    1.36 -
    1.37 -def _vm_configure2(val, vm):
    1.38 -    d = vm.configure_fields()
    1.39 -    def cbok(results):
    1.40 -        return vm
    1.41 -    def cberr(err):
    1.42 -        vm.destroy()
    1.43 -        return err
    1.44 -    d.addCallback(cbok)
    1.45 -    d.addErrback(cberr)
    1.46 -    return d
    1.47 -
    1.48  class XendDomainInfo:
    1.49      """Virtual machine object."""
    1.50  
    1.51 @@ -379,7 +358,6 @@ class XendDomainInfo:
    1.52          self.console = None
    1.53          self.devices = {}
    1.54          self.device_index = {}
    1.55 -        self.device_backends = {}
    1.56          self.configs = []
    1.57          self.info = None
    1.58          self.ipaddrs = []
    1.59 @@ -675,7 +653,6 @@ class XendDomainInfo:
    1.60          
    1.61          self.devices = {}
    1.62          self.device_index = {}
    1.63 -        self.device_backends = {}
    1.64          self.configs = []
    1.65          self.ipaddrs = []
    1.66  
    1.67 @@ -915,25 +892,6 @@ class XendDomainInfo:
    1.68              self.restart_state = None
    1.69          return d
    1.70  
    1.71 -    def configure_device_backend(self, type, sxpr):
    1.72 -        """Configure the backend domain to use for devices of a given type.
    1.73 -
    1.74 -        @param type: device type
    1.75 -        @param sxpr: config
    1.76 -        @raise: VmError if the domain id is missing
    1.77 -        @raise: VmError if the domain does not exist
    1.78 -        """
    1.79 -        dom = sxp.child_value(sxpr, 'domain')
    1.80 -        if dom is None:
    1.81 -            raise VmError('missing backend domain')
    1.82 -        dominfo = domain_exists(dom)
    1.83 -        if dominfo is None:
    1.84 -            raise VmError('invalid backend domain:' + dom)
    1.85 -        self.device_backends[type] = dominfo.dom
    1.86 -
    1.87 -    def get_device_backend(self, type):
    1.88 -        return self.device_backends.get(type, 0)
    1.89 -
    1.90      def configure_backends(self):
    1.91          """Set configuration flags if the vm is a backend for netif or blkif.
    1.92          Configure the backends to use for vbd and vif if specified.
    1.93 @@ -945,21 +903,9 @@ class XendDomainInfo:
    1.94                  self.blkif_backend = 1
    1.95              elif name == 'netif':
    1.96                  self.netif_backend = 1
    1.97 -            elif name == 'vbd':
    1.98 -                self.configure_device_backend('vbd', v)
    1.99 -            elif name == 'vif':
   1.100 -                self.configure_device_backend('vif', v)
   1.101              else:
   1.102                  raise VmError('invalid backend type:' + str(name))
   1.103  
   1.104 -    def create_backends(self):
   1.105 -        """Setup the netif and blkif backends.
   1.106 -        """
   1.107 -        if self.blkif_backend:
   1.108 -            xend.blkif_set_control_domain(self.dom, recreate=self.recreate)
   1.109 -        if self.netif_backend:
   1.110 -            xend.netif_set_control_domain(self.dom, recreate=self.recreate)
   1.111 -            
   1.112      def configure(self):
   1.113          """Configure a vm.
   1.114  
   1.115 @@ -968,12 +914,19 @@ class XendDomainInfo:
   1.116  
   1.117          returns Deferred - calls callback with vm
   1.118          """
   1.119 -        if self.blkif_backend:
   1.120 -            d = defer.Deferred()
   1.121 -            d.callback(self)
   1.122 -        else:
   1.123 -            d = xend.blkif_create(self.dom, recreate=self.recreate)
   1.124 -        d.addCallback(_vm_configure1, self)
   1.125 +        d = self.create_devices()
   1.126 +        d.addCallback(self._configure)
   1.127 +        return d
   1.128 +
   1.129 +    def _configure(self, val):
   1.130 +        d = self.configure_fields()
   1.131 +        def cbok(results):
   1.132 +            return self
   1.133 +        def cberr(err):
   1.134 +            self.destroy()
   1.135 +            return err
   1.136 +        d.addCallback(cbok)
   1.137 +        d.addErrback(cberr)
   1.138          return d
   1.139  
   1.140      def dom_construct(self, dom, config):
   1.141 @@ -1078,16 +1031,14 @@ def vm_dev_vif(vm, val, index):
   1.142      #    raise VmError('vif: vif in netif backend domain')
   1.143      vif = vm.next_device_index('vif')
   1.144      vmac = sxp.child_value(val, "mac")
   1.145 -    backend = vm.get_device_backend('vif')
   1.146 -    xend.netif_create(vm.dom, recreate=vm.recreate, backend=backend)
   1.147 +    ctrl = xend.netif_create(vm.dom, recreate=vm.recreate)
   1.148      log.debug("Creating vif dom=%d vif=%d mac=%s", vm.dom, vif, str(vmac))
   1.149 -    defer = xend.netif_dev_create(vm.dom, vif, val, recreate=vm.recreate)
   1.150 -    def fn(id):
   1.151 -        dev = xend.netif_dev(vm.dom, vif)
   1.152 +    defer = ctrl.attachDevice(vif, val, recreate=vm.recreate)
   1.153 +    def cbok(dev):
   1.154          dev.vifctl('up', vmname=vm.name)
   1.155          vm.add_device('vif', dev)
   1.156 -        return id
   1.157 -    defer.addCallback(fn)
   1.158 +        return dev
   1.159 +    defer.addCallback(cbok)
   1.160      return defer
   1.161  
   1.162  def vm_dev_vbd(vm, val, index):
   1.163 @@ -1108,7 +1059,7 @@ def vm_dev_vbd(vm, val, index):
   1.164          raise VmError('vbd: Missing dev')
   1.165      mode = sxp.child_value(val, 'mode', 'r')
   1.166      log.debug("Creating vbd dom=%d uname=%s dev=%s", vm.dom, uname, dev)
   1.167 -    defer = make_disk(vm, uname, dev, mode, vm.recreate)
   1.168 +    defer = make_disk(vm, val, uname, dev, mode, vm.recreate)
   1.169      def fn(vbd):
   1.170          vbd.dev = dev
   1.171          vbd.uname = uname
     2.1 --- a/tools/python/xen/xend/server/SrvDaemon.py	Wed Aug 18 13:07:07 2004 +0000
     2.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py	Wed Aug 18 13:09:32 2004 +0000
     2.3 @@ -651,23 +651,12 @@ class Daemon:
     2.4          """
     2.5          return self.channelF.getDomChannel(dom)
     2.6  
     2.7 -    def blkif_set_control_domain(self, dom, recreate=0):
     2.8 -        """Set the block device backend control domain.
     2.9 -        """
    2.10 -        return self.blkifCF.setControlDomain(dom, recreate=recreate)
    2.11 -    
    2.12 -    def blkif_get_control_domain(self, dom):
    2.13 -        """Get the block device backend control domain.
    2.14 -        """
    2.15 -        return self.blkifCF.getControlDomain()
    2.16 -    
    2.17 -    def blkif_create(self, dom, recreate=0, backend=0):
    2.18 +    def blkif_create(self, dom, recreate=0):
    2.19          """Create a block device interface controller.
    2.20          
    2.21 -        Returns Deferred
    2.22 +        Returns controller
    2.23          """
    2.24 -        d = self.blkifCF.createInstance(dom, recreate=recreate, backend=backend)
    2.25 -        return d
    2.26 +        return self.blkifCF.createInstance(dom, recreate=recreate)
    2.27  
    2.28      def blkifs(self):
    2.29          return [ x.sxpr() for x in self.blkifCF.getInstances() ]
    2.30 @@ -678,7 +667,7 @@ class Daemon:
    2.31      def blkif_dev(self, dom, vdev):
    2.32          return self.blkifCF.getDomainDevice(dom, vdev)
    2.33  
    2.34 -    def blkif_dev_create(self, dom, vdev, mode, segment, recreate=0):
    2.35 +    def blkif_dev_create(self, dom, config, vdev, mode, segment, recreate=0):
    2.36          """Create a block device.
    2.37          
    2.38          Returns Deferred
    2.39 @@ -686,24 +675,14 @@ class Daemon:
    2.40          ctrl = self.blkifCF.getInstanceByDom(dom)
    2.41          if not ctrl:
    2.42              raise XendError('No blkif controller: %d' % dom)
    2.43 -        d = ctrl.attachDevice(vdev, mode, segment, recreate=recreate)
    2.44 +        d = ctrl.attachDevice(config, vdev, mode, segment, recreate=recreate)
    2.45          return d
    2.46  
    2.47 -    def netif_set_control_domain(self, dom, recreate=0):
    2.48 -        """Set the network interface backend control domain.
    2.49 -        """
    2.50 -        return self.netifCF.setControlDomain(dom, recreate=recreate)
    2.51 -
    2.52 -    def netif_get_control_domain(self, dom):
    2.53 -        """Get the network interface backend control domain.
    2.54 -        """
    2.55 -        return self.netifCF.getControlDomain()
    2.56 -    
    2.57 -    def netif_create(self, dom, recreate=0, backend=0):
    2.58 +    def netif_create(self, dom, recreate=0):
    2.59          """Create a network interface controller.
    2.60          
    2.61          """
    2.62 -        return self.netifCF.createInstance(dom, recreate=recreate, backend=backend)
    2.63 +        return self.netifCF.createInstance(dom, recreate=recreate)
    2.64  
    2.65      def netifs(self):
    2.66          return [ x.sxpr() for x in self.netifCF.getInstances() ]
     3.1 --- a/tools/python/xen/xend/server/blkif.py	Wed Aug 18 13:07:07 2004 +0000
     3.2 +++ b/tools/python/xen/xend/server/blkif.py	Wed Aug 18 13:09:32 2004 +0000
     3.3 @@ -17,13 +17,19 @@ class BlkifBackendController(controller.
     3.4      """ Handler for the 'back-end' channel to a device driver domain.
     3.5      """
     3.6  
     3.7 -    def __init__(self, factory, dom):
     3.8 -        controller.BackendController.__init__(self, factory, dom)
     3.9 +    def __init__(self, ctrl, dom, handle):
    3.10 +        controller.BackendController.__init__(self, ctrl, dom, handle)
    3.11 +        self.connected = 0
    3.12 +        self.evtchn = None
    3.13 +        self.handle = handle
    3.14          self.addMethod(CMSG_BLKIF_BE,
    3.15                         CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED,
    3.16                         self.recv_be_driver_status_changed)
    3.17          self.registerChannel()
    3.18  
    3.19 +    def __str__(self):
    3.20 +        return '<BlkifBackendController %d %d>' % (self.controller.dom, self.dom)
    3.21 +
    3.22      def recv_be_driver_status_changed(self, msg, req):
    3.23          """Request handler for be_driver_status_changed messages.
    3.24          
    3.25 @@ -35,32 +41,109 @@ class BlkifBackendController(controller.
    3.26          val = unpackMsg('blkif_be_driver_status_changed_t', msg)
    3.27          status = val['status']
    3.28  
    3.29 -class BlkifControllerFactory(controller.SplitControllerFactory):
    3.30 +    def connect(self, recreate=0):
    3.31 +        """Connect the controller to the blkif control interface.
    3.32 +
    3.33 +        @param recreate: true if after xend restart
    3.34 +        @return: deferred
    3.35 +        """
    3.36 +        log.debug("Connecting blkif %s", str(self))
    3.37 +        if recreate or self.connected:
    3.38 +            d = defer.succeed(self)
    3.39 +        else:
    3.40 +            d = self.send_be_create()
    3.41 +            d.addCallback(self.respond_be_create)
    3.42 +        return d
    3.43 +        
    3.44 +    def send_be_create(self):
    3.45 +        d = defer.Deferred()
    3.46 +        msg = packMsg('blkif_be_create_t',
    3.47 +                      { 'domid'        : self.controller.dom,
    3.48 +                        'blkif_handle' : self.handle })
    3.49 +        self.writeRequest(msg, response=d)
    3.50 +        return d
    3.51 +
    3.52 +    def respond_be_create(self, msg):
    3.53 +        val = unpackMsg('blkif_be_create_t', msg)
    3.54 +        print 'respond_be_create>', val
    3.55 +        self.connected = 1
    3.56 +        return self
    3.57 +    
    3.58 +    def destroy(self):
    3.59 +        """Disconnect from the blkif control interface and destroy it.
    3.60 +        """
    3.61 +        def cb_destroy(val):
    3.62 +            self.send_be_destroy()
    3.63 +        d = defer.Deferred()
    3.64 +        d.addCallback(cb_destroy)
    3.65 +        self.send_be_disconnect(response=d)
    3.66 +        
    3.67 +    def send_be_disconnect(self, response=None):
    3.68 +        log.debug('>BlkifBackendController>send_be_disconnect> %s', str(self))
    3.69 +        msg = packMsg('blkif_be_disconnect_t',
    3.70 +                      { 'domid'        : self.controller.dom,
    3.71 +                        'blkif_handle' : self.handle })
    3.72 +        self.writeRequest(msg, response=response)
    3.73 +
    3.74 +    def send_be_destroy(self, response=None):
    3.75 +        log.debug('>BlkifBackendController>send_be_destroy> %s', str(self))
    3.76 +        msg = packMsg('blkif_be_destroy_t',
    3.77 +                      { 'domid'        : self.controller.dom,
    3.78 +                        'blkif_handle' : self.handle })
    3.79 +        self.writeRequest(msg, response=response)
    3.80 +
    3.81 +    def connectInterface(self, val):
    3.82 +        self.evtchn = channel.eventChannel(0, self.controller.dom)
    3.83 +        log.debug("Connecting blkif to event channel %s ports=%d:%d",
    3.84 +                  str(self), self.evtchn['port1'], self.evtchn['port2'])
    3.85 +        msg = packMsg('blkif_be_connect_t',
    3.86 +                      { 'domid'        : self.controller.dom,
    3.87 +                        'blkif_handle' : self.handle,
    3.88 +                        'evtchn'       : self.evtchn['port1'],
    3.89 +                        'shmem_frame'  : val['shmem_frame'] })
    3.90 +        d = defer.Deferred()
    3.91 +        d.addCallback(self.respond_be_connect)
    3.92 +        self.writeRequest(msg, response=d)
    3.93 +
    3.94 +    def respond_be_connect(self, msg):
    3.95 +        """Response handler for a be_connect message.
    3.96 +
    3.97 +        @param msg: message
    3.98 +        @type  msg: xu message
    3.99 +        """
   3.100 +        val = unpackMsg('blkif_be_connect_t', msg)
   3.101 +        print 'respond_be_connect>', str(self), val
   3.102 +        self.send_fe_interface_status_changed()
   3.103 +            
   3.104 +    def send_fe_interface_status_changed(self, response=None):
   3.105 +        msg = packMsg('blkif_fe_interface_status_changed_t',
   3.106 +                      { 'handle' : self.handle,
   3.107 +                        'status' : BLKIF_INTERFACE_STATUS_CONNECTED,
   3.108 +                        'evtchn' : self.evtchn['port2'] })
   3.109 +        self.controller.writeRequest(msg, response=response)
   3.110 +        
   3.111 +class BlkifControllerFactory(controller.ControllerFactory):
   3.112      """Factory for creating block device interface controllers.
   3.113      """
   3.114  
   3.115      def __init__(self):
   3.116 -        controller.SplitControllerFactory.__init__(self)
   3.117 +        controller.ControllerFactory.__init__(self)
   3.118  
   3.119 -    def createInstance(self, dom, recreate=0, backend=0):
   3.120 +    def createInstance(self, dom, recreate=0):
   3.121          """Create a block device controller for a domain.
   3.122  
   3.123          @param dom: domain
   3.124          @type  dom: int
   3.125          @param recreate: if true it's a recreate (after xend restart)
   3.126          @type  recreate: bool
   3.127 -        @return: deferred
   3.128 -        @rtype: twisted.internet.defer.Deferred
   3.129 +        @return: block device controller
   3.130 +        @rtype: BlkifController
   3.131          """
   3.132          blkif = self.getInstanceByDom(dom)
   3.133 -        if blkif:
   3.134 -            d = defer.Deferred()
   3.135 -            d.callback(blkif)
   3.136 -        else:
   3.137 -            blkif = BlkifController(self, dom, backend)
   3.138 +        if blkif is None:
   3.139 +            blkif = BlkifController(self, dom)
   3.140              self.addInstance(blkif)
   3.141 -            d = blkif.connect(recreate=recreate)
   3.142 -        return d
   3.143 +        return blkif
   3.144  
   3.145      def getDomainDevices(self, dom):
   3.146          """Get the block devices for a domain.
   3.147 @@ -86,15 +169,13 @@ class BlkifControllerFactory(controller.
   3.148          blkif = self.getInstanceByDom(dom)
   3.149          return (blkif and blkif.getDevice(vdev)) or None
   3.150  
   3.151 -    def createBackendController(self, dom):
   3.152 -        return BlkifBackendController(self, dom)
   3.153 -
   3.154 -class BlkDev(controller.Dev):
   3.155 +class BlkDev(controller.SplitDev):
   3.156      """Info record for a block device.
   3.157      """
   3.158  
   3.159 -    def __init__(self, ctrl, vdev, mode, segment):
   3.160 -        controller.Dev.__init__(self,  segment['device'], ctrl)
   3.161 +    def __init__(self, ctrl, config, vdev, mode, segment):
   3.162 +        controller.SplitDev.__init__(self,  segment['device'], ctrl)
   3.163 +        self.config = config
   3.164          self.dev = None
   3.165          self.uname = None
   3.166          self.vdev = vdev
   3.167 @@ -102,9 +183,10 @@ class BlkDev(controller.Dev):
   3.168          self.device = segment['device']
   3.169          self.start_sector = segment['start_sector']
   3.170          self.nr_sectors = segment['nr_sectors']
   3.171 -
   3.172 -    def getBackendController(self):
   3.173 -        return self.controller.backendController
   3.174 +        try:
   3.175 +            self.backendDomain = int(sxp.child_value(config, 'backend', '0'))
   3.176 +        except:
   3.177 +            raise XendError('invalid backend domain')
   3.178  
   3.179      def readonly(self):
   3.180          return 'w' not in self.mode
   3.181 @@ -125,77 +207,77 @@ class BlkDev(controller.Dev):
   3.182          log.debug("Destroying vbd domain=%d vdev=%d", self.controller.dom, self.vdev)
   3.183          self.send_be_vbd_destroy()
   3.184  
   3.185 -    def attach(self, d):
   3.186 +    def attach(self):
   3.187          """Attach the device to its controller.
   3.188  
   3.189 -        @param d: deferred to call with the device on success
   3.190          """
   3.191 -        d1 = defer.Deferred()
   3.192 -        d1.addCallback(self.respond_be_vbd_create, d)
   3.193 -        d1.addErrback(d.errback)
   3.194 -        self.send_be_vbd_create(response=d1)
   3.195 +        backend = self.getBackend()
   3.196 +        d1 = backend.connect()
   3.197 +        d2 = defer.Deferred()
   3.198 +        d2.addCallback(self.send_be_vbd_create)
   3.199 +        d1.chainDeferred(d2)
   3.200 +        return d2
   3.201          
   3.202 -    def send_be_vbd_create(self, response=None):
   3.203 +    def send_be_vbd_create(self, val):
   3.204 +        d = defer.Deferred()
   3.205 +        d.addCallback(self.respond_be_vbd_create)
   3.206 +        backend = self.getBackend()
   3.207          msg = packMsg('blkif_be_vbd_create_t',
   3.208                        { 'domid'        : self.controller.dom,
   3.209 -                        'blkif_handle' : self.controller.handle,
   3.210 +                        'blkif_handle' : backend.handle,
   3.211                          'vdevice'      : self.vdev,
   3.212                          'readonly'     : self.readonly() })
   3.213 -        self.getBackendController().writeRequest(msg, response=response)
   3.214 +        backend.writeRequest(msg, response=d)
   3.215 +        return d
   3.216          
   3.217 -    def respond_be_vbd_create(self, msg, d):
   3.218 +    def respond_be_vbd_create(self, msg):
   3.219          """Response handler for a be_vbd_create message.
   3.220          Tries to grow the vbd.
   3.221  
   3.222          @param msg: message
   3.223          @type  msg: xu message
   3.224 -        @param d: deferred to call
   3.225 -        @type  d: Deferred
   3.226          """
   3.227          val = unpackMsg('blkif_be_vbd_create_t', msg)
   3.228 -        d1 = defer.Deferred()
   3.229 -        d1.addCallback(self.respond_be_vbd_grow, d)
   3.230 -        if d: d1.addErrback(d.errback)
   3.231 -        self.send_be_vbd_grow(response=d1)
   3.232 +        d = self.send_be_vbd_grow()
   3.233 +        d.addCallback(self.respond_be_vbd_grow)
   3.234 +        return d
   3.235      
   3.236 -    def send_be_vbd_grow(self, response=None):
   3.237 +    def send_be_vbd_grow(self):
   3.238 +        d = defer.Deferred()
   3.239 +        backend = self.getBackend()
   3.240          msg = packMsg('blkif_be_vbd_grow_t',
   3.241                        { 'domid'                : self.controller.dom,
   3.242 -                        'blkif_handle'         : self.controller.handle,
   3.243 +                        'blkif_handle'         : backend.handle,
   3.244                          'vdevice'              : self.vdev,
   3.245                          'extent.device'        : self.device,
   3.246                          'extent.sector_start'  : self.start_sector,
   3.247                          'extent.sector_length' : self.nr_sectors })
   3.248 -        self.getBackendController().writeRequest(msg, response=response)
   3.249 +        backend.writeRequest(msg, response=d)
   3.250 +        return d
   3.251  
   3.252 -    def respond_be_vbd_grow(self, msg, d):
   3.253 +    def respond_be_vbd_grow(self, msg):
   3.254          """Response handler for a be_vbd_grow message.
   3.255  
   3.256          @param msg: message
   3.257          @type  msg: xu message
   3.258 -        @param d: deferred to call
   3.259 -        @type  d: Deferred or None
   3.260          """
   3.261          val = unpackMsg('blkif_be_vbd_grow_t', msg)
   3.262  	status = val['status']
   3.263  	if status != BLKIF_BE_STATUS_OKAY:
   3.264 -            err = XendError("Adding extent to vbd failed: device %d, error %d"
   3.265 +            raise XendError("Adding extent to vbd failed: device %d, error %d"
   3.266                              % (self.vdev, status))
   3.267 -            #if(d):
   3.268 -            #    d.errback(err)
   3.269 -            raise err
   3.270 -        if d:
   3.271 -            d.callback(self)
   3.272 +        return self
   3.273  
   3.274      def send_be_vbd_destroy(self, response=None):
   3.275          log.debug('>BlkDev>send_be_vbd_destroy> dom=%d vdev=%d',
   3.276                    self.controller.dom, self.vdev)
   3.277 +        backend = self.getBackend()
   3.278          msg = packMsg('blkif_be_vbd_destroy_t',
   3.279                        { 'domid'                : self.controller.dom,
   3.280 -                        'blkif_handle'         : self.controller.handle,
   3.281 +                        'blkif_handle'         : backend.handle,
   3.282                          'vdevice'              : self.vdev })
   3.283          self.controller.delDevice(self.vdev)
   3.284 -        self.getBackendController().writeRequest(msg, response=response)
   3.285 +        backend.writeRequest(msg, response=response)
   3.286          
   3.287          
   3.288  class BlkifController(controller.SplitController):
   3.289 @@ -203,12 +285,12 @@ class BlkifController(controller.SplitCo
   3.290      for a domain.
   3.291      """
   3.292      
   3.293 -    def __init__(self, factory, dom, backend):
   3.294 +    def __init__(self, factory, dom):
   3.295          """Create a block device controller.
   3.296          The controller must be connected using connect() before it can be used.
   3.297          Do not call directly - use createInstance() on the factory instead.
   3.298          """
   3.299 -        controller.SplitController.__init__(self, factory, dom, backend)
   3.300 +        controller.SplitController.__init__(self, factory, dom)
   3.301          self.devices = {}
   3.302          self.addMethod(CMSG_BLKIF_FE,
   3.303                         CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED,
   3.304 @@ -216,25 +298,22 @@ class BlkifController(controller.SplitCo
   3.305          self.addMethod(CMSG_BLKIF_FE,
   3.306                         CMSG_BLKIF_FE_INTERFACE_CONNECT,
   3.307                         self.recv_fe_interface_connect)
   3.308 -        self.handle = 0
   3.309 -        self.evtchn = None
   3.310          self.registerChannel()
   3.311  
   3.312      def sxpr(self):
   3.313          val = ['blkif', ['dom', self.dom]]
   3.314 -        if self.evtchn:
   3.315 -            val.append(['evtchn',
   3.316 -                        self.evtchn['port1'],
   3.317 -                        self.evtchn['port2']])
   3.318          return val
   3.319  
   3.320 +    def createBackend(self, dom, handle):
   3.321 +        return BlkifBackendController(self, dom, handle)
   3.322 +
   3.323      def getDevices(self):
   3.324          return self.devices.values()
   3.325  
   3.326      def getDevice(self, vdev):
   3.327          return self.devices.get(vdev)
   3.328  
   3.329 -    def addDevice(self, vdev, mode, segment):
   3.330 +    def addDevice(self, config, vdev, mode, segment):
   3.331          """Add a device to the device table.
   3.332  
   3.333          @param vdev:     device index
   3.334 @@ -246,8 +325,9 @@ class BlkifController(controller.SplitCo
   3.335          @return: device
   3.336          @rtype:  BlkDev
   3.337          """
   3.338 -        if vdev in self.devices: return None
   3.339 -        dev = BlkDev(self, vdev, mode, segment)
   3.340 +        if vdev in self.devices:
   3.341 +            raise XendError('device exists: ' + str(vdev))
   3.342 +        dev = BlkDev(self, config, vdev, mode, segment)
   3.343          self.devices[vdev] = dev
   3.344          return dev
   3.345  
   3.346 @@ -255,7 +335,7 @@ class BlkifController(controller.SplitCo
   3.347          if vdev in self.devices:
   3.348              del self.devices[vdev]
   3.349  
   3.350 -    def attachDevice(self, vdev, mode, segment, recreate=0):
   3.351 +    def attachDevice(self, config, vdev, mode, segment, recreate=0):
   3.352          """Attach a device to the specified interface.
   3.353          On success the returned deferred will be called with the device.
   3.354  
   3.355 @@ -270,13 +350,11 @@ class BlkifController(controller.SplitCo
   3.356          @return: deferred
   3.357          @rtype:  Deferred
   3.358          """
   3.359 -        dev = self.addDevice(vdev, mode, segment)
   3.360 -        if not dev: return -1
   3.361 -        d = defer.Deferred()
   3.362 +        dev = self.addDevice(config, vdev, mode, segment)
   3.363          if recreate:
   3.364 -            d.callback(dev)
   3.365 +            d = defer.succeed(dev)
   3.366          else:
   3.367 -            dev.attach(d)
   3.368 +            d = dev.attach()
   3.369          return d
   3.370  
   3.371      def destroy(self):
   3.372 @@ -284,7 +362,7 @@ class BlkifController(controller.SplitCo
   3.373          """
   3.374          log.debug("Destroying blkif domain=%d", self.dom)
   3.375          self.destroyDevices()
   3.376 -        self.disconnect()
   3.377 +        self.destroyBackends()
   3.378  
   3.379      def destroyDevices(self):
   3.380          """Destroy all devices.
   3.381 @@ -292,87 +370,28 @@ class BlkifController(controller.SplitCo
   3.382          for dev in self.getDevices():
   3.383              dev.destroy()
   3.384  
   3.385 -    def connect(self, recreate=0):
   3.386 -        """Connect the controller to the blkif control interface.
   3.387 +    def destroyBackends(self):
   3.388 +        for backend in self.getBackends():
   3.389 +            backend.destroy()
   3.390  
   3.391 -        @param recreate: true if after xend restart
   3.392 -        @return: deferred
   3.393 -        """
   3.394 -        log.debug("Connecting blkif domain=%d", self.dom)
   3.395 -        d = defer.Deferred()
   3.396 -        if recreate:
   3.397 -            d.callback(self)
   3.398 -        else:
   3.399 -            def cbresp(msg):
   3.400 -                return self
   3.401 -            d.addCallback(cbresp)
   3.402 -            self.send_be_create(response=d)
   3.403 -        return d
   3.404 -        
   3.405 -    def send_be_create(self, response=None):
   3.406 -        msg = packMsg('blkif_be_create_t',
   3.407 -                      { 'domid'        : self.dom,
   3.408 -                        'blkif_handle' : self.handle })
   3.409 -        self.backendController.writeRequest(msg, response=response)
   3.410 -    
   3.411 -    def disconnect(self):
   3.412 -        """Disconnect from the blkif control interface and destroy it.
   3.413 -        """
   3.414 -        def cb_destroy(val):
   3.415 -            self.send_be_destroy()
   3.416 -        d = defer.Deferred()
   3.417 -        d.addCallback(cb_destroy)
   3.418 -        self.send_be_disconnect(response=d)
   3.419 -        
   3.420 -    def send_be_disconnect(self, response=None):
   3.421 -        log.debug('>BlkifController>send_be_disconnect> dom=%d', self.dom)
   3.422 -        msg = packMsg('blkif_be_disconnect_t',
   3.423 -                      { 'domid'        : self.dom,
   3.424 -                        'blkif_handle' : self.handle })
   3.425 -        self.backendController.writeRequest(msg, response=response)
   3.426 -
   3.427 -    def send_be_destroy(self, response=None):
   3.428 -        log.debug('>BlkifController>send_be_destroy> dom=%d', self.dom)
   3.429 -        msg = packMsg('blkif_be_destroy_t',
   3.430 -                      { 'domid'        : self.dom,
   3.431 -                        'blkif_handle' : self.handle })
   3.432 -        self.backendController.writeRequest(msg, response=response)
   3.433 -        
   3.434      def recv_fe_driver_status_changed(self, msg, req):
   3.435 +        val = unpackMsg('blkif_fe_driver_status_changed_t', msg)
   3.436 +        print 'recv_fe_driver_status_changed>', val
   3.437 +        # For each backend?
   3.438          msg = packMsg('blkif_fe_interface_status_changed_t',
   3.439 -                      { 'handle' : self.handle,
   3.440 +                      { 'handle' : 0,
   3.441                          'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED,
   3.442                          'evtchn' : 0 })
   3.443          self.writeRequest(msg)
   3.444  
   3.445      def recv_fe_interface_connect(self, msg, req):
   3.446          val = unpackMsg('blkif_fe_interface_connect_t', msg)
   3.447 -        self.evtchn = channel.eventChannel(0, self.dom)
   3.448 -        log.debug("Connecting blkif to event channel dom=%d ports=%d:%d",
   3.449 -                  self.dom, self.evtchn['port1'], self.evtchn['port2'])
   3.450 -        msg = packMsg('blkif_be_connect_t',
   3.451 -                      { 'domid'        : self.dom,
   3.452 -                        'blkif_handle' : val['handle'],
   3.453 -                        'evtchn'       : self.evtchn['port1'],
   3.454 -                        'shmem_frame'  : val['shmem_frame'] })
   3.455 -        d = defer.Deferred()
   3.456 -        d.addCallback(self.respond_be_connect)
   3.457 -        self.backendController.writeRequest(msg, response=d)
   3.458 +        handle = val['handle']
   3.459 +        backend = self.getBackendByHandle(handle)
   3.460 +        if backend:
   3.461 +            backend.connectInterface(val)
   3.462 +        else:
   3.463 +            log.error('interface connect on unknown interface: handle=%d', handle)
   3.464  
   3.465 -    def respond_be_connect(self, msg):
   3.466 -        """Response handler for a be_connect message.
   3.467 -
   3.468 -        @param msg: message
   3.469 -        @type  msg: xu message
   3.470 -        """
   3.471 -        val = unpackMsg('blkif_be_connect_t', msg)
   3.472 -        self.send_fe_interface_status_changed()
   3.473 -            
   3.474 -    def send_fe_interface_status_changed(self, response=None):
   3.475 -        msg = packMsg('blkif_fe_interface_status_changed_t',
   3.476 -                      { 'handle' : self.handle,
   3.477 -                        'status' : BLKIF_INTERFACE_STATUS_CONNECTED,
   3.478 -                        'evtchn' : self.evtchn['port2'] })
   3.479 -        self.writeRequest(msg, response=response)
   3.480      
   3.481  
     4.1 --- a/tools/python/xen/xend/server/controller.py	Wed Aug 18 13:07:07 2004 +0000
     4.2 +++ b/tools/python/xen/xend/server/controller.py	Wed Aug 18 13:09:32 2004 +0000
     4.3 @@ -372,51 +372,78 @@ class Controller(CtrlMsgRcvr):
     4.4          self.deregisterChannel()
     4.5          self.factory.instanceClosed(self)
     4.6  
     4.7 -class SplitControllerFactory(ControllerFactory):
     4.8 -    """Factory for SplitControllers.
     4.9 +class BackendController(CtrlMsgRcvr):
    4.10 +    """Abstract class for a backend device controller attached to a domain.
    4.11 +
    4.12 +    @ivar controller: frontend controller
    4.13 +    @type controller: Controller
    4.14 +    @ivar dom:     domain
    4.15 +    @type dom:     int
    4.16 +    @ivar channel: channel to the domain
    4.17 +    @type channel: Channel
    4.18 +    """
    4.19 +
    4.20      
    4.21 -    @ivar backends:  mapping of domain id to backend
    4.22 -    @type backends:  {int: BackendController}
    4.23 -    """
    4.24 -    
    4.25 -    def __init__(self):
    4.26 -        ControllerFactory.__init__(self)
    4.27 -        self.backends = {}
    4.28 +    def __init__(self, controller, dom, handle):
    4.29 +        CtrlMsgRcvr.__init__(self)
    4.30 +        self.controller = controller
    4.31 +        self.dom = int(dom)
    4.32 +        self.handle = handle
    4.33 +        self.channel = None
    4.34 +        
    4.35 +    def close(self):
    4.36 +        self.lostChannel()
    4.37  
    4.38 -    def createInstance(self, dom, recreate=0, backend=0):
    4.39 -        """Create an instance. Define in a subclass.
    4.40 +    def lostChannel(self):
    4.41 +        self.deregisterChannel()
    4.42 +        self.controller.backendClosed(self)
    4.43 +        
    4.44 +class SplitController(Controller):
    4.45 +    """Abstract class for a device controller attached to a domain.
    4.46 +    A SplitController manages a BackendController for each backend domain
    4.47 +    it has at least one device for.
    4.48 +    """
    4.49  
    4.50 -        @param dom: domain
    4.51 -        @type  dom: int
    4.52 -        @param recreate: true if the instance is being recreated (after xend restart)
    4.53 -        @type  recreate: int
    4.54 -        @param backend: backend domain
    4.55 -        @type  backend: int
    4.56 -        @return: controller instance
    4.57 -        @rtype:  SplitController (or subclass)
    4.58 -        """
    4.59 -        raise NotImplementedError()
    4.60 +    def __init__(self, factory, dom):
    4.61 +        Controller.__init__(self, factory, dom)
    4.62 +        self.backends = {}
    4.63 +        self.backendHandle = 0
    4.64          
    4.65 -    def getBackendController(self, dom):
    4.66 +    def getBackends(self):
    4.67 +        return self.backends.values()
    4.68 +
    4.69 +    def getBackendByHandle(self, handle):
    4.70 +        for b in self.getBackends():
    4.71 +            if b.handle == handle:
    4.72 +                return b
    4.73 +        return None
    4.74 +
    4.75 +    def getBackendByDomain(self, dom):
    4.76 +        return self.backends.get(dom)
    4.77 +
    4.78 +    def getBackend(self, dom):
    4.79          """Get the backend controller for a domain.
    4.80  
    4.81          @param dom: domain
    4.82          @return: backend controller
    4.83          """
    4.84 -        ctrlr = self.backends.get(dom)
    4.85 -        if ctrlr is None:
    4.86 -            ctrlr = self.createBackendController(dom)
    4.87 -            self.backends[dom] = ctrlr
    4.88 -        return ctrlr
    4.89 +        b = self.getBackendByDomain(dom)
    4.90 +        if b is None:
    4.91 +            handle = self.backendHandle
    4.92 +            self.backendHandle += 1
    4.93 +            b = self.createBackend(dom, handle)
    4.94 +            self.backends[b.dom] = b
    4.95 +        return b
    4.96  
    4.97 -    def createBackendController(self, dom):
    4.98 +    def createBackend(self, dom, handle):
    4.99          """Create a backend controller. Define in a subclass.
   4.100  
   4.101          @param dom: domain
   4.102 +        @param handle: controller handle
   4.103          """
   4.104          raise NotImplementedError()
   4.105  
   4.106 -    def delBackendController(self, ctrlr):
   4.107 +    def delBackend(self, ctrlr):
   4.108          """Remove a backend controller.
   4.109  
   4.110          @param ctrlr: backend controller
   4.111 @@ -424,59 +451,11 @@ class SplitControllerFactory(ControllerF
   4.112          if ctrlr.dom in self.backends:
   4.113              del self.backends[ctrlr.dom]
   4.114  
   4.115 -    def backendControllerClosed(self, ctrlr):
   4.116 +    def backendClosed(self, ctrlr):
   4.117          """Callback called when a backend is closed.
   4.118          """
   4.119 -        self.delBackendController(ctrlr)
   4.120 -
   4.121 -class BackendController(CtrlMsgRcvr):
   4.122 -    """Abstract class for a backend device controller attached to a domain.
   4.123 -
   4.124 -    @ivar factory: controller factory
   4.125 -    @type factory: ControllerFactory
   4.126 -    @ivar dom:     domain
   4.127 -    @type dom:     int
   4.128 -    @ivar channel: channel to the domain
   4.129 -    @type channel: Channel
   4.130 -    """
   4.131 -
   4.132 -    
   4.133 -    def __init__(self, factory, dom):
   4.134 -        CtrlMsgRcvr.__init__(self)
   4.135 -        self.factory = factory
   4.136 -        self.dom = int(dom)
   4.137 -        self.channel = None
   4.138 +        self.delBackend(ctrlr)
   4.139          
   4.140 -    def close(self):
   4.141 -        self.lostChannel()
   4.142 -
   4.143 -    def lostChannel(self):
   4.144 -        self.deregisterChannel()
   4.145 -        self.factory.instanceClosed(self)
   4.146 -
   4.147 -
   4.148 -class SplitController(Controller):
   4.149 -    """Abstract class for a device controller attached to a domain.
   4.150 -    A SplitController has a BackendContoller.
   4.151 -    """
   4.152 -
   4.153 -    def __init__(self, factory, dom, backend):
   4.154 -        Controller.__init__(self, factory, dom)
   4.155 -        self.backendDomain = None
   4.156 -        self.backendController = None
   4.157 -        self.setBackendDomain(backend)
   4.158 -        
   4.159 -    def setBackendDomain(self, dom):
   4.160 -        ctrlr = self.factory.getBackendController(dom)
   4.161 -        self.backendDomain = ctrlr.dom
   4.162 -        self.backendController = ctrlr
   4.163 -
   4.164 -    def getBackendDomain(self):
   4.165 -        return self.backendDomain
   4.166 -
   4.167 -    def getBackendController(self):
   4.168 -        return self.backendController
   4.169 -
   4.170  class Dev:
   4.171      """Abstract class for a device attached to a device controller.
   4.172  
   4.173 @@ -517,4 +496,15 @@ class Dev:
   4.174          """
   4.175          raise NotImplementedError()
   4.176  
   4.177 +class SplitDev(Dev):
   4.178 +
   4.179 +    def __init__(self, idx, controller):
   4.180 +        Dev.__init__(self, idx, controller)
   4.181 +        self.backendDomain = 0
   4.182 +
   4.183 +    def getBackend(self):
   4.184 +        return self.controller.getBackend(self.backendDomain)
   4.185 +
   4.186 +
   4.187 +
   4.188      
     5.1 --- a/tools/python/xen/xend/server/netif.py	Wed Aug 18 13:07:07 2004 +0000
     5.2 +++ b/tools/python/xen/xend/server/netif.py	Wed Aug 18 13:09:32 2004 +0000
     5.3 @@ -22,8 +22,8 @@ class NetifBackendController(controller.
     5.4      """Handler for the 'back-end' channel to a device driver domain.
     5.5      """
     5.6      
     5.7 -    def __init__(self, factory, dom):
     5.8 -        controller.BackendController.__init__(self, factory, dom)
     5.9 +    def __init__(self, ctrl, dom, handle):
    5.10 +        controller.BackendController.__init__(self, ctrl, dom, handle)
    5.11          self.addMethod(CMSG_NETIF_BE,
    5.12                         CMSG_NETIF_BE_DRIVER_STATUS_CHANGED,
    5.13                         self.recv_be_driver_status_changed)
    5.14 @@ -33,14 +33,14 @@ class NetifBackendController(controller.
    5.15          val = unpackMsg('netif_be_driver_status_changed_t', msg)
    5.16          status = val['status']
    5.17  
    5.18 -class NetifControllerFactory(controller.SplitControllerFactory):
    5.19 +class NetifControllerFactory(controller.ControllerFactory):
    5.20      """Factory for creating network interface controllers.
    5.21      """
    5.22  
    5.23      def __init__(self):
    5.24          controller.ControllerFactory.__init__(self)
    5.25  
    5.26 -    def createInstance(self, dom, recreate=0, backend=0):
    5.27 +    def createInstance(self, dom, recreate=0):
    5.28          """Create or find the network interface controller for a domain.
    5.29  
    5.30          @param dom:      domain
    5.31 @@ -49,7 +49,7 @@ class NetifControllerFactory(controller.
    5.32          """
    5.33          netif = self.getInstanceByDom(dom)
    5.34          if netif is None:
    5.35 -            netif = NetifController(self, dom, backend=backend)
    5.36 +            netif = NetifController(self, dom)
    5.37              self.addInstance(netif)
    5.38          return netif
    5.39  
    5.40 @@ -72,22 +72,16 @@ class NetifControllerFactory(controller.
    5.41          netif = self.getInstanceByDom(dom)
    5.42          return (netif and netif.getDevice(vif)) or None
    5.43          
    5.44 -    def createBackendController(self, dom):
    5.45 -        return NetifBackendController(self, dom)
    5.46 -
    5.47 -class NetDev(controller.Dev):
    5.48 +class NetDev(controller.SplitDev):
    5.49      """Info record for a network device.
    5.50      """
    5.51  
    5.52      def __init__(self, ctrl, vif, config):
    5.53 -        controller.Dev.__init__(self, vif, ctrl)
    5.54 +        controller.SplitDev.__init__(self, vif, ctrl)
    5.55          self.vif = vif
    5.56          self.evtchn = None
    5.57          self.configure(config)
    5.58  
    5.59 -    def getBackendController(self):
    5.60 -        return self.controller.backendController
    5.61 -
    5.62      def configure(self, config):
    5.63          self.config = config
    5.64          self.mac = None
    5.65 @@ -108,6 +102,11 @@ class NetDev(controller.Dev):
    5.66          for ipaddr in ipaddrs:
    5.67              self.ipaddr.append(sxp.child0(ipaddr))
    5.68          
    5.69 +        try:
    5.70 +            self.backendDomain = int(sxp.child_value(config, 'backend', '0'))
    5.71 +        except:
    5.72 +            raise XendError('invalid backend domain')
    5.73 +
    5.74      def sxpr(self):
    5.75          vif = str(self.vif)
    5.76          mac = self.get_mac()
    5.77 @@ -168,16 +167,25 @@ class NetDev(controller.Dev):
    5.78          if vnet:
    5.79              vnet.vifctl(op, self.get_vifname(), self.get_mac())
    5.80  
    5.81 -    def attach(self, d):
    5.82 -        print 'attach>', d
    5.83 -        self.send_be_create(response=d)
    5.84 +    def attach(self):
    5.85 +        print 'attach>'
    5.86 +        d = self.send_be_create()
    5.87 +        d.addCallback(self.respond_be_create)
    5.88 +        return d
    5.89  
    5.90 -    def send_be_create(self, response=None):
    5.91 +    def send_be_create(self):
    5.92 +        d = defer.Deferred()
    5.93          msg = packMsg('netif_be_create_t',
    5.94                        { 'domid'        : self.controller.dom,
    5.95                          'netif_handle' : self.vif,
    5.96                          'mac'          : self.mac })
    5.97 -        self.getBackendController().writeRequest(msg, response=response)
    5.98 +        self.getBackend().writeRequest(msg, response=d)
    5.99 +        return d
   5.100 +
   5.101 +    def respond_be_create(self, msg):
   5.102 +        val = unpackMsg('netif_be_create_t', msg)
   5.103 +        print 'respond_be_create>', val
   5.104 +        return self
   5.105  
   5.106      def destroy(self):
   5.107          """Destroy the device's resources and disconnect from the back-end
   5.108 @@ -187,22 +195,23 @@ class NetDev(controller.Dev):
   5.109              self.send_be_destroy()
   5.110          log.debug("Destroying vif domain=%d vif=%d", self.controller.dom, self.vif)
   5.111          self.vifctl('down')
   5.112 -        d = defer.Deferred()
   5.113 +        d = self.send_be_disconnect()
   5.114          d.addCallback(cb_destroy)
   5.115 -        self.send_be_disconnect(response=d)
   5.116  
   5.117 -    def send_be_disconnect(self, response=None):
   5.118 +    def send_be_disconnect(self):
   5.119 +        d = defer.Deferred()
   5.120          msg = packMsg('netif_be_disconnect_t',
   5.121                        { 'domid'        : self.controller.dom,
   5.122                          'netif_handle' : self.vif })
   5.123 -        self.getBackendController().writeRequest(msg, response=response)
   5.124 +        self.getBackend().writeRequest(msg, response=d)
   5.125 +        return d
   5.126  
   5.127      def send_be_destroy(self, response=None):
   5.128          msg = packMsg('netif_be_destroy_t',
   5.129                        { 'domid'        : self.controller.dom,
   5.130                          'netif_handle' : self.vif })
   5.131          self.controller.delDevice(self.vif)
   5.132 -        self.getBackendController().writeRequest(msg, response=response)
   5.133 +        self.getBackend().writeRequest(msg, response=response)
   5.134      
   5.135      def recv_fe_interface_connect(self, val, req):
   5.136          if not req: return
   5.137 @@ -215,14 +224,12 @@ class NetDev(controller.Dev):
   5.138                          'rx_shmem_frame' : val['rx_shmem_frame'] })
   5.139          d = defer.Deferred()
   5.140          d.addCallback(self.respond_be_connect)
   5.141 -        self.getBackendController().writeRequest(msg, response=d)
   5.142 +        self.getBackend().writeRequest(msg, response=d)
   5.143          
   5.144      def respond_be_connect(self, msg):
   5.145          val = unpackMsg('netif_be_connect_t', msg)
   5.146          dom = val['domid']
   5.147          vif = val['netif_handle']
   5.148 -        print 'respond_be_connect>', '     dom=', dom, '     vif=', vif
   5.149 -        print 'respond_be_connect>', 'self.dom=', self.controller.dom, 'self.vif=', self.vif
   5.150          msg = packMsg('netif_fe_interface_status_changed_t',
   5.151                        { 'handle' : self.vif,
   5.152                          'status' : NETIF_INTERFACE_STATUS_CONNECTED,
   5.153 @@ -242,8 +249,8 @@ class NetifController(controller.SplitCo
   5.154      """Network interface controller. Handles all network devices for a domain.
   5.155      """
   5.156      
   5.157 -    def __init__(self, factory, dom, backend):
   5.158 -        controller.SplitController.__init__(self, factory, dom, backend)
   5.159 +    def __init__(self, factory, dom):
   5.160 +        controller.SplitController.__init__(self, factory, dom)
   5.161          self.devices = {}
   5.162          self.addMethod(CMSG_NETIF_FE,
   5.163                         CMSG_NETIF_FE_DRIVER_STATUS_CHANGED,
   5.164 @@ -253,6 +260,9 @@ class NetifController(controller.SplitCo
   5.165                         self.recv_fe_interface_connect)
   5.166          self.registerChannel()
   5.167  
   5.168 +    def createBackend(self, dom, handle):
   5.169 +        return NetifBackendController(self, dom, handle)
   5.170 +
   5.171      def sxpr(self):
   5.172          val = ['netif', ['dom', self.dom]]
   5.173          return val
   5.174 @@ -282,6 +292,8 @@ class NetifController(controller.SplitCo
   5.175          @param config: device configuration 
   5.176          @return: device
   5.177          """
   5.178 +        if vif in self.devices:
   5.179 +            raise XendError('device exists:' + str(vif))
   5.180          dev = NetDev(self, vif, config)
   5.181          self.devices[vif] = dev
   5.182          return dev
   5.183 @@ -310,11 +322,10 @@ class NetifController(controller.SplitCo
   5.184          @return: deferred
   5.185          """
   5.186          dev = self.addDevice(vif, config)
   5.187 -        d = defer.Deferred()
   5.188          if recreate:
   5.189 -            d.callback(self)
   5.190 +            d = defer.succeed(dev)
   5.191          else:
   5.192 -            dev.attach(d)
   5.193 +            d = dev.attach()
   5.194          return d
   5.195  
   5.196      def recv_fe_driver_status_changed(self, msg, req):
   5.197 @@ -333,5 +344,6 @@ class NetifController(controller.SplitCo
   5.198          if dev:
   5.199              dev.recv_fe_interface_connect(val, req)
   5.200          else:
   5.201 -            log.error('Received netif_fe_interface_connect for unknown vif: '+vif)
   5.202 +            log.error('Received netif_fe_interface_connect for unknown vif: dom=%d vif=%d',
   5.203 +                      self.dom, vif)
   5.204  
     6.1 --- a/tools/python/xen/xm/create.py	Wed Aug 18 13:07:07 2004 +0000
     6.2 +++ b/tools/python/xen/xm/create.py	Wed Aug 18 13:09:32 2004 +0000
     6.3 @@ -126,19 +126,12 @@ gopts.var('netif', val='no|yes',
     6.4            fn=set_bool, default=0,
     6.5            use="Make the domain a network interface backend.")
     6.6  
     6.7 -gopts.var('vbd_backend', val='DOM',
     6.8 -          fn=set_value, default=None,
     6.9 -          use='Set the domain to use for the vbd backend.')
    6.10 -
    6.11 -gopts.var('vif_backend', val='DOM',
    6.12 -          fn=set_value, default=None,
    6.13 -          use='Set the domain to use for the vif backend.')
    6.14 -
    6.15 -gopts.var('disk', val='phy:DEV,VDEV,MODE',
    6.16 +gopts.var('disk', val='phy:DEV,VDEV,MODE[,DOM]',
    6.17            fn=append_value, default=[],
    6.18            use="""Add a disk device to a domain. The physical device is DEV,
    6.19           which is exported to the domain as VDEV. The disk is read-only if MODE
    6.20 -         is 'r', read-write if MODE is 'w'.
    6.21 +         is 'r', read-write if MODE is 'w'. If DOM is specified it defines the
    6.22 +         backend driver domain to use for the disk.
    6.23           The option may be repeated to add more than one disk.
    6.24           """)
    6.25  
    6.26 @@ -153,13 +146,14 @@ gopts.var('ipaddr', val="IPADDR",
    6.27            fn=append_value, default=[],
    6.28            use="Add an IP address to the domain.")
    6.29  
    6.30 -gopts.var('vif', val="mac=MAC,bridge=BRIDGE,script=SCRIPT",
    6.31 +gopts.var('vif', val="mac=MAC,bridge=BRIDGE,script=SCRIPT,backend=DOM",
    6.32            fn=append_value, default=[],
    6.33            use="""Add a network interface with the given MAC address and bridge.
    6.34           The vif is configured by calling the given configuration script.
    6.35           If mac is not specified a random MAC address is used.
    6.36           If bridge is not specified the default bridge is used.
    6.37           If script is not specified the default script is used.
    6.38 +         If backend is not specified the default backend driver domain is used.
    6.39           This option may be repeated to add more than one vif.
    6.40           Specifying vifs will increase the number of interfaces as needed.
    6.41           """)
    6.42 @@ -241,11 +235,13 @@ def configure_image(config, vals):
    6.43  def configure_disks(config_devs, vals):
    6.44      """Create the config for disks (virtual block devices).
    6.45      """
    6.46 -    for (uname, dev, mode) in vals.disk:
    6.47 +    for (uname, dev, mode, backend) in vals.disk:
    6.48          config_vbd = ['vbd',
    6.49                        ['uname', uname],
    6.50                        ['dev', dev ],
    6.51                        ['mode', mode ] ]
    6.52 +        if backend:
    6.53 +            config_vbd.append(['backend', backend])
    6.54          config_devs.append(['device', config_vbd])
    6.55  
    6.56  def configure_pci(config_devs, vals):
    6.57 @@ -285,16 +281,20 @@ def configure_vifs(config_devs, vals):
    6.58              mac = d.get('mac')
    6.59              bridge = d.get('bridge')
    6.60              script = d.get('script')
    6.61 +            backend = d.get('backend')
    6.62          else:
    6.63              mac = randomMAC()
    6.64              bridge = None
    6.65              script = None
    6.66 +            backend = None
    6.67          config_vif = ['vif']
    6.68          config_vif.append(['mac', mac])
    6.69          if bridge:
    6.70              config_vif.append(['bridge', bridge])
    6.71          if script:
    6.72              config_vif.append(['script', script])
    6.73 +        if backend:
    6.74 +            config_vif.append(['backend', backend])
    6.75          config_devs.append(['device', config_vif])
    6.76  
    6.77  def configure_vfr(config, vals):
    6.78 @@ -320,10 +320,6 @@ def make_config(vals):
    6.79          config.append(['backend', ['blkif']])
    6.80      if vals.netif:
    6.81          config.append(['backend', ['netif']])
    6.82 -    if vals.vbd_backend:
    6.83 -        config.append(['backend', ['vbd', ['dom', vals.vbd_backend]]])
    6.84 -    if vals.vif_backend:
    6.85 -        config.append(['backend', ['vif', ['dom', vals.vif_backend]]])
    6.86      if vals.restart:
    6.87          config.append(['restart', vals.restart])
    6.88      if vals.console:
    6.89 @@ -342,7 +338,12 @@ def preprocess_disk(opts, vals):
    6.90      disk = []
    6.91      for v in vals.disk:
    6.92          d = v.split(',')
    6.93 -        if len(d) != 3:
    6.94 +        n = len(d)
    6.95 +        if n == 3:
    6.96 +            d.append(none)
    6.97 +        elif n == 4:
    6.98 +            pass
    6.99 +        else:
   6.100              opts.err('Invalid disk specifier: ' + v)
   6.101          disk.append(d)
   6.102      vals.disk = disk
   6.103 @@ -369,7 +370,7 @@ def preprocess_vifs(opts, vals):
   6.104              (k, v) = b.strip().split('=', 1)
   6.105              k = k.strip()
   6.106              v = v.strip()
   6.107 -            if k not in ['mac', 'bridge']:
   6.108 +            if k not in ['mac', 'bridge', 'script', 'backend']:
   6.109                  opts.err('Invalid vif specifier: ' + vif)
   6.110              d[k] = v
   6.111          vifs.append(d)