[PATCH 2/3] SUNRPC: Clearer error message when user space is running portmap

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Detect the case where we sent an rpcbind v4 UNSET but user space
doesn't support rpcbind protocol version 4.

We down-shift to version 2 and print a warning once in this case.
Olaf says a v2 UNSET should properly clear all entries in the rpcbind
database.

As svc_unregister() is usually done first to clear old portmapper
entries before trying to set up new ones, a v4 UNSET call will almost
always be the first to detect an rpcbind protocol version mismatch
problem.

Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx>
---

 net/sunrpc/svc.c |   51 ++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index a278a82..e93bc55 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -721,6 +721,21 @@ EXPORT_SYMBOL_GPL(svc_exit_thread);
 
 #ifdef CONFIG_SUNRPC_REGISTER_V4
 
+static u32 __svc_register_version = 4;
+
+static void __svc_rpcb_prog_mismatch_error(void)
+{
+	if (__svc_register_version == 4) {
+		printk(KERN_WARNING
+			"svc: The kernel tried an rpcbind version 4 request, "
+			"but your portmapper\n"
+			"svc: does not support rpcbind version 4.  "
+			"Switching to rpcbind version 2.\n");
+
+		__svc_register_version = 2;
+	}
+}
+
 /*
  * Register an "inet" protocol family netid with the local
  * rpcbind daemon via an rpcbind v4 SET request.
@@ -896,10 +911,20 @@ int svc_register(const struct svc_serv *serv, const unsigned short proto,
 	return error;
 }
 
+static void __svc_v2_unregister(const u32 program, const u32 version,
+				const char *progname)
+{
+	int error;
+
+	error = rpcb_register(program, version, 0, 0);
+	dprintk("svc: %s(%sv%u), error %d\n",
+			__func__, progname, version, error);
+}
+
 #ifdef CONFIG_SUNRPC_REGISTER_V4
 
-static void __svc_unregister(const u32 program, const u32 version,
-			     const char *progname)
+static int __svc_v4_unregister(const u32 program, const u32 version,
+			       const char *progname)
 {
 	struct sockaddr_in6 sin6 = {
 		.sin6_family		= AF_INET6,
@@ -912,6 +937,22 @@ static void __svc_unregister(const u32 program, const u32 version,
 				(struct sockaddr *)&sin6, "");
 	dprintk("svc: %s(%sv%u), error %d\n",
 			__func__, progname, version, error);
+	return error;
+}
+
+static void __svc_unregister(const u32 program, const u32 version,
+			     const char *progname)
+{
+	if (__svc_register_version == 4) {
+		int error = __svc_v4_unregister(program, version, progname);
+		if (error != -EPROTONOSUPPORT)
+			return;
+	}
+
+	__svc_rpcb_prog_mismatch_error();
+
+	/* Olaf says a v2 UNSET _should_ wipe everything */
+	__svc_v2_unregister(program, version, progname);
 }
 
 #else	/* CONFIG_SUNRPC_REGISTER_V4 */
@@ -919,11 +960,7 @@ static void __svc_unregister(const u32 program, const u32 version,
 static void __svc_unregister(const u32 program, const u32 version,
 			     const char *progname)
 {
-	int error;
-
-	error = rpcb_register(program, version, 0, 0);
-	dprintk("svc: %s(%sv%u), error %d\n",
-			__func__, progname, version, error);
+	__svc_v2_unregister(program, version, progname);
 }
 
 #endif	/* CONFIG_SUNRPC_REGISTER_V4 */

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux