X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fmountd%2Fcache.c;h=5612a9edf547ed626f35d27d50ffc3e22aa88612;hp=629d56746d4f498890ae5683e506d88c84fcdb37;hb=e3f2d2262fed12f0f6b77c5ac1c4072d82f1e754;hpb=944011f65513aa4c1b69fa92e0f51b8aef7c1cbc diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c index 629d567..5612a9e 100644 --- a/utils/mountd/cache.c +++ b/utils/mountd/cache.c @@ -28,6 +28,7 @@ #include "exportfs.h" #include "mountd.h" #include "xmalloc.h" +#include "fsloc.h" #include "blkid/blkid.h" @@ -412,7 +413,15 @@ void nfsd_fh(FILE *f) qword_print(f, dom); qword_printint(f, fsidtype); qword_printhex(f, fsid, fsidlen); - qword_printint(f, time(0)+30*60); + /* The fsid -> path lookup can be quite expensive as it + * potentially stats and reads lots of devices, and some of those + * might have spun-down. The Answer is not likely to + * change underneath us, and an 'exportfs -f' can always + * remove this from the kernel, so use a really log + * timeout. Maybe this should be configurable on the command + * line. + */ + qword_printint(f, 0x7fffffff); if (found) qword_print(f, found->e_path); qword_eol(f); @@ -421,6 +430,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; ih_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); @@ -431,6 +463,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)) { @@ -457,6 +490,7 @@ void nfsd_export(FILE *f) int i; char *dom, *path; nfs_export *exp, *found = NULL; + int found_type = 0; if (readline(fileno(f), &lbuf, &lbuflen) != 1) @@ -483,12 +517,15 @@ void nfsd_export(FILE *f) continue; if (strcmp(path, exp->m_export.e_path)) continue; - if (!found) + if (!found) { found = exp; - else { - xlog(L_WARNING, "%s exported to both %s and %s in %s", - path, exp->m_client->m_hostname, found->m_client->m_hostname, + found_type = i; + } else if (found_type == i && found->m_warned == 0) { + xlog(L_WARNING, "%s exported to both %s and %s, " + "arbitrarily choosing options from first", + path, found->m_client->m_hostname, exp->m_client->m_hostname, dom); + found->m_warned = 1; } } } @@ -523,7 +560,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+"); @@ -579,12 +616,6 @@ int cache_export(nfs_export *exp) int err; FILE *f; - if (exp->m_export.e_maptype != CLE_MAP_IDENT) { - xlog(L_ERROR, "%s: unsupported mapping; kernel supports only 'identity' (default)", - exp->m_export.m_path); - return -1; - } - f = fopen("/proc/net/rpc/auth.unix.ip/channel", "w"); if (!f) return -1;