X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=utils%2Fmountd%2Fcache.c;h=e8d72fa0beb1bd366ad213e07e17128ec8c401e9;hb=742190194badb6f08a4934c254d642cbf014c84e;hp=2f13f03ec9a61247228d3c4e347488c7393e3af5;hpb=291ea6c6470d4f3aa177044bc9755880c997d3d4;p=nfs-utils.git diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c index 2f13f03..e8d72fa 100644 --- a/utils/mountd/cache.c +++ b/utils/mountd/cache.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "misc.h" #include "nfslib.h" #include "exportfs.h" @@ -30,7 +31,9 @@ #include "xmalloc.h" #include "fsloc.h" +#ifdef USE_BLKID #include "blkid/blkid.h" +#endif enum nfsd_fsid { @@ -151,6 +154,7 @@ void auth_unix_gid(FILE *f) free(groups); } +#if USE_BLKID int get_uuid(char *path, char *uuid, int uuidlen, char *u) { /* extract hex digits from uuidstr and compose a uuid @@ -215,7 +219,32 @@ int get_uuid(char *path, char *uuid, int uuidlen, char *u) } return 1; } - +#endif + +/* Iterate through /etc/mtab, finding mountpoints + * at or below a given path + */ +static char *next_mnt(void **v, char *p) +{ + FILE *f; + struct mntent *me; + int l = strlen(p); + if (*v == NULL) { + f = setmntent("/etc/mtab", "r"); + *v = f; + } else + f = *v; + while ((me = getmntent(f)) != NULL && + (strncmp(me->mnt_dir, p, l) != 0 || + me->mnt_dir[l] != '/')) + ; + if (me == NULL) { + endmntent(f); + *v = NULL; + return NULL; + } + return me->mnt_dir; +} void nfsd_fh(FILE *f) { @@ -234,6 +263,7 @@ void nfsd_fh(FILE *f) unsigned int fsidnum=0; char fsid[32]; struct exportent *found = NULL; + char *found_path = NULL; nfs_export *exp; int i; int dev_missing = 0; @@ -328,9 +358,35 @@ void nfsd_fh(FILE *f) /* Now determine export point for this fsid/domain */ for (i=0 ; i < MCL_MAXTYPES; i++) { - for (exp = exportlist[i]; exp; exp = exp->m_next) { + nfs_export *next_exp; + for (exp = exportlist[i]; exp; exp = next_exp) { struct stat stb; - char u[16]; + char u[16]; + char *path; + + if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT) { + static nfs_export *prev = NULL; + static void *mnt = NULL; + + if (prev == exp) { + /* try a submount */ + path = next_mnt(&mnt, exp->m_export.e_path); + if (!path) { + next_exp = exp->m_next; + prev = NULL; + continue; + } + next_exp = exp; + } else { + prev = exp; + mnt = NULL; + path = exp->m_export.e_path; + next_exp = exp; + } + } else { + path = exp->m_export.e_path; + next_exp = exp->m_next; + } if (!client_member(dom, exp->m_client->m_hostname)) continue; @@ -339,7 +395,7 @@ void nfsd_fh(FILE *f) exp->m_export.e_mountpoint: exp->m_export.e_path)) dev_missing ++; - if (stat(exp->m_export.e_path, &stb) != 0) + if (stat(path, &stb) != 0) continue; switch(fsidtype){ case FSID_DEV: @@ -363,27 +419,32 @@ void nfsd_fh(FILE *f) goto check_uuid; case FSID_UUID8: case FSID_UUID16: - if (!is_mountpoint(exp->m_export.e_path)) + if (!is_mountpoint(path)) continue; check_uuid: +#if USE_BLKID if (exp->m_export.e_uuid) get_uuid(NULL, exp->m_export.e_uuid, uuidlen, u); - else if (get_uuid(exp->m_export.e_path, NULL, + else if (get_uuid(path, NULL, uuidlen, u) == 0) continue; if (memcmp(u, fhuuid, uuidlen) != 0) continue; break; +#else + continue; +#endif } /* It's a match !! */ - if (!found) + if (!found) { found = &exp->m_export; - else if (strcmp(found->e_path, exp->m_export.e_path)!= 0) + found_path = strdup(path); + } else if (strcmp(found->e_path, exp->m_export.e_path)!= 0) { xlog(L_WARNING, "%s and %s have same filehandle for %s, using first", - found->e_path, exp->m_export.e_path, dom); + found_path, path, dom); } } } @@ -408,7 +469,7 @@ void nfsd_fh(FILE *f) } if (found) - cache_export_ent(dom, found, found->e_path); + cache_export_ent(dom, found, found_path); qword_print(f, dom); qword_printint(f, fsidtype); @@ -464,6 +525,7 @@ static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *ex qword_printint(f, exp->e_anongid); qword_printint(f, exp->e_fsid); write_fsloc(f, exp, path); +#if USE_BLKID if (exp->e_uuid == NULL) { char u[16]; if (get_uuid(path, NULL, 16, u)) { @@ -474,6 +536,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); } +#endif } return qword_eol(f); }