Debian 6 如何增加系統啟動程式與指定順序
以往在 Debian 5 或 Ubuntu 10.04 中,我們使用下列指令所示範的內容,新增系統啟動程式:
# update-rc.d hello defaults NN
其中的 NN 可以指定啟動順序,例如 90 。
但是在 Debian 6 使用此指令時,我們將發現 NN 不作用了。這是因為 Debian 6 現在參考 LSB (Linux Standard Base) 制定的「System Initialization」規範,以啟動指令稿內的 INIT 敘述區塊決定啟動順序,不再理會參數指定的數字。同時,Debian 6 也改用 insserv 指令取代 update-rc.d 。
LSB 所制定的啟動方式,與 Ubuntu 一度引進的 uevent 機制同樣採用啟動事件決定程式項目的相依關係,進而安排啟動順序。參考「Dependency based boot sequence」了解詳情。
一份符合 LSB 規範的最精簡啟動指令稿(init script)之範例如下:
#!/bin/sh ### BEGIN INIT INFO # Provides: scriptname # Required-Start: $all # Required-Stop: # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start daemon at boot time # Description: Enable service provided by daemon. ### END INIT INFO
其中由 ### BEGIN INIT INFO
和 ### END INIT INFO
這兩行所夾起的內容,皆為啟動行為之指示。其意義請參考「How to LSBize an Init Script」。
- Provides 欄位必須指定一個可識別的名稱,一般同啟動指令稿的檔名。
此欄位所指識別名稱,可作為其他程式排定相依關係之依據。 - Required-Start 欄位指示此程式之前應先啟動哪個項目。換句話說就是排在哪個程式後面啟動。
$all 是一個虛設項目,表示所有程式項目。在 Required-Start 使用,將令此程式排在最後啟動。 - Required-Stop 欄位指示此程式應在哪個項目之前停止。換句話說就是排在哪個程式前面停止。
此欄位可以留白。 - Default-Start 欄位指示在哪些 run level 下要啟動此程式。一般都填 '2 3 4 5' 。
- Default-Stop 欄位指示在哪些 run level 下要停止此程式。一般都填 '0 1 6' 。
假設現在有 A, B 兩程式要加入系統啟動程式項目中,且 B 要排在 A 之後才能啟動。那麼 A, B 兩程式的啟動指令稿將如下所示:
/etc/init.d/test-a:
指定程式識別名稱為 test-a 。
#!/bin/sh # This is for program A. ### BEGIN INIT INFO # Provides: test-a # Required-Start: $syslog # Required-Stop: # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start daemon at boot time ### END INIT INFO
/etc/init.d/test-b:
因為 A 程式的啟動識別名稱為 test-a ,故此處的 Required-Start 欄位內容應填 test-a ,指示此項目要排在 test-a 之後。
#!/bin/sh # This is for program B. ### BEGIN INIT INFO # Provides: test-b # Required-Start: test-a # Required-Stop: # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start daemon at boot time ### END INIT INFO
接著分別執行 insserv test-a 與 insserv test-b ,啟用這兩個項目。insserv -r test-a 則會移除啟動項目。
我們可以查看 /etc/rc2.d 目錄,檢查是否建立了相關的符號連結。按照我們前述所指示的啟動相依性,通常 test-a 的符號連結會是 S18test-a ,而 test-b 的符號連結會是 S19test-b 。
目前有 8 個虛設項目: (皆以 $ 開頭)
- $local_fs
本地檔案系統被掛載。所有用到 /var 目錄的啟動項目,都要相依此項目。 - $network
網路介面被啟用。 - $named
名稱伺服功能被啟用。 - $portmap
- $remote_fs
所有檔案系統被掛載。包含 /usr 目錄節點。 - $syslog
系統記錄功能被啟用。 - $time
系統時間被設定。 - $all
所有項目後。
一般的 daemon 項目應相依 $remote_fs 與 $syslog 。而與核心模組(驅動程式)有關的項目,則相依 $local_fs 。
postinst 與 prerm
打包 debian 文件時,其中的 postinst 與 prerm 可以參考下列範例安插 insserv 的動作: