]> git.decadent.org.uk Git - nfs-utils.git/commitdiff
Merge branch 'upstream'
authorBen Hutchings <ben@decadent.org.uk>
Wed, 14 Jul 2010 01:47:18 +0000 (02:47 +0100)
committerBen Hutchings <ben@decadent.org.uk>
Wed, 14 Jul 2010 01:47:18 +0000 (02:47 +0100)
Conflicts:
configure
utils/mountd/Makefile.in

13 files changed:
configure
configure.in
support/include/exportfs.h
support/include/nfslib.h
support/nfs/exports.c
utils/exportfs/exportfs.c
utils/exportfs/exports.man
utils/mountd/Makefile.am
utils/mountd/Makefile.in
utils/mountd/cache.c
utils/mountd/fsloc.c [new file with mode: 0644]
utils/mountd/fsloc.h [new file with mode: 0644]
utils/showmount/showmount.c

index 5470ba9a5f3c841e08d1fcc7634556c9e4c6a21c..9772e21cc381c0f06c503d845082b441f52fd0f8 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /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>.
 #
@@ -728,8 +728,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # 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"
@@ -1447,7 +1447,7 @@ if test "$ac_init_help" = "long"; then
   # 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]...
 
@@ -1517,7 +1517,7 @@ fi
 
 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
 
@@ -1644,7 +1644,7 @@ fi
 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,
@@ -1658,7 +1658,7 @@ cat >config.log <<_ACEOF
 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 $@
@@ -2433,7 +2433,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='nfs-utils'
- VERSION='1.0.10'
+ VERSION='1.0.11'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -29445,7 +29445,7 @@ exec 6>&1
 # 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
@@ -29498,7 +29498,7 @@ Report bugs to <bug-autoconf@gnu.org>."
 _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'`\\"
 
index 59dc86932a788d8ae6522cadd273adf94c6ee9c2..61e5be241473403ad6f98d7fc0d0282d49345533 100644 (file)
@@ -1,6 +1,6 @@
 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)
index 10f38c797d8fe2e2152c77b4a6e586ece12ac2fe..458611b8f5ac3d3b0056c056b08079bd0040b965 100644 (file)
@@ -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];
index 13a89dad330e143bc79cd7ae62a1e9c45533d38d..c0850291222fa64a45273cf83600aa05ad943bdd 100644 (file)
@@ -80,6 +80,8 @@ struct exportent {
        int             e_nsqgids;
        int             e_fsid;
        char *          e_mountpoint;
+       int             e_fslocmethod;
+       char *          e_fslocdata;
        char *          e_uuid;
 };
 
index 0994ea2603c151c40cba1df5b9147c3bb7b4e705..31b38c3735b7be7776fac5cefd9e31cfa3775a53 100644 (file)
@@ -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);
index 2e2b6f38ca4ba4f9aa7da4d63adc46f8cd8f463c..40a6b56bc9fa15ccfe611af7d39ea728400f4295 100644 (file)
@@ -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 != '(')? ')' : ' ');
                }
        }
index 3aa8de8ab45b6af86d842c6f502929318556c39e..27a30f9448a73abe3aaba240cd0c2dfd4845d7f6 100644 (file)
@@ -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
index c8500cbd0b2117e66f5b071dabf84df557fd470a..1e76cf810b381ce85df789d9de193387b60a9a7a 100644 (file)
@@ -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 \
index fa814ea660886f13508a6dd637fbf50ff88c069f..b6047ee44d58dfd38e3a74d87764d55106fd4913 100644 (file)
@@ -52,7 +52,7 @@ PROGRAMS = $(sbin_PROGRAMS)
 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 \
@@ -229,7 +229,7 @@ EXTRA_DIST = $(man8_MANS)
 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 \
@@ -314,6 +314,7 @@ distclean-compile:
 
 @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@
@@ -424,6 +425,20 @@ mountd-svc_run.obj: svc_run.c
 @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
 
index 629d56746d4f498890ae5683e506d88c84fcdb37..a14f4f2987369fe8ae299e99b3a6d118c1cf42ef 100644 (file)
@@ -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);
 }
diff --git a/utils/mountd/fsloc.c b/utils/mountd/fsloc.c
new file mode 100644 (file)
index 0000000..44b5b97
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * 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);
+}
diff --git a/utils/mountd/fsloc.h b/utils/mountd/fsloc.h
new file mode 100644 (file)
index 0000000..8296d1c
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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 */
index 9979621e3c3a26d4cbcd2e994cfb3c71b0a8ece2..f3ac671c9308f08df356226c6fda10596db6eccd 100644 (file)
@@ -118,7 +118,7 @@ static int connect_nb(int fd, struct sockaddr_in *addr, struct timeval *tout)
        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;
@@ -185,6 +185,9 @@ static unsigned short getport(struct sockaddr_in *addr,
                        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
@@ -213,10 +216,10 @@ static unsigned short getport(struct sockaddr_in *addr,
                        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;