changeset 3957:86c9dda5df37

PSARC/2007/052 In-kernel Sharetab 6371468 /etc/dfs/sharetab should be a mntfs style file
author th199096
date Mon, 02 Apr 2007 21:38:04 -0700
parents ea75466401e7
children a3a5c9bc5256
files usr/src/cmd/dfs.cmds/sharemgr/commands.c usr/src/cmd/fs.d/Makefile usr/src/cmd/fs.d/ctfs/mount.c usr/src/cmd/fs.d/nfs/lib/sharetab.c usr/src/cmd/fs.d/nfs/lib/sharetab.h usr/src/cmd/fs.d/nfs/mountd/exportlist.c usr/src/cmd/fs.d/nfs/mountd/mountd.c usr/src/cmd/fs.d/nfs/mountd/netgroup.c usr/src/cmd/fs.d/nfs/mountd/nfsauth.c usr/src/cmd/fs.d/nfs/mountd/rmtab.c usr/src/cmd/fs.d/nfs/share/Makefile usr/src/cmd/fs.d/nfs/svc/nfs-server usr/src/cmd/fs.d/objfs/mount.c usr/src/cmd/fs.d/sharefs/Makefile usr/src/cmd/fs.d/sharefs/mount.c usr/src/cmd/fs.d/umount.c usr/src/cmd/initpkg/vfstab.sh usr/src/cmd/rexd/sharetab.c usr/src/cmd/rexd/sharetab.h usr/src/cmd/rexd/where.c usr/src/cmd/truss/systable.c usr/src/lib/common/inc/c_synonyms.h usr/src/lib/libc/amd64/Makefile usr/src/lib/libc/i386/Makefile.com usr/src/lib/libc/inc/synonyms.h usr/src/lib/libc/port/mapfile-vers usr/src/lib/libc/port/sys/sharefs.c usr/src/lib/libc/sparc/Makefile usr/src/lib/libc/sparcv9/Makefile usr/src/lib/libfsmgt/common/fs_shares.c usr/src/lib/libproc/common/proc_names.c usr/src/lib/libshare/common/libsharecore.c usr/src/pkgdefs/SUNWckr/prototype_i386 usr/src/pkgdefs/SUNWckr/prototype_sparc usr/src/pkgdefs/SUNWcsr/prototype_com usr/src/pkgdefs/SUNWcsu/prototype_com usr/src/pkgdefs/SUNWhea/prototype_com usr/src/pkgdefs/common_files/i.vfstab usr/src/tools/scripts/bfu.sh usr/src/uts/Makefile usr/src/uts/README usr/src/uts/common/Makefile.files usr/src/uts/common/Makefile.rules usr/src/uts/common/fs/gfs.c usr/src/uts/common/fs/sharefs/sharefs_vfsops.c usr/src/uts/common/fs/sharefs/sharefs_vnops.c usr/src/uts/common/fs/sharefs/sharetab.c usr/src/uts/common/fs/vfs.c usr/src/uts/common/os/sysent.c usr/src/uts/common/os/vfs_conf.c usr/src/uts/common/sharefs/Makefile usr/src/uts/common/sharefs/share.h usr/src/uts/common/sharefs/sharefs.h usr/src/uts/common/sharefs/sharetab.h usr/src/uts/common/sys/gfs.h usr/src/uts/common/sys/mntent.h usr/src/uts/common/sys/syscall.h usr/src/uts/intel/Makefile.intel.shared usr/src/uts/intel/os/name_to_sysnum usr/src/uts/intel/sharefs/Makefile usr/src/uts/sparc/Makefile.sparc.shared usr/src/uts/sparc/os/name_to_sysnum usr/src/uts/sparc/sharefs/Makefile
diffstat 63 files changed, 2312 insertions(+), 611 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/dfs.cmds/sharemgr/commands.c	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/cmd/dfs.cmds/sharemgr/commands.c	Mon Apr 02 21:38:04 2007 -0700
@@ -3164,40 +3164,6 @@
 }
 
 /*
- * check_sharetab()
- *
- * Checks to see if the /etc/dfs/sharetab file is stale (exists from
- * before the current boot). If it is, truncate it since nothing is
- * really shared.
- */
-
-static void
-check_sharetab()
-{
-	int fd;
-	struct utmpx *utmpxp;
-	struct stat st;
-
-	fd = open(SA_LEGACY_SHARETAB, O_RDWR);
-	if (fd >= 0) {
-		/*
-		 * Attempt to get a lock on the file. Whgen we get
-		 * one, then check to see if it is older than the boot
-		 * time. Truncate if older than boot.
-		 */
-	    (void) lockf(fd, F_LOCK, 0);
-	    if ((fstat(fd, &st) == 0) && /* does sharetab exist? */
-		(utmpxp = getutxent()) != NULL && /* does utmpx exist? */
-			(utmpxp->ut_xtime > st.st_mtime)) /* sharetab older? */
-		(void) ftruncate(fd, 0);
-
-	    (void) lockf(fd, F_ULOCK, 0);
-	    (void) close(fd);
-	    endutxent();
-	}
-}
-
-/*
  * sa_start_group(flags, argc, argv)
  *
  * Implements the start command.
@@ -3252,8 +3218,6 @@
 	} else {
 		sa_group_t group;
 
-		check_sharetab();
-
 		if (!all) {
 		    while (optind < argc) {
 			group = sa_get_group(handle, argv[optind]);
--- a/usr/src/cmd/fs.d/Makefile	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/cmd/fs.d/Makefile	Mon Apr 02 21:38:04 2007 -0700
@@ -45,7 +45,8 @@
 include ../Makefile.cmd
 
 SUBDIR1= lofs zfs
-SUBDIR2= dev fd pcfs nfs hsfs proc ctfs udfs ufs tmpfs cachefs autofs mntfs objfs
+SUBDIR2= dev fd pcfs nfs hsfs proc ctfs udfs ufs tmpfs cachefs \
+		autofs mntfs objfs sharefs
 SUBDIRS= $(SUBDIR1) $(SUBDIR2)
 I18NDIRS= $(SUBDIR2)
 
--- a/usr/src/cmd/fs.d/ctfs/mount.c	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/cmd/fs.d/ctfs/mount.c	Mon Apr 02 21:38:04 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -39,9 +38,11 @@
 #include <sys/signal.h>
 #include <sys/stat.h>
 #include <fslib.h>
+#include <locale.h>
 
 #define	RET_OK		0
 #define	RET_ERR		33
+#define	EXIT_MAGIC	2
 
 static void usage(void);
 
@@ -64,20 +65,39 @@
 	char *mountp;		/* Entity being mounted on */
 	char *savedoptbuf;
 	char *myname;
-	char typename[64];
+	char *typename;
 	int flags = 0;
-	int errflag = 0;
-	int qflg = 0;
+	int error_flag = 0;
+	int q_flag = 0;
+
+	int len;
+
+	(void) setlocale(LC_ALL, "");
+
+#if !defined(TEXT_DOMAIN)
+#define	TEXT_DOMAIN "SYS_TEST"
+#endif
+	(void) textdomain(TEXT_DOMAIN);
+
 
 	myname = strrchr(argv[0], '/');
-	myname = myname ? myname+1 : argv[0];
-	(void) snprintf(typename, sizeof (typename), "%s %s", fstype, myname);
+	myname = myname ? myname + 1 : argv[0];
+
+	len = strlen(fstype) + 1 + strlen(myname);
+	typename = malloc(len + 1);
+	if (!typename) {
+		(void) fprintf(stderr, gettext("%s: out of memory\n"),
+		    myname);
+		return (EXIT_MAGIC);
+	}
+
+	(void) snprintf(typename, len, "%s %s", fstype, myname);
 	argv[0] = typename;
 
 	while ((c = getopt(argc, argv, "o:rmOq")) != EOF) {
 		switch (c) {
 		case '?':
-			errflag++;
+			error_flag = 1;
 			break;
 
 		case 'o':
@@ -86,7 +106,8 @@
 				(void) fprintf(stderr,
 				    gettext("%s: Invalid argument: %s\n"),
 				    myname, optarg);
-				return (2);
+				free(typename);
+				return (EXIT_MAGIC);
 			}
 			optsize = strlen(optbuf);
 			break;
@@ -102,14 +123,14 @@
 			break;
 
 		case 'q':
-			qflg = 1;
+			q_flag = 1;
 			break;
 
 		default:
 			usage();
 		}
 	}
-	if ((argc - optind != 2) || errflag) {
+	if ((argc - optind != 2) || error_flag) {
 		usage();
 	}
 	special = argv[argc - 2];
@@ -118,24 +139,27 @@
 	if ((savedoptbuf = strdup(optbuf)) == NULL) {
 		(void) fprintf(stderr, gettext("%s: out of memory\n"),
 		    myname);
-		exit(2);
+		free(typename);
+		exit(EXIT_MAGIC);
 	}
 	if (mount(special, mountp, flags | MS_OPTIONSTR, fstype, NULL, 0,
 	    optbuf, MAX_MNTOPT_STR)) {
 		(void) fprintf(stderr, "mount: ");
 		perror(special);
+		free(typename);
 		exit(RET_ERR);
 	}
-	if (optsize && !qflg)
+	if (optsize && !q_flag)
 		cmp_requested_to_actual_options(savedoptbuf, optbuf,
 		    special, mountp);
-	return (0);
+	free(typename);
+	return (RET_OK);
 }
 
-void
+static void
 usage(void)
 {
 	(void) fprintf(stderr,
-	    "Usage: mount [-Ormq] [-o options] special mountpoint\n");
+	    gettext("Usage: mount [-Ormq] [-o options] special mountpoint\n"));
 	exit(RET_ERR);
 }
--- a/usr/src/cmd/fs.d/nfs/lib/sharetab.c	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/cmd/fs.d/nfs/lib/sharetab.c	Mon Apr 02 21:38:04 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 1999 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -38,10 +38,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <sharefs/share.h>
 #include "sharetab.h"
 
-static int logging_specified(char *);
-
 /*
  * Get an entry from the share table.
  * There should be at least 4 fields:
@@ -56,12 +55,10 @@
  *	< 0  error
  */
 int
-getshare(fd, shp)
-	FILE *fd;
-	struct share **shp;
+getshare(FILE *fd, share_t **shp)
 {
 	static char *line = NULL;
-	static struct share *sh = NULL;
+	static share_t *sh = NULL;
 	char *p;
 	char *lasts;
 	char *w = " \t";
@@ -72,7 +69,7 @@
 			return (-1);
 	}
 	if (sh == NULL) {
-		sh = (struct share *)malloc(sizeof (*sh));
+		sh = (share_t *)malloc(sizeof (*sh));
 		if (sh == NULL)
 			return (-1);
 	}
@@ -102,124 +99,15 @@
 	return (1);
 }
 
-/*
- * Append an entry to the sharetab file.
- */
-int
-putshare(fd, sh)
-	FILE *fd;
-	struct share *sh;
+share_t *
+sharedup(share_t *sh)
 {
-	int r;
-
-	if (fseek(fd, 0L, 2) < 0)
-		return (-1);
-
-	r = fprintf(fd, "%s\t%s\t%s\t%s\t%s\n",
-		sh->sh_path,
-		sh->sh_res,
-		sh->sh_fstype,
-		sh->sh_opts,
-		sh->sh_descr);
-	return (r);
-}
-
-/*
- * The entry corresponding to path is removed from the
- * sharetab file.  The file is assumed to be locked.
- * Read the entries into a linked list of share structures
- * minus the entry to be removed.  Then truncate the sharetab
- * file and write almost all of it back to the file from the
- * linked list.
- *
- * If logging information is requested then 'logging' is set
- * to non-zero if the entry is shared with logging enabled.
- *
- * Note: The file is assumed to be locked.
- */
-int
-remshare(fd, path, logging)
-	FILE *fd;
-	char *path;
-	int *logging;
-{
-	struct share *sh_tmp;
-	struct shl {			/* the linked list */
-		struct shl   *shl_next;
-		struct share *shl_sh;
-	};
-	struct shl *shl_head = NULL;
-	struct shl *shl, *prev, *next;
-	int res, remcnt;
+	share_t *nsh;
 
-	rewind(fd);
-	remcnt = 0;
-	shl = NULL;
-	while ((res = getshare(fd, &sh_tmp)) > 0) {
-		if (strcmp(path, sh_tmp->sh_path) == 0 ||
-		    strcmp(path, sh_tmp->sh_res)  == 0) {
-			remcnt++;
-			if (logging != NULL)
-				*logging = logging_specified(sh_tmp->sh_opts);
-		} else {
-			prev = shl;
-			shl = (struct shl *)malloc(sizeof (*shl));
-			if (shl == NULL) {
-				res = -1;
-				goto dealloc;
-			}
-			if (shl_head == NULL)
-				shl_head = shl;
-			else
-				prev->shl_next = shl;
-			shl->shl_next = NULL;
-			shl->shl_sh = sharedup(sh_tmp);
-			if (shl->shl_sh == NULL) {
-				res = -3;
-				goto dealloc;
-			}
-		}
-	}
-	if (res < 0)
-		goto dealloc;
-	if (remcnt == 0) {
-		res = 1;	/* nothing removed */
-		goto dealloc;
-	}
-
-	if (ftruncate(fileno(fd), 0) < 0) {
-		res = -2;
-		goto dealloc;
-	}
-
-	for (shl = shl_head; shl; shl = shl->shl_next)
-		putshare(fd, shl->shl_sh);
-	res = 1;
-
-dealloc:
-	for (shl = shl_head; shl; shl = next) {
-		/*
-		 * make sure we don't reference sharefree with NULL shl->shl_sh
-		 */
-		if (shl->shl_sh != NULL)
-			sharefree(shl->shl_sh);
-		next = shl->shl_next;
-		free(shl);
-	}
-	return (res);
-}
-
-struct share *
-sharedup(sh)
-	struct share *sh;
-{
-	struct share *nsh;
-
-	nsh = (struct share *)malloc(sizeof (*nsh));
+	nsh = (share_t *)calloc(1, sizeof (*nsh));
 	if (nsh == NULL)
 		return (NULL);
 
-	(void) memset((char *)nsh, 0, sizeof (*nsh));
 	if (sh->sh_path) {
 		nsh->sh_path = strdup(sh->sh_path);
 		if (nsh->sh_path == NULL)
@@ -254,8 +142,7 @@
 }
 
 void
-sharefree(sh)
-	struct share *sh;
+sharefree(share_t *sh)
 {
 	if (sh->sh_path != NULL)
 		free(sh->sh_path);
@@ -276,8 +163,7 @@
  * free returned value.
  */
 char *
-getshareopt(optlist, opt)
-	char *optlist, *opt;
+getshareopt(char *optlist, char *opt)
 {
 	char *p, *pe;
 	char *b;
@@ -307,29 +193,3 @@
 	free(bb);
 	return (val);
 }
-
-/*
- * Return 1 if the "log" option was specified in the optlist.
- * Return 0 otherwise.
- */
-static int
-logging_specified(optlist)
-	char *optlist;
-{
-	char *p;
-	char *b, *bb, *lasts;
-	int specified = 0;
-
-	b = bb = strdup(optlist);
-	if (b == NULL)
-		return (0);
-
-	while (p = (char *)strtok_r(b, ",", &lasts)) {
-		b = NULL;
-		if (strncmp(p, "log", 3) == 0)
-			specified++;
-	}
-
-	free(bb);
-	return (specified ? 1 : 0);
-}
--- a/usr/src/cmd/fs.d/nfs/lib/sharetab.h	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/cmd/fs.d/nfs/lib/sharetab.h	Mon Apr 02 21:38:04 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -32,6 +32,10 @@
  * under license from the Regents of the University of California.
  */
 
+/*
+ * Note: <sharefs/share.h> must be included before this file.
+ */
+
 #ifndef _SHARETAB_H
 #define	_SHARETAB_H
 
@@ -41,22 +45,6 @@
 extern "C" {
 #endif
 
-struct share {
-	char *sh_path;
-	char *sh_res;
-	char *sh_fstype;
-	char *sh_opts;
-	char *sh_descr;
-};
-
-struct sh_list {		/* cached share list */
-	struct sh_list *shl_next;
-	struct share   *shl_sh;
-};
-
-#define	SHARETAB	"/etc/dfs/sharetab"
-#define	MAXBUFSIZE	65536
-
 #define	SHOPT_RO	"ro"
 #define	SHOPT_RW	"rw"
 
@@ -77,12 +65,10 @@
 #define	SHOPT_VOLFH	"volfh"
 #endif /* VOLATILE_FH_TEST */
 
-int		getshare(FILE *, struct share **);
-int		putshare(FILE *, struct share *);
-int		remshare(FILE *, char *, int *);
-char 		*getshareopt(char *, char *);
-struct share	*sharedup(struct share *);
-void		sharefree(struct share *);
+int		getshare(FILE *, share_t **);
+char		*getshareopt(char *, char *);
+share_t		*sharedup(share_t *);
+void		sharefree(share_t *);
 
 #ifdef __cplusplus
 }
--- a/usr/src/cmd/fs.d/nfs/mountd/exportlist.c	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/cmd/fs.d/nfs/mountd/exportlist.c	Mon Apr 02 21:38:04 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -19,11 +18,10 @@
  *
  * CDDL HEADER END
  */
+
 /*
- *	exportlist.c
- *
- *	Copyright (c) 1988-1995,1998,1999 Sun Microsystems Inc.
- *	All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
  */
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -46,6 +44,8 @@
 #include <locale.h>
 #include <unistd.h>
 #include <thread.h>
+#include <sharefs/share.h>
+#include <sharefs/sharetab.h>
 #include "../lib/sharetab.h"
 #include "mountd.h"
 
--- a/usr/src/cmd/fs.d/nfs/mountd/mountd.c	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/cmd/fs.d/nfs/mountd/mountd.c	Mon Apr 02 21:38:04 2007 -0700
@@ -18,6 +18,7 @@
  *
  * CDDL HEADER END
  */
+
 /*
  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
@@ -69,6 +70,8 @@
 #include <rpcsvc/daemon_utils.h>
 #include <deflt.h>
 #include "../../fslib.h"
+#include <sharefs/share.h>
+#include <sharefs/sharetab.h>
 #include "../lib/sharetab.h"
 #include "mountd.h"
 
@@ -1946,7 +1949,12 @@
 		return;
 	}
 
-	f = fopen(SHARETAB, "r+");
+	/*
+	 * Note that since the sharetab is now in memory
+	 * and a snapshot is taken, we no longer have to
+	 * lock the file.
+	 */
+	f = fopen(SHARETAB, "r");
 	if (f == NULL) {
 		syslog(LOG_ERR, "Cannot open %s: %m", SHARETAB);
 		(void) rw_unlock(&sharetab_lock);
@@ -1954,17 +1962,6 @@
 	}
 
 	/*
-	 * Lock the file so that unshare can't
-	 * truncate it while we're reading
-	 */
-	if (lockf(fileno(f), F_LOCK, 0L) < 0) {
-		syslog(LOG_ERR, "Cannot lock %s: %m", SHARETAB);
-		(void) rw_unlock(&sharetab_lock);
-		(void) fclose(f);
-		return;
-	}
-
-	/*
 	 * Once we are sure /etc/dfs/sharetab has been
 	 * modified, flush netgroup cache entries.
 	 */
--- a/usr/src/cmd/fs.d/nfs/mountd/netgroup.c	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/cmd/fs.d/nfs/mountd/netgroup.c	Mon Apr 02 21:38:04 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -19,10 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * netgroup.c
- *
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -50,6 +48,7 @@
 #include <locale.h>
 #include <unistd.h>
 #include <thread.h>
+#include <sharefs/share.h>
 #include "../lib/sharetab.h"
 #include "mountd.h"
 
--- a/usr/src/cmd/fs.d/nfs/mountd/nfsauth.c	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/cmd/fs.d/nfs/mountd/nfsauth.c	Mon Apr 02 21:38:04 2007 -0700
@@ -18,8 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -46,6 +47,7 @@
 #include <thread.h>
 #include <netdir.h>
 #include <nfs/auth.h>
+#include <sharefs/share.h>
 #include "../lib/sharetab.h"
 #include "mountd.h"
 
--- a/usr/src/cmd/fs.d/nfs/mountd/rmtab.c	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/cmd/fs.d/nfs/mountd/rmtab.c	Mon Apr 02 21:38:04 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -19,10 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * rmtab.c
- *
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -50,6 +48,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <sharefs/share.h>
 #include "../lib/sharetab.h"
 #include "hashset.h"
 #include "mountd.h"
--- a/usr/src/cmd/fs.d/nfs/share/Makefile	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/cmd/fs.d/nfs/share/Makefile	Mon Apr 02 21:38:04 2007 -0700
@@ -21,13 +21,14 @@
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
 
 FSTYPE=		nfs
-OTHERINSTALL=	$(ROOTETC)/dfs/fstypes
+OTHERINSTALL=	$(ROOTETC)/dfs/fstypes $(ROOTETC)/dfs/sharetab
+SHARETAB=	sharetab
 
 include		../../Makefile.fstype
 
@@ -35,6 +36,16 @@
 $(ROOTETC)/dfs/fstypes :=	OWNER= root
 $(ROOTETC)/dfs/fstypes :=	GROUP= root
 
+$(ROOTETC)/dfs/sharetab :=	FILEMODE= 444
+$(ROOTETC)/dfs/sharetab :=	OWNER= root
+$(ROOTETC)/dfs/sharetab :=	GROUP= root
+
+$(SHARETAB):
+	touch $(SHARETAB)
+
+clean:
+	$(RM) $(SHARETAB)
+
 $(ROOTETC)/dfs/%: %
 	$(INS.file)
 
--- a/usr/src/cmd/fs.d/nfs/svc/nfs-server	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/cmd/fs.d/nfs/svc/nfs-server	Mon Apr 02 21:38:04 2007 -0700
@@ -62,10 +62,6 @@
 		startnfsd=1
 	fi
 
-	# When the system comes up umask is not set; so set the mode now
-
-	[ -f /etc/dfs/sharetab ] && /usr/bin/chmod 644 /etc/dfs/sharetab
-
 	# Options for nfsd are now set in /etc/default/nfs
 	if [ $startnfsd -ne 0 ]; then
 		/usr/lib/nfs/mountd
--- a/usr/src/cmd/fs.d/objfs/mount.c	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/cmd/fs.d/objfs/mount.c	Mon Apr 02 21:38:04 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -39,9 +38,11 @@
 #include <sys/signal.h>
 #include <sys/stat.h>
 #include <fslib.h>
+#include <locale.h>
 
 #define	RET_OK		0
 #define	RET_ERR		33
+#define	EXIT_MAGIC	2
 
 static void usage(void);
 
@@ -64,20 +65,39 @@
 	char *mountp;		/* Entity being mounted on */
 	char *savedoptbuf;
 	char *myname;
-	char typename[64];
+	char *typename;
 	int flags = 0;
-	int errflag = 0;
-	int qflg = 0;
+	int error_flag = 0;
+	int q_flag = 0;
+
+	int len;
+
+	(void) setlocale(LC_ALL, "");
+
+#if !defined(TEXT_DOMAIN)
+#define	TEXT_DOMAIN "SYS_TEST"
+#endif
+	(void) textdomain(TEXT_DOMAIN);
+
 
 	myname = strrchr(argv[0], '/');
-	myname = myname ? myname+1 : argv[0];
-	(void) snprintf(typename, sizeof (typename), "%s %s", fstype, myname);
+	myname = myname ? myname + 1 : argv[0];
+
+	len = strlen(fstype) + 1 + strlen(myname);
+	typename = malloc(len + 1);
+	if (!typename) {
+		(void) fprintf(stderr, gettext("%s: out of memory\n"),
+		    myname);
+		return (EXIT_MAGIC);
+	}
+
+	(void) snprintf(typename, len, "%s %s", fstype, myname);
 	argv[0] = typename;
 
 	while ((c = getopt(argc, argv, "o:rmOq")) != EOF) {
 		switch (c) {
 		case '?':
-			errflag++;
+			error_flag = 1;
 			break;
 
 		case 'o':
@@ -86,7 +106,8 @@
 				(void) fprintf(stderr,
 				    gettext("%s: Invalid argument: %s\n"),
 				    myname, optarg);
-				return (2);
+				free(typename);
+				return (EXIT_MAGIC);
 			}
 			optsize = strlen(optbuf);
 			break;
@@ -102,14 +123,14 @@
 			break;
 
 		case 'q':
-			qflg = 1;
+			q_flag = 1;
 			break;
 
 		default:
 			usage();
 		}
 	}
-	if ((argc - optind != 2) || errflag) {
+	if ((argc - optind != 2) || error_flag) {
 		usage();
 	}
 	special = argv[argc - 2];
@@ -118,24 +139,27 @@
 	if ((savedoptbuf = strdup(optbuf)) == NULL) {
 		(void) fprintf(stderr, gettext("%s: out of memory\n"),
 		    myname);
-		exit(2);
+		free(typename);
+		exit(EXIT_MAGIC);
 	}
 	if (mount(special, mountp, flags | MS_OPTIONSTR, fstype, NULL, 0,
 	    optbuf, MAX_MNTOPT_STR)) {
 		(void) fprintf(stderr, "mount: ");
 		perror(special);
+		free(typename);
 		exit(RET_ERR);
 	}
-	if (optsize && !qflg)
+	if (optsize && !q_flag)
 		cmp_requested_to_actual_options(savedoptbuf, optbuf,
 		    special, mountp);
-	return (0);
+	free(typename);
+	return (RET_OK);
 }
 
-void
+static void
 usage(void)
 {
 	(void) fprintf(stderr,
-	    "Usage: mount [-Ormq] [-o options] special mountpoint\n");
+	    gettext("Usage: mount [-Ormq] [-o options] special mountpoint\n"));
 	exit(RET_ERR);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fs.d/sharefs/Makefile	Mon Apr 02 21:38:04 2007 -0700
@@ -0,0 +1,32 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#ident	"%Z%%M%	%I%	%E% SMI"
+
+FSTYPE=		sharefs
+LIBPROG=	mount
+
+include		../Makefile.fstype
+include		../Makefile.mount
+include		../Makefile.mount.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fs.d/sharefs/mount.c	Mon Apr 02 21:38:04 2007 -0700
@@ -0,0 +1,165 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libintl.h>
+#include <errno.h>
+#include <sys/fstyp.h>
+#include <sys/fsid.h>
+#include <sys/mntent.h>
+#include <sys/mnttab.h>
+#include <sys/mount.h>
+#include <sys/signal.h>
+#include <sys/stat.h>
+#include <fslib.h>
+#include <locale.h>
+
+#define	RET_OK		0
+#define	RET_ERR		33
+#define	EXIT_MAGIC	2
+
+static void usage(void);
+
+static char  optbuf[MAX_MNTOPT_STR] = { '\0', };
+static int   optsize = 0;
+
+static char fstype[] = "sharefs";
+
+/*
+ * usage: mount [-Ormq] [-o options] special mountp
+ *
+ * This mount program is exec'ed by /usr/sbin/mount if '-F sharefs' is
+ * specified.
+ */
+int
+main(int argc, char *argv[])
+{
+	int c;
+	char *special;		/* Entity being mounted */
+	char *mountp;		/* Entity being mounted on */
+	char *savedoptbuf;
+	char *myname;
+	char *typename;
+	int flags = 0;
+	int error_flag = 0;
+	int q_flag = 0;
+
+	int len;
+
+	(void) setlocale(LC_ALL, "");
+
+#if !defined(TEXT_DOMAIN)
+#define	TEXT_DOMAIN "SYS_TEST"
+#endif
+	(void) textdomain(TEXT_DOMAIN);
+
+
+	myname = strrchr(argv[0], '/');
+	myname = myname ? myname + 1 : argv[0];
+
+	len = strlen(fstype) + 1 + strlen(myname);
+	typename = malloc(len + 1);
+	if (!typename) {
+		(void) fprintf(stderr, gettext("%s: out of memory\n"),
+		    myname);
+		return (EXIT_MAGIC);
+	}
+
+	(void) snprintf(typename, len, "%s %s", fstype, myname);
+	argv[0] = typename;
+
+	while ((c = getopt(argc, argv, "o:rmOq")) != EOF) {
+		switch (c) {
+		case '?':
+			error_flag = 1;
+			break;
+
+		case 'o':
+			if (strlcpy(optbuf, optarg, sizeof (optbuf)) >=
+			    sizeof (optbuf)) {
+				(void) fprintf(stderr,
+				    gettext("%s: Invalid argument: %s\n"),
+				    myname, optarg);
+				free(typename);
+				return (EXIT_MAGIC);
+			}
+			optsize = strlen(optbuf);
+			break;
+		case 'O':
+			flags |= MS_OVERLAY;
+			break;
+		case 'r':
+			flags |= MS_RDONLY;
+			break;
+
+		case 'm':
+			flags |= MS_NOMNTTAB;
+			break;
+
+		case 'q':
+			q_flag = 1;
+			break;
+
+		default:
+			usage();
+		}
+	}
+	if ((argc - optind != 2) || error_flag) {
+		usage();
+	}
+	special = argv[argc - 2];
+	mountp = argv[argc - 1];
+
+	if ((savedoptbuf = strdup(optbuf)) == NULL) {
+		(void) fprintf(stderr, gettext("%s: out of memory\n"),
+		    myname);
+		free(typename);
+		exit(EXIT_MAGIC);
+	}
+	if (mount(special, mountp, flags | MS_OPTIONSTR, fstype, NULL, 0,
+	    optbuf, MAX_MNTOPT_STR)) {
+		(void) fprintf(stderr, "mount: ");
+		perror(special);
+		free(typename);
+		exit(RET_ERR);
+	}
+	if (optsize && !q_flag)
+		cmp_requested_to_actual_options(savedoptbuf, optbuf,
+		    special, mountp);
+	free(typename);
+	return (RET_OK);
+}
+
+static void
+usage(void)
+{
+	(void) fprintf(stderr,
+	    gettext("Usage: mount [-Ormq] [-o options] special mountpoint\n"));
+	exit(RET_ERR);
+}
--- a/usr/src/cmd/fs.d/umount.c	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/cmd/fs.d/umount.c	Mon Apr 02 21:38:04 2007 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -52,6 +52,7 @@
 #include	<sys/mount.h>
 #include	<sys/objfs.h>
 #include	"fslib.h"
+#include	<sharefs/share.h>
 
 #define	FS_PATH		"/usr/lib/fs"
 #define	ALT_PATH	"/etc/fs"
@@ -132,6 +133,7 @@
 	"/var",
 	"/var/adm",
 	"/var/run",
+	SHARETAB,
 	NULL
 };
 
--- a/usr/src/cmd/initpkg/vfstab.sh	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/cmd/initpkg/vfstab.sh	Mon Apr 02 21:38:04 2007 -0700
@@ -20,7 +20,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -37,6 +37,7 @@
 /proc		-		/proc		proc	-	no	-
 ctfs		-		/system/contract ctfs	-	no	-
 objfs		-		/system/object	objfs	-	no	-
+sharefs		-		/etc/dfs/sharetab	sharefs	-	no	-
 fd		-		/dev/fd		fd	-	no	-
 swap		-		/tmp		tmpfs	-	yes	-
 ">vfstab
--- a/usr/src/cmd/rexd/sharetab.c	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/cmd/rexd/sharetab.c	Mon Apr 02 21:38:04 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 1989 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -32,14 +32,17 @@
  * under license from the Regents of the University of California.
  */
 
-#ident	"%Z%%M%	%I%	%E% SMI"
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 #include <stdio.h>
 #include <string.h>
+#include <sys/types.h>
+#include <sys/types32.h>
+#include <sharefs/share.h>
 #include "sharetab.h"
 
-static struct share *	sharedup();
-static void		sharefree();
+static share_t	*sharedup();
+static void	sharefree();
 
 /*
  * Get an entry from the share table.
@@ -55,22 +58,20 @@
  *	< 0  error
  */
 int
-getshare(fd, shp)
-	FILE *fd;
-	struct share **shp;
+getshare(FILE *fd, share_t **shp)
 {
 	static char *line = NULL;
-	static struct share *sh = NULL;
+	static share_t *sh = NULL;
 	register char *p;
 	char *w = " \t";
 
 	if (line == NULL) {
-		line = (char *) malloc(BUFSIZ+1);
+		line = (char *)malloc(BUFSIZ+1);
 		if (line == NULL)
 			return (-1);
 	}
 	if (sh == NULL) {
-		sh = (struct share *) malloc(sizeof(*sh));
+		sh = (share_t *)malloc(sizeof (*sh));
 		if (sh == NULL)
 			return (-1);
 	}
@@ -100,110 +101,15 @@
 	return (1);
 }
 
-/*
- * Append an entry to the sharetab file.
- */
-int
-putshare(fd, sh)
-	FILE *fd;
-	struct share *sh;
+static share_t *
+sharedup(share_t *sh)
 {
-	int r;
-
-	if (fseek(fd, 0L, 2) < 0)
-		return (-1);
-
-	r = fprintf(fd, "%s\t%s\t%s\t%s\t%s\n",
-		sh->sh_path,
-		sh->sh_res,
-		sh->sh_fstype,
-		sh->sh_opts,
-		sh->sh_descr);
-	return (r);
-}
-
-/*
- * The entry corresponding to path is removed from the
- * sharetab file.  The file is assumed to be locked.
- * Read the entries into a linked list of share structures
- * minus the entry to be removed.  Then truncate the sharetab
- * file and write almost all of it back to the file from the
- * linked list.
- * Note: The file is assumed to be locked.
- */
-int
-remshare(fd, path)
-	FILE *fd;
-	char *path;
-{
-	struct share *sh_tmp;
-	struct shl {			/* the linked list */
-		struct shl   *shl_next;
-		struct share *shl_sh;
-	};
-	struct shl *shl_head = NULL;
-	struct shl *shl, *prev, *next;
-	int res, remcnt;
+	share_t *nsh;
 
-	rewind(fd);
-	remcnt = 0;
-	while ((res = getshare(fd, &sh_tmp)) > 0) {
-		if (strcmp(path, sh_tmp->sh_path) == 0 ||
-		    strcmp(path, sh_tmp->sh_res)  == 0) {
-			remcnt++;
-		} else {
-			prev = shl;
-			shl = (struct shl *) malloc(sizeof(*shl));
-			if (shl == NULL) {
-				res = -1;
-				goto dealloc;
-			}
-			if (shl_head == NULL)
-				shl_head = shl;
-			else
-				prev->shl_next = shl;
-			shl->shl_next = NULL;
-			shl->shl_sh = sharedup(sh_tmp);
-			if (shl->shl_sh == NULL) {
-				res = -1;
-				goto dealloc;
-			}
-		}
-	}
-	if (res < 0)
-		goto dealloc;
-	if (remcnt == 0) {
-		res = 1;	/* nothing removed */
-		goto dealloc;
-	}
-
-	if (ftruncate(fileno(fd), 0) < 0) {
-		res = -1;
-		goto dealloc;
-	}
-
-	for (shl = shl_head ; shl ; shl = shl->shl_next)
-		putshare(fd, shl->shl_sh);
-	res = 1;
-
-dealloc:
-	for (shl = shl_head ; shl ; shl = next) {
-		sharefree(shl->shl_sh);
-		next = shl->shl_next;
-		free(shl);
-	}
-	return (res);
-}
-
-static struct share *
-sharedup(sh)
-	struct share *sh;
-{
-	struct share *nsh;
-	
-	nsh = (struct share *) malloc(sizeof(*nsh));
+	nsh = (share_t *)calloc(1, sizeof (*nsh));
 	if (nsh == NULL)
 		return (NULL);
+
 	nsh->sh_path = strdup(sh->sh_path);
 	if (nsh->sh_path == NULL)
 		goto alloc_failed;
@@ -227,8 +133,7 @@
 }
 
 static void
-sharefree(sh)
-	struct share *sh;
+sharefree(share_t *sh)
 {
 	if (sh == NULL)
 		return;
@@ -250,8 +155,7 @@
  * in option string "optlist".
  */
 char *
-getshareopt(optlist, opt)
-	char *optlist, *opt;
+getshareopt(char *optlist, char *opt)
 {
 	char *p, *pe;
 	char *b;
--- a/usr/src/cmd/rexd/sharetab.h	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/cmd/rexd/sharetab.h	Mon Apr 02 21:38:04 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 1999 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -32,29 +32,34 @@
  * under license from the Regents of the University of California.
  */
 
-#ident	"%Z%%M%	%I%	%E% SMI"
+/*
+ * Note: <sharefs/share.h> must be included before this file.
+ */
 
-struct share {
-	char *sh_path;
-	char *sh_res;
-	char *sh_fstype;
-	char *sh_opts;
-	char *sh_descr;
-};
+#ifndef	_SHARETAB_H
+#define	_SHARETAB_H
 
-#define SHARETAB  "/etc/dfs/sharetab"
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /* generic options */
-#define SHOPT_RO	"ro"
-#define SHOPT_RW	"rw"
+#define	SHOPT_RO	"ro"
+#define	SHOPT_RW	"rw"
 
 /* options for nfs */
-#define SHOPT_ROOT	"root"
-#define SHOPT_ANON	"anon"
-#define SHOPT_SECURE	"secure"
-#define SHOPT_WINDOW	"window"
+#define	SHOPT_ROOT	"root"
+#define	SHOPT_ANON	"anon"
+#define	SHOPT_SECURE	"secure"
+#define	SHOPT_WINDOW	"window"
 
 int		getshare();
-int		putshare();
-int		remshare();
-char *		getshareopt();
+char		*getshareopt();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_SHARETAB_H */
--- a/usr/src/cmd/rexd/where.c	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/cmd/rexd/where.c	Mon Apr 02 21:38:04 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -18,8 +17,10 @@
  * information: Portions Copyright [yyyy] [name of copyright owner]
  *
  * CDDL HEADER END
- *
- * Copyright 2001 Sun Microsystems, Inc.  All rights reserved.
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -29,7 +30,6 @@
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
-
 #include <netdb.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -45,6 +45,7 @@
 #include <sys/param.h>
 #include <sys/stat.h>
 
+#include <sharefs/share.h>
 #include "sharetab.h"
 
 extern	FILE	*setmntent();
@@ -260,27 +261,12 @@
 *setsharetab()
 {
 	FILE	*f;
-	int	fd;
 
-	/*
-	 * Create the tab file if it does not exist already
-	 */
-	if (access(SHARETAB, F_OK) < 0)	{
-		fd = open(SHARETAB, O_CREAT, 0644);
-		close(fd);
-	}
-	if (access(SHARETAB, W_OK) == 0) {
-		f = fopen(SHARETAB, "r+");
-	} else {
-		f = fopen(SHARETAB, "r");
-	}
+	f = fopen(SHARETAB, "r");
 	if (f == NULL) {
 		return (NULL);
 	}
-	if (lockf(fileno(f), F_LOCK, 0L) < 0) {
-		(void) fclose(f);
-		return (NULL);
-	}
+
 	return (f);
 }
 
--- a/usr/src/cmd/truss/systable.c	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/cmd/truss/systable.c	Mon Apr 02 21:38:04 2007 -0700
@@ -363,7 +363,7 @@
 {"sysconfig",	1, DEC, NOV, CNF},				/* 137 */
 {"adjtime",	2, DEC, NOV, HEX, HEX},				/* 138 */
 {"sysinfo",	3, DEC, NOV, INF, RST, DEC},			/* 139 */
-{ NULL,		8, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX},
+{"sharefs",	3, DEC, NOV, DEC, HEX, DEC},			/* 140 */
 {"seteuid",	1, DEC, NOV, DEC},				/* 141 */
 {"forksys",	2, DEC, NOV, DEC, HHX},				/* 142 */
 {"fork1",	0, DEC, NOV},					/* 143 */
--- a/usr/src/lib/common/inc/c_synonyms.h	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/lib/common/inc/c_synonyms.h	Mon Apr 02 21:38:04 2007 -0700
@@ -815,6 +815,7 @@
 #define	setutxent			_setutxent
 #define	sfconvert			_sfconvert
 #define	sgconvert			_sgconvert
+#define	sharefs				_sharefs
 #define	shmat				_shmat
 #define	shmctl64			_shmctl64
 #define	shmctl				_shmctl
--- a/usr/src/lib/libc/amd64/Makefile	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/lib/libc/amd64/Makefile	Mon Apr 02 21:38:04 2007 -0700
@@ -813,6 +813,7 @@
 	sbrk.o			\
 	semsys.o		\
 	set_errno.o		\
+	sharefs.o		\
 	shmsys.o		\
 	siginterrupt.o		\
 	signal.o		\
--- a/usr/src/lib/libc/i386/Makefile.com	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/lib/libc/i386/Makefile.com	Mon Apr 02 21:38:04 2007 -0700
@@ -852,6 +852,7 @@
 	sbrk.o			\
 	semsys.o		\
 	set_errno.o		\
+	sharefs.o		\
 	shmsys.o		\
 	siginterrupt.o		\
 	signal.o		\
--- a/usr/src/lib/libc/inc/synonyms.h	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/lib/libc/inc/synonyms.h	Mon Apr 02 21:38:04 2007 -0700
@@ -935,6 +935,7 @@
 #define	s_fcntl			_s_fcntl
 #define	sfconvert		_sfconvert
 #define	sgconvert		_sgconvert
+#define	sharefs			_sharefs
 #define	shmat			_shmat
 #define	shmctl64		_shmctl64
 #define	shmctl			_shmctl
--- a/usr/src/lib/libc/port/mapfile-vers	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/lib/libc/port/mapfile-vers	Mon Apr 02 21:38:04 2007 -0700
@@ -99,6 +99,7 @@
 	sem_trywait;
 	sem_unlink;
 	sem_wait;
+	sharefs;
 	shm_open;
 	shm_unlink;
 	sigqueue;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libc/port/sys/sharefs.c	Mon Apr 02 21:38:04 2007 -0700
@@ -0,0 +1,77 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#pragma weak sharefs = _sharefs
+
+#include "synonyms.h"
+#include <sys/types.h>
+#include <sys/types32.h>
+#include <rpc/types.h>
+#include <sys/vfs.h>
+#include <strings.h>
+#include <sharefs/share.h>
+#include <sys/syscall.h>
+
+#include "libc.h"
+
+#define	SMAX(i, j)		\
+	if ((j) > (i)) {	\
+		(i) = (j);	\
+	}
+
+int
+sharefs(enum sharefs_sys_op opcode, struct share *sh)
+{
+	uint32_t		i, j;
+
+	/*
+	 * We need to know the total size of the share
+	 * and also the largest element size. This is to
+	 * get enough buffer space to transfer from
+	 * userland to kernel.
+	 */
+	i = (sh->sh_path ? strlen(sh->sh_path) : 0);
+	sh->sh_size = i;
+
+	j = (sh->sh_res ? strlen(sh->sh_res) : 0);
+	sh->sh_size += j;
+	SMAX(i, j);
+
+	j = (sh->sh_fstype ? strlen(sh->sh_fstype) : 0);
+	sh->sh_size += j;
+	SMAX(i, j);
+
+	j = (sh->sh_opts ? strlen(sh->sh_opts) : 0);
+	sh->sh_size += j;
+	SMAX(i, j);
+
+	j = (sh->sh_descr ? strlen(sh->sh_descr) : 0);
+	sh->sh_size += j;
+	SMAX(i, j);
+
+	return (syscall(SYS_sharefs, opcode, sh, i));
+}
--- a/usr/src/lib/libc/sparc/Makefile	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/lib/libc/sparc/Makefile	Mon Apr 02 21:38:04 2007 -0700
@@ -877,6 +877,7 @@
 	sbrk.o			\
 	semsys.o		\
 	set_errno.o		\
+	sharefs.o		\
 	shmsys.o		\
 	siginterrupt.o		\
 	signal.o		\
--- a/usr/src/lib/libc/sparcv9/Makefile	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/lib/libc/sparcv9/Makefile	Mon Apr 02 21:38:04 2007 -0700
@@ -822,6 +822,7 @@
 	sbrk.o			\
 	semsys.o		\
 	set_errno.o		\
+	sharefs.o		\
 	shmsys.o		\
 	siginterrupt.o		\
 	signal.o		\
--- a/usr/src/lib/libfsmgt/common/fs_shares.c	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/lib/libfsmgt/common/fs_shares.c	Mon Apr 02 21:38:04 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -37,6 +37,7 @@
 #include <thread.h>
 #include <synch.h>
 #include "libfsmgt.h"
+#include <sharefs/share.h>
 #include "sharetab.h"
 
 #define	SECMODES 5
--- a/usr/src/lib/libproc/common/proc_names.c	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/lib/libproc/common/proc_names.c	Mon Apr 02 21:38:04 2007 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -258,7 +258,7 @@
 	"sysconfig",		/* 137 */
 	"adjtime",		/* 138 */
 	"systeminfo",		/* 139 */
-	NULL,			/* 140 */
+	"sharefs",		/* 140 */
 	"seteuid",		/* 141 */
 	NULL,			/* 142 */
 	"fork1",		/* 143 */
--- a/usr/src/lib/libshare/common/libsharecore.c	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/lib/libshare/common/libsharecore.c	Mon Apr 02 21:38:04 2007 -0700
@@ -52,6 +52,7 @@
 #include <signal.h>
 #include <libintl.h>
 
+#include <sharefs/share.h>
 #include "sharetab.h"
 
 #define	DFSTAB_NOTICE_LINES	5
@@ -1187,7 +1188,6 @@
 
 	if ((fp = fopen(SHARETAB, "r")) != NULL) {
 		struct share	*sharetab_entry;
-		(void) lockf(fileno(fp), F_LOCK, 0);
 
 		while (getshare(fp, &sharetab_entry) > 0) {
 		    newp = alloc_sharelist();
@@ -1828,50 +1828,6 @@
 }
 
 /*
- * checkshare(struct share *)
- *
- * If the share to write to sharetab is not present, need to add.  If
- * the share is present, replace if options are different else we want
- * to keep it.
- * Return values:
- *	1 - keep
- *	2 - replace
- * The CHK_NEW value isn't currently returned.
- */
-#define	CHK_NEW		0
-#define	CHK_KEEP	1
-#define	CHK_REPLACE	2
-static int
-checkshare(struct share *sh)
-{
-	xfs_sharelist_t *list, *head;
-	int err;
-	int ret = CHK_NEW;
-
-	head = list = get_share_list(&err);
-	while (list != NULL && ret == CHK_NEW) {
-	    if (strcmp(sh->sh_path, list->path) == 0) {
-		/* Have the same path so check if replace or keep */
-		if (strcmp(sh->sh_opts, list->options) == 0)
-		    ret = CHK_KEEP;
-		else
-		    ret = CHK_REPLACE;
-	    }
-	    list = list->next;
-	}
-	if (head != NULL) {
-	    dfs_free_list(head);
-	}
-	/*
-	 * Just in case it was added by another process after our
-	 * scan, we always replace even if we think it is new.
-	 */
-	if (ret == CHK_NEW)
-	    ret = CHK_REPLACE;
-	return (ret);
-}
-
-/*
  * sa_update_sharetab(share, proto)
  *
  * Update the sharetab file with info from the specified share.
@@ -1881,59 +1837,23 @@
 int
 sa_update_sharetab(sa_share_t share, char *proto)
 {
-	int ret = SA_OK;
-	struct share shtab;
-	char *path;
-	int logging = 0;
-	FILE *sharetab;
-	sigset_t old;
-	int action;
+	int	ret = SA_OK;
+	share_t	sh;
+	char	*path;
 
 	path = sa_get_share_attr(share, "path");
 	if (path != NULL) {
-	    (void) memset(&shtab, '\0', sizeof (shtab));
-	    sharetab = fopen(SA_LEGACY_SHARETAB, "r+");
-	    if (sharetab == NULL) {
-		sharetab = fopen(SA_LEGACY_SHARETAB, "w+");
-	    }
-	    if (sharetab != NULL) {
-		(void) setvbuf(sharetab, NULL, _IOLBF, BUFSIZ * 8);
-		sablocksigs(&old);
+		(void) memset(&sh, '\0', sizeof (sh));
+
 		/*
-		 * Fill in share structure and write it out if the
-		 * share isn't already shared with the same options.
-		 */
-		(void) fillshare(share, proto, &shtab);
-		/*
-		 * If share is new or changed, remove the old,
-		 * otherwise keep it in place since it hasn't changed.
+		 * Fill in share structure and send it to the kernel.
 		 */
-		action = checkshare(&shtab);
-		(void) lockf(fileno(sharetab), F_LOCK, 0);
-		switch (action) {
-		case CHK_REPLACE:
-		    (void) remshare(sharetab, path, &logging);
-		    (void) putshare(sharetab, &shtab);
-		    break;
-		case CHK_KEEP:
-		    /* Don't do anything */
-		    break;
-		}
-		emptyshare(&shtab);
-		(void) fflush(sharetab);
-		(void) lockf(fileno(sharetab), F_ULOCK, 0);
-		(void) fsync(fileno(sharetab));
-		saunblocksigs(&old);
-		(void) fclose(sharetab);
-	    } else {
-		if (errno == EACCES || errno == EPERM) {
-		    ret = SA_NO_PERMISSION;
-		} else {
-		    ret = SA_CONFIG_ERR;
-		}
-	    }
-	    sa_free_attr_string(path);
+		(void) fillshare(share, proto, &sh);
+		(void) sharefs(SHAREFS_ADD, &sh);
+		emptyshare(&sh);
+		sa_free_attr_string(path);
 	}
+
 	return (ret);
 }
 
@@ -1946,36 +1866,21 @@
 int
 sa_delete_sharetab(char *path, char *proto)
 {
-	int ret = SA_OK;
-	int logging = 0;
-	FILE *sharetab;
-	sigset_t old;
-#ifdef lint
-	proto = proto;
-#endif
+	int	ret = SA_OK;
+
+	share_t	sh;
 
-	if (path != NULL) {
-	    sharetab = fopen(SA_LEGACY_SHARETAB, "r+");
-	    if (sharetab == NULL) {
-		sharetab = fopen(SA_LEGACY_SHARETAB, "w+");
-	    }
-	    if (sharetab != NULL) {
-		/* should block keyboard level signals around the lock */
-		sablocksigs(&old);
-		(void) lockf(fileno(sharetab), F_LOCK, 0);
-		ret = remshare(sharetab, path, &logging);
-		(void) fflush(sharetab);
-		(void) lockf(fileno(sharetab), F_ULOCK, 0);
-		(void) fsync(fileno(sharetab));
-		saunblocksigs(&old);
-		(void) fclose(sharetab);
-	    } else {
-		if (errno == EACCES || errno == EPERM) {
-		    ret = SA_NO_PERMISSION;
-		} else {
-		    ret = SA_CONFIG_ERR;
-		}
-	    }
+	/*
+	 * Both the path and the proto are
+	 * keys into the sharetab.
+	 */
+	if (path != NULL && proto != NULL) {
+		(void) memset(&sh, '\0', sizeof (sh));
+		sh.sh_path = path;
+		sh.sh_fstype = proto;
+
+		ret = sharefs(SHAREFS_REMOVE, &sh);
 	}
+
 	return (ret);
 }
--- a/usr/src/pkgdefs/SUNWckr/prototype_i386	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/pkgdefs/SUNWckr/prototype_i386	Mon Apr 02 21:38:04 2007 -0700
@@ -152,6 +152,7 @@
 f none kernel/fs/namefs 755 root sys
 f none kernel/fs/objfs 755 root sys
 f none kernel/fs/procfs 755 root sys
+f none kernel/fs/sharefs 755 root sys
 f none kernel/fs/sockfs 755 root sys
 f none kernel/fs/specfs 755 root sys
 f none kernel/fs/tmpfs 755 root sys
@@ -338,6 +339,7 @@
 f none kernel/fs/amd64/namefs 755 root sys
 f none kernel/fs/amd64/objfs 755 root sys
 f none kernel/fs/amd64/procfs 755 root sys
+f none kernel/fs/amd64/sharefs 755 root sys
 f none kernel/fs/amd64/sockfs 755 root sys
 f none kernel/fs/amd64/specfs 755 root sys
 f none kernel/fs/amd64/tmpfs 755 root sys
--- a/usr/src/pkgdefs/SUNWckr/prototype_sparc	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/pkgdefs/SUNWckr/prototype_sparc	Mon Apr 02 21:38:04 2007 -0700
@@ -150,6 +150,7 @@
 f none kernel/fs/sparcv9/namefs 755 root sys
 f none kernel/fs/sparcv9/objfs 755 root sys
 f none kernel/fs/sparcv9/procfs 755 root sys
+f none kernel/fs/sparcv9/sharefs 755 root sys
 f none kernel/fs/sparcv9/sockfs 755 root sys
 f none kernel/fs/sparcv9/specfs 755 root sys
 f none kernel/fs/sparcv9/tmpfs 755 root sys
--- a/usr/src/pkgdefs/SUNWcsr/prototype_com	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/pkgdefs/SUNWcsr/prototype_com	Mon Apr 02 21:38:04 2007 -0700
@@ -136,6 +136,7 @@
 d none etc/devices 755 root sys
 d none etc/dfs 755 root sys
 e preserve etc/dfs/dfstab 644 root sys
+v preserve etc/dfs/sharetab 444 root root
 e preserve etc/dgroup.tab 444 root sys
 d none etc/dhcp 755 root sys
 e dhcpinittab etc/dhcp/inittab 644 root sys
--- a/usr/src/pkgdefs/SUNWcsu/prototype_com	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/pkgdefs/SUNWcsu/prototype_com	Mon Apr 02 21:38:04 2007 -0700
@@ -402,6 +402,8 @@
 f none usr/lib/fs/objfs/mount 555 root bin
 d none usr/lib/fs/proc 755 root sys
 f none usr/lib/fs/proc/mount 555 root bin
+d none usr/lib/fs/sharefs 755 root sys
+f none usr/lib/fs/sharefs/mount 555 root bin
 d none usr/lib/fs/tmpfs 755 root sys
 f none usr/lib/fs/tmpfs/mount 555 root bin
 d none usr/lib/fs/ufs 755 root sys
--- a/usr/src/pkgdefs/SUNWhea/prototype_com	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/pkgdefs/SUNWhea/prototype_com	Mon Apr 02 21:38:04 2007 -0700
@@ -492,6 +492,10 @@
 f none usr/include/sha1.h 644 root bin
 f none usr/include/sha2.h 644 root bin
 f none usr/include/shadow.h 644 root bin
+d none usr/include/sharefs 755 root bin
+f none usr/include/sharefs/share.h 644 root bin
+f none usr/include/sharefs/sharetab.h 644 root bin
+f none usr/include/sharefs/sharefs.h 644 root bin
 f none usr/include/siginfo.h 644 root bin
 f none usr/include/signal.h 644 root bin
 f none usr/include/smbios.h 644 root bin
--- a/usr/src/pkgdefs/common_files/i.vfstab	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/pkgdefs/common_files/i.vfstab	Mon Apr 02 21:38:04 2007 -0700
@@ -3,9 +3,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,8 +19,9 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -34,6 +34,7 @@
 LN_DEVFS="/devices	-	/devices	devfs	-	no	-"
 LN_CTFS="ctfs\t\t-	/system/contract	ctfs	-	no	-"
 LN_OBJFS="objfs\t\t-	/system/object	objfs	-	no	-"
+LN_SHAREFS="sharefs\t\t-	/etc/dfs/sharetab	sharefs	-	no	-"
 
 missing()
 {
@@ -58,6 +59,9 @@
 		if missing $dst /system/object; then
 			echo "$LN_OBJFS" >> $dst
 		fi
+		if missing $dst /etc/dfs/sharetab; then
+			echo "$LN_SHAREFS" >> $dst
+		fi
 	fi
 done
 exit 0
--- a/usr/src/tools/scripts/bfu.sh	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/tools/scripts/bfu.sh	Mon Apr 02 21:38:04 2007 -0700
@@ -4143,6 +4143,7 @@
 		test -h platform/$archive && rm platform/$archive
 		if [ $base = root ]; then
 			exclude="-f dev/fd home proc etc/mnttab"
+			exclude="$exclude etc/dfs/sharetab"
 			[ -d system/contract ] &&
 				exclude="$exclude system/contract"
 			[ -d system/object ] &&
--- a/usr/src/uts/Makefile	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/uts/Makefile	Mon Apr 02 21:38:04 2007 -0700
@@ -94,7 +94,8 @@
 COMMON_HDRDIRS= common/des common/fs common/gssapi common/inet common/net \
 	common/netinet common/nfs common/rpc common/sys common/vm \
 	common/c2 common/pcmcia/sys common/rpcsvc common/inet/kssl \
-	common/inet/nca common/inet/ipf/netinet common/ipp
+	common/inet/nca common/inet/ipf/netinet common/ipp \
+	common/sharefs
 
 # These aren't the only headers in closed.  But the other directories
 # are simple enough that they can be driven from the src tree.
--- a/usr/src/uts/README	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/uts/README	Mon Apr 02 21:38:04 2007 -0700
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -19,10 +18,12 @@
 #
 # CDDL HEADER END
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
+# ident	"%Z%%M%	%I%	%E% SMI"
 
 KERNEL MAKEFILE STRUCTURE
 -------------------------
@@ -243,7 +244,7 @@
 
     0]  Create the source files (and directories) as usual.
 
-    1]  Edit uts/*/Makefiles.files to define the set of objects. By convention
+    1]  Edit uts/*/Makefile.files to define the set of objects. By convention
 	the symbolic name of this set is of the form MODULE_OBJS, where
 	MODULE is the module name (i.e.: namefs). The files in each subtree
 	should be defined in the Makefile.files in the root directory of that
@@ -295,17 +296,6 @@
 
 		FS_KMODS	+= fd fifo namefs nfs proc spec ufs
 					   ------
-
-    5]	Add the appropriate components using nsecomp. Continuing with
-	the namefs example:
-
-		$ nsecomp add :src:uts.all:sun4c Comp namefs
-		$ nsecomp add :src:uts.all:sun4c:namefs Targ \
-		  all%/usr/src/uts/sun4c/namefs/Makefile
-
-	This needs to be done for all appropriate "implementation
-	architectures".
-
 Any additional questions can be easily answered by looking at the many
 existing examples.
 
--- a/usr/src/uts/common/Makefile.files	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/uts/common/Makefile.files	Mon Apr 02 21:38:04 2007 -0700
@@ -859,6 +859,8 @@
 
 MNTFS_OBJS +=	mntvfsops.o	mntvnops.o
 
+SHAREFS_OBJS +=	sharetab.o	sharefs_vfsops.o	sharefs_vnops.o
+
 SPEC_OBJS +=	specsubr.o	specvfsops.o	specvnops.o
 
 SOCK_OBJS +=	socksubr.o	sockvfsops.o	sockvnops.o	\
--- a/usr/src/uts/common/Makefile.rules	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/uts/common/Makefile.rules	Mon Apr 02 21:38:04 2007 -0700
@@ -234,6 +234,10 @@
 	$(COMPILE.c) -o $@ $<
 	$(CTFCONVERT_O)
 
+$(OBJS_DIR)/%.o:		$(UTSBASE)/common/fs/sharefs/%.c
+	$(COMPILE.c) -o $@ $<
+	$(CTFCONVERT_O)
+
 $(OBJS_DIR)/%.o:		$(UTSBASE)/common/fs/sockfs/%.c
 	$(COMPILE.c) -o $@ $<
 	$(CTFCONVERT_O)
@@ -1093,6 +1097,9 @@
 $(LINTS_DIR)/%.ln:		$(UTSBASE)/common/fs/proc/%.c
 	@($(LHEAD) $(LINT.c) $< $(LTAIL))
 
+$(LINTS_DIR)/%.ln:		$(UTSBASE)/common/fs/sharefs/%.c
+	@($(LHEAD) $(LINT.c) $< $(LTAIL))
+
 $(LINTS_DIR)/%.ln:		$(UTSBASE)/common/fs/sockfs/%.c
 	@($(LHEAD) $(LINT.c) $< $(LTAIL))
 
--- a/usr/src/uts/common/fs/gfs.c	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/uts/common/fs/gfs.c	Mon Apr 02 21:38:04 2007 -0700
@@ -96,6 +96,17 @@
  * 	gfs_vop_lookup()
  * 	gfs_vop_readdir()
  * 	gfs_vop_map()
+ *
+ * 3) Single File pseudo-filesystems
+ *
+ *    This routine creates a rooted file to be overlayed ontop of another
+ *    file in the physical filespace.
+ *
+ *    Note that the parent is NULL (actually the vfs), but there is nothing
+ *    technically keeping such a file from utilizing the "Complete GFS
+ *    management" set of routines.
+ *
+ * 	gfs_root_create_file()
  */
 
 /*
@@ -489,6 +500,26 @@
 }
 
 /*
+ * gfs_root_create_file(): create a root vnode for a GFS file as a filesystem
+ *
+ * Similar to gfs_root_create(), this creates a root vnode for a file to
+ * be the pseudo-filesystem.
+ */
+vnode_t *
+gfs_root_create_file(size_t size, vfs_t *vfsp, vnodeops_t *ops, ino64_t ino)
+{
+	vnode_t	*vp = gfs_file_create(size, NULL, ops);
+
+	((gfs_file_t *)vp->v_data)->gfs_ino = ino;
+
+	VFS_HOLD(vfsp);
+	VN_SET_VFS_TYPE_DEV(vp, vfsp, VREG, 0);
+	vp->v_flag |= VROOT | VNOCACHE | VNOMAP | VNOSWAP | VNOMOUNT;
+
+	return (vp);
+}
+
+/*
  * gfs_file_inactive()
  *
  * Called from the VOP_INACTIVE() routine.  If necessary, this routine will
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/fs/sharefs/sharefs_vfsops.c	Mon Apr 02 21:38:04 2007 -0700
@@ -0,0 +1,307 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <sys/atomic.h>
+#include <sys/cmn_err.h>
+#include <sys/errno.h>
+#include <sys/mount.h>
+#include <sharefs/sharefs.h>
+#include <sys/vfs_opreg.h>
+#include <sys/policy.h>
+#include <sys/sunddi.h>
+#include <sys/sysmacros.h>
+#include <sys/systm.h>
+
+#include <sys/mntent.h>
+#include <sys/vfs.h>
+
+/*
+ * Kernel sharetab filesystem.
+ *
+ * This is a pseudo filesystem which exports information about shares currently
+ * in kernel memory. The only element of the pseudo filesystem is a file.
+ *
+ * This file contains functions that interact with the VFS layer.
+ *
+ *	sharetab	sharefs_datanode_t	sharefs.c
+ *
+ */
+
+vnodeops_t			*sharefs_ops_data;
+
+static const fs_operation_def_t	sharefs_vfstops[];
+static gfs_opsvec_t		 sharefs_opsvec[];
+
+static int sharefs_init(int, char *);
+
+/*
+ * The sharefs system call.
+ */
+static struct sysent sharefs_sysent = {
+	3,
+	SE_32RVAL1 | SE_ARGC | SE_NOUNLOAD,
+	sharefs
+};
+
+static struct modlsys modlsys = {
+	&mod_syscallops,
+	"sharefs syscall",
+	&sharefs_sysent
+};
+
+#ifdef	_SYSCALL32_IMPL
+static struct modlsys modlsys32 = {
+	&mod_syscallops32,
+	"sharefs syscall (32-bit)",
+	&sharefs_sysent
+};
+#endif /* _SYSCALL32_IMPL */
+
+/*
+ * Module linkage
+ */
+static mntopts_t sharefs_mntopts = {
+	0,
+	NULL
+};
+
+static vfsdef_t vfw = {
+	VFSDEF_VERSION,
+	"sharefs",
+	sharefs_init,
+	VSW_HASPROTO,
+	&sharefs_mntopts,
+};
+
+extern struct mod_ops	mod_fsops;
+
+static struct modlfs modlfs = {
+	&mod_fsops,
+	"sharetab filesystem",
+	&vfw
+};
+
+static struct modlinkage modlinkage = {
+	MODREV_1,
+	&modlfs,
+	&modlsys,
+#ifdef	_SYSCALL32_IMPL
+	&modlsys32,
+#endif
+	NULL
+};
+
+int
+_init(void)
+{
+	return (mod_install(&modlinkage));
+}
+
+int
+_info(struct modinfo *modinfop)
+{
+	return (mod_info(&modlinkage, modinfop));
+}
+
+int
+_fini(void)
+{
+	/*
+	 * The sharetab filesystem cannot be unloaded.
+	 */
+	return (EBUSY);
+}
+
+/*
+ * Filesystem initialization.
+ */
+
+static int sharefs_fstype;
+static major_t sharefs_major;
+static minor_t sharefs_minor;
+
+static gfs_opsvec_t sharefs_opsvec[] = {
+	{ "sharefs sharetab file", sharefs_tops_data, &sharefs_ops_data },
+	{ NULL }
+};
+
+/* ARGSUSED */
+static int
+sharefs_init(int fstype, char *name)
+{
+	vfsops_t	*vfsops;
+	int		error;
+
+	sharefs_fstype = fstype;
+	if (error = vfs_setfsops(fstype, sharefs_vfstops, &vfsops)) {
+		cmn_err(CE_WARN, "sharefs_init: bad vfs ops template");
+		return (error);
+	}
+
+	if (error = gfs_make_opsvec(sharefs_opsvec)) {
+		(void) vfs_freevfsops(vfsops);
+		return (error);
+	}
+
+	if ((sharefs_major = getudev()) == (major_t)-1) {
+		cmn_err(CE_WARN,
+			"sharefs_init: can't get unique device number");
+		sharefs_major = 0;
+	}
+
+	sharefs_sharetab_init();
+
+	return (0);
+}
+
+/*
+ * VFS entry points
+ */
+static int
+sharefs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr)
+{
+	sharefs_vfs_t	*data;
+	dev_t		dev;
+
+	if (secpolicy_fs_mount(cr, mvp, vfsp) != 0)
+		return (EPERM);
+
+	if ((uap->flags & MS_OVERLAY) == 0 &&
+	    (mvp->v_count > 1 || (mvp->v_flag & VROOT)))
+		return (EBUSY);
+
+	data = kmem_alloc(sizeof (sharefs_vfs_t), KM_SLEEP);
+
+	/*
+	 * Initialize vfs fields
+	 */
+	vfsp->vfs_bsize = DEV_BSIZE;
+	vfsp->vfs_fstype = sharefs_fstype;
+	do {
+		dev = makedevice(sharefs_major,
+		    atomic_add_32_nv(&sharefs_minor, 1) & L_MAXMIN32);
+	} while (vfs_devismounted(dev));
+	vfs_make_fsid(&vfsp->vfs_fsid, dev, sharefs_fstype);
+	vfsp->vfs_data = data;
+	vfsp->vfs_dev = dev;
+
+	/*
+	 * Create root
+	 */
+	data->sharefs_vfs_root = sharefs_create_root_file(vfsp);
+
+	return (0);
+}
+
+static int
+sharefs_unmount(vfs_t *vfsp, int flag, struct cred *cr)
+{
+	sharefs_vfs_t	*data;
+
+	if (secpolicy_fs_unmount(cr, vfsp) != 0)
+		return (EPERM);
+
+	/*
+	 * We do not currently support forced unmounts
+	 */
+	if (flag & MS_FORCE)
+		return (ENOTSUP);
+
+	/*
+	 * We should never have a reference count of less than 2: one for the
+	 * caller, one for the root vnode.
+	 */
+	ASSERT(vfsp->vfs_count >= 2);
+
+	/*
+	 * Any active vnodes will result in a hold on the root vnode
+	 */
+	data = vfsp->vfs_data;
+	if (data->sharefs_vfs_root->v_count > 1)
+		return (EBUSY);
+
+	/*
+	 * Only allow an unmount iff there are no entries in memory.
+	 */
+	rw_enter(&sharetab_lock, RW_READER);
+	if (sharetab_size != 0) {
+		rw_exit(&sharetab_lock);
+		return (EBUSY);
+	}
+	rw_exit(&sharetab_lock);
+
+	/*
+	 * Release the last hold on the root vnode
+	 */
+	VN_RELE(data->sharefs_vfs_root);
+
+	kmem_free(data, sizeof (sharefs_vfs_t));
+
+	return (0);
+}
+
+static int
+sharefs_root(vfs_t *vfsp, vnode_t **vpp)
+{
+	sharefs_vfs_t	*data = vfsp->vfs_data;
+
+	*vpp = data->sharefs_vfs_root;
+	VN_HOLD(*vpp);
+
+	return (0);
+}
+
+static int
+sharefs_statvfs(vfs_t *vfsp, statvfs64_t *sp)
+{
+	dev32_t	d32;
+	int	total = 1;
+
+	bzero(sp, sizeof (*sp));
+	sp->f_bsize = DEV_BSIZE;
+	sp->f_frsize = DEV_BSIZE;
+	sp->f_files = total;
+	sp->f_ffree = sp->f_favail = INT_MAX - total;
+	(void) cmpldev(&d32, vfsp->vfs_dev);
+	sp->f_fsid = d32;
+	(void) strlcpy(sp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name,
+	    sizeof (sp->f_basetype));
+	sp->f_flag = vf_to_stf(vfsp->vfs_flag);
+	sp->f_namemax = SHAREFS_NAME_MAX;
+	(void) strlcpy(sp->f_fstr, "sharefs", sizeof (sp->f_fstr));
+
+	return (0);
+}
+
+static const fs_operation_def_t sharefs_vfstops[] = {
+	{ VFSNAME_MOUNT,	{ .vfs_mount = sharefs_mount } },
+	{ VFSNAME_UNMOUNT,	{ .vfs_unmount = sharefs_unmount } },
+	{ VFSNAME_ROOT,		{ .vfs_root = sharefs_root } },
+	{ VFSNAME_STATVFS,	{ .vfs_statvfs = sharefs_statvfs } },
+	{ NULL }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/fs/sharefs/sharefs_vnops.c	Mon Apr 02 21:38:04 2007 -0700
@@ -0,0 +1,384 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <fs/fs_subr.h>
+
+#include <sys/errno.h>
+#include <sys/file.h>
+#include <sys/kmem.h>
+#include <sys/kobj.h>
+#include <sys/cmn_err.h>
+#include <sys/stat.h>
+#include <sys/systm.h>
+#include <sys/sysmacros.h>
+#include <sys/atomic.h>
+#include <sys/vfs.h>
+#include <sys/vfs_opreg.h>
+
+#include <sharefs/sharefs.h>
+
+/*
+ * sharefs_snap_create: create a large character buffer with
+ * the shares enumerated.
+ */
+static int
+sharefs_snap_create(shnode_t *sft)
+{
+	sharetab_t		*sht;
+	share_t			*sh;
+	size_t			sWritten = 0;
+	int			iCount = 0;
+	char			*buf;
+
+	rw_enter(&sharefs_lock, RW_WRITER);
+	rw_enter(&sharetab_lock, RW_READER);
+
+	if (sft->sharefs_snap) {
+		/*
+		 * Nothing has changed, so no need to grab a new copy!
+		 */
+		if (sft->sharefs_generation == sharetab_generation) {
+			rw_exit(&sharetab_lock);
+			rw_exit(&sharefs_lock);
+			return (0);
+		}
+
+		ASSERT(sft->sharefs_size != 0);
+		kmem_free(sft->sharefs_snap, sft->sharefs_size + 1);
+		sft->sharefs_snap = NULL;
+	}
+
+	sft->sharefs_size = sharetab_size;
+	sft->sharefs_count = sharetab_count;
+
+	if (sft->sharefs_size == 0) {
+		rw_exit(&sharetab_lock);
+		rw_exit(&sharefs_lock);
+		return (0);
+	}
+
+	sft->sharefs_snap = kmem_zalloc(sft->sharefs_size + 1, KM_SLEEP);
+
+	buf = sft->sharefs_snap;
+
+	/*
+	 * Walk the Sharetab, dumping each entry.
+	 */
+	for (sht = sharefs_sharetab; sht != NULL; sht = sht->s_next) {
+		int	i;
+
+		for (i = 0; i < SHARETAB_HASHES; i++) {
+			for (sh = sht->s_buckets[i].ssh_sh;
+					sh != NULL;
+					sh = sh->sh_next) {
+				int	n;
+
+				if ((sWritten + sh->sh_size) >
+						sft->sharefs_size) {
+					goto error_fault;
+				}
+
+				/*
+				 * Note that sh->sh_size accounts
+				 * for the field seperators.
+				 * We need to add one for the EOL
+				 * marker. And we should note that
+				 * the space is accounted for in
+				 * each share by the EOS marker.
+				 */
+				n = snprintf(&buf[sWritten],
+					sh->sh_size + 1,
+					"%s\t%s\t%s\t%s\t%s\n",
+					sh->sh_path,
+					sh->sh_res,
+					sh->sh_fstype,
+					sh->sh_opts,
+					sh->sh_descr);
+
+				if (n != sh->sh_size) {
+					goto error_fault;
+				}
+
+				sWritten += n;
+				iCount++;
+			}
+		}
+	}
+
+	/*
+	 * We want to record the generation number and
+	 * mtime inside this snapshot.
+	 */
+	gethrestime(&sharetab_snap_time);
+	sft->sharefs_snap_time = sharetab_snap_time;
+	sft->sharefs_generation = sharetab_generation;
+
+	ASSERT(iCount == sft->sharefs_count);
+
+	rw_exit(&sharetab_lock);
+	rw_exit(&sharefs_lock);
+	return (0);
+
+error_fault:
+
+	kmem_free(sft->sharefs_snap, sft->sharefs_size + 1);
+	sft->sharefs_size = 0;
+	sft->sharefs_count = 0;
+	sft->sharefs_snap = NULL;
+	rw_exit(&sharetab_lock);
+	rw_exit(&sharefs_lock);
+
+	return (EFAULT);
+}
+
+/* ARGSUSED */
+static int
+sharefs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr)
+{
+	timestruc_t	now;
+	shnode_t	*sft = VTOSH(vp);
+
+	vap->va_type = VREG;
+	vap->va_mode = S_IRUSR | S_IRGRP | S_IROTH;
+	vap->va_nodeid = SHAREFS_INO_FILE;
+	vap->va_nlink = 1;
+
+	rw_enter(&sharefs_lock, RW_READER);
+
+	/*
+	 * If we get asked about a snapped vnode, then
+	 * we must report the data in that vnode.
+	 *
+	 * Else we report what is currently in the
+	 * sharetab.
+	 */
+	if (sft->sharefs_real_vp) {
+		rw_enter(&sharetab_lock, RW_READER);
+		vap->va_size = sharetab_size;
+		vap->va_mtime = sharetab_mtime;
+		rw_exit(&sharetab_lock);
+	} else {
+		vap->va_size = sft->sharefs_size;
+		vap->va_mtime = sft->sharefs_snap_time;
+	}
+	rw_exit(&sharefs_lock);
+
+	gethrestime(&now);
+	vap->va_atime = vap->va_ctime = now;
+
+	vap->va_uid = 0;
+	vap->va_gid = 0;
+	vap->va_rdev = 0;
+	vap->va_blksize = DEV_BSIZE;
+	vap->va_nblocks = howmany(vap->va_size, vap->va_blksize);
+	vap->va_seq = 0;
+	vap->va_fsid = vp->v_vfsp->vfs_dev;
+
+	return (0);
+}
+
+/* ARGSUSED */
+static int
+sharefs_access(vnode_t *vp, int mode, int flags, cred_t *cr)
+{
+	if (mode & (VWRITE|VEXEC))
+		return (EROFS);
+
+	return (0);
+}
+
+/* ARGSUSED */
+int
+sharefs_open(vnode_t **vpp, int flag, cred_t *cr)
+{
+	vnode_t		*vp;
+	vnode_t		*ovp = *vpp;
+	shnode_t	*sft;
+	int		error = 0;
+
+	if (flag & FWRITE)
+		return (EINVAL);
+
+	/*
+	 * Create a new sharefs vnode for each operation. In order to
+	 * avoid locks, we create a snapshot which can not change during
+	 * reads.
+	 */
+	vp = gfs_file_create(sizeof (shnode_t), NULL, sharefs_ops_data);
+
+	((gfs_file_t *)vp->v_data)->gfs_ino = SHAREFS_INO_FILE;
+
+	/*
+	 * Hold the parent!
+	 */
+	VFS_HOLD(ovp->v_vfsp);
+
+	VN_SET_VFS_TYPE_DEV(vp, ovp->v_vfsp, VREG, 0);
+
+	vp->v_flag |= VROOT | VNOCACHE | VNOMAP | VNOSWAP | VNOMOUNT;
+
+	*vpp = vp;
+	VN_RELE(ovp);
+
+	sft = VTOSH(vp);
+
+	/*
+	 * No need for the lock, no other thread can be accessing
+	 * this data structure.
+	 */
+	atomic_add_32(&sft->sharefs_refs, 1);
+	sft->sharefs_real_vp = 0;
+
+	/*
+	 * Since the sharetab could easily change on us whilst we
+	 * are dumping an extremely huge sharetab, we make a copy
+	 * of it here and use it to dump instead.
+	 */
+	error = sharefs_snap_create(sft);
+
+	return (error);
+}
+
+/* ARGSUSED */
+int
+sharefs_close(vnode_t *vp, int flag, int count,
+			offset_t off, cred_t *cr)
+{
+	shnode_t	*sft = VTOSH(vp);
+
+	if (count > 1)
+		return (0);
+
+	rw_enter(&sharefs_lock, RW_WRITER);
+	if (vp->v_count == 1) {
+		if (sft->sharefs_snap != NULL) {
+			kmem_free(sft->sharefs_snap, sft->sharefs_size + 1);
+			sft->sharefs_size = 0;
+			sft->sharefs_snap = NULL;
+			sft->sharefs_generation = 0;
+		}
+	}
+	atomic_add_32(&sft->sharefs_refs, -1);
+	rw_exit(&sharefs_lock);
+
+	return (0);
+}
+
+/* ARGSUSED */
+static int
+sharefs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr,
+			caller_context_t *ct)
+{
+	shnode_t	*sft = VTOSH(vp);
+	off_t		off = uio->uio_offset;
+	size_t		len = uio->uio_resid;
+	int		error = 0;
+
+	rw_enter(&sharefs_lock, RW_READER);
+
+	/*
+	 * First check to see if we need to grab a new snapshot.
+	 */
+	if (off == (off_t)0) {
+		rw_exit(&sharefs_lock);
+		error = sharefs_snap_create(sft);
+		if (error) {
+			return (EFAULT);
+		}
+		rw_enter(&sharefs_lock, RW_READER);
+	}
+
+	/* LINTED */
+	if (len <= 0 || off >= sft->sharefs_size) {
+		rw_exit(&sharefs_lock);
+		return (error);
+	}
+
+	if ((size_t)(off + len) > sft->sharefs_size)
+		len = sft->sharefs_size - off;
+
+	if (off < 0 || len > sft->sharefs_size) {
+		rw_exit(&sharefs_lock);
+		return (EFAULT);
+	}
+
+	if (len != 0) {
+		error = uiomove(sft->sharefs_snap + off,
+				len, UIO_READ, uio);
+	}
+
+	rw_exit(&sharefs_lock);
+	return (error);
+}
+
+/* ARGSUSED */
+static void
+sharefs_inactive(vnode_t *vp, cred_t *cr)
+{
+	gfs_file_t	*fp = vp->v_data;
+	shnode_t	*sft;
+
+	sft = (shnode_t *)gfs_file_inactive(vp);
+	if (sft) {
+		rw_enter(&sharefs_lock, RW_WRITER);
+		if (sft->sharefs_snap != NULL) {
+			kmem_free(sft->sharefs_snap, sft->sharefs_size + 1);
+		}
+
+		kmem_free(sft, fp->gfs_size);
+		rw_exit(&sharefs_lock);
+	}
+}
+
+vnode_t *
+sharefs_create_root_file(vfs_t *vfsp)
+{
+	vnode_t		*vp;
+	shnode_t	*sft;
+
+	vp = gfs_root_create_file(sizeof (shnode_t),
+			vfsp, sharefs_ops_data, SHAREFS_INO_FILE);
+
+	sft = VTOSH(vp);
+
+	sft->sharefs_real_vp = 1;
+
+	return (vp);
+}
+
+const fs_operation_def_t sharefs_tops_data[] = {
+	{ VOPNAME_OPEN,		{ .vop_open = sharefs_open } },
+	{ VOPNAME_CLOSE,	{ .vop_close = sharefs_close } },
+	{ VOPNAME_IOCTL,	{ .error = fs_inval } },
+	{ VOPNAME_GETATTR,	{ .vop_getattr = sharefs_getattr } },
+	{ VOPNAME_ACCESS,	{ .vop_access = sharefs_access } },
+	{ VOPNAME_INACTIVE,	{ .vop_inactive = sharefs_inactive } },
+	{ VOPNAME_READ,		{ .vop_read = sharefs_read } },
+	{ VOPNAME_SEEK,		{ .vop_seek = fs_seek } },
+	{ NULL }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/fs/sharefs/sharetab.c	Mon Apr 02 21:38:04 2007 -0700
@@ -0,0 +1,470 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <sys/types.h>
+#include <sys/types32.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <rpc/types.h>
+#include <sys/vfs.h>
+#include <sys/siginfo.h>
+#include <sys/proc.h>		/* for exit() declaration */
+#include <sys/kmem.h>
+#include <sys/pathname.h>
+#include <sys/debug.h>
+#include <sys/vtrace.h>
+#include <sys/cmn_err.h>
+#include <sys/atomic.h>
+
+#include <sharefs/sharefs.h>
+
+/*
+ * A macro to avoid cut-and-paste errors on getting a string field
+ * from user-land.
+ */
+#define	SHARETAB_COPYIN(field)						\
+	if (copyinstr(STRUCT_FGETP(u_sh, sh_##field),			\
+			buf,						\
+			bufsz + 1,	/* Add one for extra NUL */	\
+			&len)) {					\
+		error = EFAULT;						\
+		goto cleanup;						\
+	}								\
+	/*								\
+	 * Need to remove 1 because copyinstr() counts the NUL.		\
+	 */								\
+	len--;								\
+	sh->sh_##field = kmem_alloc(len + 1, KM_SLEEP);			\
+	bcopy(buf, sh->sh_##field, len);				\
+	sh->sh_##field[len] = '\0';					\
+	shl.shl_##field = (int)len;					\
+	sh->sh_size += shl.shl_##field;	/* Debug counting */
+
+#define	SHARETAB_DELETE_FIELD(field)					\
+	if (sh->sh_##field) {						\
+		kmem_free(sh->sh_##field,				\
+			shl ? shl->shl_##field + 1 :			\
+			strlen(sh->sh_##field) + 1);			\
+	}
+
+sharetab_t	*sharefs_sharetab = NULL;	/* The incore sharetab. */
+size_t		sharetab_size;
+uint_t		sharetab_count;
+
+krwlock_t	sharetab_lock;	/* lock to protect the cached sharetab */
+
+krwlock_t	sharefs_lock;	/* lock to protect the vnode ops */
+
+timestruc_t	sharetab_mtime;
+timestruc_t	sharetab_snap_time;
+
+uint_t		sharetab_generation;	/* Only increments and wraps! */
+
+static uint_t	pkp_tab[SHARETAB_HASHES];
+
+/*
+ * Initialize table in pseudo-random fashion
+ * for use in Pearson's string hash algorithm.
+ *
+ * See: Communications of the ACM, June 1990 Vol 33 pp 677-680
+ * http://www.acm.org/pubs/citations/journals/cacm/1990-33-6/p677-pearson
+ */
+static void
+init_pkp_tab(void)
+{
+	int	i;
+	int	j;
+	int	k = 7;
+	uint_t	s;
+
+	for (i = 0; i < SHARETAB_HASHES; i++)
+		pkp_tab[i] = i;
+
+	for (j = 0; j < 4; j++) {
+		for (i = 0; i < SHARETAB_HASHES; i++) {
+			s = pkp_tab[i];
+			k = MOD2((k + s), SHARETAB_HASHES);
+			pkp_tab[i] = pkp_tab[k];
+			pkp_tab[k] = s;
+		}
+	}
+}
+
+/*
+ * Take care of cleaning up a share.
+ * If passed in a length array, use it to determine how much
+ * space to clean up. Else, figure that out.
+ */
+static void
+sharefree(share_t *sh, sharefs_lens_t *shl)
+{
+	if (!sh)
+		return;
+
+	SHARETAB_DELETE_FIELD(path);
+	SHARETAB_DELETE_FIELD(res);
+	SHARETAB_DELETE_FIELD(fstype);
+	SHARETAB_DELETE_FIELD(opts);
+	SHARETAB_DELETE_FIELD(descr);
+
+	kmem_free(sh, sizeof (share_t));
+}
+
+/*
+ * If there is no error, then this function is responsible for
+ * cleaning up the memory associated with the share argument.
+ */
+static int
+sharefs_remove(share_t *sh, sharefs_lens_t *shl)
+{
+	int		iHash;
+	sharetab_t	*sht;
+	share_t		*s, *p;
+	int		iPath;
+
+	if (!sh)
+		return (ENOENT);
+
+	rw_enter(&sharetab_lock, RW_WRITER);
+	for (sht = sharefs_sharetab; sht != NULL; sht = sht->s_next) {
+		if (strcmp(sh->sh_fstype, sht->s_fstype) == 0) {
+			break;
+		}
+	}
+
+	/*
+	 * There does not exist a fstype in memory which
+	 * matches the share passed in.
+	 */
+	if (!sht) {
+		rw_exit(&sharetab_lock);
+		return (ENOENT);
+	}
+
+	iPath = shl ? shl->shl_path : strlen(sh->sh_path);
+	SHARETAB_HASH_IT(iHash, sh->sh_path);
+
+	/*
+	 * Now walk down the hash table and find the entry to free!
+	 */
+	for (p = NULL, s = sht->s_buckets[iHash].ssh_sh;
+			s != NULL;
+			s = s->sh_next) {
+		/*
+		 * We need exact matches.
+		 */
+		if (strcmp(sh->sh_path, s->sh_path) == 0 &&
+				strlen(s->sh_path) == iPath) {
+			if (p) {
+				p->sh_next = s->sh_next;
+			} else {
+				sht->s_buckets[iHash].ssh_sh = s->sh_next;
+			}
+
+			ASSERT(sht->s_buckets[iHash].ssh_count != 0);
+			atomic_add_32(&sht->s_buckets[iHash].ssh_count, -1);
+			atomic_add_32(&sht->s_count, -1);
+			atomic_add_32(&sharetab_count, -1);
+
+			ASSERT(sharetab_size >= s->sh_size);
+			sharetab_size -= s->sh_size;
+
+			gethrestime(&sharetab_mtime);
+			atomic_add_32(&sharetab_generation, 1);
+
+			break;
+		}
+
+		p = s;
+	}
+
+	rw_exit(&sharetab_lock);
+
+	if (!s) {
+		return (ENOENT);
+	}
+
+	s->sh_next = NULL;
+	sharefree(s, NULL);
+
+	/*
+	 * We need to free the share for the caller.
+	 */
+	sharefree(sh, shl);
+
+	return (0);
+}
+
+/*
+ * The caller must have allocated memory for us to use.
+ */
+static int
+sharefs_add(share_t *sh, sharefs_lens_t *shl)
+{
+	int		iHash;
+	sharetab_t	*sht;
+	share_t		*s, *p;
+	int		iPath;
+	int		n;
+
+	if (!sh) {
+		return (ENOENT);
+	}
+
+	/*
+	 * We need to find the hash buckets for the fstype.
+	 */
+	rw_enter(&sharetab_lock, RW_WRITER);
+	for (sht = sharefs_sharetab; sht != NULL; sht = sht->s_next) {
+		if (strcmp(sh->sh_fstype, sht->s_fstype) == 0) {
+			break;
+		}
+	}
+
+	/*
+	 * Did not exist, so allocate one and add it to the
+	 * sharetab.
+	 */
+	if (!sht) {
+		sht = kmem_zalloc(sizeof (*sht), KM_SLEEP);
+		n = strlen(sh->sh_fstype);
+		sht->s_fstype = kmem_zalloc(n + 1, KM_SLEEP);
+		(void) strncpy(sht->s_fstype, sh->sh_fstype, n);
+
+		sht->s_next = sharefs_sharetab;
+		sharefs_sharetab = sht;
+	}
+
+	/*
+	 * Now we need to find where we have to add the entry.
+	 */
+	SHARETAB_HASH_IT(iHash, sh->sh_path);
+
+	iPath = shl ? shl->shl_path : strlen(sh->sh_path);
+
+	if (shl) {
+		sh->sh_size = shl->shl_path + shl->shl_res +
+			shl->shl_fstype + shl->shl_opts +
+			shl->shl_descr;
+	} else {
+		sh->sh_size = strlen(sh->sh_path) +
+			strlen(sh->sh_res) +
+			strlen(sh->sh_fstype) +
+			strlen(sh->sh_opts) +
+			strlen(sh->sh_descr);
+	}
+
+	/*
+	 * We need to account for field seperators and
+	 * the EOL.
+	 */
+	sh->sh_size += 5;
+
+	/*
+	 * Now walk down the hash table and add the new entry!
+	 */
+	for (p = NULL, s = sht->s_buckets[iHash].ssh_sh;
+			s != NULL;
+			s = s->sh_next) {
+		/*
+		 * We need exact matches.
+		 *
+		 * We found a matching path. Either we have a
+		 * duplicate path in a share command or we are
+		 * being asked to replace an existing entry.
+		 */
+		if (strcmp(sh->sh_path, s->sh_path) == 0 &&
+				strlen(s->sh_path) == iPath) {
+			if (p) {
+				p->sh_next = sh;
+			} else {
+				sht->s_buckets[iHash].ssh_sh = sh;
+			}
+
+			sh->sh_next = s->sh_next;
+
+			ASSERT(sharetab_size >= s->sh_size);
+			sharetab_size -= s->sh_size;
+			sharetab_size += sh->sh_size;
+
+			/*
+			 * Get rid of the old node.
+			 */
+			sharefree(s, NULL);
+
+			gethrestime(&sharetab_mtime);
+			atomic_add_32(&sharetab_generation, 1);
+
+			ASSERT(sht->s_buckets[iHash].ssh_count != 0);
+			rw_exit(&sharetab_lock);
+
+			return (0);
+		}
+
+		p = s;
+	}
+
+	/*
+	 * Okay, we have gone through the entire hash chain and not
+	 * found a match. We just need to add this node.
+	 */
+	sh->sh_next = sht->s_buckets[iHash].ssh_sh;
+	sht->s_buckets[iHash].ssh_sh = sh;
+	atomic_add_32(&sht->s_buckets[iHash].ssh_count, 1);
+	atomic_add_32(&sht->s_count, 1);
+	atomic_add_32(&sharetab_count, 1);
+	sharetab_size += sh->sh_size;
+
+	gethrestime(&sharetab_mtime);
+	atomic_add_32(&sharetab_generation, 1);
+
+	rw_exit(&sharetab_lock);
+
+	return (0);
+}
+
+void
+sharefs_sharetab_init(void)
+{
+	init_pkp_tab();
+
+	rw_init(&sharetab_lock, NULL, RW_DEFAULT, NULL);
+	rw_init(&sharefs_lock, NULL, RW_DEFAULT, NULL);
+
+	sharetab_size = 0;
+	sharetab_count = 0;
+	sharetab_generation = 1;
+
+	gethrestime(&sharetab_mtime);
+	gethrestime(&sharetab_snap_time);
+}
+
+int
+sharefs(enum sharefs_sys_op opcode, share_t *sh_in, uint32_t iMaxLen)
+{
+	int		error = 0;
+	size_t		len;
+	size_t		bufsz;
+	share_t		*sh;
+
+	sharefs_lens_t	shl;
+
+	model_t		model;
+
+	char		*buf = NULL;
+
+	STRUCT_DECL(share, u_sh);
+
+	bufsz = iMaxLen;
+
+	/*
+	 * Before we do anything, lets make sure we have
+	 * a sharetab in memory if we need one.
+	 */
+	rw_enter(&sharetab_lock, RW_READER);
+	switch (opcode) {
+	case (SHAREFS_REMOVE) :
+	case (SHAREFS_REPLACE) :
+		if (!sharefs_sharetab) {
+			rw_exit(&sharetab_lock);
+			return (set_errno(ENOENT));
+		}
+		break;
+	case (SHAREFS_ADD) :
+	default :
+		break;
+	}
+	rw_exit(&sharetab_lock);
+
+	model = get_udatamodel();
+
+	/*
+	 * Initialize the data pointers.
+	 */
+	STRUCT_INIT(u_sh, model);
+	if (copyin(sh_in, STRUCT_BUF(u_sh),
+			STRUCT_SIZE(u_sh))) {
+		return (set_errno(EFAULT));
+	}
+
+	/*
+	 * Get the share.
+	 */
+	sh = kmem_zalloc(sizeof (share_t), KM_SLEEP);
+
+	/*
+	 * Get some storage for copying in the strings.
+	 */
+	buf = kmem_zalloc(bufsz + 1, KM_SLEEP);
+	bzero(&shl, sizeof (sharefs_lens_t));
+
+	/*
+	 * Only grab these two until we know what we want.
+	 */
+	SHARETAB_COPYIN(path);
+	SHARETAB_COPYIN(fstype);
+
+	switch (opcode) {
+	case (SHAREFS_ADD) :
+	case (SHAREFS_REPLACE) :
+		SHARETAB_COPYIN(res);
+		SHARETAB_COPYIN(opts);
+		SHARETAB_COPYIN(descr);
+
+		error = sharefs_add(sh, &shl);
+		break;
+
+	case (SHAREFS_REMOVE) :
+
+		error = sharefs_remove(sh, &shl);
+		break;
+
+	default:
+		error = EINVAL;
+		break;
+	}
+
+cleanup:
+
+	/*
+	 * If there is no error, then we have stashed the structure
+	 * away in the sharetab hash table or have deleted it.
+	 *
+	 * Either way, the only reason to blow away the data is if
+	 * there was an error.
+	 */
+	if (error != 0) {
+		sharefree(sh, &shl);
+	}
+
+	if (buf) {
+		kmem_free(buf, bufsz + 1);
+	}
+
+	return ((error != 0) ? set_errno(error) : 0);
+}
--- a/usr/src/uts/common/fs/vfs.c	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/uts/common/fs/vfs.c	Mon Apr 02 21:38:04 2007 -0700
@@ -852,7 +852,7 @@
 
 	/*
 	 * Mount /devices, /dev instance 1, /system/contract, /etc/mnttab,
-	 * /etc/svc/volatile, /system/object, and /proc.
+	 * /etc/svc/volatile, /etc/dfs/sharetab, /system/object, and /proc.
 	 */
 	vfs_mountdevices();
 	vfs_mountdev1();
@@ -863,6 +863,10 @@
 	vfs_mountfs("tmpfs", "/etc/svc/volatile", "/etc/svc/volatile");
 	vfs_mountfs("objfs", "objfs", OBJFS_ROOT);
 
+	if (getzoneid() == GLOBAL_ZONEID) {
+		vfs_mountfs("sharefs", "sharefs", "/etc/dfs/sharetab");
+	}
+
 #ifdef __sparc
 	/*
 	 * This bit of magic can go away when we convert sparc to
--- a/usr/src/uts/common/os/sysent.c	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/uts/common/os/sysent.c	Mon Apr 02 21:38:04 2007 -0700
@@ -21,7 +21,7 @@
 
 /* ONC_PLUS EXTRACT START */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -617,7 +617,7 @@
 	/* 137 */ SYSENT_CL("sysconfig",	sysconfig,	1),
 	/* 138 */ SYSENT_CI("adjtime",		adjtime,	2),
 	/* 139 */ SYSENT_CL("systeminfo",	systeminfo,	3),
-	/* 140 */ SYSENT_LOADABLE(),		/* reserved */
+	/* 140 */ SYSENT_LOADABLE(),		/* sharefs */
 	/* 141 */ SYSENT_CI("seteuid",		seteuid,	1),
 	/* 142 */ SYSENT_2CI("forksys",		forksys,	2),
 	/* 143 */ SYSENT_2CI("fork1",		fork1,		0),
@@ -1001,7 +1001,7 @@
 	/* 137 */ SYSENT_CI("sysconfig",	sysconfig,	1),
 	/* 138 */ SYSENT_CI("adjtime",		adjtime,	2),
 	/* 139 */ SYSENT_CI("systeminfo",	systeminfo,	3),
-	/* 140 */ SYSENT_LOADABLE32(),		/* reserved */
+	/* 140 */ SYSENT_LOADABLE32(),		/* sharefs */
 	/* 141 */ SYSENT_CI("seteuid",		seteuid,	1),
 	/* 142 */ SYSENT_2CI("forksys",		forksys,	2),
 	/* 143 */ SYSENT_2CI("fork1",		fork1,		0),
--- a/usr/src/uts/common/os/vfs_conf.c	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/uts/common/os/vfs_conf.c	Mon Apr 02 21:38:04 2007 -0700
@@ -79,6 +79,7 @@
 	{ "dev" },				/* DEV */
 	{ "ctfs" },				/* CONTRACTFS */
 	{ "objfs" },				/* OBJFS */
+	{ "sharefs" },				/* SHAREFS */
 	{ "" },					/* reserved for loadable fs */
 	{ "" },
 	{ "" },
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/sharefs/Makefile	Mon Apr 02 21:38:04 2007 -0700
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+# uts/common/nfs/Makefile
+#
+# include global definitions
+#
+include ../../../Makefile.master
+
+HDRS=	share.h	sharetab.h sharefs.h
+
+ALLHDRS= $(HDRS)
+
+ROOTDIRS= $(ROOT)/usr/include/sharefs
+
+ROOTHDRS= $(ALLHDRS:%=$(ROOTDIRS)/%)
+
+CHECKHDRS= $(HDRS:%.h=%.check) \
+	$(CLOSEDHDRS:%.h=$(CLOSED)/uts/common/sharefs/%.check)
+
+$(ROOTDIRS)/%: %
+	$(INS.file)
+
+.KEEP_STATE:
+
+.PARALLEL: $(CHECKHDRS)
+
+install_h: $(ROOTDIRS) $(ROOTHDRS)
+
+$(ROOTDIRS):
+	$(INS.dir)
+
+check:	$(CHECKHDRS)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/sharefs/share.h	Mon Apr 02 21:38:04 2007 -0700
@@ -0,0 +1,87 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SHAREFS_SHARE_H
+#define	_SHAREFS_SHARE_H
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * struct share defines the format of an exported filesystem.
+ *
+ * It is also the interface between the userland tools and
+ * the kernel.
+ */
+typedef struct share {
+	char		*sh_path;
+	char		*sh_res;
+	char		*sh_fstype;
+	char		*sh_opts;
+	char		*sh_descr;
+	size_t		sh_size;
+	struct share	*sh_next;
+} share_t;
+
+#ifdef _SYSCALL32
+typedef struct share32 {
+	caddr32_t	sh_path;
+	caddr32_t	sh_res;
+	caddr32_t	sh_fstype;
+	caddr32_t	sh_opts;
+	caddr32_t	sh_descr;
+	size32_t	sh_size;
+	caddr32_t	sh_next;
+} share32_t;
+#endif /* _SYSCALL32 */
+
+#define	SHARETAB	"/etc/dfs/sharetab"
+#define	MAXBUFSIZE	65536
+
+/*
+ * Flavors of the system call.
+ */
+enum sharefs_sys_op { SHAREFS_ADD, SHAREFS_REMOVE, SHAREFS_REPLACE };
+
+#ifdef _KERNEL
+
+extern int	sharefs(enum sharefs_sys_op opcode, struct share *sh,
+			uint32_t iMaxLen);
+
+#else
+
+extern int	sharefs(enum sharefs_sys_op opcode, struct share *sh);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_SHAREFS_SHARE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/sharefs/sharefs.h	Mon Apr 02 21:38:04 2007 -0700
@@ -0,0 +1,123 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SHAREFS_SHAREFS_H
+#define	_SHAREFS_SHAREFS_H
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/*
+ * This header provides service for the sharefs module.
+ */
+
+#include <sys/modctl.h>
+#include <sys/vfs.h>
+#include <sys/vnode.h>
+#include <sys/gfs.h>
+#include <sharefs/share.h>
+#include <sharefs/sharetab.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define	SHAREFS_ROOT	"/etc/dfs"
+#define	SHAREFS_BASE	"sharetab"
+
+/*
+ * Lengths of strings.
+ */
+typedef struct sharefs_lens {
+	int	shl_path;
+	int	shl_res;
+	int	shl_fstype;
+	int	shl_opts;
+	int	shl_descr;
+} sharefs_lens_t;
+
+/*
+ * VFS data object
+ */
+typedef struct sharefs_vfs {
+	vnode_t	*sharefs_vfs_root;
+} sharefs_vfs_t;
+
+#define	SHAREFS_NAME_MAX	MAXNAMELEN
+
+/*
+ * The lock ordering whenever sharefs_lock and sharetab_lock both
+ * need to be held is: sharefs_lock and then sharetab_lock.
+ */
+extern krwlock_t	sharefs_lock;	/* lock for the vnode ops */
+extern sharetab_t	*sharefs_sharetab;	/* The sharetab. */
+
+extern uint_t		sharetab_count;	/* How many shares? */
+extern krwlock_t	sharetab_lock;	/* lock for the cached sharetab */
+extern size_t		sharetab_size;	/* How big is the sharetab file? */
+
+extern timestruc_t	sharetab_mtime;	/* Last mod to sharetab */
+extern timestruc_t	sharetab_snap_time;	/* Last snap */
+extern uint_t		sharetab_generation;	/* Which copy is it? */
+
+#define	SHAREFS_INO_FILE	0x80
+
+extern vnode_t *sharefs_create_root_file(vfs_t *);
+
+/*
+ * Sharetab file
+ *
+ * Note that even though the sharetab code does not explictly
+ * use 'sharefs_file', it is required by GFS that the first
+ * field of the private data be a gfs_file_t.
+ */
+typedef struct shnode_t {
+	gfs_file_t	sharefs_file;		/* gfs file */
+	char		*sharefs_snap;		/* snapshot of the share */
+	size_t		sharefs_size;		/* size of the snapshot */
+	uint_t		sharefs_count;		/* number of shares */
+	uint_t		sharefs_refs;		/* reference count */
+	uint_t		sharefs_real_vp;	/* Are we a real or snap */
+	uint_t		sharefs_generation;	/* Which copy are we? */
+	timestruc_t	sharefs_snap_time;	/* When were we modded? */
+} shnode_t;
+
+/*
+ * Some conversion macros:
+ */
+#define	VTOSH(vp)	((shnode_t *)((vp)->v_data))
+
+extern const fs_operation_def_t	sharefs_tops_data[];
+extern vnodeops_t		*sharefs_ops_data;
+
+extern void sharefs_data_init(void);
+
+extern void sharefs_sharetab_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_SHAREFS_SHAREFS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/sharefs/sharetab.h	Mon Apr 02 21:38:04 2007 -0700
@@ -0,0 +1,93 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SHAREFS_SHARETAB_H
+#define	_SHAREFS_SHARETAB_H
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/*
+ * This header defines the glue to keeping a sharetab in memory.
+ * It is broken out from sharefs.h in the case that it will be
+ * reused in userland.
+ */
+
+/*
+ * Note:
+ * Must include share/share.h before this header.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct sh_list {		/* cached share list */
+	struct sh_list	*shl_next;
+	share_t		*shl_sh;
+} sh_list_t;
+
+typedef struct sharefs_hash_head {
+	share_t		*ssh_sh;
+	uint_t		ssh_count;
+} sharefs_hash_head_t;
+
+#define	SHARETAB_HASHES		256
+
+typedef struct sharetab {
+	sharefs_hash_head_t	s_buckets[SHARETAB_HASHES];
+	char			*s_fstype;
+	struct sharetab		*s_next;
+	uint_t			s_count;
+} sharetab_t;
+
+#define	MOD2(a, pow_of_2)	(a) & ((pow_of_2) - 1)
+
+/*
+ * Pearson's string hash
+ *
+ * See: Communications of the ACM, June 1990 Vol 33 pp 677-680
+ * http://www.acm.org/pubs/citations/journals/cacm/1990-33-6/p677-pearson
+ */
+#define	SHARETAB_HASH_IT(hash, path)					\
+{									\
+	uint_t		key = 0x12345678;	/* arbitrary value */	\
+	int		i, len;						\
+									\
+	len = strlen((path));						\
+									\
+	(hash) = MOD2((key + len), SHARETAB_HASHES);			\
+									\
+	for (i = 0; i < len; i++) {					\
+		(hash) = MOD2(((hash) + (path)[i]), SHARETAB_HASHES);	\
+		(hash) = pkp_tab[(hash)];				\
+	}								\
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_SHAREFS_SHARETAB_H */
--- a/usr/src/uts/common/sys/gfs.h	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/uts/common/sys/gfs.h	Mon Apr 02 21:38:04 2007 -0700
@@ -18,6 +18,7 @@
  *
  * CDDL HEADER END
  */
+
 /*
  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
@@ -96,6 +97,8 @@
     gfs_dirent_t *, gfs_inode_cb, int, gfs_readdir_cb, gfs_lookup_cb);
 extern vnode_t *gfs_root_create(size_t, struct vfs *, vnodeops_t *, ino64_t,
     gfs_dirent_t *, gfs_inode_cb, int, gfs_readdir_cb, gfs_lookup_cb);
+extern vnode_t *gfs_root_create_file(size_t, struct vfs *, vnodeops_t *,
+    ino64_t);
 
 extern void *gfs_file_inactive(vnode_t *);
 extern void *gfs_dir_inactive(vnode_t *);
--- a/usr/src/uts/common/sys/mntent.h	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/uts/common/sys/mntent.h	Mon Apr 02 21:38:04 2007 -0700
@@ -57,6 +57,8 @@
 #define	MNTTYPE_DEV	"dev"		/* /dev file system */
 #define	MNTTYPE_CTFS	"ctfs"		/* Contract file system */
 #define	MNTTYPE_OBJFS	"objfs"		/* Kernel object file system */
+#define	MNTTYPE_SHAREFS	"sharefs"	/* Kernel sharetab file system */
+
 
 #define	MNTOPT_RO	"ro"		/* Read only */
 #define	MNTOPT_RW	"rw"		/* Read/write */
--- a/usr/src/uts/common/sys/syscall.h	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/uts/common/sys/syscall.h	Mon Apr 02 21:38:04 2007 -0700
@@ -319,6 +319,7 @@
 #define	SYS_sysconfig	137
 #define	SYS_adjtime	138
 #define	SYS_systeminfo	139
+#define	SYS_sharefs	140
 #define	SYS_seteuid	141
 #define	SYS_forksys	142
 	/*
--- a/usr/src/uts/intel/Makefile.intel.shared	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/uts/intel/Makefile.intel.shared	Mon Apr 02 21:38:04 2007 -0700
@@ -454,7 +454,7 @@
 #
 FS_KMODS	+= autofs cachefs ctfs dev devfs fdfs fifofs hsfs lofs
 FS_KMODS	+= lx_afs lx_proc mntfs namefs nfs objfs zfs
-FS_KMODS	+= pcfs procfs sockfs specfs tmpfs udfs ufs
+FS_KMODS	+= pcfs procfs sockfs specfs tmpfs udfs ufs sharefs
 
 #
 #	Streams Modules (/kernel/strmod):
--- a/usr/src/uts/intel/os/name_to_sysnum	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/uts/intel/os/name_to_sysnum	Mon Apr 02 21:38:04 2007 -0700
@@ -124,6 +124,7 @@
 sysconfig		137
 adjtime			138
 systeminfo		139
+sharefs			140
 seteuid			141
 forksys			142
 fork1			143
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/intel/sharefs/Makefile	Mon Apr 02 21:38:04 2007 -0700
@@ -0,0 +1,87 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+#	This makefile drives the production of the sharetab file system
+#	kernel module.
+#
+#	intel implementation architecture dependent
+#
+
+#
+#	Path to the base of the uts directory tree (usually /usr/src/uts).
+#
+UTSBASE	= ../..
+
+#
+#	Define the module and object file sets.
+#
+MODULE		= sharefs
+OBJECTS		= $(SHAREFS_OBJS:%=$(OBJS_DIR)/%)
+LINTS		= $(SHAREFS_OBJS:%.o=$(LINTS_DIR)/%.ln)
+ROOTMODULE	= $(ROOT_FS_DIR)/$(MODULE)
+
+#
+#	Include common rules.
+#
+include $(UTSBASE)/intel/Makefile.intel
+
+#
+#	Define targets
+#
+ALL_TARGET	= $(BINARY)
+LINT_TARGET	= $(MODULE).lint
+INSTALL_TARGET	= $(BINARY) $(ROOTMODULE)
+
+#
+#	Overrides.
+#
+CFLAGS		+= $(CCVERBOSE)
+
+#
+#	Default build targets.
+#
+.KEEP_STATE:
+
+def:		$(DEF_DEPS)
+
+all:		$(ALL_DEPS)
+
+clean:		$(CLEAN_DEPS)
+
+clobber:	$(CLOBBER_DEPS)
+
+lint:		$(LINT_DEPS)
+
+modlintlib:	$(MODLINTLIB_DEPS)
+
+clean.lint:	$(CLEAN_LINT_DEPS)
+
+install:	$(INSTALL_DEPS)
+
+#
+#	Include common targets.
+#
+include $(UTSBASE)/intel/Makefile.targ
--- a/usr/src/uts/sparc/Makefile.sparc.shared	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/uts/sparc/Makefile.sparc.shared	Mon Apr 02 21:38:04 2007 -0700
@@ -334,7 +334,7 @@
 #
 FS_KMODS	+= dev devfs fdfs fifofs hsfs lofs namefs nfs pcfs tmpfs zfs
 FS_KMODS	+= specfs udfs ufs autofs cachefs procfs sockfs mntfs
-FS_KMODS	+= ctfs objfs
+FS_KMODS	+= ctfs objfs sharefs
 
 #
 #	Streams Modules (/kernel/strmod):
--- a/usr/src/uts/sparc/os/name_to_sysnum	Mon Apr 02 19:52:20 2007 -0700
+++ b/usr/src/uts/sparc/os/name_to_sysnum	Mon Apr 02 21:38:04 2007 -0700
@@ -123,6 +123,7 @@
 sysconfig		137
 adjtime			138
 systeminfo		139
+sharefs			140
 seteuid			141
 forksys			142
 fork1			143
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/sparc/sharefs/Makefile	Mon Apr 02 21:38:04 2007 -0700
@@ -0,0 +1,87 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+#	This makefile drives the production of the sharetab file system
+#	kernel module.
+#
+#	sparc architecture dependent
+#
+
+#
+#	Path to the base of the uts directory tree (usually /usr/src/uts).
+#
+UTSBASE	= ../..
+
+#
+#	Define the module and object file sets.
+#
+MODULE		= sharefs
+OBJECTS		= $(SHAREFS_OBJS:%=$(OBJS_DIR)/%)
+LINTS		= $(SHAREFS_OBJS:%.o=$(LINTS_DIR)/%.ln)
+ROOTMODULE	= $(ROOT_FS_DIR)/$(MODULE)
+
+#
+#	Include common rules.
+#
+include $(UTSBASE)/sparc/Makefile.sparc
+
+#
+#	Define targets
+#
+ALL_TARGET	= $(BINARY)
+LINT_TARGET	= $(MODULE).lint
+INSTALL_TARGET	= $(BINARY) $(ROOTMODULE)
+
+#
+#	Overrides.
+#
+CFLAGS		+= $(CCVERBOSE)
+
+#
+#	Default build targets.
+#
+.KEEP_STATE:
+
+def:		$(DEF_DEPS)
+
+all:		$(ALL_DEPS)
+
+clean:		$(CLEAN_DEPS)
+
+clobber:	$(CLOBBER_DEPS)
+
+lint:		$(LINT_DEPS)
+
+modlintlib:	$(MODLINTLIB_DEPS)
+
+clean.lint:	$(CLEAN_LINT_DEPS)
+
+install:	$(INSTALL_DEPS)
+
+#
+#	Include common targets.
+#
+include $(UTSBASE)/sparc/Makefile.targ