From nobody@FreeBSD.org  Tue Jun 15 15:57:18 2010
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 002891065675
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 15 Jun 2010 15:57:17 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id E19868FC15
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 15 Jun 2010 15:57:17 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o5FFvHbI011643
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 15 Jun 2010 15:57:17 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id o5FFvH4j011637;
	Tue, 15 Jun 2010 15:57:17 GMT
	(envelope-from nobody)
Message-Id: <201006151557.o5FFvH4j011637@www.freebsd.org>
Date: Tue, 15 Jun 2010 15:57:17 GMT
From: "Richard S. Conto" <Richard.Conto@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: ZFS "sharenfs" doesn't allow different "exports" options for different hosts
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         147881
>Category:       kern
>Synopsis:       [zfs] [patch] ZFS "sharenfs" doesn't allow different "exports" options for different hosts
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-fs
>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:  Mon Sep 10 11:50:01 UTC 2012
>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     rsc@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:
Responsible-Changed-From-To: freebsd-bugs->freebsd-fs 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Sun Jul 18 15:41:41 UTC 2010 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=147881 

From: Martin Birgmeier <martin.birgmeier@aon.at>
To: bug-followup@FreeBSD.org, Richard.Conto@gmail.com
Cc:  
Subject: Re: kern/147881: [zfs] [patch] ZFS "sharenfs" doesn't allow different
 "exports" options for different hosts
Date: Fri, 15 Oct 2010 09:15:12 +0200

 Please implement this or a similar patch. I need this in my dual 
 IPv4/IPv6 setup, where it is necessary to have something like
 
 /tank/vol   -network 192.168.0.0 -mask 255.255.0.0
 /tank/vol   -network fec0:0:0:1::/56
 
 in /etc/zfs/exports in order to get both IPv4 and IPv6 clients to work.
 
 Regards,
 
 Martin

From: Richard Conto <Richard.Conto@gmail.com>
To: Martin Birgmeier <martin.birgmeier@aon.at>
Cc: bug-followup@FreeBSD.org,
 Richard Conto <richard.conto@gmail.com>
Subject: Re: kern/147881: [zfs] [patch] ZFS "sharenfs" doesn't allow different "exports" options for different hosts
Date: Thu, 21 Oct 2010 17:10:19 -0400

 My patch is IPv4/IPv6/DNS agnostic - it ought to work either way.  NFSv4 =
 might be a problem due to the syntax differences in /etc/exports =
 (/etc/zfs/exports).
 
 All my patch does is use ';' as a special character to allow multiple =
 values (like you want) for each export.  Each value is prefixed by the =
 mount point and written to /etc/zfs/exports.
 
 
 I'm still running it - but it's for a home file server where I want to =
 restrict "root" access from certain VPNs.  Given that all it does is =
 change the output to /etc/zfs/exports, which is handled by the regular =
 NFS export mechanism, I don't think that there should be any significant =
 difference between home and production/enterprise use - unless NFS =
 exports keel over when there's hundreds of mount points (easy to do with =
 ZFS) rather than tens.  My home set up is exporting only 25 mount =
 points.
 
 --- Richard
 
 
 
 On Oct 15, 2010, at 3:15 AM, Martin Birgmeier wrote:
 
 > Please implement this or a similar patch. I need this in my dual =
 IPv4/IPv6 setup, where it is necessary to have something like
 >=20
 > /tank/vol   -network 192.168.0.0 -mask 255.255.0.0
 > /tank/vol   -network fec0:0:0:1::/56
 >=20
 > in /etc/zfs/exports in order to get both IPv4 and IPv6 clients to =
 work.
 >=20
 > Regards,
 >=20
 > Martin
 

From: Quentin Rameau <quentin.rameau@gmail.com>
To: bug-followup@freebsd.org, Richard.Conto@gmail.com
Cc:  
Subject: Re: kern/147881: [zfs] [patch] ZFS &quot;sharenfs&quot; doesn&#39;t
 allow different &quot;exports&quot; options for different hosts
Date: Tue, 27 Mar 2012 18:07:22 +0200

 --f46d042f92881cc9da04bc3bb206
 Content-Type: text/plain; charset=UTF-8
 
 I made another similar patch which does not include commented lines.
 It's for RELENG_9_0
 
 -- 
 Quentin Rameau
 
 --f46d042f92881cc9da04bc3bb206
 Content-Type: text/x-patch; charset=US-ASCII; name="fsshare.c-multipleexports.patch"
 Content-Disposition: attachment; filename="fsshare.c-multipleexports.patch"
 Content-Transfer-Encoding: base64
 X-Attachment-Id: f_h0b50y1k0
 
 LS0tIHNyYy9jZGRsL2NvbXBhdC9vcGVuc29sYXJpcy9taXNjL2Zzc2hhcmUuYy5vcmlnCTIwMTIt
 MDMtMjcgMTQ6MjM6MDkuNTI4NTU5NDUzICswMjAwCisrKyBzcmMvY2RkbC9jb21wYXQvb3BlbnNv
 bGFyaXMvbWlzYy9mc3NoYXJlLmMJMjAxMi0wMy0yNyAxNzoyODoyNi42OTA1NjUyMzggKzAyMDAK
 QEAgLTE1MSw3ICsxNTEsOCBAQAogICAgIGludCBzaGFyZSkKIHsKIAljaGFyIHRtcGZpbGVbUEFU
 SF9NQVhdOwotCWNoYXIgKmxpbmU7CisJY2hhciBvbGRvcHRzW09QVFNTSVpFXTsKKwljaGFyICps
 aW5lLCAqcywgKmV4cG9ydDsKIAlGSUxFICpuZXdmZCwgKm9sZGZkOwogCWludCBmZCwgZXJyb3I7
 CiAKQEAgLTIxMSw4ICsyMTIsMTQgQEAKIAkJZ290byBvdXQ7CiAJfQogCWlmIChzaGFyZSkgewot
 CQlmcHJpbnRmKG5ld2ZkLCAiJXNcdCVzXG4iLCBtb3VudHBvaW50LAotCQkgICAgdHJhbnNsYXRl
 X29wdHMoc2hhcmVvcHRzKSk7CisJCXN0cmxjcHkob2xkb3B0cywgc2hhcmVvcHRzLCBzaXplb2Yo
 b2xkb3B0cykpOworCQlzID0gb2xkb3B0czsKKwkJd2hpbGUgKChleHBvcnQgPSBzdHJzZXAoJnMs
 ICI7IikpICE9IE5VTEwpIHsKKwkJCWlmIChleHBvcnRbMF0gPT0gJ1wwJykKKwkJCQljb250aW51
 ZTsKKwkJCWZwcmludGYobmV3ZmQsICIlc1x0JXNcbiIsIG1vdW50cG9pbnQsCisJCQkgICAgdHJh
 bnNsYXRlX29wdHMoZXhwb3J0KSk7CisJCX0KIAl9CiAKIG91dDoK
 --f46d042f92881cc9da04bc3bb206--

From: =?iso-8859-2?Q?Radek_Krej=E8a?= <radek.krejca@starnet.cz>
To: "'bug-followup@FreeBSD.org'" <bug-followup@FreeBSD.org>,
	"'Richard.Conto@gmail.com'" <Richard.Conto@gmail.com>
Cc:  
Subject: Re: kern/147881: [zfs] [patch] ZFS &quot;sharenfs&quot; doesn&#39;t
 allow different &quot;exports&quot; options for different hosts
Date: Fri, 17 Aug 2012 13:14:31 +0200

 Thank you very much for patch, is there any time perspective of aplying thi=
 s patch (or possibility) to system?
 
 Richard, your patch has a little bug, if there is - in the hostname, it is =
 expanded as whitespace and throw mistake to log.
 
 Radek

From: Richard Conto <richard.conto@gmail.com>
To: =?utf-8?Q?Radek_Krej=C4=8Da?= <radek.krejca@starnet.cz>
Cc: Richard Conto <Richard.Conto@gmail.com>,
 "'bug-followup@FreeBSD.org'" <bug-followup@FreeBSD.org>
Subject: Re: kern/147881: [zfs] [patch] ZFS &quot;sharenfs&quot; doesn&#39;t allow different &quot;exports&quot; options for different hosts
Date: Fri, 17 Aug 2012 14:58:02 -0400

 On Aug 17, 2012, at 7:14 AM, Radek Krej=E8a wrote:
 
 > Thank you very much for patch, is there any time perspective of =
 aplying this patch (or possibility) to system?
 >=20
 > Richard, your patch has a little bug, if there is - in the hostname, =
 it is expanded as whitespace and throw mistake to log.
 >=20
 > Radek
 
 I've just applied my patch to FreeBSD-9 - and was thinking of expanding =
 it in order to be able to deal with NFS-V4 exports.
 (I was thinking of expanding '%f' as the filesystem name so the =
 filesystem name can occur in any part of the string.)
 
 Do you mean that if there is a "-" (hyphen) in the hostname, such as =
 "my-nfs-clients.local.com"), it gets mangled?  I'll look at that.=

From: Martin Matuska <mm@FreeBSD.org>
To: bug-followup@FreeBSD.org, Richard.Conto@gmail.com
Cc:  
Subject: Re: kern/147881: [zfs] [patch] ZFS &quot;sharenfs&quot; doesn&#39;t
 allow different &quot;exports&quot; options for different hosts
Date: Thu, 06 Sep 2012 15:36:13 +0200

 The purpose of the sharenfs property is not to completely replace
 /etc/exports.
 What we have is just a tricky workaround that populates /etc/zfs/exports.
 T
 he commands to NFS-share filesystems on illumos are different and our
 options are mostly incompatible with illumos.
 So you e.g. sharenfs="-maproot=root" is invalid if imported on a
 Openindiana system.
 
 Have you considered using just /etc/exports for more-complex configurations?
 
 -- 
 Martin Matuska
 FreeBSD committer
 http://blog.vx.sk
 

From: Richard Conto <richard.conto@gmail.com>
To: Martin Matuska <mm@FreeBSD.org>
Cc: Richard Conto <Richard.Conto@gmail.com>,
 bug-followup@FreeBSD.org
Subject: Re: kern/147881: [zfs] [patch] ZFS &quot;sharenfs&quot; doesn&#39;t allow different &quot;exports&quot; options for different hosts
Date: Fri, 7 Sep 2012 14:05:39 -0400

 On Sep 6, 2012, at 9:36 AM, Martin Matuska wrote:
 
 > The purpose of the sharenfs property is not to completely replace
 > /etc/exports.
 > What we have is just a tricky workaround that populates =
 /etc/zfs/exports.
 > T
 > he commands to NFS-share filesystems on illumos are different and our
 > options are mostly incompatible with illumos.
 > So you e.g. sharenfs=3D"-maproot=3Droot" is invalid if imported on a
 > Openindiana system.
 >=20
 > Have you considered using just /etc/exports for more-complex =
 configurations?
 
 Yes. It doesn't scale - and scaling is the whole purpose of NFS.  It =
 also makes it difficult for distributed management of access rights to =
 end-user NFS exports.
 
 I wouldn't mind using a FreeBSD specific attribute to populate =
 /etc/zfs/exports with FreeBSD specific values such as is used for =
 swapping to ZFS.  Merging the two different attributes would either be =
 tricky, or the use of the FreeBSD one should cause "sharenfs" to be =
 ignored entirely.
 
 
 > --=20
 > Martin Matuska
 > FreeBSD committer
 > http://blog.vx.sk
 >=20
 

From: Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>
To: bug-followup@FreeBSD.org
Cc: Richard Conto <richard.conto@gmail.com>,
	Martin Matuska <mm@FreeBSD.org>
Subject: Re: kern/147881: [zfs] [patch] ZFS "sharenfs" doesn't allow
 different "exports" options for different hosts
Date: Mon, 10 Sep 2012 14:40:08 +0300

 On Fri, Sep 07, 2012 at 06:10:07PM +0000, Richard Conto wrote:
 >  
 >  > The purpose of the sharenfs property is not to completely replace
 >  > /etc/exports.
 >  > What we have is just a tricky workaround that populates =
 >  /etc/zfs/exports.
 >  > T
 >  > he commands to NFS-share filesystems on illumos are different and our
 >  > options are mostly incompatible with illumos.
 >  > So you e.g. sharenfs=3D"-maproot=3Droot" is invalid if imported on a
 >  > Openindiana system.
 >  >=20
 >  > Have you considered using just /etc/exports for more-complex =
 >  configurations?
 >  
 >  Yes. It doesn't scale - and scaling is the whole purpose of NFS.  It =
 >  also makes it difficult for distributed management of access rights to =
 >  end-user NFS exports.
 >  
 >  I wouldn't mind using a FreeBSD specific attribute to populate =
 >  /etc/zfs/exports with FreeBSD specific values such as is used for =
 >  swapping to ZFS.  Merging the two different attributes would either be =
 >  tricky, or the use of the FreeBSD one should cause "sharenfs" to be =
 >  ignored entirely.
 
 This is a limitation of exports(5) format, that does not allow to specify
 all settings for one file system in one line.  When I had similar task
 I allowed to redefine options in one line, so address specifications can
 inherit already specified settings and can get changed or new settings.
 
 For example: /fs -ro -mapall user1 host1 -mapall user2 host2 host3 -rw host4
 
 Here, /fs is exported read-only for host{1,2,3} and read-write for host4,
 all users are mapped to user1 for host1 and all users are mapped to user2
 for host{2,3,4}.
 
 More information about format of NFS exports settings that I propose
 is available here:
 
 http://nfse.sourceforge.net/nfs.exports.5.html
>Unformatted:
