User:Fearedbliss/Installing Gentoo Linux On ZFS

Install Gentoo Linux on ZFS
Author: Jonathan Vasquez (fearedbliss) Contact: fearedbliss@gentoo.org

Preface
This guide will show you how to install Gentoo Linux with:

* Everything on ZFS (/, /boot, swap - With all feature flags enabled and lz4 compression) * ZFS 0.6.5.7 * GRUB 2 (Bootloader) - Minimum required version: 2.02-beta3 (Contains all zfs feature flag support as of 0.6.5) * OpenRC (Init) * Gentoo Stable (amd64) * Git-based Portage * Precompiled Binary Packages

Notes on other stuff you can do in the ZFS install can be found here.

Required Tools
Download my modified System Rescue CD that includes ZFS from one of the mirrors on the front page.

Linux
If you have a Linux system, you can create a bootable usb from it by doing the following:

mkdir /tmp/iso mount -o loop,ro /tmp/iso /tmp/iso/usb_inst.sh

That should open up a screen where you can select your plugged in flash drive.

Windows
You can download "Rufus" and select the ISO by clicking the little image next to the "Create a bootable disk using <>". After that, you can use the default settings and press "Start".

Download Rufus

Assumptions

 * Only installing Gentoo on one drive called /dev/sda.
 * You are using my modified System Rescue CD that includes ZFS
 * Will be using my tools (bliss-kernel, bliss-initramfs).

Also, this guide is the way I install Gentoo, not exactly the way the handbook has it.

Wipe Partition Layout
This will delete all partitions and their respective MBR/GPT data structures. No confirmation or prompt will be given.

sgdisk -Z /dev/sda

Create your partitions
fdisk /dev/sda

Once fdisk is opened, use the following layout:

/dev/sda1 = Whole Disk |   ZFS Pool    | Everything on ZFS    | Code: BF

The "->" means to just press enter and accept the default.

/ Partition

Command (m for help): n Select (default p): -> Partition number (1-4, default 1): -> First sector (2048-1953525167, default 2048): -> Last sector, +sectors or +size{K,M,G,T,P} (2048-1953525167, default 1953525167): ->

Set / Partition Type Command (m for help): t Selected partition 1 Partition type (type L to list all types): bf

Set / Partition Boot Flag Command (m for help): a Selected partition 1

Final View Command (m for help): p Disk /dev/sda: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 4096 bytes / 4096 bytes Disklabel type: dos Disk identifier: 0x7aea4caf

Device    Boot Start        End    Sectors   Size Id Type /dev/sda1 *     2048 1953525167 1953523120 931.5G bf Solaris

Write your changes Command (m for help): w

Create your zpool
Create your zpool which will contain your drives and datasets:

zpool create -f -o ashift=12 -o cachefile= -O compression=lz4 -m none -R /mnt/gentoo tank /dev/sda1

Create your zfs datasets
We will keep it simple and just create a few datasets for /, and /home. ZFS is extremely flexible and you can easily add or remove datasets in the future.

zfs create tank/gentoo zfs create -o mountpoint=/ tank/gentoo/root zfs create -o mountpoint=/home tank/gentoo/home
 * 1) Create your / and /home datasets

Create your swap zvol
This creates the zfs block device that we will use for swap.

zfs create -o sync=always -o primarycache=metadata -o secondarycache=none -b 4k -V 4G -o logbias=throughput tank/swap mkswap -f /dev/zvol/tank/swap swapon /dev/zvol/tank/swap


 * Currently, the performance of the swap zvol isn't that great. This should improve over time.
 * You should have a swap even if it is small. Your system could lock up under high load, especially since ZFS uses your physical RAM for its ARC.

Verify everything looks good
You can verify that all of these things worked by running the following:

octopus ~ # zpool status pool: tank state: ONLINE scan: none requested config:

NAME        STATE     READ WRITE CKSUM tank        ONLINE       0     0     0 /dev/sda1 ONLINE       0     0     0 errors: No known data errors

octopus ~ # zfs list NAME              USED  AVAIL  REFER  MOUNTPOINT tank              880G  2.63T   272K  none tank/gentoo       875G  2.63T   272K  none tank/gentoo/home  807G  2.63T   668G  /home tank/gentoo/root 68.0G  2.63T  31.7G  / tank/swap        4.25G  2.63T  20.3M  -

Now we are ready to install Gentoo!

Check and set your time
date

If it's wrong then fix it. Let's say it's August 24, 2014 @ 2:48 PM (will be 14:48 in 24 hour time), we would do the following:

date 082414482014

'''08 24 1448 2014 (Month, Date, 24 Hour Time, Year). It will be UTC at the moment but we will fix it once we are inside our environment.'''

Preparing to chroot
cd /mnt/gentoo wget tar xpf

If you don't have a stage 3 for your architecture already downloaded, then click here.

Copy zpool cache
mkdir etc/zfs cp /etc/zfs/zpool.cache etc/zfs

Copy network settings
cp /etc/resolv.conf etc/

Mount required devices
mount --rbind /dev dev mount --rbind /proc proc mount --rbind /sys sys

Chroot into your environment
env -i HOME=/root TERM=$TERM chroot. bash -l

Create mtab symlink
ln -sf /proc/self/mounts /etc/mtab

Fix your date
I'm in New York so I will do the following:

ln -sf /usr/share/zoneinfo/America/New_York /etc/localtime date 082412542014

Generate locales
nano /etc/locale.gen (I uncommented the en_US ISO/UTF-8 lines) locale-gen

Set hostname
nano /etc/conf.d/hostname

Edit fstab
Everything is on zfs so we don't need anything in here except for the swap zvol entry. My fstab looks as follows:

nano /etc/fstab

/dev/zvol/tank/swap    none            swap            sw              0 0

Modify make.conf
Let's modify our /etc/portage/make.conf so we can start installing stuff with a good base:

nano /etc/portage/make.conf

Example, change it to what you need:

ACCEPT_LICENSE="*" USE="mmx sse sse2 -branding"

GENTOO_SOURCES="http://xyinn.org/gentoo/ http://mirrors.rit.edu/gentoo/" PORTAGE_BINHOST="http://xyinn.org/gentoo/packages"

MAKEOPTS="-j5" EMERGE_DEFAULT_OPTS="--jobs=2 --load-average=2 --with-bdeps=y --quiet-build=y" FEATURES="buildpkg" LINGUAS="en en_US" VIDEO_CARDS="intel" INPUT_DEVICES="evdev synaptics"

Configure Portage, get the Portage Tree, and setup bliss-overlay
We will now configure portage, download the Portage Tree, and setup "bliss-overlay" through it. This means that you will be able to receive all bliss-overlay updates through portage.

Since our livecd and chroot don't have git, we will download a github snapshot that contains the .git repository as well. Normally if we download this from github directly, it won't include .git directory, which would require us to re-download all the files again after we compiled git in order to get updates via git. If we do this, we can avoid this second download.

wget http://xyinn.org/gentoo/portage/portage-snapshot.tar.xz tar xf portage-snapshot.tar.xz -C /usr/
 * 1) Bootstrap the portage tree

cp /usr/share/portage/config/repos.conf /etc/portage/repos.conf
 * 1) Copy the example portage config so we can modify it

nano /etc/portage/repos.conf
 * 1) Open repos.conf and switch the following values for the [gentoo] entry to the following:

sync-type = git sync-uri = https://github.com/fearedbliss/gentoo.git
 * 1) Add the following entry to the same file:

[bliss-overlay] location = /var/lib/overlays/bliss-overlay sync-type = git sync-uri = https://github.com/fearedbliss/bliss-overlay.git auto-sync = yes

emerge dev-vcs/git
 * 1) Compile git

emerge --sync
 * 1) Sync once more to get bliss-overlay

Install required applications
Unmask the latest version of GRUB (and enable zfs support). We need a minimum of version 2.02-beta3 so that all of our feature flags and lz4 compression are supported which will allow us to boot from our pool: echo "sys-boot/grub ~amd64" >> /etc/portage/package.accept_keywords echo "sys-boot/grub libzfs" >> /etc/portage/package.use

Unmask the latest versions of zfs: echo "sys-kernel/spl ~amd64" >> /etc/portage/package.accept_keywords echo "sys-fs/zfs ~amd64" >> /etc/portage/package.accept_keywords echo "sys-fs/zfs-kmod ~amd64" >> /etc/portage/package.accept_keywords

Now install the apps: emerge -ag bliss-kernel bliss-initramfs grub

'''Consider pinning the kernel version that was installed so that when we do a future kernel upgrade, an emerge --depclean won't delete our kernel files from the /boot directory. If the bliss-kernel ebuild that emerge pulled to install was: bliss-kernel-4.1.8, we would do:'''

emerge --noreplace =bliss-kernel-4.1.8

Update your system
emerge -uDNavg @world

'''The "g" option in the first emerge command will attempt to pull as many compatible binary packages from my server. This means you will have to compile a lot less packages. '''

Installing the bootloader onto your drive
We will need to install the bootloader. Before we do that, let's see if GRUB can detect our /'s filesystem type: grub2-probe /

It should say 'zfs'. If it doesn't, then something is wrong and your system will not boot!

Now run the following to install the bootloader to the drive: grub2-install /dev/sda

The above command should return a "Installation finished. No error reported." message. If it doesn't, then something is wrong and your system will not boot!

'''Do not upgrade your pool above version 0.6.5 if that newer version contains newer feature flags that GRUB 2 doesn't yet support. If you do, your system will become unbootable.'''

Make GRUB 2 configuration file
You can use the following configuration file as a basis for your system:

nano /boot/grub/grub.cfg

set timeout=1 set default=0
 * 1) Place the following inside the grub.cfg file

insmod zfs

menuentry "Gentoo - 4.1.8-FC.01" { linux /gentoo/root/@/boot/kernels/4.1.8-FC.01/vmlinuz root=tank/gentoo/root by=id elevator=noop quiet refresh initrd /gentoo/root/@/boot/kernels/4.1.8-FC.01/initrd }

Generating new zpool.cache file before/after reboot
ZFS is very sensitive about the data that is contained in the zpool.cache file and at this point, when we reboot, the information in it might not be completely accurate. To ensure we have a good cache file, we have instructed bliss-initramfs in the bootloader config above, to ignore the cachefile, and make a new one that is up-to-date. Once we do that, we can remake our initramfs file so that we have the latest correct information.

Generate the initramfs and move the file to its correct location
bliss-initramfs 1 4.1.8-FC.01 mv initrd-4.1.8-FC.01 /boot/kernels/4.1.8-FC.01/initrd

Final steps before reboot
emerge -ag dhcpcd syslog-ng

rc-update add zfs-mount boot rc-update add dhcpcd default rc-update add sshd default rc-update add syslog-ng default

passwd exit reboot

Remove zpool.cache refresh flag from bootloader configuration and remake initramfs
open '/boot/grub/grub.cfg' and remove the 'refresh' flag linux .... by=id elevator=noop quiet

bliss-initramfs 1 4.1.8-FC.01 mv initrd-4.1.8-FC.01 /boot/kernels/4.1.8-FC.01/initrd

Take a snapshot of your new system
Since we now have a working system, we will snapshot it in case we ever want to go back or recover files:

zfs snapshot tank/gentoo/root@2016-03-25-0000-01-INSTALL zfs snapshot tank/gentoo/home@2016-03-25-0000-01-INSTALL

You can view the contents of these snapshots by checking their respective and hidden .zfs directories:

ls /.zfs/snapshots ls /home/.zfs/snapshots

NOTE: We are naming the snapshots in this format because it's the format that my 'bliss-zfs-scripts' use, and it is also very readable.

Tools in Portage
emerge -ag sudo htop gentoolkit eix app-misc/screen app-text/tree

Bliss ZFS Scripts
The following scripts allow you to automatically:


 * Take snapshots of your pool
 * Replicate the pool to another pool (Full and Incremental Backups)
 * Clean the old snapshots on your pools.

You can download, customize, and install the scripts into your /usr/local/sbin directory. Github.

And that's it. Enjoy!