[Devel,2/2] sunrpc: bring back SUNRPC task abort logic

Submitted by Stanislav Kinsburskiy on June 23, 2017, 1:03 p.m.

Details

Message ID 20170623130334.25738.10134.stgit@localhost.localdomain
State New
Series "Handle SUNRPC tasks on container stop when network is"
Headers show

Commit Message

Stanislav Kinsburskiy June 23, 2017, 1:03 p.m.
We had this logic in vz6. But it was applied to any stop there.
The intention was to solve 2 tasks:
1) allow to stop container when network is unaccessible
2) allow to suspend container with blocked network traffic.

In vz7 we need the traffic to flow on suspend. Thus we have to distinguish
between suspend (where the network must work) and "fast stop", when we want to
kill container quickly (something similar to "reset" button).
This dinstiguishment can be based on VE struct "sunrpc_abort" attribute, which
has to be set only in case of "fast stop".

this solution allows us to mimic hardware behaviour closely. IOW, on normal
stop (or migration) SUNRPC operates normally. But when user wants to stop it
fast (i.e. he doesn't care about data, etc), then he can use "--fast" option
and this patch comes into play.

https://jira.sw.ru/browse/PSBM-66510

Signed-off-by: Stanislav Kinsburskiy <skinsbursky@virtuozzo.com>
---
 net/sunrpc/sched.c |   31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

Patch hide | download patch | download mbox

diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 16ada61..4040437 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -712,6 +712,32 @@  void rpc_release_calldata(const struct rpc_call_ops *ops, void *calldata)
 		ops->rpc_release(calldata);
 }
 
+static struct ve_struct *rpc_task_ve(struct rpc_task *task)
+{
+	if (task->tk_client)
+		return task->tk_client->cl_xprt->xprt_net->owner_ve;
+	else if (task->tk_rqstp)
+		return task->tk_rqstp->rq_xprt->xprt_net->owner_ve;
+	else
+		BUG();
+}
+
+static inline bool rpc_abort_task_ve(struct rpc_task *task)
+{
+	struct ve_struct *ve = rpc_task_ve(task);
+#if 0
+	if (likely(ve->is_running))
+		return false;
+#endif
+	if (!ve->sunrpc_abort)
+		return false;
+
+	dprintk("RPC: SUNRPC is aborted in VE%d. Drop task %5u with EIO.\n",
+			ve->veid, task->tk_pid);
+
+	return true;
+}
+
 /*
  * This is the RPC `scheduler' (or rather, the finite state machine).
  */
@@ -728,6 +754,11 @@  static void __rpc_execute(struct rpc_task *task)
 	if (RPC_IS_QUEUED(task))
 		return;
 
+	if (rpc_abort_task_ve(task)) {
+		task->tk_flags |= RPC_TASK_KILLED;
+		rpc_exit(task, -EIO);
+	}
+
 	for (;;) {
 		void (*do_action)(struct rpc_task *);