diff options
Diffstat (limited to 'xlators/nfs/server/src/nfs.c')
| -rw-r--r-- | xlators/nfs/server/src/nfs.c | 782 |
1 files changed, 712 insertions, 70 deletions
diff --git a/xlators/nfs/server/src/nfs.c b/xlators/nfs/server/src/nfs.c index 42edc95f6..75c8fe44e 100644 --- a/xlators/nfs/server/src/nfs.c +++ b/xlators/nfs/server/src/nfs.c @@ -2,19 +2,10 @@ Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.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 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 - General Public License for more details. - - You should have received a copy of the GNU 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. */ /* This is the primary translator source for NFS. @@ -41,6 +32,207 @@ #include "nfs-mem-types.h" #include "nfs3-helpers.h" #include "nlm4.h" +#include "options.h" +#include "acl3.h" +#include "rpc-drc.h" + +#define STRINGIFY(val) #val +#define TOSTRING(val) STRINGIFY(val) + +#define OPT_SERVER_AUX_GIDS "nfs.server-aux-gids" +#define OPT_SERVER_GID_CACHE_TIMEOUT "nfs.server.aux-gid-timeout" + +/* TODO: DATADIR should be based on configure's $(localstatedir) */ +#define DATADIR "/var/lib/glusterd" +#define NFS_DATADIR DATADIR "/nfs" + +/* Forward declaration */ +int nfs_add_initer (struct list_head *list, nfs_version_initer_t init); + +static int +nfs_init_version (xlator_t *this, nfs_version_initer_t init) +{ + int ret = -1; + struct nfs_initer_list *version = NULL; + struct nfs_initer_list *tmp = NULL; + rpcsvc_program_t *prog = NULL; + struct list_head *versions = NULL; + struct nfs_state *nfs = NULL; + gf_boolean_t found = _gf_false; + + if ((!this) || (!this->private) || (!init)) + return (-1); + + nfs = (struct nfs_state *)this->private; + + ret = nfs_add_initer (&nfs->versions, init); + if (ret == -1) { + gf_log (GF_NFS, GF_LOG_ERROR, + "Failed to add protocol initializer"); + goto err; + } + + versions = &nfs->versions; + list_for_each_entry_safe (version, tmp, versions, list) { + prog = version->program; + if (version->init == init) { + prog = init(this); + if (!prog) { + ret = -1; + goto err; + } + version->program = prog; + found = _gf_true; + break; + } + } + + /* program not added */ + if (!found) { + gf_log (GF_NFS, GF_LOG_ERROR, + "Program: %s NOT found", prog->progname); + goto err; + } + + /* Check if nfs.port is configured */ + if (nfs->override_portnum) + prog->progport = nfs->override_portnum; + + gf_log (GF_NFS, GF_LOG_DEBUG, "Starting program: %s", prog->progname); + + ret = rpcsvc_program_register (nfs->rpcsvc, prog); + if (ret == -1) { + gf_log (GF_NFS, GF_LOG_ERROR, "Program: %s init failed", + prog->progname); + goto err; + } + + /* Registration with portmapper is disabled, Nothing to do */ + if (!nfs->register_portmap) + goto err; + + ret = rpcsvc_program_register_portmap (prog, prog->progport); + if (ret == -1) { + gf_log (GF_NFS, GF_LOG_ERROR, + "Program %s registration failed", + prog->progname); + goto err; + } + ret = 0; /* All well */ +err: + return ret; +} + +static int +nfs_deinit_version (struct nfs_state *nfs, nfs_version_initer_t init) +{ + int ret = -1; + struct nfs_initer_list *version = NULL; + struct nfs_initer_list *tmp = NULL; + rpcsvc_program_t *prog = NULL; + struct list_head *versions = NULL; + + if ((!nfs) || (!init)) + return (-1); + + versions = &nfs->versions; + list_for_each_entry_safe (version, tmp, versions, list) { + prog = version->program; + if (version->init == init) { + prog = version->program; + ret = rpcsvc_program_unregister (nfs->rpcsvc, prog); + if (ret != 0) + return (-1); + list_del (&version->list); + GF_FREE (version); + return (0); + } + } + + return (-1); +} + +static int +nfs_reconfigure_acl3 (xlator_t *this) +{ + struct nfs_state *nfs = NULL; + + if ((!this) || (!this->private)) + return (-1); + + nfs = (struct nfs_state *)this->private; + + /* ACL is enabled */ + if (nfs->enable_acl) + return nfs_init_version (this, acl3svc_init); + + /* ACL is disabled */ + return nfs_deinit_version (nfs, acl3svc_init); +} + +static int +nfs_reconfigure_nlm4 (xlator_t *this) +{ + struct nfs_state *nfs = NULL; + + if ((!this) || (!this->private)) + return (-1); + + nfs = (struct nfs_state *)this->private; + + /* NLM is enabled */ + if (nfs->enable_nlm) + return nfs_init_version (this, nlm4svc_init); + + /* NLM is disabled */ + return nfs_deinit_version (nfs, nlm4svc_init); +} + +static int +nfs_program_register_portmap_all (struct nfs_state *nfs) +{ + struct list_head *versions = NULL; + struct nfs_initer_list *version = NULL; + struct nfs_initer_list *tmp = NULL; + rpcsvc_program_t *prog = NULL; + + if (nfs == NULL) + return (-1); + + versions = &nfs->versions; + list_for_each_entry_safe (version, tmp, versions, list) { + prog = version->program; + if (prog == NULL) + continue; + if (nfs->override_portnum) + prog->progport = nfs->override_portnum; + (void) rpcsvc_program_register_portmap (prog, prog->progport); + } + + return (0); +} + +static int +nfs_program_unregister_portmap_all (struct nfs_state *nfs) +{ + struct list_head *versions = NULL; + struct nfs_initer_list *version = NULL; + struct nfs_initer_list *tmp = NULL; + rpcsvc_program_t *prog = NULL; + + if (nfs == NULL) + return (-1); + + versions = &nfs->versions; + list_for_each_entry_safe (version, tmp, versions, list) { + prog = version->program; + if (prog == NULL) + continue; + (void) rpcsvc_program_unregister_portmap (prog); + } + + return (0); +} /* Every NFS version must call this function with the init function * for its particular version. @@ -118,7 +310,7 @@ nfs_init_versions (struct nfs_state *nfs, xlator_t *this) ret = -1; goto err; } -// prog->actorxl = this; + version->program = prog; if (nfs->override_portnum) prog->progport = nfs->override_portnum; @@ -127,17 +319,21 @@ nfs_init_versions (struct nfs_state *nfs, xlator_t *this) ret = rpcsvc_program_register (nfs->rpcsvc, prog); if (ret == -1) { - gf_log (GF_NFS, GF_LOG_ERROR, "Program init failed"); + gf_log (GF_NFS, GF_LOG_ERROR, "Program: %s init failed", + prog->progname); goto err; } - if (rpcsvc_register_portmap_enabled(nfs->rpcsvc)) { + if (nfs->register_portmap) { ret = rpcsvc_program_register_portmap (prog, prog->progport); if (ret == -1) { - gf_log (GF_NFS, GF_LOG_ERROR, "Program registration failed"); + gf_log (GF_NFS, GF_LOG_ERROR, + "Program %s registration failed", + prog->progname); goto err; } } + } ret = 0; @@ -154,22 +350,22 @@ nfs_add_all_initiators (struct nfs_state *nfs) /* Add the initializers for all versions. */ ret = nfs_add_initer (&nfs->versions, mnt3svc_init); if (ret == -1) { - gf_log (GF_NFS, GF_LOG_ERROR, "Failed to add protocol" - " initializer"); + gf_log (GF_NFS, GF_LOG_ERROR, "Failed to add " + "MOUNT3 protocol initializer"); goto ret; } ret = nfs_add_initer (&nfs->versions, mnt1svc_init); if (ret == -1) { - gf_log (GF_NFS, GF_LOG_ERROR, "Failed to add protocol" - " initializer"); + gf_log (GF_NFS, GF_LOG_ERROR, "Failed to add " + "MOUNT1 protocol initializer"); goto ret; } ret = nfs_add_initer (&nfs->versions, nfs3svc_init); if (ret == -1) { - gf_log (GF_NFS, GF_LOG_ERROR, "Failed to add protocol" - " initializer"); + gf_log (GF_NFS, GF_LOG_ERROR, "Failed to add " + "NFS3 protocol initializer"); goto ret; } @@ -182,6 +378,15 @@ nfs_add_all_initiators (struct nfs_state *nfs) } } + if (nfs->enable_acl == _gf_true) { + ret = nfs_add_initer (&nfs->versions, acl3svc_init); + if (ret == -1) { + gf_log (GF_NFS, GF_LOG_ERROR, "Failed to add " + "ACL protocol initializer"); + goto ret; + } + } + ret = 0; ret: return ret; @@ -515,10 +720,11 @@ nfs_init_state (xlator_t *this) if (!this) return NULL; - if ((!this->children) || (!this->children->xlator)) { - gf_log (GF_NFS, GF_LOG_ERROR, "nfs must have at least one" - " child subvolume"); - return NULL; + if (!this->children) { + gf_log (GF_NFS, GF_LOG_INFO, + "NFS is manually disabled: Exiting"); + /* Nothing for nfs process to do, exit cleanly */ + kill (getpid (), SIGTERM); } nfs = GF_CALLOC (1, sizeof (*nfs), gf_nfs_mt_nfs_state); @@ -574,19 +780,17 @@ nfs_init_state (xlator_t *this) } nfs->enable_nlm = _gf_true; - if (!dict_get_str (this->options, "nfs.nlm", &optstr)) { - - ret = gf_string2boolean (optstr, &boolt); - if (ret < 0) { - gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse" - " bool string"); - goto free_foppool; - } + ret = dict_get_str_boolean (this->options, "nfs.nlm", _gf_true); + if (ret == _gf_false) { + gf_log (GF_NFS, GF_LOG_INFO, "NLM is manually disabled"); + nfs->enable_nlm = _gf_false; + } - if (boolt == _gf_false) { - gf_log (GF_NFS, GF_LOG_INFO, "NLM is manually disabled"); - nfs->enable_nlm = _gf_false; - } + nfs->enable_acl = _gf_true; + ret = dict_get_str_boolean (this->options, "nfs.acl", _gf_true); + if (ret == _gf_false) { + gf_log (GF_NFS, GF_LOG_INFO, "ACL is manually disabled"); + nfs->enable_acl = _gf_false; } nfs->enable_ino32 = 0; @@ -651,6 +855,34 @@ nfs_init_state (xlator_t *this) } } + nfs->mount_udp = 0; + if (dict_get(this->options, "nfs.mount-udp")) { + ret = dict_get_str (this->options, "nfs.mount-udp", &optstr); + if (ret == -1) { + gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse dict"); + goto free_foppool; + } + + ret = gf_string2boolean (optstr, &boolt); + if (ret < 0) { + gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse bool " + "string"); + goto free_foppool; + } + + if (boolt == _gf_true) + nfs->mount_udp = 1; + } + + nfs->rmtab = gf_strdup (NFS_DATADIR "/rmtab"); + if (dict_get(this->options, "nfs.mount-rmtab")) { + ret = dict_get_str (this->options, "nfs.mount-rmtab", &nfs->rmtab); + if (ret == -1) { + gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse dict"); + goto free_foppool; + } + } + /* support both options rpc-auth.ports.insecure and * rpc-auth-allow-insecure for backward compatibility */ @@ -711,6 +943,16 @@ nfs_init_state (xlator_t *this) } } + GF_OPTION_INIT (OPT_SERVER_AUX_GIDS, nfs->server_aux_gids, + bool, free_foppool); + GF_OPTION_INIT (OPT_SERVER_GID_CACHE_TIMEOUT, nfs->server_aux_gids_max_age, + uint32, free_foppool); + + if (gid_cache_init(&nfs->gid_cache, nfs->server_aux_gids_max_age) < 0) { + gf_log(GF_NFS, GF_LOG_ERROR, "Failed to initialize group cache."); + goto free_foppool; + } + if (stat("/sbin/rpc.statd", &stbuf) == -1) { gf_log (GF_NFS, GF_LOG_WARNING, "/sbin/rpc.statd not found. " "Disabling NLM"); @@ -724,8 +966,11 @@ nfs_init_state (xlator_t *this) goto free_foppool; } + nfs->register_portmap = rpcsvc_register_portmap_enabled (nfs->rpcsvc); + this->private = (void *)nfs; INIT_LIST_HEAD (&nfs->versions); + nfs->generation = 1965; ret = 0; @@ -744,6 +989,243 @@ free_rpcsvc: return nfs; } +int +nfs_drc_init (xlator_t *this) +{ + int ret = -1; + rpcsvc_t *svc = NULL; + + svc = ((struct nfs_state *)(this->private))->rpcsvc; + if (!svc) + goto out; + + ret = rpcsvc_drc_init (svc, this->options); + + out: + return ret; +} + +int +nfs_reconfigure_state (xlator_t *this, dict_t *options) +{ + int ret = 0; + int keyindx = 0; + char *optstr = NULL; + gf_boolean_t optbool; + uint32_t optuint32; + struct nfs_state *nfs = NULL; + char *blacklist_keys[] = { + "nfs.port", + "nfs.transport-type", + "nfs.mem-factor", + NULL}; + + GF_VALIDATE_OR_GOTO (GF_NFS, this, out); + GF_VALIDATE_OR_GOTO (GF_NFS, this->private, out); + GF_VALIDATE_OR_GOTO (GF_NFS, options, out); + + nfs = (struct nfs_state *)this->private; + + /* Black listed options can't be reconfigured, they need + * NFS to be restarted. There are two cases 1. SET 2. UNSET. + * 1. SET */ + while (blacklist_keys[keyindx]) { + if (dict_get (options, blacklist_keys[keyindx])) { + gf_log (GF_NFS, GF_LOG_ERROR, + "Reconfiguring %s needs NFS restart", + blacklist_keys[keyindx]); + goto out; + } + keyindx ++; + } + + /* UNSET for nfs.mem-factor */ + if ((!dict_get (options, "nfs.mem-factor")) && + (nfs->memfactor != GF_NFS_DEFAULT_MEMFACTOR)) { + gf_log (GF_NFS, GF_LOG_INFO, + "Reconfiguring nfs.mem-factor needs NFS restart"); + goto out; + } + + /* UNSET for nfs.port */ + if ((!dict_get (options, "nfs.port")) && + (nfs->override_portnum)) { + gf_log (GF_NFS, GF_LOG_ERROR, + "Reconfiguring nfs.port needs NFS restart"); + goto out; + } + + /* reconfig nfs.mount-rmtab */ + optstr = NFS_DATADIR "/rmtab"; + if (dict_get (options, "nfs.mount-rmtab")) { + ret = dict_get_str (options, "nfs.mount-rmtab", &optstr); + if (ret < 0) { + gf_log (GF_NFS, GF_LOG_ERROR, "Failed to read " + "reconfigured option: nfs.mount-rmtab"); + goto out; + } + gf_path_strip_trailing_slashes (optstr); + } + if (strcmp (nfs->rmtab, optstr) != 0) { + mount_rewrite_rmtab (nfs->mstate, optstr); + gf_log (GF_NFS, GF_LOG_INFO, + "Reconfigured nfs.mount-rmtab path: %s", + nfs->rmtab); + } + + GF_OPTION_RECONF (OPT_SERVER_AUX_GIDS, optbool, + options, bool, out); + if (nfs->server_aux_gids != optbool) { + nfs->server_aux_gids = optbool; + gf_log(GF_NFS, GF_LOG_INFO, "Reconfigured %s with value %d", + OPT_SERVER_AUX_GIDS, optbool); + } + + GF_OPTION_RECONF (OPT_SERVER_GID_CACHE_TIMEOUT, optuint32, + options, uint32, out); + if (nfs->server_aux_gids_max_age != optuint32) { + nfs->server_aux_gids_max_age = optuint32; + gid_cache_reconf (&nfs->gid_cache, optuint32); + gf_log(GF_NFS, GF_LOG_INFO, "Reconfigured %s with value %d", + OPT_SERVER_GID_CACHE_TIMEOUT, optuint32); + } + + /* reconfig nfs.dynamic-volumes */ + ret = dict_get_str_boolean (options, "nfs.dynamic-volumes", + GF_NFS_DVM_OFF); + switch (ret) { + case GF_NFS_DVM_ON: + case GF_NFS_DVM_OFF: + optbool = ret; + break; + default: + optbool = GF_NFS_DVM_OFF; + break; + } + if (nfs->dynamicvolumes != optbool) { + nfs->dynamicvolumes = optbool; + gf_log(GF_NFS, GF_LOG_INFO, "Reconfigured nfs.dynamic-volumes" + " with value %d", optbool); + } + + optbool = _gf_false; + if (dict_get (options, "nfs.enable-ino32")) { + ret = dict_get_str_boolean (options, "nfs.enable-ino32", + _gf_false); + if (ret < 0) { + gf_log (GF_NFS, GF_LOG_ERROR, + "Failed to read reconfigured option: " + "nfs.enable-ino32"); + goto out; + } + optbool = ret; + } + if (nfs->enable_ino32 != optbool) { + nfs->enable_ino32 = optbool; + gf_log(GF_NFS, GF_LOG_INFO, "Reconfigured nfs.enable-ino32" + " with value %d", optbool); + } + + /* nfs.nlm is enabled by default */ + ret = dict_get_str_boolean (options, "nfs.nlm", _gf_true); + if (ret < 0) { + optbool = _gf_true; + } else { + optbool = ret; + } + if (nfs->enable_nlm != optbool) { + gf_log (GF_NFS, GF_LOG_INFO, "NLM is manually %s", + (optbool ? "enabled":"disabled")); + nfs->enable_nlm = optbool; + nfs_reconfigure_nlm4 (this); + } + + /* nfs.acl is enabled by default */ + ret = dict_get_str_boolean (options, "nfs.acl", _gf_true); + if (ret < 0) { + optbool = _gf_true; + } else { + optbool = ret; + } + if (nfs->enable_acl != optbool) { + gf_log (GF_NFS, GF_LOG_INFO, "ACL is manually %s", + (optbool ? "enabled":"disabled")); + nfs->enable_acl = optbool; + nfs_reconfigure_acl3 (this); + } + + ret = 0; +out: + return ret; +} + + +/* + * reconfigure() for NFS server xlator. + */ +int +reconfigure (xlator_t *this, dict_t *options) +{ + int ret = 0; + struct nfs_state *nfs = NULL; + gf_boolean_t regpmap = _gf_true; + + if ((!this) || (!this->private) || (!options)) + return (-1); + + nfs = (struct nfs_state *)this->private; + + /* Reconfigure nfs options */ + ret = nfs_reconfigure_state(this, options); + if (ret) { + gf_log (GF_NFS, GF_LOG_ERROR, + "nfs reconfigure state failed"); + return (-1); + } + + /* Reconfigure nfs3 options */ + ret = nfs3_reconfigure_state(this, options); + if (ret) { + gf_log (GF_NFS, GF_LOG_ERROR, + "nfs3 reconfigure state failed"); + return (-1); + } + + /* Reconfigure mount options */ + ret = mount_reconfigure_state(this, options); + if (ret) { + gf_log (GF_NFS, GF_LOG_ERROR, + "mount reconfigure state failed"); + return (-1); + } + + /* Reconfigure rpc layer */ + ret = rpcsvc_reconfigure_options (nfs->rpcsvc, options); + if (ret) { + gf_log (GF_NFS, GF_LOG_ERROR, + "rpcsvc reconfigure options failed"); + return (-1); + } + regpmap = rpcsvc_register_portmap_enabled(nfs->rpcsvc); + if (nfs->register_portmap != regpmap) { + nfs->register_portmap = regpmap; + if (regpmap) { + (void) nfs_program_register_portmap_all (nfs); + } else { + (void) nfs_program_unregister_portmap_all (nfs); + } + } + + /* Reconfigure drc */ + ret = rpcsvc_drc_reconfigure (nfs->rpcsvc, options); + if (ret) { + gf_log (GF_NFS, GF_LOG_ERROR, + "rpcsvc DRC reconfigure failed"); + return (-1); + } + + return (0); +} int init (xlator_t *this) { @@ -799,7 +1281,9 @@ init (xlator_t *this) { goto err; } - gf_log (GF_NFS, GF_LOG_INFO, "NFS service started"); + ret = nfs_drc_init (this); + if (ret == 0) + gf_log (GF_NFS, GF_LOG_INFO, "NFS service started"); err: return ret; @@ -810,24 +1294,26 @@ int notify (xlator_t *this, int32_t event, void *data, ...) { xlator_t *subvol = NULL; + struct nfs_state *priv = NULL; subvol = (xlator_t *)data; gf_log (GF_NFS, GF_LOG_TRACE, "Notification received: %d", event); - switch (event) - { - case GF_EVENT_CHILD_UP: - { - nfs_startup_subvolume (this, subvol); - break; - } - case GF_EVENT_PARENT_UP: - { - default_notify (this, GF_EVENT_PARENT_UP, data); - break; - } + switch (event) { + case GF_EVENT_CHILD_UP: + nfs_startup_subvolume (this, subvol); + break; + + case GF_EVENT_CHILD_MODIFIED: + priv = this->private; + ++(priv->generation); + break; + + case GF_EVENT_PARENT_UP: + default_notify (this, GF_EVENT_PARENT_UP, data); + break; } return 0; @@ -849,6 +1335,15 @@ fini (xlator_t *this) int32_t nfs_forget (xlator_t *this, inode_t *inode) { + uint64_t ctx = 0; + struct nfs_inode_ctx *ictx = NULL; + + if (inode_ctx_del (inode, this, &ctx)) + return -1; + + ictx = (struct nfs_inode_ctx *)ctx; + GF_FREE (ictx); + return 0; } @@ -937,13 +1432,39 @@ out: return ret; } +extern int32_t +nlm_priv (xlator_t *this); + +int32_t +nfs_priv (xlator_t *this) +{ + int32_t ret = -1; + + /* DRC needs the global drc structure, xl is of no use to it. */ + ret = rpcsvc_drc_priv (((struct nfs_state *)(this->private))->rpcsvc->drc); + if (ret) { + gf_log (this->name, GF_LOG_DEBUG, "Statedump of DRC failed"); + goto out; + } + + ret = nlm_priv (this); + if (ret) { + gf_log (this->name, GF_LOG_DEBUG, "Statedump of NLM failed"); + goto out; + } + out: + return ret; +} + + struct xlator_cbks cbks = { .forget = nfs_forget, }; -struct xlator_fops fops = { }; +struct xlator_fops fops; struct xlator_dumpops dumpops = { + .priv = nfs_priv, .priv_to_dict = nfs_priv_to_dict, }; @@ -955,29 +1476,53 @@ struct xlator_dumpops dumpops = { struct volume_options options[] = { { .key = {"nfs3.read-size"}, .type = GF_OPTION_TYPE_SIZET, - .description = "Size in which the client should issue read requests" - " to the Gluster NFSv3 server. Must be a multiple of" - " 4KB." + .min = GF_NFS3_RTMIN, + .max = GF_NFS3_RTMAX, + .default_value = TOSTRING(GF_NFS3_RTPREF), + .description = "Size in which the client should issue read requests " + "to the Gluster NFSv3 server. Must be a multiple of " + "4KB (4096). Min and Max supported values are 4KB " + "(4096) and 1MB (1048576) respectively. If the " + "specified value is within the supported range but " + "not a multiple of 4096, it is rounded up to the " + "nearest multiple of 4096." }, { .key = {"nfs3.write-size"}, .type = GF_OPTION_TYPE_SIZET, - .description = "Size in which the client should issue write requests" - " to the Gluster NFSv3 server. Must be a multiple of" - " 4KB." + .min = GF_NFS3_WTMIN, + .max = GF_NFS3_WTMAX, + .default_value = TOSTRING(GF_NFS3_WTPREF), + .description = "Size in which the client should issue write requests " + "to the Gluster NFSv3 server. Must be a multiple of " + "1KB (1024). Min and Max supported values are " + "4KB (4096) and 1MB(1048576) respectively. If the " + "specified value is within the supported range but " + "not a multiple of 4096, it is rounded up to the " + "nearest multiple of 4096." }, { .key = {"nfs3.readdir-size"}, .type = GF_OPTION_TYPE_SIZET, + .min = GF_NFS3_DTMIN, + .max = GF_NFS3_DTMAX, + .default_value = TOSTRING(GF_NFS3_DTPREF), .description = "Size in which the client should issue directory " - " reading requests." + "reading requests to the Gluster NFSv3 server. Must " + "be a multiple of 1KB (1024). Min and Max supported " + "values are 4KB (4096) and 1MB (1048576) respectively." + "If the specified value is within the supported range " + "but not a multiple of 4096, it is rounded up to the " + "nearest multiple of 4096." }, { .key = {"nfs3.*.volume-access"}, .type = GF_OPTION_TYPE_STR, .value = {"read-only", "read-write"}, + .default_value = "read-write", .description = "Type of access desired for this subvolume: " " read-only, read-write(default)" }, { .key = {"nfs3.*.trusted-write"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", .description = "On an UNSTABLE write from client, return STABLE flag" " to force client to not send a COMMIT request. In " "some environments, combined with a replicated " @@ -992,6 +1537,7 @@ struct volume_options options[] = { }, { .key = {"nfs3.*.trusted-sync"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", .description = "All writes and COMMIT requests are treated as async." " This implies that no write requests are guaranteed" " to be on server disks when the write reply is " @@ -1001,25 +1547,40 @@ struct volume_options options[] = { }, { .key = {"nfs3.*.export-dir"}, .type = GF_OPTION_TYPE_PATH, + .default_value = "", .description = "By default, all subvolumes of nfs are exported as " "individual exports. There are cases where a " "subdirectory or subdirectories in the volume need to " "be exported separately. This option can also be used " "in conjunction with nfs3.export-volumes option to " "restrict exports only to the subdirectories specified" - " through this option. Must be an absolute path." + " through this option. Must be an absolute path. Along" + " with path allowed list of IPs/hostname can be " + "associated with each subdirectory. If provided " + "connection will allowed only from these IPs. By " + "default connections from all IPs are allowed. " + "Format: <dir>[(hostspec[|hostspec|...])][,...]. Where" + " hostspec can be an IP address, hostname or an IP " + "range in CIDR notation. " + "e.g. /foo(192.168.1.0/24|host1|10.1.1.8),/host2." + " NOTE: Care must be taken while configuring this " + "option as invalid entries and/or unreachable DNS " + "servers can introduce unwanted delay in all the mount" + " calls." }, { .key = {"nfs3.export-dirs"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "on", .description = "By default, all subvolumes of nfs are exported as " "individual exports. There are cases where a " "subdirectory or subdirectories in the volume need to " "be exported separately. Enabling this option allows " "any directory on a volumes to be exported separately." - " Directory exports are enabled by default." + "Directory exports are enabled by default." }, { .key = {"nfs3.export-volumes"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "on", .description = "Enable or disable exporting whole volumes, instead " "if used in conjunction with nfs3.export-dir, can " "allow setting up only subdirectories as exports. On " @@ -1027,6 +1588,7 @@ struct volume_options options[] = { }, { .key = {"rpc-auth.auth-unix"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "on", .description = "Disable or enable the AUTH_UNIX authentication type." "Must always be enabled for better interoperability." "However, can be disabled if needed. Enabled by" @@ -1034,12 +1596,14 @@ struct volume_options options[] = { }, { .key = {"rpc-auth.auth-null"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "on", .description = "Disable or enable the AUTH_NULL authentication type." "Must always be enabled. This option is here only to" " avoid unrecognized option warnings" }, { .key = {"rpc-auth.auth-unix.*"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "on", .description = "Disable or enable the AUTH_UNIX authentication type " "for a particular exported volume overriding defaults" " and general setting for AUTH_UNIX scheme. Must " @@ -1049,6 +1613,7 @@ struct volume_options options[] = { }, { .key = {"rpc-auth.auth-unix.*.allow"}, .type = GF_OPTION_TYPE_STR, + .default_value = "on", .description = "Disable or enable the AUTH_UNIX authentication type " "for a particular exported volume overriding defaults" " and general setting for AUTH_UNIX scheme. Must " @@ -1058,6 +1623,7 @@ struct volume_options options[] = { }, { .key = {"rpc-auth.auth-null.*"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "on", .description = "Disable or enable the AUTH_NULL authentication type " "for a particular exported volume overriding defaults" " and general setting for AUTH_NULL. Must always be " @@ -1066,6 +1632,7 @@ struct volume_options options[] = { }, { .key = {"rpc-auth.addr.allow"}, .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST, + .default_value = "all", .description = "Allow a comma separated list of addresses and/or" " hostnames to connect to the server. By default, all" " connections are allowed. This allows users to " @@ -1073,6 +1640,7 @@ struct volume_options options[] = { }, { .key = {"rpc-auth.addr.reject"}, .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST, + .default_value = "none", .description = "Reject a comma separated list of addresses and/or" " hostnames from connecting to the server. By default," " all connections are allowed. This allows users to" @@ -1080,6 +1648,7 @@ struct volume_options options[] = { }, { .key = {"rpc-auth.addr.*.allow"}, .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST, + .default_value = "all", .description = "Allow a comma separated list of addresses and/or" " hostnames to connect to the server. By default, all" " connections are allowed. This allows users to " @@ -1087,6 +1656,7 @@ struct volume_options options[] = { }, { .key = {"rpc-auth.addr.*.reject"}, .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST, + .default_value = "none", .description = "Reject a comma separated list of addresses and/or" " hostnames from connecting to the server. By default," " all connections are allowed. This allows users to" @@ -1094,6 +1664,7 @@ struct volume_options options[] = { }, { .key = {"rpc-auth.ports.insecure"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", .description = "Allow client connections from unprivileged ports. By " "default only privileged ports are allowed. This is a" "global setting in case insecure ports are to be " @@ -1101,31 +1672,35 @@ struct volume_options options[] = { }, { .key = {"rpc-auth.ports.*.insecure"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", .description = "Allow client connections from unprivileged ports. By " "default only privileged ports are allowed. Use this" " option to enable or disable insecure ports for " - "a specific subvolume and to override the global setting " - " set by the previous option." + "a specific subvolume and to override the global " + "setting set by the previous option." }, { .key = {"rpc-auth.addr.namelookup"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", .description = "Users have the option of turning on name lookup for" " incoming client connections using this option. Use this " "option to turn on name lookups during address-based " "authentication. Turning this on will enable you to" - " use hostnames in rpc-auth.addr.* filters. In some " + " use hostnames in nfs.rpc-auth-* filters. In some " "setups, the name server can take too long to reply to DNS " - "queries resulting in timeouts of mount requests. By default, " - " name lookup is off" + "queries resulting in timeouts of mount requests. By " + "default, name lookup is off" }, { .key = {"nfs.dynamic-volumes"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", .description = "Internal option set to tell gnfs to use a different" " scheme for encoding file handles when DVM is being" " used." }, { .key = {"nfs3.*.volume-id"}, .type = GF_OPTION_TYPE_STR, + .default_value = "", .description = "When nfs.dynamic-volumes is set, gnfs expects every " "subvolume to have this option set for it, so that " "gnfs can use this option to identify the volume. " @@ -1134,22 +1709,34 @@ struct volume_options options[] = { }, { .key = {"nfs.enable-ino32"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "no", .description = "For nfs clients or apps that do not support 64-bit " "inode numbers, use this option to make NFS return " - "32-bit inode numbers instead. Disabled by default, so " - "NFS returns 64-bit inode numbers." + "32-bit inode numbers instead. Disabled by default, so" + " NFS returns 64-bit inode numbers." }, { .key = {"rpc.register-with-portmap"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "on", .description = "For systems that need to run multiple nfs servers, " "only one registration is possible with " "portmap service. Use this option to turn off portmap " "registration for Gluster NFS. On by default" }, + { .key = {"rpc.outstanding-rpc-limit"}, + .type = GF_OPTION_TYPE_INT, + .min = RPCSVC_MIN_OUTSTANDING_RPC_LIMIT, + .max = RPCSVC_MAX_OUTSTANDING_RPC_LIMIT, + .default_value = TOSTRING(RPCSVC_DEFAULT_OUTSTANDING_RPC_LIMIT), + .description = "Parameter to throttle the number of incoming RPC " + "requests from a client. 0 means no limit (can " + "potentially run out of memory)" + }, { .key = {"nfs.port"}, .type = GF_OPTION_TYPE_INT, .min = 1, .max = 0xffff, + .default_value = TOSTRING(GF_NFS3_PORT), .description = "Use this option on systems that need Gluster NFS to " "be associated with a non-default port number." }, @@ -1157,6 +1744,7 @@ struct volume_options options[] = { .type = GF_OPTION_TYPE_INT, .min = 1, .max = 1024, + .default_value = TOSTRING(GF_NFS_DEFAULT_MEMFACTOR), .description = "Use this option to make NFS be faster on systems by " "using more memory. This option specifies a multiple " "that determines the total amount of memory used. " @@ -1167,17 +1755,71 @@ struct volume_options options[] = { }, { .key = {"nfs.*.disable"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "false", .description = "This option is used to start or stop NFS server" "for individual volume." }, { .key = {"nfs.nlm"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "on", .description = "This option, if set to 'off', disables NLM server " "by not registering the service with the portmapper." " Set it to 'on' to re-enable it. Default value: 'on'" }, + { .key = {"nfs.mount-udp"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", + .description = "set the option to 'on' to enable mountd on UDP. " + "Required for some Solaris and AIX NFS clients. " + "The need for enabling this option often depends " + "on the usage of NLM." + }, + { .key = {"nfs.mount-rmtab"}, + .type = GF_OPTION_TYPE_PATH, + .default_value = DATADIR "/rmtab", + .description = "Set the location of the cache file that is used to " + "list all the NFS-clients that have connected " + "through the MOUNT protocol. If this is on shared " + "storage, all GlusterFS servers will update and " + "output (with 'showmount') the same list." + }, + { .key = {OPT_SERVER_AUX_GIDS}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", + .description = "Let the server look up which groups a user belongs " + "to, overwriting the list passed from the client. " + "This enables support for group lists longer than " + "can be passed through the NFS protocol, but is not " + "secure unless users and groups are well synchronized " + "between clients and servers." + }, + { .key = {OPT_SERVER_GID_CACHE_TIMEOUT}, + .type = GF_OPTION_TYPE_INT, + .min = 0, + .max = 3600, + .default_value = "5", + .description = "Number of seconds to cache auxiliary-GID data, when " + OPT_SERVER_AUX_GIDS " is set." + }, + { .key = {"nfs.acl"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "on", + .description = "This option is used to control ACL support for NFS." + }, + { .key = {"nfs.drc"}, + .type = GF_OPTION_TYPE_STR, + .default_value = "on", + .description = "Enable Duplicate Request Cache in gNFS server to " + "improve correctness of non-idempotent operations like " + "write, delete, link, et al" + }, + { .key = {"nfs.drc-size"}, + .type = GF_OPTION_TYPE_INT, + .default_value = "0x20000", + .description = "Sets the number of non-idempotent " + "requests to cache in drc" + }, { .key = {NULL} }, }; - |
