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