From owner-freebsd-bugs@FreeBSD.ORG Tue Jun 15 16:00:02 2010 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4A3391065674 for ; Tue, 15 Jun 2010 16:00:02 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 038CD8FC17 for ; Tue, 15 Jun 2010 16:00:02 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id o5FG01HM004873 for ; Tue, 15 Jun 2010 16:00:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id o5FG01Uo004872; Tue, 15 Jun 2010 16:00:01 GMT (envelope-from gnats) Resent-Date: Tue, 15 Jun 2010 16:00:01 GMT Resent-Message-Id: <201006151600.o5FG01Uo004872@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, "Richard S. Conto" Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 002891065675 for ; 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 ; 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 ; 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" To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: kern/147881: ZFS "sharenfs" doesn't allow different "exports" options for different hosts X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Jun 2010 16:00:02 -0000 >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 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" ' 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) ... ... (2) ... ; ... ... ; ... ... ... Empty sets of '... ...' are allowed (i.e.: multiple ';'s with only whitespace between them. Comments (with a leading '#') for '... ...' 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 #include #include + #include #include #include #include *************** *** 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: