原貼:http://www.xclinux.cn/?p=752
如何殺掉D狀態的進程?[zt]
狀態為 D (Uninterruptible sleep) ,以及狀態為 Z (Zombie)這些垃圾進程要么是求而不得,像怨婦一般等待資源(D),要么是僵而不死,像冤魂一樣等待超度(Z),它們在 CPU run_queue 里滯留不去,把 Load Average 弄的老高老高,沒看過我前一篇blog的國際友人還以為這兒民怨沸騰又出了什么大事呢。怎么辦?開槍!kill -9!看你們走是不走。但這兩種垃圾進程偏偏是刀槍不入的,不管換哪種槍法都殺不掉它們。無奈,只好reboot,像剿滅禽流感那樣不分青紅皂白地一律撲殺!
基本想法就是修改內核,遍歷進程列表,找到處於D狀態的進程,將其狀態轉換為別的狀態就可以kill掉了。
這是一種比較粗魯的方法,可能會引起一些不良后果,暫時沒有考慮。對於確切知道已經沒有什么用處,不用做清理工作的,處於D狀態怎么也殺不死的進程來說,確是很有效。
內核模塊代碼:
—————-killd.c—————-
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h> //for_each_process
MODULE_LICENSE("BSD");
static int pid = -1;
module_param(pid, int, S_IRUGO);
static int killd_init(void)
{
struct task_struct * p;
printk(KERN_ALERT "killd: force D status process to death/n");
printk(KERN_ALERT "killd: pid=%d/n", pid);
//read_lock(&tasklist_lock);
for_each_process(p){
if(p->pid == pid){
printk("killd: found/n");
set_task_state(p, TASK_STOPPED);
printk(KERN_ALERT "killd: aha, dead already/n");
return 0;
}
}
printk("not found");
//read_unlock(&tasklist_lock);
return 0;
}
static void killd_exit(void)
{
printk(KERN_ALERT "killd: bye/n");
}
module_init(killd_init);
module_exit(killd_exit);
—–Makefile————
obj-m := killd.o
編譯模塊
make -C yourkerneltree M=`pwd` modules
插入模塊的時候提供D狀態的進程號,就可以將其轉換為stopped狀態,使用普通kill就可以殺死。
./insmod ./killd.ko pid=1234