summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd/src/glusterd-snapshot.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-snapshot.c')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot.c609
1 files changed, 464 insertions, 145 deletions
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);