#!/usr/bin/env python # # vlmc tool import os, sys, subprocess, argparse, time from subprocess import call, check_call def vlmc_create(args): name = args.name[0] size = args.size snap = args.snap if size == None and snap == None: print >> sys.stderr, "At least one of the size/snap args must be provided" sys.exit(-1) if size: size = size << 20 else: size = 0 cmd = [XSEG_HOME + "/peers/user/vlmc-xseg", "%s" % SPEC, "create", "--name", "%s" % name] if snap != None: cmd.extend(["--snap", "%s" % snap]) if size != None: cmd.extend(["--size", "%s" % size]) cmd.extend(["-mp", "%s" % MPORT]) cmd.extend(["-p", "%s" % VTOOL]) os.environ['LD_LIBRARY_PATH'] = XSEG_HOME + "/lib:" + XSEG_HOME + "/lib/user" try: check_call(cmd, shell=False, env=os.environ); except Exception: sys.stderr.write("vlmc creation failed\n") sys.exit(-1) def vlmc_snapshot(args): # snapshot return def vlmc_list(args): # list return def vlmc_remove(args): name = args.name[0] cmd = [XSEG_HOME + "/peers/user/vlmc-xseg", "%s" % SPEC, "remove", "--name", "%s" % name] cmd.extend(["-mp", "%s" % MPORT]) cmd.extend(["-p", "%s" % VTOOL]) os.environ['LD_LIBRARY_PATH'] = XSEG_HOME + "/lib:" + XSEG_HOME + "/lib/user" try: check_call(cmd, shell=False, env=os.environ); except Exception: sys.stderr.write("vlmc removal failed\n") sys.exit(-1) def xsegbd_loaded(): try: os.stat("/sys/bus/xsegbd") except Exception, reason: print >> sys.stderr, reason sys.exit(-1) 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_map(args): xsegbd_loaded() name = args.name[0] prev = 3 try: result = [int(open(XSEGBD_SYSFS + "devices/" + f + "/srcport").read().strip()) for f in os.listdir(XSEGBD_SYSFS + "devices/")] result.sort() for p in result: if p - prev > 1: break else: prev = p port = prev + 1 fd = os.open(XSEGBD_SYSFS + "add", os.O_WRONLY) print >> sys.stderr, "write to %s : %s %d:%d:%d" %( XSEGBD_SYSFS + "add", name, port, port + VPORT_START -4, REQS ) os.write(fd, "%s %d:%d:%d" % (name, port, port + VPORT_START-4, REQS)) os.close(fd) except Exception, reason: print >> sys.stderr, reason sys.exit(-1) @exclusive def vlmc_unmap(args): xsegbd_loaded() device = args.name[0] try: for f in os.listdir(XSEGBD_SYSFS + "devices/"): d_id = open(XSEGBD_SYSFS + "devices/" + f + "/id").read().strip() name = open(XSEGBD_SYSFS + "devices/"+ f + "/target").read().strip() if device == DEVICE_PREFIX + d_id: fd = os.open(XSEGBD_SYSFS + "remove", os.O_WRONLY) os.write(fd, d_id) os.close(fd) sys.exit(0) print >> sys.stderr, "Device %s doesn't exist" % device sys.exit(-1) except Exception, reason: print >> sys.stderr, reason sys.exit(-1) @exclusive def vlmc_showmapped(args): xsegbd_loaded() 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) # FIXME: def vlmc_resize(args): xsegbd_loaded() name = args.name[0] size = args.size[0] try: for f in os.listdir(XSEGBD_SYSFS + "devices/"): d_id = open(XSEGBD_SYSFS + "devices/" + f + "/id").read().strip() d_name = open(XSEGBD_SYSFS + "devices/"+ f + "/name").read().strip() if name == d_name: fd = os.open(XSEGBD_SYSFS + "devices/" + d_id +"/refresh", os.O_WRONLY) os.write(fd, "1") os.close(fd) sys.exit(0) except Exception, reason: print >> sys.stderr, reason sys.exit(-1) def loadrc(rc): #FIXME try: if rc == None: execfile(os.path.expanduser("/etc/defaut/archipelago"), globals()) else: execfile(rc, globals()) except: pass 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() create_parser = subparsers.add_parser('create', help='Create volume') #group = create_parser.add_mutually_exclusive_group(required=True) create_parser.add_argument('-s', '--size', type=int, nargs='?', help='requested size in MB for create') create_parser.add_argument('--snap', type=str, nargs='?', help='create from snapshot') create_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd') create_parser.add_argument('name', type=str, nargs=1, help='volume/device name') create_parser.set_defaults(func=vlmc_create) remove_parser = subparsers.add_parser('remove', help='Delete volume') remove_parser.add_argument('name', type=str, nargs=1, help='volume/device name') remove_parser.set_defaults(func=vlmc_remove) remove_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd') rm_parser = subparsers.add_parser('rm', help='Delete volume') rm_parser.add_argument('name', type=str, nargs=1, help='volume/device name') rm_parser.set_defaults(func=vlmc_remove) rm_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd') map_parser = subparsers.add_parser('map', help='Map volume') map_parser.add_argument('name', type=str, nargs=1, help='volume/device name') map_parser.set_defaults(func=vlmc_map) map_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd') unmap_parser = subparsers.add_parser('unmap', help='Unmap volume') unmap_parser.add_argument('name', type=str, nargs=1, help='volume/device name') unmap_parser.set_defaults(func=vlmc_unmap) unmap_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd') showmapped_parser = subparsers.add_parser('showmapped', help='Show mapped volumes') showmapped_parser.set_defaults(func=vlmc_showmapped) showmapped_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd') list_parser = subparsers.add_parser('list', help='List volumes') list_parser.set_defaults(func=vlmc_list) list_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd') ls_parser = subparsers.add_parser('ls', help='List volumes') ls_parser.set_defaults(func=vlmc_list) ls_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd') resize_parser = subparsers.add_parser('resize', help='Resize volume') resize_parser.add_argument('-s', '--size', type=int, nargs=1, help='requested size in MB for resize') resize_parser.add_argument('name', type=str, nargs=1, help='volume/device name') resize_parser.set_defaults(func=vlmc_resize) resize_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd') args = parser.parse_args() loadrc(args.config) args.func(args)