fedora16でのfind_task_by_vpid関数
fedora16では、find_task_by_vpid()はEXPORTされなくなています。find_task_by_vpid()はカレントプロセスのPIDネームスペース下で、プロセスIDから取得したpidを引数として、PIDTYPE_PIDで、pid_task()をコールすることでtask_structを取得しています。pid_task()/find_pid_ns()はEXPORTされています。
struct task_struct *find_task_by_vpid(pid_t vnr) { return find_task_by_pid_ns(vnr, current->nsproxy->pid_ns); } struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns) { rcu_lockdep_assert(rcu_read_lock_held(), "find_task_by_pid_ns() needs rcu_read_lock()" " protection"); return pid_task(find_pid_ns(nr, ns), PIDTYPE_PID); }上記処理を、EXPORTとしてfind_task_by_vpid()のモジュールを作成することで、従来と同じようにfind_task_by_vpid()を使用することが可能となります。
#include <linux/nsproxy.h> #include <linux/module.h> MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("find_task_by_vpid"); MODULE_AUTHOR("y.kitamura"); struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns) { /* rcu_lockdep_assert(rcu_read_lock_held(), "find_task_by_pid_ns() needs rcu_read_lock()" " protection"); */ return pid_task(find_pid_ns(nr, ns), PIDTYPE_PID); } struct task_struct *find_task_by_vpid(pid_t vnr) { return find_task_by_pid_ns(vnr, current->nsproxy->pid_ns); } EXPORT_SYMBOL_GPL(find_task_by_vpid); static int init_find_task_by_vpid(void) { struct task_struct *process; process = find_task_by_vpid(1); if (process) { printk("%s\n", process->comm); } else { printk("pid error\n"); return -EFAULT; } return 0; } static void exit_find_task_by_vpid(void) { } module_init(init_find_task_by_vpid); module_exit(exit_find_task_by_vpid);rcu_lockdep_assertマクロは、rcuデバッグ用で、CONFIG_PROVE_RCUのコンパイル時のみ有効となるマクロです。従ってコメントとして問題ないと思います。
[root@localhost lkm]# insmod find_task_by_vpid.ko [root@localhost lkm]# dmesg : : [22057.628876] dbus[923]: [system] Successfully activated service 'org.freedesktop.PackageKit' [22454.947196] systemdここでは、init_find_task_by_vpidでの実行結果を見ていますが、EXPORT_SYMBOL_GPL(find_task_by_vpid)としているため、本モジュールが常駐すると、他のLKMからfind_task_by_vpidをコールすることができます。