>Number:         147881
>Category:       kern
>Synopsis:       ZFS "sharenfs" doesn't allow different "exports" options for 
>different hosts
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jun 15 16:00:01 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Richard S. Conto
>Release:        FreeBSD 8 CURRENT
>Organization:
Home Use / University of Michigan
>Environment:
FreeBSD foundry.family 8.1-PRERELEASE FreeBSD 8.1-PRERELEASE #0: Sun Jun 13 
03:31:00 EDT 2010     r...@foundry.family:/usr/obj/usr/src/sys/FOUNDRY  i386


>Description:
I found that I was unable to selectively NFS export my ZFS filesystems such 
that some hosts had "-maproot=0" and others had "-maproot=nobody:nobody".

The syntax and operation of 'zfs set sharenfs="xxx" <poolname>' followed by 
"zfs share -a" doesn't allow for a multi-valued 'xxx'. 
>How-To-Repeat:
(1) Set up ZFS based NFS host
(2) Set up two NFS clients, one which should have "root" access to the NFS 
exports from the ZFS host, one which shouldn't
(3) Try to make it so.
>Fix:
Here's a patch to the compatibility shim "fsshare.c" that allows the following 
syntax for "sharenfs='xxxx' where 'xxxx' can be:

(1) <export_options>... <export_hosts>...
(2) <export_options_1>... <export_hosts_1> ; <export_options_2>... 
<export_hosts_2>... ; ... <export_options_n>... <export_hosts_n>...

Empty sets of '<exports_options_n>... <exports_hosts_n>...' are allowed (i.e.: 
multiple ';'s with only whitespace between them.

Comments (with a leading '#') for '<exports_options_n>... <exports_hosts_n>...' 
are supported to allow a ZFS administrator to disable a particular 
configuration.

Patch attached with submission follows:

Index: ./src/cddl/compat/opensolaris/misc/fsshare.c
===================================================================
RCS file: 
/shares/Home/cvsupin/FreeBSD/FreeBSD-all/src/cddl/compat/opensolaris/misc/fsshare.c,v
retrieving revision 1.3.4.1
diff -c -b -w -r1.3.4.1 fsshare.c
*** ./src/cddl/compat/opensolaris/misc/fsshare.c        3 Aug 2009 08:13:06 
-0000       1.3.4.1
--- ./src/cddl/compat/opensolaris/misc/fsshare.c        13 Jun 2010 18:11:53 
-0000
***************
*** 32,37 ****
--- 32,38 ----
  #include <unistd.h>
  #include <fcntl.h>
  #include <string.h>
+ #include <strings.h>
  #include <errno.h>
  #include <libutil.h>
  #include <assert.h>
***************
*** 149,157 ****
      int share)
  {
        char tmpfile[PATH_MAX];
        char *line;
        FILE *newfd, *oldfd;
!       int fd, error;
  
        newfd = oldfd = NULL;
        error = 0;
--- 150,160 ----
      int share)
  {
        char tmpfile[PATH_MAX];
+       char each[OPTSSIZE];     /* Multiple export options per filesystem. */
        char *line;
+       char *cur, *next;               /* Next set of mountopts/hosts */
        FILE *newfd, *oldfd;
!       int fd, error, count;
  
        newfd = oldfd = NULL;
        error = 0;
***************
*** 209,217 ****
--- 212,287 ----
                goto out;
        }
        if (share) {
+               /*
+                * if 'shareopts' has ';' separators, then put out multiple
+                * exports points with (with presumeably different mountoptions 
and
+                * hosts.)
+                *
+                * If the mount options begin with a '#', treat as a comment 
and IGNORE
+                * (to allow ZFS administrators to leave configurations in 
place but disabled.)
+                */
+ 
+               if ((next = index(shareopts, ';')) == (char *) NULL) {
+                       /* Original FreeBSD implementation - compatibility? 
+                        * Note: This DOESN'T check for '#' comment 
configurations!
+                        */
                        fprintf(newfd, "%s\t%s\n", mountpoint,
                                translate_opts(shareopts));
+               } else {
+                    /* This code doesn't need to be guarded - except for the 
+                     * extra noise comments it puts into the exports file. */
+                     count = 0; 
+                     strncpy (each, shareopts, sizeof(each)-1);  /* Local copy 
to edit. */
+ 
+                     fprintf(newfd, "#\n#%s\t%s\n", mountpoint, shareopts);    
/* verbose: show originale */
+ 
+                     for (cur=each, next = index (each, ';');  next != (char 
*) NULL; 
+                                          next = index(next+1, ';')) {
+                           /* If we blow up writing the new exports file, 
don't use it! */
+                           if (ferror(newfd)) {
+                               error = ferror(newfd);
+                               goto out;
+                           }
+ 
+                           *next = '\0';  /* Clobber the ';' */
+ 
+                           /* Skip leading whitespace. */
+                           while (*cur && isspace(*cur)) {
+                               cur ++;
+                           }
+                           /* If there is anything left, use it - if it isn't 
a comment. */
+                           if (*cur && (*cur != '#'))  {
+                               fprintf(newfd, "%s\t%s\n", mountpoint, 
+                                        translate_opts(cur));
+                               count ++;       /* Count only mountpoints */
+                           }
+ 
+                           cur = next + 1;  /* Point past the ';' we found. */
+                     }
+                     
+                     /* If anything is left, run it out too. */
+                     if (*cur) {
+                           /* Skip leading whitespace. */
+                           while (*cur && isspace(*cur)) {
+                               cur ++;
+                           }
+                           if (*cur && (*cur != '#')) {
+                               fprintf(newfd, "%s\t%s\n", mountpoint, 
+                                       translate_opts(cur));
+                               count ++;
+                           }
+                     }
+ 
+                     fprintf(newfd, "# %d exports of \"%s\"\n", mountpoint);
+ 
+               } /* multi-valued ';' stuff (with '#'s too.) */
+ 
+               /* If we blew up writing the new exports file, don't use it! */
+               if (ferror(newfd)) {
+                     error = ferror(newfd);
+                     goto out;
                }
+       } /* if (share) */
  
  out:
        if (error != 0)


>Release-Note:
>Audit-Trail:
>Unformatted:
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to