]> git.decadent.org.uk Git - nfs-utils.git/commitdiff
Merge branch 'branch-1-0'
authorNeil Brown <neilb@suse.de>
Tue, 27 Feb 2007 05:35:01 +0000 (16:35 +1100)
committerNeil Brown <neilb@suse.de>
Tue, 27 Feb 2007 05:35:01 +0000 (16:35 +1100)
aclocal/tcp-wrappers.m4
support/export/export.c
support/nfs/exports.c
utils/exportfs/exportfs.c
utils/exportfs/exports.man
utils/mountd/cache.c
utils/mountd/fsloc.c [new file with mode: 0644]
utils/mountd/fsloc.h [new file with mode: 0644]

index 0fdf6113415542bd2cc52877ad7d0d291b1ac02d..35ac8e0210d842e7294c5b3a7cfc8c04a0cbbf1c 100644 (file)
@@ -4,7 +4,7 @@ AC_DEFUN([AC_TCP_WRAPPERS],[
   AC_ARG_WITH(tcp-wrappers,
     [  --with-tcp-wrappers[[=PATH]]      Enable tcpwrappers support
                  (optionally in PATH)],
-    with_tcpw=$withval, $with_tcpw=yes)
+    with_tcpw=$withval, with_tcpw=yes)
         if test "x$with_tcpw" != "xno" ; then
             saved_LIBS="$LIBS"
             saved_LDFLAGS="$LDFLAGS"
index cfb6681093fe8e629eb38ff1289794115191b10b..a4b0788e4f6977057be760769e1b680c9440cc64 100644 (file)
@@ -240,6 +240,8 @@ export_freeall(void)
                                xfree(exp->m_export.e_sqgids);
                        if (exp->m_export.e_mountpoint)
                                free(exp->m_export.e_mountpoint);
+                       if (exp->m_export.e_fslocdata)
+                               xfree(exp->m_export.e_fslocdata);
                        xfree(exp);
                }
                exportlist[i] = NULL;
index 60cfe48d6f58038f294c4fb2d4c33739c85859dd..963801583e57ba99adeacfd434379453ad3bad3b 100644 (file)
@@ -236,9 +236,11 @@ putexportent(struct exportent *ep)
        case FSLOC_REPLICA:
                fprintf(fp, "replicas=%s,", ep->e_fslocdata);
                break;
+#ifdef DEBUG
        case FSLOC_STUB:
                fprintf(fp, "fsloc=stub,");
                break;
+#endif
        default:
                xlog(L_ERROR, "unknown fsloc method for %s:%s",
                     ep->e_hostname, ep->e_path);
@@ -504,6 +506,7 @@ bad_option:
                                ep->e_mountpoint = strdup(mp+1);
                        else
                                ep->e_mountpoint = strdup("");
+#ifdef DEBUG
                } else if (strncmp(opt, "fsloc=", 6) == 0) {
                        if (strcmp(opt+6, "stub") == 0)
                                ep->e_fslocmethod = FSLOC_STUB;
@@ -512,6 +515,7 @@ bad_option:
                                     flname, flline, opt);
                                goto bad_option;
                        }
+#endif
                } else if (strncmp(opt, "refer=", 6) == 0) {
                        ep->e_fslocmethod = FSLOC_REFER;
                        ep->e_fslocdata = strdup(opt+6);
index 40a6b56bc9fa15ccfe611af7d39ea728400f4295..22e13a35b9ac9675589fc62512a133d6d45fedc4 100644 (file)
@@ -427,9 +427,11 @@ dump(int verbose)
                        case FSLOC_REPLICA:
                                c = dumpopt(c, "replicas=%s", ep->e_fslocdata);
                                break;
+#ifdef DEBUG
                        case FSLOC_STUB:
                                c = dumpopt(c, "fsloc=stub");
                                break;
+#endif
                        }
                        printf("%c\n", (c != '(')? ')' : ' ');
                }
index 27a30f9448a73abe3aaba240cd0c2dfd4845d7f6..ab63b03cfd6be56bdd56f8fda5ae5b1b53a55f39 100644 (file)
@@ -348,6 +348,20 @@ 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.)
 
+.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 a14f4f2987369fe8ae299e99b3a6d118c1cf42ef..fbe829e2d3fc188fbe686fc78a820199b5951ac3 100644 (file)
@@ -455,6 +455,7 @@ static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *ex
                qword_printint(f, exp->e_anonuid);
                qword_printint(f, exp->e_anongid);
                qword_printint(f, exp->e_fsid);
+               write_fsloc(f, exp, path);
                if (exp->e_uuid == NULL) {
                        char u[16];
                        if (get_uuid(exp->e_path, NULL, 16, u)) {
@@ -465,7 +466,6 @@ 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);
 }
@@ -548,7 +548,7 @@ void cache_open(void)
        int i;
        for (i=0; cachelist[i].cache_name; i++ ) {
                char path[100];
-               if (!manage_gids && cachelist[i].f == auth_unix_gid)
+               if (!manage_gids && cachelist[i].cache_handle == auth_unix_gid)
                        continue;
                sprintf(path, "/proc/net/rpc/%s/channel", cachelist[i].cache_name);
                cachelist[i].f = fopen(path, "r+");
diff --git a/utils/mountd/fsloc.c b/utils/mountd/fsloc.c
new file mode 100644 (file)
index 0000000..5b094b0
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * 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) {
+               xlog(L_NOTICE, "NULL replicas pointer\n");
+               return;
+       }
+       xlog(L_NOTICE, "replicas listsize=%i\n", sp->h_num);
+       for (i=0; i<sp->h_num; i++) {
+               xlog(L_NOTICE, "    %s:%s\n",
+                      sp->h_mp[i]->h_host, sp->h_mp[i]->h_path);
+       }
+}
+
+#ifdef DEBUG
+/* 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;
+
+       xlog(L_NOTICE, "called method_stub\n");
+       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;
+}
+#endif /* DEBUG */
+
+/* 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] != '/') {
+                       xlog(L_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;
+
+       xlog(L_NOTICE, "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)
+               xlog(L_NOTICE, "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;
+#ifdef DEBUG
+       case FSLOC_STUB:
+               sp = method_stub(data);
+               break;
+#endif
+       default:
+               xlog(L_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 */