diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/src/cli-cmd-parser.c | 7 | ||||
-rw-r--r-- | cli/src/cli-rpc-ops.c | 278 |
2 files changed, 221 insertions, 64 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index 287943777df..5e619f3cd17 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -3532,12 +3532,13 @@ cli_snap_status_parse (dict_t *dict, const char **words, int wordcount) out: if (ret == 0) { - ret = dict_set_int32 (dict, "cmd", cmd); + ret = dict_set_int32 (dict, "status-cmd", cmd); if (ret) { gf_log ("cli", GF_LOG_ERROR, "Could not save cmd " "of snapshot status"); } } + return ret; } @@ -3812,7 +3813,9 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options, } else if (!strcmp (w, "deactivate")) { type = GF_SNAP_OPTION_TYPE_DEACTIVATE; } - if (type != GF_SNAP_OPTION_TYPE_CONFIG) { + + if (type != GF_SNAP_OPTION_TYPE_CONFIG && + type != GF_SNAP_OPTION_TYPE_STATUS) { ret = dict_set_int32 (dict, "hold_snap_locks", _gf_true); if (ret) { gf_log ("cli", GF_LOG_ERROR, diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 9312f15dc20..37424c68559 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -82,6 +82,9 @@ char *cli_vol_task_status_str[] = {"not started", }; int32_t +gf_cli_snapshot (call_frame_t *frame, xlator_t *this, void *data); + +int32_t gf_cli_get_volume (call_frame_t *frame, xlator_t *this, void *data); @@ -7636,14 +7639,13 @@ out: } int32_t -cli_snapshot_remove_reply (gf_cli_rsp *rsp, dict_t *dict, call_frame_t *frame) +cli_snapshot_remove_reply (gf_cli_rsp *rsp, dict_t *dict) { int32_t ret = -1; char *snap_name = NULL; GF_ASSERT (rsp); GF_ASSERT (dict); - GF_ASSERT (frame); if (rsp->op_ret) { cli_err("snapshot delete: failed: %s", @@ -8361,99 +8363,128 @@ out: } int -cli_snap_status_all (dict_t *dict) { +cli_populate_req_dict_for_status (dict_t *snap_dict, dict_t *dict, int index) { int ret = -1; char key[PATH_MAX] = ""; + char *buffer = NULL; + int type = 0; int snapcount = 0; - int i = 0; + GF_ASSERT (snap_dict); GF_ASSERT (dict); - ret = dict_get_int32 (dict, "status.snapcount", &snapcount); + ret = dict_set_uint32 (snap_dict, "status-cmd", + GF_SNAP_STATUS_TYPE_SNAP); if (ret) { - gf_log ("cli", GF_LOG_ERROR, "Could not get snapcount"); + gf_log ("cli", GF_LOG_ERROR, "Could not save command " + "type in snap dict"); goto out; } - if (snapcount == 0) { - cli_out ("No snapshots present"); + ret = snprintf (key, sizeof (key), "status.snap%d.snapname", index); + if (ret < 0) { + goto out; + } + + ret = dict_get_str (dict, key, &buffer); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Could not get snapname"); + goto out; } - for (i = 0 ; i < snapcount; i++) { - ret = snprintf (key, sizeof (key), "status.snap%d",i); - if (ret < 0) { - goto out; - } - ret = cli_get_single_snap_status (dict, key); + ret = dict_set_str (snap_dict, "snapname", buffer); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Could not save snapname " + "in snap dict"); + goto out; + } + + ret = dict_set_int32 (snap_dict, "type", GF_SNAP_OPTION_TYPE_STATUS); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, + "Could not save command type"); + goto out; + } + + ret = dict_set_dynstr_with_alloc (snap_dict, "cmd-str", + "snapshot status"); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, + "Could not save command string as status"); + goto out; + } + + ret = dict_set_int32 (snap_dict, "hold_vol_locks", _gf_false); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, + "Setting volume lock flag failed"); + goto out; + } + out: return ret; } - int -cli_snapshot_status_display (dict_t *dict, gf_cli_rsp *rsp) +cli_snapshot_status (dict_t *dict, gf_cli_rsp *rsp, + call_frame_t *frame) { char key[PATH_MAX] = ""; int ret = -1; int status_cmd = -1; + cli_local_t *local = NULL; GF_ASSERT (dict); GF_ASSERT (rsp); + GF_ASSERT (frame); + + local = ((call_frame_t *) frame) -> local; + if (!local) { + gf_log ("cli", GF_LOG_ERROR, "frame->local is NULL"); + goto out; + } if (rsp->op_ret) { - cli_err ("Snapshot Status : failed: %s", - rsp->op_errstr ? rsp->op_errstr : - "Please check log file for details"); + if (rsp->op_errstr) { + ret = dict_set_dynstr_with_alloc (local->dict, + "op_err_str", + rsp->op_errstr); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to set " + "op_errstr in local dictionary"); + goto out; + } + } ret = rsp->op_ret; goto out; } - ret = dict_get_int32 (dict, "cmd", &status_cmd); + ret = dict_get_int32 (dict, "status-cmd", &status_cmd); if (ret) { gf_log ("cli", GF_LOG_ERROR, "Could not fetch status type"); goto out; } - switch (status_cmd) { - case GF_SNAP_STATUS_TYPE_ALL: - { - ret = cli_snap_status_all (dict); - if (ret) { - gf_log ("cli", GF_LOG_ERROR, "Could not fetch " - "status of all snap"); - goto out; - } - break; - } - case GF_SNAP_STATUS_TYPE_SNAP: - { - ret = snprintf (key, sizeof (key), "status.snap0"); - if (ret < 0) { - goto out; - } - ret = cli_get_single_snap_status (dict, key); - if (ret) { - gf_log ("cli", GF_LOG_ERROR, "Could not fetch " - "status of snap"); - goto out; - } - break; - } + if (status_cmd != GF_SNAP_STATUS_TYPE_SNAP) { + dict_copy (dict, local->dict); + goto out; + } - case GF_SNAP_STATUS_TYPE_VOL: - { - ret = cli_snap_status_all (dict); - if (ret) { - gf_log ("cli", GF_LOG_ERROR, "Could not fetch " - "status of snap in a volume"); - goto out; - } - break; - } - default: - break; + + ret = snprintf (key, sizeof (key), "status.snap0"); + if (ret < 0) { + goto out; } + + ret = cli_get_single_snap_status (dict, key); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Could not fetch " + "status of snap"); + goto out; + } + + ret = 0; out: return ret; } @@ -8650,7 +8681,7 @@ 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); + ret = cli_snapshot_remove_reply (&rsp, dict); if (ret) { gf_log ("cli", GF_LOG_ERROR, "Failed to delete snap"); @@ -8659,7 +8690,7 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov, break; case GF_SNAP_OPTION_TYPE_STATUS: - ret = cli_snapshot_status_display (dict, &rsp); + ret = cli_snapshot_status (dict, &rsp, frame); if (ret) { gf_log ("cli", GF_LOG_ERROR, "Failed to display " "snapshot status output."); @@ -8684,23 +8715,146 @@ out: } int32_t +gf_cli_snapshot_for_status (call_frame_t *frame, xlator_t *this, + void *data) +{ + + gf_cli_req req = {{0,}}; + dict_t *options = NULL; + int ret = -1; + int32_t cmd = -1; + cli_local_t *local = NULL; + dict_t *snap_dict = NULL; + int snapcount = 0; + int i = 0; + + if (!frame || !this || !data) + goto out; + + if (frame->local) { + local = frame->local; + } else { + goto out; + } + + options = data; + + ret = dict_get_int32 (local->dict, "status-cmd", &cmd); + + if (cmd == GF_SNAP_STATUS_TYPE_ALL || + cmd == GF_SNAP_STATUS_TYPE_VOL) { + + ret = dict_get_int32 (local->dict, "status.snapcount", + &snapcount); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Could not get snapcount"); + goto out; + } + + if (snapcount == 0) { + cli_out ("No snapshots present"); + } + + for (i = 0 ; i < snapcount; i++) { + ret = -1; + + snap_dict = dict_new(); + if (!snap_dict) + goto out; + + ret = cli_populate_req_dict_for_status (snap_dict, + local->dict, i); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Could not " + "populate snap request dictionary"); + goto out; + } + + ret = cli_to_glusterd (&req, frame, + gf_cli_snapshot_cbk, + (xdrproc_t) xdr_gf_cli_req, snap_dict, + GLUSTER_CLI_SNAP, this, cli_rpc_prog, + NULL); + + /* Ignore the return value and error for snapshot + * status of type "ALL" or "VOL" + * + * Scenario : There might be case where status command + * and delete command might be issued at the same time. + * In that case when status tried to fetch detail of + * snap which has been deleted by concurrent command, + * then it will show snapshot not present. Which will + * not be appropriate. + */ + dict_unref (snap_dict); + } + } +out: + return ret; + + if (ret && snap_dict) + dict_unref (snap_dict); +} + +int32_t gf_cli_snapshot (call_frame_t *frame, xlator_t *this, void *data) { - gf_cli_req req = {{0,}}; - dict_t *options = NULL; - int ret = -1; + gf_cli_req req = {{0,}}; + dict_t *options = NULL; + int ret = -1; + int tmp_ret = -1; + cli_local_t *local = NULL; + char *err_str = NULL; + int type = -1; if (!frame || !this || !data) goto out; + if (frame->local) { + local = frame->local; + } else { + goto out; + } + options = data; + ret = dict_get_int32 (local->dict, "type", &type); + + ret = cli_to_glusterd (&req, frame, gf_cli_snapshot_cbk, (xdrproc_t) xdr_gf_cli_req, options, GLUSTER_CLI_SNAP, this, cli_rpc_prog, NULL); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "cli_to_glusterd for " + "snapshot failed"); + goto out; + } + + if (GF_SNAP_OPTION_TYPE_STATUS == type) { + ret = gf_cli_snapshot_for_status (frame, this, data); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "cli to glusterd " + "for snapshot status command failed"); + goto out; + } + } + + ret = 0; + out: + if (ret && GF_SNAP_OPTION_TYPE_STATUS == type) { + tmp_ret = dict_get_str (local->dict, "op_err_str", &err_str); + if (err_str) { + cli_err ("Snapshot Status : failed: %s", err_str); + dict_del (local->dict, "op_err_str"); + } else { + cli_err ("Snapshot Status : failed: %s", "Please " + "check log file for details"); + } + } + gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); GF_FREE (req.dict.dict_val); |