Blob Blame History Raw
From 0a96e3d6d8dfbc81b63609c8c85e01abb6157bbb Mon Sep 17 00:00:00 2001
From: anand <anekkunt@redhat.com>
Date: Wed, 20 May 2015 19:52:11 +0530
Subject: [PATCH 268/279] glusterd: Stop/restart/notify to daemons(svcs) during reset/set on a volume

problem : Reset/set commands were not working properly. reset command returns
success but it not sending notification to svcs if corresponding graph modified.

Fix: Whenever reset/set command issued, generate the temp graph and compare
with original graph and do the fallowing actions
1.) If both graph are identical nothing to do with svcs.
2.) If any changes in graph topology restart/stop service by calling
svc manager.
3)  If changes in options send notify signal by calling glusterd_fetchspec_notify.

>Change-Id: I852c4602eafed1ae6e6a02424814fe3a83e3d4c7
>BUG: 1209329
>Signed-off-by: anand <anekkunt@redhat.com>
>Reviewed-on: http://review.gluster.org/10850
>Tested-by: NetBSD Build System <jenkins@build.gluster.org>
>Tested-by: Gluster Build System <jenkins@build.gluster.com>
>Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
>Signed-off-by: anand <anekkunt@redhat.com>

Change-Id: I306922d9fac8820e0f6159742c871d53dbd7b25f
BUG: 1230532
Signed-off-by: anand <anekkunt@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/55146
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
Tested-by: Atin Mukherjee <amukherj@redhat.com>
---
 .../bug-1209329_daemon-svcs-on-reset-volume.t      |   69 +++++++++++
 tests/volume.rc                                    |    8 ++
 xlators/mgmt/glusterd/src/glusterd-bitd-svc.c      |   64 ++++++++++-
 xlators/mgmt/glusterd/src/glusterd-brick-ops.c     |    2 +-
 xlators/mgmt/glusterd/src/glusterd-handshake.c     |   11 +--
 xlators/mgmt/glusterd/src/glusterd-nfs-svc.c       |  116 ++----------------
 xlators/mgmt/glusterd/src/glusterd-op-sm.c         |   15 ++-
 xlators/mgmt/glusterd/src/glusterd-quotad-svc.c    |   82 ++++++++++---
 xlators/mgmt/glusterd/src/glusterd-quotad-svc.h    |    3 -
 xlators/mgmt/glusterd/src/glusterd-scrub-svc.c     |   69 ++++++++++-
 xlators/mgmt/glusterd/src/glusterd-shd-svc.c       |   66 ++++++++++-
 xlators/mgmt/glusterd/src/glusterd-svc-helper.c    |  129 +++++++++++++++++---
 xlators/mgmt/glusterd/src/glusterd-svc-helper.h    |   13 ++-
 xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c      |    6 +-
 xlators/mgmt/glusterd/src/glusterd-volgen.c        |    3 +-
 xlators/mgmt/glusterd/src/glusterd-volgen.h        |   12 +--
 16 files changed, 497 insertions(+), 171 deletions(-)
 create mode 100644 tests/bugs/glusterd/bug-1209329_daemon-svcs-on-reset-volume.t

diff --git a/tests/bugs/glusterd/bug-1209329_daemon-svcs-on-reset-volume.t b/tests/bugs/glusterd/bug-1209329_daemon-svcs-on-reset-volume.t
new file mode 100644
index 0000000..aa24cf1
--- /dev/null
+++ b/tests/bugs/glusterd/bug-1209329_daemon-svcs-on-reset-volume.t
@@ -0,0 +1,69 @@
+#!/bin/bash
+
+. $(dirname $0)/../../include.rc
+. $(dirname $0)/../../volume.rc
+. $(dirname $0)/../../nfs.rc
+
+cleanup;
+
+## Start glusterd
+TEST glusterd;
+TEST pidof glusterd;
+
+## Lets create volume
+TEST $CLI volume create $V0 $H0:$B0/${V0};
+
+## Verify volume is created
+EXPECT "$V0" volinfo_field $V0 'Volume Name';
+EXPECT 'Created' volinfo_field $V0 'Status';
+
+## Start volume and verify
+TEST $CLI volume start $V0;
+EXPECT 'Started' volinfo_field $V0 'Status';
+
+##enable the bitrot and verify bitd is running or not
+TEST $CLI volume bitrot $V0 enable
+EXPECT 'on' volinfo_field $V0 'features.bitrot'
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" get_bitd_count
+
+##Do reset force which set the bitrot options to default
+TEST $CLI volume reset $V0 force;
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "0" get_bitd_count
+
+##enable the uss option and verify snapd is running or not
+TEST $CLI volume set $V0 features.uss on
+EXPECT 'on' volinfo_field $V0 'features.uss'
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" get_snapd_count
+
+##Do reset force which set the uss options to default
+TEST $CLI volume reset $V0 force;
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "0" get_snapd_count
+
+#enable nfs.disable options and verify
+TEST $CLI volume set $V0 nfs.disable on
+EXPECT 'on' volinfo_field $V0 'nfs.disable'
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "0" get_nfs_count
+
+##Do reset force which set the nfs.option to default
+TEST $CLI volume reset $V0 force;
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" get_nfs_count
+
+##enable the uss option and verify snapd is running or not
+TEST $CLI volume set $V0 features.uss on
+EXPECT 'on' volinfo_field $V0 'features.uss'
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" get_snapd_count
+
+##Disable the uss option using set command and verify snapd
+TEST $CLI volume set $V0 features.uss  off
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "0" get_snapd_count
+
+##enable nfs.disable and verify
+TEST $CLI volume set $V0 nfs.disable on
+EXPECT 'on' volinfo_field $V0 'nfs.disable'
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "0" get_nfs_count
+
+## disable nfs.disable option using set command
+TEST $CLI volume set $V0 nfs.disable  off
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" get_nfs_count
+
+cleanup;
diff --git a/tests/volume.rc b/tests/volume.rc
index 570d87d..aeffa4a 100644
--- a/tests/volume.rc
+++ b/tests/volume.rc
@@ -565,3 +565,11 @@ function quota_usage()
 {
         quota_list_field $1 4
 }
+
+function get_nfs_count {
+        ps auxww | grep glusterfs | grep nfs.pid | grep -v grep | wc -l
+}
+
+function get_snapd_count {
+        ps auxww | grep glusterfs | grep snapd.pid | grep -v grep | wc -l
+}
diff --git a/xlators/mgmt/glusterd/src/glusterd-bitd-svc.c b/xlators/mgmt/glusterd/src/glusterd-bitd-svc.c
index 6b606f8..ee96ccb 100644
--- a/xlators/mgmt/glusterd/src/glusterd-bitd-svc.c
+++ b/xlators/mgmt/glusterd/src/glusterd-bitd-svc.c
@@ -14,6 +14,7 @@
 #include "glusterd-utils.h"
 #include "glusterd-volgen.h"
 #include "glusterd-bitd-svc.h"
+#include "glusterd-svc-helper.h"
 
 void
 glusterd_bitdsvc_build (glusterd_svc_t *svc)
@@ -141,5 +142,66 @@ glusterd_bitdsvc_stop (glusterd_svc_t *svc, int sig)
 int
 glusterd_bitdsvc_reconfigure ()
 {
-        return glusterd_svc_reconfigure (glusterd_bitdsvc_create_volfile);
+        int              ret             = -1;
+        xlator_t        *this            = NULL;
+        glusterd_conf_t *priv            = NULL;
+        gf_boolean_t     identical       = _gf_false;
+
+        this = THIS;
+        GF_VALIDATE_OR_GOTO (this->name, this, out);
+
+        priv = this->private;
+        GF_VALIDATE_OR_GOTO (this->name, priv, out);
+
+        if (glusterd_should_i_stop_bitd ())
+                goto manager;
+        /*
+         * Check both OLD and NEW volfiles, if they are SAME by size
+         * and cksum i.e. "character-by-character". If YES, then
+         * NOTHING has been changed, just return.
+         */
+        ret = glusterd_svc_check_volfile_identical (priv->bitd_svc.name,
+                                                    build_bitd_graph,
+                                                    &identical);
+        if (ret)
+                goto out;
+        if (identical) {
+                ret = 0;
+                goto out;
+        }
+
+        /*
+         * They are not identical. Find out if the topology is changed
+         * OR just the volume options. If just the options which got
+         * changed, then inform the xlator to reconfigure the options.
+         */
+        identical = _gf_false; /* RESET the FLAG */
+        ret = glusterd_svc_check_topology_identical (priv->bitd_svc.name,
+                                                     build_bitd_graph,
+                                                     &identical);
+        if (ret)
+                goto out; /*not able to compare due to some corruption */
+
+        /* Topology is not changed, but just the options. But write the
+         * options to bitd volfile, so that bitd will be reconfigured.
+         */
+        if (identical) {
+                ret = glusterd_bitdsvc_create_volfile ();
+                if (ret == 0) {/* Only if above PASSES */
+                        ret = glusterd_fetchspec_notify (THIS);
+                }
+                goto out;
+        }
+
+manager:
+        /*
+         * bitd volfile's topology has been changed. bitd server needs
+         * to be RESTARTED to ACT on the changed volfile.
+         */
+        ret = priv->bitd_svc.manager (&(priv->bitd_svc), NULL,
+                                     PROC_START_NO_WAIT);
+
+out:
+        gf_msg_debug (this->name, 0, "Returning %d", ret);
+        return ret;
 }
diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
index 41080ec..caf51a4 100644
--- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
@@ -2411,7 +2411,7 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr)
 
         if (start_remove &&
             volinfo->status == GLUSTERD_STATUS_STARTED) {
-                ret = glusterd_svcs_reconfigure (volinfo);
+                ret = glusterd_svcs_reconfigure ();
                 if (ret) {
                         gf_msg (this->name, GF_LOG_WARNING, 0,
                                 GD_MSG_NFS_RECONF_FAIL,
diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c
index 5267874..fac2747 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handshake.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c
@@ -216,14 +216,9 @@ build_volfile_path (char *volume_id, char *path,
                 }
                 volid_ptr++;
 
-                if (strcmp (volid_ptr, "quotad") == 0)
-                        glusterd_quotadsvc_build_volfile_path (volid_ptr,
-                                                               priv->workdir,
-                                                               path, path_len);
-                else
-                        glusterd_svc_build_volfile_path (volid_ptr,
-                                                         priv->workdir,
-                                                         path, path_len);
+                glusterd_svc_build_volfile_path (volid_ptr,
+                                                 priv->workdir,
+                                                 path, path_len);
                 ret = 0;
                 goto out;
 
diff --git a/xlators/mgmt/glusterd/src/glusterd-nfs-svc.c b/xlators/mgmt/glusterd/src/glusterd-nfs-svc.c
index b1d9814..ea24c1e 100644
--- a/xlators/mgmt/glusterd/src/glusterd-nfs-svc.c
+++ b/xlators/mgmt/glusterd/src/glusterd-nfs-svc.c
@@ -15,6 +15,7 @@
 #include "glusterd-volgen.h"
 #include "glusterd-nfs-svc.h"
 #include "glusterd-messages.h"
+#include "glusterd-svc-helper.h"
 
 char *nfs_svc_name = "nfs";
 
@@ -66,107 +67,6 @@ glusterd_nfssvc_create_volfile ()
                                                filepath, NULL);
 }
 
-static int
-glusterd_nfssvc_check_volfile_identical (gf_boolean_t *identical)
-{
-        char            nfsvol[PATH_MAX]        = {0,};
-        char            tmpnfsvol[PATH_MAX]     = {0,};
-        glusterd_conf_t *conf                   = NULL;
-        xlator_t        *this                   = NULL;
-        int             ret                     = -1;
-        int             need_unlink             = 0;
-        int             tmp_fd                  = -1;
-
-        this = THIS;
-
-        GF_ASSERT (this);
-        GF_ASSERT (identical);
-        conf = this->private;
-
-        glusterd_svc_build_volfile_path (nfs_svc_name, conf->workdir,
-                                         nfsvol, sizeof (nfsvol));
-
-        snprintf (tmpnfsvol, sizeof (tmpnfsvol), "/tmp/gnfs-XXXXXX");
-
-        tmp_fd = mkstemp (tmpnfsvol);
-        if (tmp_fd < 0) {
-                gf_msg (this->name, GF_LOG_WARNING, errno,
-                        GD_MSG_FILE_OP_FAILED, "Unable to create temp file"
-                        " %s:(%s)", tmpnfsvol, strerror (errno));
-                goto out;
-        }
-
-        need_unlink = 1;
-
-        ret = glusterd_create_global_volfile (build_nfs_graph,
-                                              tmpnfsvol, NULL);
-        if (ret)
-                goto out;
-
-        ret = glusterd_check_files_identical (nfsvol, tmpnfsvol,
-                                              identical);
-        if (ret)
-                goto out;
-
-out:
-        if (need_unlink)
-                unlink (tmpnfsvol);
-
-        if (tmp_fd >= 0)
-                close (tmp_fd);
-
-        return ret;
-}
-
-static int
-glusterd_nfssvc_check_topology_identical (gf_boolean_t *identical)
-{
-        char            nfsvol[PATH_MAX]        = {0,};
-        char            tmpnfsvol[PATH_MAX]     = {0,};
-        glusterd_conf_t *conf                   = NULL;
-        xlator_t        *this                   = THIS;
-        int             ret                     = -1;
-        int             tmpclean                = 0;
-        int             tmpfd                   = -1;
-
-        if ((!identical) || (!this) || (!this->private))
-                goto out;
-
-        conf = (glusterd_conf_t *) this->private;
-        GF_ASSERT (conf);
-
-        /* Fetch the original NFS volfile */
-        glusterd_svc_build_volfile_path (conf->nfs_svc.name, conf->workdir,
-                                         nfsvol, sizeof (nfsvol));
-
-        /* Create the temporary NFS volfile */
-        snprintf (tmpnfsvol, sizeof (tmpnfsvol), "/tmp/gnfs-XXXXXX");
-        tmpfd = mkstemp (tmpnfsvol);
-        if (tmpfd < 0) {
-                gf_msg (this->name, GF_LOG_WARNING, errno,
-                        GD_MSG_FILE_OP_FAILED, "Unable to create temp file"
-                        " %s: (%s)", tmpnfsvol, strerror (errno));
-                goto out;
-        }
-
-        tmpclean = 1; /* SET the flag to unlink() tmpfile */
-
-        ret = glusterd_create_global_volfile (build_nfs_graph,
-                                              tmpnfsvol, NULL);
-        if (ret)
-                goto out;
-
-        /* Compare the topology of volfiles */
-        ret = glusterd_check_topology_identical (nfsvol, tmpnfsvol,
-                                                 identical);
-out:
-        if (tmpfd >= 0)
-                close (tmpfd);
-        if (tmpclean)
-                unlink (tmpnfsvol);
-        return ret;
-}
-
 int
 glusterd_nfssvc_manager (glusterd_svc_t *svc, void *data, int flags)
 {
@@ -246,17 +146,18 @@ glusterd_nfssvc_reconfigure ()
         gf_boolean_t     identical       = _gf_false;
 
         this = THIS;
-        GF_ASSERT (this);
+        GF_VALIDATE_OR_GOTO (this->name, this, out);
 
         priv = this->private;
-        GF_ASSERT (priv);
-
+        GF_VALIDATE_OR_GOTO (this->name, priv, out);
         /*
          * Check both OLD and NEW volfiles, if they are SAME by size
          * and cksum i.e. "character-by-character". If YES, then
          * NOTHING has been changed, just return.
          */
-        ret = glusterd_nfssvc_check_volfile_identical (&identical);
+        ret = glusterd_svc_check_volfile_identical (priv->nfs_svc.name,
+                                                    build_nfs_graph,
+                                                    &identical);
         if (ret)
                 goto out;
 
@@ -271,7 +172,9 @@ glusterd_nfssvc_reconfigure ()
          * changed, then inform the xlator to reconfigure the options.
          */
         identical = _gf_false; /* RESET the FLAG */
-        ret = glusterd_nfssvc_check_topology_identical (&identical);
+        ret = glusterd_svc_check_topology_identical (priv->nfs_svc.name,
+                                                     build_nfs_graph,
+                                                     &identical);
         if (ret)
                 goto out;
 
@@ -294,6 +197,7 @@ glusterd_nfssvc_reconfigure ()
                                      PROC_START_NO_WAIT);
 
 out:
+        gf_msg_debug (this->name, 0, "Returning %d", ret);
         return ret;
 
 }
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index 5e916eb..e7ad7f4 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -1785,6 +1785,7 @@ glusterd_options_reset (glusterd_volinfo_t *volinfo, char *key,
         data_t                  *value = NULL;
         char                    *key_fixed = NULL;
         xlator_t                *this = NULL;
+        glusterd_svc_t          *svc  = NULL;
 
         this = THIS;
         GF_ASSERT (this);
@@ -1820,6 +1821,12 @@ glusterd_options_reset (glusterd_volinfo_t *volinfo, char *key,
         }
 
         gd_update_volume_op_versions (volinfo);
+        if (!volinfo->is_snap_volume) {
+                svc = &(volinfo->snapd.svc);
+                ret = svc->manager (svc, volinfo, PROC_START_NO_WAIT);
+                if (ret)
+                        goto out;
+        }
 
         ret = glusterd_create_volfiles_and_notify_services (volinfo);
         if (ret) {
@@ -1836,7 +1843,7 @@ glusterd_options_reset (glusterd_volinfo_t *volinfo, char *key,
                 goto out;
 
         if (GLUSTERD_STATUS_STARTED == volinfo->status) {
-                ret = glusterd_svcs_reconfigure (volinfo);
+                ret = glusterd_svcs_reconfigure ();
                 if (ret)
                         goto out;
         }
@@ -2519,7 +2526,7 @@ glusterd_op_set_volume (dict_t *dict, char **errstr)
                         goto out;
 
                 if (GLUSTERD_STATUS_STARTED == volinfo->status) {
-                        ret = glusterd_svcs_reconfigure (volinfo);
+                        ret = glusterd_svcs_reconfigure ();
                         if (ret) {
                                 gf_msg (this->name, GF_LOG_ERROR, 0,
                                         GD_MSG_SVC_RESTART_FAIL,
@@ -2557,7 +2564,7 @@ glusterd_op_set_volume (dict_t *dict, char **errstr)
                                 goto out;
 
                         if (GLUSTERD_STATUS_STARTED == volinfo->status) {
-                                ret = glusterd_svcs_reconfigure (volinfo);
+                                ret = glusterd_svcs_reconfigure ();
                                 if (ret) {
                                         gf_msg (this->name, GF_LOG_WARNING, 0,
                                                 GD_MSG_NFS_SERVER_START_FAIL,
@@ -2773,7 +2780,7 @@ glusterd_op_stats_volume (dict_t *dict, char **op_errstr,
                 goto out;
 
         if (GLUSTERD_STATUS_STARTED == volinfo->status)
-                ret = glusterd_svcs_reconfigure (volinfo);
+                ret = glusterd_svcs_reconfigure ();
 
         ret = 0;
 
diff --git a/xlators/mgmt/glusterd/src/glusterd-quotad-svc.c b/xlators/mgmt/glusterd/src/glusterd-quotad-svc.c
index 59a7671..f3475a3 100644
--- a/xlators/mgmt/glusterd/src/glusterd-quotad-svc.c
+++ b/xlators/mgmt/glusterd/src/glusterd-quotad-svc.c
@@ -15,6 +15,7 @@
 #include "glusterd-volgen.h"
 #include "glusterd-quotad-svc.h"
 #include "glusterd-messages.h"
+#include "glusterd-svc-helper.h"
 
 char *quotad_svc_name = "quotad";
 
@@ -36,13 +37,6 @@ int glusterd_quotadsvc_init (glusterd_svc_t *svc)
         if (ret)
                 goto out;
 
-        /* glusterd_svc_build_volfile_path () doesn't put correct quotad volfile
-         * path in proc object at service initialization. Re-initialize
-         * the correct path
-         */
-        glusterd_quotadsvc_build_volfile_path (quotad_svc_name, conf->workdir,
-                                               volfile, sizeof (volfile));
-        snprintf (svc->proc.volfile, sizeof (svc->proc.volfile), "%s", volfile);
 out:
         return ret;
 }
@@ -53,8 +47,8 @@ glusterd_quotadsvc_create_volfile ()
         char             filepath[PATH_MAX] = {0,};
         glusterd_conf_t *conf               = THIS->private;
 
-        glusterd_quotadsvc_build_volfile_path (quotad_svc_name, conf->workdir,
-                                               filepath, sizeof (filepath));
+        glusterd_svc_build_volfile_path (quotad_svc_name, conf->workdir,
+                                         filepath, sizeof (filepath));
         return glusterd_create_global_volfile (build_quotad_graph,
                                                filepath, NULL);
 }
@@ -162,17 +156,67 @@ out:
 int
 glusterd_quotadsvc_reconfigure ()
 {
-        return glusterd_svc_reconfigure (glusterd_quotadsvc_create_volfile);
-}
+        int              ret             = -1;
+        xlator_t        *this            = NULL;
+        glusterd_conf_t *priv            = NULL;
+        gf_boolean_t     identical       = _gf_false;
 
-void
-glusterd_quotadsvc_build_volfile_path (char *server, char *workdir,
-                                       char *volfile, size_t len)
-{
-        char  dir[PATH_MAX] = {0,};
+        this = THIS;
+        GF_VALIDATE_OR_GOTO (this->name, this, out);
+
+        priv = this->private;
+        GF_VALIDATE_OR_GOTO (this->name, priv, out);
+
+        if (glusterd_all_volumes_with_quota_stopped ())
+                goto manager;
+
+        /*
+         * Check both OLD and NEW volfiles, if they are SAME by size
+         * and cksum i.e. "character-by-character". If YES, then
+         * NOTHING has been changed, just return.
+         */
+        ret = glusterd_svc_check_volfile_identical (priv->quotad_svc.name,
+                                                    build_quotad_graph,
+                                                    &identical);
+        if (ret)
+                goto out;
+
+        if (identical) {
+                ret = 0;
+                goto out;
+        }
+
+        /*
+         * They are not identical. Find out if the topology is changed
+         * OR just the volume options. If just the options which got
+         * changed, then inform the xlator to reconfigure the options.
+         */
+        identical = _gf_false; /* RESET the FLAG */
+        ret = glusterd_svc_check_topology_identical (priv->quotad_svc.name,
+                                                     build_quotad_graph,
+                                                     &identical);
+        if (ret)
+                goto out;
 
-        GF_ASSERT (len == PATH_MAX);
+        /* Topology is not changed, but just the options. But write the
+         * options to quotad volfile, so that quotad will be reconfigured.
+         */
+        if (identical) {
+                ret = glusterd_quotadsvc_create_volfile ();
+                if (ret == 0) {/* Only if above PASSES */
+                        ret = glusterd_fetchspec_notify (THIS);
+                }
+                goto out;
+        }
+manager:
+        /*
+         * quotad volfile's topology has been changed. quotad server needs
+         * to be RESTARTED to ACT on the changed volfile.
+         */
+        ret = priv->quotad_svc.manager (&(priv->quotad_svc), NULL,
+                                        PROC_START_NO_WAIT);
 
-        glusterd_svc_build_svcdir (server, workdir, dir, sizeof (dir));
-        snprintf (volfile, len, "%s/%s.vol", dir, server);
+out:
+        gf_msg_debug (this->name, 0, "Returning %d", ret);
+        return ret;
 }
diff --git a/xlators/mgmt/glusterd/src/glusterd-quotad-svc.h b/xlators/mgmt/glusterd/src/glusterd-quotad-svc.h
index c275aa4..5d35a00 100644
--- a/xlators/mgmt/glusterd/src/glusterd-quotad-svc.h
+++ b/xlators/mgmt/glusterd/src/glusterd-quotad-svc.h
@@ -33,7 +33,4 @@ glusterd_quotadsvc_manager (glusterd_svc_t *svc, void *data, int flags);
 int
 glusterd_quotadsvc_reconfigure ();
 
-void
-glusterd_quotadsvc_build_volfile_path (char *server, char *workdir,
-                                       char *volfile, size_t len);
 #endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-scrub-svc.c b/xlators/mgmt/glusterd/src/glusterd-scrub-svc.c
index b5c9785..3761dba 100644
--- a/xlators/mgmt/glusterd/src/glusterd-scrub-svc.c
+++ b/xlators/mgmt/glusterd/src/glusterd-scrub-svc.c
@@ -14,6 +14,7 @@
 #include "glusterd-utils.h"
 #include "glusterd-volgen.h"
 #include "glusterd-scrub-svc.h"
+#include "glusterd-svc-helper.h"
 
 char *scrub_svc_name = "scrub";
 
@@ -136,5 +137,71 @@ glusterd_scrubsvc_stop (glusterd_svc_t *svc, int sig)
 int
 glusterd_scrubsvc_reconfigure ()
 {
-        return glusterd_svc_reconfigure (glusterd_scrubsvc_create_volfile);
+        int              ret             = -1;
+        xlator_t        *this            = NULL;
+        glusterd_conf_t *priv            = NULL;
+        gf_boolean_t     identical       = _gf_false;
+
+        this = THIS;
+        GF_VALIDATE_OR_GOTO (this->name, this, out);
+
+        priv = this->private;
+        GF_VALIDATE_OR_GOTO (this->name, priv, out);
+
+        if (glusterd_should_i_stop_bitd ())
+                goto  manager;
+
+
+        /*
+         * Check both OLD and NEW volfiles, if they are SAME by size
+         * and cksum i.e. "character-by-character". If YES, then
+         * NOTHING has been changed, just return.
+         */
+        ret = glusterd_svc_check_volfile_identical (priv->scrub_svc.name,
+                                                    build_scrub_graph,
+                                                    &identical);
+        if (ret)
+                goto out;
+
+        if (identical) {
+                ret = 0;
+                goto out;
+        }
+
+        /*
+         * They are not identical. Find out if the topology is changed
+         * OR just the volume options. If just the options which got
+         * changed, then inform the xlator to reconfigure the options.
+         */
+        identical = _gf_false; /* RESET the FLAG */
+        ret = glusterd_svc_check_topology_identical (priv->scrub_svc.name,
+                                                     build_scrub_graph,
+                                                     &identical);
+        if (ret)
+                goto out;
+
+        /* Topology is not changed, but just the options. But write the
+         * options to scrub volfile, so that scrub will be reconfigured.
+         */
+        if (identical) {
+                ret = glusterd_scrubsvc_create_volfile ();
+                if (ret == 0) {/* Only if above PASSES */
+                        ret = glusterd_fetchspec_notify (THIS);
+                }
+                goto out;
+        }
+
+manager:
+        /*
+         * scrub volfile's topology has been changed. scrub server needs
+         * to be RESTARTED to ACT on the changed volfile.
+         */
+        ret = priv->scrub_svc.manager (&(priv->scrub_svc),
+                                       NULL,
+                                       PROC_START_NO_WAIT);
+
+out:
+        gf_msg_debug (this->name, 0, "Returning %d", ret);
+        return ret;
+
 }
diff --git a/xlators/mgmt/glusterd/src/glusterd-shd-svc.c b/xlators/mgmt/glusterd/src/glusterd-shd-svc.c
index f9f4189..0e664b5 100644
--- a/xlators/mgmt/glusterd/src/glusterd-shd-svc.c
+++ b/xlators/mgmt/glusterd/src/glusterd-shd-svc.c
@@ -15,6 +15,7 @@
 #include "glusterd-volgen.h"
 #include "glusterd-svc-mgmt.h"
 #include "glusterd-shd-svc.h"
+#include "glusterd-svc-helper.h"
 
 char *shd_svc_name = "glustershd";
 
@@ -182,5 +183,68 @@ out:
 int
 glusterd_shdsvc_reconfigure ()
 {
-        return glusterd_svc_reconfigure (glusterd_shdsvc_create_volfile);
+        int              ret             = -1;
+        xlator_t        *this            = NULL;
+        glusterd_conf_t *priv            = NULL;
+        gf_boolean_t     identical       = _gf_false;
+
+        this = THIS;
+        GF_VALIDATE_OR_GOTO (this->name, this, out);
+
+        priv = this->private;
+        GF_VALIDATE_OR_GOTO (this->name, priv, out);
+
+        if (glusterd_all_shd_compatible_volumes_stopped ())
+                goto manager;
+
+        /*
+         * Check both OLD and NEW volfiles, if they are SAME by size
+         * and cksum i.e. "character-by-character". If YES, then
+         * NOTHING has been changed, just return.
+         */
+        ret = glusterd_svc_check_volfile_identical (priv->shd_svc.name,
+                                                    build_shd_graph,
+                                                    &identical);
+        if (ret)
+                goto out;
+
+        if (identical) {
+                ret = 0;
+                goto out;
+        }
+
+        /*
+         * They are not identical. Find out if the topology is changed
+         * OR just the volume options. If just the options which got
+         * changed, then inform the xlator to reconfigure the options.
+         */
+        identical = _gf_false; /* RESET the FLAG */
+        ret = glusterd_svc_check_topology_identical (priv->shd_svc.name,
+                                                     build_shd_graph,
+                                                     &identical);
+        if (ret)
+                goto out;
+
+        /* Topology is not changed, but just the options. But write the
+         * options to shd volfile, so that shd will be reconfigured.
+         */
+        if (identical) {
+                ret = glusterd_shdsvc_create_volfile ();
+                if (ret == 0) {/* Only if above PASSES */
+                        ret = glusterd_fetchspec_notify (THIS);
+                }
+                goto out;
+        }
+manager:
+        /*
+         * shd volfile's topology has been changed. shd server needs
+         * to be RESTARTED to ACT on the changed volfile.
+         */
+        ret = priv->shd_svc.manager (&(priv->shd_svc), NULL,
+                                     PROC_START_NO_WAIT);
+
+out:
+        gf_msg_debug (this->name, 0, "Returning %d", ret);
+        return ret;
+
 }
diff --git a/xlators/mgmt/glusterd/src/glusterd-svc-helper.c b/xlators/mgmt/glusterd/src/glusterd-svc-helper.c
index c88b613..18136fb 100644
--- a/xlators/mgmt/glusterd/src/glusterd-svc-helper.c
+++ b/xlators/mgmt/glusterd/src/glusterd-svc-helper.c
@@ -19,9 +19,10 @@
 #include "glusterd-nfs-svc.h"
 #include "glusterd-bitd-svc.h"
 #include "glusterd-scrub-svc.h"
+#include "glusterd-svc-helper.h"
 
 int
-glusterd_svcs_reconfigure (glusterd_volinfo_t *volinfo)
+glusterd_svcs_reconfigure ()
 {
         int              ret  = 0;
         xlator_t        *this = THIS;
@@ -36,23 +37,17 @@ glusterd_svcs_reconfigure (glusterd_volinfo_t *volinfo)
         if (ret)
                 goto out;
 
-        if (volinfo && !glusterd_is_shd_compatible_volume (volinfo)) {
-                ; /* Do nothing */
-        } else {
-                ret = glusterd_shdsvc_reconfigure ();
-                if (ret)
-                        goto out;
-        }
+        ret = glusterd_shdsvc_reconfigure ();
+        if (ret)
+                goto out;
+
         if (conf->op_version == GD_OP_VERSION_MIN)
                 goto out;
 
-        if (volinfo && !glusterd_is_volume_quota_enabled (volinfo)) {
-               /*Do nothing */
-        } else {
-                ret = glusterd_quotadsvc_reconfigure ();
-                if (ret)
-                        goto out;
-        }
+        ret = glusterd_quotadsvc_reconfigure ();
+        if (ret)
+                goto out;
+
         ret = glusterd_bitdsvc_reconfigure ();
         if (ret)
                 goto out;
@@ -153,3 +148,107 @@ out:
 }
 
 
+int
+glusterd_svc_check_volfile_identical (char *svc_name,
+                                      glusterd_graph_builder_t builder,
+                                      gf_boolean_t *identical)
+{
+        char            orgvol[PATH_MAX]        = {0,};
+        char            tmpvol[PATH_MAX]        = {0,};
+        glusterd_conf_t *conf                   = NULL;
+        xlator_t        *this                   = NULL;
+        int             ret                     = -1;
+        int             need_unlink             = 0;
+        int             tmp_fd                  = -1;
+
+        this = THIS;
+
+        GF_ASSERT (this);
+        GF_ASSERT (identical);
+        conf = this->private;
+
+        glusterd_svc_build_volfile_path (svc_name, conf->workdir,
+                                         orgvol, sizeof (orgvol));
+
+        snprintf (tmpvol, sizeof (tmpvol), "/tmp/g%s-XXXXXX", svc_name);
+
+        tmp_fd = mkstemp (tmpvol);
+        if (tmp_fd < 0) {
+                gf_msg (this->name, GF_LOG_WARNING, errno,
+                        GD_MSG_FILE_OP_FAILED, "Unable to create temp file"
+                        " %s:(%s)", tmpvol, strerror (errno));
+                goto out;
+        }
+
+        need_unlink = 1;
+
+        ret = glusterd_create_global_volfile (builder,
+                                              tmpvol, NULL);
+        if (ret)
+                goto out;
+
+        ret = glusterd_check_files_identical (orgvol, tmpvol,
+                                              identical);
+        if (ret)
+                goto out;
+
+out:
+        if (need_unlink)
+                unlink (tmpvol);
+
+        if (tmp_fd >= 0)
+                close (tmp_fd);
+
+        return ret;
+}
+
+int
+glusterd_svc_check_topology_identical (char *svc_name,
+                                       glusterd_graph_builder_t builder,
+                                       gf_boolean_t *identical)
+{
+        char            orgvol[PATH_MAX]        = {0,};
+        char            tmpvol[PATH_MAX]        = {0,};
+        glusterd_conf_t *conf                   = NULL;
+        xlator_t        *this                   = THIS;
+        int             ret                     = -1;
+        int             tmpclean                = 0;
+        int             tmpfd                   = -1;
+
+        if ((!identical) || (!this) || (!this->private))
+                goto out;
+
+        conf = this->private;
+        GF_VALIDATE_OR_GOTO (this->name, conf, out);
+
+        /* Fetch the original volfile */
+        glusterd_svc_build_volfile_path (svc_name, conf->workdir,
+                                         orgvol, sizeof (orgvol));
+
+        /* Create the temporary volfile */
+        snprintf (tmpvol, sizeof (tmpvol), "/tmp/g%s-XXXXXX", svc_name);
+        tmpfd = mkstemp (tmpvol);
+        if (tmpfd < 0) {
+                gf_msg (this->name, GF_LOG_WARNING, errno,
+                        GD_MSG_FILE_OP_FAILED, "Unable to create temp file"
+                        " %s:(%s)", tmpvol, strerror (errno));
+                goto out;
+        }
+
+        tmpclean = 1; /* SET the flag to unlink() tmpfile */
+
+        ret = glusterd_create_global_volfile (builder,
+                                              tmpvol, NULL);
+        if (ret)
+                goto out;
+
+        /* Compare the topology of volfiles */
+        ret = glusterd_check_topology_identical (orgvol, tmpvol,
+                                                 identical);
+out:
+        if (tmpfd >= 0)
+                close (tmpfd);
+        if (tmpclean)
+                unlink (tmpvol);
+        return ret;
+}
diff --git a/xlators/mgmt/glusterd/src/glusterd-svc-helper.h b/xlators/mgmt/glusterd/src/glusterd-svc-helper.h
index 2af75bc..053f69a 100644
--- a/xlators/mgmt/glusterd/src/glusterd-svc-helper.h
+++ b/xlators/mgmt/glusterd/src/glusterd-svc-helper.h
@@ -18,13 +18,24 @@
 
 #include "glusterd.h"
 #include "glusterd-svc-mgmt.h"
+#include "glusterd-volgen.h"
 
 int
-glusterd_svcs_reconfigure (glusterd_volinfo_t *volinfo);
+glusterd_svcs_reconfigure ();
 
 int
 glusterd_svcs_stop ();
 
 int
 glusterd_svcs_manager (glusterd_volinfo_t *volinfo);
+
+int
+glusterd_svc_check_volfile_identical (char *svc_name,
+                                      glusterd_graph_builder_t builder,
+                                      gf_boolean_t *identical);
+int
+glusterd_svc_check_topology_identical (char *svc_name,
+                                       glusterd_graph_builder_t builder,
+                                       gf_boolean_t *identical);
+
 #endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c
index 130bc56..25314a1 100644
--- a/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c
+++ b/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c
@@ -250,7 +250,11 @@ glusterd_svc_build_volfile_path (char *server, char *workdir, char *volfile,
         GF_ASSERT (len == PATH_MAX);
 
         glusterd_svc_build_svcdir (server, workdir, dir, sizeof (dir));
-        snprintf (volfile, len, "%s/%s-server.vol", dir, server);
+
+        if (!strcmp(server, "quotad")) /*quotad has different volfile name*/
+                snprintf (volfile, len, "%s/%s.vol", dir, server);
+       else
+                snprintf (volfile, len, "%s/%s-server.vol", dir, server);
 }
 
 void
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c
index ee5cf68..836ec3e 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c
@@ -5416,8 +5416,7 @@ out:
 }
 
 int
-glusterd_create_global_volfile (int (*builder) (volgen_graph_t *graph,
-                                                dict_t *set_dict),
+glusterd_create_global_volfile (glusterd_graph_builder_t builder,
                                 char *filepath, dict_t  *mod_dict)
 {
         volgen_graph_t graph = {0,};
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.h b/xlators/mgmt/glusterd/src/glusterd-volgen.h
index cdeaea4..7453c0d 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.h
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.h
@@ -60,6 +60,9 @@ struct volgen_graph {
 };
 typedef struct volgen_graph volgen_graph_t;
 
+typedef int (*glusterd_graph_builder_t) (volgen_graph_t *graph,
+                                         dict_t *mod_dict);
+
 #define COMPLETE_OPTION(key, completion, ret)                           \
         do {                                                            \
                 if (!strchr (key, '.')) {                               \
@@ -158,8 +161,7 @@ glusterd_snapdsvc_generate_volfile (volgen_graph_t *graph,
                                     glusterd_volinfo_t *volinfo);
 
 int
-glusterd_create_global_volfile (int (*builder) (volgen_graph_t *graph,
-                                                dict_t *set_dict),
+glusterd_create_global_volfile (glusterd_graph_builder_t builder,
                                 char *filepath, dict_t  *mod_dict);
 
 int
@@ -262,12 +264,6 @@ end_sethelp_xml_doc (xmlTextWriterPtr writer);
 char*
 glusterd_get_trans_type_rb (gf_transport_type ttype);
 
-int
-glusterd_check_nfs_volfile_identical (gf_boolean_t *identical);
-
-int
-glusterd_check_nfs_topology_identical (gf_boolean_t *identical);
-
 uint32_t
 glusterd_get_op_version_for_key (char *key);
 
-- 
1.7.1