ia64/xen-unstable

changeset 4668:369e382b2f81

bitkeeper revision 1.1327.2.9 (426f9bfcIjY9QAFCPqWBbFw35vclow)

Add support for unix-domain sockets on xend.
Remove some dead code.
Signed-off-by: Mike Wray <mike.wray@hp.com>
author mjw@wray-m-3.hpl.hp.com
date Wed Apr 27 14:04:44 2005 +0000 (2005-04-27)
parents bd15906125a7
children 629cd2d0d581
files .rootkeys tools/python/xen/web/SrvBase.py tools/python/xen/web/SrvDir.py tools/python/xen/web/defer.py tools/python/xen/web/httpserver.py tools/python/xen/web/static.py tools/python/xen/xend/XendAsynchProtocol.py tools/python/xen/xend/XendClient.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainConfig.py tools/python/xen/xend/XendProtocol.py tools/python/xen/xend/XendRoot.py tools/python/xen/xend/server/SrvBase.py tools/python/xen/xend/server/SrvConsole.py tools/python/xen/xend/server/SrvDaemon.py tools/python/xen/xend/server/SrvDir.py tools/python/xen/xend/server/SrvDmesg.py tools/python/xen/xend/server/SrvDomain.py tools/python/xen/xend/server/SrvDomainDir.py tools/python/xen/xend/server/SrvEventDir.py tools/python/xen/xend/server/SrvNode.py tools/python/xen/xend/server/SrvRoot.py tools/python/xen/xend/server/SrvServer.py tools/python/xen/xend/server/SrvUsbif.py tools/python/xen/xend/server/SrvVnetDir.py tools/python/xen/xend/server/SrvXendLog.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/netif.py tools/python/xen/xend/server/usbif.py tools/python/xen/xend/util.py
line diff
     1.1 --- a/.rootkeys	Mon Apr 25 13:04:17 2005 +0000
     1.2 +++ b/.rootkeys	Wed Apr 27 14:04:44 2005 +0000
     1.3 @@ -883,7 +883,6 @@ 4267a9b16u4IEPhjRryesk6A17sobA tools/pyt
     1.4  4267a9b1FfCUjW7m9anLERcx9lwhJg tools/python/xen/web/SrvDir.py
     1.5  4267a9b1uMXIfzB6-81ZLqMCyTgJmw tools/python/xen/web/__init__.py
     1.6  4267a9b1i_zVq36tt2iQejVuR6DGFw tools/python/xen/web/connection.py
     1.7 -4267a9b1Z2SpO9v-zEDApywETZPDwA tools/python/xen/web/defer.py
     1.8  4267a9b1KzSWZwWKYrGRc9bUhow_7Q tools/python/xen/web/http.py
     1.9  4267a9b1KWNZhhmZnySe_nLASwO47g tools/python/xen/web/httpserver.py
    1.10  4267a9b21miObgEJLAgtLTAKRBK8uQ tools/python/xen/web/protocol.py
    1.11 @@ -897,13 +896,11 @@ 41597996WNvJA-DVCBmc0xU9w_XmoA tools/pyt
    1.12  40c9c468Um_qc66OQeLEceIz1pgD5g tools/python/xen/xend/EventServer.py
    1.13  40c9c468QJTEuk9g4qHxGpmIi70PEQ tools/python/xen/xend/PrettyPrint.py
    1.14  40e15b7eeQxWE_hUPB2YTgM9fsZ1PQ tools/python/xen/xend/Vifctl.py
    1.15 -4151594bBq8h-bwTfEt8dbBuojMtcA tools/python/xen/xend/XendAsynchProtocol.py
    1.16  40c9c4688m3eqnC8fhLu1APm36VOVA tools/python/xen/xend/XendClient.py
    1.17  40c9c468t6iIKTjwuYoe-UMCikDcOQ tools/python/xen/xend/XendConsole.py
    1.18  40c9c468WnXs6eOUSff23IIGI4kMfQ tools/python/xen/xend/XendDB.py
    1.19  40eee3a0sPO-WUu34uHUXOC7HliDGw tools/python/xen/xend/XendDmesg.py
    1.20  40c9c468fSl3H3IypyT0ppkbb0ZT9A tools/python/xen/xend/XendDomain.py
    1.21 -40c9c468bbKq3uC7_fuNUkiMMjArdw tools/python/xen/xend/XendDomainConfig.py
    1.22  40c9c4685ykq87_n1kVUbMr9flx9fg tools/python/xen/xend/XendDomainInfo.py
    1.23  40f50d99YiiaMI1fZBh1VCDFLD57qg tools/python/xen/xend/XendError.py
    1.24  40ffc44eGsgTEY355E3nN4mPLZHhMQ tools/python/xen/xend/XendLogging.py
    1.25 @@ -915,19 +912,15 @@ 40c9c468xzANp6o2D_MeCYwNmOIUsQ tools/pyt
    1.26  40c9c468x191zetrVlMnExfsQWHxIQ tools/python/xen/xend/__init__.py
    1.27  40c9c468S2YnCEKmk4ey8XQIST7INg tools/python/xen/xend/encode.py
    1.28  4266169ezWIlXSfY50n6HSoVFbosmw tools/python/xen/xend/scheduler.py
    1.29 -40c9c468DCpMe542varOolW1Xc68ew tools/python/xen/xend/server/SrvBase.py
    1.30  40c9c468IxQabrKJSWs0aEjl-27mRQ tools/python/xen/xend/server/SrvConsole.py
    1.31  40c9c4689Io5bxfbYIfRiUvsiLX0EQ tools/python/xen/xend/server/SrvConsoleDir.py
    1.32  40c9c468woSmBByfeXA4o_jGf2gCgA tools/python/xen/xend/server/SrvDaemon.py
    1.33 -40c9c468EQZJVkCLds-OhesJVVyZbQ tools/python/xen/xend/server/SrvDir.py
    1.34  40eee3a0m38EwYXfCSFIjWNwG6jx_A tools/python/xen/xend/server/SrvDmesg.py
    1.35  40c9c468TyHZUq8sk0FF_vxM6Sozrg tools/python/xen/xend/server/SrvDomain.py
    1.36  40c9c469WzajDjutou3X7FmL9hMf3g tools/python/xen/xend/server/SrvDomainDir.py
    1.37 -40c9c469-8mYEJJTAR6w_ClrJRAfwQ tools/python/xen/xend/server/SrvEventDir.py
    1.38  40c9c4694eu5759Dehr4Uhakei0EMg tools/python/xen/xend/server/SrvNode.py
    1.39  40c9c469TaZ83ypsrktmPSHLEZiP5w tools/python/xen/xend/server/SrvRoot.py
    1.40  40c9c469W3sgDMbBJYQdz5wbQweL0Q tools/python/xen/xend/server/SrvServer.py
    1.41 -41ee5e8cFlODpYxhBMZqo9ZgGtcHbg tools/python/xen/xend/server/SrvUsbif.py
    1.42  40c9c469aq7oXrE1Ngqf3_lBqL0RoQ tools/python/xen/xend/server/SrvVnetDir.py
    1.43  4108f181GtRoD1U9TBuJXMfBbGJwdQ tools/python/xen/xend/server/SrvXendLog.py
    1.44  40c9c469Y_aimoOFfUZoS-4eV8gEKg tools/python/xen/xend/server/__init__.py
    1.45 @@ -942,7 +935,6 @@ 40c9c469ZqILEQ8x6yWy0_51jopiCg tools/pyt
    1.46  4266169eI_oX3YBjwaeC0V-THBRnjg tools/python/xen/xend/server/pciif.py
    1.47  41ee5e8dq9NtihbL4nWKjuSLOhXPUg tools/python/xen/xend/server/usbif.py
    1.48  40c9c469LNxLVizOUpOjEaTKKCm8Aw tools/python/xen/xend/sxp.py
    1.49 -4189125cL90jKSOcBJ3Vx4nWGiXXvA tools/python/xen/xend/util.py
    1.50  40d05079aFRp6NQdo5wIh5Ly31c0cg tools/python/xen/xm/__init__.py
    1.51  40cf2937gKQcATgXKGtNeWb1PDH5nA tools/python/xen/xm/create.py
    1.52  40f552eariuUSB9TWqCPnDLz5zvxMw tools/python/xen/xm/destroy.py
     2.1 --- a/tools/python/xen/web/SrvBase.py	Mon Apr 25 13:04:17 2005 +0000
     2.2 +++ b/tools/python/xen/web/SrvBase.py	Wed Apr 27 14:04:44 2005 +0000
     2.3 @@ -12,7 +12,6 @@ from xen.xend.XendLogging import log
     2.4  import resource
     2.5  import http
     2.6  import httpserver
     2.7 -import defer
     2.8  
     2.9  def uri_pathlist(p):
    2.10      """Split a path into a list.
     3.1 --- a/tools/python/xen/web/SrvDir.py	Mon Apr 25 13:04:17 2005 +0000
     3.2 +++ b/tools/python/xen/web/SrvDir.py	Wed Apr 27 14:04:44 2005 +0000
     3.3 @@ -20,7 +20,7 @@ class SrvConstructor:
     3.4  
     3.5      def __init__(self, klass):
     3.6          """Create a constructor. It is assumed that the class
     3.7 -        should be imported as 'import klass from klass'.
     3.8 +        should be imported as 'from xen.xend.server.klass import klass'.
     3.9  
    3.10          klass	name of its class
    3.11          """
     4.1 --- a/tools/python/xen/web/defer.py	Mon Apr 25 13:04:17 2005 +0000
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,3 +0,0 @@
     4.4 -
     4.5 -class Deferred:
     4.6 -    pass
     5.1 --- a/tools/python/xen/web/httpserver.py	Mon Apr 25 13:04:17 2005 +0000
     5.2 +++ b/tools/python/xen/web/httpserver.py	Wed Apr 27 14:04:44 2005 +0000
     5.3 @@ -4,6 +4,8 @@ import string
     5.4  import socket
     5.5  import types
     5.6  from urllib import quote, unquote
     5.7 +import os
     5.8 +import os.path
     5.9  
    5.10  from xen.xend import sxp
    5.11  from xen.xend.Args import ArgError
    5.12 @@ -184,7 +186,9 @@ class HttpServerRequest(http.HttpRequest
    5.13  
    5.14          @param val: the value
    5.15          """
    5.16 -        if isinstance(val, ThreadRequest):
    5.17 +        if val is None:
    5.18 +            return val
    5.19 +        elif isinstance(val, ThreadRequest):
    5.20              return val
    5.21          elif self.useSxp():
    5.22              self.setHeader("Content-Type", sxp.mime_type)
    5.23 @@ -316,18 +320,23 @@ class HttpServer:
    5.24      def getResource(self, req):
    5.25          return self.root.getRequestResource(req)
    5.26  
    5.27 +class UnixHttpServer(HttpServer):
    5.28  
    5.29 -def main():
    5.30 -    root = SrvDir()
    5.31 -    a = root.add("a", SrvDir())
    5.32 -    b = root.add("b", SrvDir())
    5.33 -    server = HttpServer(root=root)
    5.34 -    server.run()
    5.35 -
    5.36 -if __name__ == "__main__":
    5.37 -    main()
    5.38 +    def __init__(self, path=None, root=None):
    5.39 +        HttpServer.__init__(self, interface='localhost', root=root)
    5.40 +        self.path = path
    5.41          
    5.42 -        
    5.43 -        
    5.44 -            
    5.45 -
    5.46 +    def bind(self):
    5.47 +        pathdir = os.path.dirname(self.path)
    5.48 +        if not os.path.exists(pathdir):
    5.49 +            os.makedirs(pathdir)
    5.50 +        else:
    5.51 +            try:
    5.52 +                os.unlink(self.path)
    5.53 +            except SystemExit:
    5.54 +                raise
    5.55 +            except Exception, ex:
    5.56 +                pass
    5.57 +        self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    5.58 +        #self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    5.59 +        self.socket.bind(self.path)
     6.1 --- a/tools/python/xen/web/static.py	Mon Apr 25 13:04:17 2005 +0000
     6.2 +++ b/tools/python/xen/web/static.py	Wed Apr 27 14:04:44 2005 +0000
     6.3 @@ -24,7 +24,7 @@ class File(Resource):
     6.4          if self.type:
     6.5              req.setHeader('Content-Type', self.type)
     6.6          if self.encoding:
     6.7 -            rew.setHeader('Content-Encoding', self.encoding)
     6.8 +            req.setHeader('Content-Encoding', self.encoding)
     6.9          req.setHeader('Content-Length', self.getFileSize())
    6.10          try:
    6.11              io = file(self.filename, "r")
    6.12 @@ -40,7 +40,6 @@ class File(Resource):
    6.13                  io.close()
    6.14          except:
    6.15              pass
    6.16 -        return ''
    6.17          
    6.18  
    6.19          
     7.1 --- a/tools/python/xen/xend/XendAsynchProtocol.py	Mon Apr 25 13:04:17 2005 +0000
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,94 +0,0 @@
     7.4 -# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     7.5 -
     7.6 -from twisted.protocols import http
     7.7 -from twisted.internet.protocol import ClientCreator
     7.8 -from twisted.internet.defer import Deferred
     7.9 -from twisted.internet import reactor
    7.10 -
    7.11 -from XendProtocol import XendClientProtocol, XendRequest
    7.12 -
    7.13 -class AsynchXendClient(http.HTTPClient):
    7.14 -    """A subclass of twisted's HTTPClient to deal with a connection to xend.
    7.15 -    Makes the request when connected, and delegates handling responses etc.
    7.16 -    to its protocol (usually an AsynchXendClientProtocol instance).
    7.17 -    """
    7.18 -    def __init__(self, protocol, request):
    7.19 -        self.protocol = protocol
    7.20 -        self.request = request
    7.21 -
    7.22 -    def connectionMade(self):
    7.23 -        request = self.request
    7.24 -        url = self.request.url
    7.25 -        self.sendCommand(request.method, url.fullpath())
    7.26 -        self.sendHeader('Host', url.location())
    7.27 -        for (k, v) in request.headers.items():
    7.28 -            self.sendHeader(k, v)
    7.29 -        if request.data:
    7.30 -            self.sendHeader('Content-Length', len(request.data))
    7.31 -        self.endHeaders()
    7.32 -        if request.data:
    7.33 -            self.transport.write(request.data)
    7.34 -
    7.35 -    def handleStatus(self, version, status, message):
    7.36 -        return self.protocol.handleStatus(version, status, message)
    7.37 -
    7.38 -    def handleHeader(self, key, val):
    7.39 -        return self.protocol.handleHeader(key, val)
    7.40 -
    7.41 -    def handleResponse(self, data):
    7.42 -        return self.protocol.handleResponse(data)
    7.43 -
    7.44 -class AsynchXendClientProtocol(XendClientProtocol):
    7.45 -    """An asynchronous xend client. Uses twisted to connect to xend
    7.46 -    and make the request. It does not block waiting for the result,
    7.47 -    but sets up a deferred that is called when the result becomes available.
    7.48 -
    7.49 -    Uses AsynchXendClient to manage the connection.
    7.50 -    """
    7.51 -    def __init__(self):
    7.52 -        self.err = None
    7.53 -        self.headers = {}
    7.54 -
    7.55 -    def xendRequest(self, url, method, args=None):
    7.56 -        """Make a request to xend. The returned deferred is called when
    7.57 -        the result is available.
    7.58 -        
    7.59 -        @param url:    xend request url
    7.60 -        @param method: http method: POST or GET
    7.61 -        @param args:   request arguments (dict)
    7.62 -        @return: deferred
    7.63 -        """
    7.64 -        request = XendRequest(url, method, args)
    7.65 -        self.deferred = Deferred()
    7.66 -        clientCreator = ClientCreator(reactor, AsynchXendClient, self, request)
    7.67 -        clientCreator.connectTCP(url.host, url.port)
    7.68 -        return self.deferred
    7.69 -
    7.70 -    def callErrback(self, err):
    7.71 -        if not self.deferred.called:
    7.72 -            self.err = err
    7.73 -            self.deferred.errback(err)
    7.74 -        return err
    7.75 -
    7.76 -    def callCallback(self, val):
    7.77 -        if not self.deferred.called:
    7.78 -            self.deferred.callback(val)
    7.79 -        return val
    7.80 -
    7.81 -    def handleException(self, err):
    7.82 -        return self.callErrback(err)
    7.83 -
    7.84 -    def handleHeader(self, key, val):
    7.85 -        self.headers[key.lower()] = val
    7.86 -
    7.87 -    def getHeader(self, key):
    7.88 -        return self.headers.get(key.lower())
    7.89 -
    7.90 -    def handleResponse(self, data):
    7.91 -        if self.err: return self.err
    7.92 -        val = XendClientProtocol.handleResponse(self, data)
    7.93 -        if isinstance(val, Exception):
    7.94 -            self.callErrback(val)
    7.95 -        else:
    7.96 -            self.callCallback(val)
    7.97 -        return val
     8.1 --- a/tools/python/xen/xend/XendClient.py	Mon Apr 25 13:04:17 2005 +0000
     8.2 +++ b/tools/python/xen/xend/XendClient.py	Wed Apr 27 14:04:44 2005 +0000
     8.3 @@ -2,7 +2,7 @@
     8.4  # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     8.5  """Client API for the HTTP interface on xend.
     8.6  Callable as a script - see main().
     8.7 -Supports synchronous or asynchronous connection to xend.
     8.8 +Supports inet or unix connection to xend.
     8.9  
    8.10  This API is the 'control-plane' for xend.
    8.11  The 'data-plane' is done separately. For example, consoles
    8.12 @@ -15,7 +15,9 @@ import types
    8.13  
    8.14  import sxp
    8.15  import PrettyPrint
    8.16 -from XendProtocol import XendClientProtocol, SynchXendClientProtocol, XendError
    8.17 +from XendProtocol import HttpXendClientProtocol, \
    8.18 +                         UnixXendClientProtocol, \
    8.19 +                         XendError
    8.20  
    8.21  DEBUG = 0
    8.22  
    8.23 @@ -32,15 +34,6 @@ def fileof(val):
    8.24          return val
    8.25      raise XendError('cannot convert value')
    8.26  
    8.27 -# todo: need to sort of what urls/paths are using for objects.
    8.28 -# e.g. for domains at the moment return '0'.
    8.29 -# should probably return abs path w.r.t. server, e.g. /xend/domain/0.
    8.30 -# As an arg, assume abs path is obj uri, otherwise just id.
    8.31 -
    8.32 -# Function to convert to full url: Xend.uri(path), e.g.
    8.33 -# maps /xend/domain/0 to http://wray-m-3.hpl.hp.com:8000/xend/domain/0
    8.34 -# And should accept urls for ids?
    8.35 -
    8.36  class URL:
    8.37      """A URL.
    8.38      """
    8.39 @@ -115,7 +108,7 @@ class Xend:
    8.40          @param root:    xend root path on the server
    8.41          """
    8.42          if client is None:
    8.43 -            client = SynchXendClientProtocol()
    8.44 +            client = HttpXendClientProtocol()
    8.45          self.client = client
    8.46          self.bind(srv, root)
    8.47  
    8.48 @@ -162,9 +155,6 @@ class Xend:
    8.49      def vneturl(self, id=''):
    8.50          return self.url.relative('vnet/' + str(id))
    8.51  
    8.52 -    def eventurl(self, id=''):
    8.53 -        return self.url.relative('event/' + str(id))
    8.54 -
    8.55      def xend(self):
    8.56          return self.xendGet(self.url)
    8.57  
    8.58 @@ -262,34 +252,33 @@ class Xend:
    8.59  
    8.60      def xend_domain_maxmem_set(self, id, memory):
    8.61          return self.xendPost(self.domainurl(id),
    8.62 -                             { 'op'     : 'maxmem_set',
    8.63 -                               'memory' : memory })
    8.64 +                             { 'op'      : 'maxmem_set',
    8.65 +                               'memory'  : memory })
    8.66 +
    8.67 +    def xend_domain_mem_target_set(self, id, mem_target):
    8.68 +        val = self.xendPost(self.domainurl(id),
    8.69 +                            {'op'        : 'mem_target_set',
    8.70 +                             'target'    : mem_target })
    8.71 +        return val
    8.72  
    8.73      def xend_domain_vif_limit(self, id, vif, credit, period):
    8.74          return self.xendPost(self.domainurl(id),
    8.75 -                            { 'op'      : 'vif_credit_limit',
    8.76 +                            { 'op'      : 'vif_limit_set',
    8.77                                'vif'     : vif,
    8.78                                'credit'  : credit,
    8.79                                'period'  : period })
    8.80  
    8.81 -    def xend_domain_vifs(self, id):
    8.82 +    def xend_domain_devices(self, id, type):
    8.83          return self.xendGet(self.domainurl(id),
    8.84 -                            { 'op'      : 'vifs' })
    8.85 -
    8.86 -    def xend_domain_vif(self, id, vif):
    8.87 -        return self.xendGet(self.domainurl(id),
    8.88 -                            { 'op'      : 'vif',
    8.89 -                              'vif'     : vif })
    8.90 +                             {'op'      : 'devices',
    8.91 +                              'type'    : type })
    8.92  
    8.93 -    def xend_domain_vbds(self, id):
    8.94 +    def xend_domain_device(self, id, type, idx):
    8.95          return self.xendGet(self.domainurl(id),
    8.96 -                            {'op'       : 'vbds'})
    8.97 -
    8.98 -    def xend_domain_vbd(self, id, vbd):
    8.99 -        return self.xendGet(self.domainurl(id),
   8.100 -                            {'op'       : 'vbd',
   8.101 -                             'vbd'      : vbd })
   8.102 -
   8.103 +                             {'op'      : 'device',
   8.104 +                              'type'    : type,
   8.105 +                              'idx'     : idx })
   8.106 +    
   8.107      def xend_domain_device_create(self, id, config):
   8.108          return self.xendPost(self.domainurl(id),
   8.109                               {'op'      : 'device_create',
   8.110 @@ -338,63 +327,29 @@ class Xend:
   8.111          return self.xendPost(self.vneturl(id),
   8.112                                {'op'     : 'delete' })
   8.113  
   8.114 -    def xend_event_inject(self, sxpr):
   8.115 -        val = self.xendPost(self.eventurl(),
   8.116 -                             {'op'      : 'inject',
   8.117 -                              'event'   : fileof(sxpr) })
   8.118 -
   8.119 -    def xend_domain_mem_target_set(self, id, mem_target):
   8.120 -        val = self.xendPost(self.domainurl(id),
   8.121 -                            {'op'         : 'mem_target_set',
   8.122 -                             'target'     : mem_target })
   8.123 -        return val
   8.124 -
   8.125 -def getAsynchXendClientProtocol():
   8.126 -    """Load AsynchXendClientProtocol on demand to avoid the cost.
   8.127 +def getHttpServer(srv=None):
   8.128 +    """Create and return a xend client.
   8.129      """
   8.130 -    global AsynchXendClientProtocol
   8.131 -    try:
   8.132 -       AsynchXendClientProtocol
   8.133 -    except:
   8.134 -        from XendAsynchProtocol import AsynchXendClientProtocol
   8.135 -    return AsynchXendClientProtocol
   8.136 -
   8.137 -def getAsynchServer():
   8.138 -    """Load AsynchXendClientProtocol and create an asynch xend client.
   8.139 +    return Xend(srv=srv, client=XendClientProtocol())
   8.140  
   8.141 -    @return asynch Xend
   8.142 +def getUnixServer(srv=None):
   8.143 +    """Create and return a unix-domain xend client.
   8.144      """
   8.145 -    getAsynchXendClientProtocol()
   8.146 -    return Xend(AsynchXendClientProtocol())
   8.147 +    return Xend(client=UnixXendClientProtocol(srv))
   8.148  
   8.149 -def xendmain(srv, asynch, fn, args):
   8.150 -    if asynch:
   8.151 -        getAsynchXendClientProtocol()
   8.152 -        client = AsynchXendClientProtocol() 
   8.153 +def xendmain(srv, fn, args, unix=False):
   8.154 +    if unix:
   8.155 +        xend = getUnixServer(srv)
   8.156      else:
   8.157 -        client = None
   8.158 -    xend = Xend(srv=srv, client=client)
   8.159 +        xend = getHttpServer(srv)
   8.160      xend.rc = 0
   8.161      try:
   8.162          v = getattr(xend, fn)(*args)
   8.163 +        PrettyPrint.prettyprint(v)
   8.164 +        return 0
   8.165      except XendError, err:
   8.166          print 'ERROR:', err
   8.167          return 1
   8.168 -    if asynch:
   8.169 -        def cbok(val):
   8.170 -            PrettyPrint.prettyprint(val)
   8.171 -            reactor.stop()
   8.172 -        def cberr(err):
   8.173 -            print 'ERROR:', err
   8.174 -            xend.rc = 1
   8.175 -            reactor.stop()
   8.176 -        v.addCallback(cbok)
   8.177 -        v.addErrback(cberr)
   8.178 -        reactor.run()
   8.179 -        return xend.rc
   8.180 -    else:
   8.181 -        PrettyPrint.prettyprint(v)
   8.182 -        return 0
   8.183  
   8.184  def main(argv):
   8.185      """Call an API function:
   8.186 @@ -411,16 +366,16 @@ python XendClient.py domain 0
   8.187      """
   8.188      global DEBUG
   8.189      from getopt import getopt
   8.190 -    short_options = 'x:ad'
   8.191 -    long_options = ['xend=', 'asynch', 'debug']
   8.192 +    short_options = 'x:au:d'
   8.193 +    long_options = ['xend=', 'unix=', 'debug']
   8.194      (options, args) = getopt(argv[1:], short_options, long_options)
   8.195      srv = None
   8.196 -    asynch = 0
   8.197 +    unix = 1
   8.198      for k, v in options:
   8.199          if k in ['-x', '--xend']:
   8.200              srv = v
   8.201 -        elif k in ['-a', '--asynch']:
   8.202 -            asynch = 1
   8.203 +        elif k in ['-u', '--unix']:
   8.204 +            unix = int(v)
   8.205          elif k in ['-d', '--debug']:
   8.206              DEBUG = 1
   8.207      if len(args):
   8.208 @@ -431,9 +386,9 @@ python XendClient.py domain 0
   8.209          args = []
   8.210      if not fn.startswith('xend'):
   8.211          fn = 'xend_' + fn
   8.212 -    sys.exit(xendmain(srv, asynch, fn, args))
   8.213 +    sys.exit(xendmain(srv, fn, args, unix=unix))
   8.214  
   8.215  if __name__ == "__main__":
   8.216      main(sys.argv)
   8.217  else:    
   8.218 -    server = Xend()
   8.219 +    server = getUnixServer()
     9.1 --- a/tools/python/xen/xend/XendDomain.py	Mon Apr 25 13:04:17 2005 +0000
     9.2 +++ b/tools/python/xen/xend/XendDomain.py	Wed Apr 27 14:04:44 2005 +0000
     9.3 @@ -778,7 +778,7 @@ class XendDomain:
     9.4          dominfo = self.domain_lookup(id)
     9.5          return dominfo.getDeviceByIndex(type, idx)
     9.6  
     9.7 -    def domain_vif_credit_limit(self, id, vif, credit, period):
     9.8 +    def domain_vif_limit_set(self, id, vif, credit, period):
     9.9          """Limit the vif's transmission rate
    9.10          """
    9.11          dominfo = self.domain_lookup(id)
    9.12 @@ -787,40 +787,6 @@ class XendDomain:
    9.13              raise XendError("invalid vif")
    9.14          return dev.setCreditLimit(credit, period)
    9.15          
    9.16 -    def domain_vif_ls(self, id):
    9.17 -        """Get list of virtual network interface (vif) indexes for a domain.
    9.18 -
    9.19 -        @param id: domain
    9.20 -        @return: vif indexes
    9.21 -        """
    9.22 -        return self.domain_devtype_ls(id, 'vif')
    9.23 -
    9.24 -    def domain_vif_get(self, id, vif):
    9.25 -        """Get a virtual network interface (vif) from a domain.
    9.26 -
    9.27 -        @param id: domain
    9.28 -        @param vif: vif index
    9.29 -        @return: vif device object (or None)
    9.30 -        """
    9.31 -        return self.domain_devtype_get(id, 'vif', vif)
    9.32 -
    9.33 -    def domain_vbd_ls(self, id):
    9.34 -        """Get list of virtual block device (vbd) indexes for a domain.
    9.35 -
    9.36 -        @param id: domain
    9.37 -        @return: vbd indexes
    9.38 -        """
    9.39 -        return self.domain_devtype_ls(id, 'vbd')
    9.40 -
    9.41 -    def domain_vbd_get(self, id, vbd):
    9.42 -        """Get a virtual block device (vbd) from a domain.
    9.43 -
    9.44 -        @param id: domain
    9.45 -        @param vbd: vbd index
    9.46 -        @return: vbd device (or None)
    9.47 -        """
    9.48 -        return self.domain_devtype_get(id, 'vbd', vbd)
    9.49 -
    9.50      def domain_shadow_control(self, id, op):
    9.51          """Shadow page control.
    9.52  
    10.1 --- a/tools/python/xen/xend/XendDomainConfig.py	Mon Apr 25 13:04:17 2005 +0000
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,44 +0,0 @@
    10.4 -# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    10.5 -
    10.6 -"""Handler for persistent domain configs.
    10.7 -
    10.8 -"""
    10.9 -
   10.10 -import sxp
   10.11 -import XendDB
   10.12 -import XendDomain
   10.13 -
   10.14 -__all__ = [ "XendDomainConfig" ]
   10.15 -
   10.16 -class XendDomainConfig:
   10.17 -
   10.18 -    dbpath = 'config'
   10.19 -
   10.20 -    def __init__(self):
   10.21 -        self.db = XendDB.XendDB(self.dbpath)
   10.22 -
   10.23 -    def domain_config_ls(self, path):
   10.24 -        return self.db.ls(path)
   10.25 -
   10.26 -    def domain_config_create(self, path, sxpr):
   10.27 -        self.db.save(path, sxpr)
   10.28 -        pass
   10.29 -
   10.30 -    def domain_config_delete(self, path):
   10.31 -        self.db.delete(path)
   10.32 -
   10.33 -    def domain_config_instance(self, path):
   10.34 -        """Create a domain from a config.
   10.35 -        """
   10.36 -        config = self.db.fetch(path)
   10.37 -        xd = XendDomain.instance()
   10.38 -        newdom = xd.domain_create(config)
   10.39 -        return newdom
   10.40 -
   10.41 -def instance():
   10.42 -    global inst
   10.43 -    try:
   10.44 -        inst
   10.45 -    except:
   10.46 -        inst = XendDomainConfig()
   10.47 -    return inst
    11.1 --- a/tools/python/xen/xend/XendProtocol.py	Mon Apr 25 13:04:17 2005 +0000
    11.2 +++ b/tools/python/xen/xend/XendProtocol.py	Wed Apr 27 14:04:44 2005 +0000
    11.3 @@ -1,5 +1,6 @@
    11.4  # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    11.5  
    11.6 +import socket
    11.7  import httplib
    11.8  import types
    11.9  
   11.10 @@ -122,12 +123,19 @@ class XendClientProtocol:
   11.11          """
   11.12          raise NotImplementedError()
   11.13  
   11.14 -class SynchXendClientProtocol(XendClientProtocol):
   11.15 +class HttpXendClientProtocol(XendClientProtocol):
   11.16      """A synchronous xend client. This will make a request, wait for
   11.17      the reply and return the result.
   11.18      """
   11.19  
   11.20      resp = None
   11.21 +    request = None
   11.22 +
   11.23 +    def makeConnection(self, url):
   11.24 +        return httplib.HTTPConnection(url.location())
   11.25 +
   11.26 +    def makeRequest(self, url, method, args):
   11.27 +        return XendRequest(url, method, args)
   11.28  
   11.29      def xendRequest(self, url, method, args=None):
   11.30          """Make a request to xend.
   11.31 @@ -136,8 +144,8 @@ class SynchXendClientProtocol(XendClient
   11.32          @param method: http method: POST or GET
   11.33          @param args:   request arguments (dict)
   11.34          """
   11.35 -        self.request = XendRequest(url, method, args)
   11.36 -        conn = httplib.HTTPConnection(url.location())
   11.37 +        self.request = self.makeRequest(url, method, args)
   11.38 +        conn = self.makeConnection(url)
   11.39          if DEBUG: conn.set_debuglevel(1)
   11.40          conn.request(method, url.fullpath(), self.request.data, self.request.headers)
   11.41          resp = conn.getresponse()
   11.42 @@ -154,3 +162,29 @@ class SynchXendClientProtocol(XendClient
   11.43      def getHeader(self, key):
   11.44          return self.resp.getheader(key)
   11.45  
   11.46 +class UnixConnection(httplib.HTTPConnection):
   11.47 +    """Subclass of Python library HTTPConnection that uses a unix-domain socket.
   11.48 +    """
   11.49 +
   11.50 +    def __init__(self, path):
   11.51 +        httplib.HTTPConnection.__init__(self, 'localhost')
   11.52 +        self.path = path
   11.53 +
   11.54 +    def connect(self):
   11.55 +        sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
   11.56 +        sock.connect(self.path)
   11.57 +        self.sock = sock
   11.58 +
   11.59 +class UnixXendClientProtocol(HttpXendClientProtocol):
   11.60 +    """A synchronous xend client using a unix-domain socket.
   11.61 +    """
   11.62 +
   11.63 +    XEND_PATH_DEFAULT = '/var/lib/xend/xend-socket'
   11.64 +    
   11.65 +    def __init__(self, path=None):
   11.66 +        if path is None:
   11.67 +            path = self.XEND_PATH_DEFAULT
   11.68 +        self.path = path
   11.69 +
   11.70 +    def makeConnection(self, url):
   11.71 +        return UnixConnection(self.path)
    12.1 --- a/tools/python/xen/xend/XendRoot.py	Mon Apr 25 13:04:17 2005 +0000
    12.2 +++ b/tools/python/xen/xend/XendRoot.py	Wed Apr 27 14:04:44 2005 +0000
    12.3 @@ -15,6 +15,7 @@ import sys
    12.4  
    12.5  import EventServer
    12.6  from XendLogging import XendLogging
    12.7 +from XendError import XendError
    12.8  
    12.9  # Initial create of the event server.
   12.10  eserver = EventServer.instance()
   12.11 @@ -44,6 +45,9 @@ class XendRoot:
   12.12  
   12.13      loglevel_default = 'DEBUG'
   12.14  
   12.15 +    """Default for the flag indicating whether xend should run an http server."""
   12.16 +    xend_http_server_default = 'no'
   12.17 +
   12.18      """Default interface address xend listens at. """
   12.19      xend_address_default      = ''
   12.20  
   12.21 @@ -53,7 +57,13 @@ class XendRoot:
   12.22      """Default port xend serves events at. """
   12.23      xend_event_port_default   = '8001'
   12.24  
   12.25 -    """Default inteface address xend listens at for consoles."""
   12.26 +    """Default for the flag indicating whether xend should run a unix-domain server."""
   12.27 +    xend_unix_server_default = 'yes'
   12.28 +
   12.29 +    """Default path the unix-domain server listens at."""
   12.30 +    xend_unix_path_default = '/var/lib/xend/xend-socket'
   12.31 +
   12.32 +    """Default interface address xend listens at for consoles."""
   12.33      console_address_default   = ''
   12.34  
   12.35      """Default port xend serves consoles at. """
   12.36 @@ -157,6 +167,7 @@ class XendRoot:
   12.37          logfile = self.get_config_value("logfile", self.logfile_default)
   12.38          loglevel = self.get_config_value("loglevel", self.loglevel_default)
   12.39          self.logging = XendLogging(logfile, level=loglevel)
   12.40 +        self.logging.addLogStderr()
   12.41  
   12.42      def get_logging(self):
   12.43          """Get the XendLogging instance.
   12.44 @@ -218,15 +229,35 @@ class XendRoot:
   12.45          """
   12.46          return sxp.child_value(self.config, name, val=val)
   12.47  
   12.48 +    def get_config_bool(self, name, val=None):
   12.49 +        v = self.get_config_value(name, val)
   12.50 +        if v in ['yes', '1', 'on', 1, True]:
   12.51 +            return True
   12.52 +        if v in ['no', '0', 'off', 0, False]:
   12.53 +            return False
   12.54 +        raise XendError("invalid xend config %s: expected bool: %s" % (name, v))
   12.55 +
   12.56 +    def get_config_int(self, name, val=None):
   12.57 +        v = self.get_config_value(name, val)
   12.58 +        try:
   12.59 +            return int(v)
   12.60 +        except Exception, ex:
   12.61 +            raise XendError("invalid xend config %s: expected int: %s" % (name, v))
   12.62 +
   12.63 +    def get_xend_http_server(self):
   12.64 +        """Get the flag indicating whether xend should run an http server.
   12.65 +        """
   12.66 +        return self.get_config_bool("xend-http-server", self.xend_http_server_default)
   12.67 +
   12.68      def get_xend_port(self):
   12.69          """Get the port xend listens at for its HTTP interface.
   12.70          """
   12.71 -        return int(self.get_config_value('xend-port', self.xend_port_default))
   12.72 +        return self.get_config_int('xend-port', self.xend_port_default)
   12.73  
   12.74      def get_xend_event_port(self):
   12.75          """Get the port xend listens at for connection to its event server.
   12.76          """
   12.77 -        return int(self.get_config_value('xend-event-port', self.xend_event_port_default))
   12.78 +        return self.get_config_int('xend-event-port', self.xend_event_port_default)
   12.79  
   12.80      def get_xend_address(self):
   12.81          """Get the address xend listens at for its HTTP and event ports.
   12.82 @@ -236,6 +267,16 @@ class XendRoot:
   12.83          """
   12.84          return self.get_config_value('xend-address', self.xend_address_default)
   12.85  
   12.86 +    def get_xend_unix_server(self):
   12.87 +        """Get the flag indicating whether xend should run a unix-domain server.
   12.88 +        """
   12.89 +        return self.get_config_bool("xend-unix-server", self.xend_unix_server_default)
   12.90 +
   12.91 +    def get_xend_unix_path(self):
   12.92 +        """Get the path the xend unix-domain server listens at.
   12.93 +        """
   12.94 +        return self.get_config_value("xend-unix-path", self.xend_unix_path_default)
   12.95 +
   12.96      def get_console_address(self):
   12.97          """Get the address xend listens at for its console ports.
   12.98          This defaults to the empty string which allows all hosts to connect.
   12.99 @@ -247,7 +288,7 @@ class XendRoot:
  12.100      def get_console_port_base(self):
  12.101          """Get the base port number used to generate console ports for domains.
  12.102          """
  12.103 -        return int(self.get_config_value('console-port-base', self.console_port_base_default))
  12.104 +        return self.get_config_int('console-port-base', self.console_port_base_default)
  12.105  
  12.106      def get_block_script(self, type):
  12.107          return self.get_config_value('block-%s' % type, '')
  12.108 @@ -262,8 +303,7 @@ class XendRoot:
  12.109          return self.get_config_value('vif-script', 'vif-bridge')
  12.110  
  12.111      def get_vif_antispoof(self):
  12.112 -        v = self.get_config_value('vif-antispoof', 'yes')
  12.113 -        return v in ['yes', '1', 'on']
  12.114 +        return self.get_config_bool('vif-antispoof', 'yes')
  12.115  
  12.116  def instance():
  12.117      """Get an instance of XendRoot.
    13.1 --- a/tools/python/xen/xend/server/SrvBase.py	Mon Apr 25 13:04:17 2005 +0000
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,2 +0,0 @@
    13.4 -# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    13.5 -from xen.web.SrvBase import *
    14.1 --- a/tools/python/xen/xend/server/SrvConsole.py	Mon Apr 25 13:04:17 2005 +0000
    14.2 +++ b/tools/python/xen/xend/server/SrvConsole.py	Wed Apr 27 14:04:44 2005 +0000
    14.3 @@ -2,7 +2,7 @@
    14.4  
    14.5  from xen.xend import sxp
    14.6  from xen.xend import XendConsole
    14.7 -from SrvDir import SrvDir
    14.8 +from xen.web.SrvDir import SrvDir
    14.9  
   14.10  class SrvConsole(SrvDir):
   14.11      """An individual console.
    15.1 --- a/tools/python/xen/xend/server/SrvDaemon.py	Mon Apr 25 13:04:17 2005 +0000
    15.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py	Wed Apr 27 14:04:44 2005 +0000
    15.3 @@ -326,10 +326,10 @@ class Daemon:
    15.4              self.createFactories()
    15.5              self.listenEvent(xroot)
    15.6              self.listenChannels()
    15.7 -            serverthread = SrvServer.create(bridge=1)
    15.8 +            servers = SrvServer.create()
    15.9              self.daemonize()
   15.10              print 'running serverthread...'
   15.11 -            serverthread.start()
   15.12 +            servers.start()
   15.13          except Exception, ex:
   15.14              print >>sys.stderr, 'Exception starting xend:', ex
   15.15              if DEBUG:
    16.1 --- a/tools/python/xen/xend/server/SrvDir.py	Mon Apr 25 13:04:17 2005 +0000
    16.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.3 @@ -1,3 +0,0 @@
    16.4 -# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    16.5 -from xen.web.SrvBase import *
    16.6 -from xen.web.SrvDir import *
    17.1 --- a/tools/python/xen/xend/server/SrvDmesg.py	Mon Apr 25 13:04:17 2005 +0000
    17.2 +++ b/tools/python/xen/xend/server/SrvDmesg.py	Wed Apr 27 14:04:44 2005 +0000
    17.3 @@ -5,7 +5,7 @@ import os
    17.4  from xen.xend import sxp
    17.5  from xen.xend import XendDmesg
    17.6  
    17.7 -from SrvDir import SrvDir
    17.8 +from xen.web.SrvDir import SrvDir
    17.9  
   17.10  class SrvDmesg(SrvDir):
   17.11      """Xen Dmesg output.
    18.1 --- a/tools/python/xen/xend/server/SrvDomain.py	Mon Apr 25 13:04:17 2005 +0000
    18.2 +++ b/tools/python/xen/xend/server/SrvDomain.py	Wed Apr 27 14:04:44 2005 +0000
    18.3 @@ -8,7 +8,7 @@ from xen.xend import XendConsole
    18.4  from xen.xend import PrettyPrint
    18.5  from xen.xend.Args import FormFn
    18.6  
    18.7 -from SrvDir import SrvDir
    18.8 +from xen.web.SrvDir import SrvDir
    18.9  
   18.10  class SrvDomain(SrvDir):
   18.11      """Service managing a single domain.
   18.12 @@ -35,10 +35,6 @@ class SrvDomain(SrvDir):
   18.13          return val
   18.14          
   18.15      def op_pause(self, op, req):
   18.16 -        # Pause doesn't need a thread, but request one for testing.
   18.17 -        return req.threadRequest(self.do_pause, op, req)
   18.18 -
   18.19 -    def do_pause(self, op, req):
   18.20          val = self.xd.domain_pause(self.dom.name)
   18.21          return val
   18.22  
   18.23 @@ -113,6 +109,31 @@ class SrvDomain(SrvDir):
   18.24                       ['memory', 'int']])
   18.25          val = fn(req.args, {'dom': self.dom.id})
   18.26          return val
   18.27 +    
   18.28 +    def op_mem_target_set(self, op, req):
   18.29 +        fn = FormFn(self.xd.domain_mem_target_set,
   18.30 +                    [['dom',    'str'],
   18.31 +                     ['target', 'int']])
   18.32 +        val = fn(req.args, {'dom': self.dom.id})
   18.33 +        return val
   18.34 +
   18.35 +    def op_devices(self, op, req):
   18.36 +        fn = FormFn(self.xd.domain_devtype_ls,
   18.37 +                    [['dom',    'str'],
   18.38 +                     ['type',   'str']])
   18.39 +        val = fn(req.args, {'dom': self.dom.id})
   18.40 +        return val
   18.41 +
   18.42 +    def op_device(self, op, req):
   18.43 +        fn = FormFn(self.xd.domain_devtype_get,
   18.44 +                    [['dom',    'str'],
   18.45 +                     ['type',   'str'],
   18.46 +                     ['idx',    'int']])
   18.47 +        val = fn(req.args, {'dom': self.dom.id})
   18.48 +        if val:
   18.49 +            return val.sxpr()
   18.50 +        else:
   18.51 +            raise XendError("invalid device")
   18.52  
   18.53      def op_device_create(self, op, req):
   18.54          fn = FormFn(self.xd.domain_device_create,
   18.55 @@ -145,8 +166,8 @@ class SrvDomain(SrvDir):
   18.56          val = fn(req.args, {'dom': self.dom.id})
   18.57          return val
   18.58  
   18.59 -    def op_vif_credit_limit(self, op, req):
   18.60 -        fn = FormFn(self.xd.domain_vif_credit_limit,
   18.61 +    def op_vif_limit_set(self, op, req):
   18.62 +        fn = FormFn(self.xd.domain_vif_limit_set,
   18.63                      [['dom',    'str'],
   18.64                       ['vif',    'int'],
   18.65                       ['credit', 'int'],
   18.66 @@ -154,35 +175,6 @@ class SrvDomain(SrvDir):
   18.67          val = fn(req.args, {'dom': self.dom.id})
   18.68          return val
   18.69  
   18.70 -    def op_vifs(self, op, req):
   18.71 -        devs = self.xd.domain_vif_ls(self.dom.id)
   18.72 -        return [ dev.sxpr() for dev in devs ]
   18.73 -
   18.74 -    def op_vif(self, op, req):
   18.75 -        fn = FormFn(self.xd.domain_vif_get,
   18.76 -                    [['dom', 'str'],
   18.77 -                     ['vif', 'str']])
   18.78 -        val = fn(req.args, {'dom': self.dom.id})
   18.79 -        return val
   18.80 -
   18.81 -    def op_vbds(self, op, req):
   18.82 -        devs = self.xd.domain_vbd_ls(self.dom.id)
   18.83 -        return [ dev.sxpr() for dev in devs ]
   18.84 -
   18.85 -    def op_vbd(self, op, req):
   18.86 -        fn = FormFn(self.xd.domain_vbd_get,
   18.87 -                    [['dom', 'str'],
   18.88 -                     ['vbd', 'str']])
   18.89 -        val = fn(req.args, {'dom': self.dom.id})
   18.90 -        return val
   18.91 -
   18.92 -    def op_mem_target_set(self, op, req):
   18.93 -        fn = FormFn(self.xd.domain_mem_target_set,
   18.94 -                    [['dom',    'str'],
   18.95 -                     ['target', 'int']])
   18.96 -        val = fn(req.args, {'dom': self.dom.id})
   18.97 -        return val
   18.98 -
   18.99      def render_POST(self, req):
  18.100          return self.perform(req)
  18.101          
    19.1 --- a/tools/python/xen/xend/server/SrvDomainDir.py	Mon Apr 25 13:04:17 2005 +0000
    19.2 +++ b/tools/python/xen/xend/server/SrvDomainDir.py	Wed Apr 27 14:04:44 2005 +0000
    19.3 @@ -11,7 +11,7 @@ from xen.xend.Args import FormFn
    19.4  from xen.xend.XendError import XendError
    19.5  from xen.xend.XendLogging import log
    19.6  
    19.7 -from SrvDir import SrvDir
    19.8 +from xen.web.SrvDir import SrvDir
    19.9  from SrvDomain import SrvDomain
   19.10  
   19.11  class SrvDomainDir(SrvDir):
    20.1 --- a/tools/python/xen/xend/server/SrvEventDir.py	Mon Apr 25 13:04:17 2005 +0000
    20.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.3 @@ -1,41 +0,0 @@
    20.4 -# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    20.5 -
    20.6 -from xen.xend import sxp
    20.7 -from xen.xend import EventServer
    20.8 -from SrvDir import SrvDir
    20.9 -
   20.10 -class SrvEventDir(SrvDir):
   20.11 -    """Event directory.
   20.12 -    """
   20.13 -
   20.14 -    def __init__(self):
   20.15 -        SrvDir.__init__(self)
   20.16 -        self.eserver = EventServer.instance()
   20.17 -
   20.18 -    def op_inject(self, op, req):
   20.19 -        eventstring = req.args.get('event')
   20.20 -        pin = sxp.Parser()
   20.21 -        pin.input(eventstring)
   20.22 -        pin.input_eof()
   20.23 -        sxpr = pin.get_val()
   20.24 -        self.eserver.inject(sxp.name(sxpr), sxpr)
   20.25 -        if req.use_sxp:
   20.26 -            sxp.name(sxpr)
   20.27 -        else:
   20.28 -            return '<code>' + eventstring + '</code>'
   20.29 -        
   20.30 -    def render_POST(self, req):
   20.31 -        return self.perform(req)
   20.32 -
   20.33 -    def form(self, req):
   20.34 -        action = req.prePathURL()
   20.35 -        req.write('<form method="post" action="%s" enctype="multipart/form-data">'
   20.36 -                  % action)
   20.37 -        req.write('<button type="submit" name="op" value="inject">Inject</button>')
   20.38 -        req.write('Event <input type="text" name="event" size="40"><br>')
   20.39 -        req.write('</form>')
   20.40 -        req.write('<form method="post" action="%s" enctype="multipart/form-data">'
   20.41 -                  % action)
   20.42 -        req.write('<button type="submit" name="op" value="inject">Inject</button>')
   20.43 -        req.write('Event file<input type="file" name="event"><br>')
   20.44 -        req.write('</form>')
    21.1 --- a/tools/python/xen/xend/server/SrvNode.py	Mon Apr 25 13:04:17 2005 +0000
    21.2 +++ b/tools/python/xen/xend/server/SrvNode.py	Wed Apr 27 14:04:44 2005 +0000
    21.3 @@ -2,7 +2,7 @@
    21.4  
    21.5  import os
    21.6  
    21.7 -from SrvDir import SrvDir
    21.8 +from xen.web.SrvDir import SrvDir
    21.9  from xen.xend import sxp
   21.10  from xen.xend import XendNode
   21.11  from xen.xend.Args import FormFn
    22.1 --- a/tools/python/xen/xend/server/SrvRoot.py	Mon Apr 25 13:04:17 2005 +0000
    22.2 +++ b/tools/python/xen/xend/server/SrvRoot.py	Wed Apr 27 14:04:44 2005 +0000
    22.3 @@ -2,7 +2,7 @@
    22.4  
    22.5  from xen.xend import XendRoot
    22.6  xroot = XendRoot.instance()
    22.7 -from SrvDir import SrvDir
    22.8 +from xen.web.SrvDir import SrvDir
    22.9  
   22.10  class SrvRoot(SrvDir):
   22.11      """The root of the xend server.
   22.12 @@ -16,7 +16,6 @@ class SrvRoot(SrvDir):
   22.13          ('node',    'SrvNode'       ),
   22.14          ('domain',  'SrvDomainDir'  ),
   22.15          ('console', 'SrvConsoleDir' ),
   22.16 -        ('event',   'SrvEventDir'   ),
   22.17          ('vnet',    'SrvVnetDir'    ),
   22.18          ]
   22.19  
    23.1 --- a/tools/python/xen/xend/server/SrvServer.py	Mon Apr 25 13:04:17 2005 +0000
    23.2 +++ b/tools/python/xen/xend/server/SrvServer.py	Wed Apr 27 14:04:44 2005 +0000
    23.3 @@ -27,23 +27,38 @@
    23.4  
    23.5  from threading import Thread
    23.6  
    23.7 -from xen.web.httpserver import HttpServer
    23.8 +from xen.web.httpserver import HttpServer, UnixHttpServer
    23.9  
   23.10 -from xen.xend import XendRoot
   23.11 -xroot = XendRoot.instance()
   23.12 +from xen.xend import XendRoot; xroot = XendRoot.instance()
   23.13  from xen.xend import Vifctl
   23.14 +from xen.web.SrvDir import SrvDir
   23.15 +
   23.16  from SrvRoot import SrvRoot
   23.17 -from SrvDir import SrvDir
   23.18  
   23.19 -def create(port=None, interface=None, bridge=0):
   23.20 -    if port is None:
   23.21 -        port = xroot.get_xend_port()
   23.22 -    if interface is None:
   23.23 -        interface = xroot.get_xend_address()
   23.24 -    if bridge:
   23.25 +class XendServers:
   23.26 +
   23.27 +    def __init__(self):
   23.28 +        self.servers = []
   23.29 +
   23.30 +    def add(self, server):
   23.31 +        self.servers.append(server)
   23.32 +
   23.33 +    def start(self):
   23.34          Vifctl.network('start')
   23.35 +        for server in self.servers:
   23.36 +            thread = Thread(target=server.run)
   23.37 +            thread.start()
   23.38 +
   23.39 +def create():
   23.40      root = SrvDir()
   23.41      root.putChild('xend', SrvRoot())
   23.42 -    server = HttpServer(root=root, interface=interface, port=port)
   23.43 -    thread = Thread(name="XendHttpServer", target=server.run)
   23.44 -    return thread
   23.45 +    servers = XendServers()
   23.46 +    if xroot.get_xend_http_server():
   23.47 +        port = xroot.get_xend_port()
   23.48 +        interface = xroot.get_xend_address()
   23.49 +        servers.add(HttpServer(root=root, interface=interface, port=port))
   23.50 +    if xroot.get_xend_unix_server():
   23.51 +        path = xroot.get_xend_unix_path()
   23.52 +        print 'unix path=', path
   23.53 +        servers.add(UnixHttpServer(path=path, root=root))
   23.54 +    return servers
    24.1 --- a/tools/python/xen/xend/server/SrvUsbif.py	Mon Apr 25 13:04:17 2005 +0000
    24.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.3 @@ -1,239 +0,0 @@
    24.4 -# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    24.5 -
    24.6 -from xen.web import http
    24.7 -
    24.8 -from xen.xend import sxp
    24.9 -from xen.xend import XendDomain
   24.10 -from xen.xend import XendConsole
   24.11 -from xen.xend import PrettyPrint
   24.12 -from xen.xend.Args import FormFn
   24.13 -
   24.14 -from SrvDir import SrvDir
   24.15 -
   24.16 -class SrvDomain(SrvDir):
   24.17 -    """Service managing a single domain.
   24.18 -    """
   24.19 -
   24.20 -    def __init__(self, dom):
   24.21 -        SrvDir.__init__(self)
   24.22 -        self.dom = dom
   24.23 -        self.xd = XendDomain.instance()
   24.24 -        self.xconsole = XendConsole.instance()
   24.25 -
   24.26 -    def op_configure(self, op, req):
   24.27 -        """Configure an existing domain.
   24.28 -        Configure is unusual in that it requires a domain id,
   24.29 -        not a domain name.
   24.30 -        """
   24.31 -        fn = FormFn(self.xd.domain_configure,
   24.32 -                    [['dom', 'int'],
   24.33 -                     ['config', 'sxpr']])
   24.34 -        deferred = fn(req.args, {'dom': self.dom.dom})
   24.35 -        deferred.addErrback(self._op_configure_err, req)
   24.36 -        return deferred
   24.37 -
   24.38 -    def _op_configure_err(self, err, req):
   24.39 -        req.setResponseCode(http.BAD_REQUEST, "Error: "+ str(err))
   24.40 -        return str(err)
   24.41 -        
   24.42 -    def op_unpause(self, op, req):
   24.43 -        val = self.xd.domain_unpause(self.dom.name)
   24.44 -        return val
   24.45 -        
   24.46 -    def op_pause(self, op, req):
   24.47 -        val = self.xd.domain_pause(self.dom.name)
   24.48 -        return val
   24.49 -
   24.50 -    def op_shutdown(self, op, req):
   24.51 -        fn = FormFn(self.xd.domain_shutdown,
   24.52 -                    [['dom', 'str'],
   24.53 -                     ['reason', 'str']])
   24.54 -        val = fn(req.args, {'dom': self.dom.id})
   24.55 -        req.setResponseCode(http.ACCEPTED)
   24.56 -        req.setHeader("Location", "%s/.." % req.prePathURL())
   24.57 -        return val
   24.58 -
   24.59 -    def op_destroy(self, op, req):
   24.60 -        fn = FormFn(self.xd.domain_destroy,
   24.61 -                    [['dom', 'str'],
   24.62 -                     ['reason', 'str']])
   24.63 -        val = fn(req.args, {'dom': self.dom.id})
   24.64 -        req.setHeader("Location", "%s/.." % req.prePathURL())
   24.65 -        return val
   24.66 -
   24.67 -    def op_save(self, op, req):
   24.68 -        fn = FormFn(self.xd.domain_save,
   24.69 -                    [['dom', 'str'],
   24.70 -                     ['file', 'str']])
   24.71 -        deferred = fn(req.args, {'dom': self.dom.id})
   24.72 -        deferred.addCallback(self._op_save_cb, req)
   24.73 -        deferred.addErrback(self._op_save_err, req)
   24.74 -        return deferred
   24.75 -
   24.76 -    def _op_save_cb(self, val, req):
   24.77 -        return 0
   24.78 -
   24.79 -    def _op_save_err(self, err, req):
   24.80 -        req.setResponseCode(http.BAD_REQUEST, "Error: "+ str(err))
   24.81 -        return str(err)
   24.82 -        
   24.83 -    def op_migrate(self, op, req):
   24.84 -        fn = FormFn(self.xd.domain_migrate,
   24.85 -                    [['dom', 'str'],
   24.86 -                     ['destination', 'str'],
   24.87 -                     ['live', 'int']])
   24.88 -        deferred = fn(req.args, {'dom': self.dom.id})
   24.89 -        print 'op_migrate>', deferred
   24.90 -        deferred.addCallback(self._op_migrate_cb, req)
   24.91 -        deferred.addErrback(self._op_migrate_err, req)
   24.92 -        return deferred
   24.93 -
   24.94 -    def _op_migrate_cb(self, info, req):
   24.95 -        print '_op_migrate_cb>', info, req
   24.96 -        #req.setResponseCode(http.ACCEPTED)
   24.97 -        host = info.dst_host
   24.98 -        port = info.dst_port
   24.99 -        dom  = info.dst_dom
  24.100 -        url = "http://%s:%d/xend/domain/%d" % (host, port, dom)
  24.101 -        req.setHeader("Location", url)
  24.102 -        print '_op_migrate_cb> url=', url
  24.103 -        return url
  24.104 -
  24.105 -    def _op_migrate_err(self, err, req):
  24.106 -        print '_op_migrate_err>', err, req
  24.107 -        req.setResponseCode(http.BAD_REQUEST, "Error: "+ str(err))
  24.108 -        return str(err)
  24.109 -
  24.110 -    def op_pincpu(self, op, req):
  24.111 -        fn = FormFn(self.xd.domain_pincpu,
  24.112 -                    [['dom', 'str'],
  24.113 -                     ['cpu', 'int']])
  24.114 -        val = fn(req.args, {'dom': self.dom.id})
  24.115 -        return val
  24.116 -
  24.117 -    def op_cpu_bvt_set(self, op, req):
  24.118 -        fn = FormFn(self.xd.domain_cpu_bvt_set,
  24.119 -                    [['dom', 'str'],
  24.120 -                     ['mcuadv', 'int'],
  24.121 -                     ['warpback', 'int'],
  24.122 -                     ['warpvalue', 'int'],
  24.123 -                     ['warpl', 'long'],
  24.124 -                     ['warpu', 'long']])
  24.125 -        val = fn(req.args, {'dom': self.dom.id})
  24.126 -        return val
  24.127 -    
  24.128 -    def op_cpu_fbvt_set(self, op, req):
  24.129 -        fn = FormFn(self.xd.domain_cpu_fbvt_set,
  24.130 -                    [['dom', 'str'],
  24.131 -                     ['mcuadv', 'int'],
  24.132 -                     ['warp', 'int'],
  24.133 -                     ['warpl', 'int'],
  24.134 -                     ['warpu', 'int']])
  24.135 -        val = fn(req.args, {'dom': self.dom.id})
  24.136 -        return val
  24.137 -
  24.138 -    def op_maxmem_set(self, op, req):
  24.139 -        fn = FormFn(self.xd.domain_maxmem_set,
  24.140 -                    [['dom', 'str'],
  24.141 -                     ['memory', 'int']])
  24.142 -        val = fn(req.args, {'dom': self.dom.id})
  24.143 -        return val
  24.144 -
  24.145 -    def op_device_create(self, op, req):
  24.146 -        fn = FormFn(self.xd.domain_device_create,
  24.147 -                    [['dom', 'str'],
  24.148 -                     ['config', 'sxpr']])
  24.149 -        d = fn(req.args, {'dom': self.dom.id})
  24.150 -        return d
  24.151 -
  24.152 -    def op_device_destroy(self, op, req):
  24.153 -        fn = FormFn(self.xd.domain_device_destroy,
  24.154 -                    [['dom', 'str'],
  24.155 -                     ['type', 'str'],
  24.156 -                     ['idx', 'str']])
  24.157 -        val = fn(req.args, {'dom': self.dom.id})
  24.158 -        return val
  24.159 -                
  24.160 -    def op_vifs(self, op, req):
  24.161 -        devs = self.xd.domain_vif_ls(self.dom.id)
  24.162 -        return [ dev.sxpr() for dev in devs ]
  24.163 -
  24.164 -    def op_vif(self, op, req):
  24.165 -        fn = FormFn(self.xd.domain_vif_get,
  24.166 -                    [['dom', 'str'],
  24.167 -                     ['vif', 'str']])
  24.168 -        val = fn(req.args, {'dom': self.dom.id})
  24.169 -        return val
  24.170 -
  24.171 -    def op_vbds(self, op, req):
  24.172 -        devs = self.xd.domain_vbd_ls(self.dom.id)
  24.173 -        return [ dev.sxpr() for dev in devs ]
  24.174 -
  24.175 -    def op_vbd(self, op, req):
  24.176 -        fn = FormFn(self.xd.domain_vbd_get,
  24.177 -                    [['dom', 'str'],
  24.178 -                     ['vbd', 'str']])
  24.179 -        val = fn(req.args, {'dom': self.dom.id})
  24.180 -        return val
  24.181 -
  24.182 -    def render_POST(self, req):
  24.183 -        return self.perform(req)
  24.184 -        
  24.185 -    def render_GET(self, req):
  24.186 -        op = req.args.get('op')
  24.187 -        if op and op[0] in ['vifs', 'vif', 'vbds', 'vbd']:
  24.188 -            return self.perform(req)
  24.189 -        if self.use_sxp(req):
  24.190 -            req.setHeader("Content-Type", sxp.mime_type)
  24.191 -            sxp.show(self.dom.sxpr(), out=req)
  24.192 -        else:
  24.193 -            req.write('<html><head></head><body>')
  24.194 -            self.print_path(req)
  24.195 -            #self.ls()
  24.196 -            req.write('<p>%s</p>' % self.dom)
  24.197 -            if self.dom.console:
  24.198 -                cinfo = self.dom.console
  24.199 -                cid = str(cinfo.console_port)
  24.200 -                #todo: Local xref: need to know server prefix.
  24.201 -                req.write('<p><a href="/xend/console/%s">Console %s</a></p>'
  24.202 -                          % (cid, cid))
  24.203 -                req.write('<p><a href="%s">Connect to console</a></p>'
  24.204 -                          % cinfo.uri())
  24.205 -            if self.dom.config:
  24.206 -                req.write("<code><pre>")
  24.207 -                PrettyPrint.prettyprint(self.dom.config, out=req)
  24.208 -                req.write("</pre></code>")
  24.209 -            self.form(req)
  24.210 -            req.write('</body></html>')
  24.211 -        return ''
  24.212 -
  24.213 -    def form(self, req):
  24.214 -        url = req.prePathURL()
  24.215 -        req.write('<form method="post" action="%s">' % url)
  24.216 -        req.write('<input type="submit" name="op" value="unpause">')
  24.217 -        req.write('<input type="submit" name="op" value="pause">')
  24.218 -        req.write('</form>')
  24.219 -
  24.220 -        req.write('<form method="post" action="%s">' % url)
  24.221 -        req.write('<input type="submit" name="op" value="destroy">')
  24.222 -        req.write('<input type="radio" name="reason" value="halt" checked>Halt')
  24.223 -        req.write('<input type="radio" name="reason" value="reboot">Reboot')
  24.224 -        req.write('</form>')
  24.225 -
  24.226 -        req.write('<form method="post" action="%s">' % url)
  24.227 -        req.write('<input type="submit" name="op" value="shutdown">')
  24.228 -        req.write('<input type="radio" name="reason" value="poweroff" checked>Poweroff')
  24.229 -        req.write('<input type="radio" name="reason" value="halt">Halt')
  24.230 -        req.write('<input type="radio" name="reason" value="reboot">Reboot')
  24.231 -        req.write('</form>')
  24.232 -        
  24.233 -        req.write('<form method="post" action="%s">' % url)
  24.234 -        req.write('<br><input type="submit" name="op" value="save">')
  24.235 -        req.write(' To file: <input type="text" name="file">')
  24.236 -        req.write('</form>')
  24.237 -        
  24.238 -        req.write('<form method="post" action="%s">' % url)
  24.239 -        req.write('<br><input type="submit" name="op" value="migrate">')
  24.240 -        req.write(' To host: <input type="text" name="destination">')
  24.241 -        req.write('<input type="checkbox" name="live" value="1">Live')
  24.242 -        req.write('</form>')
    25.1 --- a/tools/python/xen/xend/server/SrvVnetDir.py	Mon Apr 25 13:04:17 2005 +0000
    25.2 +++ b/tools/python/xen/xend/server/SrvVnetDir.py	Wed Apr 27 14:04:44 2005 +0000
    25.3 @@ -5,7 +5,7 @@ from xen.xend.Args import FormFn
    25.4  from xen.xend import PrettyPrint
    25.5  from xen.xend import XendVnet
    25.6  
    25.7 -from SrvDir import SrvDir
    25.8 +from xen.web.SrvDir import SrvDir
    25.9  
   25.10  class SrvVnet(SrvDir):
   25.11  
    26.1 --- a/tools/python/xen/xend/server/SrvXendLog.py	Mon Apr 25 13:04:17 2005 +0000
    26.2 +++ b/tools/python/xen/xend/server/SrvXendLog.py	Wed Apr 27 14:04:44 2005 +0000
    26.3 @@ -4,7 +4,7 @@ from xen.web import static
    26.4  
    26.5  from xen.xend import XendRoot
    26.6  
    26.7 -from SrvDir import SrvDir
    26.8 +from xen.web.SrvDir import SrvDir
    26.9  
   26.10  class SrvXendLog(SrvDir):
   26.11      """Xend log.
    27.1 --- a/tools/python/xen/xend/server/blkif.py	Mon Apr 25 13:04:17 2005 +0000
    27.2 +++ b/tools/python/xen/xend/server/blkif.py	Wed Apr 27 14:04:44 2005 +0000
    27.3 @@ -425,10 +425,10 @@ class BlkifController(DevController):
    27.4      for a domain.
    27.5      """
    27.6      
    27.7 -    def __init__(self, dctype, vm, recreate=False):
    27.8 +    def __init__(self, vm, recreate=False):
    27.9          """Create a block device controller.
   27.10          """
   27.11 -        DevController.__init__(self, dctype, vm, recreate=recreate)
   27.12 +        DevController.__init__(self, vm, recreate=recreate)
   27.13          self.backends = {}
   27.14          self.backendId = 0
   27.15          self.rcvr = None
    28.1 --- a/tools/python/xen/xend/server/channel.py	Mon Apr 25 13:04:17 2005 +0000
    28.2 +++ b/tools/python/xen/xend/server/channel.py	Wed Apr 27 14:04:44 2005 +0000
    28.3 @@ -66,6 +66,8 @@ class ChannelFactory:
    28.4      def __init__(self):
    28.5          """Constructor - do not use. Use the channelFactory function."""
    28.6          self.notifier = xu.notifier()
    28.7 +        # Register interest in all virqs.
    28.8 +        # Unfortunately virqs do not seem to be delivered.
    28.9          self.bind_virq(VIRQ_MISDIRECT)
   28.10          self.bind_virq(VIRQ_TIMER)
   28.11          self.bind_virq(VIRQ_DEBUG)
   28.12 @@ -97,6 +99,7 @@ class ChannelFactory:
   28.13  
   28.14      def main(self):
   28.15          """Main routine for the thread.
   28.16 +        Reads the notifier and dispatches to channels.
   28.17          """
   28.18          while True:
   28.19              if self.thread == None: return
   28.20 @@ -224,18 +227,23 @@ def channelFactory():
   28.21      return inst
   28.22  
   28.23  class Channel:
   28.24 +    """Chanel to a domain.
   28.25 +    Maintains a list of device handlers to dispatch requests to, based
   28.26 +    on the request type.
   28.27 +    """
   28.28  
   28.29      def __init__(self, factory, dom, local_port, remote_port):
   28.30          self.factory = factory
   28.31          self.dom = int(dom)
   28.32 -        # Registered devices.
   28.33 +        # Registered device handlers.
   28.34          self.devs = []
   28.35 -        # Devices indexed by the message types they handle.
   28.36 +        # Handlers indexed by the message types they handle.
   28.37          self.devs_by_type = {}
   28.38          self.port = self.factory.createPort(self.dom,
   28.39                                              local_port=local_port,
   28.40                                              remote_port=remote_port)
   28.41          self.closed = False
   28.42 +        # Queue of waiters for responses to requests.
   28.43          self.queue = ResponseQueue(self)
   28.44          # Make sure the port will deliver all the messages.
   28.45          self.port.register(TYPE_WILDCARD)
   28.46 @@ -298,11 +306,11 @@ class Channel:
   28.47  
   28.48  
   28.49      def registerDevice(self, types, dev):
   28.50 -        """Register a device controller.
   28.51 +        """Register a device message handler.
   28.52  
   28.53 -        @param types: message types the controller handles
   28.54 +        @param types: message types handled
   28.55          @type  types: array of ints
   28.56 -        @param dev:   device controller
   28.57 +        @param dev:   device handler
   28.58          """
   28.59          if self.closed: return
   28.60          self.devs.append(dev)
   28.61 @@ -310,9 +318,9 @@ class Channel:
   28.62              self.devs_by_type[ty] = dev
   28.63  
   28.64      def deregisterDevice(self, dev):
   28.65 -        """Remove the registration for a device controller.
   28.66 +        """Remove the registration for a device handler.
   28.67  
   28.68 -        @param dev: device controller
   28.69 +        @param dev: device handler
   28.70          """
   28.71          if dev in self.devs:
   28.72              self.devs.remove(dev)
   28.73 @@ -321,16 +329,20 @@ class Channel:
   28.74              del self.devs_by_type[ty]
   28.75  
   28.76      def getDevice(self, type):
   28.77 -        """Get the device controller handling a message type.
   28.78 +        """Get the handler for a message type.
   28.79  
   28.80          @param type: message type
   28.81          @type  type: int
   28.82          @return: controller or None
   28.83 -        @rtype:  device controller
   28.84 +        @rtype:  device handler
   28.85          """
   28.86          return self.devs_by_type.get(type)
   28.87  
   28.88      def requestReceived(self, msg):
   28.89 +        """A request has been received on the channel.
   28.90 +        Disptach it to the device handlers.
   28.91 +        Called from the channel factory thread.
   28.92 +        """
   28.93          if DEBUG:
   28.94              print 'Channel>requestReceived>', self,
   28.95              printMsg(msg)
   28.96 @@ -340,7 +352,7 @@ class Channel:
   28.97          if dev:
   28.98              responded = dev.requestReceived(msg, ty, subty)
   28.99          elif DEBUG:
  28.100 -            print "Channel>requestReceived> No device", self,
  28.101 +            print "Channel>requestReceived> No device handler", self,
  28.102              printMsg(msg)
  28.103          else:
  28.104              pass
  28.105 @@ -348,6 +360,8 @@ class Channel:
  28.106              self.writeResponse(msg)
  28.107  
  28.108      def writeRequest(self, msg):
  28.109 +        """Write a request to the channel.
  28.110 +        """
  28.111          if DEBUG:
  28.112              print 'Channel>writeRequest>', self,
  28.113              printMsg(msg, all=True)
  28.114 @@ -356,6 +370,8 @@ class Channel:
  28.115          return 1
  28.116  
  28.117      def writeResponse(self, msg):
  28.118 +        """Write a response to the channel.
  28.119 +        """
  28.120          if DEBUG:
  28.121              print 'Channel>writeResponse>', self,
  28.122              printMsg(msg, all=True)
  28.123 @@ -364,6 +380,9 @@ class Channel:
  28.124          return 1
  28.125  
  28.126      def readRequest(self):
  28.127 +        """Read a request from the channel.
  28.128 +        Called internally.
  28.129 +        """
  28.130          if self.closed:
  28.131              val =  None
  28.132          else:
  28.133 @@ -371,6 +390,9 @@ class Channel:
  28.134          return val
  28.135          
  28.136      def readResponse(self):
  28.137 +        """Read a response from the channel.
  28.138 +        Called internally.
  28.139 +        """
  28.140          if self.closed:
  28.141              val = None
  28.142          else:
  28.143 @@ -399,6 +421,10 @@ class Channel:
  28.144          return self.queue.call(msg, timeout)
  28.145  
  28.146      def responseReceived(self, msg):
  28.147 +        """A response has been received, look for a waiter to
  28.148 +        give it to.
  28.149 +        Called internally.
  28.150 +        """
  28.151          if DEBUG:
  28.152              print 'Channel>responseReceived>', self,
  28.153              printMsg(msg)
  28.154 @@ -407,7 +433,6 @@ class Channel:
  28.155      def virq(self):
  28.156          self.factory.virq()
  28.157  
  28.158 -
  28.159  class Response:
  28.160      """Entry in the response queue.
  28.161      Used to signal a response to a message.
  28.162 @@ -463,7 +488,8 @@ class ResponseQueue:
  28.163          return r
  28.164  
  28.165      def response(self, mid, msg):
  28.166 -        """Process a response.
  28.167 +        """Process a response - signals any waiter that a response
  28.168 +        has arrived.
  28.169          """
  28.170          try:
  28.171              self.lock.acquire()
    29.1 --- a/tools/python/xen/xend/server/console.py	Mon Apr 25 13:04:17 2005 +0000
    29.2 +++ b/tools/python/xen/xend/server/console.py	Wed Apr 27 14:04:44 2005 +0000
    29.3 @@ -326,8 +326,8 @@ class ConsoleController(DevController):
    29.4      """Device controller for all the consoles for a domain.
    29.5      """
    29.6  
    29.7 -    def __init__(self, dctype, vm, recreate=False):
    29.8 -        DevController.__init__(self, dctype, vm, recreate=recreate)
    29.9 +    def __init__(self, vm, recreate=False):
   29.10 +        DevController.__init__(self, vm, recreate=recreate)
   29.11          self.rcvr = None
   29.12  
   29.13      def initController(self, recreate=False, reboot=False):
    30.1 --- a/tools/python/xen/xend/server/controller.py	Mon Apr 25 13:04:17 2005 +0000
    30.2 +++ b/tools/python/xen/xend/server/controller.py	Wed Apr 27 14:04:44 2005 +0000
    30.3 @@ -9,7 +9,7 @@ from messages import msgTypeName, printM
    30.4  DEBUG = 0
    30.5  
    30.6  class CtrlMsgRcvr:
    30.7 -    """Dispatcher class for messages on a control channel.
    30.8 +    """Utility class to dispatch messages on a control channel.
    30.9      Once I{registerChannel} has been called, our message types are registered
   30.10      with the channel. The channel will call I{requestReceived}
   30.11      when a request arrives if it has one of our message types.
   30.12 @@ -105,65 +105,32 @@ class CtrlMsgRcvr:
   30.13          if self.channel:
   30.14              self.channel.deregisterDevice(self)
   30.15  
   30.16 -class DevControllerType:
   30.17 -    """Abstract class for device controller types.
   30.18 -    """
   30.19 -
   30.20 -    def __init__(self, type):
   30.21 -        self.type = type
   30.22 -
   30.23 -    def getType(self):
   30.24 -        """Get the device controller type name.
   30.25 -        """
   30.26 -        return self.type
   30.27 -
   30.28 -    def createDevController(self, vm, recreate=False):
   30.29 -        """Create a device controller for a domain.
   30.30 -           Must be implemented in subclass.
   30.31 -        """
   30.32 -        raise NotImplementedError()
   30.33 -
   30.34 -class SimpleDevControllerType(DevControllerType):
   30.35 -    """Device controller type that simply wraps a controller
   30.36 -    class and uses its constructor to create instances.
   30.37 -    """
   30.38 -    
   30.39 -    def __init__(self, type, devControllerClass):
   30.40 -        DevControllerType.__init__(self, type)
   30.41 -        self.devControllerClass = devControllerClass
   30.42 -
   30.43 -    def createDevController(self, vm, recreate=False):
   30.44 -        """Create a device controller for a domain.
   30.45 -        """
   30.46 -        ctrl = self.devControllerClass(self, vm, recreate=recreate)
   30.47 -        ctrl.initController(recreate=recreate)
   30.48 -        return ctrl
   30.49 -
   30.50  class DevControllerTable:
   30.51 -    """Table of device controller types, indexed by type name.
   30.52 +    """Table of device controller classes, indexed by type name.
   30.53      """
   30.54  
   30.55      def __init__(self):
   30.56 -        self.controllerTypes = {}
   30.57 -
   30.58 -    def getDevControllerType(self, type):
   30.59 -        return self.controllerTypes.get(type)
   30.60 +        self.controllerClasses = {}
   30.61  
   30.62 -    def addDevControllerType(self, dctype):
   30.63 -        self.controllerTypes[dctype.getType()] = dctype
   30.64 -        return dctype
   30.65 +    def getDevControllerClass(self, type):
   30.66 +        return self.controllerClasses.get(type)
   30.67  
   30.68 -    def delDevControllerType(self, type):
   30.69 -        if type in self.controllerTypes:
   30.70 -            del self.controllerTypes[type]
   30.71 +    def addDevControllerClass(self, klass):
   30.72 +        self.controllerClasses[klass.getType()] = klass
   30.73 +
   30.74 +    def delDevControllerClass(self, type):
   30.75 +        if type in self.controllerClasses:
   30.76 +            del self.controllerClasses[type]
   30.77  
   30.78      def createDevController(self, type, vm, recreate=False):
   30.79 -        dctype = self.getDevControllerType(type)
   30.80 -        if not dctype:
   30.81 +        klass = self.getDevControllerClass(type)
   30.82 +        if not klass:
   30.83              raise XendError("unknown device type: " + type)
   30.84 -        return dctype.createDevController(vm, recreate=recreate)
   30.85 +        return klass.createDevController(vm, recreate=recreate)
   30.86  
   30.87  def getDevControllerTable():
   30.88 +    """Singleton constructor for the controller table.
   30.89 +    """
   30.90      global devControllerTable
   30.91      try:
   30.92          devControllerTable
   30.93 @@ -171,12 +138,11 @@ def getDevControllerTable():
   30.94          devControllerTable = DevControllerTable()
   30.95      return devControllerTable
   30.96  
   30.97 -def addDevControllerType(dctype):
   30.98 -    return getDevControllerTable().addDevControllerType(dctype)
   30.99 -    
  30.100  def addDevControllerClass(name, klass):
  30.101 -    ty = SimpleDevControllerType(name, klass)
  30.102 -    return addDevControllerType(ty)
  30.103 +    """Add a device controller class to the controller table.
  30.104 +    """
  30.105 +    klass.name = name
  30.106 +    getDevControllerTable().addDevControllerClass(klass)
  30.107  
  30.108  def createDevController(name, vm, recreate=False):
  30.109      return getDevControllerTable().createDevController(name, vm, recreate=recreate)
  30.110 @@ -189,17 +155,29 @@ class DevController:
  30.111  
  30.112      """
  30.113  
  30.114 -    def __init__(self, dctype, vm, recreate=False):
  30.115 -        self.dctype = dctype
  30.116 +    name = None
  30.117 +
  30.118 +    def createDevController(klass, vm, recreate=False):
  30.119 +        """Class method to create a dev controller.
  30.120 +        """
  30.121 +        ctrl = klass(vm, recreate=recreate)
  30.122 +        ctrl.initController(recreate=recreate)
  30.123 +        return ctrl
  30.124 +
  30.125 +    createDevController = classmethod(createDevController)
  30.126 +
  30.127 +    def getType(klass):
  30.128 +        return klass.name
  30.129 +
  30.130 +    getType = classmethod(getType)
  30.131 +
  30.132 +    def __init__(self, vm, recreate=False):
  30.133          self.destroyed = False
  30.134          self.vm = vm
  30.135          self.deviceId = 0
  30.136          self.devices = {}
  30.137          self.device_order = []
  30.138  
  30.139 -    def getType(self):
  30.140 -        return self.dctype.getType()
  30.141 -
  30.142      def getDevControllerType(self):
  30.143          return self.dctype
  30.144  
  30.145 @@ -222,6 +200,14 @@ class DevController:
  30.146      # Redefinitions must have the same arguments.
  30.147  
  30.148      def initController(self, recreate=False, reboot=False):
  30.149 +        """Initialise the controller. Called when the controller is
  30.150 +        first created, and again after the domain is rebooted (with reboot True).
  30.151 +        If called with recreate True (and reboot False) the controller is being
  30.152 +        recreated after a xend restart.
  30.153 +
  30.154 +        As this can be a re-init (after reboot) any controller state should
  30.155 +        be reset. For example the destroyed flag.
  30.156 +        """
  30.157          self.destroyed = False
  30.158          if reboot:
  30.159              self.rebootDevices()
  30.160 @@ -229,12 +215,19 @@ class DevController:
  30.161      def newDevice(self, id, config, recreate=False):
  30.162          """Create a device with the given config.
  30.163          Must be defined in subclass.
  30.164 +        Called with recreate True when the device is being recreated after a
  30.165 +        xend restart.
  30.166  
  30.167          @return device
  30.168          """
  30.169          raise NotImplementedError()
  30.170  
  30.171      def createDevice(self, config, recreate=False, change=False):
  30.172 +        """Create a device and attach to its front- and back-ends.
  30.173 +        If recreate is true the device is being recreated after a xend restart.
  30.174 +        If change is true the device is a change to an existing domain,
  30.175 +        i.e. it is being added at runtime rather than when the domain is created.
  30.176 +        """
  30.177          dev = self.newDevice(self.nextDeviceId(), config, recreate=recreate)
  30.178          dev.init(recreate=recreate)
  30.179          self.addDevice(dev)
  30.180 @@ -252,7 +245,12 @@ class DevController:
  30.181  
  30.182      def destroyDevice(self, id, change=False, reboot=False):
  30.183          """Destroy a device.
  30.184 -        May be defined in subclass."""
  30.185 +        May be defined in subclass.
  30.186 +
  30.187 +        If reboot is true the device is being destroyed for a domain reboot.
  30.188 +
  30.189 +        The device is not deleted, since it may be recreated later.
  30.190 +        """
  30.191          dev = self.getDevice(id)
  30.192          if not dev:
  30.193              raise XendError("invalid device id: " + id)
  30.194 @@ -260,12 +258,18 @@ class DevController:
  30.195          return dev
  30.196  
  30.197      def deleteDevice(self, id, change=True):
  30.198 +        """Destroy a device and delete it.
  30.199 +        Normally called to remove a device from a domain at runtime.
  30.200 +        """
  30.201          dev = self.destroyDevice(id, change=change)
  30.202          self.removeDevice(dev)
  30.203  
  30.204      def destroyController(self, reboot=False):
  30.205          """Destroy all devices and clean up.
  30.206 -        May be defined in subclass."""
  30.207 +        May be defined in subclass.
  30.208 +        If reboot is true the controller is being destroyed for a domain reboot.
  30.209 +        Called at domain shutdown.
  30.210 +        """
  30.211          self.destroyed = True
  30.212          self.destroyDevices(reboot=reboot)
  30.213  
  30.214 @@ -394,6 +398,13 @@ class Dev:
  30.215          """Initialization. Called on initial create (when reboot is False)
  30.216          and on reboot (when reboot is True). When xend is restarting is
  30.217          called with recreate True. Define in subclass if needed.
  30.218 +
  30.219 +        Device instance variables must be defined in the class constructor,
  30.220 +        but given null or default values. The real values should be initialised
  30.221 +        in this method. This allows devices to be re-initialised.
  30.222 +
  30.223 +        Since this can be called to re-initialise a device any state flags
  30.224 +        should be reset.
  30.225          """
  30.226          self.destroyed = False
  30.227  
  30.228 @@ -404,7 +415,7 @@ class Dev:
  30.229          pass
  30.230  
  30.231      def reboot(self):
  30.232 -        """Reconnect device when the domain is rebooted.
  30.233 +        """Reconnect the device when the domain is rebooted.
  30.234          """
  30.235          self.init(reboot=True)
  30.236          self.attach()
  30.237 @@ -435,6 +446,9 @@ class Dev:
  30.238          If change is True notify destruction (runtime change).
  30.239          If reboot is True the device is being destroyed for a reboot.
  30.240          Redefine in subclass if needed.
  30.241 +
  30.242 +        Called at domain shutdown and when a device is deleted from
  30.243 +        a running domain (with change True).
  30.244          """
  30.245          self.destroyed = True
  30.246          pass
    31.1 --- a/tools/python/xen/xend/server/netif.py	Mon Apr 25 13:04:17 2005 +0000
    31.2 +++ b/tools/python/xen/xend/server/netif.py	Wed Apr 27 14:04:44 2005 +0000
    31.3 @@ -376,8 +376,8 @@ class NetifController(DevController):
    31.4      """Network interface controller. Handles all network devices for a domain.
    31.5      """
    31.6      
    31.7 -    def __init__(self, dctype, vm, recreate=False):
    31.8 -        DevController.__init__(self, dctype, vm, recreate=recreate)
    31.9 +    def __init__(self, vm, recreate=False):
   31.10 +        DevController.__init__(self, vm, recreate=recreate)
   31.11          self.channel = None
   31.12          self.rcvr = None
   31.13          self.channel = None
    32.1 --- a/tools/python/xen/xend/server/usbif.py	Mon Apr 25 13:04:17 2005 +0000
    32.2 +++ b/tools/python/xen/xend/server/usbif.py	Wed Apr 27 14:04:44 2005 +0000
    32.3 @@ -240,10 +240,10 @@ class UsbifController(DevController):
    32.4      for a domain.
    32.5      """
    32.6      
    32.7 -    def __init__(self, dctype, vm, recreate=False):
    32.8 +    def __init__(self, vm, recreate=False):
    32.9          """Create a USB device controller.
   32.10          """
   32.11 -        DevController.__init__(self, dctype, vm, recreate=recreate)
   32.12 +        DevController.__init__(self, vm, recreate=recreate)
   32.13          self.backends = {}
   32.14          self.backendId = 0
   32.15          self.rcvr = None