[PATCH 2/5] Dynamic Pseudo Root

Steve Dickson SteveD at redhat.com
Mon Feb 18 07:41:45 EST 2008


Author: Steve Dickson <steved at redhat.com>

    Main routines used in the support of dynamic pseudo roots. 

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

diff -up nfs-utils/support/export/Makefile.am.v4root nfs-utils/support/export/Makefile.am
--- nfs-utils/support/export/Makefile.am.v4root	2008-02-16 11:55:51.000000000 -0500
+++ nfs-utils/support/export/Makefile.am	2008-02-16 11:53:48.000000000 -0500
@@ -11,7 +11,7 @@ EXTRA_DIST	= mount.x
 
 noinst_LIBRARIES = libexport.a
 libexport_a_SOURCES = client.c export.c hostname.c nfsctl.c rmtab.c \
-		      xtab.c mount_clnt.c mount_xdr.c
+		      xtab.c mount_clnt.c mount_xdr.c v4root.c
 BUILT_SOURCES 	= $(GENFILES)
 
 noinst_HEADERS = mount.h
diff -up /dev/null nfs-utils/support/export/v4root.c
--- /dev/null	2008-02-13 08:13:58.514018448 -0500
+++ nfs-utils/support/export/v4root.c	2008-02-16 12:08:46.000000000 -0500
@@ -0,0 +1,214 @@
+/*
+ * support/export/v4root.c
+ *
+ * Routines that create and destroy v4 psuedo root
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "xlog.h"
+#include "exportfs.h"
+#include "nfslib.h"
+#include "misc.h"
+#include "mounts.h"
+#include "execute.h"
+
+#ifndef _PATH_PSEUDO_ROOT
+#define _PATH_PSEUDO_ROOT		NFS_STATEDIR "/v4root"
+#endif
+
+void v4root_destroy(void);
+void v4root_create(void);
+void v4root_umountall(void);
+
+int need_v4root, check_v4root;
+static char errbuf[BUFSIZ];
+static int v4root_mkroot(void);
+static int v4root_mkroot(void);
+
+static struct exportent pf_export = {
+	.e_hostname = "*",
+	.e_path     = _PATH_PSEUDO_ROOT,
+	.m_path = _PATH_PSEUDO_ROOT,
+	.e_flags = NFSEXP_READONLY | NFSEXP_ROOTSQUASH
+			| NFSEXP_NOSUBTREECHECK | NFSEXP_FSID
+			| NFSEXP_CROSSMOUNT,
+	.e_anonuid = 65534,
+	.e_anongid = 65534,
+	.e_squids = NULL,
+	.e_nsquids = 0,
+	.e_sqgids = NULL,
+	.e_nsqgids = 0,
+	.e_fsid = 0,
+	.e_mountpoint = NULL,
+};
+static struct psuedo_ent {
+	struct exportent *export;
+	char *fh;
+} psuedo_export = {NULL, NULL};
+
+int
+v4root_mount(struct mountargs *args)
+{
+	int status;
+
+	status = mount (args->spec, args->node, args->type, args->flags, args->data);
+	if (status < 0) {
+		snprintf(errbuf, BUFSIZ, "mounting %s failed: ",  args->node);
+		syserror(errbuf);
+	}
+
+	return status;
+}
+
+int
+v4root_umount(struct mountargs *args)
+{
+	int status;
+
+	if (args->flags)
+		status = umount2(args->node, args->flags);
+	else
+		status = umount(args->node);
+	if (status < 0) {
+		snprintf(errbuf, BUFSIZ, "unmounting %s failed: ",  args->node);
+		syserror(errbuf);
+	}
+
+	return status;
+}
+
+/*
+ * Destroy the psuedo root
+ */
+void
+v4root_destroy()
+{
+	if (access(_PATH_PSEUDO_ROOT, F_OK) < 0)
+		return;
+
+	psuedo_export.export = NULL;
+	psuedo_export.fh = NULL;
+	lazy_umount(_PATH_PSEUDO_ROOT);
+	exec_rmdir(_PATH_PSEUDO_ROOT);
+}
+
+/*
+ * Create the psuedo root directory
+ */
+static int
+v4root_mkroot()
+{
+	struct stat sb;
+
+	if (stat(_PATH_PSEUDO_ROOT, &sb) < 0) {
+		if (errno != ENOENT) {
+			syserror(_PATH_PSEUDO_ROOT);
+			return 1;
+		}
+		if (mkdir(_PATH_PSEUDO_ROOT, 0755) < 0) {
+			syserror("Unable to create " _PATH_PSEUDO_ROOT);
+			return 1;
+		}
+	} else if (!S_ISDIR(sb.st_mode)) {
+		errno =  ENOTDIR;
+		syserror(_PATH_PSEUDO_ROOT);
+		return 1;
+	}
+
+	return 0;
+}
+/*
+ * Creat the psuedo tree by running through
+ * the exports and bind mounting them to 
+ * directories in the tree
+ */
+void
+v4root_create()
+{
+	nfs_export	*exp, *nxt;
+	char path[BUFSIZ];
+	int		i;
+
+	if (!need_v4root)
+		return;
+
+	if (v4root_mkroot())
+		return;
+
+	if (!is_mountpoint(_PATH_PSEUDO_ROOT))
+		tmpfs_mount(_PATH_PSEUDO_ROOT);
+
+	for (i = 0; i < MCL_MAXTYPES; i++) {
+		for (exp = exportlist[i]; exp; exp = nxt) {
+			nxt = exp->m_next;
+			snprintf(path, BUFSIZ, "%s/%s", _PATH_PSEUDO_ROOT, 
+				exp->m_export.e_path);
+			if (!is_mountpoint(path)) {
+				exec_mkpath(path);
+				bind_mount(exp->m_export.e_path, path);
+			}
+		}
+	}
+	psuedo_export.export = &pf_export;
+}
+
+void
+v4root_umountall()
+{
+	v4root_destroy();
+}
+struct exportent *
+v4root_chkroot(int fsidtype, unsigned int fsidnum, char *fhuuid)
+{
+	struct exportent *psuedo_root = NULL;
+
+	if (psuedo_export.export == NULL)
+		return NULL;
+
+	switch(fsidtype) {
+		case FSID_NUM:
+			if (fsidnum == 0)
+				psuedo_root = psuedo_export.export;
+			break;
+	}
+
+	return psuedo_root;
+}
+char *
+v4root_maproot(char *path)
+{
+	char *mpath;
+
+	if (psuedo_export.export == NULL)
+		return NULL;
+
+	if (strstr(path, _PATH_PSEUDO_ROOT) == NULL)
+		return NULL;
+
+	if (strcmp(path, _PATH_PSEUDO_ROOT) != NULL) 
+		mpath = strdup(path + strlen(_PATH_PSEUDO_ROOT));
+	else
+		mpath = strdup(_PATH_PSEUDO_ROOT);
+
+	return mpath;
+}
+struct exportent *
+v4root_isroot(char *path)
+{
+	if (psuedo_export.export == NULL)
+		return NULL;
+
+	if (strcmp(path, _PATH_PSEUDO_ROOT) != NULL) 
+		return NULL;
+
+	return psuedo_export.export;
+}


More information about the NFSv4 mailing list