21ab4e
From d89f9b3b57b970bc479c5ef8abe7f18549d0e90b Mon Sep 17 00:00:00 2001
21ab4e
From: Mohammed Rafi KC <rkavunga@redhat.com>
21ab4e
Date: Thu, 6 Jul 2017 13:26:42 +0530
21ab4e
Subject: [PATCH 557/557] mgtm/core : use sha hash function for volfile check
21ab4e
21ab4e
We are storing the entire volfile and using this to check
21ab4e
volfile change. With brick multiplexing there will be lot
21ab4e
of graphs per process which will increase the memory foot
21ab4e
print of the process. So instead of storing the entire
21ab4e
graph we could use sha256 and we can compare the hash to
21ab4e
see whether volfile change happened or not.
21ab4e
21ab4e
Also with Brick multiplexing, the direct comparison of vol
21ab4e
file is not correct. There are two problems.
21ab4e
21ab4e
Problem 1:
21ab4e
21ab4e
We are currently storing one single graph (the last
21ab4e
updated volfile) whereas, what we need is the entire
21ab4e
graph with all atttached bricks.
21ab4e
21ab4e
If we fix this issue, we have second problem
21ab4e
21ab4e
Problem 2:
21ab4e
With multiplexing we have a graph that contains multiple
21ab4e
bricks. But what we are checking as part of the reconfigure
21ab4e
is, comparing the entire graph with one single graph,
21ab4e
which will always fail.
21ab4e
21ab4e
Solution:
21ab4e
We create list in glusterfs_ctx_t that stores sha256 hash
21ab4e
of individual brick graphs. When a graph changes happens
21ab4e
we compare the stored hash and the current hash. If the
21ab4e
hash matches, then no need for reconfigure. Otherwise we
21ab4e
first do the reconfigure and then update the hash.
21ab4e
21ab4e
For now, gfapi has not changed this way. Meaning when gfapi
21ab4e
volfile fetch or reconfigure happens, we still store the
21ab4e
entire graph and compare, each memory.
21ab4e
21ab4e
This is fine, because libgfapi will not load brick graphs.
21ab4e
But changing the libgfapi will make the code similar in
21ab4e
both glusterfsd-mgmt and api. Also it helps to reduce some
21ab4e
memory.
21ab4e
21ab4e
 >Change-Id: I9df917a771a52b95622ab8f63af34ec390163a77
21ab4e
 >BUG: 1467986
21ab4e
 >Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
21ab4e
 >Reviewed-on: https://review.gluster.org/17709
21ab4e
 >Smoke: Gluster Build System <jenkins@build.gluster.org>
21ab4e
 >Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
21ab4e
 >CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
21ab4e
 >Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
21ab4e
 >Reviewed-by: Amar Tumballi <amarts@redhat.com>
21ab4e
21ab4e
Change-Id: I9df917a771a52b95622ab8f63af34ec390163a77
21ab4e
BUG: 1457936
21ab4e
Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
21ab4e
Signed-off-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
21ab4e
Reviewed-on: https://code.engineering.redhat.com/gerrit/111802
21ab4e
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
21ab4e
---
21ab4e
 api/src/glfs-mgmt.c                  |   4 +-
21ab4e
 glusterfsd/src/glusterfsd-mgmt.c     |  98 +++++++++++++++--------
21ab4e
 libglusterfs/src/common-utils.c      |  12 +++
21ab4e
 libglusterfs/src/common-utils.h      |   5 ++
21ab4e
 libglusterfs/src/ctx.c               |   1 +
21ab4e
 libglusterfs/src/glusterfs.h         |   9 +++
21ab4e
 libglusterfs/src/graph.c             | 145 ++++++++++++++++++++++++++++++++---
21ab4e
 libglusterfs/src/mem-types.h         |   1 +
21ab4e
 libglusterfs/src/xlator.c            |  26 +++++++
21ab4e
 libglusterfs/src/xlator.h            |  11 ++-
21ab4e
 xlators/protocol/server/src/server.c |   3 +
21ab4e
 11 files changed, 268 insertions(+), 47 deletions(-)
21ab4e
21ab4e
diff --git a/api/src/glfs-mgmt.c b/api/src/glfs-mgmt.c
21ab4e
index 0109764..0b60092 100644
21ab4e
--- a/api/src/glfs-mgmt.c
21ab4e
+++ b/api/src/glfs-mgmt.c
21ab4e
@@ -648,8 +648,8 @@ glfs_mgmt_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count,
21ab4e
 	*  return -1(or -ve) =======> Some Internal Error occurred during the operation
21ab4e
 	*/
21ab4e
 
21ab4e
-	ret = glusterfs_volfile_reconfigure (fs->oldvollen, tmpfp, fs->ctx,
21ab4e
-					     fs->oldvolfile);
21ab4e
+        ret = gf_volfile_reconfigure (fs->oldvollen, tmpfp, fs->ctx,
21ab4e
+                                      fs->oldvolfile);
21ab4e
 	if (ret == 0) {
21ab4e
 		gf_msg_debug ("glusterfsd-mgmt", 0, "No need to re-load "
21ab4e
                               "volfile, reconfigure done");
21ab4e
diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c
21ab4e
index 365706e..bde49ba 100644
21ab4e
--- a/glusterfsd/src/glusterfsd-mgmt.c
21ab4e
+++ b/glusterfsd/src/glusterfsd-mgmt.c
21ab4e
@@ -1763,12 +1763,6 @@ out:
21ab4e
         return ret;
21ab4e
 }
21ab4e
 
21ab4e
-
21ab4e
-/* XXX: move these into @ctx */
21ab4e
-static char *oldvolfile = NULL;
21ab4e
-static int   oldvollen;
21ab4e
-
21ab4e
-
21ab4e
 int
21ab4e
 mgmt_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count,
21ab4e
                   void *myframe)
21ab4e
@@ -1779,7 +1773,10 @@ mgmt_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count,
21ab4e
         int                      ret   = 0, locked = 0;
21ab4e
         ssize_t                  size = 0;
21ab4e
         FILE                    *tmpfp = NULL;
21ab4e
-        char                    *volfilebuf = NULL;
21ab4e
+        char                    *volfile_id = NULL;
21ab4e
+        gf_volfile_t            *volfile_obj = NULL;
21ab4e
+        gf_volfile_t            *volfile_tmp = NULL;
21ab4e
+        char                     sha256_hash[SHA256_DIGEST_LENGTH] = {0, };
21ab4e
 
21ab4e
         frame = myframe;
21ab4e
         ctx = frame->this->ctx;
21ab4e
@@ -1806,14 +1803,29 @@ mgmt_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count,
21ab4e
         ret = 0;
21ab4e
         size = rsp.op_ret;
21ab4e
 
21ab4e
+        glusterfs_compute_sha256 ((const unsigned char *) rsp.spec, size,
21ab4e
+                                  sha256_hash);
21ab4e
+
21ab4e
+        volfile_id = frame->local;
21ab4e
+
21ab4e
         LOCK (&ctx->volfile_lock);
21ab4e
         {
21ab4e
                 locked = 1;
21ab4e
 
21ab4e
-                if (size == oldvollen && (memcmp (oldvolfile, rsp.spec, size) == 0)) {
21ab4e
-                        gf_log (frame->this->name, GF_LOG_INFO,
21ab4e
-                                "No change in volfile, continuing");
21ab4e
-                        goto out;
21ab4e
+                list_for_each_entry (volfile_obj,  &ctx->volfile_list,
21ab4e
+                                     volfile_list) {
21ab4e
+                        if (!strcmp (volfile_id, volfile_obj->vol_id)) {
21ab4e
+                               if (!strncmp (sha256_hash,
21ab4e
+                                      volfile_obj->volfile_checksum,
21ab4e
+                                      sizeof (volfile_obj->volfile_checksum))) {
21ab4e
+                                        gf_log (frame->this->name, GF_LOG_INFO,
21ab4e
+                                                "No change in volfile,"
21ab4e
+                                                "continuing");
21ab4e
+                                        goto out;
21ab4e
+                               }
21ab4e
+                               volfile_tmp = volfile_obj;
21ab4e
+                               break;
21ab4e
+                        }
21ab4e
                 }
21ab4e
 
21ab4e
                 tmpfp = tmpfile ();
21ab4e
@@ -1837,21 +1849,19 @@ mgmt_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count,
21ab4e
                  *  return -1(or -ve) =======> Some Internal Error occurred during the operation
21ab4e
                  */
21ab4e
 
21ab4e
-                ret = glusterfs_volfile_reconfigure (oldvollen, tmpfp, ctx, oldvolfile);
21ab4e
+                ret = glusterfs_volfile_reconfigure (tmpfp, ctx);
21ab4e
                 if (ret == 0) {
21ab4e
                         gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG,
21ab4e
                                 "No need to re-load volfile, reconfigure done");
21ab4e
-                        if (oldvolfile)
21ab4e
-                                volfilebuf = GF_REALLOC (oldvolfile, size);
21ab4e
-                        else
21ab4e
-                                volfilebuf = GF_CALLOC (1, size, gf_common_mt_char);
21ab4e
-                        if (!volfilebuf) {
21ab4e
+                        if (!volfile_tmp) {
21ab4e
                                 ret = -1;
21ab4e
+                                gf_log ("mgmt", GF_LOG_ERROR, "Graph "
21ab4e
+                                        "reconfigure succeeded with out having "
21ab4e
+                                        "checksum.");
21ab4e
                                 goto out;
21ab4e
                         }
21ab4e
-                        oldvolfile = volfilebuf;
21ab4e
-                        oldvollen = size;
21ab4e
-                        memcpy (oldvolfile, rsp.spec, size);
21ab4e
+                        strncpy (volfile_tmp->volfile_checksum, sha256_hash,
21ab4e
+                                 sizeof (volfile_tmp->volfile_checksum));
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
 
21ab4e
@@ -1867,19 +1877,23 @@ mgmt_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count,
21ab4e
                 if (ret)
21ab4e
                         goto out;
21ab4e
 
21ab4e
-                if (oldvolfile)
21ab4e
-                        volfilebuf = GF_REALLOC (oldvolfile, size);
21ab4e
-                else
21ab4e
-                        volfilebuf = GF_CALLOC (1, size, gf_common_mt_char);
21ab4e
+                if (!volfile_tmp) {
21ab4e
+                        volfile_tmp = GF_CALLOC (1, sizeof (gf_volfile_t),
21ab4e
+                                                 gf_common_volfile_t);
21ab4e
+                        if (!volfile_tmp) {
21ab4e
+                                ret = -1;
21ab4e
+                                goto out;
21ab4e
+                        }
21ab4e
 
21ab4e
-                if (!volfilebuf) {
21ab4e
-                        ret = -1;
21ab4e
-                        goto out;
21ab4e
+                        INIT_LIST_HEAD (&volfile_tmp->volfile_list);
21ab4e
+                        list_add (&volfile_tmp->volfile_list,
21ab4e
+                                  &ctx->volfile_list);
21ab4e
+                        snprintf (volfile_tmp->vol_id,
21ab4e
+                                  sizeof (volfile_tmp->vol_id), "%s",
21ab4e
+                                  volfile_id);
21ab4e
                 }
21ab4e
-
21ab4e
-                oldvolfile = volfilebuf;
21ab4e
-                oldvollen = size;
21ab4e
-                memcpy (oldvolfile, rsp.spec, size);
21ab4e
+                strncpy (volfile_tmp->volfile_checksum, sha256_hash,
21ab4e
+                         sizeof (volfile_tmp->volfile_checksum));
21ab4e
         }
21ab4e
         UNLOCK (&ctx->volfile_lock);
21ab4e
 
21ab4e
@@ -1896,7 +1910,11 @@ out:
21ab4e
         if (locked)
21ab4e
                 UNLOCK (&ctx->volfile_lock);
21ab4e
 
21ab4e
-        STACK_DESTROY (frame->root);
21ab4e
+        if (frame) {
21ab4e
+                GF_FREE (frame->local);
21ab4e
+                frame->local = NULL;
21ab4e
+                STACK_DESTROY (frame->root);
21ab4e
+        }
21ab4e
 
21ab4e
         free (rsp.spec);
21ab4e
 
21ab4e
@@ -1943,6 +1961,15 @@ glusterfs_volfile_fetch_one (glusterfs_ctx_t *ctx, char *volfile_id)
21ab4e
 
21ab4e
         req.key = volfile_id;
21ab4e
         req.flags = 0;
21ab4e
+        /*
21ab4e
+         * We are only storing one variable in local, hence using the same
21ab4e
+         * variable. If multiple local variable is required, create a struct.
21ab4e
+         */
21ab4e
+        frame->local = gf_strdup (volfile_id);
21ab4e
+        if (!frame->local) {
21ab4e
+                ret = -1;
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
 
21ab4e
         dict = dict_new ();
21ab4e
         if (!dict) {
21ab4e
@@ -1992,6 +2019,13 @@ out:
21ab4e
         GF_FREE (req.xdata.xdata_val);
21ab4e
         if (dict)
21ab4e
                 dict_unref (dict);
21ab4e
+        if (ret && frame) {
21ab4e
+                /* Free the frame->local fast, because we have not used memget
21ab4e
+                 */
21ab4e
+                GF_FREE (frame->local);
21ab4e
+                frame->local = NULL;
21ab4e
+                STACK_DESTROY (frame->root);
21ab4e
+        }
21ab4e
 
21ab4e
         return ret;
21ab4e
 }
21ab4e
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
21ab4e
index c123f70..6c02039 100644
21ab4e
--- a/libglusterfs/src/common-utils.c
21ab4e
+++ b/libglusterfs/src/common-utils.c
21ab4e
@@ -4926,3 +4926,15 @@ gf_getgrouplist (const char *user, gid_t group, gid_t **groups)
21ab4e
         }
21ab4e
         return ret;
21ab4e
 }
21ab4e
+
21ab4e
+int
21ab4e
+glusterfs_compute_sha256 (const unsigned char *content, size_t size,
21ab4e
+                          char *sha256_hash) {
21ab4e
+        SHA256_CTX               sha256;
21ab4e
+
21ab4e
+        SHA256_Init (&sha256);
21ab4e
+        SHA256_Update (&sha256, (const unsigned char *) (content), size);
21ab4e
+        SHA256_Final ((unsigned char *) sha256_hash, &sha256);
21ab4e
+
21ab4e
+        return 0;
21ab4e
+}
21ab4e
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
21ab4e
index 4765b5e..89d71a6 100644
21ab4e
--- a/libglusterfs/src/common-utils.h
21ab4e
+++ b/libglusterfs/src/common-utils.h
21ab4e
@@ -906,4 +906,9 @@ close_fds_except (int *fdv, size_t count);
21ab4e
 
21ab4e
 int
21ab4e
 gf_getgrouplist (const char *user, gid_t group, gid_t **groups);
21ab4e
+
21ab4e
+int
21ab4e
+glusterfs_compute_sha256 (const unsigned char *content, size_t size,
21ab4e
+                          char *sha256_hash);
21ab4e
+
21ab4e
 #endif /* _COMMON_UTILS_H */
21ab4e
diff --git a/libglusterfs/src/ctx.c b/libglusterfs/src/ctx.c
21ab4e
index 1f2f1a1..35f1928 100644
21ab4e
--- a/libglusterfs/src/ctx.c
21ab4e
+++ b/libglusterfs/src/ctx.c
21ab4e
@@ -32,6 +32,7 @@ glusterfs_ctx_new ()
21ab4e
 
21ab4e
         INIT_LIST_HEAD (&ctx->graphs);
21ab4e
 	INIT_LIST_HEAD (&ctx->mempool_list);
21ab4e
+        INIT_LIST_HEAD (&ctx->volfile_list);
21ab4e
 
21ab4e
 	ctx->daemon_pipe[0] = -1;
21ab4e
 	ctx->daemon_pipe[1] = -1;
21ab4e
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h
21ab4e
index 43acf4c..c58cae1 100644
21ab4e
--- a/libglusterfs/src/glusterfs.h
21ab4e
+++ b/libglusterfs/src/glusterfs.h
21ab4e
@@ -28,6 +28,7 @@
21ab4e
 #include <sys/poll.h>
21ab4e
 #include <pthread.h>
21ab4e
 #include <limits.h> /* For PATH_MAX */
21ab4e
+#include <openssl/sha.h>
21ab4e
 
21ab4e
 #include "glusterfs-fops.h" /* generated XDR values for FOPs */
21ab4e
 
21ab4e
@@ -513,9 +514,17 @@ struct _glusterfs_ctx {
21ab4e
         struct gf_ctx_tw   *tw; /* refcounted timer_wheel */
21ab4e
 
21ab4e
         gf_lock_t           volfile_lock;
21ab4e
+        struct list_head volfile_list;
21ab4e
 };
21ab4e
 typedef struct _glusterfs_ctx glusterfs_ctx_t;
21ab4e
 
21ab4e
+typedef struct {
21ab4e
+        char volfile_checksum[SHA256_DIGEST_LENGTH];
21ab4e
+        char vol_id[NAME_MAX+1];
21ab4e
+        struct list_head volfile_list;
21ab4e
+
21ab4e
+} gf_volfile_t;
21ab4e
+
21ab4e
 glusterfs_ctx_t *glusterfs_ctx_new (void);
21ab4e
 
21ab4e
 struct gf_flock {
21ab4e
diff --git a/libglusterfs/src/graph.c b/libglusterfs/src/graph.c
21ab4e
index 4c6321e..126f318 100644
21ab4e
--- a/libglusterfs/src/graph.c
21ab4e
+++ b/libglusterfs/src/graph.c
21ab4e
@@ -814,8 +814,70 @@ out:
21ab4e
  *   return -1(or -ve) =======> Some Internal Error occurred during the operation
21ab4e
  */
21ab4e
 int
21ab4e
-glusterfs_volfile_reconfigure (int oldvollen, FILE *newvolfile_fp,
21ab4e
-                               glusterfs_ctx_t *ctx, const char *oldvolfile)
21ab4e
+glusterfs_volfile_reconfigure (FILE *newvolfile_fp, glusterfs_ctx_t *ctx)
21ab4e
+{
21ab4e
+        glusterfs_graph_t *oldvolfile_graph = NULL;
21ab4e
+        glusterfs_graph_t *newvolfile_graph = NULL;
21ab4e
+
21ab4e
+        int ret = -1;
21ab4e
+
21ab4e
+        if (!ctx) {
21ab4e
+                gf_msg ("glusterfsd-mgmt", GF_LOG_ERROR, 0, LG_MSG_CTX_NULL,
21ab4e
+                        "ctx is NULL");
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
+
21ab4e
+        oldvolfile_graph = ctx->active;
21ab4e
+        if (!oldvolfile_graph) {
21ab4e
+                ret = 1;
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
+
21ab4e
+        newvolfile_graph = glusterfs_graph_construct (newvolfile_fp);
21ab4e
+
21ab4e
+        if (!newvolfile_graph) {
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
+
21ab4e
+        glusterfs_graph_prepare (newvolfile_graph, ctx,
21ab4e
+                                 ctx->cmd_args.volume_name);
21ab4e
+
21ab4e
+        if (!is_graph_topology_equal (oldvolfile_graph,
21ab4e
+                                      newvolfile_graph)) {
21ab4e
+
21ab4e
+                ret = 1;
21ab4e
+                gf_msg_debug ("glusterfsd-mgmt", 0, "Graph topology not "
21ab4e
+                              "equal(should call INIT)");
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
+
21ab4e
+        gf_msg_debug ("glusterfsd-mgmt", 0, "Only options have changed in the"
21ab4e
+                      " new graph");
21ab4e
+
21ab4e
+        ret = glusterfs_graph_reconfigure (oldvolfile_graph,
21ab4e
+                                           newvolfile_graph);
21ab4e
+        if (ret) {
21ab4e
+                gf_msg_debug ("glusterfsd-mgmt", 0, "Could not reconfigure "
21ab4e
+                              "new options in old graph");
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
+
21ab4e
+        ret = 0;
21ab4e
+out:
21ab4e
+
21ab4e
+        if (newvolfile_graph)
21ab4e
+                glusterfs_graph_destroy (newvolfile_graph);
21ab4e
+
21ab4e
+        return ret;
21ab4e
+}
21ab4e
+
21ab4e
+/* This function need to remove. This added to support gfapi volfile
21ab4e
+ * reconfigure.
21ab4e
+ */
21ab4e
+
21ab4e
+int
21ab4e
+gf_volfile_reconfigure (int oldvollen, FILE *newvolfile_fp,
21ab4e
+                        glusterfs_ctx_t *ctx, const char *oldvolfile)
21ab4e
 {
21ab4e
         glusterfs_graph_t *oldvolfile_graph = NULL;
21ab4e
         glusterfs_graph_t *newvolfile_graph = NULL;
21ab4e
@@ -837,9 +899,9 @@ glusterfs_volfile_reconfigure (int oldvollen, FILE *newvolfile_fp,
21ab4e
 
21ab4e
         if (!ctx) {
21ab4e
                 gf_msg ("glusterfsd-mgmt", GF_LOG_ERROR, 0, LG_MSG_CTX_NULL,
21ab4e
-			"ctx is NULL");
21ab4e
-		goto out;
21ab4e
-	}
21ab4e
+                        "ctx is NULL");
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
 
21ab4e
         oldvolfile_graph = ctx->active;
21ab4e
         if (!oldvolfile_graph) {
21ab4e
@@ -890,7 +952,7 @@ glusterfs_volfile_reconfigure (int oldvollen, FILE *newvolfile_fp,
21ab4e
                 goto out;
21ab4e
         }
21ab4e
 
21ab4e
-	glusterfs_graph_prepare (newvolfile_graph, ctx,
21ab4e
+        glusterfs_graph_prepare (newvolfile_graph, ctx,
21ab4e
                                  ctx->cmd_args.volume_name);
21ab4e
 
21ab4e
         if (!is_graph_topology_equal (oldvolfile_graph,
21ab4e
@@ -934,7 +996,6 @@ out:
21ab4e
         return ret;
21ab4e
 }
21ab4e
 
21ab4e
-
21ab4e
 int
21ab4e
 glusterfs_graph_reconfigure (glusterfs_graph_t *oldgraph,
21ab4e
                              glusterfs_graph_t *newgraph)
21ab4e
@@ -1038,19 +1099,56 @@ glusterfs_graph_attach (glusterfs_graph_t *orig_graph, char *path,
21ab4e
         FILE                    *fp;
21ab4e
         glusterfs_graph_t       *graph;
21ab4e
         xlator_t                *xl;
21ab4e
-        char                    *volfile_id;
21ab4e
+        char                    *volfile_id                        = NULL;
21ab4e
+        char                    *volfile_content                   = NULL;
21ab4e
+        struct stat              stbuf                             = {0,};
21ab4e
+        size_t                   file_len                          = -1;
21ab4e
+        gf_volfile_t            *volfile_obj                       = NULL;
21ab4e
+        int                      ret                               = -1;
21ab4e
+        char                     sha256_hash[SHA256_DIGEST_LENGTH] = {0, };
21ab4e
 
21ab4e
         if (!orig_graph) {
21ab4e
                 return -EINVAL;
21ab4e
         }
21ab4e
 
21ab4e
+        ret = sys_stat (path, &stbuf);
21ab4e
+        if (ret < 0) {
21ab4e
+                gf_log (THIS->name, GF_LOG_ERROR, "Unable to stat %s (%s)",
21ab4e
+                        path, strerror (errno));
21ab4e
+                return -EINVAL;
21ab4e
+        }
21ab4e
+
21ab4e
+        file_len = stbuf.st_size;
21ab4e
+        if (file_len) {
21ab4e
+                volfile_content = GF_CALLOC (file_len+1, sizeof (char),
21ab4e
+                                             gf_common_mt_char);
21ab4e
+                if (!volfile_content) {
21ab4e
+                        return -ENOMEM;
21ab4e
+                }
21ab4e
+        }
21ab4e
+
21ab4e
         fp = fopen (path, "r");
21ab4e
         if (!fp) {
21ab4e
                 gf_log (THIS->name, GF_LOG_WARNING,
21ab4e
                         "oops, %s disappeared on us", path);
21ab4e
+                GF_FREE (volfile_content);
21ab4e
+                return -EIO;
21ab4e
+        }
21ab4e
+
21ab4e
+        ret = fread (volfile_content, sizeof (char), file_len, fp);
21ab4e
+        if (ret == file_len) {
21ab4e
+              glusterfs_compute_sha256 ((const unsigned char *) volfile_content,
21ab4e
+                                         file_len, sha256_hash);
21ab4e
+        } else {
21ab4e
+                gf_log (THIS->name, GF_LOG_ERROR,
21ab4e
+                        "read failed on path %s. File size=%"GF_PRI_SIZET
21ab4e
+                        "read size=%d", path, file_len, ret);
21ab4e
+                GF_FREE (volfile_content);
21ab4e
                 return -EIO;
21ab4e
         }
21ab4e
 
21ab4e
+        GF_FREE (volfile_content);
21ab4e
+
21ab4e
         graph = glusterfs_graph_construct (fp);
21ab4e
         fclose(fp);
21ab4e
         if (!graph) {
21ab4e
@@ -1085,9 +1183,34 @@ glusterfs_graph_attach (glusterfs_graph_t *orig_graph, char *path,
21ab4e
         }
21ab4e
 
21ab4e
         /* TBD: memory leaks everywhere */
21ab4e
-        glusterfs_graph_prepare (graph, this->ctx, xl->name);
21ab4e
-        glusterfs_graph_init (graph);
21ab4e
-        glusterfs_xlator_link (orig_graph->top, graph->top);
21ab4e
+        if (glusterfs_graph_prepare (graph, this->ctx, xl->name)) {
21ab4e
+                gf_log (this->name, GF_LOG_WARNING,
21ab4e
+                        "failed to prepare graph for xlator %s", xl->name);
21ab4e
+                return -EIO;
21ab4e
+        } else if (glusterfs_graph_init (graph)) {
21ab4e
+                gf_log (this->name, GF_LOG_WARNING,
21ab4e
+                        "failed to initialize graph for xlator %s", xl->name);
21ab4e
+                return -EIO;
21ab4e
+        } else if (glusterfs_xlator_link (orig_graph->top, graph->top)) {
21ab4e
+                gf_log (this->name, GF_LOG_WARNING,
21ab4e
+                        "failed to link the graphs for xlator %s ", xl->name);
21ab4e
+                return -EIO;
21ab4e
+        }
21ab4e
+
21ab4e
+        if (!volfile_obj) {
21ab4e
+                volfile_obj = GF_CALLOC (1, sizeof (gf_volfile_t),
21ab4e
+                                         gf_common_volfile_t);
21ab4e
+                if (!volfile_obj) {
21ab4e
+                        return -EIO;
21ab4e
+                }
21ab4e
+        }
21ab4e
+
21ab4e
+        INIT_LIST_HEAD (&volfile_obj->volfile_list);
21ab4e
+        snprintf (volfile_obj->vol_id, sizeof (volfile_obj->vol_id),
21ab4e
+                  "%s", xl->volfile_id);
21ab4e
+        strncpy (volfile_obj->volfile_checksum, sha256_hash,
21ab4e
+                 sizeof (volfile_obj->volfile_checksum));
21ab4e
+        list_add (&volfile_obj->volfile_list, &this->ctx->volfile_list);
21ab4e
 
21ab4e
         return 0;
21ab4e
 }
21ab4e
diff --git a/libglusterfs/src/mem-types.h b/libglusterfs/src/mem-types.h
21ab4e
index ef7dcd0..ac3f878 100644
21ab4e
--- a/libglusterfs/src/mem-types.h
21ab4e
+++ b/libglusterfs/src/mem-types.h
21ab4e
@@ -169,6 +169,7 @@ enum gf_common_mem_types_ {
21ab4e
         /*lock migration*/
21ab4e
         gf_common_mt_lock_mig,
21ab4e
         gf_common_mt_pthread_t,
21ab4e
+        gf_common_volfile_t,
21ab4e
         gf_common_mt_end
21ab4e
 };
21ab4e
 #endif
21ab4e
diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c
21ab4e
index dc5cfaa..ec710c6 100644
21ab4e
--- a/libglusterfs/src/xlator.c
21ab4e
+++ b/libglusterfs/src/xlator.c
21ab4e
@@ -1178,3 +1178,29 @@ copy_opts_to_child (xlator_t *src, xlator_t *dst, char *glob)
21ab4e
         return dict_foreach_fnmatch (src->options, glob,
21ab4e
                                      _copy_opt_to_child, dst);
21ab4e
 }
21ab4e
+
21ab4e
+int
21ab4e
+glusterfs_delete_volfile_checksum (glusterfs_ctx_t *ctx,
21ab4e
+                                   const char *volfile_id) {
21ab4e
+
21ab4e
+        gf_volfile_t            *volfile_tmp      = NULL;
21ab4e
+        gf_volfile_t            *volfile_obj      = NULL;
21ab4e
+
21ab4e
+        list_for_each_entry (volfile_tmp,  &ctx->volfile_list,
21ab4e
+                             volfile_list) {
21ab4e
+                if (!strcmp (volfile_id, volfile_tmp->vol_id)) {
21ab4e
+                        list_del_init (&volfile_tmp->volfile_list);
21ab4e
+                        volfile_obj = volfile_tmp;
21ab4e
+                        break;
21ab4e
+                }
21ab4e
+        }
21ab4e
+
21ab4e
+        if (volfile_obj) {
21ab4e
+                GF_FREE (volfile_obj);
21ab4e
+        } else {
21ab4e
+                gf_log (THIS->name, GF_LOG_ERROR, "failed to get volfile "
21ab4e
+                        "checksum for volfile id %s.", volfile_id);
21ab4e
+        }
21ab4e
+
21ab4e
+        return 0;
21ab4e
+}
21ab4e
diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h
21ab4e
index 508146f..d94045d 100644
21ab4e
--- a/libglusterfs/src/xlator.h
21ab4e
+++ b/libglusterfs/src/xlator.h
21ab4e
@@ -1039,8 +1039,11 @@ enum gf_hdsk_event_notify_op {
21ab4e
 gf_boolean_t
21ab4e
 is_graph_topology_equal (glusterfs_graph_t *graph1, glusterfs_graph_t *graph2);
21ab4e
 int
21ab4e
-glusterfs_volfile_reconfigure (int oldvollen, FILE *newvolfile_fp,
21ab4e
-                               glusterfs_ctx_t *ctx, const char *oldvolfile);
21ab4e
+glusterfs_volfile_reconfigure (FILE *newvolfile_fp, glusterfs_ctx_t *ctx);
21ab4e
+
21ab4e
+int
21ab4e
+gf_volfile_reconfigure (int oldvollen, FILE *newvolfile_fp,
21ab4e
+                        glusterfs_ctx_t *ctx, const char *oldvolfile);
21ab4e
 
21ab4e
 int
21ab4e
 loc_touchup (loc_t *loc, const char *name);
21ab4e
@@ -1057,4 +1060,8 @@ xlator_subvolume_count (xlator_t *this);
21ab4e
 int
21ab4e
 copy_opts_to_child (xlator_t *src, xlator_t *dst, char *glob);
21ab4e
 
21ab4e
+int
21ab4e
+glusterfs_delete_volfile_checksum (glusterfs_ctx_t *ctx,
21ab4e
+                                   const char *volfile_id);
21ab4e
+
21ab4e
 #endif /* _XLATOR_H */
21ab4e
diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c
21ab4e
index 5d4d860..b3dc417 100644
21ab4e
--- a/xlators/protocol/server/src/server.c
21ab4e
+++ b/xlators/protocol/server/src/server.c
21ab4e
@@ -1575,6 +1575,9 @@ notify (xlator_t *this, int32_t event, void *data, ...)
21ab4e
                                                 break;
21ab4e
                                         }
21ab4e
                                 }
21ab4e
+                                if (victim_found)
21ab4e
+                                        glusterfs_delete_volfile_checksum (ctx,
21ab4e
+                                                 victim->volfile_id);
21ab4e
                         UNLOCK (&ctx->volfile_lock);
21ab4e
                         if (victim_found)
21ab4e
                                 (*trav_p) = (*trav_p)->next;
21ab4e
-- 
21ab4e
1.8.3.1
21ab4e