diff options
-rw-r--r-- | cli/src/cli-cmd-parser.c | 7 | ||||
-rw-r--r-- | cli/src/cli-rpc-ops.c | 278 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-snapshot.c | 188 |
3 files changed, 247 insertions, 226 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); diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c index 58e423aab1c..a4c60a87d9e 100644 --- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c +++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c @@ -3099,155 +3099,15 @@ glusterd_handle_snapshot_status (rpcsvc_request_t *req, glusterd_op_t op, dict_t *dict, char *err_str, size_t len) { int ret = -1; - char *volname = NULL; - char *snapname = NULL; - char *buf = NULL; - glusterd_conf_t *conf = NULL; xlator_t *this = NULL; - int32_t cmd = -1; - int i = 0; - dict_t *voldict = NULL; - char key[PATH_MAX] = ""; - glusterd_volinfo_t *volinfo = NULL; - glusterd_snap_t *snap = NULL; - glusterd_volinfo_t *snap_volinfo = NULL; this = THIS; GF_ASSERT (this); - conf = this->private; - GF_ASSERT (conf); GF_ASSERT (req); GF_ASSERT (dict); GF_ASSERT (err_str); - ret = dict_get_int32 (dict, "cmd", &cmd); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Could not get status type"); - goto out; - } - switch (cmd) { - case GF_SNAP_STATUS_TYPE_ALL: - { - /* IF we give "gluster snapshot status" - * then lock is held on all snaps. - * This is the place where necessary information - * (snapname and snapcount)is populated in dictionary - * for locking. - */ - ++i; - list_for_each_entry (snap, &conf->snapshots, snap_list) - { - snprintf (key, sizeof (key), "snapname%d", i); - buf = gf_strdup (snap->snapname); - if (!buf) { - ret = -1; - goto out; - } - ret = dict_set_dynstr (dict, key, buf); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, - "Could not save snapname (%s) " - "in the dictionary", - snap->snapname); - GF_FREE (buf); - goto out; - } - - buf = NULL; - i++; - } - - ret = dict_set_int32 (dict, "snapcount", i - 1); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Could not " - "save snapcount in the dictionary"); - goto out; - } - break; - } - - case GF_SNAP_STATUS_TYPE_SNAP: - { - /* IF we give "gluster snapshot status <snapname>" - * then lock is held on single snap. - * This is the place where necessary information - * (snapname)is populated in dictionary - * for locking. - */ - ret = dict_get_str (dict, "snapname", &snapname); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, - "Failed to fetch snap name"); - goto out; - } - - snap = glusterd_find_snap_by_name (snapname); - if (!snap) { - snprintf (err_str, len, "Snap (%s)" - "does not exist", snapname); - gf_log(this->name, GF_LOG_ERROR, - "%s", err_str); - ret = -1; - goto out; - } - break; - } - case GF_SNAP_STATUS_TYPE_VOL: - ret = dict_get_str (dict, "volname", &volname); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, - "Failed to fetch volname"); - goto out; - } - - ret = glusterd_volinfo_find (volname, &volinfo); - if (ret) { - snprintf (err_str, len, "Volume (%s) " - "does not exist", volname); - gf_log (this->name, GF_LOG_ERROR, - "%s", err_str); - goto out; - } - - i = 1; - list_for_each_entry (snap_volinfo, - &volinfo->snap_volumes, snapvol_list) { - snprintf (key, sizeof (key), "snapname%d", i); - - buf = gf_strdup - (snap_volinfo->snapshot->snapname); - if (!buf) { - ret = -1; - goto out; - } - - ret = dict_set_dynstr (dict, key, buf); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, - "Could not save snapname"); - GF_FREE (buf); - goto out; - } - - buf = NULL; - i++; - } - - ret = dict_set_int32 (dict, "snapcount", i-1); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, - "Could not save snapcount"); - goto out; - } - break; - default: - { - gf_log (this->name, GF_LOG_ERROR, "Unknown type"); - ret = -1; - goto out; - } - } ret = glusterd_mgmt_v3_initiate_snap_phases (req, op, dict); if (ret) { @@ -3257,11 +3117,7 @@ glusterd_handle_snapshot_status (rpcsvc_request_t *req, glusterd_op_t op, } ret = 0; - out: - if (voldict) { - dict_unref (voldict); - } return ret; } @@ -4286,7 +4142,7 @@ glusterd_snapshot_status_prevalidate (dict_t *dict, char **op_errstr, goto out; } - ret = dict_get_int32 (dict, "cmd", &cmd); + ret = dict_get_int32 (dict, "status-cmd", &cmd); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Could not fetch status cmd"); @@ -4331,7 +4187,7 @@ glusterd_snapshot_status_prevalidate (dict_t *dict, char **op_errstr, ret = glusterd_volinfo_find (volname, &volinfo); if (ret) { - ret = gf_asprintf (op_errstr, "Volume (%s)" + ret = gf_asprintf (op_errstr, "Volume (%s) " "not found", volname); if (ret < 0) { goto out; @@ -5616,19 +5472,20 @@ glusterd_get_snap_status_of_volume (char **op_errstr, dict_t *rsp_dict, list_for_each_entry_safe (snap_volinfo, temp_volinfo, &volinfo->snap_volumes, snapvol_list) { - ret = snprintf (key, sizeof (key), "status.snap%d", i); + ret = snprintf (key, sizeof (key), + "status.snap%d.snapname", i); if (ret < 0) { goto out; } - ret = glusterd_get_each_snap_object_status (op_errstr, - rsp_dict, snap_volinfo->snapshot, key); - + ret = dict_set_dynstr_with_alloc (rsp_dict, key, + snap_volinfo->snapshot->snapname); if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Function : " - "glusterd_get_single_snap_status failed"); + gf_log (this->name, GF_LOG_ERROR, "Could not save " + "snap name"); goto out; } + i++; } @@ -5664,20 +5521,20 @@ glusterd_get_all_snapshot_status (dict_t *dict, char **op_errstr, list_for_each_entry_safe (snap, tmp_snap, &priv->snapshots, snap_list) { - ret = snprintf (key, sizeof (key), "status.snap%d", i); + ret = snprintf (key, sizeof (key), + "status.snap%d.snapname", i); if (ret < 0) { goto out; } - ret = glusterd_get_each_snap_object_status (op_errstr, - rsp_dict, snap, key); - + ret = dict_set_dynstr_with_alloc (rsp_dict, key, + snap->snapname); if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Could not get " - "the details of a snap object: %s", - snap->snapname); + gf_log (this->name, GF_LOG_ERROR, "Could not save " + "snap name"); goto out; } + i++; } @@ -5688,7 +5545,7 @@ glusterd_get_all_snapshot_status (dict_t *dict, char **op_errstr, } ret = 0; -out: +out : return ret; } @@ -5715,14 +5572,14 @@ glusterd_snapshot_status_commit (dict_t *dict, char **op_errstr, conf = this->private; GF_ASSERT (conf); - ret = dict_get_int32 (dict, "cmd", &cmd); + ret = dict_get_int32 (dict, "status-cmd", &cmd); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Failed to get status cmd type"); goto out; } - ret = dict_set_int32 (rsp_dict, "cmd", cmd); + ret = dict_set_int32 (rsp_dict, "status-cmd", cmd); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Could not save status cmd in rsp dictionary"); @@ -5769,6 +5626,13 @@ glusterd_snapshot_status_commit (dict_t *dict, char **op_errstr, "get status of snap %s", get_buffer); goto out; } + + ret = dict_set_int32 (rsp_dict, "status.snapcount", 1); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Unable to " + "set snapcount to 1"); + goto out; + } break; } case GF_SNAP_STATUS_TYPE_VOL: |