WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Use XML-RPC as a transport for Xend instead of S-Express

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Use XML-RPC as a transport for Xend instead of S-Expression/HTTP.
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 23 Mar 2006 13:48:08 +0000
Delivery-date: Thu, 23 Mar 2006 13:49:41 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User anthony@xxxxxxxxxxxxxxxxxxxxx
# Node ID 5c9c44fc1c39dc6b08535e33b34c12d684c27d77
# Parent  2c77d26871f7463dd1ebb347cd615f18045ed8da
Use XML-RPC as a transport for Xend instead of S-Expression/HTTP.

This changeset introduces a new XML-RPC service that runs in Xend and the
required changes to have xm use this new service by default.

Signed-off-by: Anthony Liguori <aliguori@xxxxxxxxxx>

diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xend/XendClient.py
--- a/tools/python/xen/xend/XendClient.py       Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xend/XendClient.py       Thu Mar 23 10:25:37 2006
@@ -14,403 +14,11 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #============================================================================
 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
+# Copyright (C) 2006 Anthony Liguori <aliguori@xxxxxxxxxx>
 #============================================================================
 
-"""Client API for the HTTP interface on xend.
-Callable as a script - see main().
-Supports inet or unix connection to xend.
+from xen.util.xmlrpclib2 import ServerProxy
 
-This API is the 'control-plane' for xend.
-The 'data-plane' is done separately.
-"""
-import os
-import sys
-import types
+XML_RPC_SOCKET = "/var/run/xend-xmlrpc.sock"
 
-import sxp
-import PrettyPrint
-from XendProtocol import HttpXendClientProtocol, \
-                         UnixXendClientProtocol, \
-                         XendError
-
-def fileof(val):
-    """Converter for passing configs or other 'large' data.
-    Handles lists, files directly.
-    Assumes a string is a file name and passes its contents.
-    """
-    if isinstance(val, types.ListType):
-        return sxp.to_string(val)
-    if isinstance(val, types.StringType):
-        return file(val)
-    if hasattr(val, 'readlines'):
-        return val
-    raise XendError('cannot convert value')
-
-class URL:
-    """A URL.
-    """
-
-    def __init__(self, proto='http', host='localhost', port=None, path='', 
query=None, frag=None):
-        self.proto = proto
-        self.host = host
-        if port: port = int(port)
-        self.port = port
-        self.path = path
-        self.query = query
-        self.frag = frag
-
-    def url(self):
-        """Get the full URL string including protocol, location and the full 
path.
-        """
-        return self.proto + '://' + self.location() + self.fullpath()
-
-    def location(self):
-        """Get the location part of the URL, including host and port, if 
present.
-        """
-        if self.port:
-            return self.host + ':' + str(self.port)
-        else:
-            return self.host
-
-    def fullpath(self):
-        """Get the full path part of the URL, including query and fragment if 
present.
-        """
-        u = [ self.path ]
-        if self.query:
-            u.append('?')
-            u.append(self.query)
-        if self.frag:
-            u.append('#')
-            u.append(self.frag)
-        return ''.join(u)
-
-    def relative(self, path='', query=None, frag=None):
-        """Create a URL relative to this one.
-        """
-        return URL(proto=self.proto,
-                   host=self.host,
-                   port=self.port,
-                   path=self.path + path,
-                   query=query,
-                   frag=frag)
-
-class Xend:
-    """Client interface to Xend.
-    """
-
-    """Default location of the xend server."""
-    SRV_DEFAULT = "localhost:8000"
-
-    """Environment variable to set the location of xend."""
-    SRV_VAR = "XEND"
-
-    """Default path to the xend root on the server."""
-    ROOT_DEFAULT = "/xend/"
-
-    """Environment variable to set the xend root path."""
-    ROOT_VAR = "XEND_ROOT"
-
-    def __init__(self, client=None, srv=None, root=None):
-        """Create a xend client interface.
-        If the client protocol is not specified, the default
-        is to use a synchronous protocol.
-
-        @param client:  client protocol to use
-        @param srv:     server host, and optional port (format host:port)
-        @param root:    xend root path on the server
-        """
-        if client is None:
-            client = HttpXendClientProtocol()
-        self.client = client
-        self.bind(srv, root)
-
-    def default_server(self):
-        """Get the default location of the xend server.
-        """
-        return os.getenv(self.SRV_VAR, self.SRV_DEFAULT)
-
-    def default_root(self):
-        """Get the default root path on the xend server.
-        """
-        return os.getenv(self.ROOT_VAR, self.ROOT_DEFAULT)
-
-    def bind(self, srv=None, root=None):
-        """Bind to a given server.
-
-        @param srv:  server location (host:port)
-        @param root: xend root path on the server
-        """
-        if srv is None: srv = self.default_server()
-        if root is None: root = self.default_root()
-        if not root.endswith('/'): root += '/'
-        (host, port) = srv.split(':', 1)
-        self.url = URL(host=host, port=port, path=root)
-
-    def xendGet(self, url, args=None):
-        return self.client.xendGet(url, args)
-
-    def xendPost(self, url, data):
-        return self.client.xendPost(url, data)
-
-    def nodeurl(self, id=''):
-        return self.url.relative('node/' + str(id))
-
-    def domainurl(self, id=''):
-        return self.url.relative('domain/' + str(id))
-
-    def deviceurl(self, id=''):
-        return self.url.relative('device/' + str(id))
-
-    def vneturl(self, id=''):
-        return self.url.relative('vnet/' + str(id))
-
-    def xend(self):
-        return self.xendGet(self.url)
-
-    def xend_node(self):
-        return self.xendGet(self.nodeurl())
-        
-    def xend_node_shutdown(self):
-        return self.xendPost(self.nodeurl(),
-                             {'op'      : 'shutdown'})
-                
-    def xend_node_restart(self):
-        return self.xendPost(self.nodeurl(),
-                             {'op'      : 'reboot'})
-
-    def xend_node_get_dmesg(self):
-            return self.xendGet(self.nodeurl('dmesg'))
-
-    def xend_node_clear_dmesg(self):
-        return self.xendPost(self.nodeurl('dmesg'),
-                             {'op' : 'clear' } )
-
-    def xend_node_log(self):
-        return self.xendGet(self.nodeurl('log'))
-
-    def xend_node_cpu_bvt_slice_set(self, ctx_allow):
-        return self.xendPost(self.nodeurl(),
-                             {'op'      : 'cpu_bvt_slice_set',
-                              'ctx_allow' : ctx_allow })
-
-    def xend_domains(self):
-        return self.xendGet(self.domainurl())
-
-    def xend_list_domains(self, detail = True):
-        return self.xendGet(self.domainurl(),
-                            {'detail': detail and '1' or '0'})
-
-    def xend_domain_vcpuinfo(self, dom):
-        return self.xendGet(self.domainurl(dom), {'op': 'vcpuinfo'})
-
-    def xend_domain_create(self, conf):
-        return self.xendPost(self.domainurl(),
-                             {'op'      : 'create',
-                              'config'  : fileof(conf) })
-
-    def xend_domain_restore(self, filename):
-        return self.xendPost(self.domainurl(),
-                             {'op'      : 'restore',
-                              'file'    : filename })
-
-    def xend_domain_configure(self, id, conf):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'configure',
-                              'config'  : fileof(conf) })
-
-    def xend_domain(self, id):
-        return self.xendGet(self.domainurl(id))
-
-    def xend_domain_wait_for_devices(self, id):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'wait_for_devices' })
-
-    def xend_domain_unpause(self, id):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'unpause' })
-
-    def xend_domain_pause(self, id):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'pause' })
-
-    def xend_domain_rename(self, id, name):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'rename',
-                              'name'    : name})
-
-    def xend_domain_shutdown(self, id, reason):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'shutdown',
-                              'reason'  : reason})
-
-    def xend_domain_sysrq(self, id, key):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'sysrq',
-                              'key'     : key})
-
-    def xend_domain_destroy(self, id):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'destroy' })
-
-    def xend_domain_save(self, id, filename):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'save',
-                              'file'    : filename })
-
-    def xend_domain_migrate(self, id, dst, live=0, resource=0, port=0):
-        return self.xendPost(self.domainurl(id),
-                             {'op'         : 'migrate',
-                              'destination': dst,
-                              'live'       : live,
-                              'resource'   : resource,
-                              'port'       : port })
-
-    def xend_domain_pincpu(self, id, vcpu, cpumap):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'pincpu',
-                              'vcpu'    : vcpu,
-                              'cpumap'  : str(cpumap) })
-
-    def xend_domain_cpu_bvt_set(self, id, mcuadv, warpback, warpvalue, warpl, 
warpu):
-        return self.xendPost(self.domainurl(id),
-                             {'op'       : 'cpu_bvt_set',
-                              'mcuadv'   : mcuadv,
-                              'warpback' : warpback,
-                              'warpvalue': warpvalue,
-                              'warpl'    : warpl,
-                              'warpu'    : warpu })
-
-    def xend_domain_cpu_sedf_get(self, id):
-        return self.xendPost(self.domainurl(id),
-                             {'op' : 'cpu_sedf_get'})
-
-    def xend_domain_cpu_sedf_set(self, id, period, slice, latency, extratime, 
weight):
-        return self.xendPost(self.domainurl(id),
-                             {'op'        : 'cpu_sedf_set',
-                              'period'    : period,
-                              'slice'     : slice,
-                             'latency'   : latency,
-                             'extratime' : extratime,
-                             'weight'    : weight })
-
-    def xend_domain_maxmem_set(self, id, memory):
-        return self.xendPost(self.domainurl(id),
-                             { 'op'      : 'maxmem_set',
-                               'memory'  : memory })
-
-    def xend_domain_mem_target_set(self, id, mem_target):
-        val = self.xendPost(self.domainurl(id),
-                            {'op'        : 'mem_target_set',
-                             'target'    : mem_target })
-        return val
-
-    def xend_domain_set_vcpus(self, dom, vcpus):
-        return self.xendPost(self.domainurl(dom),
-                            {'op'    : 'set_vcpus',
-                             'vcpus' : vcpus })
-
-    def xend_domain_devices(self, id, type):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'devices',
-                              'type'    : type })
-
-    def xend_domain_device_create(self, id, config):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'device_create',
-                              'config'  : fileof(config) })
-
-    def xend_domain_device_refresh(self, id, type, dev):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'device_refresh',
-                              'type'    : type,
-                              'dev'     : dev })
-
-    def xend_domain_device_destroy(self, id, type, dev):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'device_destroy',
-                              'type'    : type,
-                              'dev'     : dev })
-
-    def xend_domain_device_configure(self, id, config, dev):
-        return self.xendPost(self.domainurl(id),
-                             {'op'      : 'device_configure',
-                              'dev'     : dev,
-                              'config'  : fileof(config) })
-
-    def xend_vnets(self):
-        return self.xendGet(self.vneturl())
-
-    def xend_vnet_create(self, conf):
-        return self.xendPost(self.vneturl(),
-                             {'op'      : 'create',
-                              'config'  : fileof(conf) })
-
-    def xend_vnet(self, id):
-        return self.xendGet(self.vneturl(id))
-
-    def xend_vnet_delete(self, id):
-        return self.xendPost(self.vneturl(id),
-                              {'op'     : 'delete' })
-
-def getHttpServer(srv=None):
-    """Create and return a xend client.
-    """
-    return Xend(srv=srv, client=HttpXendClientProtocol())
-
-def getUnixServer(srv=None):
-    """Create and return a unix-domain xend client.
-    """
-    return Xend(client=UnixXendClientProtocol(srv))
-
-def xendmain(srv, fn, args, unix=False):
-    if unix:
-        xend = getUnixServer(srv)
-    else:
-        xend = getHttpServer(srv)
-    xend.rc = 0
-    try:
-        v = getattr(xend, fn)(*args)
-        PrettyPrint.prettyprint(v)
-        return 0
-    except XendError, err:
-        print 'ERROR:', err
-        return 1
-
-def main(argv):
-    """Call an API function:
-
-    python XendClient.py fn args...
-
-    The leading 'xend_' on the function can be omitted.
-    Example:
-
-python XendClient.py domains
-    (0 8)
-python XendClient.py domain 0
-    (domain (id 0) (name Domain-0) (memory 128))
-    """
-    from getopt import getopt
-    short_options = 'x:au:d'
-    long_options = ['xend=', 'unix=', 'debug']
-    (options, args) = getopt(argv[1:], short_options, long_options)
-    srv = None
-    unix = 1
-    for k, v in options:
-        if k in ['-x', '--xend']:
-            srv = v
-        elif k in ['-u', '--unix']:
-            unix = int(v)
-    if len(args):
-        fn = args[0]
-        args = args[1:]
-    else:
-        fn = 'xend'
-        args = []
-    if not fn.startswith('xend'):
-        fn = 'xend_' + fn
-    sys.exit(xendmain(srv, fn, args, unix=unix))
-
-if __name__ == "__main__":
-    main(sys.argv)
-else:    
-    server = getUnixServer()
+server = ServerProxy('httpu:///var/run/xend-xmlrpc.sock')
diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xend/XendDomain.py       Thu Mar 23 10:25:37 2006
@@ -355,7 +355,7 @@
     def domain_unpause(self, domid):
         """Unpause domain execution."""
         try:
-            dominfo = self.domain_lookup(domid)
+            dominfo = self.domain_lookup_by_name_or_id_nr(domid)
             log.info("Domain %s (%d) unpaused.", dominfo.getName(),
                      dominfo.getDomid())
             return dominfo.unpause()
@@ -366,7 +366,7 @@
     def domain_pause(self, domid):
         """Pause domain execution."""
         try:
-            dominfo = self.domain_lookup(domid)
+            dominfo = self.domain_lookup_by_name_or_id_nr(domid)
             log.info("Domain %s (%d) paused.", dominfo.getName(),
                      dominfo.getDomid())
             return dominfo.pause()
@@ -377,10 +377,10 @@
     def domain_destroy(self, domid):
         """Terminate domain immediately."""
 
-        if domid == PRIV_DOMAIN:
-            raise XendError("Cannot destroy privileged domain %i" % domid)
-        
-        dominfo = self.domain_lookup(domid)
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+       if dominfo and dominfo.getDomid() == PRIV_DOMAIN:
+            raise XendError("Cannot destroy privileged domain %s" % domid)
+
         if dominfo:
             val = dominfo.destroy()
         else:
@@ -393,7 +393,7 @@
     def domain_migrate(self, domid, dst, live=False, resource=0, port=0):
         """Start domain migration."""
 
-        dominfo = self.domain_lookup(domid)
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
 
         if dominfo.getDomid() == PRIV_DOMAIN:
             raise XendError("Cannot migrate privileged domain %i" % domid)
@@ -418,7 +418,7 @@
         """
 
         try:
-            dominfo = self.domain_lookup(domid)
+            dominfo = self.domain_lookup_by_name_or_id_nr(domid)
 
             if dominfo.getDomid() == PRIV_DOMAIN:
                 raise XendError("Cannot save privileged domain %i" % domid)
@@ -438,7 +438,7 @@
 
         @param cpumap:  string repr of list of usable cpus
         """
-        dominfo = self.domain_lookup(domid)
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
         # convert cpumap string into a list of ints
         cpumap = map(lambda x: int(x),
                      cpumap.replace("[", "").replace("]", "").split(","))
@@ -451,7 +451,7 @@
                            warpu):
         """Set BVT (Borrowed Virtual Time) scheduler parameters for a domain.
         """
-        dominfo = self.domain_lookup(domid)
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
         try:
             return xc.bvtsched_domain_set(dom=dominfo.getDomid(),
                                           mcuadv=mcuadv,
@@ -464,7 +464,7 @@
     def domain_cpu_bvt_get(self, domid):
         """Get BVT (Borrowed Virtual Time) scheduler parameters for a domain.
         """
-        dominfo = self.domain_lookup(domid)
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
         try:
             return xc.bvtsched_domain_get(dominfo.getDomid())
         except Exception, ex:
@@ -475,7 +475,7 @@
                             weight):
         """Set Simple EDF scheduler parameters for a domain.
         """
-        dominfo = self.domain_lookup(domid)
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
         try:
             return xc.sedf_domain_set(dominfo.getDomid(), period, slice_,
                                       latency, extratime, weight)
@@ -485,7 +485,7 @@
     def domain_cpu_sedf_get(self, domid):
         """Get Simple EDF scheduler parameters for a domain.
         """
-        dominfo = self.domain_lookup(domid)
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
         try:
             
             sedf_info = xc.sedf_domain_get(dominfo.getDomid())
@@ -507,7 +507,7 @@
         @param mem: memory limit (in MiB)
         @return: 0 on success, -1 on error
         """
-        dominfo = self.domain_lookup(domid)
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
         maxmem = int(mem) * 1024
         try:
             return xc.domain_setmaxmem(dominfo.getDomid(), maxmem)
@@ -521,7 +521,7 @@
         @param last: last IO port
         @return: 0 on success, -1 on error
         """
-        dominfo = self.domain_lookup(domid)
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
         nr_ports = last - first + 1
         try:
             return xc.domain_ioport_permission(dominfo.getDomid(),
@@ -538,7 +538,7 @@
         @param last: last IO port
         @return: 0 on success, -1 on error
         """
-        dominfo = self.domain_lookup(domid)
+        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
         nr_ports = last - first + 1
         try:
             return xc.domain_ioport_permission(dominfo.getDomid(),
diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xend/XendError.py
--- a/tools/python/xen/xend/XendError.py        Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xend/XendError.py        Thu Mar 23 10:25:37 2006
@@ -15,9 +15,12 @@
 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
 #============================================================================
 
-class XendError(ValueError):
+from xmlrpclib import Fault
+
+class XendError(Fault):
     
     def __init__(self, value):
+        Fault.__init__(self, 2, value)
         self.value = value
 
     def __str__(self):
diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xend/XendRoot.py
--- a/tools/python/xen/xend/XendRoot.py Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xend/XendRoot.py Thu Mar 23 10:25:37 2006
@@ -59,6 +59,10 @@
 
     """Default for the flag indicating whether xend should run an http 
server."""
     xend_http_server_default = 'no'
+
+    xend_tcp_xmlrpc_server_default = 'no'
+
+    xend_unix_xmlrpc_server_default = 'yes'
 
     """Default interface address xend listens at. """
     xend_address_default      = ''
@@ -180,6 +184,12 @@
         """
         return self.get_config_bool("xend-http-server", 
self.xend_http_server_default)
 
+    def get_xend_tcp_xmlrpc_server(self):
+        return self.get_config_bool("xend-tcp-xmlrpc-server", 
self.xend_tcp_xmlrpc_server_default)
+
+    def get_xend_unix_xmlrpc_server(self):
+        return self.get_config_bool("xend-unix-xmlrpc-server", 
self.xend_unix_xmlrpc_server_default)
+
     def get_xend_relocation_server(self):
         """Get the flag indicating whether xend should run a relocation server.
         """
diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xend/server/SrvServer.py
--- a/tools/python/xen/xend/server/SrvServer.py Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xend/server/SrvServer.py Thu Mar 23 10:25:37 2006
@@ -52,6 +52,7 @@
 from xen.web.SrvDir import SrvDir
 
 from SrvRoot import SrvRoot
+from XMLRPCServer import XMLRPCServer
 
 
 xroot = XendRoot.instance()
@@ -114,4 +115,10 @@
         path = xroot.get_xend_unix_path()
         log.info('unix path=' + path)
         servers.add(UnixHttpServer(root, path))
+
+    if xroot.get_xend_tcp_xmlrpc_server():
+        servers.add(XMLRPCServer(True))
+
+    if xroot.get_xend_unix_xmlrpc_server():
+        servers.add(XMLRPCServer())
     return servers
diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xm/create.py     Thu Mar 23 10:25:37 2006
@@ -30,7 +30,7 @@
 
 from xen.xend import sxp
 from xen.xend import PrettyPrint
-from xen.xend.XendClient import server, XendError
+from xen.xend.XendClient import server
 from xen.xend.XendBootloader import bootloader
 from xen.util import blkif
 
@@ -813,8 +813,8 @@
     """
 
     try:
-        dominfo = server.xend_domain_create(config)
-    except XendError, ex:
+        dominfo = server.xend.domain.create(config)
+    except Exception, ex:
         import signal
         if vncpid:
             os.kill(vncpid, signal.SIGKILL)
@@ -822,13 +822,17 @@
 
     dom = sxp.child_value(dominfo, 'name')
 
-    if server.xend_domain_wait_for_devices(dom) < 0:
-        server.xend_domain_destroy(dom)
+    try:
+        server.xend.domain.waitForDevices(dom)
+    except:
+        server.xend.domain.destroy(dom)
         err("Device creation failed for domain %s" % dom)
 
     if not opts.vals.paused:
-        if server.xend_domain_unpause(dom) < 0:
-            server.xend_domain_destroy(dom)
+        try:
+            server.xend.domain.unpause(dom)
+        except:
+            server.xend.domain.destroy(dom)
             err("Failed to unpause domain %s" % dom)
     opts.info("Started domain %s" % (dom))
     return int(sxp.child_value(dominfo, 'domid'))
diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xm/main.py       Thu Mar 23 10:25:37 2006
@@ -29,8 +29,8 @@
 import socket
 import warnings
 warnings.filterwarnings('ignore', category=FutureWarning)
-
-import xen.xend.XendError
+import xmlrpclib
+
 import xen.xend.XendProtocol
 
 from xen.xend import PrettyPrint
@@ -39,6 +39,7 @@
 
 import console
 
+from xen.xend.XendClient import server
 
 # getopt.gnu_getopt is better, but only exists in Python 2.3+.  Use
 # getopt.getopt if gnu_getopt is not available.  This will mean that options
@@ -319,8 +320,7 @@
         err("xm save: Unable to create file %s" % savefile)
         sys.exit(1)
     
-    from xen.xend.XendClient import server
-    server.xend_domain_save(dom, savefile)
+    server.xend.domain.save(dom, savefile)
     
 def xm_restore(args):
     arg_check(args, "restore", 1)
@@ -331,16 +331,14 @@
         err("xm restore: Unable to read file %s" % savefile)
         sys.exit(1)
 
-    from xen.xend.XendClient import server
-    server.xend_domain_restore(savefile)
+    server.xend.domain.restore(savefile)
 
 
 def getDomains(domain_names):
-    from xen.xend.XendClient import server
     if domain_names:
-        return map(server.xend_domain, domain_names)
-    else:
-        return server.xend_list_domains()
+        return map(server.xend.domain, domain_names)
+    else:
+        return server.xend.domains(1)
 
 
 def xm_list(args):
@@ -416,12 +414,11 @@
 
 def xm_vcpu_list(args):
 
-    from xen.xend.XendClient import server
     if args:
-        dominfo = map(server.xend_domain_vcpuinfo, args)
-    else:
-        doms = server.xend_list_domains(False)
-        dominfo = map(server.xend_domain_vcpuinfo, doms)
+        dominfo = map(server.xend.domain.getVCPUInfo, args)
+    else:
+        doms = server.xend.domains(False)
+        dominfo = map(server.xend.domain.getVCPUInfo, doms)
 
     print 'Name                              ID  VCPU  CPU  State  Time(s)  
CPU Affinity'
 
@@ -475,8 +472,7 @@
             cpumap = map(lambda x: int(x), cpumap)
             cpumap.sort()
 
-            from xen.xend.XendClient import server
-            for x in server.xend_node()[1:]:
+            for x in server.xend.node.info()[1:]:
                 if len(x) > 1 and x[0] == 'nr_cpus':
                     nr_cpus = int(x[1])
                     # normalize cpumap by modulus nr_cpus, and drop duplicates
@@ -532,21 +528,18 @@
     arg_check(args, "pause", 1)
     dom = args[0]
 
-    from xen.xend.XendClient import server
-    server.xend_domain_pause(dom)
+    server.xend.domain.pause(dom)
 
 def xm_unpause(args):
     arg_check(args, "unpause", 1)
     dom = args[0]
 
-    from xen.xend.XendClient import server
-    server.xend_domain_unpause(dom)
+    server.xend.domain.unpause(dom)
 
 def xm_rename(args):
     arg_check(args, "rename", 2)
 
-    from xen.xend.XendClient import server
-    server.xend_domain_rename(args[0], args[1])
+    server.xend.domain.setName(args[0], args[1])
 
 def xm_subcommand(command, args):
     cmd = __import__(command, globals(), locals(), 'xen.xm')
@@ -574,8 +567,7 @@
     vcpu = int(args[1])
     cpumap = cpu_make_map(args[2])
     
-    from xen.xend.XendClient import server
-    server.xend_domain_pincpu(dom, vcpu, cpumap)
+    server.xend.domain.pincpu(dom, vcpu, cpumap)
 
 def xm_mem_max(args):
     arg_check(args, "mem-max", 2)
@@ -583,8 +575,7 @@
     dom = args[0]
     mem = int_unit(args[1], 'm')
 
-    from xen.xend.XendClient import server
-    server.xend_domain_maxmem_set(dom, mem)
+    server.xend.domain.maxmem_set(dom, mem)
     
 def xm_mem_set(args):
     arg_check(args, "mem-set", 2)
@@ -592,20 +583,17 @@
     dom = args[0]
     mem_target = int_unit(args[1], 'm')
 
-    from xen.xend.XendClient import server
-    server.xend_domain_mem_target_set(dom, mem_target)
+    server.xend.domain.setMemoryTarget(dom, mem_target)
     
 def xm_vcpu_set(args):
     arg_check(args, "vcpu-set", 2)
     
-    from xen.xend.XendClient import server
-    server.xend_domain_set_vcpus(args[0], int(args[1]))
+    server.xend.domain.setVCpuCount(args[0], int(args[1]))
 
 
 def xm_destroy(args):
     arg_check(args, "destroy", 1)
-    from xen.xend.XendClient import server
-    server.xend_domain_destroy(args[0])
+    server.xend.domain.destroy(args[0])
 
 
 def xm_domid(args):
@@ -613,8 +601,7 @@
 
     name = args[0]
 
-    from xen.xend.XendClient import server
-    dom = server.xend_domain(name)
+    dom = server.xend.domain(name)
     print sxp.child_value(dom, 'domid')
     
 def xm_domname(args):
@@ -622,23 +609,20 @@
 
     name = args[0]
 
-    from xen.xend.XendClient import server
-    dom = server.xend_domain(name)
+    dom = server.xend.domain(name)
     print sxp.child_value(dom, 'name')
 
 def xm_sched_bvt(args):
     arg_check(args, "sched-bvt", 6)
     dom = args[0]
     v = map(long, args[1:6])
-    from xen.xend.XendClient import server
-    server.xend_domain_cpu_bvt_set(dom, *v)
+    server.xend.domain.cpu_bvt_set(dom, *v)
 
 def xm_sched_bvt_ctxallow(args):
     arg_check(args, "sched-bvt-ctxallow", 1)
 
     slice = int(args[0])
-    from xen.xend.XendClient import server
-    server.xend_node_cpu_bvt_slice_set(slice)
+    server.xend.node.cpu_bvt_slice_set(slice)
 
 def xm_sched_sedf(args):
     def ns_to_ms(val):
@@ -695,13 +679,12 @@
                                                      'Slice(ms)', 'Lat(ms)',
                                                      'Extra','Weight')
 
-    from xen.xend.XendClient import server
     doms = filter(lambda x : domid_match(domid, x),
                         [parse_doms_info(dom) for dom in getDomains("")])
     for d in doms:
         # fetch current values so as not to clobber them
         sedf_info = \
-            parse_sedf_info(server.xend_domain_cpu_sedf_get(d['dom']))
+            parse_sedf_info(server.xend.domain.cpu_sedf_get(d['dom']))
         sedf_info['name'] = d['name']
 
         # update values in case of call to set
@@ -713,7 +696,7 @@
             v = map(int, [sedf_info['period'], sedf_info['slice'],
                           sedf_info['latency'],sedf_info['extratime'], 
                           sedf_info['weight']])
-            rv = server.xend_domain_cpu_sedf_set(d['dom'], *v)
+            rv = server.xend.domain.cpu_sedf_set(d['dom'], *v)
             if int(rv) != 0:
                 err("Failed to set sedf parameters (rv=%d)."%(rv))
 
@@ -725,8 +708,7 @@
 def xm_info(args):
     arg_check(args, "info", 0)
 
-    from xen.xend.XendClient import server
-    info = server.xend_node()
+    info = server.xend.node.info()
     
     for x in info[1:]:
         if len(x) < 2: 
@@ -738,8 +720,7 @@
     arg_check(args, "console", 1)
 
     dom = args[0]
-    from xen.xend.XendClient import server
-    info = server.xend_domain(dom)
+    info = server.xend.domain(dom)
     domid = int(sxp.child_value(info, 'domid', '-1'))
     console.execConsole(domid)
 
@@ -768,17 +749,15 @@
     if not (1 <= len(myargs) <= 2):
         err('Invalid arguments: ' + str(myargs))
 
-    from xen.xend.XendClient import server
     if not gopts.vals.clear:
-        print server.xend_node_get_dmesg()
-    else:
-        server.xend_node_clear_dmesg()
+        print server.xend.node.dmesg.info()
+    else:
+        server.xend.node.dmesg.clear()
 
 def xm_log(args):
     arg_check(args, "log", 0)
     
-    from xen.xend.XendClient import server
-    print server.xend_node_log()
+    print server.xend.node.log()
 
 def parse_dev_info(info):
     def get_info(n, t, d):
@@ -826,13 +805,12 @@
         print 'No domain parameter given'
         sys.exit(1)
     dom = params[0]
-    from xen.xend.XendClient import server
     if use_long:
-        devs = server.xend_domain_devices(dom, 'vif')
+        devs = server.xend.domain.getDeviceSxprs(dom, 'vif')
         map(PrettyPrint.prettyprint, devs)
     else:
         hdr = 0
-        for x in server.xend_domain_devices(dom, 'vif'):
+        for x in server.xend.domain.getDeviceSxprs(dom, 'vif'):
             if hdr == 0:
                 print 'Idx BE     MAC Addr.     handle state evt-ch 
tx-/rx-ring-ref BE-path'
                 hdr = 1
@@ -857,13 +835,12 @@
         print 'No domain parameter given'
         sys.exit(1)
     dom = params[0]
-    from xen.xend.XendClient import server
     if use_long:
-        devs = server.xend_domain_devices(dom, 'vbd')
+        devs = server.xend.domain.getDeviceSxprs(dom, 'vbd')
         map(PrettyPrint.prettyprint, devs)
     else:
         hdr = 0
-        for x in server.xend_domain_devices(dom, 'vbd'):
+        for x in server.xend.domain.getDeviceSxprs(dom, 'vbd'):
             if hdr == 0:
                 print 'Vdev  BE handle state evt-ch ring-ref BE-path'
                 hdr = 1
@@ -887,13 +864,12 @@
         print 'No domain parameter given'
         sys.exit(1)
     dom = params[0]
-    from xen.xend.XendClient import server
     if use_long:
-        devs = server.xend_domain_devices(dom, 'vtpm')
+        devs = server.xend.domain.getDeviceSxprs(dom, 'vtpm')
         map(PrettyPrint.prettyprint, devs)
     else:
         hdr = 0
-        for x in server.xend_domain_devices(dom, 'vtpm'):
+        for x in server.xend.domain.getDeviceSxprs(dom, 'vtpm'):
             if hdr == 0:
                 print 'Idx  BE handle state evt-ch ring-ref BE-path'
                 hdr = 1
@@ -919,8 +895,7 @@
     if len(args) == 5:
         vbd.append(['backend', args[4]])
 
-    from xen.xend.XendClient import server
-    server.xend_domain_device_create(dom, vbd)
+    server.xend.domain.device_create(dom, vbd)
 
 
 def xm_network_attach(args):
@@ -932,8 +907,7 @@
     for a in args[1:]:
         vif.append(a.split("="))
 
-    from xen.xend.XendClient import server
-    server.xend_domain_device_create(dom, vif)
+    server.xend.domain.device_create(dom, vif)
 
 
 def detach(args, command, deviceClass):
@@ -942,8 +916,7 @@
     dom = args[0]
     dev = args[1]
 
-    from xen.xend.XendClient import server
-    server.xend_domain_device_destroy(dom, deviceClass, dev)
+    server.xend.domain.destroyDevice(dom, deviceClass, dev)
 
 
 def xm_block_detach(args):
@@ -955,7 +928,6 @@
 
 
 def xm_vnet_list(args):
-    from xen.xend.XendClient import server
     try:
         (options, params) = getopt.gnu_getopt(args, 'l', ['long'])
     except getopt.GetoptError, opterr:
@@ -990,13 +962,11 @@
         print "File not found: %s" % conf
         sys.exit(1)
 
-    from xen.xend.XendClient import server
     server.xend_vnet_create(conf)
 
 def xm_vnet_delete(args):
     arg_check(args, "vnet-delete", 1)
     vnet = args[0]
-    from xen.xend.XendClient import server
     server.xend_vnet_delete(vnet)
 
 commands = {
@@ -1132,23 +1102,10 @@
             else:
                 err("Error connecting to xend: %s." % ex[1])
             sys.exit(1)
-        except xen.xend.XendError.XendError, ex:
-            if len(args) > 0:
-                handle_xend_error(argv[1], args, ex)
-            else:
-                print "Unexpected error:", sys.exc_info()[0]
-                print
-                print "Please report to xen-devel@xxxxxxxxxxxxxxxxxxx"
-                raise
-        except xen.xend.XendProtocol.XendError, ex:
-            if len(args) > 0:
-                handle_xend_error(argv[1], args, ex)
-            else:
-                print "Unexpected error:", sys.exc_info()[0]
-                print
-                print "Please report to xen-devel@xxxxxxxxxxxxxxxxxxx"
-                raise
         except SystemExit:
+            sys.exit(1)
+        except xmlrpclib.Fault, ex:
+            print "Xend generated an internal fault: %s" % ex.faultString
             sys.exit(1)
         except:
             print "Unexpected error:", sys.exc_info()[0]
diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xm/migrate.py
--- a/tools/python/xen/xm/migrate.py    Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xm/migrate.py    Thu Mar 23 10:25:37 2006
@@ -60,4 +60,4 @@
         opts.err('Invalid arguments: ' + str(args))
     dom = args[0]
     dst = args[1]
-    server.xend_domain_migrate(dom, dst, opts.vals.live, opts.vals.resource, 
opts.vals.port)
+    server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.resource, 
opts.vals.port)
diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xm/shutdown.py
--- a/tools/python/xen/xm/shutdown.py   Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xm/shutdown.py   Thu Mar 23 10:25:37 2006
@@ -53,8 +53,8 @@
           use='Shutdown and reboot.')
 
 def shutdown(opts, doms, mode, wait):
-    if doms == None: doms = server.xend_domains()
-    dom0_name = sxp.child_value(server.xend_domain(0), 'name')
+    if doms == None: doms = server.xend.domains(0)
+    dom0_name = sxp.child_value(server.xend.domain(0), 'name')
     for x in [dom0_name, DOM0_ID]:
         if x in doms:
             if opts.vals.all:
@@ -62,10 +62,10 @@
             else:
                 opts.err("Can't specify Domain-0")
     for d in doms:
-        server.xend_domain_shutdown(d, mode)
+        server.xend.domain.shutdown(d, mode)
     if wait:
         while doms:
-            alive = server.xend_domains()
+            alive = server.xend.domains(0)
             dead = []
             for d in doms:
                 if d in alive: continue
diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xm/sysrq.py
--- a/tools/python/xen/xm/sysrq.py      Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xm/sysrq.py      Thu Mar 23 10:25:37 2006
@@ -28,4 +28,4 @@
     if len(args) < 2: opts.err('Missing sysrq character')
     dom = args[0]
     req = ord(args[1][0])
-    server.xend_domain_sysrq(dom, req)
+    server.xend.domain.sysrq(dom, req)
diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/util/xmlrpclib2.py
--- /dev/null   Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/util/xmlrpclib2.py       Thu Mar 23 10:25:37 2006
@@ -0,0 +1,109 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2006 Anthony Liguori <aliguori@xxxxxxxxxx>
+#============================================================================
+
+"""
+An enhanced XML-RPC client/server interface for Python.
+"""
+
+from httplib import HTTPConnection, HTTP
+from xmlrpclib import Transport
+from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
+import xmlrpclib, socket, os, traceback
+
+# A new ServerProxy that also supports httpu urls.  An http URL comes in the
+# form:
+#
+# httpu:///absolute/path/to/socket.sock
+#
+# It assumes that the RPC handler is /RPC2.  This probably needs to be improved
+
+class HTTPUnixConnection(HTTPConnection):
+    def connect(self):
+        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        self.sock.connect(self.host)
+
+class HTTPUnix(HTTP):
+    _connection_class = HTTPUnixConnection
+
+class UnixTransport(Transport):
+    def request(self, host, handler, request_body, verbose=0):
+        self.__handler = handler
+        return Transport.request(self, host, '/RPC2', request_body, verbose)
+    def make_connection(self, host):
+        return HTTPUnix(self.__handler)
+
+class ServerProxy(xmlrpclib.ServerProxy):
+    def __init__(self, uri, transport=None, encoding=None, verbose=0,
+                 allow_none=1):
+        if transport == None:
+            (protocol, rest) = uri.split(':', 1)
+            if protocol == 'httpu':
+                uri = 'http:' + rest
+                transport = UnixTransport()
+        xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
+                                       verbose, allow_none)
+
+# This is a base XML-RPC server for TCP.  It sets allow_reuse_address to
+# true, and has an improved marshaller that serializes unknown exceptions
+# with full traceback information.
+
+class TCPXMLRPCServer(SimpleXMLRPCServer):
+    allow_reuse_address = True
+
+    def _marshaled_dispatch(self, data, dispatch_method = None):
+        params, method = xmlrpclib.loads(data)
+        try:
+            if dispatch_method is not None:
+                response = dispatch_method(method, params)
+            else:
+                response = self._dispatch(method, params)
+
+            response = (response,)
+            response = xmlrpclib.dumps(response,
+                                       methodresponse=1,
+                                       allow_none=1)
+        except xmlrpclib.Fault, fault:
+            response = xmlrpclib.dumps(fault)
+        except:
+            response = xmlrpclib.dumps(
+                xmlrpclib.Fault(1, traceback.format_exc())
+                )
+
+        return response
+
+# This is a XML-RPC server that sits on a Unix domain socket.
+# It implements proper support for allow_reuse_address by
+# unlink()'ing an existing socket.
+
+class UnixXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
+    def address_string(self):
+        try:
+            return SimpleXMLRPCRequestHandler.address_string(self)
+        except ValueError, e:
+            return self.client_address[:2]
+
+class UnixXMLRPCServer(TCPXMLRPCServer):
+    address_family = socket.AF_UNIX
+
+    def __init__(self, addr, requestHandler=UnixXMLRPCRequestHandler,
+                 logRequests=1):
+        if self.allow_reuse_address:
+            try:
+                os.unlink(addr)
+            except OSError, exc:
+                pass
+        TCPXMLRPCServer.__init__(self, addr, requestHandler, logRequests)
diff -r 2c77d26871f7 -r 5c9c44fc1c39 
tools/python/xen/xend/server/XMLRPCServer.py
--- /dev/null   Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xend/server/XMLRPCServer.py      Thu Mar 23 10:25:37 2006
@@ -0,0 +1,106 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2006 Anthony Liguori <aliguori@xxxxxxxxxx>
+#============================================================================
+
+from xen.xend import XendDomain, XendDomainInfo, XendNode, \
+                     XendLogging, XendDmesg
+from xen.util.xmlrpclib2 import UnixXMLRPCServer, TCPXMLRPCServer
+
+from xen.xend.XendClient import XML_RPC_SOCKET
+
+def lookup(domid):
+    return XendDomain.instance().domain_lookup_by_name_or_id(domid)
+
+def dispatch(domid, fn, args):
+    info = lookup(domid)
+    return getattr(info, fn)(*args)
+
+def domain(domid):
+    info = lookup(domid)
+    return info.sxpr()
+
+def domains(detail=1):
+    if detail < 1:
+        return XendDomain.instance().list_names()
+    else:
+        domains = XendDomain.instance().list_sorted()
+        return map(lambda dom: dom.sxpr(), domains)
+
+def domain_create(config):
+    info = XendDomain.instance().domain_create(config)
+    return info.sxpr()
+
+def domain_restore(src):
+    info = XendDomain.instance().domain_restore(src)
+    return info.sxpr()    
+
+def get_log():
+    f = open(XendLogging.getLogFilename(), 'r')
+    try:
+        return f.read()
+    finally:
+        f.close()
+
+methods = ['device_create', 'destroyDevice', 'getDeviceSxprs',
+           'setMemoryTarget', 'setName', 'setVCpuCount', 'shutdown',
+           'send_sysrq', 'getVCPUInfo', 'waitForDevices']
+
+exclude = ['domain_create', 'domain_restore']
+
+class XMLRPCServer:
+    def __init__(self, use_tcp=False):
+        self.ready = False
+        self.use_tcp = use_tcp
+        
+    def run(self):
+        if self.use_tcp:
+            # bind to something fixed for now as we may eliminate
+            # tcp support completely.
+            self.server = TCPXMLRPCServer(("localhost", 8005))
+        else:
+            self.server = UnixXMLRPCServer(XML_RPC_SOCKET)
+
+        # Functions in XendDomainInfo
+        for name in methods:
+            fn = eval("lambda domid, *args: dispatch(domid, '%s', args)"%name)
+            self.server.register_function(fn, "xend.domain.%s" % name)
+
+        # Functions in XendDomain
+        inst = XendDomain.instance()
+        for name in dir(inst):
+            fn = getattr(inst, name)
+            if name.startswith("domain_") and callable(fn):
+                if name not in exclude:
+                    self.server.register_function(fn, "xend.domain.%s" % 
name[7:])
+
+        # Functions in XendNode and XendDmesg
+        for type, lst, n in [(XendNode, ['info', 'cpu_bvt_slice_set'], 'node'),
+                             (XendDmesg, ['info', 'clear'], 'node.dmesg')]:
+            inst = type.instance()
+            for name in lst:
+                self.server.register_function(getattr(inst, name),
+                                              "xend.%s.%s" % (n, name))
+
+        # A few special cases
+        self.server.register_function(domain, 'xend.domain')
+        self.server.register_function(domains, 'xend.domains')
+        self.server.register_function(get_log, 'xend.node.log')
+        self.server.register_function(domain_create, 'xend.domain.create')
+        self.server.register_function(domain_restore, 'xend.domain.restore')
+
+        self.server.register_introspection_functions()
+        self.ready = True
+        self.server.serve_forever()

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Use XML-RPC as a transport for Xend instead of S-Expression/HTTP., Xen patchbot -unstable <=