# zigford.org

About | Links | Scripts
Sharing linux/windows scripts and tips

### Precision 5510 - Gentoo GNU/Linux

October 12, 2019 — Jesse Harris

This documents all configurations, apps and tweaks to get a nicely working Linux machine.

# Installation

## Partition

The system was built with an existing Windows EFI partition table but this weekend I converted it over to a luks/dmcrypt partition scheme. Thus the table was created is as follows:

1. 200Mb ESP volume
2. 477.8G Linux filesystem

The Linux filesystem is an aes-xts-plain64 with a 512 key size.

            cryptsetup luksFormat /dev/nvme0n1p6 -c aes-xts-plain64 -s 512

After the encrypted volume is created, and opened, lvm was used to create a 444Gb partition for root and the remaining 32Gb for swap/resume. The root volume then formatted with btrfs.

            mkfs.btrfs /dev/mapper/lvm-root

Mounting the btrfs root subvolume in the Gentoo Live install:

            mkdir /mnt/btrfs
            mount /dev/mapper/lvm-root /mnt/btrfs

Create 2 subvolumes in the / root and mount @root

            btrfs subvolume create /mnt/btrfs/\@root
            btrfs subvolume create /mnt/btrfs/\@home

            mount /dev/mapper/lvm-root /mnt/gentoo -o subvol=@root

## Stage3

The original stage3 tarball was `stage3-amd64-systemd-20190823.tar.bz2`
systemd was chosen so that I'm using the same init system that I need to support for my day job.

After stage 3 is extracted, mount the home subvolume and boot volume:

            mount /dev/mapper/lvm-root /mnt/gentoo/home -o subvol=@home
            mount /dev/nvme0n1p1 /mnt/gentoo/boot

Chroot in as per the Gentoo handbook

## Portage

Initial portage `make.conf` setup to get going should include the following:

            COMMON_FLAGS="-march=skylake -O2 -pipe"
            VIDEO_CARDS="intel i965"
            MAKEOPTS="-j9 -l8"
            GENTOO_MIRRORS="http://ftp.swin.edu.au/gentoo"
            EMERGE_DEFAULT_OPTS="--jobs=8 --load-average=8"
            FEATURES="${FEATURES} parallel-fetch"

More settings to be discussed in Make.conf section later. This is all that is relevant for the initial install.

## Kernel

Kernel config can be found on my kernel-configs github repo Make it with `-j8` for all cores and after installed, edit /etc/default/grub:

            GRUB_CMDLINE_LINUX="dobtrfs rootfstype=btrfs"

Use genkernel-next to build an initramfs and install grub

            genkernel initramfs
            grub-install /dev/nvme0n1

## Applications

First app in vim, as it is not in Gentoo base, other handy apps for getting the system up and running:

- app-editors/vim
- app-admin/sudo
- app-portage/eix
- app-portage/gentoolkit
- dev-vcs/git
- sys-apps/usbutils
- sys-fs/btrfsprogs
- sys-boot/os-prober
- sys-kernel/genkernel

Note Genkernel pulls in sys-kernel/linux-firmware which has the binary blobs required to get the wifi chip working on the Precision 5510.

## World build

As per the Handbook, build the world, install the kernel, grub and reboot. But! Don't forget to set the root password

# First setup

After first boot systemd has everything you need to get connected to the network to get everything going. Create a file in /etc/systemd/network to setup dhcp on eth0. Enable systemd-networkd to get going until networkmanager later.

## Administration

Setup `sudo` for quicker elevation:

            vim /etc/sudoers

            %wheel ALL=(ALL) NOPASSWD: ALL

## Useful groups

wheel : Allows to su to root, or use sudo
plugdev : Allows to connect to wifi as regular user and other hardware stuff
portage : Can write into portage distfiles for testing and making ebuilds

## Sleep and hibernate

Swap file is big enough to hold most of the RAM. Grub config is updated to specify the swap partition UUID as the resume parameter

            GRUB_CMDLINE_LINUX="dobtrfs rootfstype=btrfs resume=UUID=9a900eaa-0312-4796-93f8-da3245add9d4"

Suspend then hibernate delay is set to 4 hours:

            vim /etc/systemd/sleep.conf

            [Sleep]
            HibernateDelaySec=240min

Lidswitch is set to suspend then hibernate

            vim /etc/systemd/logind.conf

            [Login]
            HandleLidSwitch=suspend-then-hibernate
            HandleLidSwitchDocked=ignore

# Xorg and Gnome

use flags for gnome added to `make.conf`

            USE="gtk bluetooth gnome -qt gdm samba acl vim readline fuse"
            L10N="en" # for dictionary in evolution

Explanation:

`fuse` is required for `gnome-gvfs` (which is a dep of gnome-base/gnome-vfs). This makes paths mounted from gnome, visible at /run/user/UID/gvfs

emerge gnome-base/gnome and the following apps

- gnome-base/gnome-vfs # For smb connections in nautilus
- gnome-extra/evolution-ews # Connect evolution to exchange online
- x11-terms/kitty # terminal with ligature font support
- www-client/firefox-bin

# Packages for work

- net-vpn/networkmanager-openconnect # vpn in networkmanager for work
- net-misc/freerdp # Rdp to servers for work
- net-misc/icaclient # Citrix client for work

# Extending Gentoo

Apart from emerge, I'm making use of other package managers on Gentoo to complete the environment.

Install layman

            emerge -a layman
            layman -L
            layman -a snapd
            layman -a flatpak
            layman -o http://jesseharrisit.com/overlay.xml -f -a gentoo-zigford
            emerge -a app-emulation/snapd
            emerge -a app-emulation/flatpak

## snapd packages

            snap install chromium
            snap install teams-for-linux
            snap install p3xonenote
            snap install caprine

# KVM - Qemu

For virtualization, I primarily want to interface with VM's using gnome-boxes, however as it lacks the sophistication for complex VM's, I also install virt-manager.

Use flags for virtualization:

            app-emulation/libvirt apparmor virt-network
            app-emulation/qemu doc usbredir smartcard spice
            app-emulation/spice smartcard
            net-dns/dnsmasq script
            net-misc/spice-gtk smartcard usbredir vala

Kernel settings to enable networking in the kernel mentioned earlier. qemu settings required for efi virtual machine

            vim /etc/libvirt/qemu.conf
            security = "none"
            nvram = [
                "/usr/share/edk2-ovmf/OVMF_CODE.fd:/usr/share/edk2-ovmf/OVMF_VARS.fd"
            ]

For a vm in boxes to run efi:

            cp /etc/libvirt/qemu.conf ~/.config/libvirt

Group memberships:

            usermod -G kvm,libvirt,qemu -a username

Tweaks to apparmor

            sed -ie 's/#include <local/include <local/' usr.sbin.dnsmasq
            vim local/usr.sbin.dnsmasq

            capability mknod,
            /usr/libexec/libvirt_leaseshelper rix,
            /var/lib/libvirt/dnsmasq/*.status* rw,
            /run/leaseshelper.pid rwk,

            vim usr.sbin.libvirt

            capability sys_rawio,

Set libvirt images directory to no copy on write

            chattr +C /var/lib/libvirt/images

Allow Gnome-Boxes to use libvirt's networking. Also requires user to be a member of qemu group

            cat /etc/qemu/bridge.conf

            allow virbr0

# Backups

Thanks to the power of btrfs, backups are facilitated easily by snapshots. Currently I have a systemd timer set to fire every hour. It fires a script which does the following:

1. Mount the root btrfs volume to /mnt/btrfs (this houses 2 subvols)

2. Snapshot each subvol into /mnt/btrfs/snapshots/subvolname-yyyy-MM-dd-hh:mm:ss

3. Prune any snapshots that are not any of the following:

   - in the last 24 hours
   - daily in the last month
   - monthly until the backup drive fills to 10% free

4. If a designated backup drive is attached, transfer all snapshots

5. Delete all bar the last 2 transfered per subvolume

Finally, if the drive is not attached, when it does become available the script is invoked with a parameter to just catch up on the snapshots.

The script can be found on github and the systemd timer and service look like this:

/etc/snapshots.conf

            [home]
            LocalSnapshots=/mnt/btrfs/snapshots
            RemoteSnapshots=/run/media/harrisj/7cb22d51-b8a7-45ee-b1a3-2f3db51c931f
            SubvolumeRoot=/home

            [root]
            LocalSnapshots=/mnt/btrfs/snapshots
            RemoteSnapshots=/run/media/harrisj/7cb22d51-b8a7-45ee-b1a3-2f3db51c931f
            SubvolumeRoot=/

snapshot.service

            [Unit]
            Description=Take a BTRFS Snapshot of all the volumes

            [Service]
            Type=simple
            ExecStart=/usr/local/bin/snapshot

snapshot.timer

            [Unit]
            Description=Timer file for snapshot unit. Snapshots hourly and continually prunes

            [Timer]
            OnCalendar=*-*-* *:00:00
            Persistent=true

            [Install]
            WantedBy=timers.target

backup-snapshots.service

            [Unit]
            Description=Backup snapshots when backup drive is attached
            Requires=run-media-harrisj-7cb22d51\x2db8a7\x2d45ee\x2db1a3\x2d2f3db51c931f.mount
            After=run-media-harrisj-7cb22d51\x2db8a7\x2d45ee\x2db1a3\x2d2f3db51c931f.mount

            [Service]
            ExecStart=/usr/local/bin/snapshot -b

            [Install]
            WantedBy=run-media-harrisj-7cb22d51\x2db8a7\x2d45ee\x2db1a3\x2d2f3db51c931f.mount

# Docker

Docker's default IP range conflicts with works DNS. The following file switches it to another address range.

            cat /etc/docker/daemon.json
            {
                "bip": "192.168.12.5/24",
                "fixed-cidr": "192.168.12.5/25",
                "fixed-cidr-v6": "2001:db8::/64",
                "mtu": 1500
            }

# Wifi off on ethernet

In my shed the wifi is weak. I'm on wired here, so don't need the wifi. Thankfully NetworkManager offers ability to run scripts when connections change.

            cat /etc/NetworkManager/dispatcher.d/wired_only.sh
            #!/bin/sh

            IF=$1
            STATUS=$2

            if echo "$IF" |grep -q enp0s20f0u2u1i5
            then
                case "$2" in
                    up)
                        logger -s "ethernet up killing wifi"
                        rfkill block 1
                    ;;
                    down)
                        logger -s "ethernet down, raising wifi"
                        rfkill unblock 1
                    ;;
                    *)
                    ;;
                esac
            fi

# Automatically stop and start DisplayLink manager

At home, I'm using a Targus USB 3.0 dock to connect to two monitors. It's pretty convinient but it does use a few extra joules of battery (as shown by powertop).

Instead of manually stopping and starting the dlm service. I can use systemd and udev rules to run the service only when the device is attached.

            cat /etc/udev/rules.d/99-displaylink.rules
            ACTION=="add", ATTRS{idProduct}=="4306", ATTRS{idVendor}=="17e9", ENV{SYSTEMD_WANTS}="dlm.service"

This rule will start `dlm` when the usb device is detected. The following alteration to the systemd unit for dlm ensures that when the device is removed, the service is stopped.

            systemctl cat dlm
            # /lib/systemd/system/dlm.service
            [Unit]
            Description=DisplayLink Manager Service
            After=display-manager.service
            Conflicts=getty@tty7.service

            [Service]
            ExecStartPre=/sbin/modprobe evdi
            ExecStart=/opt/displaylink/DisplayLinkManager
            Restart=always
            WorkingDirectory=/opt/displaylink
            RestartSec=5

            [Install]
            WantedBy=graphical.target

            # /etc/systemd/system/dlm.service.d/override.conf
            [Unit]
            BindsTo=sys-subsystem-net-devices-enp0s20f0u2u1i5.device
            StopWhenUnneeded=true

Note that the alterations are configured using `systemctl edit dlm`

Tags: gentoo, btrfs, linux