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
59 set_pseudofs_security(struct exportent *pseudo, struct exportent *source)
64 if (source->e_flags & NFSEXP_INSECURE_PORT)
65 pseudo->e_flags |= NFSEXP_INSECURE_PORT;
66 if ((source->e_flags & NFSEXP_ROOTSQUASH) == 0)
67 pseudo->e_flags &= ~NFSEXP_ROOTSQUASH;
68 for (se = source->e_secinfo; se->flav; se++) {
69 struct sec_entry *new;
71 i = secinfo_addflavor(se->flav, pseudo);
72 new = &pseudo->e_secinfo[i];
74 if (se->flags & NFSEXP_INSECURE_PORT)
75 new->flags |= NFSEXP_INSECURE_PORT;
80 * Create a pseudo export
82 static struct exportent *
83 v4root_create(char *path, nfs_export *export)
87 struct exportent *curexp = &export->m_export;
89 dupexportent(&eep, &pseudo_root.m_export);
90 eep.e_hostname = curexp->e_hostname;
91 strncpy(eep.e_path, path, sizeof(eep.e_path));
92 if (strcmp(path, "/") != 0)
93 eep.e_flags &= ~NFSEXP_FSID;
94 set_pseudofs_security(&eep, curexp);
95 exp = export_create(&eep, 0);
98 xlog(D_CALL, "v4root_create: path '%s' flags 0x%x",
99 exp->m_export.e_path, exp->m_export.e_flags);
100 return &exp->m_export;
104 * Make sure the kernel has pseudo root support.
109 struct export_features *ef;
110 static int warned = 0;
112 ef = get_export_features();
114 if (ef->flags & NFSEXP_V4ROOT)
117 xlog(L_WARNING, "Kernel does not have pseudo root support.");
118 xlog(L_WARNING, "NFS v4 mounts will be disabled unless fsid=0");
119 xlog(L_WARNING, "is specfied in /etc/exports file.");
126 pseudofs_update(char *hostname, char *path, nfs_export *source)
130 exp = export_lookup(hostname, path, 0);
131 if (exp && !(exp->m_export.e_flags & NFSEXP_V4ROOT))
134 if (v4root_create(path, source) == NULL) {
135 xlog(L_WARNING, "v4root_set: Unable to create "
136 "pseudo export for '%s'", path);
141 /* Update an existing V4ROOT export: */
142 set_pseudofs_security(&exp->m_export, &source->m_export);
146 static int v4root_add_parents(nfs_export *exp)
148 char *hostname = exp->m_export.e_hostname;
152 path = strdup(exp->m_export.e_path);
154 xlog(L_WARNING, "v4root_add_parents: Unable to create "
155 "pseudo export for '%s'", exp->m_export.e_path);
158 for (ptr = path; ptr; ptr = strchr(ptr, '/')) {
164 ret = pseudofs_update(hostname, *path ? path : "/", exp);
175 * Create pseudo exports by running through the real export
176 * looking at the components of the path that make up the export.
177 * Those path components, if not exported, will become pseudo
178 * exports allowing them to be found when the kernel does an upcall
179 * looking for components of the v4 mount.
189 if (!v4root_support())
192 for (i = 0; i < MCL_MAXTYPES; i++) {
193 for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
194 if (exp->m_export.e_flags & NFSEXP_V4ROOT)
196 * We just added this one, so its
197 * parents are already dealt with!
201 if (strcmp(exp->m_export.e_path, "/") == 0 &&
202 !(exp->m_export.e_flags & NFSEXP_FSID)) {
203 /* Force '/' to be exported as fsid == 0*/
204 exp->m_export.e_flags |= NFSEXP_FSID;
205 exp->m_export.e_fsid = 0;
208 v4root_add_parents(exp);
209 /* XXX: error handling! */