How to use an older version of a kernel package from an earlier nixpkgs commit?

I’m trying to use an earlier version of this kernel package. The latest version isn’t supported by my old hardware.

I’m still pretty new to nix, the possible solutions I can come up with don’t seem to work:

  1. overlay + overrideAttrs to change version, etc

    This package lives at boot.kernelPackages.prl-tools, but nixpkgs.overlays seem to only replace what’s defined under pkgs.

  2. copy the content from the earlier commit to a local file, and assign it to config.hardware.parallels.package (which is how the package gets referenced).

    This seems to guarantee that nixpkgs will use the identical content used in the earlier commit, but I have no idea how to pass the arguments to the file. These arguments seem to be provided by callPackage, but I don’t know how to refer to that callPackage in my own file, or find the sources argument provided by that callPackage.

I’m at a dead end. Could someone offer some help?


Are you trying to get an old version of the module build against a newer kernel, or to get old kernel and old module in a known-matching configuration? (The former is of course better if the module does not rely on anything that has changed in the internal kernel interfaces in the meantime…)

Thanks for the quick reply.

I believe it’s the former. I use nixpkgs unstable, so my kernel should be the latest.

I failed to mention that the kernel package I use is a bit special. It’s actually a VM guest addon. I’m not sure if it supports the latest kernel, but I’d like to give it a try.

Step 1: if you try to build kernelPackages.callPackage /path/to/restored/old/version/default.nix {}, does this build and contain the expected .ko? (Probably simplest to nix-build it outside configuration in a small wrapper expression)

I’m not sure if this package produces .ko file. It seems to produce a bunch of binaries that will be started by systemd.

I added this in configuration.nix, inspired by your suggestion:

{ pkgs, lib, config, ... }: {
  # ...
  boot.kernelPackages.prl-tools = config.boot.kernelPackages.callPackage ./prl-tools/default.nix { };
  # ...

However, it failed with

error: attribute 'extend' missing

       at /nix/store/fzh2zv40km96rpsg0d945gmdkjwk7590-source/nixos/modules/system/boot/kernel.nix:40:31:

           39|       type = types.raw;
           40|       apply = kernelPackages: kernelPackages.extend (self: super: {
             |                               ^
           41|         kernel = super.kernel.override (originalArgs: {

This should not work, indeed.

Maybe boot.kernelPackages = pkgs.linuxPackages // (pkgs.linuxPackages.callPackage ./prl-tools {}); could work, though

1 Like

OMG, this is working beautifully!

The old version works with the new kernel. Thanks a lot!

Briefly, the entirety of your assignments to boot.kernelPackages taken together should be something more or less similar to linuxPackages; and your assignment ended up with just prl-tools there. // allows to take normal linuxPackages and replace just one attribute there and there is a chance of it working.

Hmm, actually exactly how I wrote it should not do anything useful; I meant pkgs.linuxPackages // { prl-tools = pkgs.linuxPackages.callPackage ./prl-tools {}; }

Hmm, actually exactly how I wrote it should not do anything useful

Well, you made me realize that my issue was not fixed by using the older kernel package. I probably did something I didn’t realize and couldn’t remember :joy:.

I meant pkgs.linuxPackages // { prl-tools = pkgs.linuxPackages.callPackage ./prl-tools {}; }

This made rebuilding much slower, looks like it took effect. Thanks for the fix.

I’m still a little curious though, why this won’t work:

boot.kernelPackages.prl-tools = config.boot.kernelPackages.callPackage ./prl-tools/default.nix { };

If config.boot.kernelPackages.callPackage is a function, then shouldn’t config.boot.kernelPackages already be what it’s supposed to be, which should be equal to boot.kernelPackages? Or, due to the laziness, setting boot.kernelPackages.prl-tools could prevent boot.kernelPackages from getting the default value?

This made rebuilding much slower, looks like it took effect. Thanks for the fix.

To be sure, you might want to find out what would mean it at least tries to do something (not just build), and check whether this is observable (maybe a daemon running with /proc/[PID]/exe inside the package, maybe a module loaded from there…)

I’m still a little curious though, why this won’t work:

I think you are reasoning too imperatively here… and there are multiple level of complicated non-imperativeness involved.

Assigning to anything within boot.kernelPackages means you specify boot.kernelPackages (with only the stuff you have assigned). You are not replacing a single thing, you happen to be assigning the entire attrset. And it is defined with mkDefault, which means that if you do not assign it, something reasonable gets used, but if you assign it, the default gets thrown away. Some other things are merged, i.e. assigning an attrset with just a few entries means using these entries and also the entries from the original attrset. The latter behaviour gives almost-imperative-deep-assignment behaviour, which lets you expect a simple behaviour… until you encounter a differently defined option.

1 Like