debuggers.hg
changeset 4672:d781b9d08e80
bitkeeper revision 1.1327.2.4 (426918a34Af7gihN8mTkq-P3KrAZXg)
Remove twisted from save/migrate handling.
This needs to use threads, so add thread support for
http server requests.
Signed-off-by: Mike Wray <mike.wray@hp.com>
Remove twisted from save/migrate handling.
This needs to use threads, so add thread support for
http server requests.
Signed-off-by: Mike Wray <mike.wray@hp.com>
line diff
1.1 --- a/tools/python/xen/web/SrvBase.py Thu Apr 21 14:11:29 2005 +0000 1.2 +++ b/tools/python/xen/web/SrvBase.py Fri Apr 22 15:30:43 2005 +0000 1.3 @@ -2,6 +2,7 @@ 1.4 1.5 import types 1.6 1.7 + 1.8 from xen.xend import sxp 1.9 from xen.xend import PrettyPrint 1.10 from xen.xend.Args import ArgError 1.11 @@ -10,6 +11,7 @@ from xen.xend.XendLogging import log 1.12 1.13 import resource 1.14 import http 1.15 +import httpserver 1.16 import defer 1.17 1.18 def uri_pathlist(p): 1.19 @@ -29,19 +31,8 @@ class SrvBase(resource.Resource): 1.20 1.21 1.22 def use_sxp(self, req): 1.23 - """Determine whether to send an SXP response to a request. 1.24 - Uses SXP if there is no User-Agent, no Accept, or application/sxp is in Accept. 1.25 - 1.26 - req request 1.27 - returns 1 for SXP, 0 otherwise 1.28 - """ 1.29 - ok = 0 1.30 - user_agent = req.getHeader('User-Agent') 1.31 - accept = req.getHeader('Accept') 1.32 - if (not user_agent) or (not accept) or (accept.find(sxp.mime_type) >= 0): 1.33 - ok = 1 1.34 - return ok 1.35 - 1.36 + return req.useSxp() 1.37 + 1.38 def get_op_method(self, op): 1.39 """Get the method for an operation. 1.40 For operation 'foo' looks for 'op_foo'. 1.41 @@ -60,7 +51,7 @@ class SrvBase(resource.Resource): 1.42 1.43 The method must return a list when req.use_sxp is true 1.44 and an HTML string otherwise (or list). 1.45 - Methods may also return a Deferred (for incomplete processing). 1.46 + Methods may also return a ThreadRequest (for incomplete processing). 1.47 1.48 req request 1.49 """ 1.50 @@ -76,85 +67,10 @@ class SrvBase(resource.Resource): 1.51 req.write("Operation not implemented: " + op) 1.52 return '' 1.53 else: 1.54 - return self._perform(op, op_method, req) 1.55 - 1.56 - def _perform(self, op, op_method, req): 1.57 - try: 1.58 - val = op_method(op, req) 1.59 - except Exception, err: 1.60 - self._perform_err(err, op, req) 1.61 - return '' 1.62 - 1.63 - if isinstance(val, defer.Deferred): 1.64 - val.addCallback(self._perform_cb, op, req, dfr=1) 1.65 - val.addErrback(self._perform_err, op, req, dfr=1) 1.66 - return server.NOT_DONE_YET 1.67 - else: 1.68 - self._perform_cb(val, op, req, dfr=0) 1.69 - return '' 1.70 - 1.71 - def _perform_cb(self, val, op, req, dfr=0): 1.72 - """Callback to complete the request. 1.73 - May be called from a Deferred. 1.74 - 1.75 - @param err: the error 1.76 - @param req: request causing the error 1.77 - @param dfr: deferred flag 1.78 - """ 1.79 - if isinstance(val, resource.ErrorPage): 1.80 - req.write(val.render(req)) 1.81 - elif self.use_sxp(req): 1.82 - req.setHeader("Content-Type", sxp.mime_type) 1.83 - sxp.show(val, out=req) 1.84 - else: 1.85 - req.write('<html><head></head><body>') 1.86 - self.print_path(req) 1.87 - if isinstance(val, types.ListType): 1.88 - req.write('<code><pre>') 1.89 - PrettyPrint.prettyprint(val, out=req) 1.90 - req.write('</pre></code>') 1.91 - else: 1.92 - req.write(str(val)) 1.93 - req.write('</body></html>') 1.94 - if dfr: 1.95 - req.finish() 1.96 - 1.97 - def _perform_err(self, err, op, req, dfr=0): 1.98 - """Error callback to complete a request. 1.99 - May be called from a Deferred. 1.100 - 1.101 - @param err: the error 1.102 - @param req: request causing the error 1.103 - @param dfr: deferred flag 1.104 - """ 1.105 - if not (isinstance(err, ArgError) or 1.106 - isinstance(err, sxp.ParseError) or 1.107 - isinstance(err, XendError)): 1.108 - if dfr: 1.109 - return err 1.110 - else: 1.111 - raise 1.112 - #log.exception("op=%s: %s", op, str(err)) 1.113 - if self.use_sxp(req): 1.114 - req.setHeader("Content-Type", sxp.mime_type) 1.115 - sxp.show(['xend.err', str(err)], out=req) 1.116 - else: 1.117 - req.setHeader("Content-Type", "text/plain") 1.118 - req.write('Error ') 1.119 - req.write(': ') 1.120 - req.write(str(err)) 1.121 - if dfr: 1.122 - req.finish() 1.123 - 1.124 + return op_method(op, req) 1.125 1.126 def print_path(self, req): 1.127 """Print the path with hyperlinks. 1.128 """ 1.129 - pathlist = [x for x in req.prepath if x != '' ] 1.130 - s = "/" 1.131 - req.write('<h1><a href="/">/</a>') 1.132 - for x in pathlist: 1.133 - s += x + "/" 1.134 - req.write(' <a href="%s">%s</a>/' % (s, x)) 1.135 - req.write("</h1>") 1.136 + req.printPath() 1.137
2.1 --- a/tools/python/xen/web/SrvDir.py Thu Apr 21 14:11:29 2005 +0000 2.2 +++ b/tools/python/xen/web/SrvDir.py Fri Apr 22 15:30:43 2005 +0000 2.3 @@ -47,9 +47,6 @@ class SrvDir(SrvBase): 2.4 self.table = {} 2.5 self.order = [] 2.6 2.7 - def __repr__(self): 2.8 - return "<SrvDir %x %s>" %(id(self), self.table.keys()) 2.9 - 2.10 def noChild(self, msg): 2.11 return resource.ErrorPage(http.NOT_FOUND, msg=msg) 2.12
3.1 --- a/tools/python/xen/web/connection.py Thu Apr 21 14:11:29 2005 +0000 3.2 +++ b/tools/python/xen/web/connection.py Fri Apr 22 15:30:43 2005 +0000 3.3 @@ -72,6 +72,8 @@ class SocketServerConnection: 3.4 return True 3.5 3.6 def dataReceived(self, data): 3.7 + if not self.connected: 3.8 + return True 3.9 if not self.protocol: 3.10 return True 3.11 try: 3.12 @@ -79,7 +81,7 @@ class SocketServerConnection: 3.13 except SystemExit: 3.14 raise 3.15 except Exception, ex: 3.16 - self.disconnect(ex) 3.17 + self.loseConnection(ex) 3.18 return True 3.19 return False 3.20 3.21 @@ -261,7 +263,7 @@ class SocketClientConnection: 3.22 except SystemExit: 3.23 raise 3.24 except Exception, ex: 3.25 - self.disconnect(ex) 3.26 + self.loseConnection(ex) 3.27 3.28 def mainLoop(self): 3.29 # Something a protocol could call. 3.30 @@ -282,7 +284,7 @@ class SocketClientConnection: 3.31 if ex.args[0] in (EWOULDBLOCK, EAGAIN, EINTR): 3.32 return False 3.33 else: 3.34 - self.disconnect(ex) 3.35 + self.loseConnection(ex) 3.36 return True 3.37 3.38 def read(self): 3.39 @@ -293,7 +295,7 @@ class SocketClientConnection: 3.40 if ex.args[0] in (EWOULDBLOCK, EAGAIN, EINTR): 3.41 return None 3.42 else: 3.43 - self.disconnect(ex) 3.44 + self.loseConnection(ex) 3.45 return True 3.46 3.47 def dataReceived(self, data): 3.48 @@ -304,11 +306,11 @@ class SocketClientConnection: 3.49 except SystemExit: 3.50 raise 3.51 except Exception, ex: 3.52 - self.disconnect(ex) 3.53 + self.loseConnection(ex) 3.54 return True 3.55 return False 3.56 3.57 - def disconnect(self, reason=None): 3.58 + def loseConnection(self, reason=None): 3.59 self.thread = None 3.60 self.closeSocket(reason) 3.61 self.closeProtocol(reason) 3.62 @@ -350,6 +352,8 @@ class SocketConnector: 3.63 3.64 def __init__(self, factory): 3.65 self.factoryStarted = False 3.66 + self.clientLost = False 3.67 + self.clientFailed = False 3.68 self.factory = factory 3.69 self.state = "disconnected" 3.70 self.transport = None 3.71 @@ -364,11 +368,14 @@ class SocketConnector: 3.72 if self.state != "disconnected": 3.73 raise socket.error(EINVAL, "cannot connect in state " + self.state) 3.74 self.state = "connecting" 3.75 + self.clientLost = False 3.76 + self.clientFailed = False 3.77 if not self.factoryStarted: 3.78 self.factoryStarted = True 3.79 self.factory.doStart() 3.80 - self.factory.startedConnecting() 3.81 + self.factory.startedConnecting(self) 3.82 self.connectTransport() 3.83 + self.state = "connected" 3.84 3.85 def stopConnecting(self): 3.86 if self.state != "connecting": 3.87 @@ -380,8 +387,12 @@ class SocketConnector: 3.88 return self.factory.buildProtocol(addr) 3.89 3.90 def connectionLost(self, reason=None): 3.91 - self.factory.doStop() 3.92 + if not self.clientLost: 3.93 + self.clientLost = True 3.94 + self.factory.clientConnectionLost(self, reason) 3.95 3.96 def connectionFailed(self, reason=None): 3.97 - self.factory.doStop() 3.98 + if not self.clientFailed: 3.99 + self.clientFailed = True 3.100 + self.factory.clientConnectionFailed(self, reason) 3.101
4.1 --- a/tools/python/xen/web/http.py Thu Apr 21 14:11:29 2005 +0000 4.2 +++ b/tools/python/xen/web/http.py Fri Apr 22 15:30:43 2005 +0000 4.3 @@ -282,7 +282,6 @@ class HttpRequest: 4.4 header_count += 1 4.5 if line == '\r\n' or line == '\n' or line == '': 4.6 break 4.7 - #print 'parseRequestHeaders>', header_bytes 4.8 header_input = StringIO(header_bytes) 4.9 self.request_headers = Message(header_input) 4.10 4.11 @@ -329,7 +328,6 @@ class HttpRequest: 4.12 self.content.seek(0,0) 4.13 4.14 def parseRequest(self): 4.15 - #print 'parseRequest>' 4.16 self.request_line = self.rin.readline() 4.17 self.parseRequestLine() 4.18 self.parseRequestHeaders() 4.19 @@ -338,7 +336,6 @@ class HttpRequest: 4.20 self.setCloseConnection(connection_mode) 4.21 self.readContent() 4.22 self.parseRequestArgs() 4.23 - #print 'parseRequest<' 4.24 4.25 def setCloseConnection(self, mode): 4.26 if not mode: return 4.27 @@ -347,8 +344,10 @@ class HttpRequest: 4.28 self.close_connection = True 4.29 elif (mode == 'keep-alive') and (self.http_version >= (1, 1)): 4.30 self.close_connection = False 4.31 - #print 'setCloseConnection>', mode, self.close_connection 4.32 4.33 + def getCloseConnection(self): 4.34 + return self.close_connection 4.35 + 4.36 def getHeader(self, k, v=None): 4.37 return self.request_headers.get(k, v) 4.38 4.39 @@ -365,7 +364,6 @@ class HttpRequest: 4.40 self.response_status = status 4.41 4.42 def setResponseHeader(self, k, v): 4.43 - #print 'setResponseHeader>', k, v 4.44 k = k.lower() 4.45 self.response_headers[k] = v 4.46 if k == 'connection': 4.47 @@ -432,7 +430,6 @@ class HttpRequest: 4.48 self.send("\r\n") 4.49 4.50 def sendResponse(self): 4.51 - #print 'sendResponse>' 4.52 if self.response_sent: 4.53 return 4.54 self.response_sent = True 4.55 @@ -443,7 +440,6 @@ class HttpRequest: 4.56 self.output.seek(0, 0) 4.57 body = self.output.getvalue() 4.58 body_length = len(body) 4.59 - #print 'sendResponse> body=', body_length, body 4.60 self.setResponseHeader("Content-Length", body_length) 4.61 if self.http_version > (0, 9): 4.62 self.send("%s %d %s\r\n" % (self.http_version_string, 4.63 @@ -451,17 +447,19 @@ class HttpRequest: 4.64 self.response_status)) 4.65 self.sendResponseHeaders() 4.66 if send_body: 4.67 - #print 'sendResponse> writing body' 4.68 self.send(body) 4.69 + self.flush() 4.70 4.71 def write(self, data): 4.72 - #print 'write>', data 4.73 self.output.write(data) 4.74 4.75 def send(self, data): 4.76 - #print 'send>', len(data), '|%s|' % data 4.77 + #print 'send>', data 4.78 self.out.write(data) 4.79 4.80 + def flush(self): 4.81 + self.out.flush() 4.82 + 4.83 def hasNoBody(self): 4.84 return ((self.request_method == "HEAD") or 4.85 (self.response_code in NO_BODY_CODES) or
5.1 --- a/tools/python/xen/web/httpserver.py Thu Apr 21 14:11:29 2005 +0000 5.2 +++ b/tools/python/xen/web/httpserver.py Fri Apr 22 15:30:43 2005 +0000 5.3 @@ -1,27 +1,137 @@ 5.4 +import threading 5.5 + 5.6 import string 5.7 import socket 5.8 +import types 5.9 from urllib import quote, unquote 5.10 5.11 +from xen.xend import sxp 5.12 +from xen.xend.Args import ArgError 5.13 +from xen.xend.XendError import XendError 5.14 + 5.15 import http 5.16 +from resource import Resource, ErrorPage 5.17 from SrvDir import SrvDir 5.18 5.19 -class HttpServerRequest(http.HttpRequest): 5.20 +class ThreadRequest: 5.21 + """A request to complete processing using a thread. 5.22 + """ 5.23 + 5.24 + def __init__(self, processor, req, fn, args, kwds): 5.25 + self.processor = processor 5.26 + self.req = req 5.27 + self.fn = fn 5.28 + self.args = args 5.29 + self.kwds = kwds 5.30 + 5.31 + def run(self): 5.32 + self.processor.setInThread() 5.33 + thread = threading.Thread(target=self.main) 5.34 + thread.setDaemon(True) 5.35 + thread.start() 5.36 + 5.37 + def call(self): 5.38 + try: 5.39 + self.fn(*self.args, **self.kwds) 5.40 + except SystemExit: 5.41 + raise 5.42 + except Exception, ex: 5.43 + self.req.resultErr(ex) 5.44 + self.req.finish() 5.45 + 5.46 + def main(self): 5.47 + self.call() 5.48 + self.processor.process() 5.49 + 5.50 + 5.51 +class RequestProcessor: 5.52 + """Processor for requests on a connection to an http server. 5.53 + Requests are executed synchonously unless they ask for a thread by returning 5.54 + a ThreadRequest. 5.55 + """ 5.56 + 5.57 + done = False 5.58 + 5.59 + inThread = False 5.60 5.61 - def __init__(self, server, addr, srd, srw): 5.62 - #print 'HttpServerRequest>', addr 5.63 + def __init__(self, server, sock, addr): 5.64 self.server = server 5.65 + self.sock = sock 5.66 + self.srd = sock.makefile('rb') 5.67 + self.srw = sock.makefile('wb') 5.68 + self.srvaddr = server.getServerAddr() 5.69 + 5.70 + def isInThread(self): 5.71 + return self.inThread 5.72 + 5.73 + def setInThread(self): 5.74 + self.inThread = True 5.75 + 5.76 + def getServer(self): 5.77 + return self.server 5.78 + 5.79 + def getRequest(self): 5.80 + return HttpServerRequest(self, self.srvaddr, self.srd, self.srw) 5.81 + 5.82 + def close(self): 5.83 + try: 5.84 + self.sock.close() 5.85 + except: 5.86 + pass 5.87 + 5.88 + def finish(self): 5.89 + self.done = True 5.90 + self.close() 5.91 + 5.92 + def process(self): 5.93 + while not self.done: 5.94 + req = self.getRequest() 5.95 + res = req.process() 5.96 + if isinstance(res, ThreadRequest): 5.97 + if self.isInThread(): 5.98 + res.call() 5.99 + else: 5.100 + res.run() 5.101 + break 5.102 + else: 5.103 + req.finish() 5.104 + 5.105 +class HttpServerRequest(http.HttpRequest): 5.106 + """A single request to an http server. 5.107 + """ 5.108 + 5.109 + def __init__(self, processor, addr, srd, srw): 5.110 + self.processor = processor 5.111 self.prepath = '' 5.112 http.HttpRequest.__init__(self, addr, srd, srw) 5.113 5.114 + def getServer(self): 5.115 + return self.processor.getServer() 5.116 + 5.117 def process(self): 5.118 - #print 'HttpServerRequest>process', 'path=', self.request_path 5.119 - self.prepath = [] 5.120 - self.postpath = map(unquote, string.split(self.request_path[1:], '/')) 5.121 - res = self.getResource() 5.122 - self.render(res) 5.123 + """Process the request. If the return value is a ThreadRequest 5.124 + it is evaluated in a thread. 5.125 + """ 5.126 + try: 5.127 + self.prepath = [] 5.128 + self.postpath = map(unquote, string.split(self.request_path[1:], '/')) 5.129 + resource = self.getResource() 5.130 + return self.render(resource) 5.131 + except SystemExit: 5.132 + raise 5.133 + except Exception, ex: 5.134 + self.processError(ex) 5.135 + 5.136 + def processError(self, ex): 5.137 + import traceback; traceback.print_exc() 5.138 + self.sendError(http.INTERNAL_SERVER_ERROR, msg=str(ex)) 5.139 + self.setCloseConnection('close') 5.140 + 5.141 + def finish(self): 5.142 self.sendResponse() 5.143 - return self.close_connection 5.144 - 5.145 + if self.close_connection: 5.146 + self.processor.finish() 5.147 + 5.148 def prePathURL(self): 5.149 url_host = self.getRequestHostname() 5.150 port = self.getPort() 5.151 @@ -37,25 +147,111 @@ class HttpServerRequest(http.HttpRequest 5.152 return ('%s://%s/%s' % (url_proto, url_host, url_path)) 5.153 5.154 def getResource(self): 5.155 - return self.server.getResource(self) 5.156 + return self.getServer().getResource(self) 5.157 5.158 - def render(self, res): 5.159 - #print 'HttpServerRequest>render', res 5.160 - if res is None: 5.161 + def render(self, resource): 5.162 + val = None 5.163 + if resource is None: 5.164 self.sendError(http.NOT_FOUND) 5.165 else: 5.166 - res.render(self) 5.167 + try: 5.168 + while True: 5.169 + val = resource.render(self) 5.170 + if not isinstance(val, Resource): 5.171 + break 5.172 + val = self.result(val) 5.173 + except SystemExit: 5.174 + raise 5.175 + except Exception, ex: 5.176 + self.resultErr(ex) 5.177 + return val 5.178 + 5.179 + def threadRequest(self, _fn, *_args, **_kwds): 5.180 + """Create a request to finish request processing in a thread. 5.181 + Use this to create a ThreadRequest to return from rendering a 5.182 + resource if you need a thread to complete processing. 5.183 + """ 5.184 + return ThreadRequest(self.processor, self, _fn, _args, _kwds) 5.185 + 5.186 + def result(self, val): 5.187 + if isinstance(val, Exception): 5.188 + return self.resultErr(val) 5.189 + else: 5.190 + return self.resultVal(val) 5.191 + 5.192 + def resultVal(self, val): 5.193 + """Callback to complete the request. 5.194 5.195 + @param val: the value 5.196 + """ 5.197 + if isinstance(val, ThreadRequest): 5.198 + return val 5.199 + elif self.useSxp(): 5.200 + self.setHeader("Content-Type", sxp.mime_type) 5.201 + sxp.show(val, out=self) 5.202 + else: 5.203 + self.write('<html><head></head><body>') 5.204 + self.printPath() 5.205 + if isinstance(val, types.ListType): 5.206 + self.write('<code><pre>') 5.207 + PrettyPrint.prettyprint(val, out=self) 5.208 + self.write('</pre></code>') 5.209 + else: 5.210 + self.write(str(val)) 5.211 + self.write('</body></html>') 5.212 + return None 5.213 + 5.214 + def resultErr(self, err): 5.215 + """Error callback to complete a request. 5.216 + 5.217 + @param err: the error 5.218 + """ 5.219 + if not isinstance(err, (ArgError, sxp.ParseError, XendError)): 5.220 + raise 5.221 + #log.exception("op=%s: %s", op, str(err)) 5.222 + if self.useSxp(): 5.223 + self.setHeader("Content-Type", sxp.mime_type) 5.224 + sxp.show(['xend.err', str(err)], out=self) 5.225 + else: 5.226 + self.setHeader("Content-Type", "text/plain") 5.227 + self.write('Error ') 5.228 + self.write(': ') 5.229 + self.write(str(err)) 5.230 + return None 5.231 + 5.232 + def useSxp(self): 5.233 + """Determine whether to send an SXP response to a request. 5.234 + Uses SXP if there is no User-Agent, no Accept, or application/sxp is in Accept. 5.235 + 5.236 + returns 1 for SXP, 0 otherwise 5.237 + """ 5.238 + ok = 0 5.239 + user_agent = self.getHeader('User-Agent') 5.240 + accept = self.getHeader('Accept') 5.241 + if (not user_agent) or (not accept) or (accept.find(sxp.mime_type) >= 0): 5.242 + ok = 1 5.243 + return ok 5.244 + 5.245 + def printPath(self): 5.246 + pathlist = [x for x in self.prepath if x != '' ] 5.247 + s = "/" 5.248 + self.write('<h1><a href="/">/</a>') 5.249 + for x in pathlist: 5.250 + s += x + "/" 5.251 + self.write(' <a href="%s">%s</a>/' % (s, x)) 5.252 + self.write("</h1>") 5.253 + 5.254 class HttpServer: 5.255 5.256 - request_queue_size = 5 5.257 + backlog = 5 5.258 + 5.259 + closed = False 5.260 5.261 def __init__(self, interface='', port=8080, root=None): 5.262 if root is None: 5.263 root = SrvDir() 5.264 self.interface = interface 5.265 self.port = port 5.266 - self.closed = False 5.267 self.root = root 5.268 5.269 def getRoot(self): 5.270 @@ -73,13 +269,12 @@ class HttpServer: 5.271 self.close() 5.272 5.273 def bind(self): 5.274 - #print 'bind>', self.interface, self.port 5.275 self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 5.276 self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 5.277 self.socket.bind((self.interface, self.port)) 5.278 5.279 def listen(self): 5.280 - self.socket.listen(self.request_queue_size) 5.281 + self.socket.listen(self.backlog) 5.282 5.283 def accept(self): 5.284 return self.socket.accept() 5.285 @@ -96,33 +291,27 @@ class HttpServer: 5.286 pass 5.287 5.288 def acceptRequest(self): 5.289 - #print 'acceptRequest>' 5.290 try: 5.291 (sock, addr) = self.accept() 5.292 - #print 'acceptRequest>', sock, addr 5.293 self.processRequest(sock, addr) 5.294 except socket.error: 5.295 return 5.296 5.297 def processRequest(self, sock, addr): 5.298 - #print 'processRequest>', sock, addr 5.299 - srd = sock.makefile('rb') 5.300 - srw = sock.makefile('wb') 5.301 - srvaddr = (socket.gethostname(), self.port) 5.302 - while True: 5.303 - #print 'HttpServerRequest...' 5.304 - req = HttpServerRequest(self, srvaddr, srd, srw) 5.305 - close = req.process() 5.306 - srw.flush() 5.307 - #print 'HttpServerRequest close=', close 5.308 - if close: 5.309 - break 5.310 try: 5.311 - #print 'close...' 5.312 - sock.close() 5.313 - except: 5.314 - pass 5.315 - #print 'processRequest<', sock, addr 5.316 + rp = RequestProcessor(self, sock, addr) 5.317 + rp.process() 5.318 + except SystemExit: 5.319 + raise 5.320 + except Exception, ex: 5.321 + print 'HttpServer>processRequest> exception: ', ex 5.322 + try: 5.323 + sock.close() 5.324 + except: 5.325 + pass 5.326 + 5.327 + def getServerAddr(self): 5.328 + return (socket.gethostname(), self.port) 5.329 5.330 def getResource(self, req): 5.331 return self.root.getRequestResource(req)
6.1 --- a/tools/python/xen/web/protocol.py Thu Apr 21 14:11:29 2005 +0000 6.2 +++ b/tools/python/xen/web/protocol.py Fri Apr 22 15:30:43 2005 +0000 6.3 @@ -1,29 +1,52 @@ 6.4 class Factory: 6.5 + """Generic protocol factory. 6.6 + """ 6.7 + 6.8 + starts = 0 6.9 6.10 def __init__(self): 6.11 pass 6.12 6.13 - def startedConnecting(self): 6.14 - print 'ServerProtocolFactory>startedConnecting>' 6.15 - pass 6.16 - 6.17 def doStart(self): 6.18 - print 'ServerProtocolFactory>doStart>' 6.19 - pass 6.20 + if self.starts == 0: 6.21 + self.startFactory() 6.22 + self.starts += 1 6.23 6.24 def doStop(self): 6.25 - print 'ServerProtocolFactory>doStop>' 6.26 - pass 6.27 + if self.starts > 0: 6.28 + self.starts -= 1 6.29 + else: 6.30 + return 6.31 + if self.starts == 0: 6.32 + self.stopFactory() 6.33 6.34 def buildProtocol(self, addr): 6.35 - print 'ServerProtocolFactory>buildProtocol>', addr 6.36 return Protocol(self) 6.37 6.38 + def startFactory(self): 6.39 + pass 6.40 + 6.41 + def stopFactory(self): 6.42 + pass 6.43 + 6.44 class ServerFactory(Factory): 6.45 + """Factory for server protocols. 6.46 + """ 6.47 pass 6.48 6.49 class ClientFactory(Factory): 6.50 - pass 6.51 + """Factory for client protocols. 6.52 + """ 6.53 + 6.54 + def startedConnecting(self, connector): 6.55 + pass 6.56 + 6.57 + def clientConnectionLost(self, connector, reason): 6.58 + pass 6.59 + 6.60 + def clientConnectionFailed(self, connector, reason): 6.61 + pass 6.62 + 6.63 6.64 class Protocol: 6.65 6.66 @@ -65,23 +88,32 @@ class Protocol: 6.67 else: 6.68 return None 6.69 6.70 -class TestClientFactory(Factory): 6.71 +class TestClientFactory(ClientFactory): 6.72 6.73 def buildProtocol(self, addr): 6.74 - print 'TestClientProtocolFactory>buildProtocol>', addr 6.75 + print 'TestClientFactory>buildProtocol>', addr 6.76 return TestClientProtocol(self) 6.77 6.78 + def startedConnecting(self, connector): 6.79 + print 'TestClientFactory>startedConnecting>', connector 6.80 + 6.81 + def clientConnectionLost(self, connector, reason): 6.82 + print 'TestClientFactory>clientConnectionLost>', connector, reason 6.83 + 6.84 + def clientConnectionFailed(self, connector, reason): 6.85 + print 'TestClientFactory>clientConnectionFailed>', connector, reason 6.86 + 6.87 class TestClientProtocol(Protocol): 6.88 6.89 def connectionMade(self, addr): 6.90 - print 'TestProtocol>connectionMade>', addr 6.91 + print 'TestClientProtocol>connectionMade>', addr 6.92 self.write("hello") 6.93 self.write("there") 6.94 6.95 class TestServerFactory(Factory): 6.96 6.97 def buildProtocol(self, addr): 6.98 - print 'TestServerProtocolFactory>buildProtocol>', addr 6.99 + print 'TestServerFactory>buildProtocol>', addr 6.100 return TestServerProtocol(self) 6.101 6.102 class TestServerProtocol(Protocol):
7.1 --- a/tools/python/xen/xend/XendDomain.py Thu Apr 21 14:11:29 2005 +0000 7.2 +++ b/tools/python/xen/xend/XendDomain.py Fri Apr 22 15:30:43 2005 +0000 7.3 @@ -369,7 +369,7 @@ class XendDomain: 7.4 7.5 @param id: domain id 7.6 """ 7.7 - dominfo = xen_domain(id) 7.8 + dominfo = self.xen_domain(id) 7.9 if dominfo: 7.10 d = self.domain_by_id.get(id) 7.11 if d: 7.12 @@ -454,7 +454,6 @@ class XendDomain: 7.13 7.14 @param src: source file 7.15 @param progress: output progress if true 7.16 - @return: deferred 7.17 """ 7.18 xmigrate = XendMigrate.instance() 7.19 return xmigrate.restore_begin(src) 7.20 @@ -667,7 +666,6 @@ class XendDomain: 7.21 """Start domain migration. 7.22 7.23 @param id: domain id 7.24 - @return: deferred 7.25 """ 7.26 # Need a cancel too? 7.27 # Don't forget to cancel restart for it. 7.28 @@ -681,7 +679,6 @@ class XendDomain: 7.29 @param id: domain id 7.30 @param dst: destination file 7.31 @param progress: output progress if true 7.32 - @return: deferred 7.33 """ 7.34 dominfo = self.domain_lookup(id) 7.35 xmigrate = XendMigrate.instance()
8.1 --- a/tools/python/xen/xend/XendMigrate.py Thu Apr 21 14:11:29 2005 +0000 8.2 +++ b/tools/python/xen/xend/XendMigrate.py Fri Apr 22 15:30:43 2005 +0000 8.3 @@ -1,6 +1,7 @@ 8.4 # Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 8.5 8.6 import traceback 8.7 +import threading 8.8 8.9 import errno 8.10 import sys 8.11 @@ -8,12 +9,8 @@ import socket 8.12 import time 8.13 import types 8.14 8.15 -from twisted.internet import reactor 8.16 -from twisted.internet import defer 8.17 -#defer.Deferred.debug = 1 8.18 -from twisted.internet.protocol import Protocol 8.19 -from twisted.internet.protocol import ClientFactory 8.20 -from twisted.python.failure import Failure 8.21 +from xen.web import reactor 8.22 +from xen.web.protocol import Protocol, ClientFactory 8.23 8.24 import sxp 8.25 import XendDB 8.26 @@ -37,11 +34,13 @@ class Xfrd(Protocol): 8.27 self.parser = sxp.Parser() 8.28 self.xinfo = xinfo 8.29 8.30 - def connectionMade(self): 8.31 + def connectionMade(self, addr=None): 8.32 # Send hello. 8.33 self.request(['xfr.hello', XFR_PROTO_MAJOR, XFR_PROTO_MINOR]) 8.34 # Send request. 8.35 self.xinfo.request(self) 8.36 + # Run the transport mainLoop which reads from the peer. 8.37 + self.transport.mainLoop() 8.38 8.39 def request(self, req): 8.40 sxp.show(req, out=self.transport) 8.41 @@ -60,7 +59,6 @@ class Xfrd(Protocol): 8.42 if self.parser.at_eof(): 8.43 self.loseConnection() 8.44 8.45 - 8.46 class XfrdClientFactory(ClientFactory): 8.47 """Factory for clients of the migration/save daemon xfrd. 8.48 """ 8.49 @@ -68,7 +66,33 @@ class XfrdClientFactory(ClientFactory): 8.50 def __init__(self, xinfo): 8.51 #ClientFactory.__init__(self) 8.52 self.xinfo = xinfo 8.53 + self.readyCond = threading.Condition() 8.54 + self.ready = False 8.55 + self.err = None 8.56 8.57 + def start(self): 8.58 + print 'XfrdClientFactory>start>' 8.59 + reactor.connectTCP('localhost', XFRD_PORT, self) 8.60 + try: 8.61 + self.readyCond.acquire() 8.62 + while not self.ready: 8.63 + self.readyCond.wait() 8.64 + finally: 8.65 + self.readyCond.release() 8.66 + print 'XfrdClientFactory>start>', 'err=', self.err 8.67 + if self.err: 8.68 + raise self.err 8.69 + return 0 8.70 + 8.71 + def notifyReady(self): 8.72 + try: 8.73 + self.readyCond.acquire() 8.74 + self.ready = True 8.75 + self.err = self.xinfo.error_summary() 8.76 + self.readyCond.notify() 8.77 + finally: 8.78 + self.readyCond.release() 8.79 + 8.80 def startedConnecting(self, connector): 8.81 pass 8.82 8.83 @@ -76,10 +100,72 @@ class XfrdClientFactory(ClientFactory): 8.84 return Xfrd(self.xinfo) 8.85 8.86 def clientConnectionLost(self, connector, reason): 8.87 - pass 8.88 + print "XfrdClientFactory>clientConnectionLost>", reason 8.89 + self.notifyReady() 8.90 8.91 def clientConnectionFailed(self, connector, reason): 8.92 + print "XfrdClientFactory>clientConnectionFailed>", reason 8.93 self.xinfo.error(reason) 8.94 + self.notifyReady() 8.95 + 8.96 +class SuspendHandler: 8.97 + 8.98 + def __init__(self, xinfo, vmid, timeout): 8.99 + self.xinfo = xinfo 8.100 + self.vmid = vmid 8.101 + self.timeout = timeout 8.102 + self.readyCond = threading.Condition() 8.103 + self.ready = False 8.104 + self.err = None 8.105 + 8.106 + def start(self): 8.107 + self.subscribe(on=True) 8.108 + timer = reactor.callLater(self.timeout, self.onTimeout) 8.109 + try: 8.110 + self.readyCond.acquire() 8.111 + while not self.ready: 8.112 + self.readyCond.wait() 8.113 + finally: 8.114 + self.readyCond.release() 8.115 + self.subscribe(on=False) 8.116 + timer.cancel() 8.117 + if self.err: 8.118 + raise XendError(self.err) 8.119 + 8.120 + def notifyReady(self, err=None): 8.121 + try: 8.122 + self.readyCond.acquire() 8.123 + if not self.ready: 8.124 + self.ready = True 8.125 + self.err = err 8.126 + self.readyCond.notify() 8.127 + finally: 8.128 + self.readyCond.release() 8.129 + 8.130 + def subscribe(self, on=True): 8.131 + # Subscribe to 'suspended' events so we can tell when the 8.132 + # suspend completes. Subscribe to 'died' events so we can tell if 8.133 + # the domain died. 8.134 + if on: 8.135 + action = eserver.subscribe 8.136 + else: 8.137 + action = eserver.unsubscribe 8.138 + action('xend.domain.suspended', self.onSuspended) 8.139 + action('xend.domain.died', self.onDied) 8.140 + 8.141 + def onSuspended(self, e, v): 8.142 + if v[1] != self.vmid: return 8.143 + print 'SuspendHandler>onSuspended>', e, v 8.144 + self.notifyReady() 8.145 + 8.146 + def onDied(self, e, v): 8.147 + if v[1] != self.vmid: return 8.148 + print 'SuspendHandler>onDied>', e, v 8.149 + self.notifyReady('Domain %s died while suspending' % self.vmid) 8.150 + 8.151 + def onTimeout(self): 8.152 + print 'SuspendHandler>onTimeout>' 8.153 + self.notifyReady('Domain %s suspend timed out' % self.vmid) 8.154 8.155 class XfrdInfo: 8.156 """Abstract class for info about a session with xfrd. 8.157 @@ -88,18 +174,17 @@ class XfrdInfo: 8.158 8.159 """Suspend timeout (seconds). 8.160 We set a timeout because suspending a domain can hang.""" 8.161 - timeout = 10 8.162 + timeout = 30 8.163 8.164 def __init__(self): 8.165 from xen.xend import XendDomain 8.166 self.xd = XendDomain.instance() 8.167 - self.deferred = defer.Deferred() 8.168 self.suspended = {} 8.169 self.paused = {} 8.170 self.state = 'init' 8.171 # List of errors encountered. 8.172 self.errors = [] 8.173 - 8.174 + 8.175 def vmconfig(self): 8.176 dominfo = self.xd.domain_get(self.src_dom) 8.177 if dominfo: 8.178 @@ -110,11 +195,10 @@ class XfrdInfo: 8.179 8.180 def add_error(self, err): 8.181 """Add an error to the error list. 8.182 - Returns the error added (which may have been unwrapped if it 8.183 - was a Twisted Failure). 8.184 + Returns the error added. 8.185 """ 8.186 - while isinstance(err, Failure): 8.187 - err = err.value 8.188 + #while isinstance(err, Failure): 8.189 + # err = err.value 8.190 if err not in self.errors: 8.191 self.errors.append(err) 8.192 return err 8.193 @@ -122,6 +206,8 @@ class XfrdInfo: 8.194 def error_summary(self, msg=None): 8.195 """Get a XendError summarising the errors (if any). 8.196 """ 8.197 + if not self.errors: 8.198 + return None 8.199 if msg is None: 8.200 msg = "errors" 8.201 if self.errors: 8.202 @@ -136,34 +222,27 @@ class XfrdInfo: 8.203 return self.errors 8.204 8.205 def error(self, err): 8.206 + print 'XfrdInfo>error>', err 8.207 self.state = 'error' 8.208 self.add_error(err) 8.209 - if not self.deferred.called: 8.210 - self.deferred.errback(self.error_summary()) 8.211 8.212 def dispatch(self, xfrd, val): 8.213 - 8.214 - def cbok(v): 8.215 - if v is None: return 8.216 - sxp.show(v, out=xfrd.transport) 8.217 - 8.218 - def cberr(err): 8.219 - v = ['xfr.err', errno.EINVAL] 8.220 - sxp.show(v, out=xfrd.transport) 8.221 - self.error(err) 8.222 - 8.223 + print 'XfrdInfo>dispatch>', val 8.224 op = sxp.name(val) 8.225 op = op.replace('.', '_') 8.226 if op.startswith('xfr_'): 8.227 fn = getattr(self, op, self.unknown) 8.228 else: 8.229 fn = self.unknown 8.230 - val = fn(xfrd, val) 8.231 - if isinstance(val, defer.Deferred): 8.232 - val.addCallback(cbok) 8.233 - val.addErrback(cberr) 8.234 - else: 8.235 - cbok(val) 8.236 + try: 8.237 + val = fn(xfrd, val) 8.238 + if val: 8.239 + sxp.show(val, out=xfrd.transport) 8.240 + except Exception, err: 8.241 + print 'XfrdInfo>dispatch> error:', err 8.242 + val = ['xfr.err', errno.EINVAL] 8.243 + sxp.show(val, out=xfrd.transport) 8.244 + self.error(err) 8.245 8.246 def unknown(self, xfrd, val): 8.247 xfrd.loseConnection() 8.248 @@ -172,6 +251,7 @@ class XfrdInfo: 8.249 def xfr_err(self, xfrd, val): 8.250 # If we get an error with non-zero code the operation failed. 8.251 # An error with code zero indicates hello success. 8.252 + print 'XfrdInfo>xfr_err>', val 8.253 v = sxp.child0(val) 8.254 err = int(sxp.child0(val)) 8.255 if not err: return 8.256 @@ -220,50 +300,19 @@ class XfrdInfo: 8.257 return ['xfr.err', val] 8.258 8.259 def xfr_vm_suspend(self, xfrd, val): 8.260 - """Suspend a domain. Suspending takes time, so we return 8.261 - a Deferred that is called when the suspend completes. 8.262 + """Suspend a domain. 8.263 Suspending can hang, so we set a timeout and fail if it 8.264 takes too long. 8.265 """ 8.266 try: 8.267 vmid = sxp.child0(val) 8.268 - d = defer.Deferred() 8.269 - # Subscribe to 'suspended' events so we can tell when the 8.270 - # suspend completes. Subscribe to 'died' events so we can tell if 8.271 - # the domain died. Set a timeout and error handler so the subscriptions 8.272 - # will be cleaned up if suspending hangs or there is an error. 8.273 - def onSuspended(e, v): 8.274 - if v[1] != vmid: return 8.275 - subscribe(on=0) 8.276 - if not d.called: 8.277 - d.callback(v) 8.278 - 8.279 - def onDied(e, v): 8.280 - if v[1] != vmid: return 8.281 - if not d.called: 8.282 - d.errback(XendError('Domain %s died while suspending' % vmid)) 8.283 - 8.284 - def subscribe(on=1): 8.285 - if on: 8.286 - action = eserver.subscribe 8.287 - else: 8.288 - action = eserver.unsubscribe 8.289 - action('xend.domain.suspended', onSuspended) 8.290 - action('xend.domain.died', onDied) 8.291 - 8.292 - def cberr(err): 8.293 - subscribe(on=0) 8.294 - self.add_error("suspend failed") 8.295 - self.add_error(err) 8.296 - return err 8.297 - 8.298 - d.addErrback(cberr) 8.299 - d.setTimeout(self.timeout) 8.300 - subscribe() 8.301 + h = SuspendHandler(self, vmid, self.timeout) 8.302 val = self.xd.domain_shutdown(vmid, reason='suspend') 8.303 self.suspended[vmid] = 1 8.304 - return d 8.305 + h.start() 8.306 + print 'xfr_vm_suspend> suspended', vmid 8.307 except Exception, err: 8.308 + print 'xfr_vm_suspend> err', err 8.309 self.add_error("suspend failed") 8.310 self.add_error(err) 8.311 traceback.print_exc() 8.312 @@ -271,6 +320,7 @@ class XfrdInfo: 8.313 return ['xfr.err', val] 8.314 8.315 def connectionLost(self, reason=None): 8.316 + print 'XfrdInfo>connectionLost>', reason 8.317 for vmid in self.suspended: 8.318 try: 8.319 self.xd.domain_destroy(vmid) 8.320 @@ -336,10 +386,11 @@ class XendMigrateInfo(XfrdInfo): 8.321 self.state = 'ok' 8.322 self.dst_dom = dom 8.323 self.xd.domain_destroy(self.src_dom) 8.324 - if not self.deferred.called: 8.325 - self.deferred.callback(self) 8.326 + #if not self.deferred.called: 8.327 + # self.deferred.callback(self) 8.328 8.329 def connectionLost(self, reason=None): 8.330 + print 'XendMigrateInfo>connectionLost>', reason 8.331 XfrdInfo.connectionLost(self, reason) 8.332 if self.state =='ok': 8.333 log.info('Migrate OK: ' + str(self.sxpr())) 8.334 @@ -386,10 +437,11 @@ class XendSaveInfo(XfrdInfo): 8.335 def xfr_save_ok(self, xfrd, val): 8.336 self.state = 'ok' 8.337 self.xd.domain_destroy(self.src_dom) 8.338 - if not self.deferred.called: 8.339 - self.deferred.callback(self) 8.340 + #if not self.deferred.called: 8.341 + # self.deferred.callback(self) 8.342 8.343 def connectionLost(self, reason=None): 8.344 + print 'XendSaveInfo>connectionLost>', reason 8.345 XfrdInfo.connectionLost(self, reason) 8.346 if self.state =='ok': 8.347 log.info('Save OK: ' + str(self.sxpr())) 8.348 @@ -493,29 +545,17 @@ class XendMigrate: 8.349 8.350 def session_begin(self, info): 8.351 """Add the session to the table and start it. 8.352 - Set up callbacks to remove the session from the table 8.353 - when it finishes. 8.354 + Remove the session from the table when it finishes. 8.355 8.356 @param info: session 8.357 @return: deferred 8.358 """ 8.359 - dfr = defer.Deferred() 8.360 - def cbok(val): 8.361 - self._delete_session(info.xid) 8.362 - if not dfr.called: 8.363 - dfr.callback(val) 8.364 - return val 8.365 - def cberr(err): 8.366 + self._add_session(info) 8.367 + try: 8.368 + xcf = XfrdClientFactory(info) 8.369 + return xcf.start() 8.370 + finally: 8.371 self._delete_session(info.xid) 8.372 - if not dfr.called: 8.373 - dfr.errback(err) 8.374 - return err 8.375 - self._add_session(info) 8.376 - info.deferred.addCallback(cbok) 8.377 - info.deferred.addErrback(cberr) 8.378 - xcf = XfrdClientFactory(info) 8.379 - reactor.connectTCP('localhost', XFRD_PORT, xcf) 8.380 - return dfr 8.381 8.382 def migrate_begin(self, dominfo, host, port=XFRD_PORT, live=0, resource=0): 8.383 """Begin to migrate a domain to another host.
9.1 --- a/tools/python/xen/xend/server/SrvConsole.py Thu Apr 21 14:11:29 2005 +0000 9.2 +++ b/tools/python/xen/xend/server/SrvConsole.py Fri Apr 22 15:30:43 2005 +0000 9.3 @@ -21,22 +21,18 @@ class SrvConsole(SrvDir): 9.4 return self.perform(req) 9.5 9.6 def render_GET(self, req): 9.7 - try: 9.8 - if self.use_sxp(req): 9.9 - req.setHeader("Content-Type", sxp.mime_type) 9.10 - sxp.show(self.info.sxpr(), out=req) 9.11 - else: 9.12 - req.write('<html><head></head><body>') 9.13 - self.print_path(req) 9.14 - #self.ls() 9.15 - req.write('<p>%s</p>' % self.info) 9.16 - req.write('<p><a href="%s">Connect to domain %d</a></p>' 9.17 - % (self.info.uri(), self.info.dom)) 9.18 - self.form(req) 9.19 - req.write('</body></html>') 9.20 - return '' 9.21 - except Exception, ex: 9.22 - self._perform_err(ex, req) 9.23 + if self.use_sxp(req): 9.24 + req.setHeader("Content-Type", sxp.mime_type) 9.25 + sxp.show(self.info.sxpr(), out=req) 9.26 + else: 9.27 + req.write('<html><head></head><body>') 9.28 + self.print_path(req) 9.29 + #self.ls() 9.30 + req.write('<p>%s</p>' % self.info) 9.31 + req.write('<p><a href="%s">Connect to domain %d</a></p>' 9.32 + % (self.info.uri(), self.info.dom)) 9.33 + self.form(req) 9.34 + req.write('</body></html>') 9.35 9.36 def form(self, req): 9.37 req.write('<form method="post" action="%s">' % req.prePathURL())
10.1 --- a/tools/python/xen/xend/server/SrvConsoleDir.py Thu Apr 21 14:11:29 2005 +0000 10.2 +++ b/tools/python/xen/xend/server/SrvConsoleDir.py Fri Apr 22 15:30:43 2005 +0000 10.3 @@ -31,20 +31,16 @@ class SrvConsoleDir(SrvDir): 10.4 return v 10.5 10.6 def render_GET(self, req): 10.7 - try: 10.8 - if self.use_sxp(req): 10.9 - req.setHeader("Content-Type", sxp.mime_type) 10.10 - self.ls_console(req, 1) 10.11 - else: 10.12 - req.write("<html><head></head><body>") 10.13 - self.print_path(req) 10.14 - self.ls(req) 10.15 - self.ls_console(req) 10.16 - #self.form(req.wfile) 10.17 - req.write("</body></html>") 10.18 - return '' 10.19 - except Exception, ex: 10.20 - self._perform_err(ex, req) 10.21 + if self.use_sxp(req): 10.22 + req.setHeader("Content-Type", sxp.mime_type) 10.23 + self.ls_console(req, 1) 10.24 + else: 10.25 + req.write("<html><head></head><body>") 10.26 + self.print_path(req) 10.27 + self.ls(req) 10.28 + self.ls_console(req) 10.29 + #self.form(req.wfile) 10.30 + req.write("</body></html>") 10.31 10.32 def ls_console(self, req, use_sxp=0): 10.33 url = req.prePathURL()
11.1 --- a/tools/python/xen/xend/server/SrvDaemon.py Thu Apr 21 14:11:29 2005 +0000 11.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py Fri Apr 22 15:30:43 2005 +0000 11.3 @@ -17,9 +17,6 @@ import StringIO 11.4 import traceback 11.5 import time 11.6 11.7 -#from twisted.internet import pollreactor; pollreactor.install() 11.8 -from twisted.internet import reactor 11.9 - 11.10 from xen.lowlevel import xu 11.11 11.12 from xen.xend import sxp 11.13 @@ -330,8 +327,6 @@ class Daemon: 11.14 self.daemonize() 11.15 print 'running serverthread...' 11.16 serverthread.start() 11.17 - print 'running reactor...' 11.18 - reactor.run() 11.19 except Exception, ex: 11.20 print >>sys.stderr, 'Exception starting xend:', ex 11.21 if DEBUG: 11.22 @@ -356,7 +351,7 @@ class Daemon: 11.23 self.channelF.start() 11.24 11.25 def exit(self, rc=0): 11.26 - reactor.disconnectAll() 11.27 + #reactor.disconnectAll() 11.28 self.channelF.stop() 11.29 # Calling sys.exit() raises a SystemExit exception, which only 11.30 # kills the current thread. Calling os._exit() makes the whole
12.1 --- a/tools/python/xen/xend/server/SrvDmesg.py Thu Apr 21 14:11:29 2005 +0000 12.2 +++ b/tools/python/xen/xend/server/SrvDmesg.py Fri Apr 22 15:30:43 2005 +0000 12.3 @@ -19,19 +19,15 @@ class SrvDmesg(SrvDir): 12.4 self.perform(req) 12.5 12.6 def render_GET(self, req): 12.7 - try: 12.8 - if self.use_sxp(req): 12.9 - req.setHeader("Content-Type", "text/plain") 12.10 - req.write(self.info()) 12.11 - else: 12.12 - req.write('<html><head></head><body>') 12.13 - self.print_path(req) 12.14 - req.write('<pre>') 12.15 - req.write(self.info()) 12.16 - req.write('</pre></body></html>') 12.17 - return '' 12.18 - except Exception, ex: 12.19 - self._perform_err(ex, req) 12.20 + if self.use_sxp(req): 12.21 + req.setHeader("Content-Type", "text/plain") 12.22 + req.write(self.info()) 12.23 + else: 12.24 + req.write('<html><head></head><body>') 12.25 + self.print_path(req) 12.26 + req.write('<pre>') 12.27 + req.write(self.info()) 12.28 + req.write('</pre></body></html>') 12.29 12.30 def info(self): 12.31 return self.xd.info()
13.1 --- a/tools/python/xen/xend/server/SrvDomain.py Thu Apr 21 14:11:29 2005 +0000 13.2 +++ b/tools/python/xen/xend/server/SrvDomain.py Fri Apr 22 15:30:43 2005 +0000 13.3 @@ -26,24 +26,27 @@ class SrvDomain(SrvDir): 13.4 not a domain name. 13.5 """ 13.6 fn = FormFn(self.xd.domain_configure, 13.7 - [['dom', 'int'], 13.8 + [['dom', 'int'], 13.9 ['config', 'sxpr']]) 13.10 - deferred = fn(req.args, {'dom': self.dom.dom}) 13.11 - return deferred 13.12 + return fn(req.args, {'dom': self.dom.dom}) 13.13 13.14 def op_unpause(self, op, req): 13.15 val = self.xd.domain_unpause(self.dom.name) 13.16 return val 13.17 13.18 def op_pause(self, op, req): 13.19 + # Pause doesn't need a thread, but request one for testing. 13.20 + return req.threadRequest(self.do_pause, op, req) 13.21 + 13.22 + def do_pause(self, op, req): 13.23 val = self.xd.domain_pause(self.dom.name) 13.24 return val 13.25 13.26 def op_shutdown(self, op, req): 13.27 fn = FormFn(self.xd.domain_shutdown, 13.28 - [['dom', 'str'], 13.29 + [['dom', 'str'], 13.30 ['reason', 'str'], 13.31 - ['key', 'int']]) 13.32 + ['key', 'int']]) 13.33 val = fn(req.args, {'dom': self.dom.id}) 13.34 req.setResponseCode(http.ACCEPTED) 13.35 req.setHeader("Location", "%s/.." % req.prePathURL()) 13.36 @@ -51,42 +54,39 @@ class SrvDomain(SrvDir): 13.37 13.38 def op_destroy(self, op, req): 13.39 fn = FormFn(self.xd.domain_destroy, 13.40 - [['dom', 'str'], 13.41 + [['dom', 'str'], 13.42 ['reason', 'str']]) 13.43 val = fn(req.args, {'dom': self.dom.id}) 13.44 req.setHeader("Location", "%s/.." % req.prePathURL()) 13.45 return val 13.46 13.47 def op_save(self, op, req): 13.48 + return req.threadRequest(self.do_save, op, req) 13.49 + 13.50 + def do_save(self, op, req): 13.51 fn = FormFn(self.xd.domain_save, 13.52 - [['dom', 'str'], 13.53 + [['dom', 'str'], 13.54 ['file', 'str']]) 13.55 - deferred = fn(req.args, {'dom': self.dom.id}) 13.56 - deferred.addCallback(self._op_save_cb, req) 13.57 - return deferred 13.58 - 13.59 - def _op_save_cb(self, val, req): 13.60 + val = fn(req.args, {'dom': self.dom.id}) 13.61 return 0 13.62 13.63 def op_migrate(self, op, req): 13.64 + return req.threadRequest(self.do_migrate, op, req) 13.65 + 13.66 + def do_migrate(self, op, req): 13.67 fn = FormFn(self.xd.domain_migrate, 13.68 - [['dom', 'str'], 13.69 + [['dom', 'str'], 13.70 ['destination', 'str'], 13.71 - ['live', 'int'], 13.72 - ['resource', 'int']]) 13.73 - deferred = fn(req.args, {'dom': self.dom.id}) 13.74 - deferred.addCallback(self._op_migrate_cb, req) 13.75 - return deferred 13.76 - 13.77 - def _op_migrate_cb(self, info, req): 13.78 - print '_op_migrate_cb>', info, req 13.79 + ['live', 'int'], 13.80 + ['resource', 'int']]) 13.81 + info = fn(req.args, {'dom': self.dom.id}) 13.82 #req.setResponseCode(http.ACCEPTED) 13.83 host = info.dst_host 13.84 port = info.dst_port 13.85 dom = info.dst_dom 13.86 url = "http://%s:%d/xend/domain/%d" % (host, port, dom) 13.87 req.setHeader("Location", url) 13.88 - print '_op_migrate_cb> url=', url 13.89 + print 'do_migrate> url=', url 13.90 return url 13.91 13.92 def op_pincpu(self, op, req): 13.93 @@ -98,57 +98,57 @@ class SrvDomain(SrvDir): 13.94 13.95 def op_cpu_bvt_set(self, op, req): 13.96 fn = FormFn(self.xd.domain_cpu_bvt_set, 13.97 - [['dom', 'str'], 13.98 - ['mcuadv', 'int'], 13.99 - ['warpback', 'int'], 13.100 + [['dom', 'str'], 13.101 + ['mcuadv', 'int'], 13.102 + ['warpback', 'int'], 13.103 ['warpvalue', 'int'], 13.104 - ['warpl', 'long'], 13.105 - ['warpu', 'long']]) 13.106 + ['warpl', 'long'], 13.107 + ['warpu', 'long']]) 13.108 val = fn(req.args, {'dom': self.dom.id}) 13.109 return val 13.110 13.111 def op_maxmem_set(self, op, req): 13.112 fn = FormFn(self.xd.domain_maxmem_set, 13.113 - [['dom', 'str'], 13.114 + [['dom', 'str'], 13.115 ['memory', 'int']]) 13.116 val = fn(req.args, {'dom': self.dom.id}) 13.117 return val 13.118 13.119 def op_device_create(self, op, req): 13.120 fn = FormFn(self.xd.domain_device_create, 13.121 - [['dom', 'str'], 13.122 + [['dom', 'str'], 13.123 ['config', 'sxpr']]) 13.124 - d = fn(req.args, {'dom': self.dom.id}) 13.125 - return d 13.126 + val = fn(req.args, {'dom': self.dom.id}) 13.127 + return val 13.128 13.129 def op_device_refresh(self, op, req): 13.130 fn = FormFn(self.xd.domain_device_refresh, 13.131 - [['dom', 'str'], 13.132 + [['dom', 'str'], 13.133 ['type', 'str'], 13.134 - ['idx', 'str']]) 13.135 + ['idx', 'str']]) 13.136 val = fn(req.args, {'dom': self.dom.id}) 13.137 return val 13.138 13.139 def op_device_destroy(self, op, req): 13.140 fn = FormFn(self.xd.domain_device_destroy, 13.141 - [['dom', 'str'], 13.142 + [['dom', 'str'], 13.143 ['type', 'str'], 13.144 - ['idx', 'str']]) 13.145 + ['idx', 'str']]) 13.146 val = fn(req.args, {'dom': self.dom.id}) 13.147 return val 13.148 13.149 def op_device_configure(self, op, req): 13.150 fn = FormFn(self.xd.domain_device_configure, 13.151 - [['dom', 'str'], 13.152 + [['dom', 'str'], 13.153 ['config', 'sxpr'], 13.154 - ['idx', 'str']]) 13.155 - d = fn(req.args, {'dom': self.dom.id}) 13.156 - return d 13.157 + ['idx', 'str']]) 13.158 + val = fn(req.args, {'dom': self.dom.id}) 13.159 + return val 13.160 13.161 def op_vif_credit_limit(self, op, req): 13.162 fn = FormFn(self.xd.domain_vif_credit_limit, 13.163 - [['dom', 'str'], 13.164 - ['vif', 'int'], 13.165 + [['dom', 'str'], 13.166 + ['vif', 'int'], 13.167 ['credit', 'int'], 13.168 ['period', 'int']]) 13.169 val = fn(req.args, {'dom': self.dom.id}) 13.170 @@ -178,7 +178,7 @@ class SrvDomain(SrvDir): 13.171 13.172 def op_mem_target_set(self, op, req): 13.173 fn = FormFn(self.xd.domain_mem_target_set, 13.174 - [['dom', 'str'], 13.175 + [['dom', 'str'], 13.176 ['target', 'int']]) 13.177 val = fn(req.args, {'dom': self.dom.id}) 13.178 return val
14.1 --- a/tools/python/xen/xend/server/SrvDomainDir.py Thu Apr 21 14:11:29 2005 +0000 14.2 +++ b/tools/python/xen/xend/server/SrvDomainDir.py Fri Apr 22 15:30:43 2005 +0000 14.3 @@ -68,7 +68,7 @@ class SrvDomainDir(SrvDir): 14.4 raise XendError("Error creating domain: " + str(ex)) 14.5 14.6 def _op_create_cb(self, dominfo, configstring, req): 14.7 - """Callback to handle deferred domain creation. 14.8 + """Callback to handle domain creation. 14.9 """ 14.10 dom = dominfo.name 14.11 domurl = "%s/%s" % (req.prePathURL(), dom) 14.12 @@ -90,14 +90,13 @@ class SrvDomainDir(SrvDir): 14.13 def op_restore(self, op, req): 14.14 """Restore a domain from file. 14.15 14.16 - @return: deferred 14.17 """ 14.18 + return req.threadRequest(self.do_restore, op, req) 14.19 + 14.20 + def do_restore(self, op, req): 14.21 fn = FormFn(self.xd.domain_restore, 14.22 [['file', 'str']]) 14.23 dominfo = fn(req.args) 14.24 - return self._op_restore_cb(dominfo, req) 14.25 - 14.26 - def _op_restore_cb(self, dominfo, req): 14.27 dom = dominfo.name 14.28 domurl = "%s/%s" % (req.prePathURL(), dom) 14.29 req.setResponseCode(http.CREATED) 14.30 @@ -116,20 +115,16 @@ class SrvDomainDir(SrvDir): 14.31 return self.perform(req) 14.32 14.33 def render_GET(self, req): 14.34 - try: 14.35 - if self.use_sxp(req): 14.36 - req.setHeader("Content-Type", sxp.mime_type) 14.37 - self.ls_domain(req, 1) 14.38 - else: 14.39 - req.write("<html><head></head><body>") 14.40 - self.print_path(req) 14.41 - self.ls(req) 14.42 - self.ls_domain(req) 14.43 - self.form(req) 14.44 - req.write("</body></html>") 14.45 - return '' 14.46 - except Exception, ex: 14.47 - self._perform_err(ex, req) 14.48 + if self.use_sxp(req): 14.49 + req.setHeader("Content-Type", sxp.mime_type) 14.50 + self.ls_domain(req, 1) 14.51 + else: 14.52 + req.write("<html><head></head><body>") 14.53 + self.print_path(req) 14.54 + self.ls(req) 14.55 + self.ls_domain(req) 14.56 + self.form(req) 14.57 + req.write("</body></html>") 14.58 14.59 def ls_domain(self, req, use_sxp=0): 14.60 url = req.prePathURL()
15.1 --- a/tools/python/xen/xend/server/SrvNode.py Thu Apr 21 14:11:29 2005 +0000 15.2 +++ b/tools/python/xen/xend/server/SrvNode.py Fri Apr 22 15:30:43 2005 +0000 15.3 @@ -35,26 +35,22 @@ class SrvNode(SrvDir): 15.4 return self.perform(req) 15.5 15.6 def render_GET(self, req): 15.7 - try: 15.8 - if self.use_sxp(req): 15.9 - req.setHeader("Content-Type", sxp.mime_type) 15.10 - sxp.show(['node'] + self.info(), out=req) 15.11 - else: 15.12 - url = req.prePathURL() 15.13 - if not url.endswith('/'): 15.14 - url += '/' 15.15 - req.write('<html><head></head><body>') 15.16 - self.print_path(req) 15.17 - req.write('<ul>') 15.18 - for d in self.info(): 15.19 - req.write('<li> %10s: %s' % (d[0], str(d[1]))) 15.20 - req.write('<li><a href="%sdmesg">Xen dmesg output</a>' % url) 15.21 - req.write('<li><a href="%slog>Xend log</a>' % url) 15.22 - req.write('</ul>') 15.23 - req.write('</body></html>') 15.24 - return '' 15.25 - except Exception, ex: 15.26 - self._perform_err(ex, req) 15.27 + if self.use_sxp(req): 15.28 + req.setHeader("Content-Type", sxp.mime_type) 15.29 + sxp.show(['node'] + self.info(), out=req) 15.30 + else: 15.31 + url = req.prePathURL() 15.32 + if not url.endswith('/'): 15.33 + url += '/' 15.34 + req.write('<html><head></head><body>') 15.35 + self.print_path(req) 15.36 + req.write('<ul>') 15.37 + for d in self.info(): 15.38 + req.write('<li> %10s: %s' % (d[0], str(d[1]))) 15.39 + req.write('<li><a href="%sdmesg">Xen dmesg output</a>' % url) 15.40 + req.write('<li><a href="%slog>Xend log</a>' % url) 15.41 + req.write('</ul>') 15.42 + req.write('</body></html>') 15.43 15.44 def info(self): 15.45 return self.xn.info()
16.1 --- a/tools/python/xen/xend/server/SrvVnetDir.py Thu Apr 21 14:11:29 2005 +0000 16.2 +++ b/tools/python/xen/xend/server/SrvVnetDir.py Fri Apr 22 15:30:43 2005 +0000 16.3 @@ -75,20 +75,16 @@ class SrvVnetDir(SrvDir): 16.4 return self.perform(req) 16.5 16.6 def render_GET(self, req): 16.7 - try: 16.8 - if self.use_sxp(req): 16.9 - req.setHeader("Content-Type", sxp.mime_type) 16.10 - self.ls_vnet(req, 1) 16.11 - else: 16.12 - req.write("<html><head></head><body>") 16.13 - self.print_path(req) 16.14 - self.ls(req) 16.15 - self.ls_vnet(req) 16.16 - self.form(req) 16.17 - req.write("</body></html>") 16.18 - return '' 16.19 - except Exception, ex: 16.20 - self._perform_err(ex, req) 16.21 + if self.use_sxp(req): 16.22 + req.setHeader("Content-Type", sxp.mime_type) 16.23 + self.ls_vnet(req, 1) 16.24 + else: 16.25 + req.write("<html><head></head><body>") 16.26 + self.print_path(req) 16.27 + self.ls(req) 16.28 + self.ls_vnet(req) 16.29 + self.form(req) 16.30 + req.write("</body></html>") 16.31 16.32 def ls_vnet(self, req, use_sxp=0): 16.33 url = req.prePathURL()
17.1 --- a/tools/python/xen/xend/server/SrvXendLog.py Thu Apr 21 14:11:29 2005 +0000 17.2 +++ b/tools/python/xen/xend/server/SrvXendLog.py Fri Apr 22 15:30:43 2005 +0000 17.3 @@ -18,7 +18,4 @@ class SrvXendLog(SrvDir): 17.4 self.logfile.encoding = None 17.5 17.6 def render_GET(self, req): 17.7 - try: 17.8 - return self.logfile.render(req) 17.9 - except Exception, ex: 17.10 - self._perform_err(ex, 'log', req) 17.11 + return self.logfile.render(req)
18.1 --- a/tools/python/xen/xend/server/usbif.py Thu Apr 21 14:11:29 2005 +0000 18.2 +++ b/tools/python/xen/xend/server/usbif.py Fri Apr 22 15:30:43 2005 +0000 18.3 @@ -62,7 +62,6 @@ class UsbBackend: 18.4 """Connect the controller to the usbif control interface. 18.5 18.6 @param recreate: true if after xend restart 18.7 - @return: deferred 18.8 """ 18.9 log.debug("Connecting usbif %s", str(self)) 18.10 if recreate or self.connected or self.connecting: