From patchwork Tue Apr 19 08:33:11 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mi Jinlong X-Patchwork-Id: 717201 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p3J8iaGu032640 for ; Tue, 19 Apr 2011 08:44:36 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753803Ab1DSIof (ORCPT ); Tue, 19 Apr 2011 04:44:35 -0400 Received: from cn.fujitsu.com ([222.73.24.84]:53759 "EHLO song.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-OK) by vger.kernel.org with ESMTP id S1753788Ab1DSIod (ORCPT ); Tue, 19 Apr 2011 04:44:33 -0400 Received: from tang.cn.fujitsu.com (tang.cn.fujitsu.com [10.167.250.3]) by song.cn.fujitsu.com (Postfix) with ESMTP id E85E0170116; Tue, 19 Apr 2011 16:44:31 +0800 (CST) Received: from mailserver.fnst.cn.fujitsu.com (tang.cn.fujitsu.com [127.0.0.1]) by tang.cn.fujitsu.com (8.14.3/8.13.1) with ESMTP id p3J8iVAm026081; Tue, 19 Apr 2011 16:44:31 +0800 Received: from [127.0.0.1] ([10.167.225.24]) by mailserver.fnst.cn.fujitsu.com (Lotus Domino Release 8.5.1FP4) with ESMTP id 2011041916320423-94691 ; Tue, 19 Apr 2011 16:32:04 +0800 Message-ID: <4DAD48C7.9090808@cn.fujitsu.com> Date: Tue, 19 Apr 2011 16:33:11 +0800 From: Mi Jinlong User-Agent: Thunderbird 2.0.0.9 (Windows/20071031) MIME-Version: 1.0 To: Steve Dickson CC: Chuck Lever , NFS Subject: [PATCH] svc: make sure mountd can get ports from /etc/services X-MIMETrack: Itemize by SMTP Server on mailserver/fnst(Release 8.5.1FP4|July 25, 2010) at 2011-04-19 16:32:04, Serialize by Router on mailserver/fnst(Release 8.5.1FP4|July 25, 2010) at 2011-04-19 16:45:05, Serialize complete at 2011-04-19 16:45:05 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Tue, 19 Apr 2011 08:44:36 +0000 (UTC) At RHEL, if user set port for mountd at /etc/services as "mount 12345/tcp", mountd should be bind to 12345, but the latest nfs-utils, mountd get a rand port, not 12345. This patch make sure mountd be bind to the port which was set at /etc/service. Signed-off-by: Mi Jinlong --- support/include/rpcmisc.h | 1 + support/nfs/svc_create.c | 9 ++++- support/nfs/svc_socket.c | 83 +++++++++++++++++++++----------------------- 3 files changed, 48 insertions(+), 45 deletions(-) diff --git a/support/include/rpcmisc.h b/support/include/rpcmisc.h index 0b06457..b806227 100644 --- a/support/include/rpcmisc.h +++ b/support/include/rpcmisc.h @@ -53,6 +53,7 @@ void rpc_init(char *name, int prog, int vers, void rpc_dispatch(struct svc_req *rq, SVCXPRT *xprt, struct rpc_dtable *dtable, int nvers, void *argp, void *resp); +int getservport(u_long number, const char *proto); extern int _rpcpmstart; extern int _rpcfdtype; diff --git a/support/nfs/svc_create.c b/support/nfs/svc_create.c index b3f75ed..fd09902 100644 --- a/support/nfs/svc_create.c +++ b/support/nfs/svc_create.c @@ -393,7 +393,7 @@ nfs_svc_create(char *name, const rpcprog_t program, const rpcvers_t version, const struct sigaction create_sigaction = { .sa_handler = SIG_IGN, }; - unsigned int visible, up; + unsigned int visible, up, servport; struct netconfig *nconf; void *handlep; @@ -417,8 +417,13 @@ nfs_svc_create(char *name, const rpcprog_t program, const rpcvers_t version, if (!(nconf->nc_flag & NC_VISIBLE)) continue; visible++; + if (port == 0) + servport = getservport(program, nconf->nc_proto); + else + servport = port; + up += svc_create_nconf(name, program, version, dispatch, - port, nconf); + servport, nconf); } if (visible == 0) diff --git a/support/nfs/svc_socket.c b/support/nfs/svc_socket.c index 03a5325..ec406a9 100644 --- a/support/nfs/svc_socket.c +++ b/support/nfs/svc_socket.c @@ -35,14 +35,46 @@ # define __close(f) close ((f)) #endif +int getservport(u_long number, const char *proto) +{ + char rpcdata [1024], servdata [1024]; + struct rpcent rpcbuf, *rpcp; + struct servent servbuf, *servp = NULL; + int ret; + + ret = getrpcbynumber_r (number, &rpcbuf, rpcdata, sizeof rpcdata, + &rpcp); + if (ret == 0 && rpcp != NULL) + { + /* First try name. */ + ret = getservbyname_r (rpcp->r_name, proto, &servbuf, servdata, + sizeof servdata, &servp); + if ((ret != 0 || servp == NULL) && rpcp->r_aliases) + { + const char **a; + + /* Then we try aliases. */ + for (a = (const char **) rpcp->r_aliases; *a != NULL; a++) + { + ret = getservbyname_r (*a, proto, &servbuf, servdata, + sizeof servdata, &servp); + if (ret == 0 && servp != NULL) + break; + } + } + } + + if (ret == 0 && servp != NULL) + return ntohs(servp->s_port); + + return 0; +} + static int svc_socket (u_long number, int type, int protocol, int reuse) { struct sockaddr_in addr; socklen_t len = sizeof (struct sockaddr_in); - char rpcdata [1024], servdata [1024]; - struct rpcent rpcbuf, *rpcp; - struct servent servbuf, *servp = NULL; int sock, ret; const char *proto = protocol == IPPROTO_TCP ? "tcp" : "udp"; @@ -66,48 +98,13 @@ svc_socket (u_long number, int type, int protocol, int reuse) memset (&addr, 0, sizeof (addr)); addr.sin_family = AF_INET; + addr.sin_port = htons(getservport(number, proto)); - ret = getrpcbynumber_r (number, &rpcbuf, rpcdata, sizeof rpcdata, - &rpcp); - if (ret == 0 && rpcp != NULL) + if (bind (sock, (struct sockaddr *) &addr, len) < 0) { - /* First try name. */ - ret = getservbyname_r (rpcp->r_name, proto, &servbuf, servdata, - sizeof servdata, &servp); - if ((ret != 0 || servp == NULL) && rpcp->r_aliases) - { - const char **a; - - /* Then we try aliases. */ - for (a = (const char **) rpcp->r_aliases; *a != NULL; a++) - { - ret = getservbyname_r (*a, proto, &servbuf, servdata, - sizeof servdata, &servp); - if (ret == 0 && servp != NULL) - break; - } - } - } - - if (ret == 0 && servp != NULL) - { - addr.sin_port = servp->s_port; - if (bind (sock, (struct sockaddr *) &addr, len) < 0) - { - perror (_("svc_socket: bind problem")); - (void) __close (sock); - sock = -1; - } - } - else - { - addr.sin_port = 0; - if (bind (sock, (struct sockaddr *) &addr, len) < 0) - { - perror (_("svc_socket: bind problem")); - (void) __close (sock); - sock = -1; - } + perror (_("svc_socket: bind problem")); + (void) __close (sock); + sock = -1; } if (sock >= 0)