summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/common-utils.h
diff options
context:
space:
mode:
authorMohammed Rafi KC <rkavunga@redhat.com>2015-12-01 09:11:01 +0000
committerAtin Mukherjee <amukherj@redhat.com>2015-12-08 23:16:53 -0800
commit28da53e26e88f23f8917810ce0177f2628aa7e9a (patch)
tree15b3efae68d21f931051dd3fdfea1d74f83dc4ed /libglusterfs/src/common-utils.h
parent848bf0db0dde745e1f3a966db0143b7003bd49b5 (diff)
tier/glusterd: Check before starting tier daemon during volume start
We start tier daemon when volume is started without looking into the previous status. The problem with that if detach-tier is started and then volume force start is actually starting tier daemon. This is also fixes a problem where tier daemon is not starting after detach stop. Change-Id: I15b56a711e12f0e24f5ab123561258bd448621f7 BUG: 1286974 Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com> Reviewed-on: http://review.gluster.org/12833 Tested-by: NetBSD Build System <jenkins@build.gluster.org> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
Diffstat (limited to 'libglusterfs/src/common-utils.h')
0 files changed, 0 insertions, 0 deletions
disperse = *data + *redundancy; } else if (*disperse > 0) { *redundancy = *disperse - *data; } else { if ((count - *data) >= *data) { cli_err ("Please provide redundancy count " "along with disperse-data count"); return -1; } else { sprintf (question, question4, count - *data); answer = cli_cmd_get_confirmation (state, question); if (answer == GF_ANSWER_NO) return -1; *redundancy = count - *data; *disperse = count; } } } if (*disperse <= 0) { if (count < 3) { cli_err ("number of bricks must be greater " "than 2"); return -1; } *disperse = count; } if (*redundancy == -1) { tmp = *disperse - 1; for (i = tmp / 2; (i > 0) && ((tmp & -tmp) != tmp); i--, tmp--); if (i == 0) { answer = cli_cmd_get_confirmation(state, question1); if (answer == GF_ANSWER_NO) return -1; *redundancy = 1; } else { *redundancy = *disperse - tmp; if (*redundancy > 1) { sprintf(question, question2, *redundancy); answer = cli_cmd_get_confirmation(state, question); if (answer == GF_ANSWER_NO) return -1; } } tmp = 0; } else { tmp = *disperse - *redundancy; } if (*redundancy > (*disperse - 1) / 2) { cli_err ("redundancy must be less than %d for a " "disperse %d volume", (*disperse + 1) / 2, *disperse); return -1; } if ((tmp & -tmp) != tmp) { answer = cli_cmd_get_confirmation(state, question3); if (answer == GF_ANSWER_NO) return -1; } return 0; } static int32_t cli_validate_disperse_volume (char *word, gf1_cluster_type type, const char **words, int32_t wordcount, int32_t index, int32_t *disperse_count, int32_t *redundancy_count, int32_t *data_count) { int ret = -1; switch (type) { case GF_CLUSTER_TYPE_NONE: case GF_CLUSTER_TYPE_DISPERSE: if (strcmp (word, "disperse") == 0) { if (*disperse_count >= 0) { cli_err ("disperse option given twice"); goto out; } if (wordcount < (index+2)) { goto out; } ret = gf_string2int (words[index + 1], disperse_count); if (ret == -1 && errno == EINVAL) { *disperse_count = 0; ret = 1; } else if (ret == -1) { goto out; } else { if (*disperse_count < 3) { cli_err ("disperse count must " "be greater than 2"); goto out; } ret = 2; } } else if (strcmp (word, "disperse-data") == 0) { if (*data_count >= 0) { cli_err ("disperse-data option given twice"); goto out; } if (wordcount < (index+2)) { goto out; } ret = gf_string2int (words[index+1], data_count); if (ret == -1 || *data_count < 2) { cli_err ("disperse-data must be greater than 1"); goto out; } ret = 2; } else if (strcmp (word, "redundancy") == 0) { if (*redundancy_count >= 0) { cli_err ("redundancy option given twice"); goto out; } if (wordcount < (index+2)) { goto out; } ret = gf_string2int (words[index+1], redundancy_count); if (ret == -1 || *redundancy_count < 1) { cli_err ("redundancy must be greater than 0"); goto out; } ret = 2; } break; case GF_CLUSTER_TYPE_STRIPE_REPLICATE: cli_err ("striped-replicated-dispersed volume " "is not supported"); goto out; case GF_CLUSTER_TYPE_TIER: cli_err ("tier-dispersed volume is not " "supported"); goto out; case GF_CLUSTER_TYPE_STRIPE: cli_err ("striped-dispersed volume is not " "supported"); goto out; case GF_CLUSTER_TYPE_REPLICATE: cli_err ("replicated-dispersed volume is not " "supported"); goto out; default: cli_err ("Invalid type given"); break; } out: return ret; } int32_t cli_validate_volname (const char *volname) { int32_t ret = -1; int32_t i = -1; static const char * const invalid_volnames[] = { "volume", "type", "subvolumes", "option", "end-volume", "all", "volume_not_in_ring", "description", "force", "snap-max-hard-limit", "snap-max-soft-limit", "auto-delete", "activate-on-create", NULL}; if (volname[0] == '-') goto out; for (i = 0; invalid_volnames[i]; i++) { if (!strcmp (volname, invalid_volnames[i])) { cli_err ("\"%s\" cannot be the name of a volume.", volname); goto out; } } if (strchr (volname, '/')) goto out; if (strlen (volname) > GD_VOLUME_NAME_MAX) { cli_err("Volume name exceeds %d characters.", GD_VOLUME_NAME_MAX); goto out; } for (i = 0; i < strlen (volname); i++) { if (!isalnum (volname[i]) && (volname[i] != '_') && (volname[i] != '-')) { cli_err ("Volume name should not contain \"%c\"" " character.\nVolume names can only" "contain alphanumeric, '-' and '_' " "characters.", volname[i]); goto out; } } ret = 0; out: return ret; } int32_t cli_cmd_volume_create_parse (struct cli_state *state, const char **words, int wordcount, dict_t **options) { dict_t *dict = NULL; char *volname = NULL; int ret = -1; gf1_cluster_type type = GF_CLUSTER_TYPE_NONE; int count = 1; int sub_count = 1; int brick_index = 0; char *trans_type = NULL; int32_t index = 0; char *bricks = NULL; int32_t brick_count = 0; char *opwords[] = { "replica", "stripe", "transport", "disperse", "redundancy", "disperse-data", "arbiter", NULL }; char *w = NULL; char *ptr = NULL; int op_count = 0; int32_t replica_count = 1; int32_t arbiter_count = 0; int32_t stripe_count = 1; int32_t disperse_count = -1; int32_t redundancy_count = -1; int32_t disperse_data_count = -1; gf_boolean_t is_force = _gf_false; int wc = wordcount; GF_ASSERT (words); GF_ASSERT (options); 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 (cli_validate_volname (volname) < 0) goto out; if (wordcount < 4) { ret = -1; goto out; } type = GF_CLUSTER_TYPE_NONE; index = 3; while (op_count < 3) { ret = -1; w = str_getunamb (words[index], opwords); if (!w) { break; } else if ((strcmp (w, "replica")) == 0) { switch (type) { case GF_CLUSTER_TYPE_STRIPE_REPLICATE: case GF_CLUSTER_TYPE_REPLICATE: cli_err ("replica option given twice"); goto out; case GF_CLUSTER_TYPE_NONE: type = GF_CLUSTER_TYPE_REPLICATE; break; case GF_CLUSTER_TYPE_STRIPE: type = GF_CLUSTER_TYPE_STRIPE_REPLICATE; break; case GF_CLUSTER_TYPE_TIER: cli_err ("replicated-tiered volume is not " "supported"); goto out; break; case GF_CLUSTER_TYPE_DISPERSE: cli_err ("replicated-dispersed volume is not " "supported"); goto out; default: cli_err ("Invalid type given"); goto out; } if (wordcount < (index+2)) { ret = -1; goto out; } replica_count = strtol (words[index+1], NULL, 0); if (replica_count < 2) { cli_err ("replica count should be greater" " than 1"); ret = -1; goto out; } ret = dict_set_int32 (dict, "replica-count", replica_count); if (ret) goto out; index += 2; if (words[index]) { if (!strcmp (words[index], "arbiter")) { ret = gf_string2int (words[index+1], &arbiter_count); if (ret == -1 || arbiter_count != 1 || replica_count != 3) { cli_err ("For arbiter " "configuration, " "replica count must be" " 3 and arbiter count " "must be 1. The 3rd " "brick of the replica " "will be the arbiter"); ret = -1; goto out; } ret = dict_set_int32 (dict, "arbiter-count", arbiter_count); if (ret) goto out; index += 2; } } } else if ((strcmp (w, "stripe")) == 0) { switch (type) { case GF_CLUSTER_TYPE_STRIPE_REPLICATE: case GF_CLUSTER_TYPE_STRIPE: cli_err ("stripe option given twice"); goto out; case GF_CLUSTER_TYPE_NONE: type = GF_CLUSTER_TYPE_STRIPE; break; case GF_CLUSTER_TYPE_REPLICATE: type = GF_CLUSTER_TYPE_STRIPE_REPLICATE; break; case GF_CLUSTER_TYPE_DISPERSE: cli_err ("striped-dispersed volume is not " "supported"); goto out; case GF_CLUSTER_TYPE_TIER: cli_err ("striped-tier volume is not " "supported"); goto out; default: cli_err ("Invalid type given"); goto out; } if (wordcount < (index + 2)) { ret = -1; goto out; } stripe_count = strtol (words[index+1], NULL, 0); if (stripe_count < 2) { cli_err ("stripe count should be greater" " than 1"); ret = -1; goto out; } ret = dict_set_int32 (dict, "stripe-count", stripe_count); if (ret) goto out; index += 2; } else if ((strcmp (w, "transport")) == 0) { if (trans_type) { cli_err ("'transport' option given more" " than one time"); 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 if ((strcasecmp (words[index+1], "tcp,rdma") == 0) || (strcasecmp (words[index+1], "rdma,tcp") == 0)) { trans_type = gf_strdup ("tcp,rdma"); } else { gf_log ("", GF_LOG_ERROR, "incorrect transport" " protocol specified"); ret = -1; goto out; } index += 2; } else if ((strcmp (w, "disperse") == 0) || (strcmp (w, "redundancy") == 0) || (strcmp (w, "disperse-data") == 0)) { ret = cli_validate_disperse_volume (w, type, words, wordcount, index, &disperse_count, &redundancy_count, &disperse_data_count); if (ret < 0) goto out; index += ret; type = GF_CLUSTER_TYPE_DISPERSE; } else { GF_ASSERT (!"opword mismatch"); ret = -1; goto out; } op_count++; } if (!trans_type) trans_type = gf_strdup ("tcp"); /* reset the count value now */ count = 1; if (index >= wordcount) { ret = -1; goto out; } brick_index = index; if (strcmp (words[wordcount - 1], "force") == 0) { is_force = _gf_true; wc = wordcount - 1; } ret = cli_cmd_bricks_parse (words, wc, brick_index, &bricks, &brick_count); if (ret) goto out; /* If brick-count is not valid when replica or stripe is given, exit here */ if (!brick_count) { cli_err ("No bricks specified"); ret = -1; goto out; } if (type == GF_CLUSTER_TYPE_DISPERSE) { ret = cli_cmd_create_disperse_check (state, &disperse_count, &redundancy_count, &disperse_data_count, brick_count); if (!ret) ret = dict_set_int32 (dict, "disperse-count", disperse_count); if (!ret) ret = dict_set_int32 (dict, "redundancy-count", redundancy_count); if (ret) goto out; sub_count = disperse_count; } else sub_count = stripe_count * replica_count; if (brick_count % sub_count) { if (type == GF_CLUSTER_TYPE_STRIPE) cli_err ("number of bricks is not a multiple of " "stripe count"); else if (type == GF_CLUSTER_TYPE_REPLICATE) cli_err ("number of bricks is not a multiple of " "replica count"); else if (type == GF_CLUSTER_TYPE_DISPERSE) cli_err ("number of bricks is not a multiple of " "disperse count"); else cli_err ("number of bricks given doesn't match " "required count"); ret = -1; goto out; } /* Everything is parsed fine. start setting info in dict */ ret = dict_set_str (dict, "volname", volname); if (ret) goto out; ret = dict_set_int32 (dict, "type", type); if (ret) goto out; ret = dict_set_dynstr (dict, "transport", trans_type); if (ret) goto out; trans_type = NULL; ret = dict_set_dynstr (dict, "bricks", bricks); if (ret) goto out; ret = dict_set_int32 (dict, "count", brick_count); if (ret) goto out; ret = dict_set_int32 (dict, "force", is_force); if (ret) goto out; *options = dict; out: if (ret) { gf_log ("cli", GF_LOG_ERROR, "Unable to parse create volume CLI"); if (dict) dict_destroy (dict); } GF_FREE (trans_type); return ret; } int32_t cli_cmd_volume_reset_parse (const char **words, int wordcount, dict_t **options) { dict_t *dict = NULL; char *volname = NULL; int ret = -1; GF_ASSERT (words); GF_ASSERT (options); dict = dict_new (); if (!dict) goto out; if (wordcount < 3) goto out; if (wordcount > 5) goto out; volname = (char *)words[2]; if (!volname) { ret = -1; goto out; } ret = dict_set_str (dict, "volname", volname); if (ret) goto out; if (wordcount == 3) { ret = dict_set_str (dict, "key", "all"); if (ret) goto out; } if (wordcount >= 4) { if (!strcmp ("force", (char*)words[3])) { ret = dict_set_int32 (dict, "force", 1); if (ret) goto out; ret = dict_set_str (dict, "key", "all"); if (ret) goto out; } else { ret = dict_set_str (dict, "key", (char *)words[3]); if (ret) goto out; } } if (wordcount == 5) { if (strcmp ("force", (char*)words[4])) { ret = -1; goto out; } else { ret = dict_set_int32 (dict, "force", 1); if (ret) goto out; } } *options = dict; out: if (ret && dict) { dict_destroy (dict); } return ret; } /* Parsing global option for NFS-Ganesha config * gluster nfs-ganesha enable/disable */ int32_t cli_cmd_ganesha_parse (struct cli_state *state, const char **words, int wordcount, dict_t **options, char **op_errstr) { dict_t *dict = NULL; int ret = -1; int flags = 0; char *key = NULL; char *value = NULL; int i = 0; char *w = NULL; char *opwords[] = { "enable", "disable", NULL }; const char *question = NULL; gf_answer_t answer = GF_ANSWER_NO; GF_ASSERT (words); GF_ASSERT (options); dict = dict_new (); if (!dict) goto out; if (wordcount != 2) goto out; key = (char *) words[0]; value = (char *) words[1]; if (!key || !value) { cli_out ("Usage : nfs-ganesha "); ret = -1; goto out; } ret = gf_strip_whitespace (value, strlen (value)); if (ret == -1) goto out; if (strcmp (key, "nfs-ganesha")) { gf_asprintf (op_errstr, "Global option: error: ' %s '" "is not a valid global option.", key); ret = -1; goto out; } w = str_getunamb (value, opwords); if (!w) { cli_out ("Invalid global option \n" "Usage : nfs-ganesha "); ret = -1; goto out; } question = "Enabling NFS-Ganesha requires Gluster-NFS to be" " disabled across the trusted pool. Do you " "still want to continue?\n"; if (strcmp (value, "enable") == 0) { answer = cli_cmd_get_confirmation (state, question); if (GF_ANSWER_NO == answer) { gf_log ("cli", GF_LOG_ERROR, "Global operation " "cancelled, exiting"); ret = -1; goto out; } } cli_out ("This will take a few minutes to complete. Please wait .."); ret = dict_set_str (dict, "key", key); if (ret) { gf_log (THIS->name, GF_LOG_ERROR, "dict set on key failed"); goto out; } ret = dict_set_str (dict, "value", value); if (ret) { gf_log (THIS->name, GF_LOG_ERROR, "dict set on value failed"); goto out; } ret = dict_set_str (dict, "globalname", "All"); if (ret) { gf_log (THIS->name, GF_LOG_ERROR, "dict set on global" " key failed."); goto out; } ret = dict_set_int32 (dict, "hold_global_locks", _gf_true); if (ret) { gf_log (THIS->name, GF_LOG_ERROR, "dict set on global key " "failed."); goto out; } *options = dict; out: if (ret) dict_unref (dict); return ret; } int32_t cli_cmd_inode_quota_parse (const char **words, int wordcount, dict_t **options) { dict_t *dict = NULL; char *volname = NULL; int ret = -1; GF_ASSERT (words); GF_ASSERT (options); dict = dict_new (); if (!dict) { gf_log ("cli", GF_LOG_ERROR, "dict_new failed"); goto out; } if (wordcount != 4) goto out; volname = (char *)words[2]; if (!volname) { ret = -1; goto out; } /* Validate the volume name here itself */ if (cli_validate_volname (volname) < 0) goto out; ret = dict_set_str (dict, "volname", volname); if (ret < 0) goto out; if (strcmp (words[3], "enable") != 0) { cli_out ("Invalid quota option : %s", words[3]); ret = -1; goto out; } ret = dict_set_int32 (dict, "type", GF_QUOTA_OPTION_TYPE_ENABLE_OBJECTS); if (ret < 0) goto out; *options = dict; out: if (ret < 0) { if (dict) dict_destroy (dict); } return ret; } int32_t cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options) { dict_t *dict = NULL; char *volname = NULL; int ret = -1; int i = -1; char key[20] = {0, }; int64_t value = 0; gf_quota_type type = GF_QUOTA_OPTION_TYPE_NONE; char *opwords[] = { "enable", "disable", "limit-usage", "remove", "list", "alert-time", "soft-timeout", "hard-timeout", "default-soft-limit", "limit-objects", "list-objects", "remove-objects", NULL}; char *w = NULL; uint32_t time = 0; double percent = 0; char *end_ptr = NULL; int64_t limit = 0; GF_ASSERT (words); GF_ASSERT (options); dict = dict_new (); if (!dict) { gf_log ("cli", GF_LOG_ERROR, "dict_new failed"); goto out; } if (wordcount < 4) goto out; volname = (char *)words[2]; if (!volname) { ret = -1; goto out; } /* Validate the volume name here itself */ if (cli_validate_volname (volname) < 0) goto out; ret = dict_set_str (dict, "volname", volname); if (ret < 0) goto out; w = str_getunamb (words[3], opwords); if (!w) { cli_out ("Invalid quota option : %s", words[3]); ret = - 1; goto out; } if (strcmp (w, "enable") == 0) { if (wordcount == 4) { type = GF_QUOTA_OPTION_TYPE_ENABLE; ret = 0; goto set_type; } else { ret = -1; goto out; } } if (strcmp (w, "disable") == 0) { if (wordcount == 4) { type = GF_QUOTA_OPTION_TYPE_DISABLE; ret = 0; goto set_type; } else { ret = -1; goto out; } } if (strcmp (w, "limit-usage") == 0) { type = GF_QUOTA_OPTION_TYPE_LIMIT_USAGE; } else if (strcmp (w, "limit-objects") == 0) { type = GF_QUOTA_OPTION_TYPE_LIMIT_OBJECTS; } if (type == GF_QUOTA_OPTION_TYPE_LIMIT_USAGE || type == GF_QUOTA_OPTION_TYPE_LIMIT_OBJECTS) { if (wordcount < 6 || wordcount > 7) { ret = -1; goto out; } if (words[4][0] != '/') { cli_err ("Please enter absolute path"); ret = -1; goto out; } ret = dict_set_str (dict, "path", (char *) words[4]); if (ret) goto out; if (!words[5]) { cli_err ("Please enter the limit value to be set"); ret = -1; goto out; } if (type == GF_QUOTA_OPTION_TYPE_LIMIT_USAGE) { ret = gf_string2bytesize_int64 (words[5], &value); if (ret != 0 || value < 0) { if (errno == ERANGE || value < 0) cli_err ("Value out of range " "(0 - %"PRId64 "): %s", INT64_MAX, words[5]); else cli_err ("Please enter a correct " "value"); goto out; } } else { errno = 0; limit = strtol (words[5], &end_ptr, 10); if (errno == ERANGE || errno == EINVAL || limit <= 0 || strcmp (end_ptr, "") != 0) { ret = -1; cli_err ("Please enter an interger value in " "the range 1 - %"PRId64, INT64