Patchwork [BUG:1750,1/1] volgen: impemlent dynamic (pattern-based) option matching

login
register
Submitter Csaba Henk
Date 2010-10-03 20:27:11
Message ID <1286137631-11040-1-git-send-email-csaba@gluster.com>
Download mbox | patch
Permalink /patch/5216/
State Accepted
Headers show

Comments

Csaba Henk - 2010-10-03 20:27:11
So now auth.addr.*.allow can be a basic option, without any specific support code!

Signed-off-by: Csaba Henk <csaba@gluster.com>
---
 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(-)

Patch

diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index 513be5b..7a69d2c 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 04867da..5c557b3 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 7c18b69..e6aa91b 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 619e329..9e672a5 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 <fnmatch.h>
+
 #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)
 {
@@ -558,50 +647,6 @@  get_vol_transport_type (glusterd_volinfo_t *volinfo, char *tt)
 }
 
 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 fe706ef..16bf1c7 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);