ia64/xen-unstable

changeset 1677:7dcb491e6c4a

bitkeeper revision 1.1041.7.1 (40eaa1b63pn-AWBaQWrFszKHGANStQ)

Tidy up messaging to device backends.
Add message response handlers indexed by message id instead of
relying on a queue of deferreds.
Tidy up error handling so that deferred errors are caught.
author mjw@wray-m-3.hpl.hp.com
date Tue Jul 06 12:57:26 2004 +0000 (2004-07-06)
parents e56d5f41a977
children 35e97fc65a8b
files tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/XendMigrate.py tools/python/xen/xend/server/SrvBase.py tools/python/xen/xend/server/SrvDaemon.py tools/python/xen/xend/server/SrvDomainDir.py tools/python/xen/xend/server/blkif.py tools/python/xen/xend/server/controller.py tools/python/xen/xend/server/messages.py tools/python/xen/xend/server/netif.py
line diff
     1.1 --- a/tools/python/xen/xend/XendDomain.py	Mon Jul 05 16:23:43 2004 +0000
     1.2 +++ b/tools/python/xen/xend/XendDomain.py	Tue Jul 06 12:57:26 2004 +0000
     1.3 @@ -8,6 +8,7 @@ import sys
     1.4  import traceback
     1.5  
     1.6  from twisted.internet import defer
     1.7 +defer.Deferred.debug = 1
     1.8  from twisted.internet import reactor
     1.9  
    1.10  import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
     2.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Mon Jul 05 16:23:43 2004 +0000
     2.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Tue Jul 06 12:57:26 2004 +0000
     2.3 @@ -15,6 +15,7 @@ import sys
     2.4  import os
     2.5  
     2.6  from twisted.internet import defer
     2.7 +defer.Deferred.debug = 1
     2.8  
     2.9  import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
    2.10  import xen.util.ip
    2.11 @@ -430,14 +431,18 @@ class XendDomainInfo:
    2.12                  raise VmError('unknown image type: ' + image_name)
    2.13              image_handler(self, image)
    2.14              deferred = self.configure()
    2.15 +            def cbok(x):
    2.16 +                print 'vm_create> cbok', x
    2.17 +                return x
    2.18 +            def cberr(err):
    2.19 +                self.destroy()
    2.20 +                return err
    2.21 +            deferred.addCallback(cbok)
    2.22 +            deferred.addErrback(cberr)
    2.23          except StandardError, ex:
    2.24              # Catch errors, cleanup and re-raise.
    2.25              self.destroy()
    2.26              raise
    2.27 -        def cbok(x):
    2.28 -            print 'vm_create> cbok', x
    2.29 -            return x
    2.30 -        deferred.addCallback(cbok)
    2.31          print 'vm_create<'
    2.32          return deferred
    2.33  
    2.34 @@ -710,6 +715,10 @@ class XendDomainInfo:
    2.35              self.name = d['name']
    2.36              self.memory = d['memory']/1024
    2.37              deferred = self.configure()
    2.38 +            def cberr(err):
    2.39 +                self.destroy()
    2.40 +                return err
    2.41 +            deferred.addErrback(cberr)
    2.42          except StandardError, ex:
    2.43              self.destroy()
    2.44              raise
     3.1 --- a/tools/python/xen/xend/XendMigrate.py	Mon Jul 05 16:23:43 2004 +0000
     3.2 +++ b/tools/python/xen/xend/XendMigrate.py	Tue Jul 06 12:57:26 2004 +0000
     3.3 @@ -6,6 +6,7 @@ import time
     3.4  
     3.5  from twisted.internet import reactor
     3.6  from twisted.internet import defer
     3.7 +defer.Deferred.debug = 1
     3.8  from twisted.internet.protocol import Protocol
     3.9  from twisted.internet.protocol import ClientFactory
    3.10  
     4.1 --- a/tools/python/xen/xend/server/SrvBase.py	Mon Jul 05 16:23:43 2004 +0000
     4.2 +++ b/tools/python/xen/xend/server/SrvBase.py	Tue Jul 06 12:57:26 2004 +0000
     4.3 @@ -8,6 +8,7 @@ import types
     4.4  import StringIO
     4.5  
     4.6  from twisted.internet import defer
     4.7 +defer.Deferred.debug = 1
     4.8  from twisted.internet import reactor
     4.9  from twisted.web import error
    4.10  from twisted.web import resource
     5.1 --- a/tools/python/xen/xend/server/SrvDaemon.py	Mon Jul 05 16:23:43 2004 +0000
     5.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py	Tue Jul 06 12:57:26 2004 +0000
     5.3 @@ -23,6 +23,7 @@ from twisted.internet import reactor
     5.4  from twisted.internet import protocol
     5.5  from twisted.internet import abstract
     5.6  from twisted.internet import defer
     5.7 +defer.Deferred.debug = 1
     5.8  
     5.9  from xen.lowlevel import xu
    5.10  
     6.1 --- a/tools/python/xen/xend/server/SrvDomainDir.py	Mon Jul 05 16:23:43 2004 +0000
     6.2 +++ b/tools/python/xen/xend/server/SrvDomainDir.py	Tue Jul 06 12:57:26 2004 +0000
     6.3 @@ -63,7 +63,8 @@ class SrvDomainDir(SrvDir):
     6.4                                     "Invalid configuration")
     6.5          try:
     6.6              deferred = self.xd.domain_create(config)
     6.7 -            deferred.addCallback(self._cb_op_create, configstring, req)
     6.8 +            deferred.addCallback(self._op_create_cb, configstring, req)
     6.9 +            deferred.addErrback(self._op_create_err, req)
    6.10              return deferred
    6.11          except Exception, ex:
    6.12              print 'op_create> Exception creating domain:'
    6.13 @@ -75,7 +76,7 @@ class SrvDomainDir(SrvDir):
    6.14              #                       str(ex))
    6.15                                     
    6.16  
    6.17 -    def _cb_op_create(self, dominfo, configstring, req):
    6.18 +    def _op_create_cb(self, dominfo, configstring, req):
    6.19          """Callback to handle deferred domain creation.
    6.20          """
    6.21          dom = dominfo.id
    6.22 @@ -95,6 +96,13 @@ class SrvDomainDir(SrvDir):
    6.23              out.close()
    6.24              return val
    6.25  
    6.26 +    def _op_create_err(self, err, req):
    6.27 +        """Callback to handle errors in deferred domain creation.
    6.28 +        """
    6.29 +        print 'op_create> Deferred Exception creating domain:', err
    6.30 +        req.setResponseCode(http.BAD_REQUEST, "Error creating domain")
    6.31 +        return str(err)
    6.32 +
    6.33      def op_restore(self, op, req):
    6.34          """Restore a domain from file.
    6.35          """
     7.1 --- a/tools/python/xen/xend/server/blkif.py	Mon Jul 05 16:23:43 2004 +0000
     7.2 +++ b/tools/python/xen/xend/server/blkif.py	Tue Jul 06 12:57:26 2004 +0000
     7.3 @@ -1,6 +1,7 @@
     7.4  # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     7.5  
     7.6  from twisted.internet import defer
     7.7 +defer.Deferred.debug = 1
     7.8  
     7.9  from xen.xend import sxp
    7.10  from xen.xend import PrettyPrint
    7.11 @@ -20,10 +21,6 @@ class BlkifControllerFactory(controller.
    7.12          self.majorTypes = [ CMSG_BLKIF_BE ]
    7.13  
    7.14          self.subTypes = {
    7.15 -            CMSG_BLKIF_BE_CREATE     : self.recv_be_create,
    7.16 -            CMSG_BLKIF_BE_CONNECT    : self.recv_be_connect,
    7.17 -            CMSG_BLKIF_BE_VBD_CREATE : self.recv_be_vbd_create,
    7.18 -            CMSG_BLKIF_BE_VBD_GROW   : self.recv_be_vbd_grow,
    7.19              CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED: self.recv_be_driver_status_changed,
    7.20              }
    7.21          self.attached = 1
    7.22 @@ -35,17 +32,20 @@ class BlkifControllerFactory(controller.
    7.23          dom      domain
    7.24          recreate if true it's a recreate (after xend restart)
    7.25          """
    7.26 -        d = self.addDeferred()
    7.27 +        d = defer.Deferred()
    7.28          blkif = self.getInstanceByDom(dom)
    7.29          if blkif:
    7.30 -            self.callDeferred(blkif)
    7.31 +            d.callback(blkif)
    7.32          else:
    7.33              blkif = BlkifController(self, dom)
    7.34              self.addInstance(blkif)
    7.35              if recreate:
    7.36 -                self.callDeferred(blkif)
    7.37 +                d.callback(blkif)
    7.38              else:
    7.39 -                blkif.send_be_create()
    7.40 +                d1 = defer.Deferred()
    7.41 +                d1.addCallback(self.respond_be_create, d)
    7.42 +                d1.addErrback(d.errback)
    7.43 +                blkif.send_be_create(response=d1)
    7.44          return d
    7.45  
    7.46      def getDomainDevices(self, dom):
    7.47 @@ -117,14 +117,14 @@ class BlkifControllerFactory(controller.
    7.48          for blkif in self.getInstances():
    7.49              blkif.reattached()
    7.50  
    7.51 -    def recv_be_create(self, msg, req):
    7.52 -        #print 'recv_be_create>'
    7.53 +    def respond_be_create(self, msg, d):
    7.54 +        print 'respond_be_create>'
    7.55          val = unpackMsg('blkif_be_create_t', msg)
    7.56          blkif = self.getInstanceByDom(val['domid'])
    7.57 -        self.callDeferred(blkif)
    7.58 +        d.callback(blkif)
    7.59      
    7.60 -    def recv_be_connect(self, msg, req):
    7.61 -        #print 'recv_be_create>'
    7.62 +    def respond_be_connect(self, msg):
    7.63 +        print 'respond_be_connect>', self
    7.64          val = unpackMsg('blkif_be_connect_t', msg)
    7.65          blkif = self.getInstanceByDom(val['domid'])
    7.66          if blkif:
    7.67 @@ -132,25 +132,30 @@ class BlkifControllerFactory(controller.
    7.68          else:
    7.69              pass
    7.70      
    7.71 -    def recv_be_vbd_create(self, msg, req):
    7.72 -        #print 'recv_be_vbd_create>'
    7.73 +    def respond_be_vbd_create(self, msg, d):
    7.74 +        print 'recv_be_vbd_create>', self
    7.75          val = unpackMsg('blkif_be_vbd_create_t', msg)
    7.76          blkif = self.getInstanceByDom(val['domid'])
    7.77          if blkif:
    7.78 -            blkif.send_be_vbd_grow(val['vdevice'])
    7.79 +            d1 = defer.Deferred()
    7.80 +            d1.addCallback(self.respond_be_vbd_grow, d)
    7.81 +            if d: d1.addErrback(d.errback)
    7.82 +            blkif.send_be_vbd_grow(val['vdevice'], response=d1)
    7.83          else:
    7.84              pass
    7.85      
    7.86 -    def recv_be_vbd_grow(self, msg, req):
    7.87 -        #print 'recv_be_vbd_grow>'
    7.88 +    def respond_be_vbd_grow(self, msg, d):
    7.89 +        print 'recv_be_vbd_grow>', self
    7.90          val = unpackMsg('blkif_be_vbd_grow_t', msg)
    7.91          # Check status?
    7.92          if self.attached:
    7.93 -            self.callDeferred(0)
    7.94 +            if d:
    7.95 +                d.callback(0)
    7.96          else:
    7.97              self.reattachDevice(val['domid'], val['vdevice'])
    7.98  
    7.99      def recv_be_driver_status_changed(self, msg, req):
   7.100 +        print 'recv_be_driver_status_changed>', self, req
   7.101          val = unpackMsg('blkif_be_driver_status_changed_t', msg)
   7.102          status = val['status']
   7.103          if status == BLKIF_DRIVER_STATUS_UP and not self.attached:
   7.104 @@ -234,20 +239,22 @@ class BlkifController(controller.Control
   7.105          """
   7.106          dev = self.addDevice(vdev, mode, segment)
   7.107          if not dev: return -1
   7.108 +        d = defer.Deferred()
   7.109          if recreate:
   7.110 -            d = defer.Deferred()
   7.111              d.callback(self)
   7.112          else:
   7.113 -            self.send_be_vbd_create(vdev)
   7.114 -            d = self.factory.addDeferred()
   7.115 +            d1 = defer.Deferred()
   7.116 +            d1.addCallback(self.factory.respond_be_vbd_create, d)
   7.117 +            d1.addErrback(d.errback)
   7.118 +            self.send_be_vbd_create(vdev, response=d1)
   7.119          return d
   7.120  
   7.121      def destroy(self):
   7.122          def cb_destroy(val):
   7.123              self.send_be_destroy()
   7.124 -        d = self.factory.addDeferred()
   7.125 +        d = defer.Deferred()
   7.126          d.addCallback(cb_destroy)
   7.127 -        self.send_be_disconnect()
   7.128 +        self.send_be_disconnect(response=d)
   7.129  
   7.130      def destroyDevices(self):
   7.131          for dev in self.getDevices():
   7.132 @@ -259,7 +266,9 @@ class BlkifController(controller.Control
   7.133          self.attached = 0
   7.134          for dev in self.devices.values():
   7.135              dev.attached = 0
   7.136 -            self.send_be_vbd_create(vdev)
   7.137 +            d1 = defer.Deferred()
   7.138 +            d1.addCallback(self.factory.respond_be_vbd_create, None)
   7.139 +            self.send_be_vbd_create(vdev, response=d1)
   7.140  
   7.141      def reattachDevice(self, vdev):
   7.142          """Reattach a device, when the back-end control domain has changed.
   7.143 @@ -300,46 +309,47 @@ class BlkifController(controller.Control
   7.144                          'blkif_handle' : val['handle'],
   7.145                          'evtchn'       : self.evtchn['port1'],
   7.146                          'shmem_frame'  : val['shmem_frame'] })
   7.147 -        self.factory.writeRequest(msg)
   7.148 -        pass
   7.149 +        d = defer.Deferred()
   7.150 +        d.addCallback(self.factory.respond_be_connect)
   7.151 +        self.factory.writeRequest(msg, response=d)
   7.152  
   7.153 -    def send_fe_interface_status_changed(self):
   7.154 +    def send_fe_interface_status_changed(self, response=None):
   7.155          msg = packMsg('blkif_fe_interface_status_changed_t',
   7.156                        { 'handle' : 0,
   7.157                          'status' : BLKIF_INTERFACE_STATUS_CONNECTED,
   7.158                          'evtchn' : self.evtchn['port2'] })
   7.159 -        self.writeRequest(msg)
   7.160 +        self.writeRequest(msg, response=response)
   7.161  
   7.162 -    def send_be_create(self):
   7.163 +    def send_be_create(self, response=None):
   7.164          msg = packMsg('blkif_be_create_t',
   7.165                        { 'domid'        : self.dom,
   7.166                          'blkif_handle' : 0 })
   7.167 -        self.factory.writeRequest(msg)
   7.168 +        self.factory.writeRequest(msg, response=response)
   7.169  
   7.170 -    def send_be_disconnect(self):
   7.171 +    def send_be_disconnect(self, response=None):
   7.172          print '>BlkifController>send_be_disconnect>', 'dom=', self.dom
   7.173          msg = packMsg('blkif_be_disconnect_t',
   7.174                        { 'domid'        : self.dom,
   7.175                          'blkif_handle' : 0 })
   7.176 -        self.factory.writeRequest(msg)
   7.177 +        self.factory.writeRequest(msg, response=response)
   7.178  
   7.179 -    def send_be_destroy(self):
   7.180 +    def send_be_destroy(self, response=None):
   7.181          print '>BlkifController>send_be_destroy>', 'dom=', self.dom
   7.182          msg = packMsg('blkif_be_destroy_t',
   7.183                        { 'domid'        : self.dom,
   7.184                          'blkif_handle' : 0 })
   7.185 -        self.factory.writeRequest(msg)
   7.186 +        self.factory.writeRequest(msg, response=response)
   7.187  
   7.188 -    def send_be_vbd_create(self, vdev):
   7.189 +    def send_be_vbd_create(self, vdev, response=None):
   7.190          dev = self.devices[vdev]
   7.191          msg = packMsg('blkif_be_vbd_create_t',
   7.192                        { 'domid'        : self.dom,
   7.193                          'blkif_handle' : 0,
   7.194                          'vdevice'      : dev.vdev,
   7.195                          'readonly'     : dev.readonly() })
   7.196 -        self.factory.writeRequest(msg)
   7.197 +        self.factory.writeRequest(msg, response=response)
   7.198          
   7.199 -    def send_be_vbd_grow(self, vdev):
   7.200 +    def send_be_vbd_grow(self, vdev, response=None):
   7.201          dev = self.devices[vdev]
   7.202          msg = packMsg('blkif_be_vbd_grow_t',
   7.203                        { 'domid'                : self.dom,
   7.204 @@ -348,9 +358,9 @@ class BlkifController(controller.Control
   7.205                          'extent.device'        : dev.device,
   7.206                          'extent.sector_start'  : dev.start_sector,
   7.207                          'extent.sector_length' : dev.nr_sectors })
   7.208 -        self.factory.writeRequest(msg)
   7.209 +        self.factory.writeRequest(msg, response=response)
   7.210  
   7.211 -    def send_be_vbd_destroy(self, vdev):
   7.212 +    def send_be_vbd_destroy(self, vdev, response=None):
   7.213          print '>BlkifController>send_be_vbd_destroy>', 'dom=', self.dom, 'vdev=', vdev
   7.214          PrettyPrint.prettyprint(self.sxpr())
   7.215          dev = self.devices[vdev]
   7.216 @@ -359,5 +369,5 @@ class BlkifController(controller.Control
   7.217                          'blkif_handle'         : 0,
   7.218                          'vdevice'              : dev.vdev })
   7.219          del self.devices[vdev]
   7.220 -        self.factory.writeRequest(msg)
   7.221 +        self.factory.writeRequest(msg, response=response)
   7.222      
     8.1 --- a/tools/python/xen/xend/server/controller.py	Mon Jul 05 16:23:43 2004 +0000
     8.2 +++ b/tools/python/xen/xend/server/controller.py	Tue Jul 06 12:57:26 2004 +0000
     8.3 @@ -1,10 +1,39 @@
     8.4  # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     8.5  
     8.6  from twisted.internet import defer
     8.7 +defer.Deferred.debug = 1
     8.8  
     8.9  import channel
    8.10  from messages import msgTypeName
    8.11  
    8.12 +DEBUG=0
    8.13 +
    8.14 +class OutOfOrderError(RuntimeError):
    8.15 +    """Error reported when a response arrives out of order.
    8.16 +    """
    8.17 +    pass
    8.18 +
    8.19 +class Responder:
    8.20 +    """Handler for a response to a message.
    8.21 +    """
    8.22 +
    8.23 +    def __init__(self, mid, deferred):
    8.24 +        """Create a responder.
    8.25 +
    8.26 +        mid      message id of response to handle
    8.27 +        deferred deferred object holding the callbacks
    8.28 +        """
    8.29 +        self.mid = mid
    8.30 +        self.deferred = deferred
    8.31 +
    8.32 +    def responseReceived(self, msg):
    8.33 +        if self.deferred.called: return
    8.34 +        self.deferred.callback(msg)
    8.35 +
    8.36 +    def error(self, err):
    8.37 +        if self.deferred.called: return
    8.38 +        self.deferred.errback(err)
    8.39 +
    8.40  class CtrlMsgRcvr:
    8.41      """Abstract class for things that deal with a control interface to a domain.
    8.42  
    8.43 @@ -26,6 +55,12 @@ class CtrlMsgRcvr:
    8.44          self.dom = None
    8.45          self.channel = None
    8.46          self.idx = None
    8.47 +        self.responders = []
    8.48 +        # Timeout (in seconds) for deferreds.
    8.49 +        self.timeout = 10
    8.50 +
    8.51 +    def setTimeout(self, timeout):
    8.52 +        self.timeout = timeout
    8.53  
    8.54      def requestReceived(self, msg, type, subtype):
    8.55          """Dispatch a request to handlers.
    8.56 @@ -34,10 +69,13 @@ class CtrlMsgRcvr:
    8.57          type    major message type
    8.58          subtype minor message type
    8.59          """
    8.60 +        msgid = msg.get_header()['id']
    8.61 +        if DEBUG:
    8.62 +            print 'requestReceived>', self, msgid, msgTypeName(type, subtype)
    8.63          method = self.subTypes.get(subtype)
    8.64          if method:
    8.65              method(msg, 1)
    8.66 -        else:
    8.67 +        elif DEBUG:
    8.68              print ('requestReceived> No handler: Message type %s %d:%d'
    8.69                     % (msgTypeName(type, subtype), type, subtype)), self
    8.70          
    8.71 @@ -48,13 +86,61 @@ class CtrlMsgRcvr:
    8.72          type    major message type
    8.73          subtype minor message type
    8.74          """
    8.75 +        msgid = msg.get_header()['id']
    8.76 +        if DEBUG:
    8.77 +            print 'responseReceived>', self, msgid, msgTypeName(type, subtype)
    8.78 +        if self.callResponders(msg):
    8.79 +            return
    8.80          method = self.subTypes.get(subtype)
    8.81          if method:
    8.82              method(msg, 0)
    8.83 -        else:
    8.84 +        elif DEBUG:
    8.85              print ('responseReceived> No handler: Message type %s %d:%d'
    8.86                     % (msgTypeName(type, subtype), type, subtype)), self
    8.87  
    8.88 +    def addResponder(self, mid, deferred):
    8.89 +        """Add a responder for a message id.
    8.90 +        The deferred is called with callback(msg) when a response
    8.91 +        with the given message id arrives. Responses are expected
    8.92 +        to arrive in order of message id. When a response arrives,
    8.93 +        waiting responders for messages with lower id have errback
    8.94 +        called with an OutOfOrder error.
    8.95 +
    8.96 +        mid      message id of response expected
    8.97 +        deferred a Deferred to handle the response
    8.98 +
    8.99 +        returns Responder
   8.100 +        """
   8.101 +        if self.timeout > 0:
   8.102 +            deferred.setTimeout(self.timeout)
   8.103 +        resp = Responder(mid, deferred)
   8.104 +        self.responders.append(resp)
   8.105 +        return resp
   8.106 +
   8.107 +    def callResponders(self, msg):
   8.108 +        """Call any waiting responders for a response message.
   8.109 +
   8.110 +        msg     response message
   8.111 +        
   8.112 +        returns 1 if there was a responder for the message, 0 otherwise
   8.113 +        """
   8.114 +        hdr = msg.get_header()
   8.115 +        mid = hdr['id']
   8.116 +        handled = 0
   8.117 +        while self.responders:
   8.118 +            resp = self.responders[0]
   8.119 +            if resp.mid > mid:
   8.120 +                break
   8.121 +            self.responders.pop()
   8.122 +            if resp.mid < mid:
   8.123 +                print 'handleResponse> Out of order:', resp.mid, mid
   8.124 +                resp.error(OutOfOrderError())
   8.125 +            else:
   8.126 +                handled = 1
   8.127 +                resp.responseReceived(msg)
   8.128 +                break
   8.129 +        return handled
   8.130 +
   8.131      def lostChannel(self):
   8.132          """Called when the channel to the domain is lost.
   8.133          """
   8.134 @@ -64,7 +150,6 @@ class CtrlMsgRcvr:
   8.135          """Register interest in our major message types with the
   8.136          channel to our domain.
   8.137          """
   8.138 -        #print 'CtrlMsgRcvr>registerChannel>', self
   8.139          self.channel = self.channelFactory.domChannel(self.dom)
   8.140          self.idx = self.channel.getIndex()
   8.141          if self.majorTypes:
   8.142 @@ -74,7 +159,6 @@ class CtrlMsgRcvr:
   8.143          """Deregister interest in our major message types with the
   8.144          channel to our domain.
   8.145          """
   8.146 -        #print 'CtrlMsgRcvr>deregisterChannel>', self
   8.147          if self.channel:
   8.148              self.channel.deregisterDevice(self)
   8.149              del self.channel
   8.150 @@ -86,10 +170,16 @@ class CtrlMsgRcvr:
   8.151          """
   8.152          return 0
   8.153  
   8.154 -    def writeRequest(self, msg):
   8.155 +    def writeRequest(self, msg, response=None):
   8.156          """Write a request to the channel.
   8.157 +
   8.158 +        msg      message
   8.159 +        response Deferred to handle the response (optional)
   8.160          """
   8.161          if self.channel:
   8.162 +            if DEBUG: print 'CtrlMsgRcvr>writeRequest>', self, msg
   8.163 +            if response:
   8.164 +                self.addResponder(msg.get_header()['id'], response)
   8.165              self.channel.writeRequest(msg)
   8.166          else:
   8.167              print 'CtrlMsgRcvr>writeRequest>', 'no channel!', self
   8.168 @@ -98,6 +188,7 @@ class CtrlMsgRcvr:
   8.169          """Write a response to the channel.
   8.170          """
   8.171          if self.channel:
   8.172 +            if DEBUG: print 'CtrlMsgRcvr>writeResponse>', self, msg
   8.173              self.channel.writeResponse(msg)
   8.174          else:
   8.175              print 'CtrlMsgRcvr>writeResponse>', 'no channel!', self
   8.176 @@ -111,7 +202,6 @@ class ControllerFactory(CtrlMsgRcvr):
   8.177      instances : mapping of index to controller instance
   8.178      dlist     : list of deferreds
   8.179      dom       : domain
   8.180 -    timeout   : deferred timeout
   8.181      """
   8.182  
   8.183      def __init__(self):
   8.184 @@ -119,8 +209,6 @@ class ControllerFactory(CtrlMsgRcvr):
   8.185          self.instances = {}
   8.186          self.dlist = []
   8.187          self.dom = 0
   8.188 -        # Timeout (in seconds) for deferreds.
   8.189 -        self.timeout = 10
   8.190          
   8.191      def addInstance(self, instance):
   8.192          """Add a controller instance (under its index).
   8.193 @@ -161,38 +249,6 @@ class ControllerFactory(CtrlMsgRcvr):
   8.194          """
   8.195          self.delInstance(instance)
   8.196  
   8.197 -    def addDeferred(self):
   8.198 -        """Add a deferred object.
   8.199 -
   8.200 -        returns deferred
   8.201 -        """
   8.202 -        d = defer.Deferred()
   8.203 -        if self.timeout > 0:
   8.204 -            # The deferred will error if not called before timeout.
   8.205 -            d.setTimeout(self.timeout)
   8.206 -        self.dlist.append(d)
   8.207 -        return d
   8.208 -
   8.209 -    def callDeferred(self, *args):
   8.210 -        """Call the top deferred object
   8.211 -
   8.212 -        args arguments
   8.213 -        """
   8.214 -        if self.dlist:
   8.215 -            d = self.dlist.pop(0)
   8.216 -            if not d.called:
   8.217 -                d.callback(*args)
   8.218 -
   8.219 -    def errDeferred(self, *args):
   8.220 -        """Signal an error to the top deferred object.
   8.221 -
   8.222 -        args arguments
   8.223 -        """
   8.224 -        if self.dlist:
   8.225 -            d = self.dlist.pop(0)
   8.226 -            if not d.called:
   8.227 -                d.errback(*args)
   8.228 -
   8.229  class Controller(CtrlMsgRcvr):
   8.230      """Abstract class for a device controller attached to a domain.
   8.231      """
     9.1 --- a/tools/python/xen/xend/server/messages.py	Mon Jul 05 16:23:43 2004 +0000
     9.2 +++ b/tools/python/xen/xend/server/messages.py	Tue Jul 06 12:57:26 2004 +0000
     9.3 @@ -179,6 +179,12 @@ msg_formats.update(shutdown_formats)
     9.4  class Msg:
     9.5      pass
     9.6  
     9.7 +_next_msgid = 0
     9.8 +
     9.9 +def nextid():
    9.10 +    global _next_msgid
    9.11 +    return ++_next_msgid
    9.12 +
    9.13  def packMsg(ty, params):
    9.14      """Pack a message.
    9.15      Any 'mac' parameter is passed in as an int[6] array and converted.
    9.16 @@ -188,7 +194,8 @@ def packMsg(ty, params):
    9.17  
    9.18      returns xu message
    9.19      """
    9.20 -    if DEBUG: print '>packMsg', ty, params
    9.21 +    msgid = nextid()
    9.22 +    if DEBUG: print '>packMsg', msgid, ty, params
    9.23      (major, minor) = msg_formats[ty]
    9.24      args = {}
    9.25      for (k, v) in params.items():
    9.26 @@ -200,7 +207,6 @@ def packMsg(ty, params):
    9.27      if DEBUG:
    9.28          for (k, v) in args.items():
    9.29              print 'packMsg>', k, v, type(v)
    9.30 -    msgid = 0
    9.31      msg = xu.message(major, minor, msgid, args)
    9.32      return msg
    9.33  
    9.34 @@ -228,7 +234,9 @@ def unpackMsg(ty, msg):
    9.35          args['mac'] = mac
    9.36          for k in macs:
    9.37              del args[k]
    9.38 -    if DEBUG: print '<unpackMsg', ty, args
    9.39 +    if DEBUG:
    9.40 +        msgid = msg.get_header()['id']
    9.41 +        print '<unpackMsg', msgid, ty, args
    9.42      return args
    9.43  
    9.44  def msgTypeName(ty, subty):
    10.1 --- a/tools/python/xen/xend/server/netif.py	Mon Jul 05 16:23:43 2004 +0000
    10.2 +++ b/tools/python/xen/xend/server/netif.py	Tue Jul 06 12:57:26 2004 +0000
    10.3 @@ -3,6 +3,7 @@
    10.4  import random
    10.5  
    10.6  from twisted.internet import defer
    10.7 +defer.Deferred.debug = 1
    10.8  
    10.9  from xen.xend import sxp
   10.10  from xen.xend import PrettyPrint
   10.11 @@ -23,8 +24,8 @@ class NetifControllerFactory(controller.
   10.12          self.majorTypes = [ CMSG_NETIF_BE ]
   10.13  
   10.14          self.subTypes = {
   10.15 -            CMSG_NETIF_BE_CREATE : self.recv_be_create,
   10.16 -            CMSG_NETIF_BE_CONNECT: self.recv_be_connect,
   10.17 +            #CMSG_NETIF_BE_CREATE : self.recv_be_create,
   10.18 +            #CMSG_NETIF_BE_CONNECT: self.recv_be_connect,
   10.19              CMSG_NETIF_BE_DRIVER_STATUS_CHANGED: self.recv_be_driver_status_changed,
   10.20              }
   10.21          self.attached = 1
   10.22 @@ -83,10 +84,7 @@ class NetifControllerFactory(controller.
   10.23          """
   10.24          return self.dom
   10.25  
   10.26 -    def recv_be_create(self, msg, req):
   10.27 -        self.callDeferred(0)
   10.28 -    
   10.29 -    def recv_be_connect(self, msg, req):
   10.30 +    def respond_be_connect(self, msg):
   10.31          val = unpackMsg('netif_be_connect_t', msg)
   10.32          dom = val['domid']
   10.33          vif = val['netif_handle']
   10.34 @@ -94,7 +92,7 @@ class NetifControllerFactory(controller.
   10.35          if netif:
   10.36              netif.send_interface_connected(vif)
   10.37          else:
   10.38 -            print "recv_be_connect> unknown vif=", vif
   10.39 +            print "respond_be_connect> unknown vif=", vif
   10.40              pass
   10.41  
   10.42      def recv_be_driver_status_changed(self, msg, req):
   10.43 @@ -168,9 +166,10 @@ class NetDev(controller.Dev):
   10.44          def cb_destroy(val):
   10.45              self.controller.send_be_destroy(self.vif)
   10.46          self.down()
   10.47 -        d = self.controller.factory.addDeferred()
   10.48 +        #d = self.controller.factory.addDeferred()
   10.49 +        d = defer.Deferred()
   10.50          d.addCallback(cb_destroy)
   10.51 -        self.controller.send_be_disconnect(self.vif)
   10.52 +        self.controller.send_be_disconnect(self.vif, response=d)
   10.53          
   10.54  
   10.55  class NetifController(controller.Controller):
   10.56 @@ -268,20 +267,19 @@ class NetifController(controller.Control
   10.57          @param vmac mac address (string)
   10.58          """
   10.59          self.addDevice(vif, vmac)
   10.60 +        d = defer.Deferred()
   10.61          if recreate:
   10.62 -            d = defer.Deferred()
   10.63              d.callback(self)
   10.64          else:
   10.65 -            d = self.factory.addDeferred()
   10.66 -            self.send_be_create(vif)
   10.67 +            self.send_be_create(vif, response=d)
   10.68          return d
   10.69  
   10.70      def reattach_devices(self):
   10.71          """Reattach all devices when the back-end control domain has changed.
   10.72          """
   10.73 -        d = self.factory.addDeferred()
   10.74 +        #d = self.factory.addDeferred()
   10.75          self.send_be_create(vif)
   10.76 -        self.attach_fe_devices(0)
   10.77 +        self.attach_fe_devices()
   10.78  
   10.79      def attach_fe_devices(self):
   10.80          for dev in self.devices.values():
   10.81 @@ -310,37 +308,39 @@ class NetifController(controller.Control
   10.82                          'evtchn'         : dev.evtchn['port1'],
   10.83                          'tx_shmem_frame' : val['tx_shmem_frame'],
   10.84                          'rx_shmem_frame' : val['rx_shmem_frame'] })
   10.85 -        self.factory.writeRequest(msg)
   10.86 +        d = defer.Deferred()
   10.87 +        d.addCallback(self.factory.respond_be_connect)
   10.88 +        self.factory.writeRequest(msg, response=d)
   10.89  
   10.90 -    def send_interface_connected(self, vif):
   10.91 +    def send_interface_connected(self, vif, response=None):
   10.92          dev = self.devices[vif]
   10.93          msg = packMsg('netif_fe_interface_status_changed_t',
   10.94                        { 'handle' : dev.vif,
   10.95                          'status' : NETIF_INTERFACE_STATUS_CONNECTED,
   10.96                          'evtchn' : dev.evtchn['port2'],
   10.97                          'mac'    : dev.mac })
   10.98 -        self.writeRequest(msg)
   10.99 +        self.writeRequest(msg, response=response)
  10.100  
  10.101 -    def send_be_create(self, vif):
  10.102 +    def send_be_create(self, vif, response=None):
  10.103          dev = self.devices[vif]
  10.104          msg = packMsg('netif_be_create_t',
  10.105                        { 'domid'        : self.dom,
  10.106                          'netif_handle' : dev.vif,
  10.107                          'mac'          : dev.mac })
  10.108 -        self.factory.writeRequest(msg)
  10.109 +        self.factory.writeRequest(msg, response=response)
  10.110  
  10.111 -    def send_be_disconnect(self, vif):
  10.112 +    def send_be_disconnect(self, vif, response=None):
  10.113          dev = self.devices[vif]
  10.114          msg = packMsg('netif_be_disconnect_t',
  10.115                        { 'domid'        : self.dom,
  10.116                          'netif_handle' : dev.vif })
  10.117 -        self.factory.writeRequest(msg)
  10.118 +        self.factory.writeRequest(msg, response=response)
  10.119  
  10.120 -    def send_be_destroy(self, vif):
  10.121 +    def send_be_destroy(self, vif, response=None):
  10.122          PrettyPrint.prettyprint(self.sxpr())
  10.123          dev = self.devices[vif]
  10.124          del self.devices[vif]
  10.125          msg = packMsg('netif_be_destroy_t',
  10.126                        { 'domid'        : self.dom,
  10.127                          'netif_handle' : vif })
  10.128 -        self.factory.writeRequest(msg)
  10.129 +        self.factory.writeRequest(msg, response=response)