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