autofs-5.0.1 - eliminate redundant DNS name lookups From: Ian Kent <raven@themaw.net> When autofs tries to lookup a DNS host name where one or more DNS servers aren't available the mount can take a long time. This is caused by autofs doing the name lookups more often than it needs to. This patch removes a number of these redundant name lookups. --- include/replicated.h | 1 + include/rpc_subs.h | 4 +++- lib/rpc_subs.c | 22 ++++++++++++++++++++-- modules/replicated.c | 25 +++++++++++++++++++------ 4 files changed, 43 insertions(+), 9 deletions(-) --- autofs-5.0.1.orig/include/replicated.h +++ autofs-5.0.1/include/replicated.h @@ -52,6 +52,7 @@ struct host { char *name; char *addr; + size_t addr_len; char *path; unsigned int version; unsigned int proximity; --- autofs-5.0.1.orig/include/rpc_subs.h +++ autofs-5.0.1/include/rpc_subs.h @@ -46,6 +46,8 @@ struct conn_info { const char *host; + const char *addr; + size_t addr_len; unsigned short port; unsigned long program; unsigned long version; @@ -61,7 +63,7 @@ int rpc_udp_getclient(struct conn_info * void rpc_destroy_udp_client(struct conn_info *); int rpc_tcp_getclient(struct conn_info *, unsigned int, unsigned int); void rpc_destroy_tcp_client(struct conn_info *); -int rpc_portmap_getclient(struct conn_info *, const char *, const char *, unsigned int); +int rpc_portmap_getclient(struct conn_info *, const char *, const char *, size_t, const char *, unsigned int); unsigned short rpc_portmap_getport(struct conn_info *, struct pmap *); int rpc_ping_proto(struct conn_info *); int rpc_ping(const char *, long, long, unsigned int); --- autofs-5.0.1.orig/lib/rpc_subs.c +++ autofs-5.0.1/lib/rpc_subs.c @@ -80,6 +80,11 @@ static CLIENT *create_udp_client(struct memset(&raddr, 0, sizeof(raddr)); raddr.sin_family = AF_INET; + if (info->addr) { + memcpy(&raddr.sin_addr.s_addr, info->addr, info->addr_len); + goto got_addr; + } + if (inet_aton(info->host, &raddr.sin_addr)) goto got_addr; @@ -305,6 +310,11 @@ static CLIENT *create_tcp_client(struct memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; + if (info->addr) { + memcpy(&addr.sin_addr.s_addr, info->addr, info->addr_len); + goto got_addr; + } + if (inet_aton(info->host, &addr.sin_addr)) goto got_addr; @@ -418,8 +428,8 @@ void rpc_destroy_tcp_client(struct conn_ } int rpc_portmap_getclient(struct conn_info *info, - const char *host, const char *proto, - unsigned int option) + const char *host, const char *addr, size_t addr_len, + const char *proto, unsigned int option) { struct protoent *pe_proto; CLIENT *client; @@ -429,6 +439,8 @@ int rpc_portmap_getclient(struct conn_in return 0; info->host = host; + info->addr = addr; + info->addr_len = addr_len; info->program = PMAPPROG; info->port = PMAPPORT; info->version = PMAPVERS; @@ -473,6 +485,8 @@ unsigned short rpc_portmap_getport(struc client = info->client; else { pmap_info.host = info->host; + pmap_info.addr = info->addr; + pmap_info.addr_len = info->addr_len; pmap_info.port = PMAPPORT; pmap_info.program = PMAPPROG; pmap_info.version = PMAPVERS; @@ -600,6 +614,8 @@ static unsigned int __rpc_ping(const cha struct pmap parms; info.host = host; + info.addr = NULL; + info.addr_len = 0; info.program = NFS_PROGRAM; info.version = version; info.send_sz = 0; @@ -780,6 +796,8 @@ exports rpc_get_exports(const char *host int status; info.host = host; + info.addr = NULL; + info.addr_len = 0; info.program = MOUNTPROG; info.version = MOUNTVERS; info.send_sz = 0; --- autofs-5.0.1.orig/modules/replicated.c +++ autofs-5.0.1/modules/replicated.c @@ -268,7 +268,9 @@ static unsigned int get_proximity(const return PROXIMITY_OTHER; } -static struct host *new_host(const char *name, const char *addr, unsigned int proximity, unsigned int weight) +static struct host *new_host(const char *name, + const char *addr, size_t addr_len, + unsigned int proximity, unsigned int weight) { struct host *new; char *tmp1, *tmp2; @@ -280,11 +282,12 @@ static struct host *new_host(const char if (!tmp1) return NULL; - tmp2 = strdup(addr); + tmp2 = malloc(addr_len); if (!tmp2) { free(tmp1); return NULL; } + memcpy(tmp2, addr, addr_len); new = malloc(sizeof(struct host)); if (!new) { @@ -296,6 +299,7 @@ static struct host *new_host(const char memset(new, 0, sizeof(struct host)); new->name = tmp1; + new->addr_len = addr_len; new->addr = tmp2; new->proximity = proximity; new->weight = weight; @@ -490,7 +494,8 @@ static unsigned int get_nfs_info(unsigne v3_ver: if (!have_port_opt) { status = rpc_portmap_getclient(pm_info, - host->name, proto, RPC_CLOSE_DEFAULT); + host->name, host->addr, host->addr_len, + proto, RPC_CLOSE_DEFAULT); if (!status) goto done_ver; } @@ -619,6 +624,8 @@ static int get_vers_and_cost(unsigned lo timeout = RPC_TIMEOUT * 8; rpc_info.host = host->name; + rpc_info.addr = host->addr; + rpc_info.addr_len = host->addr_len; rpc_info.program = NFS_PROGRAM; rpc_info.timeout.tv_sec = timeout; rpc_info.close_option = RPC_CLOSE_DEFAULT; @@ -677,6 +684,8 @@ static int get_supported_ver_and_cost(un timeout = RPC_TIMEOUT * 8; rpc_info.host = host->name; + rpc_info.addr = host->addr; + rpc_info.addr_len = host->addr_len; rpc_info.program = NFS_PROGRAM; rpc_info.timeout.tv_sec = timeout; rpc_info.close_option = RPC_CLOSE_DEFAULT; @@ -723,7 +732,8 @@ static int get_supported_ver_and_cost(un return 0; } else { int ret = rpc_portmap_getclient(&pm_info, - host->name, proto, RPC_CLOSE_DEFAULT); + host->name, host->addr, host->addr_len, + proto, RPC_CLOSE_DEFAULT); if (!ret) return 0; @@ -966,7 +976,7 @@ static int add_host_addrs(struct host ** if (prx == PROXIMITY_ERROR) return 0; - if (!(new = new_host(host, thost, prx, weight))) + if (!(new = new_host(host, thost, sizeof(saddr.sin_addr), prx, weight))) return 0; if (!add_host(list, new)) @@ -989,11 +999,14 @@ static int add_host_addrs(struct host ** } for (haddr = phe->h_addr_list; *haddr; haddr++) { + struct in_addr tt; + prx = get_proximity(*haddr, phe->h_length); if (prx == PROXIMITY_ERROR) return 0; - if (!(new = new_host(host, *haddr, prx, weight))) + memcpy(&tt, *haddr, sizeof(struct in_addr)); + if (!(new = new_host(host, *haddr, phe->h_length, prx, weight))) return 0; if (!add_host(list, new)) {