]> git.decadent.org.uk Git - nfs-utils.git/commitdiff
Extend the exportfs interface to pass fslocations info into the kernel.
authorFred Isaman <iisaman@citi.umich.edu>
Thu, 22 Feb 2007 04:48:53 +0000 (15:48 +1100)
committerNeil Brown <neilb@suse.de>
Thu, 22 Feb 2007 04:48:53 +0000 (15:48 +1100)
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>
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/cache.c

index 10f38c797d8fe2e2152c77b4a6e586ece12ac2fe..458611b8f5ac3d3b0056c056b08079bd0040b965 100644 (file)
@@ -23,6 +23,13 @@ enum {
        MCL_MAXTYPES
 };
 
        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];
 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_nsqgids;
        int             e_fsid;
        char *          e_mountpoint;
+       int             e_fslocmethod;
+       char *          e_fslocdata;
        char *          e_uuid;
 };
 
        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_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;
 
                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);
        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:
        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_mountpoint)
                dst->e_mountpoint = strdup(src->e_mountpoint);
+       if (src->e_fslocdata)
+               dst->e_fslocdata = strdup(src->e_fslocdata);
 }
 
 struct exportent *
 }
 
 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_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;
        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("");
                                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);
                } 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);
                                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 != '(')? ')' : ' ');
                }
        }
                        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.
 
 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
 .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 \
 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 \
 mountd_LDADD = ../../support/export/libexport.a \
               ../../support/nfs/libnfs.a \
               ../../support/misc/libmisc.a \
index 629d56746d4f498890ae5683e506d88c84fcdb37..a14f4f2987369fe8ae299e99b3a6d118c1cf42ef 100644 (file)
@@ -28,6 +28,7 @@
 #include "exportfs.h"
 #include "mountd.h"
 #include "xmalloc.h"
 #include "exportfs.h"
 #include "mountd.h"
 #include "xmalloc.h"
+#include "fsloc.h"
 
 #include "blkid/blkid.h"
 
 
 #include "blkid/blkid.h"
 
@@ -421,6 +422,29 @@ void nfsd_fh(FILE *f)
        return;         
 }
 
        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);
 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);
                }
                        qword_print(f, "uuid");
                        qword_printhex(f, exp->e_uuid, 16);
                }
+               write_fsloc(f, &exp, path);
        }
        return qword_eol(f);
 }
        }
        return qword_eol(f);
 }