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];
int e_nsqgids;
int e_fsid;
char * e_mountpoint;
+ int e_fslocmethod;
+ char * e_fslocdata;
char * e_uuid;
};
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;
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:
}
if (src->e_mountpoint)
dst->e_mountpoint = strdup(src->e_mountpoint);
+ if (src->e_fslocdata)
+ dst->e_fslocdata = strdup(src->e_fslocdata);
}
struct exportent *
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;
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);
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 != '(')? ')' : ' ');
}
}
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
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 \
#include "exportfs.h"
#include "mountd.h"
#include "xmalloc.h"
+#include "fsloc.h"
#include "blkid/blkid.h"
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);
qword_print(f, "uuid");
qword_printhex(f, exp->e_uuid, 16);
}
+ write_fsloc(f, &exp, path);
}
return qword_eol(f);
}