FUSE BUAT LINUX

16.48 0 Comments A+ a-

 

 

INTERMEZZO

Yo ketemu lagi. Karena kesibukan di dunia nyata dan cobaan-cobaan yang sering datang akhir-akhir ini, mungkin ini post yang terakhir (Sorry admin orang penting jadi maklum )  Kali ini kita akan ngebahas tentang fuse (file system in user space) linux. Jadi apa itu fuse ? fuse adalah file system buatan kita sendiri.


FUSE

Fuse atau singkatan dari (file system in user space) adalah file system buatan kita sendiri, dimana fungsi-fungsi yang berhubungan dengan file (seperti copy,delete,buat file baru dll) akan kita implementasikan sendiri di dalam source code. Fungsi-fungsi tersebut juga bisa kita modif, misal kita ingin ketika mengopy sebuah file muncul notifikasi, atau waktu mendelete file akan muncul sebuah log yang mencatat kapan dan apa yang kita delete juga bisa kita lakukan. Pokoknya file system versi kamu banget deh. Jadi cara kerjanya nanti, kamu akan nge-mount sebuah folder ke sebuah lokasi tempat fuse kamu bekerja.

formalitas

MAKE YOUR OWN FUSE!

Yuk langsung kita praktekan.

/*
    FUSE: Filesystem in Userspace
    Copyright (C) 2001  Miklos Szeredi (mszeredi@inf.bme.hu)

    This program can be distributed under the terms of the GNU GPL.
    See the file COPYING.
*/

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

#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/fandyaw"; //Destinasi folder yang akan di mountkan

char globalpath[1000];
int bendera=0;

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_readlink(const char *path, char *buf, size_t size)
{
    int res;
    char fpath [1000];
    sprintf(fpath,"%s%s",dirpath,path);
    res = readlink(fpath, buf, size - 1);
    if(res == -1)
        return -errno;

    buf[res] = '\0';
    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_mkdir(const char *path, mode_t mode)
{
    int res;

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

    return 0;
}

static int xmp_unlink(const char *path)
{
    int res;
char fpath [1000];
    sprintf(fpath,"%s%s",dirpath,path);
    res = unlink(fpath);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_rmdir(const char *path)
{
    int res;

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

    return 0;
}

static int xmp_symlink(const char *from, const char *to)
{
    int res;
char fpath [1000], ffrom[1000],fto[1000];
    sprintf(fto,"%s%s",dirpath,to);
    sprintf(ffrom,"%s%s",dirpath,from);
   
   
    res = symlink(ffrom, fto);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_rename(const char *from, const char *to)
{
    int res;

    char fpath [1000], ffrom[1000],fto[1000];
    sprintf(fto,"%s%s",dirpath,to);
    sprintf(ffrom,"%s%s",dirpath,from);
    res = rename(ffrom, fto);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_link(const char *from, const char *to)
{
    int res;

    char fpath [1000], ffrom[1000],fto[1000];
    sprintf(fto,"%s%s",dirpath,to);
    sprintf(ffrom,"%s%s",dirpath,from);
    res = link(ffrom, fto);
    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_chown(const char *path, uid_t uid, gid_t gid)
{
    int res;

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

    return 0;
}

static int xmp_truncate(const char *path, off_t size)
{
    int res;

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

    return 0;
}

static int xmp_utime(const char *path, struct utimbuf *buf)
{
    int res;
   
    char fpath [1000];
    sprintf(fpath,"%s%s",dirpath,path);
    res = utime(fpath, buf);
    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);
    fd = open(fpath, O_RDONLY);
    if(fd == -1)
        return -errno;

    strcpy(globalpath,fpath);

    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;

        chmod(globalpath,0000);
    char fpath [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;
   
    close(fd);
    return res;
}

/*static int xmp_statfs(struct fuse_statfs *fst)
{
    struct statfs st;
    int rv = statfs("/",&st);
    if(!rv) {
        fst->block_size  = st.f_bsize;
        fst->blocks      = st.f_blocks;
        fst->blocks_free = st.f_bavail;
        fst->files       = st.f_files;
        fst->files_free  = st.f_ffree;
        fst->namelen     = st.f_namelen;
    }
    return rv;
}
*/
static int xmp_release(const char *path, int flags)
{
    /* Just a stub.  This method is optional and can safely be left
       unimplemented */
    char fpath [1000];
    sprintf(fpath,"%s%s",dirpath,path);
    (void) fpath;
    (void) flags;
    return 0;
}

static int xmp_fsync(const char *path, int isdatasync)
{
    /* Just a stub.  This method is optional and can safely be left
       unimplemented */
    char fpath [1000];
    sprintf(fpath,"%s%s",dirpath,path);
    (void) fpath;
    (void) isdatasync;
    return 0;
}

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,
    .statfs    = xmp_statfs,
    .release    = xmp_release,
    .fsync    = xmp_fsync
   
};

int main(int argc, char *argv[])
{
    fuse_main(argc, argv, &xmp_oper);
    return 0;
}
JEKK TOP!!
jek top

Cara menjalankannya di terminal
Compile dengan gcc -Wall [nama file].c `pkg-config fuse --cflags --libs` -o [nama file]
Lalu buat sebuah direktori kosong tempat fuse itu bekerja (contoh : /tmp/fuse)
Coba jalankan fuse tadi dengan cara: ./[nama file] /tmp/fuse
Kalau udah lelah, tinggal unmount aja,caranya  :
fusermount -u /tmp/fuse
Setelah menjalankan kodingan diatas, kamu bakal bisa membuat file system lengkap dengan fungsi-fungsi sediakala sebuah file system sebagaimana mestinya. Kalu kamu ingin memodif fuse kamu, modifikasi di bagian fungsi (contoh : ingin memodif ketika mengopy file : ubah di fungsi read/write)

Oke sekial dulu postingan kali ini, terima kasih,  semoga bermanfaat dan sampai jumpa :')