A FUSE

Hello Fuse

by: burt rosenberg
at: october 2024

Overview

This project leads on to a project in key-value storage modeled after Level-DB. We will use the user's interface to the file system, and hook it into our own file system using a system called FUSE. This project introduces,

The documentation on FUSE is scarce. Here are some resources:

FUSE

Unix has mountable file systems. This means that the overall file tree can be comprised of different file systems. The passage from one file system to another is at an object that looks to the user like a directory, but it is a mount point. A mount point node is marked with the root of the filesystem which should begin at that directory.

FUSE allows user programs to be the destination of a mount point. By registering on a directory, FUSE intercepts all file requests on a path passing through that directory and packages up the request as a call into the user program. The user program provides a response by call-by-reference parameters, and the return value.

The hello fuse file system is an example Fuse filesystem. It mounts on a particular mount location, and answers all queries from the program. There is no disk or other memory system involved, other than the memory of the program implementing the hello fuse file system. When asked, it responds with a completely fixed directory contents; and when the hello file is read, it responds with the contents of a string in the memory of the hello-fuse program. When the file is written, it overwrites this string with a new string.

FUSE and the OS
Typical file writing scenario

    User-program <-----> Kernel <-----> VFS <-----> filesystem <-----> block devices, e.g. hard drive
    
Operating system hooked to deliver file requests to hello-fuse.c
      
    User-program <-----> Kernel <-----> VFS <-----> FUSE <-----> hello-fuse.c <-----> RAM memory

Registering Callbacks

FUSE requires a continuously running program to service the filesystem calls that get routed to the Fuse File System. This is a sort of server, for the service of the filesystem, that the operating system contacts when there is work to do in the FUSE file system.

The calls into the FUSE server are done by a main program providing the kernel with a menu of functions. When there is work to do, the kernel calls the function associated with the sort of work required. There is a call back for read a file, or write a file, as well as to list a directory, remove a file from a directory. Every operation that can be done on a filesystem is represented by a function in the callback table.

The FUSE Callback table
static struct fuse_operations fuse_oper = {
	// call backs for fuse
	.getattr = fs_getattr,
	.readdir = fs_readdir,
	.mkdir   = fs_mkdir,
	.rmdir   = fs_rmdir,
	.create  = fs_create,
	.unlink  = fs_unlink,
	.utimens = fs_utimens,
	.truncate = fs_truncate,
	.open    = fs_open,
	.write   = fs_write,
	.read    = fs_read,
} ;

The project

The hello-fuse.c template program given in the assignment implements many of the API functions needed. The program can,

In the above box names like fs_read were used. It is the name of a function and in hello-fuse.c that name is hello_read instead.

Since all but write is implemented, the makefile target that tests just for read should work out of the box. This only runs in Linux!, so you will need an AWS image, or run multipass on your local machine.

You will need the developer package to program with FUSE, and there is a makefile target that shows you how to install that package.

The quick test will mount hello-fuse on a mount point and go ahead and test reading, then unmount from the mount point. This is just a quick way to do things.

In general, you will need to have two shells. In one run hello-fuse with the -d option, to linger without exiting hello-fuse, getting the debug output. In the other shell you can send file requests to the hello fuse file system to see if it is working.

MANPAGE
NAME
    hello-fuse
    
SYNOPSIS	
    hello-fuse [-d] _mount_directory_
    
DESCRIPTION
    When mounted on a directory, is a file system with one file, "hello".
    
OPTIONS
    All unused options are forward to the FUSE deamon
    
    -d debugging mode

HISTORY
    The hello FUSE test program
    Csc421 semester 221 added a write function as an exercise

BUGS

Example AWS setup

  1. Login into AWS
  2. Setup the public-private key-pair, if you have not already.
  3. Start an EC2 instance.
  4. Click on the connect to copy the connect string. It begins with ssh
  5. In the directory were your private key is, enter the connect string.
  6. Note: your private key has to have permissions rx------.
You should be now at the shell of your AWS instance. Setup as follows.
    ubuntu:~$ sudo apt-get update
    ubuntu:~$ sudo apt-get install build-essential
    ubuntu:~$ sudo apt-get install libfuse-dev
    ubuntu:~$ sudo apt-get install pkg-config
    ubuntu:~$ git config --global user.name "__githubname__"
    ubuntu:~$ git config --global user.email "__githubemial__"
    ubuntu:~$ git config --global credential.helper store
    ubuntu:~$ git clone https://github.com/csc421-251/__projectrepo__
    Username for 'https://github.com': ...your_github_name.....
    Password for 'https://ojo-r@github.com': .....your_classic_token......
    ubuntu:~$ cd __projectrepo__
    ubuntu@ip:~/__projectrepo__$ make onesteptest
    gcc -Wall hello-fuse.c `pkg-config fuse --cflags --libs` -o hello-fuse
    mkdir mnt
    ./hello-fuse mnt
    ls -la mnt
    total 4
    drwxrwxr-x 4 ubuntu ubuntu 4096 Oct 24 02:24 ..
    -rw-rw-rw- 1 root   root     12 Jan  1  1970 hello
    cat mnt/hello
    Hello Fuse!
    fusermount -u mnt
    ubuntu@ip:~/__projectrepo__$ 
The onsteptest should succeed, but will go by a little too fast for you to understand the what has happened. Instead open a second ssh connection. Then
  1. In the project directory mkdir if necessary the directory mnt
  2. In one window run ./hello-fuse -d mnt to start the hello fuse filesystem daemon.
  3. In the second window see that the mnt directory is now a file system containing one file by running ls -l mnt
  4. In the daemon's window look at the debugging output.
  5. Read the one and only file of the hello fuse filesystem cat mnt/hello
  6. Control-C to shut down the daemon.
  7. See the fusermount target for a useful command if the file system does not unmount from the mnt directory.
Writing to the mnt/hello file will achieve nothing at this point.

Your job is to make writing work by writing the necessary code.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

author: burton rosenberg
created: 19 oct 2020
update: 23 oct 2024