2036 21:21:09 GMT ETag: "7c02e1f0562244ebd7a2fe8c26a2e7b774ccec7b" /* Copyright (c) 2010 Gluster, Inc. This file is part of GlusterFS. GlusterFS is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. GlusterFS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ #include #include #include #include #include #ifndef _CONFIG_H #define _CONFIG_H #include "config.h" #endif #include "cli.h" #include "cli-cmd.h" #include "cli-mem-types.h" #include "dict.h" #include "protocol-common.h" #include "cli1-xdr.h" int32_t cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options) { dict_t *dict = NULL; char *volname = NULL; char *delimiter = NULL; int ret = -1; gf1_cluster_type type = GF_CLUSTER_TYPE_NONE; int count = 1; int brick_count = 0, brick_index = 0; int brick_list_size = 1; char brick_list[120000] = {0,}; int i = 0; char *tmp_list = NULL; char *tmpptr = NULL; int j = 0; char *host_name = NULL; char *tmp = NULL; char *freeptr = NULL; char *trans_type = NULL; int32_t index = 0; char *free_list_ptr = NULL; char *bricks = NULL; GF_ASSERT (words); GF_ASSERT (options); GF_ASSERT ((strcmp (words[0], "volume")) == 0); GF_ASSERT ((strcmp (words[1], "create")) == 0); dict = dict_new (); if (!dict) goto out; if (wordcount < 3) goto out; volname = (char *)words[2]; GF_ASSERT (volname); /* Validate the volume name here itself */ { if (volname[0] == '-') goto out; if (!strcmp (volname, "all")) { cli_out ("\"all\" cannot be the name of a volume."); goto out; } if (strchr (volname, '/')) goto out; if (strlen (volname) > 512) goto out; for (i = 0; i < strlen (volname); i++) if (!isalnum (volname[i]) && (volname[i] != '_') && (volname[i] != '-')) goto out; } ret = dict_set_str (dict, "volname", volname); if (ret) goto out; if (wordcount < 4) { ret = -1; goto out; } if ((strcasecmp (words[3], "replica")) == 0) { type = GF_CLUSTER_TYPE_REPLICATE; if (wordcount < 5) { ret = -1; goto out; } count = strtol (words[4], NULL, 0); if (!count || (count < 2)) { cli_out ("replica count should be greater than 1"); ret = -1; goto out; } ret = dict_set_int32 (dict, "replica-count", count); if (ret) goto out; brick_index = 5; } else if ((strcasecmp (words[3], "stripe")) == 0) { type = GF_CLUSTER_TYPE_STRIPE; if (wordcount < 5) { ret = -1; goto out; } count = strtol (words[4], NULL, 0); if (!count || (count < 2)) { cli_out ("stripe count should be greater than 1"); ret = -1; goto out; } ret = dict_set_int32 (dict, "stripe-count", count); if (ret) goto out; brick_index = 5; } else { type = GF_CLUSTER_TYPE_NONE; brick_index = 3; } ret = dict_set_int32 (dict, "type", type); if (ret) goto out; if (type) index = 5; else index = 3; if (wordcount < (index + 1)) { ret = -1; goto out; } if (strcasecmp(words[index], "transport") == 0) { brick_index = index+2; if (wordcount < (index + 2)) { ret = -1; goto out; } if ((strcasecmp (words[index+1], "tcp") == 0)) { trans_type = gf_strdup ("tcp"); } else if ((strcasecmp (words[index+1], "rdma") == 0)) { trans_type = gf_strdup ("rdma"); } else { gf_log ("", GF_LOG_ERROR, "incorrect transport" " protocol specified"); ret = -1; goto out; } } else { trans_type = gf_strdup ("tcp"); } ret = dict_set_dynstr (dict, "transport", trans_type); if (ret) goto out; strcpy (brick_list, " "); while (brick_index < wordcount) { delimiter = strchr (words[brick_index], ':'); if (!delimiter || delimiter == words[brick_index] || *(delimiter+1) != '/') { cli_out ("wrong brick type: %s, use :" "", words[brick_index]); ret = -1; goto out; } else { cli_path_strip_trailing_slashes (delimiter + 1); } if ((brick_list_size + strlen (words[brick_index]) + 1) > 120000) { gf_log ("cli", GF_LOG_ERROR, "total brick list is larger than a request " "can take (brick_count %d)", brick_count); ret = -1; goto out; } host_name = gf_strdup(words[brick_index]); if (!host_name) { ret = -1; gf_log("cli",GF_LOG_ERROR, "Unable to allocate " "memory"); goto out; } freeptr = host_name; strtok_r(host_name, ":", &tmp); if (!(strcmp(host_name, "localhost") && strcmp (host_name, "127.0.0.1"))) { cli_out ("Please provide a valid hostname/ip other " "than localhost or 127.0.0.1"); ret = -1; GF_FREE(freeptr); goto out; } GF_FREE (freeptr); tmp_list = strdup(brick_list+1); free_list_ptr = tmp_list; j = 0; while(( brick_count != 0) && (j < brick_count)) { strtok_r (tmp_list, " ", &tmpptr); if (!(strcmp (tmp_list, words[brick_index]))) { ret = -1