[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