Merge branch 'xseg-refactor' into debian
[archipelago] / xseg / tools / vlmc
1 #!/usr/bin/env python
2 #
3 # vlmc tool
4
5 import os, sys, subprocess, argparse, time
6 from subprocess import call, check_call
7
8 def vlmc_create(args):
9     name = args.name[0]
10     size = args.size 
11     snap = args.snap
12
13     if size == None and snap == None:
14         print >> sys.stderr, "At least one of the size/snap args must be provided"
15         sys.exit(-1)
16
17     if size:
18         size = size << 20
19     else:
20         size = 0
21
22     cmd = ["vlmc-xseg", "%s" % SPEC, "create", "--name", "%s" % name]
23     if snap != None:
24             cmd.extend(["--snap", "%s" % snap])
25     if size != None:
26             cmd.extend(["--size", "%s" % size])
27     cmd.extend(["-mp", "%s" % MPORT])
28     cmd.extend(["-p", "%s" % VTOOL])
29
30     try:
31         check_call(cmd, shell=False, env=os.environ);
32     except Exception:
33             sys.stderr.write("vlmc creation failed\n")
34             sys.exit(-1)
35     
36
37 def vlmc_snapshot(args):
38     # snapshot
39     return
40
41 def vlmc_list(args):
42     # list
43     return
44
45 def vlmc_remove(args):
46     name = args.name[0]
47     cmd = ["vlmc-xseg", "%s" % SPEC, "remove", "--name", "%s" % name]
48     cmd.extend(["-mp", "%s" % MPORT])
49     cmd.extend(["-p", "%s" % VTOOL])
50
51     try:
52         check_call(cmd, shell=False, env=os.environ);
53     except Exception:
54             sys.stderr.write("vlmc removal failed\n")
55             sys.exit(-1)
56
57
58 def xsegbd_loaded():
59     try:
60         os.stat("/sys/bus/xsegbd")
61     except Exception, reason:
62         print >> sys.stderr, reason
63         sys.exit(-1)
64
65 def exclusive(fn):
66     def exclusive_args(args):
67         file = "/tmp/vlmc_map.lock"
68         while True:
69             try:
70                 fd = os.open(file, os.O_CREAT|os.O_EXCL|os.O_WRONLY)
71                 break;
72             except Exception, reason:
73                 print >> sys.stderr, reason
74                 time.sleep(0.05)
75         try:
76             fn(args)
77         finally:
78             os.close(fd)
79             os.unlink(file)
80
81     return exclusive_args
82
83 @exclusive
84 def vlmc_map(args):
85     xsegbd_loaded()
86     name = args.name[0]
87     prev = 3
88     try:
89         result = [int(open(XSEGBD_SYSFS + "devices/" + f + "/srcport").read().strip()) for f in os.listdir(XSEGBD_SYSFS + "devices/")]
90         result.sort()
91
92         for p in result:
93             if p - prev > 1:
94                break
95             else:
96                prev = p
97
98         port = prev + 1
99         fd = os.open(XSEGBD_SYSFS + "add", os.O_WRONLY)
100         print >> sys.stderr, "write to %s : %s %d:%d:%d" %( XSEGBD_SYSFS + "add", name, port, port + VPORT_START -4, REQS )
101         os.write(fd, "%s %d:%d:%d" % (name, port, port + VPORT_START-4, REQS))
102         os.close(fd)
103     except Exception, reason:
104         print >> sys.stderr, reason
105         sys.exit(-1)
106
107 @exclusive
108 def vlmc_unmap(args):
109     xsegbd_loaded()
110     device = args.name[0]
111     try:
112         for f in os.listdir(XSEGBD_SYSFS + "devices/"):
113             d_id = open(XSEGBD_SYSFS + "devices/" + f + "/id").read().strip()
114             name = open(XSEGBD_SYSFS + "devices/"+ f + "/target").read().strip()
115             if device == DEVICE_PREFIX + d_id:
116                 fd = os.open(XSEGBD_SYSFS + "remove", os.O_WRONLY)
117                 os.write(fd, d_id)
118                 os.close(fd)
119
120                 sys.exit(0)
121         print >> sys.stderr, "Device %s doesn't exist" % device
122         sys.exit(-1)
123     except Exception, reason:
124         print >> sys.stderr, reason
125         sys.exit(-1)
126
127 @exclusive
128 def vlmc_showmapped(args):
129     xsegbd_loaded()
130     print "id\tpool\timage\tsnap\tdevice"
131     try:
132         for f in os.listdir(XSEGBD_SYSFS + "devices/"):
133             d_id = open(XSEGBD_SYSFS + "devices/" + f + "/id").read().strip()
134             target = open(XSEGBD_SYSFS + "devices/"+ f + "/target").read().strip()
135
136             print "%s\t%s\t%s\t%s\t%s" % (d_id, '-', target, '-', DEVICE_PREFIX +
137             d_id)
138     except Exception, reason:
139         print >> sys.stderr, reason
140         sys.exit(-1)
141
142 # FIXME:
143 def vlmc_resize(args):
144     xsegbd_loaded()
145
146     name = args.name[0]
147     size = args.size[0]
148
149     try:
150
151         for f in os.listdir(XSEGBD_SYSFS + "devices/"):
152             d_id = open(XSEGBD_SYSFS + "devices/" + f + "/id").read().strip()
153             d_name = open(XSEGBD_SYSFS + "devices/"+ f + "/name").read().strip()
154             if name == d_name:
155                 fd = os.open(XSEGBD_SYSFS + "devices/" +  d_id +"/refresh", os.O_WRONLY)
156                 os.write(fd, "1")
157                 os.close(fd)
158
159         sys.exit(0)
160     except Exception, reason:
161         print >> sys.stderr, reason
162         sys.exit(-1)
163
164 def loadrc(rc):
165     #FIXME
166     try:
167         if rc == None:
168             execfile(os.path.expanduser("/etc/default/archipelago"), globals())
169         else:
170             execfile(rc, globals())
171     except:
172         pass
173
174 if __name__ == "__main__":
175     # parse arguments and discpatch to the correct func
176     parser = argparse.ArgumentParser(description='vlmc tool')
177     parser.add_argument('-c', '--config', type=str, nargs='?', help='config file')
178     subparsers = parser.add_subparsers()
179
180     create_parser = subparsers.add_parser('create', help='Create volume')
181     #group = create_parser.add_mutually_exclusive_group(required=True)
182     create_parser.add_argument('-s', '--size', type=int, nargs='?', help='requested size in MB for create')
183     create_parser.add_argument('--snap', type=str, nargs='?', help='create from snapshot')
184     create_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
185     create_parser.add_argument('name', type=str, nargs=1, help='volume/device name')
186     create_parser.set_defaults(func=vlmc_create)
187
188     remove_parser = subparsers.add_parser('remove', help='Delete volume')
189     remove_parser.add_argument('name', type=str, nargs=1, help='volume/device name')
190     remove_parser.set_defaults(func=vlmc_remove)
191     remove_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
192
193     rm_parser = subparsers.add_parser('rm', help='Delete volume')
194     rm_parser.add_argument('name', type=str, nargs=1, help='volume/device name')
195     rm_parser.set_defaults(func=vlmc_remove)
196     rm_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
197
198     map_parser = subparsers.add_parser('map', help='Map volume')
199     map_parser.add_argument('name', type=str, nargs=1, help='volume/device name')
200     map_parser.set_defaults(func=vlmc_map)
201     map_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
202
203     unmap_parser = subparsers.add_parser('unmap', help='Unmap volume')
204     unmap_parser.add_argument('name', type=str, nargs=1, help='volume/device name')
205     unmap_parser.set_defaults(func=vlmc_unmap)
206     unmap_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
207
208     showmapped_parser = subparsers.add_parser('showmapped', help='Show mapped volumes')
209     showmapped_parser.set_defaults(func=vlmc_showmapped)
210     showmapped_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
211
212     list_parser = subparsers.add_parser('list', help='List volumes')
213     list_parser.set_defaults(func=vlmc_list)
214     list_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
215
216     ls_parser = subparsers.add_parser('ls', help='List volumes')
217     ls_parser.set_defaults(func=vlmc_list)
218     ls_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
219
220     resize_parser = subparsers.add_parser('resize', help='Resize volume')
221     resize_parser.add_argument('-s', '--size', type=int, nargs=1, help='requested size in MB for resize')
222     resize_parser.add_argument('name', type=str, nargs=1, help='volume/device name')
223     resize_parser.set_defaults(func=vlmc_resize)
224     resize_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
225
226     args = parser.parse_args()
227     loadrc(args.config)
228     args.func(args)