2020年6月5日 星期五

Ubuntu 20.04 ZFS on root 安裝筆記

不知不覺中 Ubuntu 20.04 於五月底正式發行了,看到 ZFS on Linux 好像差不多快成熟了,就很想體會一下 ZFS 的 Copy-on-Write 以及強大的 checksum, snapshot, incremental backup 功能。 但是我的 Dell Latitude 5480 筆電必須是 dual-boot Windows 10 & Ubuntu,而 Ubuntu 20.04 的內建 ZFS on root 安裝選項是會把整個硬碟都格式化給 ZFS 使用。所以我只能自己另闢蹊徑想辦法用一些旁門左道的方式,看看有沒有可能整出一個 Ubuntu on ZFS root + dual boot。

當然要 google 一下網路上前人的經驗,比較有參考性的文件連結都收集在下面的【參考文件】。因為之前也想要體驗 Btrfs 的好處,所以我的 SSD 已經安裝了一版 Ubuntu 20.04 在分區 5,格式為 Btrfs 。在這次 ZFS 安裝前,SSD 是採用 GPT 的分區表,容量為 1T,分割如下:

 1 2 3 4 5 -
 FAT32 - BitLocker  NTFS Btrfs Free
 1024M 128M 488G 10GB 200G 324G
 EFI
 System 
 Windows 
 Reserved 
 Win 10
 System
 Windows
 Recovery 
 Ubuntu
 20.04
 -

準備分割區

基本上這次安裝就是利用 Free 的空間,多加入 2 個分割區,一個是給 boot , 主要是為了 UEFI 開機的支援,建議大小為 512M ,剩下的空間就都留給 Ubuntu System 。我的 Latitude 5480 安裝了 32GB 的 RAM,所以我是沒有使用 swap。這次安裝的起點是:我開機進入已經安裝在分區5的 Ubuntu 20.04 on Btrfs,首先就是用 sgdisk 來做增加分割的部分。
sgdisk -n6:0:+512M -t6:BF01 /dev/nvme0n1  # 在分割區5之後,切出512M給分區6,格式碼設為BF01
sgdisk -n7:0:0 -t7:BF01 /dev/nvme0n1  # 把分割區6之後所有的空間給分區7,格式碼設為BF01
檢查分區增加後的結果如下:
rick@E5480:~$ sudo sgdisk -p /dev/nvme0n1
Disk /dev/nvme0n1: 2000409264 sectors, 953.9 GiB
Model: INTEL SSDPEKKW010T7                     
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): C85DF9DB-279D-4D14-83DC-4D49489E105A
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 2000409230
Partitions will be aligned on 2048-sector boundaries
Total free space is 2669 sectors (1.3 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048         2099199   1024.0 MiB  EF00  EFI system partition
   2         2099200         2361343   128.0 MiB   0C01  Microsoft reserved ...
   3         2361344       955197439   454.3 GiB   0700  Basic data partition
   4      1980418048      2000408575   9.5 GiB     2700  Basic data partition
   5       955197440      1345822719   186.3 GiB   8300  
   6      1345822720      1346871295   512.0 MiB   BF01  
   7      1346871296      1980418047   302.1 GiB   BF01

建立 boot pool

zpool create \
    -o ashift=12 -d \
    -o feature@async_destroy=enabled \
    -o feature@bookmarks=enabled \
    -o feature@embedded_data=enabled \
    -o feature@empty_bpobj=enabled \
    -o feature@enabled_txg=enabled \
    -o feature@extensible_dataset=enabled \
    -o feature@filesystem_limits=enabled \
    -o feature@hole_birth=enabled \
    -o feature@large_blocks=enabled \
    -o feature@lz4_compress=enabled \
    -o feature@spacemap_histogram=enabled \
    -o feature@zpool_checkpoint=enabled \
    -O acltype=posixacl -O canmount=off -O compression=lz4 \
    -O devices=off -O normalization=formD -O relatime=on -O xattr=sa \
    -O mountpoint=/boot -R /mnt \
    bpool /dev/nvme0n1p6
參數重點
➤ ashift=12 是為了要讓新一代 4KB block size 硬碟發揮最好的效能。
➤ canmount=off 表示 bpool 不是主要的掛載點,而是下面接著建立的 filesystem datasets。
➤ muntpoint=/boot 將來這個 bpool 要掛在 /boot
➤ -R /mnt 表示等一下會被掛在另一個指定的地方 /mnt

建立 root pool

zpool create \
    -o ashift=12 \
    -O acltype=posixacl -O canmount=off -O compression=lz4 \
    -O dnodesize=auto -O normalization=formD -O relatime=on \
    -O xattr=sa -O mountpoint=/ -R /mnt \
    rpool /dev/nvme0n1p7

建立 filesystem datasets 當作容器

zfs create -o canmount=off -o mountpoint=none rpool/ROOT
zfs create -o canmount=off -o mountpoint=none rpool/USERDATA
zfs create -o canmount=off -o mountpoint=none bpool/BOOT

建立並掛載真正的 rootfs, boot & home filesystem datasets

zfs create -o canmount=on -o mountpoint=/     rpool/ROOT/ubuntu
zfs create -o canmount=on -o mountpoint=/home rpool/USERDATA/ubuntu
zfs create -o canmount=on -o mountpoint=/boot bpool/BOOT/ubuntu
現在 filesystem datasets 都已經掛在 /mnt 之下,接下來就是將整個系統拷貝進去。

拷貝現有系統

先建立一個現有系統 Btrfs 的唯獨快照
mkdir /media/btrfs
mount /dev/nvmen0p5 /media/btrfs
btrfs subvolume snapshot -r /media/btrfs/@ /media/btrfs/@.latest
btrfs subvolume snapshot -r /media/btrfs/@home /media/btrfs/@home.latest
接下來就是用 rsync 做完整的系統拷貝
rsync -av --info=progress2 --no-inc-recursive --human-readable /media/btrfs/ /mnt
umount /media/btrfs

將系統 chroot 到 /mnt

for d in proc sys dev; do mount --rbind /$d /mnt/$d; done
chroot /mnt
echo "nameserver 8.8.8.8" >> /etc/resolv.conf  # 設定chroot下的DNS

安裝 GURB

mount /boot/efi  # 掛上EFI分區
grub-probe /boot # 確定目前系統可以認得ZFS
update-initramfs -c -k all # 更新initrd
vi /etc/default/grub
# Add init_on_alloc=0 to: GRUB_CMDLINE_LINUX_DEFAULT # Save and quit.
update0grub # 更新boot紀錄
grub-install --target=x86_64-efi --efi-directory=/boot/efi \ --bootloader-id=ubuntu --recheck --no-floppy

修正 filesystem 掛載的順序

mkdir /etc/zfs/zfs-list.cache
touch /etc/zfs/zfs-list.cache/bpool
touch /etc/zfs/zfs-list.cache/rpool
ln -s /usr/lib/zfs-linux/zed.d/history_event-zfs-list-cacher.sh /etc/zfs/zed.d
zed -F &
# 用以下命令確認快取的檔案不是空的
cat /etc/zfs/zfs-list.cache/bpool
cat /etc/zfs/zfs-list.cache/rpool
# 確認後停止 zed
fg
Press Ctrl-C.

離開 chroot 然後準備重新開機

mount | grep -v zfs | tac | awk '/\/mnt/ {print $3}' | \
xargs -i{} umount -lf {}
zpool export -a  # 為了確保安全, 卸載 zpool
reboot           # 重新開機
如果一切正常,重開機應該就會看到grub開機選單,選擇 Ubuntu 開機之後就會看到登入畫面。

後記

我這次運氣不錯,一方面也是有仔細參考前人的文件,所以很順利的轉換成 ZFS 系統,沒有把硬碟搞爛掉,造成無法開機。如果遇到開機的問題,一定要有 Ubuntu 的開機碟在身邊,用Live-CD 的環境把 filesystem 再掛載上來,才能進行系統修復。

參考文件

沒有留言: