Commit 012da158 authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust

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: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 2a76b3bf
...@@ -1060,7 +1060,7 @@ call_bind_status(struct rpc_task *task) ...@@ -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) ...@@ -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 ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment