summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xtests/bugs/bug-1049834.t20
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot.c101
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h5
3 files changed, 118 insertions, 8 deletions
diff --git a/tests/bugs/bug-1049834.t b/tests/bugs/bug-1049834.t
index eea3297ed56..eb9a7fbe875 100755
--- a/tests/bugs/bug-1049834.t
+++ b/tests/bugs/bug-1049834.t
@@ -24,14 +24,18 @@ TEST $CLI_1 snapshot config $V0 snap-max-hard-limit 4
PID_1=$!
wait $PID_1
-#Creating 4 snapshots on the volume
-TEST create_n_snapshots $V0 4 $V0_snap
-TEST snapshot_n_exists $V0 4 $V0_snap
-
-#Creating the 5th snapshots on the volume and expecting it not to be created.
-TEST ! $CLI_1 snapshot create ${V0}_snap5 ${V0}
-TEST ! snapshot_exists 1 ${V0}_snap5
-TEST ! $CLI_1 snapshot delete ${V0}_snap5
+#Creating 3 snapshots on the volume (which is the soft-limit)
+TEST create_n_snapshots $V0 3 $V0_snap
+TEST snapshot_n_exists $V0 3 $V0_snap
+
+#Creating the 4th snapshot on the volume and expecting it to be created
+# but with the deletion of the oldest snapshot i.e 1st snapshot
+TEST $CLI_1 snapshot create ${V0}_snap4 ${V0}
+TEST snapshot_exists 1 ${V0}_snap4
+TEST ! snapshot_exists 1 ${V0}_snap1
+TEST $CLI_1 snapshot delete ${V0}_snap4
+TEST $CLI_1 snapshot create ${V0}_snap1 ${V0}
+TEST snapshot_exists 1 ${V0}_snap1
#Deleting the 4 snaps
#TEST delete_n_snapshots $V0 4 $V0_snap
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
index 44a987ef8b2..e47f85f7ff4 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c
+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
@@ -5788,6 +5788,104 @@ out:
}
int32_t
+glusterd_handle_snap_limit (dict_t *dict, dict_t *rsp_dict)
+{
+ int32_t ret = -1;
+ xlator_t *this = NULL;
+ glusterd_conf_t *priv = NULL;
+ uint64_t effective_max_limit = 0;
+ int64_t volcount = 0;
+ int64_t i = 0;
+ char *volname = NULL;
+ char key[PATH_MAX] = {0, };
+ glusterd_volinfo_t *volinfo = NULL;
+ uint64_t limit = 0;
+ int64_t count = 0;
+ glusterd_snap_t *snap = NULL;
+ glusterd_volinfo_t *tmp_volinfo = NULL;
+ glusterd_volinfo_t *other_volinfo = NULL;
+ int64_t var = 0;
+
+ this = THIS;
+ GF_ASSERT (this);
+ GF_ASSERT (dict);
+ GF_ASSERT (rsp_dict);
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ ret = dict_get_int64 (dict, "volcount", &volcount);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "failed to get the volcount");
+ goto out;
+ }
+
+ for (i = 1; i <= volcount; i++) {
+ snprintf (key, sizeof (key), "volname%ld", i);
+ ret = dict_get_str (dict, key, &volname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "failed to get the "
+ "volname");
+ goto out;
+ }
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "volinfo for %s "
+ "not found", volname);
+ 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 < priv->snap_max_hard_limit)
+ effective_max_limit = volinfo->snap_max_hard_limit;
+ else
+ effective_max_limit = priv->snap_max_hard_limit;
+
+ limit = (priv->snap_max_soft_limit * effective_max_limit)/100;
+
+ count = volinfo->snap_count - limit;
+ if (count <= 0)
+ goto out;
+
+ list_for_each_entry_safe (tmp_volinfo, other_volinfo,
+ &volinfo->snap_volumes, snapvol_list) {
+ if (var == count)
+ break;
+
+ snap = tmp_volinfo->snapshot;
+ GF_ASSERT (snap);
+
+ LOCK (&snap->lock);
+ {
+ snap->snap_status = GD_SNAP_STATUS_DECOMMISSION;
+ ret = glusterd_store_snap (snap);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "could "
+ "not store snap object %s",
+ snap->snapname);
+ goto unlock;
+ }
+
+ ret = glusterd_snap_remove (rsp_dict, snap,
+ _gf_true, _gf_true);
+ if (ret)
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to remove snap %s",
+ snap->snapname);
+ }
+ unlock: UNLOCK (&snap->lock);
+ var++;
+ }
+ }
+
+out:
+ return ret;
+}
+
+int32_t
glusterd_snapshot_create_postvalidate (dict_t *dict, int32_t op_ret,
char **op_errstr, dict_t *rsp_dict)
{
@@ -5851,6 +5949,9 @@ glusterd_snapshot_create_postvalidate (dict_t *dict, int32_t op_ret,
goto out;
}
+ //ignore the errors of autodelete
+ ret = glusterd_handle_snap_limit (dict, rsp_dict);
+
ret = 0;
out:
return ret;
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index bf4a8e283d6..02441c9148b 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -1017,8 +1017,13 @@ glusterd_add_new_entry_to_list (char *missed_info, char *snap_vol_id,
int
glusterd_snapshot_revert_restore_from_snap (glusterd_snap_t *snap);
+
int
glusterd_add_brick_status_to_dict (dict_t *dict, glusterd_volinfo_t *volinfo,
glusterd_brickinfo_t *brickinfo,
char *key_prefix);
+
+int32_t
+glusterd_handle_snap_limit (dict_t *dict, dict_t *rsp_dict);
+
#endif