不知不覺中 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。
➤ 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 再掛載上來,才能進行系統修復。
參考文件
- Setup a ZFS storage pool | Ubuntu
- ZFS - Ubuntu Wiki
- HOWTO install Ubuntu 18.04 to a Whole Disk Native ZFS Root Filesystem using Ubiquity GUI installer
- Installing UEFI ZFS Root on Ubuntu 19.10
- Installing Ubuntu on a ZFS root, with encryption and mirroring
- Ubuntu 20.04 Root on ZFS
- Ubuntu server 20.04 zfs root and OCI
- Configuring ZFS on Ubuntu 20.04
- Automating snapshots with pyznap on Centos 7
- sgdisk walkthrough
- Backing up data using rsync command
- Man page: zpool, zfs
沒有留言:
張貼留言