From 6d9bcd67e99ad638ca260f04cff401e7d9ebe3c5 Mon Sep 17 00:00:00 2001 From: Csaba Henk Date: Sun, 3 Oct 2010 14:57:11 +0000 Subject: volgen: impemlent dynamic (pattern-based) option matching So now auth.addr.*.allow can be a basic option, without any specific support code! Signed-off-by: Csaba Henk Signed-off-by: Vijay Bellur BUG: 1750 (clean up volgen) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1750 --- xlators/mgmt/glusterd/src/glusterd-op-sm.c | 23 +-- xlators/mgmt/glusterd/src/glusterd-op-sm.h | 2 +- xlators/mgmt/glusterd/src/glusterd-store.c | 10 +- xlators/mgmt/glusterd/src/glusterd-volgen.c | 220 +++++++++++++++++----------- xlators/mgmt/glusterd/src/glusterd-volgen.h | 7 - 5 files changed, 143 insertions(+), 119 deletions(-) diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 513be5b4d29..7a69d2c9e66 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -1047,7 +1047,7 @@ glusterd_op_stage_set_volume (gd1_mgmt_stage_op_req *req) int ret = 0; dict_t *dict = NULL; char *volname = NULL; - gf_boolean_t exists = _gf_false; + int exists = 0; char *key = NULL; char str[100] = {0, }; int count = 0; @@ -1094,7 +1094,7 @@ glusterd_op_stage_set_volume (gd1_mgmt_stage_op_req *req) exists = glusterd_check_option_exists(key); - if (!exists) { + if (exists != 1) { gf_log ("", GF_LOG_ERROR, "Option with name: %s " "does not exist", key); ret = -1; @@ -1168,21 +1168,6 @@ out: } - -gf_boolean_t -glusterd_check_option_exists(char *optstring) -{ - struct volopt_map_entry *vme = NULL; - - for (vme = glusterd_volopt_map; vme->key; vme++) { - if (strcmp (vme->key, optstring) == 0) - return _gf_true; - } - - return _gf_false; - -} - static int glusterd_op_perform_remove_brick (glusterd_volinfo_t *volinfo, char *brick) { @@ -2800,11 +2785,11 @@ void _delete_reconfig_opt (dict_t *this, char *key, data_t *value, void *data) { - gf_boolean_t exists = _gf_false; + int exists = 0; exists = glusterd_check_option_exists(key); - if (exists) { + if (exists == 1) { gf_log ("", GF_LOG_DEBUG, "deleting dict with key=%s,value=%s", key, value->data); dict_del (this, key); diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h index 04867da2ef3..5c557b340cb 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h @@ -217,7 +217,7 @@ glusterd_op_clear_ctx_free (glusterd_op_t op); gf_boolean_t glusterd_op_get_ctx_free (glusterd_op_t op); -gf_boolean_t +int glusterd_check_option_exists(char *optstring); int diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c index 7c18b69a927..e6aa91b4ff9 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.c +++ b/xlators/mgmt/glusterd/src/glusterd-store.c @@ -972,7 +972,7 @@ glusterd_store_retrieve_volume (char *volname) char volpath[PATH_MAX] = {0,}; glusterd_conf_t *priv = NULL; char path[PATH_MAX] = {0,}; - gf_boolean_t exists = _gf_false; + int exists = 0; ret = glusterd_volinfo_new (&volinfo); @@ -1029,6 +1029,10 @@ glusterd_store_retrieve_volume (char *volname) "failed to parse uuid"); } else { exists = glusterd_check_option_exists (key); + if (exists == -1) { + ret = -1; + goto out; + } if (exists) { ret = dict_set_str(volinfo->dict, key, gf_strdup (value)); @@ -1125,7 +1129,7 @@ void _setopts(dict_t *this, char *key, data_t *value, void *data) { int ret = 0; glusterd_store_handle_t *shandle = NULL; - gf_boolean_t exists = _gf_false; + int exists = 0; shandle = (glusterd_store_handle_t *) data; @@ -1137,7 +1141,7 @@ void _setopts(dict_t *this, char *key, data_t *value, void *data) return; exists = glusterd_check_option_exists (key); - if (exists) + if (exists == 1) gf_log ("", GF_LOG_DEBUG, "Storing in volinfo:key= %s, val=%s", key, value->data); else { diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c index 619e32920f0..9e672a57fa1 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.c +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c @@ -23,6 +23,8 @@ #include "config.h" #endif +#include + #include "xlator.h" #include "glusterd.h" #include "defaults.h" @@ -61,7 +63,12 @@ * not touch them unless you know what you do. */ -struct volopt_map_entry glusterd_volopt_map[] = { +struct volopt_map_entry { + char *key; + char *voltype; +}; + +static struct volopt_map_entry glusterd_volopt_map[] = { {"lookup-unhashed", "cluster/distribute"}, {"min-free-disk", "cluster/distribute"}, @@ -98,8 +105,8 @@ struct volopt_map_entry glusterd_volopt_map[] = { {"ping-timeout", "protocol/client"}, {"inode-lru-limit", "protocol/server"}, - {"auth.addr.%s.allow", "protocol/server:!server-auth"}, - {"auth.addr.%s.reject", "protocol/server:!server-auth"}, + {"auth.addr.*.allow", "protocol/server"}, + {"auth.addr.*.reject", "protocol/server"}, {"write-behind", "performance/write-behind:!perf"}, {"read-ahead", "performance/read-ahead:!perf"}, @@ -330,54 +337,98 @@ first_of (glusterfs_graph_t *graph) **************************/ +typedef int (*volgen_opthandler_t) (glusterfs_graph_t *graph, + struct volopt_map_entry2 *vme2, + void *param); + +struct opthandler_data { + glusterfs_graph_t *graph; + volgen_opthandler_t handler; + struct volopt_map_entry *vme; + gf_boolean_t found; + gf_boolean_t data_t_fake; + int rv; + void *param; +}; + +static void +process_option (dict_t *dict, char *key, data_t *value, void *param) +{ + struct opthandler_data *data = param; + struct volopt_map_entry2 vme2 = {0,}; + + if (data->rv) + return; + if (fnmatch (data->vme->key, key, 0) != 0) + return; + + data->found = _gf_true; + + vme2.key = key; + vme2.voltype = gf_strdup (data->vme->voltype); + if (!vme2.voltype) { + gf_log ("", GF_LOG_ERROR, "Out of memory"); + + data->rv = -1; + return; + } + vme2.option = strchr (vme2.voltype, ':'); + if (vme2.option) { + *vme2.option = '\0'; + vme2.option++; + } else + vme2.option = key; + if (data->data_t_fake) + vme2.value = (char *)value; + else + vme2.value = value->data; + + data->rv = data->handler (data->graph, &vme2, data->param); + + GF_FREE (vme2.voltype); +} + static int volgen_graph_set_options_generic (glusterfs_graph_t *graph, dict_t *dict, - void *param, - int (*handler) (glusterfs_graph_t *graph, - struct volopt_map_entry2 *vme2, - void *param)) + void *param, volgen_opthandler_t handler) { struct volopt_map_entry *vme = NULL; - struct volopt_map_entry2 vme2 = {0,}; - struct volopt_map_entry2 *vme2x = NULL; - char *value = NULL; - int ret = 0; + struct volopt_map_entry2 *vme2 = NULL; + struct opthandler_data data = {0,}; + + data.graph = graph; + data.handler = handler; + data.param = param; for (vme = glusterd_volopt_map; vme->key; vme++) { - ret = dict_get_str (dict, vme->key, &value); - if (ret) { - for (vme2x = default_volopt_map2; vme2x->key; - vme2x++) { - if (strcmp (vme2x->key, vme->key) == 0) { - value = vme2x->value; - ret = 0; - break; - } - } - } - if (ret) - continue; + data.vme = vme; + data.found = _gf_false; + data.data_t_fake = _gf_false; - vme2.key = vme->key; - vme2.voltype = gf_strdup (vme->voltype); - if (!vme2.voltype) { - gf_log ("", GF_LOG_ERROR, "Out of memory"); + dict_foreach (dict, process_option, &data); + if (data.rv) + return data.rv; - return -1; - } - vme2.option = strchr (vme2.voltype, ':'); - if (vme2.option) { - *vme2.option = '\0'; - vme2.option++; - } else - vme2.option = vme->key; - vme2.value = value; + if (data.found) + continue; - ret = handler (graph, &vme2, param); + /* check for default value */ + for (vme2 = default_volopt_map2; vme2->key; + vme2++) { + if (strcmp (vme2->key, vme->key) != 0) + continue; + + /* stupid hack to be able to reuse dict iterator + * in this context + */ + data.data_t_fake = _gf_true; + process_option (NULL, vme->key, (data_t *)vme2->value, + &data); + if (data.rv) + return data.rv; - GF_FREE (vme2.voltype); - if (ret) - return -1; + break; + } } return 0; @@ -435,14 +486,52 @@ glusterd_volinfo_get (glusterd_volinfo_t *volinfo, char *key, char **value) ret = volgen_graph_set_options_generic (NULL, volinfo->dict, &vme2, &optget_option_handler); - if (ret) + if (ret) { + gf_log ("", GF_LOG_ERROR, "Out of memory"); + return -1; + } *value = vme2.value; return 0; } +int +glusterd_check_option_exists (char *key) +{ + dict_t *dict = NULL; + struct volopt_map_entry2 vme2 = {0,}; + int ret = 0; + + vme2.key = key; + + /* We are getting a bit anal here to avoid typing + * fnmatch one more time. Orthogonality foremost! + * The internal logic of looking up in the volopt_map table + * should be coded exactly once. + * + * [[Ha-ha-ha, so now if I ever change the internals then I'll + * have to update the fnmatch in this comment also :P ]] + */ + dict = get_new_dict (); + if (!dict || dict_set_str (dict, key, "")) + goto oom; + + ret = volgen_graph_set_options_generic (NULL, dict, &vme2, + &optget_option_handler); + dict_destroy (dict); + if (ret) + goto oom; + + return !!vme2.value; + + oom: + gf_log ("", GF_LOG_ERROR, "Out of memory"); + + return -1; +} + static int volgen_graph_merge_sub (glusterfs_graph_t *dgraph, glusterfs_graph_t *sgraph) { @@ -557,50 +646,6 @@ get_vol_transport_type (glusterd_volinfo_t *volinfo, char *tt) strcpy (tt, "tcp"); } -static int -server_auth_option_handler (glusterfs_graph_t *graph, - struct volopt_map_entry2 *vme2, void *param) -{ - char *brick = NULL; - char *addrs = NULL; - char *opt = NULL; - int ret = 0; - - if (strcmp (vme2->option, "!server-auth") != 0) - return 0; - - brick = gf_strdup (vme2->value); - if (!brick) { - ret = -1; - goto out; - } - addrs = strchr (brick, ':'); - if (!addrs || !addrs[1]) { - GF_FREE (brick); - return -1; - } - *addrs++ = '\0'; - ret = gf_asprintf (&opt, vme2->key, brick); - if (ret == -1) { - opt = NULL; - goto out; - } - ret = xlator_set_option (first_of (graph), opt, addrs); - - out: - if (brick) - GF_FREE (brick); - if (opt) - GF_FREE (opt); - - if (ret == 0) - return 0; - - gf_log ("", GF_LOG_ERROR, "Out of memory"); - - return -1; -} - static int server_graph_builder (glusterfs_graph_t *graph, glusterd_volinfo_t *volinfo, dict_t *set_dict, void *param) @@ -693,9 +738,6 @@ server_graph_builder (glusterfs_graph_t *graph, glusterd_volinfo_t *volinfo, ret = xlator_set_option (xl, aaa, "*"); GF_FREE (aaa); - ret = volgen_graph_set_options_generic (graph, set_dict, NULL, - &server_auth_option_handler); - return ret; } diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.h b/xlators/mgmt/glusterd/src/glusterd-volgen.h index fe706ef335c..16bf1c73ea4 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.h +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.h @@ -27,13 +27,6 @@ #include "glusterd.h" -struct volopt_map_entry { - char *key; - char *voltype; -}; - -extern struct volopt_map_entry glusterd_volopt_map[]; - int glusterd_create_rb_volfiles (glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *brickinfo); -- cgit