Posted on October 30, 2015
Tags: nerd, nixos

The beauty of NixOS is that it’s resiliant to all sorts of blatant vandalism/incompetence. The configuration rollback menu at boot lets you try anything as long as it doesn’t corrupt the nix store.

But even if you do chop up the nix store, there are often some previous generations that you can successfully roll back to.

Of course, all Linux distros can be restored. You just need to plug in a thumbdrive with the installer image and reinstall. But with NixOS the process is much quicker, and at its worst just involves choosing an option from the GRUB2 menu.

I was trying to diagnose a hard system lockup running within KVM. After trying many options without success, I decided to test with a kernel built for a much more common distro.

How to futz with the nix store

Problem is /nix is bind-mounted read only. With btrfs you can mount the root fs again with different mount options.

mkdir /tt
mount /dev/sda /tt
touch /tt/nix/store/rcfjaddxbzc0px4vks5jy2c0hcdvbffb-linux-4.2.3/hello

Silly way of booting a debian kernel in NixOS

Rsync the kernel, modules, initrd from a Debian system. Now grab those files and put them into an existing kerrnel store directory /nix/store/rcfjaddxbzc0px4vks5jy2c0hcdvbffb-linux-4.2.3 with the same names.

Next time booting into a system configuration with this kernel, it will use your files and boot.

Except that the initrd will fail. Go back to the GRUB2 menu and edit the linux command line and add root=/dev/sda to the arguments.

How to repair the damage you did

Hint… this is not a good way of restoring the package:

rm -rf /tt/nix/store/rcfjaddxbzc0px4vks5jy2c0hcdvbffb-linux-4.2.3
nix-env -i linux-4.2.3  # won't work

Nix can check what’s broken (https://nixos.org/wiki/Install/remove_software#Repair_your_installation)

nix-store --verify --check-contents --repair

But this won’t get back your packages. Also running

nix-store --delete --ignore-liveness /nix/store/rcfjaddxbzc0px4vks5jy2c0hcdvbffb-linux-4.2.3

Is not necessarily a good idea. It will also remove packages which depend on that package. In this case it removes the system config package and henceforth no commands work.

Good thing that previous configurations can be booted from the GRUB2 menu.

At this point, building new configs may fail due to install-grub.pl looking for files from missing store directories of previous configurations.

fileparse(): need a valid pathname at /nix/store/zldbbngl0f8g5iv4rslygxwp0dbg1624-install-grub.pl line 391.

Well at long as you’re currently booted into a valid configuration, the previous ones can be cleaned out (https://nixos.org/wiki/Install/remove_software#Garbage_collection):

nix-collect-garbage -d

After this, try the rebuild and it will work.

More sensible way of booting another kernel

Rsync the kernel files from debian system to /root/deb-4.2.

cd /root/deb-4.2
ln -s vmlinuz-4.2.0-1-amd64 bzImage
ln -s System.map-4.2.0-1-amd64 System.map
ln -s initrd.img-4.2.0-1-amd64 initrd
ls lib/modules/4.2.0-1-amd64 # check it's there

Add this to your configuration, with adjustment to point to a system config that exists.

boot.loader.grub.extraEntries = ''
  menuentry "Debian kernel" {
    set systemconfig="/nix/store/3qhmv10a060bp81b2kr6735m7amm4a26-nixos-system-nixos.rodney.id.au-16.03pre-git"
    linux (hd0)/root/deb-4.2/bzImage systemConfig=$systemconfig init=$systemconfig/init console=ttyS0 loglevel=7 root=/dev/sda
    initrd (hd0)/root/deb-4.2/initrd
  }
'';

How to choose another version of Linux

Just set the boot option.

boot.kernelPackages = pkgs.linuxPackages_4_2;

How to set kernel options

Seems pretty easy…

packageOverrides = pkgs: {
  stdenv = pkgs.stdenv // {
    platform = pkgs.stdenv.platform // {
      kernelExtraConfig = "CONFIG_MAGIC_SYSRQ y" ;
    };
  }; 
};

This will obviously cause nix to build a new kernel. But you don’t have to do anything except wait.

How to apply kernel patches

It’s possible in a similar way to setting options, and looks much easier than running make-kpkg. I have spent just too much time looking at the documentation for kernel-package and debhelper.