Messages in this thread Patch in this message | | | From | (H.J. Lu) | Subject | Re: kexportfs features | Date | Sun, 13 Sep 1998 10:39:48 -0700 (PDT) |
| |
> > >>>"G. Allen Morris III" said: > > There are several improvements that I need to be made to kexportfs > > IMHO. > > > > 1. The Clients should be stored in xtab as IP numbers. > > Right now kmountd can hang for a long time on start-up > > trying to resolve names. It calls auth_init before > > it forks. I don't see any down side to this, but I > > can be myopic at times.
I moved auth_init to just before svc_run.
> > > > 2. If the kernel rejects an export kexportfs still makes an > > entry in the xtab file. This would not be a problem except > > that the order that kmountd will mount these after a reboot > > is not clear.
Please check if my patch enclosed here fixes it.
> > > > 3. The command `kexport -u bob:/usr' should unexport bob.site.net if > > that is what `bob' resolves to. I think that fixing 1. above will > > fix this problem as well. Since all lookups can be done by IP.
Done.
> > 4. There needs to be a `devived export' list. The problem is that if there > is a wildcard export like :/. If host `A' mounts / and then > `kexportfs -au' is executed followed by a `kexportfs -a' host `A' will > get a `Stale file handle' error until `kexport A:/' is executed. > Anyone have ideas on the best way to handle this problem? >
I don't know why you want to do
# kexportfs -ua # kexportfs -a
Anyway, I added "-r" to kexportfs. Please give it a try to see if it does what you want for
# kexportfs -ua # kexportfs -a
Do
# man exportfs
to see what it does.
This patch is against knfsd 980910. Please check if it fixes all the problems. If everything is ok, I will make a new knfsd.
Thanks.
H.J. ----- Index: support/export/export.c =================================================================== RCS file: /home/work/cvs/linux/knfsd/support/export/export.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 export.c --- support/export/export.c 1998/08/19 02:37:45 1.1.1.1 +++ support/export/export.c 1998/09/13 17:24:49 @@ -132,6 +132,23 @@ return NULL; } +int +export_allowed(struct hostent *hp, char *path) +{ + nfs_export *exp; + int i; + + for (i = MCL_FQDN; i < MCL_MAXTYPES; i++) { + for (exp = exportlist[i]; exp; exp = exp->m_next) { + if (!export_check(exp, hp, path)) + continue; + return 1; + } + } + + return 0; +} + nfs_export * export_lookup(char *hname, char *path) { Index: support/export/xtab.c =================================================================== RCS file: /home/work/cvs/linux/knfsd/support/export/xtab.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 xtab.c --- support/export/xtab.c 1998/08/19 02:37:45 1.1.1.1 +++ support/export/xtab.c 1998/09/13 17:23:29 @@ -15,19 +15,29 @@ #include "xlog.h" int -xtab_read(void) +xtab_read(int reexport) { struct exportent *xp; nfs_export *exp; - int lockid; + int lockid, allowed; if ((lockid = xflock(_PATH_XTAB, "r")) < 0) return 0; setexportent(_PATH_XTAB, "r"); while ((xp = getexportent()) != NULL) { - if (!(exp = export_lookup(xp->e_hostname, xp->e_path)) && - !(exp = export_create(xp))) { - continue; + exp = export_lookup(xp->e_hostname, xp->e_path); + if (!exp) { + if (reexport) { + struct hostent *hp; + hp = gethostbyname (xp->e_hostname); + allowed = hp && export_allowed (hp, xp->e_path); + } + else { + allowed = 1; + } + + if (!allowed || !(exp = export_create(xp))) + continue; } exp->m_xtabent = 1; exp->m_mayexport = 1; Index: support/include/exportfs.h =================================================================== RCS file: /home/work/cvs/linux/knfsd/support/include/exportfs.h,v retrieving revision 1.2 diff -u -r1.2 exportfs.h --- support/include/exportfs.h 1998/08/22 18:38:13 1.2 +++ support/include/exportfs.h 1998/09/13 17:23:53 @@ -56,12 +56,13 @@ void export_add(nfs_export *); nfs_export * export_lookup(char *hname, char *path); nfs_export * export_find(struct hostent *, char *path); +int export_allowed(struct hostent *, char *path); nfs_export * export_create(struct exportent *); void export_freeall(void); int export_export(nfs_export *); int export_unexport(nfs_export *); -int xtab_read(void); +int xtab_read(int reexport); int xtab_write(int append); void xtab_append(nfs_export *); Index: utils/exportfs/exportfs.c =================================================================== RCS file: /home/work/cvs/linux/knfsd/utils/exportfs/exportfs.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 exportfs.c --- utils/exportfs/exportfs.c 1998/08/19 02:37:45 1.1.1.1 +++ utils/exportfs/exportfs.c 1998/09/13 17:29:58 @@ -25,12 +25,14 @@ static void dump(int verbose); static void error(nfs_export *exp, int err); static void usage(void); +static int matchhostname(const char *h1, const char *h2); int main(int argc, char **argv) { char *options = NULL; int f_export = 1; + int f_reexport = 0; int f_all = 0; int f_verbose = 0; int f_ignore = 0; @@ -38,7 +40,7 @@ xlog_open("exportfs"); - while ((c = getopt(argc, argv, "aio:uv")) != EOF) { + while ((c = getopt(argc, argv, "aio:ruv")) != EOF) { switch(c) { case 'a': f_all = 1; @@ -49,6 +51,10 @@ case 'o': options = optarg; break; + case 'r': + f_reexport = 1; + f_all = 1; + break; case 'u': f_export = 0; break; @@ -63,7 +69,7 @@ if (!f_ignore) { export_read(_PATH_EXPORTS); - xtab_read(); + xtab_read(f_reexport); } if (optind == argc) { @@ -99,11 +105,19 @@ exp->m_client->m_hostname, exp->m_export.e_path); if (exp->m_client->m_type == MCL_FQDN) { - if (!export_export(exp)) + if (!export_export(exp)) { error(exp, errno); + exp->m_addxtab = 0; + } + else + { + exp->m_addxtab = 1; + } + } + else { + exp->m_addxtab = 1; } exp->m_xtabent = 0; /* force update */ - exp->m_addxtab = 1; } } xtab_write(0); /* replace file */ @@ -166,14 +180,41 @@ printf("exporting %s:%s\n", exp->m_client->m_hostname, exp->m_export.e_path); if (exp->m_client->m_type == MCL_FQDN) { - if (!export_export(exp)) + if (!export_export(exp)) { error(exp, errno); + exp->m_addxtab = 0; + } + else { + exp->m_addxtab = 1; + } + } + else { + exp->m_addxtab = 1; } - exp->m_addxtab = 1; xtab_write(0); } +static int +matchhostname(const char *h1, const char *h2) +{ + struct hostent *hp; + char *name; + + if (strcmp (h1, h2) == 0) + return 1; + + hp = gethostbyname (h1); + if (hp == NULL) + return 0; + + name = alloca (strlen (hp->h_name) + 1); + strcpy (name, hp->h_name); + + hp = gethostbyname (h2); + return hp && strcmp (name, hp->h_name) == 0; +} + static void unexportfs(char *arg, int verbose) { @@ -194,8 +235,8 @@ for (exp = exportlist[htype]; exp; exp = exp->m_next) { if (path && strcmp(path, exp->m_export.e_path)) continue; - if (htype != exp->m_client->m_type || - strcmp(exp->m_export.e_hostname, hname)) + if (htype != exp->m_client->m_type + || !matchhostname(exp->m_export.e_hostname, hname)) continue; if (verbose) printf("unexporting %s:%s\n", @@ -288,6 +329,6 @@ static void usage(void) { - fprintf(stderr, "usage: exportfs [-a] [host:/path]\n"); + fprintf(stderr, "usage: exportfs [-aruv] [host:/path]\n"); exit(1); } Index: utils/exportfs/exportfs.man =================================================================== RCS file: /home/work/cvs/linux/knfsd/utils/exportfs/exportfs.man,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 exportfs.man --- utils/exportfs/exportfs.man 1998/08/19 02:37:45 1.1.1.1 +++ utils/exportfs/exportfs.man 1998/09/13 17:30:49 @@ -8,6 +8,8 @@ .SH SYNOPSIS .BI "/usr/sbin/exportfs [-av] [-o " "options,.." "] [" "client:/path" " ..] .br +.BI "/usr/sbin/exportfs [-rv] [-o " "options,.." "] [" "client:/path" " ..] +.br .BI "/usr/sbin/exportfs [-av] -u [" "client:/path" " ..] .br .BI "/usr/sbin/exportfs [-v] @@ -41,6 +43,12 @@ .BI "-o " options,... Specify a list of export options in the same manner as in .BR exports(5) . +.TP +.B -r +Reexport all directories. It synchronizes /var/lib/nfs/xtab +with /etc/exports. It removes entries in /var/lib/nfs/xtab +which are deleted from /etc/exports. +.TP .TP .B -u Unexport one or more directories. Index: utils/mountd/auth.c =================================================================== RCS file: /home/work/cvs/linux/knfsd/utils/mountd/auth.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 auth.c --- utils/mountd/auth.c 1998/08/19 02:37:45 1.1.1.1 +++ utils/mountd/auth.c 1998/09/13 16:34:56 @@ -37,7 +37,7 @@ export_freeall(); // export_read(export_file); - xtab_read(); + xtab_read(0); return 1; } Index: utils/mountd/mountd.c =================================================================== RCS file: /home/work/cvs/linux/knfsd/utils/mountd/mountd.c,v retrieving revision 1.4 diff -u -r1.4 mountd.c --- utils/mountd/mountd.c 1998/09/10 17:19:28 1.4 +++ utils/mountd/mountd.c 1998/09/13 07:34:22 @@ -147,7 +147,7 @@ /* Resolve symlinks */ if (realpath(p, rpath) != NULL) { - rpath[MAXPATHLEN] = '\0'; + rpath[sizeof (rpath) - 1] = '\0'; p = rpath; } @@ -204,6 +204,7 @@ nfs_export *exp; char rpath[MAXPATHLEN+1]; char *p = *path; + char epath[MAXPATHLEN+1]; if (*p == '\0') p = "/"; @@ -213,15 +214,24 @@ /* Resolve symlinks */ if (realpath(p, rpath) != NULL) { - rpath[MAXPATHLEN] = '\0'; + rpath[sizeof (rpath) - 1] = '\0'; p = rpath; } + strncpy(epath, p, sizeof (epath)); + epath[sizeof (epath) - 1] = '\0'; - /* Now authenticate the intruder... */ - if (!(exp = auth_authenticate("mount", sin, p))) { + /* Now authenticate the intruder... + Find the longest matching exported pathname. */ + while (epath [0] == '/') { + if ((exp = auth_authenticate("mount", sin, epath))) + break; + *strrchr(epath, '/') = '\0'; + } + + if (epath [0] != '/') { *error = NFSERR_ACCES; } else if (stat(p, &stb) < 0) { - xlog(L_WARNING, "can't stat exported dir %s: %s", + xlog(L_WARNING, "can't stat dir %s: %s", p, strerror(errno)); if (errno == ENOENT) *error = NFSERR_NOENT; @@ -360,8 +370,6 @@ if (optind != argc) usage(1); - auth_init(export_file); - if (!foreground) { /* We first fork off a child. */ if ((c = fork()) > 0) @@ -377,6 +385,8 @@ setsid(); xlog_background(); } + + auth_init(export_file); svc_run(); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/faq.html
| |