Skip to content

Add cross-compilation support for disk formatting (ZFS)#1190

Open
dvaerum wants to merge 1 commit intonix-community:masterfrom
dvaerum:cross-build
Open

Add cross-compilation support for disk formatting (ZFS)#1190
dvaerum wants to merge 1 commit intonix-community:masterfrom
dvaerum:cross-build

Conversation

@dvaerum
Copy link
Copy Markdown
Contributor

@dvaerum dvaerum commented Jan 19, 2026

Add cross-compilation support for disk formatting (ZFS)
When formatting disks for a different target architecture (e.g.,
creating an aarch64 disk image from an x86_64 host), tools like ZFS that
communicate with kernel modules must use host-native binaries.

I am guessing there also exist other cases when ZFS comes into play.

This is not a problem with tools like ext4 because they do everything
in user space.

I have created an example file and used it to build the file system for
the archs aarch64, armv7l, i686, riscv64 and x86_64.

Note: The host system must have the following nixos configs enabled.

# `preferStaticEmulators` is need or the activation script in chroot
# cannot be executed because it is a different arch when the host system
boot.binfmt.preferStaticEmulators = true;
boot.binfmt.emulatedSystems = [ "<TARGET_ARCH>" ];

Update: 2026-03-04

If you get the following error when trying out this patch:

error:
       … from call site
         at /nix/store/kl1z5wlb7cb77l68l8a7n6486c2ki4qm-disko/share/disko/install-cli.nix:67:13:
           66|   # that can communicate with the running kernel
           67|   scripts = diskoSystem.config.disko.devices._scripts {
             |             ^
           68|     pkgs = diskoSystem.pkgs; # target pkgs for mount scripts
       error: function 'default' called with unexpected argument 'hostPkgs'
       at /nix/store/zaz0bhdxnm77pvnwn0y07df87b3r97sj-source/lib/default.nix:721:15:
          720|             default =
          721|               {
             |               ^
          722|                 pkgs,
Failed to build NixOS configuration 

When it happens because the disko version used in your flake input of the system you are trying to build is from upstream. You need to use this for your flake inputs:

...
    disko = {
      url = "github:nix-community/disko?ref=pull/1190/merge";
      inputs.nixpkgs.follows = "nixpkgs";
    };
...

I just bumped into this problem today and was quite confused for some time.

@Enzime
Copy link
Copy Markdown
Member

Enzime commented Jan 19, 2026

@DavHau can you take a look at this?

@dvaerum dvaerum force-pushed the cross-build branch 2 times, most recently from 789ab9f to 4c51c0c Compare January 19, 2026 21:11
@dvaerum
Copy link
Copy Markdown
Contributor Author

dvaerum commented Jan 19, 2026

Hey @Enzime, I am open for feedback, but this is a draft because it is not ready 😅

@dvaerum dvaerum force-pushed the cross-build branch 2 times, most recently from 8980f86 to 25ca103 Compare January 24, 2026 13:02
@dvaerum dvaerum force-pushed the cross-build branch 2 times, most recently from 36699f9 to b7163aa Compare February 3, 2026 20:33
When formatting disks for a different target architecture (e.g.,
creating an aarch64 disk image from an x86_64 host), tools like ZFS that
communicate with kernel modules must use host-native binaries.

I am guessing there also exist other cases when ZFS comes into play.

This is not a problem with tools like `ext4` because they do everything
in user space.

I have created an example file and used it to build the file system for
the archs `aarch64`, `armv7l`, `i686`, `riscv64` and `x86_64`.

**Note:** The host system must have the following nixos configs enabled.

```nix
# `preferStaticEmulators` is need or the activation script in chroot
# cannot be executed because it is a different arch when the host system
boot.binfmt.preferStaticEmulators = true;
boot.binfmt.emulatedSystems = [ "<TARGET_ARCH>" ];
```
@dvaerum dvaerum marked this pull request as ready for review February 3, 2026 20:53
@dvaerum
Copy link
Copy Markdown
Contributor Author

dvaerum commented Feb 3, 2026

Hey @Enzime and @DavHau

I have had some time to continue my work on this and it should not actually be working. If you want to have a look 😁

@yajo
Copy link
Copy Markdown
Contributor

yajo commented Feb 10, 2026

This does make sense. We should always be able to format drives using local arch binaries, because the output is a formatted disk where to put stuff on. I mean, I can format any USB in any computer and, later, plug it in another one; it's just the same.

I miss some docs about how to use the feature.

@dvaerum
Copy link
Copy Markdown
Contributor Author

dvaerum commented Feb 10, 2026

I miss some docs about how to use the feature.

What type of documentation are you looking for? Because the point is that you just use disko as you do now, it is just that the cross-building with ZFS (and hopefully by extension other other filesystems which uses kernel modules) setups also works. The change makes disko use the native binaries instead of emulating the binaries from another architecture.

You do have to have the following enabled/configured on the system you run disko on (but you always need that for cross-build).

{ boot.binfmt.preferStaticEmulators = true;
  boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
}

I have just added a check with an error message, as you can see here.

https://github.com/dvaerum/disko/blob/48df1b44b55e997cd498a2e3747f6958492bfa58/disko-install#L199-L218

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants