]> rtime.felk.cvut.cz Git - linux-imx.git/blobdiff - fs/coredump.c
coredump: only SIGKILL should interrupt the coredumping task
[linux-imx.git] / fs / coredump.c
index c6479658d4875c0eac32db5c262f515468d3ec76..f91cfd8cd5f2ec83284dac73eacd5b71d8449fd1 100644 (file)
@@ -280,8 +280,8 @@ static int zap_process(struct task_struct *start, int exit_code)
        return nr;
 }
 
-static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm,
-                               struct core_state *core_state, int exit_code)
+static int zap_threads(struct task_struct *tsk, struct mm_struct *mm,
+                       struct core_state *core_state, int exit_code)
 {
        struct task_struct *g, *p;
        unsigned long flags;
@@ -291,6 +291,9 @@ static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm,
        if (!signal_group_exit(tsk->signal)) {
                mm->core_state = core_state;
                nr = zap_process(tsk, exit_code);
+               /* ignore all signals except SIGKILL, see prepare_signal() */
+               tsk->signal->flags |= SIGNAL_GROUP_COREDUMP;
+               clear_tsk_thread_flag(tsk, TIF_SIGPENDING);
        }
        spin_unlock_irq(&tsk->sighand->siglock);
        if (unlikely(nr < 0))
@@ -514,17 +517,12 @@ void do_coredump(siginfo_t *siginfo)
 
        old_cred = override_creds(cred);
 
-       /*
-        * Clear any false indication of pending signals that might
-        * be seen by the filesystem code called to write the core file.
-        */
-       clear_thread_flag(TIF_SIGPENDING);
-
        ispipe = format_corename(&cn, &cprm);
 
-       if (ispipe) {
+       if (ispipe) {
                int dump_count;
                char **helper_argv;
+               struct subprocess_info *sub_info;
 
                if (ispipe < 0) {
                        printk(KERN_WARNING "format_corename failed\n");
@@ -571,15 +569,20 @@ void do_coredump(siginfo_t *siginfo)
                        goto fail_dropcount;
                }
 
-               retval = call_usermodehelper_fns(helper_argv[0], helper_argv,
-                                       NULL, UMH_WAIT_EXEC, umh_pipe_setup,
-                                       NULL, &cprm);
+               retval = -ENOMEM;
+               sub_info = call_usermodehelper_setup(helper_argv[0],
+                                               helper_argv, NULL, GFP_KERNEL,
+                                               umh_pipe_setup, NULL, &cprm);
+               if (sub_info)
+                       retval = call_usermodehelper_exec(sub_info,
+                                                         UMH_WAIT_EXEC);
+
                argv_free(helper_argv);
                if (retval) {
-                       printk(KERN_INFO "Core dump to %s pipe failed\n",
+                       printk(KERN_INFO "Core dump to %s pipe failed\n",
                               cn.corename);
                        goto close_fail;
-               }
+               }
        } else {
                struct inode *inode;