diff options
Diffstat (limited to 'libglusterfs/src/graph.c')
| -rw-r--r-- | libglusterfs/src/graph.c | 428 |
1 files changed, 319 insertions, 109 deletions
diff --git a/libglusterfs/src/graph.c b/libglusterfs/src/graph.c index a2d03fa0b..e76df1ca5 100644 --- a/libglusterfs/src/graph.c +++ b/libglusterfs/src/graph.c @@ -1,20 +1,11 @@ /* - Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ #ifndef _CONFIG_H @@ -29,28 +20,23 @@ #include "defaults.h" - - #if 0 static void _gf_dump_details (int argc, char **argv) { extern FILE *gf_log_logfile; int i = 0; - char timestr[256]; + char timestr[64]; time_t utime = 0; - struct tm *tm = NULL; pid_t mypid = 0; struct utsname uname_buf = {{0, }, }; int uname_ret = -1; - utime = time (NULL); - tm = localtime (&utime); mypid = getpid (); uname_ret = uname (&uname_buf); - /* Which git? What time? */ - strftime (timestr, 256, "%Y-%m-%d %H:%M:%S", tm); + utime = time (NULL); + gf_time_fmt (timestr, sizeof timestr, utime, gf_timefmt_FT); fprintf (gf_log_logfile, "========================================" "========================================\n"); @@ -84,44 +70,6 @@ _gf_dump_details (int argc, char **argv) #endif -static int -_log_if_option_is_invalid (xlator_t *xl, data_pair_t *pair) -{ - volume_opt_list_t *vol_opt = NULL; - volume_option_t *opt = NULL; - int i = 0; - int index = 0; - int found = 0; - - /* Get the first volume_option */ - list_for_each_entry (vol_opt, &xl->volume_options, list) { - /* Warn for extra option */ - if (!vol_opt->given_opt) - break; - - opt = vol_opt->given_opt; - for (index = 0; - ((index < ZR_OPTION_MAX_ARRAY_SIZE) && - (opt[index].key && opt[index].key[0])); index++) - for (i = 0; (i < ZR_VOLUME_MAX_NUM_KEY) && - opt[index].key[i]; i++) { - if (fnmatch (opt[index].key[i], - pair->key, - FNM_NOESCAPE) == 0) { - found = 1; - break; - } - } - } - - if (!found) { - gf_log (xl->name, GF_LOG_WARNING, - "option '%s' is not recognized", - pair->key); - } - return 0; -} - int glusterfs_xlator_link (xlator_t *pxl, xlator_t *cxl) @@ -169,7 +117,8 @@ glusterfs_graph_set_first (glusterfs_graph_t *graph, xlator_t *xl) int glusterfs_graph_insert (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx, - const char *type, const char *name) + const char *type, const char *name, + gf_boolean_t autoload) { xlator_t *ixl = NULL; @@ -195,6 +144,8 @@ glusterfs_graph_insert (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx, if (!ixl->name) goto err; + ixl->is_autoloaded = autoload; + if (xlator_set_type (ixl, type) == -1) { gf_log ("glusterfs", GF_LOG_ERROR, "%s (%s) initialization failed", @@ -213,23 +164,37 @@ err: return -1; } - int -glusterfs_graph_readonly (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx) +glusterfs_graph_acl (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx) { int ret = 0; cmd_args_t *cmd_args = NULL; cmd_args = &ctx->cmd_args; - if (!cmd_args->read_only) + if (!cmd_args->acl) return 0; - ret = glusterfs_graph_insert (graph, ctx, "features/read-only", - "readonly-autoload"); + ret = glusterfs_graph_insert (graph, ctx, "system/posix-acl", + "posix-acl-autoload", 1); return ret; } +int +glusterfs_graph_worm (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx) +{ + int ret = 0; + cmd_args_t *cmd_args = NULL; + + cmd_args = &ctx->cmd_args; + + if (!cmd_args->worm) + return 0; + + ret = glusterfs_graph_insert (graph, ctx, "features/worm", + "worm-autoload", 1); + return ret; +} int glusterfs_graph_mac_compat (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx) @@ -243,11 +208,26 @@ glusterfs_graph_mac_compat (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx) return 0; ret = glusterfs_graph_insert (graph, ctx, "features/mac-compat", - "mac-compat-autoload"); + "mac-compat-autoload", 1); return ret; } +int +glusterfs_graph_gfid_access (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx) +{ + int ret = 0; + cmd_args_t *cmd_args = NULL; + + cmd_args = &ctx->cmd_args; + + if (!cmd_args->aux_gfid_mount) + return 0; + + ret = glusterfs_graph_insert (graph, ctx, "features/gfid-access", + "gfid-access-autoload", 1); + return ret; +} static void gf_add_cmdline_options (glusterfs_graph_t *graph, cmd_args_t *cmd_args) @@ -267,7 +247,7 @@ gf_add_cmdline_options (glusterfs_graph_t *graph, cmd_args_t *cmd_args) cmd_option->key, cmd_option->value); if (ret == 0) { - gf_log (trav->name, GF_LOG_WARNING, + gf_log (trav->name, GF_LOG_INFO, "adding option '%s' for " "volume '%s' with value '%s'", cmd_option->key, trav->name, @@ -289,9 +269,9 @@ gf_add_cmdline_options (glusterfs_graph_t *graph, cmd_args_t *cmd_args) int glusterfs_graph_validate_options (glusterfs_graph_t *graph) { - volume_opt_list_t *vol_opt = NULL; xlator_t *trav = NULL; int ret = -1; + char *errstr = NULL; trav = graph->first; @@ -299,14 +279,10 @@ glusterfs_graph_validate_options (glusterfs_graph_t *graph) if (list_empty (&trav->volume_options)) continue; - vol_opt = list_entry (trav->volume_options.next, - volume_opt_list_t, list); - - ret = validate_xlator_volume_options (trav, - vol_opt->given_opt); + ret = xlator_options_validate (trav, trav->options, &errstr); if (ret) { gf_log (trav->name, GF_LOG_ERROR, - "validating translator failed"); + "validation failed: %s", errstr); return ret; } trav = trav->next; @@ -338,35 +314,46 @@ glusterfs_graph_init (glusterfs_graph_t *graph) } -int -glusterfs_graph_unknown_options (glusterfs_graph_t *graph) +static int +_log_if_unknown_option (dict_t *dict, char *key, data_t *value, void *data) { - data_pair_t *pair = NULL; - xlator_t *trav = NULL; + volume_option_t *found = NULL; + xlator_t *xl = NULL; - trav = graph->first; + xl = data; - /* Validate again phase */ - while (trav) { - pair = trav->options->members_list; - while (pair) { - _log_if_option_is_invalid (trav, pair); - pair = pair->next; - } - trav = trav->next; + found = xlator_volume_option_get (xl, key); + + if (!found) { + gf_log (xl->name, GF_LOG_WARNING, + "option '%s' is not recognized", key); } return 0; } +static void +_xlator_check_unknown_options (xlator_t *xl, void *data) +{ + dict_foreach (xl->options, _log_if_unknown_option, xl); +} + + +int +glusterfs_graph_unknown_options (glusterfs_graph_t *graph) +{ + xlator_foreach (graph->first, _xlator_check_unknown_options, NULL); + return 0; +} + + void fill_uuid (char *uuid, int size) { char hostname[256] = {0,}; struct timeval tv = {0,}; - struct tm now = {0, }; - char now_str[32]; + char now_str[64]; if (gettimeofday (&tv, NULL) == -1) { gf_log ("graph", GF_LOG_ERROR, @@ -380,8 +367,7 @@ fill_uuid (char *uuid, int size) strerror (errno)); } - localtime_r (&tv.tv_sec, &now); - strftime (now_str, 32, "%Y/%m/%d-%H:%M:%S", &now); + gf_time_fmt (now_str, sizeof now_str, tv.tv_sec, gf_timefmt_Ymd_T); snprintf (uuid, size, "%s-%d-%s:%"GF_PRI_SUSECONDS, hostname, getpid(), now_str, tv.tv_usec); @@ -446,18 +432,37 @@ glusterfs_graph_prepare (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx) /* XXX: attach to -n volname */ ret = glusterfs_graph_settop (graph, ctx); - if (ret) + if (ret) { + gf_log ("graph", GF_LOG_ERROR, "glusterfs graph settop failed"); return -1; + } - /* XXX: RO VOLUME */ - ret = glusterfs_graph_readonly (graph, ctx); - if (ret) + /* XXX: WORM VOLUME */ + ret = glusterfs_graph_worm (graph, ctx); + if (ret) { + gf_log ("graph", GF_LOG_ERROR, "glusterfs graph worm failed"); return -1; + } + ret = glusterfs_graph_acl (graph, ctx); + if (ret) { + gf_log ("graph", GF_LOG_ERROR, "glusterfs graph ACL failed"); + return -1; + } /* XXX: MAC COMPAT */ ret = glusterfs_graph_mac_compat (graph, ctx); - if (ret) + if (ret) { + gf_log ("graph", GF_LOG_ERROR, "glusterfs graph mac compat failed"); + return -1; + } + + /* XXX: gfid-access */ + ret = glusterfs_graph_gfid_access (graph, ctx); + if (ret) { + gf_log ("graph", GF_LOG_ERROR, + "glusterfs graph 'gfid-access' failed"); return -1; + } /* XXX: this->ctx setting */ for (trav = graph->first; trav; trav = trav->next) { @@ -469,6 +474,8 @@ glusterfs_graph_prepare (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx) fill_uuid (graph->graph_uuid, 128); + graph->id = ctx->graph_id++; + /* XXX: --xlator-option additions */ gf_add_cmdline_options (graph, &ctx->cmd_args); @@ -484,17 +491,23 @@ glusterfs_graph_activate (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx) /* XXX: all xlator options validation */ ret = glusterfs_graph_validate_options (graph); - if (ret) + if (ret) { + gf_log ("graph", GF_LOG_ERROR, "validate options failed"); return ret; + } /* XXX: perform init () */ ret = glusterfs_graph_init (graph); - if (ret) + if (ret) { + gf_log ("graph", GF_LOG_ERROR, "init failed"); return ret; + } ret = glusterfs_graph_unknown_options (graph); - if (ret) + if (ret) { + gf_log ("graph", GF_LOG_ERROR, "unknown options failed"); return ret; + } /* XXX: log full graph (_gf_dump_details) */ @@ -502,32 +515,224 @@ glusterfs_graph_activate (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx) ctx->active = graph; /* XXX: attach to master and set active pointer */ - if (ctx->master) + if (ctx->master) { ret = xlator_notify (ctx->master, GF_EVENT_GRAPH_NEW, graph); - if (ret) - return ret; + if (ret) { + gf_log ("graph", GF_LOG_ERROR, + "graph new notification failed"); + return ret; + } + ((xlator_t *)ctx->master)->next = graph->top; + } /* XXX: perform parent up */ ret = glusterfs_graph_parent_up (graph); - if (ret) + if (ret) { + gf_log ("graph", GF_LOG_ERROR, "parent up notification failed"); return ret; - + } return 0; } + +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) { - xlator_t *old_xl = NULL; - xlator_t *new_xl = NULL; + xlator_t *old_xl = NULL; + xlator_t *new_xl = NULL; GF_ASSERT (oldgraph); GF_ASSERT (newgraph); old_xl = oldgraph->first; + while (old_xl->is_autoloaded) { + old_xl = old_xl->children->xlator; + } + new_xl = newgraph->first; + while (new_xl->is_autoloaded) { + new_xl = new_xl->children->xlator; + } return xlator_tree_reconfigure (old_xl, new_xl); } @@ -535,7 +740,12 @@ glusterfs_graph_reconfigure (glusterfs_graph_t *oldgraph, int glusterfs_graph_destroy (glusterfs_graph_t *graph) { - return 0; -} + xlator_tree_free (graph->first); + if (graph) { + list_del_init (&graph->list); + GF_FREE (graph); + } + return 0; +} |
