Sabtu, 28 November 2015

Mengenal Kerumitan Komputer dengan 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 descriptor
yang 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.


Nggak ngerti? Singkatnya FUSE adalah suatu source code di mana dengan source code itu kita bisa nge-mount suatu folder ke dalam direktori system (yang seharusnya nggak bisa diutak-atik).  Berikut ini adalah komponen-komponen penting dalam FUSE.


1.  Alamat direktori yang ingin di-mount
***
Tentunya harus ada alamat folder yang akan di-mount. Alamat ini bersifat absolut alias tidak relatif. Source codenya seperti di bawah ini :

static const char *dirpath = "/home/laily/Documents";

2. Fungsi get attribut
***
Fungsi ini bertujuan untuk mendapat info-info penting mengenai direktori, seperti kapan dibuatnya, ukuran, kapan terakhir di-update, dan sejenisnya.
Source codenya seperti di bawah ini :

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

3. Fungsi getdir
***
Fungsi ini bertujuan untuk mendapatkan direktori-direktori yang ada di dalam direktori yang di-mount.
Source codenya seperti di bawah ini :

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

4. Fungsi read
***
Fungsi ini digunakan untuk membaca setiap file yang ada di dalam direktori yang di-mount. Tujuannya adalah untuk meng-copy isi file agar dapat dibuat di dalam direktori mount.
Source codenya seperti di bawah ini :

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;
 
    res = pread(fd, buf, size, offset);
    if(res == -1)
        res = -errno;

    close(fd);
    return res;
}

5. Fungsi makenode
***
Fungsi ini digunakan untuk membuat sebuah node kosong tanpa ekstensi yang nantinya dapat diisi oleh isi-isi yang telah di-copy ketika fungsi read sebelumnya.
Source codenya seperti di bawah ini :

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

6. Fungsi chmod
***
Seperti pada linux biasanya, fungsi ini digunakan untuk mengubah mode file, tentunya ini hal yang sudah umum bahwa mode dapat diubah agar semua user dapat mengakses dengan menggunakan "chmod 777"
Source codenya seperti di bawah ini :

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

7. Fungsi write
***
Fungsi ini menuliskan isi-isi yang sudah di-copy ketika fungsi read dijalankan, ke dalam node-node kosong yang dibuat oleh fungsi makenode.
Source codenya seperti di bawah ini :

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

    if(fd == -1)
        return -errno;
   
    res = pwrite(fd, buf, size, offset);
    rename(fpath,fpath2)
    if(res == -1)
        res = -errno;

    close(fd);
    return res;
}

8. Fungsi open
***
Fungsi ini menentukan apa yang akan terjadi ketika file dalam mount dibuka. Biasanya code di sini sering dimodifikasi agar komputer memberikan respon yang berbeda-beda ketika file dibuka, namun normalnya adalah file berjalan seperti biasa
Source codenya seperti di bawah ini :

static int xmp_open(const char *path, int flags)
{
   
    int res;
    char fpath[1000], ads[1000];
    sprintf(fpath, "%s%s", dirpath, path);
    res = open(fpath, flags);
 
    if(res == -1)
        {
        return -errno;
        }
    close(res);
    return 0;
}

9. Induk fungsi
***
Fungsi ini seperti memberi prototype fungsi apa saja yang akan di pakai ke pada fungsi main.
Source codenya seperti di bawah ini :

static struct fuse_operations xmp_oper =
{
    .getattr = xmp_getattr,
    .getdir = xmp_getdir,
    .mknod = xmp_mknod,
    .chmod = xmp_chmod,
    .open = xmp_open,
    .read = xmp_read,
    .write = xmp_write,
};

10. Fungsi main
***
Tanpa ini semua fungsi di atas tidak akan berjalan. Fungsi main memanggil semua fungsi di atas
Source codenya seperti di bawah ini :

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

Sebenarnya masih banyak fungsi-fungsi lain dalam FUSE yang dapat memodifikasi apa yang terjadi, namun sekian saja kali ini karena sudah terlalu panjang. Semoga bermanfaat!




Jumat, 27 November 2015

Opini Terhadap Rambu Lalu Lintas

Rambu lalu lintas di Indonesia sebenarnya bukan masalah yang vital atau urgent untuk dibahas. Namun, tak ada salahnya kan mengungkapkan opini yang bersifat membangun?

Siapakah yang telah berjasa besar dalam hal pengadaan rambu-rambu lalu lintas ini? Pemerintah kota? Dinas lalu lintas angkutan jalan? Menteri perhubungan? atau biro-biro lainnya? Sebenarnya siapapun itu, yang  ditekankan di sini adalah seberapa banyak yang dialokasikan untuk itu? Berapa besar dana yang digunakan untuk sebuah rambu lalu lintas? Dikalikan dengan jumlah seluruh rambu lalu lintas di Indonesia, berapa banyak yang telah dihabiskan?

Ok, sekali lagi ini bukan masalah urgent. Masih jauh lebih murah daripada biaya-biaya yang lain seperti perbaikan jalan aspal, perawatan lampu jalan, pemeliharaan pohon-pohon kota, dan lain-lain. Tetapi dalam hal rambu lalu lintas ini apabila kita bisa berhemat walaupun sedikit, itu sudah sangat membantu negara?

Ini hanya sekedar opini. Dapatkah proyek pengadaan rambu lalu lintas dilelang (seperti proyek-proyek jalan tol) kepada usaha-usaha yang berada di sekitar rambu tersebut akan dipasang. Pengusaha yang ditawari pun dapat memanfaatkan rambu tersebut sebagai iklan. Misalnya



Tentunya tetap dengan MOU tertentu.

Sehingga pemerintah dapat menghemat biaya alokasi untuk pengadaan rambu lalu-lintas, selain itu juga mendapat dana tambahan dari hasil lelang.




Kamis, 05 November 2015

Your Own Music Player

Sesuai yang telah dijanjikan di post sebelumnya menganai pendahulan thread, post kali ini akan membahas sebuah problem case yang membutuhkan teknik thread dalam penyelesaiannya.

Apabila pada post sebelumnya code bertujuan untuk membuat persegi dan segitiga secara bersama-sama, maka pada post kali ini akan berada pada satu tingkat lebih rumit yakni membuat sebuah music player standard


Oke, nggak akan se-ekstrim itu sampai user interfacenya berbasis desktop. Music player yang akan kita buat menggunakan terminal atau comand prompt.

================================================================
                                 =========PROBLEM CASE===========
================================================================

Music player yang akan dibuat harus mempunyai fitur-fitur berikut :

>>help              (menampilkan fitur)
>>list                (menampilkan file-file musik di dalam folder "playlist")
>>play              (memutar sebuah musik)
>>pause            (mem-pause musik yang sedang dijalankan)
>>continue       (meng-unpause musik yang sedang di-pause)
>>stop              (men-terminate musik player)

================================================================

Dalam kasus ini, yang berbeda dari kasus sebelumnya dan perlu treatment lebih adalah :

- memerlukan input -> fitur music player yang akan ditampilkan membuat user harus memberikan input perintah, tetapi di dalam fungsi thread tidak bisa meminta input, karena itu apabila meminta input dari user harus ada di dalam fungsi main. Selain itu input dibutuhkan juga untuk meminta judul lagu yang akan diputar.

- thread berjalan dipengaruhi suatu kondisi -> ada berbagai macam thread yang dibuat dalam program ini, namun thread yang berjalan haruslah sesuai dengan perintah yang diinputkan oleh user. Menjalankan thread Maka dalam hal ini bisa menggunakan branching if

- menggunakan banyak perintah system -> hal yang tidak dapat kita hindari yakni berinteraksi dengan system, seperti menggunakan system("pkill") untuk mematikan proses,  system("clear") untuk membersihkan layar, system("mpg123") untuk mem-play musik, dan lain-lain.

================================================================

Dengan memperhatikan 3 hal diatas, kita dapat membuat hasil code seperti berikut :

>>thread 1 : help (menampilkan fitur)


>>thread 2 : list (menampilkan daftar musik di folder playlist)


>>thread 3 : play (memutar musik)


>>thread 4 : pause (mem-pause musik)


>>thread 5 : continue (meng-unpause musik)


>>thread 6 : stop (mematikan musik)


>>fungsi main : membuat percabangan untuk memanggil thread


================================================================

Kalau digabungkan menjadi satu :

================================================================

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

pthread_t tid[7];
char lagu[10];
char ads[100];

void* playandcount(void *arg)
{
pthread_t id=pthread_self();
if(pthread_equal(id,tid[1]))
    {
system("clear");
        printf(">>help\n");
printf(">>list\n");
printf(">>play\n");
printf(">>pause\n");
printf(">>continue\n");
printf(">>stop\n");
}
else if(pthread_equal(id,tid[2]))
    {
system("clear");
        chdir ("/home/laily/Documents/MODUL3/soalshift/playlist");
system("ls | grep .mp3");
}
else if(pthread_equal(id,tid[3]))
    {
        system("pkill mpg123");
        system("clear");
        snprintf(ads, sizeof(ads), "mpg123 %s",lagu);
        system(ads);
}
else if(pthread_equal(id, tid[4]))
    {
system("clear");
sleep(3);
system("pkill -STOP mpg123");
}
else if(pthread_equal(id, tid[5]))
    {
system("clear");
sleep(3);
system("pkill -CONT mpg123");
}
else if(pthread_equal(id,tid[6]))
    {
system("clear");
sleep(3);
system("pkill mpg123");
}
return NULL;
}

int main(void)
{
system("clear");
while(1)
{
char comm[10];
int err=0;
scanf("%s",comm);
if (err!=0) printf("\ncan't create thread : [%s]", strerror(err));
else if (strcmp(comm,"help")==0)
            {
                err=pthread_create(&(tid[1]), NULL, &playandcount, NULL);
            }
            else if (strcmp(comm,"list")==0)
            {
                err=pthread_create(&(tid[2]), NULL, &playandcount, NULL);
            }
            else if (strcmp(comm,"play")==0)
            {
                scanf("%s",lagu);
                err=pthread_create(&(tid[3]), NULL, &playandcount, NULL);
            }
            else if (strcmp(comm,"pause")==0)
            {
                err=pthread_create(&(tid[4]), NULL, &playandcount, NULL);
            }
            else if (strcmp(comm,"continue")==0)
            {
                err=pthread_create(&(tid[5]), NULL, &playandcount, NULL);
            }
            else if (strcmp(comm,"stop")==0)
            {
                err=pthread_create(&(tid[6]), NULL, &playandcount, NULL);
            }
            else printf("Wrong Input\n");
}
return 0;
    }


================================================================

Tidak terlalu sulit bukan? Demikian tutorial cara membuat music player standard with thread kali ini, semoga bermanfaat

Thread : Together We Can United We Stand

Thread adalah proses yang dibagi-bagi menjadi kecil-kecil (sering disebut lightweight process) sehingga dapat dijalankan bersama-sama.


Thread-thread yang berjalan bersama-sama disebut multithread. Misalnya pada firefox, terdapat banyak thread untuk melakukan banyak task seperti menampilkan user interface, meminta input user, me-load pencarian, melakukan update, dan lain-lain. 

Together We Can United We Stand
Seperti kalimat diatas, keuntungan dari thread adalah program dapat dijlankan bersama-sama, jadi antara satu process dengan process yang lain tidak perlu saling tunggu.

Sekarang mari kita lihat perbedaan dua source code di bawah ini :

code tanpa thread




Code dengan Thread



Kedua code tersebut bertujuan mencetak bentuk persegi dan segitiga, namun pada source kedua menggunakan thread.
Apabila kedua code tersebut dicompile, akan menghasilkan output yang berbeda


Tanpa Thread






Dengan Thread


Dengan menggunakan thread kita bisa melakukan banyak proses bersama-sama, dalam code diatas thread dapat mencetak persegi dan segitiga bersamaan. Cukup mudah bukan?


Demikian sekilas mengenai thread dan keuntungannya. Untuk post berikutnya adalah suatu test case yang membutuhkan thread dalam pemecahannya.

Semoga bermanfaat