[PATCH 05/24] task_diag: add ability to get information about all tasks
From: Andrey Vagin <hidden>
Date: 2015-07-06 08:50:51
Also in:
lkml
Subsystem:
taskstats statistics interface, the rest · Maintainers:
Balbir Singh, Linus Torvalds
For that we need to set NLM_F_DUMP. A response contain on a few packets. Signed-off-by: Andrey Vagin <redacted> --- include/linux/taskstats_kern.h | 2 ++ kernel/taskdiag.c | 40 ++++++++++++++++++++++++++++++++++++++++ kernel/taskstats.c | 1 + 3 files changed, 43 insertions(+)
diff --git a/include/linux/taskstats_kern.h b/include/linux/taskstats_kern.h
index a1fd4f8..716835f 100644
--- a/include/linux/taskstats_kern.h
+++ b/include/linux/taskstats_kern.h@@ -29,6 +29,8 @@ extern void taskstats_init_early(void); struct genl_info; struct sk_buff; int taskdiag_doit(struct sk_buff *skb, struct genl_info *info); +struct netlink_callback; +int taskdiag_dumpit(struct sk_buff *skb, struct netlink_callback *cb); #else static inline void taskstats_exit(struct task_struct *tsk, int group_dead)
diff --git a/kernel/taskdiag.c b/kernel/taskdiag.c
index 7327e08..3497304 100644
--- a/kernel/taskdiag.c
+++ b/kernel/taskdiag.c@@ -112,6 +112,46 @@ err: return err; } +int taskdiag_dumpit(struct sk_buff *skb, struct netlink_callback *cb) +{ + struct pid_namespace *ns = task_active_pid_ns(current); + struct tgid_iter iter; + struct nlattr *na; + struct task_diag_pid req; + int rc; + + if (nlmsg_len(cb->nlh) < GENL_HDRLEN + sizeof(req)) + return -EINVAL; + + na = nlmsg_data(cb->nlh) + GENL_HDRLEN; + if (na->nla_type < 0) + return -EINVAL; + + memcpy(&req, nla_data(na), sizeof(req)); + + iter.tgid = cb->args[0]; + iter.task = NULL; + for (iter = next_tgid(ns, iter); + iter.task; + iter.tgid += 1, iter = next_tgid(ns, iter)) { + if (!ptrace_may_access(iter.task, PTRACE_MODE_READ)) + continue; + + rc = task_diag_fill(iter.task, skb, req.show_flags, + NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq); + if (rc < 0) { + put_task_struct(iter.task); + if (rc != -EMSGSIZE) + return rc; + break; + } + } + + cb->args[0] = iter.tgid; + + return skb->len; +} + int taskdiag_doit(struct sk_buff *skb, struct genl_info *info) { struct nlattr *nla = info->attrs[TASK_DIAG_CMD_ATTR_GET];
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 0c90d11..40f2cdf2 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c@@ -691,6 +691,7 @@ static const struct genl_ops taskstats_ops[] = { { .cmd = TASK_DIAG_CMD_GET, .doit = taskdiag_doit, + .dumpit = taskdiag_dumpit, .policy = taskdiag_cmd_get_policy, }, #endif
--
2.1.0