Revision 3c6588bf
b/debian/archipelago.lintian-overrides | ||
---|---|---|
1 | 1 |
archipelago binary: new-package-should-close-itp-bug |
2 |
archipelago binary: non-dev-pkg-with-shlib-symlink |
|
3 |
archipelago binary: package-name-doesnt-match-sonames |
/dev/null | ||
---|---|---|
1 |
#!/usr/bin/env python |
|
2 |
# |
|
3 |
# archipelagos tool |
|
4 |
|
|
5 |
import os, sys, subprocess, argparse, time, psutil, signal, errno |
|
6 |
from subprocess import call, check_call |
|
7 |
|
|
8 |
DEFAULTS='/etc/default/archipelago' |
|
9 |
|
|
10 |
#system defaults |
|
11 |
PIDFILE_PATH="/var/run/archipelago" |
|
12 |
LOGS_PATH="/var/log/archipelago" |
|
13 |
DEVICE_PREFIX="/dev/xsegbd" |
|
14 |
XSEGBD_SYSFS="/sys/bus/xsegbd/" |
|
15 |
|
|
16 |
CHARDEV_NAME="/dev/segdev" |
|
17 |
CHARDEV_MAJOR=60 |
|
18 |
CHARDEV_MINOR=0 |
|
19 |
|
|
20 |
FILE_BLOCKER='mt-pfiled' |
|
21 |
RADOS_BLOCKER='mt-sosd' |
|
22 |
MAPPER='mt-mapperd' |
|
23 |
VLMC='st-vlmcd' |
|
24 |
BLOCKER='' |
|
25 |
|
|
26 |
available_storage = {'files': FILE_BLOCKER, 'rados': RADOS_BLOCKER} |
|
27 |
|
|
28 |
peers = [] |
|
29 |
modules = ["xseg", "segdev", "xseg_posix", "xseg_pthread", "xseg_segdev"] |
|
30 |
xsegbd = "xsegbd" |
|
31 |
|
|
32 |
BPORT=0 |
|
33 |
MPORT=1 |
|
34 |
MBPORT=2 |
|
35 |
VTOOL=3 |
|
36 |
VPORT_START=204 |
|
37 |
VPORT_END=403 |
|
38 |
|
|
39 |
#default config |
|
40 |
SPEC="segdev:xsegbd:512:1024:12" |
|
41 |
|
|
42 |
NR_OPS_BLOCKERB="" |
|
43 |
NR_OPS_BLOCKERM="" |
|
44 |
NR_OPS_VLMC="" |
|
45 |
NR_OPS_MAPPER="" |
|
46 |
|
|
47 |
VERBOSITY_BLOCKERB="" |
|
48 |
VERBOSITY_BLOCKERM="" |
|
49 |
VERBOSITY_MAPPER="" |
|
50 |
VERBOSITY_VLMC="" |
|
51 |
|
|
52 |
|
|
53 |
#mt-pfiled specific options |
|
54 |
FILED_IMAGES="" |
|
55 |
FILED_MAPS="" |
|
56 |
PITHOS="" |
|
57 |
PITHOSMAPS="" |
|
58 |
|
|
59 |
#mt-sosd specific options |
|
60 |
RADOS_POOL_MAPS="" |
|
61 |
RADOS_POOL_BLOCKS="" |
|
62 |
|
|
63 |
|
|
64 |
|
|
65 |
def check_conf(): |
|
66 |
def isExec(file_path): |
|
67 |
return os.path.isfile(file_path) and os.access(file_path, os.X_OK) |
|
68 |
|
|
69 |
def validExec(program): |
|
70 |
for path in os.environ["PATH"].split(os.pathsep): |
|
71 |
exe_file = os.path.join(path, program) |
|
72 |
if isExec(exe_file): |
|
73 |
return True |
|
74 |
return False |
|
75 |
|
|
76 |
|
|
77 |
def validPort(port, limit, name): |
|
78 |
try: |
|
79 |
if int(port) >= limit: |
|
80 |
print str(port) + " >= " + limit |
|
81 |
return False |
|
82 |
except: |
|
83 |
print "Invalid port "+name+" : " + str(port) |
|
84 |
return False |
|
85 |
|
|
86 |
return True |
|
87 |
|
|
88 |
|
|
89 |
if not LOGS_PATH: |
|
90 |
print "LOGS_PATH is not set" |
|
91 |
return False |
|
92 |
if not PIDFILE_PATH: |
|
93 |
print "PIDFILE_PATH is not set" |
|
94 |
return False |
|
95 |
|
|
96 |
try: |
|
97 |
if not os.path.isdir(str(LOGS_PATH)): |
|
98 |
print "LOGS_PATH "+str(LOGS_PATH)+" does not exist" |
|
99 |
return False |
|
100 |
except: |
|
101 |
print "LOGS_PATH doesn't exist or is not a directory" |
|
102 |
return False |
|
103 |
|
|
104 |
try: |
|
105 |
os.makedirs(str(PIDFILE_PATH)) |
|
106 |
except OSError as e: |
|
107 |
if e.errno == errno.EEXIST: |
|
108 |
if os.path.isdir(str(PIDFILE_PATH)): |
|
109 |
pass |
|
110 |
else: |
|
111 |
print str(PIDFILE_PATH) + " is not a directory" |
|
112 |
return False |
|
113 |
else: |
|
114 |
print "Cannot create " + str(PIDFILE_PATH) |
|
115 |
return False |
|
116 |
except: |
|
117 |
print "PIDFILE_PATH is not set" |
|
118 |
return False |
|
119 |
|
|
120 |
splitted_spec = str(SPEC).split(':') |
|
121 |
if len(splitted_spec) < 5: |
|
122 |
"Invalid spec" |
|
123 |
return False |
|
124 |
|
|
125 |
xseg_type=splitted_spec[0] |
|
126 |
xseg_name=splitted_spec[1] |
|
127 |
xseg_ports=int(splitted_spec[2]) |
|
128 |
xseg_heapsize=int(splitted_spec[3]) |
|
129 |
xseg_align=int(splitted_spec[4]) |
|
130 |
|
|
131 |
if xseg_type != "segdev": |
|
132 |
print "Segment type not segdev" |
|
133 |
return False |
|
134 |
if xseg_name != "xsegbd": |
|
135 |
print "Segment name not equal xsegbd" |
|
136 |
return False |
|
137 |
if xseg_align != 12: |
|
138 |
print "Wrong alignemt" |
|
139 |
return False |
|
140 |
|
|
141 |
for v in [VERBOSITY_BLOCKERB, VERBOSITY_BLOCKERM, VERBOSITY_MAPPER, |
|
142 |
VERBOSITY_VLMC]: |
|
143 |
if v is None: |
|
144 |
print "Verbosity missing" |
|
145 |
try: |
|
146 |
if (int(v) > 3 or int(v) < 0): |
|
147 |
print "Invalid verbosity " + str(v) |
|
148 |
return False |
|
149 |
except: |
|
150 |
print "Invalid verbosity " + str(v) |
|
151 |
return False |
|
152 |
|
|
153 |
for n in [NR_OPS_BLOCKERB, NR_OPS_BLOCKERM, NR_OPS_VLMC, NR_OPS_MAPPER]: |
|
154 |
if n is None: |
|
155 |
print "Nr ops missing" |
|
156 |
try: |
|
157 |
if (int(n) <= 0): |
|
158 |
print "Invalid nr_ops " + str(n) |
|
159 |
return False |
|
160 |
except: |
|
161 |
print "Invalid nr_ops " + str(n) |
|
162 |
return False |
|
163 |
|
|
164 |
if not validPort(VTOOL, xseg_ports, "VTOOL"): |
|
165 |
return False |
|
166 |
if not validPort(MPORT, xseg_ports, "MPORT"): |
|
167 |
return False |
|
168 |
if not validPort(BPORT, xseg_ports, "BPORT"): |
|
169 |
return False |
|
170 |
if not validPort(MBPORT, xseg_ports, "MBPORT"): |
|
171 |
return False |
|
172 |
if not validPort(VPORT_START, xseg_ports, "VPORT_START"): |
|
173 |
return False |
|
174 |
if not validPort(VPORT_END, xseg_ports, "VPORT_END"): |
|
175 |
return False |
|
176 |
|
|
177 |
global BLOCKER |
|
178 |
try: |
|
179 |
BLOCKER = available_storage[str(STORAGE)] |
|
180 |
except: |
|
181 |
print "Invalid storage " + str(STORAGE) |
|
182 |
print "Available storage: \"" + ', "'.join(available_storage) + "\"" |
|
183 |
return False |
|
184 |
|
|
185 |
if STORAGE=="files": |
|
186 |
if FILED_IMAGES and not os.path.isdir(str(FILED_IMAGES)): |
|
187 |
print "FILED_IMAGES invalid" |
|
188 |
return False |
|
189 |
if FILED_MAPS and not os.path.isdir(str(FILED_MAPS)): |
|
190 |
print "FILED_PATH invalid" |
|
191 |
return False |
|
192 |
if PITHOS and not os.path.isdir(str(PITHOS)): |
|
193 |
print "PITHOS invalid " |
|
194 |
return False |
|
195 |
if PITHOSMAPS and not os.path.isdir(str(PITHOSMAPS)): |
|
196 |
print "PITHOSMAPS invalid" |
|
197 |
return False |
|
198 |
|
|
199 |
for p in [BLOCKER, MAPPER, VLMC]: |
|
200 |
if not validExec(p): |
|
201 |
print p + "is not a valid executable" |
|
202 |
return False |
|
203 |
|
|
204 |
return True |
|
205 |
|
|
206 |
def construct_peers(): |
|
207 |
if BLOCKER == "pfiled": |
|
208 |
peer_blockerb = [BLOCKER, |
|
209 |
["-p" , str(BPORT), "-g", str(SPEC), "-n", str(NR_OPS_BLOCKERB), |
|
210 |
str(PITHOS), str(FILED_IMAGES), "-d", |
|
211 |
"-f", os.path.join(PIDFILE_PATH, "blockerb.pid")], |
|
212 |
"blockerb"] |
|
213 |
peer_blockerm = [BLOCKER, |
|
214 |
["-p" , str(MBPORT), "-g", str(SPEC), "-n", str(NR_OPS_BLOCKERM), |
|
215 |
str(PITHOSMAPS), str(FILED_MAPS), "-d", |
|
216 |
"-f", os.path.join(PIDFILE_PATH, "blockerm.pid")], |
|
217 |
"blockerm" ] |
|
218 |
elif BLOCKER == "mt-sosd": |
|
219 |
peer_blockerb = [BLOCKER, |
|
220 |
["-p" , str(BPORT), "-g", str(SPEC), "-n", str(NR_OPS_BLOCKERB), |
|
221 |
"--pool", str(RADOS_POOL_BLOCKS), "-v", str(VERBOSITY_BLOCKERB), |
|
222 |
"-d", "--pidfile", os.path.join(PIDFILE_PATH, "blockerb.pid"), |
|
223 |
"-l", os.path.join(str(LOGS_PATH), "blockerb.log"), |
|
224 |
"-t", "3"], |
|
225 |
"blockerb"] |
|
226 |
peer_blockerm = [BLOCKER, |
|
227 |
["-p" , str(MBPORT), "-g", str(SPEC), "-n", str(NR_OPS_BLOCKERM), |
|
228 |
"--pool", str(RADOS_POOL_MAPS), "-v", str(VERBOSITY_BLOCKERM), |
|
229 |
"-d", "--pidfile", os.path.join(PIDFILE_PATH, "blockerm.pid"), |
|
230 |
"-l", os.path.join(str(LOGS_PATH), "blockerm.log"), |
|
231 |
"-t", "3"], |
|
232 |
"blockerm"] |
|
233 |
elif BLOCKER == "mt-pfiled": |
|
234 |
peer_blockerb = [BLOCKER, |
|
235 |
["-p" , str(BPORT), "-g", str(SPEC), "-n", str(NR_OPS_BLOCKERB), |
|
236 |
"--pithos", str(PITHOS), "--archip", str(FILED_IMAGES), |
|
237 |
"-v", str(VERBOSITY_BLOCKERB), |
|
238 |
"-d", "--pidfile", os.path.join(PIDFILE_PATH, "blockerb.pid"), |
|
239 |
"-l", os.path.join(str(LOGS_PATH), "blockerb.log"), |
|
240 |
"-t", str(NR_OPS_BLOCKERB), "--prefix", "archip_"], |
|
241 |
"blockerb"] |
|
242 |
peer_blockerm = [BLOCKER, |
|
243 |
["-p" , str(MBPORT), "-g", str(SPEC), "-n", str(NR_OPS_BLOCKERM), |
|
244 |
"--pithos", str(PITHOSMAPS), "--archip", str(FILED_MAPS), |
|
245 |
"-v", str(VERBOSITY_BLOCKERM), |
|
246 |
"-d", "--pidfile", os.path.join(PIDFILE_PATH, "blockerm.pid"), |
|
247 |
"-l", os.path.join(str(LOGS_PATH), "blockerm.log"), |
|
248 |
"-t", str(NR_OPS_BLOCKERM), "--prefix", "archip_"], |
|
249 |
"blockerm"] |
|
250 |
else: |
|
251 |
sys.exit(-1) |
|
252 |
|
|
253 |
peer_vlmcd = [VLMC, |
|
254 |
["-t" , "1", "-sp", str(VPORT_START), "-ep", str(VPORT_END), |
|
255 |
"-g", str(SPEC), "-n", str(NR_OPS_VLMC), "-bp", str(BPORT), |
|
256 |
"-mp", str(MPORT), "-d", "-v", str(VERBOSITY_VLMC), |
|
257 |
"--pidfile", os.path.join(PIDFILE_PATH, "vlmcd.pid"), |
|
258 |
"-l", os.path.join(str(LOGS_PATH), "vlmcd.log") |
|
259 |
], "vlmcd"] |
|
260 |
peer_mapperd = [MAPPER, |
|
261 |
["-t" , "1", "-p", str(MPORT), "-mbp", str(MBPORT), |
|
262 |
"-g", str(SPEC), "-n", str(NR_OPS_MAPPER), "-bp", str(BPORT), |
|
263 |
"--pidfile", os.path.join(PIDFILE_PATH, "mapperd.pid"), |
|
264 |
"-v", str(VERBOSITY_MAPPER), "-d", |
|
265 |
"-l", os.path.join(str(LOGS_PATH), "mapperd.log") |
|
266 |
], "mapperd"] |
|
267 |
|
|
268 |
peers = [] |
|
269 |
peers.append(peer_blockerb) |
|
270 |
peers.append(peer_blockerm) |
|
271 |
peers.append(peer_vlmcd) |
|
272 |
peers.append(peer_mapperd) |
|
273 |
|
|
274 |
return peers |
|
275 |
|
|
276 |
|
|
277 |
def exclusive(fn): |
|
278 |
def exclusive_args(args): |
|
279 |
file = "/tmp/vlmc_map.lock" |
|
280 |
while True: |
|
281 |
try: |
|
282 |
fd = os.open(file, os.O_CREAT|os.O_EXCL|os.O_WRONLY) |
|
283 |
break; |
|
284 |
except Exception, reason: |
|
285 |
print >> sys.stderr, reason |
|
286 |
time.sleep(0.05) |
|
287 |
try: |
|
288 |
r = fn(args) |
|
289 |
finally: |
|
290 |
os.close(fd) |
|
291 |
os.unlink(file) |
|
292 |
return r |
|
293 |
|
|
294 |
return exclusive_args |
|
295 |
|
|
296 |
@exclusive |
|
297 |
def vlmc_showmapped(args): |
|
298 |
try: |
|
299 |
devices = os.listdir(os.path.join(XSEGBD_SYSFS, "devices/")) |
|
300 |
except: |
|
301 |
return -1 |
|
302 |
|
|
303 |
if not devices: |
|
304 |
return -1 |
|
305 |
print "id\tpool\timage\tsnap\tdevice" |
|
306 |
try: |
|
307 |
for f in devices: |
|
308 |
d_id = open(XSEGBD_SYSFS + "devices/" + f + "/id").read().strip() |
|
309 |
target = open(XSEGBD_SYSFS + "devices/"+ f + "/target").read().strip() |
|
310 |
|
|
311 |
print "%s\t%s\t%s\t%s\t%s" % (d_id, '-', target, '-', DEVICE_PREFIX + |
|
312 |
d_id) |
|
313 |
except Exception, reason: |
|
314 |
print >> sys.stderr, reason |
|
315 |
return -2 |
|
316 |
return len(devices) |
|
317 |
|
|
318 |
def loadrc(rc): |
|
319 |
try: |
|
320 |
if rc == None: |
|
321 |
execfile(os.path.expanduser(DEFAULTS), globals()) |
|
322 |
else: |
|
323 |
execfile(rc, globals()) |
|
324 |
except: |
|
325 |
print "Cannot read config file" |
|
326 |
sys.exit(1) |
|
327 |
|
|
328 |
if not check_conf(): |
|
329 |
sys.exit(1) |
|
330 |
|
|
331 |
def loaded_modules(): |
|
332 |
lines = open("/proc/modules").read().split("\n") |
|
333 |
modules = [f.split(" ")[0] for f in lines] |
|
334 |
return modules |
|
335 |
|
|
336 |
def loaded_module(name): |
|
337 |
return name in loaded_modules() |
|
338 |
|
|
339 |
def load_module(name): |
|
340 |
modules = loaded_modules() |
|
341 |
if name in modules: |
|
342 |
return 0 |
|
343 |
cmd = ["modprobe -v %s" % name] |
|
344 |
try: |
|
345 |
check_call(cmd, shell=True); |
|
346 |
except Exception: |
|
347 |
sys.stderr.write("Module %s failed to load. \n" % name) |
|
348 |
return -1 |
|
349 |
return 0 |
|
350 |
|
|
351 |
def unload_module(name): |
|
352 |
modules = loaded_modules() |
|
353 |
if name not in modules: |
|
354 |
return 0 |
|
355 |
cmd = ["modprobe -rv %s" % name] |
|
356 |
print cmd |
|
357 |
try: |
|
358 |
check_call(cmd, shell=True); |
|
359 |
except Exception: |
|
360 |
sys.stderr.write("Module %s failed to unload. \n" % name) |
|
361 |
return -1 |
|
362 |
return 0 |
|
363 |
|
|
364 |
def create_segment(): |
|
365 |
#fixme blocking.... |
|
366 |
cmd = ["xseg", str(SPEC), "create"] |
|
367 |
try: |
|
368 |
check_call(cmd, shell=False); |
|
369 |
except Exception: |
|
370 |
sys.stderr.write("Cannot create segment. \n") |
|
371 |
return -1 |
|
372 |
return 0 |
|
373 |
|
|
374 |
def destroy_segment(): |
|
375 |
#fixme blocking.... |
|
376 |
cmd = ["xseg", str(SPEC), "destroy"] |
|
377 |
try: |
|
378 |
check_call(cmd, shell=False); |
|
379 |
except Exception: |
|
380 |
sys.stderr.write("Cannot destroy segment. \n") |
|
381 |
return 0 |
|
382 |
return 0 |
|
383 |
|
|
384 |
def check_running(name, pid = -1): |
|
385 |
for p in psutil.process_iter(): |
|
386 |
if p.name == name: |
|
387 |
if pid != -1: |
|
388 |
if pid == p.pid: |
|
389 |
return pid |
|
390 |
else: |
|
391 |
return pid |
|
392 |
return -1 |
|
393 |
|
|
394 |
def check_pidfile(name): |
|
395 |
pidfile = os.path.join(PIDFILE_PATH, name + ".pid") |
|
396 |
pf = None |
|
397 |
try: |
|
398 |
pf = open(pidfile, "r") |
|
399 |
pid = int(pf.read()) |
|
400 |
pf.close() |
|
401 |
except: |
|
402 |
if pf: |
|
403 |
pf.close() |
|
404 |
return -1 |
|
405 |
|
|
406 |
return pid |
|
407 |
|
|
408 |
def start_peer(peer): |
|
409 |
cmd = [peer[0]] + peer[1] |
|
410 |
try: |
|
411 |
check_call(cmd, shell=False); |
|
412 |
except Exception: |
|
413 |
sys.stderr.write("Peer %s start failed.\n" % peer[0]) |
|
414 |
return -1 |
|
415 |
return 0 |
|
416 |
|
|
417 |
def stop_peer(peer): |
|
418 |
pid = check_pidfile(peer[2]) |
|
419 |
if pid < 0: |
|
420 |
print " process not running" |
|
421 |
return -1 |
|
422 |
|
|
423 |
os.kill(pid, signal.SIGTERM) |
|
424 |
i = 0 |
|
425 |
while check_running(peer[0], pid) > 0: |
|
426 |
time.sleep(0.1) |
|
427 |
i += 1 |
|
428 |
if i > 150: |
|
429 |
print "process did not die in 15 secs" |
|
430 |
return -1 |
|
431 |
return 0 |
|
432 |
|
|
433 |
def peer_running(peer): |
|
434 |
pid = check_pidfile(peer[2]) |
|
435 |
if pid < 0: |
|
436 |
return -1 |
|
437 |
|
|
438 |
r = check_running(peer[0], pid) |
|
439 |
if r < 0: |
|
440 |
print "Peer " + peer[2] + " has valid pidfile but does not seem to be active" |
|
441 |
return 0 |
|
442 |
|
|
443 |
|
|
444 |
def make_segdev(): |
|
445 |
try: |
|
446 |
os.stat(str(CHARDEV_NAME)) |
|
447 |
return -2 |
|
448 |
except: |
|
449 |
pass |
|
450 |
cmd = ["mknod", str(CHARDEV_NAME), "c", str(CHARDEV_MAJOR), str(CHARDEV_MINOR)] |
|
451 |
print ' '.join(cmd) |
|
452 |
try: |
|
453 |
check_call(cmd, shell=False); |
|
454 |
except Exception: |
|
455 |
sys.stderr.write("Segdev device creation failed. \n") |
|
456 |
return -1 |
|
457 |
return 0 |
|
458 |
|
|
459 |
def remove_segdev(): |
|
460 |
try: |
|
461 |
os.stat(str(CHARDEV_NAME)) |
|
462 |
except: |
|
463 |
return -2 |
|
464 |
try: |
|
465 |
os.unlink(str(CHARDEV_NAME)) |
|
466 |
except: |
|
467 |
sys.stderr.write("Segdev device removal failed. \n") |
|
468 |
return -1 |
|
469 |
|
|
470 |
|
|
471 |
def start(args): |
|
472 |
if status(args) > 0: |
|
473 |
return -1 |
|
474 |
|
|
475 |
for m in modules: |
|
476 |
if load_module(m) < 0: |
|
477 |
stop(args) |
|
478 |
return -1 |
|
479 |
time.sleep(0.5) |
|
480 |
|
|
481 |
if make_segdev() < 0: |
|
482 |
stop(args) |
|
483 |
return -1 |
|
484 |
|
|
485 |
time.sleep(0.5) |
|
486 |
|
|
487 |
if create_segment() < 0: |
|
488 |
stop(args) |
|
489 |
return -1 |
|
490 |
|
|
491 |
time.sleep(0.5) |
|
492 |
|
|
493 |
for p in peers: |
|
494 |
if start_peer(p) < 0: |
|
495 |
stop(args) |
|
496 |
return -1 |
|
497 |
|
|
498 |
|
|
499 |
if load_module(xsegbd) < 0: |
|
500 |
stop(args) |
|
501 |
return -1 |
|
502 |
return 0 |
|
503 |
|
|
504 |
def stop(args): |
|
505 |
#check devices |
|
506 |
if vlmc_showmapped(args) > 0: |
|
507 |
print "Cannot stop archipelago. Mapped volumes exist" |
|
508 |
return -1 |
|
509 |
if unload_module(xsegbd): |
|
510 |
return -1 |
|
511 |
r = 0 |
|
512 |
for p in reversed(peers): |
|
513 |
stop_peer(p) |
|
514 |
|
|
515 |
remove_segdev() |
|
516 |
|
|
517 |
for m in reversed(modules): |
|
518 |
unload_module(m) |
|
519 |
return 0 |
|
520 |
|
|
521 |
def status(args): |
|
522 |
r = 0 |
|
523 |
if vlmc_showmapped(args) >= 0: |
|
524 |
r += 1 |
|
525 |
if loaded_module(xsegbd): |
|
526 |
print "Xsegbd loaded" |
|
527 |
r += 1 |
|
528 |
else: |
|
529 |
print "Xsegbd not loaded" |
|
530 |
for m in reversed(modules): |
|
531 |
if loaded_module(m): |
|
532 |
print m + " loaded" |
|
533 |
r += 1 |
|
534 |
else: |
|
535 |
print m + " not loaded" |
|
536 |
for p in reversed(peers): |
|
537 |
if peer_running(p) < 0: |
|
538 |
print p[0] + " not running" |
|
539 |
else: |
|
540 |
print p[0] + " running" |
|
541 |
r += 1 |
|
542 |
return r |
|
543 |
|
|
544 |
def restart(args): |
|
545 |
r = stop(args) |
|
546 |
if r < 0: |
|
547 |
return r |
|
548 |
return start(args) |
|
549 |
|
|
550 |
if __name__ == "__main__": |
|
551 |
# parse arguments and discpatch to the correct func |
|
552 |
parser = argparse.ArgumentParser(description='Archipelago tool') |
|
553 |
parser.add_argument('-c', '--config', type=str, nargs='?', help='config file') |
|
554 |
subparsers = parser.add_subparsers() |
|
555 |
|
|
556 |
start_parser = subparsers.add_parser('start', help='Start archipelago') |
|
557 |
start_parser.set_defaults(func=start) |
|
558 |
|
|
559 |
stop_parser = subparsers.add_parser('stop', help='Stop archipelago') |
|
560 |
stop_parser.set_defaults(func=stop) |
|
561 |
|
|
562 |
status_parser = subparsers.add_parser('status', help='Archipelago status') |
|
563 |
status_parser.set_defaults(func=status) |
|
564 |
|
|
565 |
restart_parser = subparsers.add_parser('restart', help='Restart archipelago') |
|
566 |
restart_parser.set_defaults(func=restart) |
|
567 |
|
|
568 |
args = parser.parse_args() |
|
569 |
loadrc(args.config) |
|
570 |
peers = construct_peers() |
|
571 |
sys.exit(args.func(args)) |
b/xseg/tools/archipelago | ||
---|---|---|
1 |
#!/usr/bin/env python |
|
2 |
# |
|
3 |
# archipelagos tool |
|
4 |
|
|
5 |
import os, sys, subprocess, argparse, time, psutil, signal, errno |
|
6 |
from subprocess import call, check_call |
|
7 |
|
|
8 |
DEFAULTS='/etc/default/archipelago' |
|
9 |
|
|
10 |
#system defaults |
|
11 |
PIDFILE_PATH="/var/run/archipelago" |
|
12 |
LOGS_PATH="/var/log/archipelago" |
|
13 |
DEVICE_PREFIX="/dev/xsegbd" |
|
14 |
XSEGBD_SYSFS="/sys/bus/xsegbd/" |
|
15 |
|
|
16 |
CHARDEV_NAME="/dev/segdev" |
|
17 |
CHARDEV_MAJOR=60 |
|
18 |
CHARDEV_MINOR=0 |
|
19 |
|
|
20 |
FILE_BLOCKER='mt-pfiled' |
|
21 |
RADOS_BLOCKER='mt-sosd' |
|
22 |
MAPPER='mt-mapperd' |
|
23 |
VLMC='st-vlmcd' |
|
24 |
BLOCKER='' |
|
25 |
|
|
26 |
available_storage = {'files': FILE_BLOCKER, 'rados': RADOS_BLOCKER} |
|
27 |
|
|
28 |
peers = [] |
|
29 |
modules = ["xseg", "segdev", "xseg_posix", "xseg_pthread", "xseg_segdev"] |
|
30 |
xsegbd = "xsegbd" |
|
31 |
|
|
32 |
BPORT=0 |
|
33 |
MPORT=1 |
|
34 |
MBPORT=2 |
|
35 |
VTOOL=3 |
|
36 |
VPORT_START=204 |
|
37 |
VPORT_END=403 |
|
38 |
|
|
39 |
#default config |
|
40 |
SPEC="segdev:xsegbd:512:1024:12" |
|
41 |
|
|
42 |
NR_OPS_BLOCKERB="" |
|
43 |
NR_OPS_BLOCKERM="" |
|
44 |
NR_OPS_VLMC="" |
|
45 |
NR_OPS_MAPPER="" |
|
46 |
|
|
47 |
VERBOSITY_BLOCKERB="" |
|
48 |
VERBOSITY_BLOCKERM="" |
|
49 |
VERBOSITY_MAPPER="" |
|
50 |
VERBOSITY_VLMC="" |
|
51 |
|
|
52 |
|
|
53 |
#mt-pfiled specific options |
|
54 |
FILED_IMAGES="" |
|
55 |
FILED_MAPS="" |
|
56 |
PITHOS="" |
|
57 |
PITHOSMAPS="" |
|
58 |
|
|
59 |
#mt-sosd specific options |
|
60 |
RADOS_POOL_MAPS="" |
|
61 |
RADOS_POOL_BLOCKS="" |
|
62 |
|
|
63 |
|
|
64 |
|
|
65 |
def check_conf(): |
|
66 |
def isExec(file_path): |
|
67 |
return os.path.isfile(file_path) and os.access(file_path, os.X_OK) |
|
68 |
|
|
69 |
def validExec(program): |
|
70 |
for path in os.environ["PATH"].split(os.pathsep): |
|
71 |
exe_file = os.path.join(path, program) |
|
72 |
if isExec(exe_file): |
|
73 |
return True |
|
74 |
return False |
|
75 |
|
|
76 |
|
|
77 |
def validPort(port, limit, name): |
|
78 |
try: |
|
79 |
if int(port) >= limit: |
|
80 |
print str(port) + " >= " + limit |
|
81 |
return False |
|
82 |
except: |
|
83 |
print "Invalid port "+name+" : " + str(port) |
|
84 |
return False |
|
85 |
|
|
86 |
return True |
|
87 |
|
|
88 |
|
|
89 |
if not LOGS_PATH: |
|
90 |
print "LOGS_PATH is not set" |
|
91 |
return False |
|
92 |
if not PIDFILE_PATH: |
|
93 |
print "PIDFILE_PATH is not set" |
|
94 |
return False |
|
95 |
|
|
96 |
try: |
|
97 |
if not os.path.isdir(str(LOGS_PATH)): |
|
98 |
print "LOGS_PATH "+str(LOGS_PATH)+" does not exist" |
|
99 |
return False |
|
100 |
except: |
|
101 |
print "LOGS_PATH doesn't exist or is not a directory" |
|
102 |
return False |
|
103 |
|
|
104 |
try: |
|
105 |
os.makedirs(str(PIDFILE_PATH)) |
|
106 |
except OSError as e: |
|
107 |
if e.errno == errno.EEXIST: |
|
108 |
if os.path.isdir(str(PIDFILE_PATH)): |
|
109 |
pass |
|
110 |
else: |
|
111 |
print str(PIDFILE_PATH) + " is not a directory" |
|
112 |
return False |
|
113 |
else: |
|
114 |
print "Cannot create " + str(PIDFILE_PATH) |
|
115 |
return False |
|
116 |
except: |
|
117 |
print "PIDFILE_PATH is not set" |
|
118 |
return False |
|
119 |
|
|
120 |
splitted_spec = str(SPEC).split(':') |
|
121 |
if len(splitted_spec) < 5: |
|
122 |
"Invalid spec" |
|
123 |
return False |
|
124 |
|
|
125 |
xseg_type=splitted_spec[0] |
|
126 |
xseg_name=splitted_spec[1] |
|
127 |
xseg_ports=int(splitted_spec[2]) |
|
128 |
xseg_heapsize=int(splitted_spec[3]) |
|
129 |
xseg_align=int(splitted_spec[4]) |
|
130 |
|
|
131 |
if xseg_type != "segdev": |
|
132 |
print "Segment type not segdev" |
|
133 |
return False |
|
134 |
if xseg_name != "xsegbd": |
|
135 |
print "Segment name not equal xsegbd" |
|
136 |
return False |
|
137 |
if xseg_align != 12: |
|
138 |
print "Wrong alignemt" |
|
139 |
return False |
|
140 |
|
|
141 |
for v in [VERBOSITY_BLOCKERB, VERBOSITY_BLOCKERM, VERBOSITY_MAPPER, |
|
142 |
VERBOSITY_VLMC]: |
|
143 |
if v is None: |
|
144 |
print "Verbosity missing" |
|
145 |
try: |
|
146 |
if (int(v) > 3 or int(v) < 0): |
|
147 |
print "Invalid verbosity " + str(v) |
|
148 |
return False |
|
149 |
except: |
|
150 |
print "Invalid verbosity " + str(v) |
|
151 |
return False |
|
152 |
|
|
153 |
for n in [NR_OPS_BLOCKERB, NR_OPS_BLOCKERM, NR_OPS_VLMC, NR_OPS_MAPPER]: |
|
154 |
if n is None: |
|
155 |
print "Nr ops missing" |
|
156 |
try: |
|
157 |
if (int(n) <= 0): |
|
158 |
print "Invalid nr_ops " + str(n) |
|
159 |
return False |
|
160 |
except: |
|
161 |
print "Invalid nr_ops " + str(n) |
|
162 |
return False |
|
163 |
|
|
164 |
if not validPort(VTOOL, xseg_ports, "VTOOL"): |
|
165 |
return False |
|
166 |
if not validPort(MPORT, xseg_ports, "MPORT"): |
|
167 |
return False |
|
168 |
if not validPort(BPORT, xseg_ports, "BPORT"): |
|
169 |
return False |
|
170 |
if not validPort(MBPORT, xseg_ports, "MBPORT"): |
|
171 |
return False |
|
172 |
if not validPort(VPORT_START, xseg_ports, "VPORT_START"): |
|
173 |
return False |
|
174 |
if not validPort(VPORT_END, xseg_ports, "VPORT_END"): |
|
175 |
return False |
|
176 |
|
|
177 |
global BLOCKER |
|
178 |
try: |
|
179 |
BLOCKER = available_storage[str(STORAGE)] |
|
180 |
except: |
|
181 |
print "Invalid storage " + str(STORAGE) |
|
182 |
print "Available storage: \"" + ', "'.join(available_storage) + "\"" |
|
183 |
return False |
|
184 |
|
|
185 |
if STORAGE=="files": |
|
186 |
if FILED_IMAGES and not os.path.isdir(str(FILED_IMAGES)): |
|
187 |
print "FILED_IMAGES invalid" |
|
188 |
return False |
|
189 |
if FILED_MAPS and not os.path.isdir(str(FILED_MAPS)): |
|
190 |
print "FILED_PATH invalid" |
|
191 |
return False |
|
192 |
if PITHOS and not os.path.isdir(str(PITHOS)): |
|
193 |
print "PITHOS invalid " |
|
194 |
return False |
|
195 |
if PITHOSMAPS and not os.path.isdir(str(PITHOSMAPS)): |
|
196 |
print "PITHOSMAPS invalid" |
|
197 |
return False |
|
198 |
|
|
199 |
for p in [BLOCKER, MAPPER, VLMC]: |
|
200 |
if not validExec(p): |
|
201 |
print p + "is not a valid executable" |
|
202 |
return False |
|
203 |
|
|
204 |
return True |
|
205 |
|
|
206 |
def construct_peers(): |
|
207 |
if BLOCKER == "pfiled": |
|
208 |
peer_blockerb = [BLOCKER, |
|
209 |
["-p" , str(BPORT), "-g", str(SPEC), "-n", str(NR_OPS_BLOCKERB), |
|
210 |
str(PITHOS), str(FILED_IMAGES), "-d", |
|
211 |
"-f", os.path.join(PIDFILE_PATH, "blockerb.pid")], |
|
212 |
"blockerb"] |
|
213 |
peer_blockerm = [BLOCKER, |
|
214 |
["-p" , str(MBPORT), "-g", str(SPEC), "-n", str(NR_OPS_BLOCKERM), |
|
215 |
str(PITHOSMAPS), str(FILED_MAPS), "-d", |
|
216 |
"-f", os.path.join(PIDFILE_PATH, "blockerm.pid")], |
|
217 |
"blockerm" ] |
|
218 |
elif BLOCKER == "mt-sosd": |
|
219 |
peer_blockerb = [BLOCKER, |
|
220 |
["-p" , str(BPORT), "-g", str(SPEC), "-n", str(NR_OPS_BLOCKERB), |
|
221 |
"--pool", str(RADOS_POOL_BLOCKS), "-v", str(VERBOSITY_BLOCKERB), |
|
222 |
"-d", "--pidfile", os.path.join(PIDFILE_PATH, "blockerb.pid"), |
|
223 |
"-l", os.path.join(str(LOGS_PATH), "blockerb.log"), |
|
224 |
"-t", "3"], |
|
225 |
"blockerb"] |
|
226 |
peer_blockerm = [BLOCKER, |
|
227 |
["-p" , str(MBPORT), "-g", str(SPEC), "-n", str(NR_OPS_BLOCKERM), |
|
228 |
"--pool", str(RADOS_POOL_MAPS), "-v", str(VERBOSITY_BLOCKERM), |
|
229 |
"-d", "--pidfile", os.path.join(PIDFILE_PATH, "blockerm.pid"), |
|
230 |
"-l", os.path.join(str(LOGS_PATH), "blockerm.log"), |
|
231 |
"-t", "3"], |
|
232 |
"blockerm"] |
|
233 |
elif BLOCKER == "mt-pfiled": |
|
234 |
peer_blockerb = [BLOCKER, |
|
235 |
["-p" , str(BPORT), "-g", str(SPEC), "-n", str(NR_OPS_BLOCKERB), |
|
236 |
"--pithos", str(PITHOS), "--archip", str(FILED_IMAGES), |
|
237 |
"-v", str(VERBOSITY_BLOCKERB), |
|
238 |
"-d", "--pidfile", os.path.join(PIDFILE_PATH, "blockerb.pid"), |
|
239 |
"-l", os.path.join(str(LOGS_PATH), "blockerb.log"), |
|
240 |
"-t", str(NR_OPS_BLOCKERB), "--prefix", "archip_"], |
|
241 |
"blockerb"] |
|
242 |
peer_blockerm = [BLOCKER, |
|
243 |
["-p" , str(MBPORT), "-g", str(SPEC), "-n", str(NR_OPS_BLOCKERM), |
|
244 |
"--pithos", str(PITHOSMAPS), "--archip", str(FILED_MAPS), |
|
245 |
"-v", str(VERBOSITY_BLOCKERM), |
|
246 |
"-d", "--pidfile", os.path.join(PIDFILE_PATH, "blockerm.pid"), |
|
247 |
"-l", os.path.join(str(LOGS_PATH), "blockerm.log"), |
|
248 |
"-t", str(NR_OPS_BLOCKERM), "--prefix", "archip_"], |
|
249 |
"blockerm"] |
|
250 |
else: |
|
251 |
sys.exit(-1) |
|
252 |
|
|
253 |
peer_vlmcd = [VLMC, |
|
254 |
["-t" , "1", "-sp", str(VPORT_START), "-ep", str(VPORT_END), |
|
255 |
"-g", str(SPEC), "-n", str(NR_OPS_VLMC), "-bp", str(BPORT), |
|
256 |
"-mp", str(MPORT), "-d", "-v", str(VERBOSITY_VLMC), |
|
257 |
"--pidfile", os.path.join(PIDFILE_PATH, "vlmcd.pid"), |
|
258 |
"-l", os.path.join(str(LOGS_PATH), "vlmcd.log") |
|
259 |
], "vlmcd"] |
|
260 |
peer_mapperd = [MAPPER, |
|
261 |
["-t" , "1", "-p", str(MPORT), "-mbp", str(MBPORT), |
|
262 |
"-g", str(SPEC), "-n", str(NR_OPS_MAPPER), "-bp", str(BPORT), |
|
263 |
"--pidfile", os.path.join(PIDFILE_PATH, "mapperd.pid"), |
|
264 |
"-v", str(VERBOSITY_MAPPER), "-d", |
|
265 |
"-l", os.path.join(str(LOGS_PATH), "mapperd.log") |
|
266 |
], "mapperd"] |
|
267 |
|
|
268 |
peers = [] |
|
269 |
peers.append(peer_blockerb) |
|
270 |
peers.append(peer_blockerm) |
|
271 |
peers.append(peer_vlmcd) |
|
272 |
peers.append(peer_mapperd) |
|
273 |
|
|
274 |
return peers |
|
275 |
|
|
276 |
|
|
277 |
def exclusive(fn): |
|
278 |
def exclusive_args(args): |
|
279 |
file = "/tmp/vlmc_map.lock" |
|
280 |
while True: |
|
281 |
try: |
|
282 |
fd = os.open(file, os.O_CREAT|os.O_EXCL|os.O_WRONLY) |
|
283 |
break; |
|
284 |
except Exception, reason: |
|
285 |
print >> sys.stderr, reason |
|
286 |
time.sleep(0.05) |
|
287 |
try: |
|
288 |
r = fn(args) |
|
289 |
finally: |
|
290 |
os.close(fd) |
|
291 |
os.unlink(file) |
|
292 |
return r |
|
293 |
|
|
294 |
return exclusive_args |
|
295 |
|
|
296 |
@exclusive |
|
297 |
def vlmc_showmapped(args): |
|
298 |
try: |
|
299 |
devices = os.listdir(os.path.join(XSEGBD_SYSFS, "devices/")) |
|
300 |
except: |
|
301 |
return -1 |
|
302 |
|
|
303 |
if not devices: |
|
304 |
return -1 |
|
305 |
print "id\tpool\timage\tsnap\tdevice" |
|
306 |
try: |
|
307 |
for f in devices: |
|
308 |
d_id = open(XSEGBD_SYSFS + "devices/" + f + "/id").read().strip() |
|
309 |
target = open(XSEGBD_SYSFS + "devices/"+ f + "/target").read().strip() |
|
310 |
|
|
311 |
print "%s\t%s\t%s\t%s\t%s" % (d_id, '-', target, '-', DEVICE_PREFIX + |
|
312 |
d_id) |
|
313 |
except Exception, reason: |
|
314 |
print >> sys.stderr, reason |
|
315 |
return -2 |
|
316 |
return len(devices) |
|
317 |
|
|
318 |
def loadrc(rc): |
|
319 |
try: |
|
320 |
if rc == None: |
|
321 |
execfile(os.path.expanduser(DEFAULTS), globals()) |
|
322 |
else: |
|
323 |
execfile(rc, globals()) |
|
324 |
except: |
|
325 |
print "Cannot read config file" |
|
326 |
sys.exit(1) |
|
327 |
|
|
328 |
if not check_conf(): |
|
329 |
sys.exit(1) |
|
330 |
|
|
331 |
def loaded_modules(): |
|
332 |
lines = open("/proc/modules").read().split("\n") |
|
333 |
modules = [f.split(" ")[0] for f in lines] |
|
334 |
return modules |
|
335 |
|
|
336 |
def loaded_module(name): |
|
337 |
return name in loaded_modules() |
|
338 |
|
|
339 |
def load_module(name): |
|
340 |
modules = loaded_modules() |
|
341 |
if name in modules: |
|
342 |
return 0 |
|
343 |
cmd = ["modprobe -v %s" % name] |
|
344 |
try: |
|
345 |
check_call(cmd, shell=True); |
|
346 |
except Exception: |
|
347 |
sys.stderr.write("Module %s failed to load. \n" % name) |
|
348 |
return -1 |
|
349 |
return 0 |
|
350 |
|
|
351 |
def unload_module(name): |
|
352 |
modules = loaded_modules() |
|
353 |
if name not in modules: |
|
354 |
return 0 |
|
355 |
cmd = ["modprobe -rv %s" % name] |
|
356 |
print cmd |
|
357 |
try: |
|
358 |
check_call(cmd, shell=True); |
|
359 |
except Exception: |
|
360 |
sys.stderr.write("Module %s failed to unload. \n" % name) |
|
361 |
return -1 |
|
362 |
return 0 |
|
363 |
|
|
364 |
def create_segment(): |
|
365 |
#fixme blocking.... |
|
366 |
cmd = ["xseg", str(SPEC), "create"] |
|
367 |
try: |
|
368 |
check_call(cmd, shell=False); |
|
369 |
except Exception: |
|
370 |
sys.stderr.write("Cannot create segment. \n") |
|
371 |
return -1 |
|
372 |
return 0 |
|
373 |
|
|
374 |
def destroy_segment(): |
|
375 |
#fixme blocking.... |
|
376 |
cmd = ["xseg", str(SPEC), "destroy"] |
|
377 |
try: |
|
378 |
check_call(cmd, shell=False); |
|
379 |
except Exception: |
|
380 |
sys.stderr.write("Cannot destroy segment. \n") |
|
381 |
return 0 |
|
382 |
return 0 |
|
383 |
|
|
384 |
def check_running(name, pid = -1): |
|
385 |
for p in psutil.process_iter(): |
|
386 |
if p.name == name: |
|
387 |
if pid != -1: |
|
388 |
if pid == p.pid: |
|
389 |
return pid |
|
390 |
else: |
|
391 |
return pid |
|
392 |
return -1 |
|
393 |
|
|
394 |
def check_pidfile(name): |
|
395 |
pidfile = os.path.join(PIDFILE_PATH, name + ".pid") |
|
396 |
pf = None |
|
397 |
try: |
|
398 |
pf = open(pidfile, "r") |
|
399 |
pid = int(pf.read()) |
|
400 |
pf.close() |
|
401 |
except: |
|
402 |
if pf: |
|
403 |
pf.close() |
|
404 |
return -1 |
|
405 |
|
|
406 |
return pid |
|
407 |
|
|
408 |
def start_peer(peer): |
|
409 |
cmd = [peer[0]] + peer[1] |
|
410 |
try: |
|
411 |
check_call(cmd, shell=False); |
|
412 |
except Exception: |
|
413 |
sys.stderr.write("Peer %s start failed.\n" % peer[0]) |
|
414 |
return -1 |
|
415 |
return 0 |
|
416 |
|
|
417 |
def stop_peer(peer): |
|
418 |
pid = check_pidfile(peer[2]) |
|
419 |
if pid < 0: |
|
420 |
print " process not running" |
|
421 |
return -1 |
|
422 |
|
|
423 |
os.kill(pid, signal.SIGTERM) |
|
424 |
i = 0 |
|
425 |
while check_running(peer[0], pid) > 0: |
|
426 |
time.sleep(0.1) |
|
427 |
i += 1 |
|
428 |
if i > 150: |
|
429 |
print "process did not die in 15 secs" |
|
430 |
return -1 |
|
431 |
return 0 |
|
432 |
|
|
433 |
def peer_running(peer): |
|
434 |
pid = check_pidfile(peer[2]) |
|
435 |
if pid < 0: |
|
436 |
return -1 |
|
437 |
|
|
438 |
r = check_running(peer[0], pid) |
|
439 |
if r < 0: |
|
440 |
print "Peer " + peer[2] + " has valid pidfile but does not seem to be active" |
|
441 |
return 0 |
|
442 |
|
|
443 |
|
|
444 |
def make_segdev(): |
|
445 |
try: |
|
446 |
os.stat(str(CHARDEV_NAME)) |
|
447 |
return -2 |
|
448 |
except: |
|
449 |
pass |
|
450 |
cmd = ["mknod", str(CHARDEV_NAME), "c", str(CHARDEV_MAJOR), str(CHARDEV_MINOR)] |
|
451 |
print ' '.join(cmd) |
|
452 |
try: |
|
453 |
check_call(cmd, shell=False); |
|
454 |
except Exception: |
|
455 |
sys.stderr.write("Segdev device creation failed. \n") |
|
456 |
return -1 |
|
457 |
return 0 |
|
458 |
|
|
459 |
def remove_segdev(): |
|
460 |
try: |
|
461 |
os.stat(str(CHARDEV_NAME)) |
|
462 |
except: |
|
463 |
return -2 |
|
464 |
try: |
|
465 |
os.unlink(str(CHARDEV_NAME)) |
|
466 |
except: |
|
467 |
sys.stderr.write("Segdev device removal failed. \n") |
|
468 |
return -1 |
|
469 |
|
|
470 |
|
|
471 |
def start(args): |
|
472 |
if status(args) > 0: |
|
473 |
return -1 |
|
474 |
|
|
475 |
for m in modules: |
|
476 |
if load_module(m) < 0: |
|
477 |
stop(args) |
|
478 |
return -1 |
|
479 |
time.sleep(0.5) |
|
480 |
|
|
481 |
if make_segdev() < 0: |
|
482 |
stop(args) |
|
483 |
return -1 |
|
484 |
|
|
485 |
time.sleep(0.5) |
|
486 |
|
|
487 |
if create_segment() < 0: |
|
488 |
stop(args) |
|
489 |
return -1 |
|
490 |
|
|
491 |
time.sleep(0.5) |
|
492 |
|
|
493 |
for p in peers: |
|
494 |
if start_peer(p) < 0: |
|
495 |
stop(args) |
|
496 |
return -1 |
|
497 |
|
|
498 |
|
|
499 |
if load_module(xsegbd) < 0: |
|
500 |
stop(args) |
|
501 |
return -1 |
|
502 |
return 0 |
|
503 |
|
|
504 |
def stop(args): |
|
505 |
#check devices |
|
506 |
if vlmc_showmapped(args) > 0: |
|
507 |
print "Cannot stop archipelago. Mapped volumes exist" |
|
508 |
return -1 |
|
509 |
if unload_module(xsegbd): |
|
510 |
return -1 |
|
511 |
r = 0 |
|
512 |
for p in reversed(peers): |
|
513 |
stop_peer(p) |
|
514 |
|
|
515 |
remove_segdev() |
|
516 |
|
|
517 |
for m in reversed(modules): |
|
518 |
unload_module(m) |
|
519 |
return 0 |
|
520 |
|
|
521 |
def status(args): |
|
522 |
r = 0 |
|
523 |
if vlmc_showmapped(args) >= 0: |
|
524 |
r += 1 |
|
525 |
if loaded_module(xsegbd): |
|
526 |
print "Xsegbd loaded" |
|
527 |
r += 1 |
|
528 |
else: |
|
529 |
print "Xsegbd not loaded" |
|
530 |
for m in reversed(modules): |
|
531 |
if loaded_module(m): |
|
532 |
print m + " loaded" |
|
533 |
r += 1 |
|
534 |
else: |
|
535 |
print m + " not loaded" |
|
536 |
for p in reversed(peers): |
|
537 |
if peer_running(p) < 0: |
|
538 |
print p[0] + " not running" |
|
539 |
else: |
|
540 |
print p[0] + " running" |
|
541 |
r += 1 |
|
542 |
return r |
|
543 |
|
|
544 |
def restart(args): |
|
545 |
r = stop(args) |
|
546 |
if r < 0: |
|
547 |
return r |
|
548 |
return start(args) |
|
549 |
|
|
550 |
if __name__ == "__main__": |
|
551 |
# parse arguments and discpatch to the correct func |
|
552 |
parser = argparse.ArgumentParser(description='Archipelago tool') |
|
553 |
parser.add_argument('-c', '--config', type=str, nargs='?', help='config file') |
|
554 |
subparsers = parser.add_subparsers() |
|
555 |
|
|
556 |
start_parser = subparsers.add_parser('start', help='Start archipelago') |
|
557 |
start_parser.set_defaults(func=start) |
|
558 |
|
|
559 |
stop_parser = subparsers.add_parser('stop', help='Stop archipelago') |
|
560 |
stop_parser.set_defaults(func=stop) |
|
561 |
|
|
562 |
status_parser = subparsers.add_parser('status', help='Archipelago status') |
|
563 |
status_parser.set_defaults(func=status) |
|
564 |
|
|
565 |
restart_parser = subparsers.add_parser('restart', help='Restart archipelago') |
|
566 |
restart_parser.set_defaults(func=restart) |
|
567 |
|
|
568 |
args = parser.parse_args() |
|
569 |
loadrc(args.config) |
|
570 |
peers = construct_peers() |
|
571 |
sys.exit(args.func(args)) |
Also available in: Unified diff