From f8a158134d89b25063b059cd4241ffc84c48f469 Mon Sep 17 00:00:00 2001 From: Avra Sengupta Date: Mon, 30 Sep 2013 16:26:33 +0530 Subject: cli: snapshot create cli interface. $ gluster snapshot help snapshot help - display help for snapshot commands snapshot create [-n ] [-d ] - Snapshot Create. $ gluster snapshot create vol1 snapshot create: ???: snap created successfully $ gluster snapshot create vol1 vol2 snapshot create: ???: consistency group created successfully (The ??? will be replaced by the glusterd snap create command with the generated snap-name or cg-name) $ gluster snapshot create vol1 vol2 -n CG1 snapshot create: CG1: consistency group created successfully $ gluster snapshot create vol1 -n snap1 -d Description snapshot create: snap1: snap created successfully $ gluster snapshot create vol1 -n snap1 -d "Description can have -d within quotes" snapshot create: snap1: snap created successfully $ gluster snapshot create vol1 -n snap1 -d Description cant have -d without quotes snapshot create: failed: Options(-n/-d) are not valid descriptions Usage: snapshot create [-n ] [-d ] $ gluster snapshot create vol1 -n "Multi word snap name" -d Description snapshot create: failed: Invalid snap name Usage: snapshot create [-n ] [-d ] $ gluster snapshot create vol1 -d Description -n "-d" snapshot create: failed: Options(-n/-d) are not valid snap names Usage: snapshot create [-n ] [-d ] $ gluster snapshot create vol1 -d -n snap1 snapshot create: failed: No description provided Usage: snapshot create [-n ] [-d ] Change-Id: I74b5a8406d72282fbb7ba7d07e0c7fe395148d38 Signed-off-by: Avra Sengupta --- cli/src/cli-cmd-parser.c | 325 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 325 insertions(+) (limited to 'cli/src/cli-cmd-parser.c') diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index cd0370acc..3d8ec5d8f 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -26,6 +26,8 @@ #include "protocol-common.h" #include "cli1-xdr.h" +#define MAX_SNAP_DESCRIPTION_LEN 1024 + static const char * id_sel (void *wcon) { @@ -2732,3 +2734,326 @@ out: return ret; } + +int32_t +cli_snap_create_desc_parse (dict_t *dict, const char **words, int wordcount, + int32_t desc_opt_loc, int32_t no_of_wrds_in_desc) +{ + int32_t ret = -1; + char *desc = NULL; + int32_t i = 0; + int32_t desc_len = 0; + + desc = GF_CALLOC (MAX_SNAP_DESCRIPTION_LEN + 1, sizeof(char), + gf_common_mt_char); + if (!desc) { + gf_log ("", GF_LOG_ERROR, "Out Of Memory"); + ret = -1; + goto out; + } + + /* Creating the description string */ + for (i = 0; i < no_of_wrds_in_desc; i++) { + if ((strcmp (words[desc_opt_loc + 1 + i], "-n") == 0) || + (strcmp (words[desc_opt_loc + 1 + i], "-d") == 0)) { + cli_out ("snapshot create: failed: Options(-n/-d) " + "are not valid descriptions"); + ret = -1; + goto out; + } + + strcat (desc, words[desc_opt_loc + 1 + i]); + strcat (desc, " "); + /* Calculating the size of the description as given by the user */ + desc_len += strlen(words[desc_opt_loc + 1 + i]); + desc_len++; + } + + /* Removing the last space in the string */ + desc[--desc_len] = '\0'; + + if (desc_len > MAX_SNAP_DESCRIPTION_LEN) { + cli_out ("snapshot create: description truncated: " + "Description provided is longer than 1024 characters"); + desc[MAX_SNAP_DESCRIPTION_LEN] = '\0'; + } + + ret = dict_set_dynstr (dict, "snap-description", desc); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to save snap description"); + goto out; + } + + ret = 0; +out: + + if (ret) { + if (desc) + GF_FREE (desc); + } + + return ret; +} + +int32_t +cli_snap_create_parse (dict_t *dict, const char **words, int wordcount, + int32_t cmdi) +{ + int32_t volcount = -1; + int32_t no_of_wrds_in_desc = -1; + int32_t name_opt_loc = -1; + int32_t desc_opt_loc = -1; + char volname_buf[PATH_MAX] = ""; + int32_t ret = -1; + int32_t i = -1; + + /* Finding the "-n" and "-d" in the cli */ + for (i = cmdi + 1; i < wordcount; i++) { + if ((strcmp (words[i], "-n") == 0) && + (name_opt_loc == -1)) + name_opt_loc = i; + + if ((strcmp (words[i], "-d") == 0) && + (desc_opt_loc == -1)) + desc_opt_loc = i; + } + + if ((name_opt_loc == -1) && (desc_opt_loc == -1)) { + /* No snap-name and description has been given */ + + volcount = (wordcount - 1) - cmdi; + } else if ((name_opt_loc > cmdi + 1) && (desc_opt_loc == -1)) { + /* If only name and no description is given */ + + /* if more than one or no snap name is given */ + if (((wordcount - 1) - name_opt_loc) != 1) { + cli_out ("snapshot create: failed: " + "Invalid snap name arguments"); + ret = -1; + goto out; + } + + volcount = (name_opt_loc - 1) - cmdi; + } else if ((name_opt_loc == -1) && (desc_opt_loc > cmdi + 1)) { + /* If no name and only description is given */ + + /* Description should not be blank */ + no_of_wrds_in_desc = (wordcount - 1) - desc_opt_loc; + if (no_of_wrds_in_desc == 0) { + cli_out ("snapshot create: failed: " + "No description provided"); + ret = -1; + goto out; + } + + volcount = (desc_opt_loc - 1) - cmdi; + } else if ((name_opt_loc > cmdi + 1) && (desc_opt_loc > cmdi + 1)) { + /* Both name and description is given */ + + /* Figuring out which comes first */ + if (name_opt_loc < desc_opt_loc) { + /* if more than one or no snap name is given */ + if ((desc_opt_loc - name_opt_loc) != 2) { + cli_out ("snapshot create: failed: " + "Invalid snap name arguments"); + ret = -1; + goto out; + } + + /* Description should not be blank */ + no_of_wrds_in_desc = (wordcount - 1) - desc_opt_loc; + if (no_of_wrds_in_desc == 0) { + cli_out ("snapshot create: failed: " + "No description provided"); + ret = -1; + goto out; + } + + volcount = (name_opt_loc - 1) - cmdi; + } else if (desc_opt_loc < name_opt_loc) { + /* if more than one or no snap name is given */ + if (((wordcount - 1) - name_opt_loc) != 1) { + cli_out ("snapshot create: failed: " + "Invalid snap name arguments"); + ret = -1; + goto out; + } + + /* Description should not be blank */ + no_of_wrds_in_desc = (name_opt_loc) - desc_opt_loc -1; + if (no_of_wrds_in_desc == 0) { + cli_out ("snapshot create: failed: " + "No description provided"); + ret = -1; + goto out; + } + + volcount = (desc_opt_loc - 1) - cmdi; + } + } + + /*At least one volume name should be present */ + if (volcount < 1) { + cli_out ("snapshot create: failed: No volume name provided"); + ret = -1; + goto out; + } + + /* Only one volume is present. volname + * should be set and not volname%d. */ + if (volcount == 1) { + ret = dict_set_str (dict, "volname", (char *)words[2]); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to save volname"); + goto out; + } + } else { + /* Saving the volume names */ + for (i = 2; i < volcount + 2; i++) { + ret = snprintf (volname_buf, sizeof(volname_buf) - 1, + "volname%d", i - 1); + volname_buf[ret] = '\0'; + + ret = dict_set_str (dict, volname_buf, + (char *)words[i]); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to save %s", + volname_buf); + goto out; + } + } + } + + /* Saving the volcount */ + ret = dict_set_int32 (dict, "volcount", volcount); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to save volcount"); + goto out; + } + + /* Saving snap-name/cg-name in dict */ + if (name_opt_loc > cmdi + 1) { + if (strstr((char *)words[name_opt_loc + 1], " ")) { + cli_out ("snapshot create: failed: Invalid snap name"); + ret = -1; + goto out; + } + + if ((strcmp ((char *)words[name_opt_loc + 1], "-n") == 0) || + (strcmp ((char *)words[name_opt_loc + 1], "-d") == 0)) { + cli_out ("snapshot create: failed: Options(-n/-d) " + "are not valid snap names"); + ret = -1; + goto out; + } + + /* Decide if it's a cg-name or a snap-name */ + if (volcount > 1) { + ret = dict_set_str (dict, "cg-name", + (char *)words[name_opt_loc + 1]); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to save cg-name"); + goto out; + } + } else { + ret = dict_set_str (dict, "snap-name", + (char *)words[name_opt_loc + 1]); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to save snap-name"); + goto out; + } + } + } + + /* Parsing the description and saving it in the dict */ + if (desc_opt_loc > cmdi + 1) { + ret = cli_snap_create_desc_parse (dict, words, + wordcount, + desc_opt_loc, + no_of_wrds_in_desc); + if (ret) { + gf_log ("", GF_LOG_ERROR, + "Unable to parse snap-description"); + goto out; + } + } + +out: + return ret; +} + +int32_t +cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options) +{ + int32_t ret = -1; + dict_t *dict = NULL; + gf1_cli_snapshot type = GF_SNAP_OPTION_TYPE_NONE; + int32_t cmdi = 0; + char *opwords[] = {"create", NULL}; + char *w = NULL; + + GF_ASSERT (words); + GF_ASSERT (options); + + dict = dict_new (); + if (!dict) + goto out; + + /* syntax: + * snapshot create [-n ] [-d ] + */ + + /* Lowest wordcount possible */ + if (wordcount < 2) { + gf_log ("", GF_LOG_ERROR, "Invalid command: Not enough arguments"); + goto out; + } + + /* In cases where the vol-name is not given + * parsing fails. volname cannot be an opword. + * and that is what this check verifies */ + w = str_getunamb (words[2], opwords); + if (w) + goto out; + + w = str_getunamb (words[1], opwords); + if (!w) { + /* Checks if the operation is a valid operation */ + gf_log ("", GF_LOG_ERROR, "Opword Mismatch"); + goto out; + } + + /* Check which op is intended */ + if (strcmp (w, "create") == 0) { + type = GF_SNAP_OPTION_TYPE_CREATE; + cmdi = 1; + ret = dict_set_int32 (dict, "type", type); + if (ret) { + gf_log ("", GF_LOG_ERROR, + "Failed to set type."); + goto out; + } + + ret = cli_snap_create_parse (dict, words, + wordcount, cmdi); + if (ret) { + gf_log ("", GF_LOG_ERROR, + "create command parsing failed."); + goto out; + } + } else { + gf_log ("", GF_LOG_ERROR, "Opword Mismatch"); + goto out; + } + + /* If you got so far, input is valid */ + ret = 0; +out: + if (ret) { + if (dict) + dict_destroy (dict); + } else + *options = dict; + + return ret; +} -- cgit