2 * Copyright (C) 2009 Red Hat <nfs@redhat.com>
4 * support/export/v4root.c
6 * Routines used to support NFSv4 pseudo roots
14 #include <sys/types.h>
16 #include <sys/queue.h>
32 static nfs_export pseudo_root = {
38 .e_flags = NFSEXP_READONLY | NFSEXP_ROOTSQUASH
39 | NFSEXP_NOSUBTREECHECK | NFSEXP_FSID
58 void set_pseudofs_security(struct exportent *pseudo, struct exportent *source)
63 if (source->e_flags & NFSEXP_INSECURE_PORT)
64 pseudo->e_flags |= NFSEXP_INSECURE_PORT;
65 for (se = source->e_secinfo; se->flav; se++) {
66 struct sec_entry *new;
68 i = secinfo_addflavor(se->flav, pseudo);
69 new = &pseudo->e_secinfo[i];
71 if (se->flags & NFSEXP_INSECURE_PORT)
72 new->flags |= NFSEXP_INSECURE_PORT;
77 * Create a pseudo export
79 static struct exportent *
80 v4root_create(char *path, nfs_export *export)
84 struct exportent *curexp = &export->m_export;
86 dupexportent(&eep, &pseudo_root.m_export);
87 eep.e_hostname = curexp->e_hostname;
88 strncpy(eep.e_path, path, sizeof(eep.e_path));
89 if (strcmp(path, "/") != 0)
90 eep.e_flags &= ~NFSEXP_FSID;
91 set_pseudofs_security(&eep, curexp);
92 exp = export_create(&eep, 0);
95 xlog(D_CALL, "v4root_create: path '%s'", exp->m_export.e_path);
96 return &exp->m_export;
100 * Make sure the kernel has pseudo root support.
105 struct export_features *ef;
106 static int warned = 0;
108 ef = get_export_features();
110 if (ef->flags & NFSEXP_V4ROOT)
113 xlog(L_WARNING, "Kernel does not have pseudo root support.");
114 xlog(L_WARNING, "NFS v4 mounts will be disabled unless fsid=0");
115 xlog(L_WARNING, "is specfied in /etc/exports file.");
121 int pseudofs_update(char *hostname, char *path, nfs_export *source)
125 exp = export_lookup(hostname, path, 0);
126 if (exp && !(exp->m_export.e_flags & NFSEXP_V4ROOT))
129 if (v4root_create(path, source) == NULL) {
130 xlog(L_WARNING, "v4root_set: Unable to create "
131 "pseudo export for '%s'", path);
136 /* Update an existing V4ROOT export: */
137 set_pseudofs_security(&exp->m_export, &source->m_export);
141 static int v4root_add_parents(nfs_export *exp)
143 char *hostname = exp->m_export.e_hostname;
147 path = strdup(exp->m_export.e_path);
149 xlog(L_WARNING, "v4root_add_parents: Unable to create "
150 "pseudo export for '%s'", exp->m_export.e_path);
153 for (ptr = path; ptr; ptr = strchr(ptr, '/')) {
159 ret = pseudofs_update(hostname, *path ? path : "/", exp);
170 * Create pseudo exports by running through the real export
171 * looking at the components of the path that make up the export.
172 * Those path components, if not exported, will become pseudo
173 * exports allowing them to be found when the kernel does an upcall
174 * looking for components of the v4 mount.
184 if (!v4root_support())
187 for (i = 0; i < MCL_MAXTYPES; i++) {
188 for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
189 if (exp->m_export.e_flags & NFSEXP_V4ROOT)
191 * We just added this one, so its
192 * parents are already dealt with!
196 if (strcmp(exp->m_export.e_path, "/") == 0 &&
197 !(exp->m_export.e_flags & NFSEXP_FSID)) {
198 /* Force '/' to be exported as fsid == 0*/
199 exp->m_export.e_flags |= NFSEXP_FSID;
200 exp->m_export.e_fsid = 0;
203 v4root_add_parents(exp);
204 /* XXX: error handling! */