autofs-5.0.3 - eliminate redundant DNS name lookups From: Ian Kent 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. --- CHANGELOG | 1 + include/replicated.h | 1 + include/rpc_subs.h | 4 +++- lib/rpc_subs.c | 22 ++++++++++++++++++++-- modules/replicated.c | 25 +++++++++++++++++++------ 5 files changed, 44 insertions(+), 9 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 3ed84d3..995daea 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -17,6 +17,7 @@ - add check for exports automatically mounted by NFS kernel client. - update nsswitch parser to ignore nsswitch sources that aren't supported. - check for map key in (possible) alternate map sources when doing lookup. +- eliminate redundant DNS name lookups. 14/01/2008 autofs-5.0.3 ----------------------- diff --git a/include/replicated.h b/include/replicated.h index 672f853..88cd08a 100644 --- a/include/replicated.h +++ b/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; diff --git a/include/rpc_subs.h b/include/rpc_subs.h index 3292e01..e20a89d 100644 --- a/include/rpc_subs.h +++ b/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 *, unsigned int, unsigned int); 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); diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c index 5797639..6be86c6 100644 --- a/lib/rpc_subs.c +++ b/lib/rpc_subs.c @@ -86,6 +86,11 @@ static CLIENT *create_udp_client(struct conn_info *info) 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; @@ -295,6 +300,11 @@ static CLIENT *create_tcp_client(struct conn_info *info) 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; @@ -407,8 +417,8 @@ void rpc_destroy_tcp_client(struct conn_info *info) } 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; @@ -418,6 +428,8 @@ int rpc_portmap_getclient(struct conn_info *info, return 0; info->host = host; + info->addr = addr; + info->addr_len = addr_len; info->program = PMAPPROG; info->port = PMAPPORT; info->version = PMAPVERS; @@ -462,6 +474,8 @@ unsigned short rpc_portmap_getport(struct conn_info *info, struct pmap *parms) 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; @@ -589,6 +603,8 @@ static unsigned int __rpc_ping(const char *host, struct pmap parms; info.host = host; + info.addr = NULL; + info.addr_len = 0; info.program = NFS_PROGRAM; info.version = version; info.send_sz = 0; @@ -769,6 +785,8 @@ exports rpc_get_exports(const char *host, long seconds, long micros, unsigned in int status; info.host = host; + info.addr = NULL; + info.addr_len = 0; info.program = MOUNTPROG; info.version = MOUNTVERS; info.send_sz = 0; diff --git a/modules/replicated.c b/modules/replicated.c index 90b2925..efbe6b4 100644 --- a/modules/replicated.c +++ b/modules/replicated.c @@ -225,7 +225,9 @@ static unsigned int get_proximity(const char *host_addr, int addr_len) 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; @@ -237,11 +239,12 @@ static struct host *new_host(const char *name, const char *addr, unsigned int pr 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) { @@ -253,6 +256,7 @@ static struct host *new_host(const char *name, const char *addr, unsigned int pr memset(new, 0, sizeof(struct host)); new->name = tmp1; + new->addr_len = addr_len; new->addr = tmp2; new->proximity = proximity; new->weight = weight; @@ -437,7 +441,8 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host, 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; } @@ -551,6 +556,8 @@ static int get_vers_and_cost(unsigned logopt, struct host *host, 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; @@ -606,6 +613,8 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host, 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; @@ -652,7 +661,8 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host, 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; @@ -868,7 +878,7 @@ static int add_host_addrs(struct host **list, const char *host, unsigned int wei 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)) @@ -891,11 +901,14 @@ static int add_host_addrs(struct host **list, const char *host, unsigned int wei } 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)) {