Overview
- minix fork and exit
- minix exec
- modules
- Unix/Posix signals
- Minix signals
Minix fork
- fork can fail if:
- there is no process table entry (last few table entries reserved
for root), or
- the required memory cannot be allocated
if either condition holds, fork fails before allocating
any resources (similar to, but not the same as, two-phase commit
-- check first, then allocate)
- copy the data and stack segments (if the text is not shared, it
is included in the data segment) to the newly allocated memory
- copy the parent's process table entry to the child's
- modify the child's parent, traced flags, exit and signal status,
and PID (next free ID < 30,000: get_free_pid(), from
servers/pm/utility.c, not in book)
- ask the kernel to fork the process
- ask the FS to duplicate the file descriptors
- ask the kernel to map the process
- send a message to the child with return value 0 (p. 882, line 18501 --
setreply is on p. 877)
- return to the parent with the child's PID
Minix exit
- a process terminates when it is killed (depending on the signal
and the signal handler) or when it calls exit
- no error checking on exit -- exit always succeeds
- cancel alarms and signals
- tell FS to close all the open files and free process slot
- tell kernel to free process slot and take care of canceling message
sends
- free the memory of the process
- if the parent is waiting, wake up the parent and free the process slot
- if no parent is waiting, leave the process in a zombie state,
with only a process table slot still allocated, and signal the parent
- either way, reparent any of this process's children to init
- in-class discussion: is it more important for exit to be fast, or
for fork to be fast, or are they equally important?
Minix wait
- wait can specify one of three possible arguments to wait for:
- for a specific process (PID)
- for any child
- for any child within a given process group
- a wait will complete if (one of) the given process has terminated,
or is being traced and has stopped
- first loop through the process table to find a child that matches
the arguments and is a zombie -- if found, clean up this process and
send a message back to the caller and return
- if found a child that matches and is stopped, send a message
back to the caller and return
- if no child is ready to report, but one or more matching processes
are running, leave the caller waiting (on receive in the system
call), mark the caller as waiting, and return, unless WNOHANG
was specified
Minix exec
- part of exec is implemented in the exec library call,
/usr/src/lib/posix/_execve.c -- this builds the initial
stack in a buffer
- it might be dangerous to trust a user library to build the stack
right, but the stack is (over)writable by the user code anyway, so there
is no loss of security
Minix exec implementation
- check to see that the stack size is reasonable
- copy the stack into an internal buffer (before freeing the memory)
- check to see that the file is accessible, by asking the file system,
including using system calls -- the file system server has some special
code to make file system calls from the PM look like they are from the
process itself
- read the executable file header (see p. 889), which also checks
to see whether this is a script (line 18938)
- scripts require executing a different file, with this one as an
argument (line 18801)
- look to see if the text can be shared (find_share, p 895)
- allocate the new memory (19019 on p. 891, called from 18812
on p. 887) -- this is the commit point,
if this succeeds, we can never return, because there is no longer an old
process image to return to
- relocate the stack (see below -- patch_ptr, not
patch_stack) and copy it to the newly allocated
stack segment
- read in the text (unless shared) and the initialized data data
- change the effective user/group ID if executing a setuid/setgid file
- set default signal handlers
- ask FS to close "close-on-exec" files
- ask the system to initialize the new stack pointer, with the
initial valid return address and to make the process ready to execute
(sys_exec, line 18878, and kernel/system/do_exec.c, p. 764)
- return, no need to send any messages
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 2.5 License.