The commit is pushed to "branch-rh9-5.14.vz9.1.x-ovz" and will appear at 
https://src.openvz.org/scm/ovz/vzkernel.git
after ark-5.14
------>
commit dc2fabbe5eff60a6b04031b54183348064f6d4ad
Author: Stanislav Kinsburskiy <skinsbur...@virtuozzo.com>
Date:   Tue Sep 28 14:42:39 2021 +0300

    sunrpc: add "kill-tasks" proc entry
    
    Boolean per-net SUNPRC proc entry. Will be used to abort SUNRPC traffic when
    necessary.
    
    https://jira.sw.ru/browse/PSBM-66510
    
    Signed-off-by: Stanislav Kinsburskiy <skinsbur...@virtuozzo.com>
    
    (cherry-picked from vz8 commit 22ca0165a75b ("sunrpc: add "kill-tasks"
    proc entry"))
    
    Follow file_operations -> proc_ops migration.
    
    Signed-off-by: Nikita Yushchenko <nikita.yushche...@virtuozzo.com>
---
 include/linux/sunrpc/clnt.h |  3 ++
 net/sunrpc/clnt.c           | 71 +++++++++++++++++++++++++++++++++++++++++++++
 net/sunrpc/netns.h          |  3 ++
 net/sunrpc/stats.c          |  8 +++++
 4 files changed, 85 insertions(+)

diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 8b5d5c97553e..ac3899388a0d 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -232,6 +232,9 @@ int         rpc_clnt_setup_test_and_add_xprt(struct 
rpc_clnt *,
 
 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);
+
 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 8b4de70e8ead..c9b92a1a3eb1 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -3071,3 +3071,74 @@ rpc_clnt_swap_deactivate(struct rpc_clnt *clnt)
 }
 EXPORT_SYMBOL_GPL(rpc_clnt_swap_deactivate);
 #endif /* CONFIG_SUNRPC_SWAP */
+
+static ssize_t write_kill_tasks(struct file *file, const char __user *buf,
+                        size_t count, loff_t *ppos)
+{
+       struct net *net = PDE_DATA(file->f_path.dentry->d_inode);
+       struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+       char tbuf[20];
+       unsigned long kill_tasks;
+       int res;
+
+       if (*ppos || count > sizeof(tbuf)-1)
+               return -EINVAL;
+       if (copy_from_user(tbuf, buf, count))
+               return -EFAULT;
+
+       tbuf[count] = 0;
+       res = kstrtoul(tbuf, 0, &kill_tasks);
+       if (res)
+               return res;
+
+       sn->kill_tasks = !!kill_tasks;
+       return count;
+}
+
+static ssize_t read_kill_tasks(struct file *file, char __user *buf,
+                        size_t count, loff_t *ppos)
+{
+       struct net *net = PDE_DATA(file->f_path.dentry->d_inode);
+       struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+       unsigned long p = *ppos;
+       char tbuf[10];
+       size_t len;
+
+       snprintf(tbuf, sizeof(tbuf), "%d\n", sn->kill_tasks);
+       len = strlen(tbuf);
+       if (p >= len)
+               return 0;
+       len -= p;
+       if (len > count)
+               len = count;
+       if (copy_to_user(buf, (void *)(tbuf+p), len))
+               return -EFAULT;
+       *ppos += len;
+       return len;
+}
+
+static const struct proc_ops kill_tasks_ops = {
+       .proc_open = nonseekable_open,
+       .proc_write = write_kill_tasks,
+       .proc_read = read_kill_tasks,
+};
+
+int rpc_task_kill_proc_init(struct net *net)
+{
+       struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+       sn->kill_tasks = 0;
+       sn->kill_tasks_proc = proc_create_data("kill-tasks",
+                                             S_IFREG|S_IRUSR|S_IWUSR,
+                                             sn->proc_net_rpc,
+                                             &kill_tasks_ops, net);
+       return sn->kill_tasks_proc ? 0 : -ENOMEM;
+}
+
+void rpc_task_kill_proc_fini(struct net *net)
+{
+       struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+       if (sn->kill_tasks_proc)
+               remove_proc_entry("kill-tasks", sn->proc_net_rpc);
+}
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
index 7ec10b92bea1..14689d6298b9 100644
--- a/net/sunrpc/netns.h
+++ b/net/sunrpc/netns.h
@@ -33,6 +33,9 @@ struct sunrpc_net {
        int pipe_version;
        atomic_t pipe_users;
        struct proc_dir_entry *use_gssp_proc;
+
+       bool kill_tasks;
+       struct proc_dir_entry *kill_tasks_proc;
 };
 
 extern unsigned int sunrpc_net_id;
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
index 77434b2017ad..45541aa49c98 100644
--- a/net/sunrpc/stats.c
+++ b/net/sunrpc/stats.c
@@ -326,6 +326,7 @@ EXPORT_SYMBOL_GPL(svc_proc_unregister);
 int rpc_proc_init(struct net *net)
 {
        struct sunrpc_net *sn;
+       int err;
 
        dprintk("RPC:       registering /proc/net/rpc\n");
        sn = net_generic(net, sunrpc_net_id);
@@ -333,11 +334,18 @@ int rpc_proc_init(struct net *net)
        if (sn->proc_net_rpc == NULL)
                return -ENOMEM;
 
+       err = rpc_task_kill_proc_init(net);
+       if (err) {
+               remove_proc_entry("rpc", net->proc_net);
+               return err;
+       }
+
        return 0;
 }
 
 void rpc_proc_exit(struct net *net)
 {
        dprintk("RPC:       unregistering /proc/net/rpc\n");
+       rpc_task_kill_proc_fini(net);
        remove_proc_entry("rpc", net->proc_net);
 }
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to