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;
103 static void init_local_signal()
105 if (xseg && sport != srcport){
106 xseg_init_local_signal(xseg, srcport);
111 int wait_reply(struct xseg_request *expected_req)
113 struct xseg_request *rec;
114 xseg_prepare_wait(xseg, srcport);
116 rec = xseg_receive(xseg, srcport, 0);
118 if (rec != expected_req) {
119 fprintf(stderr, "Unknown received req. Putting req.\n");
120 xseg_put_request(xseg, rec, srcport);
121 } else if (!(rec->state & XS_SERVED)) {
122 fprintf(stderr, "Failed req\n");
128 xseg_wait_signal(xseg, 1000000UL);
130 xseg_cancel_wait(xseg, srcport);
135 int vlmc_create(char *name, uint64_t size, char *snap)
138 int targetlen = safe_strlen(name);
139 int snaplen = safe_strlen(snap);
140 if (targetlen <= 0) {
141 fprintf(stderr, "Invalid name\n");
144 if (snaplen <= 0 && size == -1) {
145 fprintf(stderr, "Size or snap must be provided in create\n");
148 XSEGLOG("Name: %s", name);
149 XSEGLOG("Snap: %s", snap);
151 struct xseg_request *req = xseg_get_request(xseg, srcport, mportno, X_ALLOC);
153 fprintf(stderr, "Couldn't allocate xseg request\n");
156 int r = xseg_prep_request(xseg, req, targetlen, sizeof(struct xseg_request_clone));
158 fprintf(stderr, "Couldn't prep xseg request\n");
159 xseg_put_request(xseg, req, srcport);
162 //FIXME what to do if no snap ? how do i send mapper to create a non copy up volume?
163 char *target = xseg_get_target(xseg, req);
164 strncpy(target, name, targetlen);
165 struct xseg_request_clone *xclone = (struct xseg_request_clone *) xseg_get_data(xseg, req);
167 memset(xclone->target, 0, XSEG_MAX_TARGETLEN);
168 xclone->targetlen = 0;
171 strncpy(xclone->target, snap, snaplen);
172 xclone->targetlen = snaplen;
176 req->size = req->datalen;
179 xport p = xseg_submit(xseg, req, srcport, X_ALLOC);
181 fprintf(stderr, "couldn't submit req\n");
182 xseg_put_request(xseg, req, srcport);
185 xseg_signal(xseg, p);
187 ret = wait_reply(req);
189 xseg_put_request(xseg, req, srcport);
194 int vlmc_snapshot(char *name)
199 int vlmc_remove(char *name)
201 int targetlen = safe_strlen(name);
202 if (targetlen <= 0) {
203 fprintf(stderr, "Invalid name\n");
207 struct xseg_request *req = xseg_get_request(xseg, srcport, mportno, X_ALLOC);
209 fprintf(stderr, "Couldn't allocate xseg request\n");
212 int r = xseg_prep_request(xseg, req, targetlen, 0);
214 fprintf(stderr, "Couldn't prep xseg request\n");
215 xseg_put_request(xseg, req, srcport);
218 char *target = xseg_get_target(xseg, req);
219 strncpy(target, name, targetlen);
221 req->size = req->datalen;
224 xport p = xseg_submit(xseg, req, srcport, X_ALLOC);
226 fprintf(stderr, "couldn't submit req\n");
227 xseg_put_request(xseg, req, srcport);
230 xseg_signal(xseg, p);
234 xseg_put_request(xseg, req, srcport);
239 int vlmc_resize(char *name, uint64_t size)
244 int vlmc_map(char *name)
253 for (p = 2; p < cfg.nr_ports; p++) {
254 sprintf(buf, "%sdevices/%u/srcport", XSEGBD_SYSFS, p);
255 fd = open(buf, O_RDONLY);
256 if (fd < 0 && errno == ENOENT)
259 if (p == cfg.nr_ports){
260 fprintf(stderr, "No available port\n");
264 sprintf(cmd, "%s %u:%u:%u", name, p, VPORT, REQS);
265 sprintf(buf, "%sadd", XSEGBD_SYSFS);
266 fd = open(add, O_WRONLY);
268 fprintf(stderr, "Cannot open sysfs add\n");
271 r = write(fd, cmd, strlen(cmd));
273 fprintf(stderr, "write error\n");
281 int vlmc_unmap(char *name)
291 #define err_in_arg(__i, __arg) do { \
292 fprintf(stderr, "Error in argument %d (%s)\n", __i, __arg); \
296 int main(int argc, char *argv[])
300 fprintf(stderr, "insufficient arguments\n");
305 if (xseg_parse_spec(spec, &cfg)) {
306 fprintf(stderr, "Cannot parse spec\n");
310 if (xseg_initialize()) {
311 fprintf(stderr, "cannot initialize!\n");
315 xseg = xseg_join(cfg.type, cfg.name, "posix", NULL);
317 fprintf(stderr, "cannot join segment!\n");
326 // char *config = NULL;
328 for (i = 3; i < argc; i++) {
329 if ((!strcmp(argv[i], "-s") || !strcmp(argv[i], "--size")) && i+1 < argc){
330 if (!validate_numeric(argv[i+1])){
331 err_in_arg(i, argv[i]);
333 size = atol(argv[i+1]);
337 }else if ((!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config")) && i+1 < argc){
338 if (!validate_alphanumeric(argv[i+1])){
339 err_in_arg(i, argv[i]);
345 } else if (!strcmp(argv[i], "--snap") && i+1 < argc){
346 if (!validate_alphanumeric(argv[i+1])){
347 err_in_arg(i, argv[i]);
352 } else if (!strcmp(argv[i], "-mp") && i+1 < argc){
353 if (!validate_numeric(argv[i+1])){
354 err_in_arg(i, argv[i]);
356 mportno = atol(argv[i+1]);
359 } else if (!strcmp(argv[i], "-p") && i+1 < argc){
360 if (!validate_alphanumeric(argv[i+1])){
361 err_in_arg(i, argv[i]);
363 srcport = atol(argv[i+1]);
366 } else if (!strcmp(argv[i], "--name") && i+1 < argc){
367 if (!validate_alphanumeric(argv[i+1])){
368 err_in_arg(i, argv[i]);
374 err_in_arg(i, argv[i]);
378 if (srcport > cfg.nr_ports || mportno > cfg.nr_ports) {
379 fprintf(stderr, "Invalid port\n");
383 port = xseg_bind_port(xseg, srcport, NULL);
385 fprintf(stderr, "Error binding port %u\n", srcport);
391 if (!strcmp(argv[2], "create"))
392 ret = vlmc_create(name, size, snap);
393 else if (!strcmp(argv[2], "remove"))
394 ret = vlmc_remove(name);
396 else if (!strcmp(argv[2], "map"))
397 ret = vlmc_map(name);
398 else if (!strcmp(argv[2], "unmap"))
399 ret = vlmc_unmap(name);
400 else if (!strcmp(argv[2], "showmapped"))
401 ret = vlmc_showmapped();
402 else if (!strcmp(argv[2], "list") || !(strcmp(argv[2], "ls"))
405 else if (!strcmp(argv[2], "resize"))
406 ret = vlmc_resize(name, size);
408 fprintf(stderr, "unknown action (%s)\n", argv[2]);