From 005b445d684f30e8611c9b2a374cdc798a6cdcbb Mon Sep 17 00:00:00 2001 From: Raghavendra Bhat Date: Fri, 29 Nov 2013 12:29:38 +0530 Subject: cli/glusterd: implement the snap and cg delete functionalities Change-Id: Icdb66c89acdd043d0d6368c48ce2e01b1a40966f Signed-off-by: Raghavendra Bhat --- cli/src/cli-cmd-parser.c | 287 ++++++++++++++++++++++++++++++++------------- cli/src/cli-cmd-snapshot.c | 4 + cli/src/cli-rpc-ops.c | 61 ++++++++++ 3 files changed, 271 insertions(+), 81 deletions(-) (limited to 'cli/src') diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index 4bbaa4923..d1afa72a4 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -3256,6 +3256,97 @@ out: return ret; } +/* remove command takes either the snapname or the cg name. + If snap has to be remvoed for a volume, then the volume name + also should be given in the command. If cg should be removed, + then volume name is not necessary. + "gluster snapshot delete ( -s | -c )" +*/ +int32_t +cli_snap_remove_parse (dict_t *dict, const char **words, int wordcount, + unsigned int cmdi) +{ + uint32_t name_opt_loc = 0; + int32_t ret = -1; + uint32_t i = 0; + gf_boolean_t is_cg = _gf_false; + + GF_ASSERT (dict); + GF_ASSERT (words); + + /* Finding the "-s or -c" in the cli */ + for (i = cmdi; i < wordcount; i++) { + if (!strcmp (words[i], "-s") || !strcmp (words[i], "-c")) { + name_opt_loc = i; + if (!strcmp (words[i], "-c")) + is_cg = _gf_true; + break; + } + } + + if (name_opt_loc == 0) { + gf_log ("", GF_LOG_ERROR, "options -s/-c is not found in the " + "command"); + goto out; + } + + if (name_opt_loc == (wordcount - 1)) { + gf_log ("", GF_LOG_ERROR, "%s name is not given", + is_cg?"cg":"snap"); + goto out; + } + + if (!is_cg) { + if (!strcmp (words[cmdi], "-s")) { + gf_log ("", GF_LOG_ERROR, "Volume name is not given " + "for the snapshot deletion"); + ret = -1; + goto out; + } + } else { + if (strcmp (words[cmdi], "-c")) { + gf_log ("", GF_LOG_ERROR, "volume name is not needed " + "for consistency group deletion"); + ret = -1; + goto out; + } + } + + /* Saving snap-name/cg-name in dict */ + if (name_opt_loc >= cmdi) { + /* Decide if it's a cg-name or a snap-name */ + if (is_cg) { + ret = dict_set_str (dict, "cgname", + (char *)words[name_opt_loc + 1]); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to save cg-name"); + goto out; + } + } else { + ret = dict_set_int64 (dict, "volcount", 1); + if (ret) { + gf_log ("", GF_LOG_ERROR, "failed to set " + "volcount"); + goto out; + } + ret = dict_set_str (dict, "volname1", + (char *)words[name_opt_loc - 1]); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to save volname"); + goto out; + } + ret = dict_set_str (dict, "snapname", + (char *)words[name_opt_loc + 1]); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to save snapname"); + goto out; + } + } + } + +out: + return ret; +} /* Syntax: * snapshot restore (-v | -c ) @@ -3391,95 +3482,129 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options, goto out; } - /* Check which op is intended */ - if (strcmp (w, "create") == 0) { - /*syntax: - * snapshot create [-n ] - * [-d ] - */ - - /* 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; - + if (!strcmp (w, "create")) type = GF_SNAP_OPTION_TYPE_CREATE; - cmdi = 1; - - ret = cli_snap_create_parse (dict, words, wordcount, cmdi); - if (ret) { - gf_log ("", GF_LOG_ERROR, - "create command parsing failed."); - goto out; - } - } else if (strcmp (w, "delete") == 0) { - gf_log ("", GF_LOG_ERROR, "Operation Not supported"); - goto out; - } else if (strcmp (w, "restore") == 0) { - /* Syntax: - * snapshot restore (-v | -c ) - */ + if (!strcmp (w, "list")) + type = GF_SNAP_OPTION_TYPE_LIST; + if (!strcmp (w, "delete")) + type = GF_SNAP_OPTION_TYPE_DELETE; + if (!strcmp (w, "config")) + type = GF_SNAP_OPTION_TYPE_CONFIG; + if (!strcmp (w, "restore")) type = GF_SNAP_OPTION_TYPE_RESTORE; - /* Start parsing from the first option after "restore" */ - cmdi = 2; - - ret = cli_snap_restore_parse (dict, words, wordcount, cmdi); - if (ret) { - gf_log ("cli", GF_LOG_ERROR, "Failed to parse " - "restore command"); - goto out; - } - } else if (strcmp (w, "start") == 0) { - gf_log ("", GF_LOG_ERROR, "Operation Not supported"); - goto out; - } else if (strcmp (w, "stop") == 0) { - gf_log ("", GF_LOG_ERROR, "Operation Not supported"); - goto out; - } else if (strcmp (w, "list") == 0) { - /* snapshot list [ | [-s ] - * | -c ] [-d] */ - /* check if arguments contains any Keyword */ - cmdi = 2; - for (i = cmdi ; i < wordcount ; i++) { - w = str_getunamb (words[i], opwords); - if (w) { - /*Checks if the operation is a valid operation*/ - cli_out ("Usage of Keyword in wrong place"); - gf_log ("", GF_LOG_ERROR, "Opword Mismatch"); - goto out; - } - } + /* Check which op is intended */ + switch (type) { + case GF_SNAP_OPTION_TYPE_CREATE: + { + /*syntax: + snapshot create [-n ] + [-d ] + */ + + /* 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; + cmdi = 1; - type = GF_SNAP_OPTION_TYPE_LIST; + ret = cli_snap_create_parse (dict, words, + wordcount, cmdi); + if (ret) { + gf_log ("", GF_LOG_ERROR, + "create command parsing failed."); + goto out; + } + break; + } + case GF_SNAP_OPTION_TYPE_LIST: + { + /* snapshot list [ | [-s ] + * | -c ] [-d] */ + /* check if arguments contains any Keyword */ + cmdi = 2; + for (i = cmdi ; i < wordcount ; i++) { + w = str_getunamb (words[i], opwords); + if (w) { + /*Checks if the operation is a valid + operation*/ + cli_out ("Usage of Keyword in wrong " + "place"); + gf_log ("", GF_LOG_ERROR, "Opword " + "Mismatch"); + goto out; + } + } - ret = cli_snap_list_parse (dict, words, - wordcount, cmdi); + ret = cli_snap_list_parse (dict, words, + wordcount, cmdi); - if (ret) { - gf_log ("", GF_LOG_ERROR, - "list command parsing failed."); - goto out; - } - } else if (strcmp (w, "status") == 0) { - gf_log ("", GF_LOG_ERROR, "Operation Not supported"); - goto out; - } else if (strcmp (w, "config") == 0) { - /* snapshot config [snap_max_limit ] */ + if (ret) { + gf_log ("", GF_LOG_ERROR, + "list command parsing failed."); + goto out; + } + break; + } + case GF_SNAP_OPTION_TYPE_DELETE: + { + /*syntax: + snapshot remove [ -s | -c ] + */ + w = str_getunamb (words[2], opwords); + if (w) { + gf_log ("", GF_LOG_ERROR, "Opword Mismatch"); + goto out; + } - type = GF_SNAP_OPTION_TYPE_CONFIG; + cmdi = 2; - ret = cli_snap_config_parse (words, wordcount, dict, state); - if (ret) { - gf_log ("", GF_LOG_ERROR, - "config command parsing failed."); - goto out; - } - } else { - gf_log ("", GF_LOG_ERROR, "Opword Mismatch"); - goto out; + ret = cli_snap_remove_parse (dict, words, + wordcount, cmdi); + if (ret) { + gf_log ("", GF_LOG_ERROR, + "remove command parsing failed."); + goto out; + } + break; + } + case GF_SNAP_OPTION_TYPE_CONFIG: + { + /* snapshot config [snap_max_limit ] */ + ret = cli_snap_config_parse (words, wordcount, dict, + state); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, + "config command parsing failed."); + goto out; + } + break; + } + case GF_SNAP_OPTION_TYPE_RESTORE: + { + /* Syntax: + * snapshot restore (-v | + * -c ) + */ + + /* Start parsing from the first option after "restore" */ + cmdi = 2; + + ret = cli_snap_restore_parse (dict, words, wordcount, + cmdi); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to parse " + "restore command"); + goto out; + } + break; + } + default: + gf_log ("", GF_LOG_ERROR, "Opword Mismatch"); + goto out; + break; } ret = dict_set_int32 (dict, "type", type); diff --git a/cli/src/cli-cmd-snapshot.c b/cli/src/cli-cmd-snapshot.c index b3bc98abf..6aac4d29f 100644 --- a/cli/src/cli-cmd-snapshot.c +++ b/cli/src/cli-cmd-snapshot.c @@ -94,6 +94,10 @@ struct cli_cmd snapshot_cmds[] = { cli_cmd_snapshot_cbk, "Snapshot Config." }, + {"snapshot delete ( -s | -c )", + cli_cmd_snapshot_cbk, + "Snapshot Delete." + }, { NULL, NULL, NULL } }; diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 830bd763f..1a90e192c 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -7838,6 +7838,63 @@ out : return ret; } +int32_t +cli_snapshot_remove_reply (gf_cli_rsp *rsp, dict_t *dict, call_frame_t *frame) +{ + int32_t ret = -1; + char *snap_name = NULL; + char *cg_name = NULL; + int64_t volcount = -1; + char *volname = NULL; + gf_boolean_t is_cg = _gf_false; + + GF_ASSERT (rsp); + GF_ASSERT (dict); + GF_ASSERT (frame); + + if (rsp->op_ret) { + cli_err("snapshot remove: failed: %s", + rsp->op_errstr ? rsp->op_errstr : + "Please check log file for details"); + ret = rsp->op_ret; + goto out; + } + + ret = dict_get_int64 (dict, "volcount", &volcount); + if (!ret) { + if (volcount == 1) { + ret = dict_get_str (dict, "volname1", &volname); + if (ret) + gf_log ("", GF_LOG_WARNING, "getting volume name" + " failed"); + } else + is_cg = _gf_true; + } + + if (is_cg) { + if (dict_get_str (dict, "cgname", + &cg_name) != 0) + cg_name = "???"; + + cli_out ("snapshot delete: %s: consistency " + "group removed successfully", + cg_name); + } else { + if (dict_get_str (dict, "snapname", + &snap_name) != 0) + snap_name = "???"; + + cli_out ("snapshot delete: %s: " + "snap removed successfully", + snap_name); + } + + ret = 0; + +out: + return ret; +} + int gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) @@ -8045,6 +8102,10 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov, } break; + case GF_SNAP_OPTION_TYPE_DELETE: + ret = cli_snapshot_remove_reply (&rsp, dict, frame); + break; + default: cli_err ("Unknown command executed"); ret = -1; -- cgit