Blob Blame History Raw
From 7c8df30e18538917e361faff2ed032024d5ba16f Mon Sep 17 00:00:00 2001
From: Gaurav Kumar Garg <ggarg@redhat.com>
Date: Fri, 5 Jun 2015 13:58:28 +0530
Subject: [PATCH 117/129] 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>

BUG: 1227900
Change-Id: I6f63cc77c996bfc576a05801be39a2028e5db866
Signed-off-by: Gaurav Kumar Garg <ggarg@redhat.com>
upstream patch url: http://review.gluster.org/#/c/11105/
Reviewed-on: https://code.engineering.redhat.com/gerrit/50741
Reviewed-by: Venky Shankar <vshankar@redhat.com>
Tested-by: Venky Shankar <vshankar@redhat.com>
---
 cli/src/cli-cmd-parser.c                        |   33 ++++++++++++++-
 rpc/xdr/src/cli1-xdr.x                          |    1 +
 tests/bugs/bitrot/bug-1228680.t                 |   31 ++++++++++++++
 xlators/features/bit-rot/src/bitd/bit-rot.c     |   37 ++++++++++++++---
 xlators/features/bit-rot/src/bitd/bit-rot.h     |    2 +-
 xlators/mgmt/glusterd/src/glusterd-bitrot.c     |   49 +++++++++++++++++++++++
 xlators/mgmt/glusterd/src/glusterd-volgen.c     |   33 +++++++++++++++
 xlators/mgmt/glusterd/src/glusterd-volume-set.c |    7 +++
 8 files changed, 182 insertions(+), 11 deletions(-)
 create mode 100644 tests/bugs/bitrot/bug-1228680.t

diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index 2ddbe88..51da792 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -5018,8 +5018,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",
@@ -5030,6 +5030,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;
+        uint32_t           expiry_time            = 0;
 
         GF_ASSERT (words);
         GF_ASSERT (options);
@@ -5039,7 +5040,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;
         }
 
@@ -5167,6 +5168,32 @@ 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_int32 (dict, "expiry-time", 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/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..c77beed
--- /dev/null
+++ b/tests/bugs/bitrot/bug-1228680.t
@@ -0,0 +1,31 @@
+#!/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
+
+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
+
+## Set object expiry time value 20 second.
+TEST $CLI volume bitrot $V0 signing-time 20
+
+
+cleanup;
diff --git a/xlators/features/bit-rot/src/bitd/bit-rot.c b/xlators/features/bit-rot/src/bitd/bit-rot.c
index 8149083..a4821ba 100644
--- a/xlators/features/bit-rot/src/bitd/bit-rot.c
+++ b/xlators/features/bit-rot/src/bitd/bit-rot.c
@@ -753,8 +753,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);
 
@@ -1491,12 +1494,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);
@@ -1581,6 +1600,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)
@@ -1651,8 +1672,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)
@@ -1700,10 +1725,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 = "120",
+          .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 40e02eb..562f17e 100644
--- a/xlators/features/bit-rot/src/bitd/bit-rot.h
+++ b/xlators/features/bit-rot/src/bitd/bit-rot.h
@@ -162,7 +162,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 08976cf..1563102 100644
--- a/xlators/mgmt/glusterd/src/glusterd-bitrot.c
+++ b/xlators/mgmt/glusterd/src/glusterd-bitrot.c
@@ -37,6 +37,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
@@ -248,6 +249,46 @@ 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,};
+        char           *key_value           = NULL;
+
+        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);
+        key_value = gf_strdup (dkey);
+
+        ret = dict_set_dynstr (volinfo->dict, key, key_value);
+        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;
@@ -476,6 +517,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 9c09c78..a79e129 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c
@@ -3743,6 +3743,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)
 {
@@ -4981,6 +5008,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 624e577..415bc01 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
@@ -1866,6 +1866,13 @@ struct volopt_map_entry glusterd_volopt_map[] = {
           .flags      = OPT_FLAG_FORCE,
           .type       = NO_DOC,
         },
+        { .key        = "features.expiry-time",
+          .voltype    = "features/bitrot",
+          .value      = "120",
+          .option     = "expiry-time",
+          .op_version = GD_OP_VERSION_3_7_0,
+          .type       = NO_DOC,
+        },
         /* Upcall translator options */
         { .key         = "features.cache-invalidation",
           .voltype     = "features/upcall",
-- 
1.7.1