Senin, 22 Desember 2014

FUSE 


           Beberapa bulan yang lalu saya mendapatkan modul pembelajaran dengan materi FUSE. Sebelumnya FUSE adalah contoh dari file system. File system dibagi menjadi dua kata File dan System. File adalah kumpulan informasi yang berhubungan dan tersimpan di dalam secondary storage. Sedangkan System adalah suatu jaringan kerja dari prosedur- prosedur yang saling berhubunganm berkumpul bersama untuk melakukan suatu kegiatan.

            Secara garis besar yang dimaksud dengan file system adalah sebuah metode pemberian nama pada file dan merupakan cara untuk menempatkannya ke dalam sebuah media penyimpan, termasuk juga penempatan file pada struktur direktori. Setiap sistem operasi memiliki metode yang berbeda - beda untuk menempatkan file dalam struktur hirarki.


              Fuse merupakan sebuah kerangka sistem berkas pada area pengguna, terdiri dari modul kernel (fuse.ko), sebuah pustaka pada area pengguna, dan sebuah utilitas untuk melakukan proses mount (fusermount). Salah satu keistimewaan FUSE yang paling utama adalah diizinkannya proses mount oleh pengguna biasa yang aman. Hal ini memberikan kemungkinan baru untuk menggunakan sistem berkas. Salah satu contoh adalah sshfs, sebuah sistem berkas yang beroperasi pada tingkatan jaringan yang menggunakan protokol sftp. Semenjak proses mount () merupakan operasi yang membutuhkan pengguna yang memiliki hak khusus, sebuah program pembantu (fusermount) dibutuhkan untuk melakukannya yang terpasang dengan tungkatan pengguna root. 

Berikut adalah contoh kodingan mengenai FUSE dari modul yang saya praktikan :      

#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/wahyu/Downloads";

char alamat[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_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,res2;
char fpath[1000], temp[1000];
sprintf(fpath, "%s%s", dirpath, path);
strcpy(temp,fpath);
res = unlink(fpath);
do
{
sprintf(temp, "%s-copy", fpath);
res2=unlink(temp);
}
while(res2!=-1);
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 from1[1000];
char to1[1000];
sprintf(from1,"%s%s", dirpath, from);
sprintf(to1,"%s%s", dirpath, to);

res = symlink(from, to);
if(res == -1)
return -errno;

return 0;
}

static int xmp_rename(const char *from, const char *to)
{
int res;
char from1[1000];
char to1[1000];
sprintf(from1,"%s%s", dirpath, from);
sprintf(to1,"%s%s", dirpath, to);
res = rename(from1, to1);
if (res == -1)
return -errno;

return 0;
}

static int xmp_link(const char *from, const char *to)
{
int res;
char from1[1000];
char to1[1000];
sprintf(from1,"%s%s", dirpath, from);
sprintf(to1,"%s%s", dirpath, to);

res = link(from, to);
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);
strcpy(alamat,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;

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


fd = open(fpath, O_WRONLY);

char temp1[1000], temp2[1000], kata[1000];
sprintf(temp1, "%s%s", dirpath, alamat);
sprintf(temp2, "%s-copy", temp1);
FILE* a; FILE* b;
a = fopen(temp2,"w+");
b = fopen(temp1, "a+");
while(fgets(kata,1000,b)!=NULL)
{

fprintf(a,"%s",kata);
}
fclose(a);
fclose(b);
if(fd == -1)
return -errno;

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

close(fd);
return res;
}

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, //get file atribut
.readlink = xmp_readlink,
.getdir = xmp_getdir, //get directory
.mknod = xmp_mknod, //create a file node
.mkdir = xmp_mkdir, //create directory
.symlink = xmp_symlink, //create a symbolic link
.unlink = xmp_unlink, //remove file
.rmdir = xmp_rmdir, //remove directory
.rename = xmp_rename,
.link = xmp_link, //create a link
.chmod = xmp_chmod, //change the owner and group of a file
.chown = xmp_chown, // sama
.truncate = xmp_truncate, //change the size of a file
.utime = xmp_utime, //change the access and modification times of a file
.open = xmp_open,
.read = xmp_read,
.write = xmp_write,
.release = xmp_release, //release directory
.fsync = xmp_fsync //synchronize file contents

};

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