site

Website's source files.
Log | Files | Refs | LICENSE

zfs-arch.org (21716B)


      1 #+TITLE: Maximal Anti-Glow-In-The-Dark Setup for Arch Linux With ZFS
      2 #+AUTHOR: Ryan
      3 #+EMAIL: ryan@ryanmj.xyz
      4 #+OPTIONS: num:nil
      5 
      6 
      7 This guide will show you how to set up an Arch Linux (the best Linux distro) install on a root filesystem formatted with ZFS (the best file system), thus making this the best possible Linux install.
      8 
      9 Not only that, but this will also be the most /secure/ Linux install, since (nearly) everything will be encrypted, thus preventing any would-be glow-in-the-darks from accessing your data.
     10 * Imperfections
     11 Currently there are two problems that exist with this install (listed below). If you have solutions do not hesitate to [[mailto:ryan@ryanmj.xyz][email me]] your fix!
     12 
     13 Firstly, we need to have separate ~/boot~ and ~/~ partitions, which is fine, but at boot time you'll need to put in ~/boot~'s password twice. This is apparently fixable (even after install) I just haven't figured it out yet. 
     14 
     15 The current fix is to just have your computer on all the time.
     16 
     17 Secondly, there is this line from the [[https://wiki.archlinux.org/index.php/Install_Arch_Linux_on_ZFS][Arch Wiki]] that concerns me:
     18 #+BEGIN_QUOTE
     19 You can also create your ROOT dataset without having to specify mountpoint to / since GRUB will mount it to / anyway. That gives you possibility to boot into some old versions of root just by cloning it and putting as menuentry of GRUB.
     20 #+END_QUOTE
     21 
     22 The article goes on to show you how to make the dataset in this fashion, but I wasn't able to get it working! When it came time to mount the ZFS datasets to install the OS I was unable to mount ~zroot/ROOT/default~ to ~/~ at all, it would just fail. This might mean that I can't boot snapshots as ~/~ from GRUB, which would suck, and I'm not sure if this is fixable after install.  
     23 
     24 I could fix the first problem by using legacy datasets (they're called /legacy/... they must be bad!), but that would make me feel like I copped out. I'd much rather use the native, modern ZFS datasets instead.
     25 
     26         
     27 * The ISO
     28 Unless you live in the future where ZFS has been re-released under the GPL then ZFS is not an official part of the Linux project, and so it is not included in the normal Arch Linux kernel package (or the normal install ISO). As a result, some extra install steps are necessary.
     29 
     30 If you /don't/ run Arch Linux, you can use [[https://github.com/eoli3n/archiso-zfs][this script]] on a running Arch Linux install image and it should make it ZFS ready (I have not tried it myself though). If you /do/ run Arch, then you can set up your own Arch Linux install image, which is preferable anyway because you can include any package you want in the ISO.
     31 
     32 To create the Arch Live ISO:
     33 #+begin_src shell
     34   cp -r /usr/share/archiso/configs/releng archlive
     35   cd archlive
     36 #+end_src
     37 
     38 Now, add this text to the bottom of ~pacman.conf~:
     39 #+begin_src conf
     40 [archzfs]
     41 Server = https://archzfs.com/$repo/x86_64
     42 Server = https://mirror.sum7.eu/archlinux/archzfs/$repo/x86_64
     43 Server = https://mirror.biocrafting.net/archlinux/archzfs/$repo/x86_64
     44 SigLevel = Optional TrustAll
     45 
     46 [archzfs-kernels]
     47 Server = https://end.re/$repo/
     48 SigLevel = Optional TrustAll
     49 
     50 #+end_src
     51 
     52 You can also (optionally) uncomment ~Color~ and add ~ILoveCandy~.
     53 
     54 Now you copy the ~pacman.conf~ to ~airootfs~:
     55 
     56 #+begin_src shell
     57 cp pacman.conf airootfs/etc/.
     58 #+end_src
     59 
     60 Now insert ~zfs-linux~ to the bottom of ~packages.x86_64~. Optionally, you can also insert the name of any Arch Linux package you want. I'm adding in ~joe~ and ~networkmanager~ to make the install a bit easier for me. You could even add a desktop environment, browser, etc. if you wanted to - in fact, that would make some of the later steps a bit easier, as you'd be able to copy-paste from the browser (make sure you also install a terminal emulator if you go that route... I made that mistake)!
     61 
     62 Now, we can build the image:
     63 
     64 #+begin_src shell
     65 sudo mkarchiso -v .
     66 #+end_src
     67 
     68 Now all that's left to do with the image is to write it to a disk or a USB stick. If you're using a thumb drive like me, you need to find out which device your USB is mapped to (using ~fdisk~). It will probably be something along the lines of ~/dev/sdX~ with ~X~ being some letter. For example, mine was mapped to ~/dev/sde~. Once you find that out, write to the drive with ~dd~.
     69 
     70 #+begin_src shell
     71 sudo dd if=out/archlinux*.iso of=/dev/sde bs=1M status=progress
     72 #+end_src
     73 
     74 Alternatively, you could use BalenaEtcher to write to the drive... but we've been using the terminal the entire time, might as well get across the finish line with it (plus we won't have to install any annoying AUR packages)!
     75 
     76 * Installing the OS
     77 Now comes the scary part... having to actually write to your disk.
     78 
     79 Once booted into the ISO you should make sure that the ZFS kernel module is loaded:
     80 
     81 #+begin_src shell
     82 lsmod | grep zfs -i
     83 #+end_src
     84 
     85 ** Setting Up the Partitions
     86 */THIS IS THE POINT OF NO RETURN/* btw.
     87 
     88 Just like with the USB stick earlier we need to find out which device your drive is mapped to. Mine was mapped to ~/dev/sda~, but make sure you adapt the following information to your device.
     89 
     90 To signify the beginning of a new era of ZFS we will wipe the disk of its partitioning information:
     91 
     92 #+begin_src shell
     93 sgdisk --zap-all /dev/sda
     94 #+end_src
     95 
     96 From that, we will create new partitions for our system to live on. This is what the drive will look like:
     97 
     98 | Device    | Size             | Type  | Mountpoint |
     99 |-----------+------------------+-------+------------|
    100 | /dev/sda1 | 512M             | fat32 | /boot/efi  |
    101 | /dev/sda2 | 5G               | ext4  | /boot      |
    102 | /dev/sda3 | 4G               | swap  | swap       |
    103 | /dev/sda4 | Rest of the disk | zfs   | /          |
    104 
    105 ~/dev/sda1~, ~/dev/sda2~, and ~/dev/sda4~ should all be exactly as I have configured them here. ~/dev/sda3~, however, can be any size you want it to be (it's also the only partition you don't technically need). ZFS is rather memory hungry so I would recommend a hefty swap partition for any machine with <= 8G memory. 4G is a good number for a 16G machine, so you should adjust accordingly.
    106 
    107 To partition we will use ~gdisk~. Below is my usage of ~gdisk~ as an example. To adapt the output to your use, on every line that begins with `Last Sector', simply change the value to however large you want the partition to be (if you want a 8G swap partition, replace the `+4G' with `+8G'). For any empty lines, just press enter.
    108 
    109 #+begin_src shell
    110   gdisk /dev/sda
    111 
    112 GPT fdisk (gdisk) version 1.0.5
    113 
    114 Partition table scan:
    115   MBR: not present
    116   BSD: not present
    117   APM: not present
    118   GPT: not present
    119 
    120 Creating new GPT entries in memory.
    121 
    122 Command (? for help): n
    123 Partition number (1-128, default 1):
    124 First sector (34-62914526, default = 2048) or {+-}size{KMGTP}:
    125 Last sector (2048-62914526, default = 62914526) or {+-}size{KM
    126 Current type is 8300 (Linux filesystem)
    127 Hex code or GUID (L to show codes, Enter = 8300): ef00
    128 Changed type of partition to 'EFI system partition'
    129 
    130 Command (? for help): n
    131 Partition number (2-128, default 2):
    132 First sector (34-62914526, default = 1050624) or {+-}size{KMGTP}:
    133 Last sector (1050624-62914526, default = 62914526) or {+-}size{KMGTP}: +5G
    134 Current type is 8300 (Linux filesystem)
    135 Hex code or GUID (L to show codes, Enter = 8300):
    136 Changed type of partition to 'Linux filesystem'
    137 
    138 Command (? for help): n
    139 Partition number (3-128, default 3):
    140 First sector (34-62914526, default = 11536384) or {+-}size{KMGTP}:
    141 Last sector (11536384-62914526, default = 62914526) or {+-}size{KMGTP}: +4G
    142 Current type is 8300 (Linux filesystem)
    143 Hex code or GUID (L to show codes, Enter = 8300): 8200
    144 Changed type of partition to 'Linux swap'
    145 
    146 Command (? for help): n
    147 Partition number (4-128, default 4):
    148 First sector (34-62914526, default = 19924992) or {+-}size{KMGTP}:
    149 Last sector (19924992-62914526, default = 62914526) or {+-}size{KMGTP}:
    150 Current type is 8300 (Linux filesystem)
    151 Hex code or GUID (L to show codes, Enter = 8300): bf00
    152 Changed type of partition to 'Solaris root'
    153 
    154 Command (? for help): w
    155 
    156 Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
    157 PARTITIONS!!
    158 
    159 Do you want to proceed? (Y/N): Y
    160 OK; writing new GUID partition table (GPT) to /dev/sda.
    161 The operation has completed successfully.
    162 #+end_src
    163 
    164 You should get a disk that looks something like this (from ~fdisk~):
    165 
    166 #+begin_src shell
    167 Device        Start      End  Sectors  Size Type
    168 /dev/sda1      2048  1050623  1048576  512M EFI System
    169 /dev/sda2   1050624 11536383 10485760    5G Linux filesystem
    170 /dev/sda3  11536384 19924991  8388608    4G Linux swap
    171 /dev/sda4  19924992 62914526 42989535 20.5G Solaris root
    172 #+end_src
    173 
    174 ** Creating ~/boot~, ~/boot/efi~, and ~swap~
    175 *** ~/boot/efi~
    176 That was the hard part. The next step is to create the auxiliary filesystems (everything except ~/~). To crate the EFI system partition:
    177 
    178 #+begin_src shell
    179 mkfs.fat -F32 /dev/sda1
    180 #+end_src
    181 
    182 Note the `1' at the end of ~/dev/sda1~.
    183 *** ~/boot~
    184 Now to set up the encrypted ~/boot~ partition, which needs to be a separate partition from ~/~ due to GRUB not being completely compatible with ZFS. 
    185 
    186 #+begin_src shell
    187 cryptsetup luksFormat --type luks1 /dev/disk/by-id/xxx
    188 #+end_src
    189 
    190 Replace the `xxx' at the end of the command with the ID of ~/dev/sda2~ (remember, you can use tab completion on filepaths). ID's usually have a `partX' at the end which makes it easier to figure out. Put in a nice, strong password to encrypt the partition. Also, it is very imperative that the encryption type be ~luks1~, otherwise the system will not boot.
    191 
    192 Now to bring up the newly encrypted partition and format it:
    193 
    194 #+begin_src shell
    195 cryptsetup open /dev/disk/by-id/xxx cboot
    196 mkfs.ext4 /dev/mapper/cboot
    197 #+end_src
    198 
    199 Obviously, replace `xxx' with your disk ID. `cboot' at the end there is what I'm deciding to call that partition, you can give it any name you wish.
    200 *** ~swap~
    201 
    202 #+begin_src shell
    203 cryptsetup open --type plain --key-file=/dev/urandom /dev/disk/by-id/xxx cswap
    204 mkswap /dev/mapper/cswap
    205 swapon /dev/mapper/cswap
    206 #+end_src
    207 
    208 Now replace ~/dev/disk/by-id/xxx~ with the ID of ~/dev/sda3~. Like with the boot partition you can name the partition whatever you want, just replace `cswap' with your desired name.
    209 ** ZFS root Partition, or ~/~  
    210 This is what we've been waiting for...
    211 *** ~zpool~ creation 
    212 
    213 First we must determine the ~ashift~ value for our ~zpool~:
    214 
    215 #+begin_src shell
    216 lsblk -S -o NAME,PHY-SEC
    217 #+end_src
    218 
    219 | Value | Ashift |
    220 |-------+--------|
    221 | 512   |      9 |
    222 | 4k    |     12 |
    223 
    224 
    225 #+begin_src shell
    226 zpool create -f -o ashift=12 -o autoexpand=on -R /mnt \
    227              -O acltype=posixacl \
    228              -O atime=off \
    229              -O xattr=sa        \
    230              -O dnodesize=legacy    \
    231              -O normalization=formD \
    232              -O mountpoint=none     \
    233              -O canmount=off        \
    234              -O devices=off     \
    235              -O encryption=aes-256-gcm  \
    236              -O keyformat=passphrase    \
    237              -O keylocation=prompt  \
    238          zroot /dev/disk/by-id/xxx
    239 #+end_src
    240 
    241 ~zroot~ is what I've decided to call this ~zpool~.
    242 **** Customization
    243 ***** ~ashift~
    244 The ashift values are for performance and your system will work if you get them 'wrong'. In fact, the Arch Wiki recommends always using ~ashift=12~ for compatibility with other ~zpools~.
    245 ***** ~atime~
    246 It's almost never useful to know the access time of a file so I just disable it altogether. It serves only to slow down your computer, especially when using a CoW filesystem like ~zfs~. Some would say this messes up Mail programs such as ~mutt~, but I have a fix for this.
    247 
    248 If you still want atimes, swap ~atime=off~ for ~atime=on~. I believe this is the equivalent to 'stricatime' on other filesystems.
    249 
    250 You could also go for 'relatime', where an access time is only updated if the old access time is more than a day old, or if the modification time or change time are more recent. To do this, simply swap any line you have involving atime with ~relatime=on~.
    251 ***** Compression
    252 This is pretty useless on most people's root filesystem because most of your data is probably media, which is already compressed. This will likely only slow down your system and not save you much space. Nevertheless, if you want to have it, simply add this line: ~-O compression=lz4~.
    253 
    254 *** ~dataset~ creation
    255 #+begin_src shell
    256   # General datasets
    257 zfs create -o mountpoint=none zroot/data
    258 zfs create -o mountpoint=none zroot/ROOT
    259 zfs create -o mountpoint=/ -o canmount=noauto zroot/ROOT/default
    260 # Home datasets
    261 zfs create -o mountpoint=/home zroot/data/home
    262 zfs create -o mountpoint=/root zroot/data/home/root
    263 zfs create -o mountpoint=/home/ryan zroot/data/home/ryan
    264 zfs create -o mountpoint=/home/ryan/.local zroot/data/home/ryan/local
    265 zfs create -o mountpoint=/home/ryan/.local/share zroot/data/home/ryan/local/share 
    266 # If you're a degenerate who plays vidya
    267 zfs create -o mountpoint=/home/ryan/.local/share/Steam zroot/data/home/ryan/local/share/Steam
    268 zfs create -o mountpoint=/home/ryan/.cache zroot/data/home/ryan/cache 
    269 zfs create -o mountpoint=/home/ryan/.cache/yay zroot/data/home/ryan/cache/yay
    270 # If you want to use mailclients such as mutt
    271 zfs create -o mountpoint=/home/ryan/.Maildir zroot/data/home/ryan/mail
    272 # System datasets
    273 zfs create -o mountpoint=/var -o canmount=off zroot/var
    274 zfs create zroot/var/log
    275 zfs create -o mountpoint=/var/lib -o canmount=off zroot/var/lib
    276 zfs create zroot/var/lib/libvirt
    277 zfs create zroot/var/lib/docker
    278 
    279 # Set zpool as bootable
    280 zpool set bootfs=zroot/ROOT/default zroot
    281 #+end_src
    282 *** Mounting 
    283 Export the ~zpool~ (this is required), then import it (no, the ~/dev/disk/by-id~ isn't a mistake) and mount.
    284 
    285 #+begin_src shell
    286   zpool export zroot
    287   zpool import -d /dev/disk/by-id -R /inst zroot
    288   zfs load-key zroot
    289   zfs mount zroot/ROOT/default
    290   zfs mount -a
    291 #+end_src
    292 
    293 If you have errors during this step, try exporting ~zroot~ again and then reimporting it (to a new directory, i.e. replace ~/inst~) with different settings. ~ls~ the mountpoint to make sure it's empty. You can also ~df~ the mountpoint after mounting, and if the output says ~airootfs~ there has been an error, it should be ~zroot/ROOT/default~.
    294 
    295 If all is good we need to mount the auxiliary filesystems:
    296 
    297 #+begin_src shell
    298 mkdir /inst/boot
    299 mount /dev/mapper/cboot /inst/boot
    300 mkdir /inst/boot/efi
    301 mount /dev/sda1 /inst/boot/efi
    302 #+end_src
    303 
    304 Lastly, we need to copy the ZFS cache:
    305 
    306 #+begin_src shell
    307 cp /etc/zfs/zpool.cache /inst/etc/zfs/zpool.cache
    308 #+end_src
    309 
    310 If there is an error about the cache file not existing, then:
    311 
    312 #+begin_src shell
    313 zpool set cachefile=/etc/zfs/zpool.cache zroot
    314 cp /etc/zfs/zpool.cache /inst/etc/zfs/zpool.cache
    315 #+end_src
    316 
    317 *** ~pacstrap~
    318 If you haven't already we need to set up an internet connection. If you followed my instructions to crate an Arch ISO then yours should have NetworkManager, so we can set up networking like so:
    319 
    320 #+begin_src shell
    321 systemctl start NetworkManager
    322 nmcli device wifi connect "ssid" password "networkpassword"
    323 #+end_src
    324 
    325 (Obviously replace ssid with your ssid etc. etc.)
    326 
    327 ~pacman~ will fail to get the zfs-arch repos due to a gpg-related error. We can fix this by importing the arch-zfs gpg key like so:
    328 
    329 #+begin_src shell
    330 curl https://archzfs.com/archzfs.gpg > archzfs.gpg
    331 pacman-key --add archzfs.gpg
    332 #+end_src
    333 
    334 Now we can ~pacstrap~ (make sure to replace ~intel-ucode~ with ~amd-ucode~ if you have an AMD processor)!
    335 
    336 #+begin_src shell
    337   pacstrap -i /inst base base-devel zfs-linux linux-headers linux-firmware intel-ucode zsh go git python cmake networkmanager joe emacs
    338   cp /etc/pacman.conf /inst/etc/.
    339 #+end_src
    340 
    341 *** ~fstab~ and ~crypttab~
    342 To generate the fstab file:
    343 
    344 #+begin_src shell
    345   genfstab -U -p /inst >> /inst/etc/fstab
    346 #+end_src
    347 
    348 Edit the ~/inst/etc/fstab~ file and remove any entries related to ZFS (we will mount them the ZFS way). Also, replace the UUID's of the ~cswap~ and ~cboot~ partitions with ~/dev/mapper/cswap~ and ~/dev/mapper/cboot~ respectively. 
    349 
    350 Sample fstab:
    351 #+begin_src 
    352 # Static information about the filesystems.
    353 # See fstab(5) for details.
    354 
    355 # <file system> <dir> <type> <options> <dump> <pass>
    356 # /dev/mapper/cboot
    357 /dev/mapper/cboot	/boot     	ext4      	rw,relatime	0 2
    358 
    359 # /dev/sda1
    360 UUID=CE42-9249      	/boot/efi 	vfat      	rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro	0 2
    361 
    362 # /dev/mapper/cswap
    363 /dev/mapper/cswap	none      	swap      	defaults  	0 0
    364 
    365 #+end_src
    366 
    367 Lastly, edit ~/inst/etc/crypttab~ and add this line to the bottom:
    368 
    369 #+begin_src
    370 cswap          /dev/disk-by-id/xxx                                    /dev/urandom            swap,cipher=aes-cbc-essiv:sha256,size=256
    371 #+end_src
    372 
    373 You will need to insert the id of your swap partition manually. 
    374 
    375 Insert a new line at the very bottom of the file (or just make sure it ends with an empty line) and save.
    376 
    377 *** Configuring the System
    378 To begin configuration of the system we need to ~arch-chroot /inst~.
    379 
    380 **** Set Up the Kernel 
    381 Edit the file ~/etc/mkinitcpio.conf~, delete the line that begins with `HOOKS=' and replace it with 
    382 
    383 #+begin_src 
    384 HOOKS=(base udev autodetect modconf block keyboard zfs encrypt filesystems)
    385 #+end_src
    386 
    387 Then run:
    388 
    389 #+begin_src shell
    390 mkinitcpio -P
    391 #+end_src
    392 
    393 
    394 **** GRUB
    395 Edit the file ~/etc/default/grub~ and replace `GRUB_CMDLINE_LINUX' with:
    396 
    397 #+begin_src 
    398 GRUB_CMDLINE_LINUX="zfs=zroot/ROOT/default rw cryptdevice=/dev/sda2:cboot"
    399 #+end_src
    400 
    401 Uncomment ~GRUB_ENABLE_CRYPTODISK=y~ and save the file. To install GRUB:
    402 
    403 #+begin_src shell
    404 grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB
    405 ZPOOL_VDEV_NAME_PATH=1 grub-mkconfig -o /boot/grub/grub.cfg
    406 #+end_src
    407 
    408 **** Misc
    409 Remember to:
    410 - Set the hostname in ~/etc/hostname~
    411 - Generate locales
    412 - Create a user and set the password
    413 - Set the root password
    414 - Set up your timezone and enable ~ntpd~
    415 - Change your shell to ZSH (THIS IS REQUIRED)
    416 - Install ~X~ and ~pulseaudio~ (make sure you have the right ~X~ drivers [I made that mistake...])
    417 - Set up a ~yay~/~AUR~ managers
    418 - enable systemd services (NM, sshd, etc.)
    419 
    420 
    421 **** Configure ZFS
    422 
    423 The last bit of required ZFS configuration is to set it up for automounting and autoconfiguring. 
    424 
    425 #+begin_src shell
    426 # Set the hostid
    427 zgenhostid $(hostid)
    428 # Set up the cachefile and auto-import it
    429 zpool set cachefile=/etc/zfs/zpool.cache zroot
    430 systemctl enable zfs-import-cache
    431 systemctl enable zfs-import.target
    432 # Set up zed
    433 mkdir /etc/zfs/zfs-list.cache/
    434 touch /etc/zfs/zfs-list.cache/zroot
    435 ln -s /usr/lib/zfs/zed.d/history_event-zfs-list-cacher.sh /etc/zfs/zed.d
    436 systemctl enable zfs-zed.service
    437 systemctl enable zfs.target
    438 #+end_src
    439 
    440 Now start ~zed~ through the command line, and ~cat~ ~/etc/zfs/zfs-list.cache/zroot~. It should be empty, to populate it, make a change to the filesystem:
    441 
    442 #+begin_src shell
    443 zfs set atime=on zroot/data/home/ryan/mail
    444 #+end_src
    445 
    446 ~cat~ the same file again and now it should be full. If you don't have the mail dataset, just make that same change to any other dataset, then just undo it by setting ~atime=off~ again.
    447 
    448 **** Restart
    449 */DO NOT SKIP THIS/*
    450 Double check everything first!
    451 #+begin_src shell
    452 exit # the arch-chroot
    453 umount /inst/boot -R
    454 zfs umount -a
    455 zpool export zroot
    456 swapoff -a
    457 #+end_src
    458 
    459 *NOW* you may reboot.
    460 
    461 * Post-Install Configuration
    462 NOTE: All of the following commands new to run as root.
    463 #+begin_src conf
    464 ** Scrub
    465 Scrub is a feature of ZFS to prevent bitrot, a phenonenon in which a drive wears out and some of the data on it slowly becomes corrupted. ZFS has the ability to scan for and prevent this from happening, a feature called 'scrub'. To preiodically scrub your zpool you will first need to set up an AUR helper, I'll be using ~yay~. Then, enable the systemd service like so:
    466 
    467 #+begin_src shell
    468 yay -Syu systemd-zpool-scrub
    469 systemctl enable zpool-scrub@zroot.timer
    470 #+end_src
    471 ** zfs-arch gpg key
    472 Having the ~SigLevel TrustAll~ at the bottom of ~pacman.conf~ is rather unsafe, so we're going to set up archzfs's pgp key.
    473 The following steps include:
    474 - Setting up the Arch Linux packages keyring
    475 - Set up a new keyserver (if necessary)
    476 - Add the archzfs pgp key and verify it
    477 
    478 #+begin_src shell
    479 pacman-key --init
    480 pacman-key --populate archlinux
    481 pacman-key -r DDF7DB817396A49B2A2723F7403BD972F75D9D76
    482 pacman-key --lsign-key DDF7DB817396A49B2A2723F7403BD972F75D9D76
    483 pacman -Syu
    484 #+end_src
    485 
    486 If the third step fails then you can append the following line to ~/etc/pacman.d/gnupg/gpg.conf~:
    487 
    488 #+begin_src 
    489 keyserver hkp://ipv4.pool.sks-keyservers.net:11371
    490 #+end_src
    491 
    492 You should also delete any other line that starts with 'keyserver'. If that fails too, look up other trusted keyservers to try.
    493 
    494 * Fin
    495 At this point your ZFS-on-root operating system is fully configured and ready to go. Make sure you know how ZFS works if you're going to continue using it and to make full use of the filesystem's features. I recommend reading the articles below for more information. Now have fun with your future-proofed system!
    496 
    497 * Sources
    498 Most of the information in this comes from other sources online rather than myself. Here are the ones that were the most helpful (in no particular order):
    499 
    500 - [[https://artnoi.com/blog/zfsarch.html][Artnoi's Arch ZFS on Root]]
    501 - [[https://wiki.archlinux.org/index.php/Install_Arch_Linux_on_ZFS][Arch Wiki's ZFS Install Guide]]
    502 - [[https://wiki.archlinux.org/index.php/User:Altercation/Bullet_Proof_Arch_Install][Arch Wiki's User Guide to Installing Btrfs]]
    503 - [[https://www.pavelkogan.com/2014/05/23/luks-full-disk-encryption/][Pavel Kogan's Article on Full Disk Encryption]]
    504 - [[https://wiki.archlinux.org/index.php/ZFS][Arch Wiki's Article on ZFS]]
    505 - [[https://wiki.archlinux.org/index.php/Archiso][Arch Wiki's Guide on Arch ISOs]]
    506 - [[https://wiki.archlinux.org/index.php/Pacman/Package_signing][Arch Wiki's Article on GPG Keys In ~pacman~]]