e3c68b
From b0815b8a84a07d17a1215c55afc38888ee9fc37c Mon Sep 17 00:00:00 2001
e3c68b
From: Mohammed Rafi KC <rkavunga@redhat.com>
e3c68b
Date: Mon, 24 Jun 2019 12:00:20 +0530
e3c68b
Subject: [PATCH 227/255] glusterd/svc: update pid of mux volumes from the shd
e3c68b
 process
e3c68b
e3c68b
For a normal volume, we are updating the pid from a the
e3c68b
process while we do a daemonization or at the end of the
e3c68b
init if it is no-daemon mode. Along with updating the pid
e3c68b
we also lock the file, to make sure that the process is
e3c68b
running fine.
e3c68b
e3c68b
With brick mux, we were updating the pidfile from gluterd
e3c68b
after an attach/detach request.
e3c68b
e3c68b
There are two problems with this approach.
e3c68b
1) We are not holding a pidlock for any file other than parent
e3c68b
   process.
e3c68b
2) There is a chance for possible race conditions with attach/detach.
e3c68b
   For example, shd start and a volume stop could race. Let's say
e3c68b
   we are starting an shd and it is attached to a volume.
e3c68b
   While we trying to link the pid file to the running process,
e3c68b
   this would have deleted by the thread that doing a volume stop.
e3c68b
e3c68b
> upstream patch : https://review.gluster.org/#/c/glusterfs/+/22935/
e3c68b
e3c68b
>Change-Id: I29a00352102877ce09ea3f376ca52affceb5cf1a
e3c68b
>Updates: bz#1722541
e3c68b
>Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
e3c68b
e3c68b
Change-Id: I29a00352102877ce09ea3f376ca52affceb5cf1a
e3c68b
BUG: 1721802
e3c68b
Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
e3c68b
Reviewed-on: https://code.engineering.redhat.com/gerrit/175723
e3c68b
Tested-by: RHGS Build Bot <nigelb@redhat.com>
e3c68b
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
e3c68b
---
e3c68b
 glusterfsd/src/gf_attach.c                         |   2 +
e3c68b
 glusterfsd/src/glusterfsd-mgmt.c                   |  66 +++++++--
e3c68b
 libglusterfs/src/glusterfs/glusterfs.h             |   2 +-
e3c68b
 libglusterfs/src/glusterfs/libglusterfs-messages.h |   3 +-
e3c68b
 libglusterfs/src/graph.c                           | 154 ++++++++++++++++++++-
e3c68b
 rpc/xdr/src/glusterd1-xdr.x                        |   1 +
e3c68b
 xlators/mgmt/glusterd/src/glusterd-handler.c       |   2 +
e3c68b
 xlators/mgmt/glusterd/src/glusterd-handshake.c     |  42 +++++-
e3c68b
 xlators/mgmt/glusterd/src/glusterd-op-sm.c         |   4 +
e3c68b
 .../mgmt/glusterd/src/glusterd-shd-svc-helper.c    |  25 ++++
e3c68b
 .../mgmt/glusterd/src/glusterd-shd-svc-helper.h    |   3 +
e3c68b
 xlators/mgmt/glusterd/src/glusterd-shd-svc.c       |   8 +-
e3c68b
 xlators/mgmt/glusterd/src/glusterd-svc-helper.c    |  57 ++++----
e3c68b
 xlators/mgmt/glusterd/src/glusterd-syncop.c        |   2 +
e3c68b
 xlators/mgmt/glusterd/src/glusterd-utils.c         |   6 +-
e3c68b
 15 files changed, 325 insertions(+), 52 deletions(-)
e3c68b
e3c68b
diff --git a/glusterfsd/src/gf_attach.c b/glusterfsd/src/gf_attach.c
e3c68b
index 6293b9b..1bff854 100644
e3c68b
--- a/glusterfsd/src/gf_attach.c
e3c68b
+++ b/glusterfsd/src/gf_attach.c
e3c68b
@@ -65,6 +65,8 @@ send_brick_req(xlator_t *this, struct rpc_clnt *rpc, char *path, int op)
e3c68b
     brick_req.name = path;
e3c68b
     brick_req.input.input_val = NULL;
e3c68b
     brick_req.input.input_len = 0;
e3c68b
+    brick_req.dict.dict_val = NULL;
e3c68b
+    brick_req.dict.dict_len = 0;
e3c68b
 
e3c68b
     req_size = xdr_sizeof((xdrproc_t)xdr_gd1_mgmt_brick_op_req, req);
e3c68b
     iobuf = iobuf_get2(rpc->ctx->iobuf_pool, req_size);
e3c68b
diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c
e3c68b
index 1d2cd1a..f930e0a 100644
e3c68b
--- a/glusterfsd/src/glusterfsd-mgmt.c
e3c68b
+++ b/glusterfsd/src/glusterfsd-mgmt.c
e3c68b
@@ -50,13 +50,16 @@ int
e3c68b
 emancipate(glusterfs_ctx_t *ctx, int ret);
e3c68b
 int
e3c68b
 glusterfs_process_svc_attach_volfp(glusterfs_ctx_t *ctx, FILE *fp,
e3c68b
-                                   char *volfile_id, char *checksum);
e3c68b
+                                   char *volfile_id, char *checksum,
e3c68b
+                                   dict_t *dict);
e3c68b
 int
e3c68b
 glusterfs_mux_volfile_reconfigure(FILE *newvolfile_fp, glusterfs_ctx_t *ctx,
e3c68b
-                                  gf_volfile_t *volfile_obj, char *checksum);
e3c68b
+                                  gf_volfile_t *volfile_obj, char *checksum,
e3c68b
+                                  dict_t *dict);
e3c68b
 int
e3c68b
 glusterfs_process_svc_attach_volfp(glusterfs_ctx_t *ctx, FILE *fp,
e3c68b
-                                   char *volfile_id, char *checksum);
e3c68b
+                                   char *volfile_id, char *checksum,
e3c68b
+                                   dict_t *dict);
e3c68b
 int
e3c68b
 glusterfs_process_svc_detach(glusterfs_ctx_t *ctx, gf_volfile_t *volfile_obj);
e3c68b
 
e3c68b
@@ -75,7 +78,8 @@ mgmt_cbk_spec(struct rpc_clnt *rpc, void *mydata, void *data)
e3c68b
 }
e3c68b
 
e3c68b
 int
e3c68b
-mgmt_process_volfile(const char *volfile, ssize_t size, char *volfile_id)
e3c68b
+mgmt_process_volfile(const char *volfile, ssize_t size, char *volfile_id,
e3c68b
+                     dict_t *dict)
e3c68b
 {
e3c68b
     glusterfs_ctx_t *ctx = NULL;
e3c68b
     int ret = 0;
e3c68b
@@ -145,11 +149,11 @@ mgmt_process_volfile(const char *volfile, ssize_t size, char *volfile_id)
e3c68b
              * the volfile
e3c68b
              */
e3c68b
             ret = glusterfs_process_svc_attach_volfp(ctx, tmpfp, volfile_id,
e3c68b
-                                                     sha256_hash);
e3c68b
+                                                     sha256_hash, dict);
e3c68b
             goto unlock;
e3c68b
         }
e3c68b
         ret = glusterfs_mux_volfile_reconfigure(tmpfp, ctx, volfile_obj,
e3c68b
-                                                sha256_hash);
e3c68b
+                                                sha256_hash, dict);
e3c68b
         if (ret < 0) {
e3c68b
             gf_msg_debug("glusterfsd-mgmt", EINVAL, "Reconfigure failed !!");
e3c68b
         }
e3c68b
@@ -387,6 +391,8 @@ err:
e3c68b
         UNLOCK(&ctx->volfile_lock);
e3c68b
     if (xlator_req.input.input_val)
e3c68b
         free(xlator_req.input.input_val);
e3c68b
+    if (xlator_req.dict.dict_val)
e3c68b
+        free(xlator_req.dict.dict_val);
e3c68b
     free(xlator_req.name);
e3c68b
     xlator_req.name = NULL;
e3c68b
     return 0;
e3c68b
@@ -561,6 +567,8 @@ out:
e3c68b
 
e3c68b
     free(xlator_req.name);
e3c68b
     free(xlator_req.input.input_val);
e3c68b
+    if (xlator_req.dict.dict_val)
e3c68b
+        free(xlator_req.dict.dict_val);
e3c68b
     if (output)
e3c68b
         dict_unref(output);
e3c68b
     if (dict)
e3c68b
@@ -982,6 +990,8 @@ out:
e3c68b
     if (input)
e3c68b
         dict_unref(input);
e3c68b
     free(xlator_req.input.input_val); /*malloced by xdr*/
e3c68b
+    if (xlator_req.dict.dict_val)
e3c68b
+        free(xlator_req.dict.dict_val);
e3c68b
     if (output)
e3c68b
         dict_unref(output);
e3c68b
     free(xlator_req.name);
e3c68b
@@ -1062,6 +1072,8 @@ glusterfs_handle_attach(rpcsvc_request_t *req)
e3c68b
     out:
e3c68b
         UNLOCK(&ctx->volfile_lock);
e3c68b
     }
e3c68b
+    if (xlator_req.dict.dict_val)
e3c68b
+        free(xlator_req.dict.dict_val);
e3c68b
     free(xlator_req.input.input_val);
e3c68b
     free(xlator_req.name);
e3c68b
 
e3c68b
@@ -1077,6 +1089,7 @@ glusterfs_handle_svc_attach(rpcsvc_request_t *req)
e3c68b
     };
e3c68b
     xlator_t *this = NULL;
e3c68b
     glusterfs_ctx_t *ctx = NULL;
e3c68b
+    dict_t *dict = NULL;
e3c68b
 
e3c68b
     GF_ASSERT(req);
e3c68b
     this = THIS;
e3c68b
@@ -1091,20 +1104,41 @@ glusterfs_handle_svc_attach(rpcsvc_request_t *req)
e3c68b
         req->rpc_err = GARBAGE_ARGS;
e3c68b
         goto out;
e3c68b
     }
e3c68b
+
e3c68b
     gf_msg(THIS->name, GF_LOG_INFO, 0, glusterfsd_msg_41,
e3c68b
            "received attach "
e3c68b
            "request for volfile-id=%s",
e3c68b
            xlator_req.name);
e3c68b
+
e3c68b
+    dict = dict_new();
e3c68b
+    if (!dict) {
e3c68b
+        ret = -1;
e3c68b
+        errno = ENOMEM;
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+
e3c68b
+    ret = dict_unserialize(xlator_req.dict.dict_val, xlator_req.dict.dict_len,
e3c68b
+                           &dict);
e3c68b
+    if (ret) {
e3c68b
+        gf_msg(this->name, GF_LOG_WARNING, EINVAL, glusterfsd_msg_42,
e3c68b
+               "failed to unserialize xdata to dictionary");
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+    dict->extra_stdfree = xlator_req.dict.dict_val;
e3c68b
+
e3c68b
     ret = 0;
e3c68b
 
e3c68b
     if (ctx->active) {
e3c68b
         ret = mgmt_process_volfile(xlator_req.input.input_val,
e3c68b
-                                   xlator_req.input.input_len, xlator_req.name);
e3c68b
+                                   xlator_req.input.input_len, xlator_req.name,
e3c68b
+                                   dict);
e3c68b
     } else {
e3c68b
         gf_msg(this->name, GF_LOG_WARNING, EINVAL, glusterfsd_msg_42,
e3c68b
                "got attach for %s but no active graph", xlator_req.name);
e3c68b
     }
e3c68b
 out:
e3c68b
+    if (dict)
e3c68b
+        dict_unref(dict);
e3c68b
     if (xlator_req.input.input_val)
e3c68b
         free(xlator_req.input.input_val);
e3c68b
     if (xlator_req.name)
e3c68b
@@ -1241,6 +1275,8 @@ out:
e3c68b
     GF_FREE(filepath);
e3c68b
     if (xlator_req.input.input_val)
e3c68b
         free(xlator_req.input.input_val);
e3c68b
+    if (xlator_req.dict.dict_val)
e3c68b
+        free(xlator_req.dict.dict_val);
e3c68b
 
e3c68b
     return ret;
e3c68b
 }
e3c68b
@@ -1313,6 +1349,8 @@ out:
e3c68b
     if (dict)
e3c68b
         dict_unref(dict);
e3c68b
     free(xlator_req.input.input_val);  // malloced by xdr
e3c68b
+    if (xlator_req.dict.dict_val)
e3c68b
+        free(xlator_req.dict.dict_val);
e3c68b
     if (output)
e3c68b
         dict_unref(output);
e3c68b
     free(xlator_req.name);  // malloced by xdr
e3c68b
@@ -1461,6 +1499,8 @@ out:
e3c68b
     if (output)
e3c68b
         dict_unref(output);
e3c68b
     free(brick_req.input.input_val);
e3c68b
+    if (brick_req.dict.dict_val)
e3c68b
+        free(brick_req.dict.dict_val);
e3c68b
     free(brick_req.name);
e3c68b
     GF_FREE(xname);
e3c68b
     GF_FREE(msg);
e3c68b
@@ -1654,6 +1694,8 @@ out:
e3c68b
     if (dict)
e3c68b
         dict_unref(dict);
e3c68b
     free(node_req.input.input_val);
e3c68b
+    if (node_req.dict.dict_val)
e3c68b
+        free(node_req.dict.dict_val);
e3c68b
     GF_FREE(msg);
e3c68b
     GF_FREE(rsp.output.output_val);
e3c68b
     GF_FREE(node_name);
e3c68b
@@ -1757,6 +1799,8 @@ glusterfs_handle_nfs_profile(rpcsvc_request_t *req)
e3c68b
 
e3c68b
 out:
e3c68b
     free(nfs_req.input.input_val);
e3c68b
+    if (nfs_req.dict.dict_val)
e3c68b
+        free(nfs_req.dict.dict_val);
e3c68b
     if (dict)
e3c68b
         dict_unref(dict);
e3c68b
     if (output)
e3c68b
@@ -1835,6 +1879,8 @@ out:
e3c68b
     if (dict)
e3c68b
         dict_unref(dict);
e3c68b
     free(xlator_req.input.input_val);  // malloced by xdr
e3c68b
+    if (xlator_req.dict.dict_val)
e3c68b
+        free(xlator_req.dict.dict_val);
e3c68b
     if (output)
e3c68b
         dict_unref(output);
e3c68b
     free(xlator_req.name);  // malloced by xdr
e3c68b
@@ -1963,7 +2009,8 @@ out:
e3c68b
     if (dict)
e3c68b
         dict_unref(dict);
e3c68b
     free(brick_req.input.input_val);
e3c68b
-
e3c68b
+    if (brick_req.dict.dict_val)
e3c68b
+        free(brick_req.dict.dict_val);
e3c68b
     gf_log(THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
e3c68b
     return ret;
e3c68b
 }
e3c68b
@@ -2213,7 +2260,8 @@ volfile:
e3c68b
     size = rsp.op_ret;
e3c68b
     volfile_id = frame->local;
e3c68b
     if (mgmt_is_multiplexed_daemon(ctx->cmd_args.process_name)) {
e3c68b
-        ret = mgmt_process_volfile((const char *)rsp.spec, size, volfile_id);
e3c68b
+        ret = mgmt_process_volfile((const char *)rsp.spec, size, volfile_id,
e3c68b
+                                   dict);
e3c68b
         goto post_graph_mgmt;
e3c68b
     }
e3c68b
 
e3c68b
diff --git a/libglusterfs/src/glusterfs/glusterfs.h b/libglusterfs/src/glusterfs/glusterfs.h
e3c68b
index 9ec2365..b6327b8 100644
e3c68b
--- a/libglusterfs/src/glusterfs/glusterfs.h
e3c68b
+++ b/libglusterfs/src/glusterfs/glusterfs.h
e3c68b
@@ -744,7 +744,7 @@ typedef struct {
e3c68b
     char vol_id[NAME_MAX + 1];
e3c68b
     struct list_head volfile_list;
e3c68b
     glusterfs_graph_t *graph;
e3c68b
-
e3c68b
+    FILE *pidfp;
e3c68b
 } gf_volfile_t;
e3c68b
 
e3c68b
 glusterfs_ctx_t *
e3c68b
diff --git a/libglusterfs/src/glusterfs/libglusterfs-messages.h b/libglusterfs/src/glusterfs/libglusterfs-messages.h
e3c68b
index ea2aa60..7e0eebb 100644
e3c68b
--- a/libglusterfs/src/glusterfs/libglusterfs-messages.h
e3c68b
+++ b/libglusterfs/src/glusterfs/libglusterfs-messages.h
e3c68b
@@ -111,6 +111,7 @@ GLFS_MSGID(
e3c68b
     LG_MSG_PTHREAD_NAMING_FAILED, LG_MSG_SYSCALL_RETURNS_WRONG,
e3c68b
     LG_MSG_XXH64_TO_GFID_FAILED, LG_MSG_ASYNC_WARNING, LG_MSG_ASYNC_FAILURE,
e3c68b
     LG_MSG_GRAPH_CLEANUP_FAILED, LG_MSG_GRAPH_SETUP_FAILED,
e3c68b
-    LG_MSG_GRAPH_DETACH_STARTED, LG_MSG_GRAPH_ATTACH_FAILED);
e3c68b
+    LG_MSG_GRAPH_DETACH_STARTED, LG_MSG_GRAPH_ATTACH_FAILED,
e3c68b
+    LG_MSG_GRAPH_ATTACH_PID_FILE_UPDATED);
e3c68b
 
e3c68b
 #endif /* !_LG_MESSAGES_H_ */
e3c68b
diff --git a/libglusterfs/src/graph.c b/libglusterfs/src/graph.c
e3c68b
index 172dc61..05f76bf 100644
e3c68b
--- a/libglusterfs/src/graph.c
e3c68b
+++ b/libglusterfs/src/graph.c
e3c68b
@@ -1467,6 +1467,21 @@ out:
e3c68b
 }
e3c68b
 
e3c68b
 int
e3c68b
+glusterfs_svc_mux_pidfile_cleanup(gf_volfile_t *volfile_obj)
e3c68b
+{
e3c68b
+    if (!volfile_obj || !volfile_obj->pidfp)
e3c68b
+        return 0;
e3c68b
+
e3c68b
+    gf_msg_trace("glusterfsd", 0, "pidfile %s cleanup", volfile_obj->vol_id);
e3c68b
+
e3c68b
+    lockf(fileno(volfile_obj->pidfp), F_ULOCK, 0);
e3c68b
+    fclose(volfile_obj->pidfp);
e3c68b
+    volfile_obj->pidfp = NULL;
e3c68b
+
e3c68b
+    return 0;
e3c68b
+}
e3c68b
+
e3c68b
+int
e3c68b
 glusterfs_process_svc_detach(glusterfs_ctx_t *ctx, gf_volfile_t *volfile_obj)
e3c68b
 {
e3c68b
     xlator_t *last_xl = NULL;
e3c68b
@@ -1502,6 +1517,7 @@ glusterfs_process_svc_detach(glusterfs_ctx_t *ctx, gf_volfile_t *volfile_obj)
e3c68b
 
e3c68b
         list_del_init(&volfile_obj->volfile_list);
e3c68b
         glusterfs_mux_xlator_unlink(parent_graph->top, xl);
e3c68b
+        glusterfs_svc_mux_pidfile_cleanup(volfile_obj);
e3c68b
         parent_graph->last_xl = glusterfs_get_last_xlator(parent_graph);
e3c68b
         parent_graph->xl_count -= graph->xl_count;
e3c68b
         parent_graph->leaf_count -= graph->leaf_count;
e3c68b
@@ -1531,8 +1547,126 @@ out:
e3c68b
 }
e3c68b
 
e3c68b
 int
e3c68b
+glusterfs_svc_mux_pidfile_setup(gf_volfile_t *volfile_obj, const char *pid_file)
e3c68b
+{
e3c68b
+    int ret = -1;
e3c68b
+    FILE *pidfp = NULL;
e3c68b
+
e3c68b
+    if (!pid_file || !volfile_obj)
e3c68b
+        goto out;
e3c68b
+
e3c68b
+    if (volfile_obj->pidfp) {
e3c68b
+        ret = 0;
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+    pidfp = fopen(pid_file, "a+");
e3c68b
+    if (!pidfp) {
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+    volfile_obj->pidfp = pidfp;
e3c68b
+
e3c68b
+    ret = lockf(fileno(pidfp), F_TLOCK, 0);
e3c68b
+    if (ret) {
e3c68b
+        ret = 0;
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+out:
e3c68b
+    return ret;
e3c68b
+}
e3c68b
+
e3c68b
+int
e3c68b
+glusterfs_svc_mux_pidfile_update(gf_volfile_t *volfile_obj,
e3c68b
+                                 const char *pid_file, pid_t pid)
e3c68b
+{
e3c68b
+    int ret = 0;
e3c68b
+    FILE *pidfp = NULL;
e3c68b
+    int old_pid;
e3c68b
+
e3c68b
+    if (!volfile_obj->pidfp) {
e3c68b
+        ret = glusterfs_svc_mux_pidfile_setup(volfile_obj, pid_file);
e3c68b
+        if (ret == -1)
e3c68b
+            goto out;
e3c68b
+    }
e3c68b
+    pidfp = volfile_obj->pidfp;
e3c68b
+    ret = fscanf(pidfp, "%d", &old_pid);
e3c68b
+    if (ret <= 0) {
e3c68b
+        goto update;
e3c68b
+    }
e3c68b
+    if (old_pid == pid) {
e3c68b
+        ret = 0;
e3c68b
+        goto out;
e3c68b
+    } else {
e3c68b
+        gf_msg("mgmt", GF_LOG_INFO, 0, LG_MSG_GRAPH_ATTACH_PID_FILE_UPDATED,
e3c68b
+               "Old pid=%d found in pidfile %s. Cleaning the old pid and "
e3c68b
+               "Updating new pid=%d",
e3c68b
+               old_pid, pid_file, pid);
e3c68b
+    }
e3c68b
+update:
e3c68b
+    ret = sys_ftruncate(fileno(pidfp), 0);
e3c68b
+    if (ret) {
e3c68b
+        gf_msg("glusterfsd", GF_LOG_ERROR, errno,
e3c68b
+               LG_MSG_GRAPH_ATTACH_PID_FILE_UPDATED,
e3c68b
+               "pidfile %s truncation failed", pid_file);
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+
e3c68b
+    ret = fprintf(pidfp, "%d\n", pid);
e3c68b
+    if (ret <= 0) {
e3c68b
+        gf_msg("glusterfsd", GF_LOG_ERROR, errno,
e3c68b
+               LG_MSG_GRAPH_ATTACH_PID_FILE_UPDATED, "pidfile %s write failed",
e3c68b
+               pid_file);
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+
e3c68b
+    ret = fflush(pidfp);
e3c68b
+    if (ret) {
e3c68b
+        gf_msg("glusterfsd", GF_LOG_ERROR, errno,
e3c68b
+               LG_MSG_GRAPH_ATTACH_PID_FILE_UPDATED, "pidfile %s write failed",
e3c68b
+               pid_file);
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+out:
e3c68b
+    return ret;
e3c68b
+}
e3c68b
+
e3c68b
+int
e3c68b
+glusterfs_update_mux_pid(dict_t *dict, gf_volfile_t *volfile_obj)
e3c68b
+{
e3c68b
+    char *file = NULL;
e3c68b
+    int ret = -1;
e3c68b
+
e3c68b
+    GF_VALIDATE_OR_GOTO("graph", dict, out);
e3c68b
+    GF_VALIDATE_OR_GOTO("graph", volfile_obj, out);
e3c68b
+
e3c68b
+    ret = dict_get_str(dict, "pidfile", &file;;
e3c68b
+    if (ret < 0) {
e3c68b
+        gf_msg("mgmt", GF_LOG_ERROR, EINVAL, LG_MSG_GRAPH_SETUP_FAILED,
e3c68b
+               "Failed to get pidfile from dict for  volfile_id=%s",
e3c68b
+               volfile_obj->vol_id);
e3c68b
+    }
e3c68b
+
e3c68b
+    ret = glusterfs_svc_mux_pidfile_update(volfile_obj, file, getpid());
e3c68b
+    if (ret < 0) {
e3c68b
+        ret = -1;
e3c68b
+        gf_msg("mgmt", GF_LOG_ERROR, EINVAL, LG_MSG_GRAPH_SETUP_FAILED,
e3c68b
+               "Failed to update "
e3c68b
+               "the pidfile for volfile_id=%s",
e3c68b
+               volfile_obj->vol_id);
e3c68b
+
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+
e3c68b
+    if (ret == 1)
e3c68b
+        gf_msg("mgmt", GF_LOG_INFO, 0, LG_MSG_GRAPH_ATTACH_PID_FILE_UPDATED,
e3c68b
+               "PID %d updated in pidfile=%s", getpid(), file);
e3c68b
+    ret = 0;
e3c68b
+out:
e3c68b
+    return ret;
e3c68b
+}
e3c68b
+int
e3c68b
 glusterfs_process_svc_attach_volfp(glusterfs_ctx_t *ctx, FILE *fp,
e3c68b
-                                   char *volfile_id, char *checksum)
e3c68b
+                                   char *volfile_id, char *checksum,
e3c68b
+                                   dict_t *dict)
e3c68b
 {
e3c68b
     glusterfs_graph_t *graph = NULL;
e3c68b
     glusterfs_graph_t *parent_graph = NULL;
e3c68b
@@ -1615,18 +1749,25 @@ glusterfs_process_svc_attach_volfp(glusterfs_ctx_t *ctx, FILE *fp,
e3c68b
         ret = -1;
e3c68b
         goto out;
e3c68b
     }
e3c68b
+    volfile_obj->pidfp = NULL;
e3c68b
+    snprintf(volfile_obj->vol_id, sizeof(volfile_obj->vol_id), "%s",
e3c68b
+             volfile_id);
e3c68b
+
e3c68b
+    if (strcmp(ctx->cmd_args.process_name, "glustershd") == 0) {
e3c68b
+        ret = glusterfs_update_mux_pid(dict, volfile_obj);
e3c68b
+        if (ret == -1) {
e3c68b
+            goto out;
e3c68b
+        }
e3c68b
+    }
e3c68b
 
e3c68b
     graph->used = 1;
e3c68b
     parent_graph->id++;
e3c68b
     list_add(&graph->list, &ctx->graphs);
e3c68b
     INIT_LIST_HEAD(&volfile_obj->volfile_list);
e3c68b
     volfile_obj->graph = graph;
e3c68b
-    snprintf(volfile_obj->vol_id, sizeof(volfile_obj->vol_id), "%s",
e3c68b
-             volfile_id);
e3c68b
     memcpy(volfile_obj->volfile_checksum, checksum,
e3c68b
            sizeof(volfile_obj->volfile_checksum));
e3c68b
     list_add_tail(&volfile_obj->volfile_list, &ctx->volfile_list);
e3c68b
-
e3c68b
     gf_log_dump_graph(fp, graph);
e3c68b
     graph = NULL;
e3c68b
 
e3c68b
@@ -1654,7 +1795,8 @@ out:
e3c68b
 
e3c68b
 int
e3c68b
 glusterfs_mux_volfile_reconfigure(FILE *newvolfile_fp, glusterfs_ctx_t *ctx,
e3c68b
-                                  gf_volfile_t *volfile_obj, char *checksum)
e3c68b
+                                  gf_volfile_t *volfile_obj, char *checksum,
e3c68b
+                                  dict_t *dict)
e3c68b
 {
e3c68b
     glusterfs_graph_t *oldvolfile_graph = NULL;
e3c68b
     glusterfs_graph_t *newvolfile_graph = NULL;
e3c68b
@@ -1703,7 +1845,7 @@ glusterfs_mux_volfile_reconfigure(FILE *newvolfile_fp, glusterfs_ctx_t *ctx,
e3c68b
         }
e3c68b
         volfile_obj = NULL;
e3c68b
         ret = glusterfs_process_svc_attach_volfp(ctx, newvolfile_fp, vol_id,
e3c68b
-                                                 checksum);
e3c68b
+                                                 checksum, dict);
e3c68b
         goto out;
e3c68b
     }
e3c68b
 
e3c68b
diff --git a/rpc/xdr/src/glusterd1-xdr.x b/rpc/xdr/src/glusterd1-xdr.x
e3c68b
index 9b36d34..02ebec2 100644
e3c68b
--- a/rpc/xdr/src/glusterd1-xdr.x
e3c68b
+++ b/rpc/xdr/src/glusterd1-xdr.x
e3c68b
@@ -132,6 +132,7 @@ struct gd1_mgmt_brick_op_req {
e3c68b
         string  name<>;
e3c68b
         int     op;
e3c68b
         opaque  input<>;
e3c68b
+        opaque  dict<>;
e3c68b
 } ;
e3c68b
 
e3c68b
 struct gd1_mgmt_brick_op_rsp {
e3c68b
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
e3c68b
index af8a8a4..cc1f1df 100644
e3c68b
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
e3c68b
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
e3c68b
@@ -5423,6 +5423,8 @@ glusterd_print_client_details(FILE *fp, dict_t *dict,
e3c68b
 
e3c68b
     brick_req->op = GLUSTERD_BRICK_STATUS;
e3c68b
     brick_req->name = "";
e3c68b
+    brick_req->dict.dict_val = NULL;
e3c68b
+    brick_req->dict.dict_len = 0;
e3c68b
 
e3c68b
     ret = dict_set_strn(dict, "brick-name", SLEN("brick-name"),
e3c68b
                         brickinfo->path);
e3c68b
diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c
e3c68b
index 1ba58c3..86dec82 100644
e3c68b
--- a/xlators/mgmt/glusterd/src/glusterd-handshake.c
e3c68b
+++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c
e3c68b
@@ -203,7 +203,7 @@ out:
e3c68b
 
e3c68b
 size_t
e3c68b
 build_volfile_path(char *volume_id, char *path, size_t path_len,
e3c68b
-                   char *trusted_str)
e3c68b
+                   char *trusted_str, dict_t *dict)
e3c68b
 {
e3c68b
     struct stat stbuf = {
e3c68b
         0,
e3c68b
@@ -340,11 +340,19 @@ build_volfile_path(char *volume_id, char *path, size_t path_len,
e3c68b
 
e3c68b
         ret = glusterd_volinfo_find(volid_ptr, &volinfo);
e3c68b
         if (ret == -1) {
e3c68b
-            gf_log(this->name, GF_LOG_ERROR, "Couldn't find volinfo");
e3c68b
+            gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL,
e3c68b
+                   "Couldn't find volinfo for volid=%s", volid_ptr);
e3c68b
             goto out;
e3c68b
         }
e3c68b
 
e3c68b
         glusterd_svc_build_shd_volfile_path(volinfo, path, path_len);
e3c68b
+
e3c68b
+        ret = glusterd_svc_set_shd_pidfile(volinfo, dict);
e3c68b
+        if (ret == -1) {
e3c68b
+            gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
e3c68b
+                   "Couldn't set pidfile in dict for volid=%s", volid_ptr);
e3c68b
+            goto out;
e3c68b
+        }
e3c68b
         ret = 0;
e3c68b
         goto out;
e3c68b
     }
e3c68b
@@ -919,6 +927,7 @@ __server_getspec(rpcsvc_request_t *req)
e3c68b
     char addrstr[RPCSVC_PEER_STRLEN] = {0};
e3c68b
     peer_info_t *peerinfo = NULL;
e3c68b
     xlator_t *this = NULL;
e3c68b
+    dict_t *dict = NULL;
e3c68b
 
e3c68b
     this = THIS;
e3c68b
     GF_ASSERT(this);
e3c68b
@@ -971,6 +980,12 @@ __server_getspec(rpcsvc_request_t *req)
e3c68b
         goto fail;
e3c68b
     }
e3c68b
 
e3c68b
+    dict = dict_new();
e3c68b
+    if (!dict) {
e3c68b
+        ret = -ENOMEM;
e3c68b
+        goto fail;
e3c68b
+    }
e3c68b
+
e3c68b
     trans = req->trans;
e3c68b
     /* addrstr will be empty for cli socket connections */
e3c68b
     ret = rpcsvc_transport_peername(trans, (char *)&addrstr, sizeof(addrstr));
e3c68b
@@ -989,12 +1004,26 @@ __server_getspec(rpcsvc_request_t *req)
e3c68b
      */
e3c68b
     if (strlen(addrstr) == 0 || gf_is_local_addr(addrstr)) {
e3c68b
         ret = build_volfile_path(volume, filename, sizeof(filename),
e3c68b
-                                 TRUSTED_PREFIX);
e3c68b
+                                 TRUSTED_PREFIX, dict);
e3c68b
     } else {
e3c68b
-        ret = build_volfile_path(volume, filename, sizeof(filename), NULL);
e3c68b
+        ret = build_volfile_path(volume, filename, sizeof(filename), NULL,
e3c68b
+                                 dict);
e3c68b
     }
e3c68b
 
e3c68b
     if (ret == 0) {
e3c68b
+        if (dict->count > 0) {
e3c68b
+            ret = dict_allocate_and_serialize(dict, &rsp.xdata.xdata_val,
e3c68b
+                                              &rsp.xdata.xdata_len);
e3c68b
+            if (ret) {
e3c68b
+                gf_msg(this->name, GF_LOG_ERROR, 0,
e3c68b
+                       GD_MSG_DICT_SERL_LENGTH_GET_FAIL,
e3c68b
+                       "Failed to serialize dict "
e3c68b
+                       "to request buffer");
e3c68b
+                goto fail;
e3c68b
+            }
e3c68b
+            dict->extra_free = rsp.xdata.xdata_val;
e3c68b
+        }
e3c68b
+
e3c68b
         /* to allocate the proper buffer to hold the file data */
e3c68b
         ret = sys_stat(filename, &stbuf);
e3c68b
         if (ret < 0) {
e3c68b
@@ -1036,7 +1065,6 @@ __server_getspec(rpcsvc_request_t *req)
e3c68b
             goto fail;
e3c68b
         }
e3c68b
     }
e3c68b
-
e3c68b
     /* convert to XDR */
e3c68b
 fail:
e3c68b
     if (spec_fd >= 0)
e3c68b
@@ -1056,6 +1084,10 @@ fail:
e3c68b
                           (xdrproc_t)xdr_gf_getspec_rsp);
e3c68b
     free(args.key);  // malloced by xdr
e3c68b
     free(rsp.spec);
e3c68b
+
e3c68b
+    if (dict)
e3c68b
+        dict_unref(dict);
e3c68b
+
e3c68b
     if (args.xdata.xdata_val)
e3c68b
         free(args.xdata.xdata_val);
e3c68b
 
e3c68b
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
e3c68b
index 9ea695e..454877b 100644
e3c68b
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
e3c68b
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
e3c68b
@@ -655,6 +655,8 @@ glusterd_brick_op_build_payload(glusterd_op_t op,
e3c68b
             break;
e3c68b
     }
e3c68b
 
e3c68b
+    brick_req->dict.dict_len = 0;
e3c68b
+    brick_req->dict.dict_val = NULL;
e3c68b
     ret = dict_allocate_and_serialize(dict, &brick_req->input.input_val,
e3c68b
                                       &brick_req->input.input_len);
e3c68b
     if (ret)
e3c68b
@@ -723,6 +725,8 @@ glusterd_node_op_build_payload(glusterd_op_t op, gd1_mgmt_brick_op_req **req,
e3c68b
             goto out;
e3c68b
     }
e3c68b
 
e3c68b
+    brick_req->dict.dict_len = 0;
e3c68b
+    brick_req->dict.dict_val = NULL;
e3c68b
     ret = dict_allocate_and_serialize(dict, &brick_req->input.input_val,
e3c68b
                                       &brick_req->input.input_len);
e3c68b
 
e3c68b
diff --git a/xlators/mgmt/glusterd/src/glusterd-shd-svc-helper.c b/xlators/mgmt/glusterd/src/glusterd-shd-svc-helper.c
e3c68b
index 57ceda9..5661e39 100644
e3c68b
--- a/xlators/mgmt/glusterd/src/glusterd-shd-svc-helper.c
e3c68b
+++ b/xlators/mgmt/glusterd/src/glusterd-shd-svc-helper.c
e3c68b
@@ -126,3 +126,28 @@ glusterd_shd_svcproc_cleanup(glusterd_shdsvc_t *shd)
e3c68b
 out:
e3c68b
     return;
e3c68b
 }
e3c68b
+
e3c68b
+int
e3c68b
+glusterd_svc_set_shd_pidfile(glusterd_volinfo_t *volinfo, dict_t *dict)
e3c68b
+{
e3c68b
+    int ret = -1;
e3c68b
+    glusterd_svc_t *svc = NULL;
e3c68b
+    xlator_t *this = NULL;
e3c68b
+
e3c68b
+    this = THIS;
e3c68b
+    GF_VALIDATE_OR_GOTO("glusterd", this, out);
e3c68b
+    GF_VALIDATE_OR_GOTO(this->name, volinfo, out);
e3c68b
+    GF_VALIDATE_OR_GOTO(this->name, dict, out);
e3c68b
+
e3c68b
+    svc = &(volinfo->shd.svc);
e3c68b
+
e3c68b
+    ret = dict_set_dynstr_with_alloc(dict, "pidfile", svc->proc.pidfile);
e3c68b
+    if (ret) {
e3c68b
+        gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_SET_FAILED,
e3c68b
+               "Failed to set pidfile %s in dict", svc->proc.pidfile);
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+    ret = 0;
e3c68b
+out:
e3c68b
+    return ret;
e3c68b
+}
e3c68b
diff --git a/xlators/mgmt/glusterd/src/glusterd-shd-svc-helper.h b/xlators/mgmt/glusterd/src/glusterd-shd-svc-helper.h
e3c68b
index 59466ec..1f0984b 100644
e3c68b
--- a/xlators/mgmt/glusterd/src/glusterd-shd-svc-helper.h
e3c68b
+++ b/xlators/mgmt/glusterd/src/glusterd-shd-svc-helper.h
e3c68b
@@ -36,4 +36,7 @@ glusterd_recover_shd_attach_failure(glusterd_volinfo_t *volinfo,
e3c68b
 int
e3c68b
 glusterd_shdsvc_create_volfile(glusterd_volinfo_t *volinfo);
e3c68b
 
e3c68b
+int
e3c68b
+glusterd_svc_set_shd_pidfile(glusterd_volinfo_t *volinfo, dict_t *dict);
e3c68b
+
e3c68b
 #endif
e3c68b
diff --git a/xlators/mgmt/glusterd/src/glusterd-shd-svc.c b/xlators/mgmt/glusterd/src/glusterd-shd-svc.c
e3c68b
index 8ad90a9..590169f 100644
e3c68b
--- a/xlators/mgmt/glusterd/src/glusterd-shd-svc.c
e3c68b
+++ b/xlators/mgmt/glusterd/src/glusterd-shd-svc.c
e3c68b
@@ -258,14 +258,20 @@ glusterd_shdsvc_manager(glusterd_svc_t *svc, void *data, int flags)
e3c68b
     gf_boolean_t shd_restart = _gf_false;
e3c68b
 
e3c68b
     conf = THIS->private;
e3c68b
-    volinfo = data;
e3c68b
     GF_VALIDATE_OR_GOTO("glusterd", conf, out);
e3c68b
     GF_VALIDATE_OR_GOTO("glusterd", svc, out);
e3c68b
+    volinfo = data;
e3c68b
     GF_VALIDATE_OR_GOTO("glusterd", volinfo, out);
e3c68b
 
e3c68b
     if (volinfo)
e3c68b
         glusterd_volinfo_ref(volinfo);
e3c68b
 
e3c68b
+    if (volinfo->is_snap_volume) {
e3c68b
+        /* healing of a snap volume is not supported yet*/
e3c68b
+        ret = 0;
e3c68b
+        goto out;
e3c68b
+    }
e3c68b
+
e3c68b
     while (conf->restart_shd) {
e3c68b
         synclock_unlock(&conf->big_lock);
e3c68b
         sleep(2);
e3c68b
diff --git a/xlators/mgmt/glusterd/src/glusterd-svc-helper.c b/xlators/mgmt/glusterd/src/glusterd-svc-helper.c
e3c68b
index 400826f..e106111 100644
e3c68b
--- a/xlators/mgmt/glusterd/src/glusterd-svc-helper.c
e3c68b
+++ b/xlators/mgmt/glusterd/src/glusterd-svc-helper.c
e3c68b
@@ -519,7 +519,7 @@ glusterd_shd_svc_mux_init(glusterd_volinfo_t *volinfo, glusterd_svc_t *svc)
e3c68b
                 /* Take first entry from the process */
e3c68b
                 parent_svc = cds_list_entry(mux_proc->svcs.next, glusterd_svc_t,
e3c68b
                                             mux_svc);
e3c68b
-                sys_link(parent_svc->proc.pidfile, svc->proc.pidfile);
e3c68b
+                glusterd_copy_file(parent_svc->proc.pidfile, svc->proc.pidfile);
e3c68b
                 mux_conn = &parent_svc->conn;
e3c68b
                 if (volinfo)
e3c68b
                     volinfo->shd.attached = _gf_true;
e3c68b
@@ -623,12 +623,9 @@ glusterd_svc_attach_cbk(struct rpc_req *req, struct iovec *iov, int count,
e3c68b
     glusterd_volinfo_t *volinfo = NULL;
e3c68b
     glusterd_shdsvc_t *shd = NULL;
e3c68b
     glusterd_svc_t *svc = frame->cookie;
e3c68b
-    glusterd_svc_t *parent_svc = NULL;
e3c68b
-    glusterd_svc_proc_t *mux_proc = NULL;
e3c68b
     glusterd_conf_t *conf = NULL;
e3c68b
     int *flag = (int *)frame->local;
e3c68b
     xlator_t *this = THIS;
e3c68b
-    int pid = -1;
e3c68b
     int ret = -1;
e3c68b
     gf_getspec_rsp rsp = {
e3c68b
         0,
e3c68b
@@ -679,27 +676,7 @@ glusterd_svc_attach_cbk(struct rpc_req *req, struct iovec *iov, int count,
e3c68b
     }
e3c68b
 
e3c68b
     if (rsp.op_ret == 0) {
e3c68b
-        pthread_mutex_lock(&conf->attach_lock);
e3c68b
-        {
e3c68b
-            if (!strcmp(svc->name, "glustershd")) {
e3c68b
-                mux_proc = svc->svc_proc;
e3c68b
-                if (mux_proc &&
e3c68b
-                    !gf_is_service_running(svc->proc.pidfile, &pid)) {
e3c68b
-                    /*
e3c68b
-                     * When svc's are restarting, there is a chance that the
e3c68b
-                     * attached svc might not have updated it's pid. Because
e3c68b
-                     * it was at connection stage. So in that case, we need
e3c68b
-                     * to retry the pid file copy.
e3c68b
-                     */
e3c68b
-                    parent_svc = cds_list_entry(mux_proc->svcs.next,
e3c68b
-                                                glusterd_svc_t, mux_svc);
e3c68b
-                    if (parent_svc)
e3c68b
-                        sys_link(parent_svc->proc.pidfile, svc->proc.pidfile);
e3c68b
-                }
e3c68b
-            }
e3c68b
-            svc->online = _gf_true;
e3c68b
-        }
e3c68b
-        pthread_mutex_unlock(&conf->attach_lock);
e3c68b
+        svc->online = _gf_true;
e3c68b
         gf_msg(this->name, GF_LOG_INFO, 0, GD_MSG_SVC_ATTACH_FAIL,
e3c68b
                "svc %s of volume %s attached successfully to pid %d", svc->name,
e3c68b
                volinfo->volname, glusterd_proc_get_pid(&svc->proc));
e3c68b
@@ -726,7 +703,7 @@ out:
e3c68b
 
e3c68b
 extern size_t
e3c68b
 build_volfile_path(char *volume_id, char *path, size_t path_len,
e3c68b
-                   char *trusted_str);
e3c68b
+                   char *trusted_str, dict_t *dict);
e3c68b
 
e3c68b
 int
e3c68b
 __glusterd_send_svc_configure_req(glusterd_svc_t *svc, int flags,
e3c68b
@@ -751,6 +728,7 @@ __glusterd_send_svc_configure_req(glusterd_svc_t *svc, int flags,
e3c68b
     ssize_t req_size = 0;
e3c68b
     call_frame_t *frame = NULL;
e3c68b
     gd1_mgmt_brick_op_req brick_req;
e3c68b
+    dict_t *dict = NULL;
e3c68b
     void *req = &brick_req;
e3c68b
     void *errlbl = &&err;
e3c68b
     struct rpc_clnt_connection *conn;
e3c68b
@@ -776,6 +754,8 @@ __glusterd_send_svc_configure_req(glusterd_svc_t *svc, int flags,
e3c68b
     brick_req.name = volfile_id;
e3c68b
     brick_req.input.input_val = NULL;
e3c68b
     brick_req.input.input_len = 0;
e3c68b
+    brick_req.dict.dict_val = NULL;
e3c68b
+    brick_req.dict.dict_len = 0;
e3c68b
 
e3c68b
     frame = create_frame(this, this->ctx->pool);
e3c68b
     if (!frame) {
e3c68b
@@ -783,7 +763,13 @@ __glusterd_send_svc_configure_req(glusterd_svc_t *svc, int flags,
e3c68b
     }
e3c68b
 
e3c68b
     if (op == GLUSTERD_SVC_ATTACH) {
e3c68b
-        (void)build_volfile_path(volfile_id, path, sizeof(path), NULL);
e3c68b
+        dict = dict_new();
e3c68b
+        if (!dict) {
e3c68b
+            ret = -ENOMEM;
e3c68b
+            goto *errlbl;
e3c68b
+        }
e3c68b
+
e3c68b
+        (void)build_volfile_path(volfile_id, path, sizeof(path), NULL, dict);
e3c68b
 
e3c68b
         ret = sys_stat(path, &stbuf);
e3c68b
         if (ret < 0) {
e3c68b
@@ -818,6 +804,18 @@ __glusterd_send_svc_configure_req(glusterd_svc_t *svc, int flags,
e3c68b
             ret = -EIO;
e3c68b
             goto *errlbl;
e3c68b
         }
e3c68b
+        if (dict->count > 0) {
e3c68b
+            ret = dict_allocate_and_serialize(dict, &brick_req.dict.dict_val,
e3c68b
+                                              &brick_req.dict.dict_len);
e3c68b
+            if (ret) {
e3c68b
+                gf_msg(this->name, GF_LOG_ERROR, 0,
e3c68b
+                       GD_MSG_DICT_SERL_LENGTH_GET_FAIL,
e3c68b
+                       "Failed to serialize dict "
e3c68b
+                       "to request buffer");
e3c68b
+                goto *errlbl;
e3c68b
+            }
e3c68b
+            dict->extra_free = brick_req.dict.dict_val;
e3c68b
+        }
e3c68b
 
e3c68b
         frame->cookie = svc;
e3c68b
         frame->local = GF_CALLOC(1, sizeof(int), gf_gld_mt_int);
e3c68b
@@ -862,6 +860,8 @@ __glusterd_send_svc_configure_req(glusterd_svc_t *svc, int flags,
e3c68b
     GF_ATOMIC_INC(conf->blockers);
e3c68b
     ret = rpc_clnt_submit(rpc, &gd_brick_prog, op, cbkfn, &iov, 1, NULL, 0,
e3c68b
                           iobref, frame, NULL, 0, NULL, 0, NULL);
e3c68b
+    if (dict)
e3c68b
+        dict_unref(dict);
e3c68b
     GF_FREE(volfile_content);
e3c68b
     if (spec_fd >= 0)
e3c68b
         sys_close(spec_fd);
e3c68b
@@ -874,6 +874,9 @@ maybe_free_iobuf:
e3c68b
         iobuf_unref(iobuf);
e3c68b
     }
e3c68b
 err:
e3c68b
+    if (dict)
e3c68b
+        dict_unref(dict);
e3c68b
+
e3c68b
     GF_FREE(volfile_content);
e3c68b
     if (spec_fd >= 0)
e3c68b
         sys_close(spec_fd);
e3c68b
diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c
e3c68b
index 618d8bc..a8098df 100644
e3c68b
--- a/xlators/mgmt/glusterd/src/glusterd-syncop.c
e3c68b
+++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c
e3c68b
@@ -143,6 +143,8 @@ gd_brick_op_req_free(gd1_mgmt_brick_op_req *req)
e3c68b
     if (!req)
e3c68b
         return;
e3c68b
 
e3c68b
+    if (req->dict.dict_val)
e3c68b
+        GF_FREE(req->dict.dict_val);
e3c68b
     GF_FREE(req->input.input_val);
e3c68b
     GF_FREE(req);
e3c68b
 }
e3c68b
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
e3c68b
index 4c487d0..2eb5116 100644
e3c68b
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
e3c68b
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
e3c68b
@@ -5914,6 +5914,8 @@ send_attach_req(xlator_t *this, struct rpc_clnt *rpc, char *path,
e3c68b
     brick_req.name = path;
e3c68b
     brick_req.input.input_val = NULL;
e3c68b
     brick_req.input.input_len = 0;
e3c68b
+    brick_req.dict.dict_val = NULL;
e3c68b
+    brick_req.dict.dict_len = 0;
e3c68b
 
e3c68b
     req_size = xdr_sizeof((xdrproc_t)xdr_gd1_mgmt_brick_op_req, req);
e3c68b
     iobuf = iobuf_get2(rpc->ctx->iobuf_pool, req_size);
e3c68b
@@ -5977,7 +5979,7 @@ err:
e3c68b
 
e3c68b
 extern size_t
e3c68b
 build_volfile_path(char *volume_id, char *path, size_t path_len,
e3c68b
-                   char *trusted_str);
e3c68b
+                   char *trusted_str, dict_t *dict);
e3c68b
 
e3c68b
 static int
e3c68b
 attach_brick(xlator_t *this, glusterd_brickinfo_t *brickinfo,
e3c68b
@@ -6022,7 +6024,7 @@ attach_brick(xlator_t *this, glusterd_brickinfo_t *brickinfo,
e3c68b
         goto out;
e3c68b
     }
e3c68b
 
e3c68b
-    (void)build_volfile_path(full_id, path, sizeof(path), NULL);
e3c68b
+    (void)build_volfile_path(full_id, path, sizeof(path), NULL, NULL);
e3c68b
 
e3c68b
     for (tries = 15; tries > 0; --tries) {
e3c68b
         rpc = rpc_clnt_ref(other_brick->rpc);
e3c68b
-- 
e3c68b
1.8.3.1
e3c68b