diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-snapshot.c')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-snapshot.c | 494 |
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; |