From: Stas Sergeev <stsp@aknet.ru>
To: Linux kernel <linux-kernel@vger.kernel.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Subject: [path][rfc] add PR_DETACH prctl command
Date: Wed, 23 Feb 2011 16:50:27 +0300 [thread overview]
Message-ID: <4D6510A3.90905@aknet.ru> (raw)
[-- Attachment #1: Type: text/plain, Size: 451 bytes --]
Hi.
The attched patch adds the PR_DETACH prctl command.
It is needed for those rare but unfortunate cases, where
you can't daemonize your process before creating a thread.
The effect of this command is similar to the fork() and then
exit() on parent, except that:
1. PID does not change
2. Threads are not destroyed
It would be nice to know what people think about such an
approach.
Signed-off-by: stsp@aknet.ru
CC: Oleg Nesterov <oleg@redhat.com>
[-- Attachment #2: pr_detach.diff --]
[-- Type: text/plain, Size: 5514 bytes --]
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 7c99c1c..ccccfa8 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -462,7 +462,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
/* convert nsec -> ticks */
start_time = nsec_to_clock_t(start_time);
- seq_printf(m, "%d (%s) %c %d %d %d %d %d %u %lu \
+ seq_printf(m, "%d (%s) %c %d %d %d %d %d %llu %lu \
%lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
%lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld\n",
pid_nr_ns(pid, ns),
diff --git a/include/asm-generic/siginfo.h b/include/asm-generic/siginfo.h
index 942d30b..1da9c20 100644
--- a/include/asm-generic/siginfo.h
+++ b/include/asm-generic/siginfo.h
@@ -218,7 +218,8 @@ typedef struct siginfo {
#define CLD_TRAPPED (__SI_CHLD|4) /* traced child has trapped */
#define CLD_STOPPED (__SI_CHLD|5) /* child has stopped */
#define CLD_CONTINUED (__SI_CHLD|6) /* stopped child has continued */
-#define NSIGCHLD 6
+#define CLD_DETACHED (__SI_CHLD|7) /* child has detached */
+#define NSIGCHLD 7
/*
* SIGPOLL si_codes
diff --git a/include/linux/prctl.h b/include/linux/prctl.h
index a3baeb2..fbd2451 100644
--- a/include/linux/prctl.h
+++ b/include/linux/prctl.h
@@ -102,4 +102,6 @@
#define PR_MCE_KILL_GET 34
+#define PR_DETACH 35
+
#endif /* _LINUX_PRCTL_H */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 777d8a5..75c977e 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1194,7 +1194,7 @@ struct task_struct {
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
void *stack;
atomic_t usage;
- unsigned int flags; /* per process flags, defined below */
+ u64 flags; /* per process flags, defined below */
unsigned int ptrace;
int lock_depth; /* BKL lock depth */
@@ -1746,6 +1746,7 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *
#define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */
#define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezable */
#define PF_FREEZER_NOSIG 0x80000000 /* Freezer won't send signals to it */
+#define PF_DETACH 0x100000000ULL /* Detach from parent */
/*
* Only the _current_ task can read/write to tsk->flags, but other
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 156cc55..f11c1ca 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -181,7 +181,7 @@ static inline void check_for_tasks(int cpu)
(!cputime_eq(p->utime, cputime_zero) ||
!cputime_eq(p->stime, cputime_zero)))
printk(KERN_WARNING "Task %s (pid = %d) is on cpu %d "
- "(state = %ld, flags = %x)\n",
+ "(state = %ld, flags = %llx)\n",
p->comm, task_pid_nr(p), cpu,
p->state, p->flags);
}
diff --git a/kernel/exit.c b/kernel/exit.c
index f9a45eb..2c8f050 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -1507,6 +1507,38 @@ static int wait_task_continued(struct wait_opts *wo, struct task_struct *p)
return retval;
}
+static int wait_task_detached(struct wait_opts *wo, struct task_struct *p)
+{
+ int retval = 0;
+ pid_t pid = task_pid_vnr(p);
+ uid_t uid = __task_cred(p)->uid;
+
+ get_task_struct(p);
+ if (unlikely(wo->wo_flags & WNOWAIT)) {
+ read_unlock(&tasklist_lock);
+ return wait_noreap_copyout(wo, p, pid, uid, CLD_DETACHED,
+ p->exit_code >> 8);
+ }
+
+ p->flags &= ~PF_DETACH;
+ if (!ptrace_reparented(p))
+ p->parent = init_pid_ns.child_reaper;
+ p->real_parent = init_pid_ns.child_reaper;
+ p->exit_signal = SIGCHLD;
+ list_move_tail(&p->sibling, &p->real_parent->children);
+
+ read_unlock(&tasklist_lock);
+ if (wo->wo_stat)
+ retval = put_user(p->exit_code, wo->wo_stat);
+
+ if (!retval)
+ retval = wait_noreap_copyout(wo, p, pid, uid, CLD_DETACHED,
+ p->exit_code >> 8);
+ else
+ put_task_struct(p);
+ return retval;
+}
+
/*
* Consider @p for a wait by @parent.
*
@@ -1549,6 +1581,9 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace,
if (p->exit_state == EXIT_DEAD)
return 0;
+ if (p->flags & PF_DETACH)
+ return wait_task_detached(wo, p);
+
/*
* We don't reap group leaders with subthreads.
*/
diff --git a/kernel/signal.c b/kernel/signal.c
index 4e3cff1..2cd495a 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1450,10 +1450,10 @@ int do_notify_parent(struct task_struct *tsk, int sig)
BUG_ON(sig == -1);
- /* do_notify_parent_cldstop should have been called instead. */
- BUG_ON(task_is_stopped_or_traced(tsk));
+ /* do_notify_parent_cldstop should have been called instead. */
+ BUG_ON(task_is_stopped_or_traced(tsk));
- BUG_ON(!task_ptrace(tsk) &&
+ BUG_ON(!task_ptrace(tsk) && (tsk->flags & PF_EXITING) &&
(tsk->group_leader != tsk || !thread_group_empty(tsk)));
info.si_signo = sig;
diff --git a/kernel/sys.c b/kernel/sys.c
index 18da702..c09205f 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1736,6 +1736,22 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
else
error = PR_MCE_KILL_DEFAULT;
break;
+ case PR_DETACH:
+ error = -EPERM;
+ /* if parent is init, or not a group leader - bail */
+ if (me->real_parent == init_pid_ns.child_reaper)
+ break;
+ if (me->group_leader != me)
+ break;
+ if (arg2 & ~0xff)
+ break;
+ write_lock_irq(&tasklist_lock);
+ me->exit_code = arg2 << 8;
+ me->flags |= PF_DETACH;
+ do_notify_parent(me, me->exit_signal);
+ write_unlock_irq(&tasklist_lock);
+ error = 0;
+ break;
default:
error = -EINVAL;
break;
next reply other threads:[~2011-02-23 13:55 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-02-23 13:50 Stas Sergeev [this message]
2011-02-23 19:14 ` [path][rfc] add PR_DETACH prctl command Oleg Nesterov
2011-02-23 20:35 ` Stas Sergeev
2011-02-24 13:29 ` Oleg Nesterov
2011-02-24 15:13 ` Stas Sergeev
2011-02-24 15:32 ` Oleg Nesterov
2011-03-31 16:10 ` Stas Sergeev
2011-03-31 17:02 ` Oleg Nesterov
2011-03-31 17:47 ` Stas Sergeev
2011-03-31 18:18 ` Oleg Nesterov
2011-03-31 20:58 ` Stas Sergeev
2011-04-02 13:55 ` Oleg Nesterov
2011-04-02 18:20 ` Stas Sergeev
2011-04-02 22:00 ` Stas Sergeev
2011-04-01 17:02 ` Stas Sergeev
2011-04-02 14:06 ` Oleg Nesterov
2011-04-04 14:34 ` Stas Sergeev
2011-04-04 16:03 ` Oleg Nesterov
2011-04-04 20:05 ` Stas Sergeev
2011-04-05 15:15 ` Oleg Nesterov
2011-04-05 16:25 ` Stas Sergeev
2011-04-05 16:45 ` Oleg Nesterov
2011-04-05 17:51 ` Stas Sergeev
2011-04-08 10:51 ` Stas Sergeev
2011-04-08 18:55 ` Oleg Nesterov
2011-04-08 20:16 ` Stas Sergeev
2011-04-11 11:15 ` Stas Sergeev
2011-04-19 14:44 ` [path][rfc] add PR_DETACH prctl command [1/3] Stas Sergeev
2011-04-19 14:50 ` [path][rfc] add PR_DETACH prctl command [2/3] Stas Sergeev
2011-04-19 14:54 ` [path][rfc] add PR_DETACH prctl command [3/3] Stas Sergeev
2011-04-19 14:58 ` Alan Cox
2011-04-19 15:08 ` Stas Sergeev
2011-04-19 15:54 ` Alan Cox
2011-04-19 16:13 ` Oleg Nesterov
2011-04-19 16:29 ` Oleg Nesterov
2011-04-19 16:54 ` Stas Sergeev
2011-04-19 17:20 ` Oleg Nesterov
2011-04-19 17:41 ` Stas Sergeev
2011-04-19 18:17 ` Oleg Nesterov
2011-04-19 16:19 ` Stas Sergeev
2011-04-20 13:12 ` [path][rfc] add PR_DETACH prctl command [1/2] Stas Sergeev
2011-04-20 13:14 ` [path][rfc] add PR_DETACH prctl command [2/2] Stas Sergeev
2011-04-20 16:50 ` Oleg Nesterov
2011-04-20 18:45 ` Stas Sergeev
2011-04-20 19:33 ` Oleg Nesterov
2011-04-20 20:35 ` Stas Sergeev
2011-04-21 20:00 ` Oleg Nesterov
2011-04-21 20:11 ` Stas Sergeev
2011-04-21 10:02 ` Stas Sergeev
2011-04-21 20:15 ` Oleg Nesterov
2011-04-21 20:32 ` Stas Sergeev
2011-04-08 18:13 ` [path][rfc] add PR_DETACH prctl command Bryan Donlan
2011-04-08 20:26 ` Stas Sergeev
2011-04-08 20:52 ` Bryan Donlan
2011-04-08 21:14 ` Stas Sergeev
2011-04-08 21:25 ` Bryan Donlan
2011-04-08 21:38 ` Stas Sergeev
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4D6510A3.90905@aknet.ru \
--to=stsp@aknet.ru \
--cc=linux-kernel@vger.kernel.org \
--cc=oleg@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.