2017年8月30日 星期三

ZFS boot

這裡也是筆記, 主角是 ubuntu 14.04 跟 16.04, 著重在虛擬機器內系統移轉, 不在安裝. (安裝我不會)

  • 最少要有一臺 ubuntu 14.04 或 16.04, 指除了被移轉的機器之外還要再一臺.
  • ubuntu 14.04 initrd ZFS script 有些問題, poolname 僅接受 rpool 而已, 特別注意.
  • 在想要被移轉的 ubuntu 上, 先行安裝好幾個套件: zfsutils-linux, zfs-initramfs 與其它相依套件.
  • 以下增加到 /etc/initramfs-tools/modules 中:
    • spl
    • zfs
  • update-initramfs -c -k all
  • 到此時才可以將這個虛擬機器停下, 將虛擬硬碟檔案跟備份虛擬硬碟檔案分別掛到另一個可以正常運作的 ubuntu 底下
  • 在這裡我硬碟僅只使用 MBR 切割, zfs 也僅只有一個區, 外面說明會比較詳細講出如果 zfs 底下的分割區要被掛成 root 時要怎麼做, 但並沒有看到不分割時該怎麼做...
    • 僅只建立一個 MBR partition /dev/sdc1,  fdisk /dev/sdc
    • 建立 ZFS 儲存池, 假設 poolname 叫 BOOTpool:
      • zpool create BOOTpool /dev/sdc1 -O compression=lz4 -O atime=off -O mountpoint=/tmp/BOOTpool
      • zpool set bootfs=BOOTpool BOOTpool
    • copy 要移轉的虛擬硬碟內檔案到 /tmp/BOOTpool/ 下, 也就是整顆硬碟檔案 copy.
    • copy 作業可以丟背景跑, 前景還可以再做件很重要的事:
      • grub-install --boot-directory=/tmp/BOOTpool/boot/ --modules="part_msdos ext2 zfs"
    • 到此時 grub 在stage2 時才擁有讀取 zfs 的能力, 才有機會再讀到 /boot/grub/grub.cfg 執行選單工作, 而此時已經是 stage 3. 否則 grub 會跟你說它不認得 (unknow file system)
    • 檔案 copy 好後記得做些修改的動作, /etc/fstab 因為 zfs 本身就有 mountpoint 的設定所以不需要修改, 改了看來也沒用... boot/grub/grub.cfg 有幾個關鍵設定麻煩注意一下:
      • linux   /boot/vmlinuz => linux   /@/boot/vmlinuz
      • initrd  /boot/initrd.img => initrd  /@/boot/initrd.img
    •  (update) 如果是指定 sub-zpool 假設叫 BOOTpool/sys, 那麼要設成:
      • linux   /boot/vmlinuz => linux   /sys/@/boot/vmlinuz
      • initrd  /boot/initrd.img => initrd  /sys/@/boot/initrd.img
    • 否則 grub 找不到 vmlinuz 跟 initrd 無法開機.
    • 如果是比較複雜的 ZFS 內部分割請參考其它文章像這個
    • /boot/vmlinuz 後面這些 kernel parameter 切記加上 boot=zfs. 因為 zfs 不像其它的 filesystem 可以直接使用, 需要它專有工具 import 所有能用的 zpool 進來後才能掛起來, (所以如果是自製的 initrd RAMdisk image 的話要確認有沒有 zfs 工具存在, 還有掛載的 script, 否則也是沒用), 而每一家 linux distro 在 initrd 裡觸發 zfs 工具的方式都有點不同, ubuntu 是使用 boot=zfs, gentoo 使用 dozfs.
    • ubuntu 的 rootfs 下法是 root=ZFS=BOOTpool, 之所以特別說這是 ubuntu 的下法是因為這個 parameter 其實是 parser 給 initrd 內的 ZFS script 看的而不是給 kernel, 所以每一家 distro 掛法會不一樣是正常情況. 我最後 grub 內的 kernel parameter 那行是這樣:
      • linux /@/boot/vmlinuz-4.11.0-13-generic root=ZFS=BOOTpool ro boot=zfs console=tty0
      • (update) 如果 zpool 假設是 BOOTpool/sys, 上一行 root=ZFS=BOOTpool 改 root=ZFS=BOOTpool/sys
    • grub 改好後才是來最後處理 ZFS...
      • 再一次確認不會自動掛起來: zfs set atime=off BOOTpool
      • umount. zfs umount BOOTpool
      • 修改指定 zpool 掛載點 zfs set mountpoint=/ BOOTpool
      • (update) 或 sub-zpool  掛載點 zfs set mountpoint=/ BOOTpool/sys
      • 離線 zpool export BOOTpool
  • 虛擬機器改回去用這個 ZFS 虛擬硬碟. 
    • 如果開完機開的進去沒問題, 別忘了 /etc/default/grub 多加一些東西:
      • GRUB_CMDLINE_LINUX="boot=zfs"
      • update-grub
      • 請注意 update-grub 對目前的 ubuntu 14.04 無效, 但 ubuntu 14.04 可以硬裝 16.04 用的 grub-common 套件解決這個問題.
      • (update) 如果 rootfs 是在某一個 zpool 非 sub-zpool 裡的話, update-grub 中 grub-mkconfig 會很雞婆的在 zpool name 後面加個 "/" 導致開不了機, 而使用 sub zpool 的話不會有這個問題. 因此建議如上述文章所提, rootfs 最好放在某一個 sub zpool 裡如 BOOTpool/sys 不要直接是整個 zpool 如 BOOTpool.
差不多就是這樣. 
  • ubuntu 14.04 會有機會認不得 root=ZFS=BOOTpool 中的 BOOTpool, 如果不認得, 就改成它內定的 "rpool" ...
  • ubuntu 14.04 中的 grub-probe 跟 update-grub 在 rootfs 最後掛成 ZFS 後無法認到 ZFS. 但 ubuntu 14.04 可以硬裝 16.04 用的 grub-common 套件解決這個問題.
  • mountoiint 設定成 legacy 我沒有實驗成功讓它掛起來, 這種設定在一開始 zpool import 時似乎就無法找到.
  • ZFS 本身不支援 /dev/disk/by-label 與 /dev/disk/by-uuid 僅只有 /dev/disk/by-path, 所以很多筆記會以 by-path 為主. 可是我不愛用.

ZFS 在當別的儲存載體時不錯, 但當 linux rootfs 時是不是比較好, 我自己是不這麼認為...

update 20180615: 新增 rootfs 擺在 sub zpool 裡時 grub.cfg 的路徑修改. 但請注意, ubuntu 的 grub 似乎不認 main zpool 名字, 只認 sub zpool 而已 (ArchLinux 的會認, 所以 ArchLinux wiki 的教學拿來 ubuntu 上用要自己懂的修改), 所以以前使用 BOOTpool 時是 /@/ 現在使用 BOOTpool/sys 時是 /sys@/, 我沒有試過同一顆硬碟裡有一個以上 zfs 分割區時會有什麼問題, 可能只認 partition number 來分吧? 我不知道.

沒有留言: