Forking
fork()
is implemented via clone()
, which in turn called do_fork()
that does the bulk of the work
do_fork()
then calls copy_process()
, which does the following
- Call
dup_task_struct()
- This creates a new kernel stack,
thread_info
andtask_struct
structure for the duplicated process. The child and parent still have identicalPID
- This creates a new kernel stack,
- Check if the new child does not exceed number of allowed processes
- Various values of the process descriptor are cleared or set to initial values
- Child is set to
TASK_UNINTERRUPTIBLE
, meaning it cannot run yet - Call
copy_flags()
- This updates the flags in the new
task_struct
.PF_SUPERPRIV
indicates if the task used super-user is cleared.PF_FORKNOEXEC
indicates a process has not yet calledexec()
is set
- This updates the flags in the new
- Call
alloc_pid()
- This assigns an available
PID
to the new process
- This assigns an available
- Depending on the flags passed to
clone()
, either duplicate or shares open files, filesystem information, signal handlers, process address space and name space - Clean up and return pointer of the new process to caller
do_fork()
If copy_process()
returns successfully, the child is woken up and run.
The kernel runs the newly created child first. This is so copy-on-write can happen (If the parent ran first and wrote to the data, all the data will be copied to the child, inducing overhead if the child calls exec()
)