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
57 void set_pseudofs_security(struct exportent *pseudo, struct exportent *source)
62 if (source->e_flags & NFSEXP_INSECURE_PORT)
63 pseudo->e_flags |= NFSEXP_INSECURE_PORT;
64 for (se = source->e_secinfo; se->flav; se++) {
65 struct sec_entry *new;
67 i = secinfo_addflavor(se->flav, pseudo);
68 new = &pseudo->e_secinfo[i];
70 if (se->flags & NFSEXP_INSECURE_PORT)
71 new->flags |= NFSEXP_INSECURE_PORT;
76 * Create a pseudo export
78 static struct exportent *
79 v4root_create(char *path, nfs_export *export)
83 struct exportent *curexp = &export->m_export;
85 dupexportent(&eep, &pseudo_root.m_export);
86 eep.e_hostname = strdup(curexp->e_hostname);
87 strncpy(eep.e_path, path, sizeof(eep.e_path));
88 if (strcmp(path, "/") != 0)
89 eep.e_flags &= ~NFSEXP_FSID;
90 set_pseudofs_security(&eep, curexp);
91 exp = export_create(&eep, 0);
94 xlog(D_CALL, "v4root_create: path '%s'", exp->m_export.e_path);
95 return &exp->m_export;
99 * Make sure the kernel has pseudo root support.
104 struct export_features *ef;
105 static int warned = 0;
107 ef = get_export_features();
109 if (ef->flags & NFSEXP_V4ROOT)
112 xlog(L_WARNING, "Kernel does not have pseudo root support.");
113 xlog(L_WARNING, "NFS v4 mounts will be disabled unless fsid=0");
114 xlog(L_WARNING, "is specfied in /etc/exports file.");
120 int pseudofs_update(char *hostname, char *path, nfs_export *source)
124 exp = export_lookup(hostname, path, 0);
125 if (exp && !(exp->m_export.e_flags & NFSEXP_V4ROOT))
128 if (v4root_create(path, source) == NULL) {
129 xlog(L_WARNING, "v4root_set: Unable to create "
130 "pseudo export for '%s'", path);
135 /* Update an existing V4ROOT export: */
136 set_pseudofs_security(&exp->m_export, &source->m_export);
140 static int v4root_add_parents(nfs_export *exp)
142 char *hostname = exp->m_export.e_hostname;
146 path = strdup(exp->m_export.e_path);
148 xlog(L_WARNING, "v4root_add_parents: Unable to create "
149 "pseudo export for '%s'", exp->m_export.e_path);
152 for (ptr = path + 1; ptr; ptr = strchr(ptr, '/')) {
158 ret = pseudofs_update(hostname, path, exp);
169 * Create pseudo exports by running through the real export
170 * looking at the components of the path that make up the export.
171 * Those path components, if not exported, will become pseudo
172 * exports allowing them to be found when the kernel does an upcall
173 * looking for components of the v4 mount.
183 if (!v4root_support())
186 for (i = 0; i < MCL_MAXTYPES; i++) {
187 for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
188 if (exp->m_export.e_flags & NFSEXP_V4ROOT)
190 * We just added this one, so its
191 * parents are already dealt with!
195 v4root_add_parents(exp);
196 /* XXX: error handling! */