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) |