linux-2.6.33/do_fork()
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
*参照元 [#k97cd3fc]
#backlinks
*説明 [#l787cb05]
-パス: [[linux-2.6.33/kernel/fork.c]]
-FIXME: これは何?
--説明
**引数 [#uac72978]
-unsigned long clone_flags
--
-unsigned long stack_start
--
-struct pt_regs *regs
--
--[[linux-2.6.33/pt_regs]]
-unsigned long stack_size
--
-int __user *parent_tidptr
--
--[[linux-2.6.33/__user]]
-int __user *child_tidptr
--
**返り値 [#d24c5956]
-long
--
**参考 [#ldede19d]
*実装 [#d2c59d36]
/*
* Ok, this is the main fork-routine.
*
* It copies the process, and if successful kick-starts
* it and waits for it to finish using the VM if required.
*/
long do_fork(unsigned long clone_flags,
unsigned long stack_start,
struct pt_regs *regs,
unsigned long stack_size,
int __user *parent_tidptr,
int __user *child_tidptr)
{
struct task_struct *p;
int trace = 0;
long nr;
-
--[[linux-2.6.33/task_struct]]
/*
* Do some preliminary argument and permissions checkin...
* actually start allocating stuff
*/
if (clone_flags & CLONE_NEWUSER) {
if (clone_flags & CLONE_THREAD)
return -EINVAL;
-
--[[linux-2.6.33/CLONE_NEWUSER]]
-
--[[linux-2.6.33/CLONE_THREAD]]
/* hopefully this check will go away when userns suppo...
* complete
*/
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SETUID) ||
!capable(CAP_SETGID))
return -EPERM;
-
--[[linux-2.6.33/capable()]]
-
--[[linux-2.6.33/CAP_SYS_ADMIN]]
-
--[[linux-2.6.33/CAP_SETUID]]
-
--[[linux-2.6.33/CAP_SETGID]]
}
/*
* We hope to recycle these flags after 2.6.26
*/
if (unlikely(clone_flags & CLONE_STOPPED)) {
static int __read_mostly count = 100;
-
--[[linux-2.6.33/unlikely()]]
-
--[[linux-2.6.33/CLONE_STOPPED]]
-
--[[linux-2.6.33/__read_mostly]]
if (count > 0 && printk_ratelimit()) {
char comm[TASK_COMM_LEN];
-
--[[linux-2.6.33/printk_ratelimit()]]
-
--[[linux-2.6.33/TASK_COMM_LEN]]
count--;
printk(KERN_INFO "fork(): process `%s' used deprecate...
"clone flags 0x%lx\n",
get_task_comm(comm, current),
clone_flags & CLONE_STOPPED);
-
--[[linux-2.6.33/printk()]]
-
--[[linux-2.6.33/get_task_comm()]]
-
--[[linux-2.6.33/current(global)]]
}
}
/*
* When called from kernel_thread, don't do user tracin...
*/
if (likely(user_mode(regs)))
trace = tracehook_prepare_clone(clone_flags);
-
--[[linux-2.6.33/likely()]]
-
--[[linux-2.6.33/user_mode()]]
-
--[[linux-2.6.33/tracehook_prepare_clone()]]
p = copy_process(clone_flags, stack_start, regs, stack_...
child_tidptr, NULL, trace);
-
--[[linux-2.6.33/copy_process()]]
/*
* Do this prior waking up the new thread - the thread ...
* might get invalid after that point, if the thread ex...
*/
if (!IS_ERR(p)) {
struct completion vfork;
-
--[[linux-2.6.33/IS_ERR()]]
-
--[[linux-2.6.33/completion]]
trace_sched_process_fork(current, p);
-
--[[linux-2.6.33/trace_sched_process_fork()]]
nr = task_pid_vnr(p);
-
--[[linux-2.6.33/task_pid_vnr()]]
if (clone_flags & CLONE_PARENT_SETTID)
put_user(nr, parent_tidptr);
-
--[[linux-2.6.33/CLONE_PARENT_SETTID]]
-
--[[linux-2.6.33/put_user()]]
if (clone_flags & CLONE_VFORK) {
p->vfork_done = &vfork;
init_completion(&vfork);
}
-
--[[linux-2.6.33/CLONE_VFORK]]
-
--[[linux-2.6.33/init_completion()]]
audit_finish_fork(p);
tracehook_report_clone(regs, clone_flags, nr, p);
-
--[[linux-2.6.33/audit_finish_fork()]]
-
--[[linux-2.6.33/tracehook_report_clone()]]
/*
* We set PF_STARTING at creation in case tracing want...
* use this to distinguish a fully live task from one ...
* hasn't gotten to tracehook_report_clone() yet. Now...
* clear it and set the child going.
*/
p->flags &= ~PF_STARTING;
-
--[[linux-2.6.33/PF_STARTING]]
if (unlikely(clone_flags & CLONE_STOPPED)) {
/*
* We'll start up with an immediate SIGSTOP.
*/
sigaddset(&p->pending.signal, SIGSTOP);
set_tsk_thread_flag(p, TIF_SIGPENDING);
__set_task_state(p, TASK_STOPPED);
-
--[[linux-2.6.33/sigaddset()]]
-
--[[linux-2.6.33/SIGSTOP]]
-
--[[linux-2.6.33/set_tsk_thread_flag()]]
-
--[[linux-2.6.33/TIF_SIGPENDING]]
-
--[[linux-2.6.33/__set_task_state()]]
-
--[[linux-2.6.33/TASK_STOPPED]]
} else {
wake_up_new_task(p, clone_flags);
-
--[[linux-2.6.33/wake_up_new_task()]]
}
tracehook_report_clone_complete(trace, regs,
clone_flags, nr, p);
-
--[[linux-2.6.33/tracehook_report_clone_complete()]]
if (clone_flags & CLONE_VFORK) {
freezer_do_not_count();
wait_for_completion(&vfork);
freezer_count();
tracehook_report_vfork_done(p, nr);
-
--[[linux-2.6.33/freezer_do_not_count()]]
-
--[[linux-2.6.33/wait_for_completion()]]
-
--[[linux-2.6.33/freezer_count()]]
-
--[[linux-2.6.33/tracehook_report_vfork_done()]]
}
} else {
nr = PTR_ERR(p);
-
--[[linux-2.6.33/PTR_ERR()]]
}
return nr;
}
*コメント [#lf1b4559]
終了行:
*参照元 [#k97cd3fc]
#backlinks
*説明 [#l787cb05]
-パス: [[linux-2.6.33/kernel/fork.c]]
-FIXME: これは何?
--説明
**引数 [#uac72978]
-unsigned long clone_flags
--
-unsigned long stack_start
--
-struct pt_regs *regs
--
--[[linux-2.6.33/pt_regs]]
-unsigned long stack_size
--
-int __user *parent_tidptr
--
--[[linux-2.6.33/__user]]
-int __user *child_tidptr
--
**返り値 [#d24c5956]
-long
--
**参考 [#ldede19d]
*実装 [#d2c59d36]
/*
* Ok, this is the main fork-routine.
*
* It copies the process, and if successful kick-starts
* it and waits for it to finish using the VM if required.
*/
long do_fork(unsigned long clone_flags,
unsigned long stack_start,
struct pt_regs *regs,
unsigned long stack_size,
int __user *parent_tidptr,
int __user *child_tidptr)
{
struct task_struct *p;
int trace = 0;
long nr;
-
--[[linux-2.6.33/task_struct]]
/*
* Do some preliminary argument and permissions checkin...
* actually start allocating stuff
*/
if (clone_flags & CLONE_NEWUSER) {
if (clone_flags & CLONE_THREAD)
return -EINVAL;
-
--[[linux-2.6.33/CLONE_NEWUSER]]
-
--[[linux-2.6.33/CLONE_THREAD]]
/* hopefully this check will go away when userns suppo...
* complete
*/
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SETUID) ||
!capable(CAP_SETGID))
return -EPERM;
-
--[[linux-2.6.33/capable()]]
-
--[[linux-2.6.33/CAP_SYS_ADMIN]]
-
--[[linux-2.6.33/CAP_SETUID]]
-
--[[linux-2.6.33/CAP_SETGID]]
}
/*
* We hope to recycle these flags after 2.6.26
*/
if (unlikely(clone_flags & CLONE_STOPPED)) {
static int __read_mostly count = 100;
-
--[[linux-2.6.33/unlikely()]]
-
--[[linux-2.6.33/CLONE_STOPPED]]
-
--[[linux-2.6.33/__read_mostly]]
if (count > 0 && printk_ratelimit()) {
char comm[TASK_COMM_LEN];
-
--[[linux-2.6.33/printk_ratelimit()]]
-
--[[linux-2.6.33/TASK_COMM_LEN]]
count--;
printk(KERN_INFO "fork(): process `%s' used deprecate...
"clone flags 0x%lx\n",
get_task_comm(comm, current),
clone_flags & CLONE_STOPPED);
-
--[[linux-2.6.33/printk()]]
-
--[[linux-2.6.33/get_task_comm()]]
-
--[[linux-2.6.33/current(global)]]
}
}
/*
* When called from kernel_thread, don't do user tracin...
*/
if (likely(user_mode(regs)))
trace = tracehook_prepare_clone(clone_flags);
-
--[[linux-2.6.33/likely()]]
-
--[[linux-2.6.33/user_mode()]]
-
--[[linux-2.6.33/tracehook_prepare_clone()]]
p = copy_process(clone_flags, stack_start, regs, stack_...
child_tidptr, NULL, trace);
-
--[[linux-2.6.33/copy_process()]]
/*
* Do this prior waking up the new thread - the thread ...
* might get invalid after that point, if the thread ex...
*/
if (!IS_ERR(p)) {
struct completion vfork;
-
--[[linux-2.6.33/IS_ERR()]]
-
--[[linux-2.6.33/completion]]
trace_sched_process_fork(current, p);
-
--[[linux-2.6.33/trace_sched_process_fork()]]
nr = task_pid_vnr(p);
-
--[[linux-2.6.33/task_pid_vnr()]]
if (clone_flags & CLONE_PARENT_SETTID)
put_user(nr, parent_tidptr);
-
--[[linux-2.6.33/CLONE_PARENT_SETTID]]
-
--[[linux-2.6.33/put_user()]]
if (clone_flags & CLONE_VFORK) {
p->vfork_done = &vfork;
init_completion(&vfork);
}
-
--[[linux-2.6.33/CLONE_VFORK]]
-
--[[linux-2.6.33/init_completion()]]
audit_finish_fork(p);
tracehook_report_clone(regs, clone_flags, nr, p);
-
--[[linux-2.6.33/audit_finish_fork()]]
-
--[[linux-2.6.33/tracehook_report_clone()]]
/*
* We set PF_STARTING at creation in case tracing want...
* use this to distinguish a fully live task from one ...
* hasn't gotten to tracehook_report_clone() yet. Now...
* clear it and set the child going.
*/
p->flags &= ~PF_STARTING;
-
--[[linux-2.6.33/PF_STARTING]]
if (unlikely(clone_flags & CLONE_STOPPED)) {
/*
* We'll start up with an immediate SIGSTOP.
*/
sigaddset(&p->pending.signal, SIGSTOP);
set_tsk_thread_flag(p, TIF_SIGPENDING);
__set_task_state(p, TASK_STOPPED);
-
--[[linux-2.6.33/sigaddset()]]
-
--[[linux-2.6.33/SIGSTOP]]
-
--[[linux-2.6.33/set_tsk_thread_flag()]]
-
--[[linux-2.6.33/TIF_SIGPENDING]]
-
--[[linux-2.6.33/__set_task_state()]]
-
--[[linux-2.6.33/TASK_STOPPED]]
} else {
wake_up_new_task(p, clone_flags);
-
--[[linux-2.6.33/wake_up_new_task()]]
}
tracehook_report_clone_complete(trace, regs,
clone_flags, nr, p);
-
--[[linux-2.6.33/tracehook_report_clone_complete()]]
if (clone_flags & CLONE_VFORK) {
freezer_do_not_count();
wait_for_completion(&vfork);
freezer_count();
tracehook_report_vfork_done(p, nr);
-
--[[linux-2.6.33/freezer_do_not_count()]]
-
--[[linux-2.6.33/wait_for_completion()]]
-
--[[linux-2.6.33/freezer_count()]]
-
--[[linux-2.6.33/tracehook_report_vfork_done()]]
}
} else {
nr = PTR_ERR(p);
-
--[[linux-2.6.33/PTR_ERR()]]
}
return nr;
}
*コメント [#lf1b4559]
ページ名: