136 lines
4.9 KiB
Diff
136 lines
4.9 KiB
Diff
# HG changeset patch
|
|
# User anthony@rhesis.austin.ibm.com
|
|
# Node ID 8dc8c7bdcbac0e56c606fe5c9205b4d9742e60d7
|
|
# Parent 8b5a752167a17785b998a080a5c1ce1991b9379b
|
|
In some cases, Xend can return a very large integer. This so far only happens
|
|
on 64bit systems where the sizeof the Python integer is > 32bit. Presumably,
|
|
this is occuring because of the fact that we return PFNs as part of the
|
|
domain info so on a system with greater than 2G of memory we get into the
|
|
invalid integer range.
|
|
|
|
For now, the work-around is to overload the xmlrpclib Marshaller and instead
|
|
of throwing an exception when we get out-of-range integers, we marshal them
|
|
as strings. In the future, we can handle this in a more elegant way by
|
|
introducing higher-level types. We also won't have to deal with things like
|
|
PFNs once we clean up the XML-RPC interface.
|
|
|
|
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
|
|
|
|
Index: xen-3.0.3-testing/tools/python/xen/util/xmlrpclib2.py
|
|
===================================================================
|
|
--- xen-3.0.3-testing.orig/tools/python/xen/util/xmlrpclib2.py
|
|
+++ xen-3.0.3-testing/tools/python/xen/util/xmlrpclib2.py
|
|
@@ -25,10 +25,11 @@ import types
|
|
import fcntl
|
|
|
|
from httplib import HTTPConnection, HTTP
|
|
-from xmlrpclib import Transport
|
|
+from xmlrpclib import Transport, Fault
|
|
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
|
|
import SocketServer
|
|
-import xmlrpclib, socket, os, stat
|
|
+import xmlrpclib, socket, os, stat, string
|
|
+from types import *
|
|
|
|
from xen.xend.XendLogging import log
|
|
|
|
@@ -48,6 +49,9 @@ except ImportError:
|
|
#
|
|
# It assumes that the RPC handler is /RPC2. This probably needs to be improved
|
|
|
|
+MAXINT = 2L**31-1
|
|
+MININT = -2L**31
|
|
+
|
|
# We're forced to subclass the RequestHandler class so that we can work around
|
|
# some bugs in Keep-Alive handling and also enabled it by default
|
|
class XMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|
@@ -127,6 +131,67 @@ class ServerProxy(xmlrpclib.ServerProxy)
|
|
return conv_string(response)
|
|
|
|
|
|
+class Marshaller(xmlrpclib.Marshaller):
|
|
+ def __init__(self, encoding=None, allow_none=0):
|
|
+ xmlrpclib.Marshaller.__init__(self, encoding, allow_none)
|
|
+ self.dispatch[IntType] = Marshaller.dump_int
|
|
+ self.dispatch[LongType] = Marshaller.dump_long
|
|
+
|
|
+ def dump_int(self, value, write):
|
|
+ if value > MAXINT or value < MININT:
|
|
+ self.dispatch[StringType](self, str(value), write)
|
|
+ else:
|
|
+ xmlrpclib.Marshaller.dump_int(self, value, write)
|
|
+
|
|
+ def dump_long(self, value, write):
|
|
+ if value > MAXINT or value < MININT:
|
|
+ self.dispatch[StringType](self, str(value), write)
|
|
+ else:
|
|
+ xmlrpclib.Marshaller.dump_long(self, value, write)
|
|
+
|
|
+def dumps(params, methodname=None, methodresponse=None, encoding=None,
|
|
+ allow_none=0):
|
|
+ assert isinstance(params, TupleType) or isinstance(params, Fault),\
|
|
+ "argument must be tuple or Fault instance"
|
|
+
|
|
+ if isinstance(params, Fault):
|
|
+ methodresponse = 1
|
|
+ elif methodresponse and isinstance(params, TupleType):
|
|
+ assert len(params) == 1, "response tuple must be a singleton"
|
|
+
|
|
+ if not encoding:
|
|
+ encoding = "utf-8"
|
|
+
|
|
+ m = Marshaller(encoding, allow_none)
|
|
+
|
|
+ data = m.dumps(params)
|
|
+
|
|
+ if encoding != "utf-8":
|
|
+ xmlheader = "<?xml version='1.0' encoding='%s'?>\n" % str(encoding)
|
|
+ else:
|
|
+ xmlheader = "<?xml version='1.0'?>\n" # utf-8 is default
|
|
+
|
|
+ if methodname:
|
|
+ if not isinstance(methodname, StringType):
|
|
+ methodname = methodname.encode(encoding)
|
|
+ data = (
|
|
+ xmlheader,
|
|
+ "<methodCall>\n"
|
|
+ "<methodName>", methodname, "</methodName>\n",
|
|
+ data,
|
|
+ "</methodCall>\n"
|
|
+ )
|
|
+ elif methodresponse:
|
|
+ data = (
|
|
+ xmlheader,
|
|
+ "<methodResponse>\n",
|
|
+ data,
|
|
+ "</methodResponse>\n"
|
|
+ )
|
|
+ else:
|
|
+ return data
|
|
+ return string.join(data, "")
|
|
+
|
|
# This is a base XML-RPC server for TCP. It sets allow_reuse_address to
|
|
# true, and has an improved marshaller that logs and serializes exceptions.
|
|
|
|
@@ -174,15 +239,15 @@ class TCPXMLRPCServer(SocketServer.Threa
|
|
response = repr(response)[1:-1]
|
|
|
|
response = (response,)
|
|
- response = xmlrpclib.dumps(response,
|
|
- methodresponse=1,
|
|
- allow_none=1)
|
|
+ response = dumps(response,
|
|
+ methodresponse=1,
|
|
+ allow_none=1)
|
|
except xmlrpclib.Fault, fault:
|
|
- response = xmlrpclib.dumps(fault)
|
|
+ response = dumps(fault)
|
|
except Exception, exn:
|
|
import xen.xend.XendClient
|
|
log.exception(exn)
|
|
- response = xmlrpclib.dumps(
|
|
+ response = dumps(
|
|
xmlrpclib.Fault(xen.xend.XendClient.ERROR_INTERNAL, str(exn)))
|
|
|
|
return response
|