Lab 5 - XINU Process Cleanup and Restart
DUE: Tuesday, November 1st by 11:59 PM
Objectives
By the end of this lab students will be able to:
- Understand the complexity of tracking and releasing resources allocated by a process
- Learn how choices for initialization and the ability to reverse allocations affect on process termination
- Extend the XINU operating system with a new system call that can be used to cleanup and restart processes
Lab Sections
1. Background
Operating systems may need to terminate and recreate processes when they apply software updates, (e.g., new device drivers and critical security updates), repair corrupted data structures, and clean up system resources, etc. Embedded systems that operate real-time mechanisms (e.g., brake control in an automobile) are required to restart processes in situations where a problem or unexpected condition threatens continuous operation. Therefore, many operating systems provide a method for a user to invoke a reboot or shutdown of the operating system (e.g. through a graphical interface, key combination, or system call).
The restart function
For this lab you will be creating a new system call for XINU restart
to force XINU to restart user processes without performing a power cycle.
The format for the restart
system call is as follows:
syscall restart(uint32 delay);
The restart
system call terminates all user processes in the system and restarts them as if they had just been created and resumed. See “System processes vs User Processes” below for a description of which processes are callified as user
processes that need to be restarted and which processes are not.
Freeing a buffer pool
One of the resources a user process can allocate is a buffer pool. Recall, that a process calls mkbufpool
to allocate a buffer pool. Among other steps that mkbufpool
performs, it calls getmem
to allocate memory for the buffer pool. Although XINU provides provides getbuf
and freebuf
that can be used to allocate and release buffers dynamically, there is no system call to free the entire buffer pool.
As part of this lab you will need to provide a new system call freebufpool
which will allow a user to free a buffer pool that has been allocated with mkbufpool
. When freebufpool
is called, any memory allocated to the pool must be returned to the free list. Similarly, any other resources that were allocated for the pool must be released.
NOTE: When the freebufpool
system call is invoked there maybe buffers still allocated within the buffer pool. If there are any buffers currently allocated from the buffer pool then freebufpool
cannot release all the memory and should return SYSERR. It is important that any buffers allocated by processes be freed as part of the process cleanup function (see below).
The format for the freebufpool
system call is as follows:
syscall freebufpool(bpid32 poolid);
Process cleanup function
As part of being restarted, a process may need to perform cleanup on allocated memory or other operating systems resources (e.g., semaphores). To allow a process to perform cleanup you will be adding a new system call regcleanup
. The new system call will be a take a single function pointer as a parameter which will be the function pointer to the cleanup function that will be registered to the current process. The cleanup function will take no arguments and have the following format:
void process_cleanup_function();
The prototype for the regcleanup
system call is as follows:
syscall regcleanup(void *);
Cleanup functions are stored on a per process basis. Each process can register a different cleanup function. Only a single cleanup function can be registered for a given process.
NOTE: When a process is created using the create
system call, it will have no cleanup function registered (you will need to modify create.c to set the cleanup function to NULL when a process is created). You will need to make sure that if there is no cleanup function registered (the process never calls regcleanup), that XINU does not attempt to call a cleanup function for the process when it ends.
NOTE: the process stack, etc. that is freed by the kill
system call should still be done by XINU in the kill
system call. The cleanup function is only used for additional cleanup by the process.
NOTE: It is possible to change the cleanup function at any time. Furthermore, calling regcleanup(NULL)
will remove any previously-registered cleanup function for the process.
Assuming the cleanup function pointer is not NULL, the cleanup function will need to be invoked when the process ends (either explicitly through a call to kill
or implicitly by returning from the process function).
Retrieving Buffer Pool Information
For a process that allocates buffers from a buffer pool, it will most likely need to free the buffers and the buffer pool when its cleanup function executes. If a buffer pool is used by only a single process then it is possible for that process to keep track of how many buffers it has retrieved (with getbuff
) and then it can ensure that all of those buffers are freed before calling freebufpool
. However, what if a process is sharing a buffer pool with another process? How can it know when all the buffers in the pool are freed so that it can successfully call freebufpool
? To allow a process to retrieve information about the buffers in a buffer pool you will need to provide system call called bufsavail
.
The prototype for the bufsavail
system call is:
int32 bufsavail(bpid32 poolid, int32* totalbufs);
The return value from bufsavail
is the total number of buffers available in the buffer pool. The poolid
input parameter is the identifier for the buffer pool to query and the totalbufs
is an output parameter that will be set to the total number of buffers contained in the buffer pool (this parameter will have the same value as numbufs
passed to mkbufpool
).
Using the bufsavail
system call will allow a process cleanup function to query the available buffers in the buffer pool. If the number available is equal to the total buffers in the pool, then the process can know that the buffer pool has no allocated buffers and can be safely deleted with freebufpool
.
2. Setup
In /homes/cs503/xinu there is a file called xinu-fall2016-lab5.tar.gz that contains a start to the code. Unpack:
tar zxvf /u/u3/cs503/xinu/xinu-fall2016-lab5.tar.gz
This will create a directory called xinu-fall2016-lab5
.
3. Programming Tasks
Along with the main code for XINU, this tarball contains the following files (additional explanation of the contents of the files is in the following sections).
system/freebufpool.c
- function declaration for thefreebufpool
function.system/regcleanup.c
- function declaration fot theregcleanup
function.system/restart.c
- function declaration for therestart
function.system/bufsavail.c
- function declaration for thebufsavail
function.include/prototypes.h
- modified prototypes.h file which includes therestart
andfreebufpool
function.
Your task is to complete these functions to perform the requirements specified in the previous section.
Contents of ''freebufpool.c''
The freebufpool.c
file contains an empty function declaration for the freebufpool
function. Your job is to fill in code to free up the resources allocated by the buffer pool with the given pool identifier.
NOTE: It cannot be assumed that all buffers within the pool have been freed with freebuf
when freebufpool
is called. If any buffers are allocated when freebufpool
is called then it should return SYSERR
.
Contents of ''regcleanup.c''
The regcleanup.c
file contains an empty function declaration for the regcleanup
function. Your job is to fill in code to register the cleanup function with the current process. HINT: consider adding an entry to the process table.
Contents of ''restart.c''
The restart.c
file contains an empty function declaration for the restart
function. Your job is to fill in code to free up the resources allocated by user processes in XINU and restart them.
NOTE: Do not forget to delay for the specified number of seconds before the restart is started. Other processes must be allowed to execute during this delay time.
Contents of ''bufsavail.c''
The bufsavail.c
file contains an empty function declaration for the bufsavail
function. Your job is to fill in code to query the buffer pool for the available and total buffers.
NOTE: Do not forget to do parameter checking. If the pool identifier is not valid bufsavail
should return SYSERR
.
System Processes vs User Processes
As part of XINU initialization one or more processes may be created to handle critical system tasks. Take a look at system/initialize.c
where the nulluser
function calls net_init
. The net_init
function is located in net/net.c
which initializes the network stack and creates two processes ipout
and netin
for processing the sending and receiving of network packets. These processes, created by the system, are critical to XINU execution and should not be restarted as part of the restart
system call. Only user processes should be restarted, however ALL user process need to be restarted.
Question: How do you determine which process are user processes when the restart
system call is invoked?
- Answer: Prior to creating and resuming the
main
process, the only processes that exist in the system are system processes. No system process will be created after themain
process is created and resumed. So, you will need to record the list of processes that currently exist prior to creating and resumingmain
in order to determine which processes to restart when therestart
system call is invoked.
NOTE: The main
process is a user process so if it is still running when the restart
system call is invoked, it will also need to be restarted.
4. Additional Requirements
- Provide a set of test cases to ensure that your code works as required. Put these test cases in
main.c
- Make sure your test cases not only test the new functionality of the new system calls, but that existing system calls still function correctly.
- Don't forget to include test cases for the extra credit (see below) if you choose to implement the extra credit requirements. No extra credit will be awarded if test cases are not included.
- The TAs will be replacing
main.c
with their own test cases after running your submitted test cases. Make sure you do not define any dependent variables inmain.c
. You are free to modify any other file(s) to implement the lab requirements.- Make sure that there are no dependent declarations in
main.c
.
- If your submitted code does not compile (either the exact submitted code or the code after the TA's replace any test case files), you will receive zero (0) points for code execution. If this happens, you will be allowed to resubmit for half credit only.
- Please run “make clean” prior to submission so that you don't submit object files
- NOTE: When you make xinu for this lab the make file will generate a binary file in the compile directory called
xinu
. This is the file you will need to download to your backend.
5. Extra Credit - Restoring the Heap and Stack on a restart
Recall that when a process allocates memory with getmem
, XINU does not keep reference counts or records of which process allocated the memory. As such, when that process is terminated, the memory allocated by the process cannot be automatically freed.
For extra credit add a feature to allow the restart
system call to restore the freelist
to its original state before user processes were started.
Question: How do you handle memory allocated on the heap by user processes? When a process ends, the memory allocated by getmem is not automatically freed?
- Answer: Prior to creating and resuming the
main
process, the memory allocated on the heap has only been allocated by system processes (which are not restarted). Furthermore, you can also assume that system processes do not allocate additional heap after they have had a chance to run. So, prior to creating and resuming themain
process, you need to record the contents (create a snapshot) of thefreelist
(referred to asmemlist
in the XINU code) so that it can be restored to that point when therestart
is invoked. In other words, as part of the process restart, after all the user processes have ended and before they are started, thefreelist
should be restored to the state at which it was in before themain
process is created and resumed.
This additional record keeping should be implemented in system/initialize.c
.
NOTE: If a process registers a process cleanup function, the cleanup function should be allowed to execute before restoring the freelist
to the state of the snapshot.
NOTE: All processes require an allocated stack in order to run. At the time the freelist
snapshot is taken (in initialize.c
) no user process will have their stacks allocated. However, when restart
restarts user process, the processes will need to have an allocated stack. Do not forget to make sure that the correct stacks for the user processes are correctly allocated and initialized as part of restart
.
Question: How are buffer pools handled as part of the freelist
restore from the snapshot?
- Answer: The intent is that process cleanup functions to take care of freeing up buffers and buffer pools. However, consider what problems can happen if a process does not clean up the allocated buffers and pools. Should the operating system call
freebufpool
or just restore thefreelist
snapshot? The choice of how to implement this is up to you. Discuss the advantages and disadvantages of your implementation in your lab analysis report.
Additional Extra Credit Study Questions:
- Does this behavior of restart have any practical use?
- Is there a better alternative behavior of restart?
- What are the advantages and disadvantages of either implementation?
- Consider how processes can communicate in Xinu: Does restarting all user processes create any timing problems that might affect inter processes communication?
Lab Submission
What to turn in
Submit using the turnin
command (see below) your complete source code (all of XINU) including the any files you added to complete the lab. In the system
directory include a PDF file called lab5_analysis.pdf
with a report discussing:
- The details behind your implementation (including a discussion of the extra credit if attempted). As part of this discussion write answers to the following questions:
- What specific problems can occur if user processes are repeatedly killed and restarted?
- Suppose a set of user processes is killed in random order. Show how the system can be left in a state where some processes never die?
NOTE: Make sure you put your name on your report, that the file is named exactly as specified, and the file located in the directory specified.
How to submit
To turn in your lab use the following command
turnin -c cs503 -p lab5 xinu-fall2016-lab5
assuming xinu-fall2016-lab5
is the name of the directory containing your code.
If you wish to, you can verify your submission by typing the following command:
turnin -v -c cs503 -p lab5
Do not forget the -v above, as otherwise your earlier submission will be erased (it is overwritten by a blank submission).
Note that resubmitting overwrites any earlier submission and erases any record of the date/time of any such earlier submission.
We will check that the submission time stamp is before the due date; Any submission past the due date will be deducted the appropriate number of grace days. If submission is beyond your remaining number of grace days, your work will not be accepted.