summaryrefslogtreecommitdiffstats
path: root/support
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2009-12-14 17:07:19 -0500
committerSteve Dickson <steved@redhat.com>2010-01-13 15:39:14 -0500
commitd778309abd38fcd6a240448606192b9ef3411565 (patch)
treec07979cf6f7feed37c7ba1f9bb88aa2262e69291 /support
parentf783ec6a999e424054ccab773e7c6ba6b38eb1fe (diff)
downloadnfs-utils-d778309abd38fcd6a240448606192b9ef3411565.tar.gz
nfs-utils-d778309abd38fcd6a240448606192b9ef3411565.tar.xz
nfs-utils-d778309abd38fcd6a240448606192b9ef3411565.zip
exports: let kernel decide which flags vary by flavor
Query the kernel to ask which flavors vary by pseudoflavor, and use that instead of a fixed constant. To allow the possibility of more flags varying by pseudoflavor, use the set/clear_flags functions for all options instead of setting some by hand. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'support')
-rw-r--r--support/include/exportfs.h7
-rw-r--r--support/include/nfs/export.h12
-rw-r--r--support/nfs/exports.c83
3 files changed, 75 insertions, 27 deletions
diff --git a/support/include/exportfs.h b/support/include/exportfs.h
index a5cf482..ce7eac0 100644
--- a/support/include/exportfs.h
+++ b/support/include/exportfs.h
@@ -103,6 +103,13 @@ int rmtab_read(void);
struct nfskey * key_lookup(char *hname);
+struct export_features {
+ unsigned int flags;
+ unsigned int secinfo_flags;
+};
+
+struct export_features *get_export_features(void);
+
/* Record export error. */
extern int export_errno;
diff --git a/support/include/nfs/export.h b/support/include/nfs/export.h
index f7a99ba..d3e188c 100644
--- a/support/include/nfs/export.h
+++ b/support/include/nfs/export.h
@@ -24,6 +24,16 @@
#define NFSEXP_FSID 0x2000
#define NFSEXP_CROSSMOUNT 0x4000
#define NFSEXP_NOACL 0x8000 /* reserved for possible ACL related use */
-#define NFSEXP_ALLFLAGS 0xFFFF
+/*
+ * All flags supported by the kernel before addition of the
+ * export_features interface:
+ */
+#define NFSEXP_OLDFLAGS 0x7E3F
+/*
+ * Flags that can vary per flavor, for kernels before addition of the
+ * export_features interface:
+ */
+#define NFSEXP_OLD_SECINFO_FLAGS (NFSEXP_READONLY | NFSEXP_ROOTSQUASH \
+ | NFSEXP_ALLSQUASH)
#endif /* _NSF_EXPORT_H */
diff --git a/support/nfs/exports.c b/support/nfs/exports.c
index f1ca632..ef31a85 100644
--- a/support/nfs/exports.c
+++ b/support/nfs/exports.c
@@ -467,9 +467,6 @@ static void clearflags(int mask, unsigned int active, struct exportent *ep)
}
}
-/* options that can vary per flavor: */
-#define NFSEXP_SECINFO_FLAGS (NFSEXP_READONLY | NFSEXP_ROOTSQUASH \
- | NFSEXP_ALLSQUASH)
/*
* For those flags which are not allowed to vary by pseudoflavor,
* ensure that the export flags agree with the flags on each
@@ -477,10 +474,12 @@ static void clearflags(int mask, unsigned int active, struct exportent *ep)
*/
static void fix_pseudoflavor_flags(struct exportent *ep)
{
+ struct export_features *ef;
struct sec_entry *p;
+ ef = get_export_features();
for (p = ep->e_secinfo; p->flav; p++)
- p->flags |= ep->e_flags & ~NFSEXP_SECINFO_FLAGS;
+ p->flags |= ep->e_flags & ~ef->secinfo_flags;
}
/*
@@ -518,25 +517,25 @@ parseopts(char *cp, struct exportent *ep, int warn, int *had_subtree_opt_ptr)
else if (strcmp(opt, "rw") == 0)
clearflags(NFSEXP_READONLY, active, ep);
else if (!strcmp(opt, "secure"))
- ep->e_flags &= ~NFSEXP_INSECURE_PORT;
+ clearflags(NFSEXP_INSECURE_PORT, active, ep);
else if (!strcmp(opt, "insecure"))
- ep->e_flags |= NFSEXP_INSECURE_PORT;
+ setflags(NFSEXP_INSECURE_PORT, active, ep);
else if (!strcmp(opt, "sync"))
- ep->e_flags &= ~NFSEXP_ASYNC;
+ clearflags(NFSEXP_ASYNC, active, ep);
else if (!strcmp(opt, "async"))
- ep->e_flags |= NFSEXP_ASYNC;
+ setflags(NFSEXP_ASYNC, active, ep);
else if (!strcmp(opt, "nohide"))
- ep->e_flags |= NFSEXP_NOHIDE;
+ setflags(NFSEXP_NOHIDE, active, ep);
else if (!strcmp(opt, "hide"))
- ep->e_flags &= ~NFSEXP_NOHIDE;
+ clearflags(NFSEXP_NOHIDE, active, ep);
else if (!strcmp(opt, "crossmnt"))
- ep->e_flags |= NFSEXP_CROSSMOUNT;
+ setflags(NFSEXP_CROSSMOUNT, active, ep);
else if (!strcmp(opt, "nocrossmnt"))
- ep->e_flags &= ~NFSEXP_CROSSMOUNT;
+ clearflags(NFSEXP_CROSSMOUNT, active, ep);
else if (!strcmp(opt, "wdelay"))
- ep->e_flags |= NFSEXP_GATHERED_WRITES;
+ setflags(NFSEXP_GATHERED_WRITES, active, ep);
else if (!strcmp(opt, "no_wdelay"))
- ep->e_flags &= ~NFSEXP_GATHERED_WRITES;
+ clearflags(NFSEXP_GATHERED_WRITES, active, ep);
else if (strcmp(opt, "root_squash") == 0)
setflags(NFSEXP_ROOTSQUASH, active, ep);
else if (!strcmp(opt, "no_root_squash"))
@@ -547,22 +546,22 @@ parseopts(char *cp, struct exportent *ep, int warn, int *had_subtree_opt_ptr)
clearflags(NFSEXP_ALLSQUASH, active, ep);
else if (strcmp(opt, "subtree_check") == 0) {
had_subtree_opt = 1;
- ep->e_flags &= ~NFSEXP_NOSUBTREECHECK;
+ clearflags(NFSEXP_NOSUBTREECHECK, active, ep);
} else if (strcmp(opt, "no_subtree_check") == 0) {
had_subtree_opt = 1;
- ep->e_flags |= NFSEXP_NOSUBTREECHECK;
+ setflags(NFSEXP_NOSUBTREECHECK, active, ep);
} else if (strcmp(opt, "auth_nlm") == 0)
- ep->e_flags &= ~NFSEXP_NOAUTHNLM;
+ clearflags(NFSEXP_NOAUTHNLM, active, ep);
else if (strcmp(opt, "no_auth_nlm") == 0)
- ep->e_flags |= NFSEXP_NOAUTHNLM;
+ setflags(NFSEXP_NOAUTHNLM, active, ep);
else if (strcmp(opt, "secure_locks") == 0)
- ep->e_flags &= ~NFSEXP_NOAUTHNLM;
+ clearflags(NFSEXP_NOAUTHNLM, active, ep);
else if (strcmp(opt, "insecure_locks") == 0)
- ep->e_flags |= NFSEXP_NOAUTHNLM;
+ setflags(NFSEXP_NOAUTHNLM, active, ep);
else if (strcmp(opt, "acl") == 0)
- ep->e_flags &= ~NFSEXP_NOACL;
+ clearflags(NFSEXP_NOACL, active, ep);
else if (strcmp(opt, "no_acl") == 0)
- ep->e_flags |= NFSEXP_NOACL;
+ setflags(NFSEXP_NOACL, active, ep);
else if (strncmp(opt, "anonuid=", 8) == 0) {
char *oe;
ep->e_anonuid = strtol(opt+8, &oe, 10);
@@ -594,11 +593,11 @@ bad_option:
char *oe;
if (strcmp(opt+5, "root") == 0) {
ep->e_fsid = 0;
- ep->e_flags |= NFSEXP_FSID;
+ setflags(NFSEXP_FSID, active, ep);
} else {
ep->e_fsid = strtoul(opt+5, &oe, 0);
if (opt[5]!='\0' && *oe == '\0')
- ep->e_flags |= NFSEXP_FSID;
+ setflags(NFSEXP_FSID, active, ep);
else if (valid_uuid(opt+5))
ep->e_uuid = strdup(opt+5);
else {
@@ -639,19 +638,20 @@ bad_option:
} else {
xlog(L_ERROR, "%s:%d: unknown keyword \"%s\"\n",
flname, flline, opt);
- ep->e_flags |= NFSEXP_ALLSQUASH | NFSEXP_READONLY;
+ setflags(NFSEXP_ALLSQUASH | NFSEXP_READONLY, active, ep);
goto bad_option;
}
free(opt);
while (isblank(*cp))
cp++;
}
+
/*
* Turn on nohide which will allow this export to cross over
* the 'mount --bind' mount point.
*/
if (ep->e_fslocdata)
- ep->e_flags |= NFSEXP_NOHIDE;
+ setflags(NFSEXP_NOHIDE, active, ep);
fix_pseudoflavor_flags(ep);
ep->e_squids = squids;
ep->e_sqgids = sqgids;
@@ -769,3 +769,34 @@ syntaxerr(char *msg)
xlog(L_ERROR, "%s:%d: syntax error: %s",
efname, efp?efp->x_line:0, msg);
}
+struct export_features *get_export_features(void)
+{
+ static char *path = "/proc/fs/nfsd/export_features";
+ static struct export_features ef;
+ static int cached = 0;
+ char buf[50];
+ int c;
+ int fd;
+
+ if (cached)
+ return &ef;
+
+ ef.flags = NFSEXP_OLDFLAGS;
+ ef.secinfo_flags = NFSEXP_OLD_SECINFO_FLAGS;
+
+ fd = open(path, O_RDONLY);
+ if (fd == -1)
+ goto good;
+ fd = read(fd, buf, 50);
+ if (fd == -1)
+ goto err;
+ c = sscanf(buf, "%x %x", &ef.flags, &ef.secinfo_flags);
+ if (c != 2)
+ goto err;
+good:
+ cached = 1;
+ return &ef;
+err:
+ xlog(L_WARNING, "unexpected error reading %s", path);
+ return &ef;
+}