Operating systems form the backbone of modern computing systems, enabling seamless interaction between hardware and software. This project explores two key aspects of operating systems: customizing the lightweight educational operating system xv6 by implementing system calls, and building a robust multi-threaded web server capable of handling multiple clients concurrently.
- Extend xv6 functionality : By implementing and demonstrating custom system calls, we deepen our understanding of kernel development and inter-process communication.
- Develop a feature-rich web server : The web server showcases practical knowledge of multi-threading, synchornisation, HTTP protocol handling, and server management.
Prerequisites
- Unix-based operating system (for running xv6 and the server)
gcc
,make
andqemu
(for compilation)git
(to clone the repository)
Clone the the repository
$ git clone https://github.com/jyolx/OS_Project
We enhanced the xv6-riscv operating system by adding new system calls, each tailored to address specific use cases. Our modifications involved editing both kernel and user-space code.
To implement our system calls, we wrote their core functionalities in the kernel space, specifically in sysproc.c
and sysfile.c
. Each system call was assigned a unique integer identifier in syscall.h
. This identifier, along with the function definition, was mapped in the system call table within syscall.c
, enabling the kernel to recognize and route the calls. To make these system calls accessible in user space, we defined their prototypes in user.h
. The usys.pl
script was then used to generate user-space stubs that act as entry points for the system calls. Finally, we created user programs to test our system calls and added their object files to the Makefile
, ensuring they were compiled and linked during the build process.
Each system call has its wrapper function in the user space which you can run once the xv6 system is booted.
To run the xv6 system calls,
Navigate to the xv6-riscv directory and run the following commands
$ cd Project1_xv6CustomizeSystemCalls/xv6-riscv
$ make clean
$ make qemu
To exit enter Ctrl+A X
-
shmget()
- creates the shared memory and returns the shared memory ID (shmid) of the shared memory created
-
shmat()
- attaches the shared memory space created with the address space of the process
-
shmdt()
- detaches the shared memory
-
shmctl()
- destroys the shared memory
Wrapper function for writing into shared memory is
$ mywritershm
Once you enter a string to write into the shared memory run the wrapper function for reading into shared memory
$ myreadershm
-
rename()
- renames the given file to the name you want to change it to
- rename(oldname,newname)
Wrapper function for renaming file
$ myrename
-
raise()
- implemented
raise(SIGKILL)
which terminates the current process where it has been raised
- implemented
Wrapper function for raising signal
$ mysignal
-
getprocinfo()
- gives information about the current process pid, its parent pid and state of the process
Wrapper function for getting information about the current process
$ myproc
We developed a multi-threaded web server capable of handling up to 10 client requests concurrently, leveraging a thread pool architecture to manage the load. The server utilizes a producer-consumer model, where client requests act as the producers and the threads in the pool serve as consumers. The server supports essential HTTP methods to handle a wide variety of client interactions. Each request is logged, capturing relevant details of the server's activity and storing them in a log file for monitoring and debugging purposes. Authentication mechanisms are integrated for restricted resources, ensuring secure access control. Additionally, the server is equipped with robust error handling capabilities, managing various HTTP errors and providing appropriate responses to clients, contributing to a reliable and secure web service.
-
Contains sample client python code in
client.py
to simulate client requests. -
Run
clean.sh
to clear the previously stored data received from the server. -
A
data
directory gets created to store the data requested by the client.
-
-
server.config
: defines the paramaters of port, network, max thread and document root of the server -
users.txt
: keeps track of all users and with their passwords
-
-
-
Contains server data requested by the client.
-
Data can be an image, text, audio or html files.
-
Some data are under the
secure
folder which means the client needs to be authenticated to access them.
-
-
-
Contains the header files to be included to carry out the necessary functionalities
-
authentication.h
-
config.h
-
http.h
-
logger.h
-
server.h
-
-
-
- Stores all the logs throughout the server in a
server.log
file
- Stores all the logs throughout the server in a
-
-
Contains the files for carrying out all the functionalities
-
authentication.c
: Decryptes the base64 encoded username and password of the client and checks for a match inconfig/users.txt
. -
config.c
: Loads theserver.conf
onto a data structure. -
http.c
:-
Contains functions which handle the HTTP request methods like
GET
,POST
,PUT
andDELETE
. -
It also checks if the client is authorised if it requests data in the
data/secure
folder. -
It also sends back the appropriate HTTP response.
-
-
logger.c
: A basic implememtation of a logger to log the server actions on tologs/server.log
. -
server.c
: Using TCP it offers a connection with the clients, implements multithreading to handle multiple client requests and uses semaphores for synchronisation. -
main.c
: Root of the server.
-
-
-
- It serves static content like HTML, images, and audio from the
server/data
folder to the clients, ensuring content is sent in response to HTTP requests.
- It serves static content like HTML, images, and audio from the
-
-
GET
: used by clients to retrieve data from the server.$ curl http://localhost:8080/index.html
-
POST
: used by clients to send data to the server.$ curl -X POST http://localhost:8080/application.json -H "Content-Type: application/json" -d '{"name": "Jane Smith", "email": "[email protected]"}'
-
PUT
: used to update an existing resource or create a new resource if it does not already exist.$ curl -X PUT http://localhost:8080/test.txt -H "Content-Type: text/plain" -T data/test.txt
-
DELETE
: used to remove a resource from the server.$ curl -X DELETE http://localhost:8080/pic1.jpg
-
-
- The server can serve various types of content (e.g., images, text, HTML, audio) based on the request type. The content is served from the
server/data
folder.
- The server can serve various types of content (e.g., images, text, HTML, audio) based on the request type. The content is served from the
-
-
The server includes error handling mechanisms and returns appropriate HTTP error responses which include :
-
400 : Bad Request
$ curl -X HEAD http://localhost:8080/hi.txt
-
401 : Unauthorized
$ curl -u username:wrongpassword http://localhost:8080/secure/audio1.mp3
-
404: Not Found
$ curl -u http://localhost:8080/hi.txt
-
500 : Internal Server Error
$ curl -u username:password http://localhost:8080/secure/pic3.jpeg
-
-
On the other hand, it returns
200 : OK
which tells us that the client request has been handled successfully.
-
-
-
The server uses a thread pool of 10 threads to handle multiple client requests concurrently, improving performance and scalability by reusing threads for handling subsequent client connections.
-
Client requests are
enqueue()
to the queue data structure and worker threadsdequeue()
the requests from the queue. -
Access to the queue is synchronised using semaphores as used in the
Producer-Consumer problem
. -
The client requests act like the Producers and the threads which perform these requests act like the Consumers.
-
-
- The server is configured through a
server/config/server.config
file, which defines the parameters like server port, network settings, and maximum threads.
- The server is configured through a