14f8ab
From dc03340654d921916ac3890d713fc84ef4bb1e28 Mon Sep 17 00:00:00 2001
14f8ab
From: Mohit Agrawal <moagrawal@redhat.com>
14f8ab
Date: Sat, 29 Sep 2018 13:15:35 +0530
14f8ab
Subject: [PATCH 445/449] feature/changelog: Avoid thread creation if xlator is
14f8ab
 not enabled
14f8ab
14f8ab
Problem:
14f8ab
Changelog creates threads even if the changelog is not enabled
14f8ab
14f8ab
Background:
14f8ab
Changelog xlator broadly does two things
14f8ab
  1. Journalling - Cosumers are geo-rep and glusterfind
14f8ab
  2. Event Notification for registered events like (open, release etc) -
14f8ab
     Consumers are bitrot, geo-rep
14f8ab
14f8ab
The existing option "changelog.changelog" controls journalling and
14f8ab
there is no option to control event notification and is enabled by
14f8ab
default. So when bitrot/geo-rep is not enabled on the volume, threads
14f8ab
and resources(rpc and rbuf) related to event notifications consumes
14f8ab
resources and cpu cycle which is unnecessary.
14f8ab
14f8ab
Solution:
14f8ab
The solution is to have two different options as below.
14f8ab
 1. changelog-notification : Event notifications
14f8ab
 2. changelog : Journalling
14f8ab
14f8ab
This patch introduces the option "changelog-notification" which is
14f8ab
not exposed to user. When either bitrot or changelog (journalling)
14f8ab
is enabled, it internally enbales 'changelog-notification'. But
14f8ab
once the 'changelog-notification' is enabled, it will not be disabled
14f8ab
for the life time of the brick process even after bitrot and changelog
14f8ab
is disabled. As of now, rpc resource cleanup has lot of races and is
14f8ab
difficult to cleanup cleanly. If allowed, it leads to memory leaks
14f8ab
and crashes on enable/disable of bitrot or changelog (journal) in a
14f8ab
loop. Hence to be safer, the event notification is not disabled within
14f8ab
lifetime of process once enabled.
14f8ab
14f8ab
> Change-Id: Ifd00286e0966049e8eb9f21567fe407cf11bb02a
14f8ab
> Updates: #475
14f8ab
> Signed-off-by: Mohit Agrawal <moagrawal@redhat.com>
14f8ab
> (Cherry pick from commit 6de80bcd6366778ac34ce58ec496fa08cc02bd0b)
14f8ab
> (Reviewed on upstream link https://review.gluster.org/#/c/glusterfs/+/21896/)
14f8ab
14f8ab
BUG: 1790336
14f8ab
Change-Id: Ifd00286e0966049e8eb9f21567fe407cf11bb02a
14f8ab
Signed-off-by: Mohit Agrawal <moagrawal@redhat.com>
14f8ab
Reviewed-on: https://code.engineering.redhat.com/gerrit/202778
14f8ab
Tested-by: Mohit Agrawal <moagrawa@redhat.com>
14f8ab
Tested-by: RHGS Build Bot <nigelb@redhat.com>
14f8ab
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
14f8ab
---
14f8ab
 rpc/rpc-lib/src/rpcsvc.c                           |  26 ++--
14f8ab
 tests/basic/changelog/changelog-history.t          |  12 +-
14f8ab
 tests/bugs/bitrot/bug-1227996.t                    |   1 -
14f8ab
 tests/bugs/bitrot/bug-1245981.t                    |   4 +-
14f8ab
 xlators/features/changelog/src/changelog-helpers.h |   4 +
14f8ab
 .../features/changelog/src/changelog-rpc-common.c  |   3 +
14f8ab
 xlators/features/changelog/src/changelog.c         | 149 +++++++++++++++------
14f8ab
 xlators/mgmt/glusterd/src/glusterd-volgen.c        |  13 ++
14f8ab
 8 files changed, 154 insertions(+), 58 deletions(-)
14f8ab
14f8ab
diff --git a/rpc/rpc-lib/src/rpcsvc.c b/rpc/rpc-lib/src/rpcsvc.c
14f8ab
index b058932..3f184bf 100644
14f8ab
--- a/rpc/rpc-lib/src/rpcsvc.c
14f8ab
+++ b/rpc/rpc-lib/src/rpcsvc.c
14f8ab
@@ -1865,6 +1865,18 @@ rpcsvc_program_unregister(rpcsvc_t *svc, rpcsvc_program_t *program)
14f8ab
         goto out;
14f8ab
     }
14f8ab
 
14f8ab
+    pthread_rwlock_rdlock(&svc->rpclock);
14f8ab
+    {
14f8ab
+        list_for_each_entry(prog, &svc->programs, program)
14f8ab
+        {
14f8ab
+            if ((prog->prognum == program->prognum) &&
14f8ab
+                (prog->progver == program->progver)) {
14f8ab
+                break;
14f8ab
+            }
14f8ab
+        }
14f8ab
+    }
14f8ab
+    pthread_rwlock_unlock(&svc->rpclock);
14f8ab
+
14f8ab
     ret = rpcsvc_program_unregister_portmap(program);
14f8ab
     if (ret == -1) {
14f8ab
         gf_log(GF_RPCSVC, GF_LOG_ERROR,
14f8ab
@@ -1881,17 +1893,6 @@ rpcsvc_program_unregister(rpcsvc_t *svc, rpcsvc_program_t *program)
14f8ab
         goto out;
14f8ab
     }
14f8ab
 #endif
14f8ab
-    pthread_rwlock_rdlock(&svc->rpclock);
14f8ab
-    {
14f8ab
-        list_for_each_entry(prog, &svc->programs, program)
14f8ab
-        {
14f8ab
-            if ((prog->prognum == program->prognum) &&
14f8ab
-                (prog->progver == program->progver)) {
14f8ab
-                break;
14f8ab
-            }
14f8ab
-        }
14f8ab
-    }
14f8ab
-    pthread_rwlock_unlock(&svc->rpclock);
14f8ab
 
14f8ab
     gf_log(GF_RPCSVC, GF_LOG_DEBUG,
14f8ab
            "Program unregistered: %s, Num: %d,"
14f8ab
@@ -1912,6 +1913,9 @@ rpcsvc_program_unregister(rpcsvc_t *svc, rpcsvc_program_t *program)
14f8ab
 
14f8ab
     ret = 0;
14f8ab
 out:
14f8ab
+    if (prog)
14f8ab
+        GF_FREE(prog);
14f8ab
+
14f8ab
     if (ret == -1) {
14f8ab
         if (program) {
14f8ab
             gf_log(GF_RPCSVC, GF_LOG_ERROR,
14f8ab
diff --git a/tests/basic/changelog/changelog-history.t b/tests/basic/changelog/changelog-history.t
14f8ab
index 3ce4098..b56e247 100644
14f8ab
--- a/tests/basic/changelog/changelog-history.t
14f8ab
+++ b/tests/basic/changelog/changelog-history.t
14f8ab
@@ -5,6 +5,7 @@
14f8ab
 
14f8ab
 cleanup;
14f8ab
 
14f8ab
+SCRIPT_TIMEOUT=300
14f8ab
 HISTORY_BIN_PATH=$(dirname $0)/../../utils/changelog
14f8ab
 build_tester $HISTORY_BIN_PATH/get-history.c -lgfchangelog
14f8ab
 
14f8ab
@@ -68,18 +69,21 @@ TEST $CLI volume set $V0 changelog.changelog off
14f8ab
 sleep 3
14f8ab
 time_after_disable=$(date '+%s')
14f8ab
 
14f8ab
+TEST $CLI volume set $V0 changelog.changelog on
14f8ab
+sleep 5
14f8ab
+
14f8ab
 #Passes, gives the changelogs till continuous changelogs are available
14f8ab
 # but returns 1
14f8ab
-EXPECT "1" $HISTORY_BIN_PATH/get-history $time_after_enable1 $time_in_sec_htime2
14f8ab
+EXPECT_WITHIN 10 "1" $HISTORY_BIN_PATH/get-history $time_after_enable1 $time_in_sec_htime2
14f8ab
 
14f8ab
 #Fails as start falls between htime files
14f8ab
-EXPECT "-3" $HISTORY_BIN_PATH/get-history $time_between_htime $time_in_sec_htime1
14f8ab
+EXPECT_WITHIN 10 "-3" $HISTORY_BIN_PATH/get-history $time_between_htime $time_in_sec_htime1
14f8ab
 
14f8ab
 #Passes as start and end falls in same htime file
14f8ab
-EXPECT "0" $HISTORY_BIN_PATH/get-history $time_in_sec_htime1 $time_in_sec_htime2
14f8ab
+EXPECT_WITHIN 10 "0" $HISTORY_BIN_PATH/get-history $time_in_sec_htime1 $time_in_sec_htime2
14f8ab
 
14f8ab
 #Passes, gives the changelogs till continuous changelogs are available
14f8ab
-EXPECT "0" $HISTORY_BIN_PATH/get-history $time_in_sec_htime2 $time_after_disable
14f8ab
+EXPECT_WITHIN 10 "0" $HISTORY_BIN_PATH/get-history $time_in_sec_htime2 $time_after_disable
14f8ab
 
14f8ab
 TEST rm $HISTORY_BIN_PATH/get-history
14f8ab
 
14f8ab
diff --git a/tests/bugs/bitrot/bug-1227996.t b/tests/bugs/bitrot/bug-1227996.t
14f8ab
index 47ebc42..121c7b5 100644
14f8ab
--- a/tests/bugs/bitrot/bug-1227996.t
14f8ab
+++ b/tests/bugs/bitrot/bug-1227996.t
14f8ab
@@ -17,7 +17,6 @@ TEST pidof glusterd;
14f8ab
 ## Lets create and start the volume
14f8ab
 TEST $CLI volume create $V0 $H0:$B0/${V0}0 $H0:$B0/${V0}1
14f8ab
 TEST $CLI volume start $V0
14f8ab
-
14f8ab
 ## Enable bitrot on volume $V0
14f8ab
 TEST $CLI volume bitrot $V0 enable
14f8ab
 
14f8ab
diff --git a/tests/bugs/bitrot/bug-1245981.t b/tests/bugs/bitrot/bug-1245981.t
14f8ab
index 2bed4d9..f395525 100644
14f8ab
--- a/tests/bugs/bitrot/bug-1245981.t
14f8ab
+++ b/tests/bugs/bitrot/bug-1245981.t
14f8ab
@@ -47,9 +47,9 @@ touch $M0/5
14f8ab
 sleep `expr $SLEEP_TIME \* 2`
14f8ab
 
14f8ab
 backpath=$(get_backend_paths $fname)
14f8ab
-TEST getfattr -m . -n trusted.bit-rot.signature $backpath
14f8ab
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT 'trusted.bit-rot.signature' check_for_xattr 'trusted.bit-rot.signature' $backpath
14f8ab
 
14f8ab
 backpath=$(get_backend_paths $M0/new_file)
14f8ab
-TEST getfattr -m . -n trusted.bit-rot.signature $backpath
14f8ab
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT 'trusted.bit-rot.signature' check_for_xattr 'trusted.bit-rot.signature' $backpath
14f8ab
 
14f8ab
 cleanup;
14f8ab
diff --git a/xlators/features/changelog/src/changelog-helpers.h b/xlators/features/changelog/src/changelog-helpers.h
14f8ab
index 517c4dc..3afacc9 100644
14f8ab
--- a/xlators/features/changelog/src/changelog-helpers.h
14f8ab
+++ b/xlators/features/changelog/src/changelog-helpers.h
14f8ab
@@ -190,8 +190,12 @@ typedef struct changelog_ev_selector {
14f8ab
 
14f8ab
 /* changelog's private structure */
14f8ab
 struct changelog_priv {
14f8ab
+    /* changelog journalling */
14f8ab
     gf_boolean_t active;
14f8ab
 
14f8ab
+    /* changelog live notifications */
14f8ab
+    gf_boolean_t rpc_active;
14f8ab
+
14f8ab
     /* to generate unique socket file per brick */
14f8ab
     char *changelog_brick;
14f8ab
 
14f8ab
diff --git a/xlators/features/changelog/src/changelog-rpc-common.c b/xlators/features/changelog/src/changelog-rpc-common.c
14f8ab
index dcdcfb1..f2d1853 100644
14f8ab
--- a/xlators/features/changelog/src/changelog-rpc-common.c
14f8ab
+++ b/xlators/features/changelog/src/changelog-rpc-common.c
14f8ab
@@ -263,6 +263,9 @@ changelog_rpc_server_destroy(xlator_t *this, rpcsvc_t *rpc, char *sockfile,
14f8ab
     struct rpcsvc_program *prog = NULL;
14f8ab
     rpc_transport_t *trans = NULL;
14f8ab
 
14f8ab
+    if (!rpc)
14f8ab
+        return;
14f8ab
+
14f8ab
     while (*progs) {
14f8ab
         prog = *progs;
14f8ab
         (void)rpcsvc_program_unregister(rpc, prog);
14f8ab
diff --git a/xlators/features/changelog/src/changelog.c b/xlators/features/changelog/src/changelog.c
14f8ab
index d9025f3..ff06c09 100644
14f8ab
--- a/xlators/features/changelog/src/changelog.c
14f8ab
+++ b/xlators/features/changelog/src/changelog.c
14f8ab
@@ -34,6 +34,12 @@ static struct changelog_bootstrap cb_bootstrap[] = {
14f8ab
     },
14f8ab
 };
14f8ab
 
14f8ab
+static int
14f8ab
+changelog_init_rpc(xlator_t *this, changelog_priv_t *priv);
14f8ab
+
14f8ab
+static int
14f8ab
+changelog_init(xlator_t *this, changelog_priv_t *priv);
14f8ab
+
14f8ab
 /* Entry operations - TYPE III */
14f8ab
 
14f8ab
 /**
14f8ab
@@ -2008,6 +2014,11 @@ notify(xlator_t *this, int event, void *data, ...)
14f8ab
     uint64_t clntcnt = 0;
14f8ab
     changelog_clnt_t *conn = NULL;
14f8ab
     gf_boolean_t cleanup_notify = _gf_false;
14f8ab
+    char sockfile[UNIX_PATH_MAX] = {
14f8ab
+        0,
14f8ab
+    };
14f8ab
+    rpcsvc_listener_t *listener = NULL;
14f8ab
+    rpcsvc_listener_t *next = NULL;
14f8ab
 
14f8ab
     INIT_LIST_HEAD(&queue);
14f8ab
 
14f8ab
@@ -2021,23 +2032,40 @@ notify(xlator_t *this, int event, void *data, ...)
14f8ab
                "cleanup changelog rpc connection of brick %s",
14f8ab
                priv->victim->name);
14f8ab
 
14f8ab
-        this->cleanup_starting = 1;
14f8ab
-        changelog_destroy_rpc_listner(this, priv);
14f8ab
-        conn = &priv->connections;
14f8ab
-        if (conn)
14f8ab
-            changelog_ev_cleanup_connections(this, conn);
14f8ab
-        xprtcnt = GF_ATOMIC_GET(priv->xprtcnt);
14f8ab
-        clntcnt = GF_ATOMIC_GET(priv->clntcnt);
14f8ab
-
14f8ab
-        if (!xprtcnt && !clntcnt) {
14f8ab
-            LOCK(&priv->lock);
14f8ab
-            {
14f8ab
-                cleanup_notify = priv->notify_down;
14f8ab
-                priv->notify_down = _gf_true;
14f8ab
+        if (priv->rpc_active) {
14f8ab
+            this->cleanup_starting = 1;
14f8ab
+            changelog_destroy_rpc_listner(this, priv);
14f8ab
+            conn = &priv->connections;
14f8ab
+            if (conn)
14f8ab
+                changelog_ev_cleanup_connections(this, conn);
14f8ab
+            xprtcnt = GF_ATOMIC_GET(priv->xprtcnt);
14f8ab
+            clntcnt = GF_ATOMIC_GET(priv->clntcnt);
14f8ab
+            if (!xprtcnt && !clntcnt) {
14f8ab
+                LOCK(&priv->lock);
14f8ab
+                {
14f8ab
+                    cleanup_notify = priv->notify_down;
14f8ab
+                    priv->notify_down = _gf_true;
14f8ab
+                }
14f8ab
+                UNLOCK(&priv->lock);
14f8ab
+                list_for_each_entry_safe(listener, next, &priv->rpc->listeners,
14f8ab
+                                         list)
14f8ab
+                {
14f8ab
+                    if (listener->trans) {
14f8ab
+                        rpc_transport_unref(listener->trans);
14f8ab
+                    }
14f8ab
+                }
14f8ab
+                CHANGELOG_MAKE_SOCKET_PATH(priv->changelog_brick, sockfile,
14f8ab
+                                           UNIX_PATH_MAX);
14f8ab
+                sys_unlink(sockfile);
14f8ab
+                if (priv->rpc) {
14f8ab
+                    rpcsvc_destroy(priv->rpc);
14f8ab
+                    priv->rpc = NULL;
14f8ab
+                }
14f8ab
+                if (!cleanup_notify)
14f8ab
+                    default_notify(this, GF_EVENT_PARENT_DOWN, data);
14f8ab
             }
14f8ab
-            UNLOCK(&priv->lock);
14f8ab
-            if (!cleanup_notify)
14f8ab
-                default_notify(this, GF_EVENT_PARENT_DOWN, data);
14f8ab
+        } else {
14f8ab
+            default_notify(this, GF_EVENT_PARENT_DOWN, data);
14f8ab
         }
14f8ab
         goto out;
14f8ab
     }
14f8ab
@@ -2425,6 +2453,22 @@ changelog_barrier_pthread_destroy(changelog_priv_t *priv)
14f8ab
     LOCK_DESTROY(&priv->bflags.lock);
14f8ab
 }
14f8ab
 
14f8ab
+static void
14f8ab
+changelog_cleanup_rpc(xlator_t *this, changelog_priv_t *priv)
14f8ab
+{
14f8ab
+    /* terminate rpc server */
14f8ab
+    if (!this->cleanup_starting)
14f8ab
+        changelog_destroy_rpc_listner(this, priv);
14f8ab
+
14f8ab
+    (void)changelog_cleanup_rpc_threads(this, priv);
14f8ab
+    /* cleanup rot buffs */
14f8ab
+    rbuf_dtor(priv->rbuf);
14f8ab
+
14f8ab
+    /* cleanup poller thread */
14f8ab
+    if (priv->poller)
14f8ab
+        (void)changelog_thread_cleanup(this, priv->poller);
14f8ab
+}
14f8ab
+
14f8ab
 int
14f8ab
 reconfigure(xlator_t *this, dict_t *options)
14f8ab
 {
14f8ab
@@ -2433,6 +2477,9 @@ reconfigure(xlator_t *this, dict_t *options)
14f8ab
     changelog_priv_t *priv = NULL;
14f8ab
     gf_boolean_t active_earlier = _gf_true;
14f8ab
     gf_boolean_t active_now = _gf_true;
14f8ab
+    gf_boolean_t rpc_active_earlier = _gf_true;
14f8ab
+    gf_boolean_t rpc_active_now = _gf_true;
14f8ab
+    gf_boolean_t iniate_rpc = _gf_false;
14f8ab
     changelog_time_slice_t *slice = NULL;
14f8ab
     changelog_log_data_t cld = {
14f8ab
         0,
14f8ab
@@ -2454,6 +2501,7 @@ reconfigure(xlator_t *this, dict_t *options)
14f8ab
 
14f8ab
     ret = -1;
14f8ab
     active_earlier = priv->active;
14f8ab
+    rpc_active_earlier = priv->rpc_active;
14f8ab
 
14f8ab
     /* first stop the rollover and the fsync thread */
14f8ab
     changelog_cleanup_helper_threads(this, priv);
14f8ab
@@ -2487,6 +2535,29 @@ reconfigure(xlator_t *this, dict_t *options)
14f8ab
         goto out;
14f8ab
 
14f8ab
     GF_OPTION_RECONF("changelog", active_now, options, bool, out);
14f8ab
+    GF_OPTION_RECONF("changelog-notification", rpc_active_now, options, bool,
14f8ab
+                     out);
14f8ab
+
14f8ab
+    /* If journalling is enabled, enable rpc notifications */
14f8ab
+    if (active_now && !active_earlier) {
14f8ab
+        if (!rpc_active_earlier)
14f8ab
+            iniate_rpc = _gf_true;
14f8ab
+    }
14f8ab
+
14f8ab
+    if (rpc_active_now && !rpc_active_earlier) {
14f8ab
+        iniate_rpc = _gf_true;
14f8ab
+    }
14f8ab
+
14f8ab
+    /* TODO: Disable of changelog-notifications is not supported for now
14f8ab
+     * as there is no clean way of cleaning up of rpc resources
14f8ab
+     */
14f8ab
+
14f8ab
+    if (iniate_rpc) {
14f8ab
+        ret = changelog_init_rpc(this, priv);
14f8ab
+        if (ret)
14f8ab
+            goto out;
14f8ab
+        priv->rpc_active = _gf_true;
14f8ab
+    }
14f8ab
 
14f8ab
     /**
14f8ab
      * changelog_handle_change() handles changes that could possibly
14f8ab
@@ -2618,6 +2689,7 @@ changelog_init_options(xlator_t *this, changelog_priv_t *priv)
14f8ab
         goto dealloc_2;
14f8ab
 
14f8ab
     GF_OPTION_INIT("changelog", priv->active, bool, dealloc_2);
14f8ab
+    GF_OPTION_INIT("changelog-notification", priv->rpc_active, bool, dealloc_2);
14f8ab
     GF_OPTION_INIT("capture-del-path", priv->capture_del_path, bool, dealloc_2);
14f8ab
 
14f8ab
     GF_OPTION_INIT("op-mode", tmp, str, dealloc_2);
14f8ab
@@ -2656,22 +2728,6 @@ error_return:
14f8ab
     return -1;
14f8ab
 }
14f8ab
 
14f8ab
-static void
14f8ab
-changelog_cleanup_rpc(xlator_t *this, changelog_priv_t *priv)
14f8ab
-{
14f8ab
-    /* terminate rpc server */
14f8ab
-    if (!this->cleanup_starting)
14f8ab
-        changelog_destroy_rpc_listner(this, priv);
14f8ab
-
14f8ab
-    (void)changelog_cleanup_rpc_threads(this, priv);
14f8ab
-    /* cleanup rot buffs */
14f8ab
-    rbuf_dtor(priv->rbuf);
14f8ab
-
14f8ab
-    /* cleanup poller thread */
14f8ab
-    if (priv->poller)
14f8ab
-        (void)changelog_thread_cleanup(this, priv->poller);
14f8ab
-}
14f8ab
-
14f8ab
 static int
14f8ab
 changelog_init_rpc(xlator_t *this, changelog_priv_t *priv)
14f8ab
 {
14f8ab
@@ -2768,10 +2824,13 @@ init(xlator_t *this)
14f8ab
     INIT_LIST_HEAD(&priv->queue);
14f8ab
     priv->barrier_enabled = _gf_false;
14f8ab
 
14f8ab
-    /* RPC ball rolling.. */
14f8ab
-    ret = changelog_init_rpc(this, priv);
14f8ab
-    if (ret)
14f8ab
-        goto cleanup_barrier;
14f8ab
+    if (priv->rpc_active || priv->active) {
14f8ab
+        /* RPC ball rolling.. */
14f8ab
+        ret = changelog_init_rpc(this, priv);
14f8ab
+        if (ret)
14f8ab
+            goto cleanup_barrier;
14f8ab
+        priv->rpc_active = _gf_true;
14f8ab
+    }
14f8ab
 
14f8ab
     ret = changelog_init(this, priv);
14f8ab
     if (ret)
14f8ab
@@ -2783,7 +2842,9 @@ init(xlator_t *this)
14f8ab
     return 0;
14f8ab
 
14f8ab
 cleanup_rpc:
14f8ab
-    changelog_cleanup_rpc(this, priv);
14f8ab
+    if (priv->rpc_active) {
14f8ab
+        changelog_cleanup_rpc(this, priv);
14f8ab
+    }
14f8ab
 cleanup_barrier:
14f8ab
     changelog_barrier_pthread_destroy(priv);
14f8ab
 cleanup_options:
14f8ab
@@ -2808,9 +2869,10 @@ fini(xlator_t *this)
14f8ab
     priv = this->private;
14f8ab
 
14f8ab
     if (priv) {
14f8ab
-        /* terminate RPC server/threads */
14f8ab
-        changelog_cleanup_rpc(this, priv);
14f8ab
-
14f8ab
+        if (priv->active || priv->rpc_active) {
14f8ab
+            /* terminate RPC server/threads */
14f8ab
+            changelog_cleanup_rpc(this, priv);
14f8ab
+        }
14f8ab
         /* call barrier_disable to cancel timer */
14f8ab
         if (priv->barrier_enabled)
14f8ab
             __chlog_barrier_disable(this, &queue);
14f8ab
@@ -2879,6 +2941,13 @@ struct volume_options options[] = {
14f8ab
      .flags = OPT_FLAG_SETTABLE,
14f8ab
      .level = OPT_STATUS_BASIC,
14f8ab
      .tags = {"journal", "georep", "glusterfind"}},
14f8ab
+    {.key = {"changelog-notification"},
14f8ab
+     .type = GF_OPTION_TYPE_BOOL,
14f8ab
+     .default_value = "off",
14f8ab
+     .description = "enable/disable changelog live notification",
14f8ab
+     .op_version = {3},
14f8ab
+     .level = OPT_STATUS_BASIC,
14f8ab
+     .tags = {"bitrot", "georep"}},
14f8ab
     {.key = {"changelog-brick"},
14f8ab
      .type = GF_OPTION_TYPE_PATH,
14f8ab
      .description = "brick path to generate unique socket file name."
14f8ab
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c
14f8ab
index 16346e7..13f84ea 100644
14f8ab
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.c
14f8ab
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c
14f8ab
@@ -1876,6 +1876,19 @@ brick_graph_add_changelog(volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
14f8ab
     ret = xlator_set_fixed_option(xl, "changelog-dir", changelog_basepath);
14f8ab
     if (ret)
14f8ab
         goto out;
14f8ab
+
14f8ab
+    ret = glusterd_is_bitrot_enabled(volinfo);
14f8ab
+    if (ret == -1) {
14f8ab
+        goto out;
14f8ab
+    } else if (ret) {
14f8ab
+        ret = xlator_set_fixed_option(xl, "changelog-notification", "on");
14f8ab
+        if (ret)
14f8ab
+            goto out;
14f8ab
+    } else {
14f8ab
+        ret = xlator_set_fixed_option(xl, "changelog-notification", "off");
14f8ab
+        if (ret)
14f8ab
+            goto out;
14f8ab
+    }
14f8ab
 out:
14f8ab
     return ret;
14f8ab
 }
14f8ab
-- 
14f8ab
1.8.3.1
14f8ab