[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