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