Blob Blame History Raw
From cae9e746422dc54126eca96c4bacf11f24921cf2 Mon Sep 17 00:00:00 2001
From: Atin Mukherjee <amukherj@redhat.com>
Date: Wed, 1 Jul 2015 14:47:48 +0530
Subject: [PATCH 267/275] glusterd: initialize the daemon services on demand

backport of http://review.gluster.org/#/c/11488/

As of now all the daemon services are initialized at glusterD init path. Since
socket file path of per node daemon demands the uuid of the node, MY_UUID macro
is invoked as part of the initialization.

The above flow breaks the usecases where a gluster image is built following a
template could be Dockerfile, Vagrantfile or any kind of virtualization
environment. This means bringing instances of this image would have same UUIDs
for the node resulting in peer probe failure.

Solution is to lazily initialize the services on demand.

Change-Id: If7caa533026c83e98c7c7678bded67085d0bbc1e
BUG: 1245536
Signed-off-by: Atin Mukherjee <amukherj@redhat.com>
Reviewed-on: http://review.gluster.org/11488
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Tested-by: NetBSD Build System <jenkins@build.gluster.org>
Reviewed-by: Gaurav Kumar Garg <ggarg@redhat.com>
Reviewed-by: Kaushal M <kaushal@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/55044
Reviewed-by: Krishnan Parthasarathi <kparthas@redhat.com>
Tested-by: Krishnan Parthasarathi <kparthas@redhat.com>
---
 doc/developer-guide/daemon-management-framework.md |    9 ++-
 ...-1238135-lazy-daemon-initialization-on-demand.t |   16 +++++
 xlators/mgmt/glusterd/src/glusterd-bitd-svc.c      |   27 +++++++-
 xlators/mgmt/glusterd/src/glusterd-bitd-svc.h      |    3 +
 xlators/mgmt/glusterd/src/glusterd-ganesha.c       |   19 ++++--
 xlators/mgmt/glusterd/src/glusterd-nfs-svc.c       |   26 +++++++-
 xlators/mgmt/glusterd/src/glusterd-nfs-svc.h       |    3 +
 xlators/mgmt/glusterd/src/glusterd-quotad-svc.c    |   27 +++++++-
 xlators/mgmt/glusterd/src/glusterd-quotad-svc.h    |    3 +
 xlators/mgmt/glusterd/src/glusterd-scrub-svc.c     |   27 +++++++-
 xlators/mgmt/glusterd/src/glusterd-scrub-svc.h     |    3 +
 xlators/mgmt/glusterd/src/glusterd-shd-svc.c       |   26 +++++++-
 xlators/mgmt/glusterd/src/glusterd-shd-svc.h       |    3 +
 xlators/mgmt/glusterd/src/glusterd-snapd-svc.c     |   26 +++++++-
 xlators/mgmt/glusterd/src/glusterd-snapd-svc.h     |    3 +
 xlators/mgmt/glusterd/src/glusterd-snapshot.c      |   10 ---
 xlators/mgmt/glusterd/src/glusterd-store.c         |    9 ---
 xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c      |   15 +----
 xlators/mgmt/glusterd/src/glusterd-svc-mgmt.h      |    9 ++-
 xlators/mgmt/glusterd/src/glusterd-utils.c         |   25 ++------
 xlators/mgmt/glusterd/src/glusterd-volume-ops.c    |    6 --
 xlators/mgmt/glusterd/src/glusterd.c               |   67 ++++----------------
 22 files changed, 212 insertions(+), 150 deletions(-)
 create mode 100644 tests/bugs/glusterd/bug-1238135-lazy-daemon-initialization-on-demand.t

diff --git a/tests/bugs/glusterd/bug-1238135-lazy-daemon-initialization-on-demand.t b/tests/bugs/glusterd/bug-1238135-lazy-daemon-initialization-on-demand.t
new file mode 100644
index 0000000..54c3187
--- /dev/null
+++ b/tests/bugs/glusterd/bug-1238135-lazy-daemon-initialization-on-demand.t
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+. $(dirname $0)/../../include.rc
+
+cleanup;
+
+TEST glusterd;
+TEST pidof glusterd;
+
+GDWD=$($CLI system getwd)
+
+# glusterd.info file will be created on either first peer probe or volume
+# creation, hence we expect file to be not present in this case
+TEST ! -e $GDWD/glusterd.info
+
+cleanup;
diff --git a/xlators/mgmt/glusterd/src/glusterd-bitd-svc.c b/xlators/mgmt/glusterd/src/glusterd-bitd-svc.c
index 1b71b6c..6b606f8 100644
--- a/xlators/mgmt/glusterd/src/glusterd-bitd-svc.c
+++ b/xlators/mgmt/glusterd/src/glusterd-bitd-svc.c
@@ -15,13 +15,18 @@
 #include "glusterd-volgen.h"
 #include "glusterd-bitd-svc.h"
 
+void
+glusterd_bitdsvc_build (glusterd_svc_t *svc)
+{
+        svc->manager = glusterd_bitdsvc_manager;
+        svc->start = glusterd_bitdsvc_start;
+        svc->stop = glusterd_bitdsvc_stop;
+}
+
 int
 glusterd_bitdsvc_init (glusterd_svc_t *svc)
 {
-        return glusterd_svc_init (svc, bitd_svc_name,
-                                  glusterd_bitdsvc_manager,
-                                  glusterd_bitdsvc_start,
-                                  glusterd_bitdsvc_stop);
+        return glusterd_svc_init (svc, bitd_svc_name);
 }
 
 static int
@@ -65,6 +70,20 @@ glusterd_bitdsvc_manager (glusterd_svc_t *svc, void *data, int flags)
         this = THIS;
         GF_ASSERT (this);
 
+        if (!svc->inited) {
+                ret = glusterd_bitdsvc_init (svc);
+                if (ret) {
+                        gf_msg (this->name, GF_LOG_ERROR, 0,
+                                GD_MSG_BITD_INIT_FAIL, "Failed to init "
+                                "bitd service");
+                        goto out;
+                } else {
+                        svc->inited = _gf_true;
+                        gf_msg_debug (this->name, 0, "BitD service "
+                                      "initialized");
+                }
+        }
+
         if (glusterd_should_i_stop_bitd ()) {
                 ret = svc->stop (svc, SIGTERM);
         } else {
diff --git a/xlators/mgmt/glusterd/src/glusterd-bitd-svc.h b/xlators/mgmt/glusterd/src/glusterd-bitd-svc.h
index e6f5d51..103d404 100644
--- a/xlators/mgmt/glusterd/src/glusterd-bitd-svc.h
+++ b/xlators/mgmt/glusterd/src/glusterd-bitd-svc.h
@@ -20,6 +20,9 @@
 
 #define bitd_svc_name "bitd"
 
+void
+glusterd_bitdsvc_build (glusterd_svc_t *svc);
+
 int
 glusterd_bitdsvc_init (glusterd_svc_t *svc);
 
diff --git a/xlators/mgmt/glusterd/src/glusterd-ganesha.c b/xlators/mgmt/glusterd/src/glusterd-ganesha.c
index 4d2efb9..8cd2aa6 100644
--- a/xlators/mgmt/glusterd/src/glusterd-ganesha.c
+++ b/xlators/mgmt/glusterd/src/glusterd-ganesha.c
@@ -671,14 +671,19 @@ start_ganesha (char **op_errstr)
                 }
         }
 
-        ret = priv->nfs_svc.stop (&(priv->nfs_svc), SIGKILL);
-        if (ret) {
-                ret = -1;
-                gf_asprintf (op_errstr, "Gluster-NFS service could"
-                             "not be stopped, exiting.");
-                goto out;
+        /* If the nfs svc is not initialized it means that the service is not
+         * running, hence we can skip the process of stopping gluster-nfs
+         * service
+         */
+        if (priv->nfs_svc.inited) {
+                ret = priv->nfs_svc.stop (&(priv->nfs_svc), SIGKILL);
+                if (ret) {
+                        ret = -1;
+                        gf_asprintf (op_errstr, "Gluster-NFS service could"
+                                     "not be stopped, exiting.");
+                        goto out;
+                }
         }
-
         if (check_host_list()) {
                 ret = manage_service ("start");
                 if (ret)
diff --git a/xlators/mgmt/glusterd/src/glusterd-nfs-svc.c b/xlators/mgmt/glusterd/src/glusterd-nfs-svc.c
index 0c4d3c1..b1d9814 100644
--- a/xlators/mgmt/glusterd/src/glusterd-nfs-svc.c
+++ b/xlators/mgmt/glusterd/src/glusterd-nfs-svc.c
@@ -18,6 +18,14 @@
 
 char *nfs_svc_name = "nfs";
 
+void
+glusterd_nfssvc_build (glusterd_svc_t *svc)
+{
+        svc->manager = glusterd_nfssvc_manager;
+        svc->start = glusterd_nfssvc_start;
+        svc->stop = glusterd_nfssvc_stop;
+}
+
 static gf_boolean_t
 glusterd_nfssvc_need_start ()
 {
@@ -43,10 +51,7 @@ glusterd_nfssvc_need_start ()
 int
 glusterd_nfssvc_init (glusterd_svc_t *svc)
 {
-        return glusterd_svc_init (svc, nfs_svc_name,
-                                  glusterd_nfssvc_manager,
-                                  glusterd_nfssvc_start,
-                                  glusterd_nfssvc_stop);
+        return glusterd_svc_init (svc, nfs_svc_name);
 }
 
 static int
@@ -167,6 +172,19 @@ glusterd_nfssvc_manager (glusterd_svc_t *svc, void *data, int flags)
 {
         int                 ret     = -1;
 
+        if (!svc->inited) {
+                ret = glusterd_nfssvc_init (svc);
+                if (ret) {
+                        gf_msg (THIS->name, GF_LOG_ERROR, 0,
+                                GD_MSG_FAILED_INIT_NFSSVC, "Failed to init nfs "
+                                "service");
+                        goto out;
+                } else {
+                        svc->inited = _gf_true;
+                        gf_msg_debug (THIS->name, 0, "nfs service initialized");
+                }
+        }
+
         ret = svc->stop (svc, SIGKILL);
         if (ret)
                 goto out;
diff --git a/xlators/mgmt/glusterd/src/glusterd-nfs-svc.h b/xlators/mgmt/glusterd/src/glusterd-nfs-svc.h
index 210336c..c1c0330 100644
--- a/xlators/mgmt/glusterd/src/glusterd-nfs-svc.h
+++ b/xlators/mgmt/glusterd/src/glusterd-nfs-svc.h
@@ -18,6 +18,9 @@
 
 #include "glusterd-svc-mgmt.h"
 
+void
+glusterd_nfssvc_build (glusterd_svc_t *svc);
+
 int
 glusterd_nfssvc_init (glusterd_svc_t *svc);
 
diff --git a/xlators/mgmt/glusterd/src/glusterd-quotad-svc.c b/xlators/mgmt/glusterd/src/glusterd-quotad-svc.c
index 37824f6..59a7671 100644
--- a/xlators/mgmt/glusterd/src/glusterd-quotad-svc.c
+++ b/xlators/mgmt/glusterd/src/glusterd-quotad-svc.c
@@ -18,16 +18,21 @@
 
 char *quotad_svc_name = "quotad";
 
+void
+glusterd_quotadsvc_build (glusterd_svc_t *svc)
+{
+        svc->manager = glusterd_quotadsvc_manager;
+        svc->start = glusterd_quotadsvc_start;
+        svc->stop = glusterd_svc_stop;
+}
+
 int glusterd_quotadsvc_init (glusterd_svc_t *svc)
 {
         int              ret                = -1;
         char             volfile[PATH_MAX]  = {0,};
         glusterd_conf_t *conf               = THIS->private;
 
-        ret = glusterd_svc_init (svc, quotad_svc_name,
-                                 glusterd_quotadsvc_manager,
-                                 glusterd_quotadsvc_start,
-                                 glusterd_svc_stop);
+        ret = glusterd_svc_init (svc, quotad_svc_name);
         if (ret)
                 goto out;
 
@@ -60,6 +65,20 @@ glusterd_quotadsvc_manager (glusterd_svc_t *svc, void *data, int flags)
         int                 ret     = 0;
         glusterd_volinfo_t *volinfo = NULL;
 
+        if (!svc->inited) {
+                ret = glusterd_quotadsvc_init (svc);
+                if (ret) {
+                        gf_msg (THIS->name, GF_LOG_ERROR, 0,
+                                GD_MSG_FAILED_INIT_QUOTASVC, "Failed to init "
+                                "quotad service");
+                        goto out;
+                } else {
+                        svc->inited = _gf_true;
+                        gf_msg_debug (THIS->name, 0, "quotad service "
+                                      "initialized");
+                }
+        }
+
         volinfo = data;
 
         /* If all the volumes are stopped or all shd compatible volumes
diff --git a/xlators/mgmt/glusterd/src/glusterd-quotad-svc.h b/xlators/mgmt/glusterd/src/glusterd-quotad-svc.h
index 945d47e..c275aa4 100644
--- a/xlators/mgmt/glusterd/src/glusterd-quotad-svc.h
+++ b/xlators/mgmt/glusterd/src/glusterd-quotad-svc.h
@@ -18,6 +18,9 @@
 
 #include "glusterd-svc-mgmt.h"
 
+void
+glusterd_quotadsvc_build (glusterd_svc_t *svc);
+
 int
 glusterd_quotadsvc_init (glusterd_svc_t *svc);
 
diff --git a/xlators/mgmt/glusterd/src/glusterd-scrub-svc.c b/xlators/mgmt/glusterd/src/glusterd-scrub-svc.c
index 36863e2..b5c9785 100644
--- a/xlators/mgmt/glusterd/src/glusterd-scrub-svc.c
+++ b/xlators/mgmt/glusterd/src/glusterd-scrub-svc.c
@@ -17,13 +17,18 @@
 
 char *scrub_svc_name = "scrub";
 
+void
+glusterd_scrubsvc_build (glusterd_svc_t *svc)
+{
+        svc->manager = glusterd_scrubsvc_manager;
+        svc->start = glusterd_scrubsvc_start;
+        svc->stop = glusterd_scrubsvc_stop;
+}
+
 int
 glusterd_scrubsvc_init (glusterd_svc_t *svc)
 {
-        return glusterd_svc_init (svc, scrub_svc_name,
-                                  glusterd_scrubsvc_manager,
-                                  glusterd_scrubsvc_start,
-                                  glusterd_scrubsvc_stop);
+        return glusterd_svc_init (svc, scrub_svc_name);
 }
 
 static int
@@ -60,6 +65,20 @@ glusterd_scrubsvc_manager (glusterd_svc_t *svc, void *data, int flags)
 {
         int          ret    = -EINVAL;
 
+        if (!svc->inited) {
+                ret = glusterd_scrubsvc_init (svc);
+                if (ret) {
+                        gf_msg (THIS->name, GF_LOG_ERROR, 0,
+                                GD_MSG_SCRUB_INIT_FAIL, "Failed to init "
+                                "scrub service");
+                        goto out;
+                } else {
+                        svc->inited = _gf_true;
+                        gf_msg_debug (THIS->name, 0, "scrub service "
+                                      "initialized");
+                }
+        }
+
         if (glusterd_should_i_stop_bitd ()) {
                 ret = svc->stop (svc, SIGTERM);
         } else {
diff --git a/xlators/mgmt/glusterd/src/glusterd-scrub-svc.h b/xlators/mgmt/glusterd/src/glusterd-scrub-svc.h
index e2e3b0d..aeea00d 100644
--- a/xlators/mgmt/glusterd/src/glusterd-scrub-svc.h
+++ b/xlators/mgmt/glusterd/src/glusterd-scrub-svc.h
@@ -25,6 +25,9 @@ struct glusterd_scrubsvc_{
         gf_store_handle_t   *handle;
 };
 
+void
+glusterd_scrubsvc_build (glusterd_svc_t *svc);
+
 int
 glusterd_scrubsvc_init (glusterd_svc_t *svc);
 
diff --git a/xlators/mgmt/glusterd/src/glusterd-shd-svc.c b/xlators/mgmt/glusterd/src/glusterd-shd-svc.c
index 49454cc..f9f4189 100644
--- a/xlators/mgmt/glusterd/src/glusterd-shd-svc.c
+++ b/xlators/mgmt/glusterd/src/glusterd-shd-svc.c
@@ -18,13 +18,18 @@
 
 char *shd_svc_name = "glustershd";
 
+void
+glusterd_shdsvc_build (glusterd_svc_t *svc)
+{
+        svc->manager = glusterd_shdsvc_manager;
+        svc->start = glusterd_shdsvc_start;
+        svc->stop = glusterd_svc_stop;
+}
+
 int
 glusterd_shdsvc_init (glusterd_svc_t *svc)
 {
-        return glusterd_svc_init (svc, shd_svc_name,
-                                  glusterd_shdsvc_manager,
-                                  glusterd_shdsvc_start,
-                                  glusterd_svc_stop);
+        return glusterd_svc_init (svc, shd_svc_name);
 }
 
 static int
@@ -80,6 +85,19 @@ glusterd_shdsvc_manager (glusterd_svc_t *svc, void *data, int flags)
         int                 ret     = 0;
         glusterd_volinfo_t *volinfo = NULL;
 
+        if (!svc->inited) {
+                ret = glusterd_shdsvc_init (svc);
+                if (ret) {
+                        gf_msg (THIS->name, GF_LOG_ERROR, 0,
+                                GD_MSG_FAILED_INIT_SHDSVC, "Failed to init shd "
+                                "service");
+                        goto out;
+                } else {
+                        svc->inited = _gf_true;
+                        gf_msg_debug (THIS->name, 0, "shd service initialized");
+                }
+        }
+
         volinfo = data;
 
         /* If all the volumes are stopped or all shd compatible volumes
diff --git a/xlators/mgmt/glusterd/src/glusterd-shd-svc.h b/xlators/mgmt/glusterd/src/glusterd-shd-svc.h
index 469ed5d..7dbb247 100644
--- a/xlators/mgmt/glusterd/src/glusterd-shd-svc.h
+++ b/xlators/mgmt/glusterd/src/glusterd-shd-svc.h
@@ -18,6 +18,9 @@
 
 #include "glusterd-svc-mgmt.h"
 
+void
+glusterd_shdsvc_build (glusterd_svc_t *svc);
+
 int
 glusterd_shdsvc_init (glusterd_svc_t *svc);
 
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapd-svc.c b/xlators/mgmt/glusterd/src/glusterd-snapd-svc.c
index 757c7f6..2ec7200 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapd-svc.c
+++ b/xlators/mgmt/glusterd/src/glusterd-snapd-svc.c
@@ -36,6 +36,13 @@ glusterd_svc_build_snapd_logfile (char *logfile, char *logdir, size_t len)
         snprintf (logfile, len, "%s/snapd.log", logdir);
 }
 
+void
+glusterd_snapdsvc_build (glusterd_svc_t *svc)
+{
+        svc->manager = glusterd_snapdsvc_manager;
+        svc->start = glusterd_snapdsvc_start;
+        svc->stop = glusterd_svc_stop;
+}
 
 int
 glusterd_snapdsvc_init (void *data)
@@ -69,10 +76,6 @@ glusterd_snapdsvc_init (void *data)
         if (ret < 0)
                 goto out;
 
-        svc->manager = glusterd_snapdsvc_manager;
-        svc->start = glusterd_snapdsvc_start;
-        svc->stop = glusterd_svc_stop;
-
         notify = glusterd_snapdsvc_rpc_notify;
 
         glusterd_svc_build_snapd_rundir (volinfo, rundir, sizeof (rundir));
@@ -123,6 +126,21 @@ glusterd_snapdsvc_manager (glusterd_svc_t *svc, void *data, int flags)
 
         volinfo = data;
 
+        if (!svc->inited) {
+                ret = glusterd_snapdsvc_init (volinfo);
+                if (ret) {
+                        gf_msg (THIS->name, GF_LOG_ERROR, 0,
+                                GD_MSG_SNAPD_INIT_FAIL, "Failed to initialize "
+                                "snapd service for volume %s",
+                                volinfo->volname);
+                        goto out;
+                } else {
+                        svc->inited = _gf_true;
+                        gf_msg_debug (THIS->name, 0, "snapd service "
+                                      "initialized");
+                }
+        }
+
         ret = glusterd_is_snapd_enabled (volinfo);
         if (ret == -1) {
                 gf_msg (this->name, GF_LOG_ERROR, 0,
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapd-svc.h b/xlators/mgmt/glusterd/src/glusterd-snapd-svc.h
index bc5d39f..fae31e8 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapd-svc.h
+++ b/xlators/mgmt/glusterd/src/glusterd-snapd-svc.h
@@ -26,6 +26,9 @@ struct glusterd_snapdsvc_{
         gf_store_handle_t *handle;
 };
 
+void
+glusterd_snapdsvc_build (glusterd_svc_t *svc);
+
 int
 glusterd_snapdsvc_init (void *data);
 
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
index 839b274..34cafd8 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c
+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
@@ -6492,7 +6492,6 @@ glusterd_snapshot_clone_commit (dict_t *dict, char **op_errstr,
                        snap->snapname);
                goto out;
        }
-       ret = glusterd_snapdsvc_init (snap_vol);
 
        glusterd_list_add_order (&snap_vol->vol_list, &priv->volumes,
                        glusterd_compare_volume_name);
@@ -9525,15 +9524,6 @@ gd_restore_snap_volume (dict_t *dict, dict_t *rsp_dict,
                 goto out;
         }
 
-        /* Initialize the snapd service */
-        ret = glusterd_snapdsvc_init (new_volinfo);
-        if (ret) {
-                gf_msg (this->name, GF_LOG_ERROR, 0,
-                        GD_MSG_SNAPD_INIT_FAIL, "Failed to initialize snapd "
-                        "service for volume %s", orig_vol->volname);
-                goto out;
-        }
-
         ret = 0;
 out:
         if (ret) {
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c
index db7d1d4..7a605dd 100644
--- a/xlators/mgmt/glusterd/src/glusterd-store.c
+++ b/xlators/mgmt/glusterd/src/glusterd-store.c
@@ -2816,15 +2816,6 @@ glusterd_store_retrieve_volume (char *volname, glusterd_snap_t *snap)
         if (snap)
                 volinfo->is_snap_volume = _gf_true;
 
-        /* Initialize the snapd service */
-        ret = glusterd_snapdsvc_init (volinfo);
-        if (ret) {
-                gf_msg (this->name, GF_LOG_ERROR, 0,
-                        GD_MSG_SNAPD_INIT_FAIL, "Failed to initialize snapd "
-                        "service for volume %s", volinfo->volname);
-                goto out;
-        }
-
         ret = glusterd_store_update_volinfo (volinfo);
         if (ret) {
                 gf_msg (this->name, GF_LOG_ERROR, 0,
diff --git a/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c
index 04096a4..130bc56 100644
--- a/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c
+++ b/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c
@@ -49,9 +49,6 @@ static int
 glusterd_svc_init_common (glusterd_svc_t *svc,
                           char *svc_name, char *workdir,
                           char *rundir, char *logdir,
-                          glusterd_svc_manager_t manager,
-                          glusterd_svc_start_t start,
-                          glusterd_svc_stop_t stop,
                           glusterd_conn_notify_t notify)
 {
         int                     ret                        = -1;
@@ -74,10 +71,6 @@ glusterd_svc_init_common (glusterd_svc_t *svc,
         if (ret < 0)
                 goto out;
 
-        svc->manager = manager;
-        svc->start = start;
-        svc->stop = stop;
-
         if (!notify)
                 notify = glusterd_svc_common_rpc_notify;
 
@@ -126,10 +119,7 @@ svc_add_args (dict_t *cmdline, char *arg, data_t *value, void *data)
         return 0;
 }
 
-int glusterd_svc_init (glusterd_svc_t *svc, char *svc_name,
-                       glusterd_svc_manager_t manager,
-                       glusterd_svc_start_t start,
-                       glusterd_svc_stop_t stop)
+int glusterd_svc_init (glusterd_svc_t *svc, char *svc_name)
 {
         int              ret               = -1;
         char             rundir[PATH_MAX]  = {0,};
@@ -145,8 +135,7 @@ int glusterd_svc_init (glusterd_svc_t *svc, char *svc_name,
         glusterd_svc_build_rundir (svc_name, priv->workdir, rundir,
                                    sizeof (rundir));
         ret = glusterd_svc_init_common (svc, svc_name, priv->workdir, rundir,
-                                        DEFAULT_LOG_FILE_DIRECTORY, manager,
-                                        start, stop, NULL);
+                                        DEFAULT_LOG_FILE_DIRECTORY, NULL);
 
         return ret;
 }
diff --git a/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.h b/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.h
index bb4f6f1..22028d3 100644
--- a/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.h
+++ b/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.h
@@ -22,6 +22,8 @@
 struct glusterd_svc_;
 typedef struct glusterd_svc_ glusterd_svc_t;
 
+typedef void (*glusterd_svc_build_t) (glusterd_svc_t *svc);
+
 typedef int (*glusterd_svc_manager_t) (glusterd_svc_t *svc,
                                        void *data, int flags);
 typedef int (*glusterd_svc_start_t) (glusterd_svc_t *svc, int flags);
@@ -31,20 +33,19 @@ struct glusterd_svc_ {
         char                      name[PATH_MAX];
         glusterd_conn_t           conn;
         glusterd_proc_t           proc;
+        glusterd_svc_build_t      build;
         glusterd_svc_manager_t    manager;
         glusterd_svc_start_t      start;
         glusterd_svc_stop_t       stop;
         gf_boolean_t              online;
+        gf_boolean_t              inited;
 };
 
 int
 glusterd_svc_create_rundir (char *rundir);
 
 int
-glusterd_svc_init (glusterd_svc_t *svc, char *svc_name,
-                   glusterd_svc_manager_t manager,
-                   glusterd_svc_start_t start,
-                   glusterd_svc_stop_t stop);
+glusterd_svc_init (glusterd_svc_t *svc, char *svc_name);
 
 int
 glusterd_svc_start (glusterd_svc_t *svc, int flags, dict_t *cmdline);
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 1af9902..0101ec5 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -500,6 +500,9 @@ glusterd_volinfo_new (glusterd_volinfo_t **volinfo)
 
         new_volinfo->xl = THIS;
 
+        new_volinfo->snapd.svc.build = glusterd_snapdsvc_build;
+        new_volinfo->snapd.svc.build (&(new_volinfo->snapd.svc));
+
         pthread_mutex_init (&new_volinfo->reflock, NULL);
         *volinfo = glusterd_volinfo_ref (new_volinfo);
 
@@ -3776,35 +3779,17 @@ glusterd_import_friend_volume (dict_t *peer_data, size_t count)
 
         ret = glusterd_volinfo_find (new_volinfo->volname, &old_volinfo);
         if (0 == ret) {
-                /* snapdsvc initialization of old_volinfo is also required here
-                 * as glusterd_delete_stale_volume () invokes snapdsvc manager
-                 */
-                ret = glusterd_snapdsvc_init (old_volinfo);
-                if (ret) {
-                        gf_msg (this->name, GF_LOG_ERROR, 0,
-                                GD_MSG_SNAPD_INIT_FAIL, "Failed to initialize"
-                                " snapdsvc for old volume %s",
-                                old_volinfo->volname);
-                        goto out;
-                }
                 (void) gd_check_and_update_rebalance_info (old_volinfo,
                                                            new_volinfo);
                 (void) glusterd_delete_stale_volume (old_volinfo, new_volinfo);
         }
 
-        ret = glusterd_snapdsvc_init (new_volinfo);
-        if (ret) {
-                gf_msg (this->name, GF_LOG_ERROR, 0,
-                        GD_MSG_SNAPD_INIT_FAIL, "Failed to initialize "
-                        "snapdsvc for volume %s", new_volinfo->volname);
-                goto out;
-        }
-
         if (glusterd_is_volume_started (new_volinfo)) {
                 (void) glusterd_start_bricks (new_volinfo);
                 if (glusterd_is_snapd_enabled (new_volinfo)) {
                         svc = &(new_volinfo->snapd.svc);
-                        (void) svc->start (svc, PROC_START_NO_WAIT);
+                        (void) svc->manager (svc, new_volinfo,
+                                             PROC_START_NO_WAIT);
                 }
         }
 
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
index 2ad1614..b52f832 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
@@ -2302,12 +2302,6 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr)
                 goto out;
         }
 
-        ret = glusterd_snapdsvc_init (volinfo);
-        if (ret) {
-                *op_errstr = gf_strdup ("Failed to initialize snapd service");
-                goto out;
-        }
-
         ret = glusterd_create_volfiles_and_notify_services (volinfo);
         if (ret) {
                 *op_errstr = gf_strdup ("Failed to create volume files");
diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c
index 1286488..2c75545 100644
--- a/xlators/mgmt/glusterd/src/glusterd.c
+++ b/xlators/mgmt/glusterd/src/glusterd.c
@@ -1274,10 +1274,9 @@ out:
         return ret;
 }
 
-static int
-glusterd_svc_init_all ()
+static void
+glusterd_svcs_build ()
 {
-        int                 ret     = -1;
         xlator_t           *this    = NULL;
         glusterd_conf_t    *priv    = NULL;
 
@@ -1287,59 +1286,22 @@ glusterd_svc_init_all ()
         priv = this->private;
         GF_ASSERT (priv);
 
-        /* Init SHD svc */
-        ret = glusterd_shdsvc_init (&(priv->shd_svc));
-        if (ret) {
-                gf_msg (THIS->name, GF_LOG_ERROR, 0,
-                        GD_MSG_FAILED_INIT_SHDSVC,
-                        "Failed to init shd service");
-                goto out;
-        }
-        gf_msg_debug (THIS->name, 0, "shd service initialized");
+        priv->shd_svc.build = glusterd_shdsvc_build;
+        priv->shd_svc.build (&(priv->shd_svc));
 
-        /* Init NFS svc */
-        ret = glusterd_nfssvc_init (&(priv->nfs_svc));
-        if (ret) {
-                gf_msg (THIS->name, GF_LOG_ERROR, 0,
-                        GD_MSG_FAILED_INIT_NFSSVC,
-                        "Failed to init nfs service");
-                goto out;
-        }
-        gf_msg_debug (THIS->name, 0, "nfs service initialized");
+        priv->nfs_svc.build = glusterd_nfssvc_build;
+        priv->nfs_svc.build (&(priv->nfs_svc));
 
-        /* Init QuotaD svc */
-        ret = glusterd_quotadsvc_init (&(priv->quotad_svc));
-        if (ret) {
-                gf_msg (THIS->name, GF_LOG_ERROR, 0,
-                        GD_MSG_FAILED_INIT_QUOTASVC, "Failed to init quotad "
-                        "service");
-                goto out;
-        }
-        gf_msg_debug (THIS->name, 0, "quotad service initialized");
+        priv->quotad_svc.build = glusterd_quotadsvc_build;
+        priv->quotad_svc.build (&(priv->quotad_svc));
 
-        /* Init BitD svc */
-        ret = glusterd_bitdsvc_init (&(priv->bitd_svc));
-        if (ret) {
-                gf_msg (THIS->name, GF_LOG_ERROR, 0,
-                        GD_MSG_BITD_INIT_FAIL, "Failed to initialized BitD "
-                        "service");
-                goto out;
-        }
-        gf_msg_debug (THIS->name, 0, "BitD service initialized");
+        priv->bitd_svc.build = glusterd_bitdsvc_build;
+        priv->bitd_svc.build (&(priv->bitd_svc));
 
-        ret = glusterd_scrubsvc_init (&(priv->scrub_svc));
-        if (ret) {
-                gf_msg (THIS->name, GF_LOG_ERROR, 0,
-                        GD_MSG_SCRUB_INIT_FAIL, "Failed to initialized scrub "
-                        "service");
-                goto out;
-        }
-        gf_msg_debug (THIS->name, 0, "scrub service initialized");
+        priv->scrub_svc.build = glusterd_scrubsvc_build;
+        priv->scrub_svc.build (&(priv->scrub_svc));
 
-out:
-        return ret;
 }
-
 /*
  * init - called during glusterd initialization
  *
@@ -1740,6 +1702,7 @@ init (xlator_t *this)
         this->private = conf;
         glusterd_mgmt_v3_lock_init ();
         glusterd_txn_opinfo_dict_init ();
+        glusterd_svcs_build ();
 
         /* Make install copies few of the hook-scripts by creating hooks
          * directory. Hence purposefully not doing the check for the presence of
@@ -1789,10 +1752,6 @@ init (xlator_t *this)
                 goto out;
         }
 
-        ret = glusterd_svc_init_all ();
-        if (ret)
-                goto out;
-
         ret = glusterd_restore ();
         if (ret < 0)
                 goto out;
-- 
1.7.1