Blame SOURCES/autofs-5.1.4-use_hostname_for_mounts-shouldnt-prevent-selection-among-replicas.patch

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