CS计算机代考程序代写 file system Yousef Suleiman

Yousef Suleiman

OS @ run
(kernel mode) Hardware

Program
(user mode)

Within the user program:

close(fd)
A system call is made with a bad fd

Within usys.S:
#define SYSCALL(name) \

.globl name; \
name: \

movl $SYS_ ## name, %eax; \
int $T_SYSCALL; \
ret


SYSCALL(close)
The macro definition causes name to be
populated with close so a global close is
defined which gets called by the user process.
This causes close to move the SYS_close
number (which is defined by a macro in
syscall.h) into the %eax register. Then a
call to an interrupt using int with
T_SYSCALL (which is 64) is made.

Within vectors.S:
.globl vector64
vector64:

pushl $0
pushl $64
jmp alltraps

At global vector64, the instructions are to
push 0 and the trap number 64 (to kernel
stack), move to kernel mode, and jump to
alltraps.

Within trapasm.S:
.globl alltraps
alltraps:

# Build trap frame.

# Set up data segments.

# Call trap(tf), where

tf=%esp
The trap frame is built, the data segments
are set up, and trap() is called with
%esp holding 64.

Within trap.c:
void trap(struct
trapframe *tf)
{

if(tf->trapno ==
T_SYSCALL){


myproc()->tf = tf;
syscall();

The trap handler enters the if
statement for system calls and
syscall() gets executed.

Within syscall.c:
static int

Yousef Suleiman

(*syscalls[])(void) = {

[SYS_close] sys_close,
};
void
syscall(void)
{

int num;
struct proc *curproc =

myproc();

num =
curproc->tf->eax;

if(num > 0 && num < NELEM(syscalls) && syscalls[num]) { curproc->tf->eax =
syscalls[num]();

}
The eax reg value (which holds
the system call number for
sys_close) is used to call
sys_close() through the
array syscalls[num]() and
puts the result value into eax
register

Within sysfile.c:
int sys_close(void)
{

int fd;
struct file *f;
if(argfd(0, &fd, &f) < 0) return -1; ... fileclose(f); Finally, sys_close() gets called which then calls argfd() to interpret the nth argument as a file descriptor. Within file.c: void fileclose(struct file *f) { struct file ff; acquire(&ftable.lock); if(f->ref < 1) panic("fileclose"); The file table is locked and the if statement is entered checking if there are any references to that file. Because it is faulty there are none and it enters panic(). Within console.c: void panic(char *s) { ... cprintf(s); cprintf("\n"); Feedback is displayed to the user. Yousef Suleiman How to use countTraps(): The system call countTraps(int c) (where int c represents a system call number) takes in one parameter which is a system call number. To use countTraps(), simply include the user.h header file. This version of xv6 has a total of 22 system calls. If the user process calls countTraps() with a system call number between 1 and 22, it will return the number of times that specified system call has been made within that specific user process. If the user process calls countTraps with 0 as the parameter, countTraps will return the total number of system calls made by that user process. It will also print out the number of traps the entire system has made up until that point (which includes the total system calls made, hardware interrupts, and software interrupts). If an invalid parameter is passed or no system calls have been made, -1 is returned. To make it easier for the user, they can include the syscall.h header file within their program. The syscall.h header file contains textual substitutions (macros) that define each system call with its call number. For example, if the user wished to obtain the count of fork() system calls made by that process, they can call countTraps(SYS_fork). Design of countTraps(): The design of the system call countTraps() is made possible by keeping track of the number of each individual system call type made by a given user process through an array contained in the metadata of each process. It is also implemented by keeping track of the total number of traps (which includes system calls, hardware interrupts, and software interrupts) of the entire system. Given a system call number (or its position in the system call vector), countTraps() gets the current user process’s metadata (proc struct) by calling myproc(), accesses the array int[] sys_arr (which contains all the counts of each system call type), and indexes the array to access the entry relative to that system call number. If the given system call number is 0, countTraps() returns the total system calls of the user process and prints the trap counts of the entire system. The reason 0 was chosen for this specific return is because the system call numbers begin at 1. The total count of hardware and software interrupts per process (not across the system) is not kept track of. The reason for this design choice is that most hardware and software interrupts do not make it possible to access that specific process’s metadata through calling myproc() mainly because these interrupts result in the process actually being killed. This version of xv6 also does not support any keyboard interrupts that could temporarily suspend a process. Yousef Suleiman How countTraps() was implemented: To implement the system call countTraps(int c) additions had to made to the following source code files: ● proc.h - An int[] sys_arr array and int sysc declaration were added to struct proc to keep track of the count of each process’s total system calls as well as the count of each individual system call type for each process. ● proc.c - Code was added to zero out the int[] sys_arr array and set int sysc to 0 within both userinit() (where the first process is made) and the child process in fork(). The reason I chose to reset the counts of the child process once forked is because I figured that even though the child process inherits most of the parent’s attributes, it does not exist before it is forked and therefore its counts should start at 0. ● syscall.h - A line of code has to be added to define a macro for the system call number or its position in the system call vector ● defs.h - A line of code had to be added for a forward declaration of the int countTraps(int) system call. ● user.h - A line of code had to be added to define the countTraps(int) system call that can be called through the shell. ● sysproc.c - The actual body of the countTraps(int) system call was added here. It also contains three int variables (total_sysc, total_swic, and total_hwic) that hold the total system call, total hardware interrupt, and total software interrupt counts that occurred over the entire system. A line of code was also added to each system call to increment the correct entry of array int[] sys_arr (which is located inside the struct proc of proc.h). ● syscall.c - Code was added to externally define the function that connects the shell and kernel. The macro defined in syscall.h was used here to add it to the system call vector. ● usys.S - A line of code was added to define a macro to connect the user call to the actual system call sys_countTrap(). ● syscfile.c - A line of code was added to each file system call to increment the correct entry of array int[] sys_arr (which is located inside the struct proc of proc.h). ● trap.c - Code was added to the trap() function that increments the total system call, total hardware interrupt, and total software interrupt counts of the system. The trapframe maps number 0 to 31 as software interrupts/exceptions, 32 to 63 as hardware interrupts, and 64 as system call traps. The trap() function begins by checking if the trap number maps to system calls, then checks if it maps to numerous hardware interrupts, and finally (if all else is false), it assumes that it must have been a software interrupt such as a fault in user space like dividing by 0 or an issue in kernel space. Thus, the trap counts (total_sysc, total_swic, and total_hwic) just have to be incremented based on which trap had occurred. Yousef Suleiman Test Cases: Equivalence Partitioning int c == 0 The given parameter is 0 so the total traps of the system should be printed and the total system calls of the calling process is returned int c >= 1 && int
c <= 22 The given system call number falls into bounds for a specified system call. int c < 1 || int c >
22
and int c != 0
The given system call number
is out of bounds.

Majority of the
hardware
interrupts are timer
interrupts

callCountTraps
//wait 1 second
callCountTraps

Verses

callCountTraps
//wait 10 seconds
callCountTraps

Divide by zero
causing software
interrupt

divideByZero
callCountTraps
divideByZero;
callCountTraps

Parents and child
processes make
numerous different
system calls:

In parentAndChild.c:
Parent process makes 3
bogus close() calls then
forks

Child makes 1 bogus
close() call then exits

Parent waits for process

The exception occurring in
badCallCountTraps.c
should result in
countTraps() returning
-1.

Test 1 Test 2 Test 3 Test 4

To test countTraps(), three possible groupings of parameters are partitioned. The first being
that 0 was passed, the second being that a specification for a particular system call was passed,
and the last being that the parameter is out of bounds. To demonstrate these partitionings, four
different user programs were made:

● divideByZero.c: Simply performs an erroneous divide by zero that will fault.
● callCountTraps.c: A single call is made to countTraps(0) so the system’s entire

trap counts are printed.
● parentAndChild.c: A parent process makes 3 bogus calls to close(), 1 fork()

call, and 1 wait() call and the child process makes only 1 bogus call to close().
countTraps() is called after every system call to show the system call counts of the
parent and child processes.

● badCallCountTraps.c: A single call is made to countTraps(30) with 30 being
out of bounds.

Yousef Suleiman

In test 1, we run callCountTraps twice, which displays the total traps that occurred between two different moments. In test 1A,
we wait about a second before running callCountTraps a second time. The difference in hardware interrupts is 752 – 457 = 295.
In test 1B we wait about 10 seconds before running callCountTraps a second time. The difference in hardware interrupts is now
2436 – 358 = 2078. Test 1B has about twice the difference than test 1A which makes sense as the majority of the hardware
interrupts are timer interrupts which should be produced by the clock chip at a pretty constant rate. Because we waited about 10
times longer in test 1B, the difference was about 10 times greater. Thus callCountTraps should be counting all or at least the
majority of the hardware interrupts.

In test 2, we run divideByZero then callCountTraps to show that countTraps() is displaying the correct software
interrupt counts. The software interrupts go from 1 to 2 as divideByZero was run twice.

In test 3, we run parentAndChild to show that countTraps() returns the correct counts.

In test 4, we run badCallCountTraps to show that countTraps() returns -1 when faulty parameters are given.