glusterfs  8.2
About: GlusterFS is a network/cluster filesystem. The storage server (or each in a cluster) runs glusterfsd and the clients use mount command or glusterfs client to mount the exported filesystem. Release series 8.x (latest version).
  Fossies Dox: glusterfs-8.2.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

nfs.c
Go to the documentation of this file.
1 /*
2  Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
3  This file is part of GlusterFS.
4 
5  This file is licensed to you under your choice of the GNU Lesser
6  General Public License, version 3 or any later version (LGPLv3 or
7  later), or the GNU General Public License, version 2 (GPLv2), in all
8  cases as published by the Free Software Foundation.
9 */
10 
11 /* This is the primary translator source for NFS.
12  * Every other protocol version gets initialized from here.
13  */
14 
15 #include <glusterfs/defaults.h>
16 #include "rpcsvc.h"
17 #include <glusterfs/dict.h>
18 #include <glusterfs/xlator.h>
19 #include "nfs.h"
20 #include <glusterfs/mem-pool.h>
21 #include <glusterfs/logging.h>
22 #include "nfs-fops.h"
23 #include "mount3.h"
24 #include "nfs3.h"
25 #include "nfs-mem-types.h"
26 #include "nfs3-helpers.h"
27 #include "nlm4.h"
28 #include <glusterfs/options.h>
29 #include "acl3.h"
30 #include "rpc-drc.h"
31 #include <glusterfs/syscall.h>
32 #include "rpcsvc.h"
33 #include "nfs-messages.h"
34 #include "glusterfs/statedump.h"
35 
36 #define OPT_SERVER_AUX_GIDS "nfs.server-aux-gids"
37 #define OPT_SERVER_GID_CACHE_TIMEOUT "nfs.server.aux-gid-timeout"
38 #define OPT_SERVER_RPC_STATD "nfs.rpc-statd"
39 #define OPT_SERVER_RPC_STATD_PIDFILE "nfs.rpc-statd-pidfile"
40 #define OPT_SERVER_RPC_STATD_NOTIFY_PIDFILE "nfs.rpc-statd-notify-pidfile"
41 
42 #define NFS_DATADIR GLUSTERD_DEFAULT_WORKDIR "/nfs"
43 
44 /* Forward declaration */
45 static int
47  gf_boolean_t required);
48 
49 static int
51  gf_boolean_t required)
52 {
53  int ret = -1;
54  struct nfs_initer_list *version = NULL;
55  struct nfs_initer_list *tmp = NULL;
56  rpcsvc_program_t *prog = NULL;
57  struct list_head *versions = NULL;
58  struct nfs_state *nfs = NULL;
59  gf_boolean_t found = _gf_false;
60 
61  if ((!this) || (!this->private) || (!init))
62  return (-1);
63 
64  nfs = (struct nfs_state *)this->private;
65 
66  ret = nfs_add_initer(&nfs->versions, init, required);
67  if (ret == -1) {
69  "Failed to add protocol initializer");
70  goto err;
71  }
72 
73  versions = &nfs->versions;
74  list_for_each_entry_safe(version, tmp, versions, list)
75  {
76  prog = version->program;
77  if (version->init == init) {
78  prog = init(this);
79  if (!prog) {
80  ret = -1;
81  goto err;
82  }
83  version->program = prog;
84  found = _gf_true;
85  break;
86  }
87  }
88 
89  /* program not added */
90  if (!found) {
92  "Program: %s NOT found", prog->progname);
93  goto err;
94  }
95 
96  /* Check if nfs.port is configured */
97  if (nfs->override_portnum)
98  prog->progport = nfs->override_portnum;
99 
100  gf_msg_debug(GF_NFS, 0, "Starting program: %s", prog->progname);
101 
102  ret = rpcsvc_program_register(nfs->rpcsvc, prog, _gf_false);
103  if (ret == -1) {
105  "Program: %s init failed", prog->progname);
106  goto err;
107  }
108 
109  /* Registration with portmapper is disabled, Nothing to do */
110  if (!nfs->register_portmap)
111  goto err;
112 
113  ret = rpcsvc_program_register_portmap(prog, prog->progport);
114  if (ret == -1) {
116  "Program %s registration failed", prog->progname);
117  goto err;
118  }
119  ret = 0; /* All well */
120 err:
121  return ret;
122 }
123 
124 static int
126 {
127  int ret = -1;
128  struct nfs_initer_list *version = NULL;
129  struct nfs_initer_list *tmp = NULL;
130  rpcsvc_program_t *prog = NULL;
131  struct list_head *versions = NULL;
132 
133  if ((!nfs) || (!init))
134  return (-1);
135 
136  versions = &nfs->versions;
137  list_for_each_entry_safe(version, tmp, versions, list)
138  {
139  prog = version->program;
140  if (version->init == init) {
141  prog = version->program;
142  ret = rpcsvc_program_unregister(nfs->rpcsvc, prog);
143  if (ret != 0)
144  return (-1);
145  list_del(&version->list);
146  GF_FREE(version);
147  return (0);
148  }
149  }
150 
151  return (-1);
152 }
153 
154 static int
156 {
157  struct nfs_state *nfs = NULL;
158 
159  if ((!this) || (!this->private))
160  return (-1);
161 
162  nfs = (struct nfs_state *)this->private;
163 
164  /* ACL is enabled */
165  if (nfs->enable_acl)
166  return nfs_init_version(this, acl3svc_init, _gf_false);
167 
168  /* ACL is disabled */
169  return nfs_deinit_version(nfs, acl3svc_init);
170 }
171 
172 static int
174 {
175  struct nfs_state *nfs = NULL;
176 
177  if ((!this) || (!this->private))
178  return (-1);
179 
180  nfs = (struct nfs_state *)this->private;
181 
182  /* NLM is enabled */
183  if (nfs->enable_nlm)
184  return nfs_init_version(this, nlm4svc_init, _gf_false);
185 
186  /* NLM is disabled */
187  return nfs_deinit_version(nfs, nlm4svc_init);
188 }
189 
190 static int
192 {
193  struct list_head *versions = NULL;
194  struct nfs_initer_list *version = NULL;
195  struct nfs_initer_list *tmp = NULL;
196  rpcsvc_program_t *prog = NULL;
197 
198  if (nfs == NULL)
199  return (-1);
200 
201  versions = &nfs->versions;
202  list_for_each_entry_safe(version, tmp, versions, list)
203  {
204  prog = version->program;
205  if (prog == NULL)
206  continue;
207  if (nfs->override_portnum)
208  prog->progport = nfs->override_portnum;
209  (void)rpcsvc_program_register_portmap(prog, prog->progport);
210 #ifdef IPV6_DEFAULT
211  (void)rpcsvc_program_register_rpcbind6(prog, prog->progport);
212 #endif
213  }
214 
215  return (0);
216 }
217 
218 static int
220 {
221  struct list_head *versions = NULL;
222  struct nfs_initer_list *version = NULL;
223  struct nfs_initer_list *tmp = NULL;
224  rpcsvc_program_t *prog = NULL;
225 
226  if (nfs == NULL)
227  return (-1);
228 
229  versions = &nfs->versions;
230  list_for_each_entry_safe(version, tmp, versions, list)
231  {
232  prog = version->program;
233  if (prog == NULL)
234  continue;
236 #ifdef IPV6_DEFAULT
237  (void)rpcsvc_program_unregister_rpcbind6(prog);
238 #endif
239  }
240 
241  return (0);
242 }
243 
244 /* Every NFS version must call this function with the init function
245  * for its particular version.
246  */
247 static int
250 {
251  struct nfs_initer_list *new = NULL;
252  if ((!list) || (!init))
253  return -1;
254 
255  new = GF_CALLOC(1, sizeof(*new), gf_nfs_mt_nfs_initer_list);
256  if (!new) {
258  "Memory allocation failed");
259  return -1;
260  }
261 
262  new->init = init;
263  new->required = required;
264  list_add_tail(&new->list, list);
265  return 0;
266 }
267 
268 int
269 nfs_deinit_versions(struct list_head *versions, xlator_t *this)
270 {
271  struct nfs_initer_list *version = NULL;
272  struct nfs_initer_list *tmp = NULL;
273  struct nfs_state *nfs = NULL;
274 
275  if ((!versions) || (!this))
276  return -1;
277 
278  nfs = (struct nfs_state *)this->private;
279  list_for_each_entry_safe(version, tmp, versions, list)
280  {
281  /* TODO: Add version specific destructor.
282  * if (!version->deinit)
283  goto err;
284 
285  version->deinit (this);
286  */
287  if (version->program)
288  rpcsvc_program_unregister(nfs->rpcsvc, (version->program));
289 
290  list_del(&version->list);
291  GF_FREE(version);
292  }
293 
294  return 0;
295 }
296 
297 int
299 {
300  struct nfs_initer_list *version = NULL;
301  struct nfs_initer_list *tmp = NULL;
302  rpcsvc_program_t *prog = NULL;
303  int ret = -1;
304  struct list_head *versions = NULL;
305 
306  if ((!nfs) || (!this))
307  return -1;
308 
309  gf_msg_debug(GF_NFS, 0, "Initing protocol versions");
310  versions = &nfs->versions;
311  list_for_each_entry_safe(version, tmp, versions, list)
312  {
313  if (!version->init) {
314  ret = -1;
315  goto err;
316  }
317 
318  prog = version->init(this);
319  if (!prog) {
320  ret = -1;
321  goto err;
322  }
323 
324  version->program = prog;
325  if (nfs->override_portnum)
326  prog->progport = nfs->override_portnum;
327  gf_msg_debug(GF_NFS, 0, "Starting program: %s", prog->progname);
328 
329  ret = rpcsvc_program_register(nfs->rpcsvc, prog, _gf_false);
330  if (ret == -1) {
332  "Program: %s init failed", prog->progname);
333  goto err;
334  }
335  if (nfs->register_portmap) {
336  ret = rpcsvc_program_register_portmap(prog, prog->progport);
337  if (ret == -1) {
339  "%s program %s registration failed",
340  version->required ? "Required" : "Optional",
341  prog->progname);
342 
343  /* fatal error if the program is required */
344  if (version->required)
345  goto err;
346  }
347 #ifdef IPV6_DEFAULT
348  ret = rpcsvc_program_register_rpcbind6(prog, prog->progport);
349  if (ret == -1) {
351  "Program (ipv6) %s registration failed", prog->progname);
352  goto err;
353  }
354 #endif
355  }
356  }
357 
358  ret = 0;
359 err:
360  return ret;
361 }
362 
363 int
365 {
366  int ret = 0;
367 
368  /* Add the initializers for all versions. */
370  if (ret == -1) {
372  "Failed to add MOUNT3 protocol initializer");
373  goto ret;
374  }
375 
377  if (ret == -1) {
379  "Failed to add MOUNT1 protocol initializer");
380  goto ret;
381  }
382 
384  if (ret == -1) {
386  "Failed to add NFS3 protocol initializer");
387  goto ret;
388  }
389 
390  if (nfs->enable_nlm == _gf_true) {
392  if (ret == -1) {
394  "Failed to add protocol initializer");
395  goto ret;
396  }
397  }
398 
399  if (nfs->enable_acl == _gf_true) {
401  if (ret == -1) {
403  "Failed to add ACL protocol initializer");
404  goto ret;
405  }
406  }
407 
408  ret = 0;
409 ret:
410  return ret;
411 }
412 
413 int
415 {
416  int x = 0;
417  int started = 0;
418 
419  if ((!nfs) || (!xl))
420  return 1;
421 
422  LOCK(&nfs->svinitlock);
423  {
424  for (; x < nfs->allsubvols; ++x) {
425  if (nfs->initedxl[x] == xl) {
426  started = 1;
427  goto unlock;
428  }
429  }
430  }
431 unlock:
432  UNLOCK(&nfs->svinitlock);
433 
434  return started;
435 }
436 
437 int
439 {
440  int x = 0;
441 
442  if ((!nfs) || (!xl))
443  return 1;
444 
445  LOCK(&nfs->svinitlock);
446  {
447  for (; x < nfs->allsubvols; ++x) {
448  if (nfs->initedxl[x] == xl) {
449  gf_msg_debug(GF_NFS, 0, "Volume already started %s", xl->name);
450  break;
451  }
452 
453  if (nfs->initedxl[x] == NULL) {
454  nfs->initedxl[x] = xl;
455  ++nfs->upsubvols;
456  gf_msg_debug(GF_NFS, 0,
457  "Starting up: %s "
458  ", vols started till now: %d",
459  xl->name, nfs->upsubvols);
460  goto unlock;
461  }
462  }
463  }
464 unlock:
465  UNLOCK(&nfs->svinitlock);
466 
467  return 0;
468 }
469 
470 int32_t
472  int32_t op_ret, int32_t op_errno, inode_t *inode,
473  struct iatt *buf, dict_t *xattr,
474  struct iatt *postparent)
475 {
476  if (op_ret == -1) {
478  "Failed to lookup root: %s", strerror(op_errno));
479  goto err;
480  }
481 
482  nfs_subvolume_set_started(this->private, ((xlator_t *)cookie));
483  gf_msg_trace(GF_NFS, 0, "Started %s", ((xlator_t *)cookie)->name);
484 err:
485  return 0;
486 }
487 
488 int
490 {
491  int ret = -1;
492  loc_t rootloc = {
493  0,
494  };
495  nfs_user_t nfu = {
496  0,
497  };
498 
499  if ((!nfsx) || (!xl))
500  return -1;
501 
502  if (nfs_subvolume_started(nfsx->private, xl)) {
503  gf_msg_trace(GF_NFS, 0, "Subvolume already started: %s", xl->name);
504  ret = 0;
505  goto err;
506  }
507 
508  ret = nfs_root_loc_fill(xl->itable, &rootloc);
509  if (ret == -1) {
511  "Failed to init root loc");
512  goto err;
513  }
514 
515  nfs_user_root_create(&nfu);
516  ret = nfs_fop_lookup(nfsx, xl, &nfu, &rootloc, nfs_start_subvol_lookup_cbk,
517  (void *)nfsx->private);
518  if (ret < 0) {
520  "Failed to lookup root: %s", strerror(-ret));
521  goto err;
522  }
523 
524  nfs_loc_wipe(&rootloc);
525 
526 err:
527  return ret;
528 }
529 
530 int
532 {
533  int ret = -1;
534  xlator_list_t *cl = NULL;
535  struct nfs_state *nfs = NULL;
536 
537  if (!nfsx)
538  return -1;
539 
540  nfs = nfsx->private;
541  cl = nfs->subvols;
542  while (cl) {
543  gf_msg_debug(GF_NFS, 0, "Starting subvolume: %s", cl->xlator->name);
544  ret = nfs_startup_subvolume(nfsx, cl->xlator);
545  if (ret == -1) {
547  "Failed to start-up xlator: %s", cl->xlator->name);
548  goto err;
549  }
550  cl = cl->next;
551  }
552 
553  ret = 0;
554 err:
555  return ret;
556 }
557 
558 int
560 {
561  unsigned int lrusize = 0;
562  int ret = -1;
563 
564  if ((!nfs) || (!xl))
565  return -1;
566 
567  lrusize = nfs->memfactor * GF_NFS_INODE_LRU_MULT;
568  xl->itable = inode_table_new(lrusize, xl);
569  if (!xl->itable) {
571  "Failed to allocate inode table");
572  goto err;
573  }
574  ret = 0;
575 err:
576  return ret;
577 }
578 
579 int
581 {
582  int ret = -1;
583  unsigned int lrusize = 0;
584  int svcount = 0;
585 
586  if ((!nfs) || (!cl))
587  return -1;
588 
589  lrusize = nfs->memfactor * GF_NFS_INODE_LRU_MULT;
590  nfs->subvols = cl;
591  gf_msg_trace(GF_NFS, 0, "inode table lru: %d", lrusize);
592 
593  while (cl) {
594  gf_msg_debug(GF_NFS, 0, "Initing subvolume: %s", cl->xlator->name);
595  ret = nfs_init_subvolume(nfs, cl->xlator);
596  if (ret == -1) {
598  "Failed to init "
599  "xlator: %s",
600  cl->xlator->name);
601  goto err;
602  }
603  ++svcount;
604  cl = cl->next;
605  }
606 
607  LOCK_INIT(&nfs->svinitlock);
608  nfs->initedxl = GF_CALLOC(svcount, sizeof(xlator_t *), gf_nfs_mt_xlator_t);
609  if (!nfs->initedxl) {
611  "Failed to allocated inited xls");
612  ret = -1;
613  goto err;
614  }
615 
616  gf_msg_trace(GF_NFS, 0, "Inited volumes: %d", svcount);
617  nfs->allsubvols = svcount;
618  ret = 0;
619 err:
620  return ret;
621 }
622 
623 int
625 {
626  if (!newnfu)
627  return -1;
628 
629  newnfu->uid = 0;
630  newnfu->gids[0] = 0;
631  newnfu->ngrps = 1;
632 
633  return 0;
634 }
635 
636 int
637 nfs_user_create(nfs_user_t *newnfu, uid_t uid, gid_t gid,
638  rpc_transport_t *trans, gid_t *auxgids, int auxcount)
639 {
640  int x = 1;
641  int y = 0;
642 
643  /* We test for GF_REQUEST_MAXGROUPS instead of NFS_FOP_NGROUPS because
644  * the latter accounts for the @gid being in @auxgids, which is not the
645  * case here.
646  */
647  if ((!newnfu) || (auxcount > GF_REQUEST_MAXGROUPS))
648  return -1;
649 
650  newnfu->uid = uid;
651  newnfu->gids[0] = gid;
652  newnfu->ngrps = 1;
653  if (trans) {
654  memcpy(&newnfu->identifier, trans->peerinfo.identifier, UNIX_PATH_MAX);
655  }
656 
657  gf_msg_trace(GF_NFS, 0, "uid: %d, gid %d, gids: %d", uid, gid, auxcount);
658 
659  if (!auxgids)
660  return 0;
661 
662  for (; y < auxcount; ++x, ++y) {
663  newnfu->gids[x] = auxgids[y];
664  ++newnfu->ngrps;
665  gf_msg_trace(GF_NFS, 0, "gid: %d", auxgids[y]);
666  }
667 
668  return 0;
669 }
670 
671 void
673 {
674  gid_t *gidarr = NULL;
675  int gids = 0;
676 
677  if ((!req) || (!nfu))
678  return;
679 
680  gidarr = rpcsvc_auth_unix_auxgids(req, &gids);
682  rpcsvc_request_transport(req), gidarr, gids);
683 
684  return;
685 }
686 
687 void
689  gid_t gid)
690 {
691  gid_t *gidarr = NULL;
692  int gids = 0;
693 
694  if ((!req) || (!nfu))
695  return;
696 
697  gidarr = rpcsvc_auth_unix_auxgids(req, &gids);
698  nfs_user_create(nfu, uid, gid, rpcsvc_request_transport(req), gidarr, gids);
699 
700  return;
701 }
702 
703 int32_t
705 {
706  int ret = -1;
707 
708  if (!this)
709  return ret;
710 
711  ret = xlator_mem_acct_init(this, gf_nfs_mt_end + 1);
712 
713  if (ret != 0) {
714  gf_msg(this->name, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
715  "Memory accounting init failed");
716  return ret;
717  }
718 
719  return ret;
720 }
721 
722 struct nfs_state *
724 {
725  struct nfs_state *nfs = NULL;
726  int i = 0, ret = -1;
727  unsigned int fopspoolsize = 0;
728  char *optstr = NULL;
729  gf_boolean_t boolt = _gf_false;
730  struct stat stbuf = {
731  0,
732  };
733 
734  if (!this)
735  return NULL;
736 
737  if (!this->children) {
739  "NFS is manually disabled: Exiting");
740  /* Nothing for nfs process to do, exit cleanly */
741  kill(getpid(), SIGTERM);
742  }
743 
744  nfs = GF_CALLOC(1, sizeof(*nfs), gf_nfs_mt_nfs_state);
745  if (!nfs) {
747  "memory allocation failed");
748  return NULL;
749  }
750 
752  if (dict_get(this->options, "nfs.mem-factor")) {
753  ret = dict_get_str(this->options, "nfs.mem-factor", &optstr);
754  if (ret < 0) {
756  "Failed to parse dict");
757  goto free_rpcsvc;
758  }
759 
760  ret = gf_string2uint(optstr, &nfs->memfactor);
761  if (ret < 0) {
763  "Failed to parse uint string");
764  goto free_rpcsvc;
765  }
766  }
767 
768  fopspoolsize = nfs->memfactor * GF_NFS_CONCURRENT_OPS_MULT;
769  /* FIXME: Really saddens me to see this as xlator wide. */
770  nfs->foppool = mem_pool_new(struct nfs_fop_local, fopspoolsize);
771  if (!nfs->foppool) {
773  "Failed to allocate fops local pool");
774  goto free_rpcsvc;
775  }
776 
778  if (dict_get(this->options, "nfs.dynamic-volumes")) {
779  ret = dict_get_str(this->options, "nfs.dynamic-volumes", &optstr);
780  if (ret < 0) {
782  "Failed to parse dict");
783  goto free_foppool;
784  }
785 
786  ret = gf_string2boolean(optstr, &boolt);
787  if (ret < 0) {
789  "Failed to parse bool string");
790  goto free_foppool;
791  }
792 
793  if (boolt == _gf_true)
795  }
796 
797  nfs->enable_nlm = _gf_true;
798  ret = dict_get_str_boolean(this->options, "nfs.nlm", _gf_true);
799  if (ret == _gf_false) {
801  "NLM is manually disabled");
802  nfs->enable_nlm = _gf_false;
803  }
804 
805  nfs->enable_acl = _gf_true;
806  ret = dict_get_str_boolean(this->options, "nfs.acl", _gf_true);
807  if (ret == _gf_false) {
809  "ACL is manually disabled");
810  nfs->enable_acl = _gf_false;
811  }
812 
813  nfs->enable_ino32 = 0;
814  if (dict_get(this->options, "nfs.enable-ino32")) {
815  ret = dict_get_str(this->options, "nfs.enable-ino32", &optstr);
816  if (ret < 0) {
818  "Failed to parse dict");
819  goto free_foppool;
820  }
821 
822  ret = gf_string2boolean(optstr, &boolt);
823  if (ret < 0) {
825  "Failed to parse bool string");
826  goto free_foppool;
827  }
828 
829  if (boolt == _gf_true)
830  nfs->enable_ino32 = 1;
831  }
832 
833  if (dict_get(this->options, "nfs.port")) {
834  ret = dict_get_str(this->options, "nfs.port", &optstr);
835  if (ret < 0) {
837  "Failed to parse dict");
838  goto free_foppool;
839  }
840 
841  ret = gf_string2uint(optstr, &nfs->override_portnum);
842  if (ret < 0) {
844  "Failed to parse uint string");
845  goto free_foppool;
846  }
847  }
848 
849  if (dict_get(this->options, "transport.socket.bind-address")) {
850  ret = dict_get_str(this->options, "transport.socket.bind-address",
851  &optstr);
852  if (ret < 0) {
854  "Failed to parse "
855  "transport.socket.bind-address string");
856  } else {
857  this->instance_name = gf_strdup(optstr);
858  for (i = 0; i < strlen(this->instance_name); i++) {
859  if (this->instance_name[i] == '.' ||
860  this->instance_name[i] == ':')
861  this->instance_name[i] = '_';
862  }
863  }
864  }
865 
866  if (dict_get(this->options, "transport.socket.listen-port") == NULL) {
867  if (nfs->override_portnum)
868  ret = gf_asprintf(&optstr, "%d", nfs->override_portnum);
869  else
870  ret = gf_asprintf(&optstr, "%d", GF_NFS3_PORT);
871  if (ret == -1) {
873  "failed mem-allocation");
874  goto free_foppool;
875  }
876  ret = dict_set_dynstr(this->options, "transport.socket.listen-port",
877  optstr);
878  if (ret == -1) {
880  "dict_set_dynstr error");
881  goto free_foppool;
882  }
883  }
884 
885 #ifdef IPV6_DEFAULT
886  ret = dict_set_str(this->options, "transport.address-family", "inet6");
887  if (ret == -1) {
888  gf_log(GF_NFS, GF_LOG_ERROR, "dict_set_str error");
889  goto free_foppool;
890  }
891 #endif
892 
893  /* Right only socket support exists between nfs client and
894  * gluster nfs, so we can set default value as socket
895  */
896  ret = dict_set_str(this->options, "transport-type", "socket");
897  if (ret == -1) {
899  "dict_set_str error");
900  goto free_foppool;
901  }
902 
903  nfs->mount_udp = 0;
904  if (dict_get(this->options, "nfs.mount-udp")) {
905  ret = dict_get_str(this->options, "nfs.mount-udp", &optstr);
906  if (ret == -1) {
908  "Failed to parse dict");
909  goto free_foppool;
910  }
911 
912  ret = gf_string2boolean(optstr, &boolt);
913  if (ret < 0) {
915  "Failed to parse bool "
916  "string");
917  goto free_foppool;
918  }
919 
920  if (boolt == _gf_true)
921  nfs->mount_udp = 1;
922  }
923 
925  if (dict_get(this->options, "nfs.exports-auth-enable")) {
926  ret = dict_get_str(this->options, "nfs.exports-auth-enable", &optstr);
927  if (ret == -1) {
929  "Failed to parse dict");
930  goto free_foppool;
931  }
932 
933  ret = gf_string2boolean(optstr, &boolt);
934  if (ret < 0) {
936  "Failed to parse bool string");
937  goto free_foppool;
938  }
939 
940  if (boolt == _gf_true)
941  nfs->exports_auth = 1;
942  }
943 
945  if (dict_get(this->options, "nfs.auth-refresh-interval-sec")) {
946  ret = dict_get_str(this->options, "nfs.auth-refresh-interval-sec",
947  &optstr);
948  if (ret < 0) {
950  "Failed to parse dict");
951  goto free_foppool;
952  }
953 
954  ret = gf_string2uint(optstr, &nfs->auth_refresh_time_secs);
955  if (ret < 0) {
957  "Failed to parse uint string");
958  goto free_foppool;
959  }
960  }
961 
963  if (dict_get(this->options, "nfs.auth-cache-ttl-sec")) {
964  ret = dict_get_str(this->options, "nfs.auth-cache-ttl-sec", &optstr);
965  if (ret < 0) {
967  "Failed to parse dict");
968  goto free_foppool;
969  }
970 
971  ret = gf_string2uint(optstr, &nfs->auth_cache_ttl_sec);
972  if (ret < 0) {
974  "Failed to parse uint string");
975  goto free_foppool;
976  }
977  }
978 
979  /* TODO: Make this a configurable option in case we don't want to read
980  * exports/netgroup files off disk when they change. */
981  nfs->refresh_auth = 1;
982 
983  nfs->rmtab = gf_strdup(NFS_DATADIR "/rmtab");
984  if (dict_get(this->options, "nfs.mount-rmtab")) {
985  ret = dict_get_str(this->options, "nfs.mount-rmtab", &nfs->rmtab);
986  if (ret == -1) {
988  "Failed to parse dict");
989  goto free_foppool;
990  }
991 
992  /* check if writing the rmtab is disabled*/
993  if (nfs->rmtab && strcmp("/-", nfs->rmtab) == 0) {
994  GF_FREE(nfs->rmtab);
995  nfs->rmtab = NULL;
996  }
997  }
998 
999  /* support both options rpc-auth.ports.insecure and
1000  * rpc-auth-allow-insecure for backward compatibility
1001  */
1002  nfs->allow_insecure = 1;
1003  if (dict_get(this->options, "rpc-auth.ports.insecure")) {
1004  ret = dict_get_str(this->options, "rpc-auth.ports.insecure", &optstr);
1005  if (ret < 0) {
1007  "Failed to parse dict");
1008  goto free_foppool;
1009  }
1010 
1011  ret = gf_string2boolean(optstr, &boolt);
1012  if (ret < 0) {
1014  "Failed to parse bool "
1015  "string");
1016  goto free_foppool;
1017  }
1018 
1019  if (boolt == _gf_false)
1020  nfs->allow_insecure = 0;
1021  }
1022 
1023  if (dict_get(this->options, "rpc-auth-allow-insecure")) {
1024  ret = dict_get_str(this->options, "rpc-auth-allow-insecure", &optstr);
1025  if (ret < 0) {
1027  "Failed to parse dict");
1028  goto free_foppool;
1029  }
1030 
1031  ret = gf_string2boolean(optstr, &boolt);
1032  if (ret < 0) {
1034  "Failed to parse bool string");
1035  goto free_foppool;
1036  }
1037 
1038  if (boolt == _gf_false)
1039  nfs->allow_insecure = 0;
1040  }
1041 
1042  if (nfs->allow_insecure) {
1043  /* blindly set both the options */
1044  ret = dict_set_str(this->options, "rpc-auth-allow-insecure", "on");
1045  if (ret == -1) {
1047  "dict_set_str error");
1048  goto free_foppool;
1049  }
1050  ret = dict_set_str(this->options, "rpc-auth.ports.insecure", "on");
1051  if (ret == -1) {
1053  "dict_set_str error");
1054  goto free_foppool;
1055  }
1056  }
1057 
1058  GF_OPTION_INIT("nfs.rdirplus", nfs->rdirplus, bool, free_foppool);
1059 
1060  GF_OPTION_INIT(OPT_SERVER_RPC_STATD, nfs->rpc_statd, path, free_foppool);
1061 
1063  free_foppool);
1064 
1066  free_foppool);
1068  uint32, free_foppool);
1069 
1070  if (gid_cache_init(&nfs->gid_cache, nfs->server_aux_gids_max_age) < 0) {
1072  "Failed to initialize group cache.");
1073  goto free_foppool;
1074  }
1075 
1076  ret = sys_access(nfs->rpc_statd, X_OK);
1077  if (ret) {
1079  "%s not enough permissions to access. Disabling NLM",
1080  nfs->rpc_statd);
1081  nfs->enable_nlm = _gf_false;
1082  }
1083 
1084  ret = sys_stat(nfs->rpc_statd, &stbuf);
1085  if (ret || !S_ISREG(stbuf.st_mode)) {
1087  "%s not a regular file. Disabling NLM", nfs->rpc_statd);
1088  nfs->enable_nlm = _gf_false;
1089  }
1090 
1091  nfs->rpcsvc = rpcsvc_init(this, this->ctx, this->options, fopspoolsize);
1092  if (!nfs->rpcsvc) {
1093  ret = -1;
1095  "RPC service init failed");
1096  goto free_foppool;
1097  }
1098 
1099  ret = rpcsvc_set_throttle_on(nfs->rpcsvc);
1100  if (ret) {
1102  "Enabling throttle failed");
1103  goto free_foppool;
1104  }
1105 
1108  if (ret < 0) {
1110  "Failed to configure outstanding-rpc-limit");
1111  goto free_foppool;
1112  }
1113 
1115 
1116  GF_OPTION_INIT("nfs.event-threads", nfs->event_threads, uint32,
1117  free_foppool);
1118  gf_event_reconfigure_threads(this->ctx->event_pool, nfs->event_threads);
1119 
1120  this->private = (void *)nfs;
1121  INIT_LIST_HEAD(&nfs->versions);
1122  nfs->generation = 1965;
1123 
1124  ret = 0;
1125 
1126 free_foppool:
1127  if (ret < 0)
1128  mem_pool_destroy(nfs->foppool);
1129 
1130 free_rpcsvc:
1131  /*
1132  * rpcsvc_deinit */
1133  if (ret < 0) {
1134  GF_FREE(nfs);
1135  nfs = NULL;
1136  }
1137 
1138  return nfs;
1139 }
1140 
1141 int
1143 {
1144  int ret = -1;
1145  rpcsvc_t *svc = NULL;
1146 
1147  GF_VALIDATE_OR_GOTO(GF_NFS, this, out);
1148  GF_VALIDATE_OR_GOTO(GF_NFS, this->private, out);
1149 
1150  svc = ((struct nfs_state *)(this->private))->rpcsvc;
1151  if (!svc)
1152  goto out;
1153 
1154  ret = rpcsvc_drc_init(svc, this->options);
1155 
1156 out:
1157  return ret;
1158 }
1159 
1160 int
1162 {
1163  int ret = 0;
1164  int keyindx = 0;
1165  char *rmtab = NULL;
1166  char *rpc_statd = NULL;
1167  gf_boolean_t optbool;
1168  uint32_t optuint32;
1169  struct nfs_state *nfs = NULL;
1170  char *blacklist_keys[] = {"nfs.port", "nfs.transport-type",
1171  "nfs.mem-factor", NULL};
1172 
1173  GF_VALIDATE_OR_GOTO(GF_NFS, this, out);
1174  GF_VALIDATE_OR_GOTO(GF_NFS, this->private, out);
1175  GF_VALIDATE_OR_GOTO(GF_NFS, options, out);
1176 
1177  nfs = (struct nfs_state *)this->private;
1178 
1179  /* Black listed options can't be reconfigured, they need
1180  * NFS to be restarted. There are two cases 1. SET 2. UNSET.
1181  * 1. SET */
1182  while (blacklist_keys[keyindx]) {
1183  if (dict_get(options, blacklist_keys[keyindx])) {
1185  "Reconfiguring %s needs NFS restart",
1186  blacklist_keys[keyindx]);
1187  goto out;
1188  }
1189  keyindx++;
1190  }
1191 
1192  /* UNSET for nfs.mem-factor */
1193  if ((!dict_get(options, "nfs.mem-factor")) &&
1194  (nfs->memfactor != GF_NFS_DEFAULT_MEMFACTOR)) {
1196  "Reconfiguring nfs.mem-factor needs NFS restart");
1197  goto out;
1198  }
1199 
1200  /* UNSET for nfs.port */
1201  if ((!dict_get(options, "nfs.port")) && (nfs->override_portnum)) {
1203  "Reconfiguring nfs.port needs NFS restart");
1204  goto out;
1205  }
1206 
1207  /* reconfig nfs.rpc-statd... */
1210  ret = dict_get_str(options, "nfs.rpc-statd", &rpc_statd);
1211  if (ret < 0) {
1213  "Failed to read reconfigured option: "
1214  "nfs.rpc-statd");
1215  goto out;
1216  }
1217  }
1218 
1219  if (strcmp(nfs->rpc_statd, rpc_statd) != 0) {
1221  "Reconfiguring nfs.rpc-statd needs NFS restart");
1222  goto out;
1223  }
1224 
1225  /* reconfig nfs.mount-rmtab */
1226  rmtab = NFS_DATADIR "/rmtab";
1227  if (dict_get(options, "nfs.mount-rmtab")) {
1228  ret = dict_get_str(options, "nfs.mount-rmtab", &rmtab);
1229  if (ret < 0) {
1231  "Failed to read reconfigured option:"
1232  " nfs.mount-rmtab");
1233  goto out;
1234  }
1236  }
1237  /* check if writing the rmtab is disabled*/
1238  if (strcmp("/-", rmtab) == 0) {
1239  GF_FREE(nfs->rmtab);
1240  nfs->rmtab = NULL;
1242  "Disabled writing of nfs.mount-rmtab");
1243  } else if (!nfs->rmtab || strcmp(nfs->rmtab, rmtab) != 0) {
1246  "Reconfigured nfs.mount-rmtab path: %s", nfs->rmtab);
1247  }
1248 
1249  GF_OPTION_RECONF(OPT_SERVER_AUX_GIDS, optbool, options, bool, out);
1250  if (nfs->server_aux_gids != optbool) {
1251  nfs->server_aux_gids = optbool;
1253  "Reconfigured %s with value %d", OPT_SERVER_AUX_GIDS, optbool);
1254  }
1255 
1257  out);
1258  if (nfs->server_aux_gids_max_age != optuint32) {
1259  nfs->server_aux_gids_max_age = optuint32;
1260  gid_cache_reconf(&nfs->gid_cache, optuint32);
1262  "Reconfigured %s with value %d", OPT_SERVER_GID_CACHE_TIMEOUT,
1263  optuint32);
1264  }
1265 
1266  GF_OPTION_RECONF("nfs.rdirplus", optbool, options, bool, out);
1267  if (nfs->rdirplus != optbool) {
1268  nfs->rdirplus = optbool;
1270  "Reconfigured nfs.rdirplus with value %d", optbool);
1271  }
1272 
1273  /* reconfig nfs.dynamic-volumes */
1274  ret = dict_get_str_boolean(options, "nfs.dynamic-volumes", GF_NFS_DVM_OFF);
1275  switch (ret) {
1276  case GF_NFS_DVM_ON:
1277  case GF_NFS_DVM_OFF:
1278  optbool = ret;
1279  break;
1280  default:
1281  optbool = GF_NFS_DVM_OFF;
1282  break;
1283  }
1284  if (nfs->dynamicvolumes != optbool) {
1285  nfs->dynamicvolumes = optbool;
1287  "Reconfigured nfs.dynamic-volumes with value %d", optbool);
1288  }
1289 
1290  optbool = _gf_false;
1291  if (dict_get(options, "nfs.enable-ino32")) {
1292  ret = dict_get_str_boolean(options, "nfs.enable-ino32", _gf_false);
1293  if (ret < 0) {
1295  "Failed to read reconfigured option: "
1296  "nfs.enable-ino32");
1297  goto out;
1298  }
1299  optbool = ret;
1300  }
1301  if (nfs->enable_ino32 != optbool) {
1302  nfs->enable_ino32 = optbool;
1304  "Reconfigured nfs.enable-ino32 with value %d", optbool);
1305  }
1306 
1307  /* nfs.nlm is enabled by default */
1308  ret = dict_get_str_boolean(options, "nfs.nlm", _gf_true);
1309  if (ret < 0) {
1310  optbool = _gf_true;
1311  } else {
1312  optbool = ret;
1313  }
1314  if (nfs->enable_nlm != optbool) {
1316  "NLM is"
1317  " manually %s",
1318  (optbool ? "enabled" : "disabled"));
1319  nfs->enable_nlm = optbool;
1320  nfs_reconfigure_nlm4(this);
1321  }
1322 
1323  /* nfs.acl is enabled by default */
1324  ret = dict_get_str_boolean(options, "nfs.acl", _gf_true);
1325  if (ret < 0) {
1326  optbool = _gf_true;
1327  } else {
1328  optbool = ret;
1329  }
1330  if (nfs->enable_acl != optbool) {
1332  "ACL is "
1333  "manually %s",
1334  (optbool ? "enabled" : "disabled"));
1335  nfs->enable_acl = optbool;
1336  nfs_reconfigure_acl3(this);
1337  }
1338 
1339  GF_OPTION_RECONF("nfs.event-threads", nfs->event_threads, options, uint32,
1340  out);
1341  gf_event_reconfigure_threads(this->ctx->event_pool, nfs->event_threads);
1342 
1343  ret = 0;
1344 out:
1345  return ret;
1346 }
1347 
1348 /*
1349  * reconfigure() for NFS server xlator.
1350  */
1351 int
1353 {
1354  int ret = 0;
1355  struct nfs_state *nfs = NULL;
1356  gf_boolean_t regpmap = _gf_true;
1357 
1358  if ((!this) || (!this->private) || (!options))
1359  return (-1);
1360 
1361  nfs = (struct nfs_state *)this->private;
1362 
1363  /* Reconfigure nfs options */
1364  ret = nfs_reconfigure_state(this, options);
1365  if (ret) {
1367  "nfs reconfigure state failed");
1368  return (-1);
1369  }
1370 
1371  /* Reconfigure nfs3 options */
1372  ret = nfs3_reconfigure_state(this, options);
1373  if (ret) {
1375  "nfs3 reconfigure state failed");
1376  return (-1);
1377  }
1378 
1379  /* Reconfigure mount options */
1380  ret = mount_reconfigure_state(this, options);
1381  if (ret) {
1383  "mount reconfigure state failed");
1384  return (-1);
1385  }
1386 
1387  /* Reconfigure rpc layer */
1389  if (ret) {
1391  "rpcsvc reconfigure options failed");
1392  return (-1);
1393  }
1394 
1395  /* Reconfigure rpc.outstanding-rpc-limit */
1398  if (ret < 0) {
1400  "Failed to reconfigure outstanding-rpc-limit");
1401  return (-1);
1402  }
1403 
1404  regpmap = rpcsvc_register_portmap_enabled(nfs->rpcsvc);
1405  if (nfs->register_portmap != regpmap) {
1406  nfs->register_portmap = regpmap;
1407  if (regpmap) {
1409  } else {
1411  }
1412  }
1413 
1414  /* Reconfigure drc */
1415  ret = rpcsvc_drc_reconfigure(nfs->rpcsvc, options);
1416  if (ret) {
1418  "rpcsvc DRC reconfigure failed");
1419  return (-1);
1420  }
1421 
1422  return (0);
1423 }
1424 
1425 /* Main init() routine for NFS server xlator. It inits NFS v3 protocol
1426  * and its dependent protocols e.g. ACL, MOUNT v3 (mount3), NLM and
1427  * DRC.
1428  *
1429  * Usage: glusterfsd:
1430  * glusterfs_process_volfp() =>
1431  * glusterfs_graph_activate() =>
1432  * glusterfs_graph_init() =>
1433  * xlator_init () => NFS init() routine
1434  *
1435  * If init() routine fails, the glusterfsd cleans up the NFS process
1436  * by invoking cleanup_and_exit().
1437  *
1438  * RETURN:
1439  * 0 (SUCCESS) if all protocol specific inits PASS.
1440  * -1 (FAILURE) if any of them FAILS.
1441  */
1442 int
1444 {
1445  struct nfs_state *nfs = NULL;
1446  int ret = -1;
1447 
1448  if (!this)
1449  return (-1);
1450 
1451  nfs = nfs_init_state(this);
1452  if (!nfs) {
1454  "Failed to init nfs option");
1455  return (-1);
1456  }
1457 
1458  ret = nfs_add_all_initiators(nfs);
1459  if (ret) {
1461  "Failed to add initiators");
1462  return (-1);
1463  }
1464 
1465  ret = nfs_init_subvolumes(nfs, this->children);
1466  if (ret) {
1468  "Failed to init NFS exports");
1469  return (-1);
1470  }
1471 
1472  ret = mount_init_state(this);
1473  if (ret) {
1475  "Failed to init Mount state");
1476  return (-1);
1477  }
1478 
1479  ret = nlm4_init_state(this);
1480  if (ret) {
1482  "Failed to init NLM state");
1483  return (-1);
1484  }
1485 
1486  ret = nfs_init_versions(nfs, this);
1487  if (ret) {
1489  "Failed to initialize protocols");
1490  return (-1);
1491  }
1492 
1493  ret = nfs_drc_init(this);
1494  if (ret) {
1496  "Failed to initialize DRC");
1497  return (-1);
1498  }
1499 
1500  gf_msg(GF_NFS, GF_LOG_INFO, 0, NFS_MSG_STARTED, "NFS service started");
1501  return (0); /* SUCCESS */
1502 }
1503 
1504 int
1505 notify(xlator_t *this, int32_t event, void *data, ...)
1506 {
1507  xlator_t *subvol = NULL;
1508  struct nfs_state *priv = NULL;
1509 
1510  subvol = (xlator_t *)data;
1511 
1512  gf_msg_trace(GF_NFS, 0, "Notification received: %d", event);
1513 
1514  switch (event) {
1515  case GF_EVENT_CHILD_UP:
1516  nfs_startup_subvolume(this, subvol);
1517  break;
1518 
1521  priv = this->private;
1522  ++(priv->generation);
1523  break;
1524 
1525  case GF_EVENT_PARENT_UP:
1526  default_notify(this, GF_EVENT_PARENT_UP, data);
1527  break;
1528  }
1529 
1530  return 0;
1531 }
1532 
1533 void
1535 {
1536  struct nfs_state *nfs = NULL;
1537 
1538  mnt3svc_deinit(this);
1539  nfs = (struct nfs_state *)this->private;
1540  gf_msg_debug(GF_NFS, 0, "NFS service going down");
1541  nfs_deinit_versions(&nfs->versions, this);
1542  GF_FREE(this->instance_name);
1543  return;
1544 }
1545 
1546 int32_t
1548 {
1549  uint64_t ctx = 0;
1550  struct nfs_inode_ctx *ictx = NULL;
1551 
1552  if (inode_ctx_del(inode, this, &ctx))
1553  return -1;
1554 
1555  ictx = (struct nfs_inode_ctx *)(uintptr_t)ctx;
1556  GF_FREE(ictx);
1557 
1558  return 0;
1559 }
1560 
1562 _nfs_export_is_for_vol(char *exname, char *volname)
1563 {
1564  gf_boolean_t ret = _gf_false;
1565  char *tmp = NULL;
1566 
1567  tmp = exname;
1568  if (tmp[0] == '/')
1569  tmp++;
1570 
1571  if (!strcmp(tmp, volname))
1572  ret = _gf_true;
1573 
1574  return ret;
1575 }
1576 
1577 int
1578 nfs_priv_to_dict(xlator_t *this, dict_t *dict, char *brickname)
1579 {
1580  int ret = -1;
1581  struct nfs_state *priv = NULL;
1582  struct mountentry *mentry = NULL;
1583  char *volname = NULL;
1584  char key[1024] = {
1585  0,
1586  };
1587  int count = 0;
1588 
1589  GF_VALIDATE_OR_GOTO(THIS->name, this, out);
1590  GF_VALIDATE_OR_GOTO(THIS->name, dict, out);
1591 
1592  priv = this->private;
1593  GF_ASSERT(priv);
1594 
1595  ret = dict_get_str(dict, "volname", &volname);
1596  if (ret) {
1598  "Could not get volname");
1599  goto out;
1600  }
1601 
1602  list_for_each_entry(mentry, &priv->mstate->mountlist, mlist)
1603  {
1604  if (!_nfs_export_is_for_vol(mentry->exname, volname))
1605  continue;
1606 
1607  snprintf(key, sizeof(key), "client%d.hostname", count);
1608  ret = dict_set_str(dict, key, mentry->hostname);
1609  if (ret) {
1611  "Error writing hostname to dict");
1612  goto out;
1613  }
1614 
1615  /* No connection data available yet in nfs server.
1616  * Hence, setting to 0 to prevent cli failing
1617  */
1618  snprintf(key, sizeof(key), "client%d.bytesread", count);
1619  ret = dict_set_uint64(dict, key, 0);
1620  if (ret) {
1622  "Error writing bytes read to dict");
1623  goto out;
1624  }
1625 
1626  snprintf(key, sizeof(key), "client%d.byteswrite", count);
1627  ret = dict_set_uint64(dict, key, 0);
1628  if (ret) {
1630  "Error writing bytes write to dict");
1631  goto out;
1632  }
1633 
1634  count++;
1635  }
1636 
1637  ret = dict_set_int32(dict, "clientcount", count);
1638  if (ret)
1640  "Error writing client count to dict");
1641 
1642 out:
1643  gf_msg_debug(THIS->name, 0, "Returning %d", ret);
1644  return ret;
1645 }
1646 
1647 extern int32_t
1648 nlm_priv(xlator_t *this);
1649 
1650 int32_t
1652 {
1653  int32_t ret = -1;
1654 
1655  /* DRC needs the global drc structure, xl is of no use to it. */
1656  ret = rpcsvc_drc_priv(((struct nfs_state *)(this->private))->rpcsvc->drc);
1657  if (ret) {
1658  gf_msg_debug(this->name, 0, "Statedump of DRC failed");
1659  goto out;
1660  }
1661 
1662  ret = nlm_priv(this);
1663  if (ret) {
1664  gf_msg_debug(this->name, 0, "Statedump of NLM failed");
1665  goto out;
1666  }
1667 out:
1668  return ret;
1669 }
1670 
1671 int32_t
1673 {
1674  if (!this)
1675  return -1;
1676 
1677  if (this->next && this->next->itable) {
1678  gf_proc_dump_add_section("xlator.nfs.itable");
1679  inode_table_dump(this->next->itable, "xlator.nfs.itable");
1680  }
1681 
1682  return 0;
1683 }
1684 
1685 struct xlator_cbks cbks = {
1686  .forget = nfs_forget,
1687 };
1688 
1689 struct xlator_fops fops;
1690 
1691 struct xlator_dumpops dumpops = {
1692  .priv = nfs_priv,
1693  .priv_to_dict = nfs_priv_to_dict,
1694  .inode = nfs_itable_dump,
1695 };
1696 
1697 /* TODO: If needed, per-volume options below can be extended to be export
1698  * specific also because after export-dir is introduced, a volume is not
1699  * necessarily an export whereas different subdirectories within that volume
1700  * can be and may need these options to be specified separately.
1701  */
1702 struct volume_options options[] = {
1703  {.key = {"nfs3.read-size"},
1704  .type = GF_OPTION_TYPE_SIZET,
1705  .min = GF_NFS3_RTMIN,
1706  .max = GF_NFS3_RTMAX,
1707  .default_value = TOSTRING(GF_NFS3_RTPREF),
1708  .description = "Size in which the client should issue read requests "
1709  "to the Gluster NFSv3 server. Must be a multiple of "
1710  "4KB (4096). Min and Max supported values are 4KB "
1711  "(4096) and 1MB (1048576) respectively. If the "
1712  "specified value is within the supported range but "
1713  "not a multiple of 4096, it is rounded up to the "
1714  "nearest multiple of 4096."},
1715  {.key = {"nfs3.write-size"},
1716  .type = GF_OPTION_TYPE_SIZET,
1717  .min = GF_NFS3_WTMIN,
1718  .max = GF_NFS3_WTMAX,
1719  .default_value = TOSTRING(GF_NFS3_WTPREF),
1720  .description = "Size in which the client should issue write requests "
1721  "to the Gluster NFSv3 server. Must be a multiple of "
1722  "1KB (1024). Min and Max supported values are "
1723  "4KB (4096) and 1MB(1048576) respectively. If the "
1724  "specified value is within the supported range but "
1725  "not a multiple of 4096, it is rounded up to the "
1726  "nearest multiple of 4096."},
1727  {.key = {"nfs3.readdir-size"},
1728  .type = GF_OPTION_TYPE_SIZET,
1729  .min = GF_NFS3_DTMIN,
1730  .max = GF_NFS3_DTMAX,
1731  .default_value = TOSTRING(GF_NFS3_DTPREF),
1732  .description = "Size in which the client should issue directory "
1733  "reading requests to the Gluster NFSv3 server. Must "
1734  "be a multiple of 1KB (1024). Min and Max supported "
1735  "values are 4KB (4096) and 1MB (1048576) respectively."
1736  "If the specified value is within the supported range "
1737  "but not a multiple of 4096, it is rounded up to the "
1738  "nearest multiple of 4096."},
1739  {.key = {"nfs3.*.volume-access"},
1740  .type = GF_OPTION_TYPE_STR,
1741  .value = {"read-only", "read-write"},
1742  .default_value = "read-write",
1743  .description = "Type of access desired for this subvolume: "
1744  " read-only, read-write(default)"},
1745  {.key = {"nfs3.*.trusted-write"},
1746  .type = GF_OPTION_TYPE_BOOL,
1747  .default_value = "off",
1748  .description = "On an UNSTABLE write from client, return STABLE flag"
1749  " to force client to not send a COMMIT request. In "
1750  "some environments, combined with a replicated "
1751  "GlusterFS setup, this option can improve write "
1752  "performance. This flag allows user to trust Gluster"
1753  " replication logic to sync data to the disks and "
1754  "recover when required. COMMIT requests if received "
1755  "will be handled in a default manner by fsyncing."
1756  " STABLE writes are still handled in a sync manner. "
1757  "Off by default."
1758 
1759  },
1760  {.key = {"nfs3.*.trusted-sync"},
1761  .type = GF_OPTION_TYPE_BOOL,
1762  .default_value = "off",
1763  .description = "All writes and COMMIT requests are treated as async."
1764  " This implies that no write requests are guaranteed"
1765  " to be on server disks when the write reply is "
1766  "received at the NFS client. Trusted sync includes "
1767  " trusted-write behaviour. Off by default."
1768 
1769  },
1770  {.key = {"nfs3.*.export-dir"},
1771  .type = GF_OPTION_TYPE_PATH,
1772  .default_value = "",
1773  .description = "By default, all subvolumes of nfs are exported as "
1774  "individual exports. There are cases where a "
1775  "subdirectory or subdirectories in the volume need to "
1776  "be exported separately. This option can also be used "
1777  "in conjunction with nfs3.export-volumes option to "
1778  "restrict exports only to the subdirectories specified"
1779  " through this option. Must be an absolute path. Along"
1780  " with path allowed list of IPs/hostname can be "
1781  "associated with each subdirectory. If provided "
1782  "connection will allowed only from these IPs. By "
1783  "default connections from all IPs are allowed. "
1784  "Format: <dir>[(hostspec[|hostspec|...])][,...]. Where"
1785  " hostspec can be an IP address, hostname or an IP "
1786  "range in CIDR notation. "
1787  "e.g. /foo(192.168.1.0/24|host1|10.1.1.8),/host2."
1788  " NOTE: Care must be taken while configuring this "
1789  "option as invalid entries and/or unreachable DNS "
1790  "servers can introduce unwanted delay in all the mount"
1791  " calls."},
1792  {.key = {"nfs3.export-dirs"},
1793  .type = GF_OPTION_TYPE_BOOL,
1794  .default_value = "on",
1795  .description = "By default, all subvolumes of nfs are exported as "
1796  "individual exports. There are cases where a "
1797  "subdirectory or subdirectories in the volume need to "
1798  "be exported separately. Enabling this option allows "
1799  "any directory on a volumes to be exported separately."
1800  "Directory exports are enabled by default."},
1801  {.key = {"nfs3.export-volumes"},
1802  .type = GF_OPTION_TYPE_BOOL,
1803  .default_value = "on",
1804  .description = "Enable or disable exporting whole volumes, instead "
1805  "if used in conjunction with nfs3.export-dir, can "
1806  "allow setting up only subdirectories as exports. On "
1807  "by default."},
1808  {.key = {"rpc-auth.auth-unix"},
1809  .type = GF_OPTION_TYPE_BOOL,
1810  .default_value = "on",
1811  .description = "Disable or enable the AUTH_UNIX authentication type."
1812  "Must always be enabled for better interoperability. "
1813  "However, can be disabled if needed. Enabled by "
1814  "default"},
1815  {.key = {"rpc-auth.auth-null"},
1816  .type = GF_OPTION_TYPE_BOOL,
1817  .default_value = "on",
1818  .description = "Disable or enable the AUTH_NULL authentication type."
1819  "Must always be enabled. This option is here only to"
1820  " avoid unrecognized option warnings"},
1821  {.key = {"rpc-auth.auth-unix.*"},
1822  .type = GF_OPTION_TYPE_BOOL,
1823  .default_value = "on",
1824  .description = "Disable or enable the AUTH_UNIX authentication type "
1825  "for a particular exported volume overriding defaults"
1826  " and general setting for AUTH_UNIX scheme. Must "
1827  "always be enabled for better interoperability. "
1828  "However, can be disabled if needed. Enabled by "
1829  "default."},
1830  {.key = {"rpc-auth.auth-unix.*.allow"},
1831  .type = GF_OPTION_TYPE_STR,
1832  .default_value = "on",
1833  .description = "Disable or enable the AUTH_UNIX authentication type "
1834  "for a particular exported volume overriding defaults"
1835  " and general setting for AUTH_UNIX scheme. Must "
1836  "always be enabled for better interoperability. "
1837  "However, can be disabled if needed. Enabled by "
1838  "default."},
1839  {.key = {"rpc-auth.auth-null.*"},
1840  .type = GF_OPTION_TYPE_BOOL,
1841  .default_value = "on",
1842  .description = "Disable or enable the AUTH_NULL authentication type "
1843  "for a particular exported volume overriding defaults"
1844  " and general setting for AUTH_NULL. Must always be "
1845  "enabled. This option is here only to avoid "
1846  "unrecognized option warnings."},
1847  {.key = {"rpc-auth.addr.allow"},
1849  .default_value = "all",
1850  .description = "Allow a comma separated list of addresses and/or"
1851  " hostnames to connect to the server. By default, all"
1852  " connections are allowed. This allows users to "
1853  "define a general rule for all exported volumes."},
1854  {.key = {"rpc-auth.addr.reject"},
1856  .default_value = "none",
1857  .description = "Reject a comma separated list of addresses and/or"
1858  " hostnames from connecting to the server. By default,"
1859  " all connections are allowed. This allows users to "
1860  "define a general rule for all exported volumes."},
1861  {.key = {"rpc-auth.addr.*.allow"},
1863  .default_value = "all",
1864  .description = "Allow a comma separated list of addresses and/or"
1865  " hostnames to connect to the server. By default, all"
1866  " connections are allowed. This allows users to "
1867  "define a rule for a specific exported volume."},
1868  {.key = {"rpc-auth.addr.*.reject"},
1870  .default_value = "none",
1871  .description = "Reject a comma separated list of addresses and/or"
1872  " hostnames from connecting to the server. By default,"
1873  " all connections are allowed. This allows users to "
1874  "define a rule for a specific exported volume."},
1875  {.key = {"rpc-auth.ports.insecure"},
1876  .type = GF_OPTION_TYPE_BOOL,
1877  .default_value = "off",
1878  .description = "Allow client connections from unprivileged ports. By "
1879  "default only privileged ports are allowed. This is a"
1880  "global setting in case insecure ports are to be "
1881  "enabled for all exports using a single option."},
1882  {.key = {"rpc-auth.ports.*.insecure"},
1883  .type = GF_OPTION_TYPE_BOOL,
1884  .default_value = "off",
1885  .description = "Allow client connections from unprivileged ports. By "
1886  "default only privileged ports are allowed. Use this"
1887  " option to enable or disable insecure ports for "
1888  "a specific subvolume and to override the global "
1889  "setting set by the previous option."},
1890  {.key = {"rpc-auth.addr.namelookup"},
1891  .type = GF_OPTION_TYPE_BOOL,
1892  .default_value = "off",
1893  .description = "Users have the option of turning on name lookup for"
1894  " incoming client connections using this option. Use this "
1895  "option to turn on name lookups during address-based "
1896  "authentication. Turning this on will enable you to"
1897  " use hostnames in nfs.rpc-auth-* filters. In some "
1898  "setups, the name server can take too long to reply to DNS "
1899  "queries resulting in timeouts of mount requests. By "
1900  "default, name lookup is off"},
1901  {.key = {"nfs.dynamic-volumes"},
1902  .type = GF_OPTION_TYPE_BOOL,
1903  .default_value = "off",
1904  .description = "Internal option set to tell gnfs to use a different"
1905  " scheme for encoding file handles when DVM is being"
1906  " used."},
1907  {.key = {"nfs3.*.volume-id"},
1908  .type = GF_OPTION_TYPE_STR,
1909  .default_value = "",
1910  .description = "When nfs.dynamic-volumes is set, gnfs expects every "
1911  "subvolume to have this option set for it, so that "
1912  "gnfs can use this option to identify the volume. "
1913  "If all subvolumes do not have this option set, an "
1914  "error is reported."},
1915  {.key = {"nfs.enable-ino32"},
1916  .type = GF_OPTION_TYPE_BOOL,
1917  .default_value = "no",
1918  .description = "For nfs clients or apps that do not support 64-bit "
1919  "inode numbers, use this option to make NFS return "
1920  "32-bit inode numbers instead. Disabled by default, so"
1921  " NFS returns 64-bit inode numbers."},
1922  {.key = {"rpc.register-with-portmap"},
1923  .type = GF_OPTION_TYPE_BOOL,
1924  .default_value = "on",
1925  .description = "For systems that need to run multiple nfs servers, "
1926  "only one registration is possible with "
1927  "portmap service. Use this option to turn off portmap "
1928  "registration for Gluster NFS. On by default"},
1929  {.key = {"rpc.outstanding-rpc-limit"},
1930  .type = GF_OPTION_TYPE_INT,
1934  .description = "Parameter to throttle the number of incoming RPC "
1935  "requests from a client. 0 means no limit (can "
1936  "potentially run out of memory)"},
1937  {.key = {"nfs.port"},
1938  .type = GF_OPTION_TYPE_INT,
1939  .min = 1,
1940  .max = 0xffff,
1941  .default_value = TOSTRING(GF_NFS3_PORT),
1942  .description = "Use this option on systems that need Gluster NFS to "
1943  "be associated with a non-default port number."},
1944  {.key = {"nfs.mem-factor"},
1945  .type = GF_OPTION_TYPE_INT,
1946  .min = 1,
1947  .max = 1024,
1948  .default_value = TOSTRING(GF_NFS_DEFAULT_MEMFACTOR),
1949  .description = "Use this option to make NFS be faster on systems by "
1950  "using more memory. This option specifies a multiple "
1951  "that determines the total amount of memory used. "
1952  "Default value is 15. Increase to use more memory in "
1953  "order to improve performance for certain use cases."
1954  "Please consult gluster-users list before using this "
1955  "option."},
1956  {.key = {"nfs.*.disable"},
1957  .type = GF_OPTION_TYPE_BOOL,
1958  .default_value = "false",
1959  .description = "This option is used to start or stop the NFS server "
1960  "for individual volumes."},
1961  {.key = {"nfs.nlm"},
1962  .type = GF_OPTION_TYPE_BOOL,
1963  .default_value = "on",
1964  .description = "This option, if set to 'off', disables NLM server "
1965  "by not registering the service with the portmapper."
1966  " Set it to 'on' to re-enable it. Default value: 'on'"},
1967 
1968  {.key = {"nfs.mount-udp"},
1969  .type = GF_OPTION_TYPE_BOOL,
1970  .default_value = "off",
1971  .description = "set the option to 'on' to enable mountd on UDP. "
1972  "Required for some Solaris and AIX NFS clients. "
1973  "The need for enabling this option often depends "
1974  "on the usage of NLM."},
1975  {.key = {"nfs.mount-rmtab"},
1976  .type = GF_OPTION_TYPE_PATH,
1977  .default_value = NFS_DATADIR "/rmtab",
1978  .description = "Set the location of the cache file that is used to "
1979  "list all the NFS-clients that have connected "
1980  "through the MOUNT protocol. If this is on shared "
1981  "storage, all GlusterFS servers will update and "
1982  "output (with 'showmount') the same list. Set to "
1983  "\"/-\" to disable."},
1984  {.key = {OPT_SERVER_RPC_STATD},
1985  .type = GF_OPTION_TYPE_PATH,
1986  .default_value = GF_RPC_STATD_PROG,
1987  .description = "The executable of RPC statd utility. "
1988  "Defaults to " GF_RPC_STATD_PROG},
1989  {.key = {OPT_SERVER_RPC_STATD_PIDFILE},
1990  .type = GF_OPTION_TYPE_PATH,
1991  .default_value = GF_RPC_STATD_PIDFILE,
1992  .description = "The pid file of RPC statd utility. "
1993  "Defaults to " GF_RPC_STATD_PIDFILE},
1994  {.key = {OPT_SERVER_AUX_GIDS},
1995  .type = GF_OPTION_TYPE_BOOL,
1996  .default_value = "off",
1997  .description = "Let the server look up which groups a user belongs "
1998  "to, overwriting the list passed from the client. "
1999  "This enables support for group lists longer than "
2000  "can be passed through the NFS protocol, but is not "
2001  "secure unless users and groups are well synchronized "
2002  "between clients and servers."},
2003  {.key = {OPT_SERVER_GID_CACHE_TIMEOUT},
2004  .type = GF_OPTION_TYPE_INT,
2005  .min = 0,
2006  .max = 3600,
2007  .default_value = "300",
2008  .description = "Number of seconds to cache auxiliary-GID data, "
2009  "when " OPT_SERVER_AUX_GIDS " is set."},
2010  {.key = {"nfs.acl"},
2011  .type = GF_OPTION_TYPE_BOOL,
2012  .default_value = "on",
2013  .description = "This option is used to control ACL support for NFS."},
2014  {.key = {"nfs.drc"},
2015  .type = GF_OPTION_TYPE_STR,
2016  .default_value = "off",
2017  .description = "Enable Duplicate Request Cache in gNFS server to "
2018  "improve correctness of non-idempotent operations like "
2019  "write, delete, link, et al"},
2020  {.key = {"nfs.drc-size"},
2021  .type = GF_OPTION_TYPE_INT,
2022  .default_value = "0x20000",
2023  .description = "Sets the number of non-idempotent "
2024  "requests to cache in drc"},
2025  {.key = {"nfs.exports-auth-enable"},
2026  .type = GF_OPTION_TYPE_BOOL,
2027  .description = "Set the option to 'on' to enable exports/netgroup "
2028  "authentication in the NFS server and mount daemon."},
2029 
2030  {.key = {"nfs.auth-refresh-interval-sec"},
2031  .type = GF_OPTION_TYPE_INT,
2032  .description = "Frequency in seconds that the daemon should check for"
2033  " changes in the exports/netgroups file."},
2034 
2035  {.key = {"nfs.auth-cache-ttl-sec"},
2036  .type = GF_OPTION_TYPE_INT,
2037  .description = "Sets the TTL of an entry in the auth cache. Value is "
2038  "in seconds."},
2039  {.key = {"nfs.rdirplus"},
2040  .type = GF_OPTION_TYPE_BOOL,
2041  .default_value = "on",
2042  .description = "When this option is set to off NFS falls back to "
2043  "standard readdir instead of readdirp"},
2044  {
2045  .key = {"nfs.event-threads"},
2046  .type = GF_OPTION_TYPE_SIZET,
2047  .min = 1,
2048  .max = 32,
2049  .default_value = "2",
2050  .description = "Specifies the number of event threads to execute in"
2051  "in parallel. Larger values would help process"
2052  " responses faster, depending on available processing"
2053  " power. Range 1-32 threads.",
2054  .op_version = {GD_OP_VERSION_4_0_0},
2055  .flags = OPT_FLAG_SETTABLE,
2056  },
2057  {.key = {NULL}},
2058 };
2059 
2061  .init = init,
2062  .fini = fini,
2063  .notify = notify,
2064  .reconfigure = reconfigure,
2065  .mem_acct_init = mem_acct_init,
2066  .op_version = {1},
2067  .dumpops = &dumpops,
2068  .fops = &fops,
2069  .cbks = &cbks,
2070  .options = options,
2071  .identifier = "gnfs",
2073 };
nfs_reconfigure_acl3
static int nfs_reconfigure_acl3(xlator_t *this)
Definition: nfs.c:155
xlator.h
nfs_state::register_portmap
bool register_portmap
Definition: nfs.h:99
_gf_false
#define _gf_false
Definition: glusterfs.h:369
xlator_api
xlator_api_t xlator_api
Definition: nfs.c:2060
GF_NFS_DEFAULT_EXPORT_AUTH
#define GF_NFS_DEFAULT_EXPORT_AUTH
Definition: nfs.h:37
options
struct volume_options options[]
Definition: nfs.c:1702
GF_OPTION_TYPE_STR
@ GF_OPTION_TYPE_STR
Definition: options.h:23
out
#define out(x...)
Definition: gcrawler.c:35
list_del
static void list_del(struct list_head *old)
Definition: list.h:70
nfs_request_primary_user_init
void nfs_request_primary_user_init(nfs_user_t *nfu, rpcsvc_request_t *req, uid_t uid, gid_t gid)
Definition: nfs.c:688
nlm4_init_state
int nlm4_init_state(xlator_t *nfsx)
Definition: nlm4.c:2551
nfs_user_root_create
int nfs_user_root_create(nfs_user_t *newnfu)
Definition: nfs.c:624
nfs_state::allow_insecure
int allow_insecure
Definition: nfs.h:80
nfs_deinit_versions
int nfs_deinit_versions(struct list_head *versions, xlator_t *this)
Definition: nfs.c:269
xlator_api_t::init
int32_t(* init)(xlator_t *this)
Definition: xlator.h:914
GF_RPC_STATD_PIDFILE
#define GF_RPC_STATD_PIDFILE
Definition: nlm4.h:68
nfs_init_subvolumes
int nfs_init_subvolumes(struct nfs_state *nfs, xlator_list_t *cl)
Definition: nfs.c:580
TOSTRING
#define TOSTRING(val)
Definition: common-utils.h:47
sys_access
int sys_access(const char *pathname, int mode)
Definition: syscall.c:689
list_add_tail
static void list_add_tail(struct list_head *new, struct list_head *head)
Definition: list.h:35
NFS_MSG_DICT_SET_FAILED
@ NFS_MSG_DICT_SET_FAILED
Definition: nfs-messages.h:100
rpcsvc_auth_unix_auxgids
gid_t * rpcsvc_auth_unix_auxgids(rpcsvc_request_t *req, int *arrlen)
Definition: rpcsvc-auth.c:539
NFS_MSG_NFS_MAN_DISABLE
@ NFS_MSG_NFS_MAN_DISABLE
Definition: nfs-messages.h:100
NFS_MSG_LOOKUP_ROOT_FAIL
@ NFS_MSG_LOOKUP_ROOT_FAIL
Definition: nfs-messages.h:100
GF_OPTION_TYPE_CLIENT_AUTH_ADDR
@ GF_OPTION_TYPE_CLIENT_AUTH_ADDR
Definition: options.h:37
nfs_state::mstate
struct mount3_state * mstate
Definition: nfs.h:65
nfs_init_subvolume
int nfs_init_subvolume(struct nfs_state *nfs, xlator_t *xl)
Definition: nfs.c:559
nfs_state::svinitlock
gf_lock_t svinitlock
Definition: nfs.h:72
nfs_state::server_aux_gids_max_age
uint32_t server_aux_gids_max_age
Definition: nfs.h:96
NFS_MSG_PARSE_FAIL
@ NFS_MSG_PARSE_FAIL
Definition: nfs-messages.h:100
defaults.h
gid_cache_reconf
int gid_cache_reconf(gid_cache_t *cache, uint32_t timeout)
Definition: gidcache.c:42
NFS_MSG_STARTUP_FAIL
@ NFS_MSG_STARTUP_FAIL
Definition: nfs-messages.h:100
nfs_program_register_portmap_all
static int nfs_program_register_portmap_all(struct nfs_state *nfs)
Definition: nfs.c:191
NFS_MSG_INIT_FAIL
@ NFS_MSG_INIT_FAIL
Definition: nfs-messages.h:100
mem-pool.h
iatt
Definition: iatt.h:46
NFS_MSG_NLM_MAN_DISABLE
@ NFS_MSG_NLM_MAN_DISABLE
Definition: nfs-messages.h:100
mem_pool_new
#define mem_pool_new(type, count)
Definition: mem-pool.h:294
nfs_state::server_aux_gids
bool server_aux_gids
Definition: nfs.h:95
GF_VALIDATE_OR_GOTO
#define GF_VALIDATE_OR_GOTO(name, arg, label)
Definition: common-utils.h:319
nfs_user_create
int nfs_user_create(nfs_user_t *newnfu, uid_t uid, gid_t gid, rpc_transport_t *trans, gid_t *auxgids, int auxcount)
Definition: nfs.c:637
NFS_MSG_PROT_INIT_ADD_FAIL
@ NFS_MSG_PROT_INIT_ADD_FAIL
Definition: nfs-messages.h:100
rpcsvc_program::progport
uint16_t progport
Definition: rpcsvc.h:453
nfs_user_info::ngrps
int ngrps
Definition: nfs.h:131
nfs3_reconfigure_state
int nfs3_reconfigure_state(xlator_t *nfsx, dict_t *options)
Definition: nfs3.c:5703
xlator_list::next
struct xlator_list * next
Definition: xlator.h:762
THIS
#define THIS
Definition: globals.h:126
NFS_MSG_RECONFIG_VALUE
@ NFS_MSG_RECONFIG_VALUE
Definition: nfs-messages.h:100
gf_string2uint
int gf_string2uint(const char *str, unsigned int *n)
Definition: common-utils.c:1419
dumpops
struct xlator_dumpops dumpops
Definition: nfs.c:1691
sys_stat
int sys_stat(const char *path, struct stat *buf)
Definition: syscall.c:80
dict_set_uint64
int dict_set_uint64(dict_t *this, char *key, uint64_t val)
Definition: dict.c:2017
rpcsvc_program
Definition: rpcsvc.h:393
xlator_dumpops::priv
dumpop_priv_t priv
Definition: xlator.h:747
nfs_reconfigure_state
int nfs_reconfigure_state(xlator_t *this, dict_t *options)
Definition: nfs.c:1161
GF_OPTION_TYPE_INT
@ GF_OPTION_TYPE_INT
Definition: options.h:24
gid_cache_init
int gid_cache_init(gid_cache_t *cache, uint32_t timeout)
Definition: gidcache.c:25
OPT_SERVER_AUX_GIDS
#define OPT_SERVER_AUX_GIDS
Definition: nfs.c:36
RPCSVC_MIN_OUTSTANDING_RPC_LIMIT
#define RPCSVC_MIN_OUTSTANDING_RPC_LIMIT
Definition: rpcsvc.h:45
nfs_state::override_portnum
unsigned int override_portnum
Definition: nfs.h:79
GF_FREE
#define GF_FREE(free_ptr)
Definition: mem-pool.h:159
NFS_MSG_VOL_NOT_FOUND
@ NFS_MSG_VOL_NOT_FOUND
Definition: nfs-messages.h:100
nfs_state::exports_auth
int exports_auth
Definition: nfs.h:86
nfs_add_initer
static int nfs_add_initer(struct list_head *list, nfs_version_initer_t init, bool required)
Definition: nfs.c:248
dict_get
data_t * dict_get(dict_t *this, char *key)
Definition: dict.c:544
_nfs_export_is_for_vol
bool _nfs_export_is_for_vol(char *exname, char *volname)
Definition: nfs.c:1562
dict_set_int32
int dict_set_int32(dict_t *this, char *key, int32_t val)
Definition: dict.c:1837
gf_nfs_mt_nfs_initer_list
@ gf_nfs_mt_nfs_initer_list
Definition: nfs-mem-types.h:29
RPCSVC_DEF_NFS_OUTSTANDING_RPC_LIMIT
#define RPCSVC_DEF_NFS_OUTSTANDING_RPC_LIMIT
Definition: rpcsvc.h:43
nfs_state::rpc_statd_pid_file
char * rpc_statd_pid_file
Definition: nfs.h:101
GF_EVENT_SOME_DESCENDENT_UP
@ GF_EVENT_SOME_DESCENDENT_UP
Definition: glusterfs-fops.h:102
mountentry::exname
char exname[1024]
Definition: mount3.h:76
xlator_list
Definition: xlator.h:760
options.h
nfs_state::generation
uint32_t generation
Definition: nfs.h:98
inode_table_new
inode_table_t * inode_table_new(uint32_t lru_limit, xlator_t *xl)
Definition: inode.c:1754
nfs_program_unregister_portmap_all
static int nfs_program_unregister_portmap_all(struct nfs_state *nfs)
Definition: nfs.c:219
nfs_version_initer_t
rpcsvc_program_t *(* nfs_version_initer_t)(xlator_t *nfsx)
Definition: nfs.h:52
_call_frame
Definition: stack.h:63
rpcsvc.h
acl3.h
GF_NFS3_RTMAX
#define GF_NFS3_RTMAX
Definition: nfs3.h:50
nfs_initer_list::program
rpcsvc_program_t * program
Definition: nfs.h:58
syscall.h
_inode
Definition: inode.h:99
peer_info::identifier
char identifier[UNIX_PATH_MAX]
Definition: rpc-transport.h:70
NFS_MSG_RPC_CONFIG_FAIL
@ NFS_MSG_RPC_CONFIG_FAIL
Definition: nfs-messages.h:100
xlator_fops
Definition: xlator.h:561
nfs3-helpers.h
mount_reconfigure_state
int mount_reconfigure_state(xlator_t *nfsx, dict_t *options)
Definition: mount3.c:4218
nfs3.h
nfs_loc_wipe
void nfs_loc_wipe(loc_t *loc)
Definition: nfs-common.c:117
NFS_MSG_RECONFIG_VOL
@ NFS_MSG_RECONFIG_VOL
Definition: nfs-messages.h:100
gf_asprintf
int gf_asprintf(char **string_ptr, const char *format,...)
Definition: mem-pool.c:237
nfs_state::upsubvols
int upsubvols
Definition: nfs.h:74
NFS_MSG_PGM_REG_FAIL
@ NFS_MSG_PGM_REG_FAIL
Definition: nfs-messages.h:100
OPT_SERVER_GID_CACHE_TIMEOUT
#define OPT_SERVER_GID_CACHE_TIMEOUT
Definition: nfs.c:37
GF_LOG_WARNING
@ GF_LOG_WARNING
Definition: logging.h:74
dict_set_dynstr
int dict_set_dynstr(dict_t *this, char *key, char *str)
Definition: dict.c:2487
nfs_forget
int32_t nfs_forget(xlator_t *this, inode_t *inode)
Definition: nfs.c:1547
rpcsvc_drc_priv
int32_t rpcsvc_drc_priv(rpcsvc_drc_globals_t *drc)
Definition: rpc-drc.c:531
GF_EVENT_CHILD_UP
@ GF_EVENT_CHILD_UP
Definition: glusterfs-fops.h:85
INIT_LIST_HEAD
#define INIT_LIST_HEAD(head)
Definition: list.h:19
GF_NFS_CONCURRENT_OPS_MULT
#define GF_NFS_CONCURRENT_OPS_MULT
Definition: nfs.h:22
GF_OPTION_TYPE_SIZET
@ GF_OPTION_TYPE_SIZET
Definition: options.h:25
GF_NFS3_WTMIN
#define GF_NFS3_WTMIN
Definition: nfs3.h:56
rpcsvc_set_throttle_on
int rpcsvc_set_throttle_on(rpcsvc_t *svc)
Definition: rpcsvc.c:2705
nfs_startup_subvolume
int nfs_startup_subvolume(xlator_t *nfsx, xlator_t *xl)
Definition: nfs.c:489
rpc_transport
Definition: rpc-transport.h:162
nfs_root_loc_fill
int nfs_root_loc_fill(inode_table_t *itable, loc_t *loc)
Definition: nfs-common.c:273
gf_boolean_t
#define gf_boolean_t
Definition: glusterfs.h:368
uint32
uint32_t uint32
Definition: xdr-nfs3.h:41
rpcsvc_program_unregister_portmap
int rpcsvc_program_unregister_portmap(rpcsvc_program_t *prog)
Definition: rpcsvc.c:1724
GF_OPTION_TYPE_BOOL
@ GF_OPTION_TYPE_BOOL
Definition: options.h:28
GF_NFS_DEFAULT_MEMFACTOR
#define GF_NFS_DEFAULT_MEMFACTOR
Definition: nfs.h:29
nfs_state::enable_ino32
int enable_ino32
Definition: nfs.h:78
OPT_FLAG_SETTABLE
@ OPT_FLAG_SETTABLE
Definition: options.h:49
cbks
struct xlator_cbks cbks
Definition: nfs.c:1685
NFS_MSG_OPT_INIT_FAIL
@ NFS_MSG_OPT_INIT_FAIL
Definition: nfs-messages.h:100
GF_NFS3_RTPREF
#define GF_NFS3_RTPREF
Definition: nfs3.h:52
xlator_api_t
Definition: xlator.h:879
nfs_state::event_threads
uint32_t event_threads
Definition: nfs.h:103
rpcsvc_set_outstanding_rpc_limit
int rpcsvc_set_outstanding_rpc_limit(rpcsvc_t *svc, dict_t *options, int defvalue)
Definition: rpcsvc.c:2662
RPCSVC_MAX_OUTSTANDING_RPC_LIMIT
#define RPCSVC_MAX_OUTSTANDING_RPC_LIMIT
Definition: rpcsvc.h:44
UNLOCK
#define UNLOCK(x)
Definition: locking.h:79
_xlator::name
char * name
Definition: xlator.h:772
NFS_MSG_ACL_MAN_DISABLE
@ NFS_MSG_ACL_MAN_DISABLE
Definition: nfs-messages.h:100
mnt3svc_init
rpcsvc_program_t * mnt3svc_init(xlator_t *nfsx)
Definition: mount3.c:4009
rpcsvc_register_portmap_enabled
int rpcsvc_register_portmap_enabled(rpcsvc_t *svc)
Definition: rpcsvc.c:1744
xlator_dumpops
Definition: xlator.h:746
NFS_MSG_NO_MEMORY
@ NFS_MSG_NO_MEMORY
Definition: nfs-messages.h:100
gf_msg
#define gf_msg(dom, level, errnum, msgid, fmt...)
Definition: logging.h:229
NFS_MSG_RECONFIG_ENABLE
@ NFS_MSG_RECONFIG_ENABLE
Definition: nfs-messages.h:100
NFS_MSG_NLM_INFO
@ NFS_MSG_NLM_INFO
Definition: nfs-messages.h:100
NFS_MSG_ENABLE_THROTTLE_FAIL
@ NFS_MSG_ENABLE_THROTTLE_FAIL
Definition: nfs-messages.h:100
nfs_add_all_initiators
int nfs_add_all_initiators(struct nfs_state *nfs)
Definition: nfs.c:364
nfs_initer_list
Definition: nfs.h:55
NFS_MSG_WRITE_FAIL
@ NFS_MSG_WRITE_FAIL
Definition: nfs-messages.h:100
gf_string2boolean
int gf_string2boolean(const char *str, bool *b)
Definition: common-utils.c:1922
rpcsvc_drc_init
int rpcsvc_drc_init(rpcsvc_t *svc, dict_t *options)
Definition: rpc-drc.c:668
gf_msg_debug
#define gf_msg_debug(dom, errnum, fmt...)
Definition: logging.h:270
mount3_state::mountlist
struct list_head mountlist
Definition: mount3.h:140
rpcsvc_request_uid
#define rpcsvc_request_uid(req)
Definition: rpcsvc.h:279
list_head
Definition: list.h:14
NFS_MSG_DICT_GET_FAILED
@ NFS_MSG_DICT_GET_FAILED
Definition: nfs-messages.h:100
OPT_SERVER_RPC_STATD
#define OPT_SERVER_RPC_STATD
Definition: nfs.c:38
NFS_MSG_STARTED
@ NFS_MSG_STARTED
Definition: nfs-messages.h:100
GF_NFS
#define GF_NFS
Definition: nfs.h:20
nfs_state::rmtab
char * rmtab
Definition: nfs.h:93
acl3svc_init
rpcsvc_program_t * acl3svc_init(xlator_t *nfsx)
Definition: acl3.c:721
gf_event_reconfigure_threads
int gf_event_reconfigure_threads(struct event_pool *event_pool, int value)
Definition: event.c:124
nfs_inode_ctx
Definition: nfs.h:106
GF_NFS3_PORT
#define GF_NFS3_PORT
Definition: common-utils.h:105
dict_get_str
int dict_get_str(dict_t *this, char *key, char **str)
Definition: dict.c:2385
NFS_MSG_RECONFIG_PATH
@ NFS_MSG_RECONFIG_PATH
Definition: nfs-messages.h:100
inode_table_dump
void inode_table_dump(inode_table_t *itable, char *prefix)
Definition: inode.c:2463
GF_RPC_STATD_PROG
#define GF_RPC_STATD_PROG
Definition: nlm4.h:67
nfs_state::rpc_statd
char * rpc_statd
Definition: nfs.h:100
GF_NFS3_WTPREF
#define GF_NFS3_WTPREF
Definition: nfs3.h:57
GF_OPTION_TYPE_PATH
@ GF_OPTION_TYPE_PATH
Definition: options.h:30
mem_pool_destroy
void mem_pool_destroy(struct mem_pool *pool)
Definition: mem-pool.c:901
inode_ctx_del
#define inode_ctx_del(i, x, v)
Definition: inode.h:274
xlator_cbks
Definition: xlator.h:707
_xlator::private
void * private
Definition: xlator.h:822
rpcsvc_request
Definition: rpcsvc.h:155
mountentry
Definition: mount3.h:71
nfs_priv_to_dict
int nfs_priv_to_dict(xlator_t *this, dict_t *dict, char *brickname)
Definition: nfs.c:1578
rpcsvc_state::options
dict_t * options
Definition: rpcsvc-common.h:46
GF_LOG_CRITICAL
@ GF_LOG_CRITICAL
Definition: logging.h:72
nfs_fop_local
Definition: nfs-fops.h:40
_xlator
Definition: xlator.h:770
NFS_MSG_READ_FAIL
@ NFS_MSG_READ_FAIL
Definition: nfs-messages.h:100
nfs-mem-types.h
nfs.h
fops
struct xlator_fops fops
Definition: nfs.c:1689
nfs_request_user_init
void nfs_request_user_init(nfs_user_t *nfu, rpcsvc_request_t *req)
Definition: nfs.c:672
rpcsvc_reconfigure_options
int rpcsvc_reconfigure_options(rpcsvc_t *svc, dict_t *options)
Definition: rpcsvc.c:2528
rpcsvc_drc_reconfigure
int rpcsvc_drc_reconfigure(rpcsvc_t *svc, dict_t *options)
Definition: rpc-drc.c:795
nfs_init_versions
int nfs_init_versions(struct nfs_state *nfs, xlator_t *this)
Definition: nfs.c:298
GF_OPTION_INIT
#define GF_OPTION_INIT(key, val, type, err_label)
Definition: options.h:257
xlator_list::xlator
xlator_t * xlator
Definition: xlator.h:761
GF_NFS_INODE_LRU_MULT
#define GF_NFS_INODE_LRU_MULT
Definition: nfs.h:24
gf_log
#define gf_log(dom, level, fmt...)
Definition: logging.h:282
nfs_subvolume_started
int nfs_subvolume_started(struct nfs_state *nfs, xlator_t *xl)
Definition: nfs.c:414
GF_EVENT_SOME_DESCENDENT_DOWN
@ GF_EVENT_SOME_DESCENDENT_DOWN
Definition: glusterfs-fops.h:100
rpcsvc_program_register_portmap
int rpcsvc_program_register_portmap(rpcsvc_program_t *newprog, uint32_t port)
Definition: rpcsvc.c:1701
xlator_mem_acct_init
int xlator_mem_acct_init(xlator_t *xl, int num_types)
Definition: xlator.c:701
_loc
Definition: xlator.h:66
name
char * name
Definition: xdr-nfs3.h:948
rpcsvc_request_transport
#define rpcsvc_request_transport(req)
Definition: rpcsvc.h:290
nfs_deinit_version
static int nfs_deinit_version(struct nfs_state *nfs, nfs_version_initer_t init)
Definition: nfs.c:125
nfs3svc_init
rpcsvc_program_t * nfs3svc_init(xlator_t *nfsx)
Definition: nfs3.c:5683
mnt3svc_deinit
void mnt3svc_deinit(xlator_t *nfsx)
Definition: mount3.c:3979
GF_NFS_DEFAULT_AUTH_CACHE_TTL_SEC
#define GF_NFS_DEFAULT_AUTH_CACHE_TTL_SEC
Definition: nfs.h:40
gf_path_strip_trailing_slashes
void gf_path_strip_trailing_slashes(char *path)
Definition: common-utils.c:3094
gf_nfs_mt_xlator_t
@ gf_nfs_mt_xlator_t
Definition: nfs-mem-types.h:30
nfs_state::dynamicvolumes
int dynamicvolumes
Definition: nfs.h:77
nfs_state
Definition: nfs.h:62
NFS_MSG_RECONFIG_FAIL
@ NFS_MSG_RECONFIG_FAIL
Definition: nfs-messages.h:100
volume_options::category
gf_category_t category
Definition: options.h:143
nfs_state::mount_udp
int mount_udp
Definition: nfs.h:83
mount_init_state
int mount_init_state(xlator_t *nfsx)
Definition: mount3.c:3638
NFS_MSG_REG_FILE_ERROR
@ NFS_MSG_REG_FILE_ERROR
Definition: nfs-messages.h:100
volume_options
Definition: options.h:87
nfs_state::versions
struct list_head versions
Definition: nfs.h:64
init
int init(xlator_t *this)
Definition: nfs.c:1443
nfs_state::memfactor
unsigned int memfactor
Definition: nfs.h:69
nfs_drc_init
int nfs_drc_init(xlator_t *this)
Definition: nfs.c:1142
nfs_state::subvols
xlator_list_t * subvols
Definition: nfs.h:70
nfs_state::auth_refresh_time_secs
unsigned int auth_refresh_time_secs
Definition: nfs.h:90
xlator_cbks::forget
cbk_forget_t forget
Definition: xlator.h:708
nfs_init_state
struct nfs_state * nfs_init_state(xlator_t *this)
Definition: nfs.c:723
nfs_startup_subvolumes
int nfs_startup_subvolumes(xlator_t *nfsx)
Definition: nfs.c:531
nfs_user_info
Definition: nfs.h:128
GF_LOG_ERROR
@ GF_LOG_ERROR
Definition: logging.h:73
nfs_user_info::gids
gid_t gids[(16+1)]
Definition: nfs.h:130
nfs_state::gid_cache
gid_cache_t gid_cache
Definition: nfs.h:97
list_for_each_entry
#define list_for_each_entry(pos, head, member)
Definition: list.h:235
GF_REQUEST_MAXGROUPS
#define GF_REQUEST_MAXGROUPS
Definition: nfs.h:46
nfs_state::initedxl
xlator_t ** initedxl
Definition: nfs.h:75
LOCK_INIT
#define LOCK_INIT(x)
Definition: locking.h:76
nlm_priv
int32_t nlm_priv(xlator_t *this)
Definition: nlm4.c:2725
nfs_subvolume_set_started
int nfs_subvolume_set_started(struct nfs_state *nfs, xlator_t *xl)
Definition: nfs.c:438
NFS_MSG_XLATOR_INIT_FAIL
@ NFS_MSG_XLATOR_INIT_FAIL
Definition: nfs-messages.h:100
mountentry::mlist
struct list_head mlist
Definition: mount3.h:73
nfs_user_info::identifier
char identifier[UNIX_PATH_MAX]
Definition: nfs.h:133
reconfigure
int reconfigure(xlator_t *this, dict_t *options)
Definition: nfs.c:1352
rpc_transport::peerinfo
peer_info_t peerinfo
Definition: rpc-transport.h:187
gf_nfs_mt_nfs_state
@ gf_nfs_mt_nfs_state
Definition: nfs-mem-types.h:19
GF_EVENT_PARENT_UP
@ GF_EVENT_PARENT_UP
Definition: glusterfs-fops.h:81
nfs_itable_dump
int32_t nfs_itable_dump(xlator_t *this)
Definition: nfs.c:1672
logging.h
_xlator::itable
inode_table_t * itable
Definition: xlator.h:820
GF_MAINTAINED
@ GF_MAINTAINED
Definition: glusterfs.h:401
mem_acct_init
int32_t mem_acct_init(xlator_t *this)
Definition: nfs.c:704
dict.h
nfs_initer_list::required
bool required
Definition: nfs.h:59
default_notify
int default_notify(xlator_t *this, int32_t event, void *data,...)
Definition: defaults-tmpl.c:125
dict_set_str
int dict_set_str(dict_t *this, char *key, char *str)
Definition: dict.c:2410
GF_NFS_DVM_ON
#define GF_NFS_DVM_ON
Definition: nfs.h:33
NFS_MSG_INIT_GRP_CACHE_FAIL
@ NFS_MSG_INIT_GRP_CACHE_FAIL
Definition: nfs-messages.h:100
nfs_initer_list::init
nfs_version_initer_t init
Definition: nfs.h:57
GF_NFS3_DTPREF
#define GF_NFS3_DTPREF
Definition: nfs3.h:63
NFS_MSG_PGM_INIT_FAIL
@ NFS_MSG_PGM_INIT_FAIL
Definition: nfs-messages.h:100
LOCK
#define LOCK(x)
Definition: locking.h:77
statedump.h
nfs_reconfigure_nlm4
static int nfs_reconfigure_nlm4(xlator_t *this)
Definition: nfs.c:173
nfs_user_info::uid
uid_t uid
Definition: nfs.h:129
fini
void fini(xlator_t *this)
Definition: nfs.c:1534
nlm4.h
volume_options::key
char * key[4]
Definition: options.h:88
nfs_state::refresh_auth
int refresh_auth
Definition: nfs.h:88
NFS_MSG_ACL_INFO
@ NFS_MSG_ACL_INFO
Definition: nfs-messages.h:100
nfs_state::auth_cache_ttl_sec
unsigned int auth_cache_ttl_sec
Definition: nfs.h:91
nfs_init_version
static int nfs_init_version(xlator_t *this, nfs_version_initer_t init, bool required)
Definition: nfs.c:50
nfs_priv
int32_t nfs_priv(xlator_t *this)
Definition: nfs.c:1651
nfs_state::allsubvols
int allsubvols
Definition: nfs.h:73
nfs_fop_lookup
int nfs_fop_lookup(xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc, fop_lookup_cbk_t cbk, void *local)
Definition: nfs-fops.c:421
rpcsvc_state
Definition: rpcsvc-common.h:35
list_for_each_entry_safe
#define list_for_each_entry_safe(pos, n, head, member)
Definition: list.h:240
nlm4svc_init
rpcsvc_program_t * nlm4svc_init(xlator_t *nfsx)
Definition: nlm4.c:2566
_dict
Definition: dict.h:114
GF_CALLOC
#define GF_CALLOC(nmemb, size, type)
Definition: mem-pool.h:153
GF_NFS3_RTMIN
#define GF_NFS3_RTMIN
Definition: nfs3.h:51
nfs_initer_list::list
struct list_head list
Definition: nfs.h:56
dict_get_str_boolean
int dict_get_str_boolean(dict_t *this, char *key, int default_val)
Definition: dict.c:2781
NFS_DATADIR
#define NFS_DATADIR
Definition: nfs.c:42
NFS_MSG_NO_PERM
@ NFS_MSG_NO_PERM
Definition: nfs-messages.h:100
GF_ASSERT
#define GF_ASSERT(x)
Definition: common-utils.h:434
GF_NFS_DEFAULT_AUTH_REFRESH_INTERVAL_SEC
#define GF_NFS_DEFAULT_AUTH_REFRESH_INTERVAL_SEC
Definition: nfs.h:39
nfs_state::rpcsvc
rpcsvc_t * rpcsvc
Definition: nfs.h:63
nfs_state::enable_acl
int enable_acl
Definition: nfs.h:82
nfs_state::enable_nlm
int enable_nlm
Definition: nfs.h:81
GF_LOG_INFO
@ GF_LOG_INFO
Definition: logging.h:76
NFS_MSG_RPC_INIT_FAIL
@ NFS_MSG_RPC_INIT_FAIL
Definition: nfs-messages.h:100
NFS_MSG_ROOT_LOC_INIT_FAIL
@ NFS_MSG_ROOT_LOC_INIT_FAIL
Definition: nfs-messages.h:100
_gf_true
#define _gf_true
Definition: glusterfs.h:370
nfs-fops.h
nfs_start_subvol_lookup_cbk
int32_t nfs_start_subvol_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, dict_t *xattr, struct iatt *postparent)
Definition: nfs.c:471
GF_NFS_DVM_OFF
#define GF_NFS_DVM_OFF
Definition: nfs.h:34
rpcsvc_program_unregister
int rpcsvc_program_unregister(rpcsvc_t *svc, rpcsvc_program_t *program)
Definition: rpcsvc.c:1850
rpc-drc.h
gf_strdup
static char * gf_strdup(const char *src)
Definition: mem-pool.h:182
err
#define err(x...)
Definition: gcrawler.c:34
rpcsvc_program::progname
char progname[32]
Definition: rpcsvc.h:394
GD_OP_VERSION_4_0_0
#define GD_OP_VERSION_4_0_0
Definition: globals.h:103
rpcsvc_program_register
int rpcsvc_program_register(rpcsvc_t *svc, rpcsvc_program_t *program, bool add_to_head)
Definition: rpcsvc.c:2251
gf_nfs_mt_end
@ gf_nfs_mt_end
Definition: nfs-mem-types.h:46
GF_OPTION_RECONF
#define GF_OPTION_RECONF(key, val, opt, type, err_label)
Definition: options.h:321
nfs-messages.h
gf_proc_dump_add_section
int gf_proc_dump_add_section(char *key,...)
Definition: statedump.c:144
rpcsvc_request_gid
#define rpcsvc_request_gid(req)
Definition: rpcsvc.h:280
notify
int notify(xlator_t *this, int32_t event, void *data,...)
Definition: nfs.c:1505
UNIX_PATH_MAX
#define UNIX_PATH_MAX
Definition: rdd.c:26
gf_msg_trace
#define gf_msg_trace(dom, errnum, fmt...)
Definition: logging.h:276
NFS_MSG_PGM_NOT_FOUND
@ NFS_MSG_PGM_NOT_FOUND
Definition: nfs-messages.h:100
rpcsvc_init
rpcsvc_t * rpcsvc_init(xlator_t *xl, glusterfs_ctx_t *ctx, dict_t *options, uint32_t poolcount)
Definition: rpcsvc.c:2783
mount_rewrite_rmtab
void mount_rewrite_rmtab(struct mount3_state *ms, char *new_rmtab)
Definition: mount3.c:494
GF_NFS3_WTMAX
#define GF_NFS3_WTMAX
Definition: nfs3.h:55
OPT_SERVER_RPC_STATD_PIDFILE
#define OPT_SERVER_RPC_STATD_PIDFILE
Definition: nfs.c:39
GF_NFS3_DTMAX
#define GF_NFS3_DTMAX
Definition: nfs3.h:61
GF_NFS3_DTMIN
#define GF_NFS3_DTMIN
Definition: nfs3.h:62
nfs_state::foppool
struct mem_pool * foppool
Definition: nfs.h:68
nfs_state::rdirplus
bool rdirplus
Definition: nfs.h:102
mnt1svc_init
rpcsvc_program_t * mnt1svc_init(xlator_t *nfsx)
Definition: mount3.c:4141
mountentry::hostname
char hostname[1024]
Definition: mount3.h:77
mount3.h