1
#============================================================================
2
# This library is free software; you can redistribute it and/or
3
# modify it under the terms of version 2.1 of the GNU Lesser General Public
4
# License as published by the Free Software Foundation.
6
# This library is distributed in the hope that it will be useful,
7
# but WITHOUT ANY WARRANTY; without even the implied warranty of
8
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9
# Lesser General Public License for more details.
11
# You should have received a copy of the GNU Lesser General Public
12
# License along with this library; if not, write to the Free Software
13
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14
#============================================================================
15
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
16
# Copyright (C) 2005 XenSource Ltd
17
#============================================================================
25
from xen.web import protocol, tcp, unix, connection
27
from xen.xend import sxp
28
from xen.xend import XendDomain
29
from xen.xend import XendOptions
30
from xen.xend.XendError import XendError
31
from xen.xend.XendLogging import log
34
class RelocationProtocol(protocol.Protocol):
35
"""Asynchronous handler for a connected relocation socket.
39
protocol.Protocol.__init__(self)
40
self.parser = sxp.Parser()
42
def dataReceived(self, data):
44
self.parser.input(data)
45
while(self.parser.ready()):
46
val = self.parser.get_val()
47
res = self.dispatch(val)
49
if self.parser.at_eof():
58
self.transport.close()
60
def send_reply(self, sxpr):
61
io = StringIO.StringIO()
62
sxp.show(sxpr, out=io)
66
return self.transport.write(io.getvalue())
70
def send_result(self, res):
75
return self.send_reply(resp)
78
(extype, exval) = sys.exc_info()[:2]
79
return self.send_reply(['err',
80
['type', str(extype)],
81
['value', str(exval)]])
83
def opname(self, name):
84
return 'op_' + name.replace('.', '_')
86
def operror(self, name, _):
87
raise XendError('Invalid operation: ' +name)
89
def dispatch(self, req):
90
op_name = sxp.name(req)
91
op_method_name = self.opname(op_name)
92
op_method = getattr(self, op_method_name, self.operror)
93
return op_method(op_name, req)
95
def op_help(self, _1, _2):
97
if x.startswith('op_'):
98
return x[3:].replace('_', '.')
102
l = [ nameop(k) for k in dir(self) if k.startswith('op_') ]
105
def op_quit(self, _1, _2):
108
def op_receive(self, name, _):
110
self.send_reply(["ready", name])
112
XendDomain.instance().domain_restore_fd(
113
self.transport.sock.fileno(), relocating=True)
118
log.error(name + ": no transport")
119
raise XendError(name + ": no transport")
121
def op_sslreceive(self, name, _):
123
self.send_reply(["ready", name])
124
p2cread, p2cwrite = os.pipe()
125
from xen.util import oshelp
126
oshelp.fcntl_setfd_cloexec(p2cwrite, True)
127
threading.Thread(target=connection.SSLSocketServerConnection.recv2fd,
128
args=(self.transport.sock, p2cwrite)).start()
130
XendDomain.instance().domain_restore_fd(p2cread,
138
log.error(name + ": no transport")
139
raise XendError(name + ": no transport")
142
def listenRelocation():
143
xoptions = XendOptions.instance()
144
if xoptions.get_xend_unix_server():
145
path = '/var/lib/xend/relocation-socket'
146
unix.UnixListener(path, RelocationProtocol)
148
interface = xoptions.get_xend_relocation_address()
150
hosts_allow = xoptions.get_xend_relocation_hosts_allow()
151
if hosts_allow == '':
154
hosts_allow = map(re.compile, hosts_allow.split(" "))
156
if xoptions.get_xend_relocation_server():
157
port = xoptions.get_xend_relocation_port()
158
tcp.TCPListener(RelocationProtocol, port, interface = interface,
159
hosts_allow = hosts_allow)
161
if xoptions.get_xend_relocation_ssl_server():
162
port = xoptions.get_xend_relocation_ssl_port()
163
ssl_key_file = xoptions.get_xend_relocation_server_ssl_key_file()
164
ssl_cert_file = xoptions.get_xend_relocation_server_ssl_cert_file()
166
if ssl_key_file and ssl_cert_file:
167
tcp.SSLTCPListener(RelocationProtocol, port, interface = interface,
168
hosts_allow = hosts_allow,
169
ssl_key_file = ssl_key_file,
170
ssl_cert_file = ssl_cert_file)
172
raise XendError("ssl_key_file or ssl_cert_file for ssl relocation server is missing.")