[PATCH 5/5] Dynamic Pseudo Root

Steve Dickson SteveD at redhat.com
Mon Feb 18 07:46:42 EST 2008


Author: Steve Dickson <steved at redhat.com>

    To correctly build the v4root mount tree, the export
    paths have to be sort shortest to longest. So the exports
    are sorted into a queue and then that sorted queue is
    used to do the bind mounts.
    
    Signed-off-by: Steve Dickson <steved at redhat.com>

diff -up nfs-utils/support/export/v4root.c.save3 nfs-utils/support/export/v4root.c
--- nfs-utils/support/export/v4root.c.save3	2008-02-16 12:38:21.000000000 -0500
+++ nfs-utils/support/export/v4root.c	2008-02-16 12:40:27.000000000 -0500
@@ -11,6 +11,10 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/queue.h>
+#include <stdio.h>
+#include <stdlib.h>
+
 #include <unistd.h>
 #include <errno.h>
 
@@ -25,6 +29,27 @@
 #define _PATH_PSEUDO_ROOT		NFS_STATEDIR "/v4root"
 #endif
 
+struct mounts_t {
+	TAILQ_ENTRY(mounts_t) list;
+	nfs_export	*exp;
+};
+TAILQ_HEAD(mount_list, mounts_t) head = LIST_HEAD_INITIALIZER(head);
+#define QUE_SORT(_m1) { \
+	if (TAILQ_EMPTY(&head)) \
+		TAILQ_INSERT_HEAD(&head, _m1, list); \
+	else { \
+		TAILQ_FOREACH(m2, &head, list) { \
+			if (strlen(m2->exp->m_export.e_path) > \
+					strlen(_m1->exp->m_export.e_path)) { \
+				TAILQ_INSERT_BEFORE(m2, _m1, list); \
+				break; \
+			} \
+		} \
+		if (m2 == NULL) \
+			TAILQ_INSERT_TAIL(&head, _m1, list); \
+	} \
+}
+
 void v4root_destroy(void);
 void v4root_create(void);
 void v4root_umountall(void);
@@ -141,6 +166,7 @@ void
 v4root_create()
 {
 	nfs_export	*exp, *nxt;
+	struct mounts_t *m1, *m2;
 	char path[BUFSIZ];
 	int		i;
 
@@ -153,16 +179,37 @@ v4root_create()
 	if (!is_mountpoint(_PATH_PSEUDO_ROOT))
 		tmpfs_mount(_PATH_PSEUDO_ROOT);
 
-	for (i = 0; i < MCL_MAXTYPES; i++) {
+	/*
+	 * To build the mount tree correctly, we
+	 * mount shortest path to longest path.
+	 * So run through exports sorting the paths
+	 * by shortest to longest into a queue
+	 */
+	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);
-			}
+
+			m1 = (struct mounts_t *)malloc(sizeof(struct mounts_t));
+			m1->exp = exp;
+			QUE_SORT(m1);
 		}
+
+	/*
+	 * Now run through the sorted queue creating the
+	 * bind mounts as well as freeing the que elements.
+	 */
+	m1 = TAILQ_FIRST(&head);
+	while (m1 != NULL) {
+		exp = m1->exp;
+
+		snprintf(path, BUFSIZ, "%s/%s", _PATH_PSEUDO_ROOT, 
+			exp->m_export.e_path);
+		exec_mkpath(path);
+		bind_mount(exp->m_export.e_path, path);
+		
+		m2 =  TAILQ_NEXT(m1, list);
+		free(m1);
+		m1 = m2;
 	}
 	psuedo_export.export = &pf_export;
 }


More information about the NFSv4 mailing list