Linux 下的特殊檔案系統


掛載案系統

ext4.ko 的功用: 將線性的陣列翻譯成層層目錄樹狀結構 在 /lib/modules/*/kernel/ 目錄底下有很多 *.ko 檔。 這些 kernel modules 有點類似 windows 底下的驅動程式, 負責跟不同的硬體溝通。 其中 fs/ 子目錄底下的驅動程式負責認出並使用各種不同格式 (ext2/3/4、 fat、 ntfs、 isofs、 ...) 的檔案系統。 它們的功用是將一長條沒有組織的陣列 (就是硬碟的一個分割, 從第 0 磁軌到第 xxxx 磁軌), 翻譯成我們習慣的樹狀結構 (就是檔案總管或 shell 底下所看到的層層目錄)。 例如 fat.ko 認得微軟的 fila allocation table 分割; 而 isofs.ko 則認得光碟片的 iso9660 file system ... 等等。

欲啟動這種對應關係, 就下 mount 指令。 例如 mount -t ext4 /dev/sdb1 /media/sdb1 指令, 會自動載入 ext4.ko 模組, 並將 /dev/sdb1 掛載 到 /media/sdb1 子目錄底下。 此處的 /dev/sdb1 稱為一個 device file 因為它代表某顆硬碟 (一個 device) 的某個分割。 但是從 /dev/sdb1 只能看到一長條資料陣列。 至於 /media/sdb1 則叫做 mount point 掛載點, 可以是任意的空目錄。 掛載之後便可以透過 /media/sdb1 這個子目錄看見 /dev/sdb1 裝置上的樹狀結構。

用完之後, 可以下 umount /dev/sdb1umount /media/sdb1 指令, 把 /dev/sdb1 這個分割給 unmount 卸載 下來, 也就是終止這種對應關係。 所有暫存未寫入的資料, 此時會一口氣寫出去 (sync)。 這個動作相當於 windows 底下的 「安全移除隨身碟」。

大部分情況下, linux 會自動偵測該分割的格式, 自己會判斷它是那種檔案系統, 應載入那些模組來辨認, 所以 -t 其實並不需要。

檢查映像檔

-o loop 的效果: 再一次將線性的陣列翻譯成層層目錄樹狀結構 從網路上撿回來的 .iso 檔, 可不可以省下一張實體光碟片, 直接用軟體的方式 (類似 windows 底下的 「虛擬光碟」), 把裡面的檔案撈出來看呢? 如果只是想看看映像檔裡面有什麼東西, 回想 isofs.ko 與 vfat.ko 的功用, 主要是線性陣列與樹狀目錄結構之間的翻譯, 其實與硬體無關。 映像檔本身也不過就是一個很大的陣列, 當然可以叫 isofs.ko 或 vfat.ko 將它翻譯成樹狀結構。 這個機制叫做 loopback file system, 意思是將一個映像檔當成是一片實體的光碟或磁片一樣掛載進來, 像這樣: mount -o loop slackware.iso /mnt/test_cdmount -o loop floppy.img /mnt/test_floppy 此處 /mnt/test_cd 與 /mnt/test_floppy 與平常一樣只是一個普通的 mount point, 可以是任意的空目錄。 掛載完畢之後, 可以下 df 命令檢查。 從此以後, 就可以從 mount point 看到映像檔的內容。 用完要記得 umount 喔!

修改映像檔

如果進一步想對映像檔做一點小小的修改呢? 磁片映像檔可讀寫, 所以用 loopback 方式掛入之後, 可以直接進入 mount point 底下修改其中的檔案, 改完之後 umount 就完成了。 又例如 ext4 的映像檔也可以直接修改:

	dd < /dev/zero > magic.img count=2048
	mkfs -t ext4 magic.img
	mount magic.img /mnt/t1
	df	# 看到多出一個 1MB 大小的裝置被掛載起來
	nano /mnt/t1/secret.txt
	umount magic.img

至於光碟片的映像檔與光碟片一樣是唯讀的。 你可以燒一片光碟, 拷貝到硬碟上, 修改, 再用 mkisofs 指令製作新的光碟映像檔; 也可以用 loopback 方式, 省下一片光碟:

  1. mount -o loop slackware.iso /mnt/test_cd
  2. mkdir /tmp/worksp
  3. cp -r /mnt/test_cd/* /tmp/worksp
  4. 進入 /tmp/worksp 修改。
  5. mkisofs -o slackware_new.iso /tmp/worksp
  6. 用 cdrecord 燒成實體光碟片。

關於製作 iso 映像檔及燒錄光碟時可用的更多選項, 請見 CLDP 中文文件 的詳盡說明。 如果要製作開機光碟, mkisofs 時要加一些參數, 詳見 這篇

真的用到時才會佔空間的 qcow2 映像檔

請見 「用 qemu-img 與 qemu-nbd 管理 qcow2 虛擬硬碟」

...

Loopback-Root-FS

即時解壓縮的唯讀檔案系統之一: cloop

許多玩過 Knoppix 的人都知道 knoppix 可以裝那麼多軟體, 靠的是 cloop ("compressed loopback file system") 模組, 將光碟上一個六百多 MB 的檔案 KNOPPIX/KNOPPIX 當做一個 1.7G 左右的唯讀映像檔在用。

最近才發覺想使用 cloop, 並不局限於 knoppix 底下。 在 rpmfind 可以找到 cloop-utils 套件。 我找到的是 mandrake 版; 這個套件的相依性很低, 我將它用 rpm2tgz 轉成 .tgz, 直接安裝在 slackware 不需要調整就可以用。

如果要做實驗, knoppix 光碟上的 KNOPPIX/KNOPPIX 檔有點太大, 不妨找一個比較小的 morphix 迷你模組 例如 MorphixMini-rescue.mod 或更小的 MorphixMini-rootpass.mod 與 MorphixMini-xbroadcast.mod 等等, 這些也都是 cloop 檔。 首先將 cloop 映像檔解壓縮成 iso 映像檔: extract_compressed_fs MorphixMini-rescue.mod > MorphixMini-rescue.iso 然後你可以用上一節的方式查看, 甚至修改這個 iso 檔, 例如產生一個新的 MorphixMini-rescue_new.iso。 最後可以下 create_compressed_fs MorphixMini-rescue_new.iso 65536 > MorphixMini-rescue_new.mod 新的 cloop 壓縮檔就包好了。

即時解壓縮的唯讀檔案系統之二: cramfs

cloop 的製作過程需要很大的記憶體。 想製作即時解壓縮的唯讀檔案系統, 另一個選擇是使用輕薄短小的 cramfs。 這是 kernel 的標準配備, 你可以看一下 /lib/modules/2.4.*/kernel/fs/cramfs/ 確認你的系統已內建此模組。 先談使用, 等一下再談製作。 因為它是 kernel 內建的模組, 所以像 ext2, vfat 等等一樣, 不需要多一道轉檔手續, 直接用 loopback 的方式就可以掛載: 例如你已製作好一個 ckhung_wp.cramfs 映像檔, 可以下: mount -o loop ckhung_wp.cram /mnt/test 將它掛在 /mnt/test 目錄底下。 一如其他 loopback 映像檔, 從 mount point 進去就可以看到映像檔的內容。 當然它是唯讀的, 無法寫入。 常用功能都很正常: 權限, 擁有人, symolic link ...。 最大的幾個問題: 沒有時間戳記; 每個檔案大小不可超過 16MB; 整個映像檔不可超過 256MB。 掛載入系統的 cramfs, 用 df 看不到, 要用 mount 才看得到。

如何製作 cramsfs 的映像檔呢? 先確定你的系統有 mkcramfs 這個指令。 在 Mandrake 下, 只要安裝 util-linux 套件就會有。 同樣地, 它的相依性不高, 可以將 rpm -ql util-linux | grep cram 列出的所有檔拿到 slackware 底下一樣可以用。 (但不可將 util-linux 轉成 tgz 在 slackware 下安裝, 因為 slackware 有它自己的 util-linux, 會發生衝突。) 例如想將 public_html 目錄整個壓縮成一個 ckhung_wp.cramfs 映像檔, 可以下: mkcramfs public_html/ ckhung_wp.cram 壓縮起來的映像檔, 比同一個目錄壓縮成 .tgz 稍微大一些, 應該是因為檔案系統的索引部分為加速隨機讀取, 多用了一些空間。

即時解壓縮的唯讀檔案系統之三: squashfs

混合數個檔案系統: Translucent File System

Morphix 是模組化的 knoppix。 可是仔細想想: 光碟是唯讀的, 如果每個迷你模組各自為政, 並沒有與主要模組放在同一個 cloop 映像檔裡面, 而是各有各的 /usr /bin ... 等等, 那開機之後該怎麼辦呢...?

Translucent File System 就是用來解決這個問題的機制。 以下說明假設已用 morphix 開機, Translucent File System 已正常運作, 並假設已開啟一個終端機, 下過 sudo bash 指令, 變身為 root 在操作。 請到 /proc/sys/translucency 底下, 逐一將 0, 1, .. 等檔案 cat 出來看, 或者一次看完: cat [0-9]

檔案 0 裡面的這句話 /bin -> /var/tmp/trans/bin 表示: 查看 /bin 目錄時, 除了會看到原本真正存在 /bin 底下的檔案之外, 還會看到 /var/tmp/trans/bin 底下的所有檔案, 彷彿它們也放在 /bin 一樣。 /bin 目錄是映像檔, 唯讀, 因此無法直接新增檔案。 但 /var 目錄在記憶體裡面, 可讀寫, 所以如果想新增檔案, 只要放到 /var/tmp/trans/bin 底下去, 透過 translucency 機制, 就會同時呈現在 /bin 底下, 使用者會以為你將檔案放入 /bin 。 例如 ls -l /var/tmp/trans/bin 看到:

        cpio -> /mnt/mini/mod2/morphix/deb/bin/cpio
        mt-gnu -> /mnt/mini/mod2/morphix/deb/bin/mt-gnu

再到 /bin 底下, 也會看到這兩個檔案。 (其實又是 symbolic link, 再度指向另一個唯讀映像檔裡面的東東)

Symbolic link 怪怪的...

更詳細的文件: Translucent fs 的作者 Bernhard M. Wiedemann 收集了一些 連結, 其中一篇 觀念介紹 解釋得很清楚。 這個 project 有 新家, 不過新家幾乎沒有文件。

混合數個檔案系統: UnionFS 勝出

Unionfs: A Stackable Unification File System