diff options
author | Raghavendra Bhat <raghavendra@redhat.com> | 2013-07-25 01:14:48 +0530 |
---|---|---|
committer | Anand Avati <avati@redhat.com> | 2013-10-03 21:32:43 -0700 |
commit | dcfe4ab475c53cec7d117fb8052b26213a4b41db (patch) | |
tree | 4a18f76152b1779077315f49fadd0cee5c24a587 | |
parent | a25bd2d7695760c9fe35fec39065c9326f2952d6 (diff) |
glusterfsd, libgfapi: destroy the temporary graphs constructed for comparison
* The new and the oldgraphs which have been constructed whenever there is
a volfile change (either reconfigure of the existing graph or creating
a new graph) for comparison should be freed. Otherwise frequent graph
changes will lead to huge memory leak
Change-Id: I4faddb1aa9393b34cd2de6732e537a60f600026a
BUG: 948178
Signed-off-by: Raghavendra Bhat <raghavendra@redhat.com>
Reviewed-on: http://review.gluster.org/5388
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Anand Avati <avati@redhat.com>
-rw-r--r-- | api/src/glfs-mgmt.c | 159 | ||||
-rw-r--r-- | glusterfsd/src/glusterfsd-mgmt.c | 183 | ||||
-rw-r--r-- | libglusterfs/src/graph.c | 185 | ||||
-rw-r--r-- | libglusterfs/src/graph.y | 2 | ||||
-rw-r--r-- | libglusterfs/src/xlator.c | 43 | ||||
-rw-r--r-- | libglusterfs/src/xlator.h | 6 |
6 files changed, 223 insertions, 355 deletions
diff --git a/api/src/glfs-mgmt.c b/api/src/glfs-mgmt.c index 20362543e62..6843e9cb3fe 100644 --- a/api/src/glfs-mgmt.c +++ b/api/src/glfs-mgmt.c @@ -203,162 +203,6 @@ out: static int -xlator_equal_rec (xlator_t *xl1, xlator_t *xl2) -{ - xlator_list_t *trav1 = NULL; - xlator_list_t *trav2 = NULL; - int ret = 0; - - if (xl1 == NULL || xl2 == NULL) { - gf_log ("xlator", GF_LOG_DEBUG, "invalid argument"); - return -1; - } - - trav1 = xl1->children; - trav2 = xl2->children; - - while (trav1 && trav2) { - ret = xlator_equal_rec (trav1->xlator, trav2->xlator); - if (ret) { - gf_log ("glfs-mgmt", GF_LOG_DEBUG, - "xlators children not equal"); - goto out; - } - - trav1 = trav1->next; - trav2 = trav2->next; - } - - if (trav1 || trav2) { - ret = -1; - goto out; - } - - if (strcmp (xl1->name, xl2->name)) { - ret = -1; - goto out; - } -out : - return ret; -} - - -static gf_boolean_t -is_graph_topology_equal (glusterfs_graph_t *graph1, - glusterfs_graph_t *graph2) -{ - xlator_t *trav1 = NULL; - xlator_t *trav2 = NULL; - gf_boolean_t ret = _gf_true; - - trav1 = graph1->first; - trav2 = graph2->first; - - ret = xlator_equal_rec (trav1, trav2); - - if (ret) { - gf_log ("glfs-mgmt", GF_LOG_DEBUG, - "graphs are not equal"); - ret = _gf_false; - goto out; - } - - ret = _gf_true; - gf_log ("glfs-mgmt", GF_LOG_DEBUG, - "graphs are equal"); - -out: - return ret; -} - - -/* Function has 3types of return value 0, -ve , 1 - * return 0 =======> reconfiguration of options has succeeded - * return 1 =======> the graph has to be reconstructed and all the xlators should be inited - * return -1(or -ve) =======> Some Internal Error occurred during the operation - */ -static int -glusterfs_volfile_reconfigure (struct glfs *fs, FILE *newvolfile_fp) -{ - glusterfs_graph_t *oldvolfile_graph = NULL; - glusterfs_graph_t *newvolfile_graph = NULL; - FILE *oldvolfile_fp = NULL; - glusterfs_ctx_t *ctx = NULL; - - int ret = -1; - - oldvolfile_fp = tmpfile (); - if (!oldvolfile_fp) - goto out; - - if (!fs->oldvollen) { - ret = 1; // Has to call INIT for the whole graph - goto out; - } - fwrite (fs->oldvolfile, fs->oldvollen, 1, oldvolfile_fp); - fflush (oldvolfile_fp); - if (ferror (oldvolfile_fp)) { - goto out; - } - - oldvolfile_graph = glusterfs_graph_construct (oldvolfile_fp); - if (!oldvolfile_graph) { - goto out; - } - - newvolfile_graph = glusterfs_graph_construct (newvolfile_fp); - if (!newvolfile_graph) { - goto out; - } - - if (!is_graph_topology_equal (oldvolfile_graph, - newvolfile_graph)) { - - ret = 1; - gf_log ("glfs-mgmt", GF_LOG_DEBUG, - "Graph topology not equal(should call INIT)"); - goto out; - } - - gf_log ("glfs-mgmt", GF_LOG_DEBUG, - "Only options have changed in the new " - "graph"); - - ctx = fs->ctx; - - if (!ctx) { - gf_log ("glfs-mgmt", GF_LOG_ERROR, - "glusterfs_ctx_get() returned NULL"); - goto out; - } - - oldvolfile_graph = ctx->active; - - if (!oldvolfile_graph) { - gf_log ("glfs-mgmt", GF_LOG_ERROR, - "glusterfs_ctx->active is NULL"); - goto out; - } - - /* */ - ret = glusterfs_graph_reconfigure (oldvolfile_graph, - newvolfile_graph); - if (ret) { - gf_log ("glfs-mgmt", GF_LOG_DEBUG, - "Could not reconfigure new options in old graph"); - goto out; - } - - ret = 0; -out: - if (oldvolfile_fp) - fclose (oldvolfile_fp); - - return ret; -} - - -static int glusterfs_oldvolfile_update (struct glfs *fs, char *volfile, ssize_t size) { int ret = -1; @@ -451,7 +295,8 @@ mgmt_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count, * return -1(or -ve) =======> Some Internal Error occurred during the operation */ - ret = glusterfs_volfile_reconfigure (fs, tmpfp); + ret = glusterfs_volfile_reconfigure (fs->oldvollen, tmpfp, fs->ctx, + fs->oldvolfile); if (ret == 0) { gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG, "No need to re-load volfile, reconfigure done"); diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c index e40d19b0888..071066bdbaa 100644 --- a/glusterfsd/src/glusterfsd-mgmt.c +++ b/glusterfsd/src/glusterfsd-mgmt.c @@ -1330,187 +1330,7 @@ out: static char *oldvolfile = NULL; static int oldvollen = 0; -static int -xlator_equal_rec (xlator_t *xl1, xlator_t *xl2) -{ - xlator_list_t *trav1 = NULL; - xlator_list_t *trav2 = NULL; - int ret = 0; - - if (xl1 == NULL || xl2 == NULL) { - gf_log ("xlator", GF_LOG_DEBUG, "invalid argument"); - return -1; - } - - trav1 = xl1->children; - trav2 = xl2->children; - - while (trav1 && trav2) { - ret = xlator_equal_rec (trav1->xlator, trav2->xlator); - if (ret) { - gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG, - "xlators children not equal"); - goto out; - } - - trav1 = trav1->next; - trav2 = trav2->next; - } - - if (trav1 || trav2) { - ret = -1; - goto out; - } - - if (strcmp (xl1->name, xl2->name)) { - ret = -1; - goto out; - } - - /* type could have changed even if xlator names match, - e.g cluster/distrubte and cluster/nufa share the same - xlator name - */ - if (strcmp (xl1->type, xl2->type)) { - ret = -1; - goto out; - } -out : - return ret; -} - -static gf_boolean_t -is_graph_topology_equal (glusterfs_graph_t *graph1, - glusterfs_graph_t *graph2) -{ - xlator_t *trav1 = NULL; - xlator_t *trav2 = NULL; - gf_boolean_t ret = _gf_true; - - trav1 = graph1->first; - trav2 = graph2->first; - - ret = xlator_equal_rec (trav1, trav2); - - if (ret) { - gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG, - "graphs are not equal"); - ret = _gf_false; - goto out; - } - - ret = _gf_true; - gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG, - "graphs are equal"); - -out: - return ret; -} - -/* Function has 3types of return value 0, -ve , 1 - * return 0 =======> reconfiguration of options has succeeded - * return 1 =======> the graph has to be reconstructed and all the xlators should be inited - * return -1(or -ve) =======> Some Internal Error occurred during the operation - */ -static int -glusterfs_volfile_reconfigure (FILE *newvolfile_fp) -{ - glusterfs_graph_t *oldvolfile_graph = NULL; - glusterfs_graph_t *newvolfile_graph = NULL; - int oldvolfile_fd = -1; - FILE *oldvolfile_fp = NULL; - glusterfs_ctx_t *ctx = NULL; - char template[PATH_MAX] = {0}; - - int ret = -1; - - strcpy (template, "/tmp/tmp.XXXXXX"); - oldvolfile_fd = mkstemp (template); - if (oldvolfile_fd == -1) { - gf_log ("glusterfsd-mgmt", GF_LOG_ERROR, "Unable to create " - "temporary file: %s (%s)", template, - strerror (errno)); - goto out; - } - - ret = unlink (template); - if (ret < 0) { - gf_log ("glusterfsd-mgmt", GF_LOG_WARNING, "Unable to delete " - "file: %s", template); - } - - oldvolfile_fp = fdopen (oldvolfile_fd, "w+b"); - if (!oldvolfile_fp) { - gf_log ("glusterfsd-mgmt", GF_LOG_CRITICAL, "Failed to create " - "temporary volfile"); - goto out; - } - - if (!oldvollen) { - ret = 1; // Has to call INIT for the whole graph - goto out; - } - fwrite (oldvolfile, oldvollen, 1, oldvolfile_fp); - fflush (oldvolfile_fp); - if (ferror (oldvolfile_fp)) { - goto out; - } - - - oldvolfile_graph = glusterfs_graph_construct (oldvolfile_fp); - if (!oldvolfile_graph) { - goto out; - } - - newvolfile_graph = glusterfs_graph_construct (newvolfile_fp); - if (!newvolfile_graph) { - goto out; - } - - if (!is_graph_topology_equal (oldvolfile_graph, - newvolfile_graph)) { - - ret = 1; - gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG, - "Graph topology not equal(should call INIT)"); - goto out; - } - - gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG, - "Only options have changed in the new " - "graph"); - - ctx = glusterfsd_ctx; - - oldvolfile_graph = ctx->active; - if (!oldvolfile_graph) { - gf_log ("glusterfsd-mgmt", GF_LOG_ERROR, - "glusterfs_ctx->active is NULL"); - goto out; - } - - /* */ - ret = glusterfs_graph_reconfigure (oldvolfile_graph, - newvolfile_graph); - if (ret) { - gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG, - "Could not reconfigure new options in old graph"); - goto out; - } - - ret = 0; -out: - if (oldvolfile_fp) { - fclose (oldvolfile_fp); - - } else if (-1 != oldvolfile_fd) { - close (oldvolfile_fd); - - } - - return ret; -} int mgmt_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count, @@ -1576,7 +1396,7 @@ mgmt_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count, * return -1(or -ve) =======> Some Internal Error occurred during the operation */ - ret = glusterfs_volfile_reconfigure (tmpfp); + ret = glusterfs_volfile_reconfigure (oldvollen, tmpfp, ctx, oldvolfile); if (ret == 0) { gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG, "No need to re-load volfile, reconfigure done"); @@ -1609,6 +1429,7 @@ mgmt_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count, volfilebuf = GF_REALLOC (oldvolfile, size); else volfilebuf = GF_CALLOC (1, size, gf_common_mt_char); + if (!volfilebuf) { ret = -1; goto out; diff --git a/libglusterfs/src/graph.c b/libglusterfs/src/graph.c index 1dba63fc052..e76df1ca560 100644 --- a/libglusterfs/src/graph.c +++ b/libglusterfs/src/graph.c @@ -537,6 +537,184 @@ glusterfs_graph_activate (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx) int +xlator_equal_rec (xlator_t *xl1, xlator_t *xl2) +{ + xlator_list_t *trav1 = NULL; + xlator_list_t *trav2 = NULL; + int ret = 0; + + if (xl1 == NULL || xl2 == NULL) { + gf_log ("xlator", GF_LOG_DEBUG, "invalid argument"); + return -1; + } + + trav1 = xl1->children; + trav2 = xl2->children; + + while (trav1 && trav2) { + ret = xlator_equal_rec (trav1->xlator, trav2->xlator); + if (ret) { + gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG, + "xlators children not equal"); + goto out; + } + + trav1 = trav1->next; + trav2 = trav2->next; + } + + if (trav1 || trav2) { + ret = -1; + goto out; + } + + if (strcmp (xl1->name, xl2->name)) { + ret = -1; + goto out; + } + + /* type could have changed even if xlator names match, + e.g cluster/distrubte and cluster/nufa share the same + xlator name + */ + if (strcmp (xl1->type, xl2->type)) { + ret = -1; + goto out; + } +out : + return ret; +} + + +gf_boolean_t +is_graph_topology_equal (glusterfs_graph_t *graph1, glusterfs_graph_t *graph2) +{ + xlator_t *trav1 = NULL; + xlator_t *trav2 = NULL; + gf_boolean_t ret = _gf_true; + + trav1 = graph1->first; + trav2 = graph2->first; + + ret = xlator_equal_rec (trav1, trav2); + + if (ret) { + gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG, + "graphs are not equal"); + ret = _gf_false; + goto out; + } + + ret = _gf_true; + gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG, + "graphs are equal"); + +out: + return ret; +} + + +/* Function has 3types of return value 0, -ve , 1 + * return 0 =======> reconfiguration of options has succeeded + * return 1 =======> the graph has to be reconstructed and all the xlators should be inited + * return -1(or -ve) =======> Some Internal Error occurred during the operation + */ +int +glusterfs_volfile_reconfigure (int oldvollen, FILE *newvolfile_fp, + glusterfs_ctx_t *ctx, const char *oldvolfile) +{ + glusterfs_graph_t *oldvolfile_graph = NULL; + glusterfs_graph_t *newvolfile_graph = NULL; + FILE *oldvolfile_fp = NULL; + gf_boolean_t active_graph_found = _gf_true; + + int ret = -1; + + if (!oldvollen) { + ret = 1; // Has to call INIT for the whole graph + goto out; + } + + if (!ctx) { + gf_log ("glusterfsd-mgmt", GF_LOG_ERROR, + "ctx is NULL"); + goto out; + } + + oldvolfile_graph = ctx->active; + if (!oldvolfile_graph) { + active_graph_found = _gf_false; + gf_log ("glusterfsd-mgmt", GF_LOG_ERROR, + "glusterfs_ctx->active is NULL"); + + oldvolfile_fp = tmpfile (); + if (!oldvolfile_fp) { + gf_log ("glusterfsd-mgmt", GF_LOG_ERROR, "Unable to " + "create temporary volfile: (%s)", + strerror (errno)); + goto out; + } + + fwrite (oldvolfile, oldvollen, 1, oldvolfile_fp); + fflush (oldvolfile_fp); + if (ferror (oldvolfile_fp)) { + goto out; + } + + oldvolfile_graph = glusterfs_graph_construct (oldvolfile_fp); + if (!oldvolfile_graph) + goto out; + } + + newvolfile_graph = glusterfs_graph_construct (newvolfile_fp); + if (!newvolfile_graph) { + goto out; + } + + if (!is_graph_topology_equal (oldvolfile_graph, + newvolfile_graph)) { + + ret = 1; + gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG, + "Graph topology not equal(should call INIT)"); + goto out; + } + + gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG, + "Only options have changed in the new " + "graph"); + + /* */ + ret = glusterfs_graph_reconfigure (oldvolfile_graph, + newvolfile_graph); + if (ret) { + gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG, + "Could not reconfigure new options in old graph"); + goto out; + } + + ret = 0; +out: + if (oldvolfile_fp) + fclose (oldvolfile_fp); + + /* Do not simply destroy the old graph here. If the oldgraph + is constructed here in this function itself instead of getting + it from ctx->active (which happens only of ctx->active is NULL), + then destroy the old graph. If some i/o is still happening in + the old graph and the old graph is obtained from ctx->active, + then destroying the graph will cause problems. + */ + if (!active_graph_found && oldvolfile_graph) + glusterfs_graph_destroy (oldvolfile_graph); + if (newvolfile_graph) + glusterfs_graph_destroy (newvolfile_graph); + + return ret; +} + + +int glusterfs_graph_reconfigure (glusterfs_graph_t *oldgraph, glusterfs_graph_t *newgraph) { @@ -562,5 +740,12 @@ glusterfs_graph_reconfigure (glusterfs_graph_t *oldgraph, int glusterfs_graph_destroy (glusterfs_graph_t *graph) { + xlator_tree_free (graph->first); + + if (graph) { + list_del_init (&graph->list); + GF_FREE (graph); + } + return 0; } diff --git a/libglusterfs/src/graph.y b/libglusterfs/src/graph.y index ca4301ff0ac..a220abeb9ce 100644 --- a/libglusterfs/src/graph.y +++ b/libglusterfs/src/graph.y @@ -482,6 +482,7 @@ preprocess (FILE *srcfp, FILE *dstfp) cmd_buf_size *= 2; cmd = GF_REALLOC (cmd, cmd_buf_size); if (cmd == NULL) { + GF_FREE (result); return -1; } @@ -523,6 +524,7 @@ preprocess (FILE *srcfp, FILE *dstfp) out: fseek (srcfp, 0L, SEEK_SET); fseek (dstfp, 0L, SEEK_SET); + GF_FREE (cmd); GF_FREE (result); diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c index a7caedf02e7..d029475504a 100644 --- a/libglusterfs/src/xlator.c +++ b/libglusterfs/src/xlator.c @@ -538,10 +538,26 @@ out: return; } +int +xlator_list_destroy (xlator_list_t *list) +{ + xlator_list_t *next = NULL; + + while (list) { + next = list->next; + GF_FREE (list); + list = next; + } + + return 0; +} + int xlator_tree_free (xlator_t *tree) { + volume_opt_list_t *vol_opt = NULL; + volume_opt_list_t *tmp = NULL; xlator_t *trav = tree; xlator_t *prev = tree; @@ -552,9 +568,19 @@ xlator_tree_free (xlator_t *tree) while (prev) { trav = prev->next; - dict_destroy (prev->options); + if (prev->dlhandle) + dlclose (prev->dlhandle); + dict_unref (prev->options); GF_FREE (prev->name); GF_FREE (prev->type); + xlator_list_destroy (prev->children); + xlator_list_destroy (prev->parents); + + list_for_each_entry_safe (vol_opt, tmp, &prev->volume_options, + list) { + list_del_init (&vol_opt->list); + GF_FREE (vol_opt); + } GF_FREE (prev); prev = trav; } @@ -696,21 +722,6 @@ loc_is_root (loc_t *loc) } int -xlator_list_destroy (xlator_list_t *list) -{ - xlator_list_t *next = NULL; - - while (list) { - next = list->next; - GF_FREE (list); - list = next; - } - - return 0; -} - - -int xlator_destroy (xlator_t *xl) { volume_opt_list_t *vol_opt = NULL; diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index d23ee0c25d7..84a028fbcab 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -932,5 +932,9 @@ enum gf_hdsk_event_notify_op { GF_EN_DEFRAG_STATUS, GF_EN_MAX, }; - +gf_boolean_t +is_graph_topology_equal (glusterfs_graph_t *graph1, glusterfs_graph_t *graph2); +int +glusterfs_volfile_reconfigure (int oldvollen, FILE *newvolfile_fp, + glusterfs_ctx_t *ctx, const char *oldvolfile); #endif /* _XLATOR_H */ |