Selasa, 16 Desember 2014

FUSE


FUSE
Apasih FUSE itu?

FUSE adalah singkatan dari Filesystem in Userspace. FUSE sendiri dapat diartikan sebagai kernel yang memungkinkan untuk membuat filesystem sendiri tanpa harus mengakses kode kernel secara langsung.

Filesystem ini mempermudah untuk mengorganisir suatu kumpulan data agar mudah dibaca oleh user dan dipasang atas direktori tertentu

Untuk memasang(MOUNT) FUSE : ./hello.py ~/somedir
Untuk melepas (UNMOUNT) FUSE : fusermount -u ~/somedir

Cara kerja FUSE:

  • Aplikasi membuat syscall file terhubung
  • Kernel menggambarkan file terdapat pada FUSE yang dipasang
  • Kernel FUSE meneruskan permintaan ke userspace aplikasi FUSE
Operasi FUSE

  • Operasi direktori
readdir(path) : menghasilkan entri direktori untuk setiap file dalam direktori
mkdir(path, mode) : membuat direktori
rmdir(path) : menghapus direktori kosong
  • Operasi File
mknod(path, mode, dev) : membuat file
unlink(path) : menghapus file
rename(old, new) : memindah atau menguabah nama file
  • Operasi Metadata
getattr(path) : membaca metadata
chmod(path, mode) : mengubah izin
chown(path, uid, gid) : mengubah kepemilikan
  • Operasi lainnya
statfs(path)
    fsdestroy()
      create(path, flags, mode)
        utimens(path, times)
          readlink(path)
            symlink(target, name)
              link(target, name)
                fsync(path, fdatasync, fh)
                .....


                Contoh penggunaan FUSE pada Phyton :

                • readdir >>

                fuse.fuse_python_api = (0, 2)

                hello_path = '/hello'
                hello_str = 'Hello World!\n'
                class HelloFS(Fuse):

                    def readdir(self, path, offset):
                        for r in  '.', '..', hello_path[1:]:

                            yield fuse.Direntry(r)


                • open >>
                hello_path = '/hello'
                hello_str = 'Hello World!\n'
                class HelloFS(Fuse):
                    # ...

                    def open(self, path, flags):
                        if path != hello_path:
                            return -errno.ENOENT
                        accmode = os.O_RDONLY | os.O_WRONLY \
                                  | os.O_RDWR
                        if (flags & accmode) != os.O_RDONLY:
                            return -errno.EACCES
                • read >>
                def read(self, path, size, offset):
                        if path != hello_path:
                           return -errno.ENOENT
                        slen = len(hello_str)
                        if offset < slen:
                           if offset + size > slen:
                               size = slen - offset
                           buf = hello_str[offset:offset+size]
                        else:
                           buf = ''
                        return buf
                • Helper stat subclass >>
                class MyStat(fuse.Stat):
                    def __init__(self):
                        self.st_mode = 0
                        self.st_ino = 0
                        self.st_dev = 0
                        self.st_nlink = 0
                        self.st_uid = 0
                        self.st_gid = 0
                        self.st_size = 0
                        self.st_atime = 0
                        self.st_mtime = 0
                        self.st_ctime = 0
                • getattr >>
                def getattr(self, path):
                        st = MyStat()
                        if path == '/':
                            st.st_mode = stat.S_IFDIR | 0755
                            st.st_nlink = 2
                        elif path == hello_path:
                            st.st_mode = stat.S_IFREG | 0444
                            st.st_nlink = 1
                            st.st_size = len(hello_str)
                        else:
                            return -errno.ENOENT
                        return st
                • Boilerplate Main
                def main():
                    usage="\nUserspace hello example\n\n" \
                          + Fuse.fusage
                    server = HelloFS(version="%prog "
                                       + fuse.__version__,
                                     usage=usage,
                                     dash_s_do='setsingle')

                    server.parse(errex=1)
                    server.main()

                if __name__ == '__main__':
                    main()



                Selamat mencoba! :D