Diving Into NixOS (Part 1.5): Swap Files, And Other Tidbits
A brief digression
As mentioned in Part 1, my swap partition may have been a little excessive. In this post, I intend to demonstrate how to go about reducing the swap size in favor of a swap file that is created only when it is needed. The Arch Wiki has a healthy amount of information on swap for those that are interested. Broadly speaking, the motivation behind having swap space is the following (snippet from the Arch Wiki itself):
[Enabling swap] avoids out of memory conditions, where the Linux kernel OOM killer mechanism will automatically attempt to free up memory by killing processes.
Swap files on NixOS
Configuring a swap file on NixOS is trivial. A quick search through the NixOS
options shows the swapDevices.*.size
option.
If you previously created a swap partition and ran nixos-generate-config
in
your initial install of NixOS - as most would have, you will find that the
swapDevices
option has already been configured in the file at
/etc/nixos/hardware-configuration.nix
. Here's a snapshot mine at the time of
writing.
# Do not modify this file! It was generated by ‘nixos-generate-config’
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, ... }:
{
imports =
[ <nixpkgs/nixos/modules/installer/scan/not-detected.nix>
];
boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/b90bca12-d251-46e0-a407-f0b1ec87970b";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/50C8-A123";
fsType = "vfat";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/916812ug-56b8-417b-bdf1-1bdee27d4499"; }
];
nix.maxJobs = lib.mkDefault 8;
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
}
To add a swap file, it is as simple as adding an additional set to the list and re-building.
swapDevices = [
{
device = "/dev/disk/by-uuid/916812ug-56b8-417b-bdf1-1bdee27d4499";
priority = 100;
size = null;
}
{
device = "/swapfile";
priority = 0;
size = 2048;
}
];
Note that the swap partition is given higher priority. The general consensus seemed to be that the partition will have better performance than the swap file.
Re-sizing the swap partition
With the easy part over, we can move on to the second objective of re-sizing our
partitions. This isn't actually too difficult either. It can be broken down
into a few steps: update the partition table; resize the adjacent drive; then
update (once again) /etc/nixos/hardware-configuration.nix
.
Start by making sure the swap device is de-activated and the root partition is unmounted. To do this, I simply booted into the NixOS live image I had prepared from Part 1 and manipulated the partitions from there. The following may come in handy.
swapoff /dev/disk/by-label/swap
umount /dev/disk/by-label/nixos
To re-size the partitions I opt for gdisk
.
# gdisk /dev/nvme0n1
GPT fdisk (gdisk) version 1.0.3
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Command (? for help):
Before re-sizing, the table shows my swap with a size of ~2GB
.
Command (? for help): p
Disk /dev/nvme0n1: 500118192 sectors, 238.5 GiB
Model: PC401 NVMe SK hynix 256GB
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): 399YGH4A-4E93-4AE1-A42A-A63649JREDEE
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 500118158
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)
Number Start (sector) End (sector) Size Code Name
1 2048 1333247 650.0 MiB EF00 EFI system partition
2 1333248 1595391 128.0 MiB 0C01 Microsoft reserved ...
3 1595392 206395391 97.7 GiB 0700 Basic data partition
4 206395392 495802367 138.0 GiB 8304 Linux x86-64 root (/)
5 495802368 500118158 2.1 GiB 8200 Linux swap
Re-size the swap partition by first deleting both the root and the swap
partitions. This is followed by re-creating the deleted entries with the new
desired sizes. Take care to ensure the start sector for your root partition is
the same as it previously was otherwise you may bork your file system. There
are ways to shift partitions (dd
can be used to store/load the contents of a
file system), but perhaps that is for another time. Remember to commit to the
table with w
.
Number Start (sector) End (sector) Size Code Name
1 2048 1333247 650.0 MiB EF00 EFI system partition
2 1333248 1595391 128.0 MiB 0C01 Microsoft reserved ...
3 1595392 206395391 97.7 GiB 0700 Basic data partition
4 206395392 498948095 139.5 GiB 8304 Linux x86-64 root (/)
5 498948096 500118158 571.3 MiB 8200 Linux swap
With the partitions re-sized, check the file system is consistent before re-sizing it to match the new partition sizes.
# e2fsck -f /dev/disk/by-label/nixos
# resize2fs /dev/disk/by-label/nixos
Finally, re-create the swap device with mkswap
and update the UUID under
swapDevices
in your /etc/nixos/hardware-configuration.nix
alongside the swap
file entry.
I found this little exercise quite fun and educational, but I still have much to learn in way of partition tables, file systems, etc. Hopefully, with this, you not only know how to configure swap devices in NixOS but can also manipulate partitions/file systems to a certain degree. Now, onto Part 2.