Ian Kent a26132
autofs-5.1.4 - use_hostname_for_mounts shouldn't prevent selection among replicas
Ian Kent a26132
Ian Kent a26132
From: NeilBrown <neilb@suse.com>
Ian Kent a26132
Ian Kent a26132
If several replicas have been specified for a mount point,
Ian Kent a26132
and use_hostname_for_mount is set to "yes", the selection
Ian Kent a26132
between these replicas is currently disabled and the last in
Ian Kent a26132
the list is always chosen.
Ian Kent a26132
Ian Kent a26132
There is little point selecting between different addresses
Ian Kent a26132
for the one host in this case, but it is still worth
Ian Kent a26132
selecting between different hosts, particularly if different
Ian Kent a26132
weights have been specified.
Ian Kent a26132
Ian Kent a26132
This patch restores the "prune_host_list()" functionality
Ian Kent a26132
when use_hostname_for_mount is set, and modifies it slightly
Ian Kent a26132
so that only on IP address for any host:/path entry in the
Ian Kent a26132
config file is willl be successfully probed.  After a
Ian Kent a26132
success, further addresses from the same entry are skipped.
Ian Kent a26132
This is achieved by tracking an entry number ("ent_num") for
Ian Kent a26132
each 'struct host'.
Ian Kent a26132
Ian Kent a26132
Signed-off-by: NeilBrown <neilb@suse.com>
Ian Kent a26132
Signed-off-by: Ian Kent <raven@themaw.net>
Ian Kent a26132
---
Ian Kent a26132
 CHANGELOG            |    1 +
Ian Kent a26132
 include/replicated.h |    3 ++-
Ian Kent a26132
 modules/mount_nfs.c  |    2 +-
Ian Kent a26132
 modules/replicated.c |   35 ++++++++++++++++++++---------------
Ian Kent a26132
 4 files changed, 24 insertions(+), 17 deletions(-)
Ian Kent a26132
Ian Kent a26132
diff --git a/CHANGELOG b/CHANGELOG
Ian Kent a26132
index 2d5d5b1f..104fca90 100644
Ian Kent a26132
--- a/CHANGELOG
Ian Kent a26132
+++ b/CHANGELOG
Ian Kent a26132
@@ -9,6 +9,7 @@ xx/xx/2018 autofs-5.1.5
Ian Kent a26132
 - fix error return in do_nfs_mount().
Ian Kent a26132
 - add error handling for ext_mount_add().
Ian Kent a26132
 - account for recent libnsl changes.
Ian Kent a26132
+- use_hostname_for_mounts shouldn't prevent selection among replicas.
Ian Kent a26132
 
Ian Kent a26132
 19/12/2017 autofs-5.1.4
Ian Kent a26132
 - fix spec file url.
Ian Kent a26132
diff --git a/include/replicated.h b/include/replicated.h
Ian Kent a26132
index 69ab7800..0f482d21 100644
Ian Kent a26132
--- a/include/replicated.h
Ian Kent a26132
+++ b/include/replicated.h
Ian Kent a26132
@@ -57,6 +57,7 @@
Ian Kent a26132
 
Ian Kent a26132
 struct host {
Ian Kent a26132
 	char *name;
Ian Kent a26132
+	int ent_num;
Ian Kent a26132
 	struct sockaddr *addr;
Ian Kent a26132
 	size_t addr_len;
Ian Kent a26132
 	unsigned int rr;
Ian Kent a26132
@@ -70,7 +71,7 @@ struct host {
Ian Kent a26132
 };
Ian Kent a26132
 
Ian Kent a26132
 void seed_random(void);
Ian Kent a26132
-struct host *new_host(const char *, struct sockaddr *, size_t,
Ian Kent a26132
+struct host *new_host(const char *, int, struct sockaddr *, size_t,
Ian Kent a26132
 		      unsigned int, unsigned int, unsigned int);
Ian Kent a26132
 void free_host_list(struct host **);
Ian Kent a26132
 int parse_location(unsigned, struct host **, const char *, unsigned int);
Ian Kent a26132
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
Ian Kent a26132
index 77166544..4cf0cd27 100644
Ian Kent a26132
--- a/modules/mount_nfs.c
Ian Kent a26132
+++ b/modules/mount_nfs.c
Ian Kent a26132
@@ -236,7 +236,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
Ian Kent a26132
 	    (vers & NFS4_VERS_MASK) != 0 &&
Ian Kent a26132
 	    !(vers & UDP6_REQUESTED)) {
Ian Kent a26132
 		unsigned int v4_probe_ok = 0;
Ian Kent a26132
-		struct host *tmp = new_host(hosts->name,
Ian Kent a26132
+		struct host *tmp = new_host(hosts->name, 0,
Ian Kent a26132
 					    hosts->addr, hosts->addr_len,
Ian Kent a26132
 					    hosts->proximity,
Ian Kent a26132
 					    hosts->weight, hosts->options);
Ian Kent a26132
diff --git a/modules/replicated.c b/modules/replicated.c
Ian Kent a26132
index 3ac4c70f..f7b83236 100644
Ian Kent a26132
--- a/modules/replicated.c
Ian Kent a26132
+++ b/modules/replicated.c
Ian Kent a26132
@@ -83,7 +83,7 @@ void seed_random(void)
Ian Kent a26132
 	return;
Ian Kent a26132
 }
Ian Kent a26132
 
Ian Kent a26132
-struct host *new_host(const char *name,
Ian Kent a26132
+struct host *new_host(const char *name, int ent_num,
Ian Kent a26132
 		      struct sockaddr *addr, size_t addr_len,
Ian Kent a26132
 		      unsigned int proximity, unsigned int weight,
Ian Kent a26132
 		      unsigned int options)
Ian Kent a26132
@@ -116,6 +116,7 @@ struct host *new_host(const char *name,
Ian Kent a26132
 	memset(new, 0, sizeof(struct host));
Ian Kent a26132
 
Ian Kent a26132
 	new->name = tmp1;
Ian Kent a26132
+	new->ent_num = ent_num;
Ian Kent a26132
 	new->addr_len = addr_len;
Ian Kent a26132
 	new->addr = tmp2;
Ian Kent a26132
 	new->proximity = proximity;
Ian Kent a26132
@@ -714,7 +715,7 @@ done:
Ian Kent a26132
 int prune_host_list(unsigned logopt, struct host **list,
Ian Kent a26132
 		    unsigned int vers, int port)
Ian Kent a26132
 {
Ian Kent a26132
-	struct host *this, *last, *first;
Ian Kent a26132
+	struct host *this, *last, *first, *prev;
Ian Kent a26132
 	struct host *new = NULL;
Ian Kent a26132
 	unsigned int proximity, selected_version = 0;
Ian Kent a26132
 	unsigned int v2_tcp_count, v3_tcp_count, v4_tcp_count;
Ian Kent a26132
@@ -726,12 +727,6 @@ int prune_host_list(unsigned logopt, struct host **list,
Ian Kent a26132
 	if (!*list)
Ian Kent a26132
 		return 0;
Ian Kent a26132
 
Ian Kent a26132
-	/* If we're using the host name then there's no point probing
Ian Kent a26132
-	 * avialability and respose time.
Ian Kent a26132
-	 */
Ian Kent a26132
-	if (defaults_use_hostname_for_mounts())
Ian Kent a26132
-		return 1;
Ian Kent a26132
-
Ian Kent a26132
 	/* Use closest hosts to choose NFS version */
Ian Kent a26132
 
Ian Kent a26132
 	first = *list;
Ian Kent a26132
@@ -877,11 +872,18 @@ int prune_host_list(unsigned logopt, struct host **list,
Ian Kent a26132
 
Ian Kent a26132
 	first = last;
Ian Kent a26132
 	this = first;
Ian Kent a26132
+	prev = NULL;
Ian Kent a26132
 	while (this) {
Ian Kent a26132
 		struct host *next = this->next;
Ian Kent a26132
 		if (!this->name) {
Ian Kent a26132
 			remove_host(list, this);
Ian Kent a26132
 			add_host(&new, this);
Ian Kent a26132
+		} else if (defaults_use_hostname_for_mounts() && prev &&
Ian Kent a26132
+			   prev->ent_num == this->ent_num) {
Ian Kent a26132
+			/* When we use the hostname to mount, there is no
Ian Kent a26132
+			 * point in probing every address it has, just one is
Ian Kent a26132
+			 * enough.  Skip the rest.
Ian Kent a26132
+			 */
Ian Kent a26132
 		} else {
Ian Kent a26132
 			status = get_supported_ver_and_cost(logopt, this,
Ian Kent a26132
 						selected_version, port);
Ian Kent a26132
@@ -889,6 +891,7 @@ int prune_host_list(unsigned logopt, struct host **list,
Ian Kent a26132
 				this->version = selected_version;
Ian Kent a26132
 				remove_host(list, this);
Ian Kent a26132
 				add_host(&new, this);
Ian Kent a26132
+				prev = this;
Ian Kent a26132
 			}
Ian Kent a26132
 		}
Ian Kent a26132
 		this = next;
Ian Kent a26132
@@ -901,7 +904,7 @@ int prune_host_list(unsigned logopt, struct host **list,
Ian Kent a26132
 }
Ian Kent a26132
 
Ian Kent a26132
 static int add_new_host(struct host **list,
Ian Kent a26132
-			const char *host, unsigned int weight,
Ian Kent a26132
+			const char *host, int ent_num, unsigned int weight,
Ian Kent a26132
 			struct addrinfo *host_addr,
Ian Kent a26132
 			unsigned int rr, unsigned int options)
Ian Kent a26132
 {
Ian Kent a26132
@@ -940,7 +943,7 @@ static int add_new_host(struct host **list,
Ian Kent a26132
 	else
Ian Kent a26132
 		return 0;
Ian Kent a26132
 
Ian Kent a26132
-	new = new_host(host, host_addr->ai_addr, addr_len, prx, weight, options);
Ian Kent a26132
+	new = new_host(host, ent_num, host_addr->ai_addr, addr_len, prx, weight, options);
Ian Kent a26132
 	if (!new)
Ian Kent a26132
 		return 0;
Ian Kent a26132
 
Ian Kent a26132
@@ -953,7 +956,7 @@ static int add_new_host(struct host **list,
Ian Kent a26132
 	return 1;
Ian Kent a26132
 }
Ian Kent a26132
 
Ian Kent a26132
-static int add_host_addrs(struct host **list, const char *host,
Ian Kent a26132
+static int add_host_addrs(struct host **list, const char *host, int ent_num,
Ian Kent a26132
 			  unsigned int weight, unsigned int options)
Ian Kent a26132
 {
Ian Kent a26132
 	struct addrinfo hints, *ni, *this;
Ian Kent a26132
@@ -988,7 +991,7 @@ static int add_host_addrs(struct host **list, const char *host,
Ian Kent a26132
 
Ian Kent a26132
 	this = ni;
Ian Kent a26132
 	while (this) {
Ian Kent a26132
-		ret = add_new_host(list, host, weight, this, 0, options);
Ian Kent a26132
+		ret = add_new_host(list, host, ent_num, weight, this, 0, options);
Ian Kent a26132
 		if (!ret)
Ian Kent a26132
 			break;
Ian Kent a26132
 		this = this->ai_next;
Ian Kent a26132
@@ -1027,7 +1030,7 @@ try_name:
Ian Kent a26132
 		rr++;
Ian Kent a26132
 	this = ni;
Ian Kent a26132
 	while (this) {
Ian Kent a26132
-		ret = add_new_host(list, host, weight, this, rr, options);
Ian Kent a26132
+		ret = add_new_host(list, host, ent_num, weight, this, rr, options);
Ian Kent a26132
 		if (!ret)
Ian Kent a26132
 			break;
Ian Kent a26132
 		this = this->ai_next;
Ian Kent a26132
@@ -1120,6 +1123,7 @@ int parse_location(unsigned logopt, struct host **hosts,
Ian Kent a26132
 {
Ian Kent a26132
 	char *str, *p, *delim;
Ian Kent a26132
 	unsigned int empty = 1;
Ian Kent a26132
+	int ent_num = 1;
Ian Kent a26132
 
Ian Kent a26132
 	if (!list)
Ian Kent a26132
 		return 0;
Ian Kent a26132
@@ -1177,7 +1181,7 @@ int parse_location(unsigned logopt, struct host **hosts,
Ian Kent a26132
 				}
Ian Kent a26132
 
Ian Kent a26132
 				if (p != delim) {
Ian Kent a26132
-					if (!add_host_addrs(hosts, p, weight, options)) {
Ian Kent a26132
+					if (!add_host_addrs(hosts, p, ent_num, weight, options)) {
Ian Kent a26132
 						if (empty) {
Ian Kent a26132
 							p = next;
Ian Kent a26132
 							continue;
Ian Kent a26132
@@ -1199,7 +1203,7 @@ int parse_location(unsigned logopt, struct host **hosts,
Ian Kent a26132
 				*delim = '\0';
Ian Kent a26132
 				next = delim + 1;
Ian Kent a26132
 
Ian Kent a26132
-				if (!add_host_addrs(hosts, p, weight, options)) {
Ian Kent a26132
+				if (!add_host_addrs(hosts, p, ent_num, weight, options)) {
Ian Kent a26132
 					p = next;
Ian Kent a26132
 					continue;
Ian Kent a26132
 				}
Ian Kent a26132
@@ -1213,6 +1217,7 @@ int parse_location(unsigned logopt, struct host **hosts,
Ian Kent a26132
 			return 0;
Ian Kent a26132
 		}
Ian Kent a26132
 
Ian Kent a26132
+		ent_num++;
Ian Kent a26132
 		p = next;
Ian Kent a26132
 	}
Ian Kent a26132