mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	SUNRPC: new interface to force an RPC rebind
We'd like to hide fields in rpc_xprt and rpc_clnt from upper layer protocols. Start by creating an API to force RPC rebind, replacing logic that simply sets cl_port to zero. Test-plan: Destructive testing (unplugging the network temporarily). Connectathon with UDP and TCP. NFSv2/3 and NFSv4 mounting should be carefully checked. Probably need to rig a server where certain services aren't running, or that returns an error for some typical operation. Signed-off-by: Chuck Lever <cel@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
		
							parent
							
								
									0210714834
								
							
						
					
					
						commit
						35f5a422ce
					
				
					 3 changed files with 18 additions and 8 deletions
				
			
		| 
						 | 
					@ -177,7 +177,7 @@ nlm_bind_host(struct nlm_host *host)
 | 
				
			||||||
	if ((clnt = host->h_rpcclnt) != NULL) {
 | 
						if ((clnt = host->h_rpcclnt) != NULL) {
 | 
				
			||||||
		xprt = clnt->cl_xprt;
 | 
							xprt = clnt->cl_xprt;
 | 
				
			||||||
		if (time_after_eq(jiffies, host->h_nextrebind)) {
 | 
							if (time_after_eq(jiffies, host->h_nextrebind)) {
 | 
				
			||||||
			clnt->cl_port = 0;
 | 
								rpc_force_rebind(clnt);
 | 
				
			||||||
			host->h_nextrebind = jiffies + NLM_HOST_REBIND;
 | 
								host->h_nextrebind = jiffies + NLM_HOST_REBIND;
 | 
				
			||||||
			dprintk("lockd: next rebind in %ld jiffies\n",
 | 
								dprintk("lockd: next rebind in %ld jiffies\n",
 | 
				
			||||||
					host->h_nextrebind - jiffies);
 | 
										host->h_nextrebind - jiffies);
 | 
				
			||||||
| 
						 | 
					@ -217,7 +217,7 @@ nlm_rebind_host(struct nlm_host *host)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	dprintk("lockd: rebind host %s\n", host->h_name);
 | 
						dprintk("lockd: rebind host %s\n", host->h_name);
 | 
				
			||||||
	if (host->h_rpcclnt && time_after_eq(jiffies, host->h_nextrebind)) {
 | 
						if (host->h_rpcclnt && time_after_eq(jiffies, host->h_nextrebind)) {
 | 
				
			||||||
		host->h_rpcclnt->cl_port = 0;
 | 
							rpc_force_rebind(host->h_rpcclnt);
 | 
				
			||||||
		host->h_nextrebind = jiffies + NLM_HOST_REBIND;
 | 
							host->h_nextrebind = jiffies + NLM_HOST_REBIND;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -135,6 +135,7 @@ void		rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset);
 | 
				
			||||||
void		rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset);
 | 
					void		rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset);
 | 
				
			||||||
void		rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int);
 | 
					void		rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int);
 | 
				
			||||||
size_t		rpc_max_payload(struct rpc_clnt *);
 | 
					size_t		rpc_max_payload(struct rpc_clnt *);
 | 
				
			||||||
 | 
					void		rpc_force_rebind(struct rpc_clnt *);
 | 
				
			||||||
int		rpc_ping(struct rpc_clnt *clnt, int flags);
 | 
					int		rpc_ping(struct rpc_clnt *clnt, int flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static __inline__
 | 
					static __inline__
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -538,6 +538,18 @@ size_t rpc_max_payload(struct rpc_clnt *clnt)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(rpc_max_payload);
 | 
					EXPORT_SYMBOL(rpc_max_payload);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * rpc_force_rebind - force transport to check that remote port is unchanged
 | 
				
			||||||
 | 
					 * @clnt: client to rebind
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void rpc_force_rebind(struct rpc_clnt *clnt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (clnt->cl_autobind)
 | 
				
			||||||
 | 
							clnt->cl_port = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(rpc_force_rebind);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Restart an (async) RPC call. Usually called from within the
 | 
					 * Restart an (async) RPC call. Usually called from within the
 | 
				
			||||||
 * exit handler.
 | 
					 * exit handler.
 | 
				
			||||||
| 
						 | 
					@ -853,8 +865,7 @@ call_connect_status(struct rpc_task *task)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Something failed: remote service port may have changed */
 | 
						/* Something failed: remote service port may have changed */
 | 
				
			||||||
	if (clnt->cl_autobind)
 | 
						rpc_force_rebind(clnt);
 | 
				
			||||||
		clnt->cl_port = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (status) {
 | 
						switch (status) {
 | 
				
			||||||
	case -ENOTCONN:
 | 
						case -ENOTCONN:
 | 
				
			||||||
| 
						 | 
					@ -935,8 +946,7 @@ call_status(struct rpc_task *task)
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case -ECONNREFUSED:
 | 
						case -ECONNREFUSED:
 | 
				
			||||||
	case -ENOTCONN:
 | 
						case -ENOTCONN:
 | 
				
			||||||
		if (clnt->cl_autobind)
 | 
							rpc_force_rebind(clnt);
 | 
				
			||||||
			clnt->cl_port = 0;
 | 
					 | 
				
			||||||
		task->tk_action = call_bind;
 | 
							task->tk_action = call_bind;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case -EAGAIN:
 | 
						case -EAGAIN:
 | 
				
			||||||
| 
						 | 
					@ -995,8 +1005,7 @@ call_timeout(struct rpc_task *task)
 | 
				
			||||||
		printk(KERN_NOTICE "%s: server %s not responding, still trying\n",
 | 
							printk(KERN_NOTICE "%s: server %s not responding, still trying\n",
 | 
				
			||||||
			clnt->cl_protname, clnt->cl_server);
 | 
								clnt->cl_protname, clnt->cl_server);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (clnt->cl_autobind)
 | 
						rpc_force_rebind(clnt);
 | 
				
			||||||
		clnt->cl_port = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
retry:
 | 
					retry:
 | 
				
			||||||
	clnt->cl_stats->rpcretrans++;
 | 
						clnt->cl_stats->rpcretrans++;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue