diff options
Diffstat (limited to 'libglusterfs')
| -rw-r--r-- | libglusterfs/src/glusterfs.h | 2 | ||||
| -rw-r--r-- | libglusterfs/src/graph.c | 60 | ||||
| -rw-r--r-- | libglusterfs/src/xlator.c | 115 | ||||
| -rw-r--r-- | libglusterfs/src/xlator.h | 3 | 
4 files changed, 140 insertions, 40 deletions
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index 1302a11d82b..c482b3d2242 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -603,6 +603,8 @@ struct gf_flock {  #define SECURE_ACCESS_FILE     GLUSTERD_DEFAULT_WORKDIR "/secure-access"  int glusterfs_graph_prepare (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx); +int glusterfs_graph_destroy_residual (glusterfs_graph_t *graph); +int glusterfs_graph_deactivate (glusterfs_graph_t *graph);  int glusterfs_graph_destroy (glusterfs_graph_t *graph);  int glusterfs_graph_activate (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx);  glusterfs_graph_t *glusterfs_graph_construct (FILE *fp); diff --git a/libglusterfs/src/graph.c b/libglusterfs/src/graph.c index f6db5557a33..b427740f10f 100644 --- a/libglusterfs/src/graph.c +++ b/libglusterfs/src/graph.c @@ -328,6 +328,19 @@ glusterfs_graph_init (glusterfs_graph_t *graph)          return 0;  } +int +glusterfs_graph_deactivate (glusterfs_graph_t *graph) +{ +        xlator_t           *top = NULL; + +        if (graph == NULL) +                goto out; + +        top = graph->top; +        xlator_tree_fini (top); + out: +        return 0; +}  static int  _log_if_unknown_option (dict_t *dict, char *key, data_t *value, void *data) @@ -763,14 +776,53 @@ glusterfs_graph_reconfigure (glusterfs_graph_t *oldgraph,  }  int -glusterfs_graph_destroy (glusterfs_graph_t *graph) +glusterfs_graph_destroy_residual (glusterfs_graph_t *graph)  { -        GF_VALIDATE_OR_GOTO ("graph", graph, out); +        int ret = -1; -        xlator_tree_free (graph->first); +        if (graph == NULL) +                return ret; + +        ret = xlator_tree_free_memacct (graph->first);          list_del_init (&graph->list);          GF_FREE (graph); + +        return ret; +} + +/* This function destroys all the xlator members except for the + * xlator strcuture and its mem accounting field. + * + * If otherwise, it would destroy the master xlator object as well + * its mem accounting, which would mean after calling glusterfs_graph_destroy() + * there cannot be any reference to GF_FREE() from the master xlator, this is + * not possible because of the following dependencies: + * - glusterfs_ctx_t will have mem pools allocated by the master xlators + * - xlator objects will have references to those mem pools(g: dict) + * + * Ordering the freeing in any of the order will also not solve the dependency: + * - Freeing xlator objects(including memory accounting) before mem pools + *   destruction will mean not use GF_FREE while destroying mem pools. + * - Freeing mem pools and then destroying xlator objects would lead to crashes + *   when xlator tries to unref dict or other mem pool objects. + * + * Hence the way chosen out of this interdependency is to split xlator object + * free into two stages: + * - Free all the xlator members excpet for its mem accounting structure + * - Free all the mem accouting structures of xlator along with the xlator + *   object itself. + */ +int +glusterfs_graph_destroy (glusterfs_graph_t *graph) +{ +        int ret = 0; + +        GF_VALIDATE_OR_GOTO ("graph", graph, out); + +        ret = xlator_tree_free_members (graph->first); + +        ret = glusterfs_graph_destroy_residual (graph);  out: -        return 0; +        return ret;  } diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c index 7b873fcc79d..3378a35d54a 100644 --- a/libglusterfs/src/xlator.c +++ b/libglusterfs/src/xlator.c @@ -552,12 +552,62 @@ xlator_list_destroy (xlator_list_t *list)          return 0;  } - -int -xlator_tree_free (xlator_t *tree) +static int +xlator_members_free (xlator_t *xl)  {          volume_opt_list_t *vol_opt = NULL;          volume_opt_list_t *tmp     = NULL; + +        if (!xl) +                return 0; + +        GF_FREE (xl->name); +        GF_FREE (xl->type); +        if (xl->dlhandle) +                dlclose (xl->dlhandle); +        if (xl->options) +                dict_unref (xl->options); + +        xlator_list_destroy (xl->children); + +        xlator_list_destroy (xl->parents); + +        list_for_each_entry_safe (vol_opt, tmp, &xl->volume_options, list) { +                list_del_init (&vol_opt->list); +                GF_FREE (vol_opt); +        } + +        return 0; +} + +/* This function destroys all the xlator members except for the + * xlator strcuture and its mem accounting field. + * + * If otherwise, it would destroy the master xlator object as well + * its mem accounting, which would mean after calling glusterfs_graph_destroy() + * there cannot be any reference to GF_FREE() from the master xlator, this is + * not possible because of the following dependencies: + * - glusterfs_ctx_t will have mem pools allocated by the master xlators + * - xlator objects will have references to those mem pools(g: dict) + * + * Ordering the freeing in any of the order will also not solve the dependency: + * - Freeing xlator objects(including memory accounting) before mem pools + *   destruction will mean not use GF_FREE while destroying mem pools. + * - Freeing mem pools and then destroying xlator objects would lead to crashes + *   when xlator tries to unref dict or other mem pool objects. + * + * Hence the way chosen out of this interdependency is to split xlator object + * free into two stages: + * - Free all the xlator members excpet for its mem accounting structure + * - Free all the mem accouting structures of xlator along with the xlator + *   object itself. + * + * This two stages of destruction, is mainly required for glfs_fini(). + */ + +int +xlator_tree_free_members (xlator_t *tree) +{          xlator_t *trav = tree;          xlator_t *prev = tree; @@ -568,18 +618,32 @@ xlator_tree_free (xlator_t *tree)          while (prev) {                  trav = prev->next; -                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); +                xlator_members_free (prev); +                prev = trav; +        } + +        return 0; +} + +int +xlator_tree_free_memacct (xlator_t *tree) +{ +        xlator_t *trav = tree; +        xlator_t *prev = tree; +        int          i = 0; + +        if (!tree) { +                gf_log ("parser", GF_LOG_ERROR, "Translator tree not found"); +                return -1; +        } + +        while (prev) { +                trav = prev->next; +                if (prev->mem_acct.rec) { +                        for (i = 0; i < prev->mem_acct.num_types; i++) { +                                LOCK_DESTROY (&(prev->mem_acct.rec[i].lock)); +                        } +                        FREE (prev->mem_acct.rec);                  }                  GF_FREE (prev);                  prev = trav; @@ -588,7 +652,6 @@ xlator_tree_free (xlator_t *tree)          return 0;  } -  void  loc_wipe (loc_t *loc)  { @@ -766,28 +829,10 @@ loc_is_root (loc_t *loc)  int  xlator_destroy (xlator_t *xl)  { -        volume_opt_list_t *vol_opt = NULL; -        volume_opt_list_t *tmp     = NULL; -          if (!xl)                  return 0; -        GF_FREE (xl->name); -        GF_FREE (xl->type); -        if (xl->dlhandle) -                dlclose (xl->dlhandle); -        if (xl->options) -                dict_destroy (xl->options); - -        xlator_list_destroy (xl->children); - -        xlator_list_destroy (xl->parents); - -        list_for_each_entry_safe (vol_opt, tmp, &xl->volume_options, list) { -                list_del_init (&vol_opt->list); -                GF_FREE (vol_opt); -        } - +        xlator_members_free (xl);          GF_FREE (xl);          return 0; diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index 0c4e820c2d3..c1813abe6a2 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -919,7 +919,8 @@ int xlator_init (xlator_t *this);  int xlator_destroy (xlator_t *xl);  int32_t xlator_tree_init (xlator_t *xl); -int32_t xlator_tree_free (xlator_t *xl); +int32_t xlator_tree_free_members (xlator_t *xl); +int32_t xlator_tree_free_memacct (xlator_t *xl);  void xlator_tree_fini (xlator_t *xl);  | 
