fix mt-mapperd pithos read bug. plus some minor fixes
[archipelago] / xseg / peers / user / vlmc-tool.c
1 #define _GNU_SOURCE
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <stdint.h>
6 #include <ctype.h>
7 #include <sys/stat.h>
8 #include <sys/types.h>
9 #include <fcntl.h>
10 #include <unistd.h>
11
12 #include <xseg/xseg.h>
13 #include <xseg/protocol.h>
14
15 #define MAX_ARG_LEN 255
16 int safe_strlen(char *s)
17 {
18         int i;
19         if (!s)
20                 return -1;
21
22         for (i = 0; i < MAX_ARG_LEN; i++) {
23                 if (!*s) 
24                         return i;
25                 s++;
26         }
27         return -1;
28 }
29
30 int validate_alphanumeric(char *s)
31 {
32         int i;
33         int len = safe_strlen(s);
34         if (len < 0){
35                 return 0;
36         }
37
38         for (i = 0; i < len; i++) {
39                 if (!isalnum(*s)&&*s!='-'&&*s!='.')
40                         return 0;
41                 s++;
42         }
43         return 1;
44 }
45
46 int validate_numeric(char *s)
47 {
48         int i;
49         int len = safe_strlen(s);
50         if (len < 0)
51                 return 0;
52
53         for (i = 0; i < len; i++) {
54                 if (!isdigit(*s))
55                         return 0;
56                 s++;
57         }
58         return 1;
59 }
60
61 char *spec = "segdev:xsegbd:16:1024:12";
62 struct xseg *xseg;
63 struct xseg_config cfg;
64 xport srcport = NoPort;
65 xport sport = NoPort;
66 struct xseg_port *port;
67 xport mportno;
68
69 static void init_local_signal() 
70 {
71         if (xseg && sport != srcport){
72                 xseg_init_local_signal(xseg, srcport);
73                 sport = srcport;
74         }
75 }
76
77 int wait_reply(struct xseg_request *expected_req)
78 {
79         struct xseg_request *rec;
80         xseg_prepare_wait(xseg, srcport);
81         while(1) {
82                 rec = xseg_receive(xseg, srcport);
83                 if (rec) {
84                         if (rec != expected_req) {
85                                 fprintf(stderr, "Unknown received req. Putting req.\n");
86                                 xseg_put_request(xseg, rec, srcport);
87                         } else  if (!(rec->state & XS_SERVED)) {
88                                 fprintf(stderr, "Failed req\n");
89                                 return -1;
90                         } else {
91                                 break;
92                         }
93                 }
94                 xseg_wait_signal(xseg, 1000000UL);
95         }
96         xseg_cancel_wait(xseg, srcport);
97
98         return 0;
99 }
100
101 int vlmc_create(char *name, uint64_t size, char *snap)
102 {
103         int targetlen = safe_strlen(name);
104         int snaplen = safe_strlen(snap);
105         if (targetlen <= 0) {
106                 fprintf(stderr, "Invalid name\n");
107                 return -1;
108         }
109         if (snaplen <= 0 && size == -1) {
110                 fprintf(stderr, "Size or snap must be provided in create\n");
111                 return -1;
112         }
113
114         struct xseg_request *req = xseg_get_request(xseg, srcport, mportno, X_ALLOC);
115         if (!req) {
116                 fprintf(stderr, "Couldn't allocate xseg request\n");
117                 return -1;
118         }
119         int r = xseg_prep_request(xseg, req, targetlen, sizeof(struct xseg_request_clone));
120         if (r < 0){
121                 fprintf(stderr, "Couldn't prep xseg request\n");
122                 xseg_put_request(xseg, req, srcport);
123                 return -1;
124         }
125         char *target = xseg_get_target(xseg, req);
126         strncpy(target, name, targetlen);
127         struct xseg_request_clone *xclone = (struct xseg_request_clone *) xseg_get_data(xseg, req);
128         if (snaplen < 0)
129                 memset(xclone->target, 0, XSEG_MAX_TARGETLEN);
130         else {
131                 strncpy(xclone->target, snap, snaplen);
132                 xclone->target[snaplen] = 0;
133         }
134         xclone->size = size;
135         req->offset = 0;
136         req->size = req->datalen;
137         req->op = X_CLONE;
138
139         xport p = xseg_submit(xseg, req, srcport, X_ALLOC);
140         if (p == NoPort){
141                 fprintf(stderr, "couldn't submit req\n");
142                 xseg_put_request(xseg, req, srcport);
143                 return -1;
144         }
145         xseg_signal(xseg, p);
146
147         wait_reply(req);
148         
149         xseg_put_request(xseg, req, srcport);
150
151         return 0;
152 }
153
154 int vlmc_snapshot(char *name)
155 {
156         return -1;
157 }
158
159 int vlmc_remove(char *name)
160 {
161         int targetlen = safe_strlen(name);
162         if (targetlen <= 0) {
163                 fprintf(stderr, "Invalid name\n");
164                 return -1;
165         }
166
167         struct xseg_request *req = xseg_get_request(xseg, srcport, mportno, X_ALLOC);
168         if (!req) {
169                 fprintf(stderr, "Couldn't allocate xseg request\n");
170                 return -1;
171         }
172         int r = xseg_prep_request(xseg, req, targetlen, 0);
173         if (r < 0){
174                 fprintf(stderr, "Couldn't prep xseg request\n");
175                 xseg_put_request(xseg, req, srcport);
176                 return -1;
177         }
178         char *target = xseg_get_target(xseg, req);
179         strncpy(target, name, targetlen);
180         target[targetlen] = 0;
181         req->offset = 0;
182         req->size = req->datalen;
183         req->op = X_DELETE;
184         
185         xport p = xseg_submit(xseg, req, srcport, X_ALLOC);
186         if (p == NoPort){
187                 fprintf(stderr, "couldn't submit req\n");
188                 xseg_put_request(xseg, req, srcport);
189                 return -1;
190         }
191         xseg_signal(xseg, p);
192         
193         wait_reply(req);
194         
195         xseg_put_request(xseg, req, srcport);
196
197         return 0;
198 }
199
200 int vlmc_resize(char *name, uint64_t size)
201 {
202         return 0;
203 }
204
205 int vlmc_map(char *name)
206 {
207         /*
208         char cmd[1024];
209         char buf[1024];
210         int fd;
211         xport p;
212
213
214         for (p = 2; p < cfg.nr_ports; p++) {
215                 sprintf(buf, "%sdevices/%u/srcport", XSEGBD_SYSFS, p);
216                 fd = open(buf, O_RDONLY);
217                 if (fd < 0 && errno == ENOENT)
218                         break;
219         }
220         if (p == cfg.nr_ports){
221                 fprintf(stderr, "No available port\n");
222                 return -1;
223         }
224
225         sprintf(cmd, "%s %u:%u:%u", name, p, VPORT, REQS);      
226         sprintf(buf, "%sadd", XSEGBD_SYSFS);
227         fd = open(add, O_WRONLY);
228         if (fd < 0) {
229                 fprintf(stderr, "Cannot open sysfs add\n");
230                 return -1;
231         }
232         r = write(fd, cmd, strlen(cmd));
233         if (r < 0){
234                 fprintf(stderr, "write error\n");
235                 return -1;
236         }
237         */
238
239         return 0;
240 }
241
242 int vlmc_unmap(char *name)
243 {
244         return 0;
245 }
246
247 int vlmc_list()
248 {
249         return 0;
250 }
251
252 #define err_in_arg(__i, __arg) do {                                     \
253         fprintf(stderr, "Error in argument %d (%s)\n", __i, __arg);     \
254         exit(-1);                                                       \
255         } while(0)
256
257 int main(int argc, const char *argv[])
258 {
259         int i;
260         if (argc < 6){
261                 fprintf(stderr, "insufficient arguments\n");
262                 return -1;
263         }
264
265         spec = argv[1];
266         if (xseg_parse_spec(spec, &cfg)) {
267                 fprintf(stderr, "Cannot parse spec\n");
268                 return -1;
269         }
270
271         if (xseg_initialize()) {
272                 fprintf(stderr, "cannot initialize!\n");
273                 return -1;
274         }
275
276         xseg = xseg_join(cfg.type, cfg.name, "posix", NULL);
277         if (!xseg) {
278                 fprintf(stderr, "cannot join segment!\n");
279                 return -1;
280         }
281         init_local_signal();
282
283         char *name = NULL;
284         char *snap = NULL;
285         uint64_t size = -1;
286         char *pool = NULL;
287         char *config = NULL;
288
289         for (i = 3; i < argc; i++) {
290                 if ((!strcmp(argv[i], "-s") || !strcmp(argv[i], "--size")) && i+1 < argc){
291                         if (!validate_numeric(argv[i+1])){
292                                 err_in_arg(i, argv[i]);
293                         } else {
294                                 size = atol(argv[i+1]);
295                                 i++;
296                         }
297                 }else if ((!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config")) && i+1 < argc){
298                         if (!validate_alphanumeric(argv[i+1])){
299                                 err_in_arg(i, argv[i]);
300                         } else {
301                                 config = argv[i+1];
302                                 i++;
303                         }
304                 } else if (!strcmp(argv[i], "--snap") && i+1 < argc){
305                         if (!validate_alphanumeric(argv[i+1])){
306                                 err_in_arg(i, argv[i]);
307                         } else {
308                                 snap = argv[i+1];
309                                 i++;
310                         }
311                 } else if (!strcmp(argv[i], "-mp") && i+1 < argc){
312                         if (!validate_numeric(argv[i+1])){
313                                 err_in_arg(i, argv[i]);
314                         } else {
315                                 mportno = atol(argv[i+1]);
316                                 i++;
317                         }
318                 } else if (!strcmp(argv[i], "-p") && i+1 < argc){
319                         if (!validate_alphanumeric(argv[i+1])){
320                                 err_in_arg(i, argv[i]);
321                         } else {
322                                 srcport = atol(argv[i+1]);
323                                 i++;
324                         }
325                 } else if (!strcmp(argv[i], "--name") && i+1 < argc){
326                         if (!validate_alphanumeric(argv[i+1])){
327                                 err_in_arg(i, argv[i]);
328                         } else {
329                                 name = argv[i+1];
330                                 i++;
331                         }
332                 } else {
333                         err_in_arg(i, argv[i]);
334                 }
335         }
336
337         if (srcport > cfg.nr_ports || mportno > cfg.nr_ports) {
338                 fprintf(stderr, "Invalid port\n");
339                 return -1;
340         }
341
342         port = xseg_bind_port(xseg, srcport);
343         if (!port) {
344                 fprintf(stderr, "Error binding port %u\n", srcport);
345                 exit(-1);
346         }
347
348         int ret = -1;
349
350         if (!strcmp(argv[2], "create")) 
351                 ret = vlmc_create(name, size, snap);
352         else if (!strcmp(argv[2], "remove"))
353                 ret = vlmc_remove(name);
354 /*
355         else if (!strcmp(argv[2], "map"))
356                 ret = vlmc_map(name);
357         else if (!strcmp(argv[2], "unmap"))
358                 ret = vlmc_unmap(name);
359         else if (!strcmp(argv[2], "showmapped"))
360                 ret = vlmc_showmapped();
361         else if (!strcmp(argv[2], "list") || !(strcmp(argv[2], "ls"))
362                 ret = vlmc_list();
363 */
364         else if (!strcmp(argv[2], "resize"))
365                 ret = vlmc_resize(name, size);
366         else
367                 fprintf(stderr, "unknown action (%s)\n", argv[2]);
368
369         return ret;
370 }
371