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.c494
1 files changed, 284 insertions, 210 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
index cc56f9019..cd9ed3f23 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c
+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
@@ -395,14 +395,61 @@ out:
}
int
-glusterd_snapshot_config_limit_prevalidate (dict_t *dict, char **op_errstr,
- int config_command)
+snap_max_limits_validate (dict_t *dict, char *key,
+ char **op_errstr)
+{
+ char err_str[PATH_MAX] = "";
+ glusterd_conf_t *conf = NULL;
+ int ret = -1;
+ uint64_t value = 0;
+ uint64_t max_limit = GLUSTERD_SNAPS_MAX_LIMIT;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ GF_ASSERT (this);
+ GF_ASSERT (dict);
+ GF_ASSERT (key);
+ GF_ASSERT (op_errstr);
+
+ conf = this->private;
+
+ GF_ASSERT (conf);
+
+ ret = dict_get_uint64 (dict, key, &value);
+ if (ret) {
+ snprintf (err_str, PATH_MAX,"Failed to get the"
+ " value for %s", key);
+ *op_errstr = gf_strdup (err_str);
+ gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+
+ if ((value < 0) ||
+ (value > max_limit)) {
+ ret = -1;
+ snprintf (err_str, PATH_MAX, "Invalid %s "
+ "%"PRIu64 ". Expected range 0 - %"PRIu64,
+ key, value, max_limit);
+ *op_errstr = gf_strdup (err_str);
+ gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+glusterd_snapshot_config_prevalidate (dict_t *dict, char **op_errstr)
{
char *volname = NULL;
+ char *key = NULL;
glusterd_volinfo_t *volinfo = NULL;
- uint64_t limit = 0;
xlator_t *this = NULL;
int ret = -1;
+ int config_command = 0;
char err_str[PATH_MAX] = {0,};
glusterd_conf_t *conf = NULL;
@@ -416,70 +463,29 @@ glusterd_snapshot_config_limit_prevalidate (dict_t *dict, char **op_errstr,
GF_ASSERT (conf);
- switch (config_command) {
+ 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;
+ }
- 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;
+ ret = dict_get_str (dict, "config-key", &key);
- 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;
+ switch (config_command) {
+ case GF_SNAP_CONFIG_TYPE_SET:
+ if ((!strncmp (key, "snap-max-hard-limit", strlen(key))) ||
+ (!strncmp (key, "snap-max-soft-limit", strlen(key)))) {
+ /* Validations for snap-max-hard-limit and snap-max-soft-limit */
+ ret = snap_max_limits_validate (dict, key, op_errstr);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s validation failed.", key);
+ goto out;
+ }
}
break;
- case GF_SNAP_CONFIG_CG_MAX:
- break;
-
case GF_SNAP_CONFIG_DISPLAY:
ret = dict_get_str (dict, "volname", &volname);
if (ret) {
@@ -489,14 +495,14 @@ glusterd_snapshot_config_limit_prevalidate (dict_t *dict, char **op_errstr,
gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
goto out;
}
- if (!strncmp (volname, "all", 3)) {
+ if (!strncmp (volname, "all", strlen(volname))) {
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);
+ snprintf (err_str, PATH_MAX,"Volume %s does not exist.",
+ volname);
*op_errstr = gf_strdup (err_str);
gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
goto out;
@@ -510,39 +516,6 @@ out:
}
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_snap_create_pre_val_use_rsp_dict (dict_t *dst, dict_t *src)
{
char *snap_mount = NULL;
@@ -1679,17 +1652,17 @@ glusterd_snapshot_vol_get_snaplist_lk (dict_t *dict, char *keyprefix,
goto out;
}
- if (conf->snap_max_limit < volinfo->snap_max_limit) {
- snap_limit = conf->snap_max_limit;
- gf_log(this->name, GF_LOG_DEBUG, "system snap_limit is "
- "lesser than volume snap_limit, snap_limit value "
- "is set to %ld",snap_limit);
+ if (conf->snap_max_hard_limit < volinfo->snap_max_hard_limit) {
+ snap_limit = conf->snap_max_hard_limit;
+ gf_log(this->name, GF_LOG_DEBUG, "system snap-max-hard-limit is"
+ " lesser than volume snap-max-hard-limit, "
+ "snap-max-hard-limit value is set to %ld", snap_limit);
}
else {
- snap_limit = volinfo->snap_max_limit ;
- gf_log(this->name, GF_LOG_DEBUG, "volume snap_limit is "
- "lesser than system snap_limit, snap_limit value "
- "is set to %ld",snap_limit);
+ snap_limit = volinfo->snap_max_hard_limit ;
+ gf_log(this->name, GF_LOG_DEBUG, "volume snap-max-hard-limit is"
+ " lesser than system snap-max-hard-limit, "
+ "snap-max-hard-limit value is set to %ld",snap_limit);
}
if (snap_limit > volinfo->snap_count)
@@ -1942,7 +1915,7 @@ glusterd_snapshot_cg_get_snaplist_lk (dict_t *dict, glusterd_snap_cg_t *cg,
goto out;
}
- ret = snprintf (key, sizeof (key), "%s.cgname", keyprefix);
+ ret = snprintf (key, sizeof (key), "%s.cg-name", keyprefix);
if (ret < 0) { /* Only negative value is error */
goto out;
}
@@ -2690,17 +2663,21 @@ out:
int32_t
glusterd_snap_create (glusterd_volinfo_t *volinfo,
glusterd_volinfo_t *snap_volinfo,
- char *description, uuid_t *cg_id)
+ char *description, uuid_t *cg_id,
+ char *cg_name)
{
glusterd_snap_t *snap = NULL;
xlator_t *this = NULL;
glusterd_conf_t *priv = NULL;
int ret = -1;
- uuid_t snap_uuid;
this = THIS;
priv = this->private;
+ GF_ASSERT (snap_volinfo);
+ if (cg_id)
+ GF_ASSERT (cg_name);
+
if (!volinfo) {
gf_log (this->name, GF_LOG_ERROR, "volinfo is NULL");
goto out;
@@ -2719,10 +2696,12 @@ glusterd_snap_create (glusterd_volinfo_t *volinfo,
if (description)
snap->description = gf_strdup (description);
snap->time_stamp = time (NULL);
- uuid_generate (snap_uuid);
- uuid_copy (snap->snap_id, snap_uuid);
- if (cg_id)
+ uuid_copy (snap->snap_id, snap_volinfo->volume_id);
+ if (cg_id){
uuid_copy (snap->cg_id, *cg_id);
+ strncpy (snap->cg_name, cg_name,
+ sizeof (snap->cg_name) - 1);
+ }
snap->snap_volume = snap_volinfo;
strcpy (snap->snap_name, snap_volinfo->volname);
//TODO: replace strcpy with strncpy
@@ -3037,7 +3016,8 @@ out:
*/
int32_t
glusterd_do_snap (glusterd_volinfo_t *volinfo, char *snapname, dict_t *dict,
- gf_boolean_t cg, uuid_t *cg_id, int volcount, uuid_t snap_volid)
+ gf_boolean_t cg, uuid_t *cg_id, int volcount,
+ uuid_t snap_volid, char *cg_name)
{
char *snap_brick_mount_path = "";
char snapmntname[PATH_MAX] = "";
@@ -3059,6 +3039,11 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *snapname, dict_t *dict,
priv = this->private;
GF_ASSERT (priv);
+ GF_ASSERT (volinfo);
+ GF_ASSERT (snapname);
+ GF_ASSERT (dict);
+ if (cg_id)
+ GF_ASSERT (cg_name);
ret = glusterd_volinfo_dup (volinfo, &snap_volume);
strncpy (snap_volume->volname, snapname,
@@ -3174,7 +3159,8 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *snapname, dict_t *dict,
ret = dict_get_str (dict, "snap-description", &description);
// for now continue the snap, if getting description fails.
- ret = glusterd_snap_create (volinfo, snap_volume, description, cg_id);
+ ret = glusterd_snap_create (volinfo, snap_volume, description, cg_id,
+ cg_name);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "creating the"
"snap object failed for the volume %s",
@@ -4061,7 +4047,14 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
added parallely by worker threads so that
the snap creating happens parallely.
*/
- ret = glusterd_do_snap (volinfo, tmp, dict, is_cg, cg_id, i, *snap_volid);
+ if (is_cg) {
+ ret = glusterd_do_snap (volinfo, tmp, dict,
+ is_cg, cg_id, i, *snap_volid, name);
+ }
+ else {
+ ret = glusterd_do_snap (volinfo, tmp, dict,
+ is_cg, cg_id, i, *snap_volid, NULL);
+ }
if (ret) {
gf_log (this->name, GF_LOG_WARNING, "taking the "
"snapshot of the volume %s failed", volname);
@@ -4101,152 +4094,233 @@ out:
}
int
-glusterd_snapshot_config_commit (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
+snap_max_limits_set_commit (dict_t *dict, char *key, char *volname,
+ char **op_errstr)
{
- char *volname = NULL;
+ char err_str[PATH_MAX] = "";
+ glusterd_conf_t *conf = 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;
+ uint64_t value = 0;
+ xlator_t *this = NULL;
this = THIS;
GF_ASSERT (this);
GF_ASSERT (dict);
- GF_ASSERT (rsp_dict);
+ GF_ASSERT (key);
+ GF_ASSERT (volname);
GF_ASSERT (op_errstr);
conf = this->private;
GF_ASSERT (conf);
- ret = dict_get_int32 (dict, "config-command", &config_command);
+ ret = dict_get_uint64 (dict, key, &value);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get config-command type");
+ snprintf (err_str, PATH_MAX,"Failed to get the"
+ " value for %s", key);
goto out;
}
- switch (config_command) {
+ /* TODO: Initiate auto deletion when there is a limit change */
+ if (!strncmp (volname, "all", strlen(volname))) {
+ /* For system limit */
+ if (!strncmp (key, "snap-max-hard-limit", strlen(key)))
+ conf->snap_max_hard_limit = value;
+ else
+ conf->snap_max_soft_limit = value;
- 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;
ret = glusterd_store_global_info (this);
if (ret) {
- snprintf (err_str, PATH_MAX,"Failed to store the"
- " snapshot limit volinfo for system");
- *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);
+ snprintf (err_str, PATH_MAX,"Failed to store %s "
+ "for system", key);
goto out;
}
+ } else {
+ /* For one volume */
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;
+
+ if (!strncmp (key, "snap-max-hard-limit", strlen(key)))
+ volinfo->snap_max_hard_limit = value;
+ else
+ volinfo->snap_max_soft_limit = value;
+
ret = glusterd_store_volinfo (volinfo,
- GLUSTERD_VOLINFO_VER_AC_INCREMENT);
+ GLUSTERD_VOLINFO_VER_AC_INCREMENT);
if (ret) {
- snprintf (err_str, PATH_MAX,"Failed to store the"
- " snapshot limit volinfo for volume %s",
- volname);
- *op_errstr = gf_strdup (err_str);
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
+ snprintf (err_str, PATH_MAX,"Failed to store %s "
+ "for volume %s", key, volname);
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)) {
- 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 = 0;
+out:
+ if (ret) {
+ *op_errstr = gf_strdup (err_str);
+ gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
+ }
+
+ return ret;
+}
+
+int
+snap_max_limits_display_commit (dict_t *rsp_dict, char *key, char *volname,
+ char **op_errstr)
+{
+ char err_str[PATH_MAX] = "";
+ glusterd_conf_t *conf = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ int ret = -1;
+ uint64_t value = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ GF_ASSERT (this);
+ GF_ASSERT (rsp_dict);
+ GF_ASSERT (key);
+ GF_ASSERT (volname);
+ GF_ASSERT (op_errstr);
- ret = dict_set_uint64 (rsp_dict, "limit", limit);
+ conf = this->private;
+
+ GF_ASSERT (conf);
+
+ if (!strncmp (volname, "all", strlen(volname))) {
+ /* For system limit */
+ if (!strncmp (key, "snap-max-hard-limit", strlen(key)))
+ value = conf->snap_max_hard_limit;
+ else
+ value = conf->snap_max_soft_limit;
+ } else {
+ /* For one volume */
+ ret = glusterd_volinfo_find (volname, &volinfo);
if (ret) {
snprintf (err_str, PATH_MAX,"Failed to get the"
- " set limit for volume %s",
- volname);
+ " 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;
+ if (!strncmp (key, "snap-max-hard-limit", strlen(key)))
+ value = volinfo->snap_max_hard_limit;
+ else
+ value = volinfo->snap_max_soft_limit;
}
- ret = dict_set_str (rsp_dict, "volname", volname);
+ ret = dict_set_uint64 (rsp_dict, key, value);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set the"
- " volume name");
+ snprintf (err_str, PATH_MAX,"Failed to set %s "
+ "for volume %s", key, volname);
+ *op_errstr = gf_strdup (err_str);
+ gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
goto out;
}
- ret = dict_set_int32 (dict, "config-command", config_command);
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+glusterd_snapshot_config_commit (dict_t *dict, char **op_errstr,
+ dict_t *rsp_dict)
+{
+ char *volname = NULL;
+ char *key = NULL;
+ 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 (rsp_dict);
+ GF_ASSERT (op_errstr);
+
+ 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 set config-command type");
+ "failed to get config-command type");
goto out;
}
+
+ 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 = dict_get_str (dict, "config-key", &key);
+
+ switch (config_command) {
+ case GF_SNAP_CONFIG_TYPE_SET:
+ if ((!strncmp (key, "snap-max-hard-limit", strlen(key))) ||
+ (!strncmp (key, "snap-max-soft-limit", strlen(key)))) {
+ /* Commit ops for snap-max-hard-limit and snap-max-soft-limit */
+ ret = snap_max_limits_set_commit (dict, key, volname, op_errstr);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s set commit failed.", key);
+ goto out;
+ }
+ }
+ break;
+
+ case GF_SNAP_CONFIG_DISPLAY:
+ if (!key) {
+ /* For all options */
+ ret = snap_max_limits_display_commit (rsp_dict, "snap-max-hard-limit",
+ volname, op_errstr);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "snap-max-hard-limit "
+ "display commit failed.");
+ goto out;
+ }
+
+ ret = snap_max_limits_display_commit (rsp_dict, "snap-max-soft-limit",
+ volname, op_errstr);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "snap-max-soft-limit "
+ "display commit failed.");
+ goto out;
+ }
+ } else if ((!strncmp (key, "snap-max-hard-limit", strlen(key))) ||
+ (!strncmp (key, "snap-max-soft-limit", strlen(key)))) {
+ /* Commit ops for snap-max-hard-limit or snap-max-soft-limit */
+ ret = snap_max_limits_display_commit (rsp_dict, key,
+ volname, op_errstr);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s display commit failed.", key);
+ goto out;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
out:
gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
return ret;