FUSE (File System in User Space)

                Bahasan kali ini adalah FUSE, tetapi FUSE yang akan saya jelaskan disini bukanlah sebuah resistor ataupun benda semacamnya, FUSE yang akan saya jelaskan adalah File System in User Space. Filesystem in Userspace (FUSE) merupakan mekanisme sistem operasi untuk sistem operasi Unix-like yang memungkinkan pengguna tidak ber-hak istimewa menciptakan file system mereka sendiri tanpa mengubah kode kernel. Hal ini dicapai dengan menjalankan kode file system di userspace, sedangkan modul FUSE hanya menyediakan "jembatan" untuk antarmuka kernel yang sebenarnya. Bahasan kali ini memas agak berat, tapi mungkin akan lebih mudah untuk dipahami ketika mencoba memulai praktiknya.

                Pertama kita akan mencoba untuk menginstall fuse di LINUX atau sistem operasi UNIX lainnya. Installasi FUSE:
               1. Download FUSE dari http://fuse.sourceforge.net/ pada bagian Download stable release
               2. Extract file tar.gz dan masuk ke direktori FUSE. (tar –xvzf fuse-2.9.4.tar.gz)
               3. Lakukan installasi FUSE dengan cara :
                    a. Gunakan hak akses super user (sudo su)
                    b. Ketikkan perintah ./configure
                    c. Ketikkan perintah make
                    d. Ketikkan perintah make install
               4. FUSE siap digunakan
               Sebagai contoh untuk mencoba fuse kita akan membuat program fusenya langsung yang bertujuan untuk mengcopy file pada direktori yang akan di mount. Juga akan ditampilkannya pada direktori tambahan yang dapat mengakses drektori yang kita mount. File yang di copy tadi akan diberikan ekstensi .bak dan tidak bisa di edit. Untuk template code bisa di dapatkan di http://fuse.sourceforge.net/doxygen/fusexmp_8c.htm.
Berikut adalah codenya :
#define FUSE_USE_VERSION 26

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#ifdef linux
/* For pread()/pwrite()/utimensat() */
#define _XOPEN_SOURCE 700
#endif

#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
#include <sys/time.h>
#ifdef HAVE_SETXATTR
#include <sys/xattr.h>
#endif

#include<stdlib.h>
#include <sys/types.h>
//dirpath adalah lokasi foler yang akan saya gunakan untuk di mount nantinya
static const char *dirpath = "/home/rafiar/Documents/";

static int xmp_getattr(const char *path, struct stat *stbuf)
{
    int res;
    char fpath[1000];
    sprintf(fpath,"%s%s",dirpath,path);

    res = lstat(fpath, stbuf);
    if (res == -1)
        return -errno;

    return 0;
}
/*fungsi readdir akan memungkinkan kita untuk melakukan ls di folder yang akan kita buat sebagai folser backup dari folder yang akan di mount*/
static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler,off_t offset, struct fuse_file_info *fi)
{
    DIR *dp;
    struct dirent *de;
    char fpath[1000];
    sprintf(fpath,"%s%s",dirpath,path);

    (void) offset;
    (void) fi;

    dp = opendir(fpath);
    if (dp == NULL)
        return -errno;

    while ((de = readdir(dp)) != NULL) {
        struct stat st;
        memset(&st, 0, sizeof(st));
        st.st_ino = de->d_ino;
        st.st_mode = de->d_type << 12;
        if (filler(buf, de->d_name, &st, 0))
            break;
    }

    closedir(dp);
    return 0;
}
/*pada fungsi ini kita akan mendapatkan nama file yang dibuka baik di dalam folder yang di mount maupun didalam folder backupnya melalui *path, kemudian dari sini lah kita akan membuat file baru bernamakan file yang lama di tambahkan extensi .bak, juga hanya diberikan hak akses untuk dilihat saja*/
static int xmp_open(const char *path, struct fuse_file_info *fi)
{
    int res;
    char fpath[1000];
    sprintf(fpath,"%s%s",dirpath,path);

        char ch, source_file[1000], target_file[1000];
        FILE *source, *target;

        sprintf(source_file,"%s",fpath);
        source = fopen(source_file, "r");


        sprintf(target_file,"%s.bak",fpath);

        int ada;
        ada = access(target_file,F_OK);
        if(ada==0)
        {
            remove(target_file);
        }

        target = fopen(target_file, "w");

        while( ( ch = fgetc(source) ) != EOF )
            fputc(ch, target);

        char command[100];
        sprintf(command,"chmod 444 '%s.bak'",fpath);
        system(command);

        fclose(source);
        fclose(target);


        res = open(fpath, fi->flags);
        if (res == -1)
            return -errno;

    close(res);
    return 0;
}

static int xmp_read(const char *path, char *buf, size_t size, off_t offset,
            struct fuse_file_info *fi)
{
    int fd;
    int res;
    char fpath[1000];
    sprintf(fpath,"%s%s",dirpath,path);

    (void) fi;
    fd = open(fpath, O_RDONLY);
    if (fd == -1)
        return -errno;

    res = pread(fd, buf, size, offset);
    if (res == -1)
        res = -errno;

    close(fd);
    return res;
}

static int xmp_write(const char *path, const char *buf, size_t size,
             off_t offset, struct fuse_file_info *fi)
{
    int fd;
    int res;

    char fpath[1000];
    sprintf(fpath,"%s%s",dirpath,path);

    (void) fi;
    fd = open(fpath, O_WRONLY);
    if (fd == -1)
        return -errno;

    res = pwrite(fd, buf, size, offset);
    if (res == -1)
        res = -errno;

    close(fd);
    return res;
}

static struct fuse_operations xmp_oper = {
    .getattr    = xmp_getattr,
    //.access        = xmp_access,
    //.readlink    = xmp_readlink,
    .readdir    = xmp_readdir,
    //.mknod        = xmp_mknod, //pk
    //.mkdir        = xmp_mkdir, //pk
    //.symlink    = xmp_symlink,
    //.unlink        = xmp_unlink, //pk
    //.rmdir        = xmp_rmdir, //pk
    //.rename        = xmp_rename, //pk
    //.link        = xmp_link,
    //.chmod        = xmp_chmod,
    //.chown        = xmp_chown,
    //.truncate    = xmp_truncate,
#ifdef HAVE_UTIMENSAT
    .utimens    = xmp_utimens,
#endif
    .open        = xmp_open,
    .read        = xmp_read,
    .write        = xmp_write,
    //.statfs        = xmp_statfs,
    //.release    = xmp_release,
    //.fsync        = xmp_fsync,
#ifdef HAVE_POSIX_FALLOCATE
    .fallocate    = xmp_fallocate,
#endif
#ifdef HAVE_SETXATTR
    .setxattr    = xmp_setxattr,
    .getxattr    = xmp_getxattr,
    .listxattr    = xmp_listxattr,
    .removexattr    = xmp_removexattr,
#endif
};

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

               Setelah code di tulis di file .c, file siap untuk dicompile melalui terminal dengan cara gcc -Wall [nama file].c `pkg-config fuse --cflags --libs` -o [nama file]. setelah itu membuat folder baru misal dengan perintah mkdir /tmp/raf. Untuk memulai programnya tuliskan perintah ./[nama file] /tmp/raf. Sekarang untuk memulai keajaiban dari program fuse bukalah direktori /tmp/raf kemudian buka file yang ada di direktori tersebut melalui GUI, atau dengan menuliskan ls /tmp/raf pada terminal, kemudian gedit /tmp/raf/[nama_file_yang_ingin_dibuka].


Komentar

Postingan populer dari blog ini

Manajemen Biaya Proyek