2003-06-30 19:38:46

by Dan Kegel

[permalink] [raw]
Subject: Meaning of 'udp' mount option

Question 1: what does the 'udp' mount option really mean?
It appears to mean 'Use udp mostly, but use TCP when calling pmap_getmaps()'.
Question 2: is this a bug or a feature?
Question 3: if it's a feature, should we add a new mount option to
mean 'really, dude, use udp for everything'?

The long story:

Imagine, if you will, an NFS server running on an operating system
that will shut down all further TCP connects on a given port if that
port ever encounters more than five simultaneous connects.
(That's a rather perverse limitation, but unfortunately, it seems to
be widespread.)

Imagine further that you have 500 NFS clients that want to connect
simultaneously to that server. "Ah, simple, I'll just use UDP, and
avoid the issue!", you say.

Unfortunately, it appears that even when you specify UDP as a
mount option, util-linux-2.11[nz]'s mount appears
to always connect to the server's portmapper using TCP. The
culprit is glibc's pmap_getmaps, which always uses tcp.

I threw together a version of rpcinfo.c that uses udp to do
the same thing as pmap_getmaps, and it works.

The next step is for me to patch nfsmount.c's get_mountport()
to only use the standard pmap_getmaps() if mounting via TCP,
and to use my pmap_getmaps_via_udp() if mounting via UDP.

If that works, then presumably it'd be nice to fold something
like this in to the main tree. But making the 'udp' mount
option really mean 'udp, goddammit' might be too much of a
change in semantics; perhaps there should be a new mount option
always_udp?

- Dan



-------------------------------------------------------
This SF.Net email sponsored by: Free pre-built ASP.NET sites including
Data Reports, E-commerce, Portals, and Forums are available now.
Download today and enter to win an XBOX or Visual Studio .NET.
http://aspnet.click-url.com/go/psa00100006ave/direct;at.asp_061203_01/01
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs


2003-06-30 22:26:54

by Dan Kegel

[permalink] [raw]
Subject: [PATCH] Make 'udp' mount option really mean it (was: Meaning of 'udp' mount option)

Dan Kegel wrote:
> Question 1: what does the 'udp' mount option really mean?
> It appears to mean 'Use udp mostly, but use TCP when calling
> pmap_getmaps()'.
> Question 2: is this a bug or a feature?

Assuming it's a bug, here's a patch that fixes it, by using
UDP even for pmap_getmaps(). It worked for me, and I'll probably
use it, but I wouldn't be suprised if others preferred to
add a new mount option to get this behavior.

I use a retry of 5 seconds, no idea if that's right.
- Dan

--- util-linux-2.11n/mount/nfsmount.c.old Sat Sep 29 15:43:26 2001
+++ util-linux-2.11n/mount/nfsmount.c Mon Jun 30 13:48:28 2003
@@ -68,6 +68,9 @@

static char *nfs_strerror(int stat);

+static struct pmaplist *
+pmap_getmaps_udp (struct sockaddr_in *address);
+
#define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))

#define MAX_NFSPROT ((nfs_mount_version >= 4) ? 3 : 2)
@@ -142,7 +145,10 @@
p.pm_port = port;

server_addr->sin_port = PMAPPORT;
- pmap = pmap_getmaps(server_addr);
+ if (proto == IPPROTO_TCP)
+ pmap = pmap_getmaps(server_addr);
+ else
+ pmap = pmap_getmaps_udp(server_addr);

while (pmap) {
if (pmap->pml_map.pm_prog != prog)
@@ -877,3 +883,95 @@
return port;
}
#endif
+
+/* added 30 June 2003, [email protected]; modified to use udp */
+/* @(#)pmap_getmaps.c 2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_getmap.c
+ * Client interface to pmap rpc service.
+ * contains pmap_getmaps, which is only tcp service involved
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <errno.h>
+#include <libintl.h>
+
+/*
+ * Get a copy of the current port maps.
+ * Calls the pmap service remotely to do get the maps.
+ */
+struct pmaplist *
+pmap_getmaps_udp (struct sockaddr_in *address)
+{
+ struct pmaplist *head = (struct pmaplist *) NULL;
+ int socket = -1;
+ struct timeval minutetimeout;
+ struct timeval retry;
+ CLIENT *client;
+
+ minutetimeout.tv_sec = 60;
+ minutetimeout.tv_usec = 0;
+ address->sin_port = htons (PMAPPORT);
+#if 0
+ client = clnttcp_create (address, PMAPPROG,
+ PMAPVERS, &socket, 50, 500);
+#else
+ retry.tv_sec = 5;
+ retry.tv_usec = 0;
+ if ((client = clntudp_create (address, PMAPPROG,
+ PMAPVERS, retry, &socket)) == NULL)
+#endif
+ if (client != (CLIENT *) NULL)
+ {
+ if (CLNT_CALL (client, PMAPPROC_DUMP, (xdrproc_t)xdr_void, NULL,
+ (xdrproc_t)xdr_pmaplist, (caddr_t)&head,
+ minutetimeout) != RPC_SUCCESS)
+ {
+ clnt_perror (client, _("pmap_getmaps rpc problem"));
+ }
+ CLNT_DESTROY (client);
+ }
+ /* (void)close(socket); CLNT_DESTROY already closed it */
+ address->sin_port = 0;
+ return head;
+}
+



-------------------------------------------------------
This SF.Net email sponsored by: Free pre-built ASP.NET sites including
Data Reports, E-commerce, Portals, and Forums are available now.
Download today and enter to win an XBOX or Visual Studio .NET.
http://aspnet.click-url.com/go/psa00100006ave/direct;at.asp_061203_01/01
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2003-06-30 22:32:17

by Dan Kegel

[permalink] [raw]
Subject: Re: [PATCH] Make 'udp' mount option really mean it

Crap. Ignore that patch. Here's the real one.
- Dan

--- util-linux-2.11n/mount/nfsmount.c.old Sat Sep 29 15:43:26 2001
+++ util-linux-2.11n/mount/nfsmount.c Mon Jun 30 13:48:28 2003
@@ -68,6 +68,9 @@

static char *nfs_strerror(int stat);

+static struct pmaplist *
+pmap_getmaps_udp (struct sockaddr_in *address);
+
#define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))

#define MAX_NFSPROT ((nfs_mount_version >= 4) ? 3 : 2)
@@ -142,7 +145,10 @@
p.pm_port = port;

server_addr->sin_port = PMAPPORT;
- pmap = pmap_getmaps(server_addr);
+ if (proto == IPPROTO_TCP)
+ pmap = pmap_getmaps(server_addr);
+ else
+ pmap = pmap_getmaps_udp(server_addr);

while (pmap) {
if (pmap->pml_map.pm_prog != prog)
@@ -877,3 +883,95 @@
return port;
}
#endif
+
+/* added 30 June 2003, [email protected]; modified to use udp */
+/* @(#)pmap_getmaps.c 2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_getmap.c
+ * Client interface to pmap rpc service.
+ * contains pmap_getmaps, which is only tcp service involved
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <errno.h>
+#include <libintl.h>
+
+/*
+ * Get a copy of the current port maps.
+ * Calls the pmap service remotely to do get the maps.
+ */
+struct pmaplist *
+pmap_getmaps_udp (struct sockaddr_in *address)
+{
+ struct pmaplist *head = (struct pmaplist *) NULL;
+ int socket = -1;
+ struct timeval minutetimeout;
+ struct timeval retry;
+ CLIENT *client;
+
+ minutetimeout.tv_sec = 60;
+ minutetimeout.tv_usec = 0;
+ address->sin_port = htons (PMAPPORT);
+#if 0
+ client = clnttcp_create (address, PMAPPROG,
+ PMAPVERS, &socket, 50, 500);
+#else
+ retry.tv_sec = 5;
+ retry.tv_usec = 0;
+ client = clntudp_create (address, PMAPPROG,
+ PMAPVERS, retry, &socket);
+#endif
+ if (client != (CLIENT *) NULL)
+ {
+ if (CLNT_CALL (client, PMAPPROC_DUMP, (xdrproc_t)xdr_void, NULL,
+ (xdrproc_t)xdr_pmaplist, (caddr_t)&head,
+ minutetimeout) != RPC_SUCCESS)
+ {
+ clnt_perror (client, _("pmap_getmaps rpc problem"));
+ }
+ CLNT_DESTROY (client);
+ }
+ /* (void)close(socket); CLNT_DESTROY already closed it */
+ address->sin_port = 0;
+ return head;
+}
+



-------------------------------------------------------
This SF.Net email sponsored by: Free pre-built ASP.NET sites including
Data Reports, E-commerce, Portals, and Forums are available now.
Download today and enter to win an XBOX or Visual Studio .NET.
http://aspnet.click-url.com/go/psa00100006ave/direct;at.asp_061203_01/01
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs