2018年4月2日 星期一

overlayfs 練習: 小改光碟 iso 檔, 何必大手筆複製?

overlayfs 示意圖 以下三件事有什麼共通處?

  1. debian-live 光碟的 persistence 機制 用一層薄薄的 (例如 2G) 可讀寫空間來製造 「從 live CD 開機, 後來卻竟然可以將工作階段寫入硬碟」 的假象。
  2. 撰寫 dockerfile 時第一句 from 拿某個 (即使很厚重的) base image 當作地基, 如果後面的變動沒很多, 那麼在 docker build 時, 扣除下載 base image 的時間, 你的 docker image 本身的建立其實花不了多少時間。
  3. 有一個 4G 大小的 iso 檔, 我想改它的開機圖片跟選單, 可以不要把整張光碟的內容複製到硬碟上修改嗎?

答案: 它們都可以用 overlayfs 來實現。 把玩 overlay 文件系統 這篇簡中文章有很詳細的解說。 單純從 end-user 的角度來說, 其實沒有細讀也 ok, 只需要想像 gimp 或 inkscape 編輯圖片時的 「圖層」 概念, 再圖片搜尋一下, 對 overlayfs 就可以理解八九成了。 本文就不解釋原理, 直接實作第三項工作來認識 overlayfs。 (插圖取自 Data and Network Management for Containers -- Docker Tutorial)

等一下用 mount 指令使用 overlayfs 時, kernel 會自動載入 overlay 模組。 你必須在命令列上指定三個目錄:

  1. 不會被 overlayfs 寫入的下層目錄 (lowerdir)
  2. 可寫入的、 記錄差異的上層目錄 (upperdir)
  3. 合併之後看見的目錄 (也就是 mount point)

其中 lowerdir 跟 upperdir 可以是任意的目錄, 並不一定要是檔案系統。 反過來說, 就算是既有的檔案系統 (例如 iso 或 squashfs) 也必須先手動掛載, 然後 overlayfs 才看得見 (它不會自動幫你掛載 iso 或 squashfs)。

實際上 overlayfs 還需要第四個目錄: 工作用的暫存目錄 (workdir)。 而且, 根據 archlinux 超讚的文件 「如何使用 overlay filesystem」upperdir 跟 workdir 必須位於同一個檔案系統內

現在假設你想修改的光碟是 /x/cdrom/grml64-full_2017.05.iso 並且假設 /x/ovl /mnt/iso /mnt/merged 是三個空的目錄, 那麼可以這樣做:

mount -o ro /x/cdrom/grml64-full_2017.05.iso /mnt/iso
mkdir /x/ovl/rw /x/ovl/work
mount -t overlay overlay -o lowerdir=/mnt/iso,upperdir=/x/ovl/rw,workdir=/x/ovl/work /mnt/merged

在同一個目錄底下建兩個目錄, 分別作為 upperdir 跟 workdir, 這可以確保兩個目錄位於同一個檔案系統內。 事實上這也是 debian-live 的 persistence 的命名方式。 如果失敗的話, dmesg | tail 可能會查到比較有用的錯誤訊息。 例如我的某個版本的系統安裝在 zfs 上面, 結果掛載 overlay 失敗, 用 dmesg | tail 查看後, 發現 "/x/ovl/rw not supported as upperdir", 從而得知可能是因為 zfs 跟 overlay 處不來

至此, 你可以從 /mnt/merged 看到光碟內容, 但裡面的檔案是可讀寫的。 在那裡修改設定檔及背景圖檔, 然後 xorriso -as mkisofs -o /x/cdrom/grml64-new.iso -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table /mnt/merged 從 /mnt/merged 讀取新的光碟內容、 建立新的映像檔 /x/cdrom/grml64-new.iso 。

同樣的方法也適用於修改 live cd 更內層的 *.squashfs。 先前曾經按照 Remastering Grml 做, 想要要客製化 grml linux。 (另一份文件 Customizing Grml 看起來太舊, 沒試。) 失敗之後 提問, 但並未解決。 試著 安裝到硬碟 果然也失敗。 後來才想要學 overlayfs, 因為用這種方式重做 squashfs 最不需要動到原始系統開機的部分, 成功機率應該最高:

  1. 以 persistence 的方式進入 grml linux、
  2. 客製化
  3. 關機、 重開, 新進入另一版的 linux
  4. 用本文的方式把 *.squashfs 掛載在 /mnt/sq 、 把 persistence image 掛載在 /x/pers 、 mount -t overlay overlay -o lowerdir=/mnt/sq,upperdir=/x/pers/rw,workdir=/x/pers/work /mnt/merged
  5. mksquashfs /mnt/merged /...

再用新的 squashfs 製作 iso 檔... 登登! 果然客製化成功。

沒有留言:

張貼留言