[PATCH 1/5] Dynamic Pseudo Root

Steve Dickson SteveD at redhat.com
Mon Feb 18 07:39:38 EST 2008


Author: Steve Dickson <steved at dickson.boston.devel.redhat.com>

   The hooks into the main line mountd that are needed for 
   dynamic pseudo root support 

    Signed-off-by: Steve Dickson <steved at redhat.com>

diff -up nfs-utils/support/include/exportfs.h.save nfs-utils/support/include/exportfs.h
--- nfs-utils/support/include/exportfs.h.save	2008-02-16 11:55:51.000000000 -0500
+++ nfs-utils/support/include/exportfs.h	2008-02-16 11:53:48.000000000 -0500
@@ -12,6 +12,17 @@
 #include <netdb.h>
 #include "nfslib.h"
 
+enum nfsd_fsid {
+	FSID_DEV = 0,
+	FSID_NUM,
+	FSID_MAJOR_MINOR,
+	FSID_ENCODE_DEV,
+	FSID_UUID4_INUM,
+	FSID_UUID8,
+	FSID_UUID16,
+	FSID_UUID16_INUM,
+};
+
 enum {
 	MCL_FQDN = 0,
 	MCL_SUBNETWORK,
diff -up nfs-utils/support/export/xtab.c.save nfs-utils/support/export/xtab.c
--- nfs-utils/support/export/xtab.c.save	2008-02-16 11:55:51.000000000 -0500
+++ nfs-utils/support/export/xtab.c	2008-02-16 12:08:46.000000000 -0500
@@ -20,6 +20,7 @@
 #include "xio.h"
 #include "xlog.h"
 
+extern int need_v4root, clean_v4root, check_v4root;
 static void cond_rename(char *newfile, char *oldfile);
 
 static int
@@ -36,6 +37,8 @@ xtab_read(char *xtab, int is_export)
 	if ((lockid = xflock(xtab, "r")) < 0)
 		return 0;
 	setexportent(xtab, "r");
+	if (check_v4root && is_export == 1)
+		need_v4root = 1;
 	while ((xp = getexportent(is_export==0, 0)) != NULL) {
 		if (!(exp = export_lookup(xp->e_hostname, xp->e_path, is_export != 1)) &&
 		    !(exp = export_create(xp, is_export!=1))) {
@@ -48,6 +51,8 @@ xtab_read(char *xtab, int is_export)
 		case 1:
 			exp->m_xtabent = 1;
 			exp->m_mayexport = 1;
+			if ((xp->e_flags & NFSEXP_FSID) && xp->e_fsid == 0)
+				need_v4root = 0;
 			break;
 		case 2:
 			exp->m_exported = -1;/* may be exported */
diff -up nfs-utils/utils/mountd/cache.c.save nfs-utils/utils/mountd/cache.c
--- nfs-utils/utils/mountd/cache.c.save	2008-02-16 11:55:51.000000000 -0500
+++ nfs-utils/utils/mountd/cache.c	2008-02-16 12:17:30.000000000 -0500
@@ -36,18 +36,6 @@
 #include "blkid/blkid.h"
 #endif
 
-
-enum nfsd_fsid {
-	FSID_DEV = 0,
-	FSID_NUM,
-	FSID_MAJOR_MINOR,
-	FSID_ENCODE_DEV,
-	FSID_UUID4_INUM,
-	FSID_UUID8,
-	FSID_UUID16,
-	FSID_UUID16_INUM,
-};
-
 /*
  * Support routines for text-based upcalls.
  * Fields are separated by spaces.
@@ -58,10 +46,12 @@ enum nfsd_fsid {
  */
 int cache_export_ent(char *domain, struct exportent *exp, char *p);
 
-
 char *lbuf  = NULL;
 int lbuflen = 0;
 extern int use_ipaddr;
+extern struct exportent *v4root_chkroot(int , unsigned int , char *);
+extern char *v4root_maproot(char *);
+extern struct exportent *v4root_isroot(char *);
 
 void auth_unix_ip(FILE *f)
 {
@@ -134,6 +124,8 @@ void auth_unix_gid(FILE *f)
 	if (readline(fileno(f), &lbuf, &lbuflen) != 1)
 		return;
 
+	xlog(D_CALL, "auth_unix_gid: '%s'", lbuf);
+
 	cp = lbuf;
 	if (qword_get_int(&cp, &uid) != 0)
 		return;
@@ -370,6 +362,10 @@ void nfsd_fh(FILE *f)
 
 	auth_reload();
 
+	if ((found = v4root_chkroot(fsidtype, fsidnum, fhuuid))) {
+		found_path = strdup(found->e_path);
+		goto found;
+	}
 	/* Now determine export point for this fsid/domain */
 	for (i=0 ; i < MCL_MAXTYPES; i++) {
 		nfs_export *next_exp;
@@ -495,7 +491,7 @@ void nfsd_fh(FILE *f)
 		 */
 		goto out;
 	}
-
+found:
 	if (found)
 		if (cache_export_ent(dom, found, found_path) < 0)
 			found = 0;
@@ -610,7 +606,7 @@ void nfsd_export(FILE *f)
 
 	char *cp;
 	int i;
-	char *dom, *path;
+	char *dom, *path, *mpath, *v4root=NULL;
 	nfs_export *exp, *found = NULL;
 	int found_type = 0;
 	struct in_addr addr;
@@ -636,6 +632,16 @@ void nfsd_export(FILE *f)
 
 	auth_reload();
 
+	 /* See if path need to be mapped to the to the pseudo root */
+	mpath = NULL;
+	if ((v4root = v4root_maproot(path))){
+		/* If its the actual pseudo root, no need to search the table */
+		if ((found = (nfs_export *)v4root_isroot(path)))
+			goto found;
+		mpath = v4root;
+	} else
+		mpath = path;
+		
 	/* now find flags for this export point in this domain */
 	for (i=0 ; i < MCL_MAXTYPES; i++) {
 		for (exp = exportlist[i]; exp; exp = exp->m_next) {
@@ -644,15 +650,16 @@ void nfsd_export(FILE *f)
 			if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT) {
 				/* if path is a mountpoint below e_path, then OK */
 				int l = strlen(exp->m_export.e_path);
-				if (strcmp(path, exp->m_export.e_path) == 0 ||
-				    (strncmp(path, exp->m_export.e_path, l) == 0 &&
-				     path[l] == '/' &&
-				     is_mountpoint(path)))
+				if (strcmp(mpath, exp->m_export.e_path) == 0 ||
+				    (strncmp(mpath, exp->m_export.e_path, l) == 0 &&
+				     mpath[l] == '/' &&
+				     is_mountpoint(mpath)))
 					/* ok */;
 				else
 					continue;
-			} else if (strcmp(path, exp->m_export.e_path) != 0)
+			} else if (strcmp(mpath, exp->m_export.e_path) != 0)
 				continue;
+
 			if (use_ipaddr) {
 				if (he == NULL) {
 					if (!inet_aton(dom, &addr))
@@ -683,13 +690,13 @@ void nfsd_export(FILE *f)
 			} else if (found_type == i && found->m_warned == 0) {
 				xlog(L_WARNING, "%s exported to both %s and %s, "
 				     "arbitrarily choosing options from first",
-				     path, found->m_client->m_hostname, exp->m_client->m_hostname,
+				     mpath, found->m_client->m_hostname, exp->m_client->m_hostname,
 				     dom);
 				found->m_warned = 1;
 			}
 		}
 	}
-
+found:
 	if (found) {
 		if (dump_to_cache(f, dom, path, &found->m_export) < 0) {
 			xlog(L_WARNING,
@@ -704,6 +711,7 @@ void nfsd_export(FILE *f)
 	xlog(D_CALL, "nfsd_export: found %p path %s", found, path ? path : NULL);
 	if (dom) free(dom);
 	if (path) free(path);
+	if (v4root) free(v4root);
 	if (he) free(he);
 }
 
diff -up nfs-utils/utils/mountd/mountd.c.save nfs-utils/utils/mountd/mountd.c
--- nfs-utils/utils/mountd/mountd.c.save	2008-02-16 11:55:51.000000000 -0500
+++ nfs-utils/utils/mountd/mountd.c	2008-02-16 12:08:46.000000000 -0500
@@ -41,6 +41,7 @@ int reverse_resolve = 0;
 int new_cache = 0;
 int manage_gids;
 int use_ipaddr = -1;
+extern int check_v4root;
 
 /* PRC: a high-availability callout program can be specified with -H
  * When this is done, the program will receive callouts whenever clients
@@ -71,6 +72,7 @@ static struct option longopts[] =
 	{ "num-threads", 1, 0, 't' },
 	{ "reverse-lookup", 0, 0, 'r' },
 	{ "manage-gids", 0, 0, 'g' },
+	{ "v4-root", 0, 0, 'R' },
 	{ NULL, 0, 0, 0 }
 };
 
@@ -169,6 +171,7 @@ killer (int sig)
 		kill(0, SIGTERM);
 		wait_for_workers();
 	}
+	v4root_umountall();
 	xlog (L_FATAL, "Caught signal %d, un-registering and exiting.", sig);
 }
 
@@ -568,7 +571,7 @@ main(int argc, char **argv)
 
 	/* Parse the command line options and arguments. */
 	opterr = 0;
-	while ((c = getopt_long(argc, argv, "o:nFd:f:p:P:hH:N:V:vrs:t:g", longopts, NULL)) != EOF)
+	while ((c = getopt_long(argc, argv, "o:nFd:f:p:P:hH:N:V:vRrs:t:g", longopts, NULL)) != EOF)
 		switch (c) {
 		case 'g':
 			manage_gids = 1;
@@ -611,6 +614,9 @@ main(int argc, char **argv)
 		case 'n':
 			_rpcfdtype = SOCK_DGRAM;
 			break;
+		case 'R':
+			check_v4root = 1;
+			break;
 		case 'r':
 			reverse_resolve = 1;
 			break;
diff -up nfs-utils/utils/mountd/auth.c.save nfs-utils/utils/mountd/auth.c
--- nfs-utils/utils/mountd/auth.c.save	2008-02-16 11:55:51.000000000 -0500
+++ nfs-utils/utils/mountd/auth.c	2008-02-16 11:53:48.000000000 -0500
@@ -21,6 +21,7 @@
 #include "mountd.h"
 #include "xmalloc.h"
 
+
 enum auth_error
 {
   bad_path,
@@ -84,6 +85,7 @@ auth_reload()
 	static int		last_fd;
 	static unsigned int	counter;
 	int			fd;
+	extern void v4root_destroy(), v4root_create();
 
 	if ((fd = open(_PATH_ETAB, O_RDONLY)) < 0) {
 		xlog(L_FATAL, "couldn't open %s", _PATH_ETAB);
@@ -98,9 +100,12 @@ auth_reload()
 		last_inode = stb.st_ino;
 	}
 
+
+	v4root_destroy();
 	export_freeall();
 	memset(&my_client, 0, sizeof(my_client));
 	xtab_export_read();
+	v4root_create();
 	check_useipaddr();
 	++counter;
 
diff -up nfs-utils/utils/mountd/mountd.man.save nfs-utils/utils/mountd/mountd.man
--- nfs-utils/utils/mountd/mountd.man.save	2008-02-16 12:09:42.000000000 -0500
+++ nfs-utils/utils/mountd/mountd.man	2008-02-16 12:09:50.000000000 -0500
@@ -125,6 +125,14 @@ If this option is not specified the defa
 .BR /var/lib/nfs
 is used.
 .TP
+.BI "\-R," "" " \-\-v4\-root"
+Dynamically allocates a pseudo root allowing NFS version 4 mounts
+to work seamlessly with existing exports configurations.
+Without this option, the pseudo root must be static defined
+with an export containing the 'fsid=0' options. See exports(5).
+.BR Note:
+the option is ignored when the pseudo root is statically defined.
+.TP
 .BI "\-r," "" " \-\-reverse\-lookup"
 mountd tracks IP addresses in the rmtab, and when a DUMP request is made (by
 someone running showmount -a, for instance), it returns IP addresses inst



More information about the NFSv4 mailing list