summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFred Isaman <iisaman@citi.umich.edu>2007-02-22 15:48:53 +1100
committerNeil Brown <neilb@suse.de>2007-02-22 15:48:53 +1100
commit5fb04a376e6d5ba940e66507e4a615f4e94116e6 (patch)
treefc75ece9014d7fd730cae73792adb681fc473d5f
parent66d8e2870b8d3e91c27a66ebc85e012a3cda9c69 (diff)
Extend the exportfs interface to pass fslocations info into the kernel.
Extend exportfs interface to pass fslocations info into the kernel, using syntax modelled after AIX. Adds "refer=" and "replicas=" options to /etc/exports to enable use of the kernel fslocation code. Signed-off-by: Fred Isaman <iisaman@citi.umich.edu> Signed-off-by: Kevin Coffman <kwc@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de>
-rw-r--r--support/include/exportfs.h7
-rw-r--r--support/include/nfslib.h2
-rw-r--r--support/nfs/exports.c37
-rw-r--r--utils/exportfs/exportfs.c14
-rw-r--r--utils/exportfs/exports.man14
-rw-r--r--utils/mountd/Makefile.am2
-rw-r--r--utils/mountd/cache.c25
7 files changed, 98 insertions, 3 deletions
diff --git a/support/include/exportfs.h b/support/include/exportfs.h
index 10f38c7..458611b 100644
--- a/support/include/exportfs.h
+++ b/support/include/exportfs.h
@@ -23,6 +23,13 @@ enum {
MCL_MAXTYPES
};
+enum {
+ FSLOC_NONE = 0,
+ FSLOC_REFER,
+ FSLOC_REPLICA,
+ FSLOC_STUB
+};
+
typedef struct mclient {
struct mclient * m_next;
char m_hostname[NFSCLNT_IDMAX+1];
diff --git a/support/include/nfslib.h b/support/include/nfslib.h
index 13a89da..c085029 100644
--- a/support/include/nfslib.h
+++ b/support/include/nfslib.h
@@ -80,6 +80,8 @@ struct exportent {
int e_nsqgids;
int e_fsid;
char * e_mountpoint;
+ int e_fslocmethod;
+ char * e_fslocdata;
char * e_uuid;
};
diff --git a/support/nfs/exports.c b/support/nfs/exports.c
index 0994ea2..31b38c3 100644
--- a/support/nfs/exports.c
+++ b/support/nfs/exports.c
@@ -100,6 +100,8 @@ getexportent(int fromkernel, int fromexports)
def_ee.e_squids = NULL;
def_ee.e_sqgids = NULL;
def_ee.e_mountpoint = NULL;
+ def_ee.e_fslocmethod = FSLOC_NONE;
+ def_ee.e_fslocdata = NULL;
def_ee.e_nsquids = 0;
def_ee.e_nsqgids = 0;
@@ -225,7 +227,22 @@ putexportent(struct exportent *ep)
if (ep->e_mountpoint)
fprintf(fp, "mountpoint%s%s,",
ep->e_mountpoint[0]?"=":"", ep->e_mountpoint);
-
+ switch (ep->e_fslocmethod) {
+ case FSLOC_NONE:
+ break;
+ case FSLOC_REFER:
+ fprintf(fp, "refer=%s,", ep->e_fslocdata);
+ break;
+ case FSLOC_REPLICA:
+ fprintf(fp, "replicas=%s,", ep->e_fslocdata);
+ break;
+ case FSLOC_STUB:
+ fprintf(fp, "fsloc=stub,");
+ break;
+ default:
+ xlog(L_ERROR, "unknown fsloc method for %s:%s",
+ ep->e_hostname, ep->e_path);
+ }
fprintf(fp, "mapping=");
switch (ep->e_maptype) {
case CLE_MAP_IDENT:
@@ -288,6 +305,8 @@ dupexportent(struct exportent *dst, struct exportent *src)
}
if (src->e_mountpoint)
dst->e_mountpoint = strdup(src->e_mountpoint);
+ if (src->e_fslocdata)
+ dst->e_fslocdata = strdup(src->e_fslocdata);
}
struct exportent *
@@ -302,6 +321,8 @@ mkexportent(char *hname, char *path, char *options)
ee.e_squids = NULL;
ee.e_sqgids = NULL;
ee.e_mountpoint = NULL;
+ ee.e_fslocmethod = FSLOC_NONE;
+ ee.e_fslocdata = NULL;
ee.e_nsquids = 0;
ee.e_nsqgids = 0;
ee.e_uuid = NULL;
@@ -483,6 +504,20 @@ bad_option:
ep->e_mountpoint = strdup(mp+1);
else
ep->e_mountpoint = strdup("");
+ } else if (strncmp(opt, "fsloc=", 6) == 0) {
+ if (strcmp(opt+6, "stub") == 0)
+ ep->e_fslocmethod = FSLOC_STUB;
+ else {
+ xlog(L_ERROR, "%s:%d: bad option %s\n",
+ flname, flline, opt);
+ goto bad_option;
+ }
+ } else if (strncmp(opt, "refer=", 6) == 0) {
+ ep->e_fslocmethod = FSLOC_REFER;
+ ep->e_fslocdata = strdup(opt+6);
+ } else if (strncmp(opt, "replicas=", 9) == 0) {
+ ep->e_fslocmethod = FSLOC_REPLICA;
+ ep->e_fslocdata = strdup(opt+9);
} else {
xlog(L_ERROR, "%s:%d: unknown keyword \"%s\"\n",
flname, flline, opt);
diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
index 2e2b6f3..40a6b56 100644
--- a/utils/exportfs/exportfs.c
+++ b/utils/exportfs/exportfs.c
@@ -418,7 +418,19 @@ dump(int verbose)
c = dumpopt(c, "anonuid=%d", ep->e_anonuid);
if (ep->e_anongid != 65534)
c = dumpopt(c, "anongid=%d", ep->e_anongid);
-
+ switch(ep->e_fslocmethod) {
+ case FSLOC_NONE:
+ break;
+ case FSLOC_REFER:
+ c = dumpopt(c, "refer=%s", ep->e_fslocdata);
+ break;
+ case FSLOC_REPLICA:
+ c = dumpopt(c, "replicas=%s", ep->e_fslocdata);
+ break;
+ case FSLOC_STUB:
+ c = dumpopt(c, "fsloc=stub");
+ break;
+ }
printf("%c\n", (c != '(')? ')' : ' ');
}
}
diff --git a/utils/exportfs/exports.man b/utils/exportfs/exports.man
index 3aa8de8..27a30f9 100644
--- a/utils/exportfs/exports.man
+++ b/utils/exportfs/exports.man
@@ -334,6 +334,20 @@ set for such kernels. Setting both a small number and a UUID is
supported so the same configuration can be made to work on old and new
kernels alike.
+.TP
+.IR refer= path@host[+host][:path@host[+host]]
+A client referencing the export point will be directed to choose from
+the given list an alternative location for the filesystem.
+(Note that the server must have a mountpoint here, though a different
+filesystem is not required; so, for example,
+.IR "mount --bind" " /path /path"
+is sufficient.)
+.TP
+.IR replicas= path@host[+host][:path@host[+host]]
+If the client asks for alternative locations for the export point, it
+will be given this list of alternatives. (Note that actual replication
+of the filesystem must be handled elsewhere.)
+
.SS User ID Mapping
.PP
.I nfsd
diff --git a/utils/mountd/Makefile.am b/utils/mountd/Makefile.am
index c8500cb..1e76cf8 100644
--- a/utils/mountd/Makefile.am
+++ b/utils/mountd/Makefile.am
@@ -8,7 +8,7 @@ KPREFIX = @kprefix@
sbin_PROGRAMS = mountd
mountd_SOURCES = mountd.c mount_dispatch.c auth.c rmtab.c cache.c \
- svc_run.c mountd.h
+ svc_run.c fsloc.c mountd.h
mountd_LDADD = ../../support/export/libexport.a \
../../support/nfs/libnfs.a \
../../support/misc/libmisc.a \
diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c
index 629d567..a14f4f2 100644
--- a/utils/mountd/cache.c
+++ b/utils/mountd/cache.c
@@ -28,6 +28,7 @@
#include "exportfs.h"
#include "mountd.h"
#include "xmalloc.h"
+#include "fsloc.h"
#include "blkid/blkid.h"
@@ -421,6 +422,29 @@ void nfsd_fh(FILE *f)
return;
}
+static void write_fsloc(FILE *f, struct exportent *ep, char *path)
+{
+ struct servers *servers;
+
+ if (ep->e_fslocmethod == FSLOC_NONE)
+ return;
+
+ servers = replicas_lookup(ep->e_fslocmethod, ep->e_fslocdata, path);
+ if (!servers)
+ return;
+ qword_print(f, "fsloc");
+ qword_printint(f, servers->h_num);
+ if (servers->h_num >= 0) {
+ int i;
+ for (i=0; i<servers->h_num; i++) {
+ qword_print(f, servers->h_mp[i]->h_host);
+ qword_print(f, servers->h_mp[i]->h_path);
+ }
+ }
+ qword_printint(f, servers->h_referral);
+ release_replicas(servers);
+}
+
static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *exp)
{
qword_print(f, domain);
@@ -441,6 +465,7 @@ static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *ex
qword_print(f, "uuid");
qword_printhex(f, exp->e_uuid, 16);
}
+ write_fsloc(f, &exp, path);
}
return qword_eol(f);
}