Sabtu, 28 November 2015

File System : FUSE, Implementasi file system 'copy just once'

FUSE : File System in Userspace

sesuai dengan namanya dengan FUSE kita bisa mengimplementasikan file system dengan userspace program. Jadi implementasi dari FUSE bisa diprogram oleh penggunanya sendiri.

Apa itu file system :
File System adalah struktur logika yang digunakan untuk mengendalikan akses terhadap data yang ada pada harddisk. Terdapat berbagai jenis-jenisnya dan penggunaan algoritma yang berbeda.

FUSE

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.

Module kernel FUSE dan FUSE library berhubungan melalui sebuah special file descriptoryang didapatkan dengan membuka /dev/fuse. FUSE kernal module meneruskan request ke aplikasi fuse anda. aplikasi anda memerintahkan fuse cara menjawab request. FUSE kernal module dan FUSE library berkomunikasi lewat file deskriptor spesial yang diperoleh dengan membuka /dev/fuse. file ini dapat terbuka berkali-kali dan file deskriptor yang diperoleh diteruskan ke mount syscall, untuk menyesuaikan deskriptor dengan filesystem mount.

Contoh Penerapan :
Jihad dan Sekar adalah teman baik dan sangat dekat. Karena kedekatan itulah, timbul rasa yang berbeda di hati Jihad untuk Sekar. Suatu hari, Jihad mengutarakan isi hatinya kepada Sekar. Namun, Sekar ingin melihat dulu kesungguhan Jihad, Ia memberikan syarat bagi Jihad untuk mendapatkan hatinya. Syarat tersebut adalah Sekar ingin Jihad membuatkannya sebuah implementasi dari fuse yang baru saja didapatkannya dari asistensi praktikum sistem operasi. Sebelumnya, ketika asistensi hanya diajarkan implementasi dasar yaitu mengaitkan direktori lain (mount) dengan fuse. Padahal ketika dikaitkan dengan direktori (mount) Sekar ingin agar implementasi fuse tersebut memiliki kriteria sebagai berikut:
File dalam direktori tersebut hanya bisa di­copy atau dipindahkan sebanyak satu kali,sehingga file yang telah di­copy atau dipindahkan tersebut tidak dapat di­copy atau dipindahkan lagi (file terkunci). Contoh: terdapat file A. jika file A dicopy atau dipindahkan maka akan terbentuk file salinan atau hasil pindahan file A, sedangkan file A sendiri tidak bisa diapa­apakan lagi (terkunci). Namun file salinan A tetap bisa dicopy atau dipindahkan, begitu seterusnya.

Dari permasalah di atas fungsi yang kita implementasikan pada fuse yaitu.
getattr : Untuk memperoleh atribut/properties dari file yagn akan dicopy
getdir : Mendapatkan alamat file yang akan dicopy
mknod : membuat file baru yang kan dijadikan file hasil copy
chmod : digunakan untuk merubah permission agar file yang lama tidak bisa dicopy lagi.
open : membuka file yang akan dicopy untuk kemudian dibaca
read : membaca data dari file yang akan dicopy
write : menuliskan data ke file hasil mknod dan data hasil dari read

Penerapan :
Hanya dengan merubah pada fungsi write, yaitu merubah permission yang akan dicopy.
untuk mendapatkan alamat file yang akan dicopy, kita buat variabel baru, untuk mendapat alamat kita ambil pada variabel fpath di funsgi read.

Coding lengkap :

#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <sys/statfs.h>

static const char *dirpath ="/home/mifta28/SISOP4";

char readPath[1000];

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;
}

static int xmp_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler)
{
    DIR *dp;
    struct dirent *de;
    int res = 0;
    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);
    dp = opendir(fpath);
    if(dp == NULL)
        return -errno;

    while((de = readdir(dp)) != NULL)
    {
        res = filler(h, de->d_name, de->d_type);
        if(res != 0)
            break;
    }

    closedir(dp);
    return res;
}

static int xmp_mknod(const char *path, mode_t mode, dev_t rdev)
{
    int res;
    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);
    res = mknod(fpath, mode, rdev);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_chmod(const char *path, mode_t mode)
{
    int res;

    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);
    res = chmod(fpath, mode);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_open(const char *path, int flags)
{
    int res;
    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);
    res = open(fpath, 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)
{
    int fd;
    int res;
    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);
    strcpy(readPath,path);
    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)
{
    int fd;
    int res;
    int res1;
    char fpath[1000],temp1[1000];

    sprintf(fpath, "%s%s", dirpath, path);
    fd = open(fpath, O_WRONLY);
    if(fd == -1)
        return -errno;

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

    sprintf(temp1, "%s%s", dirpath, readPath);
    res1 = chmod(temp1, 0000);
    if(res1 == -1)
        res1 = -errno;

    close(fd);
    return res;
}

static struct fuse_operations xmp_oper = {
.getattr = xmp_getattr,
//.readlink = xmp_readlink,
.getdir = xmp_getdir,
.mknod = xmp_mknod,
//.mkdir = xmp_mkdir,
//.symlink = xmp_symlink,
//.unlink = xmp_unlink,
//.rmdir = xmp_rmdir,
//.rename = xmp_rename,
//.link = xmp_link,
.chmod = xmp_chmod,
//.chown = xmp_chown,
//.truncate = xmp_truncate,
//.utime = xmp_utime,
.open = xmp_open,
.read = xmp_read,
.write = xmp_write,
//.release = xmp_release,
//.fsync = xmp_fsync

};

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



Cara mengcompile program

Cara emnjalankan program , dimana tmp/fuse merupakan direktori tempat kita akan meng mount file

Proses copy pada file pertama sukses

Proses copy yang kedua untuk file yang sama maka akan terjadi error.

Sekian terimakasih :) semoga bermanfaat.


Tidak ada komentar:

Posting Komentar