2020年2月11日 星期二

zfs boot with ubuntu 20.04 and UEFI

這是這篇的延續, 也是從一套已經安裝好的 ubuntu 移植去別的硬碟這種模式, 不過這次是全部重來. 以下參考這篇 "Booting a ZFS Root via UEFI on Debian", zpool 建立手法也會幾乎跟它完全一樣. oting a ZFS Root via UEFI on Debian, 首先的需要安裝幾個東西:

  • zfsutils-linux
  • zfs-initramfs
假設原始的系統檔案裝在 /dev/nvme0n1p2
我打算安裝的目標是 /dev/sda2, /dev/sda1 為 UEFI boot, 我打算安裝後 zpool 們的樣子:
rpool
rpool/sys : /
rpool/plug : /opt/plug/

#mkfs.vfat /dev/sda1

# zpool create -o ashift=12 -o altroot=/mnt -m none rpool /dev/sda2
# zfs set compression=lz4 rpool
# zfs create -o mountpoint=/opt/plug rpool/plug
# zfs set compression=lz4 rpool/plug
# zfs create -o mountpoint=/ rpool/sys
# zfs set atime=off rpool/sys
# zfs set relatime=on rpool/sys
# zfs set compression=lz4 rpool/sys
#### 這時因為 rpool 在 zpool create (或 import) 時有下 -o altroot=/mnt 的關係, 所有根基目錄都是在 altroot 的指示之上, 所以 mountpoint 可以放心的設定為 '/'
# zfs create -o mountpoint=/opt/plug rpool/plug
# zfs mount rpool/sys 
#### 這時 df -h 會看到 rpool/sys mount 在 /mnt 下.
#### copy 全部的檔案.
# mkdir -o /tmp/src 
# mount /dev/nvme0n1p2 /tmp/src/
# cp -a /tmp/src/* /mnt/
# mount /dev/sda1 /mnt/boot/efi/
#### 安裝 grub
# grub-install --removable --recheck --force --bootloader-id=BOOT --compress=xz --target=x86_64-efi --boot-directory=/mnt/boot/ --efi-directory=/mnt//boot/efi/ --modules="part_gpt ext2 zfs"
#### 這時有一個動作非常重要, 看 grub 抓到的 zfs uuid 是什麼
# cat /mnt/boot/efi/EFI/BOOT/grub.cfg
## search.fs_uuid xxxx0000oooo1111 root hd0,gpt2
#### 要看這紅字寫的是什麼, 後面改 grub.cfg 會用到
# cat /mnt/boot/grub.cfg|grep vmlinuz|head -1
## linux   /boot/vmlinuz-5.3.0-24-generic root=UUID=00112233-4455-6677-8899-aabbccddeeff ro
#### 這裡要手動改 grub.cfg 比較囉唆, 以下是個人手段, 參考用
# sed -i 's/00112233-4455-6677-8899-aabbccddeeff/xxxx0000oooo1111/g' /mnt/boot/grub.cfg
# nano /mnt/boot/grub.cfg
#### 這裡把 vmlinuz 裡那行 root=UUID=.... 改成 root=ZFS=rpool/sys, 一個 kernel 就要改兩次, 以此類推. 還有所有的 /boot/ 這裡改成 /sys@/boot/ 否則 grub 抓不到開機用的 kernel / initramfs.
#### 
# nano /mnt/etc/fstab
#### 把原本 ext4 mount 的部份還有 swap 全 remark 掉, /boot/efi 改成 /dev/sda1 的 UUID.

後面要維護時記得 zpool 多下一個 altroot 參數, ex:
zpool import rpool -o altroot=/mnt
#### /mnt 必需要是空的

到這裡差不多完工. 過往的做法不好管制某一個 zpool readonly yes/no 還有其它屬性, 這種的比較方便. 還有就是對 UEFI 的支援. /boot/efi/EFI/BOOT/grub.cfg 裡寫的那個 UUID 我用 blkid 還是什麼工具都查不到, 雖然就像過往 btrfs / ext4 查的到 UUID 把檔案直接 co 到 UEFI partition 區裡就可以動那麼簡單, 但就是 zfs 這個 UUID 很奇特, 要透過 grub-installer 抓出來...

這次 lz4 壓縮率不比 btrfs zstd:3 來的高了, 但執行速度目前感覺上還是小贏 btrfs.

update200224: UEFI boot partition grub.cfg 中要搜尋的 fs_uuid 為 16 進位, 但 linux blkid 下看到的 zfs UUID 其實是 10 進位, 照這樣轉換去就可以簡的修改 UEFI boot 區內 grub.cfg 的內容讓 grub 可以抓到指定的 zfs partitiom, 不需要跑 grub-install

沒有留言: