Sabtu, 28 November 2015

Fuse make you con-FUSE-D

Halo lagi reader
Sekarang saya mau bagi ilmu lagi tentang fuse dan sedikit tentang filesystem


File System terdiri dari kata File dan System.


File :  kumpulan informasi yang berhubungan dan  tersimpan di dalam secondary storage, secara konsep file mempunyai beberapa tipe ada yang bertipe Data terdiri dari character, numeric, dan binary ada juga file yang bertipe program.
System :  Suatu jaringan kerja dari prosedur-prosedur yang saling berhubungan, berkumpul bersama-sama untuk melakukan suatu kegiatan atau untuk menyelesaikan suatu sasaran tertentu
Kalau masih bingung, File system itu seperti kita bisa menghapus direktori, rename file, atau membuat file/folder baru, atau sebagainya. Dan itu semua diatur oleh Komponen yang bernama "Kernel"

FUSE adalah kepanjangan dari Filesystem in Userspace. Itu berarti kita dapat membuat File System semau kita.

Gambarannya sebagai berikut

Dengan adanya Fuse kita bisa membuat filesystem kita sendiri tanpa bergantung pada konfigurasi kernel. Keren bukan? :D

Untuk mendapatnkan Komponen FUSE, anda dapat melakukan beberapa langkah berikut:

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 ^_^

Jika anda telah selesai menginstall FUSE, langkah selanjutnya adalah bermain dengan FUSE milik anda. Berikut ada contoh code FUSE yang dapat anda gunakan

#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/ncc/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;
}

static int xmp_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler)
{
 char fpath[1000];
 if(strcmp(path,"/") == 0)
 {
  path=dirpath;
  sprintf(fpath,"%s",path);
 }
 else sprintf(fpath, "%s%s",dirpath,path);
 int res = 0;
 DIR *dp;
 struct dirent *de;
 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;
 }

System ("notify-send ini masuk fuse");
 closedir(dp);
 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,
 //.readdir = hello_readdir
};

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

Ganti bagian static const char *dirpath = "/home/mhr7/Downloads" dengan
static const char *dirpath = "/home/[nama user kalian]/Downloads"

Simpan kemudian compile dengan menggunakan perintah: gcc -Wall [nama file].c `pkg-config fuse --cflags --libs` -o [nama file]

Kemudian buat sebuah direktori, misalnya: /tmp/fuse
Coba jalankan fuse tadi dengan cara: ./[nama file] /tmp/fuse
Maka semua isi direktori /home/[nama user kalian]/Downloads akan dimount ke direktori /tmp/fuse

Coba masuk ke /tmp/fuse dan jalankan perintah ls, maka semua isi direktori tersebut akan ditampilkan dan akan muncul notifikasi di bagian atas kanan monitor anda.

Jika anda menemui file .txt dalam folder anda, maka anda dapat mengclick file tersebut. Tapi tidak bisa membukanya. Karena fungsi "xmp_open" belum anda tuliskan. Saya sarankan anda untuk mengakses http://fuse.sourceforge.net/doxygen/fusexmp_8c.html untuk melihat dan mencopy fungsi-fungsi yang masih berstatus comment pada code anda.

Agar anda dapat membuka dan melihat file .txt anda, saya anjurkan anda untuk menuliskan fungsi "xmp_wirte", "xmp_open", "xmp_read", sekaligus dan menghapus comment yang ada di situ

Ada kasus lain nih, "Kok fuse di PCmu bisa, tapi di PCku kok ngga bisa?". 
Setelah dicompile, kok malah ada "warning undefined pointer type pada .open dan .write". dan yang salah adalah dibagian "void fi"

Jangan khawatir, sebetulnya itu hanya masalah versi saja. Saya sarankan anda mencoba berbagai :

#define FUSE_USE_VERSION 30 [coba 22/26/28]
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef linux
/* For pread()/pwrite()/utimensat() */
#define _XOPEN_SOURCE 700 [kalau di pc saya saya gunakan 500, di teman saya 600]
#endif

Sekian yang dapat saya bagi bersama, Sebetulnya ini masih secuplik kecil dari keseluruhan quest yang saat itu saya kerjakan. kalau masih belom faham, Bisa langsung email saja ke saya. Atau jika masih ada waktu, akan saya update postingan ini tergantung dari respond temen2 sekalian.

Terimakasih telah membaca :D

Kamis, 05 November 2015

IPC - PIPE untuk sinkronisasi data anatar terminal dalam satu pc

Halo temen2, kali ini saya belajar hal baru lagi lho dari LINUX
Kali ini yang saya pelajarai adalah mengenai PIPE

 IPC (Inter-Process Communication) adalah komunikasi antar proses untuk mengirim data dari satu proses ke proses yang lain, baik antar proses dalam satu komputer maupun proses-proses dalam komputer yang berbeda. Salah satu metode IPC adalah 'pipe'.
     Pipe merupakan komunikasi sekuensial antar proses yang saling terelasi, namun pipe memiliki kelemahan yaitu hanya bisa digunakan untuk komunikasi antar proses yang saling berhubungan, dan komunikasinya yang dilakukan adalah secara sekuensial. Urutan informasi yang ada dalam sebuah pipe ada yang mirip dengan antrian queue. Jika komunikasi yang diinginkan adalah komunikasi dua arah maka kita harus membuat dua pipe, karena sebuah pipe hanya bisa digunakan untuk komunikasi satu arah saja. 

kali ini, saya membunyai tugas baru, yaitu membuat suatu aplikasi yang saling terhubung. Aplikasi tersebut adalah aplikasi penjualan sederhana.
Ketentuan aplikasi tersebut adalah sebagai berikut:
1. Toko tersebut menjual beberapa barang yaitu, ram, vga, motherboard, psu, harddisk, dan prosessor
2. Bila ingin menambah stok/ membeli barang, cukup dengan memilih pilihan di menu lalu menginputkan "apa yang ingin kita beli <spasi> jumlahnya"
3. Setelah terjadi transaksi data harus terupdate.

Jadi begini langkahnya:
Pertama kita deklarasi terlebih dahulu sistem apa yang ingin kita gunakan dengan perintah "#include "



Lalu kita,inisialisasi terlebih dahulu apa yang akan kita buat. Dalam kasus tersebut, nama barang tidak perlu diubah ubah, jadi cukup dibikin sebagai static char saja.



Kemudian kita atur main menu program tersebut


Maka akan tampak seperti berikut



Pada menu pertama, terdapat 2 menu lagi yaitu lihat langsung atau sinkronisasi. Kenapa harus ada sinkronisasi? Karena disitulah pipe digunakan. bagaimana cara penulisannya? Cara penulisannya sebagai berikut




Dalam proses sinkronisasi, terdapat suatu while yang maksudnya adalah untuk menunggu file pipe yang bersifat "sementar" tersebut dibikin dengan cara memilih save change pada terminal lawan.



Kemudian fitur yang satunya lagi digunakan untuk sekedar melihat saja. Dan hanya berubah setelah di sinkronisasi


Lalu, fitur kedua adalah fitur untuk menambah stok (penjual) atau membeli (pembeli)
fungsi tersebut sederhana, yaitu sekedar mengurangi (pembeli) atau menjumlahkan (penjual) dari stok yang tersedia.

Begini kodingannya :


Dan begini tampilannya
inputkan dengan format "nama barang <spasi> jumlah"




fungsi terakhir adalah fungsi save change. Fungsi tersebut adalah fungsi pipe yang dibuat untuk mengirimkan data pipe salah satu terminal yang telah diubah.


mkfifo adalah suatu perintah untuk memerintah untuk membuat pipe dengan format "mkfifo(nama_file, 0666)"
0666 adalah kode yang paling sering digunakan untuk pembuatan pipe yang bersifat sequential

Secara keseluruhan, total program adalah sebagai berikut :

#include <fcntl.h> //File beli Altrenatif
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#define MAX_INP 20
#define INP 6

int main(){
char * tmp_jual = "/tmp/pipe_jual";
char * tmp_beli = "/tmp/pipe_beli";
int i, j, file_jual, file_beli, optMenu, optInput, optSee, found;
int jumlah_barang[INP], tmp_jumlah;
char nama_barang[20][20], tmp_barang[20];

//Inisialisasi
strcpy(nama_barang[0],"ram\t");
strcpy(nama_barang[1],"harddisk");
strcpy(nama_barang[2],"motherboard");
strcpy(nama_barang[3],"psu\t");
strcpy(nama_barang[4],"vga\t");
strcpy(nama_barang[5],"prosessor");
memset(&jumlah_barang, 0, sizeof(int));

system("clear");

memset(&jumlah_barang, 0, sizeof(jumlah_barang));

puts("OINK SHOPPING Pembeli");
puts("Apa yang ingin anda tahu?\n1 Lihat barang\n2 Beli barang\n3 Save change\n4 Exit\n");
printf("Input : ");
scanf("%d", &optMenu);
do{
tmp_jumlah=0;
optSee = 0;
found = 0;
optInput = 4;

if(optMenu==1){ // opsi lihat barang
while(optSee!=3){
system("clear");
puts("1 sinkronisasi\n2 lihat langsung\n\nInput : ");
scanf("%d", &optSee);
if(optSee==1){
puts("Menunggu penjual menyimpan hasilnya");
while((file_jual=open(tmp_jual, O_RDONLY)) == -1) //menunggu si penjual membuat pipe
sleep(1);
file_jual = open(tmp_jual, O_RDONLY); //membuka pipe
read(file_jual, &jumlah_barang, sizeof(jumlah_barang)); //membaca pipe yang berisi array data sekarang dan disimpan dalam array jumlah_barang
close(file_jual);
puts("Sinkronisasi berhasil . . .");
sleep(3);
}

else if(optSee==2){
system("clear");
for(i=0; i<INP; i++)
printf("%d %s \tsejumlah %d\n", i+1, nama_barang[i], jumlah_barang[i]);
printf("Input 3 untuk kembali ke menu awal\n");scanf("%d", &optSee);
}
}
}
else if(optMenu==2){ //beli barang
while(optInput!=0)
{
system("clear");
printf("Masukkan nama barang : ");//format masukan "nama_barang <spasi> jumlah"
scanf("%s", tmp_barang);
scanf("%d", &tmp_jumlah);
if(strcmp(tmp_barang, "ram")==0){
if(jumlah_barang[0]-tmp_jumlah<0){ // kalo dia beli sampe stoknya habis ya printf "maaf stok habis"
puts("Maaf stok terbatas");
}
else
jumlah_barang[0]-=tmp_jumlah; //semumpama masih ada ya sekedar dikurangi
}
else if(strcmp(tmp_barang, "harddisk")==0){
if(jumlah_barang[1]-tmp_jumlah<0){
puts("Maaf stok terbatas");
}
else
jumlah_barang[1]-=tmp_jumlah;
}
else if(strcmp(tmp_barang, "motherboard")==0){
if(jumlah_barang[2]-tmp_jumlah<0){
puts("Maaf stok terbatas");
}
else
jumlah_barang[2]-=tmp_jumlah;
}
else if(strcmp(tmp_barang, "psu")==0){
if(jumlah_barang[3]-tmp_jumlah<0){
puts("Maaf stok terbatas");
}
else
jumlah_barang[3]-=tmp_jumlah;
}
else if(strcmp(tmp_barang, "vga")==0){
if(jumlah_barang[4]-tmp_jumlah<0){
puts("Maaf stok terbatas");
}
else
jumlah_barang[4]-=tmp_jumlah;
}
else if(strcmp(tmp_barang, "prosessor")==0){
if(jumlah_barang[5]-tmp_jumlah<0){
puts("Maaf stok terbatas");
}
else
jumlah_barang[5]-=tmp_jumlah;
}
else //kalau seumpama salah ketik, berarti barangnya tidak ada
{
puts("Barang tidak ada dalam list, tolong cek kembali\n");
}
printf("\nInputkan barang lagi?\n1 untuk iya\n0 untuk tidak\n\nInput : ");
scanf("%d", &optInput);// 1 untuk iya, 0 untuk kembali
}
}
else if(optMenu==3){
mkfifo(tmp_beli, 0666);
file_beli = open(tmp_beli, O_WRONLY); // Membuka file yang sudah dibuat dengan akses write
write(file_beli, jumlah_barang, sizeof(jumlah_barang)); //menulis file dalam pipe
close(file_beli);
}
system("clear");
puts("OINK SHOPPING Pembeli");
puts("Apa yang ingin anda tahu?\n1 Lihat barang\n2 Beli barang\n3 Save change\n4 Exit\n");
printf("Input : ");
scanf("%d", &optMenu);

} while(optMenu!=4);

return 0;
}

Sekian ilmu yang bisa saya bagi kali ini. Semoga bermanfaat bagi kalian.
Thanks for visiting my blog :D