Arch Linux Notes

This page is a living document intended to save time for my future self in case the same issues ever crop up again. It’s based on my experience with running Arch on a Raspberry Pi 2, a Lenovo Flex 4, a ThinkPad P50, and a ThinkPad P51.

Arch is surprisingly stable if you remember the single most important post-install step: subscribe to the official news feed for breaking changes!

Arch screenshot

OS

Network

Display

Miscellaneous

Recovering from a bad upgrade

I once ran a pacman -Syu that spat out a bunch of errors, probably due to an unfortunate interaction between package versions available at the time. After lazily crossing my fingers and restarting the computer, I got a boot error (of course):

Failed to execute /init (error -13)
Starting init: /sbin/init exists but couldn't execute it (error -13)
Starting init: /bin/init exists but couldn't execute it (error -13)
Starting init: /bin/sh exists but couldn't execute it (error -13)
Kernel panic - not syncing: No working init found. Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.

Some weeks later I crossed my fingers and ran the upgrade command again, which fixed everything. How do you run commands on a system that you can’t even boot into? I followed this advice to use arch-chroot. Cue painfully detailed guide to arch-chroot:

  1. Before turning on the computer, plug in a USB stick with Arch on it. Also plug in an ethernet cable if your planned fix requires a connection.

  2. Turn on the computer and go into BIOS by hitting some manufacturer-specific key combination after the screen turns on (e.g. Fn+F2 on my Lenovo laptop). Find the boot priority list and reorder it so that the USB drive has the highest priority. Save, exit, and boot into USB when asked.

  3. Now you have a command prompt. This is where you’ll be using arch-chroot. Pleeease don’t blindly run this snippet as a script!

    # First, list all partitions and take note of the one that seems like your computer's root filesystem, e.g. /dev/sda8
    fdisk -l
    
    # Mount that drive
    mount /dev/sda8 /mnt
    
    # Enter your computer's root filesystem as root
    arch-chroot /mnt
    
    # Do whatever's necessary to fix the original problem (in my case, another upgrade attempt)
    pacman -Syu
    
    # Leave the chroot environment
    exit
    
    # Unmount the filesystem
    umount /mnt
    
    # Done!
    reboot
    
  4. As the computer reboots, go back into BIOS and move GRUB back to highest boot priority. Boot into your hopefully working system and remove the USB drive.

Using an external hard drive

External HDDs not marketed specifically for Mac are typically formatted as NTFS, the file system used by Windows. It’s best to keep NTFS if you ever plan to access your HDD from Windows, in which case you’ll need to do a little extra setup for Linux:

# First, plug the HDD into your computer and verify that it can be detected
lsusb

# Check that the kernel logs contain fairly detailed info about the HDD. If all you see is a few generic lines about a new USB device being detected, try restarting the computer
dmesg | tail -n 20

# List all partitions and find the one that seems like your HDD, e.g. /dev/sdb1
# (Note that NTFS drives might show up as type "fuseblk")
sudo fdisk -l

# Install ntfs-3g, which adds NTFS support to `mount`
sudo pacman -S ntfs-3g

# Create the mount point at /mnt/whatever-name-you-want
sudo mkdir /mnt/seagate

# Mount the partition you found from `fdisk -l`
sudo mount -o rw,user,async -t ntfs-3g /dev/sdb1 /mnt/seagate

# Unmount when done (before you unplug the HDD)
sudo umount /mnt/seagate

Make sure to provide async as a mount option instead of sync! The latter absolutely kills write performance on NTFS; we’re talking less than 100 kB/s.

Freeing up disk space

When uninstalling packages, always use pacman -Rs to include would-be orphans.

Pacman doesn’t delete old package versions, so you’ll need to do so yourself after package upgrades:

$ paccache -r
==> finished: 523 packages removed (disk space saved: 1.75 GiB)

Pacgraph shows your largest installed packages, which you can then remove if no longer needed.

The systemd journal can grow up to 4 GiB. If you don’t need all those logs, you can cap it to a lower value.

I had Docker for a while and later decided to uninstall it. Deleting /var/lib/docker freed up 8.1 GB.

Increasing the file watch limit

Many applications that watch your filesystem for changes can hit the OS’s (usually rather small) default limit on the number of files that can be simultaneously watched. I’ve personally run into this issue with Android Studio, Webpack, Watchman, and Syncthing.

Consider this the missing step in the Arch setup guide: drastically bumping up the inotify watch limit.

Booting UEFI with an existing EFI partition

GRUB was presenting me with its own slow-ass shell instead of an OS selection menu. The problem was that the live USB had installed some rather important files into the root filesystem’s /boot folder instead of the EFI partition.

I had mistakenly been under the impression that mounting the existing EFI partition (used by Windows) to the root filesystem’s /boot was unnecessary because both already existed and had stuff in them. Reinstalling with the partition mounted fixed things.

Ditching GRUB (only for UEFI systems)

GRUB is the kitchen sink bootloader. Systemd comes with its own UEFI bootloader that’s much simpler and works perfectly fine if all you need is an OS selection menu. As explained in the guide, just enable systemd-boot and create the two files arch.conf and loader.conf.

Suspending after inactivity

In xfce4-power-manager-settings I specified that my laptop should go to sleep after an hour of inactivity, but that setting never seemed to work. The fix is to just edit one line in one file, as described here.

Manually connecting to a WPA network

TLDR of the Arch guide (run as root):

ip link set wlp4s0 up
wpa_supplicant -D nl80211,wext -i wlp4s0 -c <(wpa_passphrase "ssid" "password")
# (Switch to another TTY at this point)
dhchpd
ping 8.8.8.8

Connecting to an L2TP/IPsec VPN

Just to be safe, uninstall all of the following packages: openswan, strongswan, networkmanager-openswan, networkmanager-strongswan, and networkmanager-libreswan. I couldn’t get any of these to work. Openswan seems capable but there’s no way I’m going to run through this gauntlet for a single VPN connection if I can avoid it.

Install networkmanager, libreswan, and networkmanager-l2tp. (It’s important to install networkmanager-l2tp last!) Then add the VPN entry as usual by right-clicking the NetworkManager applet or running nm-connection-editor.

When setting up the VPN entry, go into “IPsec Settings” and check “Enable IPsec tunnel to L2TP host”. You may also need to uncheck “Perfect Forward Secrecy”.

Update 2017-07-08: Due to a Linux kernel regression, you supposedly now must also install linux-lts and then run sudo grub-mkconfig. I still haven’t gotten it working, though.

Getting Intel Wireless 8260 card to work

Trying to activate my WiFi card with ip link set wlp4s0 up failed with a vague RTNETLINK answers: Input/output error message. Turns out that version 22 of the Linux kernel’s firmware for my particular WiFi card was problematic. You can see what firmware version you’re on by running dmesg | grep 'iwlwifi.*loaded'.

The solution was to force Linux to use the previous version of the firmware by disabling the latest version. As root:

# Stop kernel module "iwlwifi", which will need to be restarted. (Not sure what iwlmvm is, but `rmmod iwlwifi` complains that it's in the way)
rmmod iwlmvm
rmmod iwlwifi

# Rename the firmware file so that Linux won't find it
cd /lib/firmware
mv iwlwifi-8000C-22.ucode iwlwifi-8000C-22.bak

# Re-enable modules
modprobe iwlwifi
modprobe iwlmvm

Since I was setting up Arch at my office without the luxury of ethernet, I actually ended up having to go through this process twice: once on the live USB and again on my laptop’s instance of Arch.

Fixing the default LaTeX font

Rendering a LaTeX file to PDF works fine after installing texlive-core, but what’s up with the fugly text? Zooming in reveals that the bitmap version of Computer Modern is being used. We need to specify an infinitely scalable vector font instead.

The first step of the fix is to enable Latin Modern, the widely accepted successor to Computer Modern:

updmap --enable Map=lm.map

Then add this to the preamble of your LaTeX document:

\usepackage{lmodern}

Generate the PDF again, and font rendering should be fixed.

Supporting true color in xfce4-terminal

Set TERM=xterm-256color in your .zshrc / .bashrc.

Multi-monitor on ThinkPad P51

Using the default nouveau graphics driver results in xrandr freezing with an external monitor plugged in. I still haven’t gotten the DisplayPort ports to work, but here’s my solution for VGA/DVI:

  1. Install nvidia package
  2. Uninstall xf86-video-nouveau if installed
  3. Reboot computer. In BIOS, switch from “Hybrid Graphics” to “Discrete Graphics”

However, fonts might look huge in some apps after switching to nvidia

Huge fonts with NVIDIA driver

The proprietary nvidia driver misdetects my laptop screen’s DPI for some reason. This can be fixed by adding the command below to ~/.xinitrc and then rebooting.

# Replace `DP-2` with whatever `xrandr` says your laptop screen is called
xrandr --output DP-2 --dpi 96

A possibly related issue is that X fails to identify the laptop screen as the primary screen (even when no external monitors are connected), causing i3status to hide its notification area. This can be fixed by appending --primary to the command above.

Ignoring GTK theme in Firefox

In xfce4-appearance-settings I’ve selected the Adwaita-dark GTK theme. It looks decent everywhere except in Firefox, which will render dark scrollbars and form controls on otherwise light pages.

To force Firefox to use the default (light) Adwaita theme, I’ve created an executable /usr/bin/local/firefox script with these contents:

#!/usr/bin/env bash
GTK_THEME=Adwaita /usr/bin/firefox

Make sure /usr/bin/local appears before /usr/bin in your PATH.

Adding Thai font support

Install fonts-tlwg from the AUR. It looks perfectly fine and just works. I first tried ttf-ms-win10 but gave up on getting all of my Windows fonts to the same versions expected by the PKGBUILD.

Fixing audio mute

First of all, make sure you have the alsa-utils package installed. It provides two useful programs to keep open while debugging sound issues: speaker-test -t wav -c 2 plays a looping audio sample, and alsamixer shows the current volume and mute status of all audio channels.

Most people online suggest muting via the command amixer set Master toggle. This works but has an unfortunate quirk on some systems: running it a second time doesn’t actually unmute!

Muting Master mutes all channels, but unmuting Master unmutes only the Master channel. That’s a problem if you have other audio channels that depend on Master, e.g. Speaker and Headphone. The pulseaudio package provides pactl, an alternative to amixer that doesn’t suffer from the same bug. Run pactl set-sink-mute 0 toggle to toggle the mute status of all channels in unison.

In my i3 config, I have that command bound to my keyboard’s mute button like so:

bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute 0 toggle

Pacman color option unrecognized

A pacman bug causes this error when installing AUR packages with pacaur:

/usr/bin/pacman: unrecognized option '--color never'

To fix, uncomment Color in /etc/pacman.conf.

Fixing Android Studio

I was trying to set up React Native, which involves setting up Android Studio. Everything went well up until react-native run-android:

java.io.IOException: Cannot run program "/home/art/Android/Sdk/build-tools/23.0.1/aapt": error=2, No such file or directory

The solution is to enable the multilib repository and then install some packages:

pacman -S lib32-gcc-libs lib32-glibc lib32-libstdc++5 lib32-ncurses lib32-zlib

If your JAVA_HOME environment variable is unset, you may also need to set it to the grandparent directory of the file found by locate tools.jar. For example:

export JAVA_HOME=/opt/android-studio/jre

If you get errors like the one below when running Android Studio 3’s emulator, this and/or this should fix it.

Emulator: libGL error: unable to load driver: i965_dri.so

My setup

On all Arch installations:

pacman -S bc fd-rs fzf git htop ntfs-3g ripgrep sudo syncthing tmux zsh zsh-syntax-highlighting

On graphical Arch installations:

pacman -S alacritty-git dmenu easystroke evince feh firefox gimp i3-wm i3blocks i3lock i3status imagemagick jq keepassx2 network-manager-applet numlockx pacgraph rsync scrot shellcheck sublime-text-dev thunar syncthing-gtk words xfce4-goodies

My .zshrc and other dotfiles