Unionfs: 聯合文件系統的一個實例SLAX

Unionfs是一個堆棧式的聯合文件系統, 2004年由紐約州立大學石溪分校開發, 它可以把多個目錄(也叫分支)內容合併在一起, 而目錄的物理位置是分開的. Unionfs允許只讀和可讀寫目錄並存, 就是說可同時刪除和增加內容. Unionfs應用的地方很多, 比如在多個磁盤分區上合併不同文件系統的主目錄, 或把幾張CD光盤合併成一個統一的光盤目錄(歸檔). 另外, 具有寫時複製(copy-on-write)功能Unionfs可以把只讀和可讀寫文件系統合併在一起, 虛擬上允許只讀文件系統的修改可以保存到可寫文件系統當中.

SLAX是一個192MB大小的Linux發行版, 目標是爲便攜設備(如usb閃存或mini-cd)開發一個完整功能的Linux操作系統, 人們可以通過引導光盤(或其它編寫媒介)直接使用SLAX Linux. 甚至能在沒有硬盤的計算機上運行. Unionfs是SLAX系統的一個重要組成部分, 它使SLAX可做爲一個真正的Linux系統(具有可寫入的根目錄樹)來運行. 首先我們來了解unionfs.

瞭解unionfs

如果要運行unionfs, 你需要編譯內核源代碼來創建一個Linux內核模塊. Unionfs支持Linux內核2.4.20/2.6.9及更高的版本. 首先用ftp下載最新的unionfs版本, 然後解壓:

$ tar -xzf unionfs-x-y-z.tar.gz

接着cd到解壓縮後的unionfs目錄, 閱讀README和INSTALL文件. 爲了避免不必要的問題. 編譯之前, 建議考慮關閉編譯調試信息, 這隻對查找漏洞有用, 而且會顯著增加內核模塊的大小. 關閉調試信息的方法(更改兩個參數):

在源碼目錄創建一個fistdev.mk文件.
添加下面文本信息:
EXTRACFLAGS=-DUNIONFS_NDEBUG
UNIONFS_DEBUG_CFLAG=

編譯後, 不帶調試信息的內核模塊大概在90KB左右, 而沒有關閉的內核模塊爲5MB(下載用於編譯unionfs模塊的 fistdev.mk)

另外一個很重要的事項, 爲確保編譯工作無誤, 在下載和解壓unionfs源碼後你需要修改unionfs的Makefile文件的LINUXSRC變量(參考當前內核), 添加你解開後的unionfs目錄路徑.(一些情況可自動檢測到).

最後, 使用下面命令編譯和安裝unionfs模塊到/lib/modules/$(KernelVersion)/kernel/fs/unionfs目錄:

$ make
$ make install
$ depmod -a

使用unionfs

下面例子, 我們合併兩個目錄的內容到一個目錄/mnt/union. 假設所有的目錄已經存在.
$ modprobe unionfs
$ mount -t unionfs -o dirs=/mnt/cdrom1=ro:/mnt/cdrom2=ro unionfs /mnt/union

現在, 目錄/mnt/union包含來自/mnt/cdrom1和/mnt/cdrom2的所有文件和目錄, 這些文件目錄只讀. 如果cdrom1和cdrom2目錄有同樣的文件名, cdrom1有更高的優先權(因爲mount命令行cdrom1在cdrom2的左面, 以此來確定優先級).

使用unionctl

Unionfs編譯過程中創建了Unionctl(同時也創建了uniondbg)工具, 它被安裝到/usr/local/sbin目錄. Unionctl主要用於管理聯合目錄, 比如顯示, 增加, 修改或刪除分支目錄. 下面是一些簡單的例子, 我們可以使用不帶任何參數的unionctl命令來查看其它選項.

列出聯合目錄中存在的分支:

$ unionctl /mnt/union --list

輸出:

/mnt/cdrom1 (r-)
/mnt/cdrom2 (r-)

增加另一個目錄到當前的聯合目錄:

$ unionctl /mnt/union --add --after /mnt/cdrom2 --mode ro /mnt/cdrom3

然後用unionctl --list顯示:

/mnt/cdrom1 (r-)
/mnt/cdrom2 (r-)
/mnt/cdrom3 (r-)

當你更改了分支目錄, 需強行運行下面命令重新驗證聯合目錄:

uniondbg -g /mnt/union

寫入聯合目錄

在很多情況下, 合併只讀目錄十分有用. 在一個可讀寫的分支目錄添進來之前, 聯合目錄自身仍然只讀. 這種情況, 所有的修改處於最左邊的分支目錄(使用向上拷貝copy-up方法, 見下面), 我們可以使用下面其中的一個方法來刪除文件:

WHITEOUT模式, 插入文件.wh(whiteout)到一個實際的文件
DELETE_ALL模式, 從所有分支目錄刪除一個文件的所有實例.

缺省使用是WHITEOUT模式. Copy-up(向上拷貝)是一個在聯合目錄中用於處理文件修改的特殊方法. 來自ro分支目錄的文件不能被修改, 所以需要修改的文件將被拷貝到左上的可讀寫分支目錄. 然後文件被修改的文件位於rw分支目錄.

在聯合目錄上端增加一個rw分支目錄:

$ unionctl /mnt/union --add --before /mnt/cdrom1 --mode rw /mnt/changes

所有的修改將位於/mnt/changes, 聯合目錄如下顯示:

/mnt/changes (rw)
/mnt/cdrom1 (r-)
/mnt/cdrom2 (r-)
/mnt/cdrom3 (r-)

SLAX - Unionfs的實際應用

只讀媒介中的數據比如CD-ROM是不能被修改的. SLAX, 一個基於CD的Linux發行版, 支持所有目錄的數據寫入, 這需要使用特別技術來虛擬修改和保存所有數據更改到內存當中. SLAX很早就使用了這些特別的技術, 2003年底整合了ovlfs, 2004年底加入了unionfs. 2005年4月SLAX 5 推出.

SLAX的原理

你需要下面三類資源來引導內核:
1) 內核鏡像(操作系統本身, 通常是一個爲vmlinuz的文件)
2) 分區或鏡像文件(比如. initrd.gz), 包含了root文件系統和初試化程序(linurc)
3) 一些Linux加載程序(把內核讀到內存並從開始處執行)

光盤使用isoliux.bin加載程序來引導SLAX系統, 它包含了光盤文件系統的驅動程序, 這樣可以把光盤上的Linux內核(文件 vmlinuz)和root文件系統鏡像(文件 initrd.gz)讀到內存當中.

當這些文件被加載到內存, 然後執行, Linux內核在計算機的內存中創建了一個虛擬盤(叫初始ramdisk), 接着initrd.gz釋放到虛擬盤, 然後虛擬盤被加載(mount)爲root文件系統. 這裏用於SLAX的初始化ramdisk只有4.4M, 包含了一些用於處理SLAX啓動的常用軟件和驅動程序. 下面部分非常重要, 請仔細閱讀:

然後由Linux內核來執行/linuxrc文件(位於ramdisk中, 做爲初試化程序). Linuxrc的工作非常重要. 它在/union目錄創建了一個空的聯合目錄, 接着加載tmpfs到/memory目錄, 接着創建/memory/changes/(新目錄位於tmpfs, 不在ramdisk中). 接着Union被加載到/union和/memory/changes目錄, 這些新添加的目錄被做爲rw分支目錄.

然後linuxrc載入所有光盤和磁盤來搜索livecd.sgn文件. 你可能感到驚訝, 但是光盤已被載入到/union/mnt/目錄. SLAX光盤上所有需要的鏡像(*.mo)也被載入到了/memory/images/*.mo目錄, 通過使用unionctl工具, 新添加的聯合目錄將被做爲一個獨立的只讀分支目錄在第一個分支目錄後(rw 更改). 目錄結構如下:

CODE:
/(initrd, 4MB)
     |
     |---- /memory(tmpfs, 80% of RAM)
     |        |-- images
     |        |     |-- base.mo   <--loop--+
     |        |     |      |-- bin         |
     |        |     |      |-- usr         |
     |        |     |      +-- var         |
     |        |     |                      |
     |        |     |-- xwindow.mo <-loop------+   
     |        |     |      |-- etc         |   |
     |        |     |      |-- usr         |   |
     |        |     |      +-- var         |   |
     |        |     |                      |   |
     |        |     +-- kde.mo     <-loop----------+
     |        |            |-- opt         |   |   |
     |        |            |-- usr         |   |   |
     |        |            +-- var         |   |   |
     |        |                            |   |   |
     |        +-- changes                  |   |   |
     |                                     |   |   |
     +---- /union                          |   |   |
              |---- /mnt/cdrom             |   |   |
              |          |--- base.mo -----+   |   |
              |          |--- xwindow.mo ------+   |
              |          +--- kde.mo --------------+
              +---- /mnt/live

當所有模塊被添加到聯合目錄, 一個rw分支目錄在聯合目錄的上端, pivot_root然後被執行. 這是一個不錯的方法, 最初的root被移到/mnt/live和/union目錄, 成爲了一個新的root. 當運行SLAX時候, 你可以通過查看ramdisk上的原始內容來深入瞭解/mnt/live.

最後linurc執行/sbin/init, /sbin/init啓動系統所有服務和顯示登陸信息.

鏈接:
紐約州立大學石溪分校: http://www.fsl.cs.sunysb.edu/
UnionFS: http://www.fsl.cs.sunysb.edu/project-unionfs.html
SLAX: http://www.slax.org
Linux Live 腳本: http://www.linux-live.org
Linux 內核: http://www.kernel.org

參考:
Unionfs: An Unification File System examples

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章