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_infoandtask_structstructure 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_SUPERPRIVindicates if the task used super-user is cleared.PF_FORKNOEXECindicates a process has not yet calledexec()is set
- This updates the flags in the new
- Call
alloc_pid()- This assigns an available
PIDto 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())