autofs-5.0.5 - mount using address for rr

From: Ian Kent <raven@themaw.net>

When a host has multiple addresses, mount using individual address so
we can take advantage of the probing and response time calculation that's
already been done.
---

 CHANGELOG            |    1 +
 include/replicated.h |    1 +
 modules/mount_nfs.c  |   31 +++++++++++++++++++++++++------
 modules/replicated.c |   11 ++++++++---
 4 files changed, 35 insertions(+), 9 deletions(-)


diff --git a/CHANGELOG b/CHANGELOG
index 4b4389b..8b12bbe 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -69,6 +69,7 @@
 - automount(8) man page correction.
 - fix out of order locking in readmap.
 - include ip address in debug logging.
+- mount using address for DNS round robin host names.
 
 03/09/2009 autofs-5.0.5
 -----------------------
diff --git a/include/replicated.h b/include/replicated.h
index 6eb56e0..206918e 100644
--- a/include/replicated.h
+++ b/include/replicated.h
@@ -54,6 +54,7 @@ struct host {
 	char *name;
 	struct sockaddr *addr;
 	size_t addr_len;
+	unsigned int rr;
 	char *path;
 	unsigned int version;
 	unsigned int options;
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
index 817b9c6..474804a 100644
--- a/modules/mount_nfs.c
+++ b/modules/mount_nfs.c
@@ -229,13 +229,32 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
 
 		/* Not a local host - do an NFS mount */
 
-		loc = malloc(strlen(this->name) + 1 + strlen(this->path) + 1);
-		if (!loc) {
-			char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-			error(ap->logopt, "malloc: %s", estr);
-			return 1;
+		if (this->rr && this->addr) {
+			socklen_t len = INET6_ADDRSTRLEN;
+			char n_buf[len + 1];
+			const char *n_addr;
+			n_addr = get_addr_string(this->addr, n_buf, len);
+			loc = malloc(strlen(n_addr) + strlen(this->path) + 4);
+			if (!loc) {
+				char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+				error(ap->logopt, "malloc: %s", estr);
+				goto forced_fail;
+			}
+			if (this->addr->sa_family == AF_INET6) {
+				strcpy(loc, "[");
+				strcat(loc, n_addr);
+				strcat(loc, "]");
+			} else
+				strcpy(loc, n_addr);
+		} else {
+			loc = malloc(strlen(this->name) + strlen(this->path) + 2);
+			if (!loc) {
+				char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+				error(ap->logopt, "malloc: %s", estr);
+				goto forced_fail;
+			}
+			strcpy(loc, this->name);
 		}
-		strcpy(loc, this->name);
 		strcat(loc, ":");
 		strcat(loc, this->path);
 
diff --git a/modules/replicated.c b/modules/replicated.c
index 76b75c7..c9a8695 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -1059,7 +1059,8 @@ int prune_host_list(unsigned logopt, struct host **list,
 
 static int add_new_host(struct host **list,
 			const char *host, unsigned int weight,
-			struct addrinfo *host_addr, unsigned int options)
+			struct addrinfo *host_addr,
+			unsigned int rr, unsigned int options)
 {
 	struct host *new;
 	unsigned int prx;
@@ -1105,6 +1106,7 @@ static int add_new_host(struct host **list,
 		free_host(new);
 		return 0;
 	}
+	new->rr = rr;
 
 	return 1;
 }
@@ -1113,6 +1115,7 @@ static int add_host_addrs(struct host **list, const char *host,
 			  unsigned int weight, unsigned int options)
 {
 	struct addrinfo hints, *ni, *this;
+	int rr = 0;
 	int ret;
 
 	memset(&hints, 0, sizeof(hints));
@@ -1126,7 +1129,7 @@ static int add_host_addrs(struct host **list, const char *host,
 
 	this = ni;
 	while (this) {
-		ret = add_new_host(list, host, weight, this, options);
+		ret = add_new_host(list, host, weight, this, 0, options);
 		if (!ret)
 			break;
 		this = this->ai_next;
@@ -1148,8 +1151,10 @@ try_name:
 	}
 
 	this = ni;
+	if (this->ai_next)
+		rr++;
 	while (this) {
-		ret = add_new_host(list, host, weight, this, options);
+		ret = add_new_host(list, host, weight, this, rr, options);
 		if (!ret)
 			break;
 		this = this->ai_next;