add vlmc-tool.c peer and vlmc script
authorFilippos Giannakos <philipgian@grnet.gr>
Mon, 24 Sep 2012 13:26:44 +0000 (16:26 +0300)
committerFilippos Giannakos <philipgian@grnet.gr>
Mon, 24 Sep 2012 13:26:44 +0000 (16:26 +0300)
xseg/.gitignore
xseg/peers/user/Makefile
xseg/peers/user/vlmc-tool.c [new file with mode: 0644]
xseg/sys/user/python/Makefile
xseg/tools/vlmc [new file with mode: 0755]

index 09a0fac..3e1a332 100644 (file)
@@ -10,7 +10,6 @@
 .*.ko.cmd
 *.ko
 *.pyc
-tools/vlmc
 config.mk
 *tmp_versions*
 *Module*
index f2245a2..4d65688 100644 (file)
@@ -6,7 +6,7 @@ default: all
 
 #all: filed xseg sosd vlmcd mapperd
 #all: filed xseg vlmcd mapperd
-all: filed xseg mt-sosd dummy mt-vlmcd mapperd mt-mapperd pfiled monitor
+all: filed xseg mt-sosd dummy mt-vlmcd mapperd mt-mapperd pfiled monitor vlmc-xseg
 
 
 filed: filed.c $(BASE)/xseg/xseg.h
@@ -42,5 +42,8 @@ mt-mapperd: mt-mapperd.c mpeer.c mpeer.h $(BASE)/xseg/protocol.h
 pfiled: pfiled.c common.c $(BASE)/xseg/xseg.h $(BASE)/xseg/protocol.h common.h
        $(CC) $(CFLAGS) -o $@ $< common.c  $(INC) -L$(LIB) -lxseg -lpthread
 
+vlmc-xseg: vlmc-tool.c $(BASE)/xseg/xseg.h
+       $(CC) $(CFLAGS) -o $@ $< $(INC) -L$(LIB) -lxseg
+
 clean:
-       rm -f filed xseg sosd vlmcd mapperd mt-sosd dummy monitor mt-mapperd pfiled
+       rm -f filed xseg sosd vlmcd mapperd mt-sosd dummy monitor mt-mapperd pfiled vlmc-xseg
diff --git a/xseg/peers/user/vlmc-tool.c b/xseg/peers/user/vlmc-tool.c
new file mode 100644 (file)
index 0000000..06b2ca8
--- /dev/null
@@ -0,0 +1,370 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <xseg/xseg.h>
+#include <xseg/protocol.h>
+
+#define MAX_ARG_LEN 255
+int safe_strlen(char *s)
+{
+       int i;
+       if (!s)
+               return -1;
+
+       for (i = 0; i < MAX_ARG_LEN; i++) {
+               if (!s)
+                       break;
+               s++;
+       }
+       if (i == MAX_ARG_LEN)
+               return -1;
+       
+       return i;
+}
+
+int validate_alphanumeric(char *s)
+{
+       int i;
+       int len = safe_strlen(s);
+       if (len < 0)
+               return -1;
+
+       for (i = 0; i < len; i++) {
+               if (!isalnum(s))
+                       return -1;
+               s++;
+       }
+       return 0;
+}
+
+int validate_numeric(char *s)
+{
+       int i;
+       int len = safe_strlen(s);
+       if (len < 0)
+               return -1;
+
+       for (i = 0; i < len; i++) {
+               if (!isdigit(s))
+                       return -1;
+               s++;
+       }
+       return 0;
+}
+
+char *spec = "segdev:xsegbd:16:1024:12";
+struct xseg *xseg;
+struct xseg_config cfg;
+xport srcport = NoPort;
+xport sport = NoPort;
+struct xseg_port *port;
+xport mportno;
+
+static void init_local_signal() 
+{
+       if (xseg && sport != srcport){
+               xseg_init_local_signal(xseg, srcport);
+               sport = srcport;
+       }
+}
+
+int wait_reply(struct xseg_request *expected_req)
+{
+       struct xseg_request *rec;
+       xseg_prepare_wait(xseg, srcport);
+       while(1) {
+               rec = xseg_receive(xseg, srcport);
+               if (rec) {
+                       if (rec != expected_req) {
+                               fprintf(stderr, "Unknown received req. Putting req.\n");
+                               xseg_put_request(xseg, rec, srcport);
+                       } else  if (!(rec->state & XS_SERVED)) {
+                               fprintf(stderr, "Failed req\n");
+                               return -1;
+                       } else {
+                               break;
+                       }
+               }
+               xseg_wait_signal(xseg, 1000000UL);
+       }
+       xseg_cancel_wait(xseg, srcport);
+
+       return 0;
+}
+
+int vlmc_create(char *name, uint64_t size, char *snap)
+{
+       int targetlen = safe_strlen(name);
+       int snaplen = safe_strlen(snap);
+       if (targetlen <= 0) {
+               fprintf(stderr, "Invalid name\n");
+               return -1;
+       }
+       if (snaplen <= 0 && size == -1) {
+               fprintf(stderr, "Size or snap must be provided in create\n");
+               return -1;
+       }
+
+       struct xseg_request *req = xseg_get_request(xseg, srcport, mportno, X_ALLOC);
+       if (!req) {
+               fprintf(stderr, "Couldn't allocate xseg request\n");
+               return -1;
+       }
+       int r = xseg_prep_request(xseg, req, targetlen, sizeof(struct xseg_request_clone));
+       if (r < 0){
+               fprintf(stderr, "Couldn't prep xseg request\n");
+               xseg_put_request(xseg, req, srcport);
+               return -1;
+       }
+       struct xseg_request_clone *xclone = (struct xseg_request_clone *) xseg_get_data(xseg, req);
+       if (snaplen < 0)
+               memset(xclone->target, 0, XSEG_MAX_TARGETLEN);
+       else {
+               strncpy(xclone->target, snap, snaplen);
+               xclone->target[snaplen] = 0;
+       }
+       xclone->size = size;
+       req->offset = 0;
+       req->size = req->datalen;
+       req->op = X_CLONE;
+
+       xport p = xseg_submit(xseg, req, srcport, X_ALLOC);
+       if (p == NoPort){
+               fprintf(stderr, "couldn't submit req\n");
+               xseg_put_request(xseg, req, srcport);
+               return -1;
+       }
+       xseg_signal(xseg, p);
+
+       wait_reply(req);
+       
+       xseg_put_request(xseg, req, srcport);
+
+       return 0;
+}
+
+int vlmc_snapshot(char *name)
+{
+       return -1;
+}
+
+int vlmc_remove(char *name)
+{
+       int targetlen = safe_strlen(name);
+       if (targetlen <= 0) {
+               fprintf(stderr, "Invalid name\n");
+               return -1;
+       }
+
+       struct xseg_request *req = xseg_get_request(xseg, srcport, mportno, X_ALLOC);
+       if (!req) {
+               fprintf(stderr, "Couldn't allocate xseg request\n");
+               return -1;
+       }
+       int r = xseg_prep_request(xseg, req, targetlen, 0);
+       if (r < 0){
+               fprintf(stderr, "Couldn't prep xseg request\n");
+               xseg_put_request(xseg, req, srcport);
+               return -1;
+       }
+       char *target = xseg_get_target(xseg, req);
+       strncpy(target, name, targetlen);
+       target[targetlen] = 0;
+       req->offset = 0;
+       req->size = req->datalen;
+       req->op = X_DELETE;
+       
+       xport p = xseg_submit(xseg, req, srcport, X_ALLOC);
+       if (p == NoPort){
+               fprintf(stderr, "couldn't submit req\n");
+               xseg_put_request(xseg, req, srcport);
+               return -1;
+       }
+       xseg_signal(xseg, p);
+       
+       wait_reply(req);
+       
+       xseg_put_request(xseg, req, srcport);
+
+       return 0;
+}
+
+int vlmc_resize(char *name, uint64_t size)
+{
+       return 0;
+}
+
+int vlmc_map(char *name)
+{
+       /*
+       char cmd[1024];
+       char buf[1024];
+       int fd;
+       xport p;
+
+
+       for (p = 2; p < cfg.nr_ports; p++) {
+               sprintf(buf, "%sdevices/%u/srcport", XSEGBD_SYSFS, p);
+               fd = open(buf, O_RDONLY);
+               if (fd < 0 && errno == ENOENT)
+                       break;
+       }
+       if (p == cfg.nr_ports){
+               fprintf(stderr, "No available port\n");
+               return -1;
+       }
+
+       sprintf(cmd, "%s %u:%u:%u", name, p, VPORT, REQS);      
+       sprintf(buf, "%sadd", XSEGBD_SYSFS);
+       fd = open(add, O_WRONLY);
+       if (fd < 0) {
+               fprintf(stderr, "Cannot open sysfs add\n");
+               return -1;
+       }
+       r = write(fd, cmd, strlen(cmd));
+       if (r < 0){
+               fprintf(stderr, "write error\n");
+               return -1;
+       }
+       */
+
+       return 0;
+}
+
+int vlmc_unmap(char *name)
+{
+       return 0;
+}
+
+int vlmc_list()
+{
+       return 0;
+}
+
+#define err_in_arg(__i, __arg) do {                                    \
+       fprintf(stderr, "Error in argument %d (%s)\n", __i, __arg);     \
+       exit(-1);                                                       \
+       } while(0)
+
+int main(int argc, const char *argv[])
+{
+       int i;
+       if (argc < 6){
+               fprintf(stderr, "insufficient arguments\n");
+               return -1;
+       }
+
+       spec = argv[1];
+       if (xseg_parse_spec(spec, &cfg)) {
+               fprintf(stderr, "Cannot parse spec\n");
+               return -1;
+       }
+
+       if (xseg_initialize()) {
+               fprintf(stderr, "cannot initialize!\n");
+               return -1;
+       }
+
+       xseg = xseg_join(cfg.type, cfg.name, "posix", NULL);
+       if (!xseg) {
+               fprintf(stderr, "cannot join segment!\n");
+               return -1;
+       }
+       init_local_signal();
+
+       char *name = NULL;
+       char *snap = NULL;
+       uint64_t size = -1;
+       char *pool = NULL;
+       char *config = NULL;
+
+       for (i = 3; i < argc; i++) {
+               if ((!strcmp(argv[i], "-s") || !strcmp(argv[i], "--size")) && i+1 < argc){
+                       if (!validate_numeric(argv[i+1])){
+                               err_in_arg(i, argv[i]);
+                       } else {
+                               size = atol(argv[i+1]);
+                               i++;
+                       }
+               }else if ((!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config")) && i+1 < argc){
+                       if (!validate_alphanumeric(argv[i+1])){
+                               err_in_arg(i, argv[i]);
+                       } else {
+                               config = argv[i+1];
+                               i++;
+                       }
+               } else if (!strcmp(argv[i], "--snap") && i+1 < argc){
+                       if (!validate_alphanumeric(argv[i+1])){
+                               err_in_arg(i, argv[i]);
+                       } else {
+                               snap = argv[i+1];
+                               i++;
+                       }
+               } else if (!strcmp(argv[i], "-mp") && i+1 < argc){
+                       if (!validate_numeric(argv[i+1])){
+                               err_in_arg(i, argv[i]);
+                       } else {
+                               mportno = atol(argv[i+1]);
+                               i++;
+                       }
+               } else if (!strcmp(argv[i], "-p") && i+1 < argc){
+                       if (!validate_alphanumeric(argv[i+1])){
+                               err_in_arg(i, argv[i]);
+                       } else {
+                               srcport = atol(argv[i+1]);
+                               i++;
+                       }
+               } else if (!strcmp(argv[i], "--name") && i+1 < argc){
+                       if (!validate_alphanumeric(argv[i+1])){
+                               err_in_arg(i, argv[i]);
+                       } else {
+                               name = argv[i+1];
+                       }
+               } else {
+                       err_in_arg(i, argv[i]);
+               }
+       }
+
+       if (srcport > cfg.nr_ports || mportno > cfg.nr_ports) {
+               fprintf(stderr, "Invalid port\n");
+               return -1;
+       }
+
+       port = xseg_bind_port(xseg, srcport);
+       if (!port) {
+               fprintf(stderr, "Error binding port %u\n", srcport);
+               exit(-1);
+       }
+
+       int ret = -1;
+
+       if (!strcmp(argv[2], "create")) 
+               ret = vlmc_create(name, size, snap);
+       else if (!strcmp(argv[2], "remove"))
+               ret = vlmc_remove(name);
+/*
+       else if (!strcmp(argv[2], "map"))
+               ret = vlmc_map(name);
+       else if (!strcmp(argv[2], "unmap"))
+               ret = vlmc_unmap(name);
+       else if (!strcmp(argv[2], "showmapped"))
+               ret = vlmc_showmapped();
+       else if (!strcmp(argv[2], "list") || !(strcmp(argv[2], "ls"))
+               ret = vlmc_list();
+*/
+       else if (!strcmp(argv[2], "resize"))
+               ret = vlmc_resize(name, size);
+       else
+               fprintf(stderr, "Unknown action (%s)\n", argv[2]);
+
+       return ret;
+}
+
index 6147373..13f5845 100644 (file)
@@ -13,8 +13,9 @@ $(BASE)/sys/user/libxseg.so:
        make -C $(BASE)/sys/user libxseg.so
 
 xseg.xml: $(BASE)/xseg/xseg.h $(BASE)/xtypes/xq.h $(BASE)/xtypes/xlock.h \
- $(BASE)/xtypes/xpool.h $(BASE)/xtypes/xhash.h \
- $(BASE)/sys/domain.h $(BASE)/sys/util.h $(BASE)/sys/user/_sysutil.h $(BASE)/xseg/protocol.h
+       $(BASE)/xtypes/xpool.h $(BASE)/xtypes/xhash.h \
+       $(BASE)/xtypes/xheap.h $(BASE)/xtypes/xobj.h \
+       $(BASE)/sys/domain.h $(BASE)/sys/util.h $(BASE)/sys/user/_sysutil.h $(BASE)/xseg/protocol.h
        $(H2XML) -c $(INC) -o $@ $(BASE)/xseg/xseg.h
 
 xprotocol.xml: 
diff --git a/xseg/tools/vlmc b/xseg/tools/vlmc
new file mode 100755 (executable)
index 0000000..483ded6
--- /dev/null
@@ -0,0 +1,197 @@
+#!/usr/bin/env python
+#
+# vlmc tool
+
+import os, sys, subprocess, argparse
+
+def vlmc_create(args):
+    name = args.name[0]
+    size = args.size << 20
+    snap = args.snap
+
+    if size == None and snap == None:
+        print >> sys.stderr, "At least one of the size/snap args must be provided"
+        sys.exit(-1)
+
+    cmd = ["/root/archip_rest/xseg/peers/user/vlmc-xseg", "%s" % SPEC, "create", "--name", "%s" % name]
+    if snap != None:
+            cmd.extend("--snap", "%s" % snap)
+    if size != None:
+            cmd.extend("--size", "%s" % size)
+    cmd.extend("-mp", "%s" % MPORT)
+    cmd.extend("-p", "%s" % VTOOL)
+
+    result = utils.RunCmd(cmd)
+    if result.failed:
+            sys.stderr.write("vlmc creation failed\n")
+            sys.exit(-1)
+    
+
+def vlmc_snapshot(args):
+    # snapshot
+    return
+
+def vlmc_list(args):
+    # list
+    return
+
+def vlmc_remove(args):
+    name = args.name[0]
+    cmd = ["/root/archip_rest/xseg/peers/user/vlmc-xseg", "%s" % SPEC, "remove", "--name", "%s" % name]
+    cmd.extend("-mp", "%s" % MPORT)
+    cmd.extend("-p", "%s" % VTOOL)
+    result = utils.RunCmd(cmd)
+    if result.failed:
+            sys.stderr.write("vlmc creation failed\n")
+            sys.exit(-1)
+
+
+def xsegbd_loaded():
+    try:
+        os.stat("/sys/bus/xsegbd")
+    except Exception, reason:
+        print >> sys.stderr, reason
+        sys.exit(-1)
+
+def vlmc_map(args):
+    xsegbd_loaded()
+    name = args.name[0]
+    prev = 2
+    try:
+        result = [int(open(XSEGBD_SYSFS + "devices/" + f + "/srcport").read().strip()) for f in os.listdir(XSEGBD_SYSFS + "devices/")]
+        result.sort()
+
+        for p in result:
+            if p - prev > 1:
+               break
+            else:
+               prev = p
+
+        port = prev + 1
+        fd = os.open(XSEGBD_SYSFS + "add", os.O_WRONLY)
+        os.write(fd, "%s %d:%d:%d" % (name, port, VPORT, REQS))
+        os.close(fd)
+    except Exception, reason:
+        print >> sys.stderr, reason
+        sys.exit(-1)
+
+def vlmc_unmap(args):
+    xsegbd_loaded()
+    device = args.name[0]
+    try:
+        for f in os.listdir(XSEGBD_SYSFS + "devices/"):
+            d_id = open(XSEGBD_SYSFS + "devices/" + f + "/id").read().strip()
+            name = open(XSEGBD_SYSFS + "devices/"+ f + "/target").read().strip()
+            if device == DEVICE_PREFIX + d_id:
+                fd = os.open(XSEGBD_SYSFS + "remove", os.O_WRONLY)
+                os.write(fd, d_id)
+                os.close(fd)
+
+                sys.exit(0)
+        print >> sys.stderr, "Device %s doesn't exist" % device
+        sys.exit(-1)
+    except Exception, reason:
+        print >> sys.stderr, reason
+        sys.exit(-1)
+
+def vlmc_showmapped(args):
+    xsegbd_loaded()
+    print "id\tpool\timage\tsnap\tdevice"
+    try:
+        for f in os.listdir(XSEGBD_SYSFS + "devices/"):
+            d_id = open(XSEGBD_SYSFS + "devices/" + f + "/id").read().strip()
+            target = open(XSEGBD_SYSFS + "devices/"+ f + "/target").read().strip()
+
+            print "%s\t%s\t%s\t%s\t%s" % (d_id, '-', target, '-', DEVICE_PREFIX +
+            d_id)
+    except Exception, reason:
+        print >> sys.stderr, reason
+        sys.exit(-1)
+
+# FIXME:
+def vlmc_resize(args):
+    xsegbd_loaded()
+
+    name = args.name[0]
+    size = args.size[0]
+
+    try:
+
+        for f in os.listdir(XSEGBD_SYSFS + "devices/"):
+            d_id = open(XSEGBD_SYSFS + "devices/" + f + "/id").read().strip()
+            d_name = open(XSEGBD_SYSFS + "devices/"+ f + "/name").read().strip()
+            if name == d_name:
+                fd = os.open(XSEGBD_SYSFS + "devices/" +  d_id +"/refresh", os.O_WRONLY)
+                os.write(fd, "1")
+                os.close(fd)
+
+        sys.exit(0)
+    except Exception, reason:
+        print >> sys.stderr, reason
+        sys.exit(-1)
+
+def loadrc(rc):
+    #FIXME
+    try:
+        if rc == None:
+            execfile(os.path.expanduser("~/.xsegrc"), globals())
+        else:
+            execfile(rc, globals())
+    except:
+        pass
+
+if __name__ == "__main__":
+    # parse arguments and discpatch to the correct func
+    parser = argparse.ArgumentParser(description='vlmc tool')
+    parser.add_argument('-c', '--config', type=str, nargs='?', help='config file')
+    subparsers = parser.add_subparsers()
+
+    create_parser = subparsers.add_parser('create', help='Create volume')
+    #group = create_parser.add_mutually_exclusive_group(required=True)
+    create_parser.add_argument('-s', '--size', type=int, nargs='?', help='requested size in MB for create')
+    create_parser.add_argument('--snap', type=str, nargs='?', help='create from snapshot')
+    create_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
+    create_parser.add_argument('name', type=str, nargs=1, help='volume/device name')
+    create_parser.set_defaults(func=vlmc_create)
+
+    remove_parser = subparsers.add_parser('remove', help='Delete volume')
+    remove_parser.add_argument('name', type=str, nargs=1, help='volume/device name')
+    remove_parser.set_defaults(func=vlmc_remove)
+    remove_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
+
+    rm_parser = subparsers.add_parser('rm', help='Delete volume')
+    rm_parser.add_argument('name', type=str, nargs=1, help='volume/device name')
+    rm_parser.set_defaults(func=vlmc_remove)
+    rm_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
+
+    map_parser = subparsers.add_parser('map', help='Map volume')
+    map_parser.add_argument('name', type=str, nargs=1, help='volume/device name')
+    map_parser.set_defaults(func=vlmc_map)
+    map_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
+
+    unmap_parser = subparsers.add_parser('unmap', help='Unmap volume')
+    unmap_parser.add_argument('name', type=str, nargs=1, help='volume/device name')
+    unmap_parser.set_defaults(func=vlmc_unmap)
+    unmap_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
+
+    showmapped_parser = subparsers.add_parser('showmapped', help='Show mapped volumes')
+    showmapped_parser.set_defaults(func=vlmc_showmapped)
+    showmapped_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
+
+    list_parser = subparsers.add_parser('list', help='List volumes')
+    list_parser.set_defaults(func=vlmc_list)
+    list_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
+
+    ls_parser = subparsers.add_parser('ls', help='List volumes')
+    ls_parser.set_defaults(func=vlmc_list)
+    ls_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
+
+    resize_parser = subparsers.add_parser('resize', help='Resize volume')
+    resize_parser.add_argument('-s', '--size', type=int, nargs=1, help='requested size in MB for resize')
+    resize_parser.add_argument('name', type=str, nargs=1, help='volume/device name')
+    resize_parser.set_defaults(func=vlmc_resize)
+    resize_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
+
+    args = parser.parse_args()
+    loadrc(args.config)
+    args.func(args)