[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