SUNRPC: Use soft connects for autobinding over TCP
Autobinding is handled by the rpciod process, not in user processes that are generating regular RPC requests. Thus autobinding is usually not affected by signals targetting user processes, such as KILL or timer expiration events. In addition, an RPC request generated by a user process that has RPC_TASK_SOFTCONN set and needs to perform an autobind will hang if the remote rpcbind service is not available. For rpcbind queries on connection-oriented transports, let's use the new soft connect semantic to return control to the user's process quickly, if the kernel's rpcbind client can't connect to the remote rpcbind service. Logic is introduced in call_bind_status() to handle connection errors that occurred during an asynchronous rpcbind query. The logic abandons the rpcbind query if the RPC request has SOFTCONN set, and retries after a few seconds in the normal case. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
2a76b3bfa2
commit
012da158f6
|
@ -1060,7 +1060,7 @@ call_bind_status(struct rpc_task *task)
|
||||||
goto retry_timeout;
|
goto retry_timeout;
|
||||||
case -EPFNOSUPPORT:
|
case -EPFNOSUPPORT:
|
||||||
/* server doesn't support any rpcbind version we know of */
|
/* server doesn't support any rpcbind version we know of */
|
||||||
dprintk("RPC: %5u remote rpcbind service unavailable\n",
|
dprintk("RPC: %5u unrecognized remote rpcbind service\n",
|
||||||
task->tk_pid);
|
task->tk_pid);
|
||||||
break;
|
break;
|
||||||
case -EPROTONOSUPPORT:
|
case -EPROTONOSUPPORT:
|
||||||
|
@ -1069,6 +1069,21 @@ call_bind_status(struct rpc_task *task)
|
||||||
task->tk_status = 0;
|
task->tk_status = 0;
|
||||||
task->tk_action = call_bind;
|
task->tk_action = call_bind;
|
||||||
return;
|
return;
|
||||||
|
case -ECONNREFUSED: /* connection problems */
|
||||||
|
case -ECONNRESET:
|
||||||
|
case -ENOTCONN:
|
||||||
|
case -EHOSTDOWN:
|
||||||
|
case -EHOSTUNREACH:
|
||||||
|
case -ENETUNREACH:
|
||||||
|
case -EPIPE:
|
||||||
|
dprintk("RPC: %5u remote rpcbind unreachable: %d\n",
|
||||||
|
task->tk_pid, task->tk_status);
|
||||||
|
if (!RPC_IS_SOFTCONN(task)) {
|
||||||
|
rpc_delay(task, 5*HZ);
|
||||||
|
goto retry_timeout;
|
||||||
|
}
|
||||||
|
status = task->tk_status;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
dprintk("RPC: %5u unrecognized rpcbind error (%d)\n",
|
dprintk("RPC: %5u unrecognized rpcbind error (%d)\n",
|
||||||
task->tk_pid, -task->tk_status);
|
task->tk_pid, -task->tk_status);
|
||||||
|
|
|
@ -537,7 +537,7 @@ static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbi
|
||||||
.rpc_message = &msg,
|
.rpc_message = &msg,
|
||||||
.callback_ops = &rpcb_getport_ops,
|
.callback_ops = &rpcb_getport_ops,
|
||||||
.callback_data = map,
|
.callback_data = map,
|
||||||
.flags = RPC_TASK_ASYNC,
|
.flags = RPC_TASK_ASYNC | RPC_TASK_SOFTCONN,
|
||||||
};
|
};
|
||||||
|
|
||||||
return rpc_run_task(&task_setup_data);
|
return rpc_run_task(&task_setup_data);
|
||||||
|
|
Loading…
Reference in New Issue