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!
- Recovering from a bad upgrade
- Installing from PKGBUILD
- Using an external hard drive
- Freeing up disk space
- Increasing the file watch limit
- Booting UEFI with an existing EFI partition
- Ditching GRUB (only for UEFI systems)
- Suspending after inactivity
- Manually connecting to a WPA network
- Fixing iptables unknown options
- Fixing slow pip downloads
- Connecting to an L2TP/IPsec VPN
- Getting Intel Wireless 8260 card to work
- Fixing the default LaTeX font
- Supporting true color in xfce4-terminal
- Multi-monitor on ThinkPad P51
- Huge fonts with NVIDIA driver
- Ignoring GTK theme in Firefox
- Adding Thai font support
- Pairing Bluetooth headphones
- Fixing audio mute
- Pacman color option unrecognized
- Fixing Flatpak Steam
- Fixing Android Studio
- My setup
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
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.
Turn on the computer and go into BIOS by hitting some manufacturer-specific key combination after the screen turns on (e.g.
Fn+F2on 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.
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
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.
Installing from PKGBUILD
libreswan update broke compatibility with
libreswan (AUR) via
downgrade wasn’t an option since I aggressively clear my pacman cache, and after a week I got tired of waiting for the
networkmanager-l2tp fix to land in Arch’s official repo.
Solution: Clone the
libreswan repo to
cd into it,
git reset --hard to the last compatible version, and run
makepkg -si to build and install.
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
Suspending after inactivity
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) dhcpcd ping 22.214.171.124
Fixing iptables unknown options
The default version of
iptables drops support for a command-line option that Docker uses:
docker: Error response from daemon: driver failed programming external connectivity on endpoint tender_volhard (954d664336eb5ea7b2c7f808889b3033977b45f53f99ba38bbc66bfcf14a61ef): (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 80 -j DNAT --to-destination 172.17.0.2:80 ! -i docker0: iptables v1.8.2 (legacy): unknown option "--dport" Try `iptables -h' or 'iptables --help' for more information.
iptables-nft restores the legacy
--dport option. Note that whenever you update the Linux kernel, the option may become unavailable again until the next reboot.
Fixing slow pip downloads
One day my
pip install suddenly became comically slow, seemingly on the order of 10 kB/s. A
pip -vvv revealed that it was hanging on “Starting new HTTPS connection (1) pypi.org”, which led me to this post that correctly identified my issue: pip tried and failed to connect using multiple IPv6 addresses until it finally gave up and fell back to IPv4.
My workaround was to simply disable IPv6 in kernel params 🤷
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
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-ltsand then run
sudo grub-mkconfig. I still haven’t gotten it working, though.
Update 2018-12-26: I’ve given up on libreswan and networkmanager. Here’s a guide for openswan.
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:
Generate the PDF again, and font rendering should be fixed.
Supporting true color in xfce4-terminal
TERM=xterm-256color in your
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:
- Reboot computer. In BIOS, switch from “Hybrid Graphics” to “Discrete Graphics”
However, fonts might look huge in some apps after switching to
Huge fonts with NVIDIA driver
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
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
/usr/bin/local appears before
/usr/bin in your PATH.
Adding Thai font support
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.
Pairing Bluetooth headphones
pacman -S bluez bluez-utils blueman pulseaudio-bluetooth modprobe btusb systemctl enable bluetooth.service pulseaudio -k blueman-applet
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
Fixing Flatpak Steam
I installed Steam via Flatpak as documented in the Arch wiki, which initially worked fine. However, I got this error the second time I tried running Steam:
$ flatpak run com.valvesoftware.Steam ** flatpak:ERROR:libglnx/glnx-shutil.c:155:mkdir_p_at_internal: assertion failed: (!did_recurse) Bail out! flatpak:ERROR:libglnx/glnx-shutil.c:155:mkdir_p_at_internal: assertion failed: (!did_recurse) zsh: abort (core dumped) flatpak run com.valvesoftware.Steam
It looked like some symlink targets were missing…
$ ls -AGl ~/.var/app/com.valvesoftware.Steam total 8 lrwxrwxrwx 1 art 6 Jul 28 02:38 cache -> .cache lrwxrwxrwx 1 art 7 Jul 28 02:38 config -> .config drwxr-xr-x 2 art 4096 Jul 28 02:38 config.old lrwxrwxrwx 1 art 12 Jul 28 02:38 data -> .local/share drwxr-xr-x 2 art 4096 Jul 28 02:38 .ld.so
Pointing them to their counterparts in my home directory solved the issue:
$ ln -sf ~/.cache ~/.var/app/com.valvesoftware.Steam/cache $ ln -sf ~/.config ~/.var/app/com.valvesoftware.Steam/config $ ln -sf ~/.local/share ~/.var/app/com.valvesoftware.Steam/data $ ls -AGl ~/.var/app/com.valvesoftware.Steam total 8 lrwxrwxrwx 1 art 16 Jul 29 02:02 cache -> /home/art/.cache lrwxrwxrwx 1 art 17 Jul 29 02:02 config -> /home/art/.config drwxr-xr-x 2 art 4096 Jul 28 02:38 config.old lrwxrwxrwx 1 art 22 Jul 29 02:02 data -> /home/art/.local/share drwxr-xr-x 2 art 4096 Jul 28 02:38 .ld.so
Fixing Android Studio
I was trying to set up React Native, which involves setting up Android Studio. Everything went well up until
java.io.IOException: Cannot run program "/home/art/Android/Sdk/build-tools/23.0.1/aapt": error=2, No such file or directory
pacman -S lib32-gcc-libs lib32-glibc lib32-libstdc++5 lib32-ncurses lib32-zlib
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:
Emulator: libGL error: unable to load driver: i965_dri.so
On all Arch installations:
pacman -S bc fd-rs fzf git htop ncdu ntfs-3g python-pre-commit rclone ripgrep rsync sudo syncthing tmux words zsh zsh-syntax-highlighting
On graphical Arch installations:
pacman -S alacritty dmenu docker easystroke evince feh firefox gimp i3-wm i3blocks i3blocks-contrib-git i3lock i3status imagemagick jq keepassxc network-manager-applet numlockx pacgraph scrot shellcheck sublime-text-dev thunar syncthing-gtk-python3 xfce4-goodies xfce4-power-manager