Sunday, 3 November 2013

Filesystem in Userspace ( FUSE ) Tutorial

FUSE is an mechanism which allows to create own file systems to non-privileged users without editing the kernel code. Initially it was developed to support for AVFS ( A Virtual File System ). After that it will be taken as separate project. It runs file system code in user space while the FUSE module provides only a "bridge" to the actual kernel interfaces. Check the FUSE structure, it will help you to understand about FUSE.


Installation :

To use FUSE , you must be install this on your system. Just follow my steps.

Step 1 : Download FUSE 2.9.3 ( latest version ) from the following link.

==> FUSE 2.9.3.tar.gz
Step 2 : After downloaded FUSE, open terminal and move to Downloads directory by

cd Downloads

Step 3 : Extract FUSE 2.9.3.tar.gz file by

tar -zxvf fuse-2.9.3.tar.gz

Step 4 : Move to fuse-2.9.3 directory by

cd fuse-2.9.3

Step 5 : Install FUSE by

sudo ./configure

sudo make

sudo make install



Working :



Step 6 : Just create a new directory to work with on FUSE by

mkdir fusep

move to fusep directory as

cd fusep

Step 7 : Create simple helloworld program using  C program by

gedit hello.c

Now copy the following program and paste into hello.c file


#define FUSE_USE_VERSION 26

#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>

static const char *hello_str = "Hello World!\n";
static const char *hello_path = "/hello";

static int hello_getattr(const char *path, struct stat *stbuf)
{
int res = 0;

memset(stbuf, 0, sizeof(struct stat));
if (strcmp(path, "/") == 0) {
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
} else if (strcmp(path, hello_path) == 0) {
stbuf->st_mode = S_IFREG | 0444;
stbuf->st_nlink = 1;
stbuf->st_size = strlen(hello_str);
} else
res = -ENOENT;

return res;
}

static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi)
{
(void) offset;
(void) fi;

if (strcmp(path, "/") != 0)
return -ENOENT;

filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
filler(buf, hello_path + 1, NULL, 0);

return 0;
}

static int hello_open(const char *path, struct fuse_file_info *fi)
{
if (strcmp(path, hello_path) != 0)
return -ENOENT;

if ((fi->flags & 3) != O_RDONLY)
return -EACCES;

return 0;
}

static int hello_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi)
{
size_t len;
(void) fi;
if(strcmp(path, hello_path) != 0)
return -ENOENT;

len = strlen(hello_str);
if (offset < len) {
if (offset + size > len)
size = len - offset;
memcpy(buf, hello_str + offset, size);
} else
size = 0;

return size;
}

static struct fuse_operations hello_oper = {
.getattr = hello_getattr,
.readdir = hello_readdir,
.open = hello_open,
.read = hello_read,
};

int main(int argc, char *argv[])
{
return fuse_main(argc, argv, &hello_oper, NULL);
}


Save the file and close it.

Step 8 : Compile the above program by

gcc -Wall hello.c `pkg-config fuse --cflags --libs` -o hello


Step 9 : After compilation create tmp directory and run object file. Just enter the commands one-by-one given below


mkdir tmp

./hello tmp/

ls tmp/

cat tmp/hello


Thats all. You are done.

To unmount tmp directory enter the following command...

umount tmp

If you have any queries, post it in comments. We will help you.

No comments:

Post a Comment