autofs-5.1.1 - fix create_client() RPC client handling From: Ian Kent The autofs socket minimization strategy is to reuse the socket descriptor when creating an RPC client for the same protocol. But in create_client() there is a case where the socket descriptor can be obtained from RPC client, the RPC client destroyed, but not cleared in the persistent data structure. In create_client(), once an attempt is done to get the socket descriptor, the RPC client should always be destroyed and cleared in the persistent data structure. Signed-off-by: Ian Kent --- CHANGELOG | 1 + lib/rpc_subs.c | 21 ++++++++------------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 3fb933b..601a241 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -20,6 +20,7 @@ xx/xx/2016 autofs-5.1.3 - fix cachefs parse message not being logged. - fix argc off by one in mount_autofs.c. - fix _strncmp() usage. +- fix create_client() RPC client handling. 15/06/2016 autofs-5.1.2 ======================= diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c index 8995996..d0d4cf5 100644 --- a/lib/rpc_subs.c +++ b/lib/rpc_subs.c @@ -654,14 +654,12 @@ static int create_client(struct conn_info *info, CLIENT **client) *client = NULL; if (info->client) { - if (!clnt_control(info->client, CLGET_FD, (char *) &fd)) { - fd = RPC_ANYSOCK; - clnt_destroy(info->client); - info->client = NULL; - } else { + if (clnt_control(info->client, CLGET_FD, (char *) &fd)) clnt_control(info->client, CLSET_FD_NCLOSE, NULL); - clnt_destroy(info->client); - } + else + fd = RPC_ANYSOCK; + clnt_destroy(info->client); + info->client = NULL; } if (info->addr) { @@ -677,7 +675,7 @@ static int create_client(struct conn_info *info, CLIENT **client) goto out_close; } - if (!info->client && fd != RPC_ANYSOCK) { + if (fd != RPC_ANYSOCK) { close(fd); fd = RPC_ANYSOCK; } @@ -695,7 +693,6 @@ static int create_client(struct conn_info *info, CLIENT **client) if (ret) { error(LOGOPT_ANY, "hostname lookup failed: %s", gai_strerror(ret)); - info->client = NULL; goto out_close; } @@ -714,7 +711,7 @@ static int create_client(struct conn_info *info, CLIENT **client) goto out_close; } - if (!info->client && fd != RPC_ANYSOCK) { + if (fd != RPC_ANYSOCK) { close(fd); fd = RPC_ANYSOCK; } @@ -726,7 +723,6 @@ static int create_client(struct conn_info *info, CLIENT **client) done: if (!*client) { - info->client = NULL; ret = -ENOTCONN; goto out_close; } @@ -734,7 +730,6 @@ done: /* Close socket fd on destroy, as is default for rpcowned fds */ if (!clnt_control(*client, CLSET_FD_CLOSE, NULL)) { clnt_destroy(*client); - info->client = NULL; ret = -ENOTCONN; goto out_close; } @@ -742,7 +737,7 @@ done: return 0; out_close: - if (fd != -1) + if (fd != RPC_ANYSOCK) close(fd); return ret; }