I recently reimaged my homelab hypervisor. I for quite a few years have run a Debian then Ubuntu Server box with libvirt/QEMU/KVM on top. It’s time for a seachange. I’ve been on the same Arch desktop install across 2 motherboards and 6 years without a single breaking upgrade. So with me redoing my install, it’s time to do a general guide to arch for desktop or server.
This guide is going to be focused more on the desktop side of things. Perhaps someday I’ll discuss how my server is provisioned, but for a teaser: ansible to setup; to setup libvirt/QEMU/KVM, to install packages (ovmf, zfs userland), to perform upgrades, and to setup the networking. But that is for another day.
My guide through this blog post will be a QEMU/KVM and so things like disks or networking are likely very different.
And before we begin, surely the right place to go is the official install guide: https://wiki.archlinux.org/title/Installation_guide
Getting started #
I’ll assume you have flashed an Arch iso, and you are sitting with a Linux prompt not too unlike:
root@archiso ~ #
This guide is primarily focused on btrfs, luks, and my initial OS configuration, three things not exceptionally documented on the Arch wiki. If you don’t know how to flash the iso, it maybe be best to turn back and learn how dd
or tools like etcher work.
SSHing into Archiso #
The Archiso is a live bootable environment that is stored on the installation media, which is most likely a flash drive, but historically we would refer to this as a LiveCD.
During the installation of the OS, we will need an internet connection. This provides a good opportunity to use SSH. If you have another computer (how else are you reading this), being able to use a terminal over SSH is likely more efficient than the default tty.
With our prompt let’s setup a new password, make it anything, this isn’t what your installing user will use.
root@archiso ~ # passwd
New password:
Retype new password:
passwd: password updated successfully
Check your IP:
root@archiso ~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 52:54:00:d0:69:2d brd ff:ff:ff:ff:ff:ff
inet 192.168.122.130/24 metric 100 brd 192.168.122.255 scope global dynamic enp1s0
valid_lft 2853sec preferred_lft 2853sec
inet6 fe80::5054:ff:fed0:692d/64 scope link
valid_lft forever preferred_lft forever
If you don’t see a network interface like enp1s0
you will need to troubleshoot networking, use a hardline if you can, most wifi drivers need to be installed later.
Then start ssh:
root@archiso ~ # systemctl start sshd
And login from a remote system:
[tolson@magni ~]$ ssh root@192.168.122.130
Note your IP is different.
Let’s get into it.
0. Setup and considerations #
It’s very important to highlight here that the changes we are making alter the disk and are not reversible. Take care in these steps. I recommend not following this guide on a dual boot system if this is your first try. Or at least, ensure you know which disk is being used where, or disconnect it during this process.
Analyze disks #
Let’s look at our disks by running two commands:
lsblk
root@archiso ~ # lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0 7:0 0 657.4M 1 loop /run/archiso/airootfs
sr0 11:0 1 812.3M 0 rom /run/archiso/bootmnt
vda 254:0 0 20G 0 disk
fdisk -l
root@archiso ~ # fdisk -l
Disk /dev/vda: 20 GiB, 21474836480 bytes, 41943040 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/loop0: 657.39 MiB, 689319936 bytes, 1346328 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Here we can see a list of block devices and a list of current partitions. In the case of my machine. /dev/loop0
is the Archiso, and /dev/vda
is our virtual hard disk, that we will be installing to.
When following this tutorial on QEMU/KVM, if you see
vda
disks, you probably are not using UEFI, which is required by this tutorial (in that case install OVMF).
But what about physical systems and various disks?
If you’re installing onto an NVME or SSD you might see:
# NVME
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
nvme0n1 259:0 0 931.5G 0 disk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:16 1 465.8G 0 disk
What if you have other drives and they are formatted?
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 1 915G 0 disk
├─sda1 8:1 1 450G 0 part
└─sda2 8:18 1 465.7G 0 part
Output like this would suggest your drives are already provisioned. Cross reference with fdisk output to see if you know the filesystem type:
Disk /dev/sdb: 465.76 GiB, 500107862016 bytes, 976773168 sectors
Disk model: Samsung SSD 840
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: E4CC0E6C-2095-46C7-9B72-DB96F5BC1EC6
Device Start End Sectors Size Type
/dev/sdb1 2048 34815 32768 16M Microsoft reserved
/dev/sdb2 34816 976771071 976736256 465.7G Microsoft basic data
1. Partition #
Again, what we do beyond here is potentially dangerous.
EFI partition #
Remember /dev/vda
is my install disk target, yours may be different.
You will be doing the instructions after each Command (m for help):
or prompt stanza.
t@archiso ~ # fdisk /dev/vda
Welcome to fdisk (util-linux 2.37.3).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x06c0fd55.
Command (m for help): g
Created a new GPT disklabel (GUID: CC8998D4-5773-934D-B07B-CB941BE9F5D0).
Command (m for help): n
Partition number (1-128, default 1): 1
First sector (2048-41943006, default 2048): <Press Your Enter Key>
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-41943006, default 41943006): +100M
Created a new partition 1 of type 'Linux filesystem' and of size 100 MiB.
Command (m for help): t
Selected partition 1
Partition type or alias (type L to list all): 1
Changed type of partition 'Linux filesystem' to 'EFI System'.
You should after entering all of this still have a Command(m for help):
prompt in front of you, but let’s think about where we are. We just created an EFI partition which is a small partition where our bootloader and other startup applications and data are stored. Learn more about this model here.
We pressed Enter for the first sector because we wanted to start at the nearest available space.
Boot partition #
Command (m for help): n
Partition number (2-128, default 2): 2
First sector (206848-41943006, default 206848): <Press Your Enter Key>
Last sector, +/-sectors or +/-size{K,M,G,T,P} (206848-41943006, default 41943006): +300M
Created a new partition 2 of type 'Linux filesystem' and of size 300 MiB.
We’ve now just created a boot partition that will be used for our GRUB install.
This includes:
- Our GRUB config
vmzlinux
- our statically linked linux kernelinitramfs-linux.img
- our initial RAM file system which will hand off its temporary root filesystem to our filesystem
If these parts don’t make sense follow the links, but for now don’t worry about it, the later steps take care of these pieces.
BTRFS partition #
Command (m for help): n
Partition number (3-128, default 3): 3
First sector (821248-41943006, default 821248): <Press Your Enter Key>
Last sector, +/-sectors or +/-size{K,M,G,T,P} (821248-41943006, default 41943006): <Press Your Enter Key>
Created a new partition 3 of type 'Linux filesystem' and of size 19.6 GiB.
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
Just like prior steps but we hit enter twice to take up the nearest sector and all remaining space. Then we write to disk.
Command recap #
This will not be done for later steps but because we had so much terminal output and explanation, here’s every keystroke you should have applied.
g
n
1
<Enter Key>
+100M
t
1
n
2
<Enter Key>
+300M
n
3
<Enter Key>
<Enter Key>
w
To swap or not #
TLDR: This guide will not provide this instruction, but you are free to explore it. Be warmed.
Some guides will recommend swap space. I chose not to because rarely do I need it, and if you do there is no discernible difference between a swap partition or a swap file*. If you want a swap partition in between Boot Partition and BTRFS Partition add a SWAP partition equal to two times your ram (a general rule of thumb).
However later steps will not refer to this partition method, refer to the linked documentation and pay close attention to if the swap exists in your fstab
later, and that you’ve run mkswap /dev/<your swap partition
* How I do swap:
- Create a swapfile:
touch /swapfile
- Disable BTRFS Copy-On-Write:
chattr +C /swapfile
- Permissions:
chmod 0600 /swapfile
- Size swap appropriately:
fallocate -l 32G /swapfile
- Make swap:
mkswap /swapfile
- Turn on:
swapon /swapfile
This can get more interesting with subvolume swap partitions but this works just fine.
2. Boot Filesystems #
Remember your partitions are numbered the same but partition 1 for me appears as: /dev/vda1
Format EFI partition #
root@archiso ~ # mkfs.vfat -F32 /dev/vda1
mkfs.fat 4.2 (2021-01-31)
Format Boot partition #
root@archiso ~ # mkfs.ext2 /dev/vda2
mke2fs 1.46.5 (30-Dec-2021)
Discarding device blocks: done
Creating filesystem with 307200 1k blocks and 76912 inodes
Filesystem UUID: b42448a0-1df3-4865-89af-00eb3c8e786c
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729, 204801, 221185
Allocating group tables: done
Writing inode tables: done
Writing superblocks and filesystem accounting information: done
3. Format BTRFS partition #
Setup LUKS #
root@archiso ~ # cryptsetup -y -v --cipher=aes-xts-plain64 --key-size=512 --hash=sha512 luksFormat /dev/vda3
WARNING!
========
This will overwrite data on /dev/vda3 irrevocably.
Are you sure? (Type 'yes' in capital letters): YES
Enter passphrase for /dev/vda3:
Verify passphrase:
Key slot 0 created.
Command successful.
cryptsetup -y -v --cipher=aes-xts-plain64 --key-size 512 --hash=sha512 7.48s user 0.93s system 45% cpu 18.399 total
This setups our LUKS encrypted volume. The manual page man cryptsetup
can be useful, so can cryptsetup benchmark
for choosing an algorithm.
Mount LUKS #
root@archiso ~ # cryptsetup luksOpen /dev/vda3 luks
It can be a fun checkpoint to look at
lsblk
andfdisk -l
for LVM and partitions, recall what it looked like at the beginning.
Format BTRFS #
root@archiso ~ # mkfs.btrfs -L archlinux /dev/mapper/luks
btrfs-progs v5.16
See http://btrfs.wiki.kernel.org for more information.
NOTE: several default settings have changed in version 5.15, please make sure
this does not affect your deployments:
- DUP for metadata (-m dup)
- enabled no-holes (-O no-holes)
- enabled free-space-tree (-R free-space-tree)
Label: archlinux
UUID:
Node size: 16384
Sector size: 4096
Filesystem size: 19.59GiB
Block group profiles:
Data: single 8.00MiB
Metadata: DUP 256.00MiB
System: DUP 8.00MiB
SSD detected: no
Zoned device: no
Incompat features: extref, skinny-metadata, no-holes
Runtime features: free-space-tree
Checksum: crc32c
Number of devices: 1
Devices:
ID SIZE PATH
1 19.59GiB /dev/mapper/luks
4. Create BTRFS subvolumes #
Mount BTRFS #
root@archiso ~ # mount -o compress=zstd /dev/mapper/luks /mnt
You can see the BTRFS formatted LUKS LVM device (word salad) is using Zstandard compression. Whenever we mount our root filesystem we will need to remember this, this is more complicated than mount /dev/vda /mnt
.
Create subvolumes #
root@archiso ~ # cd /mnt
root@archiso /mnt # btrfs subvolume create @
Create subvolume './@'
root@archiso /mnt # btrfs subvolume create @home
Create subvolume './@home'
root@archiso /mnt # btrfs subvolume create @log
Create subvolume './@log'
root@archiso /mnt # btrfs subvolume create @srv
Create subvolume './@srv'
root@archiso /mnt # btrfs subvolume create @pkg
Create subvolume './@pkg'
root@archiso /mnt # btrfs subvolume create @tmp
Create subvolume './@tmp'
root@archiso /mnt # cd /
root@archiso / # umount /mnt
root@archiso / # mount -o compress=zstd,subvol=@ /dev/mapper/luks /mnt
Let’s take a minute to appreciate how awesome this is. For example, in the case of a laptop with limited space, having access to POSIX file namespaces instead of individual partitions can save us pain. Traditionally we might make a root partition and a home partition. Resizing these with limited space can be a problem. Other benefits with subvolumes might be things like subvolume snapshotting… Many good things with BTRFS on a workstation.
Create filesystem directories #
root@archiso / # cd /mnt
root@archiso /mnt # mkdir -p {home,srv,var/{log,cache/pacman/pkg},tmp}
root@archiso /mnt # ls
home srv tmp var
Associate filesystem directories to subvolumes #
root@archiso /mnt # mount -o compress=zstd,subvol=@home /dev/mapper/luks home
root@archiso /mnt # mount -o compress=zstd,subvol=@log /dev/mapper/luks var/log
root@archiso /mnt # mount -o compress=zstd,subvol=@pkg /dev/mapper/luks var/cache/pacman/pkg
root@archiso /mnt # mount -o compress=zstd,subvol=@srv /dev/mapper/luks srv
root@archiso /mnt # mount -o compress=zstd,subvol=@tmp /dev/mapper/luks tmp
root@archiso /mnt # mkdir /mnt/boot
root@archiso /mnt # mount /dev/vda2 /mnt/boot
root@archiso /mnt # mkdir /mnt/boot/EFI
root@archiso /mnt # mount /dev/vda1 /mnt/boot/EFI
Again I’d like to recall
lsblk
, but this time highlight it’s interesting output for demonstration purposes:root@archiso /mnt # lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS loop0 7:0 0 657.4M 1 loop /run/archiso/airootfs sr0 11:0 1 812.3M 0 rom /run/archiso/bootmnt vda 254:0 0 20G 0 disk ├─vda1 254:1 0 100M 0 part /mnt/boot/EFI ├─vda2 254:2 0 300M 0 part /mnt/boot └─vda3 254:3 0 19.6G 0 part └─luks 252:0 0 19.6G 0 crypt /mnt/tmp /mnt/srv /mnt/var/cache/pacman/pkg /mnt/var/log /mnt/home /mnt
Cool now we can install Arch on top of our LUKS BTRFS filesystem!
5. Arch install #
Pacstrap the package bootstrapper #
We require these packages:
base base-devel linux-firmware grub efibootmgr dosfstools openssh os-prober mtools linux linux-headers mkinitcpio netctl dhcpcd vim zsh dialog network-manager-applet networkmanager
But if you want wifi consider:
wireless_tools wpa_supplicant
Supply all those packages to: pacstrap -i /mnt <the packages>
root@archiso /mnt # pacstrap -i /mnt base base-devel grub efibootmgr dosfstools openssh os-prober mtools linux linux-headers mkinitcpio netctl dhcpcd vim
==> Creating install root at /mnt
==> Installing packages to /mnt
Enter a selection (default=all):
resolving dependencies...
:: There are 2 providers available for resolvconf:
:: Repository core
1) openresolv 2) systemd-resolvconf
Enter a number (default=1): 2
looking for conflicting packages...
Packages (157) acl-2.3.1-2 archlinux-keyring [ ... Output removed for brevity ... ]
Total Download Size: 86.35 MiB
Total Installed Size: 1240.61 MiB
:: Proceed with installation? [Y/n] y
[ ... Output removed for brevity ... ]
I like systemd-resolvconf
as my DNS plugin, but maybe some healthy systemd skepticism is worth pointing out.
Generate filesystem table #
root@archiso /mnt # genfstab -U /mnt >> /mnt/etc/fstab
This fstab defines how block devices should be mounted on system startup.
cat /mnt/etc/fstab
and take a peek at our previously defined LUKS LVM devices and BTRFS formatting.
Change your “root” into the bootstrap system #
root@archiso /mnt # arch-chroot /mnt
[root@archiso /]#
You can see our prompt has changed a bit. It’s now as if we were on our installed system, learn more about chroot.
Setup encryption in the initial RAM filesystem #
mkinitcpio is the tool to setup and configure the initramfs. Normally during a kernel upgrade this is managed by the system. But on our first setup, we must do the needful.
[root@archiso /]# vim /etc/mkinitcpio.conf
You will see a line like:
HOOKS=(base udev autodetect modconf block filesystems keyboard fsck)
We want it to look like:
HOOKS=(base udev autodetect modconf block encrypt filesystems keyboard fsck)
Then generate our new initramfs.
[root@archiso /]# mkinitcpio -p linux
==> Building image from preset: /etc/mkinitcpio.d/linux.preset: 'default'
-> -k /boot/vmlinuz-linux -c /etc/mkinitcpio.conf -g /boot/initramfs-linux.img
[ ... Output removed for brevity ... ]
==> Image generation successful
Setup locale #
We have a few steps to do. A locale needs to be set to ensure proper text rendering.
[root@archiso /]# vim /etc/locale.gen
For me, a user in the US it should look like
[ ... Output removed for brevity ... ]
#en_SG ISO-8859-1
en_US.UTF-8 UTF-8
#en_US ISO-8859-1
[ ... Output removed for brevity ... ]
Generate:
[root@archiso /]# locale-gen
Generating locales...
en_US.UTF-8... done
Generation complete.
Setup system locale:
[root@archiso /]# localectl set-locale LANG=en_US.UTF-8
cat > /etc/locale.conf << EOF
LANG=en_US.UTF-8
EOF
Set root password #
[root@archiso /]# passwd
New password:
Retype new password:
passwd: password updated successfully
This is your root password, might not be the best security practice but I just set this to my user’s password. 💀
6. Configure boot loader #
Install #
[root@archiso /]# grub-install --target=x86_64-efi --bootloader-id=grub_uefi --recheck
Installing for x86_64-efi platform.
Let’s not forget to configure the locale:
[root@archiso /]# mkdir -p /boot/grub/locale
[root@archiso /]# cp /usr/share/locale/en\@quot/LC_MESSAGES/grub.mo /boot/grub/locale/en.mo
Configure LUKS and grub #
We need to grab our partition UUID.
[root@archiso /]# blkid /dev/vda3
/dev/vda3: UUID="ea3c5e4b-d8c7-4ee3-a1af-733cf80f8d44" TYPE="crypto_LUKS" PARTUUID="40d13c59-5146-0544-b694-38037ef9def0"
Edit our grub config file:
[root@archiso /]# vim /etc/default/grub
You will see a line like:
GRUB_CMDLINE_LINUX=""
We want it to look like:
GRUB_CMDLINE_LINUX="cryptdevice=UUID=ea3c5e4b-d8c7-4ee3-a1af-733cf80f8d44:root"
Of course just like with
/dev/vda
your UUID is going to be very different.
We also need to enable CRYPTODISK
:
You will see a line like:
#GRUB_ENABLE_CRYPTODISK=y
We want it to look like:
GRUB_ENABLE_CRYPTODISK=y
Quite simple, just an uncomment.
Generate the finalized config:
[root@archiso /]# grub-mkconfig -o /boot/grub/grub.cfg
7. Test setup #
[root@archiso /]# exit
root@archiso /mnt # reboot
Disconnect your boot media.
Hold onto your butts.
This process should go smooth but look at I broke my install, if it doesn’t.
8. Finish install - setup user #
On boot we probably wont have networking going:
[root@archiso /]# systemctl start NetworkManager
[root@archiso /]# systemctl enable NetworkManager
If you’re on wifi this could introduce additional challenges but mainly we want to enable NetworkManager on boot. SSHD we probably don’t always want on.
nmcli
andnmtui
can be useful for configuring wireless networking.
Let’s setup a user account and login. Enter back into the Arch linux shell with:
[root@archiso /]# groupadd -r autologin
[root@archiso /]# useradd -m -g users -G wheel,autologin -s /bin/zsh tolson
[root@archiso /]# passwd tolson
If you want to continue the install from another computer, let’s start SSH again:
[root@archiso /]# systemctl start sshd
And on remote machine:
ssh tolson
as normal.
Now we need to setup the wheel, or sudoers permissions. Let’s uncomment the wheel permission group.
[root@archiso /]# vim /etc/sudoers
You will see a line like:
# %wheel ALL=(ALL:ALL) ALL
We want it to look like:
%wheel ALL=(ALL) ALL
9. Setup a login manager #
This guide is for base system setup but we will discuss briefly system setup.
[tolson@magni ~]$ sudo pacman -S lightdm lightdm-gtk-greeter accountsservice xorg-server
[tolson@magni ~]$ sudo systemctl enable lightdm
Then add to the greeter config:
[tolson@magni ~]$ sudo vim /etc/lightdm/lightdm.conf
[Seat:*]
autologin-user=tolson
10. Install a Desktop Environment #
This guide is not specifically focused on this part. Check out these pages:
I personally use i3, and sway (mostly i3 for now). To see my specific install go look at my dotfiles: https://github.com/tolson-vkn/dotfiles/tree/master/i3
Install the base DE from the command line and then restart. Should be good from here!
Tips #
Here are some handy things along the way.
You should use timeshift #
Didn’t have a great spot for this but timeshift is fantastic. I like to configure with daily snapshots.
This setup makes arch, rolling distributions, or really any Linux distro painless for upgrades. Using tech like grub-btrfs
you can make your snapshots appear in your grub menu. So your workflow for full system (specifically kernel) upgrades is to create snapshot, and then upgrade. If anything breaks just go back.
I broke my install #
Run this to mount your system and get back in action:
root@archiso /mnt # cryptsetup luksOpen /dev/vda3 luks
root@archiso /mnt # mount -o compress=zstd,subvol=@ /dev/mapper/luks /mnt
root@archiso /mnt # mount -o compress=zstd,subvol=@home /dev/mapper/luks /mnt/home
root@archiso /mnt # mount -o compress=zstd,subvol=@log /dev/mapper/luks /mnt/var/log
root@archiso /mnt # mount -o compress=zstd,subvol=@pkg /dev/mapper/luks /mnt/var/cache/pacman/pkg
root@archiso /mnt # mount -o compress=zstd,subvol=@srv /dev/mapper/luks /mnt/srv
root@archiso /mnt # mount -o compress=zstd,subvol=@tmp /dev/mapper/luks /mnt/tmp
root@archiso /mnt # mount /dev/vda2 /mnt/boot
root@archiso /mnt # mount /dev/vda1 /mnt/boot/EFI
root@archiso /mnt # arch-chroot /mnt
Missing foreign languages #
Using the yay
AUR package manager, install:
yay -S ttf-ancient-fonts ttf-ubraille adobe-source-han-sans-otc-fonts adobe-source-han-serif-otc-fonts ttf-hannom ttf-paratype otf-gfs opensiddur-hebrew-fonts persian-fonts fonts-tlwg ttf-tibetan-machine
Alacritty not showing emoji #
I use Alacritty as my terminal. I noticed problems where emoji would show in the default font not my specifically installed noto-fonts-emoji
package.
The solution was to add this to the file: /etc/fonts/fonts.conf
, within <fontconfig></fontconfig>
:
<!-- Fallback fonts preference order -->
<alias>
<family>sans-serif</family>
<prefer>
<family>Noto Color Emoji</family>
<family>Noto Sans</family>
<family>Open Sans</family>
<family>Droid Sans</family>
<family>Roboto</family>
<family>Tholoth</family>
<family>Noto Sans Arabic</family>
</prefer>
</alias>
<alias>
<family>serif</family>
<prefer>
<family>Noto Color Emoji</family>
<family>Noto Sans</family>
<family>Noto Serif</family>
<family>Droid Serif</family>
<family>Roboto Slab</family>
<family>Tholoth</family>
<family>Noto Sans Arabic</family>
</prefer>
</alias>
<alias>
<family>monospace</family>
<prefer>
<family>Noto Color Emoji</family>
<family>Noto Sans</family>
<family>Noto Sans Mono</family>
<family>Inconsolata</family>
<family>Droid Sans Mono</family>
<family>Roboto Mono</family>
</prefer>
</alias>