summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cli/src/cli-cmd-parser.c34
-rw-r--r--libglusterfs/src/common-utils.h3
-rw-r--r--rpc/xdr/src/cli1-xdr.x1
-rw-r--r--tests/bugs/bitrot/bug-1228680.t48
-rw-r--r--xlators/features/bit-rot/src/bitd/bit-rot.c37
-rw-r--r--xlators/features/bit-rot/src/bitd/bit-rot.h2
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-bitrot.c47
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.c33
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-set.c7
9 files changed, 201 insertions, 11 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index f3dd585..2f7885b 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -4994,8 +4994,8 @@ cli_cmd_bitrot_parse (const char **words, int wordcount, dict_t **options)
char *volname = NULL;
char *opwords[] = {"enable", "disable",
"scrub-throttle",
- "scrub-frequency",
- "scrub", NULL};
+ "scrub-frequency", "scrub",
+ "signing-time", NULL};
char *scrub_throt_values[] = {"lazy", "normal",
"aggressive", NULL};
char *scrub_freq_values[] = {"hourly",
@@ -5006,6 +5006,7 @@ cli_cmd_bitrot_parse (const char **words, int wordcount, dict_t **options)
NULL};
dict_t *dict = NULL;
gf_bitrot_type type = GF_BITROT_OPTION_TYPE_NONE;
+ int32_t expiry_time = 0;
GF_ASSERT (words);
GF_ASSERT (options);
@@ -5015,7 +5016,7 @@ cli_cmd_bitrot_parse (const char **words, int wordcount, dict_t **options)
goto out;
if (wordcount < 4 || wordcount > 5) {
- gf_log ("", GF_LOG_ERROR, "Invalid syntax");
+ gf_log ("cli", GF_LOG_ERROR, "Invalid syntax");
goto out;
}
@@ -5143,6 +5144,33 @@ cli_cmd_bitrot_parse (const char **words, int wordcount, dict_t **options)
goto set_type;
}
}
+ }
+
+ if (!strcmp (words[3], "signing-time")) {
+ if (!words[4]) {
+ cli_err ("Missing signing-time value for bitrot "
+ "option");
+ ret = -1;
+ goto out;
+ } else {
+ type = GF_BITROT_OPTION_TYPE_EXPIRY_TIME;
+
+ expiry_time = strtol (words[4], NULL, 0);
+ if (expiry_time < 1) {
+ cli_err ("Expiry time value should not be less"
+ " than 1");
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_set_uint32 (dict, "expiry-time",
+ (unsigned int) expiry_time);
+ if (ret) {
+ cli_out ("Failed to set dict for bitrot");
+ goto out;
+ }
+ goto set_type;
+ }
} else {
cli_err ("Invalid option %s for bitrot. Please enter valid "
"bitrot option", words[3]);
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
index 6691259..06ce0ff 100644
--- a/libglusterfs/src/common-utils.h
+++ b/libglusterfs/src/common-utils.h
@@ -90,6 +90,9 @@ void trap (void);
/* Default timeout for both barrier and changelog translator */
#define BARRIER_TIMEOUT "120"
+/* Default value of signing waiting time to sign a file for bitrot */
+#define SIGNING_TIMEOUT "120"
+
enum _gf_boolean
{
_gf_false = 0,
diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x
index 0d5d3cc..34f324f 100644
--- a/rpc/xdr/src/cli1-xdr.x
+++ b/rpc/xdr/src/cli1-xdr.x
@@ -40,6 +40,7 @@ enum gf_bitrot_type {
GF_BITROT_OPTION_TYPE_SCRUB_THROTTLE,
GF_BITROT_OPTION_TYPE_SCRUB_FREQ,
GF_BITROT_OPTION_TYPE_SCRUB,
+ GF_BITROT_OPTION_TYPE_EXPIRY_TIME,
GF_BITROT_OPTION_TYPE_MAX
};
diff --git a/tests/bugs/bitrot/bug-1228680.t b/tests/bugs/bitrot/bug-1228680.t
new file mode 100644
index 0000000..23db9d5
--- /dev/null
+++ b/tests/bugs/bitrot/bug-1228680.t
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+## Test case for bitrot
+## Tunable object signing waiting time value for bitrot.
+
+. $(dirname $0)/../../include.rc
+. $(dirname $0)/../../volume.rc
+. $(dirname $0)/../../cluster.rc
+
+SLEEP_TIME=3
+
+cleanup;
+## Start glusterd
+TEST glusterd;
+TEST pidof glusterd;
+
+## Lets create and start the volume
+TEST $CLI volume create $V0 $H0:$B0/${V0}0 $H0:$B0/${V0}1
+TEST $CLI volume start $V0
+
+## Enable bitrot on volume $V0
+TEST $CLI volume bitrot $V0 enable
+
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" get_bitd_count
+
+# wait a bit for oneshot crawler to finish
+sleep $SLEEP_TIME
+
+## negative test
+TEST ! $CLI volume bitrot $V0 signing-time -100
+
+## Set object expiry time value 5 second.
+TEST $CLI volume bitrot $V0 signing-time $SLEEP_TIME
+
+## Mount the volume
+TEST $GFS --volfile-server=$H0 --volfile-id=$V0 $M0;
+
+# create and check object signature
+fname="$M0/filezero"
+echo "ZZZ" > $fname
+
+# wait till the object is signed
+sleep `expr $SLEEP_TIME \* 2`
+
+backpath=$(get_backend_paths $fname)
+TEST getfattr -m . -n trusted.bit-rot.signature $backpath
+
+cleanup;
diff --git a/xlators/features/bit-rot/src/bitd/bit-rot.c b/xlators/features/bit-rot/src/bitd/bit-rot.c
index a645085..651c42f 100644
--- a/xlators/features/bit-rot/src/bitd/bit-rot.c
+++ b/xlators/features/bit-rot/src/bitd/bit-rot.c
@@ -748,8 +748,11 @@ br_initialize_timer (xlator_t *this, br_object_t *object, br_child_t *child,
goto out;
INIT_LIST_HEAD (&timer->entry);
+ timer->expires = (priv->expiry_time >> 1);
+ if (!timer->expires)
+ timer->expires = 1;
+
timer->data = object;
- timer->expires = priv->expiry_time;
timer->function = br_add_object_to_queue;
gf_tw_add_timer (priv->timer_wheel, timer);
@@ -1486,12 +1489,28 @@ br_rate_limit_signer (xlator_t *this, int child_count, int numbricks)
}
static int32_t
+br_signer_handle_options (xlator_t *this, br_private_t *priv, dict_t *options)
+{
+ if (options)
+ GF_OPTION_RECONF ("expiry-time", priv->expiry_time,
+ options, uint32, error_return);
+ else
+ GF_OPTION_INIT ("expiry-time", priv->expiry_time,
+ uint32, error_return);
+
+ return 0;
+
+error_return:
+ return -1;
+}
+
+static int32_t
br_signer_init (xlator_t *this, br_private_t *priv)
{
int32_t ret = 0;
int numbricks = 0;
- GF_OPTION_INIT ("expiry-time", priv->expiry_time, int32, error_return);
+ GF_OPTION_INIT ("expiry-time", priv->expiry_time, uint32, error_return);
GF_OPTION_INIT ("brick-count", numbricks, int32, error_return);
ret = br_rate_limit_signer (this, priv->child_count, numbricks);
@@ -1576,6 +1595,8 @@ init (xlator_t *this)
if (!priv->iamscrubber) {
ret = br_signer_init (this, priv);
+ if (!ret)
+ ret = br_signer_handle_options (this, priv, NULL);
} else {
ret = br_scrubber_init (this, priv);
if (!ret)
@@ -1646,8 +1667,12 @@ reconfigure (xlator_t *this, dict_t *options)
priv = this->private;
- if (!priv->iamscrubber)
+ if (!priv->iamscrubber) {
+ ret = br_signer_handle_options (this, priv, options);
+ if (ret)
+ goto err;
return 0;
+ }
ret = br_scrubber_handle_options (this, priv, options);
if (ret)
@@ -1695,10 +1720,8 @@ struct xlator_cbks cbks;
struct volume_options options[] = {
{ .key = {"expiry-time"},
.type = GF_OPTION_TYPE_INT,
- /* Let the default timer be half the value of the wait time for
- * sining (which is 120 as of now) */
- .default_value = "60",
- .description = "default time duration for which an object waits "
+ .default_value = SIGNING_TIMEOUT,
+ .description = "Waiting time for an object on which it waits "
"before it is signed",
},
{ .key = {"brick-count"},
diff --git a/xlators/features/bit-rot/src/bitd/bit-rot.h b/xlators/features/bit-rot/src/bitd/bit-rot.h
index e702f3a..7be4398 100644
--- a/xlators/features/bit-rot/src/bitd/bit-rot.h
+++ b/xlators/features/bit-rot/src/bitd/bit-rot.h
@@ -157,7 +157,7 @@ struct br_private {
and ready to be picked up for
signing and the workers which sign
the objects */
- int32_t expiry_time; /* objects "wait" time */
+ uint32_t expiry_time; /* objects "wait" time */
br_tbf_t *tbf; /* token bucket filter */
diff --git a/xlators/mgmt/glusterd/src/glusterd-bitrot.c b/xlators/mgmt/glusterd/src/glusterd-bitrot.c
index da1b54a..c32aa1e 100644
--- a/xlators/mgmt/glusterd/src/glusterd-bitrot.c
+++ b/xlators/mgmt/glusterd/src/glusterd-bitrot.c
@@ -32,6 +32,7 @@ const char *gd_bitrot_op_list[GF_BITROT_OPTION_TYPE_MAX] = {
[GF_BITROT_OPTION_TYPE_SCRUB_THROTTLE] = "scrub-throttle",
[GF_BITROT_OPTION_TYPE_SCRUB_FREQ] = "scrub-frequency",
[GF_BITROT_OPTION_TYPE_SCRUB] = "scrub",
+ [GF_BITROT_OPTION_TYPE_EXPIRY_TIME] = "expiry-time",
};
int
@@ -243,6 +244,44 @@ out:
}
static int
+glusterd_bitrot_expiry_time (glusterd_volinfo_t *volinfo, dict_t *dict,
+ char *key, char **op_errstr)
+{
+ int32_t ret = -1;
+ uint32_t expiry_time = 0;
+ xlator_t *this = NULL;
+ char dkey[1024] = {0,};
+
+ this = THIS;
+ GF_ASSERT (this);
+
+ ret = dict_get_uint32 (dict, "expiry-time", &expiry_time);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Unable to get bitrot expiry"
+ " timer value.");
+ goto out;
+ }
+
+ snprintf (dkey, sizeof (dkey), "%d", expiry_time);
+
+ ret = dict_set_dynstr_with_alloc (volinfo->dict, key, dkey);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set option %s",
+ key);
+ goto out;
+ }
+
+ ret = glusterd_bitdsvc_reconfigure ();
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to reconfigure bitrot"
+ "services");
+ goto out;
+ }
+out:
+ return ret;
+}
+
+static int
glusterd_bitrot_enable (glusterd_volinfo_t *volinfo, char **op_errstr)
{
int32_t ret = -1;
@@ -471,6 +510,14 @@ glusterd_op_bitrot (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
goto out;
break;
+ case GF_BITROT_OPTION_TYPE_EXPIRY_TIME:
+ ret = glusterd_bitrot_expiry_time (volinfo, dict,
+ "features.expiry-time",
+ op_errstr);
+ if (ret)
+ goto out;
+ break;
+
default:
gf_asprintf (op_errstr, "Bitrot command failed. Invalid "
"opcode");
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c
index 8fe1be1..e618e2c 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c
@@ -3738,6 +3738,33 @@ gd_get_matching_option (char **options, char *option)
}
static int
+bitrot_option_handler (volgen_graph_t *graph, struct volopt_map_entry *vme,
+ void *param)
+{
+ xlator_t *xl = NULL;
+ char *bitrot_option = NULL;
+ int ret = 0;
+ glusterd_volinfo_t *volinfo = NULL;
+
+ volinfo = param;
+
+ xl = first_of (graph);
+
+ if (!strcmp (vme->option, "expiry-time")) {
+ ret = gf_asprintf (&bitrot_option, "expiry-time");
+ if (ret != -1) {
+ ret = xlator_set_option (xl, bitrot_option, vme->value);
+ GF_FREE (bitrot_option);
+ }
+
+ if (ret)
+ return -1;
+ }
+
+ return ret;
+}
+
+static int
scrubber_option_handler (volgen_graph_t *graph, struct volopt_map_entry *vme,
void *param)
{
@@ -4976,6 +5003,12 @@ build_bitd_volume_graph (volgen_graph_t *graph,
goto out;
}
+ ret = volgen_graph_set_options_generic (&cgraph, set_dict,
+ volinfo,
+ bitrot_option_handler);
+ if (ret)
+ goto out;
+
ret = volgen_graph_merge_sub (graph, &cgraph, clusters);
if (ret)
goto out;
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
index 2ea2ae2..3d35252 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
@@ -1935,6 +1935,13 @@ struct volopt_map_entry glusterd_volopt_map[] = {
.flags = OPT_FLAG_FORCE,
.type = NO_DOC,
},
+ { .key = "features.expiry-time",
+ .voltype = "features/bitrot",
+ .value = SIGNING_TIMEOUT,
+ .option = "expiry-time",
+ .op_version = GD_OP_VERSION_3_7_0,
+ .type = NO_DOC,
+ },
/* Upcall translator options */
{ .key = "features.cache-invalidation",
.voltype = "features/upcall",