Migrate Linux to ZFS
Some steps I have followed to run Manjaro Linux from ZFS partition.
Backup system
Make a backup of the system for example with bsdtar command as described on Backups pages. One important thing is to make sure that system has installed linuxNN-zfs and zfs-utlis modules.
Create Manjaro Live CD with zfs support
More info: https://wiki.manjaro.org/index.php/Build_Manjaro_ISOs_with_buildiso
Clone iso-profiles:
git clone https://gitlab.manjaro.org/profiles-and-settings/iso-profiles.git ~/iso-profilesAdd required components to
manjaro/kde/Packages-Live(for me it was not enough to add it toPackages-Desktop, but to be sure add it there, too):KERNEL-zfs zfs-utils gpartedCreate iso with:
buildiso -p -f kdeBurn ISO to USB with:
sudo dd bs=4M if=/var/cache/manjaro-tools/iso/manjaro/kde/<version</manjaro-kde-<version>.iso of=/dev/<usb-drive> status=progress oflag=sync
Install EFI boot loaders
Useful EFI boot loaders: rEFInd (to choose between Windows & Linux), ZFSBootMenu (to easily boot Linux from ZFS pool).
Partitions
Created partition with type = 0xBF00 (Solaris Root). To change partition type you can use fdisk. Solaris root partition type in fdisk is 156. You can add it a label, for example “Linux” for easier identification during filesystem import.
Create ZFS pool on the partition
sudo zpool create -f -o ashift=12 -o autotrim=on -O acltype=posixacl -O xattr=sa -O atime=off -O relatime=off -O recordsize=256k -O dnodesize=legacy -O normalization=formD -O mountpoint=none -O canmount=off -O devices=off -O compression=zstd-3 ssd /dev/disk/by-partlabel/Linux
Please note! As of 2023-11-11 I have found a bug in openzfs that dnodesize=auto makes it impossible to reveive incremental backup, so I changed it form auto to disabled. If you have it enabled you can still take care and set -o dnodesize=legacy during creating datasets. It’s enough to set it to the root dataset, as the children datasets will inherit the setting.
Create containers:
sudo zfs create -o canmount=off -o mountpoint=none ssd/manjaro
Create datasets
sudo zfs create -o canmount=noauto -o mountpoint=/ ssd/manjaro/root
sudo zfs create -o mountpoint=/home ssd/manjaro/home
Verify:
zfs list
Mount ZFS filesystems
The import below automatically mounts /home folder in /mnt directory (because of automount flag), but the root must be mounted manually.
sudo zfs umount -a
sudo zpool export ssd
sudo zpool import -d /dev/disk/by-partlabel/Linux -R /mnt ssd
sudo zfs mount ssd/manjaro/root
Copy system files
One possible method:
sudo rsync -axHAWXS --numeric-ids --info=progress2 /src/ /mnt
Please note! Slash at the end of /src/ is needed. Otherwise rsync will create src subfolder.
Update system configuration
Information to boot loaders where to find root file system:
sudo zpool set bootfs=ssd/manjaro/root ssd
Copy the zpool cache file:
sudo zpool set cachefile=/etc/zfs/zpool.cache ssd
sudo mkdir -p /mnt/etc/zfs
sudo cp /etc/zfs/zpool.cache /mnt/etc/zfs/zpool.cache
Chroot to the system:
sudo chroot /mnt
mount -t proc proc /proc
mount -t sysfs sys /sys
mount -t devtmpfs udev /dev
Edit /etc/mkinitcpio.conf file and add zfs to HOOKS before filesystems and move keyboard hook before zfs. If you are not using ext4 you can remove fsck, for example:
HOOKS=(base udev autodetect modconf block keyboard zfs filesystems)
Regenerate initramfs:
mkinitcpio -P
Comment out old root and home partitions from /etc/fstab.
Enable necessary services for automatically mounting zfs datasets:
sudo systemctl enable zfs.target
sudo systemctl enable zfs-import-cache
sudo systemctl enable zfs-mount
sudo systemctl enable zfs-import.target
Exit from chroot:
umount /dev
umount /sys
umount /proc
exit
Unexport ZFS pool
sudo zfs umount ssd/manjaro/root
sudo zpool export ssd
Reboot
Now the system should be bootable from ZFSBootMenu.
If after boot the filesystem is readonly, you can load it by adding rw to the kernel command line (CTRL+E in ZFSBootMenu). After the system is loaded you can set it as persistent with:
- call
cat /proc/cmdlineto see what’s the current command line is, for example:zfs=ssd/manjaro/root nvidia-drm.modeset=1 spl.spl_hostid=0x00bab10c - call
sudo zfs set org.zfsbootmenu:commandline="<OLD_COMMAND_LINE_WITHOUT_ZFS_PART> rw" ssd/manjaro/root, for example:sudo zfs set org.zfsbootmenu:commandline="nvidia-drm.modeset=1 spl.spl_hostid=0x00bab10c rw" ssd/manjaro/root
You can set this property on the parent dataset (ssd/manjaro) and inherit it for ssd/manjaro/root (please verify if the property is set for it, if it is just unset it with inherit command).