summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvmallika <vmallika@redhat.com>2014-10-28 12:25:43 +0530
committerKaushal M <kaushal@redhat.com>2014-11-12 04:36:11 -0800
commit4fa4b7f2c2b57d1055adb76e8258b0db176bc356 (patch)
treee4beb4567c57370b8622f19746721e2a0b0f96f1
parent55aa4b185561edd7b3d1ab77a4f29a4facfdd7ff (diff)
glusterd/snapshot: Snapshot should be deactivated when it is created
By default snapshot should be deactivated and this should be a configurable option. This behaviour can be configured by the command below: gluster snapshot config activate-on-create <enable|disable> Change-Id: I1911595c32beed43bb2fca4bf99f0d264b422513 BUG: 1157991 Signed-off-by: vmallika <vmallika@redhat.com> Reviewed-on: http://review.gluster.org/8985 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Avra Sengupta <asengupt@redhat.com> Reviewed-by: Rajesh Joseph <rjoseph@redhat.com> Reviewed-by: Kaushal M <kaushal@redhat.com>
-rw-r--r--cli/src/cli-cmd-parser.c51
-rw-r--r--cli/src/cli-cmd-snapshot.c3
-rw-r--r--cli/src/cli-rpc-ops.c12
-rw-r--r--cli/src/cli-xml-output.c27
-rw-r--r--doc/admin-guide/en-US/markdown/admin_managing_snapshots.md5
-rw-r--r--doc/gluster.84
-rw-r--r--tests/basic/uss.t2
-rwxr-xr-xtests/basic/volume-snapshot.t2
-rw-r--r--tests/bugs/bug-1109889.t2
-rwxr-xr-xtests/bugs/bug-1157991.t30
-rwxr-xr-xtests/snapshot.rc6
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot.c336
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.h1
13 files changed, 327 insertions, 154 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index 27f1fec0df8..28888ba656d 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -278,7 +278,7 @@ cli_cmd_volume_create_parse (struct cli_state *state, const char **words,
"description", "force",
"snap-max-hard-limit",
"snap-max-soft-limit", "auto-delete",
- NULL};
+ "activate-on-create", NULL};
char *w = NULL;
char *ptr = NULL;
int op_count = 0;
@@ -3868,8 +3868,7 @@ cli_snap_config_parse (const char **words, int wordcount, dict_t *dict,
int8_t soft_limit = 0;
int8_t config_type = -1;
const char *question = NULL;
- unsigned int cmdi = 2;
- int8_t auto_delete = -1;
+ unsigned int cmdi = 2;
/* cmdi is command index, here cmdi is "2" (gluster snapshot config)*/
GF_ASSERT (words);
@@ -3892,7 +3891,8 @@ cli_snap_config_parse (const char **words, int wordcount, dict_t *dict,
/* Check whether the 3rd word is volname */
if (strcmp (words[cmdi], "snap-max-hard-limit") != 0
&& strcmp (words[cmdi], "snap-max-soft-limit") != 0
- && strcmp (words[cmdi], "auto-delete") != 0) {
+ && strcmp (words[cmdi], "auto-delete") != 0
+ && strcmp (words[cmdi], "activate-on-create") != 0) {
ret = dict_set_str (dict, "volname", (char *)words[cmdi]);
if (ret) {
gf_log ("cli", GF_LOG_ERROR, "Failed to set volname");
@@ -3950,10 +3950,12 @@ cli_snap_config_parse (const char **words, int wordcount, dict_t *dict,
goto out;
}
soft_limit = 1;
- goto set;
}
- if (hard_limit != 1 && (strcmp(words[cmdi], "auto-delete") == 0)) {
+ if (hard_limit || soft_limit)
+ goto set;
+
+ if (strcmp(words[cmdi], "auto-delete") == 0) {
if (vol_presence == 1) {
ret = -1;
cli_err ("As of now, auto-delete option cannot be set "
@@ -3976,19 +3978,47 @@ cli_snap_config_parse (const char **words, int wordcount, dict_t *dict,
"dictionary");
goto out;
}
- auto_delete = 1;
if (++cmdi != wordcount) {
ret = -1;
gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
goto out;
}
- }
- else {
+ } else if (strcmp(words[cmdi], "activate-on-create") == 0) {
+ if (vol_presence == 1) {
+ ret = -1;
+ cli_err ("As of now, activate-on-create option "
+ "cannot be set to volumes");
+ gf_log ("cli", GF_LOG_ERROR, "activate-on-create "
+ "option cannot be set to volumes");
+ goto out;
+ }
+
+ if (++cmdi >= wordcount) {
+ ret = -1;
+ gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
+
+ ret = dict_set_str (dict, "snap-activate-on-create",
+ (char *)words[cmdi]);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to set value "
+ "of activate-on-create in request dictionary");
+ goto out;
+ }
+
+ if (++cmdi != wordcount) {
+ ret = -1;
+ gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
+ } else {
ret = -1;
gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
goto out;
}
+
ret = 0; /* Success */
set:
@@ -3999,7 +4029,8 @@ set:
goto out;
}
- if (config_type == GF_SNAP_CONFIG_TYPE_SET && auto_delete != 1) {
+ if (config_type == GF_SNAP_CONFIG_TYPE_SET &&
+ (hard_limit || soft_limit)) {
conf_vals = snap_confopt_vals;
if (hard_limit && soft_limit) {
question = conf_vals[GF_SNAP_CONFIG_SET_BOTH].question;
diff --git a/cli/src/cli-cmd-snapshot.c b/cli/src/cli-cmd-snapshot.c
index 07d04595b06..d03b5b99dd0 100644
--- a/cli/src/cli-cmd-snapshot.c
+++ b/cli/src/cli-cmd-snapshot.c
@@ -104,7 +104,8 @@ struct cli_cmd snapshot_cmds[] = {
},
{"snapshot config [volname] ([snap-max-hard-limit <count>] "
"[snap-max-soft-limit <percent>]) "
- "| ([auto-delete <enable|disable>])",
+ "| ([auto-delete <enable|disable>])"
+ "| ([activate-on-create <enable|disable>])",
cli_cmd_snapshot_cbk,
"Snapshot Config."
},
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index e9db57259b2..08f51558506 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -7808,6 +7808,7 @@ cli_snapshot_config_display (dict_t *dict, gf_cli_rsp *rsp)
uint64_t i = 0;
uint64_t voldisplaycount = 0;
char *auto_delete = NULL;
+ char *snap_activate = NULL;
GF_ASSERT (dict);
GF_ASSERT (rsp);
@@ -7839,9 +7840,11 @@ cli_snapshot_config_display (dict_t *dict, gf_cli_rsp *rsp)
ret = dict_get_str (dict, "auto-delete", &auto_delete);
+ ret = dict_get_str (dict, "snap-activate-on-create", &snap_activate);
+
if (!hard_limit && !soft_limit
&& config_command != GF_SNAP_CONFIG_DISPLAY
- && !auto_delete) {
+ && !auto_delete && !snap_activate) {
ret = -1;
gf_log(THIS->name, GF_LOG_ERROR,
"Could not fetch config-key");
@@ -7865,6 +7868,9 @@ cli_snapshot_config_display (dict_t *dict, gf_cli_rsp *rsp)
} else if (auto_delete) {
cli_out ("snapshot config: auto-delete "
"successfully set");
+ } else if (snap_activate) {
+ cli_out ("snapshot config: activate-on-create "
+ "successfully set");
}
break;
@@ -7891,7 +7897,9 @@ cli_snapshot_config_display (dict_t *dict, gf_cli_rsp *rsp)
cli_out ("snap-max-soft-limit : %"PRIu64"%%",
soft_limit);
- cli_out ("auto-delete : %s\n", auto_delete);
+ cli_out ("auto-delete : %s", auto_delete);
+
+ cli_out ("activate-on-create : %s\n", snap_activate);
cli_out ("Snapshot Volume Configuration:");
diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c
index 66bec7ee96f..aacce140946 100644
--- a/cli/src/cli-xml-output.c
+++ b/cli/src/cli-xml-output.c
@@ -5156,7 +5156,7 @@ cli_xml_snapshot_config_show (xmlTextWriterPtr writer,
ret = dict_get_str (dict, "auto-delete", &str_value);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch auto-delet");
+ gf_log ("cli", GF_LOG_ERROR, "Could not fetch auto-delete");
goto out;
}
@@ -5164,6 +5164,17 @@ cli_xml_snapshot_config_show (xmlTextWriterPtr writer,
(xmlChar *) "autoDelete", "%s", str_value);
XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = dict_get_str (dict, "snap-activate-on-create", &str_value);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "Could not fetch snap-activate-on-create-delete");
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *) "activateOnCreate", "%s", str_value);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
/* </systemConfig> */
ret = xmlTextWriterEndElement (writer);
XML_RET_CHECK_AND_GOTO (ret, out);
@@ -5267,6 +5278,7 @@ cli_xml_snapshot_config_set (xmlTextWriterPtr writer, xmlDocPtr doc,
uint64_t soft_limit = 0;
char *volname = NULL;
char *auto_delete = NULL;
+ char *snap_activate = NULL;
GF_ASSERT (writer);
GF_ASSERT (doc);
@@ -5277,12 +5289,13 @@ cli_xml_snapshot_config_set (xmlTextWriterPtr writer, xmlDocPtr doc,
/* This is optional parameter therefore ignore the error */
ret = dict_get_uint64 (dict, "snap-max-soft-limit", &soft_limit);
ret = dict_get_str (dict, "auto-delete", &auto_delete);
+ ret = dict_get_str (dict, "snap-activate-on-create", &snap_activate);
- if (!hard_limit && !soft_limit && !auto_delete) {
+ if (!hard_limit && !soft_limit && !auto_delete && !snap_activate) {
ret = -1;
gf_log ("cli", GF_LOG_ERROR, "At least one option from "
- "snap-max-hard-limit, snap-max-soft-limit and "
- "auto-delete should be set");
+ "snap-max-hard-limit, snap-max-soft-limit, auto-delete"
+ " and snap-activate-on-create should be set");
goto out;
}
@@ -5325,6 +5338,12 @@ cli_xml_snapshot_config_set (xmlTextWriterPtr writer, xmlDocPtr doc,
XML_RET_CHECK_AND_GOTO (ret, out);
}
+ if (snap_activate) {
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *) "activateOnCreate", "%s", snap_activate);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
/* </volumeConfig> or </systemConfig> */
ret = xmlTextWriterEndElement (writer);
XML_RET_CHECK_AND_GOTO (ret, out);
diff --git a/doc/admin-guide/en-US/markdown/admin_managing_snapshots.md b/doc/admin-guide/en-US/markdown/admin_managing_snapshots.md
index 93be39d94d5..820dcb18863 100644
--- a/doc/admin-guide/en-US/markdown/admin_managing_snapshots.md
+++ b/doc/admin-guide/en-US/markdown/admin_managing_snapshots.md
@@ -150,7 +150,8 @@ the snapshots present in the system are displayed.
Syntax:
*snapshot config \[volname\] \(\[snap-max-hard-limit <count\>\] \[snap-max-soft-limit <percent>\]\)
- | \(\[auto-delete <enable|disable\>\]\)*
+ | \(\[auto-delete <enable|disable\>\]\)
+ | \(\[activate-on-create <enable|disable\>\]\)*
Details:
Displays and sets the snapshot config values.
@@ -176,6 +177,8 @@ the user gets a warning with every successful snapshot creation.
Upon reaching the hard-limit, further snapshot creations will not be allowed.
+activate-on-create is disabled by default. If you enable activate-on-create,
+then further snapshot will be activated during the time of snapshot creation.
-------------------------------------------------------------------------
**Activating a snapshot**
diff --git a/doc/gluster.8 b/doc/gluster.8
index b7e5e205e9f..d13cb6f6a17 100644
--- a/doc/gluster.8
+++ b/doc/gluster.8
@@ -128,7 +128,7 @@ This command gives status of the snapshot. The details included are snapshot bri
If snapname is specified then status of the mentioned snapshot is displayed. If volname is specified then status of all snapshots belonging to that volume is displayed. If both snapname and volname is not specified then status of all the snapshots present in the system are displayed.
.TP
-\fB\ snapshot config [volname] ([snap-max-hard-limit <count>] [snap-max-soft-limit <percent>]) | ([auto-delete <enable|disable>])
+\fB\ snapshot config [volname] ([snap-max-hard-limit <count>] [snap-max-soft-limit <percent>]) | ([auto-delete <enable|disable>]) | ([activate-on-create <enable|disable>])
Displays and sets the snapshot config values.
snapshot config without any keywords displays the snapshot config values of all volumes in the system. If volname is provided, then the snapshot config values of that volume is displayed.
@@ -144,6 +144,8 @@ When auto-delete feature is enabled, then upon reaching the soft-limit, with eve
When auto-delete feature is disabled, then upon reaching the soft-limit, the user gets a warning with every successful snapshot creation.
Upon reaching the hard-limit, further snapshot creations will not be allowed.
+
+activate-on-create is disabled by default. If you enable activate-on-create, then further snapshot will be activated during the time of snapshot creation.
.TP
\fB\ snapshot activate <snapname> \fR
Activates the mentioned snapshot.
diff --git a/tests/basic/uss.t b/tests/basic/uss.t
index a83cbeddaee..56cb757514d 100644
--- a/tests/basic/uss.t
+++ b/tests/basic/uss.t
@@ -23,6 +23,8 @@ TEST $GFS --volfile-server=$H0 --volfile-id=$V0 $M0;
for i in {1..10} ; do echo "file" > $M0/file$i ; done
+TEST $CLI snapshot config activate-on-create enable
+
TEST $CLI snapshot create snap1 $V0;
for i in {11..20} ; do echo "file" > $M0/file$i ; done
diff --git a/tests/basic/volume-snapshot.t b/tests/basic/volume-snapshot.t
index bb483850eeb..46440d1a706 100755
--- a/tests/basic/volume-snapshot.t
+++ b/tests/basic/volume-snapshot.t
@@ -86,6 +86,8 @@ start_volumes 2
EXPECT 'Started' volinfo_field $V0 'Status';
EXPECT 'Started' volinfo_field $V1 'Status';
+TEST $CLI_1 snapshot config activate-on-create enable
+
#Snapshot Operations
create_snapshots
diff --git a/tests/bugs/bug-1109889.t b/tests/bugs/bug-1109889.t
index 64d0b7ad1c6..05f65887308 100644
--- a/tests/bugs/bug-1109889.t
+++ b/tests/bugs/bug-1109889.t
@@ -25,6 +25,8 @@ MOUNT_PID=`ps ax |grep "glusterfs --volfile-sever $H0 --volfile-id=$V0 $M0" | gr
for i in {1..10} ; do echo "file" > $M0/file$i ; done
+TEST $CLI snapshot config activate-on-create enable
+
TEST $CLI snapshot create snap1 $V0;
for i in {11..20} ; do echo "file" > $M0/file$i ; done
diff --git a/tests/bugs/bug-1157991.t b/tests/bugs/bug-1157991.t
new file mode 100755
index 00000000000..97d081052e8
--- /dev/null
+++ b/tests/bugs/bug-1157991.t
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+. $(dirname $0)/../include.rc
+. $(dirname $0)/../snapshot.rc
+
+cleanup;
+TEST verify_lvm_version;
+TEST glusterd;
+TEST pidof glusterd;
+
+TEST setup_lvm 1
+
+TEST $CLI volume create $V0 $H0:$L1
+TEST $CLI volume start $V0
+
+TEST $CLI snapshot create snap1 $V0
+EXPECT 'Stopped' snapshot_status snap1;
+
+TEST $CLI snapshot config activate-on-create enable
+TEST $CLI snapshot create snap2 $V0
+EXPECT 'Started' snapshot_status snap2;
+
+#Clean up
+TEST $CLI snapshot delete snap1
+TEST $CLI snapshot delete snap2
+
+TEST $CLI volume stop $V0 force
+TEST $CLI volume delete $V0
+
+cleanup;
diff --git a/tests/snapshot.rc b/tests/snapshot.rc
index 6ca276d194b..a0c92d96343 100755
--- a/tests/snapshot.rc
+++ b/tests/snapshot.rc
@@ -291,11 +291,15 @@ function snapshot_n_exists() {
function snapshot_status()
{
local snap=$1;
+ local cli=$CLI_1;
+ if [ "$cli" = "" ]; then
+ cli=$CLI
+ fi
#TODO: Right now just fetches the status of the single snap volume.
#When snapshot will have multiple snap volumes, should have a
#cummulative logic for status
- $CLI_1 snapshot info $snap | grep "Status" | sed 's/.*: //';
+ $cli snapshot info $snap | grep "Status" | sed 's/.*: //';
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
index 68ba4458ebf..bb98cb806e3 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c
+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
@@ -220,6 +220,7 @@ snap_max_limits_display_commit (dict_t *rsp_dict, char *volname,
uint64_t opt_hard_max = GLUSTERD_SNAPS_MAX_HARD_LIMIT;
uint64_t opt_soft_max = GLUSTERD_SNAPS_DEF_SOFT_LIMIT_PERCENT;
char *auto_delete = "disable";
+ char *snap_activate = "disable";
this = THIS;
@@ -394,9 +395,26 @@ snap_max_limits_display_commit (dict_t *rsp_dict, char *volname,
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);
+ snprintf (err_str, PATH_MAX,
+ "Failed to set %s in response dictionary",
+ GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE);
+ goto out;
+ }
+
+ /* "snap-activate-on-create" might not be set by user explicitly,
+ * in that case it's better to consider the default value.
+ * Hence not erroring out if Key is not found.
+ */
+ ret = dict_get_str (conf->opts, GLUSTERD_STORE_KEY_SNAP_ACTIVATE,
+ &snap_activate);
+
+ ret = dict_set_dynstr_with_alloc (rsp_dict,
+ GLUSTERD_STORE_KEY_SNAP_ACTIVATE,
+ snap_activate);
+ if (ret) {
+ snprintf (err_str, PATH_MAX,
+ "Failed to set %s in response dictionary",
+ GLUSTERD_STORE_KEY_SNAP_ACTIVATE);
goto out;
}
@@ -1118,8 +1136,10 @@ 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 cur_auto_delete = 0;
- int req_auto_delete = 0;
+ int32_t cur_auto_delete = 0;
+ int32_t req_auto_delete = 0;
+ int32_t cur_snap_activate = 0;
+ int32_t req_snap_activate = 0;
this = THIS;
@@ -1138,14 +1158,12 @@ glusterd_snapshot_config_prevalidate (dict_t *dict, char **op_errstr)
goto out;
}
- /* config values snap-max-hard-limit and snap-max-soft-limit are
- * optional and hence we are not erroring out if values are not
- * present
- */
- gd_get_snap_conf_values_if_present (dict, &hard_limit, &soft_limit);
+ if (config_command != GF_SNAP_CONFIG_TYPE_SET) {
+ ret = 0;
+ goto out;
+ }
ret = dict_get_str (dict, "volname", &volname);
-
if (volname) {
ret = glusterd_volinfo_find (volname, &volinfo);
if (ret) {
@@ -1155,41 +1173,41 @@ glusterd_snapshot_config_prevalidate (dict_t *dict, char **op_errstr)
}
}
- switch (config_command) {
- case GF_SNAP_CONFIG_TYPE_SET:
- if (hard_limit) {
- /* Validations for snap-max-hard-limits */
- ret = snap_max_hard_limits_validate (dict, volname,
- hard_limit, op_errstr);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "snap-max-hard-limit validation "
- "failed.");
- goto out;
- }
- }
+ /* config values snap-max-hard-limit and snap-max-soft-limit are
+ * optional and hence we are not erroring out if values are not
+ * present
+ */
+ gd_get_snap_conf_values_if_present (dict, &hard_limit, &soft_limit);
- if (soft_limit) {
- max_limit = GLUSTERD_SNAPS_MAX_SOFT_LIMIT_PERCENT;
- if ((soft_limit < 0) || (soft_limit > max_limit)) {
- ret = -1;
- snprintf (err_str, PATH_MAX, "Invalid "
- "snap-max-soft-limit ""%"
- PRIu64 ". Expected range 1 - %"PRIu64,
- soft_limit, max_limit);
- goto out;
- }
- break;
+ if (hard_limit) {
+ /* Validations for snap-max-hard-limits */
+ ret = snap_max_hard_limits_validate (dict, volname,
+ hard_limit, op_errstr);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "snap-max-hard-limit validation failed.");
+ goto out;
}
+ }
- /* If hard_limit or soft_limit is set then need not check
- * for auto-delete
- */
- if (hard_limit || soft_limit) {
- ret = 0;
+ if (soft_limit) {
+ max_limit = GLUSTERD_SNAPS_MAX_SOFT_LIMIT_PERCENT;
+ if ((soft_limit < 0) || (soft_limit > max_limit)) {
+ ret = -1;
+ snprintf (err_str, PATH_MAX, "Invalid "
+ "snap-max-soft-limit ""%"
+ PRIu64 ". Expected range 1 - %"PRIu64,
+ soft_limit, max_limit);
goto out;
}
+ }
+ if (hard_limit || soft_limit) {
+ ret = 0;
+ goto out;
+ }
+
+ if (dict_get(dict, GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE)) {
req_auto_delete = dict_get_str_boolean (dict,
GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE,
_gf_false);
@@ -1201,8 +1219,7 @@ glusterd_snapshot_config_prevalidate (dict_t *dict, char **op_errstr)
}
/* Ignoring the error as the auto-delete is optional and
- * might not be present in the options dictionary.
- */
+ might not be present in the options dictionary.*/
cur_auto_delete = dict_get_str_boolean (conf->opts,
GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE,
_gf_false);
@@ -1217,9 +1234,37 @@ glusterd_snapshot_config_prevalidate (dict_t *dict, char **op_errstr)
"auto-delete is already disabled");
goto out;
}
+ } else if (dict_get(dict, GLUSTERD_STORE_KEY_SNAP_ACTIVATE)) {
+ req_snap_activate = dict_get_str_boolean (dict,
+ GLUSTERD_STORE_KEY_SNAP_ACTIVATE,
+ _gf_false);
+ if (req_snap_activate < 0) {
+ ret = -1;
+ snprintf (err_str, sizeof (err_str), "Please enter a "
+ "valid boolean value for activate-on-create");
+ goto out;
+ }
- default:
- break;
+ /* Ignoring the error as the activate-on-create is optional and
+ might not be present in the options dictionary.*/
+ cur_snap_activate = dict_get_str_boolean (conf->opts,
+ GLUSTERD_STORE_KEY_SNAP_ACTIVATE,
+ _gf_false);
+
+ if (cur_snap_activate == req_snap_activate) {
+ ret = -1;
+ if (cur_snap_activate == _gf_true)
+ snprintf (err_str, sizeof (err_str),
+ "activate-on-create is already enabled");
+ else
+ snprintf (err_str, sizeof (err_str),
+ "activate-on-create is already disabled");
+ goto out;
+ }
+ } else {
+ ret = -1;
+ snprintf (err_str, sizeof (err_str), "Invalid option");
+ goto out;
}
ret = 0;
@@ -5530,6 +5575,7 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
int ret = -1;
int64_t i = 0;
int64_t volcount = 0;
+ int32_t snap_activate = 0;
char *snapname = NULL;
char *volname = NULL;
char *tmp_name = NULL;
@@ -5635,6 +5681,34 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
goto out;
}
+ ret = dict_set_dynstr_with_alloc (rsp_dict, "snapuuid",
+ uuid_utoa (snap->snap_id));
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set snap "
+ "uuid in response dictionary for %s snapshot",
+ snap->snapname);
+ goto out;
+ }
+
+ snap_activate = dict_get_str_boolean (priv->opts,
+ GLUSTERD_STORE_KEY_SNAP_ACTIVATE,
+ _gf_false);
+ if (!snap_activate) {
+ list_for_each_entry (snap_vol, &snap->volumes, vol_list) {
+ snap_vol->status = GLUSTERD_STATUS_STOPPED;
+ ret = glusterd_store_volinfo (snap_vol,
+ GLUSTERD_VOLINFO_VER_AC_INCREMENT);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to store snap volinfo %s",
+ snap_vol->volname);
+ goto out;
+ }
+ }
+
+ goto out;
+ }
+
list_for_each_entry (snap_vol, &snap->volumes, vol_list) {
list_for_each_entry (brickinfo, &snap_vol->bricks, brick_list) {
ret = glusterd_brick_start (snap_vol, brickinfo,
@@ -5660,15 +5734,6 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
}
}
- ret = dict_set_dynstr_with_alloc (rsp_dict, "snapuuid",
- uuid_utoa (snap->snap_id));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snap "
- "uuid in response dictionary for %s snapshot",
- snap->snapname);
- goto out;
- }
-
ret = 0;
out:
@@ -5777,6 +5842,8 @@ glusterd_snapshot_config_commit (dict_t *dict, char **op_errstr,
uint64_t soft_limit = 0;
char *next_version = NULL;
char *auto_delete = NULL;
+ char *snap_activate = NULL;
+ gf_boolean_t system_conf = _gf_false;
this = THIS;
@@ -5794,6 +5861,10 @@ glusterd_snapshot_config_commit (dict_t *dict, char **op_errstr,
"failed to get config-command type");
goto out;
}
+ if (config_command != GF_SNAP_CONFIG_TYPE_SET) {
+ ret = 0;
+ goto out;
+ }
ret = dict_get_str (dict, "volname", &volname);
@@ -5804,98 +5875,90 @@ glusterd_snapshot_config_commit (dict_t *dict, char **op_errstr,
gd_get_snap_conf_values_if_present (dict, &hard_limit,
&soft_limit);
- /* Ignoring the return value as auto-delete is optional and
- * might not be present in the request dictionary.
- */
- 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) {
- /* Commit ops for snap-max-hard-limit */
- ret = snap_max_hard_limit_set_commit (dict, hard_limit,
- volname,
- op_errstr);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "snap-max-hard-limit set "
- "commit failed.");
- goto out;
- }
+ if (hard_limit) {
+ /* Commit ops for snap-max-hard-limit */
+ ret = snap_max_hard_limit_set_commit (dict, hard_limit, volname,
+ op_errstr);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "snap-max-hard-limit set commit failed.");
+ goto out;
}
+ }
- if (soft_limit) {
- /* For system limit */
-
- ret = dict_set_uint64 (conf->opts,
- GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT,
- soft_limit);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "save %s in the dictionary",
- GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT);
- goto out;
- }
-
- ret = glusterd_get_next_global_opt_version_str
- (conf->opts,
- &next_version);
- if (ret)
- goto out;
-
- ret = dict_set_str (conf->opts,
- GLUSTERD_GLOBAL_OPT_VERSION,
- next_version);
- if (ret)
- goto out;
-
- ret = glusterd_store_options (this, conf->opts);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "store options");
- goto out;
- }
+ if (soft_limit) {
+ /* For system limit */
+ system_conf = _gf_true;
+ ret = dict_set_uint64 (conf->opts,
+ GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT,
+ soft_limit);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to save %s in the dictionary",
+ GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT);
+ goto out;
}
+ }
+
+ if (hard_limit || soft_limit) {
+ ret = 0;
+ goto done;
+ }
- if (auto_delete) {
- ret = dict_set_dynstr_with_alloc (conf->opts,
+ if (!dict_get_str(dict,
+ GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE,
+ &auto_delete)) {
+ system_conf = _gf_true;
+ 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_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;
- }
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Could not "
+ "save auto-delete value in conf->opts");
+ goto out;
+ }
+ } else if (!dict_get_str(dict,
+ GLUSTERD_STORE_KEY_SNAP_ACTIVATE,
+ &snap_activate)) {
+ system_conf = _gf_true;
+ ret = dict_set_dynstr_with_alloc (conf->opts,
+ GLUSTERD_STORE_KEY_SNAP_ACTIVATE,
+ snap_activate);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Could not save "
+ "snap-activate-on-create value in conf->opts");
+ goto out;
+ }
+ } else {
+ ret = -1;
+ gf_log (this->name, GF_LOG_ERROR, "Invalid option");
+ goto out;
+ }
- ret = dict_set_str (conf->opts,
- GLUSTERD_GLOBAL_OPT_VERSION,
- next_version);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "set next global opt-version");
+done:
+ if (system_conf) {
+ 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 = glusterd_store_options (this, conf->opts);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "store options");
- goto out;
- }
+ ret = dict_set_str (conf->opts, GLUSTERD_GLOBAL_OPT_VERSION,
+ next_version);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to set next global opt-version");
+ goto out;
}
- break;
- default:
- break;
+ ret = glusterd_store_options (this, conf->opts);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to store options");
+ goto out;
+ }
}
out:
@@ -6810,6 +6873,11 @@ glusterd_snapshot (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
case GF_SNAP_OPTION_TYPE_CONFIG:
ret = glusterd_snapshot_config_commit (dict, op_errstr,
rsp_dict);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "snapshot config failed");
+ goto out;
+ }
break;
case GF_SNAP_OPTION_TYPE_DELETE:
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h
index a17800076e0..99bbb39683a 100644
--- a/xlators/mgmt/glusterd/src/glusterd-store.h
+++ b/xlators/mgmt/glusterd/src/glusterd-store.h
@@ -74,6 +74,7 @@ typedef enum glusterd_store_ver_ac_{
#define GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE "auto-delete"
#define GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT "snap-max-soft-limit"
#define GLUSTERD_STORE_KEY_SNAPD_PORT "snapd-port"
+#define GLUSTERD_STORE_KEY_SNAP_ACTIVATE "snap-activate-on-create"
#define GLUSTERD_STORE_KEY_BRICK_HOSTNAME "hostname"
#define GLUSTERD_STORE_KEY_BRICK_PATH "path"