/proc/<pid>にファイルをおいてデータを読みたい

/proc/<pid>/ にファイルを作ってデータを読めると便利なときがあったりするのでめも。

今回はcgroup.cで処理を実装して、その関数をcgroup.hにて宣言。fs/proc/base.cでcgroupのほうに追加した関数を登録する形です。/proc/<pid> にあるファイルに対する関数はここで登録されてます。 差分はこのような感じです。

git masami@kerntest:~/linux-kernel (ktest *=)$ git diff --stat
 fs/proc/base.c         | 2 ++
 include/linux/cgroup.h | 2 ++
 kernel/cgroup/cgroup.c | 7 +++++++
 3 files changed, 11 insertions(+)

最小限のコードはこのようになります。

masami@kerntest:~/linux-kernel (ktest *=)$ git diff
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 45f6bf6..db65c94 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2909,6 +2909,7 @@ static const struct pid_entry tgid_base_stuff[] = {
 #endif
 #ifdef CONFIG_CGROUPS
        ONE("cgroup",  S_IRUGO, proc_cgroup_show),
+       ONE("cg_list",  S_IRUGO, proc_cg_list_show),
 #endif
        ONE("oom_score",  S_IRUGO, proc_oom_score),
        REG("oom_adj",    S_IRUGO|S_IWUSR, proc_oom_adj_operations),
@@ -3301,6 +3302,7 @@ static const struct pid_entry tid_base_stuff[] = {
 #endif
 #ifdef CONFIG_CGROUPS
        ONE("cgroup",  S_IRUGO, proc_cgroup_show),
+       ONE("cg_list",  S_IRUGO, proc_cg_list_show),
 #endif
        ONE("oom_score", S_IRUGO, proc_oom_score),
        REG("oom_adj",   S_IRUGO|S_IWUSR, proc_oom_adj_operations),
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index ed2573e..41ae434 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -101,6 +101,8 @@ int task_cgroup_path(struct task_struct *task, char *buf, size_t buflen);
 int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry);
 int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns,
                     struct pid *pid, struct task_struct *tsk);
+int proc_cg_list_show(struct seq_file *m, struct pid_namespace *ns,
+                     struct pid *pid, struct task_struct *task);

 void cgroup_fork(struct task_struct *p);
 extern int cgroup_can_fork(struct task_struct *p);
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index c3c9a0e..ab5094f 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -4600,6 +4600,13 @@ static int __init cgroup_wq_init(void)
 }
 core_initcall(cgroup_wq_init);

+int proc_cg_list_show(struct seq_file *m, struct pid_namespace *ns,
+                     struct pid *pid, struct task_struct *task)
+{
+       seq_printf(m, "%s\n", __func__);
+       return 0;
+}
+
 /*
  * proc_cgroup_show()
  *  - Print task's cgroup paths into seq_file, one line for each hierarchy

実行するとこうなります。

masami@kerntest:~$ ls /proc/self/
./     autogroup  cgroup      comm             cwd@     fd/      io       loginuid      maps       mounts      ns/        oom_score      patch_state  root@      sessionid  stack  status   timers         wchan
../    auxv       clear_refs  coredump_filter  environ  fdinfo/  latency  make-it-fail  mem        mountstats  numa_maps  oom_score_adj  personality  sched      setgroups  stat   syscall  timerslack_ns
attr/  cg_list    cmdline     cpuset           exe@     gid_map  limits   map_files/    mountinfo  net/        oom_adj    pagemap        projid_map   schedstat  smaps      statm  task/    uid_map
masami@kerntest:~$ cat /proc/self/cg_list
proc_cg_list_show
masami@kerntest:~$