Disclaimer :
Dokumen ini sudah usang dan tidak diperbarui lagi.
|
[ << ]
[ < ]
[ Home ]
[ > ]
[ >> ]
4. Skrip Init
Daftar Isi:
4.a. Runlevel
Boot Sistem
Ketika sistem anda boot, anda akan melihat banyak teks yang beterbangan. Jika
anda memperhatikan dengan benar, anda akan mengetahui bahwa teks ini adalah
teks yang selalu ditampilkan setiap kali sistem anda boot. Urutan dalam semua
proses ini disebut boot sequences dan (lebih kurang) didefenisikan
secara statis.
Pertama-tama, bootloader akan memuat imej kernel yang telah anda tentukan di
konfigurasi bootloader ke dalam memori, setelah itu bootloader memerintahkan
CPU untuk menjalankan kernel. Ketika kernel telah dimuat dan dialankan,
bootloader akan menginisialisasi semua struktur dan tugas-tugas khusus kernel
dan memulai proses init.
Proses ini kemudian akan memastikan bahwa semua filesystem (yang didefenisikan
dalam /etc/fstab) dimuat dan siap digunakan. Kemudian beberapa
skrip yang berada pada /etc/init.d akan dijalankan, yang akan
memulai servis yang anda perlukan untuk menghasilkan suatu sistem yang sukses
di-boot.
Terakhir, setelah semua skrip dijalankan, init mengaktifkan
terminal-terminal (dalam banyak kasus ini berupa konsol virtual yang
tersembunyi di dalam Alt-F1, Alt-F2, dst) dengan melampirkan
proses khusus yang disebut agetty padanya. Proses ini akan memastikan
bahwa anda dapat login melalui terminal-terminal ini dengan menjalankan
login.
Skrip Init
init tidak hanya menjalankan skrip yang ada di dalam
/etc/init.d secara acak. Bahkan tidak menjalankan semua skrip yang
berada di dalam /etc/init.d, melainkan hanya skrip yang telah
diperintahkan untuk dijalankan saja. Skrip yang akan dijalankan ditentukan
dengan melihat isi /etc/runlevels.
Pertama-tama, init menjalankan semua skrip dari /etc/init.d
yang mempunyai symlink di /etc/runlevels/boot. Biasanya, skrip
dijalankan sesuai dengan urutan abjad, tetapi beberapa skrip mempunyai
dependensi di dalamnya, memberitahukan kepada sistem bahwa skrip yang lain
harus dijalankan terlebih dahulu sebelum ia dapat dijalankan.
Ketika semua skrip yang direferensikan oleh /etc/runlevels/boot
telah dijalankan, init melanjutkannya dengan menjalankan skrip yang
memiliki symlink di /etc/runlevels/default. Lagi-lagi, init akan
menggunakan urutan abjad untuk menentukan skrip mana yang akan dijalankan lebih
dulu, kecuali jika suatu skrip mempunyai dependensi di dalamnya yang menyebabkan
perubahan urutan agar skrip-skrip dijalankan dengan urutan yang benar.
Cara Kerja Init
Tentu saja init tidak memutuskan semuanya sendirian. Diperlukan sebuah
file konfigurasi yang menentukan tindakan apa saja yang harus diambil. File
konfigurasi ini adalah /etc/inittab.
Jika anda mengingat urutan boot yang telah kami jelaskan, anda akan mengingat
bahwa tindakan init yang pertama adalah melakukan mount semua filesystem.
Tindakan ini ditentukan pada baris berikut ini dalam /etc/inittab:
Daftar Kode 1.1: Baris inisialisasi sistem pada /etc/inittab |
si::sysinit:/sbin/rc sysinit
|
Baris ini memerintahkan init untuk menjalankan /sbin/rc sysinit
untuk menginisialisasi sistem. Skrip /sbin/rc menangani proses
inisialisasi, jadi anda boleh saja mengatakan bahwa init tidaklah
bekerja banyak -- ia hanya memberikan tugas untuk menginisialisasi sistem
kepada proses lain.
Kedua, init menjalankan semua skrip yang mempunyai symlink di
/etc/runlevels/boot yang ditentukan pada baris berikut ini:
Daftar Kode 1.2: Inisialisasi sistem, lanjutan |
rc::bootwait:/sbin/rc boot
|
Kemudian skrip rc akan melakukan tugas-tugas yang diperlukan. Perlu
dicatat bahwa opsi yang diberikan kepada rc (boot) sama dengan
subdirektori dari /etc/runlevels yang dipergunakan.
Sekarang init akan memeriksa file konfigurasinya untuk melihat
runlevel apa yang perlu dijalankan. Untuk memutuskan hal ini, maka
baris berikut ini dari /etc/inittab akan dibaca:
Daftar Kode 1.3: Baris init default |
id:3:initdefault:
|
Dalam hal ini (dimana mayoritas pengguna Gentoo akan menggunakannya), id
runlevel adalah 3. Dengan menggunakan informasi ini, init akan
memeriksa apa saja yang harus dijalankan untuk memulai runlevel 3:
Daftar Kode 1.4: Defenisi runlevel |
l0:0:wait:/sbin/rc shutdown
l1:S1:wait:/sbin/rc single
l2:2:wait:/sbin/rc nonetwork
l3:3:wait:/sbin/rc default
l4:4:wait:/sbin/rc default
l5:5:wait:/sbin/rc default
l6:6:wait:/sbin/rc reboot
|
Baris yang mendefenisikan level 3, sekali lagi, menggunakan skrip rc
untuk memulai servis (dengan argumen default). Perlu dicatat juga bahwa
argumen rc sama dengan subdirektori di dalam
/etc/runlevels.
Ketika rc selesai dijalankan, init menentukan konsol virtual apa
yang perlu diaktifkan dan perintah apa yang perlu dijalankan pada setiap konsol:
Daftar Kode 1.5: Defenisi konsol virtual |
c1:12345:respawn:/sbin/agetty 38400 tty1 linux
c2:12345:respawn:/sbin/agetty 38400 tty2 linux
c3:12345:respawn:/sbin/agetty 38400 tty3 linux
c4:12345:respawn:/sbin/agetty 38400 tty4 linux
c5:12345:respawn:/sbin/agetty 38400 tty5 linux
c6:12345:respawn:/sbin/agetty 38400 tty6 linux
|
Apakah runlevel itu?
Anda telah mengetahui bahwa init menggunakan skema penomoran untuk
menentukan runlevel apa yang harus diaktifkan. Sebuah runlevel
adalah sebuah kondisi dimana sistem berjalan dan berisi koleksi skrip (skrip
runlevel atau initscripts) yang harus dijalankan ketika anda memasuki
atau meninggalkan suatu runlevel.
Di Gentoo, terdapat tujuh runlevel yang didefenisikan, tiga runlevel internal,
dan empat runlevel yang didefenisikan user. Runlevel internal terdiri dari
sysinit, shutdown dan reboot dan melakukan hal-hal yang
sama dengan nama mereka: inisialisasi sistem, mematikan sistem dan reboot sistem.
Runlevel yang didefenisikan user berada di dalam subdirektori
/etc/runlevels: boot, default,
nonetwork dan single. Runlevel boot
memulai semua servis penting untuk sistem yang akan digunakan oleh
runlevel-runlevel lainnya. Sisa tiga runlevel dibedakan dari servis yang
dimulai: default digunakan untuk penggunaan sehari-hari,
nonetwork digunakan bila koneksi jaringan tidak diperlukan, dan
single digunakan ketika Anda harus memperbaiki sistem.
Bekerja dengan Skrip Init
Skrip yang dimulai oleh proses rc disebut skrip init.
Setiap skrip pada /etc/init.d dapat dieksekusi dengan argumen
start, stop, restart, pause, zap,
status, ineed, iuse, needsme, usesme
atau broken.
Untuk memulai, menghentikan atau memulai kembali suatu servis (dan semua servis
yang bergantung padanya), start, stop dan restart harus
digunakan:
Daftar Kode 1.6: Memulai postfix |
# /etc/init.d/postfix start
|
Catatan:
Hanya servis yang memerlukan servis yang diberikan yang akan dihentikan
atau dimulai ulang. Servis lain yang bergantung padanya (yang menggunakan
servis ini tetapi tidak memerlukannya) tidak akan diutak-atik.
|
Jika anda ingin menghentikan suatu servis, tetapi bukan servis yang bergantung
padanya, anda dapat menggunakan argumen pause:
Daftar Kode 1.7: Menghentikan postfix tetapi membiarkan servis yang bergantung padanya tetap berjalan |
# /etc/init.d/postfix pause
|
Jika Anda ingin melihat status dari suatu servis (started, stopped, paused,
...) Anda dapat menggunakan argumen status:
Daftar Kode 1.8: Informasi status postfix |
# /etc/init.d/postfix status
|
Jika informasi status memberitahukan Anda bahwa suatu servis sedang berjalan,
tetapi Anda tahu bahwa itu tidak berjalan, maka Anda dapat mereset informasi
status ke "stopped" dengan argumen zap:
Daftar Kode 1.9: Reset informasi status postfix |
# /etc/init.d/postfix zap
|
Untuk memeriksa dependensi dari servis tersebut, Anda dapat menggunakan
iuse atau ineed. Dengan ineed anda dapat melihat servis
yang benar-benar diperlukan oleh suatu servis untuk dapat berfungsi dengan
benar. Pada sisi lain, iuse menunjukkan servis yang dapat digunakan oleh
servis itu, tetapi tidak terlalu diperlukan untuk berfungsi dengan benar.
Daftar Kode 1.10: Melihat daftar semua servis yang dibutuhkan oleh postfix |
# /etc/init.d/postfix ineed
|
Demikian juga, anda dapat melihat servis-servis apa saja yang memerlukan servis
tersebut (needsme) atau yang dapat menggunakannya (usesme):
Daftar Kode 1.11: Melihat daftar semua servis yang membutuhkan postfix |
# /etc/init.d/postfix needsme
|
Terakhir, anda dapat melihat dependensi apa yang saja yang diperlukan oleh
servis tersebut tetapi tidak tersedia:
Daftar Kode 1.12: Melihat daftar dependensi yang tidak tersedia untuk postfix |
# /etc/init.d/postfix broken
|
4.b. Bekerja dengan rc-update
Apakah rc-update itu?
Sistem init Gentoo menggunakan suatu pohon dependensi untuk menentukan
servis-servis apa saja yang harus dijalankan terlebih dulu. Karena ini
merupakan tugas yang membosankan, maka kami tidak ingin user kami melakukannya
secara manual. Kami telah membuatkan sebuah utilitas yang memudahkan
administrasi runlevel dan skrip init.
Dengan rc-update anda dapat menambah dan menghapus skrip init dari suatu
runlevel. Utilitas rc-update kemudian akan secara otomatis memerintahkan
skrip depscan.sh untuk membangun ulang pohon dependensi.
Menambah dan Menghapus Servis
Anda telah menambahkan beberapa skrip init pada runlevel "default" ketika
melakukan instalasi Gentoo. Pada saat itu, mungkin anda sama sekali tidak
mempunyai bayangan "default" itu untuk apa, tetapi sekarang anda seharusnya
sudah tahu. Skrip rc-update membutuhkan argumen kedua yang
mendefenisikan aksi: add, del atau show.
Untuk menambah atau menghapus sebuah skrip init, berikan argumen add
atau del kepada rc-update, diikuti dengan skrip init dan
runlevel. Sebagai contoh:
Daftar Kode 2.1: Menghapus postfix dari runlevel default |
# rc-update del postfix default
|
Perintah rc-update -v show akan menunjukkan semua skrip init yang ada
dan daftar runlevel tempat mereka dijalankan:
Daftar Kode 2.2: Menampilkan informasi skrip init |
# rc-update -v show
|
Anda juga bisa menjalankan rc-update show (tanpa opsi -v) jika
anda hanya ingin melihat skrip init yang telah diaktifkan bersama runlevelnya.
4.c. Pengaturan Servis
Mengapa Diperlukan Pengaturan Tambahan?
Skrip init dapat menjadi begitu rumit. Oleh karena itu akan menjadi sangat
tidak menarik bagi user untuk mengedit skrip init secara langsung, karena akan
membuatnya menjadi rentan terhadap kesalahan. Bagaimanapun juga, pengaturan
servis tersebut tetaplah penting. Contohnya, Anda mungkin ingin memberikan
opsi lebih untuk servis itu sendiri.
Alasan kedua untuk memiliki pengaturan ini di luar skrip init adalah agar dapat
melakukan update skrip init tanpa harus khawatir dibatalkannya perubahan pada
pengaturan anda.
Direktori /etc/conf.d
Gentoo memberikan cara mudah untuk mengatur suatu servis: setiap skrip init
yang dapat dikonfigurasi, mempunyai suatu file di dalam
/etc/conf.d. Contohnya, skrip init apache2 (bernama
/etc/init.d/apache2) mempunyai suatu file konfigurasi yang bernama
/etc/conf.d/apache2, yang dapat berisi opsi-opsi yang ingin anda
berikan kepada server Apache 2 ketika memulai servis tersebut:
Daftar Kode 3.1: Variable yang didefenisikan pada /etc/conf.d/apache2 |
APACHE2_OPTS="-D PHP5"
|
File konfigurasi tersebut berisi variabel, dan hanya variabel (seperti
/etc/make.conf), sehingga konfigurasi servis menjadi sangat mudah.
Dan juga, kita dapat memberikan lebih banyak informasi mengenai variabel
(sebagai komentar).
4.d. Menulis Skrip Init
Haruskah saya melakukannya?
Tidak. Menulis skrip init biasanya tidak diperlukan, karena Gentoo telah
menyediakan skrip init siap pakai untuk semua servis yang disediakan. Tetapi,
anda mungkin telah menginstal suatu servis tanpa menggunakan Portage, sehingga
anda harus membuat sendiri skrip initnya.
Jangan gunakan skrip init yang disediakan oleh servis tersebut bila tidak
disebutkan secara jelas bahwa skrip tersebut ditulis untuk Gentoo: skrip init
Gentoo tidak kompatibel dengan skrip init yang digunakan oleh distro lain!
Layout
Layout dasar dari sebuah skrip init ditunjukkan di bawah ini.
Daftar Kode 4.1: Layout dasar skrip init |
#!/sbin/runscript
depend() {
}
start() {
}
stop() {
}
restart() {
}
|
Semua skrip init mengharuskan fungsi start() didefenisikan.
Sedangkan seksi yang lain adalah opsional.
Dependensi
Terdapat dua dependensi yang dapat Anda defenisikan: use dan need.
Seperti yang telah kami sebutkan sebelumnya, dependensi need lebih ketat
daripada dependensi use. Mengikuti tipe dependensi ini, anda memasukkan
servis yang dibutuhkan atau dependensi virtual.
Dependensi virtual adalah suatu dependensi yang diberikan oleh suatu
servis, tetapi tidak melulu cuma bisa diberikan oleh servis itu saja. Skrip
anda dapat bergantung pada logger sistem, tetapi terdapat banyak logger sistem
yang tersedia (metalogd, syslog-ng, sysklogd, ...). Karena anda tidak dapat
menjalankan semuanya (tidak ada sistem yang menginstal dan menjalankan
semua logger sistem ini dalam satu waktu) kami memastikan bahwa semua servis
ini menyediakan sebuah dependensi virtual.
Mari kita lihat informasi dependensi untuk servis postfix.
Daftar Kode 4.2: Informasi dependensi postfix |
depend() {
need net
use logger dns
provide mta
}
|
Seperti yang anda lihat, servis postfix:
-
membutuhkan dependensi net (virtual) (yang disediakan oleh -
misalnya - /etc/init.d/net.eth0)
-
menggunakan dependensi logger (virtual) (yang disediakan oleh -
misalnya - /etc/init.d/syslog-ng)
-
menggunakan dependensi dns (virtual) (yang disediakan oleh -
misalnya - /etc/init.d/named)
-
menyediakan dependensi mta (virtual) (yang umum untuk semua
server mail)
Mengatur urutan
Dalam beberapa kasus, anda mungkin tidak membutuhkan suatu servis, tetapi
menginginkan servis anda dimulai sebelum (atau sesudah) servis
yang lain dijalankan jika tersedia dalam sistem (catatan kondisi - ini
sudah bukan merupakan dependensi) dan berjalan dalam runlevel yang sama
(catatan kondisi - hanya servis yang berada dalam runlevel yang sama yang
terlibat). Anda dapat memberikan informasi ini dengan before atau
after.
Sebagai contoh, kita akan melihat setting dari servis Portmap:
Daftar Kode 4.3: Fungsi depend() pada servis portmap |
depend() {
need net
before inetd
before xinetd
}
|
Anda dapat juga menggunakan glob "*" untuk menangkap semua servis yang berada
pada runlevel yang sama, meskipun hal ini tidak dianjurkan.
Daftar Kode 4.4: Menjalankan skrip init sebagai skrip pertama pada runlevel |
depend() {
before *
}
|
Jika servis anda harus menulis ke disk lokal, servis tersebut harus memerlukan
localmount. Jika servis tersebut menempatkan sesuatu di dalam
/var/run sebagai sebuah pidfile, maka servis tersebut harus
dijalankan setelah bootmisc:
Daftar Kode 4.5: Contoh fungsi depend() |
depend() {
need localmount
after bootmisc
}
|
Fungsi standar
Setelah fungsi depend(), anda juga perlu mendefenisikan fungsi
start(). Fungsi ini berisi semua perintah yang diperlukan untuk
menginisialisasi servis Anda. Dianjurkan untuk menggunakan fungsi ebegin
dan eend untuk menginformasikan kepada user apa saja yang sedang terjadi:
Daftar Kode 4.6: Contoh fungsi start() |
start() {
ebegin "Starting my_service"
start-stop-daemon --start --quiet --exec /path/to/my_service \
--pidfile /path/to/my_pidfile
eend $?
}
|
--exec dan --pidfile harus digunakan pada fungsi start dan stop.
Jika servis tidak menciptakan sebuah pidfile, maka gunakan --make-pidfile
jika memungkinkan, tetapi anda harus mencobanya dahulu untuk memastikan. Jika
tidak, jangan gunakan pidfile. Anda juga dapat menambahkan --quiet pada
opsi start-stop-daemon, tapi hal ini tidak dianjurkan kecuali servis
tersebut sangat verbose. Penggunaan --quiet dapat menghalangi proses
debugging jika servic tersebut gagal dimulai.
Catatan:
Pastikan agar --exec benar-benar memanggil sebuah servis, bukannya skrip
shell yang menjalankan servis kemudian berhenti -- inilah yang seharusnya
dijalankan oleh skrip init.
|
Jika anda memerlukan contoh lebih lanjut terkait fungsi start(),
silakan baca kode sumber dari skrip init yang tersedia di dalam direktori
/etc/init.d.
Fungsi lain yang dapat anda defenisikan adalah: stop() dan
restart(). Anda tidak diharuskan untuk mendefenisikan fungsi-fungsi ini!
Sistem init kita cukup cerdas untuk mengisi fungsi-fungsi ini secara otomatis
jika anda sudah menggunakan start-stop-daemon.
Walaupun anda tidak harus menciptakan fungsi stop(), berikut ini
adalah contohnya:
Daftar Kode 4.7: Contoh fungsi stop() |
stop() {
ebegin "Stopping my_service"
start-stop-daemon --stop --exec /path/to/my_service \
--pidfile /path/to/my_pidfile
eend $?
}
|
Jika servis anda menjalankan skrip lain (mis. bash, python, atau perl), dan
skrip ini nantinya akan mengganti nama-nama (mis. foo.py ke foo),
maka anda perlu menambahkan --name ke start-stop-daemon. Anda
harus menentukan nama yang akan diganti oleh skrip anda. Pada contoh ini,
sebuah servis menjalankan foo.py, yang kemudian berganti nama menjadi
foo:
Daftar Kode 4.8: Servis yang menjalankan skrip foo |
start() {
ebegin "Starting my_script"
start-stop-daemon --start --exec /path/to/my_script \
--pidfile /path/to/my_pidfile --name foo
eend $?
}
|
start-stop-daemon menyediakan manual yang sangat bagus jika anda
memerlukan informasi lebih lanjut:
Daftar Kode 4.9: Membaca manual start-stop-daemon |
# man start-stop-daemon
|
Sintaks skrip init Gentoo berbasis Bourne Again Shell (bash), jadi anda bebas
menggunakan konstruksi yang kompatibel dengan bash di dalam skrip init anda.
Menambahkan opsi kustomisasi
Jika anda ingin skrip init anda mendukung opsi yang lebih advanced
daripada opsi-opsi yang telah kami sediakan, anda harus menambahkan opsi
tersebut pada variabel opts, dan membuat suatu fungsi dengan nama yang
sama dengan opsi tersebut. Contohnya, untuk mendukung sebuah opsi bernama
restartdelay:
Daftar Kode 4.10: Menambahkan dukungan opsi restartdelay |
opts="${opts} restartdelay"
restartdelay() {
stop()
sleep 3
start()
}
|
Variabel konfigurasi servis
Anda tidak perlu melakukan apa-apa untuk menyediakan sebuah file konfigurasi di
dalam /etc/conf.d: jika skrip init anda dijalankan, file-file
berikut ini secara otomatis akan dijadikan sebagai sumber (variabel-variabel
tersedia untuk digunakan):
- /etc/conf.d/<skrip init anda>
- /etc/conf.d/basic
- /etc/rc.conf
Juga, jika skrip init anda menyediakan dependensi virtual (seperti net),
maka file yang diasosiasikan dengan dependensi itu (seperti
/etc/conf.d/net) juga akan dijadikan sebagai sumber.
4.e. Mengubah Tingkah Laku Runlevel
Siapa yang akan diuntungkan?
Banyak pengguna laptop yang mengetahui situasi ini: di rumah anda memerlukan
net.eth0 sementara di perjalanan, anda tidak memerlukannya (karena
tidak ada jaringan yang tersedia). Dengan Gentoo, anda dapat mengubah tingkah
laku runlevel agar sesuai keinginan anda.
Contoh, anda dapat membuat suatu runlevel "default" kedua yang memiliki skrip
init yang berbeda di dalamnya. Kemudian, pada saat boot anda dapat memilih
runlevel default mana yang ingin anda gunakan.
Menggunakan softlevel
Pertama-tama, buatlah direktori runlevel untuk runlevel "default" anda yang
kedua. Sebagai contoh kami akan membuat runlevel offline:
Daftar Kode 5.1: Membuat direktori runlevel |
# mkdir /etc/runlevels/offline
|
Tambahkan skrip init yang diperlukan pada runlevel yang baru dibuat ini.
Contoh, jika anda ingin memiliki duplikat yang sama persis dengan runlevel
default anda sekarang, tetapi tanpa net.eth0:
Daftar Kode 5.2: Menambahkan skrip init yang diperlukan |
# cd /etc/runlevels/default
# for service in *; do rc-update add $service offline; done
# rc-update del net.eth0 offline
# rc-update show offline
acpid | offline
domainname | offline
local | offline
net.eth0 |
|
Walaupun net.eth0 telah dihapus dari runlevel offline, udev masih
akan tetap mencoba menjalankan semua perangkat yang ditemukannya dan
meluncurkan servis yang sesuai. Untuk itu, anda perlu menambahkan setiap servis
jaringan yang tidak anda ingin untuk dijalankan (juga servis untuk setiap
perangkat yang mungkin akan dijalankan oleh udev) ke
/etc/conf.d/rc seperti berikut:
Daftar Kode 5.3: Menonaktifkan peluncuran servis di /etc/conf.d/rc |
RC_COLDPLUG="yes"
RC_PLUG_SERVICES="!net.eth0"
|
Catatan:
Untuk mendapatkan info lanjutan tentang hal ini, bacalah komentar di dalam file
/etc/conf.d/rc.
|
Sekarang edit konfigurasi bootloader Anda dan tambahkan suatu entri baru untuk
runlevel offline. Misalnya, di file /boot/grub/grub.conf:
Daftar Kode 5.4: Menambahkan sebuah entri untuk runlevel offline |
title Gentoo Linux Offline Usage
root (hd0,0)
kernel (hd0,0)/kernel-2.4.25 root=/dev/hda3 softlevel=offline
|
VoilÃ, semuanya sudah siap sekarang. Jika Aada boot sistem dan memilih entri
yang baru ditambahkan pada waktu boot, runlevel offline akan digunakan
sebagai ganti dari default.
Menggunakan bootlevel
Menggunakan bootlevel sangat sejalan dengan softlevel.
Perbedaannya di sini hanyalah anda mendefenisikan runlevel "boot" yang kedua
dan bukan runlevel "default" yang ke dua.
[ << ]
[ < ]
[ Home ]
[ > ]
[ >> ]
Isi dokumen ini dilisensikan dengan lisensi Creative Commons -
Attribution / Share Alike.
|