2 * Copyright 2012 GRNET S.A. All rights reserved.
4 * Redistribution and use in source and binary forms, with or
5 * without modification, are permitted provided that the following
8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials
14 * provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
29 * The views and conclusions contained in the software and
30 * documentation are those of the authors and should not be
31 * interpreted as representing official policies, either expressed
32 * or implied, of GRNET S.A.
42 #include <sys/types.h>
46 #include <xseg/xseg.h>
47 #include <xseg/protocol.h>
49 #define MAX_ARG_LEN 255
50 int safe_strlen(char *s)
56 for (i = 0; i < MAX_ARG_LEN; i++) {
64 int validate_alphanumeric(char *s)
67 int len = safe_strlen(s);
72 for (i = 0; i < len; i++) {
73 if (!isalnum(*s)&&*s!='-'&&*s!='.')
80 int validate_numeric(char *s)
83 int len = safe_strlen(s);
87 for (i = 0; i < len; i++) {
95 char *spec = "segdev:xsegbd:16:1024:12";
97 struct xseg_config cfg;
98 xport srcport = NoPort;
100 struct xseg_port *port;
101 xport mportno = NoPort;
102 xport vportno = NoPort;
104 static void init_local_signal()
106 if (xseg && sport != srcport){
107 xseg_init_local_signal(xseg, srcport);
112 int wait_reply(struct xseg_request *expected_req)
114 struct xseg_request *rec;
115 xseg_prepare_wait(xseg, srcport);
117 rec = xseg_receive(xseg, srcport, 0);
119 if (rec != expected_req) {
120 fprintf(stderr, "Unknown received req. Putting req.\n");
121 xseg_put_request(xseg, rec, srcport);
122 } else if (!(rec->state & XS_SERVED)) {
123 fprintf(stderr, "Failed req\n");
129 xseg_wait_signal(xseg, 1000000UL);
131 xseg_cancel_wait(xseg, srcport);
136 int vlmc_create(char *name, uint64_t size, char *snap)
139 int targetlen = safe_strlen(name);
140 int snaplen = safe_strlen(snap);
141 if (targetlen <= 0) {
142 fprintf(stderr, "Invalid name\n");
145 if (snaplen <= 0 && size == -1) {
146 fprintf(stderr, "Size or snap must be provided in create\n");
149 XSEGLOG("Name: %s", name);
150 XSEGLOG("Snap: %s", snap);
152 struct xseg_request *req = xseg_get_request(xseg, srcport, mportno, X_ALLOC);
154 fprintf(stderr, "Couldn't allocate xseg request\n");
157 int r = xseg_prep_request(xseg, req, targetlen, sizeof(struct xseg_request_clone));
159 fprintf(stderr, "Couldn't prep xseg request\n");
160 xseg_put_request(xseg, req, srcport);
163 //FIXME what to do if no snap ? how do i send mapper to create a non copy up volume?
164 char *target = xseg_get_target(xseg, req);
165 strncpy(target, name, targetlen);
166 struct xseg_request_clone *xclone = (struct xseg_request_clone *) xseg_get_data(xseg, req);
168 memset(xclone->target, 0, XSEG_MAX_TARGETLEN);
169 xclone->targetlen = 0;
172 strncpy(xclone->target, snap, snaplen);
173 xclone->targetlen = snaplen;
177 req->size = req->datalen;
180 xport p = xseg_submit(xseg, req, srcport, X_ALLOC);
182 fprintf(stderr, "couldn't submit req\n");
183 xseg_put_request(xseg, req, srcport);
186 xseg_signal(xseg, p);
188 ret = wait_reply(req);
190 xseg_put_request(xseg, req, srcport);
195 int vlmc_snapshot(char *name)
197 int targetlen = safe_strlen(name);
198 if (targetlen <= 0) {
199 fprintf(stderr, "Invalid name\n");
203 struct xseg_request *req = xseg_get_request(xseg, srcport, vportno, X_ALLOC);
205 fprintf(stderr, "Couldn't allocate xseg request\n");
208 int r = xseg_prep_request(xseg, req, targetlen, sizeof(struct xseg_request_snapshot));
210 fprintf(stderr, "Couldn't prep xseg request\n");
211 xseg_put_request(xseg, req, srcport);
214 char *target = xseg_get_target(xseg, req);
215 strncpy(target, name, targetlen);
216 struct xseg_request_snapshot *xsnapshot = (struct xseg_request_snapshot *) xseg_get_data(xseg, req);
217 xsnapshot->target[0] = 0;
218 xsnapshot->targetlen = 0;
220 req->size = req->datalen;
221 req->op = X_SNAPSHOT;
223 xport p = xseg_submit(xseg, req, srcport, X_ALLOC);
225 fprintf(stderr, "couldn't submit req\n");
226 xseg_put_request(xseg, req, srcport);
229 xseg_signal(xseg, p);
233 struct xseg_reply_snapshot *xreply = (struct xseg_reply_snapshot *) xseg_get_data(xseg, req);
234 char buf[XSEG_MAX_TARGETLEN + 1];
235 strncpy(buf, xreply->target, xreply->targetlen);
236 buf[xreply->targetlen] = 0;
237 fprintf(stdout, "Snapshot name: %s\n", buf);
240 xseg_put_request(xseg, req, srcport);
245 int vlmc_remove(char *name)
247 int targetlen = safe_strlen(name);
248 if (targetlen <= 0) {
249 fprintf(stderr, "Invalid name\n");
253 struct xseg_request *req = xseg_get_request(xseg, srcport, mportno, X_ALLOC);
255 fprintf(stderr, "Couldn't allocate xseg request\n");
258 int r = xseg_prep_request(xseg, req, targetlen, 0);
260 fprintf(stderr, "Couldn't prep xseg request\n");
261 xseg_put_request(xseg, req, srcport);
264 char *target = xseg_get_target(xseg, req);
265 strncpy(target, name, targetlen);
267 req->size = req->datalen;
270 xport p = xseg_submit(xseg, req, srcport, X_ALLOC);
272 fprintf(stderr, "couldn't submit req\n");
273 xseg_put_request(xseg, req, srcport);
276 xseg_signal(xseg, p);
280 xseg_put_request(xseg, req, srcport);
285 int vlmc_resize(char *name, uint64_t size)
290 int vlmc_map(char *name)
299 for (p = 2; p < cfg.nr_ports; p++) {
300 sprintf(buf, "%sdevices/%u/srcport", XSEGBD_SYSFS, p);
301 fd = open(buf, O_RDONLY);
302 if (fd < 0 && errno == ENOENT)
305 if (p == cfg.nr_ports){
306 fprintf(stderr, "No available port\n");
310 sprintf(cmd, "%s %u:%u:%u", name, p, VPORT, REQS);
311 sprintf(buf, "%sadd", XSEGBD_SYSFS);
312 fd = open(add, O_WRONLY);
314 fprintf(stderr, "Cannot open sysfs add\n");
317 r = write(fd, cmd, strlen(cmd));
319 fprintf(stderr, "write error\n");
327 int vlmc_unmap(char *name)
337 #define err_in_arg(__i, __arg) do { \
338 fprintf(stderr, "Error in argument %d (%s)\n", __i, __arg); \
342 int main(int argc, char *argv[])
346 fprintf(stderr, "insufficient arguments\n");
351 if (xseg_parse_spec(spec, &cfg)) {
352 fprintf(stderr, "Cannot parse spec\n");
356 if (xseg_initialize()) {
357 fprintf(stderr, "cannot initialize!\n");
361 xseg = xseg_join(cfg.type, cfg.name, "posix", NULL);
363 fprintf(stderr, "cannot join segment!\n");
372 // char *config = NULL;
374 for (i = 3; i < argc; i++) {
375 if ((!strcmp(argv[i], "-s") || !strcmp(argv[i], "--size")) && i+1 < argc){
376 if (!validate_numeric(argv[i+1])){
377 err_in_arg(i, argv[i]);
379 size = atol(argv[i+1]);
383 }else if ((!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config")) && i+1 < argc){
384 if (!validate_alphanumeric(argv[i+1])){
385 err_in_arg(i, argv[i]);
391 } else if (!strcmp(argv[i], "--snap") && i+1 < argc){
392 if (!validate_alphanumeric(argv[i+1])){
393 err_in_arg(i, argv[i]);
398 } else if (!strcmp(argv[i], "-mp") && i+1 < argc){
399 if (!validate_numeric(argv[i+1])){
400 err_in_arg(i, argv[i]);
402 mportno = atol(argv[i+1]);
405 } else if (!strcmp(argv[i], "-vp") && i+1 < argc){
406 if (!validate_numeric(argv[i+1])){
407 err_in_arg(i, argv[i]);
409 vportno = atol(argv[i+1]);
412 } else if (!strcmp(argv[i], "-p") && i+1 < argc){
413 if (!validate_alphanumeric(argv[i+1])){
414 err_in_arg(i, argv[i]);
416 srcport = atol(argv[i+1]);
419 } else if (!strcmp(argv[i], "--name") && i+1 < argc){
420 if (!validate_alphanumeric(argv[i+1])){
421 err_in_arg(i, argv[i]);
427 err_in_arg(i, argv[i]);
431 if (srcport > cfg.nr_ports || mportno > cfg.nr_ports || vportno > cfg.nr_ports) {
432 fprintf(stderr, "Invalid port\n");
436 port = xseg_bind_port(xseg, srcport, NULL);
438 fprintf(stderr, "Error binding port %u\n", srcport);
444 if (!strcmp(argv[2], "create"))
445 ret = vlmc_create(name, size, snap);
446 else if (!strcmp(argv[2], "remove"))
447 ret = vlmc_remove(name);
449 else if (!strcmp(argv[2], "map"))
450 ret = vlmc_map(name);
451 else if (!strcmp(argv[2], "unmap"))
452 ret = vlmc_unmap(name);
453 else if (!strcmp(argv[2], "showmapped"))
454 ret = vlmc_showmapped();
455 else if (!strcmp(argv[2], "list") || !(strcmp(argv[2], "ls"))
458 else if (!strcmp(argv[2], "resize"))
459 ret = vlmc_resize(name, size);
460 else if (!strcmp(argv[2], "snapshot"))
461 ret = vlmc_snapshot(name);
463 fprintf(stderr, "unknown action (%s)\n", argv[2]);