summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cli/src/cli-cmd-parser.c7
-rw-r--r--cli/src/cli-rpc-ops.c278
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot.c188
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: