4.b. 使用 rc-update
什麼是 rc-update?
Gentoo 的 init 系統使用的是相依性列表來決定那個服務需要先啟用。這是一個複雜的工作,所以我們不會讓我們的使用者手動完成這項工作。所以我們建立了相關的執行階段工具和 init 工具方便管理。
使用 rc-update,您可以從執行階段新增或是移除 init 程序。rc-update 的工具將自動讓 depscan.sh 程序重新建立相依性資料。
新增或是移除服務
您已經在安裝 Gentoo 時將 init 程序加入過 "default" 的執行階段了。當時您應該對 "default" 沒有任何了解,但是您現在應該知道了它的意義。rc-update 程序需要第二個參數來告訴它要執行的動作:add,del 或是 show。
要增加或是移除一個 init 程序,只需要在 rc-update 後面放入 add 或是 del 的參數,然後接著就是要加入的 init 程序的名字。舉例來說:
原始碼 13: 執行階段移除 Postfix |
# rc-update del postfix default
|
rc-update show 的指令將會0按照執行順序顯示出所有可能的 init 程序清單:
原始碼 14: 顯示 init 程序資料 |
# rc-update show
|
4.c. 設定服務
為什麼需要多餘的設定?
Init 程序可以是很複雜的。所以直接編輯 init 程序會讓使用者感到困難。但是要可以正確的設定這些服務是極為重要的。舉例來說,您或許會想在啟動服務時加入某個參數。
第二個原因是為了要讓 init 程序可以更新原始設定檔以外的設定,而不會直接改到重要的設定檔。
/etc/conf.d 目錄
Gentoo 提供一個簡單的方法設定相關服務:每個 init 程序都有一個可以設定的設定檔放在 /etc/conf.d舉例來說, apache2 的 init 程序(叫做 /etc/init.d/apache2)的設定檔會放在 /etc/conf.d/apache2,這樣可以在啟動 Apache 2 伺服器時加數您需要的參數:
原始碼 15: /etc/conf.d/apache2 的變數定義 |
APACHE2_OPTS="-D PHP4" |
這種設定檔包含的變數(就和 /etc/make.conf 類似),是為了要讓服務的設定更加簡易。它也以註解的方式提供著一些相關的資料和變數用法。
4.d. 編寫 Init 程序
我需要嗎?
不。Gentoo 提供了這些 init 程序,所以您不需要自己編寫一個。但是,如果您安裝了非 Portage 提供的服務,那麼您就需要編寫一個類似 init 的程序。
如果不是針對 Gentoo 所設計的程序,請不要使用:Gentoo 的 init 程序和其他版本的 init 程序不相容!
規劃
以下為一個 init 程序的規劃。
原始碼 16: Basic layout of an init script |
#!/sbin/runscript
depend() {
(相依性資訊)
}
start() {
(啟動服務的相關指令)
}
stop() {
(停止服務的相關指令)
}
restart() {
(重新啟動服務的相關指令)
}
|
任何 init 程序 都需要 start() 功能的定義。其他的則是非必需。
相依性
您總共有兩種相依性可以定義:use 和 need。就如我們之前提到的, need 的相依性比 use 來的嚴厲。然後使用 virtual 來選擇所依賴的相依性。
virtual 是一個提供服務的相依性,但是並不是完全由這個服務提供。您的 init 程序可以依賴著系統記錄器,但是我們提供著許多系統記錄器(metalogd,syslog-ng, sysklogd,﹍)當您無法 need 所有的(執行全部的系統記錄器並不合理)我們將確定這些服務可以 提供 一個虛擬相依性。
現在讓我們來看看一個 postfix 服務所依賴的相依性。
原始碼 17: Postfix 的相依性 |
depend() {
need net
use logger dns
provide mta
}
|
如擬可見,postfix:
- 需要所有的(虛擬)net 相依性 (是由 /etc/init.d/net.eth0 所提供)
- 需要使用(虛擬) logger 相依性(是由 /etc/init.d/syslog-ng 提供)
- 需要使用(虛擬) dns 相依性(事由 /etc/init.d/named 提供)
- 提供(虛擬) mta 相依性(常用的郵件伺服器所需)
控制順序
在某些情況下您不需要一個服務,如果在系統可以提供的環境下(沒有相依的問題),但是您想要在這個服務之前 befre(開始) (或是 after(之後) 使用另外一個服務 然後 放到同一個執行階段(只有同執行階段的服務)。您可以使用 before 或是 after 設定來完成這些設定。
我們將查看 Portmap 的設定為範例:
原始碼 18: Portmap 服務的 depend() 功能 |
depend() {
need net
before inetd
before xinetd
}
|
您也可以使用 "*" 來選擇同一個執行階段內所有的服務,但是我們並不建議。
原始碼 19: 設定成為第一個同執行階段的 init 程序 |
depend() {
before *
}
|
符合標準的功能
depend() 之後,您將需要定義 start() 的功能。這個將包含著所有相關啟動服務的指令。我們建議您使用 ebegin 和 eend 功能來通知使用者正在發生什麼事:
原始碼 20: start() 功能範例 |
start() {
ebegin "Starting my_service"
start-stop-daemon --start --quiet --exec /path/to/my_service
eend $?
}
|
如果您需要更多的 start() 功能的範例,請查看您系統中放在 /etc/init.d 目錄裡面的 init 程序。關於 start-stop-daemon,我們有提供著一個很棒的說明頁讓您查閱:
原始碼 21: 查詢更多關於start-stop-daemon 的說明頁 |
# man start-stop-daemon
|
其他您可以定義的功能為:stop() 和 restart()。您不一定要定義這些功能!如果您使用 start-stop-daemon,我們 init 系統將會自動填入這些功能。
Gentoo 的 init script 語法是以 Bourne Again Shell (bash) 為基礎,所以你可以在你的 init script 中自由使用和 bash 相容的架構。
加入自訂選項
如果您想要讓您的 init 程序支援更多我們已經提供的選項,您應該將這些選項加入到 opts 變數,然後建立一個功能將此功能的命名為 opt 變數內所定義的。舉例來說,要提供一個 restartdely 的功能:
原始碼 22: 提供 restartdely 選項 |
opts="${opts} restartdelay"
restartdelay() {
stop
sleep 3 # 等待三秒才開始
start
}
|