免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: mars007
打印 上一主题 下一主题

SIGKILL信号是如何中止内核线程的? [复制链接]

论坛徽章:
0
11 [报告]
发表于 2008-10-29 08:57 |只看该作者
原帖由 mars007 于 2008-10-28 21:10 发表


内核哪部分代码做了这个操作,望samon_fu兄指出



v2.4.0

int kupdate(void *sem)
{
        struct task_struct * tsk = current;
        int interval;

        tsk->session = 1;
        tsk->pgrp = 1;
        strcpy(tsk->comm, "kupdate";

        /* sigstop and sigcont will stop and wakeup kupdate */
        spin_lock_irq(&tsk->sigmask_lock);
        sigfillset(&tsk->blocked);
        siginitsetinv(&current->blocked, sigmask(SIGCONT) | sigmask(SIGSTOP));
        recalc_sigpending(tsk);
        spin_unlock_irq(&tsk->sigmask_lock);

        up((struct semaphore *)sem);

        for (; {
                /* update interval */
                interval = bdf_prm.b_un.interval;// 5s
                if (interval) {
                        tsk->state = TASK_INTERRUPTIBLE;
                        schedule_timeout(interval);
                } else {
                stop_kupdate:
                        tsk->state = TASK_STOPPED;
                        schedule(); /* wait for SIGCONT */
                }
                /* check for sigstop */
                if (signal_pending(tsk)) {
                        int stopped = 0;
                        spin_lock_irq(&tsk->sigmask_lock);
                        if (sigismember(&tsk->pending.signal, SIGSTOP)) {
                                sigdelset(&tsk->pending.signal, SIGSTOP);
                                stopped = 1;
                        }
                        recalc_sigpending(tsk);
                        spin_unlock_irq(&tsk->sigmask_lock);
                        if (stopped)
                                goto stop_kupdate;
                }
#ifdef DEBUG
                printk("kupdate() activated...\n";
#endif
                sync_old_buffers();
        }
}

论坛徽章:
0
12 [报告]
发表于 2008-10-29 13:11 |只看该作者
klogd本来就是一个用户deamon,何来的内核线程???


谢谢qtdszws兄提醒,klogd确实是一个用户daemon,因此可以用kill -9 杀死

总结一下:内核线程是不能用kill -9 杀死的,因为内核只传递用户态进程的信号.可以向内核线程发送信号,但是内核不会传递(处理)内核线程上的信号,内核线程可以在自己的执行代码中处理发往自己的信号;内核守护线程会阻塞所有信号(daemonize()完成),但是仍然可以使用force_sig()向它发信号

论坛徽章:
0
13 [报告]
发表于 2008-10-31 20:33 |只看该作者

回复 #12 mars007 的帖子

我过会给出~~

论坛徽章:
0
14 [报告]
发表于 2008-10-31 21:44 |只看该作者
原帖由 mars007 于 2008-10-28 21:10 发表


内核哪部分代码做了这个操作,望samon_fu兄指出



对不起,这个我说错了,我说的对应代码是do_signal()中部分:
if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
                        /* Let the debugger run.  */
                        current->exit_code = signr;
                        current->state = TASK_STOPPED;
                        notify_parent(current, SIGCHLD);
                        schedule();
                                                .....

这里的理解是ptrace时,不是SIGKILL时,我这部分理解错了。

而SIGKILL时对应的处理部分是do_signal():
                        default:
                                sigaddset(&current->pending.signal, signr);
                                recalc_sigpending(current);
                                current->flags |= PF_SIGNALED;
                                do_exit(exit_code);
                                /* NOTREACHED */
                        }

跟踪do_exit(...):

NORET_TYPE void do_exit(long code)
{
        struct task_struct *tsk = current;

        if (in_interrupt())
                panic("Aiee, killing interrupt handler!");
        if (!tsk->pid)
                panic("Attempted to kill the idle task!");
        if (tsk->pid == 1)
                panic("Attempted to kill init!");
        tsk->flags |= PF_EXITING;
        del_timer_sync(&tsk->real_timer);

fake_volatile:
#ifdef CONFIG_BSD_PROCESS_ACCT
        acct_process(code);
#endif
        __exit_mm(tsk);

        lock_kernel();
        sem_exit();
        __exit_files(tsk);
        __exit_fs(tsk);
        exit_sighand(tsk);
        exit_thread();

        if (current->leader)
                disassociate_ctty(1);

        put_exec_domain(tsk->exec_domain);
        if (tsk->binfmt && tsk->binfmt->module)
                __MOD_DEC_USE_COUNT(tsk->binfmt->module);

        tsk->exit_code = code;
        exit_notify();
        schedule();
        BUG();
/*
* In order to get rid of the "volatile function does return" message
* I did this little loop that confuses gcc to think do_exit really
* is volatile. In fact it's schedule() that is volatile in some
* circumstances: when current->state = ZOMBIE, schedule() never
* returns.
*
* In fact the natural way to do all this is to have the label and the
* goto right after each other, but I put the fake_volatile label at
* the start of the function just in case something /really/ bad
* happens, and the schedule returns. This way we can try again. I'm
* not paranoid: it's just that everybody is out to get me.
*/
        goto fake_volatile;
}

这部分干的活的意思差不多,释放各种资源,然后解决进程间关系,通知父进程。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP