2008年2月17日

ivman 與 HAL

上篇文章中提到,可能需要去寫 HAL 的程式,不過發現 2 個問題:
1. libhal 是 GNU GPL 授權
2. HAL 實在很有難度阿..... = =

不過不用擔心,我找到解決方案了,那就是 ivman。
下面把我目前對 HAL、ivman、d-bus、udev 間的關聯、理解貼上來,原則上都是 google 來的。

==================================
HAL、D-bus、ivman、udev心得:

一直以來我對udev、HAL、D-bus的角色一直不很瞭解,
一直到最近桌機安裝Ubuntu之後,在前陣子要修改預設的影片播放器,
那時候才稍微知道HAL的功用。

在Windows當中,每當我們插入光碟、隨身碟時,系統就會自動開啟檔案總管,
如果是DVD影片,則會自動開啟播放程式,當然了~預設就是Windows Media Player。
正因為這樣的設計,讓M$立於不敗之地,畢竟習慣是很可怕的,
當預設的播放環境習慣之後,要選擇其他的播放環境,那麼就要有十足的說服力來說明新的播放環境比較好。

在Linux上,我一直認為沒有很好的自動判斷機制,雖然Unix一直是device file的機制,這也許是原因之一,
也許Unix一直以來都有許多的歷史包袱,但沒有就是沒有,不方便就是不方便~

Linux並不是不希望改善,所以有automount這樣的機制,現在也是內建措施之一,
但是automount實在是不怎麼樣,它很單純的設計成:
當執行 "cd /media/nfs" 時,自動 mount 這個目錄。
當超過一定時間時,自動 unmount 這個目錄。

這樣的設計顯然不怎麼聰明,但它的確是 Linux/FreeBSD 上常見的設計。

現在 Linux 的 GNOME 很聰明了,它已經能夠做到 Windows 這樣的能力,透過的是甚麼?
透過的是 HAL 的技術。

在 Linux 上,HAL 全名是 Hardware Abstraction Layer,
雖然 Windows 上也有相同的名稱,但就 google 的說法,是不同的東西。

HAL 的設計其實頗複雜,我們可以從
http://people.redhat.com/davidz/hal-spec/hal-spec.html

裡面的圖


看出來。

這張圖相對來說,是比較清楚的,不然找到的經常是UML,那種就不是很容易看懂了..... = =||

從下列網頁中可以找到比較詳細些的關係說明:
http://Linux.chinaitlab.com/driver/40018.html

要實現 Linux 上的 automount,Linux 設計了一套架構,如下:
=================================================
hotplug 是內核的一部分,在設備插入或拔出時,自動進行配置內核狀態。udev 是 hotplug 的一部分,負責維護動態的 /dev 目錄,使 /dev 目錄的內容與當前系統狀態一致。D-BUS 可以在應用程序之間傳送消息,例如可以把「連接上一台打印機」的消息發送給 HAL。HAL 可以集成多種來源的信息,包括內核消息,配置文件等等,然後根據 D-BUS 的消息進行操 作。gamin 是改進的文件狀態監視程序。
例如插入優盤。hotplug 自動加載需要的模塊,udev 創建相應的 /dev/sda1 等等節點,hotplug 向 HAL 發消息,HAL 收到消息後,根據配置文件,它運行 fstab-sync 來修改 fstab,創建 /media 的子目錄作為掛載點。gamin 檢測到 fstab 發生變化之後,通知桌面系統。桌面系統在 「計算機」 項目中建立驅動器圖標。
在拔出優盤時,與上面的過程類似,模塊被卸載,設備文件被刪除,fstab 中相應條目被刪除,/media 目錄下的掛載點也被刪除了。

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

上述這段是直接轉貼的,簡單的說:
1. Linux 2.6 kernel 包含 hotplug,來判斷硬體的插入、移除。

2. Linux OS 透過 udev 來搭配 hotplug,專門維護 /dev 下的 device file,
這也就是我之前在摩托學園發的問題的所在點,它會動態的建立出各種裝置的 device file。

3. Linux OS 透過 D-BUS 來轉發系統訊息,告知 HAL 硬體的插入、拔出動作。

4. HAL 則呼叫相對應的應用程式來執行相對應的操作。


整個 auto mount 或 auto umount 就是上述的流程,實際上 HAL 還是一組 library,
除非應用程式以 HAL 的 library 來開發,否則應用程式通常無法直接收到 HAL 的消息,
簡單的說,HAL 還太低階,雖然他能夠直接操作特定的系統消息(像 DVD影片 插入時),
但彈性不足(設定煩雜,不容易設定、修改),因此通常還需要一個 manager 來進行真正的 HAL 操作。
這在 GNOME 就是 Gnome Volume Manager。

將整個堆疊以文字分層來表示,大致如下:

GNOME Volume Manager
HAL(Hardware Abstraction Layer)
D-Bus
udev

kernel hotplug

上述這些部分,除了 kernel hotplug 之外,全部都是以 daemon 的型式,一直常駐在系統中,
所以每個程式都需要持續的執行。

因為整個架構的複雜,就某方面來說,幾乎獨佔了整個 Linux 的 automount 設計,
每個部分的可以用的程式選擇都很少。

目前的情況是,以 HAL 以上,整個架構相容性最好的是 GNOME,
其他 桌面系統(包括 KDE),似乎都沒有很好的相容性。
icewm 相關的設計更是嚴重缺乏。

所以目前可以知道的是,儘管所有 Linux(Debian、Ubuntu、Fedora) 幾乎都直接使用 udev、d-bus 甚至 HAL,
幾乎每個 Linux 上都可以看到 hald、udev 在執行中,大部分人卻不知道也不敢動這幾個東西,
有點冒險精神的人,會嘗試把它關掉,結果可能會從 try & error 中發現,這會導致系統完全無法開機..... :p
偏偏這整套東西,沒有 GNOME 時,通常沒有 Volume Manager,
然後就是大部分 Linux User 覺得它一直在跑也不知道在幹嘛,扒著資源不放。
另一部分來說,非 GNOME 的 桌面系統,要使用 HAL,經常不知道怎麼使用,
這造成了有 Linux 發行套件,使用 KDE 作為 桌面系統,卻使用 GNOME Volume Manager 這種不協調的情況。

幸好我們還有 ivman,ivman 全名 Ikke's Volume Manager
它的身份基本上等於 GNOME Volume Manager,它可以接收各種 HAL 發出的訊息,
最棒的是,ivman 不是 桌面系統 的一部份,也不是 GUI程式,
它的設定都是以 xml設定檔 方式定義,執行的程式完全由我們自己定義,
這表示它應該有不錯的彈性,儘管看起來,
它的相容性似乎不很好,而且當選擇太多時,我們反而會不知道該怎麼選擇。

ivman 要安裝,我覺得 man ivman 是最好的主意,網路上找的資料,幾乎沒辦法協助我排除安裝的問題,
後來看了 man ivman 之後,問題就解決了~

1. 在 Debian 上,ivman 直接是套件,安裝即可

2. ivman 要正常動作,要確定 udev、d-bus、hald 這幾個 daemon 都正常運作中,
這部分我相信只要沒漏裝,都是 ok 的
要測試,在 Debian 上我認為執行
/etc/init.d/dbus restart

似乎不錯,當執行 dbus(也就是 D-bus daemon) 的重新起動時,它會一併重新起動 hald(HAL Daemon)、ivman,
整個內容如下:
media [/root] -root- /etc/init.d/dbus restart
Stopping Hardware abstraction layer: hald.
Stopping Avahi mDNS/DNS-SD Daemon: avahi-daemon.
Stopping ivman: ivman.
Stopping System Tools Backends: system-tools-backends.
Stopping system message bus: dbus.
Starting system message bus: dbus.
Starting System Tools Backends: system-tools-backends.
Starting ivman: manager.c:1387 (do_startup_configure) Directory /etc/ivman/ will be used for configuration files.
ivman.
Starting Avahi mDNS/DNS-SD Daemon: avahi-daemon.
Starting Hardware abstraction layer: hald.


udev 的部分,我相信如果有問題,可能連開機都會有問題的,除非你的 Linux 不是使用 udev。

3. 執行 ivman
這部分需要『特別注意』,我之前就是這地方沒弄好,一直一直沒弄成功。
在 man ivman 中有下面這段話:
For automount purposes, Ivman should be run once from a system-wide init script and once per user session (e.g., create a link to /usr/bin/ivman in ~/.kde/Autostart or put an entry for /usr/bin/ivman in gnome-session-manager).

這句話是關鍵,它說,如果你要正常使用 ivman,你必須要執行『2 次』ivman,一次執行在 OS 開機時,
以 Debian 來說,就是
/etc/init.d/ivman

指令執行的。

另一次則要在使用者進入 桌面系統 時執行。

以我來說,我把它加入
~/.xsession

中,類似如下:
.....
icewm-session-lite &
/usr/bin/ivman &
.....



至於其他部分,就是 lirc、mythfrontend、scim,所以我就沒列出來了。

而從前面說明中,它則建議加入到 KDE 的 Autorun 或 GNOME 的 session-manager,這都是起動 X-win 時自動執行的方式,
我加入到 .xsession,實在是因為我基本上是沒用 桌面系統 的,硬要說,也就是 icewm-lite,
主要是因為我整個系統只執行 mythtv,加了大型的 桌面系統 沒有意義。

4. 設定 ivman
ivman 的設定和上面一樣,也是『2 份』,一份放 /etc/ivman/,另一份則是 ~/.ivman/ 下。
原則上,/etc/ivman/ 下的設定檔不需要動,所有使用者都只要設定 ~/.ivman/ 下的設定檔即可,
這點讓 ivman 可以根據不同的使用者,定義不同的 automount 設定,相當不錯。

當使用者執行過 ivman 後,~/.ivman/ 下的設定檔就會自動產生,基本上和系統的相同,
都是 4 個檔案,分別是:
IvmConfigActions.xml
IvmConfigConditions.xml
IvmConfigBase.xml
IvmConfigProperties.xml


其中比較重要的是『IvmConfigActions.xml',這檔案負責所有訊息的動作,
目前的進度是,我將 IvmConfigActions.xml 中的 autoplay video DVD 部分註解去除,如下:
.....
<!-- autoplay video DVDs in Xine (change PLAYER and PLAYEROPT to use a different media player -->
<ivm:Match name="hal.volume.disc.is_videodvd" value="true">
<ivm:Option name="exec" value="PLAYER='xine'; PLAYEROPT='-f dvd://'; pumount '$hal.volume.mount_point$' && ${PLAYER} ${PLAYEROPT}$hal.block.device$" />
</ivm:Match>
.....


在 DVD影片光碟 插入時,已經能夠正常使用 xine 播放。
目前正在設定當 檔案光碟 插入時的動作,目前預設是只會 automount。

附帶一點:
在設定中可以注意到,『volume.disc.is_videodvd'這個參數,這個參數是 HAL 的參數,
也就是說 ivman 會監視 HAL(或說 HAL 會發出通知),當參數改變時,ivman 就會有相對應的動作。
關鍵點,要如何知道 HAL 的參數呢?
可以執行:
> lshal
==================================

2 則留言:

匿名 提到...

真是好文章
把整個機制寫得好清楚喔

另外我是使用freebsd搭配xfce
xfce有他的thunar-volman來管理自動掛載
但thunar-volman依賴gudev(gudev又依賴udev)
所以在freebsd沒辦法實現
我現在的solution是用volman
他讀取devd的信息
來自動掛載

請問有其他更好的方案嗎??

匿名 提到...

如果有更好的建議可以寄信到cp123cp123@kimo.com嗎
謝謝你