#!/usr/bin/env python # # archipelagos tool import os, sys, subprocess, argparse, time, psutil, signal from subprocess import call, check_call BIN_PATH="/usr/bin" MAPPER="mt-mapperd" VLMC="st-vlmcd" BLOCKER="pfiled" PIDFILE_PATH="/var/run/archipelagos" CHARDEV_NAME="/dev/segdev" CHARDEV_MAJOR="60" CHARDEV_MINOR="0" try: execfile(os.path.expanduser("/etc/default/archipelagos"), globals()) except: pass #FIXME check defaults peer_blockerb = [BLOCKER, ["-p" , str(BPORT), "-g", str(SPEC), "-n", str(NR_OPS), str(PITHOS), str(IMAGES), "-d", "--pidfile", os.path.join(PIDFILE_PATH, "blockerd.pid")], "blockerb"] peer_blockerm = [BLOCKER, ["-p" , str(MBPORT), "-g", str(SPEC), "-n", str(NR_OPS), str(PITHOSMAPS), str(MAPS), "-d", "--pidfile", os.path.join(PIDFILE_PATH, "blockerm.pid")], "blockerm" ] peer_vlmcd = [VLMC, ["-t" , "1", "-sp", str(VPORT_START), "-ep", str(VPORT_END), "-g", str(SPEC), "-n", str(NR_OPS), "-bp", str(BPORT), "-mp", str(MPORT), "-d", "--pidfile", os.path.join(PIDFILE_PATH, "vlmcd.pid")], "vlmcd"] peer_mapperd = [MAPPER, ["-t" , "1", "-p", str(MPORT), "-mbp", str(MBPORT), "-g", str(SPEC), "-n", str(NR_OPS), "-bp", str(BPORT), "-d", "--pidfile", os.path.join(PIDFILE_PATH, "mapper.pid")], "mapper"] #peers = [peer_blockerb, peer_blockerm, peer_vlmcd, peer_mapperd] peers = [peer_vlmcd, peer_mapperd] modules = ["xseg", "segdev", "xseg_posix", "xseg_pthread", "xseg_segdev"] xsegbd = "xsegbd" def exclusive(fn): def exclusive_args(args): file = "/tmp/vlmc_map.lock" while True: try: fd = os.open(file, os.O_CREAT|os.O_EXCL|os.O_WRONLY) break; except Exception, reason: print >> sys.stderr, reason time.sleep(0.05) try: fn(args) finally: os.close(fd) os.unlink(file) return exclusive_args @exclusive def vlmc_showmapped(args): print "id\tpool\timage\tsnap\tdevice" try: for f in os.listdir(XSEGBD_SYSFS + "devices/"): d_id = open(XSEGBD_SYSFS + "devices/" + f + "/id").read().strip() target = open(XSEGBD_SYSFS + "devices/"+ f + "/target").read().strip() print "%s\t%s\t%s\t%s\t%s" % (d_id, '-', target, '-', DEVICE_PREFIX + d_id) except Exception, reason: print >> sys.stderr, reason sys.exit(-1) def loadrc(rc): #FIXME #check config file sanity try: if rc == None: execfile(os.path.expanduser("/etc/default/archipelagos"), globals()) else: execfile(rc, globals()) except: pass def loaded_modules(): lines = open("/proc/modules").read().split("\n") modules = [f.split(" ")[0] for f in lines] return modules def load_module(name): modules = loaded_modules() if name in modules: return 0 cmd = ["modprobe -v %s" % name] print cmd try: check_call(cmd, shell=True); except Exception: sys.stderr.write("Module %s failed to load. \n" % name) return -1 return 0 def unload_module(name): modules = loaded_modules() if name not in modules: return 0 cmd = ["modprobe -rv %s" % name] print cmd try: check_call(cmd, shell=True); except Exception: sys.stderr.write("Module %s failed to unload. \n" % name) return -1 return 0 def create_segment(): #fixme blocking.... cmd = ["xseg", str(SPEC), "create"] try: check_call(cmd, shell=False); except Exception: sys.stderr.write("Cannot create segment. \n") return -1 return 0 def destroy_segment(): #fixme blocking.... cmd = ["xseg", str(SPEC), "destroy"] try: check_call(cmd, shell=False); except Exception: sys.stderr.write("Cannot destroy segment. \n") return 0 return 0 def check_running(name, pid = -1): for p in psutil.process_iter(): if p.name == name: if pid != -1: if pid != p.pid: return -1 else: return pid return -1 def check_pidfile(name): pidfile = os.path.join(PIDFILE_PATH, name + ".pid") pf = None try: pf = open(pidfile, "r") pid = int(pf.read()) pf.close() except: if pf: pf.close() return -1 return pid def start_peer(peer): cmd = [peer[0]] + peer[1] try: check_call(cmd, shell=False); except Exception: sys.stderr.write("Peer %s start failed.\n" % peer[0]) return -1 return 0 def stop_peer(peer): pid = check_pidfile(peer[2]) if pid < 0: print " process not running" return -1 os.kill(pid, signal.SIGTERM) i = 0 while check_running(peer[0], pid) > 0: time.sleep(0.1) i += 1 if i > 100: print "process did not die in 10 secs" return -1 return 0 def make_segdev(): try: os.stat(str(CHARDEV_NAME)) return -2 except: pass cmd = ["mknod", str(CHARDEV_NAME), "c", str(CHARDEV_MAJOR), str(CHARDEV_MINOR)] print cmd try: check_call(cmd, shell=False); except Exception: sys.stderr.write("Segdev %s device creation failed. \n") return -1 return 0 def remove_segdev(): try: os.stat(str(CHARDEV_NAME)) except: return -2 try: os.unlink(str(CHARDEV_NAME)) except: sys.stderr.write("Segdev %s device removal failed. \n") return -1 def start(args): #if sth running or loaded # return -1 for m in modules: if load_module(m) < 0: stop(args) return -1 time.sleep(0.5) if make_segdev() < 0: stop(args) return -1 time.sleep(0.5) if create_segment() < 0: stop(args) return -1 time.sleep(0.5) for p in peers: if start_peer(p) < 0: stop(args) return -1 if load_module(xsegbd) < 0: stop(args) return -1 return 0 def stop(args): #check devices if unload_module(xsegbd): return -1 for p in reversed(peers): stop_peer(p) #destroy segment with timeout # if destroy_segment() < 0: # return -1 remove_segdev() for m in reversed(modules): unload_module(m) if __name__ == "__main__": # parse arguments and discpatch to the correct func parser = argparse.ArgumentParser(description='vlmc tool') parser.add_argument('-c', '--config', type=str, nargs='?', help='config file') subparsers = parser.add_subparsers() start_parser = subparsers.add_parser('start', help='Resize volume') start_parser.set_defaults(func=start) start_parser = subparsers.add_parser('stop', help='Resize volume') start_parser.set_defaults(func=stop) args = parser.parse_args() args.func(args)