Oleh Lew Pitcher, LG#105. Bahasa Indonesia oleh Triyan W. Nugroho.

Saya mengikuti sekitar 30 newsgroup usenet, dan pada sebuah kelompok pengguna linux virtual, sejumlah pertanyaan selalu saja muncul. Saya sudah terlalu sering menjawab beberapa pertanyaan tersebut sehingga jawabannya dapat ‘dikalengkan’, yang dapat dimodifikasi berdasarkan bentuk pertanyaannya.

Ini adalah salah satu jawabannya…

Pertanyaan: Adakah seseorang yang bisa memberikan penjelasan yang sederhana mengenai perbedaan soft link dan hard link? Dokumentasi yang telah saya baca menyebutkan link-link tersebut namun tidak menjelaskan artinya dan bagaimana/kapan link tersebut digunakan. Terimakasih!

Jawaban: OK, saya akan mencoba menjelaskan…

File-file Unix terdiri dari dua bagian: bagian data dan bagian nama file.

Bagian data diasosiasikan dengan sesuatu yang dinamakan sebagai ‘inode’. Inode membawa peta yang berisi letak data, file permission, dan sebagainya untuk data tersebut.

                               .---------------> ! data ! ! data ! etc
                              /                  +------+ !------+
        ! permbits, etc ! data addresses !
        +------------inode---------------+

Bagian nama file membawa sebuah nama dan nomor inode yang bersangkutan.

                         .--------------> ! permbits, etc ! addresses !
                        /                 +---------inode-------------+
        ! filename ! inode # !
        +--------------------+

Lebih dari satu nama file dapat memiliki nomor inode yang sama; file-file itu disebut sebagai saling ter-’hard link’.

        ! filename ! inode # !
        +--------------------+

                         >--------------> ! permbits, etc ! addresses !
                        /                 +---------inode-------------+
        ! othername ! inode # !
        +---------------------+

Di sisi lain, terdapat tipe file khusus yang bagian datanya membawa lokasi file lain. Karena file tersebut adalah file khusus, sistem operasi akan mengenali data tersebut sebagai lokasi, dan meneruskan aksi membuka, membaca dan menulis, sehingga aksi tersebut tidak akan mengakses data yang terdapat pada file khusus tersebut, melainkan mengakses data di dalam file yang disebutkan oleh data pada file khusus tersebut. File khusus ini disebut sebagai ‘soft link‘ atau ‘symbolic link‘ (disingkat sebagai ‘symlink‘).

        ! filename ! inode # !
        +--------------------+

                         .-------> ! permbits, etc ! addresses !
                                   +---------inode-------------+
                                                      /
                                                     /
                                                    /
    .----------------------------------------------'
   (
    '-->  !"/path/to/some/other/file"!
          +---------data-------------+
                  /                      }
    .~ ~ ~ ~ ~ ~ ~                       }-- (redirected at open() time)
   (                                     }
    '~~> ! filename ! inode # !
         +--------------------+

                          '------------> ! permbits, etc ! addresses !
                                         +---------inode-------------+
                                                            /
                                                           /
     .----------------------------------------------------'
    (
     '->  ! data !  ! data ! etc.
          +------+  +------+

Sekarang, bagian nama file disimpan pada sebuah file khusus bersama dengan bagian nama file lainnya. File khusus ini disebut sebagai direktori. Direktori, sebagai sebuah file, hanyalah sebuah array yang berisi nama-nama file lainnya.

Ketika sebuah direktori dibangun, sebenarnya direktori tersebut dihasilkan dari bagian nama file dua file khusus: ‘.’ dan ‘..’. Bagian nama file dari file ‘.’ dihasilkan dari nomor inode file direktori dimana entri telah dibuat. ‘.’ adalah sebuah hardlink dari file yang menunjuk pada direktori yang bersangkutan.

Bagian nama file ‘..’ dihasilkan dari nomor inode file direktori yang berisi bagian nama file dari file direktori yang bersangkutan. ‘..’ adalah sebuah hardlink dari file yang menunjuk ke orang tua di atas direktori yang bersangkutan.

Perintah ln digunakan untuk membuat hardlink dan softlink. Sedangkan perintah mkdir digunakan untuk membangun direktori (sistem operasi akan bertanggung jawab mengenai hardlink tersebut).

Terdapat batasan mengenai apa saja yang dapat dibuat hardlink (kedua jenis link tersebut harus berada pada filesystem yang sama, file sumber/aslinya harus ada, dan sebagainya) yang tidak terdapat pada softlink (file sumber dan target bisa berada pada filesystem yang berbeda, file sumber tidak harus ada, dan sebagainya). Di sisi lain, softlink memiliki batasan lain yang tidak dimiliki hardlink (I/O tambahan yang dibutuhkan untuk melengkapi akses file, ruang tambahan yang diambil oleh data file softlink, dan sebagainya).

Dengan kata lain, masing-masing memiliki kelebihan dan kekurangan sendiri-sendiri.

Sekarang, marilah kita mencoba untuk mempraktekkannya…

ln in action

Mari kita mulai dengan sebuah direktori kosong, dan membuat sebuah file di dalamnya.

~/directory $ ls -lia
total 3
  73477 drwxr-xr-x   2 lpitcher users        1024 Mar 11 20:16 .
  91804 drwxr-xr-x  29 lpitcher users        2048 Mar 11 20:16 ..

~/directory $ echo "This is a file" >basic.file

~/directory $ ls -lia
total 4
  73477 drwxr-xr-x   2 lpitcher users        1024 Mar 11 20:17 .
  91804 drwxr-xr-x  29 lpitcher users        2048 Mar 11 20:16 ..
  73478 -rw-r--r--   1 lpitcher users          15 Mar 11 20:17 basic.file

~/directory $ cat basic.file
This is a file

Sekarang, kita buat hardlink dari file tersebut.

~/directory $ ln basic.file hardlink.file

~/directory $ ls -lia
total 5
  73477 drwxr-xr-x   2 lpitcher users        1024 Mar 11 20:20 .
  91804 drwxr-xr-x  29 lpitcher users        2048 Mar 11 20:18 ..
  73478 -rw-r--r--   2 lpitcher users          15 Mar 11 20:17 basic.file
  73478 -rw-r--r--   2 lpitcher users          15 Mar 11 20:17 hardlink.file

~/directory $ cat hardlink.file
This is a file

Kita melihat bahwa:

  1. hardlink.file berbagi inode yang sama (73478) dengan basic.file
  2. hardlink.file berbagi data yang sama dengan basic.file

Jika kita mengubah permission dari basic.file:

~/directory $ chmod a+w basic.file

~/directory $ ls -lia
total 5
  73477 drwxr-xr-x   2 lpitcher users        1024 Mar 11 20:20 .
  91804 drwxr-xr-x  29 lpitcher users        2048 Mar 11 20:18 ..
  73478 -rw-rw-rw-   2 lpitcher users          15 Mar 11 20:17 basic.file
  73478 -rw-rw-rw-   2 lpitcher users          15 Mar 11 20:17 hardlink.file

maka akan terjadi pula perubahan permission pada hardlink.file.

Kedua file tersebut (basic.file dan hardlink.file) berbagi inode dan data yang sama, namun memiliki nama file yang berbeda.

Sekarang kita buat softlink dari file yang asli:

~/directory $ ln -s basic.file softlink.file

~/directory $ ls -lia
total 5
  73477 drwxr-xr-x   2 lpitcher users        1024 Mar 11 20:24 .
  91804 drwxr-xr-x  29 lpitcher users        2048 Mar 11 20:18 ..
  73478 -rw-rw-rw-   2 lpitcher users          15 Mar 11 20:17 basic.file
  73478 -rw-rw-rw-   2 lpitcher users          15 Mar 11 20:17 hardlink.file
  73479 lrwxrwxrwx   1 lpitcher users          10 Mar 11 20:24 softlink.file -> basic.file

~/directory $ cat softlink.file
This is a file

Disini kita melihat bahwa walaupun softlink.file mengakses data yang sama dengan basic.file dan hardlink.file, ia tidak berbagi inode yang sama (73479 vs 73478), serta tidak memiliki permission yang sama. Ia menampilkan bit permission yang baru: bit ‘l’ (softlink).

Jika kita menghapus basic.file:

~/directory $ rm basic.file

~/directory $ ls -lia
total 4
  73477 drwxr-xr-x   2 lpitcher users        1024 Mar 11 20:27 .
  91804 drwxr-xr-x  29 lpitcher users        2048 Mar 11 20:18 ..
  73478 -rw-rw-rw-   1 lpitcher users          15 Mar 11 20:17 hardlink.file
  73479 lrwxrwxrwx   1 lpitcher users          10 Mar 11 20:24 softlink.file -> basic.file

maka kita tidak bisa mengakses data yang di-link melalui softlink tersebut:

~/directory $ cat softlink.file
cat: softlink.file: No such file or directory

Namun, kita masih memiliki akses ke data yang asli melalui hardlink:

~/directory $ cat hardlink.file
This is a file

Ketika kita menghapus file yang asli, hardlink dari file tersebut tidak akan hilang. Demikian juga bila kita menghapus softlink, file yang asli tidak akan hilang.

Lebih jauh mengenai file hardlink

Ketika kita menghapus file, bagian data tidak akan dibuang hingga semua bagian nama file telah dihapus. Terdapat sebuah pencacah pada inode yang menunjukkan berapa banyak nama file yang menunjuk pada file ini, dan pencacah tersebut akan dikurangi 1 tiap kali sebuah nama file dihapus. Ketika pencacah mencapai nilai 0 (nol), inode dan data yang bersangkutan dihapus.

Pencacah tersebut juga menunjukkan berapa kali file tersebut dibuka tanpa ditutup kembali (dengan kata lain, berapa banyak referensi menuju file tersebut yang masih aktif). Hal ini memiliki konsekuensi yang tidak mudah dilihat untuk pertama kalinya: anda dapat menghapus sebuah file sehingga tidak ada bagian “nama file” yang menunjuk ke inode, tanpa mengosongkan ruang untuk bagian data dari file tersebut, karena file tersebut masih dibuka.

Apakah anda pernah menemukan diri anda pada posisi seperti ini: anda melihat bahwa /var/log/message (atau file lain yang dimiliki oleh syslog) berkembang terlalu besar, dan anda melakukan

     rm /var/log/messages
     touch /var/log/messages

Untuk mendapatkan kembali ruang yang digunakan, namun ruang yang telah dikosongkan tersebut tidak muncul? Hal ini karena, walaupun anda telah menghapus bagian nama file, terdapat sebuah proses yang menjadikan bagian data tetap terbuka (syslogd), dan sistem operasi tidak akan mengosongkan ruang yang digunakan oleh data hingga proses menutupnya. Untuk melengkapi perebutan ruang yang anda lakukan, anda harus melakukan

     kill -SIGHUP `cat /var/run/syslogd.pid`

untuk menyuruh syslogd menutup dan membuka kembali file tersebut.

Anda dapat menggunakan ini dalam program yang anda buat: apakah anda tahu bagaimana anda bisa menyembunyikan sebuah file temporary? Anda dapat melakukannya dengan menggunakan ini:

     {
        FILE *fp;

        fp = fopen("some.hidden.file","w");
        unlink("some.hidden.file"); /* deletes the filename part */

        /* some.hidden.file no longer has a filename and is truely hidden */
        fprintf(fp,"This data won't be foundn"); /* access the data part */
        /*etc*/
        fclose(fp); /* finally release the data part */
     }