diff options
Diffstat (limited to 'gluster-blockd.c')
-rw-r--r-- | gluster-blockd.c | 386 |
1 files changed, 357 insertions, 29 deletions
diff --git a/gluster-blockd.c b/gluster-blockd.c index 6b73c8b..8807b19 100644 --- a/gluster-blockd.c +++ b/gluster-blockd.c @@ -1,6 +1,6 @@ #define _GNU_SOURCE /* See feature_test_macros(7) */ #include <stdio.h> -#include <netdb.h> +#include <netdb.h> #include <sys/socket.h> # include <uuid/uuid.h> @@ -31,14 +31,103 @@ # define MSERVER_DELIMITER "," -blockResponse * -block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp) +typedef enum opterations { + CREATE_SRV = 1, + LIST_SRV = 2, + INFO_SRV = 3, + DELETE_SRV = 4, + EXEC_SRV = 5 +} opterations; + +static void +gluster_block_1(char *host, void *cobj, opterations opt, blockResponse **reply) { - //FILE *fp; CLIENT *clnt; int sockfd; struct hostent *server; struct sockaddr_in sain; + + if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + perror("gluster-blockd: socket"); + exit(1); + } + server = gethostbyname(host); + if (server == NULL) { + fprintf(stderr,"ERROR, no such host\n"); + exit(0); + } + + bzero((char *) &sain, sizeof(sain)); + sain.sin_family = AF_INET; + bcopy((char *)server->h_addr, (char *)&sain.sin_addr.s_addr, server->h_length); + sain.sin_port = htons(24006); + + if (connect(sockfd, (struct sockaddr *) &sain, sizeof(sain)) < 0) { + perror("gluster-blockd: connect"); + exit(1); + } + + clnt = clnttcp_create ((struct sockaddr_in *) &sain, GLUSTER_BLOCK, GLUSTER_BLOCK_VERS, &sockfd, 0, 0); + if (clnt == NULL) { + clnt_pcreateerror ("localhost"); + exit (1); + } + + switch(opt) { + case CREATE_SRV: + *reply = block_create_1((blockCreate *)cobj, clnt); + if (*reply == NULL) { + clnt_perror (clnt, "call failed gluster-block"); + } + break; + case DELETE_SRV: + *reply = block_delete_1((blockDelete *)cobj, clnt); + if (*reply == NULL) { + clnt_perror (clnt, "call failed gluster-block"); + } + break; + case INFO_SRV: + case LIST_SRV: + break; + case EXEC_SRV: + *reply = block_exec_1((char **)&cobj, clnt); + if (*reply == NULL) { + clnt_perror (clnt, "call failed gluster-block"); + } + break; + } + clnt_destroy (clnt); +} + +static char * +getCfgstring(char* name, char *blkServer) +{ + char *cmd; + char *exec; + char *buf = NULL; + blockResponse *reply = NULL; + + asprintf(&cmd, "%s %s", TARGETCLI_GLFS, BACKEND_CFGSTR); + asprintf(&exec, cmd, name); + + gluster_block_1(blkServer, exec, EXEC_SRV, &reply); + if (!reply || reply->exit) { + ERROR("%s on host: %s", + FAILED_GATHERING_CFGSTR, blkServer); + } + + GB_FREE(cmd); + GB_FREE(exec); + + if(reply->out) + buf = strdup(reply->out); + + return buf; +} + +blockResponse * +block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp) +{ int ret; uuid_t out; static blockCreate *cobj; @@ -66,43 +155,161 @@ block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp) //for - if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { - perror("gluster-blockd: socket"); - exit(1); + gluster_block_1(blk->block_hosts, cobj, CREATE_SRV, &reply); + +out: + return reply; +} + +static size_t +glusterBlockCreateParseSize(char *value) +{ + char *postfix; + char *tmp; + size_t sizef; + + if (!value) + return -1; + + sizef = strtod(value, &postfix); + if (sizef < 0) { + ERROR("%s", "size cannot be negative number\n"); + return -1; } - server = gethostbyname(blk->block_hosts); - if (server == NULL) { - fprintf(stderr,"ERROR, no such host\n"); - exit(0); + + tmp = postfix; + if (*postfix == ' ') + tmp = tmp + 1; + + switch (*tmp) { + case 'Y': + sizef *= 1024; + /* fall through */ + case 'Z': + sizef *= 1024; + /* fall through */ + case 'E': + sizef *= 1024; + /* fall through */ + case 'P': + sizef *= 1024; + /* fall through */ + case 'T': + sizef *= 1024; + /* fall through */ + case 'G': + sizef *= 1024; + /* fall through */ + case 'M': + sizef *= 1024; + /* fall through */ + case 'K': + case 'k': + sizef *= 1024; + /* fall through */ + case 'b': + case '\0': + return sizef; + break; + default: + ERROR("%s", "You may use k/K, M, G or T suffixes for " + "kilobytes, megabytes, gigabytes and terabytes."); + return -1; } +} - bzero((char *) &sain, sizeof(sain)); - sain.sin_family = AF_INET; - bcopy((char *)server->h_addr, (char *)&sain.sin_addr.s_addr, server->h_length); - sain.sin_port = htons(24006); +static int +glusterBlockParseCfgStringToDef(char* cfgstring, + blockCreate *blk) +{ + int ret = 0; + char *p, *sep; + + /* part before '@' is the volume name */ + p = cfgstring; + sep = strchr(p, '@'); + if (!sep) { + ret = -1; + goto fail; + } - if (connect(sockfd, (struct sockaddr *) &sain, sizeof(sain)) < 0) { - perror("gluster-blockd: connect"); - exit(1); + *sep = '\0'; + /*if (GB_STRDUP(blk->volume, p) < 0) { + ret = -1; + goto fail; + } + */ + strcpy(blk->volume, p); + + /* part between '@' and '/' is the server name */ + p = sep + 1; + sep = strchr(p, '/'); + if (!sep) { + ret = -1; + goto fail; } - clnt = clnttcp_create ((struct sockaddr_in *) &sain, GLUSTER_BLOCK, GLUSTER_BLOCK_VERS, &sockfd, 0, 0); - if (clnt == NULL) { - clnt_pcreateerror ("localhost"); - exit (1); + *sep = '\0'; + /*if (GB_STRDUP(blk->volfileserver, p) < 0) { + ret = -1; + goto fail; + } + */ + strcpy(blk->volfileserver, p); + + /* part between '/' and '(' is the filename */ + p = sep + 1; + sep = strchr(p, '('); + if (!sep) { + ret = -1; + goto fail; } - reply = block_create_1(cobj, clnt); - if (reply == NULL) { - clnt_perror (clnt, "call failed gluster-blockd"); + *(sep - 1) = '\0'; /* discard extra space at end of filename */ + /*if (GB_STRDUP(blk->gbid, p) < 0) { + ret = -1; + goto fail; + } + */ + strcpy(blk->gbid, p); + + /* part between '(' and ')' is the size */ + p = sep + 1; + sep = strchr(p, ')'); + if (!sep) { + ret = -1; + goto fail; } - clnt_destroy (clnt); + *sep = '\0'; + blk->size = glusterBlockCreateParseSize(p); + if (blk->size < 0) { + ERROR("%s", "failed while parsing size"); + ret = -1; + goto fail; + } -out: - return reply; -} + /* part between ')' and '\n' is the status */ +/* + p = sep + 1; + sep = strchr(p, '\n'); + if (!sep) { + ret = -1; + goto fail; + } + + *sep = '\0'; + if (!strcmp(p, " activated")) + blk->status = true; +*/ + return 0; + + fail: +// glusterBlockDefFree(blk); + + return ret; +} blockResponse * block_create_1_svc(blockCreate *blk, struct svc_req *rqstp) @@ -153,3 +360,124 @@ block_create_1_svc(blockCreate *blk, struct svc_req *rqstp) return obj; } +blockResponse * +block_delete_cli_1_svc(blockDeleteCli *blk, struct svc_req *rqstp) +{ + char *cfgstring; + static blockCreate *blkcfg; + static blockDelete *cobj; + static blockResponse *reply; + + if(GB_ALLOC(cobj) < 0) + goto out; + + strcpy(cobj->block_name, blk->block_name); + + //for + cfgstring = getCfgstring(blk->block_name, blk->block_hosts); + if (!cfgstring) { + ERROR("%s", "failed while gathering CfgString"); + goto out; + } + + if (GB_ALLOC(blkcfg) < 0) + goto out; + + if(glusterBlockParseCfgStringToDef(cfgstring, blkcfg)) { + ERROR("%s", "failed while parsing CfgString to glusterBlockDef"); + goto out; + } + + strcpy(cobj->gbid, blkcfg->gbid); + gluster_block_1(blk->block_hosts, cobj, DELETE_SRV, &reply); + + if (glusterBlockDeleteEntry(blkcfg)) { + ERROR("%s volume: %s host: %s", + FAILED_DELETING_FILE, blkcfg->volume, blkcfg->volfileserver); + } +out: + return reply; +} + + +blockResponse * +block_delete_1_svc(blockDelete *blk, struct svc_req *rqstp) +{ + FILE *fp; + char *backstore = NULL; + char *iqn = NULL; + char *exec = NULL; + blockResponse *obj = NULL; + + asprintf(&iqn, "%s %s %s%s", TARGETCLI_ISCSI, DELETE, IQN_PREFIX, blk->gbid); + + asprintf(&backstore, "%s %s %s", TARGETCLI_GLFS, + DELETE, blk->block_name); + + asprintf(&exec, "%s && %s", backstore, iqn); + + if(GB_ALLOC(obj) < 0) + return NULL; + + if (GB_ALLOC_N(obj->out, 4096) < 0) { + GB_FREE(obj); + return NULL; + } + + fp = popen(exec, "r"); + if (fp != NULL) { + size_t newLen = fread(obj->out, sizeof(char), 4096, fp); + if (ferror( fp ) != 0) { + ERROR("%s", "Error reading command output\n"); + } else { + obj->out[newLen++] = '\0'; + } + obj->exit = WEXITSTATUS(pclose(fp)); + } + + return obj; +} + +blockResponse * +block_exec_1_svc(char **cmd, struct svc_req *rqstp) +{ + FILE *fp; + static blockResponse *obj; + + if(GB_ALLOC(obj) < 0) + return NULL; + + if (GB_ALLOC_N(obj->out, 4096) < 0) { + GB_FREE(obj); + return NULL; + } + + fp = popen(*cmd, "r"); + if (fp != NULL) { + size_t newLen = fread(obj->out, sizeof(char), 4996, fp); + if (ferror( fp ) != 0) { + ERROR("%s", "Error reading command output\n"); + } else { + obj->out[newLen++] = '\0'; + } + obj->exit = WEXITSTATUS(pclose(fp)); + } + + return obj; +} + +blockResponse * +block_list_cli_1_svc(blockListCli *blk, struct svc_req *rqstp) +{ + + + return NULL; +} + +blockResponse * +block_info_cli_1_svc(blockInfoCli *blk, struct svc_req *rqstp) +{ + + + return NULL; +} |