diff options
author | Gaurav Kumar Garg <ggarg@redhat.com> | 2015-06-05 13:58:28 +0530 |
---|---|---|
committer | Venky Shankar <vshankar@redhat.com> | 2015-06-15 05:23:46 -0700 |
commit | 554fa0c1315d0b4b78ba35a2d332d7ac0fd07d48 (patch) | |
tree | 2b56e439a5547fe27e6f33b9bffb5dd24ba38654 | |
parent | 3fb18451311c34aeced1054472b6f81fc13dd679 (diff) |
features/bitrot: tuanble object signing waiting time value for bitrot
Currently bitrot using 120 second waiting time for object to be signed
after all fop's released. This signing waiting time value should be tunable.
Command for changing the signing waiting time will be
#gluster volume bitrot <VOLNAME> signing-time <waiting time value in second>
Change-Id: I89f3121564c1bbd0825f60aae6147413a2fbd798
BUG: 1228680
Signed-off-by: Gaurav Kumar Garg <ggarg@redhat.com>
Signed-off-by: Venky Shankar <vshankar@redhat.com>
Reviewed-on: http://review.gluster.org/11105
-rw-r--r-- | cli/src/cli-cmd-parser.c | 34 | ||||
-rw-r--r-- | libglusterfs/src/common-utils.h | 3 | ||||
-rw-r--r-- | rpc/xdr/src/cli1-xdr.x | 1 | ||||
-rw-r--r-- | tests/bugs/bitrot/bug-1228680.t | 48 | ||||
-rw-r--r-- | xlators/features/bit-rot/src/bitd/bit-rot.c | 37 | ||||
-rw-r--r-- | xlators/features/bit-rot/src/bitd/bit-rot.h | 2 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-bitrot.c | 47 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volgen.c | 33 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-set.c | 7 |
9 files changed, 201 insertions, 11 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index f3dd58528b6..2f7885b80eb 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 6691259f518..06ce0ff4d71 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 0d5d3cc360c..34f324f1099 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 00000000000..23db9d5e208 --- /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 a645085fd58..651c42fcb82 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 e702f3ac72d..7be4398d00d 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 da1b54ac1df..c32aa1e3ff3 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 8fe1be16fad..e618e2c7a35 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 2ea2ae2eadc..3d3525297f5 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", |