~ubuntu-branches/ubuntu/utopic/xen/utopic

« back to all changes in this revision

Viewing changes to tools/python/xen/xend/server/relocate.py

  • Committer: Bazaar Package Importer
  • Author(s): Bastian Blank
  • Date: 2010-05-06 15:47:38 UTC
  • mto: (1.3.1) (15.1.1 sid) (4.1.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20100506154738-agoz0rlafrh1fnq7
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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.
 
5
#
 
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.
 
10
#
 
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
#============================================================================
 
18
 
 
19
import re
 
20
import os
 
21
import sys
 
22
import StringIO
 
23
import threading
 
24
 
 
25
from xen.web import protocol, tcp, unix, connection
 
26
 
 
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
 
32
 
 
33
 
 
34
class RelocationProtocol(protocol.Protocol):
 
35
    """Asynchronous handler for a connected relocation socket.
 
36
    """
 
37
 
 
38
    def __init__(self):
 
39
        protocol.Protocol.__init__(self)
 
40
        self.parser = sxp.Parser()
 
41
 
 
42
    def dataReceived(self, data):
 
43
        try:
 
44
            self.parser.input(data)
 
45
            while(self.parser.ready()):
 
46
                val = self.parser.get_val()
 
47
                res = self.dispatch(val)
 
48
                self.send_result(res)
 
49
            if self.parser.at_eof():
 
50
                self.close()
 
51
        except SystemExit:
 
52
            raise
 
53
        except:
 
54
            self.send_error()
 
55
 
 
56
    def close(self):
 
57
        if self.transport:
 
58
            self.transport.close()
 
59
 
 
60
    def send_reply(self, sxpr):
 
61
        io = StringIO.StringIO()
 
62
        sxp.show(sxpr, out=io)
 
63
        print >> io
 
64
        io.seek(0)
 
65
        if self.transport:
 
66
            return self.transport.write(io.getvalue())
 
67
        else:
 
68
            return 0
 
69
 
 
70
    def send_result(self, res):
 
71
        if res is None:
 
72
            resp = ['ok']
 
73
        else:
 
74
            resp = ['ok', res]
 
75
        return self.send_reply(resp)
 
76
 
 
77
    def send_error(self):
 
78
        (extype, exval) = sys.exc_info()[:2]
 
79
        return self.send_reply(['err',
 
80
                                ['type', str(extype)],
 
81
                                ['value', str(exval)]])
 
82
 
 
83
    def opname(self, name):
 
84
         return 'op_' + name.replace('.', '_')
 
85
 
 
86
    def operror(self, name, _):
 
87
        raise XendError('Invalid operation: ' +name)
 
88
 
 
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)
 
94
 
 
95
    def op_help(self, _1, _2):
 
96
        def nameop(x):
 
97
            if x.startswith('op_'):
 
98
                return x[3:].replace('_', '.')
 
99
            else:
 
100
                return x
 
101
        
 
102
        l = [ nameop(k) for k in dir(self) if k.startswith('op_') ]
 
103
        return l
 
104
 
 
105
    def op_quit(self, _1, _2):
 
106
        self.close()
 
107
 
 
108
    def op_receive(self, name, _):
 
109
        if self.transport:
 
110
            self.send_reply(["ready", name])
 
111
            try:
 
112
                XendDomain.instance().domain_restore_fd(
 
113
                    self.transport.sock.fileno(), relocating=True)
 
114
            except:
 
115
                self.send_error()
 
116
                self.close()
 
117
        else:
 
118
            log.error(name + ": no transport")
 
119
            raise XendError(name + ": no transport")
 
120
 
 
121
    def op_sslreceive(self, name, _):
 
122
        if self.transport:
 
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()
 
129
            try:
 
130
                XendDomain.instance().domain_restore_fd(p2cread,
 
131
                                                        relocating=True)
 
132
            except:
 
133
                os.close(p2cread)
 
134
                os.close(p2cwrite)
 
135
                self.send_error()
 
136
                self.close()
 
137
        else:
 
138
            log.error(name + ": no transport")
 
139
            raise XendError(name + ": no transport")
 
140
 
 
141
 
 
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)
 
147
 
 
148
    interface = xoptions.get_xend_relocation_address()
 
149
 
 
150
    hosts_allow = xoptions.get_xend_relocation_hosts_allow()
 
151
    if hosts_allow == '':
 
152
        hosts_allow = None
 
153
    else:
 
154
        hosts_allow = map(re.compile, hosts_allow.split(" "))
 
155
 
 
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)
 
160
 
 
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()
 
165
 
 
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)
 
171
        else:
 
172
            raise XendError("ssl_key_file or ssl_cert_file for ssl relocation server is missing.")
 
173