From patchwork Sat May 28 09:42:24 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mi Jinlong X-Patchwork-Id: 826052 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 p4S9dtP2008898 for ; Sat, 28 May 2011 09:39:55 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751522Ab1E1Jjx (ORCPT ); Sat, 28 May 2011 05:39:53 -0400 Received: from cn.fujitsu.com ([222.73.24.84]:62275 "EHLO song.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-OK) by vger.kernel.org with ESMTP id S1751458Ab1E1Jjw (ORCPT ); Sat, 28 May 2011 05:39:52 -0400 Received: from tang.cn.fujitsu.com (tang.cn.fujitsu.com [10.167.250.3]) by song.cn.fujitsu.com (Postfix) with ESMTP id 6976D17011A; Sat, 28 May 2011 17:39:50 +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 p4S9dnBR009532; Sat, 28 May 2011 17:39:50 +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 2011052817394921-420345 ; Sat, 28 May 2011 17:39:49 +0800 Message-ID: <4DE0C380.7040608@cn.fujitsu.com> Date: Sat, 28 May 2011 17:42:24 +0800 From: Mi Jinlong User-Agent: Thunderbird 2.0.0.9 (Windows/20071031) MIME-Version: 1.0 To: Steve Dickson CC: NFS , Chuck Lever Subject: [PATCH v2] rpc.mountd: let mountd consult /etc/services for port References: <4DAD48C7.9090808@cn.fujitsu.com> In-Reply-To: <4DAD48C7.9090808@cn.fujitsu.com> X-MIMETrack: Itemize by SMTP Server on mailserver/fnst(Release 8.5.1FP4|July 25, 2010) at 2011-05-28 17:39:49, Serialize by Router on mailserver/fnst(Release 8.5.1FP4|July 25, 2010) at 2011-05-28 17:39:49, Serialize complete at 2011-05-28 17:39:49 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]); Sat, 28 May 2011 09:39:55 +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 | 80 +++++++++++++++++++++------------------------ utils/mountd/mountd.man | 5 ++- utils/statd/statd.man | 5 ++- 5 files changed, 53 insertions(+), 47 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..c159fc8 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..c252f53 100644 --- a/support/nfs/svc_socket.c +++ b/support/nfs/svc_socket.c @@ -35,14 +35,43 @@ # 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 +95,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) - { - /* 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) + if (bind(sock, (struct sockaddr *) &addr, len) < 0) { - 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) diff --git a/utils/mountd/mountd.man b/utils/mountd/mountd.man index 016a357..b322437 100644 --- a/utils/mountd/mountd.man +++ b/utils/mountd/mountd.man @@ -122,7 +122,10 @@ Ignored (compatibility with unfsd??). Specifies the port number used for RPC listener sockets. If this option is not specified, .B rpc.mountd -chooses a random ephemeral port for each listener socket. +will try to consult +.IR /etc/services , +if gets port succeed, set the same port for all listener socket, +otherwise chooses a random ephemeral port for each listener socket. .IP This option can be used to fix the port value of .BR rpc.mountd 's diff --git a/utils/statd/statd.man b/utils/statd/statd.man index b72236c..203f8c9 100644 --- a/utils/statd/statd.man +++ b/utils/statd/statd.man @@ -219,7 +219,10 @@ for details. Specifies the port number used for RPC listener sockets. If this option is not specified, .B rpc.statd -chooses a random ephemeral port for each listener socket. +will try to consult +.IR /etc/services , +if gets port succeed, set the same port for all listener socket, +otherwise chooses a random ephemeral port for each listener socket. .IP This option can be used to fix the port value of its listeners when SM_NOTIFY requests must traverse a firewall between clients and servers.