autofs-5.0.7 - probe each nfs version in turn for singleton mounts From: Ian Kent --- CHANGELOG | 1 + include/replicated.h | 2 ++ modules/mount_nfs.c | 35 ++++++++++++++++++++++++++++++++++- modules/replicated.c | 8 ++++---- 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 39d7889..48e9806 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -48,6 +48,7 @@ - fix master map mount options matching. - fix master map bogus keywork match. - fix fix map entry duplicate offset detection. +- probe each nfs version in turn for singleton mounts. 25/07/2012 autofs-5.0.7 ======================= diff --git a/include/replicated.h b/include/replicated.h index ff0e7b9..728f131 100644 --- a/include/replicated.h +++ b/include/replicated.h @@ -68,6 +68,8 @@ struct host { }; void seed_random(void); +struct host *new_host(const char *, struct sockaddr *, size_t, + unsigned int, unsigned int, unsigned int); void free_host_list(struct host **); int parse_location(unsigned, struct host **, const char *, unsigned int); int prune_host_list(unsigned, struct host **, unsigned int, int); diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c index 5424d74..81ba3ca 100644 --- a/modules/mount_nfs.c +++ b/modules/mount_nfs.c @@ -180,9 +180,42 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int * We can't probe protocol rdma so leave it to mount.nfs(8) * and and suffer the delay if a server isn't available. */ - if (!rdma) + if (rdma) + goto dont_probe; + + /* + * If this is a singleton mount, and NFSv4 only hasn't been asked + * for, and the default NFS protocol is set to v4 in the autofs + * configuration only probe NFSv4 and let mount.nfs(8) do fallback + * to NFSv3 (if it can). If the NFSv4 probe fails then probe as + * normal. + */ + if (!hosts->next && + mount_default_proto == 4 && + vers & NFS_VERS_MASK != 0 && + vers & NFS4_VERS_MASK != 0) { + unsigned int v4_probe_ok = 0; + struct host *tmp = new_host(hosts->name, + hosts->addr, hosts->addr_len, + hosts->proximity, + hosts->weight, hosts->options); + if (tmp) { + tmp->rr = hosts->rr; + prune_host_list(ap->logopt, &tmp, + NFS4_VERS_MASK|TCP_SUPPORTED, port); + /* If probe succeeds just try the mount with host in hosts */ + if (tmp) { + v4_probe_ok = 1; + free_host_list(&tmp); + } + } + if (!v4_probe_ok) + prune_host_list(ap->logopt, &hosts, vers, port); + } else { prune_host_list(ap->logopt, &hosts, vers, port); + } +dont_probe: if (!hosts) { info(ap->logopt, MODPREFIX "no hosts available"); return 1; diff --git a/modules/replicated.c b/modules/replicated.c index 6dbdade..0a044b9 100644 --- a/modules/replicated.c +++ b/modules/replicated.c @@ -280,10 +280,10 @@ static unsigned int get_proximity(struct sockaddr *host_addr) return PROXIMITY_OTHER; } -static struct host *new_host(const char *name, - struct sockaddr *addr, size_t addr_len, - unsigned int proximity, unsigned int weight, - unsigned int options) +struct host *new_host(const char *name, + struct sockaddr *addr, size_t addr_len, + unsigned int proximity, unsigned int weight, + unsigned int options) { struct host *new; struct sockaddr *tmp2;