#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for linux nfs-utils 1.0.10.
+# Generated by GNU Autoconf 2.61 for linux nfs-utils 1.0.11.
#
# Report bugs to <nfs@lists.sf.net>.
#
# Identity of this package.
PACKAGE_NAME='linux nfs-utils'
PACKAGE_TARNAME='nfs-utils'
-PACKAGE_VERSION='1.0.10'
-PACKAGE_STRING='linux nfs-utils 1.0.10'
+PACKAGE_VERSION='1.0.11'
+PACKAGE_STRING='linux nfs-utils 1.0.11'
PACKAGE_BUGREPORT='nfs@lists.sf.net'
ac_unique_file="tools/getiversion/getiversion.c"
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures linux nfs-utils 1.0.10 to adapt to many kinds of systems.
+\`configure' configures linux nfs-utils 1.0.11 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of linux nfs-utils 1.0.10:";;
+ short | recursive ) echo "Configuration of linux nfs-utils 1.0.11:";;
esac
cat <<\_ACEOF
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-linux nfs-utils configure 1.0.10
+linux nfs-utils configure 1.0.11
generated by GNU Autoconf 2.61
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by linux nfs-utils $as_me 1.0.10, which was
+It was created by linux nfs-utils $as_me 1.0.11, which was
generated by GNU Autoconf 2.61. Invocation command line was
$ $0 $@
# Define the identity of the package.
PACKAGE='nfs-utils'
- VERSION='1.0.10'
+ VERSION='1.0.11'
cat >>confdefs.h <<_ACEOF
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by linux nfs-utils $as_me 1.0.10, which was
+This file was extended by linux nfs-utils $as_me 1.0.11, which was
generated by GNU Autoconf 2.61. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-linux nfs-utils config.status 1.0.10
+linux nfs-utils config.status 1.0.11
configured by $0, generated by GNU Autoconf 2.61,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
dnl Process this file with autoconf to produce a configure script.
dnl
-AC_INIT([linux nfs-utils],[1.0.10],[nfs@lists.sf.net],[nfs-utils])
+AC_INIT([linux nfs-utils],[1.0.11],[nfs@lists.sf.net],[nfs-utils])
AC_CANONICAL_BUILD([])
AC_CANONICAL_HOST([])
AC_CONFIG_SRCDIR(tools/getiversion/getiversion.c)
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 \
am_mountd_OBJECTS = mountd-mountd.$(OBJEXT) \
mountd-mount_dispatch.$(OBJEXT) mountd-auth.$(OBJEXT) \
mountd-rmtab.$(OBJEXT) mountd-cache.$(OBJEXT) \
- mountd-svc_run.$(OBJEXT)
+ mountd-svc_run.$(OBJEXT) mountd-fsloc.$(OBJEXT)
mountd_OBJECTS = $(am_mountd_OBJECTS)
am__DEPENDENCIES_1 =
mountd_DEPENDENCIES = ../../support/export/libexport.a \
RPCPREFIX = rpc.
KPREFIX = @kprefix@
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 \
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mountd-auth.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mountd-cache.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mountd-fsloc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mountd-mount_dispatch.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mountd-mountd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mountd-rmtab.Po@am__quote@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mountd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mountd-svc_run.obj `if test -f 'svc_run.c'; then $(CYGPATH_W) 'svc_run.c'; else $(CYGPATH_W) '$(srcdir)/svc_run.c'; fi`
+mountd-fsloc.o: fsloc.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mountd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mountd-fsloc.o -MD -MP -MF $(DEPDIR)/mountd-fsloc.Tpo -c -o mountd-fsloc.o `test -f 'fsloc.c' || echo '$(srcdir)/'`fsloc.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/mountd-fsloc.Tpo $(DEPDIR)/mountd-fsloc.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fsloc.c' object='mountd-fsloc.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mountd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mountd-fsloc.o `test -f 'fsloc.c' || echo '$(srcdir)/'`fsloc.c
+
+mountd-fsloc.obj: fsloc.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mountd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mountd-fsloc.obj -MD -MP -MF $(DEPDIR)/mountd-fsloc.Tpo -c -o mountd-fsloc.obj `if test -f 'fsloc.c'; then $(CYGPATH_W) 'fsloc.c'; else $(CYGPATH_W) '$(srcdir)/fsloc.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/mountd-fsloc.Tpo $(DEPDIR)/mountd-fsloc.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fsloc.c' object='mountd-fsloc.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mountd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mountd-fsloc.obj `if test -f 'fsloc.c'; then $(CYGPATH_W) 'fsloc.c'; else $(CYGPATH_W) '$(srcdir)/fsloc.c'; fi`
+
mostlyclean-libtool:
-rm -f *.lo
#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);
}
--- /dev/null
+/*
+ * COPYRIGHT (c) 2006
+ * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization. If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+
+#include "fsloc.h"
+#include "exportfs.h"
+
+/* Debugging tool: prints out @servers info to syslog */
+static void replicas_print(struct servers *sp)
+{
+ int i;
+ if (!sp) {
+ syslog(LOG_INFO, "NULL replicas pointer");
+ return;
+ }
+ syslog(LOG_INFO, "replicas listsize=%i", sp->h_num);
+ for (i=0; i<sp->h_num; i++) {
+ syslog(LOG_INFO, "%s:%s",
+ sp->h_mp[i]->h_host, sp->h_mp[i]->h_path);
+ }
+}
+
+/* Called by setting 'Method = stub' in config file. Just returns
+ * some syntactically correct gibberish for testing purposes.
+ */
+static struct servers *method_stub(char *key)
+{
+ struct servers *sp;
+ struct mount_point *mp;
+
+ syslog(LOG_INFO, "called method_stub");
+ sp = malloc(sizeof(struct servers));
+ if (!sp)
+ return NULL;
+ mp = calloc(1, sizeof(struct mount_point));
+ if (!mp) {
+ free(sp);
+ return NULL;
+ }
+ sp->h_num = 1;
+ sp->h_mp[0] = mp;
+ mp->h_host = strdup("stub_server");
+ mp->h_path = strdup("/my/test/path");
+ sp->h_referral = 1;
+ return sp;
+}
+
+/* Scan @list, which is a NULL-terminated array of strings of the
+ * form path@host[+host], and return corresponding servers structure.
+ */
+static struct servers *parse_list(char **list)
+{
+ int i;
+ struct servers *res;
+ struct mount_point *mp;
+ char *cp;
+
+ res = malloc(sizeof(struct servers));
+ if (!res)
+ return NULL;
+ res->h_num = 0;
+
+ /* parse each of the answers in sucession. */
+ for (i=0; list[i] && i<FSLOC_MAX_LIST; i++) {
+ mp = calloc(1, sizeof(struct mount_point));
+ if (!mp) {
+ release_replicas(res);
+ return NULL;
+ }
+ cp = strchr(list[i], '@');
+ if ((!cp) || list[i][0] != '/') {
+ syslog(LOG_WARNING, "invalid entry '%s'", list[i]);
+ continue; /* XXX Need better error handling */
+ }
+ res->h_mp[i] = mp;
+ res->h_num++;
+ mp->h_path = strndup(list[i], cp - list[i]);
+ cp++;
+ mp->h_host = strdup(cp);
+ /* hosts are '+' separated, kernel expects ':' separated */
+ while ( (cp = strchr(mp->h_host, '+')) )
+ *cp = ':';
+ }
+ return res;
+}
+
+/* @data is a string of form path@host[+host][:path@host[+host]]
+ */
+static struct servers *method_list(char *data)
+{
+ char *copy, *ptr=data;
+ char **list;
+ int i, listsize;
+ struct servers *rv=NULL;
+
+ syslog(LOG_INFO, "method_list(%s)\n", data);
+ for (ptr--, listsize=1; ptr; ptr=index(ptr, ':'), listsize++)
+ ptr++;
+ list = malloc(listsize * sizeof(char *));
+ copy = strdup(data);
+ if (copy)
+ syslog(LOG_INFO, "converted to %s\n", copy);
+ if (list && copy) {
+ ptr = copy;
+ for (i=0; i<listsize; i++) {
+ list[i] = strsep(&ptr, ":");
+ }
+ rv = parse_list(list);
+ }
+ free(copy);
+ free(list);
+ replicas_print(rv);
+ return rv;
+}
+
+/* Returns appropriately filled struct servers, or NULL if had a problem */
+struct servers *replicas_lookup(int method, char *data, char *key)
+{
+ struct servers *sp=NULL;
+ switch(method) {
+ case FSLOC_NONE:
+ break;
+ case FSLOC_REFER:
+ sp = method_list(data);
+ if (sp)
+ sp->h_referral = 1;
+ break;
+ case FSLOC_REPLICA:
+ sp = method_list(data);
+ if (sp)
+ sp->h_referral = 0;
+ break;
+ case FSLOC_STUB:
+ sp = method_stub(data);
+ break;
+ default:
+ syslog(LOG_WARNING, "Unknown method = %i", method);
+ }
+ replicas_print(sp);
+ return sp;
+}
+
+void release_replicas(struct servers *server)
+{
+ int i;
+
+ if (!server) return;
+ for (i = 0; i < server->h_num; i++) {
+ free(server->h_mp[i]->h_host);
+ free(server->h_mp[i]->h_path);
+ free(server->h_mp[i]);
+ }
+ free(server);
+}
--- /dev/null
+/*
+ * COPYRIGHT (c) 2006
+ * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization. If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+#ifndef FSLOC_H
+#define FSLOC_H
+
+#define FSLOC_MAX_LIST 40
+
+struct mount_point {
+ char *h_host;
+ char *h_path;
+};
+
+struct servers {
+ int h_num;
+ struct mount_point *h_mp[FSLOC_MAX_LIST];
+ int h_referral; /* 0=replica, 1=referral */
+};
+
+struct servers *replicas_lookup(int method, char *data, char *key);
+void release_replicas(struct servers *server);
+
+#endif /* FSLOC_H */
FD_ZERO(&rset);
FD_SET(fd, &rset);
- ret = select(fd + 1, &rset, NULL, NULL, tout);
+ ret = select(fd + 1, NULL, &rset, NULL, tout);
if (ret <= 0) {
if (ret == 0)
ret = -ETIMEDOUT;
rpc_createerr.cf_error.re_errno = errno;
return 0;
}
+ client = clnttcp_create(&saddr,
+ PMAPPROG, PMAPVERS, &sock,
+ 0, 0);
} else {
/*
* bind to any unused port. If we left this up to the rpc
sock = RPC_ANYSOCK;
/* FALLTHROUGH */
}
+ client = clntudp_bufcreate(&saddr, PMAPPROG, PMAPVERS,
+ tout, &sock, send_sz, recv_sz);
}
- client = clntudp_bufcreate(&saddr, PMAPPROG, PMAPVERS,
- tout, &sock, send_sz, recv_sz);
if (!client) {
close(sock);
rpc_createerr.cf_stat = RPC_RPCBFAILURE;