diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-snapshot.c')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-snapshot.c | 134 |
1 files changed, 118 insertions, 16 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c index 456f23abe4b..af4cf171aff 100644 --- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c +++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c @@ -203,7 +203,7 @@ out: int snap_max_limits_display_commit (dict_t *rsp_dict, char *volname, - char *op_errstr) + char *op_errstr, int len) { char err_str[PATH_MAX] = ""; char buf[PATH_MAX] = ""; @@ -217,6 +217,7 @@ snap_max_limits_display_commit (dict_t *rsp_dict, char *volname, xlator_t *this = NULL; uint64_t opt_hard_max = 0; uint64_t opt_soft_max = 0; + char *auto_delete = NULL; this = THIS; @@ -312,8 +313,8 @@ snap_max_limits_display_commit (dict_t *rsp_dict, char *volname, /* 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); + snprintf (err_str, PATH_MAX, "Volume (%s) does not " + "exist", volname); goto out; } @@ -392,10 +393,30 @@ snap_max_limits_display_commit (dict_t *rsp_dict, char *volname, goto out; } + ret = dict_get_str (conf->opts, + GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE, + &auto_delete); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get " + "%s from options", + GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE); + goto out; + } + + ret = dict_set_dynstr_with_alloc (rsp_dict, + GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE, + auto_delete); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to set " + "%s in response dictionary", + GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE); + goto out; + } + ret = 0; out: if (ret) { - op_errstr = gf_strdup (err_str); + strncpy (op_errstr, err_str, len); gf_log (this->name, GF_LOG_ERROR, "%s", err_str); } return ret; @@ -1056,6 +1077,8 @@ glusterd_snapshot_config_prevalidate (dict_t *dict, char **op_errstr) uint64_t soft_limit = 0; gf_loglevel_t loglevel = GF_LOG_ERROR; uint64_t max_limit = GLUSTERD_SNAPS_MAX_HARD_LIMIT; + char *req_auto_delete = NULL; + char *cur_auto_delete = NULL; this = THIS; @@ -1078,6 +1101,9 @@ glusterd_snapshot_config_prevalidate (dict_t *dict, char **op_errstr) ret = dict_get_uint64 (dict, "snap-max-soft-limit", &soft_limit); + ret = dict_get_str (dict, GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE, + &req_auto_delete); + ret = dict_get_str (dict, "volname", &volname); if (volname) { @@ -1115,6 +1141,24 @@ glusterd_snapshot_config_prevalidate (dict_t *dict, char **op_errstr) } break; } + + if (req_auto_delete) { + ret = dict_get_str (conf->opts, + GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE, + &cur_auto_delete); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "get auto-delete value from options"); + goto out; + } + + if (strcmp (req_auto_delete, cur_auto_delete) == 0) { + ret = -1; + snprintf (err_str, PATH_MAX, "auto-delete " + "is already %sd", req_auto_delete); + goto out; + } + } default: break; } @@ -1185,13 +1229,14 @@ glusterd_handle_snapshot_config (rpcsvc_request_t *req, glusterd_op_t op, case GF_SNAP_CONFIG_DISPLAY: /* Reading data from local node only */ ret = snap_max_limits_display_commit (dict, volname, - err_str); + err_str, len); if (ret) { gf_log (this->name, GF_LOG_ERROR, "snap-max-limit " "display commit failed."); goto out; } + /* If everything is successful then send the response * back to cli */ @@ -1325,7 +1370,6 @@ glusterd_snap_create_pre_val_use_rsp_dict (dict_t *dst, dict_t *src) brick_online = 0; } } - ret = 0; out: @@ -1638,11 +1682,13 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr, effective_max_limit = opt_hard_max; if (volinfo->snap_count >= effective_max_limit) { + ret = -1; snprintf (err_str, sizeof (err_str), "The number of existing snaps has reached " - "the effective maximum limit of %"PRIu64" ," - "for the volume %s", effective_max_limit, - volname); + "the effective maximum limit of %"PRIu64", " + "for the volume (%s). Please delete few " + "snapshots before taking further snapshots.", + effective_max_limit, volname); loglevel = GF_LOG_WARNING; goto out; } @@ -5133,6 +5179,17 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr, goto out; } + if (is_origin_glusterd (dict)) { + ret = glusterd_is_snap_soft_limit_reached (origin_vol, + rsp_dict); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "check soft limit exceeded or not, " + "for volume %s ", origin_vol->volname); + goto out; + } + } + snap_vol = glusterd_do_snap_vol (origin_vol, snap, dict, rsp_dict, i); if (!snap_vol) { @@ -5285,6 +5342,7 @@ glusterd_snapshot_config_commit (dict_t *dict, char **op_errstr, uint64_t hard_limit = 0; uint64_t soft_limit = 0; char *next_version = NULL; + char *auto_delete = NULL; this = THIS; @@ -5312,6 +5370,9 @@ glusterd_snapshot_config_commit (dict_t *dict, char **op_errstr, ret = dict_get_uint64 (dict, "snap-max-soft-limit", &soft_limit); + ret = dict_get_str (dict, GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE, + &auto_delete); + switch (config_command) { case GF_SNAP_CONFIG_TYPE_SET: if (hard_limit) { @@ -5359,6 +5420,32 @@ glusterd_snapshot_config_commit (dict_t *dict, char **op_errstr, goto out; } } + + if (auto_delete) { + ret = glusterd_get_next_global_opt_version_str + (conf->opts, &next_version); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "get next global opt-version"); + goto out; + } + + ret = dict_set_dynstr_with_alloc (conf->opts, + GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE, + auto_delete); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Could not " + "save auto-delete value in conf->opts"); + goto out; + } + + ret = glusterd_store_options (this, conf->opts); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "store options"); + goto out; + } + } break; default: @@ -6096,19 +6183,19 @@ glusterd_handle_snap_limit (dict_t *dict, dict_t *rsp_dict) goto out; } - /* The minimum of the 2 limits i.e system wide limit and - volume wide limit will be considered - */ - ret = dict_get_uint64 (priv->opts, GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT, &opt_max_hard); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Failed to get " - "%s", GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT); + "%s from opts dictionary", + GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT); goto out; } + /* The minimum of the 2 limits i.e system wide limit and + volume wide limit will be considered + */ if (volinfo->snap_max_hard_limit < opt_max_hard) effective_max_limit = volinfo->snap_max_hard_limit; else @@ -6170,6 +6257,7 @@ glusterd_snapshot_create_postvalidate (dict_t *dict, int32_t op_ret, int32_t cleanup = 0; glusterd_snap_t *snap = NULL; char *snapname = NULL; + char *auto_delete = NULL; this = THIS; @@ -6188,9 +6276,14 @@ glusterd_snapshot_create_postvalidate (dict_t *dict, int32_t op_ret, if (ret) { gf_log (this->name, GF_LOG_WARNING, "cleanup " "operation failed"); - goto out; } } + /* Irrespective of status of cleanup its better + * to return from this function. As the functions + * following this block is not required to be + * executed in case of failure scenario. + */ + goto out; } ret = dict_get_str (dict, "snapname", &snapname); @@ -6224,8 +6317,17 @@ glusterd_snapshot_create_postvalidate (dict_t *dict, int32_t op_ret, goto out; } + ret = dict_get_str (priv->opts, GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE, + &auto_delete); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get " + "the value of auto-delete from options"); + goto out; + } + //ignore the errors of autodelete - ret = glusterd_handle_snap_limit (dict, rsp_dict); + if (strcmp (auto_delete, "enable") == 0) + ret = glusterd_handle_snap_limit (dict, rsp_dict); ret = 0; out: |