[Devel] [PATCH vz9 11/14] sunrpc: bring back SUNRPC task abort logic

Nikita Yushchenko nikita.yushchenko at virtuozzo.com
Mon Sep 27 09:29:57 MSK 2021


From: Stanislav Kinsburskiy <skinsbursky at virtuozzo.com>

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 per-net SUNRPC "kill-tasks" 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

SUNRPC task can have no RPC client, but RPC request instead
(this is a piece of NFSv4.1 callback magic).

In this case network has be taken from tk->rqstp object.

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

Signed-off-by: Stanislav Kinsburskiy <skinsbursky at virtuozzo.com>

(cherry-picked from vz8 commit a4802ae6b93c ("sunrpc: bring back SUNRPC task
abort logic"))

Signed-off-by: Nikita Yushchenko <nikita.yushchenko at virtuozzo.com>
---
 include/linux/sunrpc/clnt.h |  2 ++
 net/sunrpc/clnt.c           | 21 +++++++++++++++++++++
 net/sunrpc/sched.c          |  5 +++++
 3 files changed, 28 insertions(+)

diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index ac3899388a0d..4c256a981769 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -235,6 +235,8 @@ const char *rpc_proc_name(const struct rpc_task *task);
 int rpc_task_kill_proc_init(struct net *net);
 void rpc_task_kill_proc_fini(struct net *net);
 
+bool rpc_abort_task(struct rpc_task *task);
+
 void rpc_clnt_xprt_switch_put(struct rpc_clnt *);
 void rpc_clnt_xprt_switch_add_xprt(struct rpc_clnt *, struct rpc_xprt *);
 bool rpc_clnt_xprt_switch_has_addr(struct rpc_clnt *clnt,
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index c9b92a1a3eb1..c1415984a21e 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -3142,3 +3142,24 @@ void rpc_task_kill_proc_fini(struct net *net)
 	if (sn->kill_tasks_proc)
 		remove_proc_entry("kill-tasks", sn->proc_net_rpc);
 }
+
+static struct net *rpc_task_net(struct rpc_task *task)
+{
+	if (task->tk_client)
+		return rpc_net_ns(task->tk_client);
+	return task->tk_rqstp->rq_xprt->xprt_net;
+}
+
+bool rpc_abort_task(struct rpc_task *task)
+{
+	struct net *net = rpc_task_net(task);
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+	if (!sn->kill_tasks)
+		return false;
+
+	dprintk("RPC: SUNRPC traffic is suppressed. Drop task %5u with EIO.\n",
+			task->tk_pid);
+
+	return true;
+}
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index c045f63d11fa..bf7119bd2f25 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -880,6 +880,11 @@ static void __rpc_execute(struct rpc_task *task)
 	if (RPC_IS_QUEUED(task))
 		return;
 
+	if (rpc_abort_task(task)) {
+		rpc_signal_task(task);
+		rpc_exit(task, -EIO);
+	}
+
 	for (;;) {
 		void (*do_action)(struct rpc_task *);
 
-- 
2.30.2



More information about the Devel mailing list