ia64/xen-unstable

changeset 1654:90b354900bbf

bitkeeper revision 1.1041.3.1 (40e3fe2a5JO0HpkIeSaP8q6IITbNAQ)

Documentation and a couple of tidies.
author mjw@wray-m-3.hpl.hp.com
date Thu Jul 01 12:06:02 2004 +0000 (2004-07-01)
parents b4bc38d3acd4
children 6edc06968b87
files tools/python/xen/xend/server/SrvDomainDir.py tools/python/xen/xend/server/blkif.py tools/python/xen/xend/server/channel.py tools/python/xen/xend/server/console.py tools/python/xen/xend/server/controller.py tools/python/xen/xend/server/domain.py tools/python/xen/xend/server/messages.py tools/python/xen/xend/server/netif.py
line diff
     1.1 --- a/tools/python/xen/xend/server/SrvDomainDir.py	Thu Jul 01 10:20:24 2004 +0000
     1.2 +++ b/tools/python/xen/xend/server/SrvDomainDir.py	Thu Jul 01 12:06:02 2004 +0000
     1.3 @@ -1,5 +1,6 @@
     1.4  # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     1.5  
     1.6 +import traceback
     1.7  from StringIO import StringIO
     1.8  
     1.9  from twisted.protocols import http
    1.10 @@ -24,6 +25,7 @@ class SrvDomainDir(SrvDir):
    1.11          val = None
    1.12          try:
    1.13              dom = self.xd.domain_get(x)
    1.14 +            if not dom: raise KeyError('No such domain')
    1.15              val = SrvDomain(dom)
    1.16          except KeyError, ex:
    1.17              print 'SrvDomainDir>', ex
    1.18 @@ -38,6 +40,9 @@ class SrvDomainDir(SrvDir):
    1.19          return v
    1.20  
    1.21      def op_create(self, op, req):
    1.22 +        """Create a domain.
    1.23 +        Expects the domain config in request parameter 'config' in SXP format.
    1.24 +        """
    1.25          ok = 0
    1.26          try:
    1.27              configstring = req.args.get('config')[0]
    1.28 @@ -48,7 +53,8 @@ class SrvDomainDir(SrvDir):
    1.29              config = pin.get_val()
    1.30              ok = 1
    1.31          except Exception, ex:
    1.32 -            print 'op_create>', ex
    1.33 +            print 'op_create> Exception in config', ex
    1.34 +            traceback.print_exc()
    1.35          if not ok:
    1.36              req.setResponseCode(http.BAD_REQUEST, "Invalid configuration")
    1.37              return "Invalid configuration"
    1.38 @@ -60,10 +66,10 @@ class SrvDomainDir(SrvDir):
    1.39              deferred.addCallback(self._cb_op_create, configstring, req)
    1.40              return deferred
    1.41          except Exception, ex:
    1.42 -            raise
    1.43 -            #return ['err', str(ex) ]
    1.44 -            #req.setResponseCode(http.BAD_REQUEST, "Error creating domain")
    1.45 -            #return str(ex)
    1.46 +            print 'op_create> Exception creating domain:'
    1.47 +            traceback.print_exc()
    1.48 +            req.setResponseCode(http.BAD_REQUEST, "Error creating domain")
    1.49 +            return str(ex)
    1.50              #return error.ErrorPage(http.BAD_REQUEST,
    1.51              #                       "Error creating domain",
    1.52              #                       str(ex))
    1.53 @@ -90,6 +96,8 @@ class SrvDomainDir(SrvDir):
    1.54              return val
    1.55  
    1.56      def op_restore(self, op, req):
    1.57 +        """Restore a domain from file.
    1.58 +        """
    1.59          fn = FormFn(self.xd.domain_restore,
    1.60                      [['file', 'str']])
    1.61          val = fn(req.args)
    1.62 @@ -131,6 +139,8 @@ class SrvDomainDir(SrvDir):
    1.63              req.write('</ul>')
    1.64  
    1.65      def form(self, req):
    1.66 +        """Generate the form(s) for domain dir operations.
    1.67 +        """
    1.68          req.write('<form method="post" action="%s" enctype="multipart/form-data">'
    1.69                    % req.prePathURL())
    1.70          req.write('<button type="submit" name="op" value="create">Create Domain</button>')
     2.1 --- a/tools/python/xen/xend/server/blkif.py	Thu Jul 01 10:20:24 2004 +0000
     2.2 +++ b/tools/python/xen/xend/server/blkif.py	Thu Jul 01 12:06:02 2004 +0000
     2.3 @@ -1,3 +1,5 @@
     2.4 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     2.5 +
     2.6  from twisted.internet import defer
     2.7  
     2.8  from xen.xend import sxp
     2.9 @@ -28,6 +30,11 @@ class BlkifControllerFactory(controller.
    2.10          self.registerChannel()
    2.11  
    2.12      def createInstance(self, dom, recreate=0):
    2.13 +        """Create a block device controller for a domain.
    2.14 +
    2.15 +        dom      domain
    2.16 +        recreate if true it's a recreate (after xend restart)
    2.17 +        """
    2.18          d = self.addDeferred()
    2.19          blkif = self.getInstanceByDom(dom)
    2.20          if blkif:
    2.21 @@ -42,29 +49,50 @@ class BlkifControllerFactory(controller.
    2.22          return d
    2.23  
    2.24      def getDomainDevices(self, dom):
    2.25 +        """Get the block devices for a domain.
    2.26 +
    2.27 +        dom domain
    2.28 +
    2.29 +        returns devices
    2.30 +        """
    2.31          blkif = self.getInstanceByDom(dom)
    2.32          return (blkif and blkif.getDevices()) or []
    2.33  
    2.34      def getDomainDevice(self, dom, vdev):
    2.35 +        """Get a block device from a domain.
    2.36 +
    2.37 +        dom  domain
    2.38 +        vdev device index
    2.39 +
    2.40 +        returns device
    2.41 +        """
    2.42          blkif = self.getInstanceByDom(dom)
    2.43          return (blkif and blkif.getDevice(vdev)) or None
    2.44  
    2.45      def setControlDomain(self, dom, recreate=0):
    2.46 +        """Set the back-end block device controller domain.
    2.47 +
    2.48 +        dom      domain
    2.49 +        recreate if true it's a recreate (after xend restart)
    2.50 +        """
    2.51          if self.dom == dom: return
    2.52          self.deregisterChannel()
    2.53          if not recreate:
    2.54              self.attached = 0
    2.55          self.dom = dom
    2.56          self.registerChannel()
    2.57 -        #
    2.58 -        #if xend.blkif.be_port:
    2.59 -        #    xend.blkif.recovery = True
    2.60 -        #xend.blkif.be_port = xend.main.port_from_dom(dom)
    2.61  
    2.62      def getControlDomain(self):
    2.63 +        """Get the back-end block device controller domain.
    2.64 +        """
    2.65          return self.dom
    2.66  
    2.67      def reattachDevice(self, dom, vdev):
    2.68 +        """Reattach a device (on changing control domain).
    2.69 +
    2.70 +        dom  domain
    2.71 +        vdev device index
    2.72 +        """
    2.73          blkif = self.getInstanceByDom(dom)
    2.74          if blkif:
    2.75              blkif.reattachDevice(vdev)
    2.76 @@ -83,6 +111,9 @@ class BlkifControllerFactory(controller.
    2.77          return attached
    2.78                           
    2.79      def reattached(self):
    2.80 +        """Notify all block interface we have been reattached
    2.81 +        (after changing control domain).
    2.82 +        """
    2.83          for blkif in self.getInstances():
    2.84              blkif.reattached()
    2.85  
    2.86 @@ -147,7 +178,6 @@ class BlkDev(controller.Dev):
    2.87          return val
    2.88  
    2.89      def destroy(self):
    2.90 -        print 'BlkDev>destroy>', self.vdev
    2.91          PrettyPrint.prettyprint(self.sxpr())
    2.92          self.controller.send_be_vbd_destroy(self.vdev)
    2.93          
    2.94 @@ -157,7 +187,6 @@ class BlkifController(controller.Control
    2.95      """
    2.96      
    2.97      def __init__(self, factory, dom):
    2.98 -        #print 'BlkifController> dom=', dom
    2.99          controller.Controller.__init__(self, factory, dom)
   2.100          self.devices = {}
   2.101  
   2.102 @@ -172,7 +201,6 @@ class BlkifController(controller.Control
   2.103          self.attached = 1
   2.104          self.evtchn = None
   2.105          self.registerChannel()
   2.106 -        #print 'BlkifController<', 'dom=', self.dom, 'idx=', self.idx
   2.107  
   2.108      def sxpr(self):
   2.109          val = ['blkif', ['dom', self.dom]]
   2.110 @@ -183,8 +211,6 @@ class BlkifController(controller.Control
   2.111          return val
   2.112  
   2.113      def lostChannel(self):
   2.114 -        print 'BlkifController>lostChannel>', 'dom=', self.dom
   2.115 -        #self.destroyDevices()
   2.116          controller.Controller.lostChannel(self)
   2.117  
   2.118      def getDevices(self):
   2.119 @@ -201,8 +227,14 @@ class BlkifController(controller.Control
   2.120  
   2.121      def attachDevice(self, vdev, mode, segment, recreate=0):
   2.122          """Attach a device to the specified interface.
   2.123 +
   2.124 +        vdev     device index
   2.125 +        mode     read/write mode
   2.126 +        segment  segment
   2.127 +        recreate if true it's being recreated (after xend restart)
   2.128 +
   2.129 +        returns deferred
   2.130          """
   2.131 -        #print 'BlkifController>attach_device>', self.dom, vdev, mode, segment
   2.132          dev = self.addDevice(vdev, mode, segment)
   2.133          if not dev: return -1
   2.134          if recreate:
   2.135 @@ -214,13 +246,11 @@ class BlkifController(controller.Control
   2.136          return d
   2.137  
   2.138      def destroy(self):
   2.139 -        print 'BlkifController>destroy> dom=', self.dom
   2.140          def cb_destroy(val):
   2.141              self.send_be_destroy()
   2.142          d = self.factory.addDeferred()
   2.143          d.addCallback(cb_destroy)
   2.144          self.send_be_disconnect()
   2.145 -        #self.destroyDevices()
   2.146  
   2.147      def destroyDevices(self):
   2.148          for dev in self.getDevices():
   2.149 @@ -276,11 +306,6 @@ class BlkifController(controller.Control
   2.150          self.factory.writeRequest(msg)
   2.151          pass
   2.152  
   2.153 -    #def recv_fe_interface_status_changed(self, msg, req):
   2.154 -    #    (hnd, status, chan) = unpackMsg('blkif_fe_interface_status_changed_t', msg)
   2.155 -    #    print 'recv_fe_interface_status_changed>', hnd, status, chan
   2.156 -    #   pass
   2.157 -
   2.158      def send_fe_interface_status_changed(self):
   2.159          msg = packMsg('blkif_fe_interface_status_changed_t',
   2.160                        { 'handle' : 0,
     3.1 --- a/tools/python/xen/xend/server/channel.py	Thu Jul 01 10:20:24 2004 +0000
     3.2 +++ b/tools/python/xen/xend/server/channel.py	Thu Jul 01 12:06:02 2004 +0000
     3.3 @@ -1,3 +1,5 @@
     3.4 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     3.5 +
     3.6  import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
     3.7  from xen.lowlevel import xu
     3.8  from messages import msgTypeName
     3.9 @@ -24,14 +26,11 @@ class ChannelFactory:
    3.10          self.notifier = xu.notifier()
    3.11      
    3.12      def addChannel(self, channel):
    3.13 -        """Add a channel.
    3.14 +        """Add a channel. Registers with the notifier.
    3.15          """
    3.16          idx = channel.idx
    3.17          self.channels[idx] = channel
    3.18          self.notifier.bind(idx)
    3.19 -        # Try to wake it up
    3.20 -        #self.notifier.unmask(idx)
    3.21 -        #channel.notify()
    3.22  
    3.23      def getChannel(self, idx):
    3.24          """Get the channel with the given index (if any).
    3.25 @@ -40,6 +39,7 @@ class ChannelFactory:
    3.26  
    3.27      def delChannel(self, idx):
    3.28          """Remove the channel with the given index (if any).
    3.29 +        Deregisters with the notifier.
    3.30          """
    3.31          if idx in self.channels:
    3.32              del self.channels[idx]
    3.33 @@ -288,6 +288,8 @@ class Channel(BaseChannel):
    3.34                     self.getRemotePort()))
    3.35  
    3.36      def handleNotification(self):
    3.37 +        """Process outstanding messages in repsonse to notification on the port.
    3.38 +        """
    3.39          if self.closed:
    3.40              print 'handleNotification> Notification on closed channel', self
    3.41              return
    3.42 @@ -299,6 +301,8 @@ class Channel(BaseChannel):
    3.43              self.notify()
    3.44  
    3.45      def notify(self):
    3.46 +        """Notify the other end of the port that messages have been processed.
    3.47 +        """
    3.48          if self.closed: return
    3.49          self.port.notify()
    3.50  
     4.1 --- a/tools/python/xen/xend/server/console.py	Thu Jul 01 10:20:24 2004 +0000
     4.2 +++ b/tools/python/xen/xend/server/console.py	Thu Jul 01 12:06:02 2004 +0000
     4.3 @@ -1,3 +1,4 @@
     4.4 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     4.5  
     4.6  from twisted.internet import reactor
     4.7  from twisted.internet import protocol
     4.8 @@ -12,11 +13,6 @@ import controller
     4.9  from messages import *
    4.10  from params import *
    4.11  
    4.12 -"""Telnet binary option."""
    4.13 -TRANSMIT_BINARY = '0'
    4.14 -WILL = chr(251)
    4.15 -IAC = chr(255)
    4.16 -
    4.17  class ConsoleProtocol(protocol.Protocol):
    4.18      """Asynchronous handler for a console TCP socket.
    4.19      """
    4.20 @@ -36,19 +32,12 @@ class ConsoleProtocol(protocol.Protocol)
    4.21              self.loseConnection()
    4.22              return
    4.23          else:
    4.24 -            # KAF: A nice quiet successful connect. Don't bother with telnet
    4.25 -            # control sequence -- telnet is not the appropriate protocol here. 
    4.26 +            # KAF: A nice quiet successful connect.
    4.27              #self.transport.write("Connected to console %d on domain %d\n"
    4.28              #                     % (self.idx, self.controller.dom))
    4.29 -            #self.setTelnetTransmitBinary()
    4.30              eserver.inject('xend.console.connect',
    4.31                             [self.idx, self.addr[0], self.addr[1]])
    4.32  
    4.33 -    def setTelnetTransmitBinary(self):
    4.34 -        """Send the sequence to set the telnet TRANSMIT-BINARY option.
    4.35 -        """
    4.36 -        self.write(IAC + WILL + TRANSMIT_BINARY)
    4.37 -
    4.38      def dataReceived(self, data):
    4.39          if self.controller.handleInput(self, data):
    4.40              self.loseConnection()
    4.41 @@ -105,7 +94,6 @@ class ConsoleController(controller.Contr
    4.42      """
    4.43  
    4.44      def __init__(self, factory, dom, console_port):
    4.45 -        #print 'ConsoleController> dom=', dom, type(dom)
    4.46          controller.Controller.__init__(self, factory, dom)
    4.47          self.majorTypes = [ CMSG_CONSOLE ]
    4.48          self.status = "new"
    4.49 @@ -118,7 +106,6 @@ class ConsoleController(controller.Contr
    4.50          self.registerChannel()
    4.51          self.listener = None
    4.52          self.listen()
    4.53 -        #print 'ConsoleController<', 'dom=', self.dom, 'idx=', self.idx
    4.54  
    4.55      def sxpr(self):
    4.56          val =['console',
    4.57 @@ -143,7 +130,6 @@ class ConsoleController(controller.Contr
    4.58  
    4.59      def close(self):
    4.60          try:
    4.61 -            #print 'ConsoleController> close dom=', self.dom
    4.62              self.status = "closed"
    4.63              if self.conn:
    4.64                  self.conn.loseConnection()
    4.65 @@ -183,11 +169,11 @@ class ConsoleController(controller.Contr
    4.66          self.listen()
    4.67  
    4.68      def requestReceived(self, msg, type, subtype):
    4.69 -        #print '***Console', self.dom, msg.get_payload()
    4.70          self.rbuf.write(msg.get_payload())
    4.71          self.handleOutput()
    4.72          
    4.73      def responseReceived(self, msg, type, subtype):
    4.74 +        # Just ignore responses.
    4.75          pass
    4.76  
    4.77      def produceRequests(self):
    4.78 @@ -215,18 +201,14 @@ class ConsoleController(controller.Contr
    4.79          Sends it to the connected console (if any).
    4.80          """
    4.81          if self.closed():
    4.82 -            #print 'Console>handleOutput> closed'
    4.83              return -1
    4.84          if not self.conn:
    4.85 -            #print 'Console>handleOutput> not connected'
    4.86              return 0
    4.87          while not self.rbuf.empty():
    4.88              try:
    4.89 -                #print 'Console>handleOutput> writing...'
    4.90                  bytes = self.conn.write(self.rbuf.peek())
    4.91                  if bytes > 0:
    4.92                      self.rbuf.discard(bytes)
    4.93              except socket.error, error:
    4.94                  pass
    4.95 -        #print 'Console>handleOutput<'
    4.96          return 0
     5.1 --- a/tools/python/xen/xend/server/controller.py	Thu Jul 01 10:20:24 2004 +0000
     5.2 +++ b/tools/python/xen/xend/server/controller.py	Thu Jul 01 12:06:02 2004 +0000
     5.3 @@ -1,3 +1,5 @@
     5.4 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     5.5 +
     5.6  from twisted.internet import defer
     5.7  
     5.8  import channel
     5.9 @@ -5,6 +7,15 @@ from messages import msgTypeName
    5.10  
    5.11  class CtrlMsgRcvr:
    5.12      """Abstract class for things that deal with a control interface to a domain.
    5.13 +
    5.14 +    Instance variables:
    5.15 +
    5.16 +    dom       : the domain we are a control interface for
    5.17 +    majorTypes: list of major message types we are interested in
    5.18 +    subTypes  : mapping of message subtypes to methods
    5.19 +    
    5.20 +    channel   : channel to the domain
    5.21 +    idx       : channel index
    5.22      """
    5.23  
    5.24  
    5.25 @@ -17,6 +28,12 @@ class CtrlMsgRcvr:
    5.26          self.idx = None
    5.27  
    5.28      def requestReceived(self, msg, type, subtype):
    5.29 +        """Dispatch a request to handlers.
    5.30 +
    5.31 +        msg     message
    5.32 +        type    major message type
    5.33 +        subtype minor message type
    5.34 +        """
    5.35          method = self.subTypes.get(subtype)
    5.36          if method:
    5.37              method(msg, 1)
    5.38 @@ -25,6 +42,12 @@ class CtrlMsgRcvr:
    5.39                     % (msgTypeName(type, subtype), type, subtype)), self
    5.40          
    5.41      def responseReceived(self, msg, type, subtype):
    5.42 +        """Dispatch a response to handlers.
    5.43 +
    5.44 +        msg     message
    5.45 +        type    major message type
    5.46 +        subtype minor message type
    5.47 +        """
    5.48          method = self.subTypes.get(subtype)
    5.49          if method:
    5.50              method(msg, 0)
    5.51 @@ -33,9 +56,14 @@ class CtrlMsgRcvr:
    5.52                     % (msgTypeName(type, subtype), type, subtype)), self
    5.53  
    5.54      def lostChannel(self):
    5.55 +        """Called when the channel to the domain is lost.
    5.56 +        """
    5.57          pass
    5.58      
    5.59      def registerChannel(self):
    5.60 +        """Register interest in our major message types with the
    5.61 +        channel to our domain.
    5.62 +        """
    5.63          #print 'CtrlMsgRcvr>registerChannel>', self
    5.64          self.channel = self.channelFactory.domChannel(self.dom)
    5.65          self.idx = self.channel.getIndex()
    5.66 @@ -43,21 +71,32 @@ class CtrlMsgRcvr:
    5.67              self.channel.registerDevice(self.majorTypes, self)
    5.68          
    5.69      def deregisterChannel(self):
    5.70 +        """Deregister interest in our major message types with the
    5.71 +        channel to our domain.
    5.72 +        """
    5.73          #print 'CtrlMsgRcvr>deregisterChannel>', self
    5.74          if self.channel:
    5.75              self.channel.deregisterDevice(self)
    5.76              del self.channel
    5.77  
    5.78      def produceRequests(self):
    5.79 +        """Produce any queued requests.
    5.80 +
    5.81 +        return number produced
    5.82 +        """
    5.83          return 0
    5.84  
    5.85      def writeRequest(self, msg):
    5.86 +        """Write a request to the channel.
    5.87 +        """
    5.88          if self.channel:
    5.89              self.channel.writeRequest(msg)
    5.90          else:
    5.91              print 'CtrlMsgRcvr>writeRequest>', 'no channel!', self
    5.92  
    5.93      def writeResponse(self, msg):
    5.94 +        """Write a response to the channel.
    5.95 +        """
    5.96          if self.channel:
    5.97              self.channel.writeResponse(msg)
    5.98          else:
    5.99 @@ -66,6 +105,13 @@ class CtrlMsgRcvr:
   5.100  class ControllerFactory(CtrlMsgRcvr):
   5.101      """Abstract class for factories creating controllers.
   5.102      Maintains a table of instances.
   5.103 +
   5.104 +    Instance variables:
   5.105 +
   5.106 +    instances : mapping of index to controller instance
   5.107 +    dlist     : list of deferreds
   5.108 +    dom       : domain
   5.109 +    timeout   : deferred timeout
   5.110      """
   5.111  
   5.112      def __init__(self):
   5.113 @@ -77,34 +123,49 @@ class ControllerFactory(CtrlMsgRcvr):
   5.114          self.timeout = 10
   5.115          
   5.116      def addInstance(self, instance):
   5.117 +        """Add a controller instance (under its index).
   5.118 +        """
   5.119          self.instances[instance.idx] = instance
   5.120  
   5.121      def getInstance(self, idx):
   5.122 +        """Get a controller instance from its index.
   5.123 +        """
   5.124          return self.instances.get(idx)
   5.125  
   5.126      def getInstances(self):
   5.127 +        """Get a list of all controller instances.
   5.128 +        """
   5.129          return self.instances.values()
   5.130  
   5.131      def getInstanceByDom(self, dom):
   5.132 +        """Get the controller instance for the given domain.
   5.133 +        """
   5.134          for inst in self.instances.values():
   5.135              if inst.dom == dom:
   5.136                  return inst
   5.137          return None
   5.138  
   5.139      def delInstance(self, instance):
   5.140 -        #print 'ControllerFactory>delInstance>', instance.idx
   5.141 +        """Delete an instance from the table.
   5.142 +        """
   5.143          if instance.idx in self.instances:
   5.144 -            #print 'ControllerFactory>delInstance> remove', instance.idx
   5.145              del self.instances[instance.idx]
   5.146  
   5.147      def createInstance(self, dom, recreate=0):
   5.148 +        """Create an instance. Define in a subclass.
   5.149 +        """
   5.150          raise NotImplementedError()
   5.151  
   5.152      def instanceClosed(self, instance):
   5.153 -        #print 'ControllerFactory>instanceClosed>', instance.idx, instance
   5.154 +        """Callback called when an instance is closed (usually by the instance).
   5.155 +        """
   5.156          self.delInstance(instance)
   5.157  
   5.158      def addDeferred(self):
   5.159 +        """Add a deferred object.
   5.160 +
   5.161 +        returns deferred
   5.162 +        """
   5.163          d = defer.Deferred()
   5.164          if self.timeout > 0:
   5.165              # The deferred will error if not called before timeout.
   5.166 @@ -113,11 +174,19 @@ class ControllerFactory(CtrlMsgRcvr):
   5.167          return d
   5.168  
   5.169      def callDeferred(self, *args):
   5.170 +        """Call the top deferred object
   5.171 +
   5.172 +        args arguments
   5.173 +        """
   5.174          if self.dlist:
   5.175              d = self.dlist.pop(0)
   5.176              d.callback(*args)
   5.177  
   5.178      def errDeferred(self, *args):
   5.179 +        """Signal an error to the top deferred object.
   5.180 +
   5.181 +        args arguments
   5.182 +        """
   5.183          if self.dlist:
   5.184              d = self.dlist.pop(0)
   5.185              d.errback(*args)
   5.186 @@ -134,15 +203,20 @@ class Controller(CtrlMsgRcvr):
   5.187          self.idx = None
   5.188  
   5.189      def close(self):
   5.190 +        """Close the controller.
   5.191 +        """
   5.192          self.deregisterChannel()
   5.193          self.lostChannel()
   5.194  
   5.195      def lostChannel(self):
   5.196 -        #print 'Controller>lostChannel>', self, self.factory
   5.197 +        """The controller channel has been lost.
   5.198 +        """
   5.199          self.factory.instanceClosed(self)
   5.200  
   5.201  class Dev:
   5.202 -
   5.203 +    """Abstract class for a device attached to a device controller.
   5.204 +    """
   5.205 +    
   5.206      def __init__(self, controller):
   5.207          self.controller = controller
   5.208          self.props = {}
   5.209 @@ -160,9 +234,6 @@ class Dev:
   5.210          if k in self.props:
   5.211              del self.props[k]
   5.212  
   5.213 -    #def __repr__(self):
   5.214 -    #    return str(self.sxpr())
   5.215 -
   5.216      def sxpr(self):
   5.217          raise NotImplementedError()
   5.218  
     6.1 --- a/tools/python/xen/xend/server/domain.py	Thu Jul 01 10:20:24 2004 +0000
     6.2 +++ b/tools/python/xen/xend/server/domain.py	Thu Jul 01 12:06:02 2004 +0000
     6.3 @@ -1,3 +1,5 @@
     6.4 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     6.5 +
     6.6  import channel
     6.7  import controller
     6.8  from messages import *
     6.9 @@ -7,11 +9,23 @@ class DomainControllerFactory(controller
    6.10      """
    6.11  
    6.12      def createInstance(self, dom):
    6.13 +        """Create a domain controller.
    6.14 +
    6.15 +        dom domain
    6.16 +
    6.17 +        returns domain controller
    6.18 +        """
    6.19          d = DomainController(self, dom)
    6.20          self.addInstance(d)
    6.21          return d
    6.22      
    6.23      def getInstanceByDom(self, dom):
    6.24 +        """Get a domain controller for a domain, creating if necessary.
    6.25 +
    6.26 +        dom domain
    6.27 +
    6.28 +        returns domain controller
    6.29 +        """
    6.30          for inst in self.instances.values():
    6.31              if inst.dom == dom:
    6.32                  return inst
    6.33 @@ -21,8 +35,11 @@ class DomainControllerFactory(controller
    6.34  
    6.35  class DomainController(controller.Controller):
    6.36      """Generic controller for a domain.
    6.37 +    Used for domain shutdown.
    6.38      """
    6.39  
    6.40 +    """Map shutdown reasons to the message type to use.
    6.41 +    """
    6.42      reasons = {'poweroff' : 'shutdown_poweroff_t',
    6.43                 'reboot'   : 'shutdown_reboot_t',
    6.44                 'suspend'  : 'shutdown_suspend_t' }
    6.45 @@ -34,6 +51,10 @@ class DomainController(controller.Contro
    6.46          print 'DomainController>', self, self.channel, self.idx
    6.47  
    6.48      def shutdown(self, reason):
    6.49 +        """Shutdown a domain.
    6.50 +
    6.51 +        reason shutdown reason
    6.52 +        """
    6.53          msgtype = self.reasons.get(reason)
    6.54          if not msgtype:
    6.55              raise ValueError('invalid reason:' + reason)
     7.1 --- a/tools/python/xen/xend/server/messages.py	Thu Jul 01 10:20:24 2004 +0000
     7.2 +++ b/tools/python/xen/xend/server/messages.py	Thu Jul 01 12:06:02 2004 +0000
     7.3 @@ -148,6 +148,9 @@ netif_formats = {
     7.4  msg_formats.update(netif_formats)
     7.5  
     7.6  #============================================================================
     7.7 +# Domain shutdown message types.
     7.8 +#============================================================================
     7.9 +
    7.10  CMSG_SHUTDOWN = 6
    7.11  
    7.12  CMSG_SHUTDOWN_POWEROFF  = 0
    7.13 @@ -177,6 +180,14 @@ class Msg:
    7.14      pass
    7.15  
    7.16  def packMsg(ty, params):
    7.17 +    """Pack a message.
    7.18 +    Any 'mac' parameter is passed in as an int[6] array and converted.
    7.19 +
    7.20 +    ty     message type name
    7.21 +    params message parameter dict
    7.22 +
    7.23 +    returns xu message
    7.24 +    """
    7.25      if DEBUG: print '>packMsg', ty, params
    7.26      (major, minor) = msg_formats[ty]
    7.27      args = {}
    7.28 @@ -194,6 +205,15 @@ def packMsg(ty, params):
    7.29      return msg
    7.30  
    7.31  def unpackMsg(ty, msg):
    7.32 +    """Unpack a message.
    7.33 +    Any mac addresses in the message are converted to int[6] array
    7.34 +    in the return dict.
    7.35 +
    7.36 +    ty  message type
    7.37 +    msg xu message
    7.38 +
    7.39 +    returns parameter dict
    7.40 +    """
    7.41      args = msg.get_payload()
    7.42      mac = [0, 0, 0, 0, 0, 0]
    7.43      macs = []
    7.44 @@ -212,6 +232,13 @@ def unpackMsg(ty, msg):
    7.45      return args
    7.46  
    7.47  def msgTypeName(ty, subty):
    7.48 +    """Convert a message type, subtype pair (ints) to a message type name (string).
    7.49 +
    7.50 +    ty    integer message type
    7.51 +    subty integer message subtype
    7.52 +
    7.53 +    returns message type name (or None)
    7.54 +    """
    7.55      for (name, info) in msg_formats.items():
    7.56          if info[0] == ty and info[1] == subty:
    7.57              return name
     8.1 --- a/tools/python/xen/xend/server/netif.py	Thu Jul 01 10:20:24 2004 +0000
     8.2 +++ b/tools/python/xen/xend/server/netif.py	Thu Jul 01 12:06:02 2004 +0000
     8.3 @@ -1,3 +1,5 @@
     8.4 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     8.5 +
     8.6  import random
     8.7  
     8.8  from twisted.internet import defer
     8.9 @@ -30,8 +32,12 @@ class NetifControllerFactory(controller.
    8.10  
    8.11      def createInstance(self, dom, recreate=0):
    8.12          """Create or find the network interface controller for a domain.
    8.13 +
    8.14 +        dom      domain
    8.15 +        recreate if true this is a recreate (xend restarted)
    8.16 +
    8.17 +        returns netif controller
    8.18          """
    8.19 -        #print 'netif>createInstance> dom=', dom
    8.20          netif = self.getInstanceByDom(dom)
    8.21          if netif is None:
    8.22              netif = NetifController(self, dom)
    8.23 @@ -39,15 +45,31 @@ class NetifControllerFactory(controller.
    8.24          return netif
    8.25  
    8.26      def getDomainDevices(self, dom):
    8.27 +        """Get the network device controllers for a domain.
    8.28 +
    8.29 +        dom  domain
    8.30 +        
    8.31 +        returns netif controller
    8.32 +        """
    8.33          netif = self.getInstanceByDom(dom)
    8.34          return (netif and netif.getDevices()) or []
    8.35  
    8.36      def getDomainDevice(self, dom, vif):
    8.37 +        """Get a virtual network interface device for a domain.
    8.38 +
    8.39 +        dom domain
    8.40 +        vif virtual interface index
    8.41 +
    8.42 +        returns NetDev
    8.43 +        """
    8.44          netif = self.getInstanceByDom(dom)
    8.45          return (netif and netif.getDevice(vif)) or None
    8.46          
    8.47      def setControlDomain(self, dom, recreate=0):
    8.48          """Set the 'back-end' device driver domain.
    8.49 +
    8.50 +        dom      domain
    8.51 +        recreate if true this is a recreate (xend restarted)
    8.52          """
    8.53          if self.dom == dom: return
    8.54          self.deregisterChannel()
    8.55 @@ -55,13 +77,10 @@ class NetifControllerFactory(controller.
    8.56              self.attached = 0
    8.57          self.dom = dom
    8.58          self.registerChannel()
    8.59 -        #
    8.60 -        #if xend.netif.be_port.remote_dom != 0:
    8.61 -        #    xend.netif.recovery = True
    8.62 -        #    xend.netif.be_port = xend.main.port_from_dom(dom)
    8.63 -        #
    8.64  
    8.65      def getControlDomain(self):
    8.66 +        """Get the domain id of the back-end control domain.
    8.67 +        """
    8.68          return self.dom
    8.69  
    8.70      def recv_be_create(self, msg, req):
    8.71 @@ -88,23 +107,6 @@ class NetifControllerFactory(controller.
    8.72                  netif.reattach_devices()
    8.73              self.attached = 1
    8.74  
    8.75 -##         pl = msg.get_payload()
    8.76 -##         status = pl['status']
    8.77 -##         if status == NETIF_DRIVER_STATUS_UP:
    8.78 -##             if xend.netif.recovery:
    8.79 -##                 print "New netif backend now UP, notifying guests:"
    8.80 -##                 for netif_key in interface.list.keys():
    8.81 -##                     netif = interface.list[netif_key]
    8.82 -##                     netif.create()
    8.83 -##                     print "  Notifying %d" % netif.dom
    8.84 -##                     msg = xu.message(
    8.85 -##                         CMSG_NETIF_FE,
    8.86 -##                         CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED, 0,
    8.87 -##                         { 'handle' : 0, 'status' : 1 })
    8.88 -##                     netif.ctrlif_tx_req(xend.main.port_from_dom(netif.dom),msg)
    8.89 -##                 print "Done notifying guests"
    8.90 -##                 recovery = False
    8.91 -                
    8.92  class NetDev(controller.Dev):
    8.93      """Info record for a network device.
    8.94      """
    8.95 @@ -130,9 +132,13 @@ class NetDev(controller.Dev):
    8.96          return val
    8.97  
    8.98      def get_vifname(self):
    8.99 +        """Get the virtual interface device name.
   8.100 +        """
   8.101          return "vif%d.%d" % (self.controller.dom, self.vif)
   8.102  
   8.103      def get_mac(self):
   8.104 +        """Get the MAC address as a string.
   8.105 +        """
   8.106          return ':'.join(map(lambda x: "%x" % x, self.mac))
   8.107  
   8.108      def vifctl_params(self):
   8.109 @@ -141,23 +147,30 @@ class NetDev(controller.Dev):
   8.110                   'ipaddr': self.ipaddr }
   8.111  
   8.112      def up(self, bridge=None, ipaddr=[]):
   8.113 +        """Bring the device up.
   8.114 +
   8.115 +        bridge ethernet bridge to connect to
   8.116 +        ipaddr list of ipaddrs to filter using iptables
   8.117 +        """
   8.118          self.bridge = bridge
   8.119          self.ipaddr = ipaddr
   8.120          Vifctl.up(self.get_vifname(), **self.vifctl_params())
   8.121  
   8.122      def down(self):
   8.123 +        """Bring the device down.
   8.124 +        """
   8.125          Vifctl.down(self.get_vifname(), **self.vifctl_params())
   8.126  
   8.127      def destroy(self):
   8.128 +        """Destroy the device's resources and disconnect from the back-end
   8.129 +        device controller.
   8.130 +        """
   8.131          def cb_destroy(val):
   8.132              self.controller.send_be_destroy(self.vif)
   8.133 -        print 'NetDev>destroy>', 'vif=', self.vif
   8.134 -        PrettyPrint.prettyprint(self.sxpr())
   8.135          self.down()
   8.136          d = self.controller.factory.addDeferred()
   8.137          d.addCallback(cb_destroy)
   8.138          self.controller.send_be_disconnect(self.vif)
   8.139 -        #self.controller.send_be_destroy(self.vif)
   8.140          
   8.141  
   8.142  class NetifController(controller.Controller):
   8.143 @@ -165,7 +178,6 @@ class NetifController(controller.Control
   8.144      """
   8.145      
   8.146      def __init__(self, factory, dom):
   8.147 -        #print 'NetifController> dom=', dom
   8.148          controller.Controller.__init__(self, factory, dom)
   8.149          self.devices = {}
   8.150          
   8.151 @@ -178,21 +190,22 @@ class NetifController(controller.Control
   8.152                  self.recv_fe_interface_connect,
   8.153              }
   8.154          self.registerChannel()
   8.155 -        #print 'NetifController<', 'dom=', self.dom, 'idx=', self.idx
   8.156  
   8.157      def sxpr(self):
   8.158          val = ['netif', ['dom', self.dom]]
   8.159          return val
   8.160      
   8.161      def randomMAC(self):
   8.162 -        # VIFs get a random MAC address with a "special" vendor id.
   8.163 -        # 
   8.164 -        # NB. The vendor is currently an "obsolete" one that used to belong
   8.165 -        # to DEC (AA-00-00). Using it is probably a bit rude :-)
   8.166 -        # 
   8.167 -        # NB2. The first bit of the first random octet is set to zero for
   8.168 -        # all dynamic MAC addresses. This may allow us to manually specify
   8.169 -        # MAC addresses for some VIFs with no fear of clashes.
   8.170 +        """Generate a random MAC address.
   8.171 +
   8.172 +        The OUI (Organisation Unique Identifier) used is AA:00:00, which
   8.173 +        is a currently unassigned one that used to belong to DEC.
   8.174 +
   8.175 +        The remaining 3 fields are random, with the first bit of the first
   8.176 +        random field set 0.
   8.177 +
   8.178 +        returns array of 6 ints
   8.179 +        """
   8.180          mac = [ 0xaa, 0x00, 0x00,
   8.181                  random.randint(0x00, 0x7f),
   8.182                  random.randint(0x00, 0xff),
   8.183 @@ -200,29 +213,46 @@ class NetifController(controller.Control
   8.184          return mac
   8.185  
   8.186      def lostChannel(self):
   8.187 -        print 'NetifController>lostChannel>', 'dom=', self.dom
   8.188 -        #self.destroyDevices()
   8.189 +        """Method called when the channel has been lost.
   8.190 +        """
   8.191          controller.Controller.lostChannel(self)
   8.192  
   8.193      def getDevices(self):
   8.194 +        """Get a list of the devices.
   8.195 +        """
   8.196          return self.devices.values()
   8.197  
   8.198      def getDevice(self, vif):
   8.199 +        """Get a device.
   8.200 +
   8.201 +        vif device index
   8.202 +
   8.203 +        returns device (or None)
   8.204 +        """
   8.205          return self.devices.get(vif)
   8.206  
   8.207      def addDevice(self, vif, vmac):
   8.208 +        """Add a network interface. If vmac is None a random MAC is
   8.209 +        assigned. If specified, vmac must be a string of the form
   8.210 +        XX:XX:XX:XX:XX where X is hex digit.
   8.211 +
   8.212 +        vif device index
   8.213 +        vmac device MAC 
   8.214 +
   8.215 +        returns device
   8.216 +        """
   8.217          if vmac is None:
   8.218              mac = self.randomMAC()
   8.219          else:
   8.220              mac = [ int(x, 16) for x in vmac.split(':') ]
   8.221          if len(mac) != 6: raise ValueError("invalid mac")
   8.222 -        #print "attach_device>", "vif=", vif, "mac=", mac
   8.223          dev = NetDev(self, vif, mac)
   8.224          self.devices[vif] = dev
   8.225          return dev
   8.226  
   8.227      def destroy(self):
   8.228 -        print 'NetifController>destroy>', 'dom=', self.dom
   8.229 +        """Destroy the controller and all devices.
   8.230 +        """
   8.231          self.destroyDevices()
   8.232          
   8.233      def destroyDevices(self):
   8.234 @@ -306,7 +336,6 @@ class NetifController(controller.Control
   8.235          self.factory.writeRequest(msg)
   8.236  
   8.237      def send_be_destroy(self, vif):
   8.238 -        print 'NetifController>send_be_destroy>', 'dom=', self.dom, 'vif=', vif
   8.239          PrettyPrint.prettyprint(self.sxpr())
   8.240          dev = self.devices[vif]
   8.241          del self.devices[vif]