Statistics
| Branch: | Tag: | Revision:

root / xseg / tools / archipelago / archipelago / common.py @ 8ade203a

History | View | Annotate | Download (34.5 kB)

1 979bf615 Filippos Giannakos
#!/usr/bin/env python
2 979bf615 Filippos Giannakos
3 979bf615 Filippos Giannakos
# Copyright 2012 GRNET S.A. All rights reserved.
4 979bf615 Filippos Giannakos
#
5 979bf615 Filippos Giannakos
# Redistribution and use in source and binary forms, with or
6 979bf615 Filippos Giannakos
# without modification, are permitted provided that the following
7 979bf615 Filippos Giannakos
# conditions are met:
8 979bf615 Filippos Giannakos
#
9 979bf615 Filippos Giannakos
#   1. Redistributions of source code must retain the above
10 979bf615 Filippos Giannakos
#      copyright notice, this list of conditions and the following
11 979bf615 Filippos Giannakos
#      disclaimer.
12 2369891d Filippos Giannakos
#
13 979bf615 Filippos Giannakos
#   2. Redistributions in binary form must reproduce the above
14 979bf615 Filippos Giannakos
#      copyright notice, this list of conditions and the following
15 979bf615 Filippos Giannakos
#      disclaimer in the documentation and/or other materials
16 979bf615 Filippos Giannakos
#      provided with the distribution.
17 979bf615 Filippos Giannakos
#
18 979bf615 Filippos Giannakos
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
19 979bf615 Filippos Giannakos
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 979bf615 Filippos Giannakos
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 979bf615 Filippos Giannakos
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
22 979bf615 Filippos Giannakos
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 979bf615 Filippos Giannakos
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 979bf615 Filippos Giannakos
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 979bf615 Filippos Giannakos
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 979bf615 Filippos Giannakos
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 979bf615 Filippos Giannakos
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 979bf615 Filippos Giannakos
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 979bf615 Filippos Giannakos
# POSSIBILITY OF SUCH DAMAGE.
30 979bf615 Filippos Giannakos
#
31 979bf615 Filippos Giannakos
# The views and conclusions contained in the software and
32 979bf615 Filippos Giannakos
# documentation are those of the authors and should not be
33 979bf615 Filippos Giannakos
# interpreted as representing official policies, either expressed
34 979bf615 Filippos Giannakos
# or implied, of GRNET S.A.
35 979bf615 Filippos Giannakos
#
36 979bf615 Filippos Giannakos
37 979bf615 Filippos Giannakos
38 979bf615 Filippos Giannakos
from xseg.xseg_api import *
39 979bf615 Filippos Giannakos
from xseg.xprotocol import *
40 979bf615 Filippos Giannakos
from ctypes import CFUNCTYPE, cast, c_void_p, addressof, string_at, memmove, \
41 b0ef21ea Filippos Giannakos
    create_string_buffer, pointer, sizeof, POINTER, byref, c_int, c_char, Structure
42 e0192e9f Filippos Giannakos
import ctypes
43 979bf615 Filippos Giannakos
cb_null_ptrtype = CFUNCTYPE(None, uint32_t)
44 979bf615 Filippos Giannakos
45 1075ead7 Filippos Giannakos
import os
46 1075ead7 Filippos Giannakos
import sys
47 1075ead7 Filippos Giannakos
import time
48 1075ead7 Filippos Giannakos
import psutil
49 1075ead7 Filippos Giannakos
import errno
50 2daa9ec8 Filippos Giannakos
import signal
51 1075ead7 Filippos Giannakos
from subprocess import check_call
52 979bf615 Filippos Giannakos
from collections import namedtuple
53 4a7d2eb6 Filippos Giannakos
import socket
54 8b692198 Filippos Giannakos
import random
55 b0ef21ea Filippos Giannakos
from select import select
56 8ade203a Chrysostomos Nanakos
import ConfigParser
57 8b692198 Filippos Giannakos
58 8b692198 Filippos Giannakos
random.seed()
59 4a7d2eb6 Filippos Giannakos
hostname = socket.gethostname()
60 979bf615 Filippos Giannakos
61 2daa9ec8 Filippos Giannakos
valid_role_types = ['file_blocker', 'rados_blocker', 'mapperd', 'vlmcd']
62 e7b7dd84 Filippos Giannakos
valid_segment_types = ['segdev', 'posix']
63 979bf615 Filippos Giannakos
64 979bf615 Filippos Giannakos
peers = dict()
65 979bf615 Filippos Giannakos
xsegbd_args = []
66 e7b7dd84 Filippos Giannakos
segment = None
67 979bf615 Filippos Giannakos
modules = ['xseg', 'segdev', 'xseg_posix', 'xseg_pthread', 'xseg_segdev']
68 979bf615 Filippos Giannakos
xsegbd = 'xsegbd'
69 979bf615 Filippos Giannakos
70 98c5d2e9 Filippos Giannakos
BIN_DIR = '/usr/bin/'
71 94ce8b66 Filippos Giannakos
DEFAULTS = '/etc/archipelago/archipelago.conf'
72 979bf615 Filippos Giannakos
73 979bf615 Filippos Giannakos
#system defaults
74 1075ead7 Filippos Giannakos
ARCHIP_PREFIX = 'archip_'
75 1075ead7 Filippos Giannakos
LOG_SUFFIX = '.log'
76 1075ead7 Filippos Giannakos
PID_SUFFIX = '.pid'
77 1075ead7 Filippos Giannakos
PIDFILE_PATH = "/var/run/archipelago"
78 1075ead7 Filippos Giannakos
VLMC_LOCK_FILE = 'vlmc.lock'
79 1075ead7 Filippos Giannakos
LOGS_PATH = "/var/log/archipelago"
80 1075ead7 Filippos Giannakos
LOCK_PATH = "/var/lock"
81 1075ead7 Filippos Giannakos
DEVICE_PREFIX = "/dev/xsegbd"
82 1075ead7 Filippos Giannakos
XSEGBD_SYSFS = "/sys/bus/xsegbd/"
83 1075ead7 Filippos Giannakos
84 1075ead7 Filippos Giannakos
CHARDEV_NAME = "/dev/segdev"
85 1075ead7 Filippos Giannakos
CHARDEV_MAJOR = 60
86 1075ead7 Filippos Giannakos
CHARDEV_MINOR = 0
87 1075ead7 Filippos Giannakos
88 1075ead7 Filippos Giannakos
REQS = 512
89 1075ead7 Filippos Giannakos
90 98c5d2e9 Filippos Giannakos
FILE_BLOCKER = 'archip-filed'
91 6b11e79a Filippos Giannakos
RADOS_BLOCKER = 'archip-sosd'
92 6b11e79a Filippos Giannakos
MAPPER = 'archip-mapperd'
93 6b11e79a Filippos Giannakos
VLMC = 'archip-vlmcd'
94 979bf615 Filippos Giannakos
95 60485a88 Filippos Giannakos
def is_power2(x):
96 60485a88 Filippos Giannakos
    return bool(x != 0 and (x & (x-1)) == 0)
97 2daa9ec8 Filippos Giannakos
98 b0ef21ea Filippos Giannakos
#hack to test green waiting with python gevent.
99 b0ef21ea Filippos Giannakos
class posixfd_signal_desc(Structure):
100 b0ef21ea Filippos Giannakos
    pass
101 b0ef21ea Filippos Giannakos
posixfd_signal_desc._fields_ = [
102 b0ef21ea Filippos Giannakos
    ('signal_file', c_char * sizeof(c_void_p)),
103 b0ef21ea Filippos Giannakos
    ('fd', c_int),
104 b0ef21ea Filippos Giannakos
    ('flag', c_int),
105 b0ef21ea Filippos Giannakos
]
106 b0ef21ea Filippos Giannakos
107 b0ef21ea Filippos Giannakos
def xseg_wait_signal_green(ctx, sd, timeout):
108 b0ef21ea Filippos Giannakos
    posixfd_sd = cast(sd, POINTER(posixfd_signal_desc))
109 b0ef21ea Filippos Giannakos
    fd = posixfd_sd.contents.fd
110 b0ef21ea Filippos Giannakos
    select([fd], [], [], timeout/1000000.0)
111 b0ef21ea Filippos Giannakos
    while True:
112 b0ef21ea Filippos Giannakos
        try:
113 b0ef21ea Filippos Giannakos
            os.read(fd, 512)
114 b0ef21ea Filippos Giannakos
        except OSError as (e,msg):
115 b0ef21ea Filippos Giannakos
            if e == 11:
116 b0ef21ea Filippos Giannakos
                break
117 b0ef21ea Filippos Giannakos
            else:
118 b0ef21ea Filippos Giannakos
                raise OSError(e, msg)
119 b0ef21ea Filippos Giannakos
120 b0ef21ea Filippos Giannakos
121 2daa9ec8 Filippos Giannakos
class Peer(object):
122 2daa9ec8 Filippos Giannakos
    cli_opts = None
123 2daa9ec8 Filippos Giannakos
124 2daa9ec8 Filippos Giannakos
    def __init__(self, role=None, daemon=True, nr_ops=16,
125 2daa9ec8 Filippos Giannakos
                 logfile=None, pidfile=None, portno_start=None,
126 2daa9ec8 Filippos Giannakos
                 portno_end=None, log_level=0, spec=None):
127 2daa9ec8 Filippos Giannakos
        if not role:
128 2daa9ec8 Filippos Giannakos
            raise Error("Role was not provided")
129 2daa9ec8 Filippos Giannakos
        self.role = role
130 2daa9ec8 Filippos Giannakos
131 60485a88 Filippos Giannakos
        self.nr_ops = nr_ops
132 60485a88 Filippos Giannakos
        if not self.nr_ops > 0:
133 60485a88 Filippos Giannakos
            raise Error("Invalid nr_ops for %s" % role)
134 60485a88 Filippos Giannakos
135 60485a88 Filippos Giannakos
        if not is_power2(self.nr_ops):
136 60485a88 Filippos Giannakos
            raise Error("nr_ops of %s is not a power of 2" % role)
137 60485a88 Filippos Giannakos
138 2daa9ec8 Filippos Giannakos
        if not self.executable:
139 2daa9ec8 Filippos Giannakos
            raise Error("Executable must be provided for %s" % role)
140 2daa9ec8 Filippos Giannakos
141 98c5d2e9 Filippos Giannakos
        if portno_start is None:
142 60485a88 Filippos Giannakos
            raise Error("Portno_start must be provided for %s" % role)
143 2daa9ec8 Filippos Giannakos
        self.portno_start = portno_start
144 2daa9ec8 Filippos Giannakos
145 98c5d2e9 Filippos Giannakos
        if portno_end is None:
146 60485a88 Filippos Giannakos
            raise Error("Portno_end must be provided for %s" % role)
147 2daa9ec8 Filippos Giannakos
        self.portno_end = portno_end
148 2daa9ec8 Filippos Giannakos
149 2daa9ec8 Filippos Giannakos
        self.daemon = daemon
150 2daa9ec8 Filippos Giannakos
        if not spec:
151 2daa9ec8 Filippos Giannakos
            raise Error("Xseg spec was not provided for %s" % role)
152 2daa9ec8 Filippos Giannakos
        self.spec = spec
153 2daa9ec8 Filippos Giannakos
154 2daa9ec8 Filippos Giannakos
        if logfile:
155 2daa9ec8 Filippos Giannakos
            self.logfile = logfile
156 2daa9ec8 Filippos Giannakos
        else:
157 2daa9ec8 Filippos Giannakos
            self.logfile = os.path.join(LOGS_PATH, role + LOG_SUFFIX)
158 2daa9ec8 Filippos Giannakos
159 2daa9ec8 Filippos Giannakos
        if pidfile:
160 2daa9ec8 Filippos Giannakos
            self.pidfile = pidfile
161 2daa9ec8 Filippos Giannakos
        else:
162 2daa9ec8 Filippos Giannakos
            self.pidfile = os.path.join(PIDFILE_PATH, role + PID_SUFFIX)
163 2daa9ec8 Filippos Giannakos
164 2daa9ec8 Filippos Giannakos
        try:
165 2daa9ec8 Filippos Giannakos
            if not os.path.isdir(os.path.dirname(self.logfile)):
166 2daa9ec8 Filippos Giannakos
                raise Error("Log path %s does not exist" % self.logfile)
167 2daa9ec8 Filippos Giannakos
        except:
168 2daa9ec8 Filippos Giannakos
            raise Error("Log path %s does not exist or is not a directory" %
169 2daa9ec8 Filippos Giannakos
                        self.logfile)
170 2daa9ec8 Filippos Giannakos
171 2daa9ec8 Filippos Giannakos
        try:
172 2daa9ec8 Filippos Giannakos
            os.makedirs(os.path.dirname(self.pidfile))
173 2daa9ec8 Filippos Giannakos
        except OSError as e:
174 2daa9ec8 Filippos Giannakos
            if e.errno == errno.EEXIST:
175 2daa9ec8 Filippos Giannakos
                if os.path.isdir(os.path.dirname(self.pidfile)):
176 2daa9ec8 Filippos Giannakos
                    pass
177 2daa9ec8 Filippos Giannakos
                else:
178 2daa9ec8 Filippos Giannakos
                    raise Error("Pid path %s is not a directory" %
179 2daa9ec8 Filippos Giannakos
                                os.path.dirname(self.pidfile))
180 2daa9ec8 Filippos Giannakos
            else:
181 2daa9ec8 Filippos Giannakos
                raise Error("Cannot create path %s" %
182 2daa9ec8 Filippos Giannakos
                            os.path.dirname(self.pidfile))
183 2daa9ec8 Filippos Giannakos
184 2daa9ec8 Filippos Giannakos
        self.log_level = log_level
185 2daa9ec8 Filippos Giannakos
186 2daa9ec8 Filippos Giannakos
        if self.log_level < 0 or self.log_level > 3:
187 2daa9ec8 Filippos Giannakos
            raise Error("%s: Invalid log level %d" %
188 2daa9ec8 Filippos Giannakos
                        (self.role, self.log_level))
189 2daa9ec8 Filippos Giannakos
190 2daa9ec8 Filippos Giannakos
        if self.cli_opts is None:
191 2daa9ec8 Filippos Giannakos
            self.cli_opts = []
192 2daa9ec8 Filippos Giannakos
        self.set_cli_options()
193 2daa9ec8 Filippos Giannakos
194 2daa9ec8 Filippos Giannakos
    def start(self):
195 2daa9ec8 Filippos Giannakos
        if self.get_pid():
196 2daa9ec8 Filippos Giannakos
            raise Error("Peer has valid pidfile")
197 98c5d2e9 Filippos Giannakos
        cmd = [os.path.join(BIN_DIR, self.executable)] + self.cli_opts
198 2daa9ec8 Filippos Giannakos
        try:
199 2daa9ec8 Filippos Giannakos
            check_call(cmd, shell=False)
200 2daa9ec8 Filippos Giannakos
        except Exception as e:
201 2daa9ec8 Filippos Giannakos
            raise Error("Cannot start %s: %s" % (self.role, str(e)))
202 2daa9ec8 Filippos Giannakos
203 2daa9ec8 Filippos Giannakos
    def stop(self):
204 2daa9ec8 Filippos Giannakos
        pid = self.get_pid()
205 2daa9ec8 Filippos Giannakos
        if not pid:
206 2daa9ec8 Filippos Giannakos
            raise Error("Peer %s not running" % self.role)
207 2daa9ec8 Filippos Giannakos
208 2daa9ec8 Filippos Giannakos
        if self.__is_running(pid):
209 2daa9ec8 Filippos Giannakos
            os.kill(pid, signal.SIGTERM)
210 2daa9ec8 Filippos Giannakos
211 2daa9ec8 Filippos Giannakos
    def __is_running(self, pid):
212 2daa9ec8 Filippos Giannakos
        name = self.executable
213 2daa9ec8 Filippos Giannakos
        for p in psutil.process_iter():
214 2daa9ec8 Filippos Giannakos
            if p.name[0:len(name)] == name and pid == p.pid:
215 2daa9ec8 Filippos Giannakos
                return True
216 2daa9ec8 Filippos Giannakos
217 2daa9ec8 Filippos Giannakos
        return False
218 2daa9ec8 Filippos Giannakos
219 2daa9ec8 Filippos Giannakos
    def is_running(self):
220 2daa9ec8 Filippos Giannakos
        pid = self.get_pid()
221 2daa9ec8 Filippos Giannakos
        if not pid:
222 2daa9ec8 Filippos Giannakos
            return False
223 2daa9ec8 Filippos Giannakos
224 2daa9ec8 Filippos Giannakos
        if not self.__is_running(pid):
225 2daa9ec8 Filippos Giannakos
            raise Error("Peer %s has valid pidfile but is not running" %
226 2daa9ec8 Filippos Giannakos
                        self.role)
227 2daa9ec8 Filippos Giannakos
228 2daa9ec8 Filippos Giannakos
        return True
229 2daa9ec8 Filippos Giannakos
230 2daa9ec8 Filippos Giannakos
    def get_pid(self):
231 2daa9ec8 Filippos Giannakos
        if not self.pidfile:
232 2daa9ec8 Filippos Giannakos
            return None
233 2daa9ec8 Filippos Giannakos
234 2daa9ec8 Filippos Giannakos
        pf = None
235 2daa9ec8 Filippos Giannakos
        try:
236 2daa9ec8 Filippos Giannakos
            pf = open(self.pidfile, "r")
237 2daa9ec8 Filippos Giannakos
            pid = int(pf.read())
238 2daa9ec8 Filippos Giannakos
            pf.close()
239 2daa9ec8 Filippos Giannakos
        except:
240 2daa9ec8 Filippos Giannakos
            if pf:
241 2daa9ec8 Filippos Giannakos
                pf.close()
242 2daa9ec8 Filippos Giannakos
            return None
243 2daa9ec8 Filippos Giannakos
244 2daa9ec8 Filippos Giannakos
        return pid
245 2daa9ec8 Filippos Giannakos
246 2daa9ec8 Filippos Giannakos
    def set_cli_options(self):
247 2daa9ec8 Filippos Giannakos
        if self.daemon:
248 2daa9ec8 Filippos Giannakos
            self.cli_opts.append("-d")
249 2daa9ec8 Filippos Giannakos
        if self.nr_ops:
250 2daa9ec8 Filippos Giannakos
            self.cli_opts.append("-n")
251 2daa9ec8 Filippos Giannakos
            self.cli_opts.append(str(self.nr_ops))
252 2daa9ec8 Filippos Giannakos
        if self.logfile:
253 2daa9ec8 Filippos Giannakos
            self.cli_opts.append("-l")
254 2daa9ec8 Filippos Giannakos
            self.cli_opts.append(self.logfile)
255 2daa9ec8 Filippos Giannakos
        if self.pidfile:
256 2daa9ec8 Filippos Giannakos
            self.cli_opts.append("--pidfile")
257 2daa9ec8 Filippos Giannakos
            self.cli_opts.append(self.pidfile)
258 98c5d2e9 Filippos Giannakos
        if self.portno_start is not None:
259 2daa9ec8 Filippos Giannakos
            self.cli_opts.append("-sp")
260 2daa9ec8 Filippos Giannakos
            self.cli_opts.append(str(self.portno_start))
261 98c5d2e9 Filippos Giannakos
        if self.portno_end is not None:
262 2daa9ec8 Filippos Giannakos
            self.cli_opts.append("-ep")
263 2daa9ec8 Filippos Giannakos
            self.cli_opts.append(str(self.portno_end))
264 98c5d2e9 Filippos Giannakos
        if self.log_level is not None:
265 2daa9ec8 Filippos Giannakos
            self.cli_opts.append("-v")
266 2daa9ec8 Filippos Giannakos
            self.cli_opts.append(str(self.log_level))
267 2daa9ec8 Filippos Giannakos
        if self.spec:
268 2daa9ec8 Filippos Giannakos
            self.cli_opts.append("-g")
269 2daa9ec8 Filippos Giannakos
            self.cli_opts.append(self.spec)
270 2daa9ec8 Filippos Giannakos
271 2daa9ec8 Filippos Giannakos
272 2daa9ec8 Filippos Giannakos
class MTpeer(Peer):
273 2daa9ec8 Filippos Giannakos
    def __init__(self, nr_threads=1, **kwargs):
274 2daa9ec8 Filippos Giannakos
        self.nr_threads = nr_threads
275 2daa9ec8 Filippos Giannakos
        super(MTpeer, self).__init__(**kwargs)
276 2daa9ec8 Filippos Giannakos
277 2daa9ec8 Filippos Giannakos
        if self.cli_opts is None:
278 2daa9ec8 Filippos Giannakos
            self.cli_opts = []
279 2daa9ec8 Filippos Giannakos
        self.set_mtcli_options()
280 2daa9ec8 Filippos Giannakos
281 2daa9ec8 Filippos Giannakos
    def set_mtcli_options(self):
282 2daa9ec8 Filippos Giannakos
        self.cli_opts.append("-t")
283 2daa9ec8 Filippos Giannakos
        self.cli_opts.append(str(self.nr_threads))
284 2daa9ec8 Filippos Giannakos
285 2daa9ec8 Filippos Giannakos
286 2daa9ec8 Filippos Giannakos
class Sosd(MTpeer):
287 2daa9ec8 Filippos Giannakos
    def __init__(self, pool=None, **kwargs):
288 2daa9ec8 Filippos Giannakos
        self.executable = RADOS_BLOCKER
289 2daa9ec8 Filippos Giannakos
        self.pool = pool
290 2daa9ec8 Filippos Giannakos
        super(Sosd, self).__init__(**kwargs)
291 2daa9ec8 Filippos Giannakos
292 2daa9ec8 Filippos Giannakos
        if self.cli_opts is None:
293 2daa9ec8 Filippos Giannakos
            self.cli_opts = []
294 2daa9ec8 Filippos Giannakos
        self.set_sosd_cli_options()
295 2daa9ec8 Filippos Giannakos
296 2daa9ec8 Filippos Giannakos
    def set_sosd_cli_options(self):
297 2daa9ec8 Filippos Giannakos
        if self.pool:
298 2daa9ec8 Filippos Giannakos
            self.cli_opts.append("--pool")
299 2daa9ec8 Filippos Giannakos
            self.cli_opts.append(self.pool)
300 2daa9ec8 Filippos Giannakos
301 2daa9ec8 Filippos Giannakos
302 98c5d2e9 Filippos Giannakos
class Filed(MTpeer):
303 98c5d2e9 Filippos Giannakos
    def __init__(self, archip_dir=None, prefix=None, fdcache=None,
304 eab9e442 Filippos Giannakos
                 unique_str=None, nr_threads=1, nr_ops=16, **kwargs):
305 2daa9ec8 Filippos Giannakos
        self.executable = FILE_BLOCKER
306 2daa9ec8 Filippos Giannakos
        self.archip_dir = archip_dir
307 2daa9ec8 Filippos Giannakos
        self.prefix = prefix
308 98c5d2e9 Filippos Giannakos
        self.fdcache = fdcache
309 98c5d2e9 Filippos Giannakos
        self.unique_str = unique_str
310 eab9e442 Filippos Giannakos
        nr_threads = nr_ops
311 eab9e442 Filippos Giannakos
        if self.fdcache and fdcache < 2*nr_threads:
312 eab9e442 Filippos Giannakos
            raise Error("Fdcache should be greater than 2*nr_threads")
313 2daa9ec8 Filippos Giannakos
314 eab9e442 Filippos Giannakos
        super(Filed, self).__init__(nr_threads=nr_threads, nr_ops=nr_ops, **kwargs)
315 2daa9ec8 Filippos Giannakos
316 2daa9ec8 Filippos Giannakos
        if not self.archip_dir:
317 2daa9ec8 Filippos Giannakos
            raise Error("%s: Archip dir must be set" % self.role)
318 2daa9ec8 Filippos Giannakos
        if not os.path.isdir(self.archip_dir):
319 2daa9ec8 Filippos Giannakos
            raise Error("%s: Archip dir invalid" % self.role)
320 98c5d2e9 Filippos Giannakos
        if not self.fdcache:
321 98c5d2e9 Filippos Giannakos
            self.fdcache = 2*self.nr_ops
322 98c5d2e9 Filippos Giannakos
        if not self.unique_str:
323 98c5d2e9 Filippos Giannakos
            self.unique_str = hostname + '_' + str(self.portno_start)
324 2daa9ec8 Filippos Giannakos
325 2daa9ec8 Filippos Giannakos
        if self.cli_opts is None:
326 2daa9ec8 Filippos Giannakos
            self.cli_opts = []
327 98c5d2e9 Filippos Giannakos
        self.set_filed_cli_options()
328 98c5d2e9 Filippos Giannakos
329 98c5d2e9 Filippos Giannakos
    def set_filed_cli_options(self):
330 98c5d2e9 Filippos Giannakos
        if self.unique_str:
331 98c5d2e9 Filippos Giannakos
            self.cli_opts.append("--uniquestr")
332 98c5d2e9 Filippos Giannakos
            self.cli_opts.append(self.unique_str)
333 98c5d2e9 Filippos Giannakos
        if self.fdcache:
334 98c5d2e9 Filippos Giannakos
            self.cli_opts.append("--fdcache")
335 98c5d2e9 Filippos Giannakos
            self.cli_opts.append(str(self.fdcache))
336 2daa9ec8 Filippos Giannakos
        if self.archip_dir:
337 2daa9ec8 Filippos Giannakos
            self.cli_opts.append("--archip")
338 2daa9ec8 Filippos Giannakos
            self.cli_opts.append(self.archip_dir)
339 2daa9ec8 Filippos Giannakos
        if self.prefix:
340 2daa9ec8 Filippos Giannakos
            self.cli_opts.append("--prefix")
341 2daa9ec8 Filippos Giannakos
            self.cli_opts.append(self.prefix)
342 2daa9ec8 Filippos Giannakos
343 2daa9ec8 Filippos Giannakos
344 2daa9ec8 Filippos Giannakos
class Mapperd(Peer):
345 2daa9ec8 Filippos Giannakos
    def __init__(self, blockerm_port=None, blockerb_port=None, **kwargs):
346 2daa9ec8 Filippos Giannakos
        self.executable = MAPPER
347 98c5d2e9 Filippos Giannakos
        if blockerm_port is None:
348 98c5d2e9 Filippos Giannakos
            raise Error("blockerm_port must be provied for %s" % role)
349 2daa9ec8 Filippos Giannakos
        self.blockerm_port = blockerm_port
350 98c5d2e9 Filippos Giannakos
351 98c5d2e9 Filippos Giannakos
        if blockerb_port is None:
352 98c5d2e9 Filippos Giannakos
            raise Error("blockerb_port must be provied for %s" % role)
353 2daa9ec8 Filippos Giannakos
        self.blockerb_port = blockerb_port
354 2daa9ec8 Filippos Giannakos
        super(Mapperd, self).__init__(**kwargs)
355 2daa9ec8 Filippos Giannakos
356 2daa9ec8 Filippos Giannakos
        if self.cli_opts is None:
357 2daa9ec8 Filippos Giannakos
            self.cli_opts = []
358 2daa9ec8 Filippos Giannakos
        self.set_mapperd_cli_options()
359 2daa9ec8 Filippos Giannakos
360 2daa9ec8 Filippos Giannakos
    def set_mapperd_cli_options(self):
361 98c5d2e9 Filippos Giannakos
        if self.blockerm_port is not None:
362 2daa9ec8 Filippos Giannakos
            self.cli_opts.append("-mbp")
363 2daa9ec8 Filippos Giannakos
            self.cli_opts.append(str(self.blockerm_port))
364 98c5d2e9 Filippos Giannakos
        if self.blockerb_port is not None:
365 2daa9ec8 Filippos Giannakos
            self.cli_opts.append("-bp")
366 2daa9ec8 Filippos Giannakos
            self.cli_opts.append(str(self.blockerb_port))
367 2daa9ec8 Filippos Giannakos
368 2daa9ec8 Filippos Giannakos
369 2daa9ec8 Filippos Giannakos
class Vlmcd(Peer):
370 2daa9ec8 Filippos Giannakos
    def __init__(self, blocker_port=None, mapper_port=None, **kwargs):
371 2daa9ec8 Filippos Giannakos
        self.executable = VLMC
372 98c5d2e9 Filippos Giannakos
        if blocker_port is None:
373 98c5d2e9 Filippos Giannakos
            raise Error("blocker_port must be provied for %s" % role)
374 2daa9ec8 Filippos Giannakos
        self.blocker_port = blocker_port
375 98c5d2e9 Filippos Giannakos
376 98c5d2e9 Filippos Giannakos
        if mapper_port is None:
377 98c5d2e9 Filippos Giannakos
            raise Error("mapper_port must be provied for %s" % role)
378 2daa9ec8 Filippos Giannakos
        self.mapper_port = mapper_port
379 2daa9ec8 Filippos Giannakos
        super(Vlmcd, self).__init__(**kwargs)
380 2daa9ec8 Filippos Giannakos
381 2daa9ec8 Filippos Giannakos
        if self.cli_opts is None:
382 2daa9ec8 Filippos Giannakos
            self.cli_opts = []
383 2daa9ec8 Filippos Giannakos
        self.set_vlmcd_cli_opts()
384 2daa9ec8 Filippos Giannakos
385 2daa9ec8 Filippos Giannakos
    def set_vlmcd_cli_opts(self):
386 98c5d2e9 Filippos Giannakos
        if self.blocker_port is not None:
387 2daa9ec8 Filippos Giannakos
            self.cli_opts.append("-bp")
388 2daa9ec8 Filippos Giannakos
            self.cli_opts.append(str(self.blocker_port))
389 98c5d2e9 Filippos Giannakos
        if self.mapper_port is not None:
390 2daa9ec8 Filippos Giannakos
            self.cli_opts.append("-mp")
391 2daa9ec8 Filippos Giannakos
            self.cli_opts.append(str(self.mapper_port))
392 979bf615 Filippos Giannakos
393 979bf615 Filippos Giannakos
394 7bac0881 Filippos Giannakos
config = {
395 1075ead7 Filippos Giannakos
    'CEPH_CONF_FILE': '/etc/ceph/ceph.conf',
396 e7b7dd84 Filippos Giannakos
#    'SPEC': "segdev:xsegbd:1024:5120:12",
397 e7b7dd84 Filippos Giannakos
    'SEGMENT_TYPE': 'segdev',
398 e7b7dd84 Filippos Giannakos
    'SEGMENT_NAME': 'xsegbd',
399 e7b7dd84 Filippos Giannakos
    'SEGMENT_PORTS': 1024,
400 e7b7dd84 Filippos Giannakos
    'SEGMENT_SIZE': 5120,
401 e7b7dd84 Filippos Giannakos
    'SEGMENT_ALIGNMENT': 12,
402 1075ead7 Filippos Giannakos
    'XSEGBD_START': 0,
403 1075ead7 Filippos Giannakos
    'XSEGBD_END': 499,
404 47ef236d Filippos Giannakos
    'VTOOL_START': 1003,
405 47ef236d Filippos Giannakos
    'VTOOL_END': 1003,
406 1075ead7 Filippos Giannakos
    #RESERVED 1023
407 7bac0881 Filippos Giannakos
}
408 979bf615 Filippos Giannakos
409 979bf615 Filippos Giannakos
FIRST_COLUMN_WIDTH = 23
410 979bf615 Filippos Giannakos
SECOND_COLUMN_WIDTH = 23
411 979bf615 Filippos Giannakos
412 1075ead7 Filippos Giannakos
413 979bf615 Filippos Giannakos
def green(s):
414 979bf615 Filippos Giannakos
    return '\x1b[32m' + str(s) + '\x1b[0m'
415 979bf615 Filippos Giannakos
416 1075ead7 Filippos Giannakos
417 979bf615 Filippos Giannakos
def red(s):
418 979bf615 Filippos Giannakos
    return '\x1b[31m' + str(s) + '\x1b[0m'
419 979bf615 Filippos Giannakos
420 1075ead7 Filippos Giannakos
421 979bf615 Filippos Giannakos
def yellow(s):
422 979bf615 Filippos Giannakos
    return '\x1b[33m' + str(s) + '\x1b[0m'
423 979bf615 Filippos Giannakos
424 1075ead7 Filippos Giannakos
425 979bf615 Filippos Giannakos
def pretty_print(cid, status):
426 979bf615 Filippos Giannakos
    sys.stdout.write(cid.ljust(FIRST_COLUMN_WIDTH))
427 979bf615 Filippos Giannakos
    sys.stdout.write(status.ljust(SECOND_COLUMN_WIDTH))
428 979bf615 Filippos Giannakos
    sys.stdout.write('\n')
429 979bf615 Filippos Giannakos
    return
430 979bf615 Filippos Giannakos
431 1075ead7 Filippos Giannakos
432 979bf615 Filippos Giannakos
class Error(Exception):
433 979bf615 Filippos Giannakos
    def __init__(self, msg):
434 979bf615 Filippos Giannakos
        self.msg = msg
435 979bf615 Filippos Giannakos
436 979bf615 Filippos Giannakos
    def __str__(self):
437 979bf615 Filippos Giannakos
        return self.msg
438 979bf615 Filippos Giannakos
439 e7b7dd84 Filippos Giannakos
class Segment(object):
440 e7b7dd84 Filippos Giannakos
    type = 'segdev'
441 e7b7dd84 Filippos Giannakos
    name = 'xsegbd'
442 e7b7dd84 Filippos Giannakos
    ports = 1024
443 e7b7dd84 Filippos Giannakos
    size = 5120
444 e7b7dd84 Filippos Giannakos
    alignment = 12
445 e7b7dd84 Filippos Giannakos
446 e7b7dd84 Filippos Giannakos
    spec = None
447 e7b7dd84 Filippos Giannakos
448 e7b7dd84 Filippos Giannakos
    def __init__(self, type, name, ports, size, align=12):
449 e7b7dd84 Filippos Giannakos
        initialize_xseg()
450 e7b7dd84 Filippos Giannakos
        self.type = type
451 e7b7dd84 Filippos Giannakos
        self.name = name
452 e7b7dd84 Filippos Giannakos
        self.ports = ports
453 e7b7dd84 Filippos Giannakos
        self.size = size
454 e7b7dd84 Filippos Giannakos
        self.alignment = align
455 e7b7dd84 Filippos Giannakos
456 e7b7dd84 Filippos Giannakos
        if self.type not in valid_segment_types:
457 e7b7dd84 Filippos Giannakos
            raise Error("Segment type not valid")
458 e7b7dd84 Filippos Giannakos
        if self.alignment != 12:
459 e7b7dd84 Filippos Giannakos
            raise Error("Wrong alignemt")
460 e7b7dd84 Filippos Giannakos
461 e7b7dd84 Filippos Giannakos
        self.spec = self.get_spec()
462 e7b7dd84 Filippos Giannakos
463 e7b7dd84 Filippos Giannakos
    def get_spec(self):
464 e7b7dd84 Filippos Giannakos
        if not self.spec:
465 abf5c316 Filippos Giannakos
            params = [self.type, self.name, str(self.ports), str(self.size),
466 abf5c316 Filippos Giannakos
                      str(self.alignment)]
467 e7b7dd84 Filippos Giannakos
            self.spec = ':'.join(params).encode()
468 e7b7dd84 Filippos Giannakos
        return self.spec
469 e7b7dd84 Filippos Giannakos
470 e7b7dd84 Filippos Giannakos
    def create(self):
471 e7b7dd84 Filippos Giannakos
        #fixme blocking....
472 e7b7dd84 Filippos Giannakos
        xconf = xseg_config()
473 e7b7dd84 Filippos Giannakos
        c_spec = create_string_buffer(self.spec)
474 e7b7dd84 Filippos Giannakos
        xseg_parse_spec(c_spec, xconf)
475 e7b7dd84 Filippos Giannakos
        r = xseg_create(xconf)
476 e7b7dd84 Filippos Giannakos
        if r < 0:
477 e7b7dd84 Filippos Giannakos
            raise Error("Cannot create segment")
478 e7b7dd84 Filippos Giannakos
479 e7b7dd84 Filippos Giannakos
    def destroy(self):
480 e7b7dd84 Filippos Giannakos
        #fixme blocking....
481 e7b7dd84 Filippos Giannakos
        try:
482 e7b7dd84 Filippos Giannakos
            xseg = self.join()
483 e7b7dd84 Filippos Giannakos
            xseg_leave(xseg)
484 e7b7dd84 Filippos Giannakos
            xseg_destroy(xseg)
485 e7b7dd84 Filippos Giannakos
        except Exception:
486 e7b7dd84 Filippos Giannakos
            raise Error("Cannot destroy segment")
487 e7b7dd84 Filippos Giannakos
488 e7b7dd84 Filippos Giannakos
    def join(self):
489 e7b7dd84 Filippos Giannakos
        xconf = xseg_config()
490 e7b7dd84 Filippos Giannakos
        spec_buf = create_string_buffer(self.spec)
491 e7b7dd84 Filippos Giannakos
        xseg_parse_spec(spec_buf, xconf)
492 b0ef21ea Filippos Giannakos
        ctx = xseg_join(xconf.type, xconf.name, "posixfd",
493 e7b7dd84 Filippos Giannakos
                        cast(0, cb_null_ptrtype))
494 e7b7dd84 Filippos Giannakos
        if not ctx:
495 e7b7dd84 Filippos Giannakos
            raise Error("Cannot join segment")
496 e7b7dd84 Filippos Giannakos
497 e7b7dd84 Filippos Giannakos
        return ctx
498 1075ead7 Filippos Giannakos
499 979bf615 Filippos Giannakos
def check_conf():
500 2daa9ec8 Filippos Giannakos
    port_ranges = []
501 2daa9ec8 Filippos Giannakos
502 979bf615 Filippos Giannakos
    def isExec(file_path):
503 979bf615 Filippos Giannakos
        return os.path.isfile(file_path) and os.access(file_path, os.X_OK)
504 979bf615 Filippos Giannakos
505 979bf615 Filippos Giannakos
    def validExec(program):
506 979bf615 Filippos Giannakos
        for path in os.environ["PATH"].split(os.pathsep):
507 979bf615 Filippos Giannakos
            exe_file = os.path.join(path, program)
508 979bf615 Filippos Giannakos
            if isExec(exe_file):
509 979bf615 Filippos Giannakos
                return True
510 979bf615 Filippos Giannakos
        return False
511 979bf615 Filippos Giannakos
512 2daa9ec8 Filippos Giannakos
    def validatePort(portno, limit):
513 2daa9ec8 Filippos Giannakos
        if portno >= limit:
514 2daa9ec8 Filippos Giannakos
            raise Error("Portno %d out of range" % portno)
515 2daa9ec8 Filippos Giannakos
516 2daa9ec8 Filippos Giannakos
    def validatePortRange(portno_start, portno_end, limit):
517 2daa9ec8 Filippos Giannakos
        validatePort(portno_start, limit)
518 2daa9ec8 Filippos Giannakos
        validatePort(portno_end, limit)
519 2daa9ec8 Filippos Giannakos
        if portno_start > portno_end:
520 2daa9ec8 Filippos Giannakos
            raise Error("Portno_start > Portno_end: %d > %d " %
521 2daa9ec8 Filippos Giannakos
                        (portno_start, portno_end))
522 2daa9ec8 Filippos Giannakos
        for start, end in port_ranges:
523 2daa9ec8 Filippos Giannakos
            if not (portno_end < start or portno_start > end):
524 2daa9ec8 Filippos Giannakos
                raise Error("Port range conflict: (%d, %d) confilcts with (%d, %d)" %
525 2daa9ec8 Filippos Giannakos
                            (portno_start, portno_end,  start, end))
526 2daa9ec8 Filippos Giannakos
        port_ranges.append((portno_start, portno_end))
527 979bf615 Filippos Giannakos
528 e7b7dd84 Filippos Giannakos
    xseg_type = config['SEGMENT_TYPE']
529 e7b7dd84 Filippos Giannakos
    xseg_name = config['SEGMENT_NAME']
530 e7b7dd84 Filippos Giannakos
    xseg_ports = config['SEGMENT_PORTS']
531 e7b7dd84 Filippos Giannakos
    xseg_size = config['SEGMENT_SIZE']
532 e7b7dd84 Filippos Giannakos
    xseg_align = config['SEGMENT_ALIGNMENT']
533 979bf615 Filippos Giannakos
534 e7b7dd84 Filippos Giannakos
    global segment
535 e7b7dd84 Filippos Giannakos
    segment = Segment(xseg_type, xseg_name, xseg_ports, xseg_size, xseg_align)
536 979bf615 Filippos Giannakos
537 979bf615 Filippos Giannakos
538 2daa9ec8 Filippos Giannakos
    try:
539 2daa9ec8 Filippos Giannakos
        if not config['roles']:
540 2daa9ec8 Filippos Giannakos
            raise Error("Roles setup must be provided")
541 2daa9ec8 Filippos Giannakos
    except KeyError:
542 2daa9ec8 Filippos Giannakos
        raise Error("Roles setup must be provided")
543 2daa9ec8 Filippos Giannakos
544 2daa9ec8 Filippos Giannakos
    for role, role_type in config['roles']:
545 2daa9ec8 Filippos Giannakos
        if role_type not in valid_role_types:
546 2daa9ec8 Filippos Giannakos
            raise Error("%s is not a valid role" % role_type)
547 1075ead7 Filippos Giannakos
        try:
548 2daa9ec8 Filippos Giannakos
            role_config = config[role]
549 1075ead7 Filippos Giannakos
        except:
550 2daa9ec8 Filippos Giannakos
            raise Error("No config found for %s" % role)
551 2daa9ec8 Filippos Giannakos
552 2daa9ec8 Filippos Giannakos
        if role_type == 'file_blocker':
553 e7b7dd84 Filippos Giannakos
            peers[role] = Filed(role=role, spec=segment.get_spec(),
554 2daa9ec8 Filippos Giannakos
                                 prefix=ARCHIP_PREFIX, **role_config)
555 2daa9ec8 Filippos Giannakos
        elif role_type == 'rados_blocker':
556 e7b7dd84 Filippos Giannakos
            peers[role] = Sosd(role=role, spec=segment.get_spec(),
557 2daa9ec8 Filippos Giannakos
                               **role_config)
558 2daa9ec8 Filippos Giannakos
        elif role_type == 'mapperd':
559 e7b7dd84 Filippos Giannakos
            peers[role] = Mapperd(role=role, spec=segment.get_spec(),
560 2daa9ec8 Filippos Giannakos
                                  **role_config)
561 2daa9ec8 Filippos Giannakos
        elif role_type == 'vlmcd':
562 e7b7dd84 Filippos Giannakos
            peers[role] = Vlmcd(role=role, spec=segment.get_spec(),
563 2daa9ec8 Filippos Giannakos
                                **role_config)
564 2daa9ec8 Filippos Giannakos
        else:
565 2daa9ec8 Filippos Giannakos
            raise Error("No valid peer type: %s" % role_type)
566 2daa9ec8 Filippos Giannakos
        validatePortRange(peers[role].portno_start, peers[role].portno_end,
567 2daa9ec8 Filippos Giannakos
                          xseg_ports)
568 979bf615 Filippos Giannakos
569 47ef236d Filippos Giannakos
    validatePortRange(config['VTOOL_START'], config['VTOOL_END'], xseg_ports)
570 2daa9ec8 Filippos Giannakos
    validatePortRange(config['XSEGBD_START'], config['XSEGBD_END'],
571 2daa9ec8 Filippos Giannakos
                      xseg_ports)
572 e7b7dd84 Filippos Giannakos
573 e7b7dd84 Filippos Giannakos
    xsegbd_range = config['XSEGBD_END'] - config['XSEGBD_START']
574 abf5c316 Filippos Giannakos
    vlmcd_range = peers['vlmcd'].portno_end - peers['vlmcd'].portno_start
575 e7b7dd84 Filippos Giannakos
    if xsegbd_range > vlmcd_range:
576 e7b7dd84 Filippos Giannakos
        raise Error("Xsegbd port range must be smaller that vlmcd port range")
577 979bf615 Filippos Giannakos
    return True
578 979bf615 Filippos Giannakos
579 abf5c316 Filippos Giannakos
def get_segment():
580 abf5c316 Filippos Giannakos
    return segment
581 1075ead7 Filippos Giannakos
582 979bf615 Filippos Giannakos
def construct_peers():
583 979bf615 Filippos Giannakos
    return peers
584 979bf615 Filippos Giannakos
585 47ef236d Filippos Giannakos
vtool_port = None
586 8dec25eb Filippos Giannakos
def get_vtool_port():
587 47ef236d Filippos Giannakos
    global vtool_port
588 47ef236d Filippos Giannakos
    if vtool_port is None:
589 47ef236d Filippos Giannakos
        vtool_port = random.randint(config['VTOOL_START'], config['VTOOL_END'])
590 47ef236d Filippos Giannakos
    return vtool_port
591 8b692198 Filippos Giannakos
592 e924e6a4 Filippos Giannakos
acquired_locks = {}
593 e924e6a4 Filippos Giannakos
594 e924e6a4 Filippos Giannakos
def get_lock(lock_file):
595 e924e6a4 Filippos Giannakos
    while True:
596 e924e6a4 Filippos Giannakos
        try:
597 e924e6a4 Filippos Giannakos
            fd = os.open(lock_file, os.O_CREAT | os.O_EXCL | os.O_WRONLY)
598 e924e6a4 Filippos Giannakos
            break
599 e924e6a4 Filippos Giannakos
        except OSError, (err, reason):
600 e924e6a4 Filippos Giannakos
            print >> sys.stderr, lock_file, reason
601 e924e6a4 Filippos Giannakos
            if err == errno.EEXIST:
602 e924e6a4 Filippos Giannakos
                time.sleep(0.2)
603 e924e6a4 Filippos Giannakos
            else:
604 e924e6a4 Filippos Giannakos
                raise OSError(err, lock_file + ' ' + reason)
605 e924e6a4 Filippos Giannakos
    return fd
606 e924e6a4 Filippos Giannakos
607 8b692198 Filippos Giannakos
def exclusive(get_port=False):
608 47ef236d Filippos Giannakos
    def wrap(fn):
609 8b692198 Filippos Giannakos
        def lock(*args, **kwargs):
610 8b692198 Filippos Giannakos
            if not os.path.exists(LOCK_PATH):
611 8b692198 Filippos Giannakos
                try:
612 8b692198 Filippos Giannakos
                    os.mkdir(LOCK_PATH)
613 8b692198 Filippos Giannakos
                except OSError, (err, reason):
614 8b692198 Filippos Giannakos
                    print >> sys.stderr, reason
615 8b692198 Filippos Giannakos
616 8b692198 Filippos Giannakos
            if not os.path.isdir(LOCK_PATH):
617 8b692198 Filippos Giannakos
                raise Error("Locking error: %s is not a directory" % LOCK_PATH)
618 8b692198 Filippos Giannakos
619 47ef236d Filippos Giannakos
            if get_port:
620 8dec25eb Filippos Giannakos
                vtool_port = get_vtool_port()
621 47ef236d Filippos Giannakos
                lock_file = os.path.join(LOCK_PATH, VLMC_LOCK_FILE + '_' + str(vtool_port))
622 8b692198 Filippos Giannakos
            else:
623 8b692198 Filippos Giannakos
                lock_file = os.path.join(LOCK_PATH, VLMC_LOCK_FILE)
624 e924e6a4 Filippos Giannakos
            try:
625 e924e6a4 Filippos Giannakos
                depth = acquired_locks[lock_file]
626 e924e6a4 Filippos Giannakos
                if depth == 0:
627 e924e6a4 Filippos Giannakos
                    fd = get_lock(lock_file)
628 e924e6a4 Filippos Giannakos
            except KeyError:
629 e924e6a4 Filippos Giannakos
                acquired_locks[lock_file] = 0
630 e924e6a4 Filippos Giannakos
                fd = get_lock(lock_file)
631 e924e6a4 Filippos Giannakos
632 e924e6a4 Filippos Giannakos
            acquired_locks[lock_file] += 1
633 979bf615 Filippos Giannakos
            try:
634 abf5c316 Filippos Giannakos
                r = fn(*args, **kwargs)
635 8b692198 Filippos Giannakos
            finally:
636 e924e6a4 Filippos Giannakos
                acquired_locks[lock_file] -= 1
637 e924e6a4 Filippos Giannakos
                depth = acquired_locks[lock_file]
638 e924e6a4 Filippos Giannakos
                if depth == 0:
639 e924e6a4 Filippos Giannakos
                    os.close(fd)
640 e924e6a4 Filippos Giannakos
                    os.unlink(lock_file)
641 8b692198 Filippos Giannakos
            return r
642 8b692198 Filippos Giannakos
643 8b692198 Filippos Giannakos
        return lock
644 8b692198 Filippos Giannakos
    return wrap
645 1075ead7 Filippos Giannakos
646 8ade203a Chrysostomos Nanakos
def createBDict(cfg, section):
647 8ade203a Chrysostomos Nanakos
        sec_dic = {}
648 8ade203a Chrysostomos Nanakos
        sec_dic['portno_start'] = cfg.getint(section, 'portno_start')
649 8ade203a Chrysostomos Nanakos
        sec_dic['portno_end'] = cfg.getint(section, 'portno_end')
650 8ade203a Chrysostomos Nanakos
        sec_dic['log_level'] = cfg.getint(section, 'log_level')
651 8ade203a Chrysostomos Nanakos
        sec_dic['nr_ops'] = cfg.getint(section, 'nr_ops')
652 8ade203a Chrysostomos Nanakos
        try:
653 8ade203a Chrysostomos Nanakos
                sec_dic['nr_threads'] = cfg.getint(section, 'nr_threads')
654 8ade203a Chrysostomos Nanakos
                sec_dic['archip_dir'] = cfg.get(section, 'archip_dir')
655 8ade203a Chrysostomos Nanakos
                sec_dic['fdcache'] = cfg.getint(section, 'fdcache')
656 8ade203a Chrysostomos Nanakos
        except:
657 8ade203a Chrysostomos Nanakos
                sec_dic['pool'] = cfg.get(section, 'pool')
658 8ade203a Chrysostomos Nanakos
        return sec_dic
659 8ade203a Chrysostomos Nanakos
660 8ade203a Chrysostomos Nanakos
def createMDict(cfg, section):
661 8ade203a Chrysostomos Nanakos
        sec_dic = {}
662 8ade203a Chrysostomos Nanakos
        sec_dic['portno_start'] = cfg.getint(section, 'portno_start')
663 8ade203a Chrysostomos Nanakos
        sec_dic['portno_end'] = cfg.getint(section, 'portno_end')
664 8ade203a Chrysostomos Nanakos
        sec_dic['log_level'] = cfg.getint(section, 'log_level')
665 8ade203a Chrysostomos Nanakos
        sec_dic['nr_ops'] = cfg.getint(section, 'nr_ops')
666 8ade203a Chrysostomos Nanakos
        sec_dic['blockerb_port'] = cfg.getint(section, 'blockerb_port')
667 8ade203a Chrysostomos Nanakos
        sec_dic['blockerm_port'] = cfg.getint(section, 'blockerm_port')
668 8ade203a Chrysostomos Nanakos
        return sec_dic
669 8ade203a Chrysostomos Nanakos
670 8ade203a Chrysostomos Nanakos
def createVDict(cfg, section):
671 8ade203a Chrysostomos Nanakos
        sec_dic = {}
672 8ade203a Chrysostomos Nanakos
        sec_dic['portno_start'] = cfg.getint(section, 'portno_start')
673 8ade203a Chrysostomos Nanakos
        sec_dic['portno_end'] = cfg.getint(section, 'portno_end')
674 8ade203a Chrysostomos Nanakos
        sec_dic['log_level'] = cfg.getint(section, 'log_level')
675 8ade203a Chrysostomos Nanakos
        sec_dic['nr_ops'] = cfg.getint(section, 'nr_ops')
676 8ade203a Chrysostomos Nanakos
        sec_dic['blocker_port'] = cfg.getint(section, 'blocker_port')
677 8ade203a Chrysostomos Nanakos
        sec_dic['mapper_port'] = cfg.getint(section, 'mapper_port')
678 8ade203a Chrysostomos Nanakos
        return sec_dic
679 8ade203a Chrysostomos Nanakos
680 8ade203a Chrysostomos Nanakos
681 979bf615 Filippos Giannakos
def loadrc(rc):
682 979bf615 Filippos Giannakos
    try:
683 1075ead7 Filippos Giannakos
        if rc is None:
684 8ade203a Chrysostomos Nanakos
            cfg_dir = os.path.expanduser(DEFAULTS)
685 979bf615 Filippos Giannakos
        else:
686 8ade203a Chrysostomos Nanakos
            cfg_dir = rc
687 8ade203a Chrysostomos Nanakos
        cfg_fd = open(cfg_dir)
688 979bf615 Filippos Giannakos
    except:
689 979bf615 Filippos Giannakos
        raise Error("Cannot read config file")
690 979bf615 Filippos Giannakos
691 8ade203a Chrysostomos Nanakos
    cfg = ConfigParser.ConfigParser()
692 8ade203a Chrysostomos Nanakos
    cfg.readfp(cfg_fd)
693 8ade203a Chrysostomos Nanakos
    config['SEGMENT_PORTS'] = cfg.getint('XSEG','SEGMENT_PORTS')
694 8ade203a Chrysostomos Nanakos
    config['SEGMENT_SIZE'] = cfg.getint('XSEG','SEGMENT_SIZE')
695 8ade203a Chrysostomos Nanakos
    config['XSEGBD_START'] = cfg.getint('XSEG','XSEGBD_START')
696 8ade203a Chrysostomos Nanakos
    config['XSEGBD_END'] = cfg.getint('XSEG','XSEGBD_END')
697 8ade203a Chrysostomos Nanakos
    config['VTOOL_START'] = cfg.getint('XSEG','VTOOL_START')
698 8ade203a Chrysostomos Nanakos
    config['VTOOL_END'] = cfg.getint('XSEG','VTOOL_END')
699 8ade203a Chrysostomos Nanakos
    config['roles'] = eval(cfg.get('ROLES','order'))
700 8ade203a Chrysostomos Nanakos
    config['blockerb'] = createBDict(cfg, 'BLOCKERB')
701 8ade203a Chrysostomos Nanakos
    config['blockerm'] = createBDict(cfg, 'BLOCKERM')
702 8ade203a Chrysostomos Nanakos
    config['mapperd'] = createMDict(cfg, 'MAPPERD')
703 8ade203a Chrysostomos Nanakos
    config['vlmcd'] = createVDict(cfg, 'VLMCD')
704 8ade203a Chrysostomos Nanakos
705 979bf615 Filippos Giannakos
    if not check_conf():
706 979bf615 Filippos Giannakos
        raise Error("Invalid conf file")
707 979bf615 Filippos Giannakos
708 1075ead7 Filippos Giannakos
709 979bf615 Filippos Giannakos
def loaded_modules():
710 979bf615 Filippos Giannakos
    lines = open("/proc/modules").read().split("\n")
711 979bf615 Filippos Giannakos
    modules = [f.split(" ")[0] for f in lines]
712 979bf615 Filippos Giannakos
    return modules
713 979bf615 Filippos Giannakos
714 1075ead7 Filippos Giannakos
715 979bf615 Filippos Giannakos
def loaded_module(name):
716 979bf615 Filippos Giannakos
    return name in loaded_modules()
717 979bf615 Filippos Giannakos
718 1075ead7 Filippos Giannakos
719 979bf615 Filippos Giannakos
def load_module(name, args):
720 979bf615 Filippos Giannakos
    s = "Loading %s " % name
721 979bf615 Filippos Giannakos
    sys.stdout.write(s.ljust(FIRST_COLUMN_WIDTH))
722 979bf615 Filippos Giannakos
    modules = loaded_modules()
723 979bf615 Filippos Giannakos
    if name in modules:
724 979bf615 Filippos Giannakos
        sys.stdout.write(yellow("Already loaded".ljust(SECOND_COLUMN_WIDTH)))
725 979bf615 Filippos Giannakos
        sys.stdout.write("\n")
726 979bf615 Filippos Giannakos
        return
727 979bf615 Filippos Giannakos
    cmd = ["modprobe", "%s" % name]
728 979bf615 Filippos Giannakos
    if args:
729 979bf615 Filippos Giannakos
        for arg in args:
730 979bf615 Filippos Giannakos
            cmd.extend(["%s=%s" % (arg)])
731 979bf615 Filippos Giannakos
    try:
732 1075ead7 Filippos Giannakos
        check_call(cmd, shell=False)
733 979bf615 Filippos Giannakos
    except Exception:
734 979bf615 Filippos Giannakos
        sys.stdout.write(red("FAILED".ljust(SECOND_COLUMN_WIDTH)))
735 979bf615 Filippos Giannakos
        sys.stdout.write("\n")
736 1075ead7 Filippos Giannakos
        raise Error("Cannot load module %s. Check system logs" % name)
737 979bf615 Filippos Giannakos
    sys.stdout.write(green("OK".ljust(SECOND_COLUMN_WIDTH)))
738 979bf615 Filippos Giannakos
    sys.stdout.write("\n")
739 979bf615 Filippos Giannakos
740 1075ead7 Filippos Giannakos
741 979bf615 Filippos Giannakos
def unload_module(name):
742 979bf615 Filippos Giannakos
    s = "Unloading %s " % name
743 979bf615 Filippos Giannakos
    sys.stdout.write(s.ljust(FIRST_COLUMN_WIDTH))
744 979bf615 Filippos Giannakos
    modules = loaded_modules()
745 979bf615 Filippos Giannakos
    if name not in modules:
746 979bf615 Filippos Giannakos
        sys.stdout.write(yellow("Not loaded".ljust(SECOND_COLUMN_WIDTH)))
747 979bf615 Filippos Giannakos
        sys.stdout.write("\n")
748 979bf615 Filippos Giannakos
        return
749 979bf615 Filippos Giannakos
    cmd = ["modprobe -r %s" % name]
750 979bf615 Filippos Giannakos
    try:
751 1075ead7 Filippos Giannakos
        check_call(cmd, shell=True)
752 979bf615 Filippos Giannakos
    except Exception:
753 979bf615 Filippos Giannakos
        sys.stdout.write(red("FAILED".ljust(SECOND_COLUMN_WIDTH)))
754 979bf615 Filippos Giannakos
        sys.stdout.write("\n")
755 1075ead7 Filippos Giannakos
        raise Error("Cannot unload module %s. Check system logs" % name)
756 979bf615 Filippos Giannakos
    sys.stdout.write(green("OK".ljust(SECOND_COLUMN_WIDTH)))
757 979bf615 Filippos Giannakos
    sys.stdout.write("\n")
758 979bf615 Filippos Giannakos
759 979bf615 Filippos Giannakos
xseg_initialized = False
760 979bf615 Filippos Giannakos
761 1075ead7 Filippos Giannakos
762 979bf615 Filippos Giannakos
def initialize_xseg():
763 979bf615 Filippos Giannakos
    global xseg_initialized
764 b45a87cb Filippos Giannakos
    if not xseg_initialized:
765 b45a87cb Filippos Giannakos
        xseg_initialize()
766 b45a87cb Filippos Giannakos
        xseg_initialized = True
767 979bf615 Filippos Giannakos
768 1075ead7 Filippos Giannakos
769 1075ead7 Filippos Giannakos
def check_running(name, pid=None):
770 979bf615 Filippos Giannakos
    for p in psutil.process_iter():
771 b62308c0 Filippos Giannakos
        if p.name[0:len(name)] == name:
772 979bf615 Filippos Giannakos
            if pid:
773 979bf615 Filippos Giannakos
                if pid == p.pid:
774 979bf615 Filippos Giannakos
                    return pid
775 979bf615 Filippos Giannakos
            else:
776 979bf615 Filippos Giannakos
                return pid
777 979bf615 Filippos Giannakos
    return None
778 979bf615 Filippos Giannakos
779 1075ead7 Filippos Giannakos
780 979bf615 Filippos Giannakos
def check_pidfile(name):
781 979bf615 Filippos Giannakos
    pidfile = os.path.join(PIDFILE_PATH, name + PID_SUFFIX)
782 979bf615 Filippos Giannakos
    pf = None
783 979bf615 Filippos Giannakos
    try:
784 979bf615 Filippos Giannakos
        pf = open(pidfile, "r")
785 979bf615 Filippos Giannakos
        pid = int(pf.read())
786 979bf615 Filippos Giannakos
        pf.close()
787 979bf615 Filippos Giannakos
    except:
788 979bf615 Filippos Giannakos
        if pf:
789 979bf615 Filippos Giannakos
            pf.close()
790 1075ead7 Filippos Giannakos
        return -1
791 979bf615 Filippos Giannakos
792 979bf615 Filippos Giannakos
    return pid
793 979bf615 Filippos Giannakos
794 979bf615 Filippos Giannakos
class Xseg_ctx(object):
795 979bf615 Filippos Giannakos
    ctx = None
796 979bf615 Filippos Giannakos
    port = None
797 979bf615 Filippos Giannakos
    portno = None
798 b0ef21ea Filippos Giannakos
    signal_desc = None
799 979bf615 Filippos Giannakos
800 e7b7dd84 Filippos Giannakos
    def __init__(self, segment, portno):
801 e7b7dd84 Filippos Giannakos
        ctx = segment.join()
802 979bf615 Filippos Giannakos
        if not ctx:
803 979bf615 Filippos Giannakos
            raise Error("Cannot join segment")
804 979bf615 Filippos Giannakos
        port = xseg_bind_port(ctx, portno, c_void_p(0))
805 979bf615 Filippos Giannakos
        if not port:
806 979bf615 Filippos Giannakos
            raise Error("Cannot bind to port")
807 b0ef21ea Filippos Giannakos
        sd = xseg_get_signal_desc_nonstatic(ctx, port)
808 b0ef21ea Filippos Giannakos
        if not sd:
809 b0ef21ea Filippos Giannakos
            raise Error("Cannot get signal descriptor")
810 979bf615 Filippos Giannakos
        xseg_init_local_signal(ctx, portno)
811 979bf615 Filippos Giannakos
        self.ctx = ctx
812 979bf615 Filippos Giannakos
        self.port = port
813 979bf615 Filippos Giannakos
        self.portno = portno
814 b0ef21ea Filippos Giannakos
        self.signal_desc = sd
815 979bf615 Filippos Giannakos
816 979bf615 Filippos Giannakos
    def __del__(self):
817 979bf615 Filippos Giannakos
        return
818 979bf615 Filippos Giannakos
819 979bf615 Filippos Giannakos
    def __enter__(self):
820 979bf615 Filippos Giannakos
        if not self.ctx:
821 979bf615 Filippos Giannakos
            raise Error("No segment")
822 979bf615 Filippos Giannakos
        return self
823 979bf615 Filippos Giannakos
824 979bf615 Filippos Giannakos
    def __exit__(self, type_, value, traceback):
825 979bf615 Filippos Giannakos
        self.shutdown()
826 979bf615 Filippos Giannakos
        return False
827 979bf615 Filippos Giannakos
828 979bf615 Filippos Giannakos
    def shutdown(self):
829 979bf615 Filippos Giannakos
        if self.ctx:
830 e0192e9f Filippos Giannakos
        #    xseg_quit_local_signal(self.ctx, self.portno)
831 979bf615 Filippos Giannakos
            xseg_leave(self.ctx)
832 979bf615 Filippos Giannakos
        self.ctx = None
833 979bf615 Filippos Giannakos
834 e0192e9f Filippos Giannakos
    def wait_request(self):
835 b0ef21ea Filippos Giannakos
        xseg_prepare_wait(self.ctx, self.portno)
836 e0192e9f Filippos Giannakos
        while True:
837 e0192e9f Filippos Giannakos
            received = xseg_receive(self.ctx, self.portno, 0)
838 e0192e9f Filippos Giannakos
            if received:
839 b0ef21ea Filippos Giannakos
                xseg_cancel_wait(self.ctx, self.portno)
840 e0192e9f Filippos Giannakos
                return received
841 e0192e9f Filippos Giannakos
            else:
842 b0ef21ea Filippos Giannakos
                xseg_wait_signal_green(self.ctx, self.signal_desc, 10000000)
843 e0192e9f Filippos Giannakos
844 e0192e9f Filippos Giannakos
    def wait_requests(self, requests):
845 e0192e9f Filippos Giannakos
        while True:
846 e0192e9f Filippos Giannakos
            received = self.wait_request()
847 e0192e9f Filippos Giannakos
            for req in requests:
848 e0192e9f Filippos Giannakos
                xseg_req = req.req
849 e0192e9f Filippos Giannakos
                if addressof(received.contents) == \
850 e0192e9f Filippos Giannakos
                            addressof(xseg_req.contents):
851 e0192e9f Filippos Giannakos
                    return req
852 e0192e9f Filippos Giannakos
            p = xseg_respond(self.ctx, received, self.portno, X_ALLOC)
853 e0192e9f Filippos Giannakos
            if p == NoPort:
854 e0192e9f Filippos Giannakos
                xseg_put_request(self.ctx, received, self.portno)
855 e0192e9f Filippos Giannakos
            else:
856 e0192e9f Filippos Giannakos
                xseg_signal(self.ctx, p)
857 e0192e9f Filippos Giannakos
858 1075ead7 Filippos Giannakos
859 979bf615 Filippos Giannakos
class Request(object):
860 979bf615 Filippos Giannakos
    xseg_ctx = None
861 979bf615 Filippos Giannakos
    req = None
862 979bf615 Filippos Giannakos
863 e0192e9f Filippos Giannakos
    def __init__(self, xseg_ctx, dst_portno, target, datalen=0, size=0, op=None,
864 e0192e9f Filippos Giannakos
                 data=None, flags=0, offset=0):
865 e0192e9f Filippos Giannakos
        if not target:
866 e0192e9f Filippos Giannakos
            raise Error("No target")
867 e0192e9f Filippos Giannakos
        targetlen = len(target)
868 e0192e9f Filippos Giannakos
        if not datalen and data:
869 e0192e9f Filippos Giannakos
            if isinstance(data, basestring):
870 e0192e9f Filippos Giannakos
                datalen = len(data)
871 e0192e9f Filippos Giannakos
            else:
872 e0192e9f Filippos Giannakos
                datalen = sizeof(data)
873 e0192e9f Filippos Giannakos
874 979bf615 Filippos Giannakos
        ctx = xseg_ctx.ctx
875 979bf615 Filippos Giannakos
        if not ctx:
876 979bf615 Filippos Giannakos
            raise Error("No context")
877 979bf615 Filippos Giannakos
        req = xseg_get_request(ctx, xseg_ctx.portno, dst_portno, X_ALLOC)
878 979bf615 Filippos Giannakos
        if not req:
879 979bf615 Filippos Giannakos
            raise Error("Cannot get request")
880 979bf615 Filippos Giannakos
        r = xseg_prep_request(ctx, req, targetlen, datalen)
881 979bf615 Filippos Giannakos
        if r < 0:
882 979bf615 Filippos Giannakos
            xseg_put_request(ctx, req, xseg_ctx.portno)
883 979bf615 Filippos Giannakos
            raise Error("Cannot prepare request")
884 979bf615 Filippos Giannakos
        self.req = req
885 979bf615 Filippos Giannakos
        self.xseg_ctx = xseg_ctx
886 e0192e9f Filippos Giannakos
 
887 e0192e9f Filippos Giannakos
        if not self.set_target(target):
888 e0192e9f Filippos Giannakos
            self.put()
889 e0192e9f Filippos Giannakos
            raise Error("Cannot set target")
890 e0192e9f Filippos Giannakos
891 e0192e9f Filippos Giannakos
        if (data):
892 e0192e9f Filippos Giannakos
            if not self.set_data(data):
893 e0192e9f Filippos Giannakos
                self.put()
894 e0192e9f Filippos Giannakos
                raise Error("Cannot set data")
895 e0192e9f Filippos Giannakos
896 e0192e9f Filippos Giannakos
        self.set_size(size)
897 e0192e9f Filippos Giannakos
        self.set_op(op)
898 e0192e9f Filippos Giannakos
        self.set_flags(flags)
899 e0192e9f Filippos Giannakos
        self.set_offset(offset)
900 e0192e9f Filippos Giannakos
901 979bf615 Filippos Giannakos
        return
902 979bf615 Filippos Giannakos
903 979bf615 Filippos Giannakos
    def __enter__(self):
904 979bf615 Filippos Giannakos
        if not self.req:
905 979bf615 Filippos Giannakos
            raise Error("xseg request not set")
906 979bf615 Filippos Giannakos
        return self
907 979bf615 Filippos Giannakos
908 979bf615 Filippos Giannakos
    def __exit__(self, type_, value, traceback):
909 98c5d2e9 Filippos Giannakos
        self.put()
910 979bf615 Filippos Giannakos
        self.req = None
911 979bf615 Filippos Giannakos
        return False
912 979bf615 Filippos Giannakos
913 98c5d2e9 Filippos Giannakos
    def put(self, force=False):
914 98c5d2e9 Filippos Giannakos
        if not self.req:
915 98c5d2e9 Filippos Giannakos
            return False;
916 98c5d2e9 Filippos Giannakos
        if not force:
917 98c5d2e9 Filippos Giannakos
            if xq_count(byref(self.req.contents.path)) > 0:
918 98c5d2e9 Filippos Giannakos
                return False
919 98c5d2e9 Filippos Giannakos
        xseg_put_request(self.xseg_ctx.ctx, self.req, self.xseg_ctx.portno)
920 98c5d2e9 Filippos Giannakos
        self.req = None
921 98c5d2e9 Filippos Giannakos
        return True
922 98c5d2e9 Filippos Giannakos
923 98c5d2e9 Filippos Giannakos
    def get_datalen(self):
924 98c5d2e9 Filippos Giannakos
        return self.req.contents.datalen
925 98c5d2e9 Filippos Giannakos
926 979bf615 Filippos Giannakos
    def set_op(self, op):
927 979bf615 Filippos Giannakos
        self.req.contents.op = op
928 979bf615 Filippos Giannakos
929 979bf615 Filippos Giannakos
    def get_op(self):
930 979bf615 Filippos Giannakos
        return self.req.contents.op
931 979bf615 Filippos Giannakos
932 979bf615 Filippos Giannakos
    def set_offset(self, offset):
933 979bf615 Filippos Giannakos
        self.req.contents.offset = offset
934 979bf615 Filippos Giannakos
935 979bf615 Filippos Giannakos
    def get_offset(self):
936 979bf615 Filippos Giannakos
        return self.req.contents.offset
937 979bf615 Filippos Giannakos
938 979bf615 Filippos Giannakos
    def get_size(self):
939 979bf615 Filippos Giannakos
        return self.req.contents.size
940 979bf615 Filippos Giannakos
941 979bf615 Filippos Giannakos
    def set_size(self, size):
942 979bf615 Filippos Giannakos
        self.req.contents.size = size
943 979bf615 Filippos Giannakos
944 98c5d2e9 Filippos Giannakos
    def get_serviced(self):
945 98c5d2e9 Filippos Giannakos
        return self.req.contents.serviced
946 98c5d2e9 Filippos Giannakos
947 98c5d2e9 Filippos Giannakos
    def set_serviced(self, serviced):
948 98c5d2e9 Filippos Giannakos
        self.req.contents.serviced = serviced
949 98c5d2e9 Filippos Giannakos
950 979bf615 Filippos Giannakos
    def set_flags(self, flags):
951 979bf615 Filippos Giannakos
        self.req.contents.flags = flags
952 979bf615 Filippos Giannakos
953 979bf615 Filippos Giannakos
    def get_flags(self):
954 979bf615 Filippos Giannakos
        return self.req.contents.flags
955 979bf615 Filippos Giannakos
956 979bf615 Filippos Giannakos
    def set_target(self, target):
957 979bf615 Filippos Giannakos
        """Sets the target of the request, respecting request's targetlen"""
958 979bf615 Filippos Giannakos
        if len(target) != self.req.contents.targetlen:
959 979bf615 Filippos Giannakos
            return False
960 979bf615 Filippos Giannakos
        c_target = xseg_get_target_nonstatic(self.xseg_ctx.ctx, self.req)
961 979bf615 Filippos Giannakos
        p_target = create_string_buffer(target)
962 979bf615 Filippos Giannakos
#        print hex(addressof(c_target.contents))
963 979bf615 Filippos Giannakos
        memmove(c_target, p_target, len(target))
964 979bf615 Filippos Giannakos
        return True
965 979bf615 Filippos Giannakos
966 979bf615 Filippos Giannakos
    def get_target(self):
967 979bf615 Filippos Giannakos
        """Return a string to the target of the request"""
968 979bf615 Filippos Giannakos
        c_target = xseg_get_target_nonstatic(self.xseg_ctx.ctx, self.req)
969 979bf615 Filippos Giannakos
#        print "target_addr " + str(addressof(c_target.contents))
970 979bf615 Filippos Giannakos
        return string_at(c_target, self.req.contents.targetlen)
971 979bf615 Filippos Giannakos
972 979bf615 Filippos Giannakos
    def set_data(self, data):
973 1075ead7 Filippos Giannakos
        """Sets requests data. Data should be a xseg protocol structure"""
974 98c5d2e9 Filippos Giannakos
        if isinstance(data, basestring):
975 98c5d2e9 Filippos Giannakos
            if len(data) != self.req.contents.datalen:
976 98c5d2e9 Filippos Giannakos
                return False
977 98c5d2e9 Filippos Giannakos
            p_data = create_string_buffer(data)
978 98c5d2e9 Filippos Giannakos
        else:
979 98c5d2e9 Filippos Giannakos
            if sizeof(data) != self.req.contents.datalen:
980 98c5d2e9 Filippos Giannakos
                return False
981 98c5d2e9 Filippos Giannakos
            p_data = pointer(data)
982 979bf615 Filippos Giannakos
        c_data = xseg_get_data_nonstatic(self.xseg_ctx.ctx, self.req)
983 979bf615 Filippos Giannakos
        memmove(c_data, p_data, self.req.contents.datalen)
984 979bf615 Filippos Giannakos
985 979bf615 Filippos Giannakos
        return True
986 979bf615 Filippos Giannakos
987 e0192e9f Filippos Giannakos
    def get_data(self, _type=None):
988 979bf615 Filippos Giannakos
        """return a pointer to the data buffer of the request, casted to the
989 979bf615 Filippos Giannakos
        selected type"""
990 1075ead7 Filippos Giannakos
#        print "data addr " + str(addressof(xseg_get_data_nonstatic(\
991 1075ead7 Filippos Giannakos
#            self.xseg_ctx.ctx, self.req).contents))
992 1075ead7 Filippos Giannakos
#        ret = cast(xseg_get_data_nonstatic(self.xseg_ctx.ctx, self.req),
993 1075ead7 Filippos Giannakos
#                   _type)
994 979bf615 Filippos Giannakos
#        print addressof(ret.contents)
995 979bf615 Filippos Giannakos
#        return ret
996 979bf615 Filippos Giannakos
        if _type:
997 1075ead7 Filippos Giannakos
            return cast(xseg_get_data_nonstatic(self.xseg_ctx.ctx, self.req),
998 1075ead7 Filippos Giannakos
                        POINTER(_type))
999 979bf615 Filippos Giannakos
        else:
1000 1075ead7 Filippos Giannakos
            return cast(xseg_get_data_nonstatic(self.xseg_ctx.ctx, self.req),
1001 1075ead7 Filippos Giannakos
                        c_void_p)
1002 979bf615 Filippos Giannakos
1003 979bf615 Filippos Giannakos
    def submit(self):
1004 979bf615 Filippos Giannakos
        """Submit the associated xseg_request"""
1005 1075ead7 Filippos Giannakos
        p = xseg_submit(self.xseg_ctx.ctx, self.req, self.xseg_ctx.portno,
1006 1075ead7 Filippos Giannakos
                        X_ALLOC)
1007 979bf615 Filippos Giannakos
        if p == NoPort:
1008 979bf615 Filippos Giannakos
            raise Exception
1009 979bf615 Filippos Giannakos
        xseg_signal(self.xseg_ctx.ctx, p)
1010 979bf615 Filippos Giannakos
1011 979bf615 Filippos Giannakos
    def wait(self):
1012 979bf615 Filippos Giannakos
        """Wait until the associated xseg_request is responded, discarding any
1013 979bf615 Filippos Giannakos
        other requests that may be received in the meantime"""
1014 e0192e9f Filippos Giannakos
        self.xseg_ctx.wait_requests([self])
1015 979bf615 Filippos Giannakos
1016 979bf615 Filippos Giannakos
    def success(self):
1017 e0192e9f Filippos Giannakos
        if not bool(self.req.contents.state & XS_SERVED) and not \
1018 e0192e9f Filippos Giannakos
            bool(self.req.contents.state & XS_FAILED):
1019 e0192e9f Filippos Giannakos
            raise Error("Request not completed, nor Failed")
1020 e0192e9f Filippos Giannakos
        return bool((self.req.contents.state & XS_SERVED) and not \
1021 1075ead7 Filippos Giannakos
                   (self.req.contents.state & XS_FAILED))
1022 e0192e9f Filippos Giannakos
1023 e0192e9f Filippos Giannakos
    @classmethod
1024 e0192e9f Filippos Giannakos
    def get_write_request(cls, xseg, dst, target, data=None, offset=0,
1025 e0192e9f Filippos Giannakos
            datalen=0):
1026 e0192e9f Filippos Giannakos
        if data is None:
1027 e0192e9f Filippos Giannakos
            data = ""
1028 e0192e9f Filippos Giannakos
        size = len(data)
1029 e0192e9f Filippos Giannakos
        if not datalen:
1030 e0192e9f Filippos Giannakos
            datalen = size
1031 e0192e9f Filippos Giannakos
1032 e0192e9f Filippos Giannakos
        return cls(xseg, dst, target, op=X_WRITE, data=data, offset=offset,
1033 e0192e9f Filippos Giannakos
                   size=size, datalen=datalen)
1034 e0192e9f Filippos Giannakos
1035 e0192e9f Filippos Giannakos
    @classmethod
1036 e0192e9f Filippos Giannakos
    def get_read_request(cls, xseg, dst, target, size=0, offset=0, datalen=0):
1037 e0192e9f Filippos Giannakos
        if not datalen:
1038 e0192e9f Filippos Giannakos
            datalen=size
1039 e0192e9f Filippos Giannakos
        return cls(xseg, dst, target, op=X_READ, offset=offset, size=size,
1040 e0192e9f Filippos Giannakos
                   datalen=datalen)
1041 e0192e9f Filippos Giannakos
1042 e0192e9f Filippos Giannakos
    @classmethod
1043 e0192e9f Filippos Giannakos
    def get_info_request(cls, xseg, dst, target):
1044 e0192e9f Filippos Giannakos
        return cls(xseg, dst, target, op=X_INFO)
1045 e0192e9f Filippos Giannakos
1046 e0192e9f Filippos Giannakos
    @classmethod
1047 e0192e9f Filippos Giannakos
    def get_copy_request(cls, xseg, dst, target, copy_target=None, size=0, offset=0):
1048 e0192e9f Filippos Giannakos
        datalen = sizeof(xseg_request_copy)
1049 e0192e9f Filippos Giannakos
        xcopy = xseg_request_copy()
1050 e0192e9f Filippos Giannakos
        xcopy.target = target
1051 e0192e9f Filippos Giannakos
        xcopy.targetlen = len(target)
1052 e0192e9f Filippos Giannakos
        return cls(xseg, dst, copy_target, op=X_COPY, data=xcopy, datalen=datalen,
1053 e0192e9f Filippos Giannakos
                size=size, offset=offset)
1054 e0192e9f Filippos Giannakos
    @classmethod
1055 e0192e9f Filippos Giannakos
    def get_acquire_request(cls, xseg, dst, target, wait=False):
1056 e0192e9f Filippos Giannakos
        flags = 0
1057 e0192e9f Filippos Giannakos
        if not wait:
1058 e0192e9f Filippos Giannakos
            flags = XF_NOSYNC
1059 e0192e9f Filippos Giannakos
        return cls(xseg, dst, target, op=X_ACQUIRE, flags=flags)
1060 e0192e9f Filippos Giannakos
1061 e0192e9f Filippos Giannakos
    @classmethod
1062 e0192e9f Filippos Giannakos
    def get_release_request(cls, xseg, dst, target, force=False):
1063 e0192e9f Filippos Giannakos
        flags = 0
1064 e0192e9f Filippos Giannakos
        if force:
1065 e0192e9f Filippos Giannakos
            flags = XF_FORCE
1066 e0192e9f Filippos Giannakos
        return cls(xseg, dst, target, op=X_RELEASE, flags=flags)
1067 e0192e9f Filippos Giannakos
1068 e0192e9f Filippos Giannakos
    @classmethod
1069 e0192e9f Filippos Giannakos
    def get_delete_request(cls, xseg, dst, target):
1070 e0192e9f Filippos Giannakos
        return cls(xseg, dst, target, op=X_DELETE)
1071 e0192e9f Filippos Giannakos
1072 e0192e9f Filippos Giannakos
    @classmethod
1073 c07d4e0f Filippos Giannakos
    def get_clone_request(cls, xseg, dst, target, clone=None, clone_size=0,
1074 45bcbc5c Filippos Giannakos
            cont_addr=False):
1075 e0192e9f Filippos Giannakos
        datalen = sizeof(xseg_request_clone)
1076 e0192e9f Filippos Giannakos
        xclone = xseg_request_clone()
1077 e0192e9f Filippos Giannakos
        xclone.target = target
1078 e0192e9f Filippos Giannakos
        xclone.targetlen= len(target)
1079 e0192e9f Filippos Giannakos
        xclone.size = clone_size
1080 e0192e9f Filippos Giannakos
1081 c07d4e0f Filippos Giannakos
        flags = 0
1082 c07d4e0f Filippos Giannakos
        if cont_addr:
1083 c07d4e0f Filippos Giannakos
            flags = XF_CONTADDR
1084 c07d4e0f Filippos Giannakos
1085 c07d4e0f Filippos Giannakos
        return cls(xseg, dst, clone, op=X_CLONE, data=xclone, datalen=datalen,
1086 8487e2bd Filippos Giannakos
                flags=flags)
1087 e0192e9f Filippos Giannakos
1088 e0192e9f Filippos Giannakos
    @classmethod
1089 e0192e9f Filippos Giannakos
    def get_open_request(cls, xseg, dst, target):
1090 e0192e9f Filippos Giannakos
        return cls(xseg, dst, target, op=X_OPEN)
1091 e0192e9f Filippos Giannakos
1092 e0192e9f Filippos Giannakos
    @classmethod
1093 e0192e9f Filippos Giannakos
    def get_close_request(cls, xseg, dst, target):
1094 e0192e9f Filippos Giannakos
        return cls(xseg, dst, target, op=X_CLOSE)
1095 e0192e9f Filippos Giannakos
1096 e0192e9f Filippos Giannakos
    @classmethod
1097 e0192e9f Filippos Giannakos
    def get_snapshot_request(cls, xseg, dst, target, snap=None):
1098 e0192e9f Filippos Giannakos
        datalen = sizeof(xseg_request_snapshot)
1099 e0192e9f Filippos Giannakos
        xsnapshot = xseg_request_snapshot()
1100 e0192e9f Filippos Giannakos
        xsnapshot.target = snap
1101 e0192e9f Filippos Giannakos
        xsnapshot.targetlen= len(snap)
1102 e0192e9f Filippos Giannakos
1103 e0192e9f Filippos Giannakos
        return cls(xseg, dst, target, op=X_SNAPSHOT, data=xsnapshot,
1104 e0192e9f Filippos Giannakos
                datalen=datalen)
1105 e0192e9f Filippos Giannakos
1106 e0192e9f Filippos Giannakos
    @classmethod
1107 e0192e9f Filippos Giannakos
    def get_mapr_request(cls, xseg, dst, target, offset=0, size=0):
1108 e0192e9f Filippos Giannakos
        return cls(xseg, dst, target, op=X_MAPR, offset=offset, size=size,
1109 e0192e9f Filippos Giannakos
                datalen=0)
1110 e0192e9f Filippos Giannakos
1111 e0192e9f Filippos Giannakos
    @classmethod
1112 e0192e9f Filippos Giannakos
    def get_mapw_request(cls, xseg, dst, target, offset=0, size=0):
1113 e0192e9f Filippos Giannakos
        return cls(xseg, dst, target, op=X_MAPW, offset=offset, size=size,
1114 e0192e9f Filippos Giannakos
                datalen=0)
1115 c07d4e0f Filippos Giannakos
1116 c07d4e0f Filippos Giannakos
    @classmethod
1117 c07d4e0f Filippos Giannakos
    def get_hash_request(cls, xseg, dst, target, size=0, offset=0):
1118 c07d4e0f Filippos Giannakos
        return cls(xseg, dst, target, op=X_HASH, size=size, offset=offset)