direct-io.hg

changeset 2271:703b333dc90c

bitkeeper revision 1.1159.37.2 (41235cfbTT69HLcXLIBHgkcsv8UcGg)

Merge xenbk@gandalf:/var/bk/xeno-unstable.bk
into wray-m-3.hpl.hp.com:/home/mjw/repos-bk/xeno-unstable.bk
author mjw@wray-m-3.hpl.hp.com
date Wed Aug 18 13:43:23 2004 +0000 (2004-08-18)
parents 0dd4b96ce798 3974feb63b14
children 4851d48567fe
files tools/python/xen/lowlevel/xu/xu.c tools/python/xen/xend/XendClient.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/XendMigrate.py tools/python/xen/xend/server/SrvDaemon.py tools/python/xen/xend/server/SrvDomain.py tools/python/xen/xend/server/blkif.py tools/python/xen/xend/server/channel.py tools/python/xen/xend/server/controller.py tools/python/xen/xend/server/messages.py tools/python/xen/xend/server/netif.py tools/python/xen/xm/create.py tools/python/xen/xm/main.py tools/python/xen/xm/migrate.py tools/xfrd/xen_domain.c tools/xfrd/xen_domain.h tools/xfrd/xfrd.c
line diff
     1.1 --- a/tools/python/xen/lowlevel/xu/xu.c	Tue Aug 17 17:54:50 2004 +0000
     1.2 +++ b/tools/python/xen/lowlevel/xu/xu.c	Wed Aug 18 13:43:23 2004 +0000
     1.3 @@ -426,6 +426,12 @@ static PyObject *xu_message_get_payload(
     1.4          C2P(netif_fe_interface_status_changed_t, handle, Int, Long);
     1.5          C2P(netif_fe_interface_status_changed_t, status, Int, Long);
     1.6          C2P(netif_fe_interface_status_changed_t, evtchn, Int, Long);
     1.7 +        C2P(netif_fe_interface_status_changed_t, mac[0], Int, Long);
     1.8 +        C2P(netif_fe_interface_status_changed_t, mac[1], Int, Long);
     1.9 +        C2P(netif_fe_interface_status_changed_t, mac[2], Int, Long);
    1.10 +        C2P(netif_fe_interface_status_changed_t, mac[3], Int, Long);
    1.11 +        C2P(netif_fe_interface_status_changed_t, mac[4], Int, Long);
    1.12 +        C2P(netif_fe_interface_status_changed_t, mac[5], Int, Long);
    1.13          return dict;
    1.14      case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
    1.15          C2P(netif_fe_driver_status_changed_t, status,        Int, Long);
     2.1 --- a/tools/python/xen/xend/XendClient.py	Tue Aug 17 17:54:50 2004 +0000
     2.2 +++ b/tools/python/xen/xend/XendClient.py	Wed Aug 18 13:43:23 2004 +0000
     2.3 @@ -480,10 +480,11 @@ class Xend:
     2.4                               {'op'      : 'save',
     2.5                                'file'    : filename })
     2.6  
     2.7 -    def xend_domain_migrate(self, id, dst):
     2.8 +    def xend_domain_migrate(self, id, dst, live=0):
     2.9          return self.xendPost(self.domainurl(id),
    2.10 -                             {'op'      : 'migrate',
    2.11 -                              'destination': dst })
    2.12 +                             {'op'         : 'migrate',
    2.13 +                              'destination': dst,
    2.14 +                              'live'       : live })
    2.15  
    2.16      def xend_domain_pincpu(self, id, cpu):
    2.17          return self.xendPost(self.domainurl(id),
     3.1 --- a/tools/python/xen/xend/XendDomain.py	Tue Aug 17 17:54:50 2004 +0000
     3.2 +++ b/tools/python/xen/xend/XendDomain.py	Wed Aug 18 13:43:23 2004 +0000
     3.3 @@ -586,7 +586,7 @@ class XendDomain:
     3.4          self.refresh_schedule()
     3.5          return val
     3.6  
     3.7 -    def domain_migrate(self, id, dst):
     3.8 +    def domain_migrate(self, id, dst, live):
     3.9          """Start domain migration.
    3.10  
    3.11          @param id: domain id
    3.12 @@ -597,7 +597,7 @@ class XendDomain:
    3.13          print 'domain_migrate>', id, dst
    3.14          dominfo = self.domain_lookup(id)
    3.15          xmigrate = XendMigrate.instance()
    3.16 -        val = xmigrate.migrate_begin(dominfo.id, dst)
    3.17 +        val = xmigrate.migrate_begin(dominfo.id, dst, live=live)
    3.18          print 'domain_migrate<', val
    3.19          return val
    3.20  
     4.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Tue Aug 17 17:54:50 2004 +0000
     4.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Wed Aug 18 13:43:23 2004 +0000
     4.3 @@ -137,7 +137,7 @@ def lookup_disk_uname(uname):
     4.4          segments = None
     4.5      return segments
     4.6  
     4.7 -def make_disk(vm, uname, dev, mode, recreate=0):
     4.8 +def make_disk(vm, config, uname, dev, mode, recreate=0):
     4.9      """Create a virtual disk device for a domain.
    4.10  
    4.11      @param vm:       vm
    4.12 @@ -154,13 +154,8 @@ def make_disk(vm, uname, dev, mode, recr
    4.13          raise VmError("vbd: Multi-segment vdisk: uname=%s" % uname)
    4.14      segment = segments[0]
    4.15      vdev = blkdev_name_to_number(dev)
    4.16 -    backend = vm.get_device_backend('vbd')
    4.17 -    ctrl = xend.blkif_create(vm.dom, recreate=recreate, backend=backend)
    4.18 -    
    4.19 -    def fn(ctrl):
    4.20 -        return xend.blkif_dev_create(vm.dom, vdev, mode, segment, recreate=recreate)
    4.21 -    ctrl.addCallback(fn)
    4.22 -    return ctrl
    4.23 +    ctrl = xend.blkif_create(vm.dom, recreate=recreate)
    4.24 +    return ctrl.attachDevice(config, vdev, mode, segment, recreate=recreate)
    4.25          
    4.26  def vif_up(iplist):
    4.27      """send an unsolicited ARP reply for all non link-local IP addresses.
    4.28 @@ -340,22 +335,6 @@ def append_deferred(dlist, v):
    4.29      if isinstance(v, defer.Deferred):
    4.30          dlist.append(v)
    4.31  
    4.32 -def _vm_configure1(val, vm):
    4.33 -    d = vm.create_devices()
    4.34 -    d.addCallback(_vm_configure2, vm)
    4.35 -    return d
    4.36 -
    4.37 -def _vm_configure2(val, vm):
    4.38 -    d = vm.configure_fields()
    4.39 -    def cbok(results):
    4.40 -        return vm
    4.41 -    def cberr(err):
    4.42 -        vm.destroy()
    4.43 -        return err
    4.44 -    d.addCallback(cbok)
    4.45 -    d.addErrback(cberr)
    4.46 -    return d
    4.47 -
    4.48  class XendDomainInfo:
    4.49      """Virtual machine object."""
    4.50  
    4.51 @@ -379,7 +358,6 @@ class XendDomainInfo:
    4.52          self.console = None
    4.53          self.devices = {}
    4.54          self.device_index = {}
    4.55 -        self.device_backends = {}
    4.56          self.configs = []
    4.57          self.info = None
    4.58          self.ipaddrs = []
    4.59 @@ -675,7 +653,6 @@ class XendDomainInfo:
    4.60          
    4.61          self.devices = {}
    4.62          self.device_index = {}
    4.63 -        self.device_backends = {}
    4.64          self.configs = []
    4.65          self.ipaddrs = []
    4.66  
    4.67 @@ -915,25 +892,6 @@ class XendDomainInfo:
    4.68              self.restart_state = None
    4.69          return d
    4.70  
    4.71 -    def configure_device_backend(self, type, sxpr):
    4.72 -        """Configure the backend domain to use for devices of a given type.
    4.73 -
    4.74 -        @param type: device type
    4.75 -        @param sxpr: config
    4.76 -        @raise: VmError if the domain id is missing
    4.77 -        @raise: VmError if the domain does not exist
    4.78 -        """
    4.79 -        dom = sxp.child_value(sxpr, 'domain')
    4.80 -        if dom is None:
    4.81 -            raise VmError('missing backend domain')
    4.82 -        dominfo = domain_exists(dom)
    4.83 -        if dominfo is None:
    4.84 -            raise VmError('invalid backend domain:' + dom)
    4.85 -        self.device_backends[type] = dominfo.dom
    4.86 -
    4.87 -    def get_device_backend(self, type):
    4.88 -        return self.device_backends.get(type, 0)
    4.89 -
    4.90      def configure_backends(self):
    4.91          """Set configuration flags if the vm is a backend for netif or blkif.
    4.92          Configure the backends to use for vbd and vif if specified.
    4.93 @@ -945,21 +903,9 @@ class XendDomainInfo:
    4.94                  self.blkif_backend = 1
    4.95              elif name == 'netif':
    4.96                  self.netif_backend = 1
    4.97 -            elif name == 'vbd':
    4.98 -                self.configure_device_backend('vbd', v)
    4.99 -            elif name == 'vif':
   4.100 -                self.configure_device_backend('vif', v)
   4.101              else:
   4.102                  raise VmError('invalid backend type:' + str(name))
   4.103  
   4.104 -    def create_backends(self):
   4.105 -        """Setup the netif and blkif backends.
   4.106 -        """
   4.107 -        if self.blkif_backend:
   4.108 -            xend.blkif_set_control_domain(self.dom, recreate=self.recreate)
   4.109 -        if self.netif_backend:
   4.110 -            xend.netif_set_control_domain(self.dom, recreate=self.recreate)
   4.111 -            
   4.112      def configure(self):
   4.113          """Configure a vm.
   4.114  
   4.115 @@ -968,12 +914,19 @@ class XendDomainInfo:
   4.116  
   4.117          returns Deferred - calls callback with vm
   4.118          """
   4.119 -        if self.blkif_backend:
   4.120 -            d = defer.Deferred()
   4.121 -            d.callback(self)
   4.122 -        else:
   4.123 -            d = xend.blkif_create(self.dom, recreate=self.recreate)
   4.124 -        d.addCallback(_vm_configure1, self)
   4.125 +        d = self.create_devices()
   4.126 +        d.addCallback(self._configure)
   4.127 +        return d
   4.128 +
   4.129 +    def _configure(self, val):
   4.130 +        d = self.configure_fields()
   4.131 +        def cbok(results):
   4.132 +            return self
   4.133 +        def cberr(err):
   4.134 +            self.destroy()
   4.135 +            return err
   4.136 +        d.addCallback(cbok)
   4.137 +        d.addErrback(cberr)
   4.138          return d
   4.139  
   4.140      def dom_construct(self, dom, config):
   4.141 @@ -1074,20 +1027,18 @@ def vm_dev_vif(vm, val, index):
   4.142      @param index:     vif index
   4.143      @return: deferred
   4.144      """
   4.145 -    if vm.netif_backend:
   4.146 -        raise VmError('vif: vif in netif backend domain')
   4.147 +    #if vm.netif_backend:
   4.148 +    #    raise VmError('vif: vif in netif backend domain')
   4.149      vif = vm.next_device_index('vif')
   4.150      vmac = sxp.child_value(val, "mac")
   4.151 -    backend = vm.get_device_backend('vif')
   4.152 -    xend.netif_create(vm.dom, recreate=vm.recreate, backend=backend)
   4.153 +    ctrl = xend.netif_create(vm.dom, recreate=vm.recreate)
   4.154      log.debug("Creating vif dom=%d vif=%d mac=%s", vm.dom, vif, str(vmac))
   4.155 -    defer = xend.netif_dev_create(vm.dom, vif, val, recreate=vm.recreate)
   4.156 -    def fn(id):
   4.157 -        dev = xend.netif_dev(vm.dom, vif)
   4.158 +    defer = ctrl.attachDevice(vif, val, recreate=vm.recreate)
   4.159 +    def cbok(dev):
   4.160          dev.vifctl('up', vmname=vm.name)
   4.161          vm.add_device('vif', dev)
   4.162 -        return id
   4.163 -    defer.addCallback(fn)
   4.164 +        return dev
   4.165 +    defer.addCallback(cbok)
   4.166      return defer
   4.167  
   4.168  def vm_dev_vbd(vm, val, index):
   4.169 @@ -1098,8 +1049,8 @@ def vm_dev_vbd(vm, val, index):
   4.170      @param index:     vbd index
   4.171      @return: deferred
   4.172      """
   4.173 -    if vm.blkif_backend:
   4.174 -        raise VmError('vbd: vbd in blkif backend domain')
   4.175 +    #if vm.blkif_backend:
   4.176 +    #    raise VmError('vbd: vbd in blkif backend domain')
   4.177      uname = sxp.child_value(val, 'uname')
   4.178      if not uname:
   4.179          raise VmError('vbd: Missing uname')
   4.180 @@ -1108,7 +1059,7 @@ def vm_dev_vbd(vm, val, index):
   4.181          raise VmError('vbd: Missing dev')
   4.182      mode = sxp.child_value(val, 'mode', 'r')
   4.183      log.debug("Creating vbd dom=%d uname=%s dev=%s", vm.dom, uname, dev)
   4.184 -    defer = make_disk(vm, uname, dev, mode, vm.recreate)
   4.185 +    defer = make_disk(vm, val, uname, dev, mode, vm.recreate)
   4.186      def fn(vbd):
   4.187          vbd.dev = dev
   4.188          vbd.uname = uname
     5.1 --- a/tools/python/xen/xend/XendMigrate.py	Tue Aug 17 17:54:50 2004 +0000
     5.2 +++ b/tools/python/xen/xend/XendMigrate.py	Wed Aug 18 13:43:23 2004 +0000
     5.3 @@ -259,7 +259,7 @@ class XendMigrateInfo(XfrdInfo):
     5.4      """Representation of a migrate in-progress and its interaction with xfrd.
     5.5      """
     5.6  
     5.7 -    def __init__(self, xid, dom, host, port):
     5.8 +    def __init__(self, xid, dom, host, port, live):
     5.9          XfrdInfo.__init__(self)
    5.10          self.xid = xid
    5.11          self.state = 'begin'
    5.12 @@ -268,10 +268,14 @@ class XendMigrateInfo(XfrdInfo):
    5.13          self.dst_host = host
    5.14          self.dst_port = port
    5.15          self.dst_dom = None
    5.16 +        self.live = live
    5.17          self.start = 0
    5.18          
    5.19      def sxpr(self):
    5.20 -        sxpr = ['migrate', ['id', self.xid], ['state', self.state] ]
    5.21 +        sxpr = ['migrate',
    5.22 +                ['id',    self.xid   ],
    5.23 +                ['state', self.state ],
    5.24 +                ['live',  self.live  ] ]
    5.25          sxpr_src = ['src', ['host', self.src_host], ['domain', self.src_dom] ]
    5.26          sxpr.append(sxpr_src)
    5.27          sxpr_dst = ['dst', ['host', self.dst_host] ]
    5.28 @@ -289,7 +293,8 @@ class XendMigrateInfo(XfrdInfo):
    5.29                        self.src_dom,
    5.30                        vmconfig,
    5.31                        self.dst_host,
    5.32 -                      self.dst_port])
    5.33 +                      self.dst_port,
    5.34 +                      self.live ])
    5.35          
    5.36      def xfr_migrate_ok(self, xfrd, val):
    5.37          dom = int(sxp.child0(val))
    5.38 @@ -410,7 +415,7 @@ class XendMigrate:
    5.39          reactor.connectTCP('localhost', XFRD_PORT, xcf)
    5.40          return info
    5.41      
    5.42 -    def migrate_begin(self, dom, host, port=XFRD_PORT):
    5.43 +    def migrate_begin(self, dom, host, port=XFRD_PORT, live=0):
    5.44          """Begin to migrate a domain to another host.
    5.45  
    5.46          @param dom:  domain
    5.47 @@ -421,7 +426,7 @@ class XendMigrate:
    5.48          # Check dom for existence, not migrating already.
    5.49          # Subscribe to migrate notifications (for updating).
    5.50          xid = self.nextid()
    5.51 -        info = XendMigrateInfo(xid, dom, host, port)
    5.52 +        info = XendMigrateInfo(xid, dom, host, port, live)
    5.53          self.session_begin(info)
    5.54          return info.deferred
    5.55  
     6.1 --- a/tools/python/xen/xend/server/SrvDaemon.py	Tue Aug 17 17:54:50 2004 +0000
     6.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py	Wed Aug 18 13:43:23 2004 +0000
     6.3 @@ -651,23 +651,12 @@ class Daemon:
     6.4          """
     6.5          return self.channelF.getDomChannel(dom)
     6.6  
     6.7 -    def blkif_set_control_domain(self, dom, recreate=0):
     6.8 -        """Set the block device backend control domain.
     6.9 -        """
    6.10 -        return self.blkifCF.setControlDomain(dom, recreate=recreate)
    6.11 -    
    6.12 -    def blkif_get_control_domain(self, dom):
    6.13 -        """Get the block device backend control domain.
    6.14 -        """
    6.15 -        return self.blkifCF.getControlDomain()
    6.16 -    
    6.17 -    def blkif_create(self, dom, recreate=0, backend=0):
    6.18 +    def blkif_create(self, dom, recreate=0):
    6.19          """Create a block device interface controller.
    6.20          
    6.21 -        Returns Deferred
    6.22 +        Returns controller
    6.23          """
    6.24 -        d = self.blkifCF.createInstance(dom, recreate=recreate, backend=backend)
    6.25 -        return d
    6.26 +        return self.blkifCF.createInstance(dom, recreate=recreate)
    6.27  
    6.28      def blkifs(self):
    6.29          return [ x.sxpr() for x in self.blkifCF.getInstances() ]
    6.30 @@ -678,7 +667,7 @@ class Daemon:
    6.31      def blkif_dev(self, dom, vdev):
    6.32          return self.blkifCF.getDomainDevice(dom, vdev)
    6.33  
    6.34 -    def blkif_dev_create(self, dom, vdev, mode, segment, recreate=0):
    6.35 +    def blkif_dev_create(self, dom, config, vdev, mode, segment, recreate=0):
    6.36          """Create a block device.
    6.37          
    6.38          Returns Deferred
    6.39 @@ -686,24 +675,14 @@ class Daemon:
    6.40          ctrl = self.blkifCF.getInstanceByDom(dom)
    6.41          if not ctrl:
    6.42              raise XendError('No blkif controller: %d' % dom)
    6.43 -        d = ctrl.attachDevice(vdev, mode, segment, recreate=recreate)
    6.44 +        d = ctrl.attachDevice(config, vdev, mode, segment, recreate=recreate)
    6.45          return d
    6.46  
    6.47 -    def netif_set_control_domain(self, dom, recreate=0):
    6.48 -        """Set the network interface backend control domain.
    6.49 -        """
    6.50 -        return self.netifCF.setControlDomain(dom, recreate=recreate)
    6.51 -
    6.52 -    def netif_get_control_domain(self, dom):
    6.53 -        """Get the network interface backend control domain.
    6.54 -        """
    6.55 -        return self.netifCF.getControlDomain()
    6.56 -    
    6.57 -    def netif_create(self, dom, recreate=0, backend=0):
    6.58 +    def netif_create(self, dom, recreate=0):
    6.59          """Create a network interface controller.
    6.60          
    6.61          """
    6.62 -        return self.netifCF.createInstance(dom, recreate=recreate, backend=backend)
    6.63 +        return self.netifCF.createInstance(dom, recreate=recreate)
    6.64  
    6.65      def netifs(self):
    6.66          return [ x.sxpr() for x in self.netifCF.getInstances() ]
     7.1 --- a/tools/python/xen/xend/server/SrvDomain.py	Tue Aug 17 17:54:50 2004 +0000
     7.2 +++ b/tools/python/xen/xend/server/SrvDomain.py	Wed Aug 18 13:43:23 2004 +0000
     7.3 @@ -48,7 +48,7 @@ class SrvDomain(SrvDir):
     7.4          fn = FormFn(self.xd.domain_shutdown,
     7.5                      [['dom', 'str'],
     7.6                       ['reason', 'str']])
     7.7 -        val = fn(req.args, {'dom': self.dom.name})
     7.8 +        val = fn(req.args, {'dom': self.dom.id})
     7.9          req.setResponseCode(http.ACCEPTED)
    7.10          req.setHeader("Location", "%s/.." % req.prePathURL())
    7.11          return val
    7.12 @@ -57,7 +57,7 @@ class SrvDomain(SrvDir):
    7.13          fn = FormFn(self.xd.domain_destroy,
    7.14                      [['dom', 'str'],
    7.15                       ['reason', 'str']])
    7.16 -        val = fn(req.args, {'dom': self.dom.name})
    7.17 +        val = fn(req.args, {'dom': self.dom.id})
    7.18          req.setHeader("Location", "%s/.." % req.prePathURL())
    7.19          return val
    7.20  
    7.21 @@ -65,7 +65,7 @@ class SrvDomain(SrvDir):
    7.22          fn = FormFn(self.xd.domain_save,
    7.23                      [['dom', 'str'],
    7.24                       ['file', 'str']])
    7.25 -        deferred = fn(req.args, {'dom': self.dom.name})
    7.26 +        deferred = fn(req.args, {'dom': self.dom.id})
    7.27          deferred.addCallback(self._op_save_cb, req)
    7.28          deferred.addErrback(self._op_save_err, req)
    7.29          return deferred
    7.30 @@ -80,8 +80,9 @@ class SrvDomain(SrvDir):
    7.31      def op_migrate(self, op, req):
    7.32          fn = FormFn(self.xd.domain_migrate,
    7.33                      [['dom', 'str'],
    7.34 -                     ['destination', 'str']])
    7.35 -        deferred = fn(req.args, {'dom': self.dom.name})
    7.36 +                     ['destination', 'str'],
    7.37 +                     ['live', 'int']])
    7.38 +        deferred = fn(req.args, {'dom': self.dom.id})
    7.39          print 'op_migrate>', deferred
    7.40          deferred.addCallback(self._op_migrate_cb, req)
    7.41          deferred.addErrback(self._op_migrate_err, req)
    7.42 @@ -107,7 +108,7 @@ class SrvDomain(SrvDir):
    7.43          fn = FormFn(self.xd.domain_pincpu,
    7.44                      [['dom', 'str'],
    7.45                       ['cpu', 'int']])
    7.46 -        val = fn(req.args, {'dom': self.dom.name})
    7.47 +        val = fn(req.args, {'dom': self.dom.id})
    7.48          return val
    7.49  
    7.50      def op_cpu_bvt_set(self, op, req):
    7.51 @@ -118,7 +119,7 @@ class SrvDomain(SrvDir):
    7.52                       ['warpvalue', 'int'],
    7.53                       ['warpl', 'long'],
    7.54                       ['warpu', 'long']])
    7.55 -        val = fn(req.args, {'dom': self.dom.name})
    7.56 +        val = fn(req.args, {'dom': self.dom.id})
    7.57          return val
    7.58      
    7.59      def op_cpu_fbvt_set(self, op, req):
    7.60 @@ -128,7 +129,7 @@ class SrvDomain(SrvDir):
    7.61                       ['warp', 'int'],
    7.62                       ['warpl', 'int'],
    7.63                       ['warpu', 'int']])
    7.64 -        val = fn(req.args, {'dom': self.dom.name})
    7.65 +        val = fn(req.args, {'dom': self.dom.id})
    7.66          return val
    7.67  
    7.68      def op_cpu_atropos_set(self, op, req):
    7.69 @@ -138,21 +139,21 @@ class SrvDomain(SrvDir):
    7.70                       ['slice', 'int'],
    7.71                       ['latency', 'int'],
    7.72                       ['xtratime', 'int']])
    7.73 -        val = fn(req.args, {'dom': self.dom.name})
    7.74 +        val = fn(req.args, {'dom': self.dom.id})
    7.75          return val
    7.76  
    7.77      def op_maxmem_set(self, op, req):
    7.78          fn = FormFn(self.xd.domain_maxmem_set,
    7.79                      [['dom', 'str'],
    7.80                       ['memory', 'int']])
    7.81 -        val = fn(req.args, {'dom': self.dom.name})
    7.82 +        val = fn(req.args, {'dom': self.dom.id})
    7.83          return val
    7.84  
    7.85      def op_device_create(self, op, req):
    7.86          fn = FormFn(self.xd.domain_device_create,
    7.87                      [['dom', 'str'],
    7.88                       ['config', 'sxpr']])
    7.89 -        d = fn(req.args, {'dom': self.dom.name})
    7.90 +        d = fn(req.args, {'dom': self.dom.id})
    7.91          return d
    7.92  
    7.93      def op_device_destroy(self, op, req):
    7.94 @@ -160,29 +161,29 @@ class SrvDomain(SrvDir):
    7.95                      [['dom', 'str'],
    7.96                       ['type', 'str'],
    7.97                       ['idx', 'str']])
    7.98 -        val = fn(req.args, {'dom': self.dom.name})
    7.99 +        val = fn(req.args, {'dom': self.dom.id})
   7.100          return val
   7.101                  
   7.102      def op_vifs(self, op, req):
   7.103 -        devs = self.xd.domain_vif_ls(self.dom.name)
   7.104 +        devs = self.xd.domain_vif_ls(self.dom.id)
   7.105          return [ dev.sxpr() for dev in devs ]
   7.106  
   7.107      def op_vif(self, op, req):
   7.108          fn = FormFn(self.xd.domain_vif_get,
   7.109                      [['dom', 'str'],
   7.110                       ['vif', 'str']])
   7.111 -        val = fn(req.args, {'dom': self.dom.name})
   7.112 +        val = fn(req.args, {'dom': self.dom.id})
   7.113          return val
   7.114  
   7.115      def op_vbds(self, op, req):
   7.116 -        devs = self.xd.domain_vbd_ls(self.dom.name)
   7.117 +        devs = self.xd.domain_vbd_ls(self.dom.id)
   7.118          return [ dev.sxpr() for dev in devs ]
   7.119  
   7.120      def op_vbd(self, op, req):
   7.121          fn = FormFn(self.xd.domain_vbd_get,
   7.122                      [['dom', 'str'],
   7.123                       ['vbd', 'str']])
   7.124 -        val = fn(req.args, {'dom': self.dom.name})
   7.125 +        val = fn(req.args, {'dom': self.dom.id})
   7.126          return val
   7.127  
   7.128      def render_POST(self, req):
   7.129 @@ -244,4 +245,5 @@ class SrvDomain(SrvDir):
   7.130          req.write('<form method="post" action="%s">' % url)
   7.131          req.write('<br><input type="submit" name="op" value="migrate">')
   7.132          req.write(' To host: <input type="text" name="destination">')
   7.133 +        req.write('<input type="checkbox" name="live" value="1">Live')
   7.134          req.write('</form>')
     8.1 --- a/tools/python/xen/xend/server/blkif.py	Tue Aug 17 17:54:50 2004 +0000
     8.2 +++ b/tools/python/xen/xend/server/blkif.py	Wed Aug 18 13:43:23 2004 +0000
     8.3 @@ -17,79 +17,18 @@ class BlkifBackendController(controller.
     8.4      """ Handler for the 'back-end' channel to a device driver domain.
     8.5      """
     8.6  
     8.7 -    def __init__(self, factory, dom):
     8.8 -        controller.BackendController.__init__(self, factory, dom)
     8.9 +    def __init__(self, ctrl, dom, handle):
    8.10 +        controller.BackendController.__init__(self, ctrl, dom, handle)
    8.11 +        self.connected = 0
    8.12 +        self.evtchn = None
    8.13 +        self.handle = handle
    8.14          self.addMethod(CMSG_BLKIF_BE,
    8.15                         CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED,
    8.16                         self.recv_be_driver_status_changed)
    8.17 -        self.attached = 1
    8.18          self.registerChannel()
    8.19 -        
    8.20 -    def respond_be_create(self, msg, d):
    8.21 -        """Response handler for a be_create message.
    8.22 -        Calls I{d} with the block interface created.
    8.23 -
    8.24 -        @param msg: message
    8.25 -        @type  msg: xu message
    8.26 -        @param d: deferred to call
    8.27 -        @type  d: Deferred
    8.28 -        """
    8.29 -        val = unpackMsg('blkif_be_create_t', msg)
    8.30 -        blkif = self.factory.getInstanceByDom(val['domid'])
    8.31 -        d.callback(blkif)
    8.32 -
    8.33 -    def respond_be_connect(self, msg):
    8.34 -        """Response handler for a be_connect message.
    8.35 -
    8.36 -        @param msg: message
    8.37 -        @type  msg: xu message
    8.38 -        """
    8.39 -        val = unpackMsg('blkif_be_connect_t', msg)
    8.40 -        blkif = self.factory.getInstanceByDom(val['domid'])
    8.41 -        if blkif:
    8.42 -            blkif.send_fe_interface_status_changed()
    8.43 -        else:
    8.44 -            pass
    8.45 -    
    8.46 -    def respond_be_vbd_create(self, msg, dev, d):
    8.47 -        """Response handler for a be_vbd_create message.
    8.48 -        Tries to grow the vbd, and passes the deferred I{d} on for
    8.49 -        the grow to call.
    8.50  
    8.51 -        @param msg: message
    8.52 -        @type  msg: xu message
    8.53 -        @param dev: device
    8.54 -        @type  dev: BlkDev
    8.55 -        @param d: deferred to call
    8.56 -        @type  d: Deferred
    8.57 -        """
    8.58 -        val = unpackMsg('blkif_be_vbd_create_t', msg)
    8.59 -        blkif = self.factory.getInstanceByDom(val['domid'])
    8.60 -        if blkif:
    8.61 -            d1 = defer.Deferred()
    8.62 -            d1.addCallback(self.respond_be_vbd_grow, dev, d)
    8.63 -            if d: d1.addErrback(d.errback)
    8.64 -            blkif.send_be_vbd_grow(val['vdevice'], response=d1)
    8.65 -        else:
    8.66 -            pass
    8.67 -    
    8.68 -    def respond_be_vbd_grow(self, msg, dev, d):
    8.69 -        """Response handler for a be_vbd_grow message.
    8.70 -
    8.71 -        @param msg: message
    8.72 -        @type  msg: xu message
    8.73 -        @param dev: device
    8.74 -        @type  dev: BlkDev
    8.75 -        @param d: deferred to call
    8.76 -        @type  d: Deferred or None
    8.77 -        """
    8.78 -        val = unpackMsg('blkif_be_vbd_grow_t', msg)
    8.79 -	status = val['status']
    8.80 -	if status != BLKIF_BE_STATUS_OKAY:
    8.81 -            raise XendError("Adding extent to vbd failed: device %x, error %d"
    8.82 -                            % (val['extent.device'], status))
    8.83 -        if d:
    8.84 -            d.callback(dev)
    8.85 +    def __str__(self):
    8.86 +        return '<BlkifBackendController %d %d>' % (self.controller.dom, self.dom)
    8.87  
    8.88      def recv_be_driver_status_changed(self, msg, req):
    8.89          """Request handler for be_driver_status_changed messages.
    8.90 @@ -101,45 +40,110 @@ class BlkifBackendController(controller.
    8.91          """
    8.92          val = unpackMsg('blkif_be_driver_status_changed_t', msg)
    8.93          status = val['status']
    8.94 -        if status == BLKIF_DRIVER_STATUS_UP and not self.attached:
    8.95 -            for blkif in self.factory.getInstances():
    8.96 -                if blkif.backendController == self:
    8.97 -                    blkif.detach()
    8.98 - 
    8.99 +
   8.100 +    def connect(self, recreate=0):
   8.101 +        """Connect the controller to the blkif control interface.
   8.102 +
   8.103 +        @param recreate: true if after xend restart
   8.104 +        @return: deferred
   8.105 +        """
   8.106 +        log.debug("Connecting blkif %s", str(self))
   8.107 +        if recreate or self.connected:
   8.108 +            d = defer.succeed(self)
   8.109 +        else:
   8.110 +            d = self.send_be_create()
   8.111 +            d.addCallback(self.respond_be_create)
   8.112 +        return d
   8.113 +        
   8.114 +    def send_be_create(self):
   8.115 +        d = defer.Deferred()
   8.116 +        msg = packMsg('blkif_be_create_t',
   8.117 +                      { 'domid'        : self.controller.dom,
   8.118 +                        'blkif_handle' : self.handle })
   8.119 +        self.writeRequest(msg, response=d)
   8.120 +        return d
   8.121  
   8.122 -class BlkifControllerFactory(controller.SplitControllerFactory):
   8.123 +    def respond_be_create(self, msg):
   8.124 +        val = unpackMsg('blkif_be_create_t', msg)
   8.125 +        print 'respond_be_create>', val
   8.126 +        self.connected = 1
   8.127 +        return self
   8.128 +    
   8.129 +    def destroy(self):
   8.130 +        """Disconnect from the blkif control interface and destroy it.
   8.131 +        """
   8.132 +        def cb_destroy(val):
   8.133 +            self.send_be_destroy()
   8.134 +        d = defer.Deferred()
   8.135 +        d.addCallback(cb_destroy)
   8.136 +        self.send_be_disconnect(response=d)
   8.137 +        
   8.138 +    def send_be_disconnect(self, response=None):
   8.139 +        log.debug('>BlkifBackendController>send_be_disconnect> %s', str(self))
   8.140 +        msg = packMsg('blkif_be_disconnect_t',
   8.141 +                      { 'domid'        : self.controller.dom,
   8.142 +                        'blkif_handle' : self.handle })
   8.143 +        self.writeRequest(msg, response=response)
   8.144 +
   8.145 +    def send_be_destroy(self, response=None):
   8.146 +        log.debug('>BlkifBackendController>send_be_destroy> %s', str(self))
   8.147 +        msg = packMsg('blkif_be_destroy_t',
   8.148 +                      { 'domid'        : self.controller.dom,
   8.149 +                        'blkif_handle' : self.handle })
   8.150 +        self.writeRequest(msg, response=response)
   8.151 +
   8.152 +    def connectInterface(self, val):
   8.153 +        self.evtchn = channel.eventChannel(0, self.controller.dom)
   8.154 +        log.debug("Connecting blkif to event channel %s ports=%d:%d",
   8.155 +                  str(self), self.evtchn['port1'], self.evtchn['port2'])
   8.156 +        msg = packMsg('blkif_be_connect_t',
   8.157 +                      { 'domid'        : self.controller.dom,
   8.158 +                        'blkif_handle' : self.handle,
   8.159 +                        'evtchn'       : self.evtchn['port1'],
   8.160 +                        'shmem_frame'  : val['shmem_frame'] })
   8.161 +        d = defer.Deferred()
   8.162 +        d.addCallback(self.respond_be_connect)
   8.163 +        self.writeRequest(msg, response=d)
   8.164 +
   8.165 +    def respond_be_connect(self, msg):
   8.166 +        """Response handler for a be_connect message.
   8.167 +
   8.168 +        @param msg: message
   8.169 +        @type  msg: xu message
   8.170 +        """
   8.171 +        val = unpackMsg('blkif_be_connect_t', msg)
   8.172 +        print 'respond_be_connect>', str(self), val
   8.173 +        self.send_fe_interface_status_changed()
   8.174 +            
   8.175 +    def send_fe_interface_status_changed(self, response=None):
   8.176 +        msg = packMsg('blkif_fe_interface_status_changed_t',
   8.177 +                      { 'handle' : self.handle,
   8.178 +                        'status' : BLKIF_INTERFACE_STATUS_CONNECTED,
   8.179 +                        'evtchn' : self.evtchn['port2'] })
   8.180 +        self.controller.writeRequest(msg, response=response)
   8.181 +        
   8.182 +class BlkifControllerFactory(controller.ControllerFactory):
   8.183      """Factory for creating block device interface controllers.
   8.184      """
   8.185  
   8.186      def __init__(self):
   8.187 -        controller.SplitControllerFactory.__init__(self)
   8.188 -        self.attached = 1
   8.189 +        controller.ControllerFactory.__init__(self)
   8.190  
   8.191 -    def createInstance(self, dom, recreate=0, backend=0):
   8.192 +    def createInstance(self, dom, recreate=0):
   8.193          """Create a block device controller for a domain.
   8.194  
   8.195          @param dom: domain
   8.196          @type  dom: int
   8.197          @param recreate: if true it's a recreate (after xend restart)
   8.198          @type  recreate: bool
   8.199 -        @return: deferred
   8.200 -        @rtype: twisted.internet.defer.Deferred
   8.201 +        @return: block device controller
   8.202 +        @rtype: BlkifController
   8.203          """
   8.204 -        d = defer.Deferred()
   8.205          blkif = self.getInstanceByDom(dom)
   8.206 -        if blkif:
   8.207 -            d.callback(blkif)
   8.208 -        else:
   8.209 -            blkif = BlkifController(self, dom, backend)
   8.210 +        if blkif is None:
   8.211 +            blkif = BlkifController(self, dom)
   8.212              self.addInstance(blkif)
   8.213 -            if recreate:
   8.214 -                d.callback(blkif)
   8.215 -            else:
   8.216 -                d1 = defer.Deferred()
   8.217 -                d1.addCallback(blkif.backendController.respond_be_create, d)
   8.218 -                d1.addErrback(d.errback)
   8.219 -                blkif.send_be_create(response=d1)
   8.220 -        return d
   8.221 +        return blkif
   8.222  
   8.223      def getDomainDevices(self, dom):
   8.224          """Get the block devices for a domain.
   8.225 @@ -158,82 +162,20 @@ class BlkifControllerFactory(controller.
   8.226          @param dom: domain
   8.227          @type  dom: int
   8.228          @param vdev: device index
   8.229 -        @type  vedv: int
   8.230 +        @type  vdev: int
   8.231          @return: device
   8.232          @rtype:  device
   8.233          """
   8.234          blkif = self.getInstanceByDom(dom)
   8.235          return (blkif and blkif.getDevice(vdev)) or None
   8.236  
   8.237 -    def createBackendController(self, dom):
   8.238 -        return BlkifBackendController(self, dom)
   8.239 -
   8.240 -    def setControlDomain(self, dom, recreate=0):
   8.241 -        """Set the back-end block device controller domain.
   8.242 -
   8.243 -        @param dom: domain
   8.244 -        @type  dom: int
   8.245 -        @param recreate: if true it's a recreate (after xend restart)
   8.246 -        @type  recreate: int
   8.247 -        """
   8.248 -        if self.dom == dom: return
   8.249 -        self.deregisterChannel()
   8.250 -        if not recreate:
   8.251 -            self.attached = 0
   8.252 -        self.dom = dom
   8.253 -        self.registerChannel()
   8.254 -
   8.255 -    def getControlDomain(self):
   8.256 -        """Get the back-end block device controller domain.
   8.257 -
   8.258 -        @return: domain
   8.259 -        @rtype:  int
   8.260 -        """
   8.261 -        return self.dom
   8.262 -
   8.263 -    def reattachDevice(self, dom, vdev):
   8.264 -        """Reattach a device (on changing control domain).
   8.265 -
   8.266 -        @param dom: domain
   8.267 -        @type  dom: int
   8.268 -        @param vdev: device index
   8.269 -        @type  vdev: int
   8.270 -        """
   8.271 -        blkif = self.getInstanceByDom(dom)
   8.272 -        if blkif:
   8.273 -            blkif.reattachDevice(vdev)
   8.274 -        self.attached = self.devicesAttached()
   8.275 -        if self.attached:
   8.276 -            self.reattached()
   8.277 -
   8.278 -    def devicesAttached(self):
   8.279 -        """Check if all devices are attached.
   8.280 -
   8.281 -        @return: true if all devices attached
   8.282 -        @rtype:  bool
   8.283 -        """
   8.284 -        attached = 1
   8.285 -        for blkif in self.getInstances():
   8.286 -            if not blkif.attached:
   8.287 -                attached = 0
   8.288 -                break
   8.289 -        return attached
   8.290 -                         
   8.291 -    def reattached(self):
   8.292 -        """Notify all block interfaces we have been reattached
   8.293 -        (after changing control domain).
   8.294 -        """
   8.295 -        for blkif in self.getInstances():
   8.296 -            blkif.reattached()
   8.297 -
   8.298 -
   8.299 -
   8.300 -class BlkDev(controller.Dev):
   8.301 +class BlkDev(controller.SplitDev):
   8.302      """Info record for a block device.
   8.303      """
   8.304  
   8.305 -    def __init__(self, ctrl, vdev, mode, segment):
   8.306 -        controller.Dev.__init__(self,  segment['device'], ctrl)
   8.307 +    def __init__(self, ctrl, config, vdev, mode, segment):
   8.308 +        controller.SplitDev.__init__(self,  segment['device'], ctrl)
   8.309 +        self.config = config
   8.310          self.dev = None
   8.311          self.uname = None
   8.312          self.vdev = vdev
   8.313 @@ -241,7 +183,10 @@ class BlkDev(controller.Dev):
   8.314          self.device = segment['device']
   8.315          self.start_sector = segment['start_sector']
   8.316          self.nr_sectors = segment['nr_sectors']
   8.317 -        self.attached = 1
   8.318 +        try:
   8.319 +            self.backendDomain = int(sxp.child_value(config, 'backend', '0'))
   8.320 +        except:
   8.321 +            raise XendError('invalid backend domain')
   8.322  
   8.323      def readonly(self):
   8.324          return 'w' not in self.mode
   8.325 @@ -260,15 +205,92 @@ class BlkDev(controller.Dev):
   8.326  
   8.327      def destroy(self):
   8.328          log.debug("Destroying vbd domain=%d vdev=%d", self.controller.dom, self.vdev)
   8.329 -        self.controller.send_be_vbd_destroy(self.vdev)
   8.330 +        self.send_be_vbd_destroy()
   8.331 +
   8.332 +    def attach(self):
   8.333 +        """Attach the device to its controller.
   8.334 +
   8.335 +        """
   8.336 +        backend = self.getBackend()
   8.337 +        d1 = backend.connect()
   8.338 +        d2 = defer.Deferred()
   8.339 +        d2.addCallback(self.send_be_vbd_create)
   8.340 +        d1.chainDeferred(d2)
   8.341 +        return d2
   8.342 +        
   8.343 +    def send_be_vbd_create(self, val):
   8.344 +        d = defer.Deferred()
   8.345 +        d.addCallback(self.respond_be_vbd_create)
   8.346 +        backend = self.getBackend()
   8.347 +        msg = packMsg('blkif_be_vbd_create_t',
   8.348 +                      { 'domid'        : self.controller.dom,
   8.349 +                        'blkif_handle' : backend.handle,
   8.350 +                        'vdevice'      : self.vdev,
   8.351 +                        'readonly'     : self.readonly() })
   8.352 +        backend.writeRequest(msg, response=d)
   8.353 +        return d
   8.354 +        
   8.355 +    def respond_be_vbd_create(self, msg):
   8.356 +        """Response handler for a be_vbd_create message.
   8.357 +        Tries to grow the vbd.
   8.358 +
   8.359 +        @param msg: message
   8.360 +        @type  msg: xu message
   8.361 +        """
   8.362 +        val = unpackMsg('blkif_be_vbd_create_t', msg)
   8.363 +        d = self.send_be_vbd_grow()
   8.364 +        d.addCallback(self.respond_be_vbd_grow)
   8.365 +        return d
   8.366 +    
   8.367 +    def send_be_vbd_grow(self):
   8.368 +        d = defer.Deferred()
   8.369 +        backend = self.getBackend()
   8.370 +        msg = packMsg('blkif_be_vbd_grow_t',
   8.371 +                      { 'domid'                : self.controller.dom,
   8.372 +                        'blkif_handle'         : backend.handle,
   8.373 +                        'vdevice'              : self.vdev,
   8.374 +                        'extent.device'        : self.device,
   8.375 +                        'extent.sector_start'  : self.start_sector,
   8.376 +                        'extent.sector_length' : self.nr_sectors })
   8.377 +        backend.writeRequest(msg, response=d)
   8.378 +        return d
   8.379 +
   8.380 +    def respond_be_vbd_grow(self, msg):
   8.381 +        """Response handler for a be_vbd_grow message.
   8.382 +
   8.383 +        @param msg: message
   8.384 +        @type  msg: xu message
   8.385 +        """
   8.386 +        val = unpackMsg('blkif_be_vbd_grow_t', msg)
   8.387 +	status = val['status']
   8.388 +	if status != BLKIF_BE_STATUS_OKAY:
   8.389 +            raise XendError("Adding extent to vbd failed: device %d, error %d"
   8.390 +                            % (self.vdev, status))
   8.391 +        return self
   8.392 +
   8.393 +    def send_be_vbd_destroy(self, response=None):
   8.394 +        log.debug('>BlkDev>send_be_vbd_destroy> dom=%d vdev=%d',
   8.395 +                  self.controller.dom, self.vdev)
   8.396 +        backend = self.getBackend()
   8.397 +        msg = packMsg('blkif_be_vbd_destroy_t',
   8.398 +                      { 'domid'                : self.controller.dom,
   8.399 +                        'blkif_handle'         : backend.handle,
   8.400 +                        'vdevice'              : self.vdev })
   8.401 +        self.controller.delDevice(self.vdev)
   8.402 +        backend.writeRequest(msg, response=response)
   8.403 +        
   8.404          
   8.405  class BlkifController(controller.SplitController):
   8.406      """Block device interface controller. Handles all block devices
   8.407      for a domain.
   8.408      """
   8.409      
   8.410 -    def __init__(self, factory, dom, backend):
   8.411 -        controller.SplitController.__init__(self, factory, dom, backend)
   8.412 +    def __init__(self, factory, dom):
   8.413 +        """Create a block device controller.
   8.414 +        The controller must be connected using connect() before it can be used.
   8.415 +        Do not call directly - use createInstance() on the factory instead.
   8.416 +        """
   8.417 +        controller.SplitController.__init__(self, factory, dom)
   8.418          self.devices = {}
   8.419          self.addMethod(CMSG_BLKIF_FE,
   8.420                         CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED,
   8.421 @@ -276,25 +298,22 @@ class BlkifController(controller.SplitCo
   8.422          self.addMethod(CMSG_BLKIF_FE,
   8.423                         CMSG_BLKIF_FE_INTERFACE_CONNECT,
   8.424                         self.recv_fe_interface_connect)
   8.425 -        self.attached = 1
   8.426 -        self.evtchn = None
   8.427          self.registerChannel()
   8.428  
   8.429      def sxpr(self):
   8.430          val = ['blkif', ['dom', self.dom]]
   8.431 -        if self.evtchn:
   8.432 -            val.append(['evtchn',
   8.433 -                        self.evtchn['port1'],
   8.434 -                        self.evtchn['port2']])
   8.435          return val
   8.436  
   8.437 +    def createBackend(self, dom, handle):
   8.438 +        return BlkifBackendController(self, dom, handle)
   8.439 +
   8.440      def getDevices(self):
   8.441          return self.devices.values()
   8.442  
   8.443      def getDevice(self, vdev):
   8.444          return self.devices.get(vdev)
   8.445  
   8.446 -    def addDevice(self, vdev, mode, segment):
   8.447 +    def addDevice(self, config, vdev, mode, segment):
   8.448          """Add a device to the device table.
   8.449  
   8.450          @param vdev:     device index
   8.451 @@ -306,12 +325,17 @@ class BlkifController(controller.SplitCo
   8.452          @return: device
   8.453          @rtype:  BlkDev
   8.454          """
   8.455 -        if vdev in self.devices: return None
   8.456 -        dev = BlkDev(self, vdev, mode, segment)
   8.457 +        if vdev in self.devices:
   8.458 +            raise XendError('device exists: ' + str(vdev))
   8.459 +        dev = BlkDev(self, config, vdev, mode, segment)
   8.460          self.devices[vdev] = dev
   8.461          return dev
   8.462  
   8.463 -    def attachDevice(self, vdev, mode, segment, recreate=0):
   8.464 +    def delDevice(self, vdev):
   8.465 +        if vdev in self.devices:
   8.466 +            del self.devices[vdev]
   8.467 +
   8.468 +    def attachDevice(self, config, vdev, mode, segment, recreate=0):
   8.469          """Attach a device to the specified interface.
   8.470          On success the returned deferred will be called with the device.
   8.471  
   8.472 @@ -326,137 +350,48 @@ class BlkifController(controller.SplitCo
   8.473          @return: deferred
   8.474          @rtype:  Deferred
   8.475          """
   8.476 -        dev = self.addDevice(vdev, mode, segment)
   8.477 -        if not dev: return -1
   8.478 -        d = defer.Deferred()
   8.479 +        dev = self.addDevice(config, vdev, mode, segment)
   8.480          if recreate:
   8.481 -            d.callback(dev)
   8.482 +            d = defer.succeed(dev)
   8.483          else:
   8.484 -            d1 = defer.Deferred()
   8.485 -            d1.addCallback(self.backendController.respond_be_vbd_create, dev, d)
   8.486 -            d1.addErrback(d.errback)
   8.487 -            self.send_be_vbd_create(vdev, response=d1)
   8.488 +            d = dev.attach()
   8.489          return d
   8.490  
   8.491      def destroy(self):
   8.492 -        def cb_destroy(val):
   8.493 -            self.send_be_destroy()
   8.494 +        """Destroy the controller and all devices.
   8.495 +        """
   8.496          log.debug("Destroying blkif domain=%d", self.dom)
   8.497 -        d = defer.Deferred()
   8.498 -        d.addCallback(cb_destroy)
   8.499 -        self.send_be_disconnect(response=d)
   8.500 +        self.destroyDevices()
   8.501 +        self.destroyBackends()
   8.502  
   8.503      def destroyDevices(self):
   8.504 +        """Destroy all devices.
   8.505 +        """
   8.506          for dev in self.getDevices():
   8.507              dev.destroy()
   8.508  
   8.509 -    def detach(self):
   8.510 -        """Detach all devices, when the back-end control domain has changed.
   8.511 -        """
   8.512 -        self.attached = 0
   8.513 -        for dev in self.devices.values():
   8.514 -            dev.attached = 0
   8.515 -            d1 = defer.Deferred()
   8.516 -            d1.addCallback(self.backendController.respond_be_vbd_create, None, None)
   8.517 -            self.send_be_vbd_create(vdev, response=d1)
   8.518 -
   8.519 -    def reattachDevice(self, vdev):
   8.520 -        """Reattach a device, when the back-end control domain has changed.
   8.521 -        """
   8.522 -        dev = self.devices[vdev]
   8.523 -        dev.attached = 1
   8.524 -        attached = 1
   8.525 -        for dev in self.devices.values():
   8.526 -            if not dev.attached:
   8.527 -                attached = 0
   8.528 -                break
   8.529 -        self.attached = attached
   8.530 -        return self.attached
   8.531 -
   8.532 -    def reattached(self):
   8.533 -        """All devices have been reattached after the back-end control
   8.534 -        domain has changed.
   8.535 -        """
   8.536 -        msg = packMsg('blkif_fe_interface_status_changed_t',
   8.537 -                      { 'handle' : 0,
   8.538 -                        'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED})
   8.539 -        self.writeRequest(msg)
   8.540 +    def destroyBackends(self):
   8.541 +        for backend in self.getBackends():
   8.542 +            backend.destroy()
   8.543  
   8.544      def recv_fe_driver_status_changed(self, msg, req):
   8.545 +        val = unpackMsg('blkif_fe_driver_status_changed_t', msg)
   8.546 +        print 'recv_fe_driver_status_changed>', val
   8.547 +        # For each backend?
   8.548          msg = packMsg('blkif_fe_interface_status_changed_t',
   8.549                        { 'handle' : 0,
   8.550                          'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED,
   8.551                          'evtchn' : 0 })
   8.552          self.writeRequest(msg)
   8.553 -    
   8.554 +
   8.555      def recv_fe_interface_connect(self, msg, req):
   8.556          val = unpackMsg('blkif_fe_interface_connect_t', msg)
   8.557 -        self.evtchn = channel.eventChannel(0, self.dom)
   8.558 -        log.debug("Connecting blkif to event channel dom=%d ports=%d:%d",
   8.559 -                  self.dom, self.evtchn['port1'], self.evtchn['port2'])
   8.560 -        msg = packMsg('blkif_be_connect_t',
   8.561 -                      { 'domid'        : self.dom,
   8.562 -                        'blkif_handle' : val['handle'],
   8.563 -                        'evtchn'       : self.evtchn['port1'],
   8.564 -                        'shmem_frame'  : val['shmem_frame'] })
   8.565 -        d = defer.Deferred()
   8.566 -        d.addCallback(self.backendController.respond_be_connect)
   8.567 -        self.backendController.writeRequest(msg, response=d)
   8.568 -
   8.569 -    def send_fe_interface_status_changed(self, response=None):
   8.570 -        msg = packMsg('blkif_fe_interface_status_changed_t',
   8.571 -                      { 'handle' : 0,
   8.572 -                        'status' : BLKIF_INTERFACE_STATUS_CONNECTED,
   8.573 -                        'evtchn' : self.evtchn['port2'] })
   8.574 -        self.writeRequest(msg, response=response)
   8.575 -
   8.576 -    def send_be_create(self, response=None):
   8.577 -        msg = packMsg('blkif_be_create_t',
   8.578 -                      { 'domid'        : self.dom,
   8.579 -                        'blkif_handle' : 0 })
   8.580 -        self.backendController.writeRequest(msg, response=response)
   8.581 -
   8.582 -    def send_be_disconnect(self, response=None):
   8.583 -        log.debug('>BlkifController>send_be_disconnect> dom=%d', self.dom)
   8.584 -        msg = packMsg('blkif_be_disconnect_t',
   8.585 -                      { 'domid'        : self.dom,
   8.586 -                        'blkif_handle' : 0 })
   8.587 -        self.backendController.writeRequest(msg, response=response)
   8.588 +        handle = val['handle']
   8.589 +        backend = self.getBackendByHandle(handle)
   8.590 +        if backend:
   8.591 +            backend.connectInterface(val)
   8.592 +        else:
   8.593 +            log.error('interface connect on unknown interface: handle=%d', handle)
   8.594  
   8.595 -    def send_be_destroy(self, response=None):
   8.596 -        log.debug('>BlkifController>send_be_destroy> dom=%d', self.dom)
   8.597 -        msg = packMsg('blkif_be_destroy_t',
   8.598 -                      { 'domid'        : self.dom,
   8.599 -                        'blkif_handle' : 0 })
   8.600 -        self.backendController.writeRequest(msg, response=response)
   8.601 +    
   8.602  
   8.603 -    def send_be_vbd_create(self, vdev, response=None):
   8.604 -        dev = self.devices[vdev]
   8.605 -        msg = packMsg('blkif_be_vbd_create_t',
   8.606 -                      { 'domid'        : self.dom,
   8.607 -                        'blkif_handle' : 0,
   8.608 -                        'vdevice'      : dev.vdev,
   8.609 -                        'readonly'     : dev.readonly() })
   8.610 -        self.backendController.writeRequest(msg, response=response)
   8.611 -        
   8.612 -    def send_be_vbd_grow(self, vdev, response=None):
   8.613 -        dev = self.devices[vdev]
   8.614 -        msg = packMsg('blkif_be_vbd_grow_t',
   8.615 -                      { 'domid'                : self.dom,
   8.616 -                        'blkif_handle'         : 0,
   8.617 -                        'vdevice'              : dev.vdev,
   8.618 -                        'extent.device'        : dev.device,
   8.619 -                        'extent.sector_start'  : dev.start_sector,
   8.620 -                        'extent.sector_length' : dev.nr_sectors })
   8.621 -        self.backendController.writeRequest(msg, response=response)
   8.622 -
   8.623 -    def send_be_vbd_destroy(self, vdev, response=None):
   8.624 -        log.debug('>BlkifController>send_be_vbd_destroy> dom=%d vdev=%d', self.dom, vdev)
   8.625 -        dev = self.devices[vdev]
   8.626 -        msg = packMsg('blkif_be_vbd_destroy_t',
   8.627 -                      { 'domid'                : self.dom,
   8.628 -                        'blkif_handle'         : 0,
   8.629 -                        'vdevice'              : dev.vdev })
   8.630 -        del self.devices[vdev]
   8.631 -        self.backendController.writeRequest(msg, response=response)
   8.632 -    
     9.1 --- a/tools/python/xen/xend/server/channel.py	Tue Aug 17 17:54:50 2004 +0000
     9.2 +++ b/tools/python/xen/xend/server/channel.py	Wed Aug 18 13:43:23 2004 +0000
     9.3 @@ -333,13 +333,15 @@ class Channel(BaseChannel):
     9.4          (ty, subty) = self.getMessageType(msg)
     9.5          #todo:  Must respond before writing any more messages.
     9.6          #todo:  Should automate this (respond on write)
     9.7 -        self.port.write_response(msg)
     9.8 +        responded = 0
     9.9          dev = self.getDevice(ty)
    9.10          if dev:
    9.11 -            dev.requestReceived(msg, ty, subty)
    9.12 +            responded = dev.requestReceived(msg, ty, subty)
    9.13          else:
    9.14              print ("requestReceived> No device: Message type %s %d:%d"
    9.15                     % (msgTypeName(ty, subty), ty, subty)), self
    9.16 +        if not responded:
    9.17 +            self.port.write_response(msg)
    9.18  
    9.19      def handleResponses(self):
    9.20          work = 0
    10.1 --- a/tools/python/xen/xend/server/controller.py	Tue Aug 17 17:54:50 2004 +0000
    10.2 +++ b/tools/python/xen/xend/server/controller.py	Wed Aug 18 13:43:23 2004 +0000
    10.3 @@ -125,12 +125,14 @@ class CtrlMsgRcvr:
    10.4          if DEBUG:
    10.5              print 'requestReceived>',
    10.6              printMsg(msg, all=1)
    10.7 +        responded = 0
    10.8          method = self.getMethod(type, subtype)
    10.9          if method:
   10.10 -            method(msg, 1)
   10.11 +            responded = method(msg, 1)
   10.12          elif DEBUG:
   10.13              print ('requestReceived> No handler: Message type %s %d:%d'
   10.14                     % (msgTypeName(type, subtype), type, subtype)), self
   10.15 +        return responded
   10.16          
   10.17      def responseReceived(self, msg, type, subtype):
   10.18          """Dispatch a response to handlers.
   10.19 @@ -370,51 +372,78 @@ class Controller(CtrlMsgRcvr):
   10.20          self.deregisterChannel()
   10.21          self.factory.instanceClosed(self)
   10.22  
   10.23 -class SplitControllerFactory(ControllerFactory):
   10.24 -    """Factory for SplitControllers.
   10.25 +class BackendController(CtrlMsgRcvr):
   10.26 +    """Abstract class for a backend device controller attached to a domain.
   10.27 +
   10.28 +    @ivar controller: frontend controller
   10.29 +    @type controller: Controller
   10.30 +    @ivar dom:     domain
   10.31 +    @type dom:     int
   10.32 +    @ivar channel: channel to the domain
   10.33 +    @type channel: Channel
   10.34 +    """
   10.35 +
   10.36      
   10.37 -    @ivar backends:  mapping of domain id to backend
   10.38 -    @type backends:  {int: BackendController}
   10.39 -    """
   10.40 -    
   10.41 -    def __init__(self):
   10.42 -        ControllerFactory.__init__(self)
   10.43 -        self.backends = {}
   10.44 +    def __init__(self, controller, dom, handle):
   10.45 +        CtrlMsgRcvr.__init__(self)
   10.46 +        self.controller = controller
   10.47 +        self.dom = int(dom)
   10.48 +        self.handle = handle
   10.49 +        self.channel = None
   10.50 +        
   10.51 +    def close(self):
   10.52 +        self.lostChannel()
   10.53  
   10.54 -    def createInstance(self, dom, recreate=0, backend=0):
   10.55 -        """Create an instance. Define in a subclass.
   10.56 +    def lostChannel(self):
   10.57 +        self.deregisterChannel()
   10.58 +        self.controller.backendClosed(self)
   10.59 +        
   10.60 +class SplitController(Controller):
   10.61 +    """Abstract class for a device controller attached to a domain.
   10.62 +    A SplitController manages a BackendController for each backend domain
   10.63 +    it has at least one device for.
   10.64 +    """
   10.65  
   10.66 -        @param dom: domain
   10.67 -        @type  dom: int
   10.68 -        @param recreate: true if the instance is being recreated (after xend restart)
   10.69 -        @type  recreate: int
   10.70 -        @param backend: backend domain
   10.71 -        @type  backend: int
   10.72 -        @return: controller instance
   10.73 -        @rtype:  SplitController (or subclass)
   10.74 -        """
   10.75 -        raise NotImplementedError()
   10.76 +    def __init__(self, factory, dom):
   10.77 +        Controller.__init__(self, factory, dom)
   10.78 +        self.backends = {}
   10.79 +        self.backendHandle = 0
   10.80          
   10.81 -    def getBackendController(self, dom):
   10.82 +    def getBackends(self):
   10.83 +        return self.backends.values()
   10.84 +
   10.85 +    def getBackendByHandle(self, handle):
   10.86 +        for b in self.getBackends():
   10.87 +            if b.handle == handle:
   10.88 +                return b
   10.89 +        return None
   10.90 +
   10.91 +    def getBackendByDomain(self, dom):
   10.92 +        return self.backends.get(dom)
   10.93 +
   10.94 +    def getBackend(self, dom):
   10.95          """Get the backend controller for a domain.
   10.96  
   10.97          @param dom: domain
   10.98          @return: backend controller
   10.99          """
  10.100 -        ctrlr = self.backends.get(dom)
  10.101 -        if ctrlr is None:
  10.102 -            ctrlr = self.createBackendController(dom)
  10.103 -            self.backends[dom] = ctrlr
  10.104 -        return ctrlr
  10.105 +        b = self.getBackendByDomain(dom)
  10.106 +        if b is None:
  10.107 +            handle = self.backendHandle
  10.108 +            self.backendHandle += 1
  10.109 +            b = self.createBackend(dom, handle)
  10.110 +            self.backends[b.dom] = b
  10.111 +        return b
  10.112  
  10.113 -    def createBackendController(self, dom):
  10.114 +    def createBackend(self, dom, handle):
  10.115          """Create a backend controller. Define in a subclass.
  10.116  
  10.117          @param dom: domain
  10.118 +        @param handle: controller handle
  10.119          """
  10.120          raise NotImplementedError()
  10.121  
  10.122 -    def delBackendController(self, ctrlr):
  10.123 +    def delBackend(self, ctrlr):
  10.124          """Remove a backend controller.
  10.125  
  10.126          @param ctrlr: backend controller
  10.127 @@ -422,59 +451,11 @@ class SplitControllerFactory(ControllerF
  10.128          if ctrlr.dom in self.backends:
  10.129              del self.backends[ctrlr.dom]
  10.130  
  10.131 -    def backendControllerClosed(self, ctrlr):
  10.132 +    def backendClosed(self, ctrlr):
  10.133          """Callback called when a backend is closed.
  10.134          """
  10.135 -        self.delBackendController(ctrlr)
  10.136 -
  10.137 -class BackendController(CtrlMsgRcvr):
  10.138 -    """Abstract class for a backend device controller attached to a domain.
  10.139 -
  10.140 -    @ivar factory: controller factory
  10.141 -    @type factory: ControllerFactory
  10.142 -    @ivar dom:     domain
  10.143 -    @type dom:     int
  10.144 -    @ivar channel: channel to the domain
  10.145 -    @type channel: Channel
  10.146 -    """
  10.147 -
  10.148 -    
  10.149 -    def __init__(self, factory, dom):
  10.150 -        CtrlMsgRcvr.__init__(self)
  10.151 -        self.factory = factory
  10.152 -        self.dom = int(dom)
  10.153 -        self.channel = None
  10.154 +        self.delBackend(ctrlr)
  10.155          
  10.156 -    def close(self):
  10.157 -        self.lostChannel()
  10.158 -
  10.159 -    def lostChannel(self):
  10.160 -        self.deregisterChannel()
  10.161 -        self.factory.instanceClosed(self)
  10.162 -
  10.163 -
  10.164 -class SplitController(Controller):
  10.165 -    """Abstract class for a device controller attached to a domain.
  10.166 -    A SplitController has a BackendContoller.
  10.167 -    """
  10.168 -
  10.169 -    def __init__(self, factory, dom, backend):
  10.170 -        Controller.__init__(self, factory, dom)
  10.171 -        self.backendDomain = None
  10.172 -        self.backendController = None
  10.173 -        self.setBackendDomain(backend)
  10.174 -        
  10.175 -    def setBackendDomain(self, dom):
  10.176 -        ctrlr = self.factory.getBackendController(dom)
  10.177 -        self.backendDomain = ctrlr.dom
  10.178 -        self.backendController = ctrlr
  10.179 -
  10.180 -    def getBackendDomain(self):
  10.181 -        return self.backendDomain
  10.182 -
  10.183 -    def getBackendController(self):
  10.184 -        return self.backendController
  10.185 -
  10.186  class Dev:
  10.187      """Abstract class for a device attached to a device controller.
  10.188  
  10.189 @@ -515,4 +496,15 @@ class Dev:
  10.190          """
  10.191          raise NotImplementedError()
  10.192  
  10.193 +class SplitDev(Dev):
  10.194 +
  10.195 +    def __init__(self, idx, controller):
  10.196 +        Dev.__init__(self, idx, controller)
  10.197 +        self.backendDomain = 0
  10.198 +
  10.199 +    def getBackend(self):
  10.200 +        return self.controller.getBackend(self.backendDomain)
  10.201 +
  10.202 +
  10.203 +
  10.204      
    11.1 --- a/tools/python/xen/xend/server/messages.py	Tue Aug 17 17:54:50 2004 +0000
    11.2 +++ b/tools/python/xen/xend/server/messages.py	Wed Aug 18 13:43:23 2004 +0000
    11.3 @@ -215,7 +215,7 @@ def packMsg(ty, params):
    11.4          else:
    11.5              args[k] = v
    11.6      msg = xu.message(major, minor, msgid, args)
    11.7 -    if DEBUG: print '<packMsg', msg.get_header()['id'], ty, params
    11.8 +    if DEBUG: print '<packMsg', msg.get_header()['id'], ty, args
    11.9      return msg
   11.10  
   11.11  def unpackMsg(ty, msg):
   11.12 @@ -231,8 +231,9 @@ def unpackMsg(ty, msg):
   11.13      @rtype: dict
   11.14      """
   11.15      args = msg.get_payload()
   11.16 +    if DEBUG: print '>unpackMsg', args
   11.17      if isinstance(args, types.StringType):
   11.18 -        args = { 'value': args }
   11.19 +        args = {'value': args}
   11.20      else:
   11.21          mac = [0, 0, 0, 0, 0, 0]
   11.22          macs = []
   11.23 @@ -284,5 +285,5 @@ def printMsg(msg, out=sys.stdout, all=0)
   11.24      ty = msgTypeName(major, minor)
   11.25      print >>out, 'message:', 'type=', ty, '%d:%d' % (major, minor), 'id=%d' % msgid
   11.26      if all:
   11.27 -        print >>out, 'payload=', unpackMsg(ty, msg)
   11.28 +        print >>out, 'payload=', msg.get_payload()
   11.29  
    12.1 --- a/tools/python/xen/xend/server/netif.py	Tue Aug 17 17:54:50 2004 +0000
    12.2 +++ b/tools/python/xen/xend/server/netif.py	Wed Aug 18 13:43:23 2004 +0000
    12.3 @@ -22,45 +22,25 @@ class NetifBackendController(controller.
    12.4      """Handler for the 'back-end' channel to a device driver domain.
    12.5      """
    12.6      
    12.7 -    def __init__(self, factory, dom):
    12.8 -        controller.BackendController.__init__(self, factory, dom)
    12.9 +    def __init__(self, ctrl, dom, handle):
   12.10 +        controller.BackendController.__init__(self, ctrl, dom, handle)
   12.11          self.addMethod(CMSG_NETIF_BE,
   12.12                         CMSG_NETIF_BE_DRIVER_STATUS_CHANGED,
   12.13                         self.recv_be_driver_status_changed)
   12.14 -        self.attached = 1
   12.15          self.registerChannel()
   12.16  
   12.17 -    def respond_be_connect(self, msg):
   12.18 -        val = unpackMsg('netif_be_connect_t', msg)
   12.19 -        dom = val['domid']
   12.20 -        vif = val['netif_handle']
   12.21 -        netif = self.factory.getInstanceByDom(dom)
   12.22 -        if netif:
   12.23 -            netif.send_interface_connected(vif)
   12.24 -        else:
   12.25 -            log.warning("respond_be_connect> unknown vif dom=%d vif=%d", dom, vif)
   12.26 -            pass
   12.27 -
   12.28      def recv_be_driver_status_changed(self, msg, req):
   12.29          val = unpackMsg('netif_be_driver_status_changed_t', msg)
   12.30          status = val['status']
   12.31 -        if status == NETIF_DRIVER_STATUS_UP and not self.attached:
   12.32 -            # If we are not attached the driver domain was changed, and
   12.33 -            # this signals the new driver domain is ready.
   12.34 -            for netif in self.factory.getInstances():
   12.35 -                if netif.backendController == self:
   12.36 -                    netif.reattach_devices()
   12.37 -            self.attached = 1
   12.38  
   12.39 -class NetifControllerFactory(controller.SplitControllerFactory):
   12.40 +class NetifControllerFactory(controller.ControllerFactory):
   12.41      """Factory for creating network interface controllers.
   12.42      """
   12.43  
   12.44      def __init__(self):
   12.45          controller.ControllerFactory.__init__(self)
   12.46 -        self.attached = 1
   12.47  
   12.48 -    def createInstance(self, dom, recreate=0, backend=0):
   12.49 +    def createInstance(self, dom, recreate=0):
   12.50          """Create or find the network interface controller for a domain.
   12.51  
   12.52          @param dom:      domain
   12.53 @@ -69,7 +49,7 @@ class NetifControllerFactory(controller.
   12.54          """
   12.55          netif = self.getInstanceByDom(dom)
   12.56          if netif is None:
   12.57 -            netif = NetifController(self, dom, backend=backend)
   12.58 +            netif = NetifController(self, dom)
   12.59              self.addInstance(netif)
   12.60          return netif
   12.61  
   12.62 @@ -92,35 +72,12 @@ class NetifControllerFactory(controller.
   12.63          netif = self.getInstanceByDom(dom)
   12.64          return (netif and netif.getDevice(vif)) or None
   12.65          
   12.66 -    def createBackendController(self, dom):
   12.67 -        return NetifBackendController(self, dom)
   12.68 -
   12.69 -    def setControlDomain(self, dom, recreate=0):
   12.70 -        """Set the 'back-end' device driver domain.
   12.71 -
   12.72 -        @param dom:     domain
   12.73 -        @param recreate: if true this is a recreate (xend restarted)
   12.74 -        """
   12.75 -        if self.dom == dom: return
   12.76 -        self.deregisterChannel()
   12.77 -        if not recreate:
   12.78 -            self.attached = 0
   12.79 -        self.dom = dom
   12.80 -        self.registerChannel()
   12.81 -
   12.82 -    def getControlDomain(self):
   12.83 -        """Get the domain id of the back-end control domain.
   12.84 -
   12.85 -        @return domain id
   12.86 -        """
   12.87 -        return self.dom
   12.88 -
   12.89 -class NetDev(controller.Dev):
   12.90 +class NetDev(controller.SplitDev):
   12.91      """Info record for a network device.
   12.92      """
   12.93  
   12.94      def __init__(self, ctrl, vif, config):
   12.95 -        controller.Dev.__init__(self, vif, ctrl)
   12.96 +        controller.SplitDev.__init__(self, vif, ctrl)
   12.97          self.vif = vif
   12.98          self.evtchn = None
   12.99          self.configure(config)
  12.100 @@ -145,6 +102,11 @@ class NetDev(controller.Dev):
  12.101          for ipaddr in ipaddrs:
  12.102              self.ipaddr.append(sxp.child0(ipaddr))
  12.103          
  12.104 +        try:
  12.105 +            self.backendDomain = int(sxp.child_value(config, 'backend', '0'))
  12.106 +        except:
  12.107 +            raise XendError('invalid backend domain')
  12.108 +
  12.109      def sxpr(self):
  12.110          vif = str(self.vif)
  12.111          mac = self.get_mac()
  12.112 @@ -205,25 +167,90 @@ class NetDev(controller.Dev):
  12.113          if vnet:
  12.114              vnet.vifctl(op, self.get_vifname(), self.get_mac())
  12.115  
  12.116 +    def attach(self):
  12.117 +        print 'attach>'
  12.118 +        d = self.send_be_create()
  12.119 +        d.addCallback(self.respond_be_create)
  12.120 +        return d
  12.121 +
  12.122 +    def send_be_create(self):
  12.123 +        d = defer.Deferred()
  12.124 +        msg = packMsg('netif_be_create_t',
  12.125 +                      { 'domid'        : self.controller.dom,
  12.126 +                        'netif_handle' : self.vif,
  12.127 +                        'mac'          : self.mac })
  12.128 +        self.getBackend().writeRequest(msg, response=d)
  12.129 +        return d
  12.130 +
  12.131 +    def respond_be_create(self, msg):
  12.132 +        val = unpackMsg('netif_be_create_t', msg)
  12.133 +        print 'respond_be_create>', val
  12.134 +        return self
  12.135 +
  12.136      def destroy(self):
  12.137          """Destroy the device's resources and disconnect from the back-end
  12.138          device controller.
  12.139          """
  12.140          def cb_destroy(val):
  12.141 -            self.controller.send_be_destroy(self.vif)
  12.142 +            self.send_be_destroy()
  12.143          log.debug("Destroying vif domain=%d vif=%d", self.controller.dom, self.vif)
  12.144          self.vifctl('down')
  12.145 -        d = defer.Deferred()
  12.146 +        d = self.send_be_disconnect()
  12.147          d.addCallback(cb_destroy)
  12.148 -        self.controller.send_be_disconnect(self.vif, response=d)
  12.149 +
  12.150 +    def send_be_disconnect(self):
  12.151 +        d = defer.Deferred()
  12.152 +        msg = packMsg('netif_be_disconnect_t',
  12.153 +                      { 'domid'        : self.controller.dom,
  12.154 +                        'netif_handle' : self.vif })
  12.155 +        self.getBackend().writeRequest(msg, response=d)
  12.156 +        return d
  12.157 +
  12.158 +    def send_be_destroy(self, response=None):
  12.159 +        msg = packMsg('netif_be_destroy_t',
  12.160 +                      { 'domid'        : self.controller.dom,
  12.161 +                        'netif_handle' : self.vif })
  12.162 +        self.controller.delDevice(self.vif)
  12.163 +        self.getBackend().writeRequest(msg, response=response)
  12.164 +    
  12.165 +    def recv_fe_interface_connect(self, val, req):
  12.166 +        if not req: return
  12.167 +        self.evtchn = channel.eventChannel(0, self.controller.dom)
  12.168 +        msg = packMsg('netif_be_connect_t',
  12.169 +                      { 'domid'          : self.controller.dom,
  12.170 +                        'netif_handle'   : self.vif,
  12.171 +                        'evtchn'         : self.evtchn['port1'],
  12.172 +                        'tx_shmem_frame' : val['tx_shmem_frame'],
  12.173 +                        'rx_shmem_frame' : val['rx_shmem_frame'] })
  12.174 +        d = defer.Deferred()
  12.175 +        d.addCallback(self.respond_be_connect)
  12.176 +        self.getBackend().writeRequest(msg, response=d)
  12.177          
  12.178 +    def respond_be_connect(self, msg):
  12.179 +        val = unpackMsg('netif_be_connect_t', msg)
  12.180 +        dom = val['domid']
  12.181 +        vif = val['netif_handle']
  12.182 +        msg = packMsg('netif_fe_interface_status_changed_t',
  12.183 +                      { 'handle' : self.vif,
  12.184 +                        'status' : NETIF_INTERFACE_STATUS_CONNECTED,
  12.185 +                        'evtchn' : self.evtchn['port2'],
  12.186 +                        'mac'    : self.mac })
  12.187 +        self.controller.writeRequest(msg)
  12.188  
  12.189 +    def attach_fe_device(self):
  12.190 +        msg = packMsg('netif_fe_interface_status_changed_t',
  12.191 +                      { 'handle' : self.vif,
  12.192 +                        'status' : NETIF_INTERFACE_STATUS_DISCONNECTED,
  12.193 +                        'evtchn' : 0,
  12.194 +                        'mac'    : self.mac })
  12.195 +        self.controller.writeRequest(msg)
  12.196 +        
  12.197  class NetifController(controller.SplitController):
  12.198      """Network interface controller. Handles all network devices for a domain.
  12.199      """
  12.200      
  12.201 -    def __init__(self, factory, dom, backend):
  12.202 -        controller.SplitController.__init__(self, factory, dom, backend)
  12.203 +    def __init__(self, factory, dom):
  12.204 +        controller.SplitController.__init__(self, factory, dom)
  12.205          self.devices = {}
  12.206          self.addMethod(CMSG_NETIF_FE,
  12.207                         CMSG_NETIF_FE_DRIVER_STATUS_CHANGED,
  12.208 @@ -233,6 +260,9 @@ class NetifController(controller.SplitCo
  12.209                         self.recv_fe_interface_connect)
  12.210          self.registerChannel()
  12.211  
  12.212 +    def createBackend(self, dom, handle):
  12.213 +        return NetifBackendController(self, dom, handle)
  12.214 +
  12.215      def sxpr(self):
  12.216          val = ['netif', ['dom', self.dom]]
  12.217          return val
  12.218 @@ -262,10 +292,16 @@ class NetifController(controller.SplitCo
  12.219          @param config: device configuration 
  12.220          @return: device
  12.221          """
  12.222 +        if vif in self.devices:
  12.223 +            raise XendError('device exists:' + str(vif))
  12.224          dev = NetDev(self, vif, config)
  12.225          self.devices[vif] = dev
  12.226          return dev
  12.227  
  12.228 +    def delDevice(self, vif):
  12.229 +        if vif in self.devices:
  12.230 +            del self.devices[vif]
  12.231 +
  12.232      def destroy(self):
  12.233          """Destroy the controller and all devices.
  12.234          """
  12.235 @@ -285,79 +321,29 @@ class NetifController(controller.SplitCo
  12.236          @param recreate: recreate flag (true after xend restart)
  12.237          @return: deferred
  12.238          """
  12.239 -        self.addDevice(vif, config)
  12.240 -        d = defer.Deferred()
  12.241 +        dev = self.addDevice(vif, config)
  12.242          if recreate:
  12.243 -            d.callback(self)
  12.244 +            d = defer.succeed(dev)
  12.245          else:
  12.246 -            self.send_be_create(vif, response=d)
  12.247 +            d = dev.attach()
  12.248          return d
  12.249  
  12.250 -    def reattach_devices(self):
  12.251 -        """Reattach all devices when the back-end control domain has changed.
  12.252 -        """
  12.253 -        self.send_be_create(vif)
  12.254 -        self.attach_fe_devices()
  12.255 -
  12.256 -    def attach_fe_devices(self):
  12.257 -        for dev in self.devices.values():
  12.258 -            msg = packMsg('netif_fe_interface_status_changed_t',
  12.259 -                          { 'handle' : dev.vif,
  12.260 -                            'status' : NETIF_INTERFACE_STATUS_DISCONNECTED,
  12.261 -                            'evtchn' : 0,
  12.262 -                            'mac'    : dev.mac })
  12.263 -            self.writeRequest(msg)
  12.264 -    
  12.265      def recv_fe_driver_status_changed(self, msg, req):
  12.266          if not req: return
  12.267          msg = packMsg('netif_fe_driver_status_changed_t',
  12.268                        { 'status'        : NETIF_DRIVER_STATUS_UP,
  12.269                          'nr_interfaces' : len(self.devices) })
  12.270          self.writeRequest(msg)
  12.271 -        self.attach_fe_devices()
  12.272 -
  12.273 +        for dev in self.devices.values():
  12.274 +            dev.attach_fe_device()
  12.275 +    
  12.276      def recv_fe_interface_connect(self, msg, req):
  12.277          val = unpackMsg('netif_fe_interface_connect_t', msg)
  12.278 -        dev = self.devices[val['handle']]
  12.279 -        dev.evtchn = channel.eventChannel(0, self.dom)
  12.280 -        msg = packMsg('netif_be_connect_t',
  12.281 -                      { 'domid'          : self.dom,
  12.282 -                        'netif_handle'   : dev.vif,
  12.283 -                        'evtchn'         : dev.evtchn['port1'],
  12.284 -                        'tx_shmem_frame' : val['tx_shmem_frame'],
  12.285 -                        'rx_shmem_frame' : val['rx_shmem_frame'] })
  12.286 -        d = defer.Deferred()
  12.287 -        d.addCallback(self.backendController.respond_be_connect)
  12.288 -        self.backendController.writeRequest(msg, response=d)
  12.289 -
  12.290 -    def send_interface_connected(self, vif, response=None):
  12.291 -        dev = self.devices[vif]
  12.292 -        msg = packMsg('netif_fe_interface_status_changed_t',
  12.293 -                      { 'handle' : dev.vif,
  12.294 -                        'status' : NETIF_INTERFACE_STATUS_CONNECTED,
  12.295 -                        'evtchn' : dev.evtchn['port2'],
  12.296 -                        'mac'    : dev.mac })
  12.297 -        self.writeRequest(msg, response=response)
  12.298 +        vif = val['handle']
  12.299 +        dev = self.devices.get(vif)
  12.300 +        if dev:
  12.301 +            dev.recv_fe_interface_connect(val, req)
  12.302 +        else:
  12.303 +            log.error('Received netif_fe_interface_connect for unknown vif: dom=%d vif=%d',
  12.304 +                      self.dom, vif)
  12.305  
  12.306 -    def send_be_create(self, vif, response=None):
  12.307 -        dev = self.devices[vif]
  12.308 -        msg = packMsg('netif_be_create_t',
  12.309 -                      { 'domid'        : self.dom,
  12.310 -                        'netif_handle' : dev.vif,
  12.311 -                        'mac'          : dev.mac })
  12.312 -        self.backendController.writeRequest(msg, response=response)
  12.313 -
  12.314 -    def send_be_disconnect(self, vif, response=None):
  12.315 -        dev = self.devices[vif]
  12.316 -        msg = packMsg('netif_be_disconnect_t',
  12.317 -                      { 'domid'        : self.dom,
  12.318 -                        'netif_handle' : dev.vif })
  12.319 -        self.backendController.writeRequest(msg, response=response)
  12.320 -
  12.321 -    def send_be_destroy(self, vif, response=None):
  12.322 -        dev = self.devices[vif]
  12.323 -        del self.devices[vif]
  12.324 -        msg = packMsg('netif_be_destroy_t',
  12.325 -                      { 'domid'        : self.dom,
  12.326 -                        'netif_handle' : vif })
  12.327 -        self.backendController.writeRequest(msg, response=response)
    13.1 --- a/tools/python/xen/xm/create.py	Tue Aug 17 17:54:50 2004 +0000
    13.2 +++ b/tools/python/xen/xm/create.py	Wed Aug 18 13:43:23 2004 +0000
    13.3 @@ -126,19 +126,12 @@ gopts.var('netif', val='no|yes',
    13.4            fn=set_bool, default=0,
    13.5            use="Make the domain a network interface backend.")
    13.6  
    13.7 -gopts.var('vbd_backend', val='DOM',
    13.8 -          fn=set_value, default=None,
    13.9 -          use='Set the domain to use for the vbd backend.')
   13.10 -
   13.11 -gopts.var('vif_backend', val='DOM',
   13.12 -          fn=set_value, default=None,
   13.13 -          use='Set the domain to use for the vif backend.')
   13.14 -
   13.15 -gopts.var('disk', val='phy:DEV,VDEV,MODE',
   13.16 +gopts.var('disk', val='phy:DEV,VDEV,MODE[,DOM]',
   13.17            fn=append_value, default=[],
   13.18            use="""Add a disk device to a domain. The physical device is DEV,
   13.19           which is exported to the domain as VDEV. The disk is read-only if MODE
   13.20 -         is 'r', read-write if MODE is 'w'.
   13.21 +         is 'r', read-write if MODE is 'w'. If DOM is specified it defines the
   13.22 +         backend driver domain to use for the disk.
   13.23           The option may be repeated to add more than one disk.
   13.24           """)
   13.25  
   13.26 @@ -153,13 +146,14 @@ gopts.var('ipaddr', val="IPADDR",
   13.27            fn=append_value, default=[],
   13.28            use="Add an IP address to the domain.")
   13.29  
   13.30 -gopts.var('vif', val="mac=MAC,bridge=BRIDGE,script=SCRIPT",
   13.31 +gopts.var('vif', val="mac=MAC,bridge=BRIDGE,script=SCRIPT,backend=DOM",
   13.32            fn=append_value, default=[],
   13.33            use="""Add a network interface with the given MAC address and bridge.
   13.34           The vif is configured by calling the given configuration script.
   13.35           If mac is not specified a random MAC address is used.
   13.36           If bridge is not specified the default bridge is used.
   13.37           If script is not specified the default script is used.
   13.38 +         If backend is not specified the default backend driver domain is used.
   13.39           This option may be repeated to add more than one vif.
   13.40           Specifying vifs will increase the number of interfaces as needed.
   13.41           """)
   13.42 @@ -241,11 +235,13 @@ def configure_image(config, vals):
   13.43  def configure_disks(config_devs, vals):
   13.44      """Create the config for disks (virtual block devices).
   13.45      """
   13.46 -    for (uname, dev, mode) in vals.disk:
   13.47 +    for (uname, dev, mode, backend) in vals.disk:
   13.48          config_vbd = ['vbd',
   13.49                        ['uname', uname],
   13.50                        ['dev', dev ],
   13.51                        ['mode', mode ] ]
   13.52 +        if backend:
   13.53 +            config_vbd.append(['backend', backend])
   13.54          config_devs.append(['device', config_vbd])
   13.55  
   13.56  def configure_pci(config_devs, vals):
   13.57 @@ -285,16 +281,20 @@ def configure_vifs(config_devs, vals):
   13.58              mac = d.get('mac')
   13.59              bridge = d.get('bridge')
   13.60              script = d.get('script')
   13.61 +            backend = d.get('backend')
   13.62          else:
   13.63              mac = randomMAC()
   13.64              bridge = None
   13.65              script = None
   13.66 +            backend = None
   13.67          config_vif = ['vif']
   13.68          config_vif.append(['mac', mac])
   13.69          if bridge:
   13.70              config_vif.append(['bridge', bridge])
   13.71          if script:
   13.72              config_vif.append(['script', script])
   13.73 +        if backend:
   13.74 +            config_vif.append(['backend', backend])
   13.75          config_devs.append(['device', config_vif])
   13.76  
   13.77  def configure_vfr(config, vals):
   13.78 @@ -320,10 +320,6 @@ def make_config(vals):
   13.79          config.append(['backend', ['blkif']])
   13.80      if vals.netif:
   13.81          config.append(['backend', ['netif']])
   13.82 -    if vals.vbd_backend:
   13.83 -        config.append(['backend', ['vbd', ['dom', vals.vbd_backend]]])
   13.84 -    if vals.vif_backend:
   13.85 -        config.append(['backend', ['vif', ['dom', vals.vif_backend]]])
   13.86      if vals.restart:
   13.87          config.append(['restart', vals.restart])
   13.88      if vals.console:
   13.89 @@ -342,7 +338,12 @@ def preprocess_disk(opts, vals):
   13.90      disk = []
   13.91      for v in vals.disk:
   13.92          d = v.split(',')
   13.93 -        if len(d) != 3:
   13.94 +        n = len(d)
   13.95 +        if n == 3:
   13.96 +            d.append(None)
   13.97 +        elif n == 4:
   13.98 +            pass
   13.99 +        else:
  13.100              opts.err('Invalid disk specifier: ' + v)
  13.101          disk.append(d)
  13.102      vals.disk = disk
  13.103 @@ -369,7 +370,7 @@ def preprocess_vifs(opts, vals):
  13.104              (k, v) = b.strip().split('=', 1)
  13.105              k = k.strip()
  13.106              v = v.strip()
  13.107 -            if k not in ['mac', 'bridge']:
  13.108 +            if k not in ['mac', 'bridge', 'script', 'backend']:
  13.109                  opts.err('Invalid vif specifier: ' + vif)
  13.110              d[k] = v
  13.111          vifs.append(d)
    14.1 --- a/tools/python/xen/xm/main.py	Tue Aug 17 17:54:50 2004 +0000
    14.2 +++ b/tools/python/xen/xm/main.py	Wed Aug 18 13:43:23 2004 +0000
    14.3 @@ -305,7 +305,7 @@ class ProgMigrate(Prog):
    14.4          migrate.help([self.name] + args)
    14.5      
    14.6      def main(self, args):
    14.7 -        migrate.main([self.name] + args)
    14.8 +        migrate.main(args)
    14.9  
   14.10  xm.prog(ProgMigrate)
   14.11  
    15.1 --- a/tools/python/xen/xm/migrate.py	Tue Aug 17 17:54:50 2004 +0000
    15.2 +++ b/tools/python/xen/xm/migrate.py	Wed Aug 18 13:43:23 2004 +0000
    15.3 @@ -22,6 +22,10 @@ gopts.opt('help', short='h',
    15.4           fn=set_true, default=0,
    15.5           use="Print this help.")
    15.6  
    15.7 +gopts.opt('live', short='l',
    15.8 +          fn=set_true, default=0,
    15.9 +          use="Use live migration.")
   15.10 +
   15.11  def help(argv):
   15.12      gopts.argv = argv
   15.13      gopts.usage()
   15.14 @@ -33,10 +37,10 @@ def main(argv):
   15.15          opts.usage()
   15.16          return
   15.17      if len(args) != 2:
   15.18 -        opts.err('Invalid arguments')
   15.19 +        opts.err('Invalid arguments: ' + str(args))
   15.20      dom = args[0]
   15.21      dst = args[1]
   15.22      if dom in [DOM0_NAME, DOM0_ID]:
   15.23          opts.err('Cannot migrate ' + dom)
   15.24 -    server.xend_domain_migrate(dom, dst)
   15.25 +    server.xend_domain_migrate(dom, dst, opts.vals.live)
   15.26          
    16.1 --- a/tools/xfrd/xen_domain.c	Tue Aug 17 17:54:50 2004 +0000
    16.2 +++ b/tools/xfrd/xen_domain.c	Wed Aug 18 13:43:23 2004 +0000
    16.3 @@ -53,7 +53,10 @@ void xcfini(void){
    16.4   * At some point during this the domain is suspended, and then there's no way back.
    16.5   * Even if something later goes wrong we can't restart the domain.
    16.6   */
    16.7 -int xen_domain_snd(Conn *xend, IOStream *io, uint32_t dom, char *vmconfig, int vmconfig_n){
    16.8 +int xen_domain_snd(Conn *xend, IOStream *io,
    16.9 +                   uint32_t dom,
   16.10 +                   char *vmconfig, int vmconfig_n,
   16.11 +                   int live){
   16.12      int err = 0;
   16.13  #ifdef _XEN_XFR_STUB_
   16.14      char buf[1024];
   16.15 @@ -89,7 +92,9 @@ int xen_domain_snd(Conn *xend, IOStream 
   16.16      ioctxt->suspend = domain_suspend;
   16.17      ioctxt->vmconfig = vmconfig;
   16.18      ioctxt->vmconfig_n = vmconfig_n;
   16.19 -
   16.20 +    if(live){
   16.21 +        ioctxt->flags |= XCFLAGS_LIVE;
   16.22 +    }
   16.23      err = xc_linux_save(xcinit(), ioctxt);
   16.24  #endif   
   16.25      dprintf("< err=%d\n", err);
    17.1 --- a/tools/xfrd/xen_domain.h	Tue Aug 17 17:54:50 2004 +0000
    17.2 +++ b/tools/xfrd/xen_domain.h	Wed Aug 18 13:43:23 2004 +0000
    17.3 @@ -7,7 +7,10 @@
    17.4  /** Define to use stubs. Undefine to use Xen ops. */
    17.5  //#define _XEN_XFR_STUB_
    17.6  
    17.7 -extern int xen_domain_snd(Conn *xend, IOStream *io, uint32_t dom, char *vmconfig, int vmconfig_n);
    17.8 +extern int xen_domain_snd(Conn *xend, IOStream *io,
    17.9 +                          uint32_t dom,
   17.10 +                          char *vmconfig, int vmconfig_n,
   17.11 +                          int live);
   17.12  extern int xen_domain_rcv(IOStream *io, uint32_t *dom, char **vmconfig, int *vmconfig_n);
   17.13  
   17.14  
    18.1 --- a/tools/xfrd/xfrd.c	Tue Aug 17 17:54:50 2004 +0000
    18.2 +++ b/tools/xfrd/xfrd.c	Wed Aug 18 13:43:23 2004 +0000
    18.3 @@ -81,7 +81,7 @@ receiver:
    18.4          (xfr.hello <major> <minor>)
    18.5          (xfr.err <code> <reason>)
    18.6  
    18.7 -        xend->xfrd (xfr.migrate  <domain> <vmconfig> <host> <port>)
    18.8 +        xend->xfrd (xfr.migrate  <domain> <vmconfig> <host> <port> <live>)
    18.9                     (xfr.save <domain> <vmconfig> <file>)
   18.10          xfrd->xend (xfr.suspend <domain>)
   18.11          xfrd->xend (xfr.progress <percent> <rate: kb/s>)
   18.12 @@ -95,7 +95,7 @@ receiver:
   18.13  Sxpr oxfr_configure; // (xfr.configure <vmid> <vmconfig>)
   18.14  Sxpr oxfr_err;       // (xfr.err <code>)
   18.15  Sxpr oxfr_hello;     // (xfr.hello <major> <minor>)
   18.16 -Sxpr oxfr_migrate;   // (xfr.migrate <vmid> <vmconfig> <host> <port>)
   18.17 +Sxpr oxfr_migrate;   // (xfr.migrate <vmid> <vmconfig> <host> <port> <live>)
   18.18  Sxpr oxfr_migrate_ok;// (xfr.migrate.ok <value>)
   18.19  Sxpr oxfr_progress;  // (xfr.progress <percent> <rate: kb/s>)
   18.20  Sxpr oxfr_save;      // (xfr.save <vmid> <vmconfig> <file>)
   18.21 @@ -235,6 +235,7 @@ typedef struct XfrState {
   18.22      unsigned long xfr_port;
   18.23      char *xfr_host;
   18.24      uint32_t vmid_new;
   18.25 +    int live;
   18.26  } XfrState;
   18.27  
   18.28  /** Get the name of a transfer state.
   18.29 @@ -607,7 +608,9 @@ int xfr_send_state(XfrState *state, Conn
   18.30      if(err) goto exit;
   18.31      dprintf(">*** Sending domain %u\n", state->vmid);
   18.32      err = xen_domain_snd(xend, peer->out,
   18.33 -                         state->vmid, state->vmconfig, state->vmconfig_n);
   18.34 +                         state->vmid,
   18.35 +                         state->vmconfig, state->vmconfig_n,
   18.36 +                         state->live);
   18.37      dprintf(">*** Sent domain %u\n", state->vmid);
   18.38      if(err) goto exit;
   18.39      // Sending the domain suspends it, and there's no way back.
   18.40 @@ -752,7 +755,10 @@ int xfr_save(Args *args, XfrState *state
   18.41          err = -EINVAL;
   18.42          goto exit;
   18.43      }
   18.44 -    err = xen_domain_snd(xend, io, state->vmid, state->vmconfig, state->vmconfig_n);
   18.45 +    err = xen_domain_snd(xend, io,
   18.46 +                         state->vmid,
   18.47 +                         state->vmconfig, state->vmconfig_n,
   18.48 +                         0);
   18.49      if(err){
   18.50          err = xfr_error(xend, err);
   18.51      } else {
   18.52 @@ -852,6 +858,8 @@ int xfrd_service(Args *args, int peersoc
   18.53          if(err) goto exit;
   18.54          err = portof(sxpr_childN(sxpr, n++, ONONE), &port);
   18.55          if(err) goto exit;
   18.56 +        err = intof(sxpr_childN(sxpr, n++, ONONE), &state->live);
   18.57 +        if(err) goto exit;
   18.58          err = xfr_send(args, state, conn, addr, port);
   18.59  
   18.60      } else if(sxpr_elementp(sxpr, oxfr_save)){