G22.3033-010 Lab 4: User-level NFS3 server

Due date: Monday, Mar 2.

Introduction

This lab is a short lab designed to make you familiar with the SFS software infrastructure. In the previous assignments you have used SFS's libasync. In this assignment, you will be exposed to a functional distributed file system, RPC, and the NFS 3 protocol. If you choose a final project in the area of distributed file systems the SFS the SFS infrastructure can save you a lot of time.

This assignment should only require about 40 lines of code. You are supposed to fill in a missing funciton in a user-level NFS3 server. At the end of the assignment you will have an operational, distributed file system. Once you have completed the assignment, you should start thinking of what you want to do for a final project. The final project is essentially to build a cool system of your own design and write a short paper about it. (If you don't have any specific ideas for a project yourself, the web page suggests a number of possible projects.)

Fetching and compiling sfsusrv

Get the source for sfsusrv in ~class/src/sfsusrv.tar.gz. Configure and compile it as you did for the multifinger lab:
% tar xzf ~class/src/sfsusrv.tar.gz
% cd sfsusrv
% sh ./setup
automake: configure.in: installing `./install-sh'
automake: configure.in: installing `./mkinstalldirs'
automake: configure.in: installing `./missing'
configure.in: 22: required file `./ltconfig' not found
automake: Makefile.am: installing `./INSTALL'
automake: Makefile.am: installing `./COPYING'
+ autoconf
+ set +x
% setenv DEBUG -g
% ./configure --with-sfs=/home/c/class/lib/debug
creating cache ./config.cache
checking for a BSD compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking whether make sets ${MAKE}... yes
checking for working aclocal... found
checking for working autoconf... found
checking for working automake... found
checking for working autoheader... found
checking for working makeinfo... found
checking host system type... i386-unknown-openbsd2.8
...
updating cache ./config.cache
creating ./config.status
creating Makefile
creating config.h
% 
Remember, It is very important that you supply the argument --with-sfs=/home/c/class/lib/debug to ./configure. If you don't, things will appear to work, but you will get a version of the SFS libraries without built-in debugging sanity checks.

Next create a public/private key pair for sfsusrv to use to prove its identity to clients. Run these commands in your sfsusrv directory to create a new private key and put it in the file sfs_host_key:

% sfskey gen -P sfs_host_key
Creating new key for sfs_host_key.
       Key Name: dm@class3.scs.cs.nyu.edu

sfskey needs secret bits with which to seed the random number generator.
Please type some random or unguessable text until you hear a beep:
DONE            
% 
Type return when sfskey prompts you for the Key Name.

Running sfsusrv

You will need to run both sfsusrv and a client program. You can't run them them on the same machine. The client program must be run as root, and so is already running for you an the 5 class machines.

In order to avoid conflicts between different students running sfsusrv on the same machine, you should choose a unique port for yourself between 1024 and 65536. Let's call it my-port.

To test sfsusrv, open two windows on two different class machines. Say you want to use class2 as the client, and class3 as the server. On the server machine:

class3% cd ~/sfsusrv
class3% mkdir /tmp/export-$user
class3% rm sfsusrv_config
class3% echo 'keyfile sfs_host_key' > sfsusrv_config
class3% echo "export /tmp/export-$user" >> sfsusrv_config
class3% setenv SFS_PORT my-port
class3% ./sfsusrv -f sfsusrv_config
If all went well, you should see output like this:
sfsusrv: version 0.5, pid 8493
sfsusrv: serving /sfs/class3.scs.cs.nyu.edu:dgn84hqianfvqpvh7a42wgubqz9pdy9g
sfsusrv: No sfssd detected, running in standalone mode.
The /sfs/my-port@class3.scs.cs.nyu.edu:dgn84... is a self-certifying pathname. It contains enough information for an SFS client to contact your SFS server and verify the server's identity: the class3.scs.cs.nyu.edu part names the server, and the bytes after the colon are a hash of the server's public key and server name. You can find out more about self-certifying pathnames and SFS at http://www.fs.net; we will also read a paper about SFS (see schedule).

sfsusrv is now acting as an SFS file server for the directory /tmp/export-$user. Now you need to access that server from a client machine.

Accessing the server from a client machine

The SFS software should automatically mount your server if you simply cd to the appropriate directory. In the window you have on the client machine, type:
class2% cd /sfs/my-port@class3.scs.cs.nyu.edu:dgn84hqianfvqpvh7a42wgubqz9pdy9g
class2% ls
You should see a list of the files in /tmp/export-$user on the sfsusrv machine.

Reading a file

Now try to read a file on the client machine:
class2% touch junk
class2% echo hi > junk
class2% cat junk
cat: junk: Input/output error
You can't read the file because sfsusrv doesn't implement the read operation. Your job is to implement the NFS3 read RPC. The file that implements the NFS3 RPCs is client.C. Open client.C and you will see how the other NFS3 RPCs are implemented using standard file system system calls; your job is to create a similar implementation for read, filling in the empty client::nfs3_read() function.

If you do this correctly, you will only have to make changes to client.C, but feel free to understand how the server works.

Here are some hints:

Tracing RPCs

After you've added read to sfsusrv correctly, do the following to help you understand how the SFS client and server communicate with RPC.

Stop your sfsusrv with control-C, then re-start it with these commands:

class3% env ASRV_TRACE=10 ./sfsusrv -f sfsusrv_config >& sfsusrv.trace
Type these commands on the sfscd machine:
class2% cd /sfs/PASTE_PATHNAME_HERE
class2% rm junk
class2% echo hello > junk
class2% cat junk
class2% cat junk
Stop sfsusrv. Now look at the RPC queries and replies recorded in sfsusrv.trace.


How/What to hand in

You should place your code in ~class/handin/lab4 as usual. Put your answers to the RPC questions in ~class/handin/lab4/$user/answers.txt.