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