summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cli/src/cli-cmd-parser.c104
-rw-r--r--cli/src/cli-cmd-snapshot.c6
-rw-r--r--cli/src/cli-rpc-ops.c49
-rw-r--r--rpc/xdr/src/cli1-xdr.c11
-rw-r--r--rpc/xdr/src/cli1-xdr.h11
-rw-r--r--rpc/xdr/src/cli1-xdr.x10
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mgmt.c8
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot.c609
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c11
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.c3
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h3
11 files changed, 656 insertions, 169 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index cf790918c..b7078ff28 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -3163,6 +3163,82 @@ out:
return ret;
}
+int32_t
+cli_snap_config_parse (const char **words, int wordcount, dict_t *options)
+{
+ dict_t *dict = NULL;
+ char *volname = NULL;
+ int ret = -1;
+ char *key = NULL;
+ char *value = NULL;
+ uint64_t limit = 0;
+ gf1_cli_snapshot type = GF_SNAP_OPTION_TYPE_NONE;
+
+ GF_ASSERT (words);
+ GF_ASSERT (options);
+
+ if ((wordcount != 3) && (wordcount != 5))
+ goto out;
+
+ volname = (char *)words[2];
+
+ GF_ASSERT (volname);
+
+ type = GF_SNAP_OPTION_TYPE_CONFIG;
+ ret = dict_set_int32 (options, "type", type);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR,
+ "Failed to set type.");
+ goto out;
+ }
+
+ ret = dict_set_str (options, "volname", volname);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR,
+ "Failed to set volname.");
+ goto out;
+ }
+
+ /* snapshot config <volname | all> [snap_max_limit <count>] */
+
+ if (wordcount == 3) {
+ ret = dict_set_int32 (options, "config-command",
+ GF_SNAP_CONFIG_DISPLAY);
+ goto out;
+ }
+
+ key = (char *) words[3];
+ value = (char *) words[4];
+ if ( !key || !value) {
+ ret = -1;
+ goto out;
+ }
+ if (strncmp (key, "snap-max-limit", 14)) {
+ gf_log ("", GF_LOG_ERROR, "Invalid key");
+ goto out;
+ }
+ if (!strncmp (volname, "all", 3)) {
+ ret = dict_set_int32 (options, "config-command",
+ GF_SNAP_CONFIG_SYS_MAX);
+ } else {
+ ret = dict_set_int32 (options, "config-command",
+ GF_SNAP_CONFIG_VOL_MAX);
+ }
+
+ limit = (uint64_t) atoll (value);
+ ret = dict_set_uint64 (options, "limit", limit);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR,
+ "Failed to set limit.");
+ goto out;
+ }
+ if (ret)
+ goto out;
+
+out:
+ return ret;
+}
+
int32_t
cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options)
@@ -3171,7 +3247,7 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options)
dict_t *dict = NULL;
gf1_cli_snapshot type = GF_SNAP_OPTION_TYPE_NONE;
int32_t cmdi = 0;
- char *opwords[] = {"create", "list", NULL};
+ char *opwords[] = {"create", "list", "config", NULL};
char *w = NULL;
int i = 0;
@@ -3211,12 +3287,6 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options)
goto out;
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);
@@ -3239,14 +3309,8 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options)
goto out;
}
}
- type = GF_SNAP_OPTION_TYPE_LIST;
- ret = dict_set_int32 (dict, "type" , type);
- if (ret) {
- gf_log ("" , GF_LOG_ERROR,
- "Failed to set type.");
- goto out;
- }
+ type = GF_SNAP_OPTION_TYPE_LIST;
ret = cli_snap_list_parse (dict, words,
wordcount, cmdi);
@@ -3256,11 +3320,23 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options)
"list command parsing failed.");
goto out;
}
+ } else if (strcmp (w, "config") == 0){
+ /* snapshot config <volname | all> [snap_max_limit <count>] */
+
+ type = GF_SNAP_OPTION_TYPE_CONFIG;
+
+ ret = cli_snap_config_parse (words, wordcount, dict);
} else {
gf_log ("", GF_LOG_ERROR, "Opword Mismatch");
goto out;
}
+ ret = dict_set_int32 (dict, "type", type);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR,
+ "Failed to set type.");
+ goto out;
+ }
/* If you got so far, input is valid */
ret = 0;
out:
diff --git a/cli/src/cli-cmd-snapshot.c b/cli/src/cli-cmd-snapshot.c
index afe8bf901..6c2b3d5e5 100644
--- a/cli/src/cli-cmd-snapshot.c
+++ b/cli/src/cli-cmd-snapshot.c
@@ -77,7 +77,7 @@ struct cli_cmd snapshot_cmds[] = {
cli_cmd_snapshot_help_cbk,
"display help for snapshot commands"
},
- {"snapshot create <volnames> [-n <snap-name/cg-name>] [-d <description>]",
+ {"snapshot create <volnames> [-n <snap-name|cg-name>] [-d <description>]",
cli_cmd_snapshot_cbk,
"Snapshot Create."
},
@@ -86,6 +86,10 @@ struct cli_cmd snapshot_cmds[] = {
cli_cmd_snapshot_cbk,
"Snapshot List."
},
+ {"snapshot config < volname | all > [ snap-max-limit <count> ]",
+ cli_cmd_snapshot_cbk,
+ "Snapshot Config."
+ },
{ NULL, NULL, NULL }
};
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index 20cad3bb3..e881e18fc 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -7806,6 +7806,9 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,
int32_t type = 0;
int64_t volcount = -1;
call_frame_t *frame = NULL;
+ uint64_t limit = 0;
+ int32_t config_command = 0;
+ char *volname = NULL;
if (req->rpc_status == -1) {
ret = -1;
@@ -7903,6 +7906,52 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,
}
break;
+ case GF_SNAP_OPTION_TYPE_CONFIG:
+ if (rsp.op_ret) {
+ cli_err ("Snapshot Config : failed: %s",
+ rsp.op_errstr ? rsp.op_errstr :
+ "Please check log file for details");
+ ret = rsp.op_ret;
+ goto out;
+ }
+
+ ret = dict_get_int32 (dict, "config-command", &config_command);
+
+ if (ret) {
+ gf_log("", GF_LOG_DEBUG, "Could not fetch config type");
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log("", GF_LOG_DEBUG, "Could not fetch "
+ "volname");
+ ret = -1;
+ goto out;
+ }
+
+ if (!strcmp (volname, "all")) {
+ volname = "System";
+ }
+
+ if (config_command == GF_SNAP_CONFIG_DISPLAY) {
+
+ ret = dict_get_uint64 (dict, "limit", &limit);
+ if (ret) {
+ gf_log("", GF_LOG_DEBUG, "Could not fetch "
+ "limit for %s", volname);
+ ret = -1;
+ goto out;
+ }
+ cli_out ("Max snapshot count set for %s is %"PRIu64,
+ volname, limit);
+ } else {
+ cli_out ("Snapshot config max set for %s successfull",
+ volname);
+ }
+ break;
+
default:
cli_err ("Unknown command executed");
ret = -1;
diff --git a/rpc/xdr/src/cli1-xdr.c b/rpc/xdr/src/cli1-xdr.c
index f0f08d334..97b210e14 100644
--- a/rpc/xdr/src/cli1-xdr.c
+++ b/rpc/xdr/src/cli1-xdr.c
@@ -190,6 +190,17 @@ xdr_gf1_cli_snapshot (XDR *xdrs, gf1_cli_snapshot *objp)
}
bool_t
+xdr_gf1_cli_snapshot_config (XDR *xdrs, gf1_cli_snapshot_config *objp)
+{
+ register int32_t *buf;
+ buf = NULL;
+
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_gf_cli_req (XDR *xdrs, gf_cli_req *objp)
{
register int32_t *buf;
diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h
index 0987d6d41..4c4cb0f18 100644
--- a/rpc/xdr/src/cli1-xdr.h
+++ b/rpc/xdr/src/cli1-xdr.h
@@ -182,6 +182,15 @@ enum gf1_cli_snapshot {
};
typedef enum gf1_cli_snapshot gf1_cli_snapshot;
+enum gf1_cli_snapshot_config {
+ GF_SNAP_CONFIG_TYPE_NONE = 0,
+ GF_SNAP_CONFIG_SYS_MAX = 0 + 1,
+ GF_SNAP_CONFIG_VOL_MAX = 0 + 2,
+ GF_SNAP_CONFIG_DISPLAY = 0 + 3,
+ GF_SNAP_CONFIG_CG_MAX = 0 + 4,
+};
+typedef enum gf1_cli_snapshot_config gf1_cli_snapshot_config;
+
struct gf_cli_req {
struct {
u_int dict_len;
@@ -294,6 +303,7 @@ extern bool_t xdr_gf1_cli_stats_op (XDR *, gf1_cli_stats_op*);
extern bool_t xdr_gf1_cli_top_op (XDR *, gf1_cli_top_op*);
extern bool_t xdr_gf_cli_status_type (XDR *, gf_cli_status_type*);
extern bool_t xdr_gf1_cli_snapshot (XDR *, gf1_cli_snapshot*);
+extern bool_t xdr_gf1_cli_snapshot_config (XDR *, gf1_cli_snapshot_config*);
extern bool_t xdr_gf_cli_req (XDR *, gf_cli_req*);
extern bool_t xdr_gf_cli_rsp (XDR *, gf_cli_rsp*);
extern bool_t xdr_gf1_cli_peer_list_req (XDR *, gf1_cli_peer_list_req*);
@@ -323,6 +333,7 @@ extern bool_t xdr_gf1_cli_stats_op ();
extern bool_t xdr_gf1_cli_top_op ();
extern bool_t xdr_gf_cli_status_type ();
extern bool_t xdr_gf1_cli_snapshot ();
+extern bool_t xdr_gf1_cli_snapshot_config ();
extern bool_t xdr_gf_cli_req ();
extern bool_t xdr_gf_cli_rsp ();
extern bool_t xdr_gf1_cli_peer_list_req ();
diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x
index 3a28d5256..8167abbf9 100644
--- a/rpc/xdr/src/cli1-xdr.x
+++ b/rpc/xdr/src/cli1-xdr.x
@@ -124,7 +124,7 @@ enum gf_cli_status_type {
/* Identifiers for snapshot clis */
enum gf1_cli_snapshot {
- GF_SNAP_OPTION_TYPE_NONE,
+ GF_SNAP_OPTION_TYPE_NONE = 0,
GF_SNAP_OPTION_TYPE_CREATE,
GF_SNAP_OPTION_TYPE_DELETE,
GF_SNAP_OPTION_TYPE_RESTORE,
@@ -135,6 +135,14 @@ enum gf1_cli_snapshot {
GF_SNAP_OPTION_TYPE_CONFIG
};
+enum gf1_cli_snapshot_config {
+ GF_SNAP_CONFIG_TYPE_NONE = 0,
+ GF_SNAP_CONFIG_SYS_MAX,
+ GF_SNAP_CONFIG_VOL_MAX,
+ GF_SNAP_CONFIG_DISPLAY,
+ GF_SNAP_CONFIG_CG_MAX
+};
+
struct gf_cli_req {
opaque dict<>;
} ;
diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-mgmt.c
index defd8f477..e6f341ada 100644
--- a/xlators/mgmt/glusterd/src/glusterd-mgmt.c
+++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.c
@@ -1316,14 +1316,6 @@ glusterd_mgmt_v3_initiate_all_phases (rpcsvc_request_t *req, glusterd_op_t op,
goto out;
}
- /* BRICK OP PHASE */
- ret = glusterd_mgmt_v3_brick_op (conf, op, req_dict,
- &op_errstr, npeers);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Brick Ops Failed");
- goto out;
- }
-
/* COMMIT OP PHASE */
ret = glusterd_mgmt_v3_commit (conf, op, req_dict,
&op_errstr, npeers);
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
index c946e4dbd..87ed711dc 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c
+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
@@ -44,7 +44,155 @@
#endif
int
-glusterd_snapshot_prevalidate (dict_t *dict, char **op_errstr,
+glusterd_snapshot_config_limit_prevalidate (dict_t *dict, char **op_errstr,
+ int config_command)
+{
+ char *volname = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ uint64_t limit = 0;
+ xlator_t *this = NULL;
+ int ret = -1;
+ char err_str[PATH_MAX] = {0,};
+ glusterd_conf_t *conf = NULL;
+
+ this = THIS;
+
+ GF_ASSERT (this);
+ GF_ASSERT (dict);
+ GF_ASSERT (*op_errstr);
+
+ conf = this->private;
+
+ GF_ASSERT (conf);
+
+ switch (config_command) {
+
+ case GF_SNAP_CONFIG_SYS_MAX:
+ ret = dict_get_uint64 (dict, "limit", &limit);
+ if (ret) {
+ snprintf (err_str, PATH_MAX,"Failed to get the"
+ " snapshot limit");
+ *op_errstr = gf_strdup (err_str);
+ gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+ if (limit < 0 || limit > GLUSTERD_SNAPS_MAX_LIMIT) {
+ ret = -1;
+ snprintf (err_str, PATH_MAX,"Invalid max snap limit "
+ "%"PRIu64 ". Expected range 0 - %"PRIu64,
+ limit, conf->snap_max_limit);
+ *op_errstr = gf_strdup (err_str);
+ gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+ break;
+
+ case GF_SNAP_CONFIG_VOL_MAX:
+ // volume wide limit
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ snprintf (err_str, PATH_MAX,"Failed to get the"
+ " volume name");
+ *op_errstr = gf_strdup (err_str);
+ gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret) {
+ snprintf (err_str, PATH_MAX,"Failed to get the"
+ " volinfo for volume %s", volname);
+ *op_errstr = gf_strdup (err_str);
+ gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+ ret = dict_get_uint64 (dict, "limit", &limit);
+ if (ret) {
+ snprintf (err_str, PATH_MAX,"Failed to get the"
+ " snapshot limit volinfo for volume %s",
+ volname);
+ *op_errstr = gf_strdup (err_str);
+ gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+ if (limit < 0 || limit > conf->snap_max_limit) {
+ ret = -1;
+ snprintf (err_str, PATH_MAX,"Invalid max snap limit "
+ "%"PRIu64 " for volume %s. Expected range"
+ " 0 - %"PRIu64, limit, volname,
+ conf->snap_max_limit);
+ *op_errstr = gf_strdup (err_str);
+ gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+ break;
+
+ case GF_SNAP_CONFIG_CG_MAX:
+ break;
+
+ case GF_SNAP_CONFIG_DISPLAY:
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ snprintf (err_str, PATH_MAX,"Failed to get the"
+ " volume name");
+ *op_errstr = gf_strdup (err_str);
+ gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+ if (!strncmp (volname, "all", 3)) {
+ ret = 0;
+ goto out;
+ }
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret) {
+ snprintf (err_str, PATH_MAX,"Failed to get the"
+ " volinfo for volume %s", volname);
+ *op_errstr = gf_strdup (err_str);
+ gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+ break;
+ default:
+ break;
+ }
+out:
+ return ret;
+}
+
+int
+glusterd_snapshot_config_prevalidate (dict_t *dict, char **op_errstr)
+{
+ int config_command = 0;
+ xlator_t *this = NULL;
+ int ret = -1;
+
+ this = THIS;
+ ret = dict_get_int32 (dict, "config-command", &config_command);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to get config-command type");
+ goto out;
+ }
+
+ switch (config_command) {
+ case GF_SNAP_CONFIG_SYS_MAX:
+ case GF_SNAP_CONFIG_VOL_MAX:
+ case GF_SNAP_CONFIG_CG_MAX:
+ case GF_SNAP_CONFIG_DISPLAY:
+ ret = glusterd_snapshot_config_limit_prevalidate (dict,
+ op_errstr,
+ config_command);
+ break;
+ default:
+ ret = -1;
+ gf_log (this->name, GF_LOG_ERROR, "Incorrect config op");
+ break;
+ }
+out:
+ return ret;
+}
+
+int
+glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
dict_t *rsp_dict)
{
char *volname = NULL;
@@ -52,6 +200,49 @@ glusterd_snapshot_prevalidate (dict_t *dict, char **op_errstr,
int64_t volume_count = 0;
char volname_buf[PATH_MAX] = {0, };
int64_t i = 0;
+ xlator_t *this = NULL;
+ int ret = -1;
+
+ ret = dict_get_int64 (dict, "volcount", &volume_count);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "failed to "
+ "get the volume count");
+ goto out;
+ }
+ for (i = 0; i < volume_count; i++) {
+ snprintf (volname_buf, sizeof (volname_buf),
+ "volname%ld", i+1);
+ ret = dict_get_str (dict, volname_buf,
+ &volname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to get volume name");
+ goto out;
+ }
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to get the volinfo for "
+ "the volume %s", volname);
+ goto out;
+ }
+ if (glusterd_is_defrag_on (volinfo)) {
+ ret = -1;
+ gf_log (this->name, GF_LOG_WARNING,
+ "rebalance process is running "
+ "for the volume %s", volname);
+ goto out;
+ }
+ //Also check whether geo replication is running
+ }
+out:
+ return ret;
+}
+
+int
+glusterd_snapshot_prevalidate (dict_t *dict, char **op_errstr,
+ dict_t *rsp_dict)
+{
int snap_command = 0;
xlator_t *this = NULL;
int ret = -1;
@@ -61,6 +252,7 @@ glusterd_snapshot_prevalidate (dict_t *dict, char **op_errstr,
GF_ASSERT (this);
GF_ASSERT (dict);
GF_ASSERT (rsp_dict); //not sure if this is needed, verify.
+
ret = dict_get_int32 (dict, "type", &snap_command);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "unable to get the type of "
@@ -69,49 +261,20 @@ glusterd_snapshot_prevalidate (dict_t *dict, char **op_errstr,
}
switch (snap_command) {
- case (GF_SNAP_OPTION_TYPE_CREATE):
- {
- ret = dict_get_int64 (dict, "volcount", &volume_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "get the volume count");
- goto out;
- }
- for (i = 0; i < volume_count; i++) {
- snprintf (volname_buf, sizeof (volname_buf),
- "volname%ld", i+1);
- ret = dict_get_str (dict, volname_buf,
- &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get volume name");
- goto out;
- }
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get the volinfo for "
- "the volume %s", volname);
- goto out;
- }
- if (glusterd_is_defrag_on (volinfo)) {
- gf_log (this->name, GF_LOG_WARNING,
- "rebalance process is running "
- "for the volume %s", volname);
- goto out;
- }
- //Also check whether geo replication is running
- }
- break;
- }
+ case (GF_SNAP_OPTION_TYPE_CREATE):
+ ret = glusterd_snapshot_create_prevalidate (dict, op_errstr,
+ rsp_dict);
+ break;
+
+ case (GF_SNAP_OPTION_TYPE_CONFIG):
+ ret = glusterd_snapshot_config_prevalidate (dict, op_errstr);
+ break;
+
default:
gf_log (this->name, GF_LOG_WARNING, "invalid snap command");
goto out;
break;
}
-
- ret = 0;
-
out:
return ret;
}
@@ -2088,123 +2251,96 @@ out:
*/
int32_t
-glusterd_snapshot (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
+glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
+ dict_t *rsp_dict)
{
- int ret = -1;
- int i = 0;
- int snap_command = 0;
- int64_t volume_count = 0;
- gf_boolean_t is_cg = _gf_false;
- char *name = NULL;
- char *volname = NULL;
- char *tmp = NULL;
- char volname_buf[PATH_MAX] = {0, };
- xlator_t *this = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_snap_cg_t *cg = NULL;
- glusterd_conf_t *priv = NULL;
- uuid_t cg_id;
-
- this = THIS;
+ char *name = NULL;
+ char *volname = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ int64_t volume_count = 0;
+ char volname_buf[PATH_MAX] = {0, };
+ int i = 0;
+ xlator_t *this = NULL;
+ int ret = -1;
+ glusterd_snap_cg_t *cg = NULL;
+ gf_boolean_t is_cg = _gf_false;
+ uuid_t cg_id;
+ glusterd_conf_t *priv = NULL;
+ char *tmp = NULL;
+
+ ret = dict_get_int64 (dict, "volcount", &volume_count);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "failed to "
+ "get the volume count");
+ goto out;
+ }
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (rsp_dict); //not sure if this is needed, verify.
+ //snap-name should not be set if volume_count > 1
+ ret = dict_get_str (dict, "snap-name", &name);
+ if (volume_count > 1 && !ret)
+ GF_ASSERT (0);
- priv = this->private;
- GF_ASSERT (priv);
+ if (volume_count > 1) {
+ is_cg = _gf_true;
+ ret = dict_get_str (dict, "cg-name", &name);
+ uuid_generate (cg_id);
+ } else if (volume_count == 1) {
+ ret = dict_get_str (dict, "snap-name", &name);
+ }
- ret = dict_get_int32 (dict, "type", &snap_command);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "unable to get the type of "
- "the snapshot command");
- goto out;
+ if (!name) {
+ name = generate_snapname (volname, NULL, is_cg);
+ if (!name) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "strdup of internal snapname"
+ " ((%s) failed for the "
+ "volume %s", name,
+ volname);
+ goto out;
+ }
}
- switch (snap_command) {
- case (GF_SNAP_OPTION_TYPE_CREATE):
- {
- ret = dict_get_int64 (dict, "volcount", &volume_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "get the volume count");
- goto out;
- }
+ for (i = 1; i < volume_count + 1; i++) {
+ snprintf (volname_buf, sizeof (volname_buf),
+ "volname%d", i);
+ ret = dict_get_str (dict, volname_buf,
+ &volname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to get volume name");
+ goto out;
+ }
- //snap-name should not be set if volume_count > 1
- ret = dict_get_str (dict, "snap-name", &name);
- if (volume_count > 1 && !ret)
- GF_ASSERT (0);
-
- if (volume_count > 1) {
- is_cg = _gf_true;
- ret = dict_get_str (dict, "cg-name", &name);
- uuid_generate (cg_id);
- } else if (volume_count == 1) {
- ret = dict_get_str (dict, "snap-name", &name);
- }
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to get the volinfo for "
+ "the volume %s", volname);
+ goto out;
+ }
- if (!name) {
- name = generate_snapname (volname, NULL, is_cg);
- if (!name) {
- gf_log (this->name, GF_LOG_ERROR,
- "strdup of internal snapname"
- " ((%s) failed for the "
- "volume %s", name,
- volname);
- goto out;
- }
- }
+ tmp = generate_snapname (volname, name, is_cg);
+ if (!tmp) {
+ gf_log (this->name,
+ GF_LOG_ERROR, "strdup "
+ "failed (%s)", name);
+ goto out;
+ }
- for (i = 1; i < volume_count + 1; i++) {
- snprintf (volname_buf, sizeof (volname_buf),
- "volname%d", i);
- ret = dict_get_str (dict, volname_buf,
- &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get volume name");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get the volinfo for "
- "the volume %s", volname);
- goto out;
- }
-
- tmp = generate_snapname (volname, name, is_cg);
- if (!tmp) {
- gf_log (this->name,
- GF_LOG_ERROR, "strdup "
- "failed (%s)", name);
- goto out;
- }
-
- /* TODO: Create a stub where the bricks are
- added parallely by worker threads so that
- the snap creating happens parallely.
- */
- ret = glusterd_do_snap (volinfo, tmp, dict,
- is_cg, cg_id);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "taking the "
- "snapshot of the volume %s failed",
- volname);
- goto out;
- }
- }
- break;
+ /* TODO: Create a stub where the bricks are
+ added parallely by worker threads so that
+ the snap creating happens parallely.
+ */
+ ret = glusterd_do_snap (volinfo, tmp, dict,
+ is_cg, cg_id);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "taking the "
+ "snapshot of the volume %s failed",
+ volname);
+ goto out;
}
- default:
- gf_log (this->name, GF_LOG_WARNING, "invalid snap command");
- goto out;
- break;
}
-
if (volume_count > 1) {
cg = glusterd_new_snap_cg_object (volume_count);
if (!cg) {
@@ -2227,6 +2363,187 @@ glusterd_snapshot (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
goto out;
}
}
+out:
+ return ret;
+}
+
+int
+glusterd_snapshot_config_commit (dict_t *dict, char **op_errstr,
+ dict_t *rsp_dict)
+{
+ char *volname = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ uint64_t limit = 0;
+ xlator_t *this = NULL;
+ int ret = -1;
+ char err_str[PATH_MAX] = {0,};
+ glusterd_conf_t *conf = NULL;
+ int config_command = 0;
+
+ this = THIS;
+
+ GF_ASSERT (this);
+ GF_ASSERT (dict);
+ GF_ASSERT (*op_errstr);
+ GF_ASSERT (rsp_dict);
+
+ conf = this->private;
+
+ GF_ASSERT (conf);
+
+ ret = dict_get_int32 (dict, "config-command", &config_command);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to get config-command type");
+ goto out;
+ }
+
+ switch (config_command) {
+
+ case GF_SNAP_CONFIG_SYS_MAX:
+ ret = dict_get_uint64 (dict, "limit", &limit);
+ if (ret) {
+ snprintf (err_str, PATH_MAX,"Failed to get the"
+ " snapshot limit");
+ *op_errstr = gf_strdup (err_str);
+ gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+ conf->snap_max_limit = limit;
+ // TODO: do store
+
+ break;
+
+ case GF_SNAP_CONFIG_VOL_MAX:
+ // volume wide limit
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ snprintf (err_str, PATH_MAX,"Failed to get the"
+ " volume name");
+ *op_errstr = gf_strdup (err_str);
+ gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret) {
+ snprintf (err_str, PATH_MAX,"Failed to get the"
+ " volinfo for volume %s", volname);
+ *op_errstr = gf_strdup (err_str);
+ gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+ ret = dict_get_uint64 (dict, "limit", &limit);
+ if (ret) {
+ snprintf (err_str, PATH_MAX,"Failed to get the"
+ " snapshot limit volinfo for volume %s",
+ volname);
+ *op_errstr = gf_strdup (err_str);
+ gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+ volinfo->snap_max_limit = limit;
+ //TODO: do store
+ break;
+
+ case GF_SNAP_CONFIG_CG_MAX:
+ break;
+ case GF_SNAP_CONFIG_DISPLAY:
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ snprintf (err_str, PATH_MAX,"Failed to get the"
+ " volume name");
+ *op_errstr = gf_strdup (err_str);
+ gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+ if (!strncmp (volname, "all", 3)) {
+ limit = conf->snap_max_limit;
+ } else {
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret) {
+ snprintf (err_str, PATH_MAX,"Failed to get the"
+ " volinfo for volume %s", volname);
+ *op_errstr = gf_strdup (err_str);
+ gf_log (this->name, GF_LOG_ERROR, "%s",
+ err_str);
+ goto out;
+ }
+ limit = volinfo->snap_max_limit;
+ }
+
+ ret = dict_set_uint64 (rsp_dict, "limit", limit);
+ if (ret) {
+ snprintf (err_str, PATH_MAX,"Failed to get the"
+ " set limit for volume %s",
+ volname);
+ *op_errstr = gf_strdup (err_str);
+ gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ ret = dict_set_str (rsp_dict, "volname", volname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set the"
+ " volume name");
+ goto out;
+ }
+ ret = dict_set_int32 (dict, "config-command", config_command);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to set config-command type");
+ goto out;
+ }
+out:
+ return ret;
+}
+int32_t
+glusterd_snapshot (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
+{
+
+ xlator_t *this = NULL;
+ glusterd_conf_t *priv = NULL;
+ int32_t snap_command = 0;
+ int ret = -1;
+
+ this = THIS;
+
+ GF_ASSERT (this);
+ GF_ASSERT (dict);
+ GF_ASSERT (rsp_dict); //not sure if this is needed, verify.
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ ret = dict_get_int32 (dict, "type", &snap_command);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "unable to get the type of "
+ "the snapshot command");
+ goto out;
+ }
+
+ switch (snap_command) {
+ case (GF_SNAP_OPTION_TYPE_CREATE):
+ ret = glusterd_snapshot_create_commit (dict, op_errstr,
+ rsp_dict);
+ break;
+
+ case GF_SNAP_OPTION_TYPE_CONFIG:
+ ret = glusterd_snapshot_config_commit (dict, op_errstr,
+ rsp_dict);
+ break;
+
+ default:
+ gf_log (this->name, GF_LOG_WARNING, "invalid snap command");
+ goto out;
+ break;
+ }
+
+
ret = 0;
@@ -2313,12 +2630,14 @@ glusterd_handle_snapshot_fn (rpcsvc_request_t *req)
case GF_SNAP_OPTION_TYPE_LIST:
ret = glusterd_handle_snapshot_list (req, cli_op, dict);
break;
+ case GF_SNAP_OPTION_TYPE_CONFIG:
+ ret = glusterd_mgmt_v3_initiate_all_phases (req, cli_op, dict);
+ break;
case GF_SNAP_OPTION_TYPE_RESTORE:
case GF_SNAP_OPTION_TYPE_DELETE:
case GF_SNAP_OPTION_TYPE_START:
case GF_SNAP_OPTION_TYPE_STOP:
case GF_SNAP_OPTION_TYPE_STATUS:
- case GF_SNAP_OPTION_TYPE_CONFIG:
gf_log (this->name, GF_LOG_ERROR, "Operation (%d) not "
"supported ", type);
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 771b0af5a..1f5cc741b 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -427,6 +427,12 @@ glusterd_volinfo_new (glusterd_volinfo_t **volinfo)
{
glusterd_volinfo_t *new_volinfo = NULL;
int32_t ret = -1;
+ xlator_t *this = NULL;
+ glusterd_conf_t *conf = NULL;
+
+ this = THIS;
+
+ conf = this->private;
GF_ASSERT (volinfo);
@@ -455,6 +461,11 @@ glusterd_volinfo_new (glusterd_volinfo_t **volinfo)
goto out;
}
+ if (conf)
+ new_volinfo->snap_max_limit = conf->snap_max_limit;
+ else
+ new_volinfo->snap_max_limit = GLUSTERD_SNAPS_MAX_LIMIT;
+
new_volinfo->xl = THIS;
*volinfo = new_volinfo;
diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c
index c0531d375..60f671902 100644
--- a/xlators/mgmt/glusterd/src/glusterd.c
+++ b/xlators/mgmt/glusterd/src/glusterd.c
@@ -1321,6 +1321,9 @@ init (xlator_t *this)
conf->gfs_mgmt = &gd_brick_prog;
strncpy (conf->workdir, workdir, PATH_MAX);
+ conf->snap_max_limit = GLUSTERD_SNAPS_MAX_LIMIT;
+ //TODO: read from saved value and update
+
synclock_init (&conf->big_lock);
pthread_mutex_init (&conf->xprt_lock, NULL);
INIT_LIST_HEAD (&conf->xprt_list);
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index 10b338dda..1d5aa515b 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -52,6 +52,7 @@
"S56glusterd-geo-rep-create-post.sh"
+#define GLUSTERD_SNAPS_MAX_LIMIT 256
#define GLUSTERD_SERVER_QUORUM "server"
#define FMTSTR_CHECK_VOL_EXISTS "Volume %s does not exist"
@@ -157,6 +158,7 @@ typedef struct {
rpcsvc_t *uds_rpc; /* RPCSVC for the unix domain socket */
uint32_t base_port;
struct list_head snap_cg;
+ uint64_t snap_max_limit;
char *snap_bricks_directory;
} glusterd_conf_t;
@@ -276,6 +278,7 @@ struct glusterd_volinfo_ {
int type;
int brick_count;
uint64_t snap_count;
+ uint64_t snap_max_limit;
struct list_head vol_list;
struct list_head bricks;
struct list_head snaps;