aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2008-09-25 11:56:57 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2008-09-29 18:13:40 -0400
commitf6fb3f6f591b50fa4f51962ad06ee0d8782e1bc8 (patch)
tree2a50459b61ffdecac33bf99f41a24ce521994f1d /net
parent9d548b9c955c0709d1229d21d0bc14afa6b356de (diff)
SUNRPC: Fix up svc_unregister()
With the new rpcbind code, a PMAP_UNSET will not have any effect on services registered via rpcbind v3 or v4. Implement a version of svc_unregister() that uses an RPCB_UNSET with an empty netid string to make sure we have cleared *all* entries for a kernel RPC service when shutting down, or before starting a fresh instance of the service. Use the new version only when CONFIG_SUNRPC_REGISTER_V4 is enabled; otherwise, the legacy PMAP version is used to ensure complete backwards-compatibility with the Linux portmapper daemon. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/svc.c58
1 files changed, 38 insertions, 20 deletions
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index b8d2fcd0f715..54c98d876847 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -896,31 +896,51 @@ int svc_register(const struct svc_serv *serv, const unsigned short proto,
896 return error; 896 return error;
897} 897}
898 898
899#ifdef CONFIG_SUNRPC_REGISTER_V4
900
901static void __svc_unregister(const u32 program, const u32 version,
902 const char *progname)
903{
904 struct sockaddr_in6 sin6 = {
905 .sin6_family = AF_INET6,
906 .sin6_addr = IN6ADDR_ANY_INIT,
907 .sin6_port = 0,
908 };
909 int error;
910
911 error = rpcb_v4_register(program, version,
912 (struct sockaddr *)&sin6, "");
913 dprintk("svc: %s(%sv%u), error %d\n",
914 __func__, progname, version, error);
915}
916
917#else /* CONFIG_SUNRPC_REGISTER_V4 */
918
919static void __svc_unregister(const u32 program, const u32 version,
920 const char *progname)
921{
922 int error;
923
924 error = rpcb_register(program, version, 0, 0);
925 dprintk("svc: %s(%sv%u), error %d\n",
926 __func__, progname, version, error);
927}
928
929#endif /* CONFIG_SUNRPC_REGISTER_V4 */
930
899/* 931/*
900 * All transport protocols and ports for this service are removed 932 * All netids, bind addresses and ports registered for [program, version]
901 * from the local rpcbind database if the service is not hidden. 933 * are removed from the local rpcbind database (if the service is not
902 * 934 * hidden) to make way for a new instance of the service.
903 * The result of unregistration is reported via dprintk for those
904 * who want verification of the result, but is otherwise not
905 * important.
906 * 935 *
907 * The local rpcbind daemon listens on either only IPv6 or only 936 * The result of unregistration is reported via dprintk for those who want
908 * IPv4. The kernel can't tell how it's configured. However, 937 * verification of the result, but is otherwise not important.
909 * AF_INET addresses are mapped to AF_INET6 in IPv6-only config-
910 * urations, so even an unregistration request on AF_INET will
911 * get to a local rpcbind daemon listening only on AF_INET6. So
912 * we always unregister via AF_INET.
913 *
914 * At this point we don't need rpcbind version 4 for unregis-
915 * tration: A v2 UNSET request will clear all transports (netids),
916 * addresses, and address families for [program, version].
917 */ 938 */
918static void svc_unregister(const struct svc_serv *serv) 939static void svc_unregister(const struct svc_serv *serv)
919{ 940{
920 struct svc_program *progp; 941 struct svc_program *progp;
921 unsigned long flags; 942 unsigned long flags;
922 unsigned int i; 943 unsigned int i;
923 int error;
924 944
925 clear_thread_flag(TIF_SIGPENDING); 945 clear_thread_flag(TIF_SIGPENDING);
926 946
@@ -931,9 +951,7 @@ static void svc_unregister(const struct svc_serv *serv)
931 if (progp->pg_vers[i]->vs_hidden) 951 if (progp->pg_vers[i]->vs_hidden)
932 continue; 952 continue;
933 953
934 error = rpcb_register(progp->pg_prog, i, 0, 0); 954 __svc_unregister(progp->pg_prog, i, progp->pg_name);
935 dprintk("svc: svc_unregister(%sv%u), error %d\n",
936 progp->pg_name, i, error);
937 } 955 }
938 } 956 }
939 957