Patchwork [BUG:2064] CLI : NFS persistent local/global options.

login
register
Submitter Gaurav
Date 2011-03-01 11:32:39
Message ID <1298979159-13601-1-git-send-email-gaurav@gluster.com>
Download mbox | patch
Permalink /patch/6315/
State Accepted
Delegated to: Anand Avati
Headers show

Comments

Gaurav - 2011-03-01 11:32:39
From: Gaurav <gaurav@gluster.com>


Signed-off-by: Gaurav <gaurav@gluster.com>
---
 xlators/mgmt/glusterd/src/glusterd-handler.c |   15 +-
 xlators/mgmt/glusterd/src/glusterd-op-sm.c   |  211 ++++++++---
 xlators/mgmt/glusterd/src/glusterd-utils.c   |    1 +
 xlators/mgmt/glusterd/src/glusterd-volgen.c  |  524 +++++++++++++++++++++-----
 xlators/mgmt/glusterd/src/glusterd-volgen.h  |    5 +
 xlators/mgmt/glusterd/src/glusterd.h         |    3 +
 6 files changed, 597 insertions(+), 162 deletions(-)

Patch

diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index b2d191b..efba9e2 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -284,11 +284,16 @@  glusterd_add_volume_detail_to_dict (glusterd_volinfo_t *volinfo,
         dict_t                  *dict = NULL;
         data_t                  *value = NULL;
         int                     opt_count = 0;
+        glusterd_conf_t         *priv = NULL;
 
 
         GF_ASSERT (volinfo);
         GF_ASSERT (volumes);
 
+        priv = THIS->private;
+
+        GF_ASSERT (priv);
+
         snprintf (key, 256, "volume%d.name", count);
         ret = dict_set_str (volumes, key, volinfo->volname);
         if (ret)
@@ -342,11 +347,11 @@  glusterd_add_volume_detail_to_dict (glusterd_volinfo_t *volinfo,
         while (pairs) {
                 if (1 == glusterd_check_option_exists (pairs->key, NULL)) {
                         value = pairs->value;
-                        if (!value) 
+                        if (!value)
                                 continue;
 
-                        snprintf (reconfig_key, 256, "volume%d.option.%s", count, 
-                                 pairs->key);
+                        snprintf (reconfig_key, 256, "volume%d.option.%s", count,
+                                  pairs->key);
                         ret = dict_set_str  (volumes, reconfig_key, value->data);
                         if (!ret)
                             opt_count++;
@@ -356,9 +361,6 @@  glusterd_add_volume_detail_to_dict (glusterd_volinfo_t *volinfo,
 
         snprintf (key, 256, "volume%d.opt_count", count);
         ret = dict_set_int32 (volumes, key, opt_count);
-        if (ret)
-            goto out;
-
 out:
         return ret;
 }
@@ -3429,7 +3431,6 @@  respond:
         ret = dict_set_int32 (volumes, "count", count);
         if (ret)
                 goto out;
-
         ret = dict_allocate_and_serialize (volumes, &rsp.volumes.volumes_val,
                                            (size_t *)&rsp.volumes.volumes_len);
 
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index 9cf34fe..fc8f86a 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -1098,6 +1098,21 @@  glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)
         char                                     errstr[2048]  = {0, };
         glusterd_volinfo_t                      *volinfo       = NULL;
         dict_t                                  *val_dict      = NULL;
+        gf_boolean_t                             global_opt    = _gf_false;
+        glusterd_volinfo_t                      *voliter       = NULL;
+        glusterd_conf_t                         *priv          = NULL;
+        xlator_t                                *this          = NULL;
+
+        GF_ASSERT (dict);
+        this = THIS;
+        GF_ASSERT (this);
+        priv = this->private;
+        GF_ASSERT (priv);
+
+        val_dict = dict_new();
+        if (!val_dict)
+                goto out;
+
 
         ret = dict_get_str (dict, "volname", &volname);
         if (ret) {
@@ -1144,7 +1159,7 @@  glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)
 
 
 	for ( count = 1; ret != 1 ; count++ ) {
-
+                global_opt = _gf_false;
 		sprintf (str, "key%d", count);
 		ret = dict_get_str (dict, str, &key);
 
@@ -1183,6 +1198,11 @@  glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)
 
                 if (key_fixed)
                         key = key_fixed;
+
+                ret = glusterd_check_globaloption (key);
+                if (ret)
+                        global_opt = _gf_true;
+
                 ret = dict_set_str (val_dict, key, value);
 
                 if (ret) {
@@ -1196,14 +1216,25 @@  glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)
                         GF_FREE (key_fixed);
                         key_fixed = NULL;
                 }
-	}
 
-        *op_errstr = NULL;
-        ret = glusterd_validate_reconfopts (volinfo, val_dict, op_errstr);
-        if (ret) {
-                gf_log ("glusterd", GF_LOG_DEBUG, "Could not create temp "
-                        "volfile, some option failed: %s", *op_errstr);
-                goto out;
+                *op_errstr = NULL;
+                if (!global_opt)
+                        ret = glusterd_validate_reconfopts (volinfo, val_dict, op_errstr);
+                else {
+                        voliter = NULL;
+                        list_for_each_entry (voliter, &priv->volumes, vol_list) {
+                                ret = glusterd_validate_globalopts (voliter, val_dict, op_errstr);
+                                if (ret)
+                                        break;
+                        }
+                }
+
+                if (ret) {
+                        gf_log ("glusterd", GF_LOG_DEBUG, "Could not create temp "
+                                "volfile, some option failed: %s", *op_errstr);
+                        goto out;
+                }
+                dict_del (val_dict, key);
         }
 
 
@@ -3839,7 +3870,6 @@  glusterd_restart_brick_servers (glusterd_volinfo_t *volinfo)
         return 0;
 }
 
-
 static int
 glusterd_op_set_volume (dict_t *dict)
 {
@@ -3848,12 +3878,14 @@  glusterd_op_set_volume (dict_t *dict)
         char                                    *volname = NULL;
         xlator_t                                *this = NULL;
         glusterd_conf_t                         *priv = NULL;
-	int					 count = 1;
+        int                                      count = 1;
         int                                      restart_flag = 0;
 	char					*key = NULL;
 	char					*key_fixed = NULL;
 	char					*value = NULL;
 	char					 str[50] = {0, };
+        gf_boolean_t                             global_opt    = _gf_false;
+        glusterd_volinfo_t                       *voliter = NULL;
 
         this = THIS;
         GF_ASSERT (this);
@@ -3876,8 +3908,14 @@  glusterd_op_set_volume (dict_t *dict)
 
 	for ( count = 1; ret != -1 ; count++ ) {
 
-		sprintf (str, "key%d", count);
-		ret = dict_get_str (dict, str, &key);
+                global_opt = _gf_false;
+                sprintf (str, "key%d", count);
+                ret = dict_get_str (dict, str, &key);
+
+                if (ret) {
+                        break;
+                }
+
                 if (!ret) {
                         ret = glusterd_check_option_exists (key, &key_fixed);
                         GF_ASSERT (ret);
@@ -3888,26 +3926,45 @@  glusterd_op_set_volume (dict_t *dict)
                         ret = 0;
                 }
 
-		if (ret)
-			break;
-
-		sprintf (str, "value%d", count);
-		ret = dict_get_str (dict, str, &value);
+                ret = glusterd_check_globaloption (key);
+                if (ret)
+                        global_opt = _gf_true;
 
-		if (ret) {
+                sprintf (str, "value%d", count);
+                ret = dict_get_str (dict, str, &value);
+                if (ret) {
                         gf_log ("", GF_LOG_ERROR,
                                 "invalid key,value pair in 'volume set'");
-			ret = -1;
-			goto out;
-        	}
+                        ret = -1;
+                        goto out;
+                }
 
-                value = gf_strdup (value);
-                if (value) {
-                        if (key_fixed)
-                                key = key_fixed;
-		        ret = dict_set_dynstr (volinfo->dict, key, value);
-                } else
+                if (!global_opt)
+                        value = gf_strdup (value);
+
+                if (!value) {
+                        gf_log ("", GF_LOG_ERROR,
+                                "Unable to set the options in 'volume set'");
                         ret = -1;
+                        goto out;
+                }
+
+                if (key_fixed)
+                        key = key_fixed;
+
+                if (global_opt) {
+                       list_for_each_entry (voliter, &priv->volumes, vol_list) {
+                               value = gf_strdup (value);
+                               ret = dict_set_dynstr (voliter->dict, key, value);
+                               if (ret)
+                                       goto out;
+                       }
+                }
+                else {
+                        ret = dict_set_dynstr (volinfo->dict, key, value);
+                        if (ret)
+                                goto out;
+                }
 
                 if (strcmp (key, MARKER_VOL_KEY) == 0 &&
                     GLUSTERD_STATUS_STARTED == volinfo->status) {
@@ -3915,51 +3972,93 @@  glusterd_op_set_volume (dict_t *dict)
                         restart_flag = 1;
                 }
 
-		if (ret) {
-                        gf_log ("", GF_LOG_ERROR,
-                                "Unable to set the options in 'volume set'");
-			ret = -1;
-			goto out;
-        	}
 
                 if (key_fixed) {
                         GF_FREE (key_fixed);
+
                         key_fixed = NULL;
                 }
-	}
-
-	if ( count == 1 ) {
-		gf_log ("", GF_LOG_ERROR, "No options received ");
-		ret = -1;
-		goto out;
-	}
+        }
 
-	ret = glusterd_create_volfiles (volinfo);
 
-	if (ret) {
-                gf_log ("", GF_LOG_ERROR, "Unable to create volfile for"
-                        " 'volume set'");
-		ret = -1;
-		goto out;
+        if ( count == 1 ) {
+                gf_log ("", GF_LOG_ERROR, "No options received ");
+                ret = -1;
+                goto out;
         }
 
-        if (restart_flag) {
-                if (glusterd_restart_brick_servers (volinfo)) {
+        if (!global_opt) {
+                ret = glusterd_create_volfiles (volinfo);
+                if (ret) {
+                        gf_log ("", GF_LOG_ERROR, "Unable to create volfile for"
+                                " 'volume set'");
                         ret = -1;
                         goto out;
                 }
+
+                if (restart_flag) {
+                        if (glusterd_restart_brick_servers (volinfo)) {
+                                ret = -1;
+                                goto out;
+                        }
+                }
+
+                ret = glusterd_store_update_volume (volinfo);
+                if (ret)
+                        goto out;
+
+                ret = glusterd_volume_compute_cksum (volinfo);
+                if (ret)
+                        goto out;
+
+                if (GLUSTERD_STATUS_STARTED == volinfo->status) {
+                        ret = glusterd_check_generate_start_nfs (volinfo);
+                        if (ret) {
+                                gf_log ("", GF_LOG_WARNING,
+                                         "Unable to restart NFS-Server");
+                                goto out;
+                        }
+                }
+
         }
+        else {
+                list_for_each_entry (voliter, &priv->volumes, vol_list) {
+                        volinfo = voliter;
+                        ret = glusterd_create_volfiles (volinfo);
+                        if (ret) {
+                                gf_log ("", GF_LOG_ERROR, "Unable to create volfile for"
+                                        " 'volume set'");
+                                ret = -1;
+                                goto out;
+                        }
 
-        ret = glusterd_store_update_volume (volinfo);
-        if (ret)
-                goto out;
+                        if (restart_flag) {
+                                if (glusterd_restart_brick_servers (volinfo)) {
+                                        ret = -1;
+                                        goto out;
+                                }
+                        }
+
+                        ret = glusterd_store_update_volume (volinfo);
+                        if (ret)
+                                goto out;
+
+                        ret = glusterd_volume_compute_cksum (volinfo);
+                        if (ret)
+                                goto out;
+
+                        if (GLUSTERD_STATUS_STARTED == volinfo->status) {
+                                ret = glusterd_check_generate_start_nfs (volinfo);
+                                if (ret) {
+                                        gf_log ("", GF_LOG_WARNING,
+                                                "Unable to restart NFS-Server");
+                                        goto out;
+                                }
+                        }
+                }
+        }
 
-        ret = glusterd_volume_compute_cksum (volinfo);
-        if (ret)
-                goto out;
 
-        if (GLUSTERD_STATUS_STARTED == volinfo->status)
-                ret = glusterd_check_generate_start_nfs (volinfo);
 
         ret = 0;
 
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 8da1b06..0c91047 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -1816,6 +1816,7 @@  glusterd_check_generate_start_nfs (glusterd_volinfo_t *volinfo)
                 goto out;
         }
 
+
         ret = glusterd_create_nfs_volfile ();
         if (ret)
                 goto out;
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c
index 90b227c..ec14b66 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c
@@ -75,71 +75,91 @@ 
  * "NODOC" entries are not part of the public interface and are subject
  * to change at any time.
  */
+typedef enum  { DOC, NO_DOC, GLOBAL_DOC, GLOBAL_NO_DOC } option_type_t;
+
 
 struct volopt_map_entry {
         char *key;
         char *voltype;
         char *option;
         char *value;
+        option_type_t type;
 };
 
 static struct volopt_map_entry glusterd_volopt_map[] = {
-        {"cluster.lookup-unhashed",              "cluster/distribute",        }, /* NODOC */
-        {"cluster.min-free-disk",                "cluster/distribute",        }, /* NODOC */
-
-        {"cluster.entry-change-log",             "cluster/replicate",         }, /* NODOC */
-        {"cluster.read-subvolume",               "cluster/replicate",         }, /* NODOC */
-        {"cluster.background-self-heal-count",   "cluster/replicate",         }, /* NODOC */
-        {"cluster.metadata-self-heal",           "cluster/replicate",         }, /* NODOC */
-        {"cluster.data-self-heal",               "cluster/replicate",         }, /* NODOC */
-        {"cluster.entry-self-heal",              "cluster/replicate",         }, /* NODOC */
-        {"cluster.strict-readdir",               "cluster/replicate",         }, /* NODOC */
-        {"cluster.self-heal-window-size",        "cluster/replicate",         "data-self-heal-window-size",},
-        {"cluster.data-change-log",              "cluster/replicate",         }, /* NODOC */
-        {"cluster.metadata-change-log",          "cluster/replicate",         }, /* NODOC */
-        {"cluster.data-self-heal-algorithm",     "cluster/replicate",         "data-self-heal-algorithm"},
-
-        {"cluster.stripe-block-size",            "cluster/stripe",            "block-size",},
-
-        {"diagnostics.latency-measurement",      "debug/io-stats",            },
-        {"diagnostics.dump-fd-stats",            "debug/io-stats",            },
-        {"diagnostics.brick-log-level",          "debug/io-stats",            "!log-level",},
-        {"diagnostics.client-log-level",         "debug/io-stats",            "!log-level",},
-
-        {"performance.cache-max-file-size",      "performance/io-cache",      "max-file-size",},
-        {"performance.cache-min-file-size",      "performance/io-cache",      "min-file-size",},
-        {"performance.cache-refresh-timeout",    "performance/io-cache",      "cache-timeout",},
-        {"performance.cache-priority",           "performance/io-cache",      "priority",}, /* NODOC */
-        {"performance.cache-size",               "performance/io-cache",      },
-        {"performance.cache-size",               "performance/quick-read",    },
-        {"performance.flush-behind",             "performance/write-behind",      "flush-behind",},
-
-        {"performance.io-thread-count",          "performance/io-threads",    "thread-count",},
-
-        {"performance.disk-usage-limit",         "performance/quota",         }, /* NODOC */
-        {"performance.min-free-disk-limit",      "performance/quota",         }, /* NODOC */
-
-        {"performance.write-behind-window-size", "performance/write-behind",  "cache-size",},
-
-        {"network.frame-timeout",                "protocol/client",           },
-        {"network.ping-timeout",                 "protocol/client",           },
-        {"network.inode-lru-limit",              "protocol/server",           }, /* NODOC */
 
-        {"auth.allow",                           "protocol/server",           "!server-auth", "*"},
-        {"auth.reject",                          "protocol/server",           "!server-auth",},
-
-        {"transport.keepalive",                   "protocol/server",           "transport.socket.keepalive",},
-
-        {"performance.write-behind",             "performance/write-behind",  "!perf", "on"}, /* NODOC */
-        {"performance.read-ahead",               "performance/read-ahead",    "!perf", "on"}, /* NODOC */
-        {"performance.io-cache",                 "performance/io-cache",      "!perf", "on"}, /* NODOC */
-        {"performance.quick-read",               "performance/quick-read",    "!perf", "on"}, /* NODOC */
-        {"performance.stat-prefetch",            "performance/stat-prefetch", "!perf", "on"},      /* NODOC */
-
-        {"nfs.enable-ino32",                     "nfs/server",                "nfs.enable-ino32",},
-        {"nfs.mem-factor",                       "nfs/server",                "nfs.mem-factor",},
-
-        {MARKER_VOL_KEY,                         "features/marker",           "!marker", "off"},
+        {"cluster.lookup-unhashed",              "cluster/distribute", NULL, NULL, NO_DOC       }, /* NODOC */
+        {"cluster.min-free-disk",                "cluster/distribute", NULL, NULL, NO_DOC       }, /* NODOC */
+
+        {"cluster.entry-change-log",             "cluster/replicate",  NULL, NULL, NO_DOC        }, /* NODOC */
+        {"cluster.read-subvolume",               "cluster/replicate",  NULL, NULL, NO_DOC       }, /* NODOC */
+        {"cluster.background-self-heal-count",   "cluster/replicate",  NULL, NULL, NO_DOC       }, /* NODOC */
+        {"cluster.metadata-self-heal",           "cluster/replicate",  NULL, NULL, NO_DOC        }, /* NODOC */
+        {"cluster.data-self-heal",               "cluster/replicate",  NULL, NULL, NO_DOC        }, /* NODOC */
+        {"cluster.entry-self-heal",              "cluster/replicate",  NULL, NULL, NO_DOC        }, /* NODOC */
+        {"cluster.strict-readdir",               "cluster/replicate",  NULL, NULL, NO_DOC        }, /* NODOC */
+        {"cluster.self-heal-window-size",        "cluster/replicate",         "data-self-heal-window-size", NULL, DOC},
+        {"cluster.data-change-log",              "cluster/replicate",  NULL, NULL, NO_DOC        }, /* NODOC */
+        {"cluster.metadata-change-log",          "cluster/replicate",  NULL, NULL, NO_DOC        }, /* NODOC */
+        {"cluster.data-self-heal-algorithm",     "cluster/replicate",         "data-self-heal-algorithm", NULL,DOC},
+
+        {"cluster.stripe-block-size",            "cluster/stripe",            "block-size", NULL, DOC},
+
+        {"diagnostics.latency-measurement",      "debug/io-stats",     NULL, NULL, NO_DOC         },
+        {"diagnostics.dump-fd-stats",            "debug/io-stats",     NULL, NULL, NO_DOC        },
+        {"diagnostics.brick-log-level",          "debug/io-stats",            "!log-level", NULL, DOC},
+        {"diagnostics.client-log-level",         "debug/io-stats",            "!log-level", NULL, DOC},
+
+        {"performance.cache-max-file-size",      "performance/io-cache",      "max-file-size", NULL, DOC},
+        {"performance.cache-min-file-size",      "performance/io-cache",      "min-file-size", NULL, DOC},
+        {"performance.cache-refresh-timeout",    "performance/io-cache",      "cache-timeout", NULL, DOC},
+        {"performance.cache-priority",           "performance/io-cache",      "priority", NULL, DOC}, /* NODOC */
+        {"performance.cache-size",               "performance/io-cache",   NULL, NULL, NO_DOC    },
+        {"performance.cache-size",               "performance/quick-read", NULL, NULL, NO_DOC    },
+        {"performance.flush-behind",             "performance/write-behind",      "flush-behind", NULL, DOC},
+
+        {"performance.io-thread-count",          "performance/io-threads",    "thread-count", DOC},
+
+        {"performance.disk-usage-limit",         "performance/quota",   NULL, NULL, NO_DOC       }, /* NODOC */
+        {"performance.min-free-disk-limit",      "performance/quota",   NULL, NULL, NO_DOC       }, /* NODOC */
+
+        {"performance.write-behind-window-size", "performance/write-behind",  "cache-size", NULL, DOC},
+
+        {"network.frame-timeout",                "protocol/client",    NULL, NULL, NO_DOC        },
+        {"network.ping-timeout",                 "protocol/client",    NULL, NULL, NO_DOC        },
+        {"network.inode-lru-limit",              "protocol/server",    NULL, NULL, NO_DOC        }, /* NODOC */
+
+        {"auth.allow",                           "protocol/server",           "!server-auth", "*", DOC},
+        {"auth.reject",                          "protocol/server",           "!server-auth", NULL, DOC},
+
+        {"transport.keepalive",                   "protocol/server",           "transport.socket.keepalive", NULL, NO_DOC},
+
+        {"performance.write-behind",             "performance/write-behind",  "!perf", "on", NO_DOC}, /* NODOC */
+        {"performance.read-ahead",               "performance/read-ahead",    "!perf", "on", NO_DOC}, /* NODOC */
+        {"performance.io-cache",                 "performance/io-cache",      "!perf", "on", NO_DOC}, /* NODOC */
+        {"performance.quick-read",               "performance/quick-read",    "!perf", "on", NO_DOC}, /* NODOC */
+        {"performance.stat-prefetch",            "performance/stat-prefetch", "!perf", "on", NO_DOC},      /* NODOC */
+
+        {MARKER_VOL_KEY,                         "features/marker",           "!marker", "off", NO_DOC},
+
+        {"nfs.enable-ino32",                     "nfs/server",                "nfs.enable-ino32", NULL, GLOBAL_DOC},
+        {"nfs.export-dirs",                      "nfs/server",                "nfs3.export-dirs", NULL, GLOBAL_DOC},
+        {"nfs.export-volumes",                   "nfs/server",                "nfs3.export-volumes", NULL, GLOBAL_DOC},
+        {"nfs.addr-namelookup",                  "nfs/server",                "rpc-auth.addr.namelookup", NULL, GLOBAL_DOC},
+        {"nfs.dynamic-volumes",                  "nfs/server",                "nfs.dynamic-volumes", NULL, GLOBAL_DOC},
+        {"nfs.register-with-portmap",            "nfs/server",                "rpc.register-with-portmap", NULL, GLOBAL_DOC},
+        {"nfs.port",                             "nfs/server",                "nfs.port", NULL, GLOBAL_DOC},
+
+        {"nfs.rpc-auth-unix",                    "nfs/server",                "!nfs.rpc-auth-auth-unix", NULL, DOC},
+        {"nfs.rpc-auth-null",                    "nfs/server",                "!nfs.rpc-auth-auth-null", NULL, DOC},
+        {"nfs.rpc-auth-allow",                   "nfs/server",                "!nfs.rpc-auth.addr.allow", NULL, DOC},
+        {"nfs.rpc-auth-reject",                  "nfs/server",                "!nfs.rpc-auth.addr.reject", NULL, DOC},
+        {"nfs.ports-insecure",                   "nfs/server",                "!nfs.auth.ports.insecure", NULL, DOC},
+
+        {"nfs.trusted-sync",                     "nfs/server",                "!nfs-trusted-sync", NULL, DOC},
+        {"nfs.trusted-write",                    "nfs/server",                "!nfs-trusted-write", NULL, DOC},
+        {"nfs.volume-access",                    "nfs/server",                "!nfs-volume-access", NULL, DOC},
+        {"nfs.export-dir",                       "nfs/server",                "!nfs-export-dir", NULL, DOC},
 
         {NULL,                                                                }
 };
@@ -154,6 +174,7 @@  static struct volopt_map_entry glusterd_volopt_map[] = {
 
 
 
+
 static xlator_t *
 xlator_instantiate_va (const char *type, const char *format, va_list arg)
 {
@@ -531,6 +552,7 @@  struct opthandler_data {
         gf_boolean_t found;
         gf_boolean_t data_t_fake;
         int rv;
+        char *volname;
         void *param;
 };
 
@@ -718,6 +740,109 @@  glusterd_volinfo_get (glusterd_volinfo_t *volinfo, char *key, char **value)
         return volgen_dict_get (volinfo->dict, key, value);
 }
 
+gf_boolean_t
+glusterd_check_globaloption (char *key)
+{
+        char *completion = NULL;
+        struct volopt_map_entry *vmep = NULL;
+        int   ret = 0;
+
+        if (!strchr (key, '.')) {
+                ret = option_complete (key, &completion);
+                if (ret) {
+                        gf_log ("", GF_LOG_ERROR, "Out of memory");
+                        return _gf_false;
+                }
+
+                if (!completion) {
+                        gf_log ("", GF_LOG_ERROR, "option %s does not exist",
+                                        key);
+                        return _gf_false;
+                }
+        }
+
+        for (vmep = glusterd_volopt_map; vmep->key; vmep++) {
+                if (strcmp (vmep->key, key) == 0) {
+                        if ((vmep->type == GLOBAL_DOC) ||
+                            (vmep->type == GLOBAL_NO_DOC))
+                                return _gf_true;
+                        else
+                                return _gf_false;
+                }
+        }
+
+        return _gf_false;
+}
+
+gf_boolean_t
+glusterd_check_localoption (char *key)
+{
+        char *completion = NULL;
+        struct volopt_map_entry *vmep = NULL;
+        int   ret = 0;
+
+        if (!strchr (key, '.')) {
+                ret = option_complete (key, &completion);
+                if (ret) {
+                        gf_log ("", GF_LOG_ERROR, "Out of memory");
+                        return _gf_false;
+                }
+
+                if (!completion) {
+                        gf_log ("", GF_LOG_ERROR, "option %s does not exist",
+                                        key);
+                        return _gf_false;
+               }
+        }
+
+        for (vmep = glusterd_volopt_map; vmep->key; vmep++) {
+                if (strcmp (vmep->key, key) == 0) {
+                        if ((vmep->type == DOC) ||
+                            (vmep->type == NO_DOC))
+                                return _gf_true;
+                        else
+                                return _gf_false;
+                }
+        }
+
+        return _gf_false;
+}
+
+int
+glusterd_check_voloption (char *key)
+{
+        char *completion = NULL;
+        struct volopt_map_entry *vmep = NULL;
+        int ret = 0;
+
+        if (!strchr (key, '.')) {
+                ret = option_complete (key, &completion);
+                if (ret) {
+                        gf_log ("", GF_LOG_ERROR, "Out of memory");
+                        return _gf_false;
+                }
+
+                if (!completion) {
+                        gf_log ("", GF_LOG_ERROR, "option %s does not exist",
+                                        key);
+                        return _gf_false;
+                }
+        }
+
+        for (vmep = glusterd_volopt_map; vmep->key; vmep++) {
+                if (strcmp (vmep->key, key) == 0) {
+                        if ((vmep->type == DOC) ||
+                            (vmep->type == DOC))
+                                return _gf_true;
+                        else
+                                return _gf_false;
+                }
+        }
+
+        return _gf_false;
+
+}
+
 int
 glusterd_check_option_exists (char *key, char **completion)
 {
@@ -1286,6 +1411,173 @@  build_client_graph (glusterfs_graph_t *graph, glusterd_volinfo_t *volinfo,
                                     &client_graph_builder);
 }
 
+static int
+nfs_option_handler (glusterfs_graph_t *graph,
+                            struct volopt_map_entry *vme, void *param)
+{
+        xlator_t *xl = NULL;
+        char *aa = NULL;
+        int   ret   = 0;
+        glusterd_volinfo_t *volinfo = NULL;
+
+        volinfo = param;
+
+        xl = first_of (graph);
+
+/*        if (vme->type  == GLOBAL_DOC || vme->type == GLOBAL_NO_DOC) {
+
+                ret = xlator_set_option (xl, vme->key, vme->value);
+        }*/
+        if ( !volinfo || !volinfo->volname)
+                return 0;
+
+        if (! strcmp (vme->option, "!nfs.rpc-auth-addr-allow")) {
+                ret = gf_asprintf (&aa, "rpc-auth.addr.%s.allow",
+                                        volinfo->volname);
+
+                if (ret != -1) {
+                        ret = xlator_set_option (xl, aa, vme->value);
+                        GF_FREE (aa);
+                }
+
+                if (ret)
+                        return -1;
+        }
+
+        if (! strcmp (vme->option, "!nfs.rpc-auth-addr-reject")) {
+                ret = gf_asprintf (&aa, "rpc-auth.addr.%s.reject",
+                                        volinfo->volname);
+
+                if (ret != -1) {
+                        ret = xlator_set_option (xl, aa, vme->value);
+                        GF_FREE (aa);
+                }
+
+                if (ret)
+                        return -1;
+        }
+
+        if (! strcmp (vme->option, "!nfs.rpc-auth-auth-unix")) {
+                ret = gf_asprintf (&aa, "rpc-auth.auth.unix.%s",
+                                        volinfo->volname);
+
+                if (ret != -1) {
+                        ret = xlator_set_option (xl, aa, vme->value);
+                        GF_FREE (aa);
+                }
+
+                if (ret)
+                        return -1;
+        }
+        if (! strcmp (vme->option, "!nfs.rpc-auth-auth-null")) {
+                ret = gf_asprintf (&aa, "rpc-auth.auth.null.%s",
+                                        volinfo->volname);
+
+                if (ret != -1) {
+                        ret = xlator_set_option (xl, aa, vme->value);
+                        GF_FREE (aa);
+                }
+
+                if (ret)
+                        return -1;
+        }
+
+        if (! strcmp (vme->option, "!nfs-trusted-sync")) {
+                ret = gf_asprintf (&aa, "nfs3.%s.trusted-sync",
+                                        volinfo->volname);
+
+                if (ret != -1) {
+                        ret = xlator_set_option (xl, aa, vme->value);
+                        GF_FREE (aa);
+                }
+
+                if (ret)
+                        return -1;
+        }
+
+        if (! strcmp (vme->option, "!nfs-trusted-write")) {
+                ret = gf_asprintf (&aa, "nfs3.%s.trusted-write",
+                                        volinfo->volname);
+
+                if (ret != -1) {
+                        ret = xlator_set_option (xl, aa, vme->value);
+                        GF_FREE (aa);
+                }
+
+                if (ret)
+                        return -1;
+        }
+
+        if (! strcmp (vme->option, "!nfs-volume-access")) {
+                ret = gf_asprintf (&aa, "nfs3.%s.volume-access",
+                                        volinfo->volname);
+
+                if (ret != -1) {
+                        ret = xlator_set_option (xl, aa, vme->value);
+                        GF_FREE (aa);
+                }
+
+                if (ret)
+                        return -1;
+        }
+
+        if (! strcmp (vme->option, "!nfs-export-dir")) {
+                ret = gf_asprintf (&aa, "nfs3.%s.export-dir",
+                                        volinfo->volname);
+
+                if (ret != -1) {
+                        ret = xlator_set_option (xl, aa, vme->value);
+                        GF_FREE (aa);
+                }
+
+                if (ret)
+                        return -1;
+        }
+
+
+
+        if (! strcmp (vme->option, "!nfs.ports-insecure")) {
+                ret = gf_asprintf (&aa, "rpc-auth.ports.%s.insecure",
+                                        volinfo->volname);
+
+                if (ret != -1) {
+                        ret = xlator_set_option (xl, aa, vme->value);
+                        GF_FREE (aa);
+                }
+
+                if (ret)
+                        return -1;
+        }
+
+
+        /*key = strchr (vme->key, '.') + 1;
+
+        for (trav = xl->children; trav; trav = trav->next) {
+                ret = gf_asprintf (&aa, "auth.addr.%s.%s", trav->xlator->name,
+                                   key);
+                if (ret != -1) {
+                        ret = xlator_set_option (xl, aa, vme->value);
+                        GF_FREE (aa);
+                }
+                if (ret)
+                        return -1;
+        }*/
+
+        return 0;
+}
+
+static int
+nfs_spec_option_handler (glusterfs_graph_t *graph,
+                            struct volopt_map_entry *vme, void *param)
+{
+        int ret = 0;
+
+        ret = nfs_option_handler (graph, vme, param);
+        if (!ret)
+                return basic_option_handler (graph, vme, NULL);
+        return ret;
+}
+
 /* builds a graph for nfs server role, with option overrides in mod_dict */
 static int
 build_nfs_graph (glusterfs_graph_t *graph, dict_t *mod_dict)
@@ -1297,8 +1589,6 @@  build_nfs_graph (glusterfs_graph_t *graph, dict_t *mod_dict)
         dict_t             *set_dict      = NULL;
         xlator_t           *nfsxl         = NULL;
         char               *skey          = NULL;
-        char               *enable_ino32  = NULL;
-        char               *mem_factor     = NULL;
         int                 ret           = 0;
 
         this = THIS;
@@ -1306,10 +1596,7 @@  build_nfs_graph (glusterfs_graph_t *graph, dict_t *mod_dict)
         priv = this->private;
         GF_ASSERT (priv);
 
-        if (mod_dict)
-                set_dict = dict_copy (mod_dict, NULL);
-        else
-                set_dict = dict_new ();
+        set_dict = dict_new ();
         if (!set_dict) {
                 gf_log ("", GF_LOG_ERROR, "Out of memory");
                 return -1;
@@ -1355,36 +1642,6 @@  build_nfs_graph (glusterfs_graph_t *graph, dict_t *mod_dict)
                 if (ret)
                         goto out;
 
-                if (!dict_get (set_dict, "nfs.enable-ino32")) {
-                        ret = glusterd_volinfo_get (voliter,
-                                                    "nfs.enable-ino32",
-                                                    &enable_ino32);
-                        if (ret)
-                                goto out;
-                        if (enable_ino32) {
-                                ret = dict_set_str (set_dict,
-                                                    "nfs.enable-ino32",
-                                                    enable_ino32);
-                                if (ret)
-                                        goto out;
-                        }
-                }
-
-                if (!dict_get (set_dict, "nfs.mem-factor")) {
-                        ret = glusterd_volinfo_get (voliter,
-                                                    "nfs.mem-factor",
-                                                    &mem_factor);
-                        if (ret)
-                                goto out;
-                        if (mem_factor) {
-                                ret = dict_set_str (set_dict,
-                                                    "nfs.mem-factor",
-                                                    mem_factor);
-                                if (ret)
-                                        goto out;
-                        }
-                }
-
                 /* If both RDMA and TCP are the transport_type, use RDMA
                    for NFS client protocols */
                 if (voliter->transport_type == GF_TRANSPORT_BOTH_TCP_RDMA) {
@@ -1395,15 +1652,25 @@  build_nfs_graph (glusterfs_graph_t *graph, dict_t *mod_dict)
                 }
 
                 memset (&cgraph, 0, sizeof (cgraph));
-                ret = build_client_graph (&cgraph, voliter, set_dict);
+                ret = build_client_graph (&cgraph, voliter, mod_dict);
                 if (ret)
                         goto out;;
                 ret = volgen_graph_merge_sub (graph, &cgraph);
                 if (ret)
-                        goto out;;
+                        goto out;
+
+                if (mod_dict) {
+                        dict_copy (mod_dict, set_dict);
+                        ret = volgen_graph_set_options_generic (graph, set_dict, voliter,
+                                                        nfs_spec_option_handler);
+                }
+                else
+                        ret = volgen_graph_set_options_generic (graph, voliter->dict, voliter,
+                                                        nfs_spec_option_handler);
+
         }
 
-        ret = volgen_graph_set_options (graph, set_dict);
+
 
  out:
         dict_destroy (set_dict);
@@ -1706,8 +1973,6 @@  validate_nfsopts (glusterd_volinfo_t *volinfo,
         glusterfs_graph_t graph = {{0,},};
         int     ret = -1;
 
-        GF_ASSERT (volinfo);
-
         ret = build_nfs_graph (&graph, val_dict);
         if (!ret)
                 ret = graph_reconf_validateopt (&graph, op_errstr);
@@ -1786,14 +2051,75 @@  out:
         return ret;
 }
 
+static void
+_check_globalopt (dict_t *this, char *key, data_t *value, void *ret_val)
+{
+        int *ret = NULL;
+
+        ret = ret_val;
+        if (*ret)
+                return;
+        if (!glusterd_check_globaloption (key))
+                *ret = 1;
+}
+
+int
+glusterd_validate_globalopts (glusterd_volinfo_t *volinfo,
+                              dict_t *val_dict, char **op_errstr)
+{
+        int ret = 0;
+
+        dict_foreach (val_dict, _check_globalopt, &ret);
+        if (ret) {
+                *op_errstr = gf_strdup ( "option specified is not a global option");
+                return -1;
+        }
+        ret = glusterd_validate_brickreconf (volinfo, val_dict, op_errstr);
+
+        if (ret) {
+                gf_log ("", GF_LOG_DEBUG,
+                        "Could not Validate  bricks");
+                goto out;
+        }
+
+        ret = validate_clientopts (volinfo, val_dict, op_errstr);
+        if (ret) {
+                gf_log ("", GF_LOG_DEBUG,
+                        "Could not Validate client");
+                goto out;
+        }
+
+        ret = validate_nfsopts (volinfo, val_dict, op_errstr);
+
+
+out:
+                gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+                return ret;
+}
+
+static void
+_check_localopt (dict_t *this, char *key, data_t *value, void *ret_val)
+{
+        int *ret = NULL;
+
+        ret = ret_val;
+        if (*ret)
+                return;
+        if (!glusterd_check_localoption (key))
+                *ret = 1;
+}
+
 int
 glusterd_validate_reconfopts (glusterd_volinfo_t *volinfo, dict_t *val_dict,
                               char **op_errstr)
 {
-        int ret = -1;
-
-        gf_log ("", GF_LOG_DEBUG, "Inside Validate reconfigure options");
+        int ret = 0;
 
+        dict_foreach (val_dict, _check_localopt, &ret);
+        if (ret) {
+                *op_errstr = gf_strdup ( "option specified is not a local option");
+                return -1;
+        }
         ret = glusterd_validate_brickreconf (volinfo, val_dict, op_errstr);
 
         if (ret) {
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.h b/xlators/mgmt/glusterd/src/glusterd-volgen.h
index 372832c..4f4b4b7 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.h
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.h
@@ -43,4 +43,9 @@  int glusterd_delete_volfile (glusterd_volinfo_t *volinfo,
 
 int glusterd_volinfo_get (glusterd_volinfo_t *volinfo, char *key, char **value);
 
+int glusterd_validate_globalopts (glusterd_volinfo_t *volinfo, dict_t *val_dict, char **op_errstr);
+
+int glusterd_validate_localopts (dict_t *val_dict, char **op_errstr);
+gf_boolean_t glusterd_check_globaloption (char *key);
+
 #endif
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index 81c8884..d98ddb1 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -85,6 +85,9 @@  struct glusterd_store_iter_ {
 
 typedef struct glusterd_store_iter_     glusterd_store_iter_t;
 
+struct glusterd_volgen {
+        dict_t *dict;
+};
 typedef struct {
         struct _volfile_ctx *volfile;
 	pthread_mutex_t   mutex;