COMP3300/6330 Lab 3 – Operating Systems Implementation
Step 1 – Prep
Read through the manual pages for mmap, mprotect, signal. Provide a simple summary of what these programs do (make notes in your notebook) Read
through the documentation on the virtual file system, which can be found within “Documentation/filesystems/vfs.txt” from the root directory of linux source code.
In what way does the vfs make it simpler for someone implementing a file system?
The mmap() system call provides a way for a user process to ask the kernel to map some pages from a file or device into the memory space of the process.
The return value from mmap() is a pointer that points to an area of memory that, when accessed, will cause a page fault and a load of the corresponding page
of data from the device or file. By using mmap() a process can treat data in a file or device as memory, which provides a very convenient programming
interface for some tasks.
memalign() is a library call that allocates aligned memory. It is very similar to malloc() except that it takes an additional parameter that determines the minimum
memory alignment required for the returned memory.
In this lab you will use an alignment of 4096 so that the returned memory is guaranteed to be on a page boundary. This needs to be done because the memory
management hardware works in units of one page and cannot set permissions on sub-page units.
The prototype for memalign is:
void *memalign(size_t alignment, size_t size);
Note that you should include “malloc.h”.
Step 2 – File copying using mmap
See the description of the mmap() system call in the mmap man page.
An interesting way to copy a file is to memory map the source and destination files then to use memcpy() to copy the data between them. This allows you to
copy a file without a read() or write() system call.
Write a mmap_copy program that copies a file. It should take 3 parameters on the command line, the source file name, the destination file name and the size of
the source file in bytes. Your program will need to perform the following steps:
Open the source file for reading
Open the destination file for reading and writing
Use the ftruncate() call to set the size of the destination file
Use mmap() on the source file descriptor to map in the file read-only (hint: you will need to use PROT_READ)
Use mmap() on the destination file descriptor to map in the file with write permission (hint: you will need to use PROT_READ|PROT_WRITE and
memcpy() the data from one file to the other
close both files
Test your program by copying files of different sizes and seeing if they are the same after copying using cmp.
Step 3 – Setting memory protections
The mprotect() system call allows you to set the protections on a set of pages in your processes address space. This allows you to set pages as read-only or
to allow the pages to be executed.
Have a look at the mprotect() man page.
In this exercise you will allocate some memory then set the memory non-writeable and install a signal handler to catch a segmentation fault.
You will then attempt to write to the memory and your signal handler will be called as the memory management hardware detects a fault.
Inside your signal handler you will use mprotect to make the memory writeable again then return. The write to the memory will then continue.
Your program should perform the following steps:
Allocate a page of memory using memalign(). See the description of memalign() above.
Set the memory as non-writeable using mprotect(),
Install a signal handler for the SIGSEGV signal using the signal() library call.
Attempt to write to the write-protected memory
Your signal handler should print out a message then set the page of memory as writeable using mprotect() and return. Write out a message saying that your program has completed the write
Step 4 – Downloading and mounting the vvsfs
To mount and check the file system do the following
cd into the vvsfs directory
use “make” make the module and the various helper utilities
load the module into the kernel with insmod (and sudo)
(cat /proc/filesystems to check that the new file system is registered)
make an empty directory to mount the vvsfs, such as: “mkdir testdir”.
make an empty file to use as the raw block device: “dd of=vvsfs.raw if=/dev/zero bs=512 count=100”
make a vvsfs filesystem on the raw file: “./mkfs.vvsfs vvsfs.raw”
mount the vvsfs: “sudo mount -t vvsfs -o loop vvsfs.raw testdir”
use “cat /proc/mounts” to check that it was mounted okay.
‘cd’ into the directory and try a few different file operations.
create two files, say “file1” and “file2”, write some data into them.
what is the difference between “ls” and “ls file1” in terms of the routines that are executed?
examine the code and attempt to work out which routines are executed when you do the following actions: read from a file, writing to a file, listing a
directory, and creating a new file. (Hint: check the end of dmesg for the debug messages from the vvsfs module)
what happens when you attempt to remove a file?
‘cd’ to the directory you mounted the vvsfs on and determine the number of bytes this direcory takes up. What is odd about this result?
unmount the filesystem. (use the umount command)
remove the vvsfs module.